Compare commits

..

553 Commits

Author SHA1 Message Date
81db6a3171 release: cut the v10.0.12 release 2020-08-24 15:15:10 -07:00
8224e65e70 docs(localize): fix angular.json syntax (#38553)
In chapter internationalization (i18n) at section "Deploy multiple locales" the syntax for angular.json is wrong.
This commit fixes the angular.json, when specifying the translation file and the baseHref for a locale.

PR Close #38553
2020-08-24 09:25:38 -07:00
9e50cef507 test(language-service): [Ivy] return cursor position in overwritten template (#38552)
In many testing scenarios, there is a common pattern:

1. Overwrite template (inline or external)
2. Find cursor position
3. Call one of language service APIs
4. Inspect spans in result

In order to faciliate this pattern, this commit refactors
`MockHost.overwrite()` and `MockHost.overwriteInlineTemplate()` to
allow a faux cursor symbol `¦` to be injected into the template, and
the methods will automatically remove it before updating the script snapshot.
Both methods will return the cursor position and the new text without
the cursor symbol.

This makes testing very convenient. Here's a typical example:

```ts
const {position, text} = mockHost.overwrite('template.html', `{{ ti¦tle }}`);
const quickInfo = ngLS.getQuickInfoAtPosition('template.html', position);
const {start, length} = quickInfo!.textSpan;
expect(text.substring(start, start + length)).toBe('title');
```

PR Close #38552
2020-08-24 09:25:07 -07:00
66d8c223a9 feat(language-service): introduce hybrid visitor to locate AST node (#38540)
This commit introduces two visitors, one for Template AST and the other
for Expression AST to allow us to easily find the node that most closely
corresponds to a given cursor position.

This is crucial because many language service APIs take in a `position`
parameter, and the information returned depends on how well we can find
a good candidate node.

In View Engine implementation of language service, the search for the node
and the processing of information to return the result are strongly coupled.
This makes the code hard to understand and hard to debug because the stack
trace is often littered with layers of visitor calls.

With this new feature, we could test the "searching" part separately and
colocate all the logic (aka hacks) that's required to retrieve an accurate
span for a given node.

Right now, only the most "narrow" node is returned by the main exported
function `findNodeAtPosition`. If needed, we could expose the entire AST
path, or expose other methods to provide more context for a node.

Note that due to limitations in the template AST interface, there are
a few known cases where microsyntax spans are not recorded properly.
This will be dealt with in a follow-up PR.

PR Close #38540
2020-08-24 09:24:21 -07:00
814b43647d fix(compiler-cli): adding references to const enums in runtime code (#38542)
We had a couple of places where we were assuming that if a particular
symbol has a value, then it will exist at runtime. This is true in most cases,
but it breaks down for `const` enums.

Fixes #38513.

PR Close #38542
2020-08-21 12:23:24 -07:00
6b98567b6b fix(dev-infra): ignore comments when validating commit messages (#38438)
When creating a commit with the git cli, git pre-populates the editor
used to enter the commit message with some comments (i.e. lines starting
with `#`). These comments contain helpful instructions or information
regarding the changes that are part of the commit. As happens with all
commit message comments, they are removed by git and do not end up in
the final commit message.

However, the file that is passed to the `commit-msg` to be validated
still contains these comments. This may affect the outcome of the commit
message validation. In such cases, the author will not realize that the
commit message is not in the desired format until the linting checks
fail on CI (which validates the final commit messages and is not
affected by this issue), usually several minutes later.

Possible ways in which the commit message validation outcome can be
affected:
- The minimum body length check may pass incorrectly, even if there is
  no actual body, because the comments are counted as part of the body.
- The maximum line length check may fail incorrectly due to a very long
  line in the comments.

This commit fixes the problem by removing comment lines before
validating a commit message.

Fixes #37865

PR Close #38438
2020-08-21 12:17:17 -07:00
7f2a3e4b6b docs: apply code styling in template reference variables guide (#38522)
PR Close #38522
2020-08-20 13:01:37 -07:00
1775f351d6 fix(docs-infra): fix vertical alignment of external link icons (#38410)
At some places external link icons appear as a subscript. For example
8366effeec/aio/content/guide/roadmap.md\#L37
this commit places external link icons in the middle to improve there
positioning in a line.

PR Close #38410
2020-08-20 09:40:05 -07:00
1df52d9acd docs: udpate the details (#37967)
updating my twitter handle and bio as it is changed from
Angular and Web Tech to Angular also the
twitter handle is changed to SantoshYadavDev

PR Close #37967
2020-08-20 09:39:05 -07:00
77e8db4484 docs(core): Fix typo in JSDoc for AbstractType<T> (#38541)
PR Close #38541
2020-08-20 09:30:24 -07:00
c90262e619 Revert "Revert "fix(core): remove closing body tag from inert DOM builder (#38454)""
This reverts commit 87bbf69ce8.
2020-08-20 08:56:01 -07:00
87bbf69ce8 Revert "fix(core): remove closing body tag from inert DOM builder (#38454)"
This reverts commit 552853648c.
2020-08-19 21:02:55 -07:00
552853648c fix(core): remove closing body tag from inert DOM builder (#38454)
Fix a bug in the HTML sanitizer where an unclosed iframe tag would
result in an escaped closing body tag as the output:

_sanitizeHtml(document, '<iframe>') => '&lt;/body&gt;'

This closing body tag comes from the DOMParserHelper where the HTML to be
sanitized is wrapped with surrounding body tags. When an opening iframe
tag is parsed by DOMParser, which DOMParserHelper uses, everything up
until its matching closing tag is consumed as a text node. In the above
example this includes the appended closing body tag.

By removing the explicit closing body tag from the DOMParserHelper and
relying on the body tag being closed implicitly at the end, the above
example is sanitized as expected:

_sanitizeHtml(document, '<iframe>') => ''

PR Close #38454
2020-08-19 14:18:47 -07:00
07b99f5975 fix(localize): parse all parts of a translation with nested HTML (#38452)
Previously nested container placeholders (i.e. HTML elements) were
not being fully parsed from translation files. This resulted in bad
translation of messages that contain these placeholders.

Note that this causes the canonical message ID to change for
such messages. Currently all messages generated from
templates use "legacy" message ids that are not affected by
this change, so this fix should not be seen as a breaking change.

Fixes #38422

PR Close #38452
2020-08-19 14:16:48 -07:00
57d1a483fc fix(localize): include the last placeholder in parsed translation text (#38452)
When creating a `ParsedTranslation` from a set of message parts and
placeholder names a textual representation of the message is computed.
Previously the last placeholder and text segment were missing from this
computed message string.

PR Close #38452
2020-08-19 14:16:45 -07:00
d662a6449e refactor(compiler-cli): add getTemplateOfComponent to TemplateTypeChecker (#38355)
This commit adds a `getTemplateOfComponent` method to the
`TemplateTypeChecker` API, which retrieves the actual nodes parsed and used
by the compiler for template type-checking. This is advantageous for the
language service, which may need to query other APIs in
`TemplateTypeChecker` that require the same nodes used to bind the template
while generating the TCB.

Fixes #38352

PR Close #38355
2020-08-19 14:07:07 -07:00
e57a2b3c47 docs: Typos fixes in the binding syntax guide (#38519)
PR Close #38519
2020-08-19 14:05:53 -07:00
a3f3082bf0 release: cut the v10.0.11 release 2020-08-19 09:05:11 -07:00
0570c240e4 docs: Fix typo in the inputs and outputs guide (#38524)
PR Close #38524
2020-08-19 08:27:48 -07:00
398118f708 feat(dev-infra): create a wizard for building commit messages (#38457)
Creates a wizard to walk through creating a commit message in the correct
template for commit messages in Angular repositories.

PR Close #38457
2020-08-18 17:01:18 -07:00
dcc3f6d74d feat(dev-infra): tooling to check out pending PR (#38474)
Creates a tool within ng-dev to checkout a pending PR from the upstream repository.  This automates
an action that many developers on the Angular team need to do periodically in the process of testing
and reviewing incoming PRs.

Example usage:
  ng-dev pr checkout <pr-number>

PR Close #38474
2020-08-18 16:22:52 -07:00
0af95332e9 fix(router): ensure routerLinkActive updates when associated routerLinks change (#38511)
This commit introduces a new subscription in the `routerLinkActive` directive which triggers an update
when any of its associated routerLinks have changes. `RouterLinkActive` not only needs to know when
links are added or removed, but it also needs to know about if a link it already knows about
changes in some way.

Quick note that `from...mergeAll` is used instead of just a simple
`merge` (or `scheduled...mergeAll`) to avoid introducing new rxjs
operators in order to keep bundle size down.

Fixes #18469

PR Close #38511
2020-08-18 10:21:55 -07:00
f9a76a7d06 Revert "fix(router): ensure routerLinkActive updates when associated routerLinks change (#38349)" (#38511)
This reverts commit e0e5c9f195.
Failures in Google tests were detected.

PR Close #38511
2020-08-18 10:21:52 -07:00
832a54ee42 docs(common): Wrong parameter description on TrackBy (#38495)
Track By Function receive the T[index] data, not the node id.
TrackByFunction reference description has the same issue.
PR Close #38495
2020-08-18 10:08:47 -07:00
e8f4294e7f refactor(localize): update yargs and typings for yargs (#38502)
Updating yargs and typings for the updated yargs module.

PR Close #38502
2020-08-18 10:06:32 -07:00
ce448f4341 refactor(ngcc): update yargs and typings for yargs (#38502)
Updating yargs and typings for the updated yargs module.

PR Close #38502
2020-08-18 10:06:29 -07:00
847eaa0fa3 refactor(dev-infra): update yargs and typings for yargs (#38502)
Updating yargs and typings for the updated yargs module.

PR Close #38502
2020-08-18 10:06:26 -07:00
3e80f0e526 release: cut the v10.0.10 release 2020-08-17 13:10:36 -07:00
f3dd6c224c fix(ngcc): detect synthesized delegate constructors for downleveled ES2015 classes (#38500)
Similarly to the change we landed in the `@angular/core` reflection
capabilities, we need to make sure that ngcc can detect pass-through
delegate constructors for classes using downleveled ES2015 output.

More details can be found in the preceding commit, and in the issue
outlining the problem: #38453.

Fixes #38453.

PR Close #38500
2020-08-17 12:50:19 -07:00
863acb6c21 fix(core): detect DI parameters in JIT mode for downleveled ES2015 classes (#38500)
In the Angular Package Format, we always shipped UMD bundles and previously even ES5 module output.
With V10, we removed the ES5 module output but kept the UMD ES5 output.

For this, we were able to remove our second TypeScript transpilation. Instead we started only
building ES2015 output and then downleveled it to ES5 UMD for the NPM packages. This worked
as expected but unveiled an issue in the `@angular/core` reflection capabilities.

In JIT mode, Angular determines constructor parameters (for DI) using the `ReflectionCapabilities`. The
reflection capabilities basically read runtime metadata of classes to determine the DI parameters. Such
metadata can be either stored in static class properties like `ctorParameters` or within TypeScript's `design:params`.

If Angular comes across a class that does not have any parameter metadata, it tries to detect if the
given class is actually delegating to an inherited class. It does this naively in JIT by checking if the
stringified class (function in ES5) matches a certain pattern. e.g.

```js
function MatTable() {
  var _this = _super.apply(this, arguments) || this;
```

These patterns are reluctant to changes of the class output. If a class is not recognized properly, the
DI parameters will be assumed empty and the class is **incorrectly** constructed without arguments.

This actually happened as part of v10 now. Since we downlevel ES2015 to ES5 (instead of previously
compiling sources directly to ES5), the class output changed slightly so that Angular no longer detects
it. e.g.

```js
var _this = _super.apply(this, __spread(arguments)) || this;
```

This happens because the ES2015 output will receive an auto-generated constructor if the class
defines class properties. This constructor is then already containing an explicit `super` call.

```js
export class MatTable extends CdkTable {
    constructor() {
        super(...arguments);
        this.disabled = true;
    }
}
```

If we then downlevel this file to ES5 with `--downlevelIteration`, TypeScript adjusts the `super` call so that
the spread operator is no longer used (not supported in ES5). The resulting super call is different to the
super call that would have been emitted if we would directly transpile to ES5. Ultimately, Angular no
longer detects such classes as having an delegate constructor -> and DI breaks.

We fix this by expanding the rather naive RegExp patterns used for the reflection capabilities
so that downleveled pass-through/delegate constructors are properly detected. There is a risk
of a false-positive as we cannot detect whether `__spread` is actually the TypeScript spread
helper, but given the reflection patterns already make lots of assumptions (e.g. that `super` is
actually the superclass, we should be fine making this assumption too. The false-positive would
not result in a broken app, but rather in unnecessary providers being injected (as a noop).

Fixes #38453

PR Close #38500
2020-08-17 12:50:16 -07:00
989e8a1f99 fix(router): ensure routerLinkActive updates when associated routerLinks change (#38349)
This commit introduces a new subscription in the `routerLinkActive` directive which triggers an update
when any of its associated routerLinks have changes. `RouterLinkActive` not only needs to know when
links are added or removed, but it also needs to know about if a link it already knows about
changes in some way.

Quick note that `from...mergeAll` is used instead of just a simple
`merge` (or `scheduled...mergeAll`) to avoid introducing new rxjs
operators in order to keep bundle size down.

Fixes #18469

PR Close #38349
2020-08-17 12:34:02 -07:00
84d1ba792b refactor(language-service): [Ivy] remove temporary compiler (#38310)
Now that Ivy compiler has a proper `TemplateTypeChecker` interface
(see https://github.com/angular/angular/pull/38105) we no longer need to
keep the temporary compiler implementation.

The temporary compiler was created to enable testing infrastructure to
be developed for the Ivy language service.

This commit removes the whole `ivy/compiler` directory and moves two
functions `createTypeCheckingProgramStrategy` and
`getOrCreateTypeCheckScriptInfo` to the `LanguageService` class.

Also re-enable the Ivy LS test since it's no longer blocking development.

PR Close #38310
2020-08-17 11:30:36 -07:00
b32126c335 fix(common): Allow scrolling when browser supports scrollTo (#38468)
This commit fixes a regression from "fix(common): ensure
scrollRestoration is writable (#30630)" that caused scrolling to not
happen at all in browsers that do not support scroll restoration. The
issue was that `supportScrollRestoration` was updated to return `false`
if a browser did not have a writable `scrollRestoration`. However, the
previous behavior was that the function would return `true` if
`window.scrollTo` was defined. Every scrolling function in the
`ViewportScroller` used `supportScrollRestoration` and, with the update
in bb88c9fa3d, no scrolling would be
performed if a browser did not have writable `scrollRestoration` but
_did_ have `window.scrollTo`.

Note, that this failure was detected in the saucelabs tests. IE does not
support scroll restoration so IE tests were failing.

PR Close #38468
2020-08-14 11:41:26 -07:00
d5e09f4d62 fix(core): fix multiple nested views removal from ViewContainerRef (#38317)
When removal of one view causes removal of another one from the same
ViewContainerRef it triggers an error with views length calculation. This commit
fixes this bug by removing a view from the list of available views before invoking
actual view removal (which might be recursive and relies on the length of the list
of available views).

Fixes #38201.

PR Close #38317
2020-08-13 13:35:56 -07:00
Ahn
c25c57c3a3 style(compiler-cli): remove unused constant (#38441)
Remove unused constant allDiagnostics

PR Close #38441
2020-08-13 13:32:44 -07:00
692e34d4a2 test(docs-infra): remove deprecated ReflectiveInjector (#38408)
This commit replaces the old and slow `ReflectiveInjector` that was
deprecated in v5 with the new `Injector`. Note: This change was only
done in the spec files inside the `aio` folder.

While changing this, it was not possible to directly use `Injector.get`
to get the correct typing for the mocked classes. For example:

```typescript
locationService = injector.get<TestLocationService>(LocationService);
```

Fails with:

> Argument of type 'typeof LocationService' is not assignable to parameter
of type 'Type<TestLocationService> | InjectionToken<TestLocationService> |
AbstractType<TestLocationService>'.
  Type 'typeof LocationService' is not assignable to type 'Type<TestLocationService>'.
    Property 'searchResult' is missing in type 'LocationService' but required in type
    'TestLocationService'.

Therefore, it was necessary to first convert to `unknown` and then to
`TestLocationService`.

```typescript
locationService = injector.get(LocationService) as unknown as TestLocationService;
```

PR Close #38408
2020-08-13 12:56:17 -07:00
071348eb72 build: run browsers tests on chromium locally (#38435) (#38450)
Previously we added a browser target for `firefox` into the
dev-infra package. It looks like as part of this change, we
accidentally switched the local web testing target to `firefox`.

Web tests are not commonly run locally as we use Domino and
NodeJS tests for primary development. Sometimes though we intend
to run tests in a browser. This would currently work with Firefox
but not on Windows (as Firefox is a noop there in Bazel).

This commit switches the primary browser back to `chromium`. Also
Firefox has been added as a second browser to web testing targets.

This allows us to reduce browsers in the legacy Saucelabs job. i.e.
not running Chrome and Firefox there. This should increase stability
and speed up the legacy job (+ reduced rate limit for Saucelabs).

PR Close #38435

PR Close #38450
2020-08-13 12:55:16 -07:00
8803f9f4dc ci: disable saucelabs tests on Firefox ESR while investigating failures (#37647) (#38450)
Firefox ESR tests fail running the acceptance tests on saucelabs.  These tests are being
disabled while investigating the failure as it is not entirely clear whether this is
saucelabs failure or a something like a memory pressure error in the test itself.

PR Close #37647

PR Close #38450
2020-08-13 12:55:13 -07:00
aa816d3887 ci: disable closure size tracking test (#38449)
We should define ngDevMode to false in Closure, but --define only works in the global scope.
With ngDevMode not being set to false, this size tracking test provides little value but a lot of
headache to continue updating the size.

PR Close #38449
2020-08-13 11:41:16 -07:00
a5ba40a78b refactor(router): Add annotations to correct Router documentation (#38448)
The `@HostListener` functions and lifecycle hooks aren't intended to be public API but
do need to appear in the `.d.ts` files or type checking will break. Adding the
nodoc annotation will correctly hide this function on the docs site.

Again, note that `@internal` cannot be used because the result would be
that the functions then do not appear in the `.d.ts` files. This would
break lifecycle hooks because the class would be seen as not
implementing the interface correctly. This would also break
`HostListener` because the compiled templates would attempt to call the
`onClick` functions, but those would also not appear in the `d.ts` and
would produce errors like "Property 'onClick' does not exist on type 'RouterLinkWithHref'".

PR Close #38448
2020-08-13 11:36:13 -07:00
cb83b8a887 fix(core): error if CSS custom property in host binding has number in name (#38432)
Fixes an error if a CSS custom property, used inside a host binding, has a
number in its name. The error is thrown because the styling parser only
expects characters from A to Z,dashes, underscores and a handful of other
characters.

Fixes #37292.

PR Close #38432
2020-08-13 10:35:11 -07:00
8bb726e899 build: update ng-dev config file for new commit message configuration (#38430)
Removes the commit message types from the config as they are now staticly
defined in the dev-infra code.

PR Close #38430
2020-08-13 09:11:25 -07:00
88662a540d feat(dev-infra): migrate to unified commit message types in commit message linting (#38430)
Previously commit message types were provided as part of the ng-dev config in the repository
using the ng-dev toolset.  This change removes this configuration expectation and instead
predefines the valid types for commit messages.

Additionally, with this new unified set of types requirements around providing a scope have
been put in place.  Scopes are either required, optional or forbidden for a given commit
type.

PR Close #38430
2020-08-13 09:11:23 -07:00
9b32a5917c feat(dev-infra): update to latest benchpress version (#38440)
We recently updated the benchpress package to have a more loose
Angular core peer dependency, and less other unused dependencies.

We should make sure to use that in the dev-infra package so that
peer dependencies can be satisified in consumer projects, and so
that less unused dependencies are brought into projects.

PR Close #38440
2020-08-13 09:09:34 -07:00
ffd1691ba9 feat(dev-infra): save invalid commit message attempts to be restored on next commit attempt (#38304)
When a commit message fails validation, rather than throwing out the commit message entirely
the commit message is saved into a draft file and restored on the next commit attempt.

PR Close #38304
2020-08-13 08:45:28 -07:00
afd4417a7b refactor(dev-infra): extract the commit message parsing function into its own file (#38429)
Extracts the commit message parsing function into its own file.

PR Close #38429
2020-08-12 16:10:08 -07:00
2f53bbba20 docs: remove unused Input decorator (#38306)
In the part "5. Add In-app Navigation" of the tutorial it was already removed
PR Close #38306
2020-08-12 11:26:11 -07:00
a4f99f4de9 refactor(dev-infra): use promptConfirm util in ng-dev's formatter (#38419)
Use the promptConfirm util instead of manually creating a confirm prompt with
inquirer.

PR Close #38419
2020-08-12 11:25:12 -07:00
0711128d28 docs: update web-worker CLI commands to bash style (#38421)
With this change we update the CLI generate commands to be in bash style.

PR Close #38421
2020-08-12 11:24:36 -07:00
25f79ba73e release: cut the v10.0.9 release 2020-08-12 09:35:37 -07:00
2590a9b535 docs: delete one superfluous sentence (#38339)
PR Close #38339
2020-08-12 08:23:19 -07:00
f68a1d3708 build: run formatting automatically on pre-commit hook (#38402)
Runs the `ng-dev format changed` command whenever the `git commit` command is
run.  As all changes which are checked by CI will require this check passing, this
change can prevent needless roundtrips to correct lint/formatting errors. This
automatic formatting can be bypassed with the `--no-verify` flag on the `git commit`
command.

PR Close #38402
2020-08-11 16:32:55 -07:00
89f7f63e18 feat(dev-infra): Add support for formatting all staged files (#38402)
Adds an ng-dev formatter option to format all of the staged files. This will can
be used to format only the staged files during the pre-commit hook.

PR Close #38402
2020-08-11 16:32:55 -07:00
ca2b4bcd4b fix(compiler-cli): avoid creating value expressions for symbols from type-only imports (#38415)
In TypeScript 3.8 support was added for type-only imports, which only brings in
the symbol as a type, not their value. The Angular compiler did not yet take
the type-only keyword into account when representing symbols in type positions
as value expressions. The class metadata that the compiler emits would include
the value expression for its parameter types, generating actual imports as
necessary. For type-only imports this should not be done, as it introduces an
actual import of the module that was originally just a type-only import.

This commit lets the compiler deal with type-only imports specially, preventing
a value expression from being created.

Backports #37912 to patch

PR Close #38415
2020-08-11 12:31:58 -07:00
f6cfc9294b ci: update payload size limits for Closure tests (#38411)
Currently the Closure-related tests are not tree-shaking the dev-mode-only content, thus payload
size checks are failing even if dev-mode-only content is added.
The 2e9fdbde9e commit
added some logic to JIT compiler, which is likely triggered the payload size increase. This commit
updates the payload size limits for Closure-related test to get master and patch branches back to
the "green" state.

PR Close #38411
2020-08-11 10:59:40 -07:00
5b87c67aed fix(compiler-cli): infer quote expressions as any type in type checker (#37917)
"Quote expressions" are expressions that start with an identifier followed by a
comma, allowing arbitrary syntax to follow. These kinds of expressions would
throw a an error in the template type checker, which would make them hard to
track down. As quote expressions are not generally used at all, the error would
typically occur for URLs that would inadvertently occur in a binding:

```html
<a [href]="https://example.com"></a>
```

This commit lets such bindings be inferred as the `any` type.

Fixes #36568
Resolves FW-2051

PR Close #37917
2020-08-11 09:54:54 -07:00
f5b9d87913 fix(compiler): evaluate safe navigation expressions in correct binding order (#37911)
When using the safe navigation operator in a binding expression, a temporary
variable may be used for storing the result of a side-effectful call.
For example, the following template uses a pipe and a safe property access:

```html
<app-person-view [enabled]="enabled" [firstName]="(person$ | async)?.name"></app-person-view>
```

The result of the pipe evaluation is stored in a temporary to be able to check
whether it is present. The temporary variable needs to be declared in a separate
statement and this would also cause the full expression itself to be pulled out
into a separate statement. This would compile into the following
pseudo-code instructions:

```js
var temp = null;
var firstName = (temp = pipe('async', ctx.person$)) == null ? null : temp.name;
property('enabled', ctx.enabled)('firstName', firstName);
```

Notice that the pipe evaluation happens before evaluating the `enabled` binding,
such that the runtime's internal binding index would correspond with `enabled`,
not `firstName`. This introduces a problem when the pipe uses `WrappedValue` to
force a change to be detected, as the runtime would then mark the binding slot
corresponding with `enabled` as dirty, instead of `firstName`. This results
in the `enabled` binding to be updated, triggering setters and affecting how
`OnChanges` is called.

In the pseudo-code above, the intermediate `firstName` variable is not strictly
necessary---it only improved readability a bit---and emitting it inline with
the binding itself avoids the out-of-order execution of the pipe:

```js
var temp = null;
property('enabled', ctx.enabled)
  ('firstName', (temp = pipe('async', ctx.person$)) == null ? null : temp.name);
```

This commit introduces a new `BindingForm` that results in the above code to be
generated and adds compiler and acceptance tests to verify the proper behavior.

Fixes #37194

PR Close #37911
2020-08-11 09:51:11 -07:00
3acebdcf5d fix(core): prevent NgModule scope being overwritten in JIT compiler (#37795)
In JIT compiled apps, component definitions are compiled upon first
access. For a component class `A` that extends component class `B`, the
`B` component is also compiled when the `InheritDefinitionFeature` runs
during the compilation of `A` before it has finalized. A problem arises
when the compilation of `B` would flush the NgModule scoping queue,
where the NgModule declaring `A` is still pending. The scope information
would be applied to the definition of `A`, but its compilation is still
in progress so requesting the component definition would compile `A`
again from scratch. This "inner compilation" is correctly assigned the
NgModule scope, but once the "outer compilation" of `A` finishes it
would overwrite the inner compilation's definition, losing the NgModule
scope information.

In summary, flushing the NgModule scope queue could trigger a reentrant
compilation, where JIT compilation is non-reentrant. To avoid the
reentrant compilation, a compilation depth counter is introduced to
avoid flushing the NgModule scope during nested compilations.

Fixes #37105

PR Close #37795
2020-08-11 09:50:28 -07:00
02aca135bd fix(dev-infra): update i18n-related file locations in PullApprove config (#38403)
The changes in https://github.com/angular/angular/pull/38368 split `render3/i18n.ts` files into
smaller scripts, but the PullApprove config was not updated to reflect that. This commit updates
the PullApprove config to reflect the recent changes in i18n-related files.

PR Close #38403
2020-08-10 17:29:52 -07:00
32109dc414 fix(core): queries not matching string injection tokens (#38321)
Queries weren't matching directives that provide themselves via string
injection tokens, because the assumption was that any string passed to
a query decorator refers to a template reference.

These changes make it so we match both template references and
providers while giving precedence to the template references.

Fixes #38313.
Fixes #38315.

PR Close #38321
2020-08-10 15:27:25 -07:00
c9acb7b7e2 fix(compiler-cli): preserve quotes in class member names (#38387)
When we were outputting class members for `setClassMetadata` calls,
we were using the string representation of the member name. This can
lead to us generating invalid code when the name contains dashes and
is quoted (e.g. `@Output() 'has-dashes' = new EventEmitter()`), because
the quotes will be stripped for the string representation.

These changes fix the issue by using the original name AST node that was
used for the declaration and which knows whether it's supposed to be
quoted or not.

Fixes #38311.

PR Close #38387
2020-08-10 15:26:46 -07:00
545444d86f refactor(core): break i18n.ts into smaller files (#38368)
This commit contains no changes to code. It only breaks `i18n.ts` file
into `i18n.ts` + `i18n_apply.ts` + `i18n_parse.ts` +
`i18n_postprocess.ts` for easier maintenance.

PR Close #38368
2020-08-10 15:07:44 -07:00
7f111491a8 fix(platform-server): remove styles added by ServerStylesHost on destruction (#38367)
When a ServerStylesHost instance is destroyed, all of the shared styles added to the DOM
head element by that instance should be removed.  Without this removal, over time a large
number of style rules will build up and cause extra memory pressure.  This brings the
ServerStylesHost in line with the DomStylesHost used by the platform browser, which
performs this same cleanup.

PR Close #38367
2020-08-10 13:12:24 -07:00
ee5123f5dc fix(core): Store the currently selected ICU in LView (#38345)
The currently selected ICU was incorrectly being stored it `TNode`
rather than in `LView`.

Remove: `TIcuContainerNode.activeCaseIndex`
Add: `LView[TIcu.currentCaseIndex]`

PR Close #38345
2020-08-10 12:41:18 -07:00
3dfaf56fdd docs: Remove redundant sentence from Router (#38398)
PR Close #38398
2020-08-10 09:52:31 -07:00
432a688edf docs: update team contributors page (#38384)
Removing Kara, Denny, Judy, Tony, Matias as they are no longer actively working on the project
PR Close #38384
2020-08-10 09:51:51 -07:00
42a649d80f docs: fix purpose description of "builders.json" (#36830)
PR Close #36830
2020-08-07 15:04:57 -07:00
47fbfb37bf refactor(forms): get rid of duplicate functions (#38371) (#38380)
This commit performs minor refactoring in Forms package to get rid of duplicate functions.
It looks like the functions were duplicated due to a slightly different type signatures, but
their logic is completely identical. The logic in retained functions remains the same and now
these function also accept a generic type to achieve the same level of type safety.

PR Close #38380
2020-08-07 12:11:37 -07:00
4107abba2d refactor(common): use getElementById in ViewportScroller.scrollToAnchor (#38372)
This commit uses getElementById and getElementsByName when an anchor scroll happens,
to avoid escaping the anchor and wrapping the code in a try/catch block.

Related to #28960

PR Close #38372
2020-08-07 11:17:53 -07:00
1d26bc544e test: update components repo to test against recent revision (#38273) (#38378)
The changes in angular/components#20136 are required to allow the
framework tests to succeed.

PR Close #38273

PR Close #38378
2020-08-07 11:12:49 -07:00
ef7b70a375 refactor(core): add debug ranges to LViewDebug with matchers (#38359)
This change provides better typing for the `LView.debug` property which
is intended to be used by humans while debugging the application with
`ngDevMode` turned on.

In addition this chang also adds jasmine matchers for better asserting
that `LView` is in the correct state.

PR Close #38359
2020-08-06 16:58:12 -07:00
deb290bc2c refactor(core): extract icuSwitchCase, icuUpdateCase, removeNestedIcu (#38154) (#38370)
Extract `icuSwitchCase`, `icuUpdateCase`, `removeNestedIcu` into
separate functions to align them with the `.debug` property text.

PR Close #38154

PR Close #38370
2020-08-06 16:27:28 -07:00
5c8b7d2c64 refactor(core): add human readable debug for i18n (#38154) (#38370)
I18n code breaks up internationalization into opCodes which are then stored
in arrays. To make it easier to debug the codebase this PR adds `debug`
property to the arrays which presents the data in human readable format.

PR Close #38154

PR Close #38370
2020-08-06 16:27:27 -07:00
f5d5bac076 fix(service-worker): fix the chrome debugger syntax highlighter (#38332)
The Chrome debugger is not able to render the syntax properly when the
code contains backticks. This is a known issue in Chrome and they have an
open [issue](https://bugs.chromium.org/p/chromium/issues/detail?id=659515) for that.
This commit adds the work-around to use double backslash with one
backtick ``\\` `` at the end of the line.

This can be reproduced by running the following command:

`yarn bazel test //packages/forms/test --config=debug`

When opening the chrome debugger tools, you should see the correct
code highlighting syntax.

PR Close #38332
2020-08-06 15:22:57 -07:00
ad16e2f97a docs(service-worker): describe how asset-/data-group order affects request handling (#38364)
The order of asset- and data-groups in `ngsw-config.json` affects how a
request is handled by the ServiceWorker. Previously, this was not
clearly documented.

This commit describes how the order of asset-/data-groups affects
request handling.

Closes #21189

PR Close #38364
2020-08-06 11:41:59 -07:00
d0191a7397 fix(docs-infra): correctly generate CLI commands docs when the overview page moves (#38365)
Previously, the [processCliCommands][1] dgeni processor, which is used
to generate the docs pages for the CLI commands, expected the CLI
commands overview page (with a URL of `cli`) to exist as a child of a
top-level navigation section (`CLI Commands`). If one tried to move the
`CLI Commands` section inside another section, `processCliCommnads`
would fail to find it and thus fail to generate the CLI commands docs.
This problem came up in #38353.

This commit updates the `processCliCommands` processor to be able to
find it regardless of the position of the `CLI Commands` section inside
the navigation doc.

[1]:
dca4443a8e/aio/tools/transforms/cli-docs-package/processors/processCliCommands.js (L7-L9)

PR Close #38365
2020-08-06 11:41:07 -07:00
016a41b14d fix(compiler-cli): mark eager NgModuleFactory construction as not side effectful (#38320)
Roll forward of #38147.

This allows Closure compiler to tree shake unused constructor calls to `NgModuleFactory`, which is otherwise considered
side-effectful. The Angular compiler generates factory objects which are exported but typically not used, as they are
only needed for compatibility with View Engine. This results in top-level constructor calls, such as:

```typescript
export const FooNgFactory = new NgModuleFactory(Foo);
```

`NgModuleFactory` has a side-effecting constructor, so this statement cannot be tree shaken, even if `FooNgFactory` is
never imported. The `NgModuleFactory` continues to reference its associated `NgModule` and prevents the module and all
its unused dependencies from being tree shaken, making Closure builds significantly larger than necessary.

The fix here is to wrap `NgModuleFactory` constructor with `noSideEffects(() => /* ... */)`, which tricks the Closure
compiler into assuming that the invoked function has no side effects. This allows it to tree-shake unused
`NgModuleFactory()` constructors when they aren't imported. Since the factory can be removed, the module can also be
removed (if nothing else references it), thus tree shaking unused dependencies as expected.

The one notable edge case is for lazy loaded modules. Internally, lazy loading is done as a side effect when the lazy
script is evaluated. For Angular, this side effect is registering the `NgModule`. In Ivy this is done by the
`NgModuleFactory` constructor, so lazy loaded modules **cannot** have their top-level `NgModuleFactory` constructor
call tree shaken. We handle this case by looking for the `id` field on `@NgModule` annotations. All lazy loaded modules
include an `id`. When this `id` is found, the `NgModuleFactory` is generated **without** with `noSideEffects()` call,
so Closure will not tree shake it and the module will lazy-load correctly.

PR Close #38320
2020-08-06 09:02:17 -07:00
7a527b4f95 refactor(compiler): add ModuleInfo interface (#38320)
This introduces a new `ModuleInfo` interface to represent some of the statically analyzed data from an `NgModule`. This
gets passed into transforms to give them more context around a given `NgModule` in the compilation.

PR Close #38320
2020-08-06 09:02:17 -07:00
fd28f0c219 refactor(core): add noSideEffects() as private export (#38320)
This is to enable the compiler to generate `noSideEffects()` calls. This is a private export, gated by `ɵ`.

PR Close #38320
2020-08-06 09:02:17 -07:00
7342b1ecdf docs: remove https://angular.io from internal links (#38360)
PR #36601 introduces icons on all links if the link contains
https:// or http:// but there were some internal links left
which contained https://angular.io. Removed https://angular.io
from all these links.

PR Close #38360
2020-08-06 09:01:35 -07:00
58f4b3ad80 fix(common): ensure scrollRestoration is writable (#30630) (#38357)
Some specialised browsers that do not support scroll restoration
(e.g. some web crawlers) do not allow `scrollRestoration` to be
writable.

We already sniff the browser to see if it has the `window.scrollTo`
method, so now we also check whether `window.history.scrollRestoration`
is writable too.

Fixes #30629

PR Close #30630

PR Close #38357
2020-08-05 17:49:56 -07:00
3974312c3a style(docs-infra): reformat ScrollService file (#30630) (#38357)
Pre-empting code formatting changes when the
code is updated in a subsequent commit.

PR Close #30630

PR Close #38357
2020-08-05 17:49:55 -07:00
db897f4f7a docs: add a page with the Angular roadmap (#38356)
PR Close #38356
2020-08-05 17:16:38 -07:00
77093c21b7 refactor(platform-browser): specify return type of parseEventName (#38089)
This commit refactors the argument of the `parseEventName` function
to use an object with named properties instead of using an object indexer.

PR Close #38089
2020-08-05 17:06:29 -07:00
415131413d fix(router): prevent calling unsubscribe on undefined subscription in RouterPreloader (#38344)
Previously, the `ngOnDestroy` method called `unsubscribe` regardless of if `subscription` had
been initialized.  This can lead to an error attempting to call `unsubscribe` of undefined.
This change prevents this error, and instead only attempts `unsubscribe` when the subscription
has been defined.

PR Close #38344
2020-08-05 10:54:42 -07:00
df01a82fa2 fix(compiler-cli): match wrapHost parameter types within plugin interface (#38004)
The `TscPlugin` interface using a type of `ts.CompilerHost&Partial<UnifiedModulesHost>` for the `host` parameter
of the `wrapHost` method. However, prior to this change, the interface implementing `NgTscPlugin` class used a
type of `ts.CompilerHost&UnifiedModulesHost` for the parameter. This change corrects the inconsistency and
allows `UnifiedModulesHost` members to be optional when using the `NgtscPlugin`.

PR Close #38004
2020-08-05 10:54:08 -07:00
1912fa34ba feat(dev-infra): provide organization-wide merge-tool label configuration (#38223)
Previously, each Angular repository had its own strategy/configuration
for merging pull requests and cherry-picking. We worked out a new
strategy for labeling/branching/versioning that should be the canonical
strategy for all actively maintained projects in the Angular organization.

This PR provides a `ng-dev` merge configuration that implements the
labeling/branching/merging as per the approved proposal.

See the following document for the proposal this commit is based on
for the merge script labeling/branching: https://docs.google.com/document/d/197kVillDwx-RZtSVOBtPb4BBIAw0E9RT3q3v6DZkykU

The merge tool label configuration can be conveniently accesed
within each `.ng-dev` configuration, and can also be extended
if there are special labels on individual projects. This is one
of the reasons why the labels are not directly built into the
merge script. The script should remain unopinionated and flexible.

The configuration is conceptually powerful enough to achieve the
procedures as outlined in the versioning/branching/labeling proposal.

PR Close #38223
2020-08-05 10:53:18 -07:00
db5e1de07a feat(dev-infra): support user-failures when computing branches for target label (#38223)
The merge tool provides a way for configurations to determine the branches
for a label lazily. This is supported because it allows labels to respect
the currently selected base branch through the Github UI. e.g. if `target: label`
is applied on a PR and the PR is based on the patch branch, then the change
could only go into the selected target branch, while if it would be based on
`master`, the change would be cherry-picked to `master` too. This allows for
convenient back-porting of changes if they did not apply cleanly to the primary
development branch (`master`).

We want to expand this function so that it is possible to report failures if an
invalid target label is appplied (e.g. `target: major` not allowed in
some situations), or if the Github base branch is not valid for the given target
label (e.g. if `target: lts` is used, but it's not based on a LTS branch).

PR Close #38223
2020-08-05 10:53:18 -07:00
84661eac64 feat(dev-infra): provide github API instance to lazy merge configuration (#38223)
The merge script currently accepts a configuration function that will
be invoked _only_ when the `ng-dev merge` command is executed. This
has been done that way because the merge tooling usually relies on
external requests to Git or NPM for constructing the branch configurations.

We do not want to perform these slow external queries on any `ng-dev` command
though, so this became a lazily invoked function.

This commit adds support for these configuration functions to run
asynchronously (by returning a Promise that will be awaited), so that
requests could also be made to the Github API. This is benefical as it
could avoid dependence on the local Git state and the HTTP requests
are more powerful/faster.

Additionally, in order to be able to perform Github API requests
with an authenticated instance, the merge tool will pass through
a `GithubClient` instance that uses the specified `--github-token`
(or from the environment). This ensures that all API requests use
the same `GithubClient` instance and can be authenticated (mitigating
potential rate limits).

PR Close #38223
2020-08-05 10:53:18 -07:00
629203f17a docs: fix typo in glossary (#38318)
Add missing comma  in structural directive section that made dash display incorrectly.

PR Close #38318
2020-08-05 10:52:28 -07:00
2ab8e88924 release: cut the v10.0.8 release 2020-08-04 15:51:57 -07:00
a91dd2e42a build: cleanup .bazelrc file to no longer set unused flags (#38124)
This option is no longer needed in Bazel and will be an error in the future

PR Close #38124
2020-08-03 12:53:11 -07:00
6eca80b4aa revert: docs(core): correct SomeService to SomeComponent (#38325)
This reverts commit b4449e35bf.

The example given from the previous change was for a component selector and not a provider selector.

This change fixes it.

Fixes #38323.

PR Close #38325
2020-08-03 12:52:20 -07:00
cea46786a2 fix(compiler): update unparsable character reference entity error messages (#38319)
Within an angular template, when a character entity is unable to be parsed, previously a generic
unexpected character error was thrown.  This does not properly express the issue that was discovered
as the issue is actually caused by the discovered character making the whole of the entity unparsable.
The compiler will now instead inform via the error message what string was attempted to be parsed
and what it was attempted to be parsed as.

Example, for this template:
```
<p>
  &#x123p
</p>
```
Before this change:
`Unexpected character "p"`

After this change:
`Unable to parse entity "&#x123p" - hexadecimal character reference entities must end with ";"`

Fixes #26067

PR Close #38319
2020-07-31 15:32:54 -07:00
9c5fc1693a refactor(docs-infra): update docs examples tslint.json to match CLI and fix failures (#38143)
This commit updates the `tslint.json` configuration file, that is used
to lint the docs examples, to match the one generated for new Angular
CLI apps. There are some minimal differences (marked with `TODO`
comments) for things, such as component selector prefix, that would
require extensive and/or difficult to validate changes in guides.

This commit also includes the final adjustments to make the docs
examples code compatible with the new tslint rules. (The bulk of the
work has been done in previous commits.)

PR Close #38143
2020-07-31 11:00:08 -07:00
42f5770b7b refactor(docs-infra): fix docs examples for Angular-specific tslint rules (#38143)
This commit updates the docs examples to be compatible with the
following Angular-specific tslint rules:
- `component-selector`
- `directive-selector`
- `no-conflicting-lifecycle`
- `no-host-metadata-property`
- `no-input-rename`
- `no-output-native`
- `no-output-rename`

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:08 -07:00
01db37435f refactor(docs-infra): fix docs examples for tslint rule prefer-const (#38143)
This commit updates the docs examples to be compatible with the
`prefer-const` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:08 -07:00
07a003352d refactor(docs-infra): fix docs examples for tslint rules related to underscores in variable names (#38143)
This commit updates the docs examples to be compatible with the
`variable-name` tslint rule without requiring the
`allow-leading-underscore` and `allow-trailing-underscore` options.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:08 -07:00
ac009d293d refactor(docs-infra): fix docs examples for tslint rules related to variable names (#38143)
This commit updates the docs examples to be compatible with the
`no-shadowed-variable` and `variable-name` tslint rules.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:08 -07:00
eb8f8c93c8 refactor(docs-infra): fix docs examples for tslint rule member-ordering (#38143)
This commit updates the docs examples to be compatible with the
`member-ordering` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:08 -07:00
18a5117d1e refactor(docs-infra): fix docs examples for tslint rule no-angle-bracket-type-assertion (#38143)
This commit updates the docs examples to be compatible with the
`no-angle-bracket-type-assertion` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:08 -07:00
ff72da60d3 refactor(docs-infra): fix docs examples for tslint rules related to object properties (#38143)
This commit updates the docs examples to be compatible with the
`no-string-literal`, `object-literal-key-quotes` and
`object-literal-shorthand` tslint rules.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:08 -07:00
d4a723a464 refactor(docs-infra): fix docs examples for tslint rule only-arrow-functions (#38143)
This commit updates the docs examples to be compatible with the
`only-arrow-functions` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:08 -07:00
9c2f0b8ac4 style(docs-infra): fix docs examples for tslint rule jsdoc-format (#38143)
This commit updates the docs examples to be compatible with the
`jsdoc-format` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:07 -07:00
dc081fb0bf style(docs-infra): fix docs examples for tslint rule semicolon (#38143)
This commit updates the docs examples to be compatible with the
`semicolon` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:07 -07:00
f882099f9d style(docs-infra): fix docs examples for tslint rules related to whitespace (#38143)
This commit updates the docs examples to be compatible with the `align`,
`space-before-function-paren` and `typedef-whitespace` tslint rules.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:07 -07:00
24498eb416 style(docs-infra): fix docs examples for tslint rule import-spacing (#38143)
This commit updates the docs examples to be compatible with the
`import-spacing` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:07 -07:00
4c2cdc682b refactor(docs-infra): remove unnecessary use strict from docs examples TS files (#38143)
By default, TypeScript will emit `"use strict"` directives, so it is not
necessary to include `'use strict'` in `.ts` files:
https://www.typescriptlang.org/docs/handbook/compiler-options.html#:~:text=--noImplicitUseStrict

PR Close #38143
2020-07-31 11:00:07 -07:00
1cb66bb39f refactor(docs-infra): remove unused styleguide examples (#38143)
The `03-*` code style rule have been removed from the style guide in
be0bc799f3.

This commit removes the corresponding files and related unused code from
the`styleguide` example project.

PR Close #38143
2020-07-31 11:00:07 -07:00
7ff5ef27c7 fix(language-service): [ivy] do not retrieve ts.Program at startup (#38120)
This commit removes compiler instantiation at startup.
This is because the constructor is invoked during the plugin loading phase,
in which the project has not been completely loaded.

Retrieving `ts.Program` at startup will trigger an `updateGraph` operation,
which could only be called after the Project has loaded completely.
Without this change, the Ivy LS cannot be loaded as a tsserver plugin.

Note that the whole `Compiler` class is temporary, so changes made there are
only for development. Once we have proper integration with ngtsc the
`Compiler` class would be removed.

PR Close #38120
2020-07-30 16:54:20 -07:00
03d8e317c4 fix(compiler): add PURE annotation to getInheritedFactory calls (#38291)
Currently the `getInheritedFactory` function is implemented to allow
closure to remove the call if the base factory is unused.  However, this
method does not work with terser.  By adding the PURE annotation,
terser will also be able to remove the call when unused.

PR Close #38291
2020-07-30 16:53:52 -07:00
1de4fe5dbf release: cut the v10.0.7 release 2020-07-30 16:37:25 -07:00
879ff08f0e fix(compiler): Metadata should not include methods on Object.prototype (#38292)
This commit fixes a bug in View Engine whereby the compiler errorneously
thinks that a method of a component has decorator metadata when that
method is one of those in `Object.prototype`, for example `toString`.

This bug is discovered in v10.0.4 of `@angular/language-service` after
the default bundle format was switched from ES5 to ES2015.

ES5 output:
```js
if (propMetadata[propName]) {
    decorators.push.apply(decorators, __spread(propMetadata[propName]));
}
```

ES2015 output:
```js
if (propMetadata[propName]) {
    decorators.push(...propMetadata[propName]);
}
```

The bug was not discovered in ES5 because the polyfill for the spread
operator happily accepts parameters that do not have the `iterable`
symbol:

```js
function __spread() {
    for (var ar = [], i = 0; i < arguments.length; i++)
        ar = ar.concat(__read(arguments[i]));
    return ar;
}
```

whereas in es2015 it’ll fail since the iterable symbol is not present in
`propMetadata['toString']` which evaluates to a function.

Fixes https://github.com/angular/vscode-ng-language-service/issues/859

PR Close #38292
2020-07-30 15:18:28 -07:00
a15d7ac1da Revert "fix(compiler): mark NgModuleFactory construction as not side effectful (#38147)" (#38303)
This reverts commit 7f8c2225f2.

This commit caused test failures internally, which were traced back to the
optimizer removing NgModuleFactory constructor calls when those calls caused
side-effectful registration of NgModules by their ids.

PR Close #38303
2020-07-30 12:19:36 -07:00
4a6abbdfc6 fix(compiler-cli): correct type of makeDiagnostic()
This commit corrects the type of makeDiagnostic()'s messageText parameter,
which was not compatible with some compiler refactorings merged to 10.0.x
due to unforeseen dependencies on prior refactorings.
2020-07-29 18:00:40 -07:00
78eb5f6777 refactor(compiler-cli): create diagnostics using ts.DiagnosticRelatedInformation (#37587)
Previously, an anonymous type was used for creating a diagnostic with related
information. The anonymous type would then be translated into the necessary
`ts.DiagnosticRelatedInformation` shape within `makeDiagnostic`. This commit
switches the `makeDiagnostic` signature over to taking `ts.DiagnosticRelatedInformation`
directly and introduces `makeRelatedInformation` to easily create such objects.
This is done to aid in making upcoming work more readable.

PR Close #37587
2020-07-29 17:50:08 -07:00
0cdb5231c2 test(compiler-cli): disable one TypeChecker test on Windows due to path sensitivity issue (#38294)
This commit disables one TypeChecker test (added as a part of
https://github.com/angular/angular/pull/38105) which make assertions about the filename while
running on Windows.

Such assertions are currently suffering from a case sensitivity issue.

PR Close #38294
2020-07-29 17:49:45 -07:00
5af845d049 docs(router): clarify how base href is used to construct targets (#38123)
The documentation is not clear on how the base href and APP_BASE_HREF are used. This commit
should help clarify more complicated use-cases beyond the most common one of just a '/'

PR Close #38123
2020-07-29 13:34:02 -07:00
a5c28497b5 fix(compiler): mark NgModuleFactory construction as not side effectful (#38147)
This allows Closure compiler to tree shake unused constructor calls to `NgModuleFactory`, which is otherwise considered
side-effectful. The Angular compiler generates factory objects which are exported but typically not used, as they are
only needed for compatibility with View Engine. This results in top-level constructor calls, such as:

```typescript
export const FooNgFactory = new NgModuleFactory(Foo);
```

`NgModuleFactory` has a side-effecting constructor, so this statement cannot be tree shaken, even if `FooNgFactory` is
never imported. The `NgModuleFactory` continues to reference its associated `NgModule` and prevents the module and all
its unused dependencies from being tree shaken. This effectively prevents all components from being tree shaken, making
Closure builds significantly larger than they should be.

The fix here is to wrap `NgModuleFactory` constructor with `noSideEffects(() => /* ... */)`, which tricks the Closure
compiler into assuming that the invoked function has no side effects. This allows it to tree-shake unused
`NgModuleFactory()` constructors when they aren't imported. Since the factory can be removed, the module can also be
removed (if nothing else references it), thus tree shaking unused components as expected.

PR Close #38147
2020-07-29 13:32:08 -07:00
801ad62ae3 refactor(compiler): wrap large strings in function (#38253)
Large strings constants are now wrapped in a function which is called whenever used. This works around a unique
limitation of Closure, where it will **always** inline string literals at **every** usage, regardless of how large the
string literal is or how many times it is used.The workaround is to use a function rather than a string literal.
Closure has differently inlining semantics for functions, where it will check the length of the function and the number
of times it is used before choosing to inline it. By using a function, `ngtsc` makes Closure more conservative about
inlining large strings, and avoids blowing up the bundle size.This optimization is only used if the constant is a large
string. A wrapping function is not included for other use cases, since it would just increase the bundle size and add
unnecessary runtime performance overhead.

PR Close #38253
2020-07-29 13:31:04 -07:00
7d4d2e29b0 docs: update bio picture (#38272)
Updates my profile picture which was quite old.

PR Close #38272
2020-07-29 10:33:37 -07:00
c33f719ddc refactor(docs-infra): Lazy-loads SVG icons (#38268)
Prior to this commit, SVG icons were all loaded in the constructor
of the `CustomIconRegistry`. This commit avoids that, and loads SVG
icons on demand.

PR Close #38268
2020-07-29 10:32:55 -07:00
69fc6b4f75 refactor(docs-infra): simplify/improve CopierService hidden textarea creation (#38244)
This commit simplifies the creation of the temporary, hidden
`<textarea>` element used by `CopierService` by switching from absolute
to fixed positioning and not requiring page's scroll offset.

It also makes the following minor improvements:
- Make the element invisible (via `opacity: 0`).
- Instruct screen-readers to ignore the element (via
  `aria-hidden: true`).

NOTE: These improvements are based on Angular CDK's [PendingCopy][1]
      class and the changes proposed in PR angular/components#20073.

[1]: https://github.com/angular/components/blob/89b5fa89d1437c3054c5/src/cdk/clipboard/pending-copy.ts

PR Close #38244
2020-07-29 10:32:07 -07:00
5ec4c02a43 fix(docs-infra): preserve focus on copy (and prevent scrolling to bottom on IE11) (#38244)
The `CopierService` is used for copying text to the user's clipboard. It
is, for example, used in `CodeComponent` to copy example code snippets.
This is implemented by creating a temporary, hidden `<textarea>`
elements, setting its value to the text that needs to be copied,
executing the `copy` command and finally removing the element from the
DOM.

Previously, as a result of `CopierService`'s implementation, the focused
element would lose focus, while the temporary `<textarea>` element would
implicitly gain focus when selecting its contents. This had an even
worse side-effect on IE11, which seems to scroll to the bottom of the
containing element (here `<body>`) when the focused element is removed.

This commit fixes these issues by keeping track of the previously
focused element and restoring its focus after the copy operation.

NOTE: This fix is inspired by Angular CDK's [PendingCopy][1] class.

[1]: https://github.com/angular/components/blob/89b5fa89d1437c3054c5/src/cdk/clipboard/pending-copy.ts

Fixes #37796

PR Close #38244
2020-07-29 10:32:07 -07:00
f0489ee72a refactor(docs-infra): improve code readability of CopierService (#38244)
This commit improves the code readability of the `CopierService` by:
- Adding/Improving JSDoc comments for methods.
- Avoiding unnecessary instance-wide properties.
- Fixing indentation to be consistent (at two spaces).
- Clearly separating the logic for creating and populating a
  `<textarea>` from the logic for selecting and copying its contents.

PR Close #38244
2020-07-29 10:32:06 -07:00
d0f625305b refactor(compiler-cli): support type-checking a single component (#38105)
This commit adds a method `getDiagnosticsForComponent` to the
`TemplateTypeChecker`, which does the minimum amount of work to retrieve
diagnostics for a single component.

With the normal `ReusedProgramStrategy` this offers virtually no improvement
over the standard `getDiagnosticsForFile` operation, but if the
`TypeCheckingProgramStrategy` supports separate shims for each component,
this operation can yield a faster turnaround for components that are
declared in files with many other components.

PR Close #38105
2020-07-29 10:31:22 -07:00
c15a58fa2b refactor(compiler-cli): add TemplateId to template diagnostics (#38105)
Previously, a stable template id was implemented for each component in a
file. This commit adds this id to each `TemplateDiagnostic` generated from
the template type-checker, so it can potentially be used for filtration.

PR Close #38105
2020-07-29 10:31:22 -07:00
3d67d1970b refactor(compiler-cli): allow overriding templates in the type checker (#38105)
This commit adds an `overrideComponentTemplate` operation to the template
type-checker. This operation changes the template used during template
type-checking operations.

Overriding a template causes any previous work for it to be discarded, and
the template type-checking engine will regenerate the TCB for that template
on the next request.

This operation can be used by a consumer such as the language service to
get rapid feedback or diagnostics as the user is editing a template file,
without the need for a full incremental build iteration.

Closes #38058

PR Close #38105
2020-07-29 10:31:22 -07:00
ce08a3c8c7 refactor(compiler-cli): efficient single-file type checking diagnostics (#38105)
Previously, the `TemplateTypeChecker` abstraction allowed fetching
diagnostics for a single file, but under the hood would generate type
checking code for the entire program to satisfy the request.

With this commit, an `OptimizeFor` hint is passed to `getDiagnosticsForFile`
which indicates whether the user intends to request diagnostics for the
whole program or is truly interested in just the single file. If the latter,
the `TemplateTypeChecker` can perform only the work needed to produce
diagnostics for just that file, thus returning answers more efficiently.

PR Close #38105
2020-07-29 10:31:22 -07:00
bc29712271 refactor(compiler-cli): allow program strategies to opt out of inlining (#38105)
The template type-checking engine relies on the abstraction interface
`TypeCheckingProgramStrategy` to create updated `ts.Program`s for
template type-checking. The basic API is that the type-checking engine
requests changes to certain files in the program, and the strategy provides
an updated `ts.Program`.

Typically, such changes are made to 'ngtypecheck' shim files, but certain
conditions can cause template type-checking to require "inline" operations,
which change user .ts files instead. The strategy used by 'ngc' (the
`ReusedProgramStrategy`) supports these kinds of updates, but other clients
such as the language service might not always support modifying user files.

To accommodate this, the `TypeCheckingProgramStrategy` interface was
modified to include a `supportsInlineOperations` flag. If an implementation
specifies `false` for inline support, the template type-checking system will
return diagnostics on components which would otherwise require inline
operations.

Closes #38059

PR Close #38105
2020-07-29 10:31:22 -07:00
cc48b5c066 refactor(compiler-cli): introduce the TemplateTypeChecker abstraction (#38105)
This commit significantly refactors the 'typecheck' package to introduce a
new abstraction, the `TemplateTypeChecker`. To achieve this:

* a 'typecheck:api' package is introduced, containing common interfaces that
  consumers of the template type-checking infrastructure can depend on
  without incurring a dependency on the template type-checking machinery as
  a whole.
* interfaces for `TemplateTypeChecker` and `TypeCheckContext` are introduced
  which contain the abstract operations supported by the implementation
  classes `TemplateTypeCheckerImpl` and `TypeCheckContextImpl` respectively.
* the `TemplateTypeChecker` interface supports diagnostics on a whole
  program basis to start with, but the implementation is purposefully
  designed to support incremental diagnostics at a per-file or per-component
  level.
* `TemplateTypeChecker` supports direct access to the type check block of a
  component.
* the testing utility is refactored to be a lot more useful, and new tests
  are added for the new abstraction.

PR Close #38105
2020-07-29 10:31:22 -07:00
deba0e21f1 refactor(compiler-cli): make file/shim split 1:n instead of 1:1 (#38105)
Previously in the template type-checking engine, it was assumed that every
input file would have an associated type-checking shim. The type check block
code for all components in the input file would be generated into this shim.

This is fine for whole-program type checking operations, but to support the
language service's requirements for low latency, it would be ideal to be
able to check a single component in isolation, especially if the component
is declared along with many others in a single file.

This commit removes the assumption that the file/shim mapping is 1:1, and
introduces the concept of component-to-shim mapping. Any
`TypeCheckingProgramStrategy` must provide such a mapping.

To achieve this:

 * type checking record information is now split into file-level data as
   well as per-shim data.
 * components are now assigned a stable `TemplateId` which is unique to the
   file in which they're declared.

PR Close #38105
2020-07-29 10:31:21 -07:00
0469d9240a Revert "refactor(platform-browser): specify return type of parseEventName (#38089)"
This reverts commit c3ddc3d6b1.
2020-07-29 09:30:39 -07:00
cdda60a430 release: cut the v10.0.6 release 2020-07-28 14:38:28 -07:00
7570356bfa build: fix broken build (#38274)
```
export const __core_private_testing_placeholder__ = '';
```
This API should be removed. But doing so seems to break `google3` and
so it requires a bit of investigation. A work around is to mark it as
`@codeGenApi` for now and investigate later.

PR Close #38274
2020-07-28 12:31:00 -07:00
c4a97d822e Revert "ci: roll back phased review conditions" (#38259)
This reverts commit ca8eafc2983f983803cd03e4a08bf732672712dd.

PR Close #38259
2020-07-28 11:26:29 -07:00
fc4dfc5eb1 ci: only check active groups for the no-groups-above-this-* checks (#38259)
Since PullApprove starts all inactive groups as a pending state, to properly
assess if any groups we care about are pending we must only check the active
groups.  We additionally do this with rejected because the intention of the
reusable checks is around checking active rules only.

PR Close #38259
2020-07-28 11:26:28 -07:00
25d95dae6d docs(elements): update api doc for custom elements (#38252)
by adding cross-references to Angular Elements Overview guide.

PR Close #38252
2020-07-28 11:19:04 -07:00
1c4fcce2a1 fix(core): Attribute decorator attributeName is mandatory (#38131)
`Attribute` decorator has defined `attributeName` as optional but actually its
 mandatory and compiler throws an error if `attributeName` is undefined. Made
`attributeName` mandatory in the `Attribute` decorator to reflect this functionality

Fixes #32658

PR Close #38131
2020-07-28 11:17:25 -07:00
Ahn
6e73faaed7 docs(core): correct SomeService to SomeComponent (#38264)
PR Close #38264
2020-07-28 11:10:59 -07:00
41c9910613 docs: update api reference doc for router-link-active directive (#38247)
Edits and organizes the usage information for the directive.

PR Close #38247
2020-07-28 11:09:45 -07:00
aaddef213d ci: roll back phased review conditions (#38257)
It was determined that the list of 'pending' groups also included inactive groups.
That means that the 'no-groups-above-this-pending' would generally fail because
there's almost always some inactive group above it.

This commit removes the conditions for phased review while we
investigate if the inactive groups can be excluded.

PR Close #38257
2020-07-28 10:02:15 -07:00
02f3aee1db docs: Refactor module-types.md to make it easier to understand (#38206)
Project DOCS-736 to rewrite headings to focus on user tasks,
verify that the content is up-to-date and complete, and
add relevant links to other NgModule topics to improve readability.
Also addresses one of many issues in GitHub issue 21531.

PR Close #38206
2020-07-28 10:01:38 -07:00
c27ba96093 ci: add more owners for limited categories (#38170)
* Add alxhub, atscott, and AndrewKushnir to code owners
* Add atscott & AndrewKushnir to public-api and size-tracking

Follow-up to #37994

PR Close #38170
2020-07-28 10:01:05 -07:00
c5a474cb54 docs: Refactor ngmodule-vs-jsmodule.md to make it easier to understand (#38148)
Project DOCS-734 to rewrite headings to focus on user tasks,
verify that the content is up-to-date and complete, and
add relevant links to other NgModule topics to improve readability.
Also addresses one of many issues in GitHub issue 21531.

PR Close #38148
2020-07-28 10:00:29 -07:00
d5264f5645 fix(core): unify the signature between ngZone and noopZone (#37581)
Now we have two implementations of Zone in Angular, one is NgZone, the other is NoopZone.
They should have the same signatures, includes
1. properties
2. methods

In this PR, unify the signatures of the two implementations, and remove the unnecessary cast.

PR Close #37581
2020-07-28 09:59:49 -07:00
0cd4b87021 Revert "refactor(core): remove unused export (#38224)"
This reverts commit c6c8e15813.
2020-07-28 09:56:24 -07:00
b1e7775a8a fix(compiler-cli): Add support for string literal class members (#38226)
The current implementation of the TypeScriptReflectionHost does not account for members that
are string literals, i.e. `class A { 'string-literal-prop': string; }`

PR Close #38226
2020-07-27 15:26:27 -07:00
87f5feff11 docs: update api reference doc for router link directive (#38181)
Edits and organizes the usage information for the directive.

PR Close #38181
2020-07-27 15:25:45 -07:00
c3ddc3d6b1 refactor(platform-browser): specify return type of parseEventName (#38089)
This commit refactors the argument of the `parseEventName` function
to use an object with named properties instead of using an object indexer.

PR Close #38089
2020-07-27 15:25:00 -07:00
cec39a7d16 test: update ts-api-guardian's strip_export_pattern to exclude Ivy instructions (#38224)
Previously the instructions were included in the golden files to monitor the frequency and rate of
the instruction API changes for the purpose of understanding the stability of this API (as it was
considered for becoming a public API and deployed to npm via generated code).

This experiment has confirmed that the instruction API is not stable enough to be used as public
API. We've since also came up with an alternative plan to compile libraries with the Ivy compiler
for npm deployment and this plan does not rely on making Ivy instructions public.

For these reasons, I'm removing the instructions from the golden files as it's no longer important
to track them.

The are three instructions that are still being included: `ɵɵdefineInjectable`, `ɵɵinject`, and
`ɵɵInjectableDef`.

These instructions are already generated by the VE compiler to support tree-shakable providers, and
code depending on these instructions is already deployed to npm. For this reason we need to treat
them as public api.

This change also reduces the code review overhead, because changes to public api golden files now
require multiple approvals.

PR Close #38224
2020-07-27 15:23:28 -07:00
c6c8e15813 refactor(core): remove unused export (#38224)
This export used to be here to turn this file into an ES Module - this is no longer needed
because the file contains imports.

PR Close #38224
2020-07-27 15:10:24 -07:00
752fd14fe5 refactor: correct @publicApi and @codeGenApi markers in various files (#38224)
The markers were previously incorrectly assigned. I noticed the issues when reviewing
the golden files and this change corrects them.

PR Close #38224
2020-07-27 15:10:18 -07:00
776067cd43 fix(zone.js): zone patch rxjs should return null _unsubscribe correctly. (#37091)
Close #31684.

In some rxjs operator, such as `retryWhen`, rxjs internally will set
`Subscription._unsubscribe` method to null, and the current zone.js monkey patch
didn't handle this case correctly, even rxjs set _unsubscribe to null, zone.js
still return a function by finding the prototype chain.

This PR fix this issue and the following test will pass.

```
const errorGenerator = () => {
  return throwError(new Error('error emit'));
};

const genericRetryStrategy = (finalizer: () => void) => (attempts: Observable<any>) =>
    attempts.pipe(
      mergeMap((error, i) => {
        const retryAttempt = i + 1;
        if (retryAttempt > 3) {
          return throwError(error);
        }
        return timer(retryAttempt * 1);
      }),
      finalize(() => finalizer()));

errorGenerator()
  .pipe(
    retryWhen(genericRetryStrategy(() => {
      expect(log.length).toBe(3);
      done();
    })),
    catchError(error => of(error)))
  .subscribe()
```

PR Close #37091
2020-07-27 12:11:27 -07:00
e87a46be21 docs: add template ref var to glossary (#36743)
There is not an entry in the glossary for template
reference variable. To clarify for site visitors,
we are adding one here.

PR Close #36743
2020-07-27 12:01:47 -07:00
89a7ff3ada docs: fix breaking URL for RxJS marble testing (#38209)
When checking this URL for the `RxJS marble testing` Ive found it pointing to `Page not found`

PR Close #38209
2020-07-27 11:12:08 -07:00
3d6e50dc02 docs: clarify the description of pipes (#37950)
This commit clarifies some of the language regarding pipes in the pipes guide.
This commit also specifies the term transforming rather than formatting.

PR Close #37950
2020-07-27 10:23:21 -07:00
264950bbf2 fix(compiler): share identical stylesheets between components in the same file (#38213)
Prior to this commit, duplicated styles defined in multiple components in the same file were not
shared between components, thus causing extra payload size. This commit updates compiler logic to
use `ConstantPool` for the styles (while generating the `styles` array on component def), which
enables styles sharing when needed (when duplicates styles are present).

Resolves #38204.

PR Close #38213
2020-07-27 10:11:56 -07:00
84c5be0b5b refactor(compiler): allow strings with certain length to be included into ConstantPool (#38213)
Prior to this commit, the `ConstantPool` ignored all primitive values. It turned out that it's
beneficial to include strings above certain length to the pool as well. This commit updates the
`ConstantPool` logic to allow such strings to be shared across multiple instances if needed.
For instance, this is helpful for component styles that might be reused across multiple components
in the same file.

PR Close #38213
2020-07-27 10:09:48 -07:00
eda8f2f8b9 refactor(compiler): separate compilation and transform phases (#38213)
This commit splits the transformation into 2 separate steps: Ivy compilation and actual transformation
of corresponding TS nodes. This is needed to have all `o.Expression`s generated before any TS transforms
happen. This allows `ConstantPool` to properly identify expressions that can be shared across multiple
components declared in the same file.

Resolves #38203.

PR Close #38213
2020-07-27 10:09:33 -07:00
cc52945d00 docs: add ng-add save option (#38198)
PR Close #38198
2020-07-27 09:52:15 -07:00
07f184a69d refactor(router): extract Router config utils to a separate file (#38229)
This commit refactors Router package to move config utils to a separate file for better
organization and to resolve the problem with circular dependency issue.

Resolves #38212.

PR Close #38229
2020-07-27 09:49:14 -07:00
a123ef58b1 fix(dev-infra): Ensure conditions with groups do not fail verification (#37798)
There are a few changes in this PR to ensure conditions that are based
on groups (i.e. `- groups.pending.length == 0`) do not fail the verify
task:

* Remove the warning when a condition is encountered that depends on the
`groups` state. The warning will otherwise be printed once for every
file that triggers the execution of the condition (400,000+ times)
* Add an `unverifiable` flag to `GroupCondition` interface and set it to
true when an error is encountered due to attempting to get the state of
`groups` in a condition
* Ignore any unverifiable conditions when gathering unmatched
conditions. These should not be considered `unmatched` for verification
purposes.
* Print the unverifiable conditions by group in the results

Sample output:
```

┌──────────────────────────────────────────────────────────────────────────────┐
│                         PullApprove results by group                         │
└──────────────────────────────────────────────────────────────────────────────┘
Groups skipped (4 groups)
Matched conditions by Group (37 groups)
Unmatched conditions by Group (0 groups)
Unverifiable conditions by Group (3 groups)
  [public-api]
    len(groups.pending.exclude("required-minimum-review")...
    len(groups.rejected.exclude("required-minimum-review")...
  [size-tracking]
    len(groups.pending.exclude("required-minimum-review")...
    len(groups.rejected.exclude("required-minimum-review")...
  [circular-dependencies]
    len(groups.pending.exclude("required-minimum-review")...
    len(groups.rejected.exclude("required-minimum-review")...

```

PR Close #37798
2020-07-24 18:02:49 -07:00
024126dde4 feat(dev-infra): add phased review to groups requiring final sign-off after initial review (#37798)
The size-tracking, public-api, and circular-dependencies groups can get a lot of
PRs to review. In addition, the members of these groups do not always
have the necessary context to fully review the PR in question. This
change ensures that the owners in the groups where the changes are being
made have approve the changes (ie, the aren't pending or rejected)
before requesting final sign-off from these three critical groups.

PR Close #37798
2020-07-24 18:02:42 -07:00
4275c34818 refactor(dev-infra): create anchors/aliases for excluded always active groups (#37798)
global-approvers, global-docs-approvers, and required-minimum-review groups are always active. It's useful
to have aliases for getting groups that are active/pending/rejected while excluding these few.

PR Close #37798
2020-07-24 18:02:19 -07:00
c4e6f585c5 fix(zone.js): patch nodejs EventEmtter.prototype.off (#37863)
Close #35473

zone.js nodejs patch should also patch `EventEmitter.prototype.off` as `removeListener`.
So `off` can correctly remove the listeners added by `EventEmitter.prototype.addListener`

PR Close #37863
2020-07-24 15:45:01 -07:00
7467fd36b9 fix(zone.js): clearTimeout/clearInterval should call on object global (#37858)
Close #37333

`clearTimeout` is patched by `zone.js`, and it finally calls the native delegate of `clearTimeout`,
the current implemention only call `clearNative(id)`, but it should call on object `global` like
`clearNative.call(global, id)`. Otherwise in some env, it will throw error
`clearTimeout called on an object that does not implement interface Window`

PR Close #37858
2020-07-24 15:22:48 -07:00
aca01985fd docs: Fix link by removing a space (#38214)
PR Close #38214
2020-07-24 09:53:06 -07:00
eb5e14e6e0 docs(core): Fix incorrectly rendered code example in structural directives guide (#38207)
The code example was missing a close brace and also incorrectly rendered
the template div as an actual div in the page DOM.

PR Close #38207
2020-07-24 09:52:31 -07:00
b8af10902f docs: fixed that class attribute is not closed (#38219)
PR Close #38219
2020-07-24 08:15:44 -07:00
f411c9e5b9 build(docs-infra): simplify ExampleZipper by removing PackageJsonCustomizer (#38192)
Previously, `ExampleZipper` (the tool used for creating ZIP archives
from our docs examples) used the `PackageJsonCustomizer` to generate
`package.json` files for each example type. This had the following
drawbacks:
- The generated files had to be kept up-to-date with the corresponding
  boilerplate files in `aio/tools/examples/shared/boilerplate/` and
  there was no easy way to find out when the files got out-of-sync.
- The `PackageJsonCustomizer` logic was non-trivial and difficult to
  reason about.
- The same information was duplicated in the boilerplate files and the
  customizer configuration files.

This setup was useful when we used a single `package.json` file for all
docs examples. Now, however, each example type can have its own
boilerplate `package.json` file, including scripts and dependencies
relevant to the example type. Therefore, it is no longer necessary to
generate `package.json` files for ZIP archives.

This commit eliminates the drawbacks mentioned above and simplifies the
`ExampleZipper` tool by removing `PackageJsonCustomizer` and re-using
the boilerplate `package.json` files for ZIP archives.

The changes in this commit also fix some ZIP archives that were
previously broken (for example due to missing dependencies).

PR Close #38192
2020-07-23 11:08:12 -07:00
7f455e6eec fix(docs-infra): correctly display copy button in IE11 (#38186)
Fix button top portion was clipped in IE11 by setting overflow to visible

Fixes #37816

PR Close #38186
2020-07-23 11:07:29 -07:00
e36caafa52 build(docs-infra): upgrade cli command docs sources to a404d2a86 (#38183)
Updating [angular#10.0.x](https://github.com/angular/angular/tree/10.0.x) from
[cli-builds#10.0.x](https://github.com/angular/cli-builds/tree/10.0.x).

##
Relevant changes in
[commit range](14af4e07c...a404d2a86):

**Modified**
- help/update.json

PR Close #38183
2020-07-23 11:06:55 -07:00
5e89d98876 refactor(dev-infra): Add support for groups in the conditions evaluator (#38164)
Conditions can refer to the groups array that is a list of the preceding groups.
This commit adds support to the verification for those conditions.

This commit also adds some tests to the parsing and condition matching
to ensure everything works as expected.

PR Close #38164
2020-07-23 11:05:43 -07:00
200dbd4860 docs: add Kevin Kreuzer to GDE page (#37929)
This commit adds Kevin Kreuzer to the Angular GDE page along with a biography, his contributions, and a photograph.

PR Close #37929
2020-07-23 11:03:58 -07:00
c90952884a docs: update dynamic-component loading guide (#36959)
The 'entryComponents' array is no longer a special case for dynamic component loading because of the Ivy compiler.

PR Close #36959
2020-07-23 11:03:02 -07:00
7c2d8fc672 docs: remove duplicate https:// (#38199)
This doc contained a duplicate `http://` before the domain name leading to an invalid link.
This commit fixes this issue.
PR Close #38199
2020-07-23 10:54:45 -07:00
a50a688aaf docs: update api reference for router outlet directive (#38166)
Incorporate more specific information about multiple outlets and how to target them, with link to tutorial example.

PR Close #38166
2020-07-22 20:50:13 -07:00
6ec7297e43 build(docs-infra): remove boilerplate file listings in example-boilerplate.js (#38173)
To avoid unnecessary code duplication in docs examples, we have some
boilerplate files for various example types (in
`aio/tools/examples/shared/boilerplate/`). These files are copied to
each example project in `aio/content/examples/` (according to the
example's type, as specified in its `example-config.json` file).

Previously, the `example-boilerplate.js`, which is responsible for
copying the boilerplate files, had lists for files to be copied for each
project type and only copied the listed files from the boilerplate
directory to the example directory. This approach had some drawbacks:
- Files need to be updated in two separate locations: in the boilerplate
  directory that includes the files and the file list in
  `example-boilerplate.js`.
- It is easy to add a file in the boilerplate directory but forget to
  add it in `example-boilerplate.js` and not realize that it is not
  being included in the example project (including the generated
  StackBlitz project and ZIP archive).

This commit changes the approach by removing the boilerplate file
listings from `example-boilerplate.js` and copying all files from a
boilerplate directory to example directories. This addresses the above
drawbacks and simplifies the `example-boilerplate.js` script.

I have verified that the resulting code example doc regions as well as
the generated StackBlitz projects and ZIP archives are identical to the
ones generated before this commit.

PR Close #38173
2020-07-22 10:15:10 -07:00
f264cd1cb8 fix(docs-infra): include .gitignore file in CLI-based docs examples (#38173)
Previously, the `.gitignore` file that is part of the boilerplate files
for CLI-based docs examples (located in
`aio/tools/examples/shared/boilerplate/cli/`) was not added to the
example projects, because it was not included in the boilerplate file
list in `example-boilerplate.js`.

This commit fixes it by adding the `.gitignore` file to the list. This
ensures that docs examples more closely match CLI-generated projects.

PR Close #38173
2020-07-22 10:15:10 -07:00
fc17bddcde fix(docs-infra): correctly add polyfills.ts file as boilerplate for i18n docs examples (#38173)
Docs examples of type `i18n` need a slightly modified version of
`polyfills.ts` that imports `@angular/localize/init`. Previously, this
file was not included in `i18n` example projects for two reasons:

- While the file was included in the `i18n` boilerplate files (at
  `aio/tools/examples/shared/boilerplate/i18n/`), it was not included in
  the boilerplate file list in `example-boilerplate.js`.
- The file was in the wrong location: It was located at the project root
  instead of inside the `src/` directory.

This commit addresses the above issues (i.e. adds the file to the
boilerplate file list for `i18n` projects and moves the file inside the
`src/` directory).

PR Close #38173
2020-07-22 10:15:10 -07:00
0765626761 build(docs-infra): remove obsolete systemjs.config.web[.build].js files from docs examples (#38173)
There were some `systemjs.config.web[.build].js` files in the `systemjs`
boilerplate directory that are not used any more. In the past, these
files were used in the Plunker-based live examples, but we no longer use
Plunker for live examples.

This commit removes these obsolete files.

PR Close #38173
2020-07-22 10:15:10 -07:00
f146b34042 build(docs-infra): remove obsolete typings.d.ts files from angular.io and docs examples (#38173)
There were two `typings.d.ts` files with SystemJS module definitions in
`aio/src/` and `aio/tools/examples/shared/boilerplate/cli/`. These are
remnants from old CLI versions that used SystemJS and are no longer
needed. For docs examples specifically, these files were never copied
over to example projects and thus not included in StackBlitz projects
and ZIP archives.

This commit removes these obsolete files.

PR Close #38173
2020-07-22 10:15:10 -07:00
f899d6ea44 docs: fix typo in ng_control.ts (#38157)
PR Close #38157
2020-07-22 10:14:24 -07:00
c18d7a1469 docs: fix typo from singular to plural spelling (#36586)
This commit fixes the spelling of the singular form
of the word function to the plural spelling in
packages/core/src/application_init.ts

PR Close #36586
2020-07-22 10:12:45 -07:00
2c7ff82f31 release: cut the v10.0.5 release 2020-07-22 09:36:00 -07:00
3f8f3a2daa docs: fix type in lazy-load callout (#38153)
PR Close #38153
2020-07-21 14:30:48 -07:00
f5eeb1a714 docs: fix DOCUMENT import path (#38158) (#38159)
PR Close #38159
2020-07-21 11:35:42 -07:00
2af3d9c040 refactor(core): rename synthetic host property and listener instructions (#38150)
This commit updates synthetic host property and listener instruction names to better align with other instructions.
The `ɵɵupdateSyntheticHostBinding` instruction was renamed to `ɵɵsyntheticHostProperty` (to match the `ɵɵhostProperty`
instruction name) and `ɵɵcomponentHostSyntheticListener` was renamed to `ɵɵsyntheticHostListener` since this
instruction is generated for both Components and Directives (so 'component' is removed from the name).
This PR is a followup after PR #35568.

PR Close #38150
2020-07-21 09:11:49 -07:00
4664acce50 docs: add routing terms to glossary (#38053)
Update glossary to add term definitions for routing; componentless route, link parameters array, router outlet.

PR Close #38053
2020-07-20 17:09:34 -07:00
3797861dfe docs(router): fix typos (#38132)
PR Close #38132
2020-07-20 14:12:22 -07:00
d6d3984524 docs(common): fix selector field in NgIfAs example component (#35854)
PR Close #35854
2020-07-20 13:35:05 -07:00
c17f5c10cc build: update pullapprove to remove @matsko from reviewer lists (#38146)
With @matsko leaving the Angular team, we need to update the pullapprove
configuration to reflect his no longer being a reviewer for file groups
throughout the repository.

PR Close #38146
2020-07-20 13:33:59 -07:00
9cb318f5a2 docs: separate template syntax into multiple docs (#36954)
This is part of a re-factor of template syntax and
structure. The first phase breaks out template syntax
into multiple documents. The second phase will be
a rewrite of each doc.

Specifically, this PR does the following:

- Breaks sections of the current template syntax document each into their own page.
- Corrects the links to and from these new pages.
- Adds template syntax subsection to the left side NAV which contains all the new pages.
- Adds the new files to pullapprove.

PR Close #36954
2020-07-20 11:16:45 -07:00
b026dd8b52 docs: add known issue for bazel (#38074)
This commit adds a known issue for windows, when running tests using
`bazal run`, instead of using `bazel test`

PR Close #38074
2020-07-20 11:15:37 -07:00
0ebc316311 refactor(dev-infra): Update triage labels documentation (#38081)
Add new type: confusing and type: use-case labels to the triage readme as well
as clarify that freq and severity are only required for type: bug/fix

PR Close #38081
2020-07-20 11:14:48 -07:00
dc412c5f02 refactor(dev-infra): allow use-case and confusing types to be marked as 'triaged' (#38081)
Some issue reports don't really fall into any of the current buckets that count
towards triage level 2: bug/fix, feature, or refactor. Some reports are:
* working as intended but confusing - the labels might be 'type: confusing', 'comp: docs', 'comp: router'
* generally working as originally designed but a use-case could be argued for a different implementation.
 This type of report is a little hard to triage; it may be neither a bug, nor feature but more of a
 'type: use-case'. These may eventually turn into a bug/fix or feature, but can't necessarily be
 put in those buckets immediately.

PR Close #38081
2020-07-20 11:14:47 -07:00
e80278cf02 fix(compiler): properly associate source spans for implicitly closed elements (#38126)
HTML is very lenient when it comes to closing elements, so Angular's parser has
rules that specify which elements are implicitly closed when closing a tag.
The parser keeps track of the nesting of tag names using a stack and parsing
a closing tag will pop as many elements off the stack as possible, provided
that the elements can be implicitly closed.

For example, consider the following templates:

- `<div><br></div>`, the `<br>` is implicitly closed when parsing `</div>`,
  because `<br>` is a void element.
- `<div><p></div>`, the `<p>` is implicitly closed when parsing `</div>`,
  as `<p>` is allowed to be closed by the closing of its parent element.
- `<ul><li>A <li>B</ul>`, the first `<li>` is implicitly closed when parsing
  the second `<li>`, whereas the second `<li>` would be implicitly closed when
  parsing the `</ul>`.

In all the cases above the parsed structure would be correct, however the source
span of the closing `</div>` would incorrectly be assigned to the element that
is implicitly closed. The problem was that closing an element would associate
the source span with the element at the top of the stack, however this may not
be the element that is actually being closed if some elements would be
implicitly closed.

This commit fixes the issue by assigning the end source span with the element
on the stack that is actually being closed. Any implicitly closed elements that
are popped off the stack will not be assigned an end source span, as the
implicit closing implies that no ending element is present.

Note that there is a difference between self-closed elements such as `<input/>`
and implicitly closed elements such as `<input>`. The former does have an end
source span (identical to its start source span) whereas the latter does not.

Fixes #36118
Resolves FW-2004

PR Close #38126
2020-07-20 10:02:07 -07:00
307699ac89 refactor(compiler): remove unused parser methods (#38126)
These methods are no longer used so they can safely be removed.

PR Close #38126
2020-07-20 10:02:06 -07:00
4df0b7e9de build(language-service): Remove ls_rollup_bundle (#38086) (#38129)
`ls_rollup_bundle` is no longer needed since we could invoke `ng_rollup_bundle`
directly.

Background: language service runs rollup to produce a single file to reduce
startup time in the editor. However, due to the need to load dynamic versions
of typescript at runtime (think the case where users can change typescript
version in their editor), we hack the "banner" to export a CommonJS default function,
so that we could dynamically load the typescript module provided at runtime via AMD
and use it throughout the implementation.

PR Close #38086

PR Close #38129
2020-07-20 10:00:55 -07:00
371831f9cb docs(core): add note about not mutating multi provider arrays (#37645)
Adds a note to the provider docs that users shouldn't mutate an array that
is returned from a `multi` provider, because it can cause unforeseen
consequences in other parts of the app.

Closes #37481.

PR Close #37645
2020-07-20 10:00:06 -07:00
8e305e7099 docs: correct flag default values in --strict (#37982)
Docs state that `strictInjectionParameters` is true by default in `ng new`, however this is not the case in `10.0.1`. It is only set when `--strict` is provided. Clarified that the `--strict` flag is required.

`strictTemplates` does not mention anything about `--strict`, so I included a similar point that it is `true` when a new project is generated with `--strict`.

PR Close #37982
2020-07-17 16:26:50 -07:00
481df830ad build: Ignore .history for the xyz.local-history VSCode extension (#38121)
Ignore .history for the xyz.local-history VSCode extension

PR Close #38121
2020-07-17 13:33:40 -07:00
14b4718cc2 fix(core): Allow modification of lifecycle hooks any time before bootstrap (#38119)
Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`.
The result is that it is not possible to do any sort of meta-programing
such as mixins or adding lifecycle hooks using custom decorators since
any such code executes after `ɵɵdefineComponent` has extracted the
lifecycle hooks from the prototype. Additionally the behavior is
inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle
hooks is possible because the whole `ɵɵdefineComponent` is placed in
getter which is executed lazily. This is because JIT mode must compile a
template which can be specified as `templateURL` and those we are
waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy
  lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the
  codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the
`ɵɵdefineComponent` so that lifecycle hook access would be monomorphic.
This decision was made before we had `T*` data structures. By not
reading the lifecycle hooks we are moving the megamorhic read form
`ɵɵdefineComponent` to instructions. However, the reads happen on
`firstTemplatePass` only and are subsequently cached in the `T*` data
structures. The result is that the overall performance should be same
(or slightly better as the intermediate `ComponentDef` has been
removed.)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer
      be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix #30497

PR Close #38119
2020-07-17 13:14:35 -07:00
7b6e73cb98 fix(core): error due to integer overflow when there are too many host bindings (#38014)
We currently use 16 bits to store information about nodes in a view.
The 16 bits give us 65536 entries in the array, but the problem is that while
the number is large, it can be reached by ~4300 directive instances with host
bindings which could realistically happen is a very large view, as seen in #37876.
Once we hit the limit, we end up overflowing which eventually leads to a runtime error.

These changes bump to using 20 bits which gives us around 1048576 entries in
the array or 16 times more than the current amount which could still technically
be reached, but is much less likely and the user may start hitting browser limitations
by that point.

I picked the 20 bit number since it gives us enough buffer over the 16 bit one,
while not being as massive as a 24 bit or 32 bit.

I've also added a dev mode assertion so it's easier to track down if it happens
again in the future.

Fixes #37876.

PR Close #38014
2020-07-17 12:58:16 -07:00
f2ca4634e2 fix(docs-infra): correctly display SVG icons in IE11 (#38046)
Fix two issues that affected displaying of SVG icons in IE11:

1. All SVG icons except for one appeared empty. This was related how the
CustomIconRegistry re-used the same <div> element to create all
SVG elements.

2. The GitHub and Twitter buttons next to the search bar were not sized
properly.

Fixes #37847

PR Close #38046
2020-07-17 11:44:35 -07:00
d30cf2f9d6 docs(docs-infra): reformat redundant sentence (#38109)
reformat sentence uses the npm package manager since npm is node package manager

Fixes #38106

PR Close #38109
2020-07-17 11:39:17 -07:00
e9cb6fbe87 build(language-service): add script to build package locally (#38103)
This commit adds a script to build @angular/language-service
locally so that it can be consumed by the Angular extension for
local development.

PR Close #38103
2020-07-16 16:39:55 -07:00
99960a98d2 docs: update router api documentation (#37980)
Edit descriptions, usage examples, and add links to be complete and consistent with API reference doc style

PR Close #37980
2020-07-16 13:52:41 -07:00
9ac3383d01 build(language-service): remove typescript from ivy bundle (#38088)
Currently the Ivy language service bundle is [10MB](
https://unpkg.com/browse/@angular/language-service@10.0.4/bundles/) because we
accidentally included typescript in the bundle.

With this change, the bundle size goes down to 1.6MB, which is even smaller
than the View Engine bundle (1.8MB).

```bash
$ yarn bazel build //packages/language-service/bundles:ivy
$ ls -lh dist/bin/packages/language-service/bundles/ivy.umd.js
1.6M Jul 15 15:49 dist/bin/packages/language-service/bundles/ivy.umd.js
```

PR Close #38088
2020-07-16 11:04:58 -07:00
06ac75724f ci: add more owners for some categories (#37994)
* Add petebacondarwin to public-api, size-tracking, and circular-dependencies
* Add mhevery, josephperrott, and jelbourn to code-ownership

PR Close #37994
2020-07-16 11:03:56 -07:00
a1d691ecc8 docs: add Ajit Singh to the collaborators (#37792)
Ajit Singh is a newly added collborator after a few months of contributing add him to the contributors.json

PR Close #37792
2020-07-16 11:02:08 -07:00
6e329721be docs: add Emma Twersky to DevRel Contributor page (#38084)
This commit adds Emma Twersky to the Angular Contributors page along with a bio & a photograph.

PR Close #38084
2020-07-15 13:50:40 -07:00
739bf5c325 docs: fix typo in "Creating libraries" guide (by publishing...ensures --> publishing...ensures) (#38032)
PR Close #38032
2020-07-15 13:12:15 -07:00
ee340b7c6c docs(service-worker): fix typos in SwRegistrationOptions API docs (#38047)
PR Close #38047
2020-07-15 13:10:26 -07:00
17ddab98fb fix(core): incorrectly validating properties on ng-content and ng-container (#37773)
Fixes the following issues related to how we validate properties during JIT:
- The invalid property warning was printing `null` as the node name
for `ng-content`. The problem is that when generating a template from
 `ng-content` we weren't capturing the node name.
- We weren't running property validation on `ng-container` at all.
This used to be supported on ViewEngine and seems like an oversight.

In the process of making these changes, I found and cleaned up a
few places where we were passing in `LView` unnecessarily.

PR Close #37773
2020-07-15 12:39:40 -07:00
4f65f473e4 ci(docs-infra): increase minimum a11y scores for various pages (#37899)
As part of our CI checks, we ensure the a11y score on certain angular.io
pages do not fall below some thresholds.

This commit increases these thresholds based on our current scores to
ensure we do not regress below current values.

PR Close #37899
2020-07-15 12:38:08 -07:00
527a04d21e build(docs-infra): upgrade lighthouse to 6.1.0 (#37899)
To take advantage of lazy loaded images `img[loading=lazy]`, this commit
upgrades lighthouse to version 6.1.0.

Closes #35965

PR Close #37899
2020-07-15 12:38:08 -07:00
f2ee468d76 fix(dev-infra): add missing BUILD file to dev-infra/bazel:files (#38026)
* Without this BUILD file we were seeing errors about the reference to
  expand_template.bzl in ng_rollup_bundle.bzl because dev-infra/bazel
  was not considered a package.

PR Close #38026
2020-07-15 12:34:47 -07:00
0320096538 fix(dev-infra): fix broken zone.js substitution for dev-infra:npm_package (#38026)
* fix substitution that was broken by PR #36540 to match
  the new import path

PR Close #38026
2020-07-15 12:34:47 -07:00
7abb48adfe feat(dev-infra): add bazel firefox browser with RBE compatibility (#38029)
Adds Firefox as browser to `dev-infra/browsers` with RBE
compatibility. The default Firefox browser is not compatible similar to
the default Chromium version exposed by `rules_webtesting`.

The Angular Components repository will use this browser target as
it enables RBE support. Also it gives us more flexibility about
the Firefox version we test against. The version provided by
`rules_webtesting` is very old and most likely not frequently
updated (based on past experience).

PR Close #38029
2020-07-15 12:34:06 -07:00
b40d3c0817 docs: update reference doc for router guards and resolvers (#38079)
Complete and clarify descriptions and example of the guard and resolver functions in Router API documentation.

PR Close #38079
2020-07-15 12:32:12 -07:00
0e5617152a docs: remove all references to Angular Console (#37608)
Angular Console has been renamed and links no longer work. It has been decided to remove references to this third-party tool from the AIO documentation.

Closes #37604

PR Close #37608
2020-07-15 12:30:59 -07:00
dba402344f fix(compiler-cli): ensure file_system handles mixed Windows drives (#38030)
The `fs.relative()` method assumed that the file-system is a single tree,
which is not the case in Windows, where you can have multiple drives,
e.g. `C:`, `D:` etc.

This commit changes `fs.relative()` so that it no longer forces the result
to be a `PathSegment` and then flows that refactoring through the rest of
the compiler-cli (and ngcc).  The main difference is that now, in some cases,
we needed to check whether the result is "rooted", i.e an `AbsoluteFsPath`,
rather than a `PathSegment`, before using it.

Fixes #36777

PR Close #38030
2020-07-15 12:29:44 -07:00
13d176302b release: cut the v10.0.4 release 2020-07-15 10:56:55 -07:00
e3b801053a fix(ngcc): report a warning if ngcc tries to use a solution-style tsconfig (#38003)
In CLI v10 there was a move to use the new solution-style tsconfig
which became available in TS 3.9.

The result of this is that the standard tsconfig.json no longer contains
important information such as "paths" mappings, which ngcc might need to
correctly compute dependencies.

ngcc (and ngc and tsc) infer the path to tsconfig.json if not given an
explicit tsconfig file-path. But now that means it infers the solution
tsconfig rather than one that contains the useful information it used to
get.

This commit logs a warning in this case to inform the developer
that they might not have meant to load this tsconfig and offer
alternative options.

Fixes #36386

PR Close #38003
2020-07-14 13:21:32 -07:00
6626739798 docs(core): fixes minor typo in initNgDevMode function docs (#38042)
PR Close #38042
2020-07-14 13:17:33 -07:00
396033da80 refactor(forms): remove unnecessary ! operators from validators (#36805)
When we added the strict null checks, the lexer had some `!` operators added to prevent the compilation from failing.

See #24571

PR Close #36805
2020-07-14 11:01:54 -07:00
02ee9d2938 docs(forms): Fix typos in template-driven forms tutorial (#37933)
Fix two typos in the 'Building a template-driven form` that caused the guide to not be displayed correctly.

PR Close #37933
2020-07-14 11:01:30 -07:00
a4c7f183d7 docs(forms): Minor fix in forms overview guide (#37933)
Remove an article from the `Data flow in forms` section of the forms overview guide. The use of `the` and `a` together
is not syntactically correct.

PR Close #37933
2020-07-14 11:01:30 -07:00
d690eec88f docs(router): fix typo in "spotlight on pathmatch" (#38039)
https://angular.io/guide/router-tutorial-toh#pathmatch

PR Close #38039
2020-07-14 09:20:19 -07:00
10e4dfae27 docs(router): fix typo in https://angular.io/guide/router#activated-route (#38034)
In angular.io, it linked to the wrong part of the page. https://angular.io/guide/router#activated-route

PR Close #38034
2020-07-14 09:10:26 -07:00
f8d948b46b docs: fix live examples in testing guides (#38038)
In #37957, parts of the testing guide were broken out into separate
guides. As part of that work, the `<live-example>` tags were also copied
to the new guides. These `<live-example>` tags did not specify the
targeted example project via the `name` attribute, thus they were
implicitly targeting the example with the same name as the guide they
were in. See the [Docs style guide][1] for more info.

However, there is only one example project (`testing/`) and all
`<live-example>` tags were supposed to target that. This worked fine on
the `testing.md` guide, but it broke on other guides (which tried to
target non-existing example projects based on their names).

This commit fixes it by explicitly specifying which example is targeted
by the `<live-example>` tags. It also removes the `embedded-style`
attribute that has no effect.

[1]: https://angular.io/guide/docs-style-guide#live-examples

Fixes #38036

PR Close #38038
2020-07-14 09:10:01 -07:00
9cf78d5701 docs(core): Fixed typo in Type JSdoc (#37930)
Updated comment doc in packages/core/src/interface/type.ts

PR Close #37930
2020-07-13 14:30:56 -07:00
45471dbbd6 refactor(dev-infra): allow for consumption with rules_nodejs v2.0.0 (#37968)
With `rules_nodejs` v2.0.0 being in RC phase currently, we should
make sure that the package is compatible so that we can use it
in the components repo in combination with rules_nodejs v2.0.0.

In v2.0.0 of the NodeJS rules, Bazel workspaces are recommended
to no longer be symlinked under a separate repository. Instead,
bazel rules and targets should be accessed directly from the
user-selected NPM repository. Usually `@npm`, so that the import
changes to `@npm//@angular/dev-infra-private/<..>`.

PR Close #37968
2020-07-13 14:18:23 -07:00
387e8386d1 fix(language-service): remove completion for string (#37983)
If the user inputs a string(e.g. `<div [ngClass]="'str~{cursor}'"></div>`), the completion is useless.

PR Close #37983
2020-07-13 14:16:56 -07:00
eec6e4be7a docs: fixed typo in https://angular.io/guide/glossary (#36220)
PR Close #36220
2020-07-13 14:10:07 -07:00
b711f25892 docs(router): fix typo 'containa' to 'contains' (#36764)
Closes #36763

PR Close #36764
2020-07-13 14:09:33 -07:00
788f0453f7 docs: Add Scully to resources.json (#37678)
Add Scully to the resource page by adding it to the "Tooling" subcategory in resources.json file

PR Close #37678
2020-07-13 14:08:41 -07:00
45b1775a53 docs: remove Markus Padourek from angular collaborators (#37962)
This person was never onboarded

PR Close #37962
2020-07-13 14:08:14 -07:00
53e4ff72d2 docs: fix typo in router.md (#37227)
This commit fixes a typo in the router documentation. "Benfits of a routing module" => "Benefits of a routing module"

PR Close #37227
2020-07-13 09:27:29 -07:00
7813a7d129 docs(http): Remove extra semicolons in the http guide (#37228)
An extra semicolon in searchHeroes function was removed in the http guide
found in aio/content/guide/http.md

docs(http): Remove extra semicolon in a code example found in the http guide

Removed extra semicolon in handleError function in the file located at
aio/content/examples/http/src/app/config/config.service.ts, which serves
as a source of code examples for the http guide.

Replace a comma for a dot in the comment at line 79 to ensure consistency
with the rest of the document.

Capitalized and added a dot at the end of the comment at line 84 to
ensure consistency with the other comments.

PR Close #37228
2020-07-13 09:25:20 -07:00
c0ced6dc2d build(docs-infra): ensure the correct files are in the i18n example (#37947)
The Stackblitz and zip-file include `doc-files` unnecssarily and are missing
the locale files. This commit updates the `stackblitz.json` to fix this.

PR Close #37947
2020-07-13 09:24:34 -07:00
8157ee87b0 build(docs-infra): remove unnecessary zipper.json file (#37947)
The `zipper.json` file is only needed if the example does not
have a `stackblitz.json` file, which this (i18n) example does.

Moreover, it appears that having both can cause the generated
zip file to be corrupted and not unzippable.

Fixes #37849

PR Close #37947
2020-07-13 09:24:34 -07:00
ab051aba27 docs: reformat and update CONTRIBUTING.md (#37951)
This doc is very old and rusty. I'm reformatting it to follow the one-setence-per-line rule.
I also updated a few sections, since they were either poorly written or obsolete.

PR Close #37951
2020-07-13 09:23:04 -07:00
5a61ef0c49 build: add .gitmessage file with commit message template (#37951)
Git provides a way to create a commit message template via the `.gitmessage` file.

Introduce an Angular-specific .gitmessage template based on the original Commit Message Guidelines.
https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-commit-message-guidelines

If this template workflow is proven in practice, we can move the commit message guidelines into the
.gitmessage file to prevent duplication of the content.

This change is a follow up on #37949 and is inspired by info found in the following blog post:
https://thoughtbot.com/blog/better-commit-messages-with-a-gitmessage-template

PR Close #37951
2020-07-13 09:23:04 -07:00
c451dbda9f build: adding shared .ng-dev/gitconfig file for convenience and consistent git config (#37951)
This file is inert unless it's explicitly included into the local git config via:

```
git config --add include.path '../.ng-dev/gitconfig'
```

Calling that command will append the following into `.git/config` of the current git workspace
(i.e. $GIT_DIR, typically `angular/.git/config`):

```
[include]
	path = ../.ng-dev/gitconfig
```

I'm intentionally keeping the config inert for now until we prove that this is a good idea.

Eventually we could roll this change out to all the contributors via an npm post-install script.

PR Close #37951
2020-07-13 09:23:04 -07:00
0d38288078 docs: Move router tutorial (toh) from router.md to new file (#37979)
In an effort to make angular documentation easier for users to read,
we are moving the router tutorial currently in router.md to a new file.
To support this change, we have done the following:

* Update files to fix any broken links caused by moving the file
* Updated the new file to follow tutorial guidelines
* Add the new file to the table of  contents under, Tutorials.

PR Close #37979
2020-07-10 15:04:56 -07:00
2e9b953e9d docs(router): fix routerLink docs (#37997)
The current content for the routerLink commands input does not make it to aio.
fixes #35414

PR Close #37997
2020-07-10 11:24:29 -07:00
a94383f168 fix(compiler): check more cases for pipe usage inside host bindings (#37883)
Builds on top of #34655 to support more cases that could be using a pipe inside host bindings (e.g. ternary expressions or function calls).

Fixes #37610.

PR Close #37883
2020-07-10 11:00:21 -07:00
75c40ddd61 feat(dev-infra): commit message validation should skip lines consisting of URLs (#37890)
The dev-infra commit message validation optionally can check for lines
to not exceed a given amount of characters. This is desired for most
commit messages, but sometimes not actionable if a long URL is inserted
into the commit message. With this commit, we skip the max line length
check for lines that start with an URL.

PR Close #37890
2020-07-10 10:59:29 -07:00
86a75a0670 build: split dev-infra configuration into individual files (#37890)
Splits the dev-infra configurations into individual files inside the
`.ng-dev/` folder. This helps with clarity as there is no single
configuration file that becomes extremely large and difficult to
maintain.

Additionally, more explicit configuration types are now used. This
fixed the max-line length setting for commit message validation.
This option is currently named incorrectly and a noop.

PR Close #37890
2020-07-10 10:59:29 -07:00
c776825fdd fix(dev-infra): include bazel utility files in npm package (#37891)
We recently added a new folder for common bazel utilities
to `dev-infra`. The `ng_rollup_bundle` rule relies on an
utility that is provided by this `bazel/` folder.

Unfortunately though it looks like this folder is currently
not included in the NPM package, so that the `ng_rollup_bundle`
rule does not work as expected. This commit fixes that by
including the bazel utilities in the NPM package.

PR Close #37891
2020-07-10 10:06:12 -07:00
1cc9383d91 build: set up caretaker note label in merge tooling (#37778)
Leverage the caretaker note label configuration in ng-dev's merge
tooling to prompt the caretaker for confirmation  when a PR has
the `PR action: merge-assistance` label. This should help to
surface for the caretaker, PRs which may need additional steps
taken, announcement messaging, etc.

PR Close #37778
2020-07-10 16:58:36 +00:00
8ed1e53e99 test: update symbol goldens to reflect optimized application (#37778)
Interestingly enough, our rollup bundle optimization pipeline
did not work properly before 1b827b058e5060963590628d4735e6ac83c6dfdd.

Unused declarations were not elided because build optimizer did not
consider the Angular packages as side-effect free. Build optimizer has
a hard-coded list of Angular packages that are considered side-effect
free. Though this one did not match in the old version of the rollup
bundle rule, as internal sources were resolved through their resolved
bazel-out paths. Hence build optimizer could not detect the known
Angular framework packages. Now though, since we leverage the
Bazel-idiomatic `@bazel/rollup` implementation, sources are resolved
through linked `node_modules`, and build optimizer is able to properly
detect files as side-effect free.

PR Close #37778
2020-07-10 16:58:35 +00:00
7833c88ac4 ci: update components-repo-unit-tests job commit (#37778)
Updates to the latest commit of the `angular/components` repository. We
need to do this because we removed the `esm5.bzl` output flavour aspect,
but an old version of the components repo relied on this file to exist.

This is no longer the case, and we can simply update the version of the
components repo we can test against.

PR Close #37778
2020-07-10 16:58:35 +00:00
12f177399f fix(language-service): non-existent module format in package output (#37778)
The language-service package currently sets the `module` `package.json`
property and refers to a folder called `fesm5`. The language-service
though does not build with `ng_package` so this folder never existed.
Now with APF v10, ng package would not generate this folder either.

We should just remove the property as the primary entry-point is
the UMD bundle resolved through `main`. There is no module flavour
exposed to the NPM package as `pkg_npm` uses the named AMD module
devmode output that doesn't work for `module`.

PR Close #37778
2020-07-10 16:58:35 +00:00
5be32366be test: remove unused stale ng_package test golden file (#37778)
It looks like there is a leftover golden in the `ng_package`
tests that is no longer used anywhere and does not reflect
the latest Angular Package Format v10 changes. We should be
able to remove it to keep our codebase healthy.

PR Close #37778
2020-07-10 16:58:35 +00:00
5b7d2eeabf refactor(dev-infra): ng_rollup_bundle rule should leverage @bazel/rollup (#37778)
Refactors the `ng_rollup_bundle` rule to a macro that relies on
the `@bazel/rollup` package. This means that the rule no longer
deals with custom ESM5 flavour output, but rather only builds
prodmode ES2015 output. This matches the common build output
in Angular projects, and optimizations done in CLI where
ES2015 is the default optimization input.

The motiviation for this change is:

* Not duplicating rollup Bazel rules. Instead leveraging the official
rollup rule.
* Not dealing with a third TS output flavor in Bazel.The ESM5 flavour has the
potential of slowing down local development (as it requires compilation replaying)
* Updating the rule to be aligned with current CLI optimizations.

This also _fixes_ a bug that surfaced in the old rollup bundle rule.
Code that is unused, is not removed properly. The new rule fixes this by
setting the `toplevel` flag. This instructs terser to remove unused
definitions at top-level. This matches the optimization applied in CLI
projects. Notably the CLI doesn't need this flag, as code is always
wrapped by Webpack. Hence, the unused code eliding runs by default.

PR Close #37778
2020-07-10 16:58:35 +00:00
6cd10a1b10 feat(bazel): provide LinkablePackageInfo from ng_module (#37778)
Adds the `LinkablePackageInfo` to the `ng_module` rule. This allows
the linker to properly link `ng_module` targets in Node runtime
actions. Currently this does not work properly and packages like
`@angular/core` are not linked, so we cannot rely on the linker.

9a5de3728b/internal/linker/link_node_modules.bzl (L144-L146).

PR Close #37778
2020-07-10 16:58:35 +00:00
822652aa0d refactor(bazel): cleanup ng_package rule to not build fesm5 and esm5 output (#37778)
As of Angular Package Format v10, we no longer ship a `fesm5` and
`fesm5` output in packages. We made this change to the `ng_package`
rule but intentionally did not clean up related build actions.

This follow-up commit cleans this up by:

* No longer building fesm5 bundles, or providing esm2015 output.
* No longer requesting and building a third flavor for ESM5. We can
use TSC to downlevel ES2015 sources/prodmode output similarly to how it
is done in `ng-packagr`.

The third output flavor (ESM5) resulted in a build slow-down as we
required a full recompilation of sources. Now, we only have a single
compilation for prodmode output, and then downlevel it on-demand
to ES5 for the UMD bundles. Here is timing for building the release
packages in `angular/angular` before this change, and afterwards:

* Before: 462.157s = ~7.7min
* After: 339.703s =  ~5.6min

This signifies a time reduction by 27% when running
`./scripts/build/build-packages-dist.sh`.

PR Close #37778
2020-07-10 16:58:35 +00:00
cf47ace493 refactor(dev-infra): migrate github api in GitClient to rely on GithubClient (#37778)
GitClient now uses GithubClient for github API interactions.  GithubClient is
a class which extends Octokit and provides a member which allows for GraphQL
requests against the Github GraphQL api, as well as providing convenience methods
for common/repeated Github API requests.

PR Close #37778
2020-07-10 16:58:35 +00:00
0595f11950 refactor(dev-infra): cleanup shared package dependencies (#37778)
Cleans up the dependencies used in the shared dev-infra package
configuration. With the recent benchmarking utilities that have
been added, a lot of peer dependencies have been added.

We decided that we don't want to list every used dependencies as
peer dependency as that could result in unnecessary churn/noise
for consumers of the dev-infra package. Additionally, not all parts
of the dev-infra package are necessarily used.

Due to this, we want to apply the following rules for the package
dependencies:

1. If a dependency is only used in a shipped Bazel macro/rule that can be
optionally consumed, omit it from `package.json`. Bazel reports the
missing dependency on its own, so we want to avoid adding it to the
package json file.

2. Otherwise, if the dependency is large and commonly used (like
buildifier), add it to the `peerDependencies`. If not, add it
to the dependencies that are always brought in. We consider it
as acceptable to bring in a few small dependencies that might not
be used or not. Making all of those option would complicate the
use of the dev-infra package.

ds

PR Close #37778
2020-07-10 16:58:35 +00:00
35df312ea4 refactor(dev-infra): use shelljs instead of fs-extra for benchmark utils (#37778)
We added a new dependency on `fs-extra` to the dev-infra package. We can
remove this dependency and replace it with `shelljs` that is extensively
used in other places already.

The motiviation is that we can reduce dependencies needed for
for consumption of the shared dev-infra package.

PR Close #37778
2020-07-10 16:58:34 +00:00
489eb8519e feat(dev-infra): support for caretaker note label in merge script (#37595) (#37778)
Adds support for a caretaker note label to the merge script.
Whenever a configured label is applied, the merge script will
not merge automatically, but instead prompt first in order
to ensure that the caretaker paid attention to the manual
caretaker note on the PR. This helps if a PR needs special
attention.

PR Close #37595

PR Close #37778
2020-07-10 16:58:34 +00:00
b76a2dc2cb fix(bazel): ng_module rule does not expose flat module information in Ivy (#36971)
The `ng_module` rule supports the generation of flat module bundles. In
View Engine, information about this flat module bundle is exposed
as a Bazel provider. This is helpful as other rules like `ng_package`
could rely on this information to determine entry-points for the APF.

With Ivy this currently does not work because the flat module
information is not exposed in the provider. The reason for this is
unclear. We should also provide this information in Ivy so that rules
like `ng_package` can also determine the correct entry-points when a
package is built specifically with `--config=ivy`.

PR Close #36971
2020-07-09 22:11:17 +00:00
f2f5f7fc6e docs(animations): Added consistency in code examples (#37081)
PR Close #37081
2020-07-09 22:08:01 +00:00
8ee23ba67b docs: add explanation for providedIn any (#35283)
Angular 9 introduces a new value for providedIn called `any` which lets us use unique instance
for servicec in each lazy loaded module, this PR is to document the same

fixes #35179

PR Close #35283
2020-07-09 10:12:00 -07:00
ecb422b360 ci: fix payload size (#37993)
Payload size test is failing on the 10.0.x branch at the moment.

PR Close #37993
2020-07-09 10:09:10 -07:00
60389d5441 refactor(service-worker): use nominal type for normalized URLs (#37922)
Some ServiceWorker operations and methods require normalized URLs.
Previously, the generic `string` type was used.

This commit introduces a new `NormalizedUrl` type, a special kind of
`string`, to make this requirement explicit and use the type system to
enforce it.

PR Close #37922
2020-07-09 09:44:58 -07:00
b186db70db fix(service-worker): correctly handle relative base href (#37922)
In some cases, it is useful to use a relative base href in the app (e.g.
when an app has to be accessible on different URLs, such as on an
intranet and the internet - see #25055 for a related discussion).

Previously, the Angular ServiceWorker was not able to handle relative
base hrefs (for example when building the with `--base-href=./`).

This commit fixes this by normalizing all URLs from the ServiceWorker
configuration wrt the ServiceWorker's scope.

Fixes #25055

PR Close #37922
2020-07-09 09:44:58 -07:00
324b6f1b1a test(service-worker): make mock implementations more similar to actual ones (#37922)
This commit makes the mock implementations used is ServiceWorker tests
behave more similar to the actual ones.

PR Close #37922
2020-07-09 09:44:58 -07:00
cdba1d37a4 refactor(service-worker): move asset URL normalization to Adapter (#37922)
This is in preparation of enabling the ServiceWorker to handle
relative paths in `ngsw.json` (as discussed in #25055), which will
require normalizing URLs in other parts of the ServiceWorker.

PR Close #37922
2020-07-09 09:44:58 -07:00
dc42c97ee4 fix(service-worker): correctly serve ngsw/state with a non-root SW scope (#37922)
The Angular ServiceWorker can serve requests to a special virtual path,
`ngsw/state`, showing [information about its internal state][1], which
can be useful for debugging.

Previously, this would only work if the ServiceWorker's [scope][2] was
the root directory (`/`). Otherwise, (e.g. when building the app with
`--baseHref=/some/path/`), the ServiceWorker would fail to detect a
request to `/some/path/ngsw/state` as matching `ngsw/state` and would
not serve it with the debugging information.

This commit fixes it by ensuring that the ServiceWorker's scope is taken
into account when detecting a request to `ngsw/state`.

[1]: https://angular.io/guide/service-worker-devops#locating-and-analyzing-debugging-information
[2]: https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/scope

Fixes #30505

PR Close #37922
2020-07-09 09:44:57 -07:00
bc00e8d312 docs: add Formly library to the list of resources (#37257)
This commit adds the Formly library to the Angular list of resources at aio/content/marketing/resources.json.

PR Close #37257
2020-07-09 09:19:49 -07:00
720b71d01f docs(router): get rid of unnecessary line in wildcard route example and fixing wildcard docregions (#37127)
The wildcard example leads to display a 404 page with the PageNotFoundComponent. But before, there is a wildcard to redirect to the FirstComponent and because of the routes order the FirstComponent will be displayed; which it is not the target of the wildcard route example code. Also, fixing some wildcard docregions
PR Close #37127
2020-07-08 16:04:51 -07:00
1132b07c53 test: fix test failure in saucelabs ivy ie10 (#37892)
One of the ivy acceptance tests currently fails in IE10. This
is because we recently added a new test that asserts that injecting
`ViewRef` results in a `NullInjectorError`.

Due to limitations in TypeScript and in polyfills for `setPrototypeOf`,
the error cannot be thrown as `ViewRef` is always considered injectable.
In reality, `ViewRef` should not be injectable, as explicitly noted
in c00f4ab2ae.

There seems no way to simulate the proper prototype chain in such
browsers that do not natively support `__proto__`, so TypeScript
and `core-js` polyfills simply break the prototype chain and
assign inherited properties directly on `ViewRef`. i.e. so that
`ViewRef.__NG_ELEMENT_ID__` exists and DI picks it up.

There is a way for TypeScript to theoretically generate proper
prototype chain in ES5 output, but they intend to only bother
about the proper prototype chain in ES6 where `setPrototypeOf`
etc. are offically standarized. See the response:

https://github.com/microsoft/TypeScript/issues/1601#issuecomment-94892833.

PR Close #37892
2020-07-08 16:03:34 -07:00
9230194794 build(docs-infra): update @angular/cli to 10.0.1 (#37898)
This commit updates the version of Angular CLI used in angular.io to
version 10.0.1. It also reverts some changes (namely commits 38dfbc775f
and eee2fd22e0) which were made due to an older bug that is fixed in
the latest version. See #37688 for more details.

Fixes #37699

PR Close #37898
2020-07-08 16:02:47 -07:00
d724896f04 refactor(docs-infra): avoid Material style duplication warning (#37898)
This commit removes some duplicate imports of Material themes and
theming-related utilities. While this change does not have any impact on
the size of the generated `styles.css` file, it silences a build warning
pointing to [Avoiding duplicated theming styles][1].

[1]: db4b0cd1bf/guides/duplicate-theming-styles.md

PR Close #37898
2020-07-08 16:02:47 -07:00
29866dfb91 build(docs-infra): update @angular/material to 10.0.1 (#37898)
This commit updates the version of Angular Components used in angular.io
to version 10.0.1. It also updates the angular.io app to adapt to
breaking changes.

PR Close #37898
2020-07-08 16:02:47 -07:00
a249622159 build(docs-infra): update @angular/core to 10.0.2 (#37898)
This commit updates the version of Angular framework used in angular.io
to version 10.0.2. It also features a commit message with a 100+ chars
long body.

PR Close #37898
2020-07-08 16:02:47 -07:00
9f2393fb80 refactor(core): remove duplicated WrappedValue class (#37940)
Before this refactoring we had the WrappedValue class in
2 separate places:
- packages/core/src/change_detection/change_detection_util.ts
- packages/core/src/util/WrappedValue.ts

This commit removes the duplicate, leaving the class that has
the deprecation notice.

PR Close #37940
2020-07-08 16:02:17 -07:00
d5f8040d0a docs: break testing doc into multiple docs (#37957)
This commit breaks up the testing document into nine total documents, with each document focusing on an existing section of the current testing documentation. There are no content changes.

PR Close #37957
2020-07-08 16:01:50 -07:00
e0b8ea136b docs(elements): fix typo (you custom element --> your custom element) (#37966)
PR Close #37966
2020-07-08 16:01:22 -07:00
879b2273c1 ci: decrease the minBodyLength commit message limit to 20 chars (#37949)
The motivation behind this change is to improve the productivity in the angular/angular repo
without sacrificing the original goal of having better understanding of changes within
the repo.

When the minBodyLength limit was originally introduced the goal was simple: force
committers to provide more contextual information for each change coming into the
repo. Too often we found ourselves in a situation where nobody understood what
motivated some of the changes and we needed more contextual info to know if the
change was correct, desirable, and still relevant (at a later point in time).

When the limit was introduced, we needed to pick a minimum body length - given no
data, and frustration with even big changes being committed with just a words in
the subject (along the lines of "fix(core): fixing a bug"), we overcompensated
and started off with a really high bar of minBodyLength set to 100 chars.

This turned out to be impractical and created a big friction point in making valid
changes in the angular/angular repo, and in fact caused some of the refactorings
and smaller changes to be either skipped or combined into other commits which
increased the burden for code reviewers.

The evidence in the friction points can be seen in the number of PRs that fail to pass
the current lint check on the first try, but more importantly also in the "creative"
writing that some of the committers are forced to resort to in order to satisfy the
current checks. Examples:

- 286fbf42c6
- b2816a1536

Given that we primarily care to document the motivation behind each change
(the answer to the ultimate question: WHY?), I've collected several *common* &
*valid* commit messages that are minimalistic and capture the WHY sufficiently:

```
Refactoring for readability.  => 28 chars
Improving variable naming.    => 26 chars
Additional test coverage.     => 25 chars
Cleaning up the code.         => 21 chars
Simplified the code.          => 20 chars
```

These commit message bodies in addition to the commit message subject should
sufficiently satisfy the need to capture the context and motivation behind each
change without creating an undue burden on committers.

Example minimalistic commit message:

------

refactor(core): cleanup the expression parser

Simplifying the code.

----

Given this research, I'm decreasing the minBodyLenth in angular/angular to 20 chars.

The commit message quality can be additionally improved by implementing a commit message
template via `.gitmessage` that will guide the committers in following our commit message
guidelines via instructions provided in the form of in-the-flow help rather than as an after
the fact lint check.

More info: https://thoughtbot.com/blog/better-commit-messages-with-a-gitmessage-template

I'm intentionally deferring such change for a separate PR as not to complicate or delay the
minBodyLength limit decrease.

PR Close #37949
2020-07-08 15:43:03 -07:00
f24972b1b1 release: cut the v10.0.3 release 2020-07-08 13:44:29 -07:00
d2886b3bb4 build: filter out duplicate cherry-picked commits in changelog (#37956)
Often changelogs are generated from the patch branch and then
cherry-picked into the `CHANGELOG.md` file in `master` for
better access and readability. This is problematic though as
`conventional-changelog` (the tool we use for generating the
changelog), will duplicate commits when a future changelog
is generated from `master` then (i.e. for a new minor release).

This happens because conventional-changelog always generates the
changelog from the latest tag in a given branch to `HEAD`. The
tag in the patch branch does not correspond to any SHA in `master`
so the intersection of commits is not automatically omitted.

We work around this naively (until we have a better tool provided
by dev-infra), by deduping commits that are already part of the
changelog. This has proven to work as expected in the components
repo.

PR Close #37956
2020-07-08 12:04:47 -07:00
f296fea112 docs: minor fixes to docs related to updating to v10 (#37897)
This commit includes a couple of minor fixes to docs related to updating
to v10:
- Fix markdown link in "Updating to Angular version 10" guide.
- Correctly display numbered list in
  "Solution-style `tsconfig.json` migration" guide.

PR Close #37897
2020-07-07 12:17:05 -07:00
2605fc46e7 feat(dev-infra): merge script should link to original commit when cherry-picking with API strategy (#37889)
The merge script uses `git cherry-pick` for both the API merge strategy
and the autosquash strategy. It uses cherry-pick to push commits to
different target branches (e.g. into the `10.0.x` branch).

Those commits never point to the commits that landed in the primary
Github branch though. For the autosquash strategy the pull request number
is always included, so there is a way to go back to the source. On the other
hand though, for commits cherry-picked in the API merge strategy, the
pull request number might not always be included (due to Github's
implementation of the rebase merge method).

e.g.
27f52711c0

For those cases we'd want to link the cherry-picked commits to the
original commits so that the corresponding PR is easier to track
down. This is not needed for the autosquash strategy (as outlined
before), but it would have been good for consistency. Unfortunately
though this would rather complicate the strategy as the autosquash
strategy cherry-picks directly from the PR head, so the SHAs that
are used in the primary branch are not known.

PR Close #37889
2020-07-07 12:16:22 -07:00
9d54b3a14b fix(docs-infra): prevent search-bar from overlapping nav-items (#37938)
As part of angular.io's responsive layout, the menu shown in the top-bar
is collapsed into the sidenav on narrow screens at the point where the
search-bar (on the right side of the top-bar) would overlap with the
menu's nav-items.

Previously, the value used as break-point would work on marketing pages,
where the hamburger button is not shown on wide screens. However, on
docs pages (where the hamburger button is always shown, pushing the menu
further to the right), the search-bar would still overlap the menu
nav-items on some resolutions.

This commit fixes it by raising the screen width threshold at a value
that ensures there is no overlap even on pages where the hamburger
button is visible alongside the top-bar menu.

Fixes #37937

PR Close #37938
2020-07-06 13:57:38 -07:00
d09a6283ed refactor(docs-infra): decouple showing the top-menu in top-bar from showing the sidenav (#37938)
As part of angular.io's responsive layout, the following rules are
applied:
- On wide screens, a menu is shown in the top-bar and the sidenav is
  shown side-by-side with the docs content.
- On narrow screens, the top-menu is moved from the top-bar to the
  sidenav and the sidenav is closed by default and floats over the
  content when manually opened.

Previously, the break-points at which the top-menu was shown in the
top-bar and the sidenav was shown side-by-side with the content were the
same (using a single variable).

This commit decouples the two break-points to make it possible to use
different values in the future.

PR Close #37938
2020-07-06 13:57:38 -07:00
1c168c3a44 refactor(docs-infra): use Sass variable for top-bar hamburger button show/hide threshold (#37938)
Use a Sass variable for the screen width break-point at which the
top-bar hamburger button is hidden/shown. This allows more easily
updating the break-point.

PR Close #37938
2020-07-06 13:57:38 -07:00
0f74479c47 build(docs-infra): improve applying post-install patches (#37896)
In `aio/`, we have a mechanism to apply patches in a `postinstall` hook.
See `aio/tools/cli-patches/README.md` for more info.

Previously, we had to update `aio/tools/cli-patches/patch.js` to list
each `.patch` file separately. While working on #37688, I found it
helpful for the script to automatically pick up `.patch` files.

This commit updates the script to automatically pick up and apply
`.patch` files from the `aio/tools/cli-patches/` directory. If one wants
to keep a `.patch` file but not apply it, they can change the file's
extension or move it to a sub-directory (without having to update the
script).

PR Close #37896
2020-07-06 13:56:15 -07:00
790bb949f6 fix(core): handle spaces after select and plural ICU keywords (#37866)
Currently when the `plural` or `select` keywords in an ICU contain trailing spaces (e.g. `{count, select , ...}`), these spaces are also included into the key names in ICU vars (e.g. "VAR_SELECT "). These trailing spaces are not desirable, since they will later be converted into `_` symbols while normalizing placeholder names, thus causing mismatches at runtime (i.e. placeholder will not be replaced with the correct value). This commit updates the code to trim these spaces while generating an object with placeholders, to make sure the runtime logic can replace these placeholders with the right values.

PR Close #37866
2020-07-06 13:55:48 -07:00
2adcad6dd2 fix(dev-infra): fix typo in ng-dev config (#37862)
The logic to exclude certain types of commits (specifically 'docs' ones) was implemented in c5b125b7db. The ng-dev config was updated in the followup commit acf3cff9ee, but there was a typo that prevented the new logic from being activated. This commit updates the name of the config option in the ng-dev config to the right one (minBodyLengthTypeExcludes).

PR Close #37862
2020-07-06 13:55:19 -07:00
242ef1ace1 docs: mention for depreciation for Testbed.get() (#37815)
As mention in https://angular.io/guide/deprecations for this API, it may be important mention for this to make developers migrate or avoid using it

PR Close #37815
2020-07-06 13:42:28 -07:00
842b6a1247 docs: clean up api doc in core (#37053)
Add introductions to usage examples and edit descriptions to be more complete and consistent with current API reference styles

PR Close #37053
2020-06-30 12:11:16 -07:00
98335529eb docs: add missing single quote (#37854)
The current code is missing a single quote at the end of the import.

(cherry picked from commit e13171ea2960dd0fa0666cb964b53799d2883e3a)

PR Close #37854
2020-06-30 12:10:14 -07:00
ca7ee794bf release: cut the v10.0.2 release 2020-06-30 11:40:40 -07:00
f9f2ba6faf docs: add Sonu Kapoor to the collaborator list (#37777)
After 6 months of continuous contributions, Sonu Kapoor did finally make
it into the collaborator list.

PR Close #37777
2020-06-30 10:47:55 -07:00
aea1d211d4 docs: update /config/app-package-json redirect (#37774)
With this change we change the redirect for `/config/app-package-json` from `https://webpack.js.org/configuration/optimization/#optimizationsideeffects` to `https://angular.io/guide/strict-mode#non-local-side-effects-in-applications`

The latter page has more details.

PR Close #37774
2020-06-30 10:45:53 -07:00
57a518a36d perf(compiler-cli): fix memory leak in retained incremental state (#37835)
Incremental compilation allows for the output state of one compilation to be
reused as input to the next compilation. This involves retaining references
to instances from prior compilations, which must be done carefully to avoid
memory leaks.

This commit fixes such a leak with a complicated retention chain:

* `TrackedIncrementalBuildStrategy` unnecessarily hangs on to the previous
  `IncrementalDriver` (state of the previous compilation) once the current
  compilation completes.

  In general this is unnecessary, but should be safe as long as the chain
  only goes back one level - if the `IncrementalDriver` doesn't retain any
  previous `TrackedIncrementalBuildStrategy` instances. However, this does
  happen:

* `NgCompiler` indirectly causes retention of previous `NgCompiler`
  instances (and thus previous `TrackedIncrementalBuildStrategy` instances)
  through accidental capture of the `this` context in a closure created in
  its constructor. This closure is wrapped in a `ts.ModuleResolutionCache`
  used to create a `ModuleResolver` class, which is passed to the program's
  `TraitCompiler` on construction.

* The `IncrementalDriver` retains a reference to the `TraitCompiler` of the
  previous compilation, completing the reference chain.

The final retention chain thus looks like:

* `TrackedIncrementalBuildStrategy` of current program
* `.previous`: `IncrementalDriver` of previous program
* `.lastGood.traitCompiler`: `TraitCompiler`
* `.handlers[..].moduleResolver.moduleResolutionCache`: cache
* (via `getCanonicalFileName` closure): `NgCompiler`
* `.incrementalStrategy`: `TrackedIncrementalBuildStrategy` of previous
  program.

The closure link is the "real" leak here. `NgCompiler` is creating a closure
for `getCanonicalFileName`, delegating to its
`this.adapter.getCanonicalFileName`, for the purposes of creating a
`ts.ModuleResolutionCache`. The fact that the closure references
`NgCompiler` thus eventually causes previous `NgCompiler` iterations to be
retained. This is also potentially problematic due to the shared nature of
`ts.ModuleResolutionCache`, which is potentially retained across multiple
compilations intentionally.

This commit fixes the first two links in the retention chain: the build
strategy is patched to not retain a `previous` pointer, and the `NgCompiler`
is patched to not create a closure in the first place, but instead pass a
bound function. This ensures that the `NgCompiler` does not retain previous
instances of itself in the first place, even if the build strategy does
end up retaining the previous incremental state unnecessarily.

The third link (`IncrementalDriver` unnecessarily retaining the whole
`TraitCompiler`) is not addressed in this commit as it's a more
architectural problem that will require some refactoring. However, the leak
potential of this retention is eliminated thanks to fixing the first two
issues.

PR Close #37835
2020-06-29 16:34:52 -07:00
29b83189b0 build(docs-infra): update to latest dgeni-packages (#37793)
This update of dgeni-packages to 0.28.4 fixes the
rendering of type initializers for classes and interfaces.

Closes #37694

PR Close #37793
2020-06-29 15:01:16 -07:00
1d3df7885d docs: correct the spelling mistake in observables error handling code (#36437)
This commit fixes a spelling error in the word error in the
observables.md guide. It is currently
spelled errror  and the mistake is not intentional.

PR Close #36437
2020-06-29 15:00:39 -07:00
fd06ffa2af docs: change definition of providedIn any (#35292)
change in the definition of providedIn:any any instance creates a singleton instance
for each lazy loaded module and one instance for eager loaded module

PR Close #35292
2020-06-29 15:00:01 -07:00
36a1622dd1 docs: correct left nav to remove duplicated page links (#37833)
The major sections Angular Libraries, Schematics, and CLI Builders appear twice, in their old location under Techniques, and in the new correct location under Extending Angular.

PR Close #37833
2020-06-29 14:57:37 -07:00
7a91b23cb5 fix(core): fake_async_fallback should have the same logic with fake-async (#37680)
PR https://github.com/angular/angular/pull/37523 failed when trying to use `rxjs delay` operator
inside `fakeAsync`, and the reasons are:

1. we need to import `rxjs-fake-async` patch to make the integration work.
2. since in `angular` repo, the bazel target `/tools/testing:node` not using `zone-testing` bundle,
instead it load `zone-spec` packages seperately, so it causes one issue which is the `zone.js/testing/fake-async`
package is not loaded, we do have a fallback logic under `packages/core/testing` calles `fake_async_fallback`,
but the logic is out of date with `fake-async` under `zone.js` package.

So this PR, I updated the content of `fake_async_fallback` to make it consistent with
`fake-async`. And I will make another PR to try to remove the `fallback` logic.

PR Close #37680
2020-06-29 12:22:52 -07:00
4b90b6a226 fix(ngcc): prevent including JavaScript sources outside of the package (#37596)
When ngcc creates an entry-point program, the `allowJs` option is enabled
in order to operate on the JavaScript source files of the entry-point.
A side-effect of this approach is that external modules that don't ship
declaration files will also have their JavaScript source files loaded
into the program, as the `allowJs` flag allows for them to be imported.
This may pose an issue in certain edge cases, where ngcc would inadvertently
operate on these external modules. This can introduce all sorts of undesirable
behavior and incompatibilities, e.g. the reflection host that is selected for
the entry-point's format could be incompatible with that of the external
module's JavaScript bundles.

To avoid these kinds of issues, module resolution that would resolve to
a JavaScript file located outside of the package will instead be rejected,
as if the file would not exist. This would have been the behavior when
`allowJs` is set to false, which is the case in typical Angular compilations.

Fixes #37508

PR Close #37596
2020-06-29 12:21:23 -07:00
b13daa4cdf refactor(ngcc): let isWithinPackage operate on paths instead of source files (#37596)
Changes `isWithinPackage` to take an `AbsoluteFsPath` instead of `ts.SourceFile`,
to allow for an upcoming change to use it when no `ts.SourceFile` is available,
but just a path.

PR Close #37596
2020-06-29 12:21:23 -07:00
0c6f026828 docs: Changing typo Stacblitz into Stackblitz in the Tour of Hereos tutorial docs page (#37794)
Changing the typo of Stacblitz into Stackblitz in the tour of hereos tutorial docs page since that is the actual name of the service

PR Close #37794
2020-06-29 12:17:41 -07:00
a2520bd267 docs: remove first person from 2 sentences (#37768)
This commit removes two instances of the first person in the
Dependency injection providers documentation.

PR Close #37768
2020-06-29 12:17:04 -07:00
b928a209a4 docs: add Amadou Sall to GDE page (#36509)
This commit adds Amadou Sall to the Angular GDE page along with a
biography, his role at Air France, and a photograph.

PR Close #36509
2020-06-29 12:16:23 -07:00
89e16ed6a5 fix(elements): fire custom element output events during component initialization (#37570)
Previously, event listeners for component output events attached on an
Angular custom element before inserting it into the DOM (i.e. before
instantiating the underlying component) didn't fire for events emitted
during initialization lifecycle hooks, such as `ngAfterContentInit`,
`ngAfterViewInit`, `ngOnChanges` (initial call) and `ngOnInit`.
The reason was that `NgElementImpl` [subscribed to events][1] _after_
calling [ngElementStrategy#connect()][2], which is where the
[initial change detection][3] takes place (running the initialization
lifecycle hooks).

This commit fixes this by:
1. Ensuring `ComponentNgElementStrategy#events` is defined and available
   for subscribing to, even before instantiating the component.
2. Changing `NgElementImpl` to subscribe to `NgElementStrategy#events`
   (if available) before calling `NgElementStrategy#connect()` (which
   initializes the component instance) if available.
3. Falling back to the old behavior (subscribing to `events` after
   calling `connect()` for strategies that do not initialize `events`
   before their `connect()` is run).

NOTE:
By falling back to the old behavior when `NgElementStrategy#events` is
not initialized before calling `NgElementStrategy#connect()`, we avoid
breaking existing custom `NgElementStrategy` implementations (with
@remackgeek's [ElementZoneStrategy][4] being a commonly used example).

Jira issue: [FW-2010](https://angular-team.atlassian.net/browse/FW-2010)

[1]: c0143cb2ab/packages/elements/src/create-custom-element.ts (L167-L170)
[2]: c0143cb2ab/packages/elements/src/create-custom-element.ts (L164)
[3]: c0143cb2ab/packages/elements/src/component-factory-strategy.ts (L158)
[4]: f1b6699495/projects/elements-zone-strategy/src/lib/element-zone-strategy.ts

Fixes #36141

PR Close #37570
2020-06-29 10:33:40 -07:00
1a1f99af37 fix(ngcc): ensure lockfile is removed when analyzeFn fails (#37739)
Previously an error thrown in the `analyzeFn` would cause
the ngcc process to exit immediately without removing the
lockfile, and potentially before the unlocker process had been
successfully spawned resulting in the lockfile being orphaned
and left behind.

Now we catch these errors and remove the lockfile as needed.

PR Close #37739
2020-06-29 10:29:12 -07:00
df2cd37ed2 fix(core): error when invoking callbacks registered via ViewRef.onDestroy (#37543) (#37783)
Invoking a callback registered through `ViewRef.onDestroy` throws an error, because we weren't registering it correctly in the internal data structure. These changes also remove the `storeCleanupFn` function, because it was mostly identical to `storeCleanupWithContext` and was only used in one place.

Fixes #36213.

PR Close #37543

PR Close #37783
2020-06-29 10:27:39 -07:00
12a71bc6bc fix(core): determine required DOMParser feature availability (#36578) (#37783)
Verify that HTML parsing is supported in addition to DOMParser existence.
This maybe wasn't as important before when DOMParser was used just as a
fallback on Firefox, but now that DOMParser is the default choice, we need
to be more accurate.

PR Close #37783
2020-06-29 10:27:39 -07:00
7d270c235a refactor(core): split inert strategies to separate classes (#36578) (#37783)
The `inertDocument` member is only needed when using the InertDocument
strategy. By separating the DOMParser and InertDocument strategies into
separate classes, we can easily avoid creating the inert document
unnecessarily when using DOMParser.

PR Close #37783
2020-06-29 10:27:39 -07:00
b0b7248504 fix(core): do not trigger CSP alert/report in Firefox and Chrome (#36578) (#37783)
If [innerHTML] is used in a component and a Content-Security-Policy is set
that does not allow inline styles then Firefox and Chrome show the following
message:

> Content Security Policy: The page’s settings observed the loading of a
resource at self (“default-src”). A CSP report is being sent.

This message is caused because Angular is creating an inline style tag to
test for a browser bug that we use to decide what sanitization strategy to
use, which causes CSP violation errors if inline CSS is prohibited.

This test is no longer necessary, since the `DOMParser` is now safe to use
and the `style` based check is redundant.

In this fix, we default to using `DOMParser` if it is available and fall back
to `createHTMLDocument()` if needed. This is the approach used by DOMPurify
too.

The related unit tests in `html_sanitizer_spec.ts`, "should not allow
JavaScript execution when creating inert document" and "should not allow
JavaScript hidden in badly formed HTML to get through sanitization (Firefox
bug)", are left untouched to assert that the behavior hasn't changed in
those scenarios.

Fixes #25214.

PR Close #37783
2020-06-29 10:27:38 -07:00
78460c1848 test(core): update symbols used in the test app (#37785)
This commit updates the golden file that contains the set of symbols used in the test TODO app. The `storeCleanupFn` function was replaced by `storeCleanupWithContext` in 75b119eafc and this commit updates the golden file to reflect that.

PR Close #37785
2020-06-26 16:44:00 -07:00
75b119eafc fix(core): error when invoking callbacks registered via ViewRef.onDestroy (#37543)
Invoking a callback registered through `ViewRef.onDestroy` throws an error, because we weren't registering it correctly in the internal data structure. These changes also remove the `storeCleanupFn` function, because it was mostly identical to `storeCleanupWithContext` and was only used in one place.

Fixes #36213.

PR Close #37543
2020-06-26 15:02:43 -07:00
64b0ae93f7 fix(core): don't consider inherited NG_ELEMENT_ID during DI (#37574)
Special DI tokens like `ChangeDetectorRef` and `ElementRef` can provide a factory via `NG_ELEMENT_ID`. The problem is that we were reading it off the token as `token[NG_ELEMENT_ID]` which will go up the prototype chain if it couldn't be found on the current token, resulting in the private `ViewRef` API being exposed, because it extends `ChangeDetectorRef`.

These changes fix the issue by guarding the property access with `hasOwnProperty`.

Fixes #36235.

PR Close #37574
2020-06-26 15:01:21 -07:00
7c0b25f5a6 fix(language-service): incorrect autocomplete results on unknown symbol (#37518)
This commit fixes a bug whereby the language service would incorrectly
return HTML elements if autocomplete is requested for an unknown symbol.
This is because we walk through every possible scenario, and fallback to
element autocomplete if none of the scenarios match.

The fix here is to return results from interpolation if we know for sure
we are in a bound text. This means we will now return an empty results if
there is no suggestions.

This commit also refactors the code a little to make it easier to
understand.

PR Close #37518
2020-06-26 14:51:33 -07:00
07b5df3a19 release: cut the v10.0.1 release 2020-06-26 13:17:36 -07:00
e7023726f4 ci: exclude "docs" commit type from minBodyLength commit message validation (#37764)
docs commits are sometimes trivial (e.g. an obvious typo fix) and in such cases its very
akward to to write up 100 chars worth of text about why this typo fix is the best thing in the
world and why it is so important and crucial that we must know why we are fixing the typo
at all. After all most typos are not just typos. Or are they? We'll shall see...

PR Close #37764
2020-06-26 11:13:10 -07:00
a9ccd9254c feat(dev-infra): add support for minBodyLengthTypeExcludes to commit-message validation (#37764)
This feature will allow us to exclude certain commits from the 100 chars minBodyLength requirement for commit
messages which is hard to satisfy for commits that make trivial changes (e.g. fixing typos in docs or comments).

PR Close #37764
2020-06-26 11:13:10 -07:00
335f3271d2 refactor(core): throw more descriptive error message in case of invalid host element (#35916)
This commit replaces an assert with more descriptive error message that is thrown in case `<ng-template>` or `<ng-container>` is used as host element for a Component.

Resolves #35240.

PR Close #35916
2020-06-26 11:10:15 -07:00
7f93f7ef47 build: move shims_for_IE to third_party directory (#37624)
The shims_for_IE.js file contains vendor code that predates the third_party
directory. This file is currently used for internal karma testing setup. This
change corrects this by moving the shims_for_IE file to //third_part/

PR Close #37624
2020-06-26 11:09:02 -07:00
cf46a87fcd refactor(compiler-cli): Remove any cast for CompilerHost (#37079)
This commit removes the FIXME for casting CompilerHost to any since
google3 is now already on TS 3.8.

PR Close #37079
2020-06-26 11:08:18 -07:00
ad6680f602 fix(language-service): reinstate getExternalFiles() (#37750)
`getExternalFiles()` is an API that could optionally be provided by a tsserver plugin
to notify the server of any additional files that should belong to a particular project.

This API was removed in https://github.com/angular/angular/pull/34260 mainly
due to performance reasons.

However, with the introduction of "solution-style" tsconfig in typescript 3.9,
the Angular extension could no longer reliably detect the owning Project solely
based on the ancestor tsconfig.json. In order to support this use case, we have
to reinstate `getExternalFiles()`.

Fixes https://github.com/angular/vscode-ng-language-service/issues/824

PR Close #37750
2020-06-26 09:57:08 -07:00
5e287f67af docs: correct outdated dev instructions for public api golds (#37026)
This change updates the dev instructions to reflect the location and generation of public API golds, which changed in #35768.

PR Close #37026
2020-06-26 09:56:33 -07:00
ecfe6e0609 docs: add note about the month being zero-based in the Date constructor (#37770)
Because the month is zero based, it may confuse some users that '3'
is in fact 'April'. This comment should clear that up.

PR Close #37770
2020-06-26 09:55:19 -07:00
df9790dd11 fix(dev-infra): support running scripts from within a detached head (#37737)
Scripts provided in the `ng-dev` command might use local `git`
commands. For such scripts, we keep track of the branch that
has been checked out before the command has been invoked.

We do this so that we can later (upon command completion)
restore back to the original branch. We do not want to
leave the Git repository in a dirty state.

It looks like this logic currently only deals with branches
but does not work properly when a command is invoked from
a detached head. We can make it work by just checking out
the previous revision (if no branch is checked out).

PR Close #37737
2020-06-26 09:51:10 -07:00
67cfc4c9bc build: add wombot proxy for publish config for @angular/benchpress (#37752)
Adds the publishConfig registry value to the package.json of the
@angular/benchpress package to publish it via wombat rather than
through npm directly.

PR Close #37752
2020-06-25 17:08:19 -07:00
a68e623c80 docs(elements): fixed command that adds the package @angular/elements (#37681)
I was using schematics with the `--name` parameter instead of the `--project`, I did both ways before sending and my suspicion about outdated documentation was confirmed

PR Close #37681
2020-06-25 17:07:30 -07:00
9e3915ba48 docs: typo fixes for schematics-for-libraries.md (#37753)
Addresses small typos such as extra whitespaces.

This change was extracted from #29505.
This change was extracted from #29505.
This change was extracted from #29505.

PR Close #37753
2020-06-25 17:06:38 -07:00
ba2de61748 fix(docs-infra): fix deploy-to-firebase.sh for master and v10.0.x branches (#37762)
The deployment to aio is currently failing because #37721 introduced
"project" entry into the firebase.json which means that we now need to
select the deployment target before deploying to firebase.

This change fixes the issue and refactors the file to be easier to read.

I also added extra echo statements so that the CI logs are easier to
read in case we need to troubleshoot future issues.

PR Close #37762
2020-06-25 17:03:25 -07:00
a9a4edebe2 fix(docs-infra): fix typo in the deploy-to-firebase.sh script (#37754)
This typo caused the script to fail on Linux (interestingly it works fine on Mac).

This is a painful reminder that we should not write any more Bash scripts EVER. shelljs FTW! :-)

PR Close #37754
2020-06-25 15:21:25 -07:00
64f2ffa166 fix(core): cleanup DOM elements when root view is removed (#37600)
Currently when bootstrapped component is being removed using `ComponentRef.destroy` or `NgModuleRef.destroy` methods, DOM nodes may be retained in the DOM tree. This commit fixes that problem by always attaching host element of the internal root view to the component's host view node, so the cleanup can happen correctly.

Resolves #36449.

PR Close #37600
2020-06-25 14:34:36 -07:00
13020b9cc2 fix(migrations): do not incorrectly add todo for @Injectable or @Pipe (#37732)
As of v10, the `undecorated-classes-with-decorated-fields` migration
generally deals with undecorated classes using Angular features. We
intended to run this migation as part of v10 again as undecorated
classes with Angular features are no longer supported in planned v11.

The migration currently behaves incorrectly in some cases where an
`@Injectable` or `@Pipe` decorated classes uses the `ngOnDestroy`
lifecycle hook. We incorrectly add a TODO for those classes. This
commit fixes that.

Additionally, this change makes the migration more robust to
not migrate a class if it inherits from a component, pipe
injectable or non-abstract directive. We previously did not
need this as the undecorated-classes-with-di migration ran
before, but this is no longer the case.

Last, this commit fixes an issue where multiple TODO's could be
added. This happens when multiple Angular CLI build targets have
an overlap in source files. Multiple programs then capture the
same source file, causing the migration to detect an undecorated
class multiple times (i.e. adding a TODO twice).

Fixes #37726.

PR Close #37732
2020-06-25 14:22:09 -07:00
96b96fba0f perf(compiler-cli): fix regressions in incremental program reuse (#37690)
Commit 4213e8d5 introduced shim reference tagging into the compiler, and
changed how the `TypeCheckProgramHost` worked under the hood during the
creation of a template type-checking program. This work enabled a more
incremental flow for template type-checking, but unintentionally introduced
several regressions in performance, caused by poor incrementality during
`ts.Program` creation.

1. The `TypeCheckProgramHost` was made to rely on the `ts.CompilerHost` to
   retrieve instances of `ts.SourceFile`s from the original program. If the
   host does not return the original instance of such files, but instead
   creates new instances, this has two negative effects: it incurs
   additional parsing time, and it interferes with TypeScript's ability to
   reuse information about such files.

2. During the incremental creation of a `ts.Program`, TypeScript compares
   the `referencedFiles` of `ts.SourceFile` instances from the old program
   with those in the new program. If these arrays differ, TypeScript cannot
   fully reuse the old program. The implementation of reference tagging
   introduced in 4213e8d5 restores the original `referencedFiles` array
   after a `ts.Program` is created, which means that future incremental
   operations involving that program will always fail this comparison,
   effectively limiting the incrementality TypeScript can achieve.

Problem 1 exacerbates problem 2: if a new `ts.SourceFile` is created by the
host after shim generation has been disabled, it will have an untagged
`referencedFiles` array even if the original file's `referencedFiles` was
not restored, triggering problem 2 when creating the template type-checking
program.

To fix these issues, `referencedFiles` arrays are now restored on the old
`ts.Program` prior to the creation of a new incremental program. This allows
TypeScript to get the most out of reusing the old program's data.

Additionally, the `TypeCheckProgramHost` now uses the original `ts.Program`
to retrieve original instances of `ts.SourceFile`s where possible,
preventing issues when a host would otherwise return fresh instances.

Together, these fixes ensure that program reuse is as incremental as
possible, and tests have been added to verify this for certain scenarios.

An optimization was further added to prevent the creation of a type-checking
`ts.Program` in the first place if no type-checking is necessary.

PR Close #37690
2020-06-25 14:13:34 -07:00
2cbe53a9ba docs: Uses correct component in the MessageService (#37666)
This commit uses the correct component (`HeroesComponent`) in the.
`MessageService`. Previously, the `MessageService` was using
`HeroeService`.

Closes #37654

PR Close #37666
2020-06-25 13:49:00 -07:00
48755114e5 feat(docs-infra): update deploy-to-firebase.sh script to support v9 multisite setup (#37721)
v9.angular.io was used to pilot the firebase hosting multisites setup for angular.io.

The deployments so far have been done manually to control the deployment process.

This change, automates the deployment for v9.angular.io so that future deployments can be made from
the CI.

See https://angular-team.atlassian.net/browse/DEV-125 for more info.

In the process of updating the scripts I rediscovered a bug in the deploy-to-firebase.sh script that
incorrect compared two numbers as strings. This previously worked correctly because we were comparing
single digit numbers. With the release of v10, we now compare 9 > 10 which behaves differently for
strings and numbers. The bug was fixed by switching to an arithmetic comparison of the two variables.

This bug has been fixed on the master branch but not on the 9.1.x branch. I realized this during the
rebase, but found my version to be a bit cleaner, so I kept it.

PR Close #37721
2020-06-25 13:44:53 -07:00
a5d5f67be7 fix(http): avoid abort a request when fetch operation is completed (#37367)
`abort` method is calling, even if fetch operation is completed

Fixes https://github.com/angular/angular/issues/36537

PR Close #37367
2020-06-25 12:09:40 -07:00
dfb58c44a2 fix(forms): correct usage of selectedOptions (#37620)
Previously, `registerOnChange` used `hasOwnProperty` to identify if the
property is supported. However, this does not work as the `selectedOptions`
property is an inherited property. This commit fixes this by verifying
the property on the prototype instead.

Closes #37433

PR Close #37620
2020-06-25 12:08:01 -07:00
69948ce919 fix(router): add null support for RouterLink directive (#32616)
Value of "undefined" passed as segment in routerLink is stringified to string "undefined".
This change introduces the same behavior for value of "null".

PR Close #32616
2020-06-25 11:58:01 -07:00
3190ccf3b2 fix(router): fix error when calling ParamMap.get function (#31599)
fix this.params.hasOwnProperty is not a function in case of creating an object using Object.create()

PR Close #31599
2020-06-25 11:57:25 -07:00
a8ea8173aa fix(router): RouterLinkActive should run CD when setting isActive (#21411)
When using the routerLinkActive directive inside a component that is using ChangeDetectionStrategy.OnPush and lazy loaded module routes the routerLinkActive directive does not update after clicking a link to a lazy loaded route that has not already been loaded.

Also the OnPush nav component does not set routerLinkActive correctly when the default route loads, the non-OnPush nav component works fine.

regression caused by #15943
closes #19934

PR Close #21411
2020-06-25 11:56:26 -07:00
e13a49d1f0 feat(dev-infra): add a way to pass assets down to a benchmark application (#37695)
* add a param called ng_assets to the component_benchmark macro to allow static assets to be provided to the base angular app, not just through the ts_devserver

PR Close #37695
2020-06-25 11:51:52 -07:00
2f0b8f675a docs: Add support schedule for v10 (#37745)
This commit adds the support schedule for v10.
v10.0.0 was released on June 24, 2020.
Active support ends six months later, on Dec 24, 2020.
Long term support ends a year after that, on Dec 24, 2021.

PR Close #37745
2020-06-25 11:49:18 -07:00
c2aed033ba ci(compiler-cli): exempt compiler-cli .bazel files from dev-infra approval (#37558)
Previously, dev-infra approval (via PullApprove) was required for all
.bazel files in the monorepo, including those in packages/compiler-cli.

The compiler-cli package is a little special in this sense:
 * it's not shipped to NPM in the APF
 * it uses lots of internal subpackages to organize and test its code

As a result:
 * changes to compiler-cli BUILD.bazel files are not user visible and
   don't have larger implications for the packages published to NPM,
   unlike changes to other BUILD.bazel files in the repo
 * the requirement for dev-infra approval for BUILD.bazel changes is
   overly burdensome, because compiler-cli build files change more
   rapidly than those of other packages.

This commit exempts the compiler-cli's build files from the requirement
for dev-infra approval. It will be sufficient for such files to be
approved by the normal compiler reviewers.

PR Close #37558
2020-06-25 11:47:51 -07:00
0f8a780b0d docs: Replace $emdash; with an actual em dash (#37723)
fix documentation in the lifecycle hooks guide where $emdash; was not being replaced by an actual em dash (-)

PR Close #37723
2020-06-25 11:41:54 -07:00
c5bc2e77c8 fix(forms): change error message (#37643)
Error message mention that ngModel and ngModelChange will be removed in Angular v7 but right not now sure when it will be removed so changed it to a future version

PR Close #37643
2020-06-25 11:37:00 -07:00
079310dc7c test(docs-infra): add end to end tests for api reference (#37612)
Api search functionality only had unit tests @gkalpak suggested we should have some e2e tests too. Added some end to end tests.

Fixes #35170

PR Close #37612
2020-06-25 11:36:03 -07:00
0d2cdf6165 docs: add v9.angular.io to the angular.io version picker (#37719)
Now that v10 is out, it's time to add the v9.angular.io link to the version picker, so here we go...

PR Close #37719
2020-06-24 19:53:25 -07:00
436dde271f docs(changelog): fix v10 announcement url (#37722)
PR Close #37722
2020-06-24 19:50:45 -07:00
96891a076f release: sort the v10.0.0 release in CHANGELOG.md 2020-06-24 15:58:06 -07:00
9ce0067bdf release: consolidate the v10.0.0 release CHANGELOG.md 2020-06-24 13:55:21 -07:00
345940bbc1 release: cut the v10.0.0 release 2020-06-24 11:46:57 -07:00
c49507b289 docs: updating guides and docs related to the v10 release (#37705)
Mostly just adding links to the migrations that were missing, adding the migrations into the navbar,
as well as correcting the @angular/bazel removal in the update guide.

I also added a commented out preamble for the release notes.

PR Close #37705
2020-06-24 09:37:35 -07:00
c730142508 Revert "docs: add lightweight token page to library section of docs (#36144)"
This reverts commit 27aa00b15f.
2020-06-24 09:29:01 -07:00
27aa00b15f docs: add lightweight token page to library section of docs (#36144)
adds new DI technique recommendation for libraries to ensure tree-shaking for unused services
includes reasons for packaging schematics with libraries, clarify schematic usage recommendation

PR Close #36144
2020-06-23 16:34:51 -07:00
36a00a255b ci(docs-infra): disable flaky tests (#37673)
I could not figure out the root cause of the flakes, so disabling the
flaky tests for now. See
https://github.com/angular/angular/pull/37637#issuecomment-647608149 for
more info.

Fixes #37629

PR Close #37673
2020-06-23 13:13:53 -07:00
0e3249c89b docs: add tslib update migration docs (#37402)
This adds documentation for the v10.0 tooling migration `update-libraries-tslib` contained within the `@schematics/angular` package.

PR Close #37402
2020-06-23 13:07:40 -07:00
920019ab70 docs: add module/target compiler option migration docs (#37429)
This adds documentation for the v10.0 tooling migration `update-module-and-target-compiler-options` contained within the `@schematics/angular` package.

PR Close #37429
2020-06-23 12:46:23 -07:00
82c8b44db7 docs: Initial commit of update guide for v10 release. (#37152)
This update includes modifications to the navigation.json file to
remove unneeded migration guides.

TODO: Redirects from v9 topics to v10; links to removed migration
guides need to point to v9.angular.io.

PR Close #37152
2020-06-23 11:56:50 -07:00
bb3a307d5a docs: add solution-style tsconfig migration docs (#37512)
This adds documentation for the v10.0 tooling migration `solution-style-tsconfig` contained within the `@schematics/angular` package.

PR Close #37512
2020-06-23 11:55:02 -07:00
dcb0ddaf5e docs: add strict-mode.md file to pullapprove (#37679)
When I created the strict-mode.md file, I didn't add it to the
pullapprove list. Now it's there.

The issue was introduced in #37486.

PR Close #37679
2020-06-23 10:05:51 -07:00
4c1edd52c5 docs: Add content for new strict mode for Angular CLI (#37486)
In v10, the Angular CLI supports a strict mode, which turns
on additional flags for the TypeScript and Angular compilers.

PR Close #37486
2020-06-22 16:29:16 -07:00
d512e27979 docs: fix invalid anchor for CLI flags in deprecation guide (#37662)
7521834296 added content for CLI
deprecations to the `angular.io` deprecations guide. It looks
like the anchor for the CLI deprecations is incorrect and
ends up showing up as code in the guide.

This commit fixes the anchor so that it doesn't show
up as code in the guide.

PR Close #37662
2020-06-22 10:57:16 -07:00
0619d82e0b docs: Refactor-i18n (#36924)
Rewrite headings to focus on tasks and separate reference info and best practices from tasks. Add missing steps or procedures, and links to important information. Make the example open in StackBlitz. See i18n Documentation Plan at https://docs.google.com/document/d/1aV2TKsIqry7JnNiHEfhmheu5rNAbNl1IRYVhYErc7Ks/edit?usp=sharing

PR Close #36924
2020-06-22 10:53:00 -07:00
a4038d5b94 Revert "fix(router): fix navigation ignoring logic to compare to the browser url (#37408)" (#37650)
This reverts commit d3a817549b.

The reason for the revert is the problem reported in g3 which requires additional investigation.

PR Close #37650
2020-06-22 10:47:47 -07:00
e3d5e1fab7 docs: fix grammatical errors in developer docs (#37633)
The CONTRIBUTOR and DEVELOPER markdown docs contained a few typos
and grammatical errors, which are fixed in this commit.

PR Close #37633
2020-06-18 16:04:59 -07:00
035036308a docs(core): correct type for opts.read (#37626)
The ContentChildren decorator has a metadata property named "read" which
can be used to read a different token from the queried elements. The
documentation incorrectly says "True to read..." when it should say
"Used to read...".

PR Close #37626
2020-06-18 16:04:10 -07:00
0d29259d9b docs: move ng-vikings 2020 to the already presented section (#37466)
This commit moves the ng-vikings 2020 event from the currently presenting
section into the already presented section.

PR Close #37466
2020-06-17 11:18:48 -07:00
26b0f3dc96 docs: add side effect package.json in app structure (#37521)
With this change we add the special `package.json` which is used to mark the application free of non-local side-effects in the application source files section

PR Close #37521
2020-06-16 11:57:40 -07:00
5c9306b0fe docs: @angular/language‑service is no longer a dev-dependencies (#37521)
`@angular/
language‑service` is no longer needed as a dev-dependencies, infact we no longer generate project with this dependency as it can conflict with the https://marketplace.visualstudio.com/items?itemName=Angular.ng-template

PR Close #37521
2020-06-16 11:57:40 -07:00
3befb0e4b9 docs: add new section for CLI deprecations (#37332)
Current documentation does not list CLI flag deprecations. This
change adds it for v10.

PR Close #37332
2020-06-16 11:57:05 -07:00
97bb88f10b docs: wrong example in routerLink (#37590)
In routerLink if a fragment is added than fragment example shows that it is added before the params '/user/bob#education?debug=true' but actually they are added after that '/user/bob?debug=true#education' changed documentation to show correct example

Fixes #18630

PR Close #37590
2020-06-16 09:45:23 -07:00
6c7467a58b perf(forms): optimize internal method _anyControls in FormGroup (#32534)
The method was previously looping through all controls, even after finding at least one that
satisfies the provided condition. This can be a bottleneck with large forms. The new version
of the method returns as soon as a single control which conforms to the condition is found.

PR Close #32534
2020-06-15 14:31:48 -07:00
c579a85c12 ci: include PR author as an approver of all PRs (#36915)
This change adds an implicit approval for any change by the
PR author.  This allows for a PR author to provide the required
owner approval for an area of the code base.

This change helps to align the review methodology with how Google's
internal system works. Where anyone is able to provide the LGTM
for a change if thats all that is needed.

PR Close #36915
2020-06-15 14:29:33 -07:00
400fdd08fd fix(dev-infra): allow for deep merging of pullapprove config aliases (#36915)
Set the yaml parser to support deep merges of yaml aliases,
to support having a default value for all rules to build upon.

PR Close #36915
2020-06-15 14:29:33 -07:00
c1fe6c9c81 release: cut the v10.0.0-rc.6 release 2020-06-15 14:01:15 -07:00
c58a0bea91 build: Update size to make tests pass again
`//integration:cli-hello-world-ivy-i18n_test` was failing because the size has decreased from expected 37640 to actual 37246.
2020-06-15 13:51:02 -07:00
88a934b93c refactor(compiler-cli): skip class decorators in tooling constructor parameters transform (#37545)
We recently added a transformer to NGC that is responsible for downleveling Angular
decorators and constructor parameter types. The primary goal was to mitigate a
TypeScript limitation/issue that surfaces in Angular projects due to the heavy
reliance on type metadata being captured for DI. Additionally this is a pre-requisite
of making `tsickle` optional in the Angular bazel toolchain.

See: 401ef71ae5 for more context on this.

Another (less important) goal was to make sure that the CLI can re-use
this transformer for its JIT mode compilation. The CLI (as outlined in
the commit mentioned above), already has a transformer for downleveling
constructor parameters. We want to avoid this duplication and exported
the transform through the tooling-private compiler entry-point.

Early experiments in using this transformer over the current one, highlighted
that in JIT, class decorators cannot be downleveled. Angular relies on those
to be invoked immediately for JIT (so that factories etc. are generated upon loading)

The transformer we exposed, always downlevels such class decorators
though, so that would break CLI's JIT mode. We can address the CLI's
needs by adding another flag to skip class decorators. This will allow
us to continue with the goal of de-duplication.

PR Close #37545
2020-06-15 12:47:57 -07:00
cde5cced69 refactor(compiler-cli): make IncrementalBuild strategy configurable (#37339)
Commit 24b2f1da2b introduced an `NgCompiler` which operates on a
`ts.Program` independently of the `NgtscProgram`. The NgCompiler got its
`IncrementalDriver` (for incremental reuse of Angular compilation results)
by looking at a monkey-patched property on the `ts.Program`.

This monkey-patching operation causes problems with the Angular indexer
(specifically, it seems to cause the indexer to retain too much of prior
programs, resulting in OOM issues). To work around this, `IncrementalDriver`
reuse is now handled by a dedicated `IncrementalBuildStrategy`. One
implementation of this interface is used by the `NgtscProgram` to perform
the old-style reuse, relying on the previous instance of `NgtscProgram`
instead of monkey-patching. Only for `NgTscPlugin` is the monkey-patching
strategy used, as the plugin sits behind an interface which only provides
access to the `ts.Program`, not a prior instance of the plugin.

PR Close #37339
2020-06-15 09:50:09 -07:00
472bedd3ea docs(service-worker): minor fixes/improvements in the SW Communication guide (#37555)
This commit includes various fixes/improvements for the
"Service worker communication" guide.

This partially addresses #37527.

PR Close #37555
2020-06-15 09:48:56 -07:00
d8a06d03bd docs(service-worker): update default value of SwRegistrationOptions#registrationStrategy (#37555)
The default value was changed from `registerWhenStable` to
`registerWhenStable:30000` in 29e8a64cf0,
but the decumentation was not updated to reflect that.

This commit updates the documentation to mention the correct default
value.

PR Close #37555
2020-06-15 09:48:56 -07:00
32020f9fb3 fix(language-service): wrong completions in conditional operator (#37505)
In `a ? b.~{cursor}`, the LS will provide the symbols in the scope of the current template, because the `path.tail` is `falseExp` whose value is `EmptyExpr`, and the span of `falseExp` is wider than the `trueExp`, so the value of `path` should be narrowed.

PR Close #37505
2020-06-15 09:41:26 -07:00
d574b14934 docs: describe how to configure CommonJS modules (#37331)
In version 10, we have a new option for the `angular.json` file,
`allowedCommonJsDependencies`, so users can opt in to support
CommonJS modules.

PR Close #37331
2020-06-15 09:40:45 -07:00
00c5d89e7d refactor: move hover into a proper @media hover (#37320)
This commit moves the contributor hover into the `@media(hover:hover)`
query. This will help to identify if the user's primary input mechanism
can hover over elements.

PR Close #37320
2020-06-15 09:39:17 -07:00
d2c8aefe64 docs: Update documentation to reflect addition of tsconfig.base.json. (#37222)
In version 10, there is a new `tsconfig.json` file, which contains
the paths to all other `tsconfig` files used in a workspace. The
previous `tsconfig.json` file still exists, but has been renamed to
`tsconfig.base.json`.

In addition to documenting this change, I have updated files that
refer to TypeScript configuration files generically to remove specific
references to `tsconfig.json.` This should help avoid confusing users.

PR Close #37222
2020-06-15 09:37:01 -07:00
ba796bbdd3 feat(bazel): expose explicit mapping from closure to devmode files (#36262)
This feature is aimed at development tooling that has to translate
production build inputs into their devmode equivalent. The current
process involves guessing the devmode filename based on string
replace patterns. This allows consuming build actions to read the
known mappings instead.

This is a change in anticipation of an update to the general
Typescript build rules to consume this data.

PR Close #36262
2020-06-15 09:35:35 -07:00
a0bb2ba7b7 docs: Change 'function' to 'method' for clarity that getHereos() is (#35998)
intended as a class method

Change 'function' to 'method' for clarity that getHereos() is
intended as a class method in Tour of Heroes part 4.

PR Close #35998
2020-06-15 09:07:52 -07:00
f9fa3b5b6c docs: update CONTRIBUTING.md with info about major docs changes (#35238)
The goal of this change is to clarify definition of major feature submissions to include writing new topics for the docs.

PR Close #35238
2020-06-15 09:05:16 -07:00
f89d438116 docs: fix typo in control_value_accessor.ts (#37057)
This commit updates the `ControlValueAccessor` class description in the `@angular/forms` package to fix a typo.

PR Close #37057
2020-06-12 15:11:11 -07:00
1abe791d46 Revert "feat(platform-server): use absolute URLs from Location for HTTP (#37071)" (#37547)
This reverts commit 9edea0bb75.

PR Close #37547
2020-06-12 15:09:58 -07:00
1502ae78b6 Revert "fix(platform-server): correctly handle absolute relative URLs (#37341)" (#37547)
This reverts commit 420d1c35f5.

PR Close #37547
2020-06-12 15:09:58 -07:00
bad6e719de feat(dev-infra): add # to outputed list of PRs for discover-new-conflicts (#37556)
Adding in a `#` prepended to each PR number in the list of conflicting PRs
found by the discover-new-conflicts script will allow for users to copy
paste the output from the script into a github comment and have the PRs
automatically link.

PR Close #37556
2020-06-12 15:08:53 -07:00
8c7129f3d2 ci: upload build results to ResultStore for CI linux bazel executions (#37560)
Bazel invocations will upload to ResultStore to allow for us to have better viewing
of execution/build logs.  This is only done on CI as the BES API requires credentials
from service accounts, rather than end user accounts.

PR Close #37560
2020-06-12 15:08:04 -07:00
dbff6f71e1 style(common): enforce format on newly included files (#36940)
Historically files to be formatted were added to a listing (via matchers)
to be included in formatting.  Instead, this change begins efforts to
instead include all files in format enforcement, relying instead on an
opt out methodology.

PR Close #36940
2020-06-12 15:06:43 -07:00
fcd934ccf6 style(dev-infra): enforce format on newly included files (#36940)
Historically files to be formatted were added to a listing (via matchers)
to be included in formatting.  Instead, this change begins efforts to
instead include all files in format enforcement, relying instead on an
opt out methodology.

PR Close #36940
2020-06-12 15:06:43 -07:00
45a8f340d9 build: increase scope of files with enforced formatting (#36940)
Historically files to be formatted were added to a listing (via matchers)
to be included in formatting.  Instead, this change begins efforts to
instead include all files in format enforcement, relying instead on an
opt out methodology.

PR Close #36940
2020-06-12 15:06:42 -07:00
5856513405 docs: add redirects for cli generated config files (#37533)
With this change we add redirects for config files generated by the Angular CLI. These links form part of a comment in the generated files, thus it is important that they valid for the many years to come.

PR Close #37533
2020-06-12 08:51:24 -07:00
01fa3ee5c3 docs: fix contributor website links with no protocol (#37528)
Two contributor website links do not have a protocol so they are treated as a relative URL and do not work as expected.

PR Close #37528
2020-06-12 08:50:52 -07:00
b8d69ffdf3 docs: document how external link icons work (#37025)
After PR #36601 which added icons to all external links. Documented how this is happening via comments in scss file. For details visit PR #36601

PR Close #37025
2020-06-12 08:50:18 -07:00
7ef60ec2a9 docs: small change in the Introduction (#35528)
The word "both" is automatically connected with the previous two bullet points and not the following two (because documents are usually read from top to bottom), which made the original sentence confusing for first time readers.

PR Close #35528
2020-06-11 19:11:57 -07:00
83f905c0e1 docs: fix result of sanitization example (#36059)
This commit fixes sanitization example
in https://angular.io/guide/template-syntax#content-security.

* Escape < and > of interpolation result.
* Fix result of property binding result.

PR Close #36059
2020-06-11 19:11:23 -07:00
72ba3a3918 docs: make correction in Tutorial toh-pt6 (#37516)
Fixes issue [29535](https://github.com/angular/angular/issues/29535) for the tutorial (toh-pt6) to remove the phrase that directed the reader to delete mock-heroes.ts when it is still needed for further tutorial steps.

PR Close #37516
2020-06-11 19:10:49 -07:00
df10597da4 fix(compiler): unable to resolve destructuring variable declarations (#37497)
Currently the partial evaluator isn't able to resolve a variable declaration that uses destructuring in the form of `const {value} = {value: 0}; const foo = value;`. These changes add some logic to allow for us to resolve the variable's value.

Fixes #36917.

PR Close #37497
2020-06-11 19:10:04 -07:00
5db2e794a9 fix(router): fix navigation ignoring logic to compare to the browser url (#37408)
This PR changes the logic for determining when to skip route processing from
using the URL of the last attempted navigation to the actual resulting URL after
that transition.

Because guards may prevent navigation and reset the browser URL, the raw
URL of the previous transition may not match the actual URL of the
browser at the end of the navigation process. For that reason, we need to use
`urlAfterRedirects` instead.

Other notes:
These checks in scheduleNavigation were added in eb2ceff4ba
The test still passes and, more surprisingly, passes if the checks are removed
completely. There have likely been changes to the navigation handling that
handle the test in a different way. That said, it still appears to be important
to keep the checks there in some capacity because it does affect how many
navigation events occur. This addresses an issue that came up in #16710: https://github.com/angular/angular/issues/16710#issuecomment-634869739
This also partially addresses #13586 in fixing history for imperative
navigations that are cancelled by guards.

PR Close #37408
2020-06-11 19:03:41 -07:00
486aa06747 docs: add tslib change to v10 CHANGELOG (#37303)
Previously the tslib 2.0 change was not listed in the CHANGELOG because
it was marked as a refactoring. This change is important enough to be
listed in the changelog even tough it doesn't affect most of the users.

For users that do get unexpectedly affected by this change, it might be
useful to find the change listed in the CHANGELOG.

PR Close #37303
2020-06-11 19:01:26 -07:00
01ce1b32df refactor(compiler): remove extra imports (#37246)
There are some extra imports in the compiler package. These imports are not used anywhere in the file. So, removed those extra imports

PR Close #37246
2020-06-11 19:00:34 -07:00
c78b0b2c51 docs: update api ref doc for platform browser (#37186)
Edit descriptions, usage examples, and add links to be complete and consistent with API reference doc style

PR Close #37186
2020-06-11 18:59:12 -07:00
9ade1c3ea3 fix(ngcc): correctly get config for packages in nested node_modules/ (#37040)
Previously, ngcc would only be able to match an ngcc configuration to
packages that were located inside the project's top-level
`node_modules/`. However, if there are multiple versions of a package in
a project (e.g. as a transitive dependency of other packages), multiple
copies of a package (at different versions) may exist in nested
`node_modules/` directories. For example, one at
`<project-root>/node_modules/some-package/` and one at
`<project-root>/node_modules/other-package/node_modules/some-package/`.
In such cases, ngcc was only able to detect the config for the first
copy but not for the second.

This commit fixes this by returning a new instance of
`ProcessedNgccPackageConfig` for each different package path (even if
they refer to the same package name). In these
`ProcessedNgccPackageConfig`, the `entryPoints` paths have been
processed to take the package path into account.

PR Close #37040
2020-06-11 18:58:38 -07:00
315a4cfcd4 refactor(ngcc): add packageName property to EntryPoint interface (#37040)
This commit adds a `packageName` property to the `EntryPoint` interface.
In a subsequent commit this will be used to retrieve the correct ngcc
configuration for each package, regardless of its path.

PR Close #37040
2020-06-11 18:58:38 -07:00
11c04027ab fix(ngcc): correctly retrieve a package's version from its package.json (#37040)
In order to retrieve the ngcc configuration (if any) for an entry-point,
ngcc has to detect the containing package's version.

Previously, ngcc would try to read the version from the entry-point's
`package.json` file, which was different than the package's top-level
`package.json` for secondary entry-points. For example, it would try to
read it from `node_modules/@angular/common/http/package.json` for
entry-point `@angular/common/http`. However, the `package.json` files
for secondary entry-points are not guaranteed to include a `version`
property.

This commit fixes this by first trying to read the version from the
_package's_ `package.json` (falling back to the entry-point's
`package.json`). For example, it will first try to read it from
`@angular/common/package.json` for entry-point `@angular/common/http`.

PR Close #37040
2020-06-11 18:58:38 -07:00
eabe3b4c39 refactor(ngcc): refactor how info is retrieved from entry-point package.json (#37040)
This commit refactors the way info is retrieved from entry-point
`package.json` files to make it easier to extract more info (such as the
package's name) in the future. It also avoids reading and parsing the
`package.json` file multiple times (as was happening before).

PR Close #37040
2020-06-11 18:58:37 -07:00
d471454675 refactor(ngcc): rename EntryPoint#package to EntryPoint#packagePath (#37040)
Rename the `package` property to `packagePath` on the `EntryPoint`
interface. This makes it more clear that the `packagePath` property
holds the absolute path to the containing package (similar to how `path`
holds the path to the entry-point). This will also align with the
`packageName` property that will be added in a subsequent commit.

This commit also re-orders the `EntryPoint` properties to group related
properties together and to match the order of properties on instances
with that on the interface.

PR Close #37040
2020-06-11 18:58:37 -07:00
bf57776b59 fix(ngcc): correctly get config for sub-entry-points when primary entry-point is ignored (#37040)
Previously, when an entry-point was ignored via an ngcc config, ngcc
would scan sub-directories for sub-entry-points, but would not use the
correct `packagePath`. For example, if `@angular/common` was ignored, it
would look at `@angular/common/http` but incorrectly use
`.../@angular/common/http` as the `packagePath` (instead of
`.../@angular/common`). As a result, it would not retrieve the correct
ngcc config for the actual package.

This commit fixes it by ensuring the correct `packagePath` is used, even
if the primary entry-point corresponding to that path is ignored. In
order to do this, a new return value for `getEntryPointInfo()` is added:
`IGNORED_ENTRY_POINT`. This is used to differentiate between directories
that correspond to no or an incompatible entry-point and those that
correspond to an entry-point that could otherwise be valid but is
explicitly ignored. Consumers of `getEntryPointInfo()` can then use this
info to discard ignored entry-points, but still use the correct
`packagePath` when scanning their sub-directories for secondary
entry-points.

PR Close #37040
2020-06-11 18:58:37 -07:00
a32579ae5b refactor(ngcc): clean up unused imports, unused regex parenthesis, typos (#37040)
This is a follow-up to #37075, because I didn't manage to finish my
review before the PR got merged.

PR Close #37040
2020-06-11 18:58:37 -07:00
780601d27a refactor(ngcc): fix typos in comments (#37040)
This is a follow-up to #36944, because I didn't manage to finish my
review before the PR got merged.

PR Close #37040
2020-06-11 18:58:37 -07:00
c909e731d7 fix(zone.js): remove unused Promise overwritten setter logic (#36851)
In the early Zone.js versions (< 0.10.3), `ZoneAwarePromise` did not support `Symbol.species`,
so when user used a 3rd party `Promise` such as `es6-promise`, and try to load the promise library after import of `zone.js`, the loading promise library will overwrite the patched `Promise` from `zone.js` and will break `Promise` semantics with respect to `zone.js`.

Starting with `zone.js` 0.10.3, `Symbol.species` is supported therefore this will not longer be an issue. (https://github.com//pull/34533)

Before 0.10.3, the logic in zone.js tried to handle the case in the wrong way. It did so by overriding the descriptor of `global.Promise`, to allow the 3rd party libraries to override native `Promise` instead of `ZoneAwarePromise`. This is not the correct solution, and since the `Promise.species` is now supported, the 3rd party solution of overriding `global.Promise` is no longer needed.

PR removes the wrong work around logic. (This will improve the bundle size.)

PR Close #36851
2020-06-11 18:56:19 -07:00
9b8eb42354 fix(core): should fake a top event task when coalescing events to prevent draining microTaskQueue too early. (#36841)
Close #36839.

This is a known issue of zone.js,

```
(window as any)[(Zone as any).__symbol__('setTimeout')](() => {
  let log = '';
  button.addEventListener('click', () => {
    Zone.current.scheduleMicroTask('test', () => log += 'microtask;');
    log += 'click;';
  });
  button.click();
  expect(log).toEqual('click;microtask;');
  done();
});
```

Since in this case, we use native `setTimeout` which is not a ZoneTask,
so zone.js consider the button click handler as the top Task then drain the
microTaskQueue after the click at once, which is not correct(too early).

This case was an edge case and not reported by the users, until we have the
new option ngZoneEventCoalescing, since the event coalescing will happen
in native requestAnimationFrame, so it will not be a ZoneTask, and zone.js will
consider any Task happen in the change detection stage as the top task, and if
there are any microTasks(such as Promise.then) happen in the process, it may be
drained earlier than it should be, so to prevent this situation, we need to schedule
a fake event task and run the change detection check in this fake event task,
so the Task happen in the change detection stage will not be
considered as top ZoneTask.

PR Close #36841
2020-06-11 18:54:22 -07:00
0757174e8e docs: Refactor-pipes (#36820)
Language tightened, and headings rewritten to focus on user tasks. Tasks now separated from concepts, and clarified as examples. Content is up-to-date and complete. Links to important information and relevant topics added.

PR Close #36820
2020-06-11 18:45:15 -07:00
3a43cdefe8 release: cut the v10.0.0-rc.5 release 2020-06-11 15:49:34 -07:00
38c48beddd refactor(elements): add accessor workaround for build-optimizer (#37456)
Build-optimizer currently uses TypeScript 3.6 which is unable to resolve an 'accessor' in 'getTypeOfVariableOrParameterOrPropertyWorker'.

Unfortunately, in Build optimizer we cannot update the version of TypeScript because of https://github.com/microsoft/TypeScript/issues/38412

PR Close #37456
2020-06-11 12:05:35 -07:00
ad5749fb04 build: add @babel/preset-env to dependencies (#37456)
`@babel/preset-env` is needed by for NGCC tests: 3569fdf451/packages/compiler-cli/ngcc/test/BUILD.bazel (L84)

However this is not as a depedency in the angular repo.

PR Close #37456
2020-06-11 12:05:35 -07:00
f6a838e9ee build: update CLI packages to the latest RC version for v10 (#37456)
With this change we update the Angular CLI repo and aio packages to the latest RC version for version 10.

PR Close #37456
2020-06-11 12:05:34 -07:00
a6d1f4aaf1 build: update to typescript 3.9.5 (#37456)
This TypeScript version contains the revert for the classes wrapped in IIFE change that was introduced in version 3.9.

PR Close #37456
2020-06-11 12:05:34 -07:00
eca8d11ee2 fix(ngcc): use annotateForClosureCompiler option (#36652)
Adds @nocollapse to static properties added by ngcc
iff annotateForClosureCompiler is true.

The Closure Compiler will collapse static properties
into the global namespace.  Adding this annotation keeps
the properties attached to their respective object, which
allows them to be referenced via a class's constructor.
The annotation is already added by ngtsc and ngc under the
same option, this commit extends the functionality to ngcc.

Closes #36618.

PR Close #36652
2020-06-11 11:12:56 -07:00
a195b7dbe4 docs: add example links to 'DoCheck' lifeycle hook docs (#36574)
There were some examples for 'DoCheck' in the lifeCycle hooks guide. Added a link to the relevant section of the guide in the 'DoCheck()' api docs.

Fixes #35596

PR Close #36574
2020-06-11 11:09:58 -07:00
083d7ec902 docs: Minor grammar fix: "bug-free" (#36515)
Change documentation to a more grammatically correct format. "bug-free" is preferred over "bug free".

PR Close #36515
2020-06-11 11:07:54 -07:00
9d2d0cae6d docs: remove out of date GDEs (#36467)
Periodic documentation cleanup of GDEs which are no longer in the Angular program.

Removed:
 - "Filip Bruun Bech-Larsen"
 - "Vinci Rufus"
 - "Jeff Cross"

PR Close #36467
2020-06-11 11:04:11 -07:00
c2f4a9bf71 build: remove ngcontainer Docker (#36421)
ngcontainer Dockerfile was noted as deprecated ~2 years ago, we no longer
rely on it anymore nor do we publish it.

PR Close #36421
2020-06-10 12:59:07 -07:00
231095fe8a build: add commit message scope for migration changes (#36390)
This is a proposal commit that adds a separate scope for
migration changes. The motiviation is that migrations aren't
necessarily always affecting `@angular/core`, but are just
stored in the core package for a canonical location when
someone runs `ng update`. Additionally, it rather seems confusing in the
changelog if migration changes are listed under `core`.

PR Close #36390
2020-06-10 12:03:45 -07:00
28a532483a docs: add Mike Huang as a GDE (#36472)
Update the GDE listing with info abbout Mike Huang.
Update the GDE listing with info abbout Mike Huang.

PR Close #36472
2020-06-10 11:53:25 -07:00
83853a215d docs: remove redundant web-worker nav (#37289)
Web- worker was 2 times in the nav pointing towards the same file, just with different names removed one to remove redundancy

PR Close #37289
2020-06-10 11:52:06 -07:00
8248307a99 fix(ngcc): do not scan import expressions in d.ts files (#37503)
It is quite common for the TS compiler to have to add synthetic
types to function signatures, where the developer has not
explicitly provided them.  This results in `import(...)` expressions
appearing in typings files.  For example in `@ngrx/data` there is a
class with a getter that has an implicit type:

```ts
export declare class EntityCollectionServiceBase<...> {
  ...
  get store() {
    return this.dispatcher.store;
  }
  ...
}
```

In the d.ts file for this we get:

```ts
get store(): Store<import("@ngrx/data").EntityCache>;
```

Given that this file is within the `@ngrx/data` package already,
this caused ngcc to believe that there was a circular dependency,
causing it to fail to process the package - and in fact crash!

This commit resolves this problem by ignoring `import()` expressions
when scanning typings programs for dependencies. This ability was
only introduced very recently in a 10.0.0 RC release, and so it has
limited benefit given that up till now ngcc has been able to process
libraries effectively without it. Moreover, in the rare case that a
package does have such a dependency, it should get picked up
by the sync ngcc+CLI integration point.

PR Close #37503
2020-06-10 11:51:19 -07:00
67bd88b19a feat(language-service): Remove HTML entities autocompletion (#37515)
This commit removes the autocompletion feature for HTML entities.
HTML entites are things like `&amp;`, `&lt;` etc.

There are a few reasons for the decision:

1. It is outside the core functionality of Angular LS
2. The implementation relies on regex, which incurs performance cost
3. There isn't much value if users do not already know which entity
   they want to use
4. The list that we provide is not exhaustive

PR Close #37515
2020-06-10 11:50:55 -07:00
9f698b4de0 release: cut the v10.0.0-rc.4 release 2020-06-10 11:31:29 -07:00
742f3d6787 Revert "fix(elements): fire custom element output events during component initialization (#36161)" (#37524)
This reverts commit e9bff5fe9f. Failures
were detected in Google tests due to this commit

PR Close #37524
2020-06-10 17:28:57 +00:00
323651bd38 fix(compiler-cli): downlevel angular decorators to static properties (#37382)
In v7 of Angular we removed `tsickle` from the default `ngc` pipeline.
This had the negative potential of breaking ES2015 output and SSR due
to a limitation in TypeScript.

TypeScript by default preserves type information for decorated constructor
parameters when `emitDecoratorMetadata` is enabled. For example,
consider this snippet below:

```
@Directive()
export class MyDirective {
  constructor(button: MyButton) {}
}

export class MyButton {}
```

TypeScript would generate metadata for the `MyDirective` class it has
a decorator applied. This metadata would be needed in JIT mode, or
for libraries that provide `MyDirective` through NPM. The metadata would
look as followed:

```
let MyDirective = class MyDir {}

MyDirective = __decorate([
  Directive(),
  __metadata("design:paramtypes", [MyButton]),
], MyDirective);

let MyButton = class MyButton {}
```

Notice that TypeScript generated calls to `__decorate` and
`__metadata`. These calls are needed so that the Angular compiler
is able to determine whether `MyDirective` is actually an directive,
and what types are needed for dependency injection.

The limitation surfaces in this concrete example because `MyButton`
is declared after the `__metadata(..)` call, while `__metadata`
actually directly references `MyButton`. This is illegal though because
`MyButton` has not been declared at this point. This is due to the
so-called temporal dead zone in JavaScript. Errors like followed will
be reported at runtime when such file/code evaluates:

```
Uncaught ReferenceError: Cannot access 'MyButton' before initialization
```

As noted, this is a TypeScript limitation because ideally TypeScript
shouldn't evaluate `__metadata`/reference `MyButton` immediately.
Instead, it should defer the reference until `MyButton` is actually
declared. This limitation will not be fixed by the TypeScript team
though because it's a limitation as per current design and they will
only revisit this once the tc39 decorator proposal is finalized
(currently stage-2 at time of writing).

Given this wontfix on the TypeScript side, and our heavy reliance on
this metadata in libraries (and for JIT mode), we intend to fix this
from within the Angular compiler by downleveling decorators to static
properties that don't need to evaluate directly. For example:

```
MyDirective.ctorParameters = () => [MyButton];
```

With this snippet above, `MyButton` is not referenced directly. Only
lazily when the Angular runtime needs it. This mitigates the temporal
dead zone issue caused by a limitation in TypeScript's decorator
metadata output. See: https://github.com/microsoft/TypeScript/issues/27519.

In the past (as noted; before version 7), the Angular compiler by
default used tsickle that already performed this transformation. We
moved the transformation to the CLI for JIT and `ng-packager`, but now
we realize that we can move this all to a single place in the compiler
so that standalone ngc consumers can benefit too, and that we can
disable tsickle in our Bazel `ngc-wrapped` pipeline (that currently
still relies on tsickle to perform this decorator processing).

This transformation also has another positive side-effect of making
Angular application/library code more compatible with server-side
rendering. In principle, TypeScript would also preserve type information
for decorated class members (similar to how it did that for constructor
parameters) at runtime. This becomes an issue when your application
relies on native DOM globals for decorated class member types. e.g.

```
@Input() panelElement: HTMLElement;
```

Your application code would then reference `HTMLElement` directly
whenever the source file is loaded in NodeJS for SSR. `HTMLElement`
does not exist on the server though, so that will become an invalid
reference. One could work around this by providing global mocks for
these DOM symbols, but that doesn't match up with other places where
dependency injection is used for mocking DOM/browser specific symbols.

More context in this issue: #30586. The TL;DR here is that the Angular
compiler does not care about types for these class members, so it won't
ever reference `HTMLElement` at runtime.

Fixes #30106. Fixes #30586. Fixes #30141.
Resolves FW-2196. Resolves FW-2199.

PR Close #37382
2020-06-10 09:24:12 -07:00
9d397eb5a1 Revert "build: remove wombot proxy registry from package.jsons for release (#37378)" (#37495)
This reverts commit 26849ca99d.

PR Close #37495
2020-06-10 08:21:46 -07:00
6114cd2bd4 perf(core): avoid pulling in jit-specific code in aot bundles (#37372) (#37514)
In #29083 a call to `getCompilerFacade` was added to `ApplicationRef` which pulls in a bit of JIT-specific code. Since the code path that calls the function can't be hit for an AOT-compiled app, these changes add an `ngJitMode` guard which will allow for dead code elimination to drop it completely. Testing it out against a new CLI project showed a difference of ~1.2kb.

PR Close #37372

PR Close #37514
2020-06-09 14:49:05 -07:00
d494f7bd5e docs(dev-infra): add comment about what the requiredBaseCommit is (#37509)
Add a comment to describe what the commit was for the given SHA so that we don't have to look it up.

PR Close #37509
2020-06-09 13:29:24 -07:00
ec6a7ab721 docs: wrong links in lifecycle hooks api documentaion (#36557)
lifecycle hooks api detailed documentation contained links which were pointing to onChanges hook only which is removed, made each hook point towards its deafult page link

PR Close #36557
2020-06-09 11:16:43 -07:00
ad6d2b4619 docs(core): fix path referenced in comments of both compiler facade interface files (#37370)
Previously the comments for these files referenced a path to "packages/core/src/render3/jit/compiler_facade_interface.ts" that does not exist in the current codebase.

This PR corrects the path in these comments.

PR Close #37370
2020-06-09 08:28:26 -07:00
c093390010 fix(dev-infra): local changes check not working (#37489)
Looks like we broke the `hasLocalChanges` check in the git client
when we moved it over from the merge script. The problem is that
we are using `git` in the first argument of `git.run`. That
means that we under-the-hood run `git git <..>`.

This commit fixes that, but also switches to a better variant
for ensuring no local changes because it exits with non-zero
when there are local changes.

PR Close #37489
2020-06-09 08:27:32 -07:00
acd69f2be2 fix(dev-infra): rebase pr script not working (#37489)
The dev-infra rebase PR script currently does not work due to
the following issues:

1. The push refspec is incorrect. It refers to the `base` of the PR, and
not to the `head` of the PR.
2. The push `--force-with-lease` option does not work in a detached head
as no remote-tracking branch is set up.

PR Close #37489
2020-06-09 08:27:32 -07:00
5d2f341653 fix(dev-infra): incorrect token sanitization when no token is specified (#37489)
We recently moved over the git client from the merge script to the
common dev-infra utils. This made specifying a token optional, but
it looks like the logic for sanitizing messages doesn't account
for that, and we currently add `<TOKEN>` between every message
character. e.g.

```
Executing: git <TOKEN>g<TOKEN>i<TOKEN>t<TOKEN>
<TOKEN>s<TOKEN>t<TOKEN>a<TOKEN>t<TOKEN>u<TOKEN>s<TOKEN>
```

PR Close #37489
2020-06-09 08:27:32 -07:00
420d1c35f5 fix(platform-server): correctly handle absolute relative URLs (#37341)
Previously, we would simply prepend any relative URL with the HREF
for the current route (pulled from document.location). However,
this does not correctly account for the leading slash URLs that
would otherwise be parsed correctly in the browser, or the
presence of a base HREF in the DOM.

Therefore, we use the built-in URL implementation for NodeJS,
which implements the WHATWG standard that's used in the browser.
We also pull the base HREF from the DOM, falling back on the full
HREF as the browser would, to form the correct request URL.

Fixes #37314

PR Close #37341
2020-06-09 08:27:00 -07:00
08647267bb fix(common): prevent duplicate URL change notifications (#37459)
Prevent duplicate notifications from being emitted when multiple URL change listeners are registered using SpyLocation#onUrlChange.

Use `@internal` annotation for the `_urlChangeSubscription` properties instead of the `private` access modifier. Otherwise, we get in trouble because of  `SpyLocation implements Location`.

PR Close #37459
2020-06-09 08:26:34 -07:00
215d50d2f6 test(common): prefer TestBed.inject over inject (#37459)
Use the strongly typed TestBed.inject rather than the weakly typed inject test utility function. Reuse injected dependency variables between sibling test cases.

PR Close #37459
2020-06-09 08:26:34 -07:00
bf2cb6fa48 feat(language-service): TS references from template items (#37437)
Keen and I were talking about what it would take to support getting
references at a position in the current language service, since it's
unclear when more investment in the Ivy LS will be available. Getting TS
references from a template is trivial -- we simply need to get the
definition of a symbol, which is already handled by the language
service, and ask the TS language service to give us the references for
that definition.

This doesn't handle references in templates, but that could be done in a
subsequent pass.

Part of https://github.com/angular/vscode-ng-language-service/issues/29

PR Close #37437
2020-06-08 17:23:49 -07:00
e97a2d4123 fix(language-service): Improve signature selection by finding exact match (#37494)
The function signature selection algorithm is totally naive. It'd
unconditionally pick the first signature if there are multiple
overloads. This commit improves the algorithm by returning an exact
match if one exists.

PR Close #37494
2020-06-08 17:23:12 -07:00
585e3f6adc fix(router): Fix relative link generation from empty path components (#37446)
Partial resubmit of #26243
Fixes incorrect url tree generation for empty path components with children.
Adds a test to demonstrate the failure of createUrlTree for those routes.
Fixes #13011
Fixes #35687

PR Close #37446
2020-06-08 17:15:38 -07:00
7f77ce1a48 release: cut the v10.0.0-rc.3 release 2020-06-08 17:03:59 -07:00
a1616ce181 docs: add note on publishing libraries in ivy (#36556)
Libraries are still build using view engine even after Ivy being the default engine for building angular apps. Added note on why libraries are built using VE and how they will be automatically compiled in Ivy using ngcc making it compatible for both

Fixes #35625

PR Close #36556
2020-06-08 15:05:52 -07:00
1c22dff714 docs(docs-infra): fix small typo (#37258)
The style guide docs had a typo "Alerts and Calllouts". Callouts is
spelled with two l's, not three. This PR fixes the typo.

PR Close #37258
2020-06-08 14:42:50 -07:00
8d1d6e8f70 docs: place download section in toh to the top (#36567)
this is part of a larger effort to standardise download sections on angular.io

This commit partially addresses #35459

PR Close #36567
2020-06-08 11:41:52 -07:00
e7f4aba5a3 docs(service-worker): add staleWhileRevalidate strategy (#37301)
There is great workaround for implementing staleWhileRevalidate strategy in service-worker by setting strategy to freshness and timeout to 0u. Documented this in service worker config where all other strategies are documented

Fixes #20402

PR Close #37301
2020-06-08 11:41:20 -07:00
fdbe9f5d9f refactor(core): assert TNode is not a container when setting attribute on element (#37111)
This PR provides a more helpful error than the one currently present:
`el.setAttribute is not a function`. It is not valid to have directives with host bindings
on `ng-template` or `ng-container` nodes. VE would silently ignore this, while Ivy
attempts to set the attribute and throws an error because these are comment nodes
and do not have `setAttribute` functionality.

It is better to throw a helpful error than to silently ignore this because
putting a directive with host binding on an `ng-template` or `ng-container` is most often a mistake.
Developers should be made aware that the host binding will have no effect in these cases.

Note that an error is already thrown in Ivy, as mentioned above, so this
is not a breaking change and can be merged to both master and patch.

Resolves #35994

PR Close #37111
2020-06-08 11:21:05 -07:00
8bead6bfdd test(language-service): Remove all markers from test project (#37475)
This commit removes all markers from the inline template in
`AppComponent` and external template in `TemplateReference`.

Test scenarios should be colocated with the test cases themselves.
Besides, many existing cases are invalid. For example, if we want to
test autocomplete for HTML element, the existing test case is like:
```
<~{cursor} h1>
```
This doesn't make much sense, becasue the language service already sees
the `h1` tag in the template. The correct test case should be:
```
<~{cursor
```
IMO, this reflects the real-world use case better.

This commit also uncovers a bug in the way HTML entities autocompletion
is done. There's an off-by-one error in which a cursor that immediately
trails the ampersand character fails to trigger HTML entities
autocompletion.

PR Close #37475
2020-06-08 10:25:43 -07:00
52dda73dbb ci: remove IgorMinar from reviewers list for pullapprove fallback group (#36456)
Historically we have had a pullapprove group `fallback` which acted as
a catch all for files which did not match any other groups.  This
group assigned reviews to IgorMinar, however it was not apparent that
this group was assigned.  This change removes this assignment.  This
group as active should always coincide with failures of the pullapprove
verification script. We continue to have this group as a secondary test
ensuring all files in the repo are captured by the pullapprove config.

PR Close #36456
2020-06-08 10:07:45 -07:00
31b3888a2f style(ngcc): post-merge review tidy up (#37461)
This commit tidies up a few of the code comments from a recent commit to
help improve the clarity of the algorithm.

PR Close #37461
2020-06-08 09:32:11 -07:00
6f938470c2 fix(service-worker): Don't stay locked in EXISTING_CLIENTS_ONLY if corrupted data (#37453)
**Problem**

After #31109 and #31865, it's still possible to get locked in state
`EXISTING_CLIENTS_ONLY`, without any possibility to get out (even by
pushing new updates on the server).
More specifically, if control doc `/latest` of `ngsw:/:db:control` once
gets a bad value, then the service worker will fail early, and won't be
able to overwrite `/latest` with new, valid values (the ones from future
updates).

For example, once in this state, URL `/ngsw/state` will show:

    NGSW Debug Info:
    Driver state: EXISTING_CLIENTS_ONLY (Degraded due to failed initialization: Invariant violated (initialize): latest hash 8b75… has no known manifest
    Error: Invariant violated (initialize): latest hash 8b75… has no known manifest
        at Driver.<anonymous> (https://my.app/ngsw-worker.js:2302:27)
        at Generator.next (<anonymous>)
        at fulfilled (https://my.app/ngsw-worker.js:175:62))
    Latest manifest hash: 8b75…
    Last update check: 22s971u

... with hash `8b75…` corresponding to no installed version.

**Solution**

Currently, when such a case happens, the service worker [simply fails
with an assertion][1]. Because this failure happens early, and is not
handled, the service worker is not able to update `/latest` to new
installed app versions.

I propose to detect this corrupted case (a `latest` hash that doesn't
match any installed version) a few lines above, so that the service
worker can correctly call its [already existing cleaning code][2].

[1]: https://github.com/angular/angular/blob/3569fdf/packages/service-worker/worker/src/driver.ts#L559-L563
[2]: https://github.com/angular/angular/blob/3569fdf/packages/service-worker/worker/src/driver.ts#L505-L519

This change successfully fixes the problem described above.

Unit test written with the help of George Kalpakas. Thank you!

PR Close #37453
2020-06-08 09:31:35 -07:00
776c4afc03 fix(dev-infra): await setup in runBenchmark (#37428)
* Fix for issue #36986.
* Changes runBenchmark into an async function.
* Awaits config.setup in runBenchmark.

PR Close #37428
2020-06-08 09:17:35 -07:00
536dd647c6 build: update to latest stable Chromium 83.0.4103 in both rules_webtesting and puppeteer (#37427)
Also added in detailed instructions of the process to determine the URLs corresponding to Chromium version desired

PR Close #37427
2020-06-08 09:16:40 -07:00
51d581ab27 build: upgrade to bazel 3.2.0 and rules_nodejs 1.7.0 (#37358)
Upgrade to rely on bazel version 3.2.0 and rules_nodejs 1.7.0.  This
is part of a routine update as new versions become available.

PR Close #37358
2020-06-08 09:15:50 -07:00
75294e7dad ci: special case tooling-cli-shared-api review group (#37467)
The new tooling-cli-shared-api is used to guard changes to packages/compiler-cli/src/tooling.ts
which is a private API sharing channel between Angular FW and CLI.

Changes to this file should be rare and explicitly approved by at least two members
of the CLI team.

PR Close #37467
2020-06-05 19:23:53 -07:00
04bada7a9d ci: extend and update the reviewer groups (#37467)
Update the pullapprove config to require multiple reviews for sensitive groups in order
to force distribution of knowledge and improve the review quality.

PR Close #37467
2020-06-05 19:23:53 -07:00
2349143477 fix(dev-infra): properly determine oauth scopes for git client token (#37462)
Resubmit of b2bd38699b since
85b6c94cc6 accidentally reverted
the fix due to rebasing most likely.

PR Close #37462
2020-06-05 11:04:37 -07:00
e9bff5fe9f fix(elements): fire custom element output events during component initialization (#36161)
Previously, event listeners for component output events attached on an
Angular custom element before inserting it into the DOM (i.e. before
instantiating the underlying component) didn't fire for events emitted
during initialization lifecycle hooks, such as `ngAfterContentInit`,
`ngAfterViewInit`, `ngOnChanges` (initial call) and `ngOnInit`.
The reason was that that `NgElementImpl` [subscribed to events][1]
_after_ calling [ngElementStrategy#connect()][2], which is where the
[initial change detection][3] takes place (running the initialization
lifecycle hooks).

This commit fixes this by:
1. Ensuring `ComponentNgElementStrategy#events` is defined and available
   for subscribing to, even before instantiating the component.
2. Ensuring `NgElementImpl` subscribes to `NgElementStrategy#events`
   before calling `NgElementStrategy#connect()` (which initializes the
   component instance).

Jira issue: [FW-2010](https://angular-team.atlassian.net/browse/FW-2010)

[1]: c0143cb2ab/packages/elements/src/create-custom-element.ts (L167-L170)
[2]: c0143cb2ab/packages/elements/src/create-custom-element.ts (L164)
[3]: c0143cb2ab/packages/elements/src/component-factory-strategy.ts (L158)

Fixes #36141

PR Close #36161
2020-06-05 10:36:39 -07:00
411cb0cb92 refactor(elements): remove unnecessary non-null assertions and as any type-casts (#36161)
This commit removes some unnecessary non-null assertions (`!`) and
`as any` type-casts from the `elements` package.

PR Close #36161
2020-06-05 10:36:39 -07:00
53e1fb3554 refactor(dev-infra): move GitClient to common util (#37318)
Moves GitClient from merge script into common utils for unified
method of performing git actions throughout the ng-dev toolset.

PR Close #37318
2020-06-05 09:46:40 -07:00
2cb3b66640 fix(ngcc): find decorated constructor params on IIFE wrapped classes (#37436)
Now in TS 3.9, classes in ES2015 can be wrapped in an IIFE.
This commit ensures that we still find the static properties that contain
decorator information, even if they are attached to the adjacent node
of the class, rather than the implementation or declaration.

Fixes #37330

PR Close #37436
2020-06-05 09:22:04 -07:00
5af3144330 refactor(dev-infra): use the exec() helper from utils/shelljs whenever possible (#37444)
There is an `exec()` helper provided by `utils/shelljs.ts`, which is a
wrapper around ShellJS' `exec()` with some default options (currently
`silent: true`). The intention is to avoid having to pass these options
to every invocation of the `exec()` function.

This commit updates all code inside `dev-infra/` to use this helper
whenever possible).

NOTE: For simplicity, the `utils/shelljs` helper does not support some
      of the less common call signatures of the original `exec()`
      helper, so in some cases we still need to use the original.

PR Close #37444
2020-06-05 09:21:18 -07:00
e4043cbb3a docs: fix minor error in the "Structural directives" guide (#37452)
The sample code used in this guide uses [class.od]="odd".
But, in another portion of the guide, [ngClass]="odd" is mentioned instead.

PR Close #37452
2020-06-05 09:20:43 -07:00
fff424a35f fix(common): prevent duplicate URL change notifications (#37404)
Prevent duplicate notifications from being emitted when multiple URL change listeners are registered using Location#onUrlChange.

PR Close #37404
2020-06-04 16:45:06 -07:00
b5d1c8b05a docs: fix various typos (#37443)
This change just fixes various typos and misspellings across several docs.

I've included also a fix for an issue surfaced via #37423.

Closes #37423

PR Close #37443
2020-06-04 16:03:55 -07:00
d713e33cc4 style(dev-infra): correct tslint failures in dev-infra directory (#37233)
Fixes tslint failures in dev-infra directory as the directory is now
part of the tslint enforced files.

PR Close #37233
2020-06-04 12:44:46 -07:00
3d327d25f0 build: add dev-infra to tslint selected files (#37233)
Adds the dev-infra files to the scope of files on which tslint is
enforced.  This will allow for better code management/conformance.

PR Close #37233
2020-06-04 12:44:46 -07:00
077283bf0f fix(dev-infra): clean up usages within pullapprove tooling (#37338)
Clean up pullapprove tooling to use newly created common utils.
Additionally, use newly created logging levels rather than
verbose flagging.

PR Close #37338
2020-06-04 12:43:45 -07:00
9ec25ea036 refactor(dev-infra): change required base commit sha (#37424)
Update the commit sha to require that PRs have been rebased beyond the one which has new header requirements so we don't get failures after merging

PR Close #37424
2020-06-04 10:44:14 -07:00
878cfe669c fix(dev-infra): properly determine oauth scopes for git client token (#37439)
We recently added a better reporting mechanism for oauth tokens
in the dev-infra git util. Unfortunately the logic broke as part
of addressing PR review feedback. Right now, always the empty
promise from `oauthScopes` will be used as `getAuthScopes` considers
it as the already-requested API value. This is not the case as
the default promise is also truthy. We should just fix this by making
the property nullable.

PR Close #37439
2020-06-04 10:42:53 -07:00
5f0be3cb2e feat(dev-infra): Add oauth scope check to ensure necessary permissions for merge tooling (#37421)
Adds an assertion that the provided TOKEN has OAuth scope permissions for `repo`
as this is required for all merge attempts.

On failure, provides detailed error message with remediation steps for the user.

PR Close #37421
2020-06-04 09:35:59 -07:00
9e28e14c08 fix(dev-infra): ensure ts-node is registered with commonjs as module (#37422)
We recently added support for automatic registration of `ts-node`
when the dev-infra configuration is loaded.

In addition to registering ts-node, we should also ensure that the
`commonjs` module is set up. By default, `ts-node` would use ES module
imports that are not supported by default in NodeJS.

PR Close #37422
2020-06-04 09:34:33 -07:00
954d002884 feat(dev-infra): migrate release tool to use new logging system (#37422)
Migrate the release tool in ng-dev to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37422
2020-06-04 09:34:32 -07:00
0a48591e53 feat(dev-infra): migrate ts-circular-dependencies tool to use new logging system (#37422)
Migrate the ts-circular-dependencies tool in ng-dev to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37422
2020-06-04 09:34:32 -07:00
d37c723951 feat(dev-infra): migrate merge tool to use new logging system (#37422)
Migrate the merge tool in ng-dev to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37422
2020-06-04 09:34:32 -07:00
9078ca557e feat(dev-infra): migrate ng-dev utils to use new logging system (#37422)
Migrate the ng-dev utils to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37422
2020-06-04 09:34:32 -07:00
2be1ef6ba0 feat(dev-infra): migrate pullapprove tool to use new logging system (#37422)
Migrate the pullapprove tool in ng-dev to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37422
2020-06-04 09:34:32 -07:00
47c02efccb feat(dev-infra): migrate rebase tool to use new logging system (#37422)
Migrate the rebase tool in ng-dev to use new logging system rather
than directly calling console.*  to create a better experience
for users.

PR Close #37422
2020-06-04 09:34:32 -07:00
d7ecfb432a feat(dev-infra): migrate discover-new-conflicts tool to use new logging system (#37422)
Migrate the discover-new-conflicts tool in ng-dev to use new logging system
rather than directly calling console.* to create a better experience
for users.

PR Close #37422
2020-06-04 09:34:32 -07:00
59abf4a33f feat(dev-infra): migrate commit-message tool to use new logging system (#37422)
Migrate the commit-message tool in ng-dev to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37422
2020-06-04 09:34:32 -07:00
d6e715e726 feat(dev-infra): migrate format tool to use new logging system (#37422)
Migrate the formatting tool in ng-dev to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37422
2020-06-04 09:34:32 -07:00
fcfcd1037c feat(dev-infra): add group functions to logging system and remove color param (#37422)
Adds .group and .groupEnd functions to each of the logging functions
to allow creating groups in the logged output.  Additionally removes
the color parameter from logging functions, in favor of the color
being applied to the string at the call site.

PR Close #37422
2020-06-04 09:34:31 -07:00
f3ccd29e7b feat(ngcc): implement a program-based entry-point finder (#37075)
This finder is designed to only process entry-points that are reachable
by the program defined by a tsconfig.json file.

It is triggered by calling `mainNgcc()` with the `findEntryPointsFromTsConfigProgram`
option set to true. It is ignored if a `targetEntryPointPath` has been
provided as well.

It is triggered from the command line by adding the `--use-program-dependencies`
option, which is also ignored if the `--target` option has been provided.

Using this option can speed up processing in cases where there is a large
number of dependencies installed but only a small proportion of the
entry-points are actually imported into the application.

PR Close #37075
2020-06-04 09:22:40 -07:00
5c0bdae809 fix(ngcc): capture dynamic import expressions as well as declarations (#37075)
Previously we only checked for static import declaration statements.
This commit also finds import paths from dynamic import expressions.

Also this commit should speed up processing: Previously we were parsing
the source code contents into a `ts.SourceFile` and then walking the parsed
AST to find import paths.
Generating an AST is unnecessary work and it is faster and creates less
memory pressure to just scan the source code contents with the TypeScript
scanner, identifying import paths from the tokens.

PR Close #37075
2020-06-04 09:22:40 -07:00
838902556b refactor(ngcc): move shared code into DependencyHostBase (#37075)
The various dependency hosts had a lot of duplicated code.
This commit refactors them to move this into the base class.

PR Close #37075
2020-06-04 09:22:40 -07:00
c6872c02d8 fix(ngcc): ensure that more dependencies are found by EsmDependencyHost (#37075)
Previously this host was skipping files if they had imports that spanned
multiple lines, or if the import was a dynamic import expression.

PR Close #37075
2020-06-04 09:22:40 -07:00
819982ea20 docs: add blank line before header (#37391)
Currently, `Formatting your source code` is not being formatted as a header because of a missing empty line.
PR Close #37391
2020-06-04 09:20:26 -07:00
f9daa136c3 perf(ngcc): cache parsed tsconfig between runs (#37417)
This commit will store a cached copy of the parsed tsconfig
that can be reused if the tsconfig path is the same.

This will improve the ngcc "noop" case, where there is no processing
to do, when the entry-points have already been processed.
Previously we were parsing this config every time we checked for
entry-points to process, which can take up to seconds in some
cases.

Resolves #36882

PR Close #37417
2020-06-04 09:19:38 -07:00
6a0d2ed6c8 ci(docs-infra): skip deploying RC version when lexicographically smaller than stable (#37426)
The angular.io production deployment script (`deploy-to-firebase.sh`)
compares the major version corresponding to the current branch (e.g.
`8` for branch `8.1.x`) against the major stable version (e.g. `9` if
the current stable version is `9.1.0`). It then uses the result of that
comparison to determine whether the current branch corresponds to a
newer version than stable (i.e. an RC version) and thus should not be
deployed or to an older version and thus may need to be deployed to an
archive vX.angular.io project.

Previously, the script was using string comparison (`<`) to compare the
two major versions. This could produce incorrect results for an RC major
version that is numerically greater than the stable but
lexicographically smaller. For example, 10 vs 9 (10 is numerically
greater but lexicographically smaller than 9).
Example of a CI job that incorrectly tried to deploy an RC branch to
production: https://circleci.com/gh/angular/angular/726414

This commit fixes it by switching to an integer comparison (i.e. using
the `-lt` operator).

PR Close #37426
2020-06-04 09:17:29 -07:00
2c1f35e794 fix(language-service): Recover from error in analyzing Ng Modules (#37108)
In place of failing to return analyzed Ng Modules when the analyzer
fails, return the previously-analyzed Ng Modules (which may be empty)
and log an error.

Closes https://github.com/angular/vscode-ng-language-service/issues/777

PR Close #37108
2020-06-03 15:56:19 -07:00
5345e8da45 docs: update the stackblitz in the GitHub Issue template (#37219)
This commit updates the bug report stackblitz template for opening a new
issue based on the current angular release.

Closes #37063

PR Close #37219
2020-06-03 15:55:44 -07:00
e35269dd87 docs: update file header to be correct (#37425)
The file header should be Google LLC rather than Google Inc. because it is now an LLC after Alphabet Holdings was formed.

PR Close #37425
2020-06-03 15:31:29 -07:00
60a03b7ef7 refactor(compiler-cli): extract NgCompilerAdapter interface (#37118)
`NgCompiler` is the heart of ngtsc and can be used to analyze and compile
Angular programs in a variety of environments. Most of these integrations
rely on `NgProgram` and the creation of an `NgCompilerHost` in order to
create a `ts.Program` with the right shape for `NgCompiler`.

However, certain environments (such as the Angular Language Service) have
their own mechanisms for creating `ts.Program`s that don't make use of a
`ts.CompilerHost`. In such environments, an `NgCompilerHost` does not make
sense.

This commit breaks the dependency of `NgCompiler` on `NgCompilerHost` and
extracts the specific interface of the host on which `NgCompiler` depends
into a new interface, `NgCompilerAdapter`. This interface includes methods
from `ts.CompilerHost`, the `ExtendedTsCompilerHost`, as well as APIs from
`NgCompilerHost`.

A consumer such as the language service can implement this API without
needing to jump through hoops to create an `NgCompilerHost` implementation
that somehow wraps its specific environment.

PR Close #37118
2020-06-03 13:29:45 -07:00
305b5a3887 fix(compiler-cli): use ModuleWithProviders type if static eval fails (#37126)
When the compiler encounters a function call within an NgModule imports
section, it attempts to resolve it to an NgModule-annotated class by
looking at the function body and evaluating the statements there. This
evaluation can only understand simple functions which have a single
return statement as their body. If the function the user writes is more
complex than that, the compiler won't be able to understand it and
previously the PartialEvaluator would return a "DynamicValue" for
that import.

With this change, in the event the function body resolution fails the
PartialEvaluator will now attempt to use its foreign function resolvers to
determine the correct result from the function's type signtaure instead. If
the function is annotated with a correct ModuleWithProviders type, the
compiler will be able to understand the import without static analysis of
the function body.

PR Close #37126
2020-06-03 13:23:16 -07:00
bc549361d3 fix(core): infinite loop if injectable using inheritance has a custom decorator (#37022)
If we detect that an injectable class is inheriting from another injectable, we generate code that looks something like this:

```
const baseFactory = ɵɵgetInheritedFactory(Child);

@Injectable()
class Parent {}

@Injectable()
class Child extends Parent {
  static ɵfac = (t) => baseFactory(t || Child)
}
```

This usually works fine, because the `ɵɵgetInheritedFactory` resolves to the factory of `Parent`, but the logic can break down if the `Child` class has a custom decorator. Custom decorators can return a new class that extends the original once, which means that the `ɵɵgetInheritedFactory` call will now resolve to the factory of the `Child`, causing an infinite loop.

These changes fix the issue by changing the inherited factory resolution logic so that it walks up the prototype chain class-by-class, while skipping classes that have the same factory as the class that was passed in.

Fixes #35733.

PR Close #37022
2020-06-03 13:16:26 -07:00
084b627f2e refactor(dev-infra): small changes and fixes (#36800)
Rename bazel workspace from npm_dev_infra to npm_angular_dev_infra_private to make it clear that this package is private to angular.
Change driver-utilities module_name to match the new bazel workspace name.
Correct a comment by rewording it from "deployed version" to "published version".
Fix merge conflicts in tmpl-package.json
Make "//packages/bazel/src:esm5.bzl" replacement more generalized so that importing from "//packages/bazel" works.
Deleted "dev_infra/*" path from modules/benchmarks tsconfig.
Moved //dev-infra/benchmark/browsers to //dev-infra/browsers.

PR Close #36800
2020-06-03 13:12:31 -07:00
6755d00601 revert: "revert: "build(core): use dev-infra's component_benchmark to show PoC (#36434)" (#36798)" (#36800)
This reverts commit 90a2796a7e.

PR Close #36800
2020-06-03 13:12:31 -07:00
cba1da3e44 revert: "revert: "build(dev-infra): update package.json and :npm_package (#36434)" (#36798)" (#36800)
This reverts commit f5ff2068a4.

PR Close #36800
2020-06-03 13:12:31 -07:00
7be8bb1489 revert: "revert: "feat(dev-infra): exposed new rule 'component_benchmark' via dev_infra (#36434)" (#36798)" (#36800)
This reverts commit ad8c4cdd75.

PR Close #36800
2020-06-03 13:12:31 -07:00
c7c0c1f626 refactor(forms): use a type guard to get rid of casts (#32541)
Use an explicit type guard when checking if a given object is of type AbstractControlOptions,
instead of a simple function returning a boolean value. This allows us to remove manual type
casting when using this function, relying instead on TypeScript to infer correct types.

PR Close #32541
2020-06-03 12:29:26 -07:00
3aa4629f92 docs: refactor template-driven forms doc as a tutorial (#36732)
rework content to meet current documentation standards and conventions, structure as tutorial document type

PR Close #36732
2020-06-03 12:27:28 -07:00
2d86dbb090 docs: update aio in support for #BlackLivesMatter (#37409)
Update angular.io in support for #BlackLivesMatter. The PR updates the
styles of the landing page and changes the current survey notification.

PR Close #37409
2020-06-03 11:20:57 -07:00
91767ff0f9 ci: temporarily disable Android 10 browser unit tests on Saucelabs (#37399)
Disabling Android 10 browser unit tests on Saucelabs due to errors.

After remediation from Saucelabs to correct the discovered failures, this change can be reverted to renable the tests on Android 10.

Example of failures seen:

```
02 06 2020 14:03:05.048:INFO [SaucelabsLauncher]: Chrome 10.0 (Android) session at https://saucelabs.com/tests/54f5fb181db644a3b4779187c2309000

02 06 2020 14:03:06.869:INFO [Chrome Mobile 74.0.3729 (Android 0.0.0)]: Disconnected browser returned on socket E-bi0p0NKtghk-HcAAAO with id 85563367.

Chrome Mobile 74.0.3729 (Android 0.0.0) ERROR: Error: XHR error loading http://angular-ci.local:9876/base/node_modules/rxjs/internal/operators/zip.js

	Error loading http://angular-ci.local:9876/base/node_modules/rxjs/internal/operators/zip.js as "../internal/operators/zip" from http://angular-ci.local:9876/base/node_modules/rxjs/operators/index.js

Error: XHR error loading http://angular-ci.local:9876/base/node_modules/rxjs/internal/operators/zip.js

    at error (http://angular-ci.local:9876/base/node_modules/systemjs/dist/system.src.js?1c6a6c12fec50a8db7aeebe8e06e2b70135c0615:1028:16)

    at XMLHttpRequest.xhr.onreadystatechange [as __zone_symbol__ON_PROPERTYreadystatechange] (http://angular-ci.local:9876/base/node_modules/systemjs/dist/system.src.js?1c6a6c12fec50a8db7aeebe8e06e2b70135c0615:1036:13)

    at XMLHttpRequest.wrapFn (http://angular-ci.local:9876/base/dist/bin/packages/zone.js/npm_package/dist/zone.js?942d01da94828e1c75e8527fa8d06f363d6379ce:809:43)

    at ZoneDelegate.invokeTask (http://angular-ci.local:9876/base/dist/bin/packages/zone.js/npm_package/dist/zone.js?942d01da94828e1c75e8527fa8d06f363d6379ce:432:35)

    at Zone.runTask (http://angular-ci.local:9876/base/dist/bin/packages/zone.js/npm_package/dist/zone.js?942d01da94828e1c75e8527fa8d06f363d6379ce:201:55)

    at ZoneTask.invokeTask [as invoke] (http://angular-ci.local:9876/base/dist/bin/packages/zone.js/npm_package/dist/zone.js?942d01da94828e1c75e8527fa8d06f363d6379ce:514:38)

    at invokeTask (http://angular-ci.local:9876/base/dist/bin/packages/zone.js/npm_package/dist/zone.js?942d01da94828e1c75e8527fa8d06f363d6379ce:1722:18)

    at XMLHttpRequest.globalZoneAwareCallback (http://angular-ci.local:9876/base/dist/bin/packages/zone.js/npm_package/dist/zone.js?942d01da94828e1c75e8527fa8d06f363d6379ce:1748:21)
```

PR Close #37399
2020-06-02 17:32:34 -04:00
078b004ecc docs(core): remove v10 mention from @Injectable warning (#37383)
In v9, we started showing a console warning when
instantiating a token that inherited its @Injectable
decorator rather than providing its own. This warning
said that the pattern would become an error in v10.

However, we have decided to wait until at least v11
to throw in this case, so this commit updates the
warning to be less prescriptive about the exact
version when the pattern will no longer be supported.

PR Close #37383
2020-06-02 17:30:58 -04:00
930d204d83 perf(ngcc): allow immediately reporting a stale lock file (#37250)
Currently, if an ngcc process is killed in a manner that it doesn't clean
up its lock file (or is killed too quickly) the compiler reports that it
is waiting on the PID of a process that doesn't exist, and that it will
wait up to a maximum of N seconds. This PR updates the locking code to
additionally check if the process exists, and if it does not it will
immediately bail out, and print the location of the lock file so a user
may clean it up.

PR Close #37250
2020-06-02 17:30:03 -04:00
8d82cdfc77 docs: refactor forms overview (#36919)
Reorganize and edit content of existing form overview to conform to current doc standards and styles

PR Close #36919
2020-06-02 17:29:15 -04:00
cb6996b5c3 build: fix integration payload sizes 2020-06-02 12:06:52 -07:00
a4f7740332 docs(router): fix a typo in example code (#37309)
The code in the example docs used TestBed.configureTestModule instead of TestBed.configureTestingModule.

PR Close #37309
2020-06-01 17:19:46 -04:00
ba0faa2f77 refactor(core): remove looseIdentical in favor of built-in Object.is (#37191)
Remove `looseIdentical` implementation and instead use the ES2015 `Object.is` in its place.
They behave exactly the same way except for `+0`/`-0`.
`looseIdentical(+0, -0)` => `true`
`Object.is(+0, -0)` => `false`

Other than the difference noted above, this is not be a breaking change because:
1. `looseIdentical` is a private API
2. ES2015 is listed as a mandatory polyfill in the [browser support
guide](https://angular.io/guide/browser-support#mandatory-polyfills)
3. Also note that `Ivy` already uses `Object.is` in `bindingUpdated`.

PR Close #37191
2020-06-01 17:19:17 -04:00
3e68029522 test(language-service): disable ivy ls tests on CI (#37348)
This commit disables the tests for Ivy version of language service on CI
because the compiler APIs are not yet stable, so language service should
not assert against its behavipr.

PR Close #37348
2020-06-01 17:18:51 -04:00
b4e26b5828 fix(ngcc): do not inline source-maps for non-inline typings source-maps (#37363)
Inline source-maps in typings files can impact IDE performance
so ngcc should only add such maps if the original typings file
contains inline source-maps.

Fixes #37324

PR Close #37363
2020-06-01 17:18:31 -04:00
15cf7fcac2 docs(core): fix typo in decorators.ts relating to the use of Object.defineProperty. (#37369)
Previously there was a typo in a comment within the PropDecorator function relating to and justifying the use of Object.defineProperty. This PR clears up the wording that comment

PR Close #37369
2020-06-01 17:18:08 -04:00
24ff0eb13b docs: fix typo in deprecations (#37379)
This PR fixes a typo in the deprecations guide, changing 'dropped support for of Windows 10...' to 'dropped support for Windows 10...'

PR Close #37379
2020-06-01 17:17:44 -04:00
cf86f72eb7 release: cut the v10.0.0-rc.2 release 2020-06-01 10:51:58 -07:00
61486f14f1 build: remove wombot proxy registry from package.jsons for release (#37378)
Due to an outage with the proxy we rely on for publishing, we need
to temporarily directly publish to NPM using our own angular
credentials again.

PR Close #37378
2020-06-01 12:41:19 -04:00
d16a7f3ecc fix(core): reenable decorator downleveling for Angular npm packages (#37317)
In #37221 we disabled tsickle passes from transforming the tsc output that is used to publish all
Angular framework and components packages (@angular/*).

This change however revealed a bug in the ngc that caused __decorate and __metadata calls to still
be emitted in the JS code even though we don't depend on them.

Additionally it was these calls that caused code in @angular/material packages to fail at runtime
due to circular dependency in the emitted decorator code documeted as
https://github.com/microsoft/TypeScript/issues/27519.

This change partially rolls back #37221 by reenabling the decorator to static fields (static
properties) downleveling.

This is just a temporary workaround while we are also fixing root cause in `ngc` - tracked as
FW-2199.

Resolves FW-2198.
Related to FW-2196

PR Close #37317
2020-05-29 18:52:01 -04:00
82761ec50e docs: Mention Bazel builder and schematics in Deprecations section (#37190)
This commit adds Bazel builder and schematics to the global list of
deprecations in Angular. A link to the migration doc is added.

PR Close #37190
2020-05-28 21:35:41 -04:00
235bfa77a9 docs(bazel): Mention Architect prototype and Slack Channel (#37190)
This commit adds a link to the Bazel prototype for orchestrating
multiple CLI architects and also adds a link to the #angular channel in
the Bazel Slack workspace.

PR Close #37190
2020-05-28 21:35:41 -04:00
299ae1bb1c docs: Cleanup Bazel schematics deprecation doc (#37190)
This commit improves some wording in the deprecation doc for Bazel
builder and schematics in `@angular/bazel` and fixes the formatting.

PR Close #37190
2020-05-28 21:35:41 -04:00
80f7522dab refactor(bazel): Remove schematics and builder from package.json (#37190)
This commit removes the fields for ng-add, schematics and builder from
package.json of `@angular/bazel`.

PR Close #37190
2020-05-28 21:35:41 -04:00
028921e369 docs: Add guide/bazel to Service Worker navigationUrls (#37190)
This commit adds an exception for "guide/bazel" to the navigationUrls in
the Service Worker config. This is needed for redirection to work.

PR Close #37190
2020-05-28 21:35:41 -04:00
a4e11bb524 docs: Redirect /guide/bazel to deprecation doc in Angular repo (#37190)
This commit adds a 301 redirect for /guide/bazel on angular.io to the
deprecation doc for Angular Bazel schematics in Angular repo.

PR Close #37190
2020-05-28 21:35:41 -04:00
a4131752d2 test: remove Bazel schematics integration test (#37190)
This commit removes the integration test for schematics in
`@angular/bazel` that is used to generate a Bazel builder. The Bazel
builder has been deprecated.

PR Close #37190
2020-05-28 21:35:40 -04:00
060dcfbba1 ci: Remove aio/content/guide/bazel.md from pullapprove (#37190)
This commit removes aio/content/guide/bazel.md from the Bazel list in
pullapprove since Bazel builder has been deprecated and the doc has been
deleted.

PR Close #37190
2020-05-28 21:35:40 -04:00
4be7008f80 docs: Remove 'Building with Bazel' section (#37190)
This commit removes "Building with Bazel" section from angular.io
navigation list and Angular CLI landing page.

PR Close #37190
2020-05-28 21:35:40 -04:00
4a0d05515e refactor(bazel): Remove Schematics for Bazel Builder (#37190)
This commit removes `ng-add` and `ng-new` schematics for the Bazel
Builder, and update the corresponding BUILD files.

PR Close #37190
2020-05-28 21:35:40 -04:00
83ab99c746 docs: Remove Bazel builder from @angular/bazel (#37190)
This commit adds a deprecation doc for Bazel builder in
`@angular/bazel` and removes the corresponding guide in angular.io.

PR Close #37190
2020-05-28 21:35:40 -04:00
270da1f69f build(docs-infra): upgrade cli command docs sources to 14af4e07c (#37310)
Updating [angular#10.0.x](https://github.com/angular/angular/tree/10.0.x) from [cli-builds#10.0.x](https://github.com/angular/cli-builds/tree/10.0.x).

##
Relevant changes in [commit range](200a21f8a...14af4e07c):

**Modified**
- help/generate.json

PR Close #37310
2020-05-28 18:43:44 -04:00
6b0e46e36c docs: fix typo in committer.md (#37171)
Fix a type of COMMITTER.md, the url of the pullapprove service should be https://docs.pullapprove.com/,
now the document has an additional `https` prefix.

PR Close #37171
2020-05-28 18:43:05 -04:00
3642707145 build: use static patch value for targetting branches in merge config (#37299)
Due to the desired patch branch (10.0.x) being on a semver version
that is unreleased as stable (there is no 10.0.0 on latest, it is on
next) our logic for determining target patch branches does not work.

This change is a workaround to unblock merging in the repo while a
longer term answer is discovered.

PR Close #37299
2020-05-28 15:18:20 -07:00
0ea76edfd8 build: migrate ng-dev config to .ng-dev directory (#37299)
Migrate to using .ng-dev directory for ng-dev configuration to allow
better management of the configuration using multiple files.  The
intention is to prevent the config file from becoming unruly.

PR Close #37299
2020-05-28 15:18:20 -07:00
d493a83b2b docs(platform-server): fix renderModule usage guidance with Ivy (#37296)
Before the introduction of the Ivy renderer, users would compile
their applications and use the resulting factories for SSR, since
these post-compilation artifacts ensured faster delivery. Thus,
using the original module as the rendering entrypoint was
considered suboptimal and was discouraged.

However, with the introduction of Ivy, this guidance is no longer
applicable since these factories are no longer generated.
Comparable speed is achieved using the factory-less module
renderer, and so we update the guiance in the docs for the method.

PR Close #37296
2020-05-28 16:07:32 -04:00
f1721d5cef build: update requiredBaseCommit for patch branch merges (#37316)
Updates the requiredBaseCommit for merging to patch branch to the
latest commit message validation fix found in the 10.0.x branch.

Previously, the patch branch commit used was for the 9.1.x branch.

PR Close #37316
2020-05-28 16:06:08 -04:00
5b3fd6aa82 docs: add IE mobile to deprecated browsers (#37313)
Mobile versions of IE should also be deprecated, as the same reasons for deprecating IE 9 and 10 apply.

PR Close #37313
2020-05-27 17:23:18 -04:00
6f829180f7 build: update license headers to reference Google LLC (#37205)
Update the license headers throughout the repository to reference Google LLC
rather than Google Inc, for the required license headers.

PR Close #37205
2020-05-26 14:27:01 -04:00
27b95ba64a build: Update file-header lint rule to Google LLC (#37205)
Update the file-header lint rule to properly reference Google LLC
rather than Google Inc, for the required headers.

PR Close #37205
2020-05-26 14:27:01 -04:00
ef405b1e90 build: deprecate old merge script (#37247)
Deprecate the old merge script as it no longer correctly chooses
the patch branch due to relying on numerical sorting order from
git.  Git actually provides a lexicographical sorting order.  This
that 9.0.x will be chosen rather than 10.0.x as it is sorted based
the 9 vs 1, rather than 9 vs 10.

PR Close #37247
2020-05-26 14:25:44 -04:00
441073bad5 feat(dev-infra): expose script for determining merge branches (#37217)
The components repo and framework repository follow the same patch
branch concept. We should be able to share a script for determining
these merge branches.

Additonally the logic has been improved compared to the old merge script because
we no longer consult `git ls-remote` unless really needed. Currently,
`git ls-remote` is always consulted, even though not necessarily needed.

This can slow down the merge script and the caretaker process when a
couple of PRs are merged (personally saw around ~4 seconds per merge).

Additionally, the new logic is more strict and will ensure (in most
cases) that no wrong patch/minor branch is determined. Previously,
the script just used the lexicographically greatest patch branch.
This _could_ be wrong when a new patch branch has been created too
early, or by accident.

PR Close #37217
2020-05-21 10:38:19 -07:00
758 changed files with 8231 additions and 24350 deletions

View File

@ -743,8 +743,8 @@ jobs:
- run: yarn --cwd packages/zone.js promisetest
- run: yarn --cwd packages/zone.js promisefinallytest
- run: yarn bazel build //packages/zone.js:npm_package &&
cp dist/bin/packages/zone.js/npm_package/bundles/zone-mix.umd.js ./packages/zone.js/test/extra/ &&
cp dist/bin/packages/zone.js/npm_package/bundles/zone-patch-electron.umd.js ./packages/zone.js/test/extra/ &&
cp dist/bin/packages/zone.js/npm_package/dist/zone-mix.js ./packages/zone.js/test/extra/ &&
cp dist/bin/packages/zone.js/npm_package/dist/zone-patch-electron.js ./packages/zone.js/test/extra/ &&
yarn --cwd packages/zone.js electrontest
- run: yarn --cwd packages/zone.js jesttest

View File

@ -73,14 +73,15 @@ merge:
- "packages/zone.js/scripts/**"
# comment that will be added to a PR when there is a conflict, leave empty or set to false to disable
mergeConflictComment: "Hi @{{PRAuthor}}! This PR has merge conflicts due to recent upstream merges.\nPlease help to unblock it by resolving these conflicts. Thanks!"
mergeConflictComment: "Hi @{{PRAuthor}}! This PR has merge conflicts due to recent upstream merges.
\nPlease help to unblock it by resolving these conflicts. Thanks!"
# label to monitor
mergeLabel: "action: merge"
mergeLabel: "PR action: merge"
# adding any of these labels will also add the merge label
mergeLinkedLabels:
- "action: merge-assistance"
- "PR action: merge-assistance"
# list of checks that will determine if the merge label can be added
checks:
@ -93,17 +94,17 @@ merge:
# whether the PR shouldn't have a conflict with the base branch
noConflict: true
# list of labels that a PR needs to have, checked with a regexp (e.g. "target:" will work for the label "target: master")
# list of labels that a PR needs to have, checked with a regexp (e.g. "PR target:" will work for the label "PR target: master")
requiredLabels:
- "target: *"
- "PR target: *"
- "cla: yes"
# list of labels that a PR shouldn't have, checked after the required labels with a regexp
forbiddenLabels:
- "target: TBD"
- "action: cleanup"
- "action: review"
- "state: blocked"
- "PR target: TBD"
- "PR action: cleanup"
- "PR action: review"
- "PR state: blocked"
- "cla: no"
# list of PR statuses that need to be successful
@ -120,7 +121,12 @@ merge:
# the comment that will be added when the merge label is added despite failing checks, leave empty or set to false to disable
# {{MERGE_LABEL}} will be replaced by the value of the mergeLabel option
# {{PLACEHOLDER}} will be replaced by the list of failing checks
mergeRemovedComment: "I see that you just added the `{{MERGE_LABEL}}` label, but the following checks are still failing:\n{{PLACEHOLDER}}\n\n**If you want your PR to be merged, it has to pass all the CI checks.**\n\nIf you can't get the PR to a green state due to flakes or broken master, please try rebasing to master and/or restarting the CI job. If that fails and you believe that the issue is not due to your change, please contact the caretaker and ask for help."
mergeRemovedComment: "I see that you just added the `{{MERGE_LABEL}}` label, but the following checks are still failing:
\n{{PLACEHOLDER}}
\n
\n**If you want your PR to be merged, it has to pass all the CI checks.**
\n
\nIf you can't get the PR to a green state due to flakes or broken master, please try rebasing to master and/or restarting the CI job. If that fails and you believe that the issue is not due to your change, please contact the caretaker and ask for help."
# options for the triage plugin
triage:
@ -180,4 +186,4 @@ rerunCircleCI:
# set to true to disable
disabled: false
# the label which when added triggers a rerun of the default CircleCI workflow
triggerRerunLabel: "action: rerun CI at HEAD"
triggerRerunLabel: "PR action: rerun CI at HEAD"

View File

@ -1,19 +0,0 @@
import {CaretakerConfig} from '../dev-infra/caretaker/config';
/** The configuration for `ng-dev caretaker` commands. */
export const caretaker: CaretakerConfig = {
githubQueries: [
{
name: 'Merge Queue',
query: `is:pr is:open status:success label:"action: merge"`,
},
{
name: 'Merge Assistance Queue',
query: `is:pr is:open status:success label:"action: merge-assistance"`,
},
{
name: 'Primary Triage Queue',
query: `is:open is:issue no:milestone`,
}
]
};

View File

@ -1,4 +1,3 @@
import {caretaker} from './caretaker';
import {commitMessage} from './commit-message';
import {format} from './format';
import {github} from './github';
@ -9,5 +8,4 @@ module.exports = {
format,
github,
merge,
caretaker,
};

View File

@ -1,25 +1,38 @@
import {DevInfraMergeConfig} from '../dev-infra/pr/merge/config';
import {getDefaultTargetLabelConfiguration} from '../dev-infra/pr/merge/defaults';
import {github} from './github';
import {MergeConfig} from '../dev-infra/pr/merge/config';
/**
* Configuration for the merge tool in `ng-dev`. This sets up the labels which
* are respected by the merge script (e.g. the target labels).
*/
export const merge: DevInfraMergeConfig['merge'] = async api => {
export const merge = (): MergeConfig => {
// TODO: resume dynamically determining patch branch
const patch = '10.0.x';
return {
githubApiMerge: false,
claSignedLabel: 'cla: yes',
mergeReadyLabel: /^action: merge(-assistance)?/,
caretakerNoteLabel: 'action: merge-assistance',
mergeReadyLabel: /^PR action: merge(-assistance)?/,
caretakerNoteLabel: 'PR action: merge-assistance',
commitMessageFixupLabel: 'commit message fixup',
labels: await getDefaultTargetLabelConfiguration(api, github, '@angular/core'),
labels: [
{
pattern: 'PR target: master-only',
branches: ['master'],
},
{
pattern: 'PR target: patch-only',
branches: [patch],
},
{
pattern: 'PR target: master & patch',
branches: ['master', patch],
},
],
requiredBaseCommits: {
// PRs that target either `master` or the patch branch, need to be rebased
// on top of the latest commit message validation fix.
// These SHAs are the commits that update the required license text in the header.
'master': '5aeb9a4124922d8ac08eb73b8f322905a32b0b3a',
'10.0.x': '27b95ba64a5d99757f4042073fd1860e20e3ed24',
[patch]: '27b95ba64a5d99757f4042073fd1860e20e3ed24'
},
};
};

View File

@ -115,42 +115,6 @@ pullapprove_conditions:
groups:
# =========================================================
# Global Approvers
#
# All reviews performed for global approvals require using
# the `Reviewed-for:` specifier to set the approval
# specificity as documented at:
# https://docs.pullapprove.com/reviewed-for/
# =========================================================
global-approvers:
type: optional
reviewers:
teams:
- framework-global-approvers
reviews:
request: 0
required: 1
reviewed_for: required
# =========================================================
# Global Approvers For Docs
#
# All reviews performed for global docs approvals require
# using the `Reviewed-for:` specifier to set the approval
# specificity as documented at:
# https://docs.pullapprove.com/reviewed-for/
# =========================================================
global-docs-approvers:
type: optional
reviewers:
teams:
- framework-global-approvers-for-docs-only-changes
reviews:
request: 0
required: 1
reviewed_for: required
# =========================================================
# Require review on all PRs
#
@ -159,9 +123,6 @@ groups:
# one review is provided before the group is satisfied.
# =========================================================
required-minimum-review:
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
reviews:
request: 0 # Do not request any reviews from the reviewer group
required: 1 # Require that all PRs have approval from at least one of the users in the group
@ -196,12 +157,48 @@ groups:
- manughub # Manu Murthy
- mgechev # Minko Gechev
- mhevery # Miško Hevery
- michaelprentice # Michael Prentice
- mmalerba # Miles Malerba
- petebacondarwin # Pete Bacon Darwin
- pkozlowski-opensource # Pawel Kozlowski
- Splaktar # Michael Prentice
- StephenFluin # Stephen Fluin
# =========================================================
# Global Approvers
#
# All reviews performed for global approvals require using
# the `Reviewed-for:` specifier to set the approval
# specificity as documented at:
# https://docs.pullapprove.com/reviewed-for/
# =========================================================
global-approvers:
type: optional
reviewers:
teams:
- framework-global-approvers
reviews:
request: 0
required: 1
reviewed_for: required
# =========================================================
# Global Approvers For Docs
#
# All reviews performed for global docs approvals require
# using the `Reviewed-for:` specifier to set the approval
# specificity as documented at:
# https://docs.pullapprove.com/reviewed-for/
# =========================================================
global-docs-approvers:
type: optional
reviewers:
teams:
- framework-global-approvers-for-docs-only-changes
reviews:
request: 0
required: 1
reviewed_for: required
# =========================================================
# Framework: Animations
# =========================================================
@ -335,7 +332,6 @@ groups:
'aio/content/images/guide/dependency-injection-in-action/**',
'aio/content/guide/dependency-injection-navtree.md',
'aio/content/guide/dependency-injection-providers.md',
'aio/content/guide/lightweight-injection-tokens.md',
'aio/content/guide/displaying-data.md',
'aio/content/examples/displaying-data/**',
'aio/content/images/guide/displaying-data/**',
@ -787,21 +783,6 @@ groups:
- JiaLiPassion
- mhevery
# =========================================================
# in-memory-web-api
# =========================================================
in-memory-web-api:
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
- >
contains_any_globs(files, [
'packages/misc/angular-in-memory-web-api/**',
])
reviewers:
users:
- IgorMinar
- crisbeto
# =========================================================
# Benchpress
@ -1110,7 +1091,6 @@ groups:
'dev-infra/**',
'docs/BAZEL.md',
'docs/CARETAKER.md',
'docs/CODING_STANDARDS.md',
'docs/COMMITTER.md',
'docs/DEBUG.md',
'docs/DEBUG_COMPONENTS_REPO_IVY.md',

View File

@ -20,9 +20,9 @@ filegroup(
# do not sort
srcs = [
"@npm//:node_modules/core-js/client/core.js",
"//packages/zone.js/bundles:zone.umd.js",
"//packages/zone.js/bundles:zone-testing.umd.js",
"//packages/zone.js/bundles:task-tracking.umd.js",
"//packages/zone.js/dist:zone.js",
"//packages/zone.js/dist:zone-testing.js",
"//packages/zone.js/dist:task-tracking.js",
"//:test-events.js",
"//:third_party/shims_for_IE.js",
# Including systemjs because it defines `__eval`, which produces correct stack traces.

View File

@ -1,81 +1,3 @@
<a name="10.1.0"></a>
# 10.1.0 (2020-09-02)
### Features
* **bazel:** provide LinkablePackageInfo from ng_module ([#37623](https://github.com/angular/angular/issues/37623)) ([6898eab](https://github.com/angular/angular/commit/6898eab))
* **common:** add ReadonlyMap in place of Map in keyValuePipe ([#37311](https://github.com/angular/angular/issues/37311)) ([3373453](https://github.com/angular/angular/commit/3373453)), closes [#37308](https://github.com/angular/angular/issues/37308)
* **compiler-cli:** add `SourceFile.getOriginalLocation()` to sourcemaps package ([#32912](https://github.com/angular/angular/issues/32912)) ([6abb8d0](https://github.com/angular/angular/commit/6abb8d0))
* **compiler-cli:** Add compiler option to report errors when assigning to restricted input fields ([#38249](https://github.com/angular/angular/issues/38249)) ([71138f6](https://github.com/angular/angular/commit/71138f6))
* **compiler-cli:** add support for TypeScript 4.0 ([#38076](https://github.com/angular/angular/issues/38076)) ([0fc44e0](https://github.com/angular/angular/commit/0fc44e0))
* **compiler-cli:** explain why an expression cannot be used in AOT compilations ([#37587](https://github.com/angular/angular/issues/37587)) ([712f1bd](https://github.com/angular/angular/commit/712f1bd))
* **compiler:** support unary operators for more accurate type checking ([#37918](https://github.com/angular/angular/issues/37918)) ([874792d](https://github.com/angular/angular/commit/874792d)), closes [#20845](https://github.com/angular/angular/issues/20845) [#36178](https://github.com/angular/angular/issues/36178)
* **core:** rename async to waitForAsync to avoid confusing ([#37583](https://github.com/angular/angular/issues/37583)) ([8f07429](https://github.com/angular/angular/commit/8f07429))
* **core:** support injection token as predicate in queries ([#37506](https://github.com/angular/angular/issues/37506)) ([97dc85b](https://github.com/angular/angular/commit/97dc85b)), closes [#21152](https://github.com/angular/angular/issues/21152) [#36144](https://github.com/angular/angular/issues/36144)
* **core:** update reference and doc to change `async` to `waitAsync`. ([#37583](https://github.com/angular/angular/issues/37583)) ([8fbf40b](https://github.com/angular/angular/commit/8fbf40b))
* **forms:** AbstractControl to store raw validators in addition to combined validators function ([#37881](https://github.com/angular/angular/issues/37881)) ([ad7046b](https://github.com/angular/angular/commit/ad7046b))
* **localize:** allow duplicate messages to be handled during extraction ([#38082](https://github.com/angular/angular/issues/38082)) ([cf9a47b](https://github.com/angular/angular/commit/cf9a47b)), closes [#38077](https://github.com/angular/angular/issues/38077)
* **localize:** expose `canParse()` diagnostics ([#37909](https://github.com/angular/angular/issues/37909)) ([ec32eba](https://github.com/angular/angular/commit/ec32eba)), closes [#37901](https://github.com/angular/angular/issues/37901)
* **localize:** implement message extraction tool ([#32912](https://github.com/angular/angular/issues/32912)) ([190561d](https://github.com/angular/angular/commit/190561d))
* **platform-browser:** Allow `sms`-URLs ([#31463](https://github.com/angular/angular/issues/31463)) ([fc5c34d](https://github.com/angular/angular/commit/fc5c34d)), closes [#31462](https://github.com/angular/angular/issues/31462)
* **platform-server:** add option for absolute URL HTTP support ([#37539](https://github.com/angular/angular/issues/37539)) ([d37049a](https://github.com/angular/angular/commit/d37049a)), closes [#37071](https://github.com/angular/angular/issues/37071)
* **router:** better warning message when a router outlet has not been instantiated ([#30246](https://github.com/angular/angular/issues/30246)) ([1609815](https://github.com/angular/angular/commit/1609815))
### Bug Fixes
* **bazel:** fix integration test for bazel building ([#38629](https://github.com/angular/angular/issues/38629)) ([dd82f2f](https://github.com/angular/angular/commit/dd82f2f))
* **common:** date pipe gives wrong week number ([#37632](https://github.com/angular/angular/issues/37632)) ([ef1fb6d](https://github.com/angular/angular/commit/ef1fb6d)), closes [#33961](https://github.com/angular/angular/issues/33961)
* **common:** narrow `NgIf` context variables in template type checker ([#36627](https://github.com/angular/angular/issues/36627)) ([9c8bc4a](https://github.com/angular/angular/commit/9c8bc4a))
* **compiler-cli:** avoid creating value expressions for symbols from type-only imports ([#37912](https://github.com/angular/angular/issues/37912)) ([18098d3](https://github.com/angular/angular/commit/18098d3)), closes [#37900](https://github.com/angular/angular/issues/37900)
* **compiler-cli:** ensure source-maps can handle webpack:// protocol ([#32912](https://github.com/angular/angular/issues/32912)) ([decd95e](https://github.com/angular/angular/commit/decd95e))
* **compiler-cli:** only read source-map comment from last line ([#32912](https://github.com/angular/angular/issues/32912)) ([07a07e3](https://github.com/angular/angular/commit/07a07e3))
* **compiler-cli:** type-check inputs that include undefined when there's coercion members ([#38273](https://github.com/angular/angular/issues/38273)) ([7525f3a](https://github.com/angular/angular/commit/7525f3a))
* **compiler:** incorrectly inferring namespace for HTML nodes inside SVG ([#38477](https://github.com/angular/angular/issues/38477)) ([0dda97e](https://github.com/angular/angular/commit/0dda97e)), closes [#37218](https://github.com/angular/angular/issues/37218)
* **compiler:** mark `NgModuleFactory` construction as not side effectful ([#38147](https://github.com/angular/angular/issues/38147)) ([7f8c222](https://github.com/angular/angular/commit/7f8c222))
* **core:** Allow modification of lifecycle hooks any time before bootstrap ([#35464](https://github.com/angular/angular/issues/35464)) ([737506e](https://github.com/angular/angular/commit/737506e)), closes [#30497](https://github.com/angular/angular/issues/30497)
* **core:** detect DI parameters in JIT mode for downleveled ES2015 classes ([#38463](https://github.com/angular/angular/issues/38463)) ([ca07da4](https://github.com/angular/angular/commit/ca07da4)), closes [#38453](https://github.com/angular/angular/issues/38453)
* **core:** determine required DOMParser feature availability ([#36578](https://github.com/angular/angular/issues/36578)) ([#36578](https://github.com/angular/angular/issues/36578)) ([c509243](https://github.com/angular/angular/commit/c509243))
* **core:** do not trigger CSP alert/report in Firefox and Chrome ([#36578](https://github.com/angular/angular/issues/36578)) ([#36578](https://github.com/angular/angular/issues/36578)) ([b950d46](https://github.com/angular/angular/commit/b950d46)), closes [#25214](https://github.com/angular/angular/issues/25214)
* **core:** move generated i18n statements to the `consts` field of ComponentDef ([#38404](https://github.com/angular/angular/issues/38404)) ([cb05c01](https://github.com/angular/angular/commit/cb05c01))
* **elements:** run strategy methods in correct zone ([#37814](https://github.com/angular/angular/issues/37814)) ([8df888d](https://github.com/angular/angular/commit/8df888d)), closes [#24181](https://github.com/angular/angular/issues/24181)
* **forms:** handle form groups/arrays own pending async validation ([#22575](https://github.com/angular/angular/issues/22575)) ([77b62a5](https://github.com/angular/angular/commit/77b62a5)), closes [#10064](https://github.com/angular/angular/issues/10064)
* **language-service:** non-existent module format in package output ([#37623](https://github.com/angular/angular/issues/37623)) ([413a0fb](https://github.com/angular/angular/commit/413a0fb))
* **localize:** ensure required XLIFF parameters are serialized ([#38575](https://github.com/angular/angular/issues/38575)) ([f0af387](https://github.com/angular/angular/commit/f0af387)), closes [#38570](https://github.com/angular/angular/issues/38570)
* **localize:** extract the correct message ids ([#38498](https://github.com/angular/angular/issues/38498)) ([ac461e1](https://github.com/angular/angular/commit/ac461e1))
* **localize:** render ICU placeholders in extracted translation files ([#38484](https://github.com/angular/angular/issues/38484)) ([81c3e80](https://github.com/angular/angular/commit/81c3e80))
* **localize:** render text of extracted placeholders ([#38536](https://github.com/angular/angular/issues/38536)) ([14e90be](https://github.com/angular/angular/commit/14e90be))
* **ngcc:** detect synthesized delegate constructors for downleveled ES2015 classes ([#38463](https://github.com/angular/angular/issues/38463)) ([3b9c802](https://github.com/angular/angular/commit/3b9c802)), closes [#38453](https://github.com/angular/angular/issues/38453) [#38453](https://github.com/angular/angular/issues/38453)
* **router:** defer loading of wildcard module until needed ([#38348](https://github.com/angular/angular/issues/38348)) ([8f708b5](https://github.com/angular/angular/commit/8f708b5)), closes [#25494](https://github.com/angular/angular/issues/25494)
* **router:** fix navigation ignoring logic to compare to the browser url ([#37716](https://github.com/angular/angular/issues/37716)) ([a5ffca0](https://github.com/angular/angular/commit/a5ffca0)), closes [#16710](https://github.com/angular/angular/issues/16710) [#13586](https://github.com/angular/angular/issues/13586)
* **router:** properly compare array queryParams for equality ([#37709](https://github.com/angular/angular/issues/37709)) ([#37860](https://github.com/angular/angular/issues/37860)) ([1801d0c](https://github.com/angular/angular/commit/1801d0c))
* **router:** remove parenthesis for primary outlet segment after removing auxiliary outlet segment ([#24656](https://github.com/angular/angular/issues/24656)) ([#37163](https://github.com/angular/angular/issues/37163)) ([71f008f](https://github.com/angular/angular/commit/71f008f))
* **router:** restore 'history.state' object for navigations coming from Angular router ([#28108](https://github.com/angular/angular/issues/28108)) ([#28176](https://github.com/angular/angular/issues/28176)) ([df76a20](https://github.com/angular/angular/commit/df76a20))
* **router:** support lazy loading for empty path named outlets ([#38379](https://github.com/angular/angular/issues/38379)) ([7ad3264](https://github.com/angular/angular/commit/7ad3264)), closes [#12842](https://github.com/angular/angular/issues/12842)
### Code Refactoring
* **router:** export DefaultRouteReuseStrategy to Router public_api ([#31575](https://github.com/angular/angular/issues/31575)) ([ca79880](https://github.com/angular/angular/commit/ca79880))
### Performance Improvements
* **compiler-cli:** don't emit template guards when child scope is empty ([#38418](https://github.com/angular/angular/issues/38418)) ([1388c17](https://github.com/angular/angular/commit/1388c17))
* **compiler-cli:** fix regressions in incremental program reuse ([#37641](https://github.com/angular/angular/issues/37641)) ([5103d90](https://github.com/angular/angular/commit/5103d90))
* **compiler-cli:** only generate directive declarations when used ([#38418](https://github.com/angular/angular/issues/38418)) ([fb8f4b4](https://github.com/angular/angular/commit/fb8f4b4))
* **compiler-cli:** only generate type-check code for referenced DOM elements ([#38418](https://github.com/angular/angular/issues/38418)) ([f42e6ce](https://github.com/angular/angular/commit/f42e6ce))
* **forms:** use internal `ngDevMode` flag to tree-shake error messages in prod builds ([#37821](https://github.com/angular/angular/issues/37821)) ([201a546](https://github.com/angular/angular/commit/201a546)), closes [#37697](https://github.com/angular/angular/issues/37697)
* **ngcc:** shortcircuit tokenizing in ESM dependency host ([#37639](https://github.com/angular/angular/issues/37639)) ([bd7f440](https://github.com/angular/angular/commit/bd7f440))
* **ngcc:** use `EntryPointManifest` to speed up noop `ProgramBaseEntryPointFinder` ([#37665](https://github.com/angular/angular/issues/37665)) ([9318e23](https://github.com/angular/angular/commit/9318e23))
* **router:** apply prioritizedGuardValue operator to optimize CanLoad guards ([#37523](https://github.com/angular/angular/issues/37523)) ([d7dd295](https://github.com/angular/angular/commit/d7dd295))
<a name="10.0.14"></a>
## 10.0.14 (2020-08-26)
<a name="10.0.12"></a>
## 10.0.12 (2020-08-24)
@ -93,6 +15,7 @@
* **language-service:** introduce hybrid visitor to locate AST node ([#38540](https://github.com/angular/angular/issues/38540)) ([66d8c22](https://github.com/angular/angular/commit/66d8c22))
<a name="10.0.11"></a>
## 10.0.11 (2020-08-19)
@ -139,6 +62,7 @@
* **service-worker:** fix the chrome debugger syntax highlighter ([#38332](https://github.com/angular/angular/issues/38332)) ([f5d5bac](https://github.com/angular/angular/commit/f5d5bac))
<a name="10.0.8"></a>
## 10.0.8 (2020-08-04)
@ -207,6 +131,7 @@
* **bazel:** provide LinkablePackageInfo from ng_module ([#37778](https://github.com/angular/angular/issues/37778)) ([6cd10a1](https://github.com/angular/angular/commit/6cd10a1)), closes [/github.com/bazelbuild/rules_nodejs/blob/9a5de3728b05bf1647bbb87ad99f54e626604705/internal/linker/link_node_modules.bzl#L144-L146](https://github.com//github.com/bazelbuild/rules_nodejs/blob/9a5de3728b05bf1647bbb87ad99f54e626604705/internal/linker/link_node_modules.bzl/issues/L144-L146)
<a name="10.0.3"></a>
## 10.0.3 (2020-07-08)
@ -217,16 +142,6 @@
<a name="9.1.12"></a>
## [9.1.12](https://github.com/angular/angular/compare/9.1.11...9.1.12) (2020-07-08)
### Bug Fixes
* **core:** infinite loop if injectable using inheritance has a custom decorator ([6c1ab47](https://github.com/angular/angular/commit/6c1ab47)), closes [#35733](https://github.com/angular/angular/issues/35733)
<a name="10.0.2"></a>
## [10.0.2](https://github.com/angular/angular/compare/10.0.1...10.0.2) (2020-06-30)
@ -338,6 +253,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **compiler:** avoid undefined expressions in holey array ([#36343](https://github.com/angular/angular/issues/36343)) ([5516802](https://github.com/angular/angular/commit/5516802))
* **compiler:** handle type references to namespaced symbols correctly ([#36106](https://github.com/angular/angular/issues/36106)) ([4aa4e6f](https://github.com/angular/angular/commit/4aa4e6f)), closes [#36006](https://github.com/angular/angular/issues/36006)
* **compiler:** normalize line endings in ICU expansions ([#36741](https://github.com/angular/angular/issues/36741)) ([70dd27f](https://github.com/angular/angular/commit/70dd27f)), closes [#36725](https://github.com/angular/angular/issues/36725)
* **compiler:** record correct end of expression ([#34690](https://github.com/angular/angular/issues/34690)) ([df890d7](https://github.com/angular/angular/commit/df890d7)), closes [#33477](https://github.com/angular/angular/issues/33477)
* **compiler:** remove outdated and invalid warning for unresolved DI parameters ([#36985](https://github.com/angular/angular/issues/36985)) ([d0280a0](https://github.com/angular/angular/commit/d0280a0))
* **compiler:** resolve enum values in binary operations ([#36461](https://github.com/angular/angular/issues/36461)) ([64022f5](https://github.com/angular/angular/commit/64022f5)), closes [#35584](https://github.com/angular/angular/issues/35584)
* **compiler:** switch to 'referencedFiles' for shim generation ([#36211](https://github.com/angular/angular/issues/36211)) ([4213e8d](https://github.com/angular/angular/commit/4213e8d))
@ -488,12 +404,12 @@ https://github.com/microsoft/TypeScript/issues/38374 for more
information and updates.
If you used Closure Compiler with Angular in the past, you will likely
be better off consuming Angular packages built from sources directly
be better off consuming Angular packages built from sources directly
rather than consuming the version we publish on npm,
which is primarily optimized for Webpack/Rollup + Terser build pipeline.
As a temporary workaround, you might consider using your current build
pipeline with Closure flag `--compilation_level=SIMPLE`. This flag
pipeline with Closure flag `--compilation_level=SIMPLE`. This flag
will ensure that your build pipeline produces buildable and
runnable artifacts, at the cost of increased payload size due to
advanced optimizations being disabled.
@ -501,17 +417,17 @@ advanced optimizations being disabled.
If you were affected by this change, please help us understand your
needs by leaving a comment on https://github.com/angular/angular/issues/37234.
* **core:** make generic mandatory for ModuleWithProviders
* **core:** make generic mandatory for ModuleWithProviders
A generic type parameter has always been required for the `ModuleWithProviders` pattern to work with Ivy, but prior to this commit, View Engine allowed the generic type to be omitted (though support was officially deprecated).
If you're using `ModuleWithProviders` without a generic type in your application code, a v10 migration will update your code for you.
If you're using `ModuleWithProviders` without a generic type in your application code, a v10 migration will update your code for you.
However, if you are using View Engine and also depending on a library that omits the generic type, you will now get a build time error similar to:
```
error TS2314: Generic type 'ModuleWithProviders<T>' requires 1 type argument(s).
```
In this case, ngcc won't help you (because it's Ivy-only) and the migration only covers application code.
You should contact the library author to fix their library to provide a type parameter when they use this class.
@ -594,30 +510,6 @@ subscribe to the observable and call markForCheck as needed.
<a name="9.1.11"></a>
## [9.1.11](https://github.com/angular/angular/compare/9.1.10...9.1.11) (2020-06-10)
### Reverts
* **elements:** fire custom element output events during component initialization ([dc9da17](https://github.com/angular/angular/commit/dc9da17))
<a name="9.1.10"></a>
## [9.1.10](https://github.com/angular/angular/compare/9.1.9...9.1.10) (2020-06-09)
### Bug Fixes
* **elements:** fire custom element output events during component initialization ([454e073](https://github.com/angular/angular/commit/454e073)), closes [/github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/create-custom-element.ts#L167-L170](https://github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/create-custom-element.ts/issues/L167-L170) [/github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/create-custom-element.ts#L164](https://github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/create-custom-element.ts/issues/L164) [/github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/component-factory-strategy.ts#L158](https://github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/component-factory-strategy.ts/issues/L158) [#36141](https://github.com/angular/angular/issues/36141)
### Performance Improvements
* **ngcc:** cache parsed tsconfig between runs ([1aae94a](https://github.com/angular/angular/commit/1aae94a)), closes [#37417](https://github.com/angular/angular/issues/37417) [#36882](https://github.com/angular/angular/issues/36882)
<a name="9.1.9"></a>
## [9.1.9](https://github.com/angular/angular/compare/9.1.8...9.1.9) (2020-05-20)
@ -659,7 +551,6 @@ This release contains various API docs improvements.
* **compiler-cli**: Revert "fix(compiler-cli): fix case-sensitivity issues in NgtscCompilerHost (#36968)" (#37003)
<a name="9.1.5"></a>
## [9.1.5](https://github.com/angular/angular/compare/9.1.4...9.1.5) (2020-05-07)
@ -705,7 +596,6 @@ This release contains various API docs improvements.
* **ngcc:** recognize enum declarations emitted in JavaScript ([#36550](https://github.com/angular/angular/issues/36550)) ([c440165](https://github.com/angular/angular/commit/c440165)), closes [#35584](https://github.com/angular/angular/issues/35584)
<a name="9.1.3"></a>
## [9.1.3](https://github.com/angular/angular/compare/9.1.2...9.1.3) (2020-04-22)
@ -720,8 +610,8 @@ This release contains various API docs improvements.
* **core:** prevent unknown property check for AOT-compiled components ([#36072](https://github.com/angular/angular/issues/36072)) ([fe1d9ba](https://github.com/angular/angular/commit/fe1d9ba)), closes [#35945](https://github.com/angular/angular/issues/35945)
* **core:** properly identify modules affected by overrides in TestBed ([#36649](https://github.com/angular/angular/issues/36649)) ([9724169](https://github.com/angular/angular/commit/9724169)), closes [#36619](https://github.com/angular/angular/issues/36619)
* **language-service:** properly evaluate types in comparable expressions ([#36529](https://github.com/angular/angular/issues/36529)) ([5bab498](https://github.com/angular/angular/commit/5bab498))
* **ngcc:** display unlocker process output in sync mode ([#36637](https://github.com/angular/angular/issues/36637)) ([da159bd](https://github.com/angular/angular/commit/da159bd)), closes [/github.com/nodejs/node/issues/3596#issuecomment-250890218](https://github.com/nodejs/node/issues/3596/issues/issuecomment-250890218)
* **ngcc:** do not use cached file-system ([#36687](https://github.com/angular/angular/issues/36687)) ([18be33a](https://github.com/angular/angular/commit/18be33a)), closes [/github.com/angular/angular-cli/issues/16860#issuecomment-614694269](https://github.com/angular/angular-cli/issues/16860/issues/issuecomment-614694269)
* **ngcc:** display unlocker process output in sync mode ([#36637](https://github.com/angular/angular/issues/36637)) ([da159bd](https://github.com/angular/angular/commit/da159bd)), closes [/github.com/nodejs/node/issues/3596#issuecomment-250890218](https://github.com/nodejs/node/issues/3596#issuecomment-250890218)
* **ngcc:** do not use cached file-system ([#36687](https://github.com/angular/angular/issues/36687)) ([18be33a](https://github.com/angular/angular/commit/18be33a)), closes [/github.com/angular/angular-cli/issues/16860#issuecomment-614694269](https://github.com/angular/angular-cli/issues/16860#issuecomment-614694269)
@ -742,7 +632,7 @@ This release contains various API docs improvements.
* **upgrade:** update $locationShim to handle Location changes before initialization ([#36498](https://github.com/angular/angular/issues/36498)) ([a67afcc](https://github.com/angular/angular/commit/a67afcc)), closes [#36492](https://github.com/angular/angular/issues/36492)
### Performance Improvements
* **ngcc:** only load if it is needed ([#36486](https://github.com/angular/angular/issues/36486)) ([e06512b](https://github.com/angular/angular/commit/e06512b)) * **ngcc:** read dependencies from entry-point manifest ([#36486](https://github.com/angular/angular/issues/36486)) ([918e628](https://github.com/angular/angular/commit/918e628)), closes [#issuecomment-608401834](https://github.com/angular/angular/issues/issuecomment-608401834)
* **ngcc:** only load if it is needed ([#36486](https://github.com/angular/angular/issues/36486)) ([e06512b](https://github.com/angular/angular/commit/e06512b)) * **ngcc:** read dependencies from entry-point manifest ([#36486](https://github.com/angular/angular/issues/36486)) ([918e628](https://github.com/angular/angular/commit/918e628)), closes [#issuecomment-608401834](https://github.com/angular/angular#issuecomment-608401834)
* **ngcc:** reduce the size of the entry-point manifest file ([#36486](https://github.com/angular/angular/issues/36486)) ([603b094](https://github.com/angular/angular/commit/603b094))
@ -762,7 +652,7 @@ This release contains various API docs improvements.
* **core:** undecorated-classes migration should handle derived abstract classes ([#35339](https://github.com/angular/angular/issues/35339)) ([a631b99](https://github.com/angular/angular/commit/a631b99))
* **language-service:** infer type of elements of array-like objects ([#36312](https://github.com/angular/angular/issues/36312)) ([ff523c9](https://github.com/angular/angular/commit/ff523c9)), closes [#36191](https://github.com/angular/angular/issues/36191)
* **language-service:** use the `HtmlAst` to get the span of HTML tag ([#36371](https://github.com/angular/angular/issues/36371)) ([ffa4e11](https://github.com/angular/angular/commit/ffa4e11))
* **ngcc:** add process title ([#36448](https://github.com/angular/angular/issues/36448)) ([136596d](https://github.com/angular/angular/commit/136596d)), closes [/github.com/angular/angular/issues/36414#issuecomment-609644282](https://github.com/angular/angular/issues/36414/issues/issuecomment-609644282)
* **ngcc:** add process title ([#36448](https://github.com/angular/angular/issues/36448)) ([136596d](https://github.com/angular/angular/commit/136596d)), closes [36414#issuecomment-609644282](https://github.com/angular/angular/issues/36414#issuecomment-609644282)
* **ngcc:** allow ngcc configuration to match pre-release versions of packages ([#36370](https://github.com/angular/angular/issues/36370)) ([cb0a2a0](https://github.com/angular/angular/commit/cb0a2a0))
* **ngcc:** correctly detect imported TypeScript helpers ([#36284](https://github.com/angular/angular/issues/36284)) ([879457c](https://github.com/angular/angular/commit/879457c)), closes [#36089](https://github.com/angular/angular/issues/36089)
* **ngcc:** correctly identify relative Windows-style import paths ([#36372](https://github.com/angular/angular/issues/36372)) ([0daa488](https://github.com/angular/angular/commit/0daa488))
@ -839,9 +729,12 @@ To learn about the release highlights and our CLI-powered automated update workf
* **animations:** allow computeStyle to work on elements created in Node ([#35810](https://github.com/angular/angular/issues/35810)) ([17cf04e](https://github.com/angular/angular/commit/17cf04e))
* **animations:** false positive when detecting Node in Webpack builds ([#35134](https://github.com/angular/angular/issues/35134)) ([dc4ae4b](https://github.com/angular/angular/commit/dc4ae4b)), closes [#35117](https://github.com/angular/angular/issues/35117)
* **animations:** process shorthand `margin` and `padding` styles correctly ([#35701](https://github.com/angular/angular/issues/35701)) ([35c9f0d](https://github.com/angular/angular/commit/35c9f0d)), closes [#35463](https://github.com/angular/angular/issues/35463)
* **bazel:** devserver shows blank page in Windows ([#35159](https://github.com/angular/angular/issues/35159)) ([727f92f](https://github.com/angular/angular/commit/727f92f))
* **bazel:** do not use manifest paths for generated imports within compilation unit ([#35841](https://github.com/angular/angular/issues/35841)) ([9581658](https://github.com/angular/angular/commit/9581658))
* **bazel:** ng_package rule creates incorrect UMD module exports ([#35792](https://github.com/angular/angular/issues/35792)) ([5c2a908](https://github.com/angular/angular/commit/5c2a908)), closes [angular/components#18652](https://github.com/angular/components/issues/18652)
* **bazel:** prod server doesn't serve files in windows ([#35991](https://github.com/angular/angular/issues/35991)) ([96e3449](https://github.com/angular/angular/commit/96e3449))
* **bazel:** spawn prod server using port 4200 ([#35160](https://github.com/angular/angular/issues/35160)) ([829f506](https://github.com/angular/angular/commit/829f506))
* **bazel:** update ibazel to 0.11.1 ([#35158](https://github.com/angular/angular/issues/35158)) ([4e6d237](https://github.com/angular/angular/commit/4e6d237))
* **bazel:** update several packages for better windows support ([#35991](https://github.com/angular/angular/issues/35991)) ([32f099a](https://github.com/angular/angular/commit/32f099a))
* **bazel:** update typescript peer dependency range ([#36013](https://github.com/angular/angular/issues/36013)) ([5e3a898](https://github.com/angular/angular/commit/5e3a898))
* **common:** let `KeyValuePipe` accept type unions with `null` ([#36093](https://github.com/angular/angular/issues/36093)) ([407fa42](https://github.com/angular/angular/commit/407fa42)), closes [#35743](https://github.com/angular/angular/issues/35743)
@ -850,6 +743,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **compiler:** Propagate value span of ExpressionBinding to ParsedProperty ([#36133](https://github.com/angular/angular/issues/36133)) ([2ce5fa3](https://github.com/angular/angular/commit/2ce5fa3))
* **compiler:** do not recurse to find static symbols of same module ([#35262](https://github.com/angular/angular/issues/35262)) ([e179c58](https://github.com/angular/angular/commit/e179c58))
* **compiler:** record correct end of expression ([#34690](https://github.com/angular/angular/issues/34690)) ([df890d7](https://github.com/angular/angular/commit/df890d7)), closes [#33477](https://github.com/angular/angular/issues/33477)
* **compiler:** report errors for missing binding names ([#34595](https://github.com/angular/angular/issues/34595)) ([d13cab7](https://github.com/angular/angular/commit/d13cab7))
* **compiler:** support directive inputs with interpolations on `<ng-template>`s ([#35984](https://github.com/angular/angular/issues/35984)) ([79659ee](https://github.com/angular/angular/commit/79659ee)), closes [#35752](https://github.com/angular/angular/issues/35752)
* **compiler:** support i18n attributes on `<ng-template>` tags ([#35681](https://github.com/angular/angular/issues/35681)) ([40da51f](https://github.com/angular/angular/commit/40da51f))
* **compiler:** type-checking error for duplicate variables in templates ([#35674](https://github.com/angular/angular/issues/35674)) ([2c41bb8](https://github.com/angular/angular/commit/2c41bb8)), closes [#35186](https://github.com/angular/angular/issues/35186)
@ -887,13 +781,19 @@ To learn about the release highlights and our CLI-powered automated update workf
* **core:** workaround Terser inlining bug ([#36200](https://github.com/angular/angular/issues/36200)) ([f71d132](https://github.com/angular/angular/commit/f71d132))
* **elements:** correctly handle setting inputs to `undefined` ([#36140](https://github.com/angular/angular/issues/36140)) ([e066bdd](https://github.com/angular/angular/commit/e066bdd))
* **elements:** correctly set `SimpleChange#firstChange` for pre-existing inputs ([#36140](https://github.com/angular/angular/issues/36140)) ([447a600](https://github.com/angular/angular/commit/447a600)), closes [#36130](https://github.com/angular/angular/issues/36130)
* **elements:** schematics fail with schema.json not found error ([#35211](https://github.com/angular/angular/issues/35211)) ([94d002b](https://github.com/angular/angular/commit/94d002b)), closes [#35154](https://github.com/angular/angular/issues/35154)
* **forms:** change Array.reduce usage to Array.forEach ([#35349](https://github.com/angular/angular/issues/35349)) ([554c2cb](https://github.com/angular/angular/commit/554c2cb))
* **ivy:** `LFrame` needs to release memory on `leaveView()` ([#35156](https://github.com/angular/angular/issues/35156)) ([b9b512f](https://github.com/angular/angular/commit/b9b512f)), closes [#35148](https://github.com/angular/angular/issues/35148)
* **ivy:** add attributes and classes to host elements based on selector ([#34481](https://github.com/angular/angular/issues/34481)) ([f95b8ce](https://github.com/angular/angular/commit/f95b8ce))
* **ivy:** ensure module imports are instantiated before the module being declared ([#35172](https://github.com/angular/angular/issues/35172)) ([b6a3a73](https://github.com/angular/angular/commit/b6a3a73))
* **ivy:** error if directive with synthetic property binding is on same node as directive that injects ViewContainerRef ([#35343](https://github.com/angular/angular/issues/35343)) ([d6bc63f](https://github.com/angular/angular/commit/d6bc63f)), closes [#35342](https://github.com/angular/angular/issues/35342)
* **ivy:** narrow `NgIf` context variables in template type checker ([#35125](https://github.com/angular/angular/issues/35125)) ([40039d8](https://github.com/angular/angular/commit/40039d8)), closes [#34572](https://github.com/angular/angular/issues/34572)
* **ivy:** queries should match elements inside ng-container with the descendants: false option ([#35384](https://github.com/angular/angular/issues/35384)) ([3f4e02b](https://github.com/angular/angular/commit/3f4e02b)), closes [#34768](https://github.com/angular/angular/issues/34768)
* **ivy:** repeat template guards to narrow types in event handlers ([#35193](https://github.com/angular/angular/issues/35193)) ([dea1b96](https://github.com/angular/angular/commit/dea1b96)), closes [#35073](https://github.com/angular/angular/issues/35073)
* **ivy:** set namespace for host elements of dynamically created components ([#35136](https://github.com/angular/angular/issues/35136)) ([480a4c3](https://github.com/angular/angular/commit/480a4c3))
* **ivy:** support dynamic query tokens in AOT mode ([#35307](https://github.com/angular/angular/issues/35307)) ([3e3a1ef](https://github.com/angular/angular/commit/3e3a1ef)), closes [#34267](https://github.com/angular/angular/issues/34267)
* **ivy:** wrong context passed to ngOnDestroy when resolved multiple times ([#35249](https://github.com/angular/angular/issues/35249)) ([5fbfe69](https://github.com/angular/angular/commit/5fbfe69)), closes [#35167](https://github.com/angular/angular/issues/35167)
* **language-service:** Suggest ? and ! operator on nullable receiver ([#35200](https://github.com/angular/angular/issues/35200)) ([3cc24a9](https://github.com/angular/angular/commit/3cc24a9))
* **language-service:** fix calculation of pipe spans ([#35986](https://github.com/angular/angular/issues/35986)) ([406419b](https://github.com/angular/angular/commit/406419b))
* **language-service:** get the right 'ElementAst' in the nested HTML tag ([#35317](https://github.com/angular/angular/issues/35317)) ([8e354da](https://github.com/angular/angular/commit/8e354da))
* **language-service:** infer $implicit value for ngIf template contexts ([#35941](https://github.com/angular/angular/issues/35941)) ([18b1bd4](https://github.com/angular/angular/commit/18b1bd4))
@ -918,6 +818,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **ngcc:** correctly detect outer aliased class identifiers in ES5 ([#35527](https://github.com/angular/angular/issues/35527)) ([fde8915](https://github.com/angular/angular/commit/fde8915)), closes [#35399](https://github.com/angular/angular/issues/35399)
* **ngcc:** do not crash on entry-point that fails to compile ([#36083](https://github.com/angular/angular/issues/36083)) ([ff665b9](https://github.com/angular/angular/commit/ff665b9))
* **ngcc:** do not crash on overlapping entry-points ([#36083](https://github.com/angular/angular/issues/36083)) ([c9f554c](https://github.com/angular/angular/commit/c9f554c))
* **ngcc:** ensure that path-mapped secondary entry-points are processed correctly ([#35227](https://github.com/angular/angular/issues/35227)) ([c3c1140](https://github.com/angular/angular/commit/c3c1140)), closes [#35188](https://github.com/angular/angular/issues/35188)
* **ngcc:** handle imports in dts files when processing CommonJS ([#35191](https://github.com/angular/angular/issues/35191)) ([b6e8847](https://github.com/angular/angular/commit/b6e8847)), closes [#34356](https://github.com/angular/angular/issues/34356)
* **ngcc:** handle mappings outside the content when flattening source-maps ([#35718](https://github.com/angular/angular/issues/35718)) ([73cf7d5](https://github.com/angular/angular/commit/73cf7d5)), closes [#35709](https://github.com/angular/angular/issues/35709)
* **ngcc:** handle missing sources when flattening source-maps ([#35718](https://github.com/angular/angular/issues/35718)) ([72c4fda](https://github.com/angular/angular/commit/72c4fda)), closes [#35709](https://github.com/angular/angular/issues/35709)
@ -1175,7 +1076,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **compiler-cli:** require node 10 as runtime engine ([#34722](https://github.com/angular/angular/issues/34722)) ([7b77b3d](https://github.com/angular/angular/commit/7b77b3d))
* **language-service:** specific suggestions for template context diags ([#34751](https://github.com/angular/angular/issues/34751)) ([cc7fca4](https://github.com/angular/angular/commit/cc7fca4))
* **language-service:** support multiple symbol definitions ([#34782](https://github.com/angular/angular/issues/34782)) ([2f2396c](https://github.com/angular/angular/commit/2f2396c))
* **ngcc:** lock ngcc when processing ([#34722](https://github.com/angular/angular/issues/34722)) ([6dd51f1](https://github.com/angular/angular/commit/6dd51f1)), closes [/github.com/angular/angular/issues/32431#issuecomment-571825781](https://github.com/angular/angular/issues/32431/issues/issuecomment-571825781)
* **ngcc:** lock ngcc when processing ([#34722](https://github.com/angular/angular/issues/34722)) ([6dd51f1](https://github.com/angular/angular/commit/6dd51f1)), closes [32431#issuecomment-571825781](https://github.com/angular/angular/issues/32431#issuecomment-571825781)
* work around 'noImplicityAny' incompatibility due to ts3.7 update ([#34798](https://github.com/angular/angular/issues/34798)) ([251d548](https://github.com/angular/angular/commit/251d548))
* **animations:** not waiting for child animations to finish when removing parent in Ivy ([#34702](https://github.com/angular/angular/issues/34702)) ([92c17fe](https://github.com/angular/angular/commit/92c17fe)), closes [#33597](https://github.com/angular/angular/issues/33597)
* **common:** ensure diffing in ngStyle/ngClass correctly emits value changes ([#34307](https://github.com/angular/angular/issues/34307)) ([93a035f](https://github.com/angular/angular/commit/93a035f)), closes [#34336](https://github.com/angular/angular/issues/34336) [#34444](https://github.com/angular/angular/issues/34444)
@ -1306,7 +1207,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **ngcc:** do not output duplicate ɵprov properties ([#34085](https://github.com/angular/angular/issues/34085)) ([5a8d25d](https://github.com/angular/angular/commit/5a8d25d))
* **ngcc:** render localized strings when in ES5 format ([#33857](https://github.com/angular/angular/issues/33857)) ([c6695fa](https://github.com/angular/angular/commit/c6695fa))
* **ngcc:** render UMD global imports correctly ([#34012](https://github.com/angular/angular/issues/34012)) ([83989b8](https://github.com/angular/angular/commit/83989b8))
* **ngcc:** report errors from `analyze` and `resolve` processing ([#33964](https://github.com/angular/angular/issues/33964)) ([ca5d772](https://github.com/angular/angular/commit/ca5d772)), closes [/github.com/angular/angular/issues/33685#issuecomment-557091719](https://github.com/angular/angular/issues/33685/issues/issuecomment-557091719)
* **ngcc:** report errors from `analyze` and `resolve` processing ([#33964](https://github.com/angular/angular/issues/33964)) ([ca5d772](https://github.com/angular/angular/commit/ca5d772)), closes [33685#issuecomment-557091719](https://github.com/angular/angular/issues/33685#issuecomment-557091719)
* **router:** make routerLinkActive work with query params which contain arrays ([#22666](https://github.com/angular/angular/issues/22666)) ([f1bf5b2](https://github.com/angular/angular/commit/f1bf5b2)), closes [#22223](https://github.com/angular/angular/issues/22223)
* **service-worker:** allow creating post api requests after cache failure ([#33930](https://github.com/angular/angular/issues/33930)) ([63c9123](https://github.com/angular/angular/commit/63c9123)), closes [#33793](https://github.com/angular/angular/issues/33793)
* **service-worker:** throw when using the unsupported `versionedFiles` option in config ([#33903](https://github.com/angular/angular/issues/33903)) ([250e6fd](https://github.com/angular/angular/commit/250e6fd))
@ -1385,7 +1286,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **language-service:** Should not crash if expr ends unexpectedly ([#33524](https://github.com/angular/angular/issues/33524)) ([9ebac71](https://github.com/angular/angular/commit/9ebac71))
* **ngcc:** handle new `__spreadArrays` tslib helper ([#33617](https://github.com/angular/angular/issues/33617)) ([d749dd3](https://github.com/angular/angular/commit/d749dd3)), closes [#33614](https://github.com/angular/angular/issues/33614)
* **ngcc:** override `getInternalNameOfClass()` and `getAdjacentNameOfClass()` for ES5 ([#33533](https://github.com/angular/angular/issues/33533)) ([93a23b9](https://github.com/angular/angular/commit/93a23b9))
* **ngcc:** render adjacent statements after static properties ([#33630](https://github.com/angular/angular/issues/33630)) ([fe12d0d](https://github.com/angular/angular/commit/fe12d0d)), closes [/github.com/angular/angular/pull/33337#issuecomment-545487737](https://github.com/angular/angular/pull/33337/issues/issuecomment-545487737)
* **ngcc:** render adjacent statements after static properties ([#33630](https://github.com/angular/angular/issues/33630)) ([fe12d0d](https://github.com/angular/angular/commit/fe12d0d)), closes [/github.com/angular/angular/pull/33337#issuecomment-545487737](https://github.com/angular/angular/pull/33337#issuecomment-545487737)
* **ngcc:** render new definitions using the inner name of the class ([#33533](https://github.com/angular/angular/issues/33533)) ([85298e3](https://github.com/angular/angular/commit/85298e3))
* **service-worker:** ensure initialization before handling messages ([#32525](https://github.com/angular/angular/issues/32525)) ([72eba77](https://github.com/angular/angular/commit/72eba77)), closes [#25611](https://github.com/angular/angular/issues/25611)
* **compiler:** i18n - ignore `alt-trans` tags in XLIFF 1.2 ([#33450](https://github.com/angular/angular/issues/33450)) ([936700a](https://github.com/angular/angular/commit/936700a)), closes [#33161](https://github.com/angular/angular/issues/33161)
@ -1415,7 +1316,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **language-service:** Add directive selectors & banana-in-a-box to completions ([#33311](https://github.com/angular/angular/issues/33311)) ([49eec5d](https://github.com/angular/angular/commit/49eec5d))
* **language-service:** Add global symbol for $any() ([#33245](https://github.com/angular/angular/issues/33245)) ([3f257e9](https://github.com/angular/angular/commit/3f257e9))
* **language-service:** Preserve CRLF in templates for language-service ([#33241](https://github.com/angular/angular/issues/33241)) ([65a0d2b](https://github.com/angular/angular/commit/65a0d2b))
* **ngcc:** do not fail when multiple workers try to create the same directory ([#33237](https://github.com/angular/angular/issues/33237)) ([8017229](https://github.com/angular/angular/commit/8017229)), closes [/github.com/angular/angular/pull/33049#issuecomment-540485703](https://github.com/angular/angular/pull/33049/issues/issuecomment-540485703)
* **ngcc:** do not fail when multiple workers try to create the same directory ([#33237](https://github.com/angular/angular/issues/33237)) ([8017229](https://github.com/angular/angular/commit/8017229)), closes [/github.com/angular/angular/pull/33049#issuecomment-540485703](https://github.com/angular/angular/pull/33049#issuecomment-540485703)
* **bazel:** Remove angular devkit and restore ngc postinstall ([#32946](https://github.com/angular/angular/issues/32946)) ([f036684](https://github.com/angular/angular/commit/f036684))
* **common:** remove deprecated support for intl API ([#29250](https://github.com/angular/angular/issues/29250)) ([9e7668f](https://github.com/angular/angular/commit/9e7668f)), closes [#18284](https://github.com/angular/angular/issues/18284)
* **compiler:** absolute source span for template attribute expressions ([#33189](https://github.com/angular/angular/issues/33189)) ([fd4fed1](https://github.com/angular/angular/commit/fd4fed1))
@ -1472,7 +1373,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **language-service:** Turn on strict mode for test project ([#32783](https://github.com/angular/angular/issues/32783)) ([28358b6](https://github.com/angular/angular/commit/28358b6))
* **ngcc:** ensure private exports are added for `ModuleWithProviders` ([#32902](https://github.com/angular/angular/issues/32902)) ([002a97d](https://github.com/angular/angular/commit/002a97d))
* **ngcc:** handle presence of both `ctorParameters` and `__decorate` ([#32901](https://github.com/angular/angular/issues/32901)) ([747f0cf](https://github.com/angular/angular/commit/747f0cf))
* **ngcc:** make the build-marker error more clear ([#32712](https://github.com/angular/angular/issues/32712)) ([0ea4875](https://github.com/angular/angular/commit/0ea4875)), closes [/github.com/angular/angular/issues/31354#issuecomment-532080537](https://github.com/angular/angular/issues/31354/issues/issuecomment-532080537)
* **ngcc:** make the build-marker error more clear ([#32712](https://github.com/angular/angular/issues/32712)) ([0ea4875](https://github.com/angular/angular/commit/0ea4875)), closes [31354#issuecomment-532080537](https://github.com/angular/angular/issues/31354#issuecomment-532080537)
* **upgrade:** fix AngularJsUrlCodec to support Safari ([#32959](https://github.com/angular/angular/issues/32959)) ([39e8ceb](https://github.com/angular/angular/commit/39e8ceb))
* **ivy:** ensure `window.ng.getDebugNode` returns debug info for component elements ([#32780](https://github.com/angular/angular/issues/32780)) ([5651fa3](https://github.com/angular/angular/commit/5651fa3))
* **ivy:** ensure multiple map-based bindings do not skip intermediate values ([#32774](https://github.com/angular/angular/issues/32774)) ([86fd571](https://github.com/angular/angular/commit/86fd571))
@ -1581,7 +1482,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **ivy:** graceful evaluation of unknown or invalid expressions ([#33453](https://github.com/angular/angular/issues/33453)) ([ce30888](https://github.com/angular/angular/commit/ce30888))
* **ivy:** implement unknown element detection in jit mode ([#33419](https://github.com/angular/angular/issues/33419)) ([c83f501](https://github.com/angular/angular/commit/c83f501))
* add a flag in bootstrap to enable coalesce event change detection to improve performance ([#30533](https://github.com/angular/angular/issues/30533)) ([44623a1](https://github.com/angular/angular/commit/44623a1))
* **bazel:** update [@bazel](https://github.com/bazel)/schematics to Bazel 1.0.0 ([#33476](https://github.com/angular/angular/issues/33476)) ([540d104](https://github.com/angular/angular/commit/540d104)), closes [/github.com/angular/angular/pull/33367#issuecomment-547643246](https://github.com/angular/angular/pull/33367/issues/issuecomment-547643246)
* **bazel:** update [@bazel](https://github.com/bazel)/schematics to Bazel 1.0.0 ([#33476](https://github.com/angular/angular/issues/33476)) ([540d104](https://github.com/angular/angular/commit/540d104)), closes [/github.com/angular/angular/pull/33367#issuecomment-547643246](https://github.com/angular/angular/pull/33367#issuecomment-547643246)
* **bazel:** update bazel-schematics to use Ivy and new rollup_bundle ([#33435](https://github.com/angular/angular/issues/33435)) ([bf913cc](https://github.com/angular/angular/commit/bf913cc))
* **ivy:** i18n - support inlining of XTB formatted translation files ([#33444](https://github.com/angular/angular/issues/33444)) ([2c623fd](https://github.com/angular/angular/commit/2c623fd))
* **language-service:** add support for text replacement ([#33091](https://github.com/angular/angular/issues/33091)) ([da4eb91](https://github.com/angular/angular/commit/da4eb91))
@ -1623,7 +1524,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **ivy:** i18n - implement compile-time inlining ([#32881](https://github.com/angular/angular/issues/32881)) ([2cdb3a0](https://github.com/angular/angular/commit/2cdb3a0))
* **ivy:** i18n - render legacy message ids in `$localize` if requested ([#32937](https://github.com/angular/angular/issues/32937)) ([bcbf3e4](https://github.com/angular/angular/commit/bcbf3e4))
* **language-service:** module definitions on directive hover ([#32763](https://github.com/angular/angular/issues/32763)) ([0d186dd](https://github.com/angular/angular/commit/0d186dd)), closes [#32565](https://github.com/angular/angular/issues/32565)
* **ngcc:** expose `--create-ivy-entry-points` option on ivy-ngcc ([#33049](https://github.com/angular/angular/issues/33049)) ([b2b917d](https://github.com/angular/angular/commit/b2b917d)), closes [/github.com/angular/angular/pull/32999#issuecomment-539937368](https://github.com/angular/angular/pull/32999/issues/issuecomment-539937368)
* **ngcc:** expose `--create-ivy-entry-points` option on ivy-ngcc ([#33049](https://github.com/angular/angular/issues/33049)) ([b2b917d](https://github.com/angular/angular/commit/b2b917d)), closes [/github.com/angular/angular/pull/32999#issuecomment-539937368](https://github.com/angular/angular/pull/32999#issuecomment-539937368)
* update rxjs peerDependencies minimum requirment to 6.5.3 ([#32812](https://github.com/angular/angular/issues/32812)) ([66658c4](https://github.com/angular/angular/commit/66658c4))
* **ivy:** support ng-add in localize package ([#32791](https://github.com/angular/angular/issues/32791)) ([e41cbfb](https://github.com/angular/angular/commit/e41cbfb))
* **language-service:** allow retreiving synchronized analyzed NgModules ([#32779](https://github.com/angular/angular/issues/32779)) ([98feee7](https://github.com/angular/angular/commit/98feee7))
@ -1839,7 +1740,7 @@ API surface going forward.
* **core:** Injector.get now accepts abstract classes to return
type-safe values. Previous implementation returned `any` through the
deprecated implementation.
* Angular now compiles with Ivy by default ([#32219](https://github.com/angular/angular/issues/32219)) ([ec4381d](https://github.com/angular/angular/commit/ec4381d)).
* Angular now compiles with Ivy by default ([#32219](https://github.com/angular/angular/issues/32219)) ([ec4381d](https://github.com/angular/angular/commit/ec4381d)).
If you aren't familiar with Ivy, read our [blog post about the Ivy preview](https://blog.angular.io/its-time-for-the-compatibility-opt-in-preview-of-ivy-38f3542a282f?gi=8bfeb44b05c) and see the list of changes [here](https://docs.google.com/document/d/1Dije0AsJ0PxL3NaeNPxpYDeapj30b_QC0xfeIvIIzgg/preview).
@ -2002,6 +1903,7 @@ This release contains various API docs improvements.
* **language-service:** Eagarly initialize data members ([#31577](https://github.com/angular/angular/issues/31577)) ([0110de2](https://github.com/angular/angular/commit/0110de2))
* **bazel:** revert location of xi18n outputs to bazel-genfiles ([#31410](https://github.com/angular/angular/issues/31410)) ([1d3e227](https://github.com/angular/angular/commit/1d3e227))
* **compiler:** give ASTWithSource its own visit method ([#31347](https://github.com/angular/angular/issues/31347)) ([6aaca21](https://github.com/angular/angular/commit/6aaca21))
* **core:** handle `undefined` meta in `injectArgs` ([#31333](https://github.com/angular/angular/issues/31333)) ([80ccd6c](https://github.com/angular/angular/commit/80ccd6c)), closes [CLI #14888](https://github.com/angular/angular-cli/issues/14888)
* **service-worker:** cache opaque responses in data groups with `freshness` strategy ([#30977](https://github.com/angular/angular/issues/30977)) ([d7be38f](https://github.com/angular/angular/commit/d7be38f)), closes [#30968](https://github.com/angular/angular/issues/30968)
* **service-worker:** cache opaque responses when requests exceeds timeout threshold ([#30977](https://github.com/angular/angular/issues/30977)) ([93abc35](https://github.com/angular/angular/commit/93abc35))
@ -2031,6 +1933,7 @@ This release contains various API docs improvements.
* use the correct WTF array to iterate over ([#31208](https://github.com/angular/angular/issues/31208)) ([4aed480](https://github.com/angular/angular/commit/4aed480))
* **compiler-cli:** Return original sourceFile instead of redirected sourceFile from getSourceFile ([#26036](https://github.com/angular/angular/issues/26036)) ([13dbb98](https://github.com/angular/angular/commit/13dbb98)), closes [#22524](https://github.com/angular/angular/issues/22524)
* **core:** export provider interfaces that are part of the public API types ([#31377](https://github.com/angular/angular/issues/31377)) ([bebf089](https://github.com/angular/angular/commit/bebf089)), closes [/github.com/angular/angular/pull/31377#discussion_r299254408](https://github.com/angular/angular/pull/31377/issues/discussion_r299254408) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts#L365-L366](https://github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts/issues/L365-L366) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts#L283-L284](https://github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts/issues/L283-L284) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/index.ts#L23](https://github.com/angular/angular/blob/9e34670b2/packages/core/src/di/index.ts/issues/L23)
<a name="8.1.1"></a>
@ -2208,6 +2111,7 @@ To learn about the release highlights and our CLI-powered automated update workf
### Features
* add support for TypeScript 3.4 (and drop older versions) ([#29372](https://github.com/angular/angular/issues/29372)) ([ef85336](https://github.com/angular/angular/commit/ef85336))
* **common:** add ability to watch for AngularJS URL updates through `onUrlChange` hook ([#30466](https://github.com/angular/angular/issues/30466)) ([8022d36](https://github.com/angular/angular/commit/8022d36))
* **common:** stricter types for `SlicePipe` ([#30156](https://github.com/angular/angular/issues/30156)) ([722b2fa](https://github.com/angular/angular/commit/722b2fa))
* **bazel:** use `rbe_autoconfig()` and new container ([#29336](https://github.com/angular/angular/issues/29336)) ([e562acc](https://github.com/angular/angular/commit/e562acc))
* **common:** add @angular/common/upgrade package for `$location`-related APIs ([#30055](https://github.com/angular/angular/issues/30055)) ([152d99e](https://github.com/angular/angular/commit/152d99e))
@ -2324,6 +2228,8 @@ To learn about the release highlights and our CLI-powered automated update workf
* **bazel:** use `//:tsconfig.json` as the default for `ng_module` ([#29670](https://github.com/angular/angular/issues/29670)) ([b14537a](https://github.com/angular/angular/commit/b14537a))
* **compiler-cli:** ngcc - cope with processing entry-points multiple times ([#29657](https://github.com/angular/angular/issues/29657)) ([6b39c9c](https://github.com/angular/angular/commit/6b39c9c))
* **core:** static-query schematic should detect static queries in getters. ([#29609](https://github.com/angular/angular/issues/29609)) ([33016b8](https://github.com/angular/angular/commit/33016b8))
* **common:** escape query selector used when anchor scrolling ([#29577](https://github.com/angular/angular/issues/29577)) ([7671c73](https://github.com/angular/angular/commit/7671c73)), closes [#28193](https://github.com/angular/angular/issues/28193)
* **router:** adjust setting navigationTransition when a new navigation cancels an existing one ([#29636](https://github.com/angular/angular/issues/29636)) ([e884c0c](https://github.com/angular/angular/commit/e884c0c)), closes [#29389](https://github.com/angular/angular/issues/29389) [#29590](https://github.com/angular/angular/issues/29590)
* **bazel:** allow `ng_module` users to set `createExternalSymbolFactoryReexports` ([#29459](https://github.com/angular/angular/issues/29459)) ([21be0fb](https://github.com/angular/angular/commit/21be0fb))
* **bazel:** workaround problem reading summary files from node_modules ([#29459](https://github.com/angular/angular/issues/29459)) ([769d960](https://github.com/angular/angular/commit/769d960))
* **compiler:** inherit param types when class has a constructor which takes no declared parameters and delegates up ([#29232](https://github.com/angular/angular/issues/29232)) ([0007564](https://github.com/angular/angular/commit/0007564))
@ -2350,7 +2256,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **platform-server:** update minimum domino version to latest released ([#28893](https://github.com/angular/angular/issues/28893)) ([79e2ca0](https://github.com/angular/angular/commit/79e2ca0))
* **router:** removed obsolete TODO comment ([#29085](https://github.com/angular/angular/issues/29085)) ([72ecc45](https://github.com/angular/angular/commit/72ecc45))
* **service-worker:** detect new version even if files are identical to an old one ([#26006](https://github.com/angular/angular/issues/26006)) ([586234b](https://github.com/angular/angular/commit/586234b)), closes [#24338](https://github.com/angular/angular/issues/24338)
* **service-worker:** ignore passive mixed content requests ([#25994](https://github.com/angular/angular/issues/25994)) ([48214e2](https://github.com/angular/angular/commit/48214e2)), closes [/github.com/angular/angular/issues/23012#issuecomment-376430187](https://github.com/angular/angular/issues/23012/issues/issuecomment-376430187) [#23012](https://github.com/angular/angular/issues/23012)
* **service-worker:** ignore passive mixed content requests ([#25994](https://github.com/angular/angular/issues/25994)) ([48214e2](https://github.com/angular/angular/commit/48214e2)), closes [23012#issuecomment-376430187](https://github.com/angular/angular/issues/23012#issuecomment-376430187) [#23012](https://github.com/angular/angular/issues/23012)
* **bazel:** Pin browsers for schematics ([#28913](https://github.com/angular/angular/issues/28913)) ([1145bdb](https://github.com/angular/angular/commit/1145bdb))
* **bazel:** rxjs_umd_modules should always be present ([#28881](https://github.com/angular/angular/issues/28881)) ([9ae14db](https://github.com/angular/angular/commit/9ae14db))
* **compiler:** use correct variable in invalid function ([#28656](https://github.com/angular/angular/issues/28656)) ([f75acbd](https://github.com/angular/angular/commit/f75acbd))
@ -2412,6 +2318,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **core:** deprecate integration with the Web Tracing Framework (WTF) ([#30642](https://github.com/angular/angular/issues/30642)) ([b408445](https://github.com/angular/angular/commit/b408445))
* **platform-webworker:** deprecate platform-webworker ([#30642](https://github.com/angular/angular/issues/30642)) ([361f181](https://github.com/angular/angular/commit/361f181))
* `TestBed.get()` has two signatures, one which is typed and another which accepts and returns `any`. The signature for `any` is deprecated; all usage of `TestBed.get()` should go through the typed API. This mainly affects string tokens
(which aren't supported) and abstract class tokens.
Before:
@ -2564,7 +2471,7 @@ This release contains various API docs improvements.
* **animations:** ensure `position` and `display` styles are handled outside of keyframes/web-animations ([#28911](https://github.com/angular/angular/issues/28911)) ([86981b3](https://github.com/angular/angular/commit/86981b3)), closes [#24923](https://github.com/angular/angular/issues/24923) [#25635](https://github.com/angular/angular/issues/25635)
* **router:** removed obsolete TODO comment ([#29085](https://github.com/angular/angular/issues/29085)) ([2a25ac2](https://github.com/angular/angular/commit/2a25ac2))
* **service-worker:** detect new version even if files are identical to an old one ([#26006](https://github.com/angular/angular/issues/26006)) ([5669333](https://github.com/angular/angular/commit/5669333)), closes [#24338](https://github.com/angular/angular/issues/24338)
* **service-worker:** ignore passive mixed content requests ([#25994](https://github.com/angular/angular/issues/25994)) ([b598e88](https://github.com/angular/angular/commit/b598e88)), closes [/github.com/angular/angular/issues/23012#issuecomment-376430187](https://github.com/angular/angular/issues/23012/issues/issuecomment-376430187) [#23012](https://github.com/angular/angular/issues/23012)
* **service-worker:** ignore passive mixed content requests ([#25994](https://github.com/angular/angular/issues/25994)) ([b598e88](https://github.com/angular/angular/commit/b598e88)), closes [23012#issuecomment-376430187](https://github.com/angular/angular/issues/23012#issuecomment-376430187) [#23012](https://github.com/angular/angular/issues/23012)
<a name="7.2.7"></a>
@ -2660,6 +2567,14 @@ This release contains various API docs improvements.
# [8.0.0-beta.0](https://github.com/angular/angular/compare/7.2.0...8.0.0-beta.0) (2019-01-16)
### Bug Fixes
### Features
### Performance Improvements
@ -2807,9 +2722,42 @@ This release contains various API docs improvements.
# [7.1.0](https://github.com/angular/angular/compare/7.1.0-rc.0...7.1.0) (2018-11-21)
### Bug Fixes
* **core:** allow null value for renderer setElement(…) ([#17065](https://github.com/angular/angular/issues/17065)) ([ff15043](https://github.com/angular/angular/commit/ff15043)), closes [#13686](https://github.com/angular/angular/issues/13686)
* **router:** fix regression where navigateByUrl promise didn't resolve on CanLoad failure ([#26455](https://github.com/angular/angular/issues/26455)) ([1c9b065](https://github.com/angular/angular/commit/1c9b065)), closes [#26284](https://github.com/angular/angular/issues/26284)
* **service-worker:** clean up caches from old SW versions ([#26319](https://github.com/angular/angular/issues/26319)) ([2326b9c](https://github.com/angular/angular/commit/2326b9c))
* **upgrade:** properly destroy upgraded component elements and descendants ([#26209](https://github.com/angular/angular/issues/26209)) ([071934e](https://github.com/angular/angular/commit/071934e)), closes [#26208](https://github.com/angular/angular/issues/26208)
* **compiler:** generate inputs with aliases properly ([#26774](https://github.com/angular/angular/issues/26774)) ([19fcfc3](https://github.com/angular/angular/commit/19fcfc3))
* **compiler:** generate relative paths only in summary file errors ([#26759](https://github.com/angular/angular/issues/26759)) ([56f44be](https://github.com/angular/angular/commit/56f44be))
* **core:** ignore comment nodes under unsafe elements ([#25879](https://github.com/angular/angular/issues/25879)) ([d5cbcef](https://github.com/angular/angular/commit/d5cbcef))
* **core:** Remove static dependency from @angular/core to @angular/compiler ([#26734](https://github.com/angular/angular/issues/26734)) ([d042c4a](https://github.com/angular/angular/commit/d042c4a))
* **core:** support computed base class in metadata inheritance ([#24014](https://github.com/angular/angular/issues/24014)) ([95743e3](https://github.com/angular/angular/commit/95743e3))
* **bazel:** unknown replay compiler error in windows ([#26711](https://github.com/angular/angular/issues/26711)) ([aed95fd](https://github.com/angular/angular/commit/aed95fd))
* **core:** ensure that `ɵdefineNgModule` is available in flat-file formats ([#26403](https://github.com/angular/angular/issues/26403)) ([a64859b](https://github.com/angular/angular/commit/a64859b))
* **router:** remove type bludgeoning of context and outlet when running CanDeactivate ([#26496](https://github.com/angular/angular/issues/26496)) ([496372d](https://github.com/angular/angular/commit/496372d)), closes [#18253](https://github.com/angular/angular/issues/18253)
* **service-worker:** add typing to public api guard and fix lint errors ([#25860](https://github.com/angular/angular/issues/25860)) ([1061875](https://github.com/angular/angular/commit/1061875))
* **upgrade:** improve downgrading-related error messages ([#26217](https://github.com/angular/angular/issues/26217)) ([7dbc103](https://github.com/angular/angular/commit/7dbc103))
* **upgrade:** make typings compatible with older AngularJS typings ([#26880](https://github.com/angular/angular/issues/26880)) ([64647af](https://github.com/angular/angular/commit/64647af)), closes [#26420](https://github.com/angular/angular/issues/26420)
* **compiler-cli:** add missing tslib dependency ([#27063](https://github.com/angular/angular/issues/27063)) ([c31e78f](https://github.com/angular/angular/commit/c31e78f))
* **compiler-cli:** only pass canonical genfile paths to compiler host ([#27062](https://github.com/angular/angular/issues/27062)) ([0ada23a](https://github.com/angular/angular/commit/0ada23a))
* **router:** add `relativeLinkResolution` to `recognize` operator ([#26990](https://github.com/angular/angular/issues/26990)) ([a752971](https://github.com/angular/angular/commit/a752971)), closes [#26983](https://github.com/angular/angular/issues/26983)
### Features
* **bazel:** Bazel workspace schematics ([#26971](https://github.com/angular/angular/issues/26971)) ([b07bd30](https://github.com/angular/angular/commit/b07bd30))
* **router:** add prioritizedGuardValue operator optimization and allowing UrlTree return from guard ([#26478](https://github.com/angular/angular/issues/26478)) ([fdfedce](https://github.com/angular/angular/commit/fdfedce))
* **compiler:** ability to mark an InvokeFunctionExpr as pure ([#26860](https://github.com/angular/angular/issues/26860)) ([4dfa71f](https://github.com/angular/angular/commit/4dfa71f))
* **forms:** add updateOn option to FormBuilder ([#24599](https://github.com/angular/angular/issues/24599)) ([e9e804f](https://github.com/angular/angular/commit/e9e804f))
* **router:** allow guards to return UrlTree as well as boolean ([#26521](https://github.com/angular/angular/issues/26521)) ([081f95c](https://github.com/angular/angular/commit/081f95c))
* **router:** allow redirect from guards by returning UrlTree ([#26521](https://github.com/angular/angular/issues/26521)) ([152ca66](https://github.com/angular/angular/commit/152ca66))
* **router:** guard returning UrlTree cancels current navigation and redirects ([#26521](https://github.com/angular/angular/issues/26521)) ([4e9f2e5](https://github.com/angular/angular/commit/4e9f2e5)), closes [#24618](https://github.com/angular/angular/issues/24618)
* **service-worker:** add typing for messagesClicked in SwPush service ([#25860](https://github.com/angular/angular/issues/25860)) ([c78c221](https://github.com/angular/angular/commit/c78c221))
* **service-worker:** close notifications and focus window on click ([#25860](https://github.com/angular/angular/issues/25860)) ([f5d5a3d](https://github.com/angular/angular/commit/f5d5a3d))
* **service-worker:** handle 'notificationclick' events ([#25860](https://github.com/angular/angular/issues/25860)) ([cf6ea28](https://github.com/angular/angular/commit/cf6ea28)), closes [#20956](https://github.com/angular/angular/issues/20956) [#22311](https://github.com/angular/angular/issues/22311)
* **upgrade:** support downgrading multiple modules ([#26217](https://github.com/angular/angular/issues/26217)) ([93837e9](https://github.com/angular/angular/commit/93837e9)), closes [#26062](https://github.com/angular/angular/issues/26062)
* **router:** add pathParamsChange mode for runGuardsAndResolvers ([#26861](https://github.com/angular/angular/issues/26861)) ([bf6ac6c](https://github.com/angular/angular/commit/bf6ac6c)), closes [#18253](https://github.com/angular/angular/issues/18253)
<a name="7.1.0-rc.0"></a>
@ -2912,7 +2860,10 @@ This release contains various API docs improvements.
### Bug Fixes
* **core:** allow null value for renderer setElement(…) ([#17065](https://github.com/angular/angular/issues/17065)) ([ff15043](https://github.com/angular/angular/commit/ff15043)), closes [#13686](https://github.com/angular/angular/issues/13686)
* **router:** fix regression where navigateByUrl promise didn't resolve on CanLoad failure ([#26455](https://github.com/angular/angular/issues/26455)) ([1c9b065](https://github.com/angular/angular/commit/1c9b065)), closes [#26284](https://github.com/angular/angular/issues/26284)
* **service-worker:** clean up caches from old SW versions ([#26319](https://github.com/angular/angular/issues/26319)) ([2326b9c](https://github.com/angular/angular/commit/2326b9c))
* **upgrade:** properly destroy upgraded component elements and descendants ([#26209](https://github.com/angular/angular/issues/26209)) ([071934e](https://github.com/angular/angular/commit/071934e)), closes [#26208](https://github.com/angular/angular/issues/26208)
### Features
@ -3084,6 +3035,7 @@ Note: the 6.1.5 release on npm accidentally glitched-out midway, so we cut 6.1.6
### Bug Fixes
* **animations:** always render end-state styles for orphaned DOM nodes ([#24236](https://github.com/angular/angular/issues/24236)) ([dc4a3d0](https://github.com/angular/angular/commit/dc4a3d0))
* **animations:** set animations styles properly on platform-server ([#24624](https://github.com/angular/angular/issues/24624)) ([0b356d4](https://github.com/angular/angular/commit/0b356d4))
* **animations:** do not throw errors when a destroyed component is animated ([#23836](https://github.com/angular/angular/issues/23836)) ([d2a8687](https://github.com/angular/angular/commit/d2a8687))
* **animations:** Fix browser detection logic ([#24188](https://github.com/angular/angular/issues/24188)) ([b492b9e](https://github.com/angular/angular/commit/b492b9e))
* **animations:** properly clean up queried element styles in safari/edge ([#23633](https://github.com/angular/angular/issues/23633)) ([da9ff25](https://github.com/angular/angular/commit/da9ff25))
@ -3095,6 +3047,7 @@ Note: the 6.1.5 release on npm accidentally glitched-out midway, so we cut 6.1.6
* **common:** format fractional seconds ([#24844](https://github.com/angular/angular/issues/24844)) ([0b4d85e](https://github.com/angular/angular/commit/0b4d85e)), closes [#24831](https://github.com/angular/angular/issues/24831)
* **common:** properly update collection reference in NgForOf ([#24684](https://github.com/angular/angular/issues/24684)) ([ff84c5c](https://github.com/angular/angular/commit/ff84c5c)), closes [#24155](https://github.com/angular/angular/issues/24155)
* **common:** use correct currency format for locale de-AT ([#24658](https://github.com/angular/angular/issues/24658)) ([dcabb05](https://github.com/angular/angular/commit/dcabb05)), closes [#24609](https://github.com/angular/angular/issues/24609)
* **common:** use correct ICU plural for locale mk ([#24659](https://github.com/angular/angular/issues/24659)) ([64a8584](https://github.com/angular/angular/commit/64a8584))
* **compiler:** fix a few non-tree-shakeable code patterns ([#24677](https://github.com/angular/angular/issues/24677)) ([50d4a4f](https://github.com/angular/angular/commit/50d4a4f))
* **compiler:** i18n_extractor now outputs the correct source file name ([#24885](https://github.com/angular/angular/issues/24885)) ([c8ad965](https://github.com/angular/angular/commit/c8ad965)), closes [#24884](https://github.com/angular/angular/issues/24884)
* **compiler:** support `.` in import statements. ([#20634](https://github.com/angular/angular/issues/20634)) ([d8f7b29](https://github.com/angular/angular/commit/d8f7b29)), closes [#20363](https://github.com/angular/angular/issues/20363)
@ -3130,6 +3083,7 @@ Note: the 6.1.5 release on npm accidentally glitched-out midway, so we cut 6.1.6
* **service-worker:** don't include sourceMappingURL in ngsw-worker ([#24877](https://github.com/angular/angular/issues/24877)) ([8620373](https://github.com/angular/angular/commit/8620373)), closes [#23596](https://github.com/angular/angular/issues/23596)
* **service-worker:** avoid network requests when looking up hashed resources in cache ([#24127](https://github.com/angular/angular/issues/24127)) ([52d43a9](https://github.com/angular/angular/commit/52d43a9))
* **service-worker:** fix `SwPush.unsubscribe()` ([#24162](https://github.com/angular/angular/issues/24162)) ([3ed2d75](https://github.com/angular/angular/commit/3ed2d75)), closes [#24095](https://github.com/angular/angular/issues/24095)
* **service-worker:** add badge to NOTIFICATION_OPTION_NAMES ([#23241](https://github.com/angular/angular/issues/23241)) ([fb59b2d](https://github.com/angular/angular/commit/fb59b2d)), closes [#23196](https://github.com/angular/angular/issues/23196)
* **service-worker:** check platformBrowser before accessing navigator.serviceWorker ([#21231](https://github.com/angular/angular/issues/21231)) ([0bdd30e](https://github.com/angular/angular/commit/0bdd30e))
* **service-worker:** correctly handle requests with empty `clientId` ([#23625](https://github.com/angular/angular/issues/23625)) ([e0ed59e](https://github.com/angular/angular/commit/e0ed59e)), closes [#23526](https://github.com/angular/angular/issues/23526)
* **service-worker:** deprecate `versionedFiles` in asset-group resources ([#23584](https://github.com/angular/angular/issues/23584)) ([1d378e2](https://github.com/angular/angular/commit/1d378e2))
@ -3330,6 +3284,8 @@ To learn about the release highlights and our new CLI-powered update workflow fo
* **forms:** multiple validators for array method ([#20766](https://github.com/angular/angular/issues/20766)) ([941e88f](https://github.com/angular/angular/commit/941e88f)), closes [#20665](https://github.com/angular/angular/issues/20665)
* **forms:** allow markAsPending to emit events ([#20212](https://github.com/angular/angular/issues/20212)) ([e86b64b](https://github.com/angular/angular/commit/e86b64b)), closes [#17958](https://github.com/angular/angular/issues/17958)
* **platform-browser:** add token marking which the type of animation module nearest in the injector tree ([#23075](https://github.com/angular/angular/issues/23075)) ([b551f84](https://github.com/angular/angular/commit/b551f84))
* **platform-browser:** do not throw error when Hammer.js not loaded ([#22257](https://github.com/angular/angular/issues/22257)) ([991300b](https://github.com/angular/angular/commit/991300b)), closes [#16992](https://github.com/angular/angular/issues/16992)
* **platform-browser:** fix [#19604](https://github.com/angular/angular/issues/19604), can config hammerOptions ([#21979](https://github.com/angular/angular/issues/21979)) ([1d571b2](https://github.com/angular/angular/commit/1d571b2))
* **platform-server:** bump Domino to v2.0 ([#22411](https://github.com/angular/angular/issues/22411)) ([d3827a0](https://github.com/angular/angular/commit/d3827a0))
* **router:** add navigationSource and restoredState to NavigationStart event ([#21728](https://github.com/angular/angular/issues/21728)) ([c40ae7f](https://github.com/angular/angular/commit/c40ae7f))
* **service-worker:** add support for configuring navigations URLs ([#23339](https://github.com/angular/angular/issues/23339)) ([08325aa](https://github.com/angular/angular/commit/08325aa)), closes [#20404](https://github.com/angular/angular/issues/20404)
@ -3548,7 +3504,12 @@ To learn about the release highlights and our new CLI-powered update workflow fo
### Bug Fixes
* **platform-server:** generate correct stylings for camel case names ([#22263](https://github.com/angular/angular/issues/22263)) ([de02a7a](https://github.com/angular/angular/commit/de02a7a)), closes [#19235](https://github.com/angular/angular/issues/19235)
* **router:** don't mutate route configs ([#22358](https://github.com/angular/angular/issues/22358)) ([8f0a064](https://github.com/angular/angular/commit/8f0a064)), closes [#22203](https://github.com/angular/angular/issues/22203)
* **router:** fix URL serialization so special characters are only encoded where needed ([#22337](https://github.com/angular/angular/issues/22337)) ([789a47e](https://github.com/angular/angular/commit/789a47e)), closes [#10280](https://github.com/angular/angular/issues/10280)
* **upgrade:** correctly destroy nested downgraded component ([#22400](https://github.com/angular/angular/issues/22400)) ([4aef9de](https://github.com/angular/angular/commit/4aef9de)), closes [#22392](https://github.com/angular/angular/issues/22392)
* **upgrade:** correctly handle `=` bindings in `@angular/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([6638390](https://github.com/angular/angular/commit/6638390))
* **upgrade:** fix empty transclusion content with AngularJS@>=1.5.8 ([#22167](https://github.com/angular/angular/issues/22167)) ([a9a0e27](https://github.com/angular/angular/commit/a9a0e27)), closes [#22175](https://github.com/angular/angular/issues/22175)
@ -3943,6 +3904,15 @@ Note: Due to an animation fix back in 5.1.1 ([c2b3792](https://github.com/angula
<a name="5.1.0-beta.0"></a>
# [5.1.0-beta.0](https://github.com/angular/angular/compare/5.0.0-rc.4...5.1.0-beta.0) (2017-11-08)
### Bug Fixes
* **compiler:** don't overwrite missingTranslation's value in JIT ([#19952](https://github.com/angular/angular/issues/19952)) ([799cbb9](https://github.com/angular/angular/commit/799cbb9))
* **compiler:** report a reasonable error with invalid metadata ([#20062](https://github.com/angular/angular/issues/20062)) ([da22c48](https://github.com/angular/angular/commit/da22c48))
* **compiler-cli:** don't report emit diagnostics when `--noEmitOnError` is off ([#20063](https://github.com/angular/angular/issues/20063)) ([8639995](https://github.com/angular/angular/commit/8639995))
* **core:** `__symbol__` should return `__zone_symbol__` without zone.js loaded ([#19541](https://github.com/angular/angular/issues/19541)) ([678d1cf](https://github.com/angular/angular/commit/678d1cf))
* **core:** should support event.stopImmediatePropagation ([#19222](https://github.com/angular/angular/issues/19222)) ([7083791](https://github.com/angular/angular/commit/7083791))
* **platform-browser:** support Symbols in custom `jasmineToString()` method ([#19794](https://github.com/angular/angular/issues/19794)) ([5a6efa7](https://github.com/angular/angular/commit/5a6efa7))
### Features
* **compiler:** introduce `TestBed.overrideTemplateUsingTestingModule` ([a460066](https://github.com/angular/angular/commit/a460066)), closes [#19815](https://github.com/angular/angular/issues/19815)
@ -3978,12 +3948,14 @@ Note: Due to an animation fix back in 5.1.1 ([c2b3792](https://github.com/angula
* **compiler-cli:** add watch mode to `ngc` ([#18818](https://github.com/angular/angular/issues/18818)) ([06d01b2](https://github.com/angular/angular/commit/06d01b2))
* **compiler-cli:** lower metadata `useValue` and `data` literal fields ([#18905](https://github.com/angular/angular/issues/18905)) ([0e64261](https://github.com/angular/angular/commit/0e64261))
* **compiler:** add representation of placeholders to xliff & xmb ([b3085e9](https://github.com/angular/angular/commit/b3085e9)), closes [#17345](https://github.com/angular/angular/issues/17345)
* **compiler:** allow multiple exportAs names ([#18723](https://github.com/angular/angular/issues/18723)) ([7ec28fe](https://github.com/angular/angular/commit/7ec28fe))
* **compiler:** enabled strict checking of parameters to an `@Injectable` ([#19412](https://github.com/angular/angular/issues/19412)) ([dfb8d21](https://github.com/angular/angular/commit/dfb8d21))
* **compiler:** make `.ngsummary.json` files portable ([2572bf5](https://github.com/angular/angular/commit/2572bf5))
* **compiler:** reuse the TypeScript typecheck for template typechecking. ([#19152](https://github.com/angular/angular/issues/19152)) ([996c7c2](https://github.com/angular/angular/commit/996c7c2))
* **compiler:** set `enableLegacyTemplate` to false by default ([#18756](https://github.com/angular/angular/issues/18756)) ([56238fe](https://github.com/angular/angular/commit/56238fe))
* **compiler:** use typescript for resolving resource paths ([43226cb](https://github.com/angular/angular/commit/43226cb))
* **core:** Create StaticInjector which does not depend on Reflect polyfill. ([d9d00bd](https://github.com/angular/angular/commit/d9d00bd))
* **core:** add option to remove blank text nodes from compiled templates ([#18823](https://github.com/angular/angular/issues/18823)) ([b8b551c](https://github.com/angular/angular/commit/b8b551c))
* **core:** support for bootstrap with custom zone ([#17672](https://github.com/angular/angular/issues/17672)) ([344a5ca](https://github.com/angular/angular/commit/344a5ca))
* **forms:** add default updateOn values for groups and arrays ([#18536](https://github.com/angular/angular/issues/18536)) ([ff5c58b](https://github.com/angular/angular/commit/ff5c58b))
* **forms:** add options arg to abstract controls ([ebef5e6](https://github.com/angular/angular/commit/ebef5e6))
@ -4342,6 +4314,7 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
* **animations:** properly collect :enter nodes that exist within multi-level DOM trees ([40f77cb](https://github.com/angular/angular/commit/40f77cb)), closes [#17632](https://github.com/angular/angular/issues/17632)
* **animations:** compute removal node height correctly ([185075d](https://github.com/angular/angular/commit/185075d))
* **animations:** do not treat a `0` animation state as `void` ([451257a](https://github.com/angular/angular/commit/451257a))
* **animations:** properly collect :enter nodes in a partially updated collection ([6ca4692](https://github.com/angular/angular/commit/6ca4692)), closes [#17440](https://github.com/angular/angular/issues/17440)
* **animations:** remove duplicate license header ([e096a85](https://github.com/angular/angular/commit/e096a85))
* **common/http:** document HttpClient, fixing a few other issues ([1855989](https://github.com/angular/angular/commit/1855989))
* **common/http:** don't guess Content-Type for FormData bodies ([#18104](https://github.com/angular/angular/issues/18104)) ([4f1e4ff](https://github.com/angular/angular/commit/4f1e4ff)), closes [#18096](https://github.com/angular/angular/issues/18096)
@ -4450,6 +4423,7 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
* **animations:** compute removal node height correctly ([185075d](https://github.com/angular/angular/commit/185075d))
* **animations:** do not treat a `0` animation state as `void` ([451257a](https://github.com/angular/angular/commit/451257a))
* **animations:** properly collect :enter nodes in a partially updated collection ([6ca4692](https://github.com/angular/angular/commit/6ca4692)), closes [#17440](https://github.com/angular/angular/issues/17440)
* **animations:** remove duplicate license header ([b192dd5](https://github.com/angular/angular/commit/b192dd5))
* **forms:** temp roll back breaking change with min/max directives ([b8c39cd](https://github.com/angular/angular/commit/b8c39cd)), closes [#17491](https://github.com/angular/angular/issues/17491)
@ -4685,6 +4659,7 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
* **benchpress:** Update types for TypeScript nullability support ([14669f2](https://github.com/angular/angular/commit/14669f2))
* **common:** Update types for TypeScript nullability support ([d8b73e4](https://github.com/angular/angular/commit/d8b73e4))
* **compiler:** fix build error in xliff2 ([bd704c9](https://github.com/angular/angular/commit/bd704c9))
* **compiler:** fix inheritance for AOT with summaries ([#15583](https://github.com/angular/angular/issues/15583)) ([8ef621a](https://github.com/angular/angular/commit/8ef621a))
* **compiler:** ignore calls to unresolved symbols in metadata ([38a7e0d](https://github.com/angular/angular/commit/38a7e0d)), closes [#15969](https://github.com/angular/angular/issues/15969)
* **compiler:** ignore calls to unresolved symbols in metadata ([#15970](https://github.com/angular/angular/issues/15970)) ([ce47d33](https://github.com/angular/angular/commit/ce47d33)), closes [#15969](https://github.com/angular/angular/issues/15969)
* **compiler:** Inform user where Quoted error was thrown ([a77b126](https://github.com/angular/angular/commit/a77b126))
@ -4701,8 +4676,10 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
* **http:** Update types for TypeScript nullability support ([c36ec9b](https://github.com/angular/angular/commit/c36ec9b))
* **http:** Update types for TypeScript nullability support ([ec028b8](https://github.com/angular/angular/commit/ec028b8))
* **language-service:** avoid throwing exceptions when reporting metadata errors ([7764c5c](https://github.com/angular/angular/commit/7764c5c))
* **language-service:** detect when there isn't a tsconfig.json ([258d539](https://github.com/angular/angular/commit/258d539)), closes [#15874](https://github.com/angular/angular/issues/15874)
* **language-service:** improve resilience to incomplete information ([71a8627](https://github.com/angular/angular/commit/71a8627))
* **language-service:** infer correct type of `?.` expressions ([0a3a9af](https://github.com/angular/angular/commit/0a3a9af)), closes [#15885](https://github.com/angular/angular/issues/15885)
* **language-service:** initialize static reflector correctly ([fe0d02f](https://github.com/angular/angular/commit/fe0d02f)), closes [#15768](https://github.com/angular/angular/issues/15768)
* **language-service:** look for type constructors on canonical symbol ([2ddf3bc](https://github.com/angular/angular/commit/2ddf3bc))
* **language-service:** only use canonical symbols ([5a88d2f](https://github.com/angular/angular/commit/5a88d2f))
* **language-service:** parse extended i18n forms ([bde9771](https://github.com/angular/angular/commit/bde9771))
@ -4727,6 +4704,7 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
### Features
* **animations:** Update types for TypeScript nullability support ([38d75d4](https://github.com/angular/angular/commit/38d75d4)), closes [#15870](https://github.com/angular/angular/issues/15870)
* **compiler:** add source files to xmb/xliff translations ([#14705](https://github.com/angular/angular/issues/14705)) ([4054055](https://github.com/angular/angular/commit/4054055)), closes [#14190](https://github.com/angular/angular/issues/14190)
* **compiler:** Implement i18n XLIFF 2.0 serializer ([#14185](https://github.com/angular/angular/issues/14185)) ([09c4cb2](https://github.com/angular/angular/commit/09c4cb2)), closes [#11735](https://github.com/angular/angular/issues/11735)
* **upgrade:** allow setting the angularjs lib at runtime ([#15168](https://github.com/angular/angular/issues/15168)) ([e927aea](https://github.com/angular/angular/commit/e927aea))
@ -5464,18 +5442,27 @@ returned value being an array.
### Bug Fixes
* **animations:** fix internal jscompiler issue and AOT quoting ([#13798](https://github.com/angular/angular/issues/13798)) ([c2aa981](https://github.com/angular/angular/commit/c2aa981))
* **common:** support numeric value as discrete cases for NgPlural ([#13876](https://github.com/angular/angular/issues/13876)) ([f364557](https://github.com/angular/angular/commit/f364557))
* **compiler:** [i18n] XMB/XTB placeholder names can contain only A-Z, 0-9, _n ([d02eab4](https://github.com/angular/angular/commit/d02eab4))
* **compiler:** fix regexp to support firefox 31 ([#14082](https://github.com/angular/angular/issues/14082)) ([b2f9d56](https://github.com/angular/angular/commit/b2f9d56)), closes [#14029](https://github.com/angular/angular/issues/14029) [#13900](https://github.com/angular/angular/issues/13900)
* **core:** export animation classes required for Renderer impl ([#14002](https://github.com/angular/angular/issues/14002)) ([83361d8](https://github.com/angular/angular/commit/83361d8)), closes [#14001](https://github.com/angular/angular/issues/14001)
* **core:** fix not declared variable in view engine ([#14045](https://github.com/angular/angular/issues/14045)) ([d3a3a8e](https://github.com/angular/angular/commit/d3a3a8e))
* **http:** don't create a blob out of ArrayBuffer when type is application/octet-stream ([#13992](https://github.com/angular/angular/issues/13992)) ([1200cf2](https://github.com/angular/angular/commit/1200cf2)), closes [#13973](https://github.com/angular/angular/issues/13973)
* **router:** enable loadChildren with function in aot ([#13909](https://github.com/angular/angular/issues/13909)) ([635bf02](https://github.com/angular/angular/commit/635bf02)), closes [#11075](https://github.com/angular/angular/issues/11075)
* **router:** routerLinkActive should not throw when not initialized ([#13273](https://github.com/angular/angular/issues/13273)) ([e8ea741](https://github.com/angular/angular/commit/e8ea741)), closes [#13270](https://github.com/angular/angular/issues/13270)
* **upgrade:** detect async downgrade component changes ([#13812](https://github.com/angular/angular/issues/13812)) ([d6382bf](https://github.com/angular/angular/commit/d6382bf)), closes [#6385](https://github.com/angular/angular/issues/6385) [#6385](https://github.com/angular/angular/issues/6385) [#10660](https://github.com/angular/angular/issues/10660) [#12318](https://github.com/angular/angular/issues/12318) [#12034](https://github.com/angular/angular/issues/12034)
* **upgrade/static:** ensure upgraded injector is initialized early enough ([#14065](https://github.com/angular/angular/issues/14065)) ([6152eb2](https://github.com/angular/angular/commit/6152eb2)), closes [#13811](https://github.com/angular/angular/issues/13811)
### Features
* **build:** optionally build an ES2015 distro ([#13471](https://github.com/angular/angular/issues/13471)) ([be6c95a](https://github.com/angular/angular/commit/be6c95a))
* **core:** add event support to view engine ([0adb97b](https://github.com/angular/angular/commit/0adb97b))
* **core:** add initial view engine ([#14014](https://github.com/angular/angular/issues/14014)) ([2f87eb5](https://github.com/angular/angular/commit/2f87eb5))
* **core:** add pure expression support to view engine ([6541737](https://github.com/angular/angular/commit/6541737))
* **core:** Add type information to injector.get() ([#13785](https://github.com/angular/angular/issues/13785)) ([d169c24](https://github.com/angular/angular/commit/d169c24))
* **security:** allow calc and gradient functions. ([#13943](https://github.com/angular/angular/issues/13943)) ([e19bf70](https://github.com/angular/angular/commit/e19bf70))
* **tsc-wrapped:** Support of vinyl like config file was added ([#13987](https://github.com/angular/angular/issues/13987)) ([0c7726d](https://github.com/angular/angular/commit/0c7726d))
* **upgrade:** Support ng-model in downgraded components ([#10578](https://github.com/angular/angular/issues/10578)) ([e21e9c5](https://github.com/angular/angular/commit/e21e9c5))
@ -6003,12 +5990,19 @@ Note: The 2.3.0-beta.0 release also contains all the changes present in the 2.2.
### Features (summary of all features from 2.2.0-beta.0 - 2.2.0-rc.0 releases)
* **common:** support narrow forms for month and weekdays in DatePipe ([#12297](https://github.com/angular/angular/issues/12297)) ([f77ab6a](https://github.com/angular/angular/commit/f77ab6a)), closes [#12294](https://github.com/angular/angular/issues/12294)
* **core:** map 'for' attribute to 'htmlFor' property ([#10546](https://github.com/angular/angular/issues/10546)) ([634b3bb](https://github.com/angular/angular/commit/634b3bb)), closes [#7516](https://github.com/angular/angular/issues/7516)
* **core:** add the find method to QueryList ([7c16ef9](https://github.com/angular/angular/commit/7c16ef9))
* **forms:** add hasError and getError to AbstractControlDirective ([#11985](https://github.com/angular/angular/issues/11985)) ([592f40a](https://github.com/angular/angular/commit/592f40a)), closes [#7255](https://github.com/angular/angular/issues/7255)
* **forms:** add ng-pending CSS class during async validation ([#11243](https://github.com/angular/angular/issues/11243)) ([97bc971](https://github.com/angular/angular/commit/97bc971)), closes [#10336](https://github.com/angular/angular/issues/10336)
* **forms:** add emitEvent to AbstractControl methods ([#11949](https://github.com/angular/angular/issues/11949)) ([b9fc090](https://github.com/angular/angular/commit/b9fc090))
* **forms:** make 'parent' a public property of 'AbstractControl' ([#11855](https://github.com/angular/angular/issues/11855)) ([445e592](https://github.com/angular/angular/commit/445e592))
* **forms:** Validator.pattern accepts a RegExp ([#12323](https://github.com/angular/angular/issues/12323)) ([bf60418](https://github.com/angular/angular/commit/bf60418))
* **router:** add a provider making angular1/angular2 integration easier ([#12769](https://github.com/angular/angular/issues/12769)) ([6e35d13](https://github.com/angular/angular/commit/6e35d13))
* **router:** add support for custom url matchers ([7340735](https://github.com/angular/angular/commit/7340735)), closes [#12442](https://github.com/angular/angular/issues/12442) [#12772](https://github.com/angular/angular/issues/12772)
* **router:** export routerLinkActive w/ isActive property ([c9f58cf](https://github.com/angular/angular/commit/c9f58cf))
* **router:** add support for ng1/ng2 migration ([#12160](https://github.com/angular/angular/issues/12160)) ([8b9ab44](https://github.com/angular/angular/commit/8b9ab44))
* **upgrade:** add support for AoT compiled upgrade applications ([d6791ff](https://github.com/angular/angular/commit/d6791ff)), closes [#12239](https://github.com/angular/angular/issues/12239)
* **upgrade:** add support for `require` in UpgradeComponent ([fe1d0e2](https://github.com/angular/angular/commit/fe1d0e2))
* **upgrade:** add/improve support for lifecycle hooks in UpgradeComponent ([469010e](https://github.com/angular/angular/commit/469010e))

View File

@ -230,6 +230,7 @@ Must be one of the following:
* **fix**: A bug fix
* **perf**: A code change that improves performance
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
* **test**: Adding missing tests or correcting existing tests

View File

@ -1,31 +1,31 @@
import { TestBed, waitForAsync } from '@angular/core/testing';
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { ReactiveModule } from './reactive/reactive.module';
import { TemplateModule } from './template/template.module';
import { ReactiveModule } from './reactive/reactive.module';
describe('AppComponent', () => {
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
imports: [ReactiveModule, TemplateModule],
declarations: [AppComponent],
})
.compileComponents();
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ReactiveModule, TemplateModule],
declarations: [
AppComponent
],
}).compileComponents();
}));
it('should create the app', waitForAsync(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
it('should create the app', async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
}));
expect(app).toBeTruthy();
}));
it('should render title', waitForAsync(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
it('should render title', async(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Forms Overview');
}));
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Forms Overview');
}));
});

View File

@ -1,18 +1,19 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms';
import { createNewEvent } from '../../shared/utils';
import { FavoriteColorComponent } from './favorite-color.component';
import { createNewEvent } from '../../shared/utils';
describe('Favorite Color Component', () => {
let component: FavoriteColorComponent;
let fixture: ComponentFixture<FavoriteColorComponent>;
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule(
{imports: [ReactiveFormsModule], declarations: [FavoriteColorComponent]})
.compileComponents();
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ ReactiveFormsModule ],
declarations: [ FavoriteColorComponent ]
})
.compileComponents();
}));
beforeEach(() => {

View File

@ -1,16 +1,19 @@
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { async, ComponentFixture, TestBed, tick, fakeAsync } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { createNewEvent } from '../../shared/utils';
import { FavoriteColorComponent } from './favorite-color.component';
import { createNewEvent } from '../../shared/utils';
describe('FavoriteColorComponent', () => {
let component: FavoriteColorComponent;
let fixture: ComponentFixture<FavoriteColorComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({imports: [FormsModule], declarations: [FavoriteColorComponent]})
.compileComponents();
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ FormsModule ],
declarations: [ FavoriteColorComponent ]
})
.compileComponents();
}));
beforeEach(() => {
@ -25,29 +28,29 @@ describe('FavoriteColorComponent', () => {
// #docregion model-to-view
it('should update the favorite color on the input field', fakeAsync(() => {
component.favoriteColor = 'Blue';
component.favoriteColor = 'Blue';
fixture.detectChanges();
fixture.detectChanges();
tick();
tick();
const input = fixture.nativeElement.querySelector('input');
const input = fixture.nativeElement.querySelector('input');
expect(input.value).toBe('Blue');
}));
expect(input.value).toBe('Blue');
}));
// #enddocregion model-to-view
// #docregion view-to-model
it('should update the favorite color in the component', fakeAsync(() => {
const input = fixture.nativeElement.querySelector('input');
const event = createNewEvent('input');
const input = fixture.nativeElement.querySelector('input');
const event = createNewEvent('input');
input.value = 'Red';
input.dispatchEvent(event);
input.value = 'Red';
input.dispatchEvent(event);
fixture.detectChanges();
fixture.detectChanges();
expect(component.favoriteColor).toEqual('Red');
}));
expect(component.favoriteColor).toEqual('Red');
}));
// #enddocregion view-to-model
});

View File

@ -1,4 +1,4 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MyLibComponent } from './my-lib.component';
@ -6,8 +6,11 @@ describe('MyLibComponent', () => {
let component: MyLibComponent;
let fixture: ComponentFixture<MyLibComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({declarations: [MyLibComponent]}).compileComponents();
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MyLibComponent ]
})
.compileComponents();
}));
beforeEach(() => {

View File

@ -1,16 +1,19 @@
import { DebugElement } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
describe('AppComponent', () => {
let de: DebugElement;
let comp: AppComponent;
let fixture: ComponentFixture<AppComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({declarations: [AppComponent]}).compileComponents();
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AppComponent ]
})
.compileComponents();
}));
beforeEach(() => {
@ -19,11 +22,12 @@ describe('AppComponent', () => {
de = fixture.debugElement.query(By.css('h1'));
});
it('should create component', () => expect(comp).toBeDefined());
it('should create component', () => expect(comp).toBeDefined() );
it('should have expected <h1> text', () => {
fixture.detectChanges();
const h1 = de.nativeElement;
expect(h1.textContent).toMatch(/angular/i, '<h1> should say something about "Angular"');
expect(h1.textContent).toMatch(/angular/i,
'<h1> should say something about "Angular"');
});
});

View File

@ -11,7 +11,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>

View File

@ -10,8 +10,8 @@ import { Hero } from '../shared/hero.model';
template: `
<section>
Our list of heroes:
<toh-hero *ngFor="let hero of heroes" [hero]="hero">
</toh-hero>
<hero-profile *ngFor="let hero of heroes" [hero]="hero">
</hero-profile>
Total powers: {{totalPowers}}<br>
Average power: {{totalPowers / heroes.length}}
</section>

View File

@ -1,6 +1,6 @@
// #docplaster
// #docregion
import { TestBed, waitForAsync } from '@angular/core/testing';
import { TestBed, async } from '@angular/core/testing';
// #enddocregion
import { AppComponent } from './app-initial.component';
/*
@ -12,29 +12,29 @@ describe('AppComponent', () => {
*/
describe('AppComponent (initial CLI version)', () => {
// #docregion
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
declarations: [AppComponent],
})
.compileComponents();
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent
],
}).compileComponents();
}));
it('should create the app', async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
}));
it(`should have as title 'app'`, async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('app');
}));
it('should render title', async(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
}));
it('should create the app', waitForAsync(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
}));
it(`should have as title 'app'`, waitForAsync(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('app');
}));
it('should render title', waitForAsync(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
}));
});
// #enddocregion
@ -43,13 +43,16 @@ import { DebugElement } from '@angular/core';
import { ComponentFixture } from '@angular/core/testing';
describe('AppComponent (initial CLI version - as it should be)', () => {
let app: AppComponent;
let de: DebugElement;
let fixture: ComponentFixture<AppComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [AppComponent],
declarations: [
AppComponent
],
});
fixture = TestBed.createComponent(AppComponent);
@ -67,6 +70,7 @@ describe('AppComponent (initial CLI version - as it should be)', () => {
it('should render title in an h1 tag', () => {
fixture.detectChanges();
expect(de.nativeElement.querySelector('h1').textContent).toContain('Welcome to app!');
expect(de.nativeElement.querySelector('h1').textContent)
.toContain('Welcome to app!');
});
});

View File

@ -1,7 +1,7 @@
// For more examples:
// https://github.com/angular/angular/blob/master/modules/@angular/router/test/integration.spec.ts
import { waitForAsync, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { asyncData } from '../testing';
@ -21,9 +21,9 @@ import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { AboutComponent } from './about/about.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { TwainService } from './twain/twain.service';
import { HeroService, TestHeroService } from './model/testing/test-hero.service';
import { TwainService } from './twain/twain.service';
let comp: AppComponent;
let fixture: ComponentFixture<AppComponent>;
@ -32,51 +32,54 @@ let router: Router;
let location: SpyLocation;
describe('AppComponent & RouterTestingModule', () => {
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
imports: [
AppModule,
RouterTestingModule.withRoutes(routes),
],
providers: [{provide: HeroService, useClass: TestHeroService}]
})
.compileComponents();
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
AppModule,
RouterTestingModule.withRoutes(routes),
],
providers: [
{ provide: HeroService, useClass: TestHeroService }
]
})
.compileComponents();
}));
it('should navigate to "Dashboard" immediately', fakeAsync(() => {
createComponent();
tick(); // wait for async data to arrive
expectPathToBe('/dashboard', 'after initialNavigation()');
expectElementOf(DashboardComponent);
}));
createComponent();
tick(); // wait for async data to arrive
expectPathToBe('/dashboard', 'after initialNavigation()');
expectElementOf(DashboardComponent);
}));
it('should navigate to "About" on click', fakeAsync(() => {
createComponent();
click(page.aboutLinkDe);
// page.aboutLinkDe.nativeElement.click(); // ok but fails in phantom
createComponent();
click(page.aboutLinkDe);
// page.aboutLinkDe.nativeElement.click(); // ok but fails in phantom
advance();
expectPathToBe('/about');
expectElementOf(AboutComponent);
}));
advance();
expectPathToBe('/about');
expectElementOf(AboutComponent);
}));
it('should navigate to "About" w/ browser location URL change', fakeAsync(() => {
createComponent();
location.simulateHashChange('/about');
// location.go('/about'); // also works ... except, perhaps, in Stackblitz
advance();
expectPathToBe('/about');
expectElementOf(AboutComponent);
}));
createComponent();
location.simulateHashChange('/about');
// location.go('/about'); // also works ... except, perhaps, in Stackblitz
advance();
expectPathToBe('/about');
expectElementOf(AboutComponent);
}));
// Can't navigate to lazy loaded modules with this technique
xit('should navigate to "Heroes" on click (not working yet)', fakeAsync(() => {
createComponent();
page.heroesLinkDe.nativeElement.click();
advance();
expectPathToBe('/heroes');
}));
createComponent();
page.heroesLinkDe.nativeElement.click();
advance();
expectPathToBe('/heroes');
}));
});
@ -91,37 +94,37 @@ let loader: SpyNgModuleFactoryLoader;
///////// Can't get lazy loaded Heroes to work yet
xdescribe('AppComponent & Lazy Loading (not working yet)', () => {
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
imports: [
AppModule,
RouterTestingModule.withRoutes(routes),
],
})
.compileComponents();
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
AppModule,
RouterTestingModule.withRoutes(routes),
],
})
.compileComponents();
}));
beforeEach(fakeAsync(() => {
createComponent();
loader = TestBed.inject(NgModuleFactoryLoader) as SpyNgModuleFactoryLoader;
loader.stubbedModules = {expected: HeroModule};
loader.stubbedModules = { expected: HeroModule };
router.resetConfig([{path: 'heroes', loadChildren: 'expected'}]);
}));
it('should navigate to "Heroes" on click', waitForAsync(() => {
page.heroesLinkDe.nativeElement.click();
advance();
expectPathToBe('/heroes');
expectElementOf(HeroListComponent);
}));
it('should navigate to "Heroes" on click', async(() => {
page.heroesLinkDe.nativeElement.click();
advance();
expectPathToBe('/heroes');
expectElementOf(HeroListComponent);
}));
it('can navigate to "Heroes" w/ browser location URL change', fakeAsync(() => {
location.go('/heroes');
advance();
expectPathToBe('/heroes');
expectElementOf(HeroListComponent);
}));
location.go('/heroes');
advance();
expectPathToBe('/heroes');
expectElementOf(HeroListComponent);
}));
});
////// Helpers /////////
@ -131,9 +134,9 @@ xdescribe('AppComponent & Lazy Loading (not working yet)', () => {
* Wait a tick, then detect changes, and tick again
*/
function advance(): void {
tick(); // wait while navigating
fixture.detectChanges(); // update view
tick(); // wait for async data to arrive
tick(); // wait while navigating
fixture.detectChanges(); // update view
tick(); // wait for async data to arrive
}
function createComponent() {
@ -145,8 +148,8 @@ function createComponent() {
router = injector.get(Router);
router.initialNavigation();
spyOn(injector.get(TwainService), 'getQuote')
// fake fast async observable
.and.returnValue(asyncData('Test Quote'));
// fake fast async observable
.and.returnValue(asyncData('Test Quote'));
advance();
page = new Page();
@ -165,14 +168,14 @@ class Page {
constructor() {
const links = fixture.debugElement.queryAll(By.directive(RouterLinkWithHref));
this.aboutLinkDe = links[2];
this.aboutLinkDe = links[2];
this.dashboardLinkDe = links[0];
this.heroesLinkDe = links[1];
this.heroesLinkDe = links[1];
// for debugging
this.comp = comp;
this.comp = comp;
this.fixture = fixture;
this.router = router;
this.router = router;
}
}

View File

@ -1,70 +1,66 @@
// #docplaster
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { Component, DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { RouterLinkDirectiveStub } from '../testing';
import { AppComponent } from './app.component';
import { RouterLinkDirectiveStub } from '../testing';
// #docregion component-stubs
@Component({selector: 'app-banner', template: ''})
class BannerStubComponent {
}
class BannerStubComponent {}
@Component({selector: 'router-outlet', template: ''})
class RouterOutletStubComponent {
}
class RouterOutletStubComponent { }
@Component({selector: 'app-welcome', template: ''})
class WelcomeStubComponent {
}
class WelcomeStubComponent {}
// #enddocregion component-stubs
let comp: AppComponent;
let fixture: ComponentFixture<AppComponent>;
describe('AppComponent & TestModule', () => {
beforeEach(waitForAsync(() => {
beforeEach(async(() => {
// #docregion testbed-stubs
TestBed
.configureTestingModule({
declarations: [
AppComponent, RouterLinkDirectiveStub, BannerStubComponent, RouterOutletStubComponent,
WelcomeStubComponent
]
})
// #enddocregion testbed-stubs
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(AppComponent);
comp = fixture.componentInstance;
});
TestBed.configureTestingModule({
declarations: [
AppComponent,
RouterLinkDirectiveStub,
BannerStubComponent,
RouterOutletStubComponent,
WelcomeStubComponent
]
})
// #enddocregion testbed-stubs
.compileComponents().then(() => {
fixture = TestBed.createComponent(AppComponent);
comp = fixture.componentInstance;
});
}));
tests();
});
//////// Testing w/ NO_ERRORS_SCHEMA //////
describe('AppComponent & NO_ERRORS_SCHEMA', () => {
beforeEach(waitForAsync(() => {
beforeEach(async(() => {
// #docregion no-errors-schema, mixed-setup
TestBed
.configureTestingModule({
declarations: [
AppComponent,
// #enddocregion no-errors-schema
BannerStubComponent,
// #docregion no-errors-schema
RouterLinkDirectiveStub
],
schemas: [NO_ERRORS_SCHEMA]
})
// #enddocregion no-errors-schema, mixed-setup
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(AppComponent);
comp = fixture.componentInstance;
});
TestBed.configureTestingModule({
declarations: [
AppComponent,
// #enddocregion no-errors-schema
BannerStubComponent,
// #docregion no-errors-schema
RouterLinkDirectiveStub
],
schemas: [ NO_ERRORS_SCHEMA ]
})
// #enddocregion no-errors-schema, mixed-setup
.compileComponents().then(() => {
fixture = TestBed.createComponent(AppComponent);
comp = fixture.componentInstance;
});
}));
tests();
});
@ -76,23 +72,30 @@ import { AppModule } from './app.module';
import { AppRoutingModule } from './app-routing.module';
describe('AppComponent & AppModule', () => {
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({imports: [AppModule]})
// Get rid of app's Router configuration otherwise many failures.
// Doing so removes Router declarations; add the Router stubs
.overrideModule(AppModule, {
remove: {imports: [AppRoutingModule]},
add: {declarations: [RouterLinkDirectiveStub, RouterOutletStubComponent]}
})
beforeEach(async(() => {
.compileComponents()
TestBed.configureTestingModule({
imports: [ AppModule ]
})
.then(() => {
fixture = TestBed.createComponent(AppComponent);
comp = fixture.componentInstance;
});
// Get rid of app's Router configuration otherwise many failures.
// Doing so removes Router declarations; add the Router stubs
.overrideModule(AppModule, {
remove: {
imports: [ AppRoutingModule ]
},
add: {
declarations: [ RouterLinkDirectiveStub, RouterOutletStubComponent ]
}
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(AppComponent);
comp = fixture.componentInstance;
});
}));
tests();
@ -104,10 +107,11 @@ function tests() {
// #docregion test-setup
beforeEach(() => {
fixture.detectChanges(); // trigger initial data binding
fixture.detectChanges(); // trigger initial data binding
// find DebugElements with an attached RouterLinkStubDirective
linkDes = fixture.debugElement.queryAll(By.directive(RouterLinkDirectiveStub));
linkDes = fixture.debugElement
.queryAll(By.directive(RouterLinkDirectiveStub));
// get attached link directive instances
// using each DebugElement's injector
@ -128,8 +132,8 @@ function tests() {
});
it('can click Heroes link in template', () => {
const heroesLinkDe = linkDes[1]; // heroes link DebugElement
const heroesLink = routerLinks[1]; // heroes link directive
const heroesLinkDe = linkDes[1]; // heroes link DebugElement
const heroesLink = routerLinks[1]; // heroes link directive
expect(heroesLink.navigatedTo).toBeNull('should not have navigated yet');

View File

@ -1,6 +1,6 @@
// #docplaster
// #docregion import-async
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
// #enddocregion import-async
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
@ -14,12 +14,11 @@ describe('BannerComponent (external files)', () => {
describe('Two beforeEach', () => {
// #docregion async-before-each
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
declarations: [BannerComponent],
})
.compileComponents(); // compile template and css
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BannerComponent ],
})
.compileComponents(); // compile template and css
}));
// #enddocregion async-before-each
@ -27,7 +26,7 @@ describe('BannerComponent (external files)', () => {
// #docregion sync-before-each
beforeEach(() => {
fixture = TestBed.createComponent(BannerComponent);
component = fixture.componentInstance; // BannerComponent test instance
component = fixture.componentInstance; // BannerComponent test instance
h1 = fixture.nativeElement.querySelector('h1');
});
// #enddocregion sync-before-each
@ -37,17 +36,16 @@ describe('BannerComponent (external files)', () => {
describe('One beforeEach', () => {
// #docregion one-before-each
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
declarations: [BannerComponent],
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(BannerComponent);
component = fixture.componentInstance;
h1 = fixture.nativeElement.querySelector('h1');
});
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BannerComponent ],
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(BannerComponent);
component = fixture.componentInstance;
h1 = fixture.nativeElement.querySelector('h1');
});
}));
// #enddocregion one-before-each
@ -71,3 +69,4 @@ describe('BannerComponent (external files)', () => {
});
}
});

View File

@ -1,16 +1,14 @@
// #docplaster
// #docregion import-by
import { By } from '@angular/platform-browser';
// #enddocregion import-by
// #docregion import-debug-element
import { DebugElement } from '@angular/core';
// #enddocregion import-debug-element
// #docregion v1
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
// #enddocregion v1
import { BannerComponent } from './banner-initial.component';
/*
// #docregion v1
import { BannerComponent } from './banner.component';
@ -19,12 +17,15 @@ describe('BannerComponent', () => {
// #enddocregion v1
*/
describe('BannerComponent (initial CLI generated)', () => {
// #docregion v1
// #docregion v1
let component: BannerComponent;
let fixture: ComponentFixture<BannerComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({declarations: [BannerComponent]}).compileComponents();
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BannerComponent ]
})
.compileComponents();
}));
beforeEach(() => {
@ -43,7 +44,9 @@ describe('BannerComponent (initial CLI generated)', () => {
describe('BannerComponent (minimal)', () => {
it('should create', () => {
// #docregion configureTestingModule
TestBed.configureTestingModule({declarations: [BannerComponent]});
TestBed.configureTestingModule({
declarations: [ BannerComponent ]
});
// #enddocregion configureTestingModule
// #docregion createComponent
const fixture = TestBed.createComponent(BannerComponent);
@ -62,7 +65,9 @@ describe('BannerComponent (with beforeEach)', () => {
let fixture: ComponentFixture<BannerComponent>;
beforeEach(() => {
TestBed.configureTestingModule({declarations: [BannerComponent]});
TestBed.configureTestingModule({
declarations: [ BannerComponent ]
});
fixture = TestBed.createComponent(BannerComponent);
component = fixture.componentInstance;
});

View File

@ -1,21 +1,22 @@
// #docplaster
import { DebugElement } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { addMatchers, click } from '../../testing';
import { Hero } from '../model/hero';
import { Hero } from '../model/hero';
import { DashboardHeroComponent } from './dashboard-hero.component';
beforeEach(addMatchers);
beforeEach( addMatchers );
describe('DashboardHeroComponent class only', () => {
// #docregion class-only
it('raises the selected event when clicked', () => {
const comp = new DashboardHeroComponent();
const hero: Hero = {id: 42, name: 'Test'};
const hero: Hero = { id: 42, name: 'Test' };
comp.hero = hero;
comp.selected.subscribe((selectedHero: Hero) => expect(selectedHero).toBe(hero));
@ -25,31 +26,33 @@ describe('DashboardHeroComponent class only', () => {
});
describe('DashboardHeroComponent when tested directly', () => {
let comp: DashboardHeroComponent;
let expectedHero: Hero;
let fixture: ComponentFixture<DashboardHeroComponent>;
let heroDe: DebugElement;
let heroEl: HTMLElement;
beforeEach(waitForAsync(() => {
beforeEach(async(() => {
// #docregion setup, config-testbed
TestBed
.configureTestingModule({declarations: [DashboardHeroComponent]})
// #enddocregion setup, config-testbed
.compileComponents();
TestBed.configureTestingModule({
declarations: [ DashboardHeroComponent ]
})
// #enddocregion setup, config-testbed
.compileComponents();
}));
beforeEach(() => {
// #docregion setup
fixture = TestBed.createComponent(DashboardHeroComponent);
comp = fixture.componentInstance;
comp = fixture.componentInstance;
// find the hero's DebugElement and element
heroDe = fixture.debugElement.query(By.css('.hero'));
heroDe = fixture.debugElement.query(By.css('.hero'));
heroEl = heroDe.nativeElement;
// mock the hero supplied by the parent component
expectedHero = {id: 42, name: 'Test Name'};
expectedHero = { id: 42, name: 'Test Name' };
// simulate the parent setting the input property with that hero
comp.hero = expectedHero;
@ -93,8 +96,8 @@ describe('DashboardHeroComponent when tested directly', () => {
let selectedHero: Hero;
comp.selected.subscribe((hero: Hero) => selectedHero = hero);
click(heroDe); // click helper with DebugElement
click(heroEl); // click helper with native element
click(heroDe); // click helper with DebugElement
click(heroEl); // click helper with native element
expect(selectedHero).toBe(expectedHero);
});
@ -108,21 +111,22 @@ describe('DashboardHeroComponent when inside a test host', () => {
let fixture: ComponentFixture<TestHostComponent>;
let heroEl: HTMLElement;
beforeEach(waitForAsync(() => {
beforeEach(async(() => {
// #docregion test-host-setup
TestBed
.configureTestingModule({declarations: [DashboardHeroComponent, TestHostComponent]})
// #enddocregion test-host-setup
.compileComponents();
TestBed.configureTestingModule({
declarations: [ DashboardHeroComponent, TestHostComponent ]
})
// #enddocregion test-host-setup
.compileComponents();
}));
beforeEach(() => {
// #docregion test-host-setup
// create TestHostComponent instead of DashboardHeroComponent
fixture = TestBed.createComponent(TestHostComponent);
fixture = TestBed.createComponent(TestHostComponent);
testHost = fixture.componentInstance;
heroEl = fixture.nativeElement.querySelector('.hero');
fixture.detectChanges(); // trigger initial data binding
heroEl = fixture.nativeElement.querySelector('.hero');
fixture.detectChanges(); // trigger initial data binding
// #enddocregion test-host-setup
});
@ -151,10 +155,8 @@ import { Component } from '@angular/core';
</dashboard-hero>`
})
class TestHostComponent {
hero: Hero = {id: 42, name: 'Test Name'};
hero: Hero = {id: 42, name: 'Test Name' };
selectedHero: Hero;
onSelected(hero: Hero) {
this.selectedHero = hero;
}
onSelected(hero: Hero) { this.selectedHero = hero; }
}
// #enddocregion test-host

View File

@ -1,5 +1,6 @@
// #docplaster
import { ComponentFixture, inject, TestBed, waitForAsync } from '@angular/core/testing';
import { async, inject, ComponentFixture, TestBed
} from '@angular/core/testing';
import { addMatchers, asyncData, click } from '../../testing';
import { HeroService } from '../model/hero.service';
@ -11,7 +12,7 @@ import { Router } from '@angular/router';
import { DashboardComponent } from './dashboard.component';
import { DashboardModule } from './dashboard.module';
beforeEach(addMatchers);
beforeEach ( addMatchers );
let comp: DashboardComponent;
let fixture: ComponentFixture<DashboardComponent>;
@ -20,7 +21,9 @@ let fixture: ComponentFixture<DashboardComponent>;
describe('DashboardComponent (deep)', () => {
beforeEach(() => {
TestBed.configureTestingModule({imports: [DashboardModule]});
TestBed.configureTestingModule({
imports: [ DashboardModule ]
});
});
compileAndCreate();
@ -40,8 +43,10 @@ import { NO_ERRORS_SCHEMA } from '@angular/core';
describe('DashboardComponent (shallow)', () => {
beforeEach(() => {
TestBed.configureTestingModule(
{declarations: [DashboardComponent], schemas: [NO_ERRORS_SCHEMA]});
TestBed.configureTestingModule({
declarations: [ DashboardComponent ],
schemas: [NO_ERRORS_SCHEMA]
});
});
compileAndCreate();
@ -58,26 +63,25 @@ describe('DashboardComponent (shallow)', () => {
/** Add TestBed providers, compile, and create DashboardComponent */
function compileAndCreate() {
// #docregion compile-and-create-body
beforeEach(waitForAsync(() => {
beforeEach(async(() => {
// #docregion router-spy
const routerSpy = jasmine.createSpyObj('Router', ['navigateByUrl']);
const heroServiceSpy = jasmine.createSpyObj('HeroService', ['getHeroes']);
TestBed
.configureTestingModule({
providers: [
{provide: HeroService, useValue: heroServiceSpy}, {provide: Router, useValue: routerSpy}
]
})
// #enddocregion router-spy
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(DashboardComponent);
comp = fixture.componentInstance;
TestBed.configureTestingModule({
providers: [
{ provide: HeroService, useValue: heroServiceSpy },
{ provide: Router, useValue: routerSpy }
]
})
// #enddocregion router-spy
.compileComponents().then(() => {
fixture = TestBed.createComponent(DashboardComponent);
comp = fixture.componentInstance;
// getHeroes spy returns observable of test heroes
heroServiceSpy.getHeroes.and.returnValue(asyncData(getTestHeroes()));
});
// getHeroes spy returns observable of test heroes
heroServiceSpy.getHeroes.and.returnValue(asyncData(getTestHeroes()));
});
// #enddocregion compile-and-create-body
}));
}
@ -89,20 +93,23 @@ function compileAndCreate() {
function tests(heroClick: () => void) {
it('should NOT have heroes before ngOnInit', () => {
expect(comp.heroes.length).toBe(0, 'should not have heroes before ngOnInit');
expect(comp.heroes.length).toBe(0,
'should not have heroes before ngOnInit');
});
it('should NOT have heroes immediately after ngOnInit', () => {
fixture.detectChanges(); // runs initial lifecycle hooks
fixture.detectChanges(); // runs initial lifecycle hooks
expect(comp.heroes.length).toBe(0, 'should not have heroes until service promise resolves');
expect(comp.heroes.length).toBe(0,
'should not have heroes until service promise resolves');
});
describe('after get dashboard heroes', () => {
let router: Router;
// Trigger component so it gets heroes and binds to them
beforeEach(waitForAsync(() => {
beforeEach(async(() => {
router = fixture.debugElement.injector.get(Router);
fixture.detectChanges(); // runs ngOnInit -> getHeroes
fixture.whenStable() // No need for the `lastPromise` hack!
@ -110,8 +117,8 @@ function tests(heroClick: () => void) {
}));
it('should HAVE heroes', () => {
expect(comp.heroes.length)
.toBeGreaterThan(0, 'should have heroes after service promise resolves');
expect(comp.heroes.length).toBeGreaterThan(0,
'should have heroes after service promise resolves');
});
it('should DISPLAY heroes', () => {
@ -123,7 +130,8 @@ function tests(heroClick: () => void) {
// #docregion navigate-test
it('should tell ROUTER to navigate when hero clicked', () => {
heroClick(); // trigger click on first inner <div class="hero">
heroClick(); // trigger click on first inner <div class="hero">
// args passed to router.navigateByUrl() spy
const spy = router.navigateByUrl as jasmine.Spy;
@ -131,8 +139,10 @@ function tests(heroClick: () => void) {
// expecting to navigate to id of the component's first hero
const id = comp.heroes[0].id;
expect(navArgs).toBe('/heroes/' + id, 'should nav to HeroDetail for first hero');
expect(navArgs).toBe('/heroes/' + id,
'should nav to HeroDetail for first hero');
});
// #enddocregion navigate-test
});
}

View File

@ -1,23 +1,18 @@
// tslint:disable-next-line:no-unused-variable
import { fakeAsync, tick, waitForAsync } from '@angular/core/testing';
import { async, fakeAsync, tick } from '@angular/core/testing';
import { interval, of } from 'rxjs';
import { delay, take } from 'rxjs/operators';
describe('Angular async helper', () => {
describe('async', () => {
let actuallyDone = false;
beforeEach(() => {
actuallyDone = false;
});
beforeEach(() => { actuallyDone = false; });
afterEach(() => {
expect(actuallyDone).toBe(true, 'actuallyDone should be true');
});
afterEach(() => { expect(actuallyDone).toBe(true, 'actuallyDone should be true'); });
it('should run normal test', () => {
actuallyDone = true;
});
it('should run normal test', () => { actuallyDone = true; });
it('should run normal async test', (done: DoneFn) => {
setTimeout(() => {
@ -26,50 +21,39 @@ describe('Angular async helper', () => {
}, 0);
});
it('should run async test with task', waitForAsync(() => {
setTimeout(() => {
actuallyDone = true;
}, 0);
}));
it('should run async test with task',
async(() => { setTimeout(() => { actuallyDone = true; }, 0); }));
it('should run async test with task', waitForAsync(() => {
it('should run async test with task', async(() => {
const id = setInterval(() => {
actuallyDone = true;
clearInterval(id);
}, 100);
}));
it('should run async test with successful promise', waitForAsync(() => {
const p = new Promise(resolve => {
setTimeout(resolve, 10);
});
p.then(() => {
actuallyDone = true;
});
it('should run async test with successful promise', async(() => {
const p = new Promise(resolve => { setTimeout(resolve, 10); });
p.then(() => { actuallyDone = true; });
}));
it('should run async test with failed promise', waitForAsync(() => {
const p = new Promise((resolve, reject) => {
setTimeout(reject, 10);
});
p.catch(() => {
actuallyDone = true;
});
it('should run async test with failed promise', async(() => {
const p = new Promise((resolve, reject) => { setTimeout(reject, 10); });
p.catch(() => { actuallyDone = true; });
}));
// Use done. Can also use async or fakeAsync.
it('should run async test with successful delayed Observable', (done: DoneFn) => {
const source = of(true).pipe(delay(10));
const source = of (true).pipe(delay(10));
source.subscribe(val => actuallyDone = true, err => fail(err), done);
});
it('should run async test with successful delayed Observable', waitForAsync(() => {
const source = of(true).pipe(delay(10));
it('should run async test with successful delayed Observable', async(() => {
const source = of (true).pipe(delay(10));
source.subscribe(val => actuallyDone = true, err => fail(err));
}));
it('should run async test with successful delayed Observable', fakeAsync(() => {
const source = of(true).pipe(delay(10));
const source = of (true).pipe(delay(10));
source.subscribe(val => actuallyDone = true, err => fail(err));
tick(10);
@ -80,9 +64,7 @@ describe('Angular async helper', () => {
// #docregion fake-async-test-tick
it('should run timeout callback with delay after call tick with millis', fakeAsync(() => {
let called = false;
setTimeout(() => {
called = true;
}, 100);
setTimeout(() => { called = true; }, 100);
tick(100);
expect(called).toBe(true);
}));
@ -91,9 +73,7 @@ describe('Angular async helper', () => {
// #docregion fake-async-test-tick-new-macro-task-sync
it('should run new macro task callback with delay after call tick with millis',
fakeAsync(() => {
function nestedTimer(cb: () => any): void {
setTimeout(() => setTimeout(() => cb()));
}
function nestedTimer(cb: () => any): void { setTimeout(() => setTimeout(() => cb())); }
const callback = jasmine.createSpy('callback');
nestedTimer(callback);
expect(callback).not.toHaveBeenCalled();
@ -106,9 +86,7 @@ describe('Angular async helper', () => {
// #docregion fake-async-test-tick-new-macro-task-async
it('should not run new macro task callback with delay after call tick with millis',
fakeAsync(() => {
function nestedTimer(cb: () => any): void {
setTimeout(() => setTimeout(() => cb()));
}
function nestedTimer(cb: () => any): void { setTimeout(() => setTimeout(() => cb())); }
const callback = jasmine.createSpy('callback');
nestedTimer(callback);
expect(callback).not.toHaveBeenCalled();
@ -134,9 +112,7 @@ describe('Angular async helper', () => {
// need to add `import 'zone.js/dist/zone-patch-rxjs-fake-async'
// to patch rxjs scheduler
let result = null;
of('hello').pipe(delay(1000)).subscribe(v => {
result = v;
});
of ('hello').pipe(delay(1000)).subscribe(v => { result = v; });
expect(result).toBeNull();
tick(1000);
expect(result).toBe('hello');
@ -157,18 +133,12 @@ describe('Angular async helper', () => {
describe('use jasmine.clock()', () => {
// need to config __zone_symbol__fakeAsyncPatchLock flag
// before loading zone.js/dist/zone-testing
beforeEach(() => {
jasmine.clock().install();
});
afterEach(() => {
jasmine.clock().uninstall();
});
beforeEach(() => { jasmine.clock().install(); });
afterEach(() => { jasmine.clock().uninstall(); });
it('should auto enter fakeAsync', () => {
// is in fakeAsync now, don't need to call fakeAsync(testFn)
let called = false;
setTimeout(() => {
called = true;
}, 100);
setTimeout(() => { called = true; }, 100);
jasmine.clock().tick(100);
expect(called).toBe(true);
});
@ -182,7 +152,7 @@ describe('Angular async helper', () => {
}
// need to config __zone_symbol__supportWaitUnResolvedChainedPromise flag
// before loading zone.js/dist/zone-testing
it('should wait until promise.then is called', waitForAsync(() => {
it('should wait until promise.then is called', async(() => {
let finished = false;
new Promise((res, rej) => {
jsonp('localhost:8080/jsonp', () => {
@ -198,4 +168,5 @@ describe('Angular async helper', () => {
}));
});
// #enddocregion async-test-promise-then
});

View File

@ -24,18 +24,17 @@ import { FormsModule } from '@angular/forms';
// Forms symbols imported only for a specific test below
import { NgModel, NgControl } from '@angular/forms';
import {
ComponentFixture, fakeAsync, inject, TestBed, tick, waitForAsync
import { async, ComponentFixture, fakeAsync, inject, TestBed, tick
} from '@angular/core/testing';
import { addMatchers, newEvent, click } from '../../testing';
export class NotProvided extends ValueService { /* example below */ }
beforeEach(addMatchers);
export class NotProvided extends ValueService { /* example below */}
beforeEach( addMatchers );
describe('demo (with TestBed):', () => {
//////// Service Tests /////////////
//////// Service Tests /////////////
// #docregion ValueService
describe('ValueService', () => {
@ -65,13 +64,13 @@ describe('demo (with TestBed):', () => {
// #enddocregion testbed-get-w-null
});
it('test should wait for ValueService.getPromiseValue', waitForAsync(() => {
it('test should wait for ValueService.getPromiseValue', async(() => {
service.getPromiseValue().then(
value => expect(value).toBe('promise value')
);
}));
it('test should wait for ValueService.getObservableValue', waitForAsync(() => {
it('test should wait for ValueService.getObservableValue', async(() => {
service.getObservableValue().subscribe(
value => expect(value).toBe('observable value')
);
@ -151,7 +150,7 @@ describe('demo (with TestBed):', () => {
TestBed.configureTestingModule({ providers: [ValueService] });
});
beforeEach(waitForAsync(inject([ValueService], (service: ValueService) => {
beforeEach(async(inject([ValueService], (service: ValueService) => {
service.getPromiseValue().then(value => serviceValue = value);
})));
@ -160,11 +159,11 @@ describe('demo (with TestBed):', () => {
});
});
/////////// Component Tests //////////////////
/////////// Component Tests //////////////////
describe('TestBed component tests', () => {
beforeEach(waitForAsync(() => {
beforeEach(async(() => {
TestBed
.configureTestingModule({
imports: [DemoModule],
@ -236,7 +235,7 @@ describe('demo (with TestBed):', () => {
// #docregion ButtonComp
it('should support clicking a button', () => {
const fixture = TestBed.createComponent(LightswitchComponent);
const btn = fixture.debugElement.query(By.css('button'));
const btn = fixture.debugElement.query(By.css('button'));
const span = fixture.debugElement.query(By.css('span')).nativeElement;
fixture.detectChanges();
@ -249,7 +248,7 @@ describe('demo (with TestBed):', () => {
// #enddocregion ButtonComp
// ngModel is async so we must wait for it with promise-based `whenStable`
it('should support entering text in input box (ngModel)', waitForAsync(() => {
it('should support entering text in input box (ngModel)', async(() => {
const expectedOrigName = 'John';
const expectedNewName = 'Sally';
@ -279,10 +278,10 @@ describe('demo (with TestBed):', () => {
input.dispatchEvent(newEvent('input'));
return fixture.whenStable();
})
.then(() => {
expect(comp.name).toBe(expectedNewName,
`After ngModel updates the model, comp.name should be ${expectedNewName} `);
});
.then(() => {
expect(comp.name).toBe(expectedNewName,
`After ngModel updates the model, comp.name should be ${expectedNewName} `);
});
}));
// fakeAsync version of ngModel input test enables sync test style
@ -328,9 +327,9 @@ describe('demo (with TestBed):', () => {
const fixture = TestBed.createComponent(ReversePipeComponent);
fixture.detectChanges();
const comp = fixture.componentInstance;
const comp = fixture.componentInstance;
const input = fixture.debugElement.query(By.css('input')).nativeElement as HTMLInputElement;
const span = fixture.debugElement.query(By.css('span')).nativeElement as HTMLElement;
const span = fixture.debugElement.query(By.css('span')).nativeElement as HTMLElement;
// simulate user entering new name in input
input.value = inputText;
@ -382,12 +381,12 @@ describe('demo (with TestBed):', () => {
expect(el.styles.color).toBe(comp.color, 'color style');
expect(el.styles.width).toBe(comp.width + 'px', 'width style');
// #enddocregion dom-attributes
// #enddocregion dom-attributes
// Removed on 12/02/2016 when ceased public discussion of the `Renderer`. Revive in future?
// expect(el.properties['customProperty']).toBe(true, 'customProperty');
// #docregion dom-attributes
// #docregion dom-attributes
});
// #enddocregion dom-attributes
@ -401,10 +400,10 @@ describe('demo (with TestBed):', () => {
const fixture = TestBed.configureTestingModule({
declarations: [Child1Component],
})
.overrideComponent(Child1Component, {
set: { template: '<span>Fake</span>' }
})
.createComponent(Child1Component);
.overrideComponent(Child1Component, {
set: { template: '<span>Fake</span>' }
})
.createComponent(Child1Component);
fixture.detectChanges();
expect(fixture).toHaveText('Fake');
@ -414,14 +413,14 @@ describe('demo (with TestBed):', () => {
const fixture = TestBed.configureTestingModule({
declarations: [TestProvidersComponent],
})
.overrideComponent(TestProvidersComponent, {
remove: { providers: [ValueService] },
add: { providers: [{ provide: ValueService, useClass: FakeValueService }] },
.overrideComponent(TestProvidersComponent, {
remove: { providers: [ValueService]},
add: { providers: [{ provide: ValueService, useClass: FakeValueService }] },
// Or replace them all (this component has only one provider)
// set: { providers: [{ provide: ValueService, useClass: FakeValueService }] },
})
.createComponent(TestProvidersComponent);
// Or replace them all (this component has only one provider)
// set: { providers: [{ provide: ValueService, useClass: FakeValueService }] },
})
.createComponent(TestProvidersComponent);
fixture.detectChanges();
expect(fixture).toHaveText('injected value: faked value', 'text');
@ -437,14 +436,14 @@ describe('demo (with TestBed):', () => {
const fixture = TestBed.configureTestingModule({
declarations: [TestViewProvidersComponent],
})
.overrideComponent(TestViewProvidersComponent, {
// remove: { viewProviders: [ValueService]},
// add: { viewProviders: [{ provide: ValueService, useClass: FakeValueService }] },
.overrideComponent(TestViewProvidersComponent, {
// remove: { viewProviders: [ValueService]},
// add: { viewProviders: [{ provide: ValueService, useClass: FakeValueService }] },
// Or replace them all (this component has only one viewProvider)
set: { viewProviders: [{ provide: ValueService, useClass: FakeValueService }] },
})
.createComponent(TestViewProvidersComponent);
// Or replace them all (this component has only one viewProvider)
set: { viewProviders: [{ provide: ValueService, useClass: FakeValueService }] },
})
.createComponent(TestViewProvidersComponent);
fixture.detectChanges();
expect(fixture).toHaveText('injected value: faked value');
@ -454,20 +453,20 @@ describe('demo (with TestBed):', () => {
// TestComponent is parent of TestProvidersComponent
@Component({ template: '<my-service-comp></my-service-comp>' })
class TestComponent { }
class TestComponent {}
// 3 levels of ValueService provider: module, TestCompomponent, TestProvidersComponent
const fixture = TestBed.configureTestingModule({
declarations: [TestComponent, TestProvidersComponent],
providers: [ValueService]
providers: [ValueService]
})
.overrideComponent(TestComponent, {
set: { providers: [{ provide: ValueService, useValue: {} }] }
})
.overrideComponent(TestProvidersComponent, {
set: { providers: [{ provide: ValueService, useClass: FakeValueService }] }
})
.createComponent(TestComponent);
.overrideComponent(TestComponent, {
set: { providers: [{ provide: ValueService, useValue: {} }] }
})
.overrideComponent(TestProvidersComponent, {
set: { providers: [{ provide: ValueService, useClass: FakeValueService }] }
})
.createComponent(TestComponent);
let testBedProvider: ValueService;
let tcProvider: ValueService;
@ -490,10 +489,10 @@ describe('demo (with TestBed):', () => {
const fixture = TestBed.configureTestingModule({
declarations: [ShellComponent, NeedsContentComponent, Child1Component, Child2Component, Child3Component],
})
.overrideComponent(ShellComponent, {
set: {
selector: 'test-shell',
template: `
.overrideComponent(ShellComponent, {
set: {
selector: 'test-shell',
template: `
<needs-content #nc>
<child-1 #content text="My"></child-1>
<child-2 #content text="dog"></child-2>
@ -502,9 +501,9 @@ describe('demo (with TestBed):', () => {
<div #content>!</div>
</needs-content>
`
}
})
.createComponent(ShellComponent);
}
})
.createComponent(ShellComponent);
fixture.detectChanges();
@ -616,7 +615,7 @@ describe('demo (with TestBed):', () => {
});
// must be async test to see child flow to parent
it('changed child value flows to parent', waitForAsync(() => {
it('changed child value flows to parent', async(() => {
fixture.detectChanges();
getChild();
@ -626,14 +625,14 @@ describe('demo (with TestBed):', () => {
// Wait one JS engine turn!
setTimeout(() => resolve(), 0);
})
.then(() => {
fixture.detectChanges();
.then(() => {
fixture.detectChanges();
expect(child.ngOnChangesCounter).toBe(2,
'expected 2 changes: initial value and changed value');
expect(parent.parentValue).toBe('bar',
'parentValue should eq changed parent value');
});
expect(child.ngOnChangesCounter).toBe(2,
'expected 2 changes: initial value and changed value');
expect(parent.parentValue).toBe('bar',
'parentValue should eq changed parent value');
});
}));

View File

@ -1,5 +1,8 @@
// #docplaster
import { ComponentFixture, fakeAsync, inject, TestBed, tick, waitForAsync } from '@angular/core/testing';
import {
async, ComponentFixture, fakeAsync, inject, TestBed, tick
} from '@angular/core/testing';
import { Router } from '@angular/router';
import {
@ -33,54 +36,59 @@ describe('HeroDetailComponent', () => {
function overrideSetup() {
// #docregion hds-spy
class HeroDetailServiceSpy {
testHero: Hero = {id: 42, name: 'Test Hero'};
testHero: Hero = {id: 42, name: 'Test Hero' };
/* emit cloned test hero */
getHero = jasmine.createSpy('getHero').and.callFake(
() => asyncData(Object.assign({}, this.testHero)));
() => asyncData(Object.assign({}, this.testHero))
);
/* emit clone of test hero, with changes merged in */
saveHero = jasmine.createSpy('saveHero')
.and.callFake((hero: Hero) => asyncData(Object.assign(this.testHero, hero)));
saveHero = jasmine.createSpy('saveHero').and.callFake(
(hero: Hero) => asyncData(Object.assign(this.testHero, hero))
);
}
// #enddocregion hds-spy
// the `id` value is irrelevant because ignored by service stub
beforeEach(() => activatedRoute.setParamMap({id: 99999}));
beforeEach(() => activatedRoute.setParamMap({ id: 99999 }));
// #docregion setup-override
beforeEach(waitForAsync(() => {
beforeEach(async(() => {
const routerSpy = createRouterSpy();
TestBed
.configureTestingModule({
imports: [HeroModule],
providers: [
{provide: ActivatedRoute, useValue: activatedRoute},
{provide: Router, useValue: routerSpy},
TestBed.configureTestingModule({
imports: [ HeroModule ],
providers: [
{ provide: ActivatedRoute, useValue: activatedRoute },
{ provide: Router, useValue: routerSpy},
// #enddocregion setup-override
// HeroDetailService at this level is IRRELEVANT!
{provide: HeroDetailService, useValue: {}}
// HeroDetailService at this level is IRRELEVANT!
{ provide: HeroDetailService, useValue: {} }
// #docregion setup-override
]
})
]
})
// Override component's own provider
// #docregion override-component-method
.overrideComponent(
HeroDetailComponent,
{set: {providers: [{provide: HeroDetailService, useClass: HeroDetailServiceSpy}]}})
// #enddocregion override-component-method
// Override component's own provider
// #docregion override-component-method
.overrideComponent(HeroDetailComponent, {
set: {
providers: [
{ provide: HeroDetailService, useClass: HeroDetailServiceSpy }
]
}
})
// #enddocregion override-component-method
.compileComponents();
.compileComponents();
}));
// #enddocregion setup-override
// #docregion override-tests
let hdsSpy: HeroDetailServiceSpy;
beforeEach(waitForAsync(() => {
beforeEach(async(() => {
createComponent();
// get the component's injected HeroDetailServiceSpy
hdsSpy = fixture.debugElement.injector.get(HeroDetailService) as any;
@ -95,32 +103,33 @@ function overrideSetup() {
});
it('should save stub hero change', fakeAsync(() => {
const origName = hdsSpy.testHero.name;
const newName = 'New Name';
const origName = hdsSpy.testHero.name;
const newName = 'New Name';
page.nameInput.value = newName;
page.nameInput.dispatchEvent(newEvent('input')); // tell Angular
page.nameInput.value = newName;
page.nameInput.dispatchEvent(newEvent('input')); // tell Angular
expect(component.hero.name).toBe(newName, 'component hero has new name');
expect(hdsSpy.testHero.name).toBe(origName, 'service hero unchanged before save');
expect(component.hero.name).toBe(newName, 'component hero has new name');
expect(hdsSpy.testHero.name).toBe(origName, 'service hero unchanged before save');
click(page.saveBtn);
expect(hdsSpy.saveHero.calls.count()).toBe(1, 'saveHero called once');
click(page.saveBtn);
expect(hdsSpy.saveHero.calls.count()).toBe(1, 'saveHero called once');
tick(); // wait for async save to complete
expect(hdsSpy.testHero.name).toBe(newName, 'service hero has new name after save');
expect(page.navigateSpy.calls.any()).toBe(true, 'router.navigate called');
}));
tick(); // wait for async save to complete
expect(hdsSpy.testHero.name).toBe(newName, 'service hero has new name after save');
expect(page.navigateSpy.calls.any()).toBe(true, 'router.navigate called');
}));
// #enddocregion override-tests
it('fixture injected service is not the component injected service',
// inject gets the service from the fixture
inject([HeroDetailService], (fixtureService: HeroDetailService) => {
// use `fixture.debugElement.injector` to get service from component
const componentService = fixture.debugElement.injector.get(HeroDetailService);
// inject gets the service from the fixture
inject([HeroDetailService], (fixtureService: HeroDetailService) => {
expect(fixtureService).not.toBe(componentService, 'service injected from fixture');
}));
// use `fixture.debugElement.injector` to get service from component
const componentService = fixture.debugElement.injector.get(HeroDetailService);
expect(fixtureService).not.toBe(componentService, 'service injected from fixture');
}));
}
////////////////////
@ -130,22 +139,21 @@ const firstHero = getTestHeroes()[0];
function heroModuleSetup() {
// #docregion setup-hero-module
beforeEach(waitForAsync(() => {
beforeEach(async(() => {
const routerSpy = createRouterSpy();
TestBed
.configureTestingModule({
imports: [HeroModule],
// #enddocregion setup-hero-module
// declarations: [ HeroDetailComponent ], // NO! DOUBLE DECLARATION
// #docregion setup-hero-module
providers: [
{provide: ActivatedRoute, useValue: activatedRoute},
{provide: HeroService, useClass: TestHeroService},
{provide: Router, useValue: routerSpy},
]
})
.compileComponents();
TestBed.configureTestingModule({
imports: [ HeroModule ],
// #enddocregion setup-hero-module
// declarations: [ HeroDetailComponent ], // NO! DOUBLE DECLARATION
// #docregion setup-hero-module
providers: [
{ provide: ActivatedRoute, useValue: activatedRoute },
{ provide: HeroService, useClass: TestHeroService },
{ provide: Router, useValue: routerSpy},
]
})
.compileComponents();
}));
// #enddocregion setup-hero-module
@ -153,17 +161,17 @@ function heroModuleSetup() {
describe('when navigate to existing hero', () => {
let expectedHero: Hero;
beforeEach(waitForAsync(() => {
beforeEach(async(() => {
expectedHero = firstHero;
activatedRoute.setParamMap({id: expectedHero.id});
activatedRoute.setParamMap({ id: expectedHero.id });
createComponent();
}));
// #docregion selected-tests
// #docregion selected-tests
it('should display that hero\'s name', () => {
expect(page.nameDisplay.textContent).toBe(expectedHero.name);
});
// #enddocregion route-good-id
// #enddocregion route-good-id
it('should navigate when click cancel', () => {
click(page.cancelBtn);
@ -182,10 +190,10 @@ function heroModuleSetup() {
});
it('should navigate when click save and save resolves', fakeAsync(() => {
click(page.saveBtn);
tick(); // wait for async save to complete
expect(page.navigateSpy.calls.any()).toBe(true, 'router.navigate called');
}));
click(page.saveBtn);
tick(); // wait for async save to complete
expect(page.navigateSpy.calls.any()).toBe(true, 'router.navigate called');
}));
// #docregion title-case-pipe
it('should convert hero name to Title Case', () => {
@ -207,14 +215,14 @@ function heroModuleSetup() {
expect(nameDisplay.textContent).toBe('Quick Brown Fox');
});
// #enddocregion title-case-pipe
// #enddocregion selected-tests
// #docregion route-good-id
// #enddocregion selected-tests
// #docregion route-good-id
});
// #enddocregion route-good-id
// #docregion route-no-id
describe('when navigate with no hero id', () => {
beforeEach(waitForAsync(createComponent));
beforeEach(async( createComponent ));
it('should have hero.id === 0', () => {
expect(component.hero.id).toBe(0);
@ -228,8 +236,8 @@ function heroModuleSetup() {
// #docregion route-bad-id
describe('when navigate to non-existent hero id', () => {
beforeEach(waitForAsync(() => {
activatedRoute.setParamMap({id: 99999});
beforeEach(async(() => {
activatedRoute.setParamMap({ id: 99999 });
createComponent();
}));
@ -245,10 +253,11 @@ function heroModuleSetup() {
let service: HeroDetailService;
fixture = TestBed.createComponent(HeroDetailComponent);
expect(
// Throws because `inject` only has access to TestBed's injector
// which is an ancestor of the component's injector
inject([HeroDetailService], (hds: HeroDetailService) => service = hds))
.toThrowError(/No provider for HeroDetailService/);
// Throws because `inject` only has access to TestBed's injector
// which is an ancestor of the component's injector
inject([HeroDetailService], (hds: HeroDetailService) => service = hds )
)
.toThrowError(/No provider for HeroDetailService/);
// get `HeroDetailService` with component's own injector
service = fixture.debugElement.injector.get(HeroDetailService);
@ -261,31 +270,30 @@ import { FormsModule } from '@angular/forms';
import { TitleCasePipe } from '../shared/title-case.pipe';
function formsModuleSetup() {
// #docregion setup-forms-module
beforeEach(waitForAsync(() => {
// #docregion setup-forms-module
beforeEach(async(() => {
const routerSpy = createRouterSpy();
TestBed
.configureTestingModule({
imports: [FormsModule],
declarations: [HeroDetailComponent, TitleCasePipe],
providers: [
{provide: ActivatedRoute, useValue: activatedRoute},
{provide: HeroService, useClass: TestHeroService},
{provide: Router, useValue: routerSpy},
]
})
.compileComponents();
TestBed.configureTestingModule({
imports: [ FormsModule ],
declarations: [ HeroDetailComponent, TitleCasePipe ],
providers: [
{ provide: ActivatedRoute, useValue: activatedRoute },
{ provide: HeroService, useClass: TestHeroService },
{ provide: Router, useValue: routerSpy},
]
})
.compileComponents();
}));
// #enddocregion setup-forms-module
it('should display 1st hero\'s name', waitForAsync(() => {
const expectedHero = firstHero;
activatedRoute.setParamMap({id: expectedHero.id});
createComponent().then(() => {
expect(page.nameDisplay.textContent).toBe(expectedHero.name);
});
}));
it('should display 1st hero\'s name', async(() => {
const expectedHero = firstHero;
activatedRoute.setParamMap({ id: expectedHero.id });
createComponent().then(() => {
expect(page.nameDisplay.textContent).toBe(expectedHero.name);
});
}));
}
///////////////////////
@ -293,30 +301,29 @@ import { SharedModule } from '../shared/shared.module';
function sharedModuleSetup() {
// #docregion setup-shared-module
beforeEach(waitForAsync(() => {
beforeEach(async(() => {
const routerSpy = createRouterSpy();
TestBed
.configureTestingModule({
imports: [SharedModule],
declarations: [HeroDetailComponent],
providers: [
{provide: ActivatedRoute, useValue: activatedRoute},
{provide: HeroService, useClass: TestHeroService},
{provide: Router, useValue: routerSpy},
]
})
.compileComponents();
TestBed.configureTestingModule({
imports: [ SharedModule ],
declarations: [ HeroDetailComponent ],
providers: [
{ provide: ActivatedRoute, useValue: activatedRoute },
{ provide: HeroService, useClass: TestHeroService },
{ provide: Router, useValue: routerSpy},
]
})
.compileComponents();
}));
// #enddocregion setup-shared-module
it('should display 1st hero\'s name', waitForAsync(() => {
const expectedHero = firstHero;
activatedRoute.setParamMap({id: expectedHero.id});
createComponent().then(() => {
expect(page.nameDisplay.textContent).toBe(expectedHero.name);
});
}));
it('should display 1st hero\'s name', async(() => {
const expectedHero = firstHero;
activatedRoute.setParamMap({ id: expectedHero.id });
createComponent().then(() => {
expect(page.nameDisplay.textContent).toBe(expectedHero.name);
});
}));
}
/////////// Helpers /////
@ -340,21 +347,11 @@ function createComponent() {
// #docregion page
class Page {
// getter properties wait to query the DOM until called.
get buttons() {
return this.queryAll<HTMLButtonElement>('button');
}
get saveBtn() {
return this.buttons[0];
}
get cancelBtn() {
return this.buttons[1];
}
get nameDisplay() {
return this.query<HTMLElement>('span');
}
get nameInput() {
return this.query<HTMLInputElement>('input');
}
get buttons() { return this.queryAll<HTMLButtonElement>('button'); }
get saveBtn() { return this.buttons[0]; }
get cancelBtn() { return this.buttons[1]; }
get nameDisplay() { return this.query<HTMLElement>('span'); }
get nameInput() { return this.query<HTMLInputElement>('input'); }
gotoListSpy: jasmine.Spy;
navigateSpy: jasmine.Spy;

View File

@ -1,4 +1,4 @@
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync
import { async, ComponentFixture, fakeAsync, TestBed, tick
} from '@angular/core/testing';
import { By } from '@angular/platform-browser';
@ -7,12 +7,13 @@ import { DebugElement } from '@angular/core';
import { Router } from '@angular/router';
import { addMatchers, newEvent } from '../../testing';
import { HeroService } from '../model/hero.service';
import { getTestHeroes, TestHeroService } from '../model/testing/test-hero.service';
import { HeroModule } from './hero.module';
import { HeroListComponent } from './hero-list.component';
import { HighlightDirective } from '../shared/highlight.directive';
import { HeroService } from '../model/hero.service';
const HEROES = getTestHeroes();
@ -23,20 +24,20 @@ let page: Page;
/////// Tests //////
describe('HeroListComponent', () => {
beforeEach(waitForAsync(() => {
beforeEach(async(() => {
addMatchers();
const routerSpy = jasmine.createSpyObj('Router', ['navigate']);
TestBed
.configureTestingModule({
imports: [HeroModule],
providers: [
{provide: HeroService, useClass: TestHeroService},
{provide: Router, useValue: routerSpy}
]
})
.compileComponents()
.then(createComponent);
TestBed.configureTestingModule({
imports: [HeroModule],
providers: [
{ provide: HeroService, useClass: TestHeroService },
{ provide: Router, useValue: routerSpy}
]
})
.compileComponents()
.then(createComponent);
}));
it('should display heroes', () => {
@ -51,35 +52,36 @@ describe('HeroListComponent', () => {
});
it('should select hero on click', fakeAsync(() => {
const expectedHero = HEROES[1];
const li = page.heroRows[1];
li.dispatchEvent(newEvent('click'));
tick();
// `.toEqual` because selectedHero is clone of expectedHero; see FakeHeroService
expect(comp.selectedHero).toEqual(expectedHero);
}));
const expectedHero = HEROES[1];
const li = page.heroRows[1];
li.dispatchEvent(newEvent('click'));
tick();
// `.toEqual` because selectedHero is clone of expectedHero; see FakeHeroService
expect(comp.selectedHero).toEqual(expectedHero);
}));
it('should navigate to selected hero detail on click', fakeAsync(() => {
const expectedHero = HEROES[1];
const li = page.heroRows[1];
li.dispatchEvent(newEvent('click'));
tick();
const expectedHero = HEROES[1];
const li = page.heroRows[1];
li.dispatchEvent(newEvent('click'));
tick();
// should have navigated
expect(page.navSpy.calls.any()).toBe(true, 'navigate called');
// should have navigated
expect(page.navSpy.calls.any()).toBe(true, 'navigate called');
// composed hero detail will be URL like 'heroes/42'
// expect link array with the route path and hero id
// first argument to router.navigate is link array
const navArgs = page.navSpy.calls.first().args[0];
expect(navArgs[0]).toContain('heroes', 'nav to heroes detail URL');
expect(navArgs[1]).toBe(expectedHero.id, 'expected hero.id');
}));
// composed hero detail will be URL like 'heroes/42'
// expect link array with the route path and hero id
// first argument to router.navigate is link array
const navArgs = page.navSpy.calls.first().args[0];
expect(navArgs[0]).toContain('heroes', 'nav to heroes detail URL');
expect(navArgs[1]).toBe(expectedHero.id, 'expected hero.id');
}));
it('should find `HighlightDirective` with `By.directive', () => {
// #docregion by
// Can find DebugElement either by css selector or by directive
const h2 = fixture.debugElement.query(By.css('h2'));
const h2 = fixture.debugElement.query(By.css('h2'));
const directive = fixture.debugElement.query(By.directive(HighlightDirective));
// #enddocregion by
expect(h2).toBe(directive);

View File

@ -1,7 +1,6 @@
// #docplaster
// #docregion without-toBlob-macrotask
import { fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { TestBed, async, tick, fakeAsync } from '@angular/core/testing';
import { CanvasComponent } from './canvas.component';
describe('CanvasComponent', () => {
@ -11,29 +10,29 @@ describe('CanvasComponent', () => {
(window as any).__zone_symbol__FakeAsyncTestMacroTask = [
{
source: 'HTMLCanvasElement.toBlob',
callbackArgs: [{size: 200}],
callbackArgs: [{ size: 200 }],
},
];
});
// #enddocregion enable-toBlob-macrotask
// #docregion without-toBlob-macrotask
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
declarations: [CanvasComponent],
})
.compileComponents();
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
CanvasComponent
],
}).compileComponents();
}));
it('should be able to generate blob data from canvas', fakeAsync(() => {
const fixture = TestBed.createComponent(CanvasComponent);
const canvasComp = fixture.componentInstance;
const fixture = TestBed.createComponent(CanvasComponent);
const canvasComp = fixture.componentInstance;
fixture.detectChanges();
expect(canvasComp.blobSize).toBe(0);
fixture.detectChanges();
expect(canvasComp.blobSize).toBe(0);
tick();
expect(canvasComp.blobSize).toBeGreaterThan(0);
}));
tick();
expect(canvasComp.blobSize).toBeGreaterThan(0);
}));
});
// #enddocregion without-toBlob-macrotask

View File

@ -1,13 +1,14 @@
// #docplaster
import { fakeAsync, ComponentFixture, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { async, fakeAsync, ComponentFixture, TestBed, tick } from '@angular/core/testing';
import { asyncData, asyncError } from '../../testing';
import { of, throwError } from 'rxjs';
import { last } from 'rxjs/operators';
import { TwainComponent } from './twain.component';
import { TwainService } from './twain.service';
import { TwainComponent } from './twain.component';
describe('TwainComponent', () => {
let component: TwainComponent;
@ -31,12 +32,14 @@ describe('TwainComponent', () => {
// Create a fake TwainService object with a `getQuote()` spy
const twainService = jasmine.createSpyObj('TwainService', ['getQuote']);
// Make the spy return a synchronous Observable with the test data
getQuoteSpy = twainService.getQuote.and.returnValue(of(testQuote));
getQuoteSpy = twainService.getQuote.and.returnValue( of(testQuote) );
// #enddocregion spy
TestBed.configureTestingModule({
declarations: [TwainComponent],
providers: [{provide: TwainService, useValue: twainService}]
declarations: [ TwainComponent ],
providers: [
{ provide: TwainService, useValue: twainService }
]
});
fixture = TestBed.createComponent(TwainComponent);
@ -55,7 +58,7 @@ describe('TwainComponent', () => {
// The quote would not be immediately available if the service were truly async.
// #docregion sync-test
it('should show quote after component initialized', () => {
fixture.detectChanges(); // onInit()
fixture.detectChanges(); // onInit()
// sync spy result shows testQuote immediately after init
expect(quoteEl.textContent).toBe(testQuote);
@ -68,19 +71,20 @@ describe('TwainComponent', () => {
// Use `fakeAsync` because the component error calls `setTimeout`
// #docregion error-test
it('should display error when TwainService fails', fakeAsync(() => {
// tell spy to return an error observable
getQuoteSpy.and.returnValue(throwError('TwainService test failure'));
// tell spy to return an error observable
getQuoteSpy.and.returnValue(
throwError('TwainService test failure'));
fixture.detectChanges(); // onInit()
// sync spy errors immediately after init
fixture.detectChanges(); // onInit()
// sync spy errors immediately after init
tick(); // flush the component's setTimeout()
tick(); // flush the component's setTimeout()
fixture.detectChanges(); // update errorMessage within setTimeout()
fixture.detectChanges(); // update errorMessage within setTimeout()
expect(errorMessage()).toMatch(/test failure/, 'should display error');
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
}));
expect(errorMessage()).toMatch(/test failure/, 'should display error');
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
}));
// #enddocregion error-test
});
@ -109,28 +113,28 @@ describe('TwainComponent', () => {
// #docregion fake-async-test
it('should show quote after getQuote (fakeAsync)', fakeAsync(() => {
fixture.detectChanges(); // ngOnInit()
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
fixture.detectChanges(); // ngOnInit()
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
tick(); // flush the observable to get the quote
fixture.detectChanges(); // update view
tick(); // flush the observable to get the quote
fixture.detectChanges(); // update view
expect(quoteEl.textContent).toBe(testQuote, 'should show quote');
expect(errorMessage()).toBeNull('should not show error');
}));
expect(quoteEl.textContent).toBe(testQuote, 'should show quote');
expect(errorMessage()).toBeNull('should not show error');
}));
// #enddocregion fake-async-test
// #docregion async-test
it('should show quote after getQuote (async)', waitForAsync(() => {
fixture.detectChanges(); // ngOnInit()
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
it('should show quote after getQuote (async)', async(() => {
fixture.detectChanges(); // ngOnInit()
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
fixture.whenStable().then(() => { // wait for async getQuote
fixture.detectChanges(); // update view with quote
expect(quoteEl.textContent).toBe(testQuote);
expect(errorMessage()).toBeNull('should not show error');
});
}));
fixture.whenStable().then(() => { // wait for async getQuote
fixture.detectChanges(); // update view with quote
expect(quoteEl.textContent).toBe(testQuote);
expect(errorMessage()).toBeNull('should not show error');
});
}));
// #enddocregion async-test
@ -138,8 +142,8 @@ describe('TwainComponent', () => {
it('should show last quote (quote done)', (done: DoneFn) => {
fixture.detectChanges();
component.quote.pipe(last()).subscribe(() => {
fixture.detectChanges(); // update view with quote
component.quote.pipe( last() ).subscribe(() => {
fixture.detectChanges(); // update view with quote
expect(quoteEl.textContent).toBe(testQuote);
expect(errorMessage()).toBeNull('should not show error');
done();
@ -153,7 +157,7 @@ describe('TwainComponent', () => {
// the spy's most recent call returns the observable with the test quote
getQuoteSpy.calls.mostRecent().returnValue.subscribe(() => {
fixture.detectChanges(); // update view with quote
fixture.detectChanges(); // update view with quote
expect(quoteEl.textContent).toBe(testQuote);
expect(errorMessage()).toBeNull('should not show error');
done();
@ -163,16 +167,16 @@ describe('TwainComponent', () => {
// #docregion async-error-test
it('should display error when TwainService fails', fakeAsync(() => {
// tell spy to return an async error observable
getQuoteSpy.and.returnValue(asyncError<string>('TwainService test failure'));
// tell spy to return an async error observable
getQuoteSpy.and.returnValue(asyncError<string>('TwainService test failure'));
fixture.detectChanges();
tick(); // component shows error after a setTimeout()
fixture.detectChanges(); // update error message
fixture.detectChanges();
tick(); // component shows error after a setTimeout()
fixture.detectChanges(); // update error message
expect(errorMessage()).toMatch(/test failure/, 'should display error');
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
}));
expect(errorMessage()).toMatch(/test failure/, 'should display error');
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
}));
// #enddocregion async-error-test
});
});

View File

@ -1,12 +1,12 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { of } from 'rxjs';
import { HeroSearchComponent } from '../hero-search/hero-search.component';
import { HeroService } from '../hero.service';
import { HEROES } from '../mock-heroes';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { DashboardComponent } from './dashboard.component';
import { HeroSearchComponent } from '../hero-search/hero-search.component';
import { RouterTestingModule } from '@angular/router/testing';
import { of } from 'rxjs';
import { HEROES } from '../mock-heroes';
import { HeroService } from '../hero.service';
describe('DashboardComponent', () => {
let component: DashboardComponent;
@ -14,16 +14,23 @@ describe('DashboardComponent', () => {
let heroService;
let getHeroesSpy;
beforeEach(waitForAsync(() => {
beforeEach(async(() => {
heroService = jasmine.createSpyObj('HeroService', ['getHeroes']);
getHeroesSpy = heroService.getHeroes.and.returnValue(of(HEROES));
TestBed
.configureTestingModule({
declarations: [DashboardComponent, HeroSearchComponent],
imports: [RouterTestingModule.withRoutes([])],
providers: [{provide: HeroService, useValue: heroService}]
})
.compileComponents();
getHeroesSpy = heroService.getHeroes.and.returnValue( of(HEROES) );
TestBed.configureTestingModule({
declarations: [
DashboardComponent,
HeroSearchComponent
],
imports: [
RouterTestingModule.withRoutes([])
],
providers: [
{ provide: HeroService, useValue: heroService }
]
})
.compileComponents();
}));
beforeEach(() => {
@ -40,11 +47,12 @@ describe('DashboardComponent', () => {
expect(fixture.nativeElement.querySelector('h3').textContent).toEqual('Top Heroes');
});
it('should call heroService', waitForAsync(() => {
expect(getHeroesSpy.calls.any()).toBe(true);
}));
it('should call heroService', async(() => {
expect(getHeroesSpy.calls.any()).toBe(true);
}));
it('should display 4 links', async(() => {
expect(fixture.nativeElement.querySelectorAll('a').length).toEqual(4);
}));
it('should display 4 links', waitForAsync(() => {
expect(fixture.nativeElement.querySelectorAll('a').length).toEqual(4);
}));
});

View File

@ -12,7 +12,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script>

View File

@ -26,7 +26,7 @@
<script src="phone-detail/phone-detail.module.js"></script>
<script src="/node_modules/core-js/client/shim.min.js"></script>
<script src="/node_modules/zone.js/bundles/zone.umd.min.js"></script>
<script src="/node_modules/zone.js/dist/zone.min.js"></script>
<script>window.module = 'aot';</script>
</head>

View File

@ -1,16 +1,22 @@
// #docregion
// #docregion activatedroute
import { TestBed, waitForAsync } from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router';
// #enddocregion activatedroute
import { Observable, of } from 'rxjs';
import { async, TestBed } from '@angular/core/testing';
import { PhoneDetailComponent } from './phone-detail.component';
import { Phone, PhoneData } from '../core/phone/phone.service';
import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe';
function xyzPhoneData(): PhoneData {
return {name: 'phone xyz', snippet: '', images: ['image/url1.png', 'image/url2.png']};
return {
name: 'phone xyz',
snippet: '',
images: ['image/url1.png', 'image/url2.png']
};
}
class MockPhone {
@ -28,9 +34,10 @@ class ActivatedRouteMock {
// #enddocregion activatedroute
describe('PhoneDetailComponent', () => {
// #docregion activatedroute
beforeEach(waitForAsync(() => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ CheckmarkPipe, PhoneDetailComponent ],
providers: [
@ -48,4 +55,5 @@ describe('PhoneDetailComponent', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain(xyzPhoneData().name);
});
});

View File

@ -1,14 +1,13 @@
/* tslint:disable */
// #docregion
import {SpyLocation} from '@angular/common/testing';
import {NO_ERRORS_SCHEMA} from '@angular/core';
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import {ActivatedRoute} from '@angular/router';
import {Observable, of} from 'rxjs';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable, of } from 'rxjs';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SpyLocation } from '@angular/common/testing';
import {Phone, PhoneData} from '../core/phone/phone.service';
import {PhoneListComponent} from './phone-list.component';
import { PhoneListComponent } from './phone-list.component';
import { Phone, PhoneData } from '../core/phone/phone.service';
class ActivatedRouteMock {
constructor(public snapshot: any) {}
@ -17,7 +16,8 @@ class ActivatedRouteMock {
class MockPhone {
query(): Observable<PhoneData[]> {
return of([
{name: 'Nexus S', snippet: '', images: []}, {name: 'Motorola DROID', snippet: '', images: []}
{name: 'Nexus S', snippet: '', images: []},
{name: 'Motorola DROID', snippet: '', images: []}
]);
}
}
@ -25,18 +25,18 @@ class MockPhone {
let fixture: ComponentFixture<PhoneListComponent>;
describe('PhoneList', () => {
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
declarations: [PhoneListComponent],
providers: [
{provide: ActivatedRoute, useValue: new ActivatedRouteMock({params: {'phoneId': 1}})},
{provide: Location, useClass: SpyLocation},
{provide: Phone, useClass: MockPhone},
],
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents();
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PhoneListComponent ],
providers: [
{ provide: ActivatedRoute, useValue: new ActivatedRouteMock({ params: { 'phoneId': 1 } }) },
{ provide: Location, useClass: SpyLocation },
{ provide: Phone, useClass: MockPhone },
],
schemas: [ NO_ERRORS_SCHEMA ]
})
.compileComponents();
}));
beforeEach(() => {
@ -47,15 +47,20 @@ describe('PhoneList', () => {
fixture.detectChanges();
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2);
expect(compiled.querySelector('.phone-list-item:nth-child(1)').textContent)
.toContain('Motorola DROID');
expect(compiled.querySelector('.phone-list-item:nth-child(2)').textContent)
.toContain('Nexus S');
expect(
compiled.querySelector('.phone-list-item:nth-child(1)').textContent
).toContain('Motorola DROID');
expect(
compiled.querySelector('.phone-list-item:nth-child(2)').textContent
).toContain('Nexus S');
});
xit('should set the default value of orderProp model', () => {
fixture.detectChanges();
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('select option:last-child').selected).toBe(true);
expect(
compiled.querySelector('select option:last-child').selected
).toBe(true);
});
});

View File

@ -3,7 +3,7 @@ var fsExtra = require('fs-extra');
var resources = [
// polyfills
'node_modules/core-js/client/shim.min.js',
'node_modules/zone.js/bundles/zone.umd.min.js',
'node_modules/zone.js/dist/zone.min.js',
// css
'app/app.css',
'app/app.animations.css',
@ -20,7 +20,6 @@ var resources = [
'app/phone-detail/phone-detail.module.js'
];
resources.map(function(sourcePath) {
// Need to rename zone.umd.min.js to zone.min.js
var destPath = `aot/${sourcePath}`.replace('.umd.min.js', '.min.js');
var destPath = `aot/${sourcePath}`;
fsExtra.copySync(sourcePath, destPath);
});

View File

@ -27,7 +27,7 @@
<!-- #docregion angular -->
<script src="/node_modules/core-js/client/shim.min.js"></script>
<script src="/node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="/node_modules/zone.js/dist/zone.js"></script>
<script src="/node_modules/systemjs/dist/system.src.js"></script>
<!-- #enddocregion angular -->
<script src="/systemjs.config.1.js"></script>

View File

@ -21,8 +21,8 @@ module.exports = function(config) {
'node_modules/core-js/client/shim.js',
// zone.js
'node_modules/zone.js/bundles/zone.umd.js',
'node_modules/zone.js/bundles/zone-testing.umd.js',
'node_modules/zone.js/dist/zone.js',
'node_modules/zone.js/dist/zone-testing.js',
// RxJs.
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },

View File

@ -31,8 +31,8 @@ module.exports = function(config) {
'node_modules/core-js/client/shim.js',
// zone.js
'node_modules/zone.js/bundles/zone.umd.js',
'node_modules/zone.js/bundles/zone-testing.umd.js',
'node_modules/zone.js/dist/zone.js',
'node_modules/zone.js/dist/zone-testing.js',
// RxJs
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },

View File

@ -1,16 +1,22 @@
// #docregion
// #docregion activatedroute
import { TestBed, waitForAsync } from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router';
// #enddocregion activatedroute
import { Observable, of } from 'rxjs';
import { async, TestBed } from '@angular/core/testing';
import { PhoneDetailComponent } from './phone-detail.component';
import { Phone, PhoneData } from '../core/phone/phone.service';
import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe';
function xyzPhoneData(): PhoneData {
return {name: 'phone xyz', snippet: '', images: ['image/url1.png', 'image/url2.png']};
return {
name: 'phone xyz',
snippet: '',
images: ['image/url1.png', 'image/url2.png']
};
}
class MockPhone {
@ -28,9 +34,10 @@ class ActivatedRouteMock {
// #enddocregion activatedroute
describe('PhoneDetailComponent', () => {
// #docregion activatedroute
beforeEach(waitForAsync(() => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ CheckmarkPipe, PhoneDetailComponent ],
providers: [
@ -48,4 +55,5 @@ describe('PhoneDetailComponent', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain(xyzPhoneData().name);
});
});

View File

@ -1,14 +1,13 @@
/* tslint:disable */
// #docregion routestuff
import {SpyLocation} from '@angular/common/testing';
import {NO_ERRORS_SCHEMA} from '@angular/core';
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import {ActivatedRoute} from '@angular/router';
import {Observable, of} from 'rxjs';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable, of } from 'rxjs';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SpyLocation } from '@angular/common/testing';
import {Phone, PhoneData} from '../core/phone/phone.service';
import {PhoneListComponent} from './phone-list.component';
import { PhoneListComponent } from './phone-list.component';
import { Phone, PhoneData } from '../core/phone/phone.service';
// #enddocregion routestuff
@ -19,7 +18,8 @@ class ActivatedRouteMock {
class MockPhone {
query(): Observable<PhoneData[]> {
return of([
{name: 'Nexus S', snippet: '', images: []}, {name: 'Motorola DROID', snippet: '', images: []}
{name: 'Nexus S', snippet: '', images: []},
{name: 'Motorola DROID', snippet: '', images: []}
]);
}
}
@ -27,20 +27,20 @@ class MockPhone {
let fixture: ComponentFixture<PhoneListComponent>;
describe('PhoneList', () => {
// #docregion routestuff
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({
declarations: [PhoneListComponent],
providers: [
{provide: ActivatedRoute, useValue: new ActivatedRouteMock({params: {'phoneId': 1}})},
{provide: Location, useClass: SpyLocation},
{provide: Phone, useClass: MockPhone},
],
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents();
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PhoneListComponent ],
providers: [
{ provide: ActivatedRoute, useValue: new ActivatedRouteMock({ params: { 'phoneId': 1 } }) },
{ provide: Location, useClass: SpyLocation },
{ provide: Phone, useClass: MockPhone },
],
schemas: [ NO_ERRORS_SCHEMA ]
})
.compileComponents();
}));
beforeEach(() => {
@ -52,15 +52,20 @@ describe('PhoneList', () => {
fixture.detectChanges();
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2);
expect(compiled.querySelector('.phone-list-item:nth-child(1)').textContent)
.toContain('Motorola DROID');
expect(compiled.querySelector('.phone-list-item:nth-child(2)').textContent)
.toContain('Nexus S');
expect(
compiled.querySelector('.phone-list-item:nth-child(1)').textContent
).toContain('Motorola DROID');
expect(
compiled.querySelector('.phone-list-item:nth-child(2)').textContent
).toContain('Nexus S');
});
xit('should set the default value of orderProp model', () => {
fixture.detectChanges();
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('select option:last-child').selected).toBe(true);
expect(
compiled.querySelector('select option:last-child').selected
).toBe(true);
});
});

View File

@ -12,7 +12,7 @@
<link rel="stylesheet" href="app.css" />
<script src="/node_modules/core-js/client/shim.min.js"></script>
<script src="/node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="/node_modules/zone.js/dist/zone.js"></script>
<script src="/node_modules/systemjs/dist/system.src.js"></script>
<!-- #enddocregion full -->
<script src="/systemjs.config.1.js"></script>

View File

@ -31,8 +31,8 @@ module.exports = function(config) {
'node_modules/core-js/client/shim.js',
// zone.js
'node_modules/zone.js/bundles/zone.umd.js',
'node_modules/zone.js/bundles/zone-testing.umd.js',
'node_modules/zone.js/dist/zone.js',
'node_modules/zone.js/dist/zone-testing.js',
// RxJs
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },

View File

@ -31,7 +31,7 @@ For example:
```json
{
"extends": "../tsconfig.json",
"extends": "../tsconfig.base.json",
"compilerOptions": {
"experimentalDecorators": true,
...

View File

@ -17,7 +17,7 @@ An NgModule is defined by a class decorated with `@NgModule()`. The `@NgModule()
* `imports`: Other modules whose exported classes are needed by component templates declared in *this* NgModule.
* `providers`: Creators of [services](guide/architecture-services) that this NgModule contributes to the global collection of services; they become accessible in all parts of the app. (You can also specify providers at the component level.)
* `providers`: Creators of [services](guide/architecture-services) that this NgModule contributes to the global collection of services; they become accessible in all parts of the app. (You can also specify providers at the component level, which is often preferred.)
* `bootstrap`: The main application view, called the *root component*, which hosts all other app views. Only the *root NgModule* should set the `bootstrap` property.

View File

@ -12,7 +12,7 @@ Every application has at least one Angular module, the _root_ module,
which must be present for bootstrapping the application on launch.
By convention and by default, this NgModule is named `AppModule`.
When you use the [Angular CLI](cli) command `ng new` to generate an app, the default `AppModule` looks like the following:
When you use the [Angular CLI](cli) command `ng new` to generate an app, the default `AppModule` is as follows.
```typescript
/* JavaScript imports */
@ -90,6 +90,8 @@ A declarable can only belong to one module, so only declare it in
one `@NgModule`. When you need it elsewhere,
import the module that has the declarable you need in it.
**Only `@NgModule` references** go in the `imports` array.
### Using directives with `@NgModule`
@ -131,7 +133,7 @@ The module's `imports` array appears exclusively in the `@NgModule` metadata obj
It tells Angular about other NgModules that this particular module needs to function properly.
This list of modules are those that export components, directives, or pipes
that component templates in this module reference. In this case, the component is
that the component templates in this module reference. In this case, the component is
`AppComponent`, which references components, directives, or pipes in `BrowserModule`,
`FormsModule`, or `HttpClientModule`.
A component template can reference another component, directive,

View File

@ -526,7 +526,7 @@ For example:
// __Zone_enable_cross_context_check = true;
&lt;/script>
&lt;!-- zone.js required by Angular -->
&lt;script src="node_modules/zone.js/bundles/zone.umd.js">&lt;/script>
&lt;script src="node_modules/zone.js/dist/zone.js">&lt;/script>
&lt;!-- application polyfills -->
</code-example>

View File

@ -1,13 +1,16 @@
# Creating libraries
This page provides a conceptual overview of how you can create and publish new libraries to extend Angular functionality.
You can create and publish new libraries to extend Angular functionality. If you find that you need to solve the same problem in more than one app (or want to share your solution with other developers), you have a candidate for a library.
If you find that you need to solve the same problem in more than one app (or want to share your solution with other developers), you have a candidate for a library.
A simple example might be a button that sends users to your company website, that would be included in all apps that your company builds.
<div class="alert is-helpful">
<p>For more details on how a library project is structured you can refer the <a href="guide/file-structure#library-project-files">Library Project Files</a></p>
</div>
## Getting started
Use the Angular CLI to generate a new library skeleton in a new workspace with the following commands.
Use the Angular CLI to generate a new library skeleton with the following command:
<code-example language="bash">
ng new my-workspace --create-application=false
@ -15,18 +18,12 @@ Use the Angular CLI to generate a new library skeleton in a new workspace with t
ng generate library my-lib
</code-example>
The `ng generate` command creates the `projects/my-lib` folder in your workspace, which contains a component and a service inside an NgModule.
<div class="alert is-helpful">
For more details on how a library project is structured, refer to the [Library project files](guide/file-structure#library-project-files) section of the [Project File Structure guide](guide/file-structure).
You can use the monorepo model to use the same workspace for multiple projects.
See [Setting up for a multi-project workspace](guide/file-structure#multiple-projects).
<p>You can use the monorepo model to use the same workspace for multiple projects. See <a href="guide/file-structure#multiple-projects">Setting up for a multi-project workspace</a>.</p>
</div>
When you generate a new library, the workspace configuration file, `angular.json`, is updated with a project of type 'library'.
This creates the `projects/my-lib` folder in your workspace, which contains a component and a service inside an NgModule.
The workspace configuration file, `angular.json`, is updated with a project of type 'library'.
<code-example format="json">
"projects": {
@ -72,30 +69,35 @@ Here are some things to consider in migrating application functionality to a lib
* Components should expose their interactions through inputs for providing context, and outputs for communicating events to other components.
* Services should declare their own providers (rather than declaring providers in the NgModule or a component), so that they are *tree-shakable*. This allows the compiler to leave the service out of the bundle if it never gets injected into the application that imports the library. For more about this, see [Tree-shakable providers](guide/dependency-injection-providers#tree-shakable-providers).
* If you register global service providers or share providers across multiple NgModules, use the [`forRoot()` and `forChild()` patterns](guide/singleton-services) provided by the [RouterModule](api/router/RouterModule).
* Check all internal dependencies.
* For custom classes or interfaces used in components or service, check whether they depend on additional classes or interfaces that also need to be migrated.
* Similarly, if your library code depends on a service, that service needs to be migrated.
* If your library code or its templates depend on other libraries (such as Angular Material, for instance), you must configure your library with those dependencies.
* If your library code or its templates depend on other libraries (such a Angular Material, for instance), you must configure your library with those dependencies.
* Consider how you provide services to client applications.
## Reusable code and schematics
* Services should declare their own providers (rather than declaring providers in the NgModule or a component), so that they are *tree-shakable*. This allows the compiler to leave the service out of the bundle if it never gets injected into the application that imports the library. For more about this, see [Tree-shakable providers](guide/dependency-injection-providers#tree-shakable-providers).
A library typically includes *reusable code* that defines components, services, and other Angular artifacts (pipes, directives, and so on) that you simply import into a project.
A library is packaged into an npm package for publishing and sharing, and this package can also include [schematics](guide/glossary#schematic) that provide instructions for generating or transforming code directly in your project, in the same way that the CLI creates a generic skeleton app with `ng generate component`.
A schematic that is combined with a library can, for example, provide the Angular CLI with the information it needs to generate a particular component defined in that library.
* If you register global service providers or share providers across multiple NgModules, use the [`forRoot()` and `forChild()` design patterns](guide/singleton-services) provided by the [RouterModule](api/router/RouterModule).
What you include in your library is determined by the kind of task you are trying to accomplish.
For example, if you want a dropdown with some canned data to show how to add it to your app, your library could define a schematic to create it.
For a component like a dropdown that would contain different passed-in values each time, you could provide it as a component in a shared library.
* If your library provides optional services that might not be used by all client applications, support proper tree-shaking for that case by using the [lightweight token design pattern](guide/lightweight-injection-tokens).
Suppose you want to read a configuration file and then generate a form based on that configuration.
If that form will need additional customization by the user, it might work best as a schematic.
However, if the forms will always be the same and not need much customization by developers, then you could create a dynamic component that takes the configuration and generates the form.
In general, the more complex the customization, the more useful the schematic approach.
{@a integrating-with-the-cli}
## Integrating with the CLI using code-generation schematics
## Integrating with the CLI
A library typically includes *reusable code* that defines components, services, and other Angular artifacts (pipes, directives, and so on) that you simply import into a project.
A library is packaged into an npm package for publishing and sharing.
This package can also include [schematics](guide/glossary#schematic) that provide instructions for generating or transforming code directly in your project, in the same way that the CLI creates a generic new component with `ng generate component`.
A schematic that is packaged with a library can, for example, provide the Angular CLI with the information it needs to generate a component that configures and uses a particular feature, or set of features, defined in that library.
One example of this is Angular Material's navigation schematic which configures the CDK's `BreakpointObserver` and uses it with Material's `MatSideNav` and `MatToolbar` components.
You can create and include the following kinds of schematics.
A library can include [schematics](guide/glossary#schematic) that allow it to integrate with the Angular CLI.
* Include an installation schematic so that `ng add` can add your library to a project.
@ -103,20 +105,11 @@ You can create and include the following kinds of schematics.
* Include an update schematic so that `ng update` can update your librarys dependencies and provide migrations for breaking changes in new releases.
What you include in your library depends on your task.
For example, you could define a schematic to create a dropdown that is pre-populated with canned data to show how to add it to an app.
If you want a dropdown that would contain different passed-in values each time, your library could define a schematic to create it with a given configuration. Developers could then use `ng generate` to configure an instance for their own app.
Suppose you want to read a configuration file and then generate a form based on that configuration.
If that form will need additional customization by the developer who is using your library, it might work best as a schematic.
However, if the forms will always be the same and not need much customization by developers, then you could create a dynamic component that takes the configuration and generates the form.
In general, the more complex the customization, the more useful the schematic approach.
To learn more, see [Schematics Overview](guide/schematics) and [Schematicsfor Libraries](guide/schematics-for-libraries).
## Publishing your library
Use the Angular CLI and the npm package manager to build and publish your library as an npm package.
Use the Angular CLI and the npm package manager to build and publish your library as an npm package.
Before publishing a library to NPM, build it using the `--prod` flag which will use the older compiler and runtime known as View Engine instead of Ivy.

View File

@ -448,13 +448,13 @@ When targeting older browsers, [polyfills](guide/browser-support#polyfills) can
To maximize compatibility, you could ship a single bundle that includes all your compiled code, plus any polyfills that may be needed.
Users with modern browsers, however, shouldn't have to pay the price of increased bundle size that comes with polyfills they don't need.
Differential loading, which is supported in Angular CLI version 8 and higher, can help solve this problem.
Differential loading, which is supported by default in Angular CLI version 8 and higher, solves this problem.
Differential loading is a strategy that allows your web application to support multiple browsers, but only load the necessary code that the browser needs. When differential loading is enabled the CLI builds two separate bundles as part of your deployed application.
Differential loading is a strategy that allows your web application to support multiple browsers, but only load the necessary code that the browser needs. When differential loading is enabled (which is the default) the CLI builds two separate bundles as part of your deployed application.
* The first bundle contains modern ES2015 syntax. This bundle takes advantage of built-in support in modern browsers, ships fewer polyfills, and results in a smaller bundle size.
* The first bundle contains modern ES2015 syntax, takes advantage of built-in support in modern browsers, ships fewer polyfills, and results in a smaller bundle size.
* The second bundle contains code in the old ES5 syntax, along with all necessary polyfills. This second bundle is larger, but supports older browsers.
* The second bundle contains code in the old ES5 syntax, along with all necessary polyfills. This results in a larger bundle size, but supports older browsers.
### Differential builds
@ -463,9 +463,9 @@ The [`ng build` CLI command](cli/build) queries the browser configuration and th
The following configurations determine your requirements.
* Browserslist
* Browsers list
The Browserslist configuration file is included in your application [project structure](guide/file-structure#application-configuration-files) and provides the minimum browsers your application supports. See the [Browserslist spec](https://github.com/browserslist/browserslist) for complete configuration options.
The `browserslist` configuration file is included in your application [project structure](guide/file-structure#application-configuration-files) and provides the minimum browsers your application supports. See the [Browserslist spec](https://github.com/browserslist/browserslist) for complete configuration options.
* TypeScript configuration
@ -509,27 +509,16 @@ Each script tag has a `type="module"` or `nomodule` attribute. Browsers with nat
### Configuring differential loading
To include differential loading in your application builds, you must configure the Browserslist and TypeScript configuration files in your application project.
Differential loading is supported by default with version 8 and later of the Angular CLI.
For each application project in your workspace, you can configure how builds are produced based on the `browserslist` and `tsconfig.json` configuration files in your application project.
The following examples show a `browserlistrc` and `tsconfig.json` file for a newly created Angular application. In this configuration, legacy browsers such as IE 9-11 are ignored, and the compilation target is ES2015.
For a newly created Angular application, legacy browsers such as IE 9-11 are ignored, and the compilation target is ES2015.
<code-example language="none" header="browserslistrc">
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# For the full list of supported browsers by the Angular framework, please see:
# https://angular.io/guide/browser-support
# You can see what browsers were selected by your queries by running:
# npx browserslist
last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major version
last 2 iOS major versions
<code-example language="none" header="browserslist">
> 0.5%
last 2 versions
Firefox ESR
not dead
not IE 9-11 # For IE 9-11 support, remove 'not'.
</code-example>
@ -560,24 +549,36 @@ not IE 9-11 # For IE 9-11 support, remove 'not'.
</code-example>
The default configuration creates two builds, with differential loading enabled.
<div class="alert is-important">
To see which browsers are supported and determine which settings meet to your browser support requirements, see the [Browserslist compatibility page](https://browserl.ist/?q=%3E+0.5%25%2C+last+2+versions%2C+Firefox+ESR%2C+not+dead%2C+not+IE+9-11).
To see which browsers are supported with the default configuration and determine which settings meet to your browser support requirements, see the [Browserslist compatibility page](https://browserl.ist/?q=%3E+0.5%25%2C+last+2+versions%2C+Firefox+ESR%2C+not+dead%2C+not+IE+9-11).
</div>
The Browserslist configuration allows you to ignore browsers without ES2015 support. In this case, a single build is produced.
The `browserslist` configuration allows you to ignore browsers without ES2015 support. In this case, a single build is produced.
If your Browserslist configuration includes support for any legacy browsers, the build target in the TypeScript configuration determines whether the build will support differential loading.
If your `browserslist` configuration includes support for any legacy browsers, the build target in the TypeScript configuration determines whether the build will support differential loading.
{@a configuration-table }
| Browserslist | ES target | Build result |
| browserslist | ES target | Build result |
| -------- | -------- | -------- |
| ES5 support disabled | es2015 | Single build, ES5 not required |
| ES5 support enabled | es5 | Single build w/conditional polyfills for ES5 only |
| ES5 support enabled | es2015 | Differential loading (two builds w/conditional polyfills) |
### Opting out of differential loading
Differential loading can be explicitly disabled if it causes unexpected issues, or if you need to target ES5 specifically for legacy browser support.
To explicitly disable differential loading and create an ES5 build:
- Enable the `dead` or `IE` browsers in the `browserslist` configuration file by removing the `not` keyword in front of them.
- To create a single ES5 build, set the target in the `compilerOptions` to `es5`.
{@a test-and-serve}
## Local development in older browsers

View File

@ -58,12 +58,12 @@ v9 - v12
| `@angular/core` | [`ANALYZE_FOR_ENTRY_COMPONENTS`](api/core/ANALYZE_FOR_ENTRY_COMPONENTS) | <!--v9--> v11 |
| `@angular/router` | [`loadChildren` string syntax](#loadChildren) | <!--v9--> v11 |
| `@angular/core/testing` | [`TestBed.get`](#testing) | <!--v9--> v12 |
| `@angular/core/testing` | [`async`](#testing) | <!--v9--> v12 |
| `@angular/router` | [`ActivatedRoute` params and `queryParams` properties](#activatedroute-props) | unspecified |
| template syntax | [`/deep/`, `>>>`, and `::ng-deep`](#deep-component-style-selector) | <!--v7--> unspecified |
| browser support | [`IE 9 and 10, IE mobile`](#ie-9-10-and-mobile) | <!--v10--> v11 |
For information about Angular CDK and Angular Material deprecations, see the [changelog](https://github.com/angular/components/blob/master/CHANGELOG.md).
## Deprecated APIs
@ -109,7 +109,6 @@ Tip: In the [API reference section](api) of this doc site, deprecated APIs are i
| API | Replacement | Deprecation announced | Notes |
| --- | ----------- | --------------------- | ----- |
| [`TestBed.get`](api/core/testing/TestBed#get) | [`TestBed.inject`](api/core/testing/TestBed#inject) | v9 | Same behavior, but type safe. |
| [`async`](api/core/testing/async) | [`waitForAsync`](api/core/testing/waitForAsync) | v10 | Same behavior, but rename to avoid confusion. |
{@a forms}
@ -479,7 +478,7 @@ The final decision was made on three key points:
{@a wrapped-value}
### `WrappedValue`
### `WrappedValue`
The purpose of `WrappedValue` is to allow the same object instance to be treated as different for the purposes of change detection.
It is commonly used with the `async` pipe in the case where the `Observable` produces the same instance of the value.
@ -489,7 +488,7 @@ No replacement is planned for this deprecation.
If you rely on the behavior that the same object instance should cause change detection, you have two options:
- Clone the resulting value so that it has a new identity.
- Explicitly call [`ChangeDetectorRef.detectChanges()`](api/core/ChangeDetectorRef#detectchanges) to force the update.
- Explicitly call [`ChangeDetectorRef.detectChanges()`](api/core/ChangeDetectorRef#detectchanges) to force the update.
{@a deprecated-cli-flags}
## Deprecated CLI APIs and Options

View File

@ -79,7 +79,7 @@ To incorporate the feature module into your app, you have to let the root module
<code-example path="feature-modules/src/app/app.module.ts" region="app-module" header="src/app/app.module.ts"></code-example>
Now the `AppModule` knows about the feature module. If you were to add any service providers to the feature module, `AppModule` would know about those too, as would any other feature modules. However, NgModules dont expose their components by default.
Now the `AppModule` knows about the feature module. If you were to add any service providers to the feature module, `AppModule` would know about those too, as would any other feature modules. However, NgModules dont expose their components.
## Rendering a feature modules component template

View File

@ -40,7 +40,8 @@ The top level of the workspace contains workspace-wide configuration files, conf
| `package-lock.json` | Provides version information for all packages installed into `node_modules` by the npm client. See [npm documentation](https://docs.npmjs.com/files/package-lock.json) for details. If you use the yarn client, this file will be [yarn.lock](https://yarnpkg.com/lang/en/docs/yarn-lock/) instead. |
| `src/` | Source files for the root-level application project. |
| `node_modules/` | Provides [npm packages](guide/npm-packages) to the entire workspace. Workspace-wide `node_modules` dependencies are visible to all projects. |
| `tsconfig.json` | The base [TypeScript](https://www.typescriptlang.org/) configuration for projects in the workspace. All other configuration files inherit from this base file. For more information, see the [Configuration inheritance with extends](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#configuration-inheritance-with-extends) section of the TypeScript documentation.|
| `tsconfig.json` | The `tsconfig.json` file is a ["Solution Style"](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-9.html#support-for-solution-style-tsconfigjson-files) TypeScript configuration file. Code editors and TypeScripts language server use this file to improve development experience. Compilers do not use this file. |
| `tsconfig.base.json` | The base [TypeScript](https://www.typescriptlang.org/) configuration for projects in the workspace. All other configuration files inherit from this base file. For more information, see the [Configuration inheritance with extends](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#configuration-inheritance-with-extends) section of the TypeScript documentation.|
| `tslint.json` | Default [TSLint](https://palantir.github.io/tslint/) configuration for projects in the workspace. |
@ -102,7 +103,7 @@ Angular components, templates, and styles go here.
The application-specific configuration files for the root application reside at the workspace root level.
For a multi-project workspace, project-specific configuration files are in the project root, under `projects/project-name/`.
Project-specific [TypeScript](https://www.typescriptlang.org/) configuration files inherit from the workspace-wide `tsconfig.json`, and project-specific [TSLint](https://palantir.github.io/tslint/) configuration files inherit from the workspace-wide `tslint.json`.
Project-specific [TypeScript](https://www.typescriptlang.org/) configuration files inherit from the workspace-wide `tsconfig.base.json`, and project-specific [TSLint](https://palantir.github.io/tslint/) configuration files inherit from the workspace-wide `tslint.json`.
| APPLICATION-SPECIFIC CONFIG FILES | PURPOSE |
| :--------------------- | :------------------------------------------|

View File

@ -11,11 +11,11 @@ That said, some applications will likely need to apply some manual updates.
In version 10, [a few deprecated APIs have been removed](guide/updating-to-version-10#removals) and there are a [few breaking changes](guide/updating-to-version-10#breaking-changes) unrelated to Ivy.
If you're seeing errors after updating to version 9, you'll first want to rule those changes out.
To do so, temporarily [turn off Ivy](guide/ivy#opting-out-of-angular-ivy) in your `tsconfig.json` and re-start your app.
To do so, temporarily [turn off Ivy](guide/ivy#opting-out-of-angular-ivy) in your `tsconfig.base.json` and re-start your app.
If you're still seeing the errors, they are not specific to Ivy. In this case, you may want to consult the [general version 10 guide](guide/updating-to-version-10). If you've opted into any of the new, stricter type-checking settings, you may also want to check out the [template type-checking guide](guide/template-typecheck).
If the errors are gone, switch back to Ivy by removing the changes to the `tsconfig.json` and review the list of expected changes below.
If the errors are gone, switch back to Ivy by removing the changes to the `tsconfig.base.json` and review the list of expected changes below.
{@a payload-size-debugging}
### Payload size debugging

View File

@ -87,7 +87,7 @@ To make one, enter the following command in the terminal, where `customers` is t
ng generate module customers --route customers --module app.module
</code-example>
This creates a `customers` folder having the new lazy-loadable feature module `CustomersModule` defined in the `customers.module.ts` file and the routing module `CustomersRoutingModule` defined in the `customers-routing.module.ts` file. The command automatically declares the `CustomersComponent` and imports `CustomersRoutingModule` inside the new feature module.
This creates a `customers` folder with the new lazy-loadable module `CustomersModule` defined in the `customers.module.ts` file. The command automatically declares the `CustomersComponent` inside the new feature module.
Because the new module is meant to be lazy-loaded, the command does NOT add a reference to the new feature module in the application's root module file, `app.module.ts`.
Instead, it adds the declared route, `customers` to the `routes` array declared in the module provided as the `--module` option.

View File

@ -1,187 +0,0 @@
# Optimizing client app size with lightweight injection tokens
This page provides a conceptual overview of a dependency injection technique that is recommended for library developers.
Designing your library with *lightweight injection tokens* helps optimize the bundle size of client applications that use your library.
You can manage the dependency structure among your components and injectable services to optimize bundle size by using [tree-shakable providers](guide/dependency-injection-providers#tree-shakable-providers).
This normally ensures that if a provided component or service is never actually used by the app, the compiler can eliminate its code from the bundle.
However, due to the way Angular stores injection tokens, it is possible that such an unused component or service can end up in the bundle anyway.
This page describes a dependency-injection design pattern that supports proper tree-shaking by using lightweight injection tokens.
The lightweight injection token design pattern is especially important for library developers. It ensures that when an application uses only some of your library's capabilities, the unused code can be eliminated from the client's app bundle.
When an application uses your library, there might be some services that your library supplies which the client app doesn't use.
In this case, the app developer should expect that service to be tree-shaken, and not contribute to the size of the compiled app.
Because the application developer cannot know about or remedy a tree-shaking problem in the library, it is the responsibility of the library developer to do so.
To prevent the retention of unused components, your library should use the lightweight injection token design pattern.
## When tokens are retained
To better explain the condition under which token retention occurs, consider a library that provides a library-card component, which contains a body and can contain an optional header.
```
<lib-card>
<lib-header>...</lib-header>
</lib-card>
```
In a likely implementation, the `<lib-card>` component uses `@ContentChild()` or `@ContentChildren()` to obtain `<lib-header>` and `<lib-body>`, as in the following.
```
@Component({
selector: 'lib-header',
...,
})
class LibHeaderComponent {}
@Component({
selector: 'lib-card',
...,
})
class LibCardComponent {
@ContentChild(LibHeaderComponent)
header: LibHeaderComponent|null = null;
}
```
Because `<lib-header>` is optional, the element can appear in the template in its minimal form,
`<lib-card></lib-card>`.
In this case, `<lib-header>` is not used and you would expect it to be tree-shaken, but that is not what happens.
This is because `LibCardComponent` actually contains two references to the `LibHeaderComponent`.
`@ContentChild(LibHeaderComponent) header: LibHeaderComponent;`
* One of these reference is in the *type position*-- that is, it specifies `LibHeaderComponent` as a type: `header: LibHeaderComponent;`.
* The other reference is in the *value position*-- that is, LibHeaderComponent is the value of the `@ContentChild()` parameter decorator: `@ContentChild(LibHeaderComponent)`.
The compiler handles token references in these positions differently.
* The compiler erases *type position* references after conversion from TypeScript, so they have no impact on tree-shaking.
* The compiler must retain *value position* references at runtime, which prevents the component from being tree-shaken.
In the example, the compiler retains the `LibHeaderComponent` token that occurs in the value position, which prevents the referenced component from being tree-shaken, even if the application developer does not actually use `<lib-header>` anywhere.
If `LibHeaderComponent` is large (code, template, and styles), including it unnecessarily can significantly increase the size of the client application.
## When to use the lightweight injection token pattern
The tree-shaking problem arises when a component is used as an injection token.
There are two cases when that can happen.
* The token is used in the value position of a [content query](guide/lifecycle-hooks#using-aftercontent-hooks "See more about using content queries.").
* The token is used as a type specifier for constructor injection.
In the following example, both uses of the `OtherComponent` token cause retention of `OtherComponent` (that is, prevent it from being tree-shaken when it is not used).
```
class MyComponent {
constructor(@Optional() other: OtherComponent) {}
@ContentChild(OtherComponent)
other: OtherComponent|null;
}
```
Although tokens used only as type specifiers are removed when converted to JavaScript, all tokens used for dependency injection are needed at runtime.
These effectively change `constructor(@Optional() other: OtherComponent)` to `constructor(@Optional() @Inject(OtherComponent) other)`. The token is now in a value position, and causes the tree shaker to retain the reference.
<div class="alert is helpful">
For all services, a library should use [tree-shakable providers](guide/dependency-injection-providers#tree-shakable-providers), providing dependencies at the root level rather than in component constructors.
</div>
## Using lightweight injection tokens
The lightweight injection token design pattern consists of using a small abstract class as an injection token, and providing the actual implementation at a later stage.
The abstract class is retained (not tree-shaken), but it is small and has no material impact on the application size.
The following example shows how this works for the `LibHeaderComponent`.
```
abstract class LibHeaderToken {}
@Component({
selector: 'lib-header',
providers: [
{provide: LibHeaderToken, useExisting: LibHeaderComponent}
]
...,
})
class LibHeaderComponent extends LibHeaderToken {}
@Component({
selector: 'lib-card',
...,
})
class LibCardComponent {
@ContentChild(LibHeaderToken) header: LibHeaderToken|null = null;
}
```
In this example, the `LibCardComponent` implementation no longer refers to `LibHeaderComponent` in either the type position or the value position.
This allows full tree shaking of `LibHeaderComponent` to take place.
The `LibHeaderToken` is retained, but it is only a class declaration, with no concrete implementation. It is small and does not materially impact the application size when retained after compilation.
Instead, `LibHeaderComponent` itself implements the abstract `LibHeaderToken` class. You can safely use that token as the provider in the component definition, allowing Angular to correctly inject the concrete type.
To summarize, the lightweight injection token pattern consists of the following.
1. A lightweight injection token that is represented as an abstract class.
2. A component definition that implements the abstract class.
3. Injection of the lightweight pattern, using ` @ContentChild()` or `@ContentChildren()`.
4. A provider in the implementation of the lightweight injection token which associates the lightweight injection token with the implementation.
### Use the lightweight injection token for API definition
A component that injects a lightweight injection token might need to invoke a method in the injected class.
Because the token is now an abstract class, and the injectable component implements that class, you must also declare an abstract method in the abstract lightweight injection token class.
The implementation of the method (with all of its code overhead) resides in the injectable component that can be tree-shaken.
This allows the parent to communicate with the child (if it is present) in a type-safe manner.
For example, the `LibCardComponent` now queries`LibHeaderToken` rather than `LibHeaderComponent`.
The following example shows how the pattern allows `LibCardComponent` to communicate with the `LibHeaderComponent` without actually referring to `LibHeaderComponent`.
```
abstract class LibHeaderToken {
abstract doSomething(): void;
}
@Component({
selector: 'lib-header',
providers: [
{provide: LibHeaderToken, useExisting: LibHeader}
]
...,
})
class LibHeaderComponent extends LibHeaderToken {
doSomething(): void {
// Concrete implementation of `doSomething`
}
}
@Component({
selector: 'lib-card',
...,
})
class LibCardComponent implement AfterContentInit {
@ContentChild(LibHeaderToken)
header: LibHeaderToken|null = null;
ngAfterContentInit(): void {
this.header && this.header.doSomething();
}
}
```
In this example the parent queries the token to obtain the child component, and stores the resulting component reference if it is present.
Before calling a method in the child, the parent component checks to see if the child component is present.
If the child component has been tree-shaken, there is no runtime reference to it, and no call to its method.
### Naming your lightweight injection token
Lightweight injection tokens are only useful with components. The Angular style guide suggests that you name components using the "Component" suffix. The example "LibHeaderComponent" follows this convention.
To maintain the relationship between the component and its token while still distinguishing between them, the recommended style is to use the component base name with the suffix "Token" to name your lightweight injection tokens: "LibHeaderToken".

View File

@ -0,0 +1,55 @@
# Solution-style `tsconfig.json` migration
## What does this migration do?
This migration adds support to existing projects for TypeScript's new ["solution-style" tsconfig feature](https://devblogs.microsoft.com/typescript/announcing-typescript-3-9/#solution-style-tsconfig).
Support is added by making two changes:
1. Renaming the workspace-level `tsconfig.json` to `tsconfig.base.json`.
All project [TypeScript configuration files](guide/typescript-configuration) will extend from this base which contains the common options used throughout the workspace.
2. Adding the solution `tsconfig.json` file at the root of the workspace.
This `tsconfig.json` file will only contain references to project-level TypeScript configuration files and is only used by editors/IDEs.
As an example, the solution `tsconfig.json` for a new project is as follows:
```json
// This is a "Solution Style" tsconfig.json file, and is used by editors and TypeScripts language server to improve development experience.
// It is not intended to be used to perform a compilation.
{
"files": [],
"references": [
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.spec.json"
},
{
"path": "./e2e/tsconfig.json"
}
]
}
```
## Why is this migration necessary?
Solution-style `tsconfig.json` files provide an improved editing experience and fix several long-standing defects when editing files in an IDE.
IDEs that leverage the TypeScript language service (for example, [Visual Studio Code](https://code.visualstudio.com)), will only use TypeScript configuration files that are named `tsconfig.json`.
In complex projects, there may be more than one compilation unit and each of these units may have different settings and options.
With the Angular CLI, a project will have application code that will target a browser.
It will also have unit tests that should not be included within the built application and that also need additional type information present (`jasmine` in this case).
Both parts of the project also share some but not all of the code within the project.
As a result, two separate TypeScript configuration files (`tsconfig.app.json` and `tsconfig.spec.json`) are needed to ensure that each part of the application is configured properly and that the right types are used for each part.
Also if web workers are used within a project, an additional tsconfig (`tsconfig.worker.json`) is needed.
Web workers use similar but incompatible types to the main browser application.
This requires the additional configuration file to ensure that the web worker files use the appropriate types and will build successfully.
While the Angular build system knows about all of these TypeScript configuration files, an IDE using TypeScript's language service does not.
Because of this, an IDE will not be able to properly analyze the code from each part of the project and may generate false errors or make suggestions that are incorrect for certain files.
By leveraging the new solution-style tsconfig, the IDE can now be aware of the configuration of each part of a project.
This allows each file to be treated appropriately based on its tsconfig.
IDE features such as error/warning reporting and auto-suggestion will operate more effectively as well.
The TypeScript 3.9 release [blog post](https://devblogs.microsoft.com/typescript/announcing-typescript-3-9/#solution-style-tsconfig) also contains some additional information regarding this new feature.

View File

@ -9,7 +9,7 @@ This process helps ensure that intentional changes to the options are kept in pl
TypeScript Configuration File(s) | Changed Property | Existing Value | New Value
------------- | ------------- | ------------- | ------------- | -------------
`<workspace base>/tsconfig.json` | `"module"` | `"esnext"` | `"es2020"`
`<workspace base>/tsconfig.base.json` | `"module"` | `"esnext"` | `"es2020"`
Used in `browser` builder options (`ng build` for applications) | `"module"` | `"esnext"` | `"es2020"`
Used in `ng-packgr` builder options (`ng build` for libraries) | `"module"` | `"esnext"` | `"es2020"`
Used in `karma` builder options (`ng test` for applications) | `"module"` | `"esnext"` | `"es2020"`

View File

@ -101,7 +101,7 @@ should import `BrowserModule` from `@angular/platform-browser`.
`BrowserModule` provides services that are essential to launch and run a browser app.
`BrowserModule` also re-exports `CommonModule` from `@angular/common`,
which means that components in the `AppModule` also have access to
which means that components in the `AppModule` module also have access to
the Angular directives every app needs, such as `NgIf` and `NgFor`.
Do not import `BrowserModule` in any other module.
@ -140,7 +140,7 @@ declared in this NgModule.
You _can_ export any declarable class&mdash;components, directives, and pipes&mdash;whether
it's declared in this NgModule or in an imported NgModule.
You _can_ re-export entire imported NgModules, which effectively re-export all of their exported classes.
You _can_ re-export entire imported NgModules, which effectively re-exports all of their exported classes.
An NgModule can even export a module that it doesn't import.
<hr/>
@ -192,7 +192,7 @@ Its only purpose is to add http service providers to the application as a whole.
The `forRoot()` static method is a convention that makes it easy for developers to configure services and providers that are intended to be singletons. A good example of `forRoot()` is the `RouterModule.forRoot()` method.
Apps pass a `Routes` array to `RouterModule.forRoot()` in order to configure the app-wide `Router` service with routes.
Apps pass a `Routes` object to `RouterModule.forRoot()` in order to configure the app-wide `Router` service with routes.
`RouterModule.forRoot()` returns a [ModuleWithProviders](api/core/ModuleWithProviders).
You add that result to the `imports` list of the root `AppModule`.

View File

@ -36,7 +36,7 @@ NgModule metadata does the following:
* Declares which components, directives, and pipes belong to the module.
* Makes some of those components, directives, and pipes public so that other module's component templates can use them.
* Imports other modules with the components, directives, and pipes that components in the current module need.
* Provides services that other application components can use.
* Provides services that the other application components can use.
Every Angular app has at least one module, the root module.
You [bootstrap](guide/bootstrapping) that module to launch the application.

View File

@ -114,7 +114,6 @@ In case of a false positive like these, there are a few options:
|Strictness flag|Effect|
|-|-|
|`strictInputTypes`|Whether the assignability of a binding expression to the `@Input()` field is checked. Also affects the inference of directive generic types. |
|`strictInputAccessModifiers`|Whether access modifiers such as `private`/`protected`/`readonly` are honored when assigning a binding expression to an `@Input()`. If disabled, the access modifiers of the `@Input` are ignored; only the type is checked.|
|`strictNullInputTypes`|Whether `strictNullChecks` is honored when checking `@Input()` bindings (per `strictInputTypes`). Turning this off can be useful when using a library that was not built with `strictNullChecks` in mind.|
|`strictAttributeTypes`|Whether to check `@Input()` bindings that are made using text attributes (for example, `<mat-tab label="Step 1">` vs `<mat-tab [label]="'Step 1'">`).
|`strictSafeNavigationTypes`|Whether the return type of safe navigation operations (for example, `user?.name`) will be correctly inferred based on the type of `user`). If disabled, `user?.name` will be of type `any`.

View File

@ -159,10 +159,10 @@ It also generates an initial test file for the component, `banner-external.compo
<div class="alert is-helpful">
Because `compileComponents` is asynchronous, it uses
the [`waitForAsync`](api/core/testing/waitForAsync) utility
the [`async`](api/core/testing/async) utility
function imported from `@angular/core/testing`.
Please refer to the [waitForAsync](guide/testing-components-scenarios#waitForAsync) section for more details.
Please refer to the [async](guide/testing-components-scenarios#async) section for more details.
</div>
@ -375,5 +375,6 @@ Some noteworthy observations:
When you're filtering by CSS selector and only testing properties of a browser's _native element_, the `By.css` approach may be overkill.
It's often easier and more clear to filter with a standard `HTMLElement` method
such as `querySelector()` or `querySelectorAll()`.
such as `querySelector()` or `querySelectorAll()`,
as you'll see in the next set of tests.

View File

@ -190,7 +190,7 @@ It knows who the user is based on a property of the injected `UserService`:
<code-example path="testing/src/app/welcome/welcome.component.ts" header="app/welcome/welcome.component.ts"></code-example>
The `WelcomeComponent` has decision logic that interacts with the service, logic that makes this component worth testing.
Here's the testing module configuration for the spec file:
Here's the testing module configuration for the spec file, `app/welcome/welcome.component.spec.ts`:
<code-example path="testing/src/app/welcome/welcome.component.spec.ts" region="config-test-module" header="app/welcome/welcome.component.spec.ts"></code-example>
@ -402,7 +402,7 @@ There is no nested syntax (like a `Promise.then()`) to disrupt the flow of contr
<div class="alert is-helpful">
Limitation: The `fakeAsync()` function won't work if the test body makes an `XMLHttpRequest` (XHR) call.
XHR calls within a test are rare, but if you need to call XHR, see [`waitForAsync()`](#waitForAsync), below.
XHR calls within a test are rare, but if you need to call XHR, see [`async()`](#async), below.
</div>
@ -415,7 +415,7 @@ You do have to call [tick()](api/core/testing/tick) to advance the (virtual) clo
Calling [tick()](api/core/testing/tick) simulates the passage of time until all pending asynchronous activities finish.
In this case, it waits for the error handler's `setTimeout()`.
The [tick()](api/core/testing/tick) function accepts milliseconds and tickOptions as parameters, the millisecond (defaults to 0 if not provided) parameter represents how much the virtual clock advances. For example, if you have a `setTimeout(fn, 100)` in a `fakeAsync()` test, you need to use tick(100) to trigger the fn callback. The tickOptions is an optional parameter with a property called `processNewMacroTasksSynchronously` (defaults to true) that represents whether to invoke new generated macro tasks when ticking.
The [tick()](api/core/testing/tick) function accepts milliseconds and tickOptions as parameters, the millisecond (defaults to 0 if not provided) parameter represents how much the virtual clock advances. For example, if you have a `setTimeout(fn, 100)` in a `fakeAsync()` test, you need to use tick(100) to trigger the fn callback. The tickOptions is an optional parameter with a property called `processNewMacroTasksSynchronously` (defaults to true) represents whether to invoke new generated macro tasks when ticking.
<code-example
path="testing/src/app/demo/async-helper.spec.ts"
@ -587,36 +587,41 @@ Then call `detectChanges()` to tell Angular to update the screen.
Then you can assert that the quote element displays the expected text.
{@a waitForAsync}
{@a async}
#### Async test with _waitForAsync()_
#### Async test with _async()_
To use `waitForAsync()` functionality, you must import `zone.js/dist/zone-testing` in your test setup file.
To use `async()` functionality, you must import `zone.js/dist/zone-testing` in your test setup file.
If you created your project with the Angular CLI, `zone-testing` is already imported in `src/test.ts`.
The `fakeAsync()` utility function has a few limitations.
In particular, it won't work if the test body makes an `XMLHttpRequest` (XHR) call.
XHR calls within a test are rare so you can generally stick with [`fakeAsync()`](#fake-async).
But if you ever do need to call `XMLHttpRequest`, you'll want to know about `async()`.
<div class="alert is-helpful">
The `TestBed.compileComponents()` method (see [below](#compile-components)) calls `XHR`
to read external template and css files during "just-in-time" compilation.
Write tests that call `compileComponents()` with the `waitForAsync()` utility.
Write tests that call `compileComponents()` with the `async()` utility.
</div>
Here's the previous `fakeAsync()` test, re-written with the `waitForAsync()` utility.
Here's the previous `fakeAsync()` test, re-written with the `async()` utility.
<code-example
path="testing/src/app/twain/twain.component.spec.ts"
region="async-test">
</code-example>
The `waitForAsync()` utility hides some asynchronous boilerplate by arranging for the tester's code
The `async()` utility hides some asynchronous boilerplate by arranging for the tester's code
to run in a special _async test zone_.
You don't need to pass Jasmine's `done()` into the test and call `done()` because it is `undefined` in promise or observable callbacks.
But the test's asynchronous nature is revealed by the call to `fixture.whenStable()`,
which breaks the linear flow of control.
When using an `intervalTimer()` such as `setInterval()` in `waitForAsync()`, remember to cancel the timer with `clearInterval()` after the test, otherwise the `waitForAsync()` never ends.
When using an `intervalTimer()` such as `setInterval()` in `async()`, remember to cancel the timer with `clearInterval()` after the test, otherwise the `async()` never ends.
{@a when-stable}
@ -636,18 +641,18 @@ update the quote element with the expected text.
#### Jasmine _done()_
While the `waitForAsync()` and `fakeAsync()` functions greatly
While the `async()` and `fakeAsync()` functions greatly
simplify Angular asynchronous testing,
you can still fall back to the traditional technique
and pass `it` a function that takes a
[`done` callback](https://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support).
You can't call `done()` in `waitForAsync()` or `fakeAsync()` functions, because the `done parameter`
You can't call `done()` in `async()` or `fakeAsync()` functions, because the `done parameter`
is `undefined`.
Now you are responsible for chaining promises, handling errors, and calling `done()` at the appropriate moments.
Writing test functions with `done()`, is more cumbersome than `waitForAsync()`and `fakeAsync()`, but it is occasionally necessary when code involves the `intervalTimer()` like `setInterval`.
Writing test functions with `done()`, is more cumbersome than `async()`and `fakeAsync()`, but it is occasionally necessary when code involves the `intervalTimer()` like `setInterval`.
Here are two more versions of the previous test, written with `done()`.
The first one subscribes to the `Observable` exposed to the template by the component's `quote` property.
@ -733,7 +738,7 @@ you tell the `TestScheduler` to _flush_ its queue of prepared tasks like this.
region="test-scheduler-flush"></code-example>
This step serves a purpose analogous to [tick()](api/core/testing/tick) and `whenStable()` in the
earlier `fakeAsync()` and `waitForAsync()` examples.
earlier `fakeAsync()` and `async()` examples.
The balance of the test is the same as those examples.
#### Marble error testing
@ -1226,7 +1231,7 @@ and provide for _all_ services injected in _any_ component in the tree.
That's too much effort just to answer a few simple questions about links.
This section describes two techniques for minimizing the setup.
Use them, alone or in combination, to stay focused on testing the primary component.
Use them, alone or in combination, to stay focused on the testing the primary component.
{@a stub-component}
@ -1335,7 +1340,7 @@ The `HostListener` wires the click event of the host element
Clicking the anchor should trigger the `onClick()` method,
which sets the stub's telltale `navigatedTo` property.
Tests inspect `navigatedTo` to confirm that clicking the anchor
sets the expected route definition.
set the expected route definition.
<div class="alert is-helpful">
@ -1530,7 +1535,7 @@ You must call `compileComponents()` within an asynchronous test function.
<div class="alert is-critical">
If you neglect to make the test function async
(e.g., forget to use `waitForAsync()` as described below),
(e.g., forget to use `async()` as described below),
you'll see this error message
<code-example language="sh" class="code-shell" hideCopy>
@ -1544,7 +1549,7 @@ A typical approach is to divide the setup logic into two separate `beforeEach()`
1. An async `beforeEach()` that compiles the components
1. A synchronous `beforeEach()` that performs the remaining setup.
To follow this pattern, import the `waitForAsync()` helper with the other testing symbols.
To follow this pattern, import the `async()` helper with the other testing symbols.
<code-example
path="testing/src/app/banner/banner-external.component.spec.ts"
@ -1560,7 +1565,7 @@ Write the first async `beforeEach` like this.
region="async-before-each"
header="app/banner/banner-external.component.spec.ts (async beforeEach)"></code-example>
The `waitForAsync()` helper function takes a parameterless function with the body of the setup.
The `async()` helper function takes a parameterless function with the body of the setup.
The `TestBed.configureTestingModule()` method returns the `TestBed` class so you can chain
calls to other `TestBed` static methods such as `compileComponents()`.
@ -1568,7 +1573,7 @@ calls to other `TestBed` static methods such as `compileComponents()`.
In this example, the `BannerComponent` is the only component to compile.
Other examples configure the testing module with multiple components
and may import application modules that hold yet more components.
Any of them could require external files.
Any of them could be require external files.
The `TestBed.compileComponents` method asynchronously compiles all components configured in the testing module.

View File

@ -19,13 +19,13 @@ Here's a summary of the stand-alone functions, in order of likely utility:
<tr>
<td style="vertical-align: top">
<code>waitForAsync</code>
<code>async</code>
</td>
<td>
Runs the body of a test (`it`) or setup (`beforeEach`) function within a special _async test zone_.
See [discussion above](guide/testing-components-scenarios#waitForAsync).
See [discussion above](guide/testing-components-scenarios#async).
</td>
</tr>

View File

@ -75,7 +75,7 @@ The tests run again, the browser refreshes, and the new test results appear.
The CLI takes care of Jasmine and Karma configuration for you.
You can fine-tune many options by editing the `karma.conf.js` in the root folder of the project and
You can fine-tune many options by editing the `karma.conf.js` and
the `test.ts` files in the `src/` folder.
The `karma.conf.js` file is a partial Karma configuration file.
@ -217,7 +217,7 @@ script:
- npm run e2e -- --protractor-config=e2e/protractor-ci.conf.js
```
This does the same things as the CircleCI configuration, except that Travis doesn't come with Chrome, so use Chromium instead.
This does the same things as the Circle CI configuration, except that Travis doesn't come with Chrome, so we use Chromium instead.
Step 2: Commit your changes and push them to your repository.

View File

@ -18,7 +18,32 @@ that are important to Angular developers, including details about the following
## Configuration files
A given Angular workspace contains several TypeScript configuration files.
At the root `tsconfig.json` file specifies the base TypeScript and Angular compiler options that all projects in the workspace inherit.
At the root level, there are two main TypeScript configuration files: a `tsconfig.json` file and a `tsconfig.base.json` file.
The `tsconfig.json` file is a ["Solution Style"](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-9.html#support-for-solution-style-tsconfigjson-files) TypeScript configuration file.
Code editors and TypeScripts language server use this file to improve development experience.
Compilers do not use this file.
The `tsconfig.json` file contains a list of paths to the other TypeScript configuration files used in the workspace.
<code-example lang="json" header="tsconfig.json" linenums="false">
{
"files": [],
"references": [
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.spec.json"
},
{
"path": "./projects/my-lib/tsconfig.lib.json"
}
]
}
</code-example>
The `tsconfig.base.json` file specifies the base TypeScript and Angular compiler options that all projects in the workspace inherit.
The TypeScript and Angular have a wide range of options which can be used to configure type-checking features and generated output.
For more information, see the [Configuration inheritance with extends](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#configuration-inheritance-with-extends) section of the TypeScript documentation.
@ -30,9 +55,9 @@ For details about configuration inheritance, see the [Configuration inheritance
</div>
The initial `tsconfig.json` for an Angular workspace typically looks like the following example.
The initial `tsconfig.base.json` for an Angular workspace typically looks like the following example.
<code-example lang="json" header="tsconfig.json" linenums="false">
<code-example lang="json" header="tsconfig.base.json" linenums="false">
{
"compileOnSave": false,
"compilerOptions": {

View File

@ -48,7 +48,8 @@ src/
app/ ... <i>application code</i>
app.server.module.ts <i>* server-side application module</i>
server.ts <i>* express web server</i>
tsconfig.json <i>TypeScript base configuration</i>
tsconfig.json <i>TypeScript solution style configuration</i>
tsconfig.base.json <i>TypeScript base configuration</i>
tsconfig.app.json <i>TypeScript browser application configuration</i>
tsconfig.server.json <i>TypeScript server application configuration</i>
tsconfig.spec.json <i>TypeScript tests configuration</i>
@ -226,7 +227,7 @@ as a navigation URL intended for the router.
Fortunately, application routes have something in common: their URLs lack file extensions.
(Data requests also lack extensions but they're easy to recognize because they always begin with `/api`.)
All static asset requests have a file extension (such as `main.js` or `/node_modules/zone.js/bundles/zone.umd.js`).
All static asset requests have a file extension (such as `main.js` or `/node_modules/zone.js/dist/zone.js`).
Because we use routing, we can easily recognize the three types of requests and handle them differently.

View File

@ -77,5 +77,6 @@ Read about the migrations the CLI handles for you automatically:
* [Migrating missing `@Directive()`/`@Component()` decorators](guide/migration-undecorated-classes)
* [Migrating `ModuleWithProviders`](guide/migration-module-with-providers)
* [Solution-style `tsconfig.json` migration](guide/migration-solution-style-tsconfig)
* [`tslib` direct dependency migration](guide/migration-update-libraries-tslib)
* [Update `module` and `target` compiler options migration](guide/migration-update-module-and-target-compiler-options)

View File

@ -306,9 +306,9 @@ If you develop angular locally with `ng serve`, a `websocket` connection is set
In Windows, by default, one application can only have 6 websocket connections, <a href="https://msdn.microsoft.com/library/ee330736%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396#websocket_maxconn" title="MSDN WebSocket settings">MSDN WebSocket Settings</a>.
So when IE is refreshed (manually or automatically by `ng serve`), sometimes the websocket does not close properly. When websocket connections exceed the limitations, a `SecurityError` will be thrown. This error will not affect the angular application, you can just restart IE to clear this error, or modify the windows registry to update the limitations.
## Appendix: Test using `fakeAsync()/waitForAsync()`
## Appendix: Test using `fakeAsync()/async()`
If you use the `fakeAsync()/waitForAsync()` helper function to run unit tests (for details, read the [Testing guide](guide/testing-components-scenarios#fake-async)), you need to import `zone.js/dist/zone-testing` in your test setup file.
If you use the `fakeAsync()/async()` helper function to run unit tests (for details, read the [Testing guide](guide/testing-components-scenarios#fake-async)), you need to import `zone.js/dist/zone-testing` in your test setup file.
<div class="alert is-important">
If you create project with `Angular/CLI`, it is already imported in `src/test.ts`.

View File

@ -743,11 +743,6 @@
"url": "guide/creating-libraries",
"title": "Creating Libraries",
"tooltip": "Extend Angular by creating, publishing, and using your own libraries."
},
{
"url": "guide/lightweight-injection-tokens",
"title": "Lightweight Injection Tokens for Libraries",
"tooltip": "Optimize client app size by designing library services with lightweight injection tokens."
}
]
},
@ -858,6 +853,11 @@
"title": "Missing @Injectable() Decorators",
"tooltip": "Migration to add missing @Injectable() decorators and incomplete provider definitions."
},
{
"url": "guide/migration-solution-style-tsconfig",
"title": "Solution-style `tsconfig.json`",
"tooltip": "Migration to create a solution-style `tsconfig.json`."
},
{
"url": "guide/migration-update-libraries-tslib",
"title": "`tslib` direct dependency",

View File

@ -40,7 +40,7 @@ A later part of this tutorial, [Use forms for user input](start/start-forms "Try
<code-example header="src/app/cart.service.ts" path="getting-started/src/app/cart.service.1.ts"></code-example>
<div class="alert is-helpful">
<div class="alert is-helpful>
The StackBlitz generator might provide the cart service in `app.module.ts` by default. That differs from the example, which uses a bundle-optimization technique, an `@Injectable()` decorator with the `{ providedIn: 'root' }` statement.
For more information about services, see [Introduction to Services and Dependency Injection](guide/architecture-services "Concepts > Intro to Services and DI").
@ -236,7 +236,7 @@ For more information about services, see [Introduction to Services and Dependenc
<!-- Accessing data with the HTTP client -->
Servers often return data in the form of a stream.
Streams are useful because they make it easy to transform the returned data and make modifications to the way you request that data.
Streams are useful because they make it easy to transform the returned data and make modifications to the way you request that data.
The Angular HTTP client, `HttpClient`, is a built-in way to fetch data from external APIs and provide them to your app as a stream.
This section shows you how to use the HTTP client to retrieve shipping prices from an external file.

View File

@ -23,7 +23,7 @@
"build-local-with-viewengine": "yarn ~~build",
"prebuild-local-with-viewengine-ci": "node scripts/switch-to-viewengine && yarn setup-local-ci",
"build-local-with-viewengine-ci": "yarn ~~build --progress=false",
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js ef770f1cb",
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js a404d2a86",
"lint": "yarn check-env && yarn docs-lint && ng lint && yarn example-lint && yarn tools-lint",
"test": "yarn check-env && ng test",
"pree2e": "yarn check-env && yarn update-webdriver",

View File

@ -5,13 +5,9 @@
</div>
<mat-toolbar color="primary" class="app-toolbar no-print" [class.transitioning]="isTransitioning">
<mat-toolbar-row class="notification-container">
<aio-notification notificationId="survey-march-2020" expirationDate="2020-04-15" [dismissOnContentClick]="true" (dismissed)="notificationDismissed()">
<a href="https://goo.gle/angular-survey-2020">
<mat-icon class="icon" svgIcon="insert_comment" aria-label="Announcement"></mat-icon>
<span class="message">Help Angular by taking a <b>1 minute survey</b>!</span>
<span class="action-button">Go to survey</span>
</a>
<mat-toolbar-row class="notification-container blm-message">
<aio-notification notificationId="blm-2020" expirationDate="2022-04-15" [dismissOnContentClick]="true" (dismissed)="notificationDismissed()">
#BlackLivesMatter
</aio-notification>
</mat-toolbar-row>
<mat-toolbar-row>

View File

@ -8,11 +8,6 @@
Join the community of millions of developers who build compelling user interfaces with Angular.">
<base href="/">
<link rel="preconnect" href="https://www.google-analytics.com">
<link rel="dns-prefetch" href="https://www.google-analytics.com">
<link rel="preconnect" href="https://stats.g.doubleclick.net">
<link rel="dns-prefetch" href="https://stats.g.doubleclick.net">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="search" type="application/opensearchdescription+xml" href="assets/opensearch.xml">

View File

@ -183,8 +183,8 @@ section#intro {
// ANGULAR LINE
.background-sky {
background-color: $blue;
background: $bluegradient;
background-color: $black;
background: $black;
color: $white;
}

View File

@ -22,9 +22,16 @@ mat-toolbar.mat-toolbar {
}
}
.blm-message {
text-align: center;
justify-content: center;
background: #2d2d2d;
font-size: 0.75em;
}
// HOME PAGE OVERRIDE: TOPNAV TOOLBAR
aio-shell.page-home mat-toolbar.mat-toolbar {
background-color: $blue;
background-color: $black;
@media (min-width: 481px) {
&:not(.transitioning) {

View File

@ -8,7 +8,6 @@ ts_library(
],
module_name = "@angular/dev-infra-private",
deps = [
"//dev-infra/caretaker",
"//dev-infra/commit-message",
"//dev-infra/format",
"//dev-infra/pr",

View File

@ -132,7 +132,7 @@ def component_benchmark(
# The server for our application.
ts_devserver(
name = server,
bootstrap = ["//packages/zone.js/bundles:zone.umd.js"],
bootstrap = ["//packages/zone.js/dist:zone.js"],
port = 4200,
static_files = assets + styles,
deps = [":" + app_main + ".min_debug.js"],

View File

@ -1,26 +0,0 @@
load("@npm_bazel_typescript//:index.bzl", "ts_library")
ts_library(
name = "caretaker",
srcs = [
"cli.ts",
],
module_name = "@angular/dev-infra-private/caretaker",
visibility = ["//dev-infra:__subpackages__"],
deps = [
"//dev-infra/caretaker/check",
"@npm//@types/yargs",
"@npm//yargs",
],
)
ts_library(
name = "config",
srcs = [
"config.ts",
],
visibility = ["//dev-infra:__subpackages__"],
deps = [
"//dev-infra/utils",
],
)

View File

@ -1,21 +0,0 @@
load("@npm_bazel_typescript//:index.bzl", "ts_library")
ts_library(
name = "check",
srcs = glob(["*.ts"]),
module_name = "@angular/dev-infra-private/caretaker/service-statuses",
visibility = ["//dev-infra:__subpackages__"],
deps = [
"//dev-infra/caretaker:config",
"//dev-infra/utils",
"@npm//@types/fs-extra",
"@npm//@types/node",
"@npm//@types/node-fetch",
"@npm//@types/yargs",
"@npm//multimatch",
"@npm//node-fetch",
"@npm//typed-graphqlify",
"@npm//yaml",
"@npm//yargs",
],
)

View File

@ -1,27 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {GitClient} from '../../utils/git';
import {getCaretakerConfig} from '../config';
import {printG3Comparison} from './g3';
import {printGithubTasks} from './github';
import {printServiceStatuses} from './services';
/** Check the status of services which Angular caretakers need to monitor. */
export async function checkServiceStatuses(githubToken: string) {
/** The configuration for the caretaker commands. */
const config = getCaretakerConfig();
/** The GitClient for interacting with git and Github. */
const git = new GitClient(githubToken, config);
await printServiceStatuses();
await printGithubTasks(git, config.caretaker);
await printG3Comparison(git);
}

View File

@ -1,39 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {Arguments, Argv, CommandModule} from 'yargs';
import {addGithubTokenFlag} from '../../utils/yargs';
import {checkServiceStatuses} from './check';
export interface CaretakerCheckOptions {
githubToken: string;
}
/** URL to the Github page where personal access tokens can be generated. */
export const GITHUB_TOKEN_GENERATE_URL = `https://github.com/settings/tokens`;
/** Builds the command. */
function builder(yargs: Argv) {
return addGithubTokenFlag(yargs);
}
/** Handles the command. */
async function handler({githubToken}: Arguments<CaretakerCheckOptions>) {
await checkServiceStatuses(githubToken);
}
/** yargs command module for checking status information for the repository */
export const CheckModule: CommandModule<{}, CaretakerCheckOptions> = {
handler,
builder,
command: 'check',
describe: 'Check the status of information the caretaker manages for the repository',
};

View File

@ -1,123 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {existsSync, readFileSync} from 'fs-extra';
import * as multimatch from 'multimatch';
import {join} from 'path';
import {parse as parseYaml} from 'yaml';
import {getRepoBaseDir} from '../../utils/config';
import {bold, debug, info} from '../../utils/console';
import {GitClient} from '../../utils/git';
/** Compare the upstream master to the upstream g3 branch, if it exists. */
export async function printG3Comparison(git: GitClient) {
const angularRobotFilePath = join(getRepoBaseDir(), '.github/angular-robot.yml');
if (!existsSync(angularRobotFilePath)) {
return debug('No angular robot configuration file exists, skipping.');
}
/** The configuration defined for the angular robot. */
const robotConfig = parseYaml(readFileSync(angularRobotFilePath).toString());
/** The files to be included in the g3 sync. */
const includeFiles = robotConfig?.merge?.g3Status?.include || [];
/** The files to be expected in the g3 sync. */
const excludeFiles = robotConfig?.merge?.g3Status?.exclude || [];
if (includeFiles.length === 0 && excludeFiles.length === 0) {
debug('No g3Status include or exclude lists are defined in the angular robot configuration,');
debug('skipping.');
return;
}
/** Random prefix to create unique branch names. */
const randomPrefix = `prefix${Math.floor(Math.random() * 1000000)}`;
/** Ref name of the temporary master branch. */
const masterRef = `${randomPrefix}-master`;
/** Ref name of the temporary g3 branch. */
const g3Ref = `${randomPrefix}-g3`;
/** Url of the ref for fetching master and g3 branches. */
const refUrl = `https://github.com/${git.remoteConfig.owner}/${git.remoteConfig.name}.git`;
/** The result fo the fetch command. */
const fetchResult = git.runGraceful(['fetch', refUrl, `master:${masterRef}`, `g3:${g3Ref}`]);
// If the upstream repository does not have a g3 branch to compare to, skip the comparison.
if (fetchResult.status !== 0) {
if (fetchResult.stderr.includes(`couldn't find remote ref g3`)) {
return debug('No g3 branch exists on upstream, skipping.');
}
throw Error('Fetch of master and g3 branches for comparison failed.');
}
/** The statistical information about the git diff between master and g3. */
const stats = getDiffStats(git);
// Delete the temporarily created mater and g3 branches.
git.runGraceful(['branch', '-D', masterRef, g3Ref]);
info.group(bold('g3 branch check'));
info(`${stats.commits} commits between g3 and master`);
if (stats.files === 0) {
info('✅ No sync is needed at this time');
} else {
info(`${stats.files} files changed, ${stats.insertions} insertions(+), ${
stats.deletions} deletions(-) will be included in the next sync`);
}
info.groupEnd();
info();
/**
* Get git diff stats between master and g3, for all files and filtered to only g3 affecting
* files.
*/
function getDiffStats(git: GitClient) {
/** The diff stats to be returned. */
const stats = {
insertions: 0,
deletions: 0,
files: 0,
commits: 0,
};
// Determine the number of commits between master and g3 refs. */
stats.commits = parseInt(git.run(['rev-list', '--count', `${g3Ref}..${masterRef}`]).stdout, 10);
// Get the numstat information between master and g3
git.run(['diff', `${g3Ref}...${masterRef}`, '--numstat'])
.stdout
// Remove the extra space after git's output.
.trim()
// Split each line of git output into array
.split('\n')
// Split each line from the git output into components parts: insertions,
// deletions and file name respectively
.map(line => line.split('\t'))
// Parse number value from the insertions and deletions values
// Example raw line input:
// 10\t5\tsrc/file/name.ts
.map(line => [Number(line[0]), Number(line[1]), line[2]] as [number, number, string])
// Add each line's value to the diff stats, and conditionally to the g3
// stats as well if the file name is included in the files synced to g3.
.forEach(([insertions, deletions, fileName]) => {
if (checkMatchAgainstIncludeAndExclude(fileName, includeFiles, excludeFiles)) {
stats.insertions += insertions;
stats.deletions += deletions;
stats.files += 1;
}
});
return stats;
}
/** Determine whether the file name passes both include and exclude checks. */
function checkMatchAgainstIncludeAndExclude(
file: string, includes: string[], excludes: string[]) {
return multimatch(multimatch(file, includes), excludes, {flipNegate: true}).length !== 0;
}
}

View File

@ -1,56 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {alias, params, types} from 'typed-graphqlify';
import {bold, debug, info} from '../../utils/console';
import {GitClient} from '../../utils/git';
import {CaretakerConfig} from '../config';
interface GithubInfoQuery {
[key: string]: {
issueCount: number,
};
}
/** Retrieve the number of matching issues for each github query. */
export async function printGithubTasks(git: GitClient, config: CaretakerConfig) {
if (!config.githubQueries?.length) {
debug('No github queries defined in the configuration, skipping.');
return;
}
info.group(bold('Github Tasks'));
await getGithubInfo(git, config);
info.groupEnd();
info();
}
/** Retrieve query match counts and log discovered counts to the console. */
async function getGithubInfo(git: GitClient, {githubQueries: queries = []}: CaretakerConfig) {
/** The query object for graphql. */
const graphQlQuery: {[key: string]: {issueCount: number}} = {};
/** The Github search filter for the configured repository. */
const repoFilter = `repo:${git.remoteConfig.owner}/${git.remoteConfig.name}`;
queries.forEach(({name, query}) => {
/** The name of the query, with spaces removed to match GraphQL requirements. */
const queryKey = alias(name.replace(/ /g, ''), 'search');
graphQlQuery[queryKey] = params(
{
type: 'ISSUE',
query: `"${repoFilter} ${query.replace(/"/g, '\\"')}"`,
},
{issueCount: types.number},
);
});
/** The results of the generated github query. */
const results = await git.github.graphql.query(graphQlQuery);
Object.values(results).forEach((result, i) => {
info(`${queries[i]?.name.padEnd(25)} ${result.issueCount}`);
});
}

View File

@ -1,79 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import fetch from 'node-fetch';
import {bold, green, info, red} from '../../utils/console';
/** The status levels for services. */
enum ServiceStatus {
GREEN,
RED
}
/** The results of checking the status of a service */
interface StatusCheckResult {
status: ServiceStatus;
description: string;
lastUpdated: Date;
}
/** Retrieve and log stasuses for all of the services of concern. */
export async function printServiceStatuses() {
info.group(bold(`Service Statuses (checked: ${new Date().toLocaleString()})`));
logStatus('CircleCI', await getCircleCiStatus());
logStatus('Github', await getGithubStatus());
logStatus('NPM', await getNpmStatus());
logStatus('Saucelabs', await getSaucelabsStatus());
info.groupEnd();
info();
}
/** Log the status of the service to the console. */
function logStatus(serviceName: string, status: StatusCheckResult) {
serviceName = serviceName.padEnd(15);
if (status.status === ServiceStatus.GREEN) {
info(`${serviceName} ${green('✅')}`);
} else if (status.status === ServiceStatus.RED) {
info.group(`${serviceName} ${red('❌')} (Updated: ${status.lastUpdated.toLocaleString()})`);
info(` Details: ${status.description}`);
info.groupEnd();
}
}
/** Gets the service status information for Saucelabs. */
async function getSaucelabsStatus(): Promise<StatusCheckResult> {
return getStatusFromStandardApi('https://status.us-west-1.saucelabs.com/api/v2/status.json');
}
/** Gets the service status information for NPM. */
async function getNpmStatus(): Promise<StatusCheckResult> {
return getStatusFromStandardApi('https://status.npmjs.org/api/v2/status.json');
}
/** Gets the service status information for CircleCI. */
async function getCircleCiStatus(): Promise<StatusCheckResult> {
return getStatusFromStandardApi('https://status.circleci.com/api/v2/status.json');
}
/** Gets the service status information for Github. */
async function getGithubStatus(): Promise<StatusCheckResult> {
return getStatusFromStandardApi('https://www.githubstatus.com/api/v2/status.json');
}
/** Retrieve the status information for a service which uses a standard API response. */
async function getStatusFromStandardApi(url: string) {
const result = await fetch(url).then(result => result.json());
const status = result.status.indicator === 'none' ? ServiceStatus.GREEN : ServiceStatus.RED;
return {
status,
description: result.status.description,
lastUpdated: new Date(result.page.updated_at)
};
}

View File

@ -1,16 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {Argv} from 'yargs';
import {CheckModule} from './check/cli';
/** Build the parser for the caretaker commands. */
export function buildCaretakerParser(yargs: Argv) {
return yargs.command(CheckModule);
}

View File

@ -1,24 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {assertNoErrors, getConfig, NgDevConfig} from '../utils/config';
export interface CaretakerConfig {
githubQueries?: {name: string; query: string;}[];
}
/** Retrieve and validate the config as `CaretakerConfig`. */
export function getCaretakerConfig() {
// List of errors encountered validating the config.
const errors: string[] = [];
// The non-validated config object.
const config: Partial<NgDevConfig<{caretaker: CaretakerConfig}>> = getConfig();
assertNoErrors(errors);
return config as Required<typeof config>;
}

View File

@ -13,11 +13,8 @@ import {buildCommitMessageParser} from './commit-message/cli';
import {buildFormatParser} from './format/cli';
import {buildReleaseParser} from './release/cli';
import {buildPrParser} from './pr/cli';
import {captureLogOutputForCommand} from './utils/console';
import {buildCaretakerParser} from './caretaker/cli';
yargs.scriptName('ng-dev')
.middleware(captureLogOutputForCommand)
.demandCommand()
.recommendCommands()
.command('commit-message <command>', '', buildCommitMessageParser)
@ -26,7 +23,6 @@ yargs.scriptName('ng-dev')
.command('pullapprove <command>', '', buildPullapproveParser)
.command('release <command>', '', buildReleaseParser)
.command('ts-circular-deps <command>', '', tsCircularDependenciesBuilder)
.command('caretaker <command>', '', buildCaretakerParser)
.wrap(120)
.strict()
.parse();

View File

@ -8,21 +8,35 @@
import {Arguments, Argv, CommandModule} from 'yargs';
import {addGithubTokenFlag} from '../../utils/yargs';
import {error} from '../../utils/console';
import {checkOutPullRequestLocally} from '../common/checkout-pr';
export interface CheckoutOptions {
prNumber: number;
githubToken: string;
'github-token'?: string;
}
/** URL to the Github page where personal access tokens can be generated. */
export const GITHUB_TOKEN_GENERATE_URL = `https://github.com/settings/tokens`;
/** Builds the checkout pull request command. */
function builder(yargs: Argv) {
return addGithubTokenFlag(yargs).positional('prNumber', {type: 'number', demandOption: true});
return yargs.positional('prNumber', {type: 'number', demandOption: true}).option('github-token', {
type: 'string',
description: 'Github token. If not set, token is retrieved from the environment variables.'
});
}
/** Handles the checkout pull request command. */
async function handler({prNumber, githubToken}: Arguments<CheckoutOptions>) {
async function handler({prNumber, 'github-token': token}: Arguments<CheckoutOptions>) {
const githubToken = token || process.env.GITHUB_TOKEN || process.env.TOKEN;
if (!githubToken) {
error('No Github token set. Please set the `GITHUB_TOKEN` environment variable.');
error('Alternatively, pass the `--github-token` command line flag.');
error(`You can generate a token here: ${GITHUB_TOKEN_GENERATE_URL}`);
process.exitCode = 1;
return;
}
const prCheckoutOptions = {allowIfMaintainerCannotModify: true, branchName: `pr-${prNumber}`};
await checkOutPullRequestLocally(prNumber, githubToken, prCheckoutOptions);
}

View File

@ -8,24 +8,36 @@
import {Arguments, Argv} from 'yargs';
import {addGithubTokenFlag} from '../../utils/yargs';
import {error, red, yellow} from '../../utils/console';
import {mergePullRequest} from './index';
import {GITHUB_TOKEN_GENERATE_URL, mergePullRequest} from './index';
/** The options available to the merge command via CLI. */
export interface MergeCommandOptions {
githubToken: string;
'github-token'?: string;
'pr-number': number;
}
/** Builds the options for the merge command. */
export function buildMergeCommand(yargs: Argv): Argv<MergeCommandOptions> {
return addGithubTokenFlag(yargs).help().strict().positional(
'pr-number', {demandOption: true, type: 'number'});
return yargs.help()
.strict()
.positional('pr-number', {demandOption: true, type: 'number'})
.option('github-token', {
type: 'string',
description: 'Github token. If not set, token is retrieved from the environment variables.'
});
}
/** Handles the merge command. i.e. performs the merge of a specified pull request. */
export async function handleMergeCommand(
{'pr-number': pr, githubToken}: Arguments<MergeCommandOptions>) {
await mergePullRequest(pr, githubToken);
export async function handleMergeCommand(args: Arguments<MergeCommandOptions>) {
const githubToken = args['github-token'] || process.env.GITHUB_TOKEN || process.env.TOKEN;
if (!githubToken) {
error(red('No Github token set. Please set the `GITHUB_TOKEN` environment variable.'));
error(red('Alternatively, pass the `--github-token` command line flag.'));
error(yellow(`You can generate a token here: ${GITHUB_TOKEN_GENERATE_URL}`));
process.exit(1);
}
await mergePullRequest(args['pr-number'], githubToken);
}

View File

@ -165,11 +165,6 @@ export async function findActiveVersionBranches(
latestVersionBranch: string | null,
releaseCandidateBranch: string | null,
}> {
// Version representing the release-train currently in the next phase. Note that we ignore
// patch and pre-release segments in order to be able to compare the next release train to
// other release trains from version branches (which follow the `N.N.x` pattern).
const nextReleaseTrainVersion = semver.parse(`${nextVersion.major}.${nextVersion.minor}.0`)!;
let latestVersionBranch: string|null = null;
let releaseCandidateBranch: string|null = null;
@ -182,21 +177,15 @@ export async function findActiveVersionBranches(
// next version-branch as that one is supposed to be the latest active version-branch. If it
// is not, then an error will be thrown due to two FF/RC branches existing at the same time.
for (const {name, parsed} of branches) {
// It can happen that version branches have been accidentally created which are more recent
// than the release-train in the next branch (i.e. `master`). We could ignore such branches
// silently, but it might be symptomatic for an outdated version in the `next` branch, or an
// It can happen that version branches that are more recent than the version in the next
// branch (i.e. `master`) have been created. We could ignore such branches silently, but
// it might actually be symptomatic for an outdated version in the `next` branch, or an
// accidentally created branch by the caretaker. In either way we want to raise awareness.
if (semver.gt(parsed, nextReleaseTrainVersion)) {
if (semver.gte(parsed, nextVersion)) {
throw Error(
`Discovered unexpected version-branch "${name}" for a release-train that is ` +
`more recent than the release-train currently in the "${nextBranchName}" branch. ` +
`Please either delete the branch if created by accident, or update the outdated ` +
`version in the next branch (${nextBranchName}).`);
} else if (semver.eq(parsed, nextReleaseTrainVersion)) {
throw Error(
`Discovered unexpected version-branch "${name}" for a release-train that is already ` +
`active in the "${nextBranchName}" branch. Please either delete the branch if ` +
`created by accident, or update the version in the next branch (${nextBranchName}).`);
`Discovered unexpected version-branch that is representing a minor ` +
`version more recent than the one in the "${nextBranchName}" branch. Consider ` +
`deleting the branch, or check if the version in "${nextBranchName}" is outdated.`);
}
const version = await getVersionOfBranch(repo, name);

View File

@ -280,21 +280,7 @@ describe('default target labels', () => {
.toBeRejectedWithError('Invalid version detected in following branch: 11.1.x.');
});
it('should error if version-branch more recent than "next" is discovered', async () => {
interceptBranchVersionRequest('master', '11.2.0-next.0');
interceptBranchVersionRequest('11.3.x', '11.3.0-next.0');
interceptBranchVersionRequest('11.1.x', '11.1.5');
interceptBranchesListRequest(['11.1.x', '11.3.x']);
await expectAsync(getBranchesForLabel('target: lts', '10.2.x'))
.toBeRejectedWithError(
'Discovered unexpected version-branch "11.3.x" for a release-train that is ' +
'more recent than the release-train currently in the "master" branch. Please ' +
'either delete the branch if created by accident, or update the outdated version ' +
'in the next branch (master).');
});
it('should error if branch is matching with release-train in the "next" branch', async () => {
it('should error if branch more recent than version in "next" branch is found', async () => {
interceptBranchVersionRequest('master', '11.2.0-next.0');
interceptBranchVersionRequest('11.2.x', '11.2.0-next.0');
interceptBranchVersionRequest('11.1.x', '11.1.5');
@ -302,9 +288,9 @@ describe('default target labels', () => {
await expectAsync(getBranchesForLabel('target: lts', '10.2.x'))
.toBeRejectedWithError(
'Discovered unexpected version-branch "11.2.x" for a release-train that is already ' +
'active in the "master" branch. Please either delete the branch if created by ' +
'accident, or update the version in the next branch (master).');
'Discovered unexpected version-branch that is representing a minor version more ' +
'recent than the one in the "master" branch. Consider deleting the branch, or check ' +
'if the version in "master" is outdated.');
});
it('should allow merging PR only into patch branch with "target: patch"', async () => {

View File

@ -11,11 +11,13 @@ import {getConfig, getRepoBaseDir} from '../../utils/config';
import {error, green, info, promptConfirm, red, yellow} from '../../utils/console';
import {GitClient} from '../../utils/git';
import {GithubApiRequestError} from '../../utils/git/github';
import {GITHUB_TOKEN_GENERATE_URL} from '../../utils/yargs';
import {loadAndValidateConfig, MergeConfigWithRemote} from './config';
import {loadAndValidateConfig, MergeConfig, MergeConfigWithRemote} from './config';
import {MergeResult, MergeStatus, PullRequestMergeTask} from './task';
/** URL to the Github page where personal access tokens can be generated. */
export const GITHUB_TOKEN_GENERATE_URL = `https://github.com/settings/tokens`;
/**
* Merges a given pull request based on labels configured in the given merge configuration.

View File

@ -16,6 +16,9 @@ import {isPullRequest, loadAndValidatePullRequest,} from './pull-request';
import {GithubApiMergeStrategy} from './strategies/api-merge';
import {AutosquashMergeStrategy} from './strategies/autosquash-merge';
/** Github OAuth scopes required for the merge task. */
const REQUIRED_SCOPES = ['repo'];
/** Describes the status of a pull request merge. */
export const enum MergeStatus {
UNKNOWN_GIT_ERROR,
@ -48,19 +51,8 @@ export class PullRequestMergeTask {
* @param force Whether non-critical pull request failures should be ignored.
*/
async merge(prNumber: number, force = false): Promise<MergeResult> {
// Check whether the given Github token has sufficient permissions for writing
// to the configured repository. If the repository is not private, only the
// reduced `public_repo` OAuth scope is sufficient for performing merges.
const hasOauthScopes = await this.git.hasOauthScopes((scopes, missing) => {
if (!scopes.includes('repo')) {
if (this.config.remote.private) {
missing.push('repo');
} else if (!scopes.includes('public_repo')) {
missing.push('public_repo');
}
}
});
// Assert the authenticated GitClient has access on the required scopes.
const hasOauthScopes = await this.git.hasOauthScopes(...REQUIRED_SCOPES);
if (hasOauthScopes !== true) {
return {
status: MergeStatus.GITHUB_ERROR,

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