Compare commits

..

198 Commits

Author SHA1 Message Date
074266b896 release: cut the v10.0.0-next.2 release 2020-04-15 16:09:35 -07:00
c4dc642f99 docs: release notes for the v9.1.2 release 2020-04-15 16:04:09 -07:00
e041ac6f0d fix(ngcc): display output from the unlocker process on Windows (#36569)
On Windows, the output of a detached process (such as the unlocker
process used by `LockFileWithChildProcess`) is not shown in the parent
process' stdout.

This commit addresses this by piping the spawned process' stdin/stdout
and manually writing to the parent process' stdout.

PR Close #36569
2020-04-15 09:25:27 -07:00
66effde9f3 fix(ngcc): do not spawn unlocker processes on cluster workers (#36569)
The current ngcc lock-file strategy spawns a new process in order to
capture a potential `SIGINT` and remove the lock-file. For more
information see #35861.

Previously, this unlocker process was spawned as soon as the `LockFile`
was instantiated in order to have it available as soon as possible
(given that spawning a process is an asynchronous operation). Since the
`LockFile` was instantiated and passed to the `Executor`, this meant
that an unlocker process was spawned for each cluster worker, when
running ngcc in parallel mode. These processes were not needed, since
the `LockFile` was not used in cluster workers, but we still had to pay
the overhead of each process' own memory and V8 instance.
(NOTE: This overhead was small compared to the memory consumed by ngcc's
normal operations, but still unnecessary.)

This commit avoids the extra processes by only spawning an unlocker
process when running on the cluster master process and not on worker
processes.

PR Close #36569
2020-04-15 09:25:27 -07:00
663b768780 fix(ngcc): force ngcc to exit on error (#36622)
For some reason (possibly related to async/await promises)
the ngcc process is not exiting when spawned from the CLI
when there has been an error (such as when it timesout waiting
for a lockfile to become free).

Calling `process.exit()` directly fixes this.

Fixes #36616

PR Close #36622
2020-04-15 09:24:54 -07:00
0147de9044 build: fix circular deps failure (#36629)
With the large scale refactoring of the repo to the new version of clang-format, some import orders were changed.

Specifically the imports found in this range.

The file previously read:

import {TestBed} from './test_bed';
import {ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, TestBedStatic, TestComponentRenderer, TestModuleMetadata} from './test_bed_common';
import {R3TestBedCompiler} from './r3_test_bed_compiler';
and now reads:

import {R3TestBedCompiler} from './r3_test_bed_compiler';
import {TestBed} from './test_bed';
import {ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, TestBedStatic, TestComponentRenderer, TestModuleMetadata} from './test_bed_common';
This change in order cause the circular dependency to be entered earlier and changed the golden file for our circular deps discovery.

PR Close #36629
2020-04-14 13:56:55 -07:00
b010849102 build: update to latest version of yarn (#36464)
PR Close #36464
2020-04-14 12:47:30 -07:00
698b0288be build: reformat repo to new clang@1.4.0 (#36613)
PR Close #36613
2020-04-14 12:08:36 -07:00
5e80e7e216 refactor(language-service): clean up and exports and consolidate types (#36533)
PR Close #36533
2020-04-14 10:17:43 -07:00
d50cb30443 test: disable failing saucelabs tests (#36620)
PR Close #36620
2020-04-14 10:13:33 -07:00
29122c518b style: lint (#36580)
PR Close #36580
2020-04-14 10:12:59 -07:00
58e175318c build: update to rules_nodejs 1.6.0 (#36580)
Lots of bug fixes and stability fixes. Last 1.x release for rules_nodejs.

PR Close #36580
2020-04-14 10:12:59 -07:00
f88e63519a docs: edit to setup-local (#36168)
PR Close #36168
2020-04-13 17:33:35 -07:00
0cc53fb398 fix(upgrade): update $locationShim to handle Location changes before initialization (#36498)
Updates the $locationShim to receive the most recent Location change
made, even if it happened before initialize() is called. This is
important when AngularJS bootstrapping is deferred and there is a delay
between when $locationShim is constructed and when it is initialized.
With this change, the $locationShim will correctly reflect any redirects
that occurred between construction and initialization.

Closes #36492

PR Close #36498
2020-04-13 17:33:00 -07:00
713bce19f4 docs: move ng-conf 2020 to the already presented section (#36413)
PR Close #36413
2020-04-13 08:20:03 -07:00
d972821889 fix(docs-infra): contribute page not visible correctly on mobile devices (#36573)
on mobile devices screen size < 600px the contribute page is not visible in correct form changed styles to make it visible correctly

PR Close #36573
2020-04-13 08:19:01 -07:00
2d16b4711e fix(docs-infra): fix About page button text being truncated on small screens (#36576)
On small screens (e.g. on mobile), the text on some of the buttons in
the About page was truncated. Changed the text size, margin and
padding so that the the whole text is visible on such screens (320px to
480px).

PR Close #36576
2020-04-13 08:18:11 -07:00
9181b73e5a docs: fix typo in Tests guide (#36592)
PR Close #36592
2020-04-13 08:17:27 -07:00
5737e65700 docs(zone.js): fix typos in NgZone guide code example (#36597)
Fixes #36594

PR Close #36597
2020-04-13 08:16:59 -07:00
ca677481a2 fix(core): undecorated-classes-with-decorated-fields migration should avoid error if base class has no value declaration (#36543)
The undecorated-classes-with-decorated-fields migration relies on
the type checker to resolve base classes of individual classes.

It could happen that resolved base classes have no value declaration.
e.g. if they are declared through an interface in the default types.
Currently the migration will throw in such situations because it assumes
that `ts.Symbol#valueDeclaration` is always present. This is not the
case, but we don't get good type-checking here due to a bug in the
TypeScript types. See:
https://github.com/microsoft/TypeScript/issues/24706.

Fixes #36522.

PR Close #36543
2020-04-10 13:53:15 -07:00
6ab43d7335 fix(ngcc): correctly detect external files from nested node_modules/ (#36559)
Previously, when we needed to detect whether a file is external to a
package, we only checked whether the relative path to the file from the
package's root started with `..`. This would detect external imports
when the packages were siblings (e.g. peer dependencies or hoisted to
the top of `node_modules/` by the package manager), but would fail to
detect imports from packages located in nested `node_modules/` as
external. For example, importing `node_modules/foo/node_modules/bar`
from a file in `node_modules/foo/` would be considered internal to the
`foo` package.

This could result in processing/analyzing more files than necessary.
More importantly it could lead to errors due to trying to analyze
non-Angular packages that were direct dependencies of Angular packages.

This commit fixes it by also verifying that the relative path to a file
does not start with `node_modules/`.

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

Fixes #36526

PR Close #36559
2020-04-10 09:10:26 -07:00
fee316161d build: update REQUIRED_BASE_SHA in merge script to clang 1.4.0 upgrade commit (#36547)
Updating `REQUIRED_BASE_SHA` for master and patch branches to make sure PRs that we merge are rebased after clang 1.4.0 upgrade.

PR Close #36547
2020-04-09 16:00:31 -07:00
2e4244d521 fix(docs-infra): fix elements example when used with ES5 (#36536)
Previously, the `elements` docs example only worked in browsers that
natively supported Custom Elements and ES2015 modules. Furthermore, it
didn't work on StackBlitz, because StackBlitz ignores the specified
`target` in `tsconfig.json` and uses the UMD bundles (i.e. ES5 code)
even on browsers that do support ES2015.
(NOTE: In the past, this was not a problem, because we explicitly did
not provide a StackBlitz example. This has changed in #36067.)

This commit ensures the example works on all browsers and also on
StackBlitz by providing the necessary Custom Elements polyfills.

Fixes #36532

PR Close #36536
2020-04-09 13:35:27 -07:00
3bedfdac9d perf(ngcc): only load if it is needed (#36486)
PR Close #36486
2020-04-09 11:33:28 -07:00
ec0ce6005a perf(ngcc): reduce the size of the entry-point manifest file (#36486)
The base path for package and entry-points is known so there is
no need to store these in the file. Also this commit avoids storing
empty arrays unnecessarily.

PR Close #36486
2020-04-09 11:33:28 -07:00
a185efbd60 perf(ngcc): read dependencies from entry-point manifest (#36486)
Previously, even if an entry-point did not need to be processed,
ngcc would always parse the files of the entry-point to compute
its dependencies. This can take a lot of time for large node_modules.

Now these dependencies are cached in the entry-point manifest,
and read from there rather than computing them every time.

See https://github.com/angular/angular/issues/36414\#issuecomment-608401834
FW-2047

PR Close #36486
2020-04-09 11:33:28 -07:00
4aa4e6fd03 fix(compiler): handle type references to namespaced symbols correctly (#36106)
When the compiler needs to convert a type reference to a value
expression, it may encounter a type that refers to a namespaced symbol.
Such namespaces need to be handled specially as there's various forms
available. Consider a namespace named "ns":

1. One can refer to a namespace by itself: `ns`. A namespace is only
   allowed to be used in a type position if it has been merged with a
   class, but even if this is the case it may not be possible to convert
   that type into a value expression depending on the import form. More
   on this later (case a below)
2. One can refer to a type within the namespace: `ns.Foo`. An import
   needs to be generated to `ns`, from which the `Foo` property can then
   be read.
3. One can refer to a type in a nested namespace within `ns`:
   `ns.Foo.Bar` and possibly even deeper nested. The value
   representation is similar to case 2, but includes additional property
   accesses.

The exact strategy of how to deal with these cases depends on the type
of import used. There's two flavors available:

a. A namespaced import like `import * as ns from 'ns';` that creates
   a local namespace that is irrelevant to the import that needs to be
   generated (as said import would be used instead of the original
   import).

   If the local namespace "ns" itself is referred to in a type position,
   it is invalid to convert it into a value expression. Some JavaScript
   libraries publish a value as default export using `export = MyClass;`
   syntax, however it is illegal to refer to that value using "ns".
   Consequently, such usage in a type position *must* be accompanied by
   an `@Inject` decorator to provide an explicit token.

b. An explicit namespace declaration within a module, that can be
   imported using a named import like `import {ns} from 'ns';` where the
   "ns" module declares a namespace using `declare namespace ns {}`.
   In this case, it's the namespace itself that needs to be imported,
   after which any qualified references into the namespace are converted
   into property accesses.

Before this change, support for namespaces in the type-to-value
conversion was limited and only worked  correctly for a single qualified
name using a namespace import (case 2a). All other cases were either
producing incorrect code or would crash the compiler (case 1a).

Crashing the compiler is not desirable as it does not indicate where
the issue is. Moreover, the result of a type-to-value conversion is
irrelevant when an explicit injection token is provided using `@Inject`,
so referring to a namespace in a type position (case 1) could still be
valid.

This commit introduces logic to the type-to-value conversion to be able
to properly deal with all type references to namespaced symbols.

Fixes #36006
Resolves FW-1995

PR Close #36106
2020-04-09 11:32:21 -07:00
078b0be4dc fix(common): locales/global/*.js are not ES5 compliant (#36342)
Although this code has been part of Angular 9.x I only noticed this
error when upgrading to Angular 9.1.x because historically the source
locale data was not injected when localizing, but as of
angular/angular-cli#16394 (9.1.0) it is now included. This tipped me off
that my other bundles were not being built properly, and this change
allows me to build a valid ES5 bundle (I have also added a verification
step to my build pipeline to alert me if this error appears again in any
of my bundles).

I found the `locales/global/*.js` file paths being referenced by the
`I18nOptions` in
@angular-devkit/build-angular/src/utils/i18n-options.ts,
and following that it looks like it is actually loaded and used in
@angular-devkit/build-angular/src/utils/process-bundle.ts. I saw the
function `terserMangle` does appear that it is likely aware of the build
being ES5, but I'm not sure why this is not producing a valid ES5
bundle.

This change updates `tools/gulp-tasks/cldr/extract.js` to produce ES5
compliant `locales/global/*.js` and that fixes my issue. However, I am
not sure if @angular-devkit/build-angular should be modified to produce
a valid ES5 bundle instead or if the files could be TypeScript rather
than JavaScript files.

A test that a valid ES5 bundle is produced would be helpful, and I hope
this is reproducible and not some issue with my config.

PR Close #36342
2020-04-09 11:30:32 -07:00
13ae2d7271 style: format forms validators to fix lint error (#36546)
PR Close #36546
2020-04-09 11:18:22 -07:00
99b93e55cb docs(forms): clarify the description of minLength and maxLength (#36297)
Previously, it was not clear that the `minLength` and `maxLength` validators
can only be used with objects that contain a `length` property. This commit
clarifies this.

PR Close #36297
2020-04-09 10:31:03 -07:00
80e6c07d89 fix(router): pass correct component to canDeactivate checks when using two or more sibling router-outlets (#36302)
fixes #34614

There's an edge case where if I use two (or more) sibling <router-outlet>s in two (or more) child routes where their parent route doesn't have a component then preactivation will trigger all canDeactivate checks with the same component because it will use wrong OutletContext.

PR Close #36302
2020-04-09 10:09:43 -07:00
34aa5570ed fix(dev-infra): fix commit message validation in git worktrees (#36507)
Previously, the `pre-commit-validate` command (used in the `commit-msg`
git hook) assumed that the commit message was stored in
`.git/COMMIT_EDITMSG` file. This is usually true, but not when using
[git worktrees](https://git-scm.com/docs/git-worktree), where `.git` is
a file containing the path to the actual git directory.

This commit fixes it by taking advantage of the fact that git passes the
actual path of the file holding the commit message to the `commit-msg`
hook and husky exposes the arguments passed by git as
`$HUSKY_GIT_PARAMS`.

NOTE:
We cannot use the environment variable directly in the `commit-msg` hook
command, because environment variables need to be referenced differently
on Windows (`%VAR_NAME%`) vs macOS/Linux (`$VAR_NAME`). Instead, we pass
the name of the environment variable and the validation script reads the
variable's value off of `process.env`.

PR Close #36507
2020-04-09 09:46:18 -07:00
e526f74dfd refactor(compiler): create a new root BindingScope for each template (#36362)
Previously we had a singleton `ROOT_SCOPE` object, from
which all `BindingScope`s derived. But this caused ngcc to
produce non-deterministic output when running multiple workers
in parallel, since each process had its own `ROOT_SCOPE`.

In reality there is no need for `BindingScope` reference names
to be unique across an entire application (or in the case of ngcc
across all the libraries). Instead we just need uniqueness within
a template.

This commit changes the compiler to create a new root `BindingScope`
each time it compiles a component's template.

Resolves #35180

PR Close #36362
2020-04-09 09:44:56 -07:00
9e78f55c32 style: typescript lint fix (#36531)
PR Close #36531
2020-04-09 00:59:21 +00:00
f1731d807e Revert "refactor(bazel): use runfiles helper in ts-api-guardian (#36471)" (#36531)
This reverts commit 92c4f3d508.

PR Close #36531
2020-04-09 00:59:21 +00:00
92c4f3d508 refactor(bazel): use runfiles helper in ts-api-guardian (#36471)
Pre-fractor for future rules_nodejs release when require.resolve patches are removed.

PR Close #36471
2020-04-08 15:57:52 -07:00
e92fce1c27 fix(language-service): remove circular dependency instance (#36463)
PR Close #36463
2020-04-08 15:29:09 -07:00
83a9159063 style(compiler): reformat of codebase with new clang-format version (#36520)
This commit reformats the packages/compiler tree using the new version of
clang-format.

PR Close #36520
2020-04-08 14:51:08 -07:00
0a69a2832b style(compiler-cli): reformat of codebase with new clang-format version (#36520)
This commit reformats the packages/compiler-cli tree using the new version
of clang-format.

PR Close #36520
2020-04-08 14:51:08 -07:00
717df13207 fix(ngcc): do not warn if paths mapping does not exist (#36525)
In cc4b813e75 the `getBasePaths()`
function was changed to log a warning if a `basePath()` computed from
the `paths` mappings did not exist. It turns out this is a common and
accepted scenario, so we should not log warnings in this case.

Fixes #36518

PR Close #36525
2020-04-08 14:29:57 -07:00
b40b5576df release: cut the v10.0.0-next.1 release 2020-04-08 12:28:12 -07:00
03f2f1ae47 build(bazel): fix runfiles resolve in karma-saucelabs.js after $location => $rootpath cleanup (#36511)
This wasn't caught by CI on the PR as this binary is only run once daily via a monitor job.

PR Close #36511
2020-04-08 12:13:27 -07:00
a8978ebf8e build: ts-circular-deps tool should normalize golden (#36505)
Currently the golden output of the circular-deps tool is purely
based on the order of source files passed to the tool, and on the
amount of imports inside source files.

This is actually resulting in deterministic output as running
the tool multiple times without any changes to source files,
results in the same output.

Though it seems like the tool is too strict and we can avoid
unnecessary golden changes if:

1. A source file that is part of a cycle is imported earlier (in terms
of how the analyzer visits them). This could result in the cycle path
starting with a different source file.

2. Source files which are not part of a cycle are imported earlier
(in terms of how the analyzer visits them). This could result in moved
items in the golden if re-approved (even though the cycles remain the same)

To fix this, we normalize the cycle path array that serves as
serializable data structure for the text-based goldens. Since
the paths represents a cycle, the path can be shifted in a
deterministic way so that cycles don't change unnecessarily
in the golden, and to simplify comparison of cycles.

Additionally, we sort the cycles in a deterministic way so
that the golden doesn't change unnecessarily (as explained above).

PR Close #36505
2020-04-08 12:12:58 -07:00
7d7b59efa5 docs: update the Support policy and schedule (#35390)
PR Close #35359

PR Close #35390
2020-04-08 12:12:32 -07:00
4cf89d4bd7 docs: replace browserslist with .browserslistrc (#36504)
In version 10, this file has been changed.

See: https://github.com/angular/angular-cli/pull/17367

PR Close #36504
2020-04-08 12:12:03 -07:00
d47b318fee build: remove fullTemplateTypeCheck from aio tsconfig (#36502)
`fullTemplateTypeCheck` is no longer required since we now use `strictTemplates` which is a superset of the former option.

Follow-up on: 04f61c0c3e (r38354112)

PR Close #36502
2020-04-08 12:11:28 -07:00
e485236502 test(language-service): Inline test cases in parsing-cases.ts (#36495)
This commit removes individual components from parsing-cases.ts and
colocate them with the actual tests. This makes the tests more readable.

PR Close #36495
2020-04-08 12:11:04 -07:00
41667de778 fix(zone.js): add issue numbers of @types/jasmine to the test cases (#34625)
Some cases will still need to use `spy as any` cast, because `@types/jasmine` have some issues,
1. The issue jasmine doesn't handle optional method properties, https://github.com/DefinitelyTyped/DefinitelyTyped/issues/43486
2. The issue jasmine doesn't handle overload method correctly, https://github.com/DefinitelyTyped/DefinitelyTyped/issues/42455

PR Close #34625
2020-04-08 12:10:34 -07:00
ef4736d052 build: update jasmine to 3.5 (#34625)
1. update jasmine to 3.5
2. update @types/jasmine to 3.5
3. update @types/jasminewd2 to 2.0.8

Also fix several cases, the new jasmine 3 will help to create test cases correctly,
such as in the `jasmine 2.x` version, the following case will pass

```
expect(1 == 2);
```

But in jsamine 3, the case will need to be

```
expect(1 == 2).toBeTrue();
```

PR Close #34625
2020-04-08 12:10:34 -07:00
db4a448439 release: cut the v10.0.0-next.0 release 2020-04-08 11:08:01 -07:00
7549c65502 build: update matching regex for bazel stamping (#36523)
Previously, the bazel stamping regex only matched on versions
0-9 for major and minor numbers, this update allows for matching
on any number for major, minor or patch.

PR Close #36523
2020-04-08 11:04:08 -07:00
1beccc1a6c docs: release notes for the v9.1.1 release 2020-04-07 16:37:55 -07:00
0075017b43 docs: update reactive forms page (#35969)
PR Close #35969
2020-04-07 15:24:17 -07:00
4374931b0e fix(zone.js): zone.js patch jest should handle done correctly (#36022)
`zone.js` supports jest `test.each()` methods, but it
introduces a bug, which is the `done()` function will not be handled correctly.

```
it('should work with done', done => {
  // done will be undefined.
});
```

The reason is the logic of monkey patching `test` method is different from `jasmine` patch

// jasmine patch
```
return testBody.length === 0
   ? () => testProxyZone.run(testBody, null)
   : done => testProxyZone.run(testBody, null, [done]);
```

// jest patch
```
 return function(...args) {
   return testProxyZone.run(testBody, null, args);
 };
```

the purpose of this change is to handle the following cases.

```
test.each([1, 2])('test.each', (arg1, arg2) => {
  expect(arg1).toBe(1);
  expect(arg2).toBe(2);
});
```

so in jest, it is a little complex, because the `testBody`'s parameter may be bigger than 1, so the
logic in `jasmine`

```
return testBody.length === 0
   ? () => testProxyZone.run(testBody, null)
   : done => testProxyZone.run(testBody, null, [done]);
```
will not work for `test.each` in jest.

So in this PR, I created a dynamic `Function` to return the correct length of paramters (which is required by jest core), to handle
1. normal `test` with or without `done`.
2. each with parameters with or without done.

PR Close #36022
2020-04-07 15:22:16 -07:00
64022f51d4 fix(compiler): resolve enum values in binary operations (#36461)
During static evaluation of expressions, the partial evaluator
may come across a binary + operator for which it needs to
evaluate its operands. Any of these operands may be a reference
to an enum member, in which case the enum member's value needs
to be used as literal value, not the enum member reference
itself. This commit fixes the behavior by resolving an
`EnumValue` when used as a literal value.

Fixes #35584
Resolves FW-1951

PR Close #36461
2020-04-07 15:21:51 -07:00
f9f6e2e1b3 style(compiler): reformat partial evaluator source tree (#36461)
PR Close #36461
2020-04-07 15:21:51 -07:00
aecf9de738 fix(ngcc): correctly identify relative Windows-style import paths (#36372)
Previously, `isRelativePath()` assumed paths are *nix-style. This caused
Windows-style paths (such as `C:\foo\some-package\some-file.js`) to not
be recognized as "relative" imports.

This commit fixes this by using the OS-agnostic `isRooted()` helper and
also accounting for both styles of path delimiters: `/` and `\`

PR Close #36372
2020-04-07 15:21:27 -07:00
81195a238b fix(language-service): use the HtmlAst to get the span of HTML tag (#36371)
The HTML tag may include `-` (e.g. `app-root`), so use the `HtmlAst` to get the span.

PR Close #36371
2020-04-07 15:10:33 -07:00
96a3de6364 style(docs-infra): removed extra , from _resources.scss file (#35935)
there was a typo in _resourcess.scss file there was an extra comma added some spaces too that were needed for proper styling of the code

PR Close #35935
2020-04-07 15:08:57 -07:00
00027130ea fix(docs-infra): fix resources page tabs text which is not visible on small screens (#35935)
on small mobile screens the top tab bar contains text which was not visible on small screens changed text size, margin and padding so that the text could be contained in these screens (320px to 480px)

PR Close #35935
2020-04-07 15:08:57 -07:00
4a18428de6 docs(forms): Remove unnecessary repeating periods (#36474)
PR Close #36474
2020-04-07 11:35:43 -07:00
7f28845f58 test(language-service): remove ng-for-cases.ts (#36470)
This commit removes ng-for-cases.ts and moves all test cases to
inline expressions in TEST_TEMPLATE.

PR Close #36470
2020-04-07 11:34:38 -07:00
1dd0b6cc18 test(language-service): remove ng-if-cases.ts (#36470)
This commit removes ng-if-cases.ts and moves all test cases to inline
expressions in TEST_TEMPLATE.

PR Close #36470
2020-04-07 11:34:38 -07:00
e0415dbf16 fix(router): state data missing in routerLink (#36462)
fixes #33173 - router state data is missing on routerLink when used
with non-anchor elements.

PR Close #36462
2020-04-07 11:31:25 -07:00
95fc3d4c5c fix(core): ngOnDestroy on multi providers called with incorrect context (#35840)
Currently destroy hooks are stored in memory as `[1, hook, 5, hook]` where
the numbers represent the index at which to find the context and `hook` is
the function to be invoked. This breaks down for `multi` providers,
because the value at the index will be an array of providers, resulting in
the hook being invoked with an array of all the multi provider values,
rather than the provider that was destroyed. In ViewEngine `ngOnDestroy`
wasn't being called for `multi` providers at all.

These changes fix the issue by changing the structure of the destroy hooks to `[1, hook, 5, [0, hook, 3, hook]]` where the indexes inside the inner array point to the provider inside of the multi provider array. Note that this is slightly different from the original design which called for the structure to be `[1, hook, 5, [hook, hook]`, because in the process of implementing it, I realized that we wouldn't get passing the correct context if only some of the `multi` providers have `ngOnDestroy` and others don't.

I've run the newly-added `view_destroy_hooks` benchmark against these changes and compared it to master. The difference seems to be insignificant (between 1% and 2% slower).

Fixes #35231.

PR Close #35840
2020-04-07 10:31:41 -07:00
e145fa13b1 test(language-service): delete expression-cases.ts (#36468)
This commit deletes `expression-cases.ts` and moves the test cases to
inline expressions in TEST_TEMPLATE.

PR Close #36468
2020-04-07 10:20:27 -07:00
5fa7b8ba56 fix(ngcc): detect non-emitted, non-imported TypeScript helpers (#36418)
When TypeScript downlevels ES2015+ code to ES5, it uses some helper
functions to emulate some ES2015+ features, such as spread syntax. The
TypeScript compiler can be configured to emit these helpers into the
transpiled code (which is controlled by the `noEmitHelpers` option -
false by default). It can also be configured to import these helpers
from the `tslib` module (which is controlled by the `importHelpers`
option - false by default).

While most of the time the helpers will be either emitted or imported,
it is possible that one configures their app to neither emit nor import
them. In that case, the helpers could, for example, be made available on
the global object. This is what `@nativescript/angular`
v9.0.0-next-2019-11-12-155500-01 does. See, for example, [common.js][1].

Ngcc must be able to detect and statically evaluate these helpers.
Previously, it was only able to detect emitted or imported helpers.

This commit adds support for detecting these helpers if they are neither
emitted nor imported. It does this by checking identifiers for which no
declaration (either concrete or inline) can be found against a list of
known TypeScript helper function names.

[1]: https://unpkg.com/browse/@nativescript/angular@9.0.0-next-2019-11-12-155500-01/common.js

PR Close #36418
2020-04-07 10:19:22 -07:00
2c7d366c82 refactor(language-service): provide service for attribute binding type (#36301)
This commit refactors the process for determining the type of an Angular
attribute to be use a function that takes an attribute name and returns
the Angular attribute kind and name, rather than requiring the user to
query match the attribute name with the regex and query the matching
array.

This refactor prepares for a future change that will improve the
experience of completing attributes in `()`, `[]`, or `[()]` contexts.

PR Close #36301
2020-04-07 10:18:32 -07:00
2dd6f25647 ci: manually set available resources for bazel on windows CI (#36458)
PR Close #36458
2020-04-07 10:12:29 -07:00
d2623f13d9 style(zone.js): fix lint errors after clang update (#36487)
Recent ZoneJS-related commit (416c786774) update the `promise.ts` file, but it looks like original PR was not rebased after clang update. As a result, the `lint` CircleCI job started to fail in master after merging that PR (https://github.com/angular/angular/pull/36311). This commit updates the format of the `promise.ts` script according to the new clang rules.

PR Close #36487
2020-04-07 10:10:34 -07:00
7d0af179e3 style(forms): reformat of the forms package after clang update (#36466)
PR Close #36466
2020-04-07 09:47:09 -07:00
416c786774 fix(zone.js): should not try to patch fetch if it is not writable (#36311)
Close #36142

In Firefox extensions, the `window.fetch` is not configurable, that means

```
const desc = Object.getOwnPropertyDescriptor(window, 'fetch');
desc.writable === false;
```

So in this case, we should not try to patch `fetch`, otherwise, it will
throw error ('fetch is ReadOnly`)

PR Close #36311
2020-04-06 15:34:33 -07:00
93302b7fb8 build: update to latest version of husky (#36459)
PR Close #36459
2020-04-06 15:33:26 -07:00
eb8c6c7eff test(language-service): Move pipe tests to TEST_TEMPLATE (#36407)
This commit simplifies the completion tests for pipes by moving them to TEST_TEMPLATE.

PR Close #36407
2020-04-06 15:32:33 -07:00
8660806ddc build(docs-infra): renamed e2e property of example-config.json to tests (#36143)
Each docs example has an `example-config.json` configuration file. Among
other things, this file can be used to specify what commands to run in
order to test the example. (If not specified, the `run-example-e2e.js`
script will run a default `yarn e2e` command.)

Previously, the property specifying the test commands was called `e2e`.
This is because in the past only e2e tests were run for docs examples.
Since recently, some examples may specify commands for other types of
tests (such as unit tests). Therefore, calling the property that holds
the list of test commands `e2e` no longer makes sense and can be
misleading to people looking at the configuration files.

This commit renamed the property to the more generic `tests`. In the
future, the `run-example-e2e.js` script (and corresponding npm script)
should be renamed and refactored to also avoid giving the impression
that only e2e tests are run.

Discussed in:
https://github.com/angular/angular/pull/36143#discussion_r395148379

PR Close #36143
2020-04-06 15:31:07 -07:00
4c5e085c93 build(docs-infra): update docs examples package.json templates wrt core-js (#36143)
The `core-js` dependency is no longer included in `package.json` for
`cli`-type examples, but only for the `systemjs` ones. This commit
updates the `package.json` templates to reflect that (and also updates
the `npm-packages` guide accordingly).

PR Close #36143
2020-04-06 15:31:07 -07:00
d707124fd9 test(docs-infra): fix unit tests and run them for specific docs examples on CI (#36143)
Previously, only e2e tests were run for docs examples on CI. As a
result, unit tests (which are included in the zipped archives we provide
for users to download and play with the examples locally) were often
outdated and broken.

This commit configures specific docs examples that have meaningful unit
tests to run them on CI (via the `run-example-e2e.js` script). Where
necessary, the unit tests are fixed to ensure they pass and reflect the
changes in the corresponding component/service.
This commit also removes some auto-generated unit tests that are not
meaningful (e.g. make trivial assertions, such that a component instance
is truthy) and are often broken anyway (e.g. because the corresponding
component has been changed in ways that make the tests fail).

PR Close #36143
2020-04-06 15:31:07 -07:00
aece3669e5 build(docs-infra): switch docs examples to Ivy (#36143)
The docs examples are switched to Ivy. On CI, the tests are run with
both Ivy and ViewEngine.

Partially addresses:
[FW-1609](https://angular-team.atlassian.net/browse/FW-1609)

PR Close #36143
2020-04-06 15:31:07 -07:00
09c84169d5 docs: fix broken guide link (tutorial/index --> tutorial) (#36453)
Replace broken link (`tutorial/index`) with `tutorial`.

PR Close #36453
2020-04-06 13:56:00 -07:00
d43c30688a fix(core): avoid migration error when non-existent symbol is imported (#36367)
In rare cases a project with configured `rootDirs` that has imports to
non-existent identifiers could fail in the migration.

This happens because based on the application code, the migration could
end up trying to resolve the `ts.Symbol` of such non-existent
identifiers. This isn't a problem usually, but due to a upstream bug
in the TypeScript compiler, a runtime error is thrown.

This is because TypeScript is unable to compute a relative path from the
originating source file to the imported source file which _should_
provide the non-existent identifier. An issue for this has been reported
upstream: https://github.com/microsoft/TypeScript/issues/37731. The
issue only surfaces since our migrations don't provide an absolute base
path that is used for resolving the root directories.

To fix this, we ensure that we never use relative paths when parsing
tsconfig files. More details can be found in the TS issue.

Fixes #36346.

PR Close #36367
2020-04-06 13:21:54 -07:00
ee70a18a75 fix(ngcc): don't crash on cyclic source-map references (#36452)
The source-map flattening was throwing an error when there
is a cyclic dependency between source files and source-maps.
The error was either a custom one describing the cycle, or a
"Maximum call stack size exceeded" one.

Now this is handled more leniently, resulting in a partially loaded
source file (or source-map) and a warning logged.

Fixes #35727
Fixes #35757
Fixes https://github.com/angular/angular-cli/issues/17106
Fixes https://github.com/angular/angular-cli/issues/17115

PR Close #36452
2020-04-06 13:19:53 -07:00
76a8cd57ae fix(ngcc): add process title (#36448)
Add process.title, so it's clearly in the task manager when ngcc is running

See: https://github.com/angular/angular/issues/36414#issuecomment-609644282

PR Close #36448
2020-04-06 13:19:17 -07:00
4c7f89ff6d ci: exclude ngcc directory from fw-compiler pull-approve rule (#35933)
ngcc has its own pull-approve group

PR Close #35933
2020-04-06 13:16:37 -07:00
f9fb8338f5 fix(ngcc): support ignoring deep-imports via package config (#36423)
Recently we added support for ignoring specified deep-import
warnings by providing sets of regular expressions within the
`ngcc.config.js` file. But this was only working for the project
level configuration.

This commit fixes ngcc so that it will also read these regular
expressions from package level configuration too.

Fixes #35750

PR Close #36423
2020-04-06 11:32:09 -07:00
6b3aa60446 fix(ngcc): support simple browser property in entry-points (#36396)
The `browser` package.json property is now supported to the same
level as `main` - i.e. it is sniffed for UMD, ESM5 and CommonJS.

The `browser` property can also contain an object with file overrides
but this is not supported by ngcc.

Fixes #36062

PR Close #36396
2020-04-06 11:31:10 -07:00
2463548fa7 fix(ngcc): sniff main property for ESM5 format (#36396)
Previously, `main` was only checked for `umd` or `commonjs`
formats. Now if there are `import` or `export` statements in the
source file it will be deemed to be in `esm5` format.

Fixes #35788

PR Close #36396
2020-04-06 11:31:10 -07:00
1140bbc25c refactor(language-service): reformat using clang-format (#36426)
clang-format was recently updated and any PRs that touch files in the
language service will have to reformat all the files.

Instead of changing the formatting in those PRs, this PR formats all
files in language-service package once and for all.

PR Close #36426
2020-04-06 09:29:42 -07:00
1b4df6484e docs: add missing command in WebWorker guide (#36397)
The command was accidentally removed in #36383

PR Close #36397
2020-04-06 09:29:17 -07:00
f40d51733a fix(dev-infra): use commit message validation from @angular/dev-infra-private (#36172)
Prior to this change we manage a local version of commit message validation
in addition to the commit message validation tool contained in the ng-dev
tooling.  By adding the ability to validate a range of commit messages
together, the remaining piece of commit message validation that is in the
local version is replicated.

We use both commands provided by the `ng-dev commit-message` tooling:
- pre-commit-validate: Set to automatically run on an git hook to validate
    commits as they are created locally.
- validate-range: Run by CI for every PR, testing that all of the commits
    added by the PR are valid when considered together.  Ensuring that all
    fixups are matched to another commit in the change.

PR Close #36172
2020-04-06 09:28:52 -07:00
e893c5a330 fix(compiler-cli): pass real source spans where they are empty (#31805)
Some consumers of functions that take `ParseSourceSpan`s currently pass
empty and incorrect source spans. This fixes those cases.

PR Close #31805
2020-04-06 09:28:27 -07:00
8be8466a00 style(ngcc): reformat of ngcc after clang update (#36447)
PR Close #36447
2020-04-06 09:26:57 -07:00
c8bef1259c docs: adding Doguhan Uluca as GDE resource (#34789)
PR Close #34789
2020-04-03 14:03:57 -07:00
568e9df1d6 fix(router): allow UrlMatcher to return null (#36402)
The matcher is allowed to return null per
https://angular.io/api/router/UrlMatcher#usage-notes

And run `yarn gulp format` to pick up recent clang format changes.

Closes #29824

BREAKING CHANGE: UrlMatcher's type now reflects that it could always return
    null.

    If you implemented your own Router or Recognizer class, please update it to
    handle matcher returning null.

PR Close #36402
2020-04-03 11:16:23 -07:00
a555fdba32 build: update pullapprove config to better handle global approvals (#36384)
Beginning with this change, global approvals will now require the approver
to include `Reviewed-for: global-approvers`, and a docs global approval
requires `Reviewed-for: global-docs-approvers`.

Historically, providing a review by any member of the global reviewer
groups would automatically be considered a global review.  This change
enforces that global approval should be an intentional, explicit action.

The global-approvers and global-docs-approvers group will not be
requested as reviews by pullapprove.

PR Close #36384
2020-04-03 11:11:30 -07:00
36535e9abd fix(dev-infra): correct pullapprove global approval regex (#36384)
PR Close #36384
2020-04-03 11:11:30 -07:00
6402a9ae2a build: rebuild yarn lock from scratch (#36377)
Rebuild the yarn lock file from scratch to collapse instances where
one package is able to satisfy multiple dependencies.  Currently we
have some situations where we have multiple versions when one would
work.

Example:
```
"@babel/code-frame@^7.0.0":
  version "7.0.0"
  resolved "https://registry.yarnpkg.com/@babel/cod
  integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij
  dependencies:
    "@babel/highlight" "^7.0.0"

"@babel/code-frame@^7.5.5":
  version "7.5.5"
  resolved "https://registry.yarnpkg.com/@babel/cod
  integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQ
  dependencies:
    "@babel/highlight" "^7.0.0"

"@babel/code-frame@^7.8.3":
  version "7.8.3"
  resolved "https://registry.yarnpkg.com/@babel/cod
  integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0j
  dependencies:
    "@babel/highlight" "^7.8.3"
```

becomes

```
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3":
  version "7.8.3"
  resolved "https://registry.yarnpkg.com/@babel/cod
  integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0j
  dependencies:
    "@babel/highlight" "^7.8.3"
```

PR Close #36377
2020-04-03 11:09:17 -07:00
ca25c957bf fix(ngcc): correctly detect imported TypeScript helpers (#36284)
The `NgccReflectionHost`s have logic for detecting certain known
declarations (such as `Object.assign()` and TypeScript helpers), which
allows the `PartialEvaluator` to evaluate expressions it would not be
able to statically evaluate otherwise.

In #36089, `DelegatingReflectionHost` was introduced, which delegates to
a TypeScript `ReflectionHost` when reflecting on TypeScript files, which
for ngcc's case means `.d.ts` files of dependencies. As a result, ngcc
lost the ability to detect TypeScript helpers imported from `tslib`,
because `DelegatingReflectionHost` was not able to apply the known
declaration detection logic while reflecting on `tslib`'s `.d.ts` files.

This commit fixes this by ensuring `DelegatingReflectionHost` calls the
`NgccReflectionHost`'s `detectKnownDeclaration()` method as necessary,
even when using the TypeScript `ReflectionHost`.

NOTE:
The previous commit exposed a bug in ngcc that was hidden due to the
tests' being inconsistent with how the `ReflectionHost`s are used in the
actual program. The changes in this commit are verified by ensuring the
failing tests are now passing (hence no new tests are added).

PR Close #36284
2020-04-03 11:08:46 -07:00
93f07aee6c test(ngcc): use DelegatingReflectionHost for testing NgccReflectionHosts (#36284)
In #36089, `DelegatingReflectionHost` was introduced. Under the hood, it
delegates another `NgccReflectionHost` in order to reflect over the
program's source files, while using a different TypeScript
`ReflectionHost` to reflect over `.d.ts` files (which is how external
dependencies are represented in the program).

Previously, the `NgccReflectionHost`s were used directly in tests. This
does not exercise them in the way they are exercised in the actual
program, because (when used directly) they will also reflect on `.d.ts`
files too (instead of delegating to the TypeScript `ReflectionHost`).
This could hide bugs that would happen on the actual program.

This commit fixes this by using the `DelegatingReflectionHost` in the
various `NgccReflectionHost` tests.

NOTE:
This change will cause some of the existing tests to start failing.
These failures demonstrate pre-existing bugs in ngcc, that were hidden
due to the tests' being inconsistent with how the `ReflectionHost`s are
used in the actual program. They will be fixed in the next commit.

PR Close #36284
2020-04-03 11:08:46 -07:00
0af6e9fcbb refactor(ngcc): move logic for identifying known declarations to method (#36284)
The `NgccReflectionHost`s have logic for detecting certain known
declarations (such as `Object.assign()` and TypeScript helpers), which
allows the `PartialEvaluator` to evaluate expressions it would not be
able to statically evaluate otherwise.

This commit moves the logic for identifying these known declarations to
dedicated methods. This is in preparation of allowing ngcc's
`DelegatingReflectionHost` (introduced in #36089) to also apply the
known declaration detection logic when reflecting on TypeScript sources.

PR Close #36284
2020-04-03 11:08:46 -07:00
008e12edda fix(benchpress): fix typings in lview_debug.ts (#36236)
* Installing & using benchpress was throwing typescript errors because typings were not defined for the getters in lview_debug.ts

PR Close #36236
2020-04-03 11:06:07 -07:00
1927d0c7db docs: place download section in angular forms to the top (#36075)
This commit partially addresses #35459

PR Close #36075
2020-04-03 11:05:31 -07:00
9a0a90feb3 docs: place download section in angular forms validation to the top of the page (#36074)
This commit partially addresses #35459

PR Close #36074
2020-04-03 11:03:36 -07:00
76d86d5a07 docs: place download section in angular pipes to the top (#36073)
This commit partially addresses #35459

PR Close #36073
2020-04-03 11:01:08 -07:00
de7a9a3b93 docs: place download section to the top of the page (#36067)
Previously, the download link to the example for the angular element
guide was in the middle of the page. To make it easier for the user to
find the download link, it has been placed to the top of the page.

This commit partially addresses #35459

PR Close #36067
2020-04-03 11:00:26 -07:00
04f61c0c3e build: enable strictTemplates in AIO (#36391)
PR Close #36391
2020-04-02 10:53:12 -07:00
c810ac7153 build: sort module resolution warnings in ts-circular-deps tool (#36361)
For better overview of modules that cannot be resolved in the
`ts-circular-deps` tool, the warnings are now sorted.

Additionally, an empty line between fixed and new circular dependencies
is now printed. That should slightly help with distinguishing.

PR Close #36361
2020-04-02 10:52:47 -07:00
c24ad560fa feat(core): undecorated-classes migration should handle derived abstract classes (#35339)
In version 10, undecorated base classes that use Angular features need
to be decorated explicitly with `@Directive()`. Additionally, derived
classes of abstract directives need to be decorated.

The migration already handles this for undecorated classes that are
not explicitly decorated, but since in V9, abstract directives can be
used, we also need to handle this for explicitly decorated abstract
directives. e.g.

```
@Directive()
export class Base {...}

// needs to be decorated by migration when updating from v9 to v10
export class Wrapped extends Base {}

@Component(...)
export class Cmp extends Wrapped {}
```

PR Close #35339
2020-04-02 10:51:49 -07:00
3d2db5c5f0 test: add integration test for undecorated-classes-with-decorated-fields migration (#35339)
We don't have an integration test for the `undecorated-classes-with-decorated-fields
migration. For consistency and to cover for the latest changes, we add
it to the `ng update` integration test.

PR Close #35339
2020-04-02 10:51:48 -07:00
32eafef6a7 fix(core): undecorated-classes-with-decorated-fields migration does not decorate derived classes (#35339)
The `undecorated-classes-with-decorated-fields` migration has been
introduced with 904a2018e0, but misses
logic for decorating derived classes of undecorated classes which use
Angular features. Example scenario:

```ts
export abstract class MyBaseClass {
  @Input() someInput = true;
}

export abstract class BaseClassTwo extends MyBaseClass {}

@Component(...)
export class MyButton extends BaseClassTwo {}
```

Both abstract classes would need to be migrated. Previously, the migration
only added `@Directive()` to `MyBaseClass`, but with this change, it
also decorates `BaseClassTwo`.

This is necessary because the Angular Compiler requires `BaseClassTwo` to
have a directive definition when it flattens the directive metadata for
`MyButton` in order to perform type checking. Technically, not decorating
`BaseClassTwo` does not break at runtime.

We basically want to enforce consistent use of `@Directive` to simplify the
mental model. [See the migration guide](https://angular.io/guide/migration-undecorated-classes#migrating-classes-that-use-field-decorators).

Fixes #34376.

PR Close #35339
2020-04-02 10:51:48 -07:00
2366480250 refactor(core): move schematic import manager to shared utils (#35339)
The import manager has been created for both the `missing-injectable`
and `undecorated-classes-with-di` migration. Both initial PRs brought
in the manager class, so the manager is duplicated in the schematics.

In order to reduce this duplication, and to expose the manager to other
schematics/migrations, we move it into the shared schematic utils.

PR Close #35339
2020-04-02 10:51:48 -07:00
8e55a11283 refactor(core): move schematic base classes logic into shared utils (#35339)
Moves the `findBaseClassDeclarations` method into the shared
schematic utilities. This method will be useful for future
migrations, and for planned changes to the
`undecorated-classes-with-decorated-fields` migration.

PR Close #35339
2020-04-02 10:51:48 -07:00
e9de28111d build: enable service-worker tests on saucelabs (#36129)
Enables the `service-worker` tests on Saucelabs and fixes some issues that were preventing them from running on IE. The issues were:
1. We were serving es2017 code during tests. I've set it to es5.
2. The check which was verifying whether the environment is supported ended up hitting a `require` call in the browser which caused it to fail on browsers that don't support the `URL` API.

PR Close #36129
2020-04-01 15:37:47 -07:00
75afd80ae8 refactor(compiler): add @nocollapse annotation using a synthetic comment (#35932)
In Ivy, Angular decorators are compiled into static fields that are
inserted into a class declaration in a TypeScript transform. When
targeting Closure compiler such fields need to be annotated with
`@nocollapse` to prevent them from being lifted from a static field into
a variable, as that would prevent the Ivy runtime from being able to
find the compiled definitions.

Previously, there was a bug in TypeScript where synthetic comments added
in a transform would not be emitted at all, so as a workaround a global
regex-replace was done in the emit's `writeFile` callback that would add
the `@nocollapse` annotation to all static Ivy definition fields. This
approach is no longer possible when ngtsc is running as TypeScript
plugin, as a plugin cannot control emit behavior.

The workaround is no longer necessary, as synthetic comments are now
properly emitted, likely as of
https://github.com/microsoft/TypeScript/pull/22141 which has been
released with TypeScript 2.8.

This change is required for running ngtsc as TypeScript plugin in
Bazel's `ts_library` rule, to move away from the custom `ngc_wrapped`
approach.

Resolves FW-1952

PR Close #35932
2020-04-01 15:37:06 -07:00
a5eb0e56b6 docs(zone.js): fix typos and align formatting (#35907)
PR Close #35907
2020-04-01 15:35:37 -07:00
4d458db1b5 docs: update and edit web-worker page (#36383)
PR Close #36383
2020-04-01 15:25:47 -07:00
24a92472bf ci: use dev-infra cli from local sources (#36326)
Use dev-infra cli from local sources rather than loading
from @angular/dev-infra-private builds.

PR Close #36326
2020-04-01 15:24:29 -07:00
43006bcc45 feat(dev-infra): standard CLI commands using yargs (#36326)
Creates a standard model for CLI commands provided by ng-dev.
Allows for us to have any of the tools/scripts extend to be
included in the ng-dev command, or be standalone using the same
yargs parser.

PR Close #36326
2020-04-01 15:24:28 -07:00
326240eb91 fix(ngcc): allow ngcc configuration to match pre-release versions of packages (#36370)
Ngcc supports providing a project-level configuration to affect how
certain dependencies are processed and also has a built-in fallback
configuration for some unmaintained packages. Each entry in these
configurations could be scoped to specific versions of a package by
providing a version range. If no version range is provided for a
package, it defaults to `*` (with the intention of matching any
version).

Previously, the installed version of a package was tested against the
version range using the [semver][1] package's `satisfies()` function
with the default options. By default, `satisfies()` does not match
pre-releases (see [here][2] for more details on reasoning). While this
makes sense when determining what version of a dependency to install
(trying to avoid unexpected breaking changes), it is not desired in the
case of ngcc.

This commit fixes it by explicitly specifying that pre-release versions
should be matched normally.

[1]: https://www.npmjs.com/package/semver
[2]: https://github.com/npm/node-semver#prerelease-tags

PR Close #36370
2020-04-01 13:32:32 -07:00
b59bc0e38c fix(platform-server): update xhr2 dependency (#36366)
Previous versions of xhr2 used the depreciated "new Buffer()".

Closes #36358

PR Close #36366
2020-04-01 13:31:38 -07:00
5516802142 fix(compiler): avoid undefined expressions in holey array (#36343)
From G3 bug ID: 116443331

The View Engine compiler crashes when it tries to compile a test in JIT mode
that includes the d3-scale-chromatic library [1]. The d3 package initializes
some arrays using the following pattern:

```js
export var scheme = new Array(3).concat(
  "d8b365f5f5f55ab4ac",
  // ... more entries
).map(colors);
```

The stack trace from the crash is as follows:

```
TypeError: Cannot read property 'visitExpression' of undefined
    at ../../../third_party/javascript/angular2/rc/packages/compiler/src/output/abstract_emitter.ts:505:39
    at JitEmitterVisitor.AbstractEmitterVisitor.visitAllObjects third_party/javascript/angular2/rc/packages/compiler/src/output/abstract_emitter.ts?l=526
    at JitEmitterVisitor.AbstractEmitterVisitor.visitAllExpressions third_party/javascript/angular2/rc/packages/compiler/src/output/abstract_emitter.ts?l=505
    at JitEmitterVisitor.AbstractEmitterVisitor.visitLiteralArrayExpr third_party/javascript/angular2/rc/packages/compiler/src/output/abstract_emitter.ts?l=484
    at LiteralArrayExpr.visitExpression third_party/javascript/angular2/rc/packages/compiler/src/output/output_ast.ts?l=791
    at ../../../third_party/javascript/angular2/rc/packages/compiler/src/output/abstract_emitter.ts:492:19
    at JitEmitterVisitor.AbstractEmitterVisitor.visitAllObjects third_party/javascript/angular2/rc/packages/compiler/src/output/abstract_emitter.ts?l=526
    at JitEmitterVisitor.AbstractEmitterVisitor.visitLiteralMapExpr third_party/javascript/angular2/rc/packages/compiler/src/output/abstract_emitter.ts?l=490
    at LiteralMapExpr.visitExpression third_party/javascript/angular2/rc/packages/compiler/src/output/output_ast.ts?l=819
    at ../../../third_party/javascript/angular2/rc/packages/compiler/src/output/abstract_emitter.ts:505:39
    at JitEmitterVisitor.AbstractEmitterVisitor.visitAllObjects third_party/javascript/angular2/rc/packages/compiler/src/output/abstract_emitter.ts?l=526
    at JitEmitterVisitor.AbstractEmitterVisitor.visitAllExpressions third_party/javascript/angular2/rc/packages/compiler/src/output/abstract_emitter.ts?l=505
    at JitEmitterVisitor.AbstractEmitterVisitor.visitInvokeFunctionExpr third_party/javascript/angular2/rc/packages/compiler/src/output/abstract_emitter.ts?l=318
    at JitEmitterVisitor.AbstractJsEmitterVisitor.visitInvokeFunctionExpr third_party/javascript/angular2/rc/packages/compiler/src/output/abstract_js_emitter.ts?l=112
    at InvokeFunctionExpr.visitExpression third_party/javascript/angular2/rc/packages/compiler/src/output/output_ast.ts?l=440
```

This is because the corresponding output AST for the array is of the form

```ts
[
  undefined,
  undefined,
  undefined,
  o.LiteralExpr,
  // ...
]
```

The output AST is clearly malformed and breaks the type representation of
`LiteralArrayExpr` in which every entry is expected to be of type `Expression`.

This commit fixes the bug by using a plain `for` loop to iterate over the
entire length of the holey array and convert undefined elements to
`LiteralExpr`.

[1]: https://github.com/d3/d3-scale-chromatic/blob/master/src/diverging/BrBG.js

PR Close #36343
2020-04-01 13:31:14 -07:00
cc4b813e75 fix(ngcc): handle bad path mappings when finding entry-points (#36331)
Previously, a bad baseUrl or path mapping passed to an `EntryPointFinder`
could cause the original `sourceDirectory` to be superceded by a higher
directory. This could result in none of the sourceDirectory entry-points being
processed.

Now missing basePaths computed from path-mappings are discarded with
a warning. Further, if the `baseUrl` is the root directory then a warning is
given as this is most likely an error in the tsconfig.json.

Resolves #36313
Resolves #36283

PR Close #36331
2020-04-01 13:30:46 -07:00
64631063ae docs: fix typo in Tests guide (#36330)
Fixing typo in testing.md

PR Close #36330
2020-04-01 13:30:16 -07:00
719224bffd feat(dev-infra): add support for new global approvers in pullapprove (#36324)
Pullapprove as added a few new features to allow for us to better
execute our expectation for global approvals. We need to allow for
an expectation that our global approver groups are not in the list
of approved groups. Additionally, since approval groups apply to
all files in the repo, the global approval groups also do not have
conditions defined for them, which means pullapprove verification
need to allow for no conditions need to be defined.

PR Close #36324
2020-04-01 13:25:48 -07:00
fe2b6923ba fix(language-service): infer type of elements of array-like objects (#36312)
Currently the language service only provides support for determining the
type of array-like members when the array-like object is an `Array`.
However, there are other kinds of array-like objects, including
`ReadonlyArray`s and `readonly`-property arrays. This commit adds
support for retrieving the element type of arbitrary array-like objects.

Closes #36191

PR Close #36312
2020-04-01 13:24:53 -07:00
38ad1d97ab fix(ngcc): handle entry-points within container folders (#36305)
The previous optimizations in #35756 to the
`DirectoryWalkerEntryPointFinder` were over zealous
with regard to packages that have entry-points stored
in "container" directories in the package, where the
container directory was not an entry-point itself.

Now we will also walk such "container" folders as long
as they do not contain `.js` files, which we regard as an
indicator that the directory will not contain entry-points.

Fixes #36216

PR Close #36305
2020-04-01 13:20:52 -07:00
372b9101e2 refactor(ngcc): simplify DirectoryWalkerEntryPointFinder (#36305)
This commit simplifies the `DirectoryWalkerEntryPointFinder` inter-method
calling to make it easier to follow, and also to support controlling
walking of a directory based on its children.

PR Close #36305
2020-04-01 13:20:52 -07:00
7e62aa0c6e refactor(ngcc): rename INVALID_ENTRY_POINT to INCOMPATIBLE_ENTRY_POINT (#36305)
This name better reflects its meaning.

PR Close #36305
2020-04-01 13:20:52 -07:00
36e927a8c6 fix(zone.js): UNPATCHED_EVENTS and PASSIVE_EVENTS should be string[] not boolean (#36258)
__zone_symbol__UNPATCHED_EVENTS and __zone_symbol__PASSIVE_EVENTS should be string[] type not boolean.
For example:
```
const config = window as ZoneGlobalConfigurations;
config.__zone_symbol__UNPATCHED_EVENTS = ['scroll'];
config.__zone_symbol__PASSIVE_EVENTS = ['scroll'];
```

PR Close #36258
2020-04-01 13:20:00 -07:00
9d8bb634f9 fix(benchpress): update dependencies (#36205)
* updated, added, and removed dependencies in package.json
* added dependencies to BUILD.bazel

PR Close #36205
2020-04-01 13:19:33 -07:00
c5c57f6737 build: update to clang 1.4.0 and only run clang format on changed files (#36203)
Update to clang@1.4.0 to gain support for optional changing and nullish
coalescing.  Because this would trigger a change on >1800 files in the
repository, also changes our format enforcement to only be run against
changed files.  This will allow us to incramentally roll out the value
add of the upgraded clang format.

PR Close #36203
2020-04-01 13:18:09 -07:00
51a89c32c4 docs: update and edit web-worker page (#36026)
PR Close #36026
2020-04-01 13:17:26 -07:00
e1ac2efe4a docs: make page titles and toc task-oriented (#36024)
PR Close #36024
2020-04-01 13:16:48 -07:00
702e17cfe2 docs: change page title and minor edit (#36021)
PR Close #36021
2020-04-01 13:16:18 -07:00
4d1d0fa03b docs: update ng-conf announcement to remove livestream link (#36382)
Since the livestream for ng-conf is not public this year,
(and is only available to ng-conf attendees), we are
removing the link from the angular.io homepage.

Instead, we are now pointing to the ng-conf homepage for
more information.

PR Close #36382
2020-04-01 13:14:42 -07:00
ec8bae1b27 docs: update end date of survey to middle of April (#36339)
PR Close #36339
2020-04-01 11:10:58 -07:00
08348fc2e8 build(docs-infra): rename duplicate test name (#36348)
When running `docs-test` for the docs generation, a warning is printed for a
duplicate test. This commit fixes this issue.

PR Close #36348
2020-03-31 11:06:16 -07:00
63fbc71439 build: don't use deprecated $(location) pre-declared variable (#36308)
$(location) is not recommended in the bazel docs as depending on context it will either return the value of $(execpath) or $(rootpath). rules_nodejs now supports $(rootpath) and $(execpath) in templated_args of nodejs_binary.

PR Close #36308
2020-03-31 11:02:56 -07:00
b44f7b5e16 fix(zone.js): fix 2 bluebird test cases for each/mapSeries (#36295)
`Bluebird.each` and `Bluebird.mapSeries` will accept a callback with `value` parameter,
the `value` should be the item in the array, not array itself.

For example:
```
const arr = [1, 2];
Bluebird.each(arr, function(value, idx) {
  console.log(`value: ${value}, idx: ${idx}`);
})
```

the output will be
```
value: 1, idx: 0
value: 2, idx: 1
```

This PR fix the test cases for `each` and `mapSeries` APIs.

PR Close #36295
2020-03-31 10:59:56 -07:00
c5df9ce474 build(zone.js): update zone.js version to 0.10.3 (#36214)
PR Close #36214
2020-03-31 10:59:17 -07:00
2510e7dad6 docs: fix typo in Schematics guide (#36328)
Fixing typo in schematics-for-libraries.md
PR Close #36328
2020-03-30 15:32:05 -07:00
80c68583d1 refactor(core): use more narrow QueryList import to avoid circular deps issue (#36286)
Prior to this commit, the `packages/core/src/render3/interfaces/query.ts` file used to import `QueryList` using `../../linker`, which contains a lot of re-exports and as a result, this one import caused a lot of circular deps cycles reported by the tool that checks such deps. In other places in the code the `QueryList` is imported using more narrow import (`linker/query_list`), so this commit uses the same pattern. This change allowed to reduce the number of known cycles from 343 to 207, the golden file was updated accordingly.

PR Close #36286
2020-03-30 15:31:39 -07:00
5b6ced5599 build: update to rules_nodejs 1.5.0 (#36307)
### New stuff

* The `ts_project` rule is a simple wrapper around the TypeScript compiler, `tsc`. This is an alternative to `ts_library` but not a replacement. Read more about the trade-offs at https://bazelbuild.github.io/rules_nodejs/TypeScript#alternatives or read the [API docs](https://bazelbuild.github.io/rules_nodejs/TypeScript#ts_project)
* `pkg_npm` can now be used as a dependency within your repo as well as for publishing to npm. It provides a `LinkablePackageInfo` which is our internal API to pass package name/path to downstream compilations, essentially providing the "Lerna" feature.
* There is experimental support for Bazel's "worker mode" in `rollup_bundle`, which essentially puts Rollup in watch mode. Add the `supports_workers = True` attribute to opt-in.
* Better support for [pre-defined label variables](https://docs.bazel.build/versions/master/be/make-variables.html#predefined_label_variables) like `$(rootpath)` and `$(execpath)` - we no longer recommend using `$(location)` at all.

See release notes https://github.com/bazelbuild/rules_nodejs/releases/tag/1.5.0 for more info.

PR Close #36307
2020-03-30 11:25:16 -07:00
a383116b43 docs: fix typo in Dependency Injection guide (#36304)
Fixing typo in dependency-injection-navtree.md

PR Close #36304
2020-03-30 11:14:55 -07:00
c6dd900f60 fix(ngcc): do not write entry-point manifest outside node_modules (#36299)
Fixes #36296

PR Close #36299
2020-03-30 11:03:26 -07:00
5ac308060d refactor(ngcc): rename workerCount to maxWorkerCount (#36298)
Now that we spawn workers lazily as needed, this private property is
really the upper limit on how many workers we might spawn.

PR Close #36298
2020-03-30 11:02:52 -07:00
bc089abd32 docs: add strictTemplates in place of fullTemplateTypeCheck (#35628)
Co-Authored-By: Igor Minar <iminar@google.com>

Updating the recommended defaults for template typechecking strictness to the most strict in order
to catch most of the errors at compile time.

See https://angular.io/guide/template-typecheck for more info.

PR Close #35628
2020-03-30 10:57:15 -07:00
c94a33c525 refactor(dev-infra): fix lint warnings for Pullapprove-related scripts (#36287)
The `dev-infra` scripts were added to the list of sources that should be verified with clang (b07b6edc2a), but the Pullapprove-related scripts that were merged before (83e4a76afa) doesn't pass these checks. This commit updates a couple scripts to have a proper formatting.

PR Close #36287
2020-03-28 23:21:12 -07:00
5cee709266 fix(ngcc): do not spawn more processes than intended in parallel mode (#36280)
When running in parallel mode, ngcc spawns multiple worker processed to
process the various entry-points. The number of max allowed processes is
determined by the number of CPU cores available to the OS. There is also
currently an [upper limit of 8][1]. The number of active workers is in
turn inferred by the number of [task assignments][2].

In the past, counting the entries of `ClusterMaster#taskAssignments` was
enough, because worker processes were spawned eagerly at the beginning
and corresponding entries were created in `taskAssignments`.
Since #35719 however, worker processes are spawned lazily on an as
needed basis. Because there is some delay between
[spawning a process][3] and [inserting it][4] into `taskAssignments`,
there is a short period of time when `taskAssignment.size` does not
actually represent the number of spawned processes. This can result in
spawning more than `ClusterMaster#workerCount` processes.

An example of this can be seen in #36278, where the debug logs indicate
9 worker processes had been spawned (`All 9 workers are currently busy`)
despite the hard limit of 8.

This commit fixes this by using `cluster.workers` to compute the number
of spawned worker processes. `cluster.workers` is updated synchronously
with `cluster.fork()` and thus reflects the number of spawned workers
accurately at all times.

[1]: https://github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/main.ts#L429
[2]: https://github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts#L108
[3]: https://github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts#L110
[4]: https://github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts#L199

PR Close #36280
2020-03-27 14:12:28 -07:00
2d0847c307 docs: update release nots with blog post (#36268)
PR Close #36268
2020-03-27 11:18:23 -07:00
995cd15a69 fix(ngcc): correctly identify the package path of secondary entry-points (#36249)
Previously we only searched for package paths below the set of `basePaths`
that were computed from the `basePath` provided to ngcc and the set of
`pathMappings`.

In some scenarios, such as hoisted packages, the entry-point is not within
any of the `basePaths` identified above. For example:

```
project
  packages
    app
      node_modules
        app-lib (depends on lib1)
  node_modules
    lib1 (depends on lib2)
      node_modules
        lib2 (depends on lib3/entry-point)
    lib3
      entry-point
```

When CLI is compiling `app-lib` ngcc will be given
`project/packages/app/node_modules` as the `basePath.

If ngcc is asked to target `lib2`, the `targetPath` will be
`project/node_modules/lib1/node_modules/lib2`.

Since `lib2` depends upon `lib3/entry-point`, ngcc will need to compute
the package path for `project/node_modules/lib3/entry-point`.

Since `project/node_modules/lib3/entry-point` is not contained in the `basePath`
`project/packages/app/node_modules`, ngcc failed to compute the `packagePath`
correctly, instead assuming that it was the same as the entry-point path.

Now we also consider the nearest `node_modules` folder to the entry-point
path as an additional `basePath`. If one is found then we use the first
directory directly below that `node_modules` directory as the package path.

In the case of our example this extra `basePath` would be `project/node_modules`
which allows us to compute the `packagePath` of `project/node_modules/lib3`.

Fixes #35747

PR Close #36249
2020-03-27 11:17:45 -07:00
16497438d6 fix(core): run APP_INITIALIZERs before accessing LOCALE_ID token in Ivy TestBed (#36237)
Prior to this commit, Ivy TestBed was accessing locale ID before `APP_INITIALIZER` functions were called. This execution order is not consistent with the app bootstrap logic in `application_ref.ts`. This commit updates Ivy TestBed execution order to call initializers first (since they might affect `LOCALE_ID` token value) and accessing and setting locale ID after that.

Fixes #36230.

PR Close #36237
2020-03-27 11:16:57 -07:00
b54db86f43 build: fix bad pullapprove rule (#36232)
The dev-infra pull approve group contained a condition with
the glob having a string concatenation rather than a comma
separated list. This corrects this error, and in another PR
we will correct the verification scripts failure to catch
this.

PR Close #36232
2020-03-27 11:15:38 -07:00
44acf6734b build: allow custom module resolution for ts-circular-deps tests (#36226)
Currently the `ts-circular-deps` tool uses a hard-coded module resolver
that only works in the `angular/angular` repository.

If the tool is consumed in other repositories through the shared
dev-infra package, the module resolution won't work, and a few
resolvable imports (usually cross-entry-points) are accidentally
skipped. For each test, the resolution might differ, so tests can
now configure their module resolution in a configuration file.

Note that we intentionally don't rely on tsconfig's for module
resolution as parsing their mappings rather complicates the
circular dependency tool. Additionally, not every test has a
corresponding tsconfig file.

Also, hard-coding mappings to `@angular/*` while accepting a
path to the packages folder would work, but it would mean
that the circular deps tool is no longer self-contained. Rather,
and also for better flexibility, a custom resolver should be
specified.

PR Close #36226
2020-03-27 11:14:49 -07:00
b07b6edc2a build: add dev-infra to clang format sources to format (#36204)
PR Close #36204
2020-03-27 11:13:17 -07:00
83e4a76afa feat(dev-infra): handle excluding files via globs in pullapprove (#36162)
Updates the pullapprove verification script to handle
cases of excluding globs from groups.

PR Close #36162
2020-03-27 11:12:48 -07:00
bfa7b1a494 docs: correct a misleading sentence (#36155) (#36158)
Fixes #36155

PR Close #36158
2020-03-27 10:49:31 -07:00
8e0dec538e docs: clarify observables doc with new titles and tooltips (#36023)
PR Close #36023
2020-03-27 10:49:03 -07:00
1c385a1c22 build(docs-infra): do not include CI-specific config in docs examples ZIP archives (#36018)
In #35381, a new Protractor config file was introduced in docs examples,
`protractor-puppeteer.conf.js`, that was only supposed to be used on CI
and not be shipped with the ZIP archives provided for users to download
and experiment with the docs examples locally.

The logic to ignore the `protractor-puppeteer.conf.js` file was
incorrect, resulting in the file being retained in some examples (e.g.
[universal][1]). The problem was not immediately obvious, because most
examples explicitly specify all `**/*.js` files as ignored, but for
other examples the file was retained in the ZIP archive.

This commit fixes the logic to ensure the file is excluded from all docs
examples ZIP archives.

[1]: https://v9.angular.io/generated/zips/universal/universal.zip

PR Close #36018
2020-03-27 10:48:30 -07:00
f9bc84cd99 build(docs-infra): remove obsolete properties from zipper.json files (#36018)
The `removeSystemJsConfig` and `type` properties (present in some
`zipper.json` files) are now obsolete and are not taken into account by
the example zipper:
- `removeSystemJsConfig` is no longer relevant since most examples have
  been migrated to use the CLI.
- `type` is no longer relevant, because the project type is determined
  based on the `projectType` property in `example-config.json` files.

This commit removes these properties from `zipper.json` files and
updates the `example-zipper` docs to not mention them.

PR Close #36018
2020-03-27 10:48:30 -07:00
2d7c95fb70 fix(service-worker): prevent SW registration strategies from affecting app stabilization (#35870)
Previously, some of the built-in ServiceWorker registration strategies,
namely `registerWithDelay:<timeout>` and `registerWhenStable:<timeout>`,
would register potentially long-running timeout, thus preventing the app
from stabilizing before the timeouts expired. This was especially
problematic for the `registerWhenStable:<timeout>` strategy, which waits
for the app to stabilize, because the strategy itself would prevent the
app from stabilizing and thus the ServiceWorker would always be
registered after the timeout.

This commit fixes this by subscribing to the registration strategy
observable outside the Angular zone, thus not affecting the app's
stabilization.

PR Close #35870
2020-03-27 10:47:44 -07:00
29e8a64cf0 fix(service-worker): by default register the SW after 30s even the app never stabilizes (#35870)
Previously, when using the default ServiceWorker registration strategy
Angular would wait indefinitely for the [app to stabilize][1], before
registering the ServiceWorker script. This could lead to a situation
where the ServiceWorker would never be registered when there was a
long-running task (such as an interval or recurring timeout).

Such tasks can often be started by a 3rd-party dependency (beyond the
developer's control or even without them realizing). In addition, this
situation is particularly hard to detect, because the ServiceWorker is
typically not used during development and on production builds a
previous ServiceWorker instance might be already active.

This commit fixes this by changing the default registration strategy
from `registerWhenStable` to `registerWhenStable:30000`, which will
ensure that the ServiceWorker will be registered after 30s at the
latest, even if the app has not stabilized by then.

Fixes #34464

PR Close #35870
2020-03-27 10:47:44 -07:00
00efacf561 feat(service-worker): support timeout in registerWhenStable SW registration strategy (#35870)
Previously, when using the `registerWhenStable` ServiceWorker
registration strategy (which is also the default) Angular would wait
indefinitely for the [app to stabilize][1], before registering the
ServiceWorker script. This could lead to a situation where the
ServiceWorker would never be registered when there was a long-running
task (such as an interval or recurring timeout).

Such tasks can often be started by a 3rd-party dependency (beyond the
developer's control or even without them realizing). In addition, this
situation is particularly hard to detect, because the ServiceWorker is
typically not used during development and on production builds a
previous ServiceWorker instance might be already active.

This commit enhances the `registerWhenStable` registration strategy by
adding support for an optional `<timeout>` argument, which guarantees
that the ServiceWorker will be registered when the timeout expires, even
if the app has not stabilized yet.

For example, with `registerWhenStable:5000` the ServiceWorker will be
registered as soon as the app stabilizes or after 5 seconds if the app
has not stabilized by then.

Related to #34464.

[1]: https://angular.io/api/core/ApplicationRef#is-stable-examples

PR Close #35870
2020-03-27 10:47:44 -07:00
d96995b4e3 docs: update glossary defs for components, templates, and views (#35559)
PR Close #35559
2020-03-27 10:46:49 -07:00
fc3e5cb6d3 docs: coalesce release notes for the v9.1.0 release (#36247)
Merge all of the release notes across all v9.1.0 releases into a single one.

PR Close #36247
2020-03-25 14:11:07 -07:00
d37dad82f1 build: ensure that refs and shas for PRs only need to be requested once (#36207)
This is done by requesting the refs and shas for the PR when the
env.sh script is run.  Additionally, the env.sh script is now setup
to write all of the environment variables created to a cache file
and subsequent loads of the environment load the values from there.

The get-refs-and-shas-for-target.js script now also first attempts
to load the refs and shas from an environment variable before
falling back to requesting from github via the API.

PR Close #36207
2020-03-25 11:49:42 -07:00
22710fc353 docs: release notes for the v9.1.0 release 2020-03-25 09:44:22 -07:00
4f66250618 docs: release notes for the v9.1.0-rc.2 release 2020-03-24 16:18:10 -07:00
d783519835 fix(common): let KeyValuePipe accept type unions with null (#36093)
`KeyValuePipe` currently accepts `null` values as well as `Map`s and a
few others. However, due to the way in which TS overloads work, a type
of `T|null` will not be accepted by `KeyValuePipe`'s signatures, even
though both `T` and `null` individually would be.

To make this work, each signature that accepts some type `T` has been
duplicated with a second one below it that accepts a `T|null` and
includes `null` in its return type.

Fixes #35743

PR Close #36093
2020-03-24 14:41:41 -07:00
b8e9a30d3b fix(ngcc): use preserve whitespaces from tsconfig if provided (#36189)
Previously ngcc never preserved whitespaces but this is at odds
with how the ViewEngine compiler works. In ViewEngine, library
templates are recompiled with the current application's tsconfig
settings, which meant that whitespace preservation could be set
in the application tsconfig file.

This commit allows ngcc to use the `preserveWhitespaces` setting
from tsconfig when compiling library templates. One should be aware
that this disallows different projects with different tsconfig settings
to share the same node_modules folder, with regard to whitespace
preservation. But this is already the case in the current ngcc since
this configuration is hard coded right now.

Fixes #35871

PR Close #36189
2020-03-24 14:25:06 -07:00
32ce8b1326 feat(compiler): add dependency info and ng-content selectors to metadata (#35695)
This commit augments the `FactoryDef` declaration of Angular decorated
classes to contain information about the parameter decorators used in
the constructor. If no constructor is present, or none of the parameters
have any Angular decorators, then this will be represented using the
`null` type. Otherwise, a tuple type is used where the entry at index `i`
corresponds with parameter `i`. Each tuple entry can be one of two types:

1. If the associated parameter does not have any Angular decorators,
   the tuple entry will be the `null` type.
2. Otherwise, a type literal is used that may declare at least one of
   the following properties:
   - "attribute": if `@Attribute` is present. The injected attribute's
   name is used as string literal type, or the `unknown` type if the
   attribute name is not a string literal.
   - "self": if `@Self` is present, always of type `true`.
   - "skipSelf": if `@SkipSelf` is present, always of type `true`.
   - "host": if `@Host` is present, always of type `true`.
   - "optional": if `@Optional` is present, always of type `true`.

   A property is only present if the corresponding decorator is used.

   Note that the `@Inject` decorator is currently not included, as it's
   non-trivial to properly convert the token's value expression to a
   type that is valid in a declaration file.

Additionally, the `ComponentDefWithMeta` declaration that is created for
Angular components has been extended to include all selectors on
`ng-content` elements within the component's template.

This additional metadata is useful for tooling such as the Angular
Language Service, as it provides the ability to offer suggestions for
directives/components defined in libraries. At the moment, such
tooling extracts the necessary information from the _metadata.json_
manifest file as generated by ngc, however this metadata representation
is being replaced by the information emitted into the declaration files.

Resolves FW-1870

PR Close #35695
2020-03-24 14:21:42 -07:00
ff4eb0cb63 docs(elements): correct typo in custom elements image (#36090)
Fixes #36050

PR Close #36090
2020-03-24 10:36:11 -07:00
9ba46d9f88 fix(elements): correctly handle setting inputs to undefined (#36140)
Previously, when an input property was initially set to `undefined` it
would not be correctly recognized as a change (and trigger
`ngOnChanges()`).

This commit ensures that explicitly setting an input to `undefined` is
correctly handled the same as setting the property to any other value.
This aligns the behavior of Angular custom elements with that of the
corresponding components when used directly (not as custom elements).

PR Close #36140
2020-03-24 10:29:33 -07:00
b14ac96750 fix(elements): correctly set SimpleChange#firstChange for pre-existing inputs (#36140)
Previously, when an input property was set on an `NgElement` before
instantiating the underlying component, the `SimpleChange` object passed
to `ngOnChanges()` would have `firstChange` set to false, even if this
was the first change (as far as the component instance was concerned).

This commit fixes this by ensuring `SimpleChange#firstChange` is set to
true on first change, regardless if the property was set before or after
instantiating the component. This alignthe behavior of Angular custom
elements with that of the corresponding components when used directly
(not as custom elements).

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

Fixes #36130

PR Close #36140
2020-03-24 10:29:32 -07:00
55dac05cf2 docs: fix typo in testing component with dependencies (#36219)
Fixes #36210

PR Close #36219
2020-03-24 10:19:47 -07:00
ae28d7c0b2 build(docs-infra): upgrade cli command docs sources to 56c648827 (#36224)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](f5dd5b16a...56c648827):

**Modified**
- help/build.json
- help/lint.json
- help/test.json

PR Close #36224
2020-03-24 10:16:49 -07:00
380de1e7b4 fix(ngcc): use path-mappings from tsconfig in dependency resolution (#36180)
When computing the dependencies between packages which are not in
node_modules, we may need to rely upon path-mappings to find the path
to the imported entry-point.

This commit allows ngcc to use the path-mappings from a tsconfig
file to find dependencies. By default any tsconfig.json file in the directory
above the `basePath` is loaded but it is possible to use a path to a
specific file by providing the `tsConfigPath` property to mainNgcc,
or to turn off loading any tsconfig file by setting `tsConfigPath` to `null`.
At the command line this is controlled via the `--tsconfig` option.

Fixes #36119

PR Close #36180
2020-03-24 10:16:12 -07:00
4f9717331d test(common): Add test for NgForOfContext.count (#36046)
`NgForOfContext.count` is the length of the iterable.

PR Close #36046
2020-03-24 10:15:11 -07:00
36fc28642a docs(common): Add missing entry for NgForOfContext.count (#36046)
`count` is available in `NgForOfContext` but it's missing in the docs.

PR Close #36046
2020-03-24 10:15:11 -07:00
a323b9b1a3 test(core): re-enable IE 10/11 test on SauceLabs (#35962)
I was not able to reproduce IE 10/11 failrue of the disabled
tests on SauceLabs any more. I did some cleanup of the test
in question but I doubt it was the root cause of the problem.

PR Close #35962
2020-03-24 10:14:47 -07:00
58f4254fba fix(dev-infra): use @angular/dev-infra-private package for pullapprove verification (#35996)
Adds devDependency on @angular/dev-infra-private and removes the verify script
from tools, relying instead on the script from ng-dev.

PR Close #35996
2020-03-24 10:14:05 -07:00
4419907b08 docs: release notes for the v9.1.0-rc.1 release 2020-03-23 13:22:17 -07:00
9d415f9c3f fix(docs-infra): change app-list-item to app-item-list (#35601)
The `app-list-item` component sounds like it is used for a single
item, however it renders a list of items. There were also
several changes in the documentation, where it was becoming
confusing if the `app-list-item` is using a single item or multiple
items. This commit fixes this issue. It renames the component and its
respective properties to make sure that the intention is very clear.

Closes #35598

PR Close #35601
2020-03-23 11:40:15 -07:00
fced8ee40e fix(localize): allow ICU expansion case to start with any character except } (#36123)
Previously, an expansion case could only start with an alpha numeric character.
This commit fixes this by allowing an expansion case to start with any character
except `}`.

The [ICU spec](http://userguide.icu-project.org/formatparse/messages) is pretty vague:

> Use a "select" argument to select sub-messages via a fixed set of keywords.

It does not specify what can be a "keyword" but from looking at the surrounding syntax it
appears that it can indeed be any string that does not contain a `}` character.

Closes #31586

PR Close #36123
2020-03-23 11:37:12 -07:00
1cb7b88505 fix(dev-infra): change circular deps positional params to camelCase (#36165)
Changes the positional params for the circular deps tooling to
use camelCase as it requires being defined in camelCase while
in strict mode.  Additionally, remove the `version()` call as
the boolean arguement does not exist in current versions and
throws errors on execution.

PR Close #36165
2020-03-23 11:36:28 -07:00
0e76b32aa5 fix(dev-infra): prep ts-circular-deps to load via node_modules (#36165)
to run ts-circular-deps via installed node_modules, we needed to set
the hashbang of the script to be a node environment, and discover the
project directory based on where the script is run rather than the
scripts file location.

PR Close #36165
2020-03-23 11:36:28 -07:00
e81ad3a1bc docs: Add asterisk info in template syntax guide (#36176)
Add helpful alert for asterisk syntax in the `ngFor` section of template syntax guide

PR Close #36176
2020-03-23 11:36:09 -07:00
c3a85ceabc docs: Change important alert of ngFor (#36176)
Update the important alert of ngFor so that it has a unique format with that of ngIf

PR Close #36176
2020-03-23 11:36:09 -07:00
85e0e366df docs(elements): Edge supports Web Components (#36182)
PR Close #36182
2020-03-23 11:35:49 -07:00
0ce8ad3493 fix(core): workaround Terser inlining bug (#36200)
This variable name change works around https://github.com/terser/terser/issues/615, which was causing the JIT production tests to fail in the Angular CLI repository (https://github.com/angular/angular-cli/issues/17264).

PR Close #36200
2020-03-23 11:34:39 -07:00
528e25a81a build(docs-infra): upgrade cli command docs sources to f5dd5b16a (#36159)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](6aa3c134c...f5dd5b16a):

**Modified**
- help/update.json

PR Close #36159
2020-03-20 13:57:18 -07:00
d25012e864 docs(zone.js): Typos on zone.md file and fixes on code examples. (#36138)
1. During reading the documentation I found some code examples that were refering to the class properties via methods, but without specifying the context `this`.
2. The 'onInvoke' hook was duplicated
3. A minor typo on `Zones and execution contexts` section
4. A minor typo on `Zones and async lifecycle hooks` section

PR Close #36138
2020-03-20 13:57:00 -07:00
c21c46a8e8 fix(docs-infra): include correct dependencies in StackBlitz examples (#36071)
Previously, all StackBlitz examples included the default dependencies
for `cli`-type projects. However, different example types may have
different `package.json` files with different dependencies.
For example, the [boilerplate `package.json`][1] for `elements` examples
includes an extra dependency on `@angular/elements`.

This commit changes `StackblitzBuilder` to use the dependencies that
correspond to each example type.
(NOTE: Manually verified the changes.)

Jira issue: [FW-2002][2]

[1]: https://github.com/angular/angular/blob/05d058622/aio/tools/examples/shared/boilerplate/elements/package.json
[2]: https://angular-team.atlassian.net/browse/FW-2002

PR Close #36071
2020-03-20 13:56:26 -07:00
9cc8bd5f7d refactor(docs-infra): clean up stackblitz-builder/builder.js script (#36071)
- Remove unused dependencies.
- Change `var` to `const/let`.
- Change regular functions as callbacks to arrow functions.
- Remove unnecessary intermediate variables.
- Switch from custom `_existsSync()` implementation to built-in
  `fs.existsSync()`.

PR Close #36071
2020-03-20 13:56:26 -07:00
ae3eaf8b16 test(compiler): remove whitespace in spans (#36169)
https://github.com/angular/angular/pull/36133 and https://github.com/angular/angular/pull/35986
caused a conflict in test after they both got merged to master.
This PR fixes the failed tests.

PR Close #36169
2020-03-20 12:52:31 -07:00
d714b95fb9 feat(compiler): Propagate value span of ExpressionBinding to ParsedProperty (#36133)
This commit propagates the correct value span in an ExpressionBinding of
a microsyntax expression to ParsedProperty, which in turn porpagates the
span to the template ASTs (both VE and Ivy).

PR Close #36133
2020-03-20 10:21:11 -07:00
912692137a fix(docs-infra): fix image name in example (#36127)
Closes #35618

PR Close #36127
2020-03-20 10:20:36 -07:00
6fc85073d2 feat(dev-infra): create commit-message validation script/tooling (#36117)
PR Close #36117
2020-03-20 10:20:12 -07:00
989dea7083 refactor(benchpress): delete broken code (#35922)
PR Close #35922
2020-03-20 10:19:48 -07:00
2226 changed files with 51175 additions and 40056 deletions

View File

@ -34805,15 +34805,27 @@ function hasMergeConflicts(str) {
function parse(str, fileLoc) {
const parser = new Parser(str, fileLoc);
parser.next();
try {
return parser.parse();
} catch (error1) {
if (!fileLoc.endsWith(`.yml`)) {
try {
return safeLoad(str, {
schema: FAILSAFE_SCHEMA
});
} catch (error2) {
throw error1;
return parser.parse();
} catch (error1) {
try {
return safeLoad(str, {
schema: FAILSAFE_SCHEMA
});
} catch (error2) {
throw error1;
}
}
} else {
const result = safeLoad(str, {
schema: FAILSAFE_SCHEMA
});
if (typeof result === 'object') {
return result;
} else {
return {};
}
}
}
@ -46666,7 +46678,7 @@ function mkdirfix (name, opts, cb) {
/* 194 */
/***/ (function(module, exports) {
module.exports = {"name":"yarn","installationMethod":"unknown","version":"1.21.1","license":"BSD-2-Clause","preferGlobal":true,"description":"📦🐈 Fast, reliable, and secure dependency management.","dependencies":{"@zkochan/cmd-shim":"^3.1.0","babel-runtime":"^6.26.0","bytes":"^3.0.0","camelcase":"^4.0.0","chalk":"^2.1.0","cli-table3":"^0.4.0","commander":"^2.9.0","death":"^1.0.0","debug":"^3.0.0","deep-equal":"^1.0.1","detect-indent":"^5.0.0","dnscache":"^1.0.1","glob":"^7.1.1","gunzip-maybe":"^1.4.0","hash-for-dep":"^1.2.3","imports-loader":"^0.8.0","ini":"^1.3.4","inquirer":"^6.2.0","invariant":"^2.2.0","is-builtin-module":"^2.0.0","is-ci":"^1.0.10","is-webpack-bundle":"^1.0.0","js-yaml":"^3.13.1","leven":"^2.0.0","loud-rejection":"^1.2.0","micromatch":"^2.3.11","mkdirp":"^0.5.1","node-emoji":"^1.6.1","normalize-url":"^2.0.0","npm-logical-tree":"^1.2.1","object-path":"^0.11.2","proper-lockfile":"^2.0.0","puka":"^1.0.0","read":"^1.0.7","request":"^2.87.0","request-capture-har":"^1.2.2","rimraf":"^2.5.0","semver":"^5.1.0","ssri":"^5.3.0","strip-ansi":"^4.0.0","strip-bom":"^3.0.0","tar-fs":"^1.16.0","tar-stream":"^1.6.1","uuid":"^3.0.1","v8-compile-cache":"^2.0.0","validate-npm-package-license":"^3.0.4","yn":"^2.0.0"},"devDependencies":{"babel-core":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^6.2.5","babel-plugin-array-includes":"^2.0.3","babel-plugin-inline-import":"^3.0.0","babel-plugin-transform-builtin-extend":"^1.1.2","babel-plugin-transform-inline-imports-commonjs":"^1.0.0","babel-plugin-transform-runtime":"^6.4.3","babel-preset-env":"^1.6.0","babel-preset-flow":"^6.23.0","babel-preset-stage-0":"^6.0.0","babylon":"^6.5.0","commitizen":"^2.9.6","cz-conventional-changelog":"^2.0.0","eslint":"^4.3.0","eslint-config-fb-strict":"^22.0.0","eslint-plugin-babel":"^5.0.0","eslint-plugin-flowtype":"^2.35.0","eslint-plugin-jasmine":"^2.6.2","eslint-plugin-jest":"^21.0.0","eslint-plugin-jsx-a11y":"^6.0.2","eslint-plugin-prefer-object-spread":"^1.2.1","eslint-plugin-prettier":"^2.1.2","eslint-plugin-react":"^7.1.0","eslint-plugin-relay":"^0.0.28","eslint-plugin-yarn-internal":"file:scripts/eslint-rules","execa":"^0.11.0","fancy-log":"^1.3.2","flow-bin":"^0.66.0","git-release-notes":"^3.0.0","gulp":"^4.0.0","gulp-babel":"^7.0.0","gulp-if":"^2.0.1","gulp-newer":"^1.0.0","gulp-plumber":"^1.0.1","gulp-sourcemaps":"^2.2.0","jest":"^22.4.4","jsinspect":"^0.12.6","minimatch":"^3.0.4","mock-stdin":"^0.3.0","prettier":"^1.5.2","string-replace-loader":"^2.1.1","temp":"^0.8.3","webpack":"^2.1.0-beta.25","yargs":"^6.3.0"},"resolutions":{"sshpk":"^1.14.2"},"engines":{"node":">=4.0.0"},"repository":"yarnpkg/yarn","bin":{"yarn":"./bin/yarn.js","yarnpkg":"./bin/yarn.js"},"scripts":{"build":"gulp build","build-bundle":"node ./scripts/build-webpack.js","build-chocolatey":"powershell ./scripts/build-chocolatey.ps1","build-deb":"./scripts/build-deb.sh","build-dist":"bash ./scripts/build-dist.sh","build-win-installer":"scripts\\build-windows-installer.bat","changelog":"git-release-notes $(git describe --tags --abbrev=0 $(git describe --tags --abbrev=0)^)..$(git describe --tags --abbrev=0) scripts/changelog.md","dupe-check":"yarn jsinspect ./src","lint":"eslint . && flow check","pkg-tests":"yarn --cwd packages/pkg-tests jest yarn.test.js","prettier":"eslint src __tests__ --fix","release-branch":"./scripts/release-branch.sh","test":"yarn lint && yarn test-only","test-only":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --verbose","test-only-debug":"node --inspect-brk --max_old_space_size=4096 node_modules/jest/bin/jest.js --runInBand --verbose","test-coverage":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --coverage --verbose","watch":"gulp watch","commit":"git-cz"},"jest":{"collectCoverageFrom":["src/**/*.js"],"testEnvironment":"node","modulePathIgnorePatterns":["__tests__/fixtures/","packages/pkg-tests/pkg-tests-fixtures","dist/"],"testPathIgnorePatterns":["__tests__/(fixtures|__mocks__)/","updates/","_(temp|mock|install|init|helpers).js$","packages/pkg-tests"]},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}}}
module.exports = {"name":"yarn","installationMethod":"unknown","version":"1.22.4","license":"BSD-2-Clause","preferGlobal":true,"description":"📦🐈 Fast, reliable, and secure dependency management.","dependencies":{"@zkochan/cmd-shim":"^3.1.0","babel-runtime":"^6.26.0","bytes":"^3.0.0","camelcase":"^4.0.0","chalk":"^2.1.0","cli-table3":"^0.4.0","commander":"^2.9.0","death":"^1.0.0","debug":"^3.0.0","deep-equal":"^1.0.1","detect-indent":"^5.0.0","dnscache":"^1.0.1","glob":"^7.1.1","gunzip-maybe":"^1.4.0","hash-for-dep":"^1.2.3","imports-loader":"^0.8.0","ini":"^1.3.4","inquirer":"^6.2.0","invariant":"^2.2.0","is-builtin-module":"^2.0.0","is-ci":"^1.0.10","is-webpack-bundle":"^1.0.0","js-yaml":"^3.13.1","leven":"^2.0.0","loud-rejection":"^1.2.0","micromatch":"^2.3.11","mkdirp":"^0.5.1","node-emoji":"^1.6.1","normalize-url":"^2.0.0","npm-logical-tree":"^1.2.1","object-path":"^0.11.2","proper-lockfile":"^2.0.0","puka":"^1.0.0","read":"^1.0.7","request":"^2.87.0","request-capture-har":"^1.2.2","rimraf":"^2.5.0","semver":"^5.1.0","ssri":"^5.3.0","strip-ansi":"^4.0.0","strip-bom":"^3.0.0","tar-fs":"^1.16.0","tar-stream":"^1.6.1","uuid":"^3.0.1","v8-compile-cache":"^2.0.0","validate-npm-package-license":"^3.0.4","yn":"^2.0.0"},"devDependencies":{"babel-core":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^6.2.5","babel-plugin-array-includes":"^2.0.3","babel-plugin-inline-import":"^3.0.0","babel-plugin-transform-builtin-extend":"^1.1.2","babel-plugin-transform-inline-imports-commonjs":"^1.0.0","babel-plugin-transform-runtime":"^6.4.3","babel-preset-env":"^1.6.0","babel-preset-flow":"^6.23.0","babel-preset-stage-0":"^6.0.0","babylon":"^6.5.0","commitizen":"^2.9.6","cz-conventional-changelog":"^2.0.0","eslint":"^4.3.0","eslint-config-fb-strict":"^22.0.0","eslint-plugin-babel":"^5.0.0","eslint-plugin-flowtype":"^2.35.0","eslint-plugin-jasmine":"^2.6.2","eslint-plugin-jest":"^21.0.0","eslint-plugin-jsx-a11y":"^6.0.2","eslint-plugin-prefer-object-spread":"^1.2.1","eslint-plugin-prettier":"^2.1.2","eslint-plugin-react":"^7.1.0","eslint-plugin-relay":"^0.0.28","eslint-plugin-yarn-internal":"file:scripts/eslint-rules","execa":"^0.11.0","fancy-log":"^1.3.2","flow-bin":"^0.66.0","git-release-notes":"^3.0.0","gulp":"^4.0.0","gulp-babel":"^7.0.0","gulp-if":"^2.0.1","gulp-newer":"^1.0.0","gulp-plumber":"^1.0.1","gulp-sourcemaps":"^2.2.0","jest":"^22.4.4","jsinspect":"^0.12.6","minimatch":"^3.0.4","mock-stdin":"^0.3.0","prettier":"^1.5.2","string-replace-loader":"^2.1.1","temp":"^0.8.3","webpack":"^2.1.0-beta.25","yargs":"^6.3.0"},"resolutions":{"sshpk":"^1.14.2"},"engines":{"node":">=4.0.0"},"repository":"yarnpkg/yarn","bin":{"yarn":"./bin/yarn.js","yarnpkg":"./bin/yarn.js"},"scripts":{"build":"gulp build","build-bundle":"node ./scripts/build-webpack.js","build-chocolatey":"powershell ./scripts/build-chocolatey.ps1","build-deb":"./scripts/build-deb.sh","build-dist":"bash ./scripts/build-dist.sh","build-win-installer":"scripts\\build-windows-installer.bat","changelog":"git-release-notes $(git describe --tags --abbrev=0 $(git describe --tags --abbrev=0)^)..$(git describe --tags --abbrev=0) scripts/changelog.md","dupe-check":"yarn jsinspect ./src","lint":"eslint . && flow check","pkg-tests":"yarn --cwd packages/pkg-tests jest yarn.test.js","prettier":"eslint src __tests__ --fix","release-branch":"./scripts/release-branch.sh","test":"yarn lint && yarn test-only","test-only":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --verbose","test-only-debug":"node --inspect-brk --max_old_space_size=4096 node_modules/jest/bin/jest.js --runInBand --verbose","test-coverage":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --coverage --verbose","watch":"gulp watch","commit":"git-cz"},"jest":{"collectCoverageFrom":["src/**/*.js"],"testEnvironment":"node","modulePathIgnorePatterns":["__tests__/fixtures/","packages/pkg-tests/pkg-tests-fixtures","dist/"],"testPathIgnorePatterns":["__tests__/(fixtures|__mocks__)/","updates/","_(temp|mock|install|init|helpers).js$","packages/pkg-tests"]},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}}}
/***/ }),
/* 195 */
@ -69876,12 +69888,12 @@ function getRcConfigForFolder(cwd) {
}
function loadRcFile(fileText, filePath) {
var _parse = (0, (_lockfile || _load_lockfile()).parse)(fileText, 'yarnrc');
var _parse = (0, (_lockfile || _load_lockfile()).parse)(fileText, filePath);
let values = _parse.object;
if (filePath.match(/\.yml$/)) {
if (filePath.match(/\.yml$/) && typeof values.yarnPath === 'string') {
values = { 'yarn-path': values.yarnPath };
}
@ -74848,7 +74860,20 @@ let run = exports.run = (() => {
} else {
let suggestion;
for (const commandName in scripts) {
for (var _iterator9 = scripts.keys(), _isArray9 = Array.isArray(_iterator9), _i9 = 0, _iterator9 = _isArray9 ? _iterator9 : _iterator9[Symbol.iterator]();;) {
var _ref16;
if (_isArray9) {
if (_i9 >= _iterator9.length) break;
_ref16 = _iterator9[_i9++];
} else {
_i9 = _iterator9.next();
if (_i9.done) break;
_ref16 = _i9.value;
}
const commandName = _ref16;
const steps = leven(commandName, action);
if (steps < 2) {
suggestion = commandName;
@ -74933,19 +74958,19 @@ let run = exports.run = (() => {
const printedCommands = new Map();
for (var _iterator9 = pkgCommands, _isArray9 = Array.isArray(_iterator9), _i9 = 0, _iterator9 = _isArray9 ? _iterator9 : _iterator9[Symbol.iterator]();;) {
var _ref16;
for (var _iterator10 = pkgCommands, _isArray10 = Array.isArray(_iterator10), _i10 = 0, _iterator10 = _isArray10 ? _iterator10 : _iterator10[Symbol.iterator]();;) {
var _ref17;
if (_isArray9) {
if (_i9 >= _iterator9.length) break;
_ref16 = _iterator9[_i9++];
if (_isArray10) {
if (_i10 >= _iterator10.length) break;
_ref17 = _iterator10[_i10++];
} else {
_i9 = _iterator9.next();
if (_i9.done) break;
_ref16 = _i9.value;
_i10 = _iterator10.next();
if (_i10.done) break;
_ref17 = _i10.value;
}
const pkgCommand = _ref16;
const pkgCommand = _ref17;
const action = scripts.get(pkgCommand);
invariant(action, 'Action must exists');
@ -76076,6 +76101,11 @@ class TarballFetcher extends (_baseFetcher || _load_baseFetcher()).default {
chown: false, // don't chown. just leave as it is
map: header => {
header.mtime = now;
if (header.linkname) {
const basePath = path.posix.dirname(path.join('/', header.name));
const jailPath = path.posix.join(basePath, header.linkname);
header.linkname = path.posix.relative('/', jailPath);
}
return header;
},
fs: patchedFs
@ -78409,6 +78439,11 @@ class RequestManager {
rejectNext(err);
};
const rejectWithoutUrl = function rejectWithoutUrl(err) {
err.message = err.message;
rejectNext(err);
};
const queueForRetry = reason => {
const attempts = params.retryAttempts || 0;
if (attempts >= this.maxRetryAttempts - 1) {
@ -78464,6 +78499,11 @@ class RequestManager {
}
}
if (res.statusCode === 401 && res.caseless && res.caseless.get('server') === 'GitHub.com') {
const message = `${res.body.message}. If using GITHUB_TOKEN in your env, check that it is valid.`;
rejectWithoutUrl(new Error(this.reporter.lang('unauthorizedResponse', res.caseless.get('server'), message)));
}
if (res.statusCode === 401 && res.headers['www-authenticate']) {
const authMethods = res.headers['www-authenticate'].split(/,\s*/).map(s => s.toLowerCase());
@ -96966,12 +97006,14 @@ function _load_asyncToGenerator() {
let run = exports.run = (() => {
var _ref = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (config, reporter, flags, args) {
if (flags.install) {
const installVersion = flags[`2`] ? `berry` : flags.install;
if (installVersion) {
const lockfilePath = path.resolve(config.cwd, 'yarn.lock');
if (!(yield (_fs || _load_fs()).exists(lockfilePath))) {
yield (_fs || _load_fs()).writeFile(lockfilePath, '');
}
yield (_child || _load_child()).spawn((_constants || _load_constants()).NODE_BIN_PATH, [process.argv[1], 'policies', 'set-version', flags.install], {
yield (_child || _load_child()).spawn((_constants || _load_constants()).NODE_BIN_PATH, [process.argv[1], 'policies', 'set-version', installVersion], {
stdio: 'inherit',
cwd: config.cwd
});
@ -97266,6 +97308,7 @@ function setFlags(commander) {
commander.option('-y, --yes', 'use default options');
commander.option('-p, --private', 'use default options and private true');
commander.option('-i, --install <value>', 'install a specific Yarn release');
commander.option('-2', 'generates the project using Yarn 2');
}
function hasWrapper(commander, args) {
@ -98254,6 +98297,7 @@ var _buildSubCommands = (0, (_buildSubCommands2 || _load_buildSubCommands()).def
let bundleUrl;
let bundleVersion;
let isV2 = false;
if (range === 'nightly' || range === 'nightlies') {
bundleUrl = 'https://nightly.yarnpkg.com/latest.js';
@ -98261,10 +98305,18 @@ var _buildSubCommands = (0, (_buildSubCommands2 || _load_buildSubCommands()).def
} else if (range === 'berry' || range === 'v2' || range === '2') {
bundleUrl = 'https://github.com/yarnpkg/berry/raw/master/packages/berry-cli/bin/berry.js';
bundleVersion = 'berry';
isV2 = true;
} else {
const releases = yield fetchReleases(config, {
includePrereleases: allowRc
});
let releases = [];
try {
releases = yield fetchReleases(config, {
includePrereleases: allowRc
});
} catch (e) {
reporter.error(e.message);
return;
}
const release = releases.find(function (release) {
// $FlowFixMe
@ -98285,7 +98337,6 @@ var _buildSubCommands = (0, (_buildSubCommands2 || _load_buildSubCommands()).def
reporter.log(`Downloading ${chalk.green(bundleUrl)}...`);
const bundle = yield fetchBundle(config, bundleUrl);
const rc = (0, (_rc || _load_rc()).getRcConfigForFolder)(config.lockfileFolder);
const yarnPath = path.resolve(config.lockfileFolder, `.yarn/releases/yarn-${bundleVersion}.js`);
reporter.log(`Saving it into ${chalk.magenta(yarnPath)}...`);
@ -98293,10 +98344,22 @@ var _buildSubCommands = (0, (_buildSubCommands2 || _load_buildSubCommands()).def
yield (_fs || _load_fs()).writeFile(yarnPath, bundle);
yield (_fs || _load_fs()).chmod(yarnPath, 0o755);
const rcPath = `${config.lockfileFolder}/.yarnrc`;
reporter.log(`Updating ${chalk.magenta(rcPath)}...`);
rc['yarn-path'] = path.relative(config.lockfileFolder, yarnPath);
yield (_fs || _load_fs()).writeFilePreservingEol(rcPath, `${(0, (_lockfile || _load_lockfile()).stringify)(rc)}\n`);
const targetPath = path.relative(config.lockfileFolder, yarnPath).replace(/\\/g, '/');
if (isV2) {
const rcPath = `${config.lockfileFolder}/.yarnrc.yml`;
reporter.log(`Updating ${chalk.magenta(rcPath)}...`);
yield (_fs || _load_fs()).writeFilePreservingEol(rcPath, `yarnPath: ${JSON.stringify(targetPath)}\n`);
} else {
const rcPath = `${config.lockfileFolder}/.yarnrc`;
reporter.log(`Updating ${chalk.magenta(rcPath)}...`);
const rc = (0, (_rc || _load_rc()).getRcConfigForFolder)(config.lockfileFolder);
rc['yarn-path'] = targetPath;
yield (_fs || _load_fs()).writeFilePreservingEol(rcPath, `${(0, (_lockfile || _load_lockfile()).stringify)(rc)}\n`);
}
reporter.log(`Done!`);
})();
@ -99619,11 +99682,11 @@ let run = exports.run = (() => {
throw new (_errors || _load_errors()).MessageError(reporter.lang('workspaceRootNotFound', config.cwd));
}
if (flags.originalArgs < 1) {
if (args.length < 1) {
throw new (_errors || _load_errors()).MessageError(reporter.lang('workspaceMissingWorkspace'));
}
if (flags.originalArgs < 2) {
if (args.length < 2) {
throw new (_errors || _load_errors()).MessageError(reporter.lang('workspaceMissingCommand'));
}
@ -99632,7 +99695,7 @@ let run = exports.run = (() => {
const workspaces = yield config.resolveWorkspaces(workspaceRootFolder, manifest);
var _ref2 = flags.originalArgs || [];
var _ref2 = args || [];
const workspaceName = _ref2[0],
rest = _ref2.slice(1);
@ -99818,28 +99881,23 @@ let runScript = exports.runScript = (() => {
const workspaces = yield config.resolveWorkspaces(workspaceRootFolder, manifest);
try {
var _ref6 = flags.originalArgs || [];
const _ = _ref6[0],
rest = _ref6.slice(1);
for (var _iterator4 = Object.keys(workspaces), _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
var _ref7;
var _ref6;
if (_isArray4) {
if (_i4 >= _iterator4.length) break;
_ref7 = _iterator4[_i4++];
_ref6 = _iterator4[_i4++];
} else {
_i4 = _iterator4.next();
if (_i4.done) break;
_ref7 = _i4.value;
_ref6 = _i4.value;
}
const workspaceName = _ref7;
const workspaceName = _ref6;
const loc = workspaces[workspaceName].loc;
reporter.log(`${os.EOL}> ${workspaceName}`);
yield (_child || _load_child()).spawn((_constants2 || _load_constants2()).NODE_BIN_PATH, [(_constants2 || _load_constants2()).YARN_BIN_PATH, ...rest], {
yield (_child || _load_child()).spawn((_constants2 || _load_constants2()).NODE_BIN_PATH, [(_constants2 || _load_constants2()).YARN_BIN_PATH, 'run', ...args], {
stdio: 'inherit',
cwd: loc
});
@ -100059,7 +100117,11 @@ let main = exports.main = (() => {
commandName = 'install';
isKnownCommand = true;
}
if (commandName === 'set' && args[0] === 'version') {
commandName = 'policies';
args.splice(0, 1, 'set-version');
isKnownCommand = true;
}
if (!isKnownCommand) {
// if command is not recognized, then set default to `run`
args.unshift(commandName);
@ -100070,15 +100132,20 @@ let main = exports.main = (() => {
let warnAboutRunDashDash = false;
// we are using "yarn <script> -abc", "yarn run <script> -abc", or "yarn node -abc", we want -abc
// to be script options, not yarn options
const PROXY_COMMANDS = new Set([`run`, `create`, `node`]);
if (PROXY_COMMANDS.has(commandName)) {
// PROXY_COMMANDS is a map of command name to the number of preservedArgs
const PROXY_COMMANDS = {
run: 1, // yarn run {command}
create: 1, // yarn create {project}
node: 0, // yarn node
workspaces: 1, // yarn workspaces {command}
workspace: 2 // yarn workspace {package} {command}
};
if (PROXY_COMMANDS.hasOwnProperty(commandName)) {
if (endArgs.length === 0) {
let preservedArgs = 0;
// the "run" and "create" command take one argument that we want to parse as usual (the
// script/package name), hence the splice(1)
if (command === (_index3 || _load_index3()).default.run || command === (_index3 || _load_index3()).default.create) {
preservedArgs += 1;
}
// $FlowFixMe doesn't like that PROXY_COMMANDS doesn't have keys for all commands.
let preservedArgs = PROXY_COMMANDS[commandName];
// If the --into option immediately follows the command (or the script name in the "run/create"
// case), we parse them as regular options so that we can cd into them
if (args[preservedArgs] === `--into`) {
@ -100090,7 +100157,6 @@ let main = exports.main = (() => {
}
}
(_commander || _load_commander()).default.originalArgs = args;
args = [...preCommandArgs, ...args];
command.setFlags((_commander || _load_commander()).default);
@ -100532,6 +100598,11 @@ let start = (() => {
const opts = { stdio: 'inherit', env: Object.assign({}, process.env, { YARN_IGNORE_PATH: 1 }) };
let exitCode = 0;
process.on(`SIGINT`, function () {
// We don't want SIGINT to kill our process; we want it to kill the
// innermost process, whose end will cause our own to exit.
});
try {
if (yarnPath.endsWith(`.js`)) {
exitCode = yield (0, (_child || _load_child()).spawnp)(process.execPath, [yarnPath, ...argv], opts);
@ -104923,6 +104994,7 @@ const messages = {
errorExtractingTarball: 'Extracting tar content of $1 failed, the file appears to be corrupt: $0',
updateInstalling: 'Installing $0...',
hostedGitResolveError: 'Error connecting to repository. Please, check the url.',
unauthorizedResponse: 'Received a 401 from $0. $1',
unknownFetcherFor: 'Unknown fetcher for $0',
@ -106797,7 +106869,7 @@ const semver = __webpack_require__(22);
const path = __webpack_require__(0);
const url = __webpack_require__(24);
const VALID_BIN_KEYS = /^[a-z0-9_-]+$/i;
const VALID_BIN_KEYS = /^(?!\.{0,2}$)[a-z0-9._-]+$/i;
const LICENSE_RENAMES = {
'MIT/X11': 'MIT',
@ -107660,7 +107732,11 @@ function parseRcPaths(paths, parser) {
try {
return parser((0, (_fs || _load_fs()).readFileSync)(path).toString(), path);
} catch (error) {
return {};
if (error.code === 'ENOENT' || error.code === 'EISDIR') {
return {};
} else {
throw error;
}
}
}));
}

View File

@ -2,4 +2,4 @@
# yarn lockfile v1
yarn-path ".yarn/releases/yarn-1.21.1.js"
yarn-path ".yarn/releases/yarn-1.22.4.js"

View File

@ -1,3 +1,115 @@
<a name="10.0.0-next.2"></a>
# [10.0.0-next.2](https://github.com/angular/angular/compare/10.0.0-next.1...10.0.0-next.2) (2020-04-15)
### Bug Fixes
* **common:** `locales/global/*.js` are not ES5 compliant ([#36342](https://github.com/angular/angular/issues/36342)) ([078b0be](https://github.com/angular/angular/commit/078b0be)), closes [angular/angular-cli#16394](https://github.com/angular/angular-cli/issues/16394)
* **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)
* **core:** undecorated-classes-with-decorated-fields migration should avoid error if base class has no value declaration ([#36543](https://github.com/angular/angular/issues/36543)) ([ca67748](https://github.com/angular/angular/commit/ca67748)), closes [#36522](https://github.com/angular/angular/issues/36522)
* **ngcc:** correctly detect external files from nested `node_modules/` ([#36559](https://github.com/angular/angular/issues/36559)) ([6ab43d7](https://github.com/angular/angular/commit/6ab43d7)), closes [#36526](https://github.com/angular/angular/issues/36526)
* **ngcc:** display output from the unlocker process on Windows ([#36569](https://github.com/angular/angular/issues/36569)) ([e041ac6](https://github.com/angular/angular/commit/e041ac6))
* **ngcc:** do not spawn unlocker processes on cluster workers ([#36569](https://github.com/angular/angular/issues/36569)) ([66effde](https://github.com/angular/angular/commit/66effde)), closes [#35861](https://github.com/angular/angular/issues/35861)
* **ngcc:** do not warn if `paths` mapping does not exist ([#36525](https://github.com/angular/angular/issues/36525)) ([717df13](https://github.com/angular/angular/commit/717df13)), closes [#36518](https://github.com/angular/angular/issues/36518)
* **ngcc:** force ngcc to exit on error ([#36622](https://github.com/angular/angular/issues/36622)) ([663b768](https://github.com/angular/angular/commit/663b768)), closes [#36616](https://github.com/angular/angular/issues/36616)
* **router:** pass correct component to canDeactivate checks when using two or more sibling router-outlets ([#36302](https://github.com/angular/angular/issues/36302)) ([80e6c07](https://github.com/angular/angular/commit/80e6c07)), closes [#34614](https://github.com/angular/angular/issues/34614)
* **upgrade:** update $locationShim to handle Location changes before initialization ([#36498](https://github.com/angular/angular/issues/36498)) ([0cc53fb](https://github.com/angular/angular/commit/0cc53fb)), 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)) ([3bedfda](https://github.com/angular/angular/commit/3bedfda))
* **ngcc:** read dependencies from entry-point manifest ([#36486](https://github.com/angular/angular/issues/36486)) ([a185efb](https://github.com/angular/angular/commit/a185efb)), closes [#issuecomment-608401834](https://github.com/angular/angular/issues/issuecomment-608401834)
* **ngcc:** reduce the size of the entry-point manifest file ([#36486](https://github.com/angular/angular/issues/36486)) ([ec0ce60](https://github.com/angular/angular/commit/ec0ce60))
<a name="9.1.2"></a>
## [9.1.2](https://github.com/angular/angular/compare/9.1.1...9.1.2) (2020-04-15)
### Bug Fixes
* **compiler:** handle type references to namespaced symbols correctly ([#36106](https://github.com/angular/angular/issues/36106)) ([468cf69](https://github.com/angular/angular/commit/468cf69)), closes [#36006](https://github.com/angular/angular/issues/36006)
* **core:** undecorated-classes-with-decorated-fields migration should avoid error if base class has no value declaration ([#36543](https://github.com/angular/angular/issues/36543)) ([3992341](https://github.com/angular/angular/commit/3992341)), closes [#36522](https://github.com/angular/angular/issues/36522)
* **ngcc:** correctly detect external files from nested `node_modules/` ([#36559](https://github.com/angular/angular/issues/36559)) ([8c559ef](https://github.com/angular/angular/commit/8c559ef)), closes [#36526](https://github.com/angular/angular/issues/36526)
* **ngcc:** display output from the unlocker process on Windows ([#36569](https://github.com/angular/angular/issues/36569)) ([12266b2](https://github.com/angular/angular/commit/12266b2))
* **ngcc:** do not spawn unlocker processes on cluster workers ([#36569](https://github.com/angular/angular/issues/36569)) ([e385abc](https://github.com/angular/angular/commit/e385abc)), closes [#35861](https://github.com/angular/angular/issues/35861)
* **ngcc:** do not warn if `paths` mapping does not exist ([#36525](https://github.com/angular/angular/issues/36525)) ([33eee43](https://github.com/angular/angular/commit/33eee43)), closes [#36518](https://github.com/angular/angular/issues/36518)
* **ngcc:** force ngcc to exit on error ([#36622](https://github.com/angular/angular/issues/36622)) ([933cbfb](https://github.com/angular/angular/commit/933cbfb)), closes [#36616](https://github.com/angular/angular/issues/36616) * **router:** pass correct component to canDeactivate checks when using two or more sibling router-outlets ([#36302](https://github.com/angular/angular/issues/36302)) ([8e7f903](https://github.com/angular/angular/commit/8e7f903)), closes [#34614](https://github.com/angular/angular/issues/34614) * **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:** 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))
<a name="10.0.0-next.1"></a>
# [10.0.0-next.1](https://github.com/angular/angular/compare/10.0.0-next.0...10.0.0-next.1) (2020-04-08)
This release contains various API docs improvements.
<a name="10.0.0-next.0"></a>
# [10.0.0-next.0](https://github.com/angular/angular/compare/9.1.0-rc.0...10.0.0-next.0) (2020-04-08)
### Bug Fixes
* **common:** let `KeyValuePipe` accept type unions with `null` ([#36093](https://github.com/angular/angular/issues/36093)) ([d783519](https://github.com/angular/angular/commit/d783519)), closes [#35743](https://github.com/angular/angular/issues/35743)
* **compiler:** avoid undefined expressions in holey array ([#36343](https://github.com/angular/angular/issues/36343)) ([5516802](https://github.com/angular/angular/commit/5516802))
* **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:** 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-cli:** pass real source spans where they are empty ([#31805](https://github.com/angular/angular/issues/31805)) ([e893c5a](https://github.com/angular/angular/commit/e893c5a))
* **core:** avoid migration error when non-existent symbol is imported ([#36367](https://github.com/angular/angular/issues/36367)) ([d43c306](https://github.com/angular/angular/commit/d43c306)), closes [#36346](https://github.com/angular/angular/issues/36346)
* **core:** ngOnDestroy on multi providers called with incorrect context ([#35840](https://github.com/angular/angular/issues/35840)) ([95fc3d4](https://github.com/angular/angular/commit/95fc3d4)), closes [#35231](https://github.com/angular/angular/issues/35231)
* **core:** run `APP_INITIALIZER`s before accessing `LOCALE_ID` token in Ivy TestBed ([#36237](https://github.com/angular/angular/issues/36237)) ([1649743](https://github.com/angular/angular/commit/1649743)), closes [#36230](https://github.com/angular/angular/issues/36230)
* **core:** undecorated-classes-with-decorated-fields migration does not decorate derived classes ([#35339](https://github.com/angular/angular/issues/35339)) ([32eafef](https://github.com/angular/angular/commit/32eafef)), closes [#34376](https://github.com/angular/angular/issues/34376)
* **core:** workaround Terser inlining bug ([#36200](https://github.com/angular/angular/issues/36200)) ([0ce8ad3](https://github.com/angular/angular/commit/0ce8ad3))
* **elements:** correctly handle setting inputs to `undefined` ([#36140](https://github.com/angular/angular/issues/36140)) ([9ba46d9](https://github.com/angular/angular/commit/9ba46d9))
* **elements:** correctly set `SimpleChange#firstChange` for pre-existing inputs ([#36140](https://github.com/angular/angular/issues/36140)) ([b14ac96](https://github.com/angular/angular/commit/b14ac96)), closes [#36130](https://github.com/angular/angular/issues/36130)
* **language-service:** infer type of elements of array-like objects ([#36312](https://github.com/angular/angular/issues/36312)) ([fe2b692](https://github.com/angular/angular/commit/fe2b692)), 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)) ([81195a2](https://github.com/angular/angular/commit/81195a2))
* **localize:** allow ICU expansion case to start with any character except `}` ([#36123](https://github.com/angular/angular/issues/36123)) ([fced8ee](https://github.com/angular/angular/commit/fced8ee)), closes [#31586](https://github.com/angular/angular/issues/31586)
* **ngcc:** add process title ([#36448](https://github.com/angular/angular/issues/36448)) ([76a8cd5](https://github.com/angular/angular/commit/76a8cd5)), closes [/github.com/angular/angular/issues/36414#issuecomment-609644282](https://github.com//github.com/angular/angular/issues/36414/issues/issuecomment-609644282)
* **ngcc:** allow ngcc configuration to match pre-release versions of packages ([#36370](https://github.com/angular/angular/issues/36370)) ([326240e](https://github.com/angular/angular/commit/326240e))
* **ngcc:** correctly detect imported TypeScript helpers ([#36284](https://github.com/angular/angular/issues/36284)) ([ca25c95](https://github.com/angular/angular/commit/ca25c95)), 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)) ([aecf9de](https://github.com/angular/angular/commit/aecf9de))
* **ngcc:** correctly identify the package path of secondary entry-points ([#36249](https://github.com/angular/angular/issues/36249)) ([995cd15](https://github.com/angular/angular/commit/995cd15)), closes [#35747](https://github.com/angular/angular/issues/35747)
* **ngcc:** detect non-emitted, non-imported TypeScript helpers ([#36418](https://github.com/angular/angular/issues/36418)) ([5fa7b8b](https://github.com/angular/angular/commit/5fa7b8b))
* **ngcc:** do not spawn more processes than intended in parallel mode ([#36280](https://github.com/angular/angular/issues/36280)) ([5cee709](https://github.com/angular/angular/commit/5cee709)), closes [#35719](https://github.com/angular/angular/issues/35719) [#36278](https://github.com/angular/angular/issues/36278) [/github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/main.ts#L429](https://github.com//github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/main.ts/issues/L429) [/github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts#L108](https://github.com//github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts/issues/L108) [/github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts#L110](https://github.com//github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts/issues/L110) [/github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts#L199](https://github.com//github.com/angular/angular/blob/b8e9a30d3b6/packages/compiler-cli/ngcc/src/execution/cluster/master.ts/issues/L199)
* **ngcc:** do not write entry-point manifest outside node_modules ([#36299](https://github.com/angular/angular/issues/36299)) ([c6dd900](https://github.com/angular/angular/commit/c6dd900)), closes [#36296](https://github.com/angular/angular/issues/36296)
* **ngcc:** don't crash on cyclic source-map references ([#36452](https://github.com/angular/angular/issues/36452)) ([ee70a18](https://github.com/angular/angular/commit/ee70a18)), closes [#35727](https://github.com/angular/angular/issues/35727) [#35757](https://github.com/angular/angular/issues/35757)
* **ngcc:** handle bad path mappings when finding entry-points ([#36331](https://github.com/angular/angular/issues/36331)) ([cc4b813](https://github.com/angular/angular/commit/cc4b813)), closes [#36313](https://github.com/angular/angular/issues/36313) [#36283](https://github.com/angular/angular/issues/36283)
* **ngcc:** handle entry-points within container folders ([#36305](https://github.com/angular/angular/issues/36305)) ([38ad1d9](https://github.com/angular/angular/commit/38ad1d9)), closes [#35756](https://github.com/angular/angular/issues/35756) [#36216](https://github.com/angular/angular/issues/36216)
* **ngcc:** sniff `main` property for ESM5 format ([#36396](https://github.com/angular/angular/issues/36396)) ([2463548](https://github.com/angular/angular/commit/2463548)), closes [#35788](https://github.com/angular/angular/issues/35788)
* **ngcc:** support ignoring deep-imports via package config ([#36423](https://github.com/angular/angular/issues/36423)) ([f9fb833](https://github.com/angular/angular/commit/f9fb833)), closes [#35750](https://github.com/angular/angular/issues/35750)
* **ngcc:** support simple `browser` property in entry-points ([#36396](https://github.com/angular/angular/issues/36396)) ([6b3aa60](https://github.com/angular/angular/commit/6b3aa60)), closes [#36062](https://github.com/angular/angular/issues/36062)
* **ngcc:** use path-mappings from tsconfig in dependency resolution ([#36180](https://github.com/angular/angular/issues/36180)) ([380de1e](https://github.com/angular/angular/commit/380de1e)), closes [#36119](https://github.com/angular/angular/issues/36119)
* **ngcc:** use preserve whitespaces from tsconfig if provided ([#36189](https://github.com/angular/angular/issues/36189)) ([b8e9a30](https://github.com/angular/angular/commit/b8e9a30)), closes [#35871](https://github.com/angular/angular/issues/35871)
* **platform-server:** update `xhr2` dependency ([#36366](https://github.com/angular/angular/issues/36366)) ([b59bc0e](https://github.com/angular/angular/commit/b59bc0e)), closes [#36358](https://github.com/angular/angular/issues/36358)
* **router:** allow UrlMatcher to return null ([#36402](https://github.com/angular/angular/issues/36402)) ([568e9df](https://github.com/angular/angular/commit/568e9df)), closes [#29824](https://github.com/angular/angular/issues/29824)
* **router:** state data missing in routerLink ([#36462](https://github.com/angular/angular/issues/36462)) ([e0415db](https://github.com/angular/angular/commit/e0415db)), closes [#33173](https://github.com/angular/angular/issues/33173)
* **service-worker:** by default register the SW after 30s even the app never stabilizes ([#35870](https://github.com/angular/angular/issues/35870)) ([29e8a64](https://github.com/angular/angular/commit/29e8a64)), closes [#34464](https://github.com/angular/angular/issues/34464)
* **service-worker:** prevent SW registration strategies from affecting app stabilization ([#35870](https://github.com/angular/angular/issues/35870)) ([2d7c95f](https://github.com/angular/angular/commit/2d7c95f))
### Features
* **compiler:** add dependency info and ng-content selectors to metadata ([#35695](https://github.com/angular/angular/issues/35695)) ([32ce8b1](https://github.com/angular/angular/commit/32ce8b1))
* **compiler:** Propagate value span of ExpressionBinding to ParsedProperty ([#36133](https://github.com/angular/angular/issues/36133)) ([d714b95](https://github.com/angular/angular/commit/d714b95))
* **core:** undecorated-classes migration should handle derived abstract classes ([#35339](https://github.com/angular/angular/issues/35339)) ([c24ad56](https://github.com/angular/angular/commit/c24ad56))
* **service-worker:** support timeout in `registerWhenStable` SW registration strategy ([#35870](https://github.com/angular/angular/issues/35870)) ([00efacf](https://github.com/angular/angular/commit/00efacf)), closes [#34464](https://github.com/angular/angular/issues/34464)
### BREAKING CHANGES
* **router:** UrlMatcher's type now reflects that it could always return
null.
If you implemented your own Router or Recognizer class, please update it to
handle matcher returning null.
<a name="9.1.1"></a>
## [9.1.1](https://github.com/angular/angular/compare/9.1.0...9.1.1) (2020-04-07)
@ -32,7 +144,6 @@
* **router:** state data missing in routerLink ([#36462](https://github.com/angular/angular/issues/36462)) ([0e7a89a](https://github.com/angular/angular/commit/0e7a89a)), closes [#33173](https://github.com/angular/angular/issues/33173)
<a name="9.1.0"></a>
# [9.1.0](https://github.com/angular/angular/compare/9.0.0...9.1.0) (2020-03-25)

View File

@ -8,8 +8,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# Fetch rules_nodejs so we can install our npm dependencies
http_archive(
name = "build_bazel_rules_nodejs",
sha256 = "d0c4bb8b902c1658f42eb5563809c70a06e46015d64057d25560b0eb4bdc9007",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/1.5.0/rules_nodejs-1.5.0.tar.gz"],
sha256 = "f9e7b9f42ae202cc2d2ce6d698ccb49a9f7f7ea572a78fd451696d03ef2ee116",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/1.6.0/rules_nodejs-1.6.0.tar.gz"],
)
# Check the rules_nodejs version and download npm dependencies
@ -17,7 +17,7 @@ http_archive(
# assert on that.
load("@build_bazel_rules_nodejs//:index.bzl", "check_rules_nodejs_version", "node_repositories", "yarn_install")
check_rules_nodejs_version(minimum_version_string = "1.5.0")
check_rules_nodejs_version(minimum_version_string = "1.6.0")
# Setup the Node.js toolchain
node_repositories(

View File

@ -99,7 +99,7 @@ Project-specific [TypeScript](https://www.typescriptlang.org/) configuration fil
| APPLICATION-SPECIFIC CONFIG FILES | PURPOSE |
| :--------------------- | :------------------------------------------|
| `browserslist` | Configures sharing of target browsers and Node.js versions among various front-end tools. See [Browserslist on GitHub](https://github.com/browserslist/browserslist) for more information. |
| `.browserslistrc` | Configures sharing of target browsers and Node.js versions among various front-end tools. See [Browserslist on GitHub](https://github.com/browserslist/browserslist) for more information. |
| `karma.conf.js` | Application-specific [Karma](https://karma-runner.github.io/2.0/config/configuration-file.html) configuration. |
| `tsconfig.app.json` | Application-specific [TypeScript](https://www.typescriptlang.org/) configuration, including TypeScript and Angular template compiler options. See [TypeScript Configuration](guide/typescript-configuration) and [Angular Compiler Options](guide/angular-compiler-options). |
| `tsconfig.spec.json` | [TypeScript](https://www.typescriptlang.org/) configuration for the application tests. See [TypeScript Configuration](guide/typescript-configuration). |

View File

@ -101,7 +101,8 @@ The following table provides the status for Angular versions under support.
Version | Status | Released | Active Ends | LTS Ends
------- | ------ | ------------ | ------------ | ------------
^8.0.0 | Active | May 28, 2019 | Nov 28, 2019 | Nov 28, 2020
^9.0.0 | Active | Feb 06, 2020 | Aug 06, 2020 | Aug 06, 2021
^8.0.0 | LTS | May 28, 2019 | Nov 28, 2019 | Nov 28, 2020
^7.0.0 | LTS | Oct 18, 2018 | Apr 18, 2019 | Apr 18, 2020
Angular versions ^4.0.0, ^5.0.0 and ^6.0.0 are no longer under support.

View File

@ -18,11 +18,19 @@ If you are new to Angular, see [Getting Started](start). Getting Started helps y
{@a prerequisites}
## Prerequisites
Before you begin, make sure your development environment includes `Node.js®` and an npm package manager.
To use the Angular framework, you should be familiar with the following:
* [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
* [HTML](https://developer.mozilla.org/docs/Learn/HTML/Introduction_to_HTML)
* [CSS](https://developer.mozilla.org/docs/Learn/CSS/First_steps)
Knowledge of [TypeScript](https://www.typescriptlang.org/) is helpful, but not required.
{@a nodejs}
### Node.js
Make sure your development environment includes `Node.js®` and an npm package manager.
Angular requires a [current, active LTS, or maintenance LTS](https://nodejs.org/about/releases/) version of `Node.js`. See the `engines` key for the specific version requirements in our [package.json](https://unpkg.com/@angular/cli/package.json).
* To check your version, run `node -v` in a terminal/console window.

View File

@ -1277,7 +1277,7 @@ In this example, we have a new macro task (nested setTimeout), by default, when
region="fake-async-test-tick-new-macro-task-async">
</code-example>
And in some case, we don't want to trigger the new macro task when ticking, we can use `tick(milliseconds, {processNewMacroTasksSynchronously: false})` to not invoke new maco task.
And in some case, we don't want to trigger the new macro task when ticking, we can use `tick(milliseconds, {processNewMacroTasksSynchronously: false})` to not invoke new macro task.
#### Comparing dates inside fakeAsync()

View File

@ -53,7 +53,7 @@ The initial `tsconfig.json` for an Angular app typically looks like the followin
]
},
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"strictTemplates": true,
"strictInjectionParameters": true
}
}
@ -62,7 +62,6 @@ The initial `tsconfig.json` for an Angular app typically looks like the followin
{@a noImplicitAny}
### *noImplicitAny* and *suppressImplicitAnyIndexErrors*
TypeScript developers disagree about whether the `noImplicitAny` flag should be `true` or `false`.
@ -96,6 +95,7 @@ For more information about how the TypeScript configuration affects compilation,
</div>
{@a typings}
## TypeScript typings
@ -146,7 +146,6 @@ For instance, to install typings for `jasmine` you run `npm install @types/jasmi
{@a target}
### *target*
By default, the target is `es2015`, which is supported only in modern browsers. You can configure the target to `es5` to specifically support legacy browsers. [Differential loading](guide/deployment#differential-loading) is also provided by the Angular CLI to support modern, and legacy browsers with separate bundles.

View File

@ -29,8 +29,8 @@ To clarify how changes are detected and values updated, consider the following c
```javascript
<html>
<div id="dataDiv"></div>
<button id="btn">updateData<btn>
<canvas id="canvas"><canvas>
<button id="btn">updateData</button>
<canvas id="canvas"></canvas>
<script>
let value = 'initialValue';
// initial rendering

View File

@ -13,12 +13,6 @@
</tr>
</thead>
<tbody>
<!-- ng-conf 2020 -->
<tr>
<th><a href="https://ng-conf.org/" title="ng-conf">ng-conf</a></th>
<td>Salt Lake City, Utah</td>
<td>April 1-3, 2020</td>
</tr>
<tr>
<th><a href="https://ngvikings.org/" title="ngVikings">ngVikings</a></th>
<td>Oslo, Norway</td>
@ -37,6 +31,12 @@
</tr>
</thead>
<tbody>
<!-- ng-conf 2020 -->
<tr>
<th><a href="https://ng-conf.org/" title="ng-conf">ng-conf</a></th>
<td>Salt Lake City, Utah</td>
<td>April 1-3, 2020</td>
</tr>
<!-- ngIndia 2020 -->
<tr>
<th><a href="https://www.ng-ind.com/" title="ngIndia">ngIndia</a></th>

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 526c3cc37",
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js 56c648827",
"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",
@ -83,7 +83,7 @@
"//engines-comment": "Keep this in sync with /package.json and /aio/tools/examples/shared/package.json",
"engines": {
"node": ">=10.9.0 <13.0.0",
"yarn": ">=1.21.1 <2"
"yarn": ">=1.22.4 <2"
},
"private": true,
"dependencies": {

View File

@ -7,13 +7,26 @@
justify-content: space-between;
max-width: 880px;
@media (max-width: 600px) {
flex-direction: column;
}
> :first-child {
margin-right: 2rem;
width: 60%;
@media (max-width: 600px) {
width: 100%;
}
}
&:last-child {
margin-bottom: 0;
}
.button {
@media (max-width: 600px) {
margin-top: 14px;
}
}
}
}

View File

@ -19,6 +19,14 @@ aio-contributor-list {
.group-buttons {
margin: 32px auto;
@media (max-width: 480px) {
.filter-button.button {
font-size: 1.2rem;
padding: 0;
margin: 0;
}
}
a {
&.selected {
background-color: $blue;

View File

@ -8,7 +8,8 @@
{ "name": "e2e", "command": "ng e2e" }
],
"dependencies": [
"@angular/elements"
"@angular/elements",
"@webcomponents/custom-elements"
],
"devDependencies": [
"@angular-devkit/build-angular",

View File

@ -30,7 +30,7 @@ const BOILERPLATE_PATHS = {
// This maps the CLI files that exists in a parent folder
const cliRelativePath = BOILERPLATE_PATHS.cli.map(file => `../cli/${file}`);
BOILERPLATE_PATHS.elements = [...cliRelativePath, 'package.json'];
BOILERPLATE_PATHS.elements = [...cliRelativePath, 'package.json', 'src/polyfills.ts'];
BOILERPLATE_PATHS.i18n = [...cliRelativePath, 'angular.json', 'package.json'];
@ -79,7 +79,7 @@ class ExampleBoilerPlate {
if (!fs.existsSync(SHARED_NODE_MODULES_PATH)) {
throw new Error(
`The shared node_modules folder for the examples (${SHARED_NODE_MODULES_PATH}) is missing.\n` +
`Perhaps you need to run "yarn example-use-npm" or "yarn example-use-local" to install the dependencies?`);
'Perhaps you need to run "yarn example-use-npm" or "yarn example-use-local" to install the dependencies?');
}
if (!viewengine) {

View File

@ -21,6 +21,7 @@
"@angular/platform-browser": "~9.0.6",
"@angular/platform-browser-dynamic": "~9.0.6",
"@angular/router": "~9.0.6",
"@webcomponents/custom-elements": "^1.4.1",
"angular-in-memory-web-api": "~0.9.0",
"rxjs": "~6.5.4",
"tslib": "^1.10.0",

View File

@ -0,0 +1,70 @@
/**
* This file includes polyfills needed by Angular and is loaded before the app.
* You can add your own extra polyfills to this file.
*
* This file is divided into 2 sections:
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
* file.
*
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
*
* Learn more in https://angular.io/guide/browser-support
*/
/***************************************************************************************************
* BROWSER POLYFILLS
*/
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
/**
* Web Animations `@angular/platform-browser/animations`
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
*/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
/**
* By default, zone.js will patch all possible macroTask and DomEvents
* user can disable parts of macroTask/DomEvents patch by setting following flags
* because those flags need to be set before `zone.js` being loaded, and webpack
* will put import in the top of bundle, so user need to create a separate file
* in this directory (for example: zone-flags.ts), and put the following flags
* into that file, and then add the following code before importing zone.js.
* import './zone-flags';
*
* The flags allowed in zone-flags.ts are listed here.
*
* The following flags will work for all browsers.
*
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch
* requestAnimationFrame
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch
* specified eventNames
*
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch for IE/Edge
*
* (window as any).__Zone_enable_cross_context_check = true;
*
*/
/***************************************************************************************************
* Zone JS is required by default for Angular itself.
*/
import 'zone.js/dist/zone'; // Included with Angular CLI.
/***************************************************************************************************
* APPLICATION IMPORTS
*/
// Custom Elements polyfill. Required for browsers that do not natively support Custom Elements.
import '@webcomponents/custom-elements';
// Custom Elements ES5 shim. Required when using ES5 bundles on browsers that natively support
// Custom Elements (either because the browser does not support ES2015 modules or because the app
// is explicitly configured to generate ES5 only bundles).
import '@webcomponents/custom-elements/src/native-shim';

View File

@ -34,6 +34,7 @@
"@nguniversal/common": "~9.0.1",
"@nguniversal/express-engine": "~9.0.1",
"@nguniversal/module-map-ngfactory-loader": "~9.0.0-next.9",
"@webcomponents/custom-elements": "^1.4.1",
"angular": "1.7.9",
"angular-in-memory-web-api": "~0.9.0",
"angular-route": "1.7.9",

View File

@ -1425,6 +1425,11 @@
"@webassemblyjs/wast-parser" "1.8.5"
"@xtuc/long" "4.2.2"
"@webcomponents/custom-elements@^1.4.1":
version "1.4.1"
resolved "https://registry.yarnpkg.com/@webcomponents/custom-elements/-/custom-elements-1.4.1.tgz#9803aaa2286a13a4ba200a7a2ea767871598eb60"
integrity sha512-vNCS1+3sxJOpoIsBjUQiXjGLngakEAGOD5Ale+6ikg6OZG5qI5O39frm3raPhud/IwnF4vec5ags05YBsgzcuA==
"@xtuc/ieee754@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"

View File

@ -37,7 +37,6 @@
],
"angularCompilerOptions": {
"disableTypeScriptVersionCheck": true,
"fullTemplateTypeCheck": true,
"strictInjectionParameters": true,
"strictTemplates": true
}

View File

@ -14,9 +14,29 @@ export function buildCommitMessageParser(localYargs: yargs.Argv) {
return localYargs.help()
.strict()
.command(
'pre-commit-validate', 'Validate the most recent commit message', {},
() => {
validateFile('.git/COMMIT_EDITMSG');
'pre-commit-validate', 'Validate the most recent commit message', {
'file': {
type: 'string',
conflicts: ['file-env-variable'],
description: 'The path of the commit message file.',
},
'file-env-variable': {
type: 'string',
conflicts: ['file'],
description:
'The key of the environment variable for the path of the commit message file.',
coerce: arg => {
const file = process.env[arg];
if (!file) {
throw new Error(`Provided environment variable "${arg}" was not found.`);
}
return file;
},
}
},
args => {
const file = args.file || args.fileEnvVariable || '.git/COMMIT_EDITMSG';
validateFile(file);
})
.command(
'validate-range', 'Validate a range of commit messages', {

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {readFileSync} from 'fs';
import {join} from 'path';
import {resolve} from 'path';
import {getRepoBaseDir} from '../utils/config';
@ -14,7 +14,7 @@ import {validateCommitMessage} from './validate';
/** Validate commit message at the provided file path. */
export function validateFile(filePath: string) {
const commitMessage = readFileSync(join(getRepoBaseDir(), filePath), 'utf8');
const commitMessage = readFileSync(resolve(getRepoBaseDir(), filePath), 'utf8');
if (validateCommitMessage(commitMessage)) {
console.info('√ Valid commit message');
return;

View File

@ -13,7 +13,7 @@ import * as ts from 'typescript';
import {getFileStatus} from './file_system';
import {getModuleReferences} from './parser';
export type ModuleResolver = (specifier: string) => string | null;
export type ModuleResolver = (specifier: string) => string|null;
/**
* Reference chains describe a sequence of source files which are connected through imports.
@ -69,7 +69,7 @@ export class Analyzer {
getSourceFile(filePath: string): ts.SourceFile {
const resolvedPath = resolve(filePath);
if (this._sourceFileCache.has(resolvedPath)) {
return this._sourceFileCache.get(resolvedPath) !;
return this._sourceFileCache.get(resolvedPath)!;
}
const fileContent = readFileSync(resolvedPath, 'utf8');
const sourceFile =
@ -105,7 +105,7 @@ export class Analyzer {
if (!this.unresolvedFiles.has(originFilePath)) {
this.unresolvedFiles.set(originFilePath, [specifier]);
}
this.unresolvedFiles.get(originFilePath) !.push(specifier);
this.unresolvedFiles.get(originFilePath)!.push(specifier);
}
/** Resolves the given import specifier to the corresponding source file. */

View File

@ -20,8 +20,17 @@ export type Golden = CircularDependency[];
* the source file objects are mapped to their relative file names.
*/
export function convertReferenceChainToGolden(refs: ReferenceChain[], baseDir: string): Golden {
return refs.map(
chain => chain.map(({fileName}) => convertPathToForwardSlash(relative(baseDir, fileName))));
return refs
.map(
// Normalize cycles as the paths can vary based on which node in the cycle is visited
// first in the analyzer. The paths represent cycles. Hence we can shift nodes in a
// deterministic way so that the goldens don't change unnecessarily and cycle comparison
// is simpler.
chain => normalizeCircularDependency(
chain.map(({fileName}) => convertPathToForwardSlash(relative(baseDir, fileName)))))
// Sort cycles so that the golden doesn't change unnecessarily when cycles are detected
// in different order (e.g. new imports cause cycles to be detected earlier or later).
.sort(compareCircularDependency);
}
/**
@ -44,6 +53,53 @@ export function compareGoldens(actual: Golden, expected: Golden) {
return {newCircularDeps, fixedCircularDeps};
}
/**
* Normalizes the a circular dependency by ensuring that the path starts with the first
* node in alphabetical order. Since the path array represents a cycle, we can make a
* specific node the first element in the path that represents the cycle.
*
* This method is helpful because the path of circular dependencies changes based on which
* file in the path has been visited first by the analyzer. e.g. Assume we have a circular
* dependency represented as: `A -> B -> C`. The analyzer will detect this cycle when it
* visits `A`. Though when a source file that is analyzed before `A` starts importing `B`,
* the cycle path will detected as `B -> C -> A`. This represents the same cycle, but is just
* different due to a limitation of using a data structure that can be written to a text-based
* golden file.
*
* To account for this non-deterministic behavior in goldens, we shift the circular
* dependency path to the first node based on alphabetical order. e.g. `A` will always
* be the first node in the path that represents the cycle.
*/
function normalizeCircularDependency(path: CircularDependency): CircularDependency {
if (path.length <= 1) {
return path;
}
let indexFirstNode: number = 0;
let valueFirstNode: string = path[0];
// Find a node in the cycle path that precedes all other elements
// in terms of alphabetical order.
for (let i = 1; i < path.length; i++) {
const value = path[i];
if (value.localeCompare(valueFirstNode, 'en') < 0) {
indexFirstNode = i;
valueFirstNode = value;
}
}
// If the alphabetically first node is already at start of the path, just
// return the actual path as no changes need to be made.
if (indexFirstNode === 0) {
return path;
}
// Move the determined first node (as of alphabetical order) to the start of a new
// path array. The nodes before the first node in the old path are then concatenated
// to the end of the new path. This is possible because the path represents a cycle.
return [...path.slice(indexFirstNode), ...path.slice(0, indexFirstNode)];
}
/** Checks whether the specified circular dependencies are equal. */
function isSameCircularDependency(actual: CircularDependency, expected: CircularDependency) {
if (actual.length !== expected.length) {
@ -56,3 +112,20 @@ function isSameCircularDependency(actual: CircularDependency, expected: Circular
}
return true;
}
/**
* Compares two circular dependencies by respecting the alphabetic order of nodes in the
* cycle paths. The first nodes which don't match in both paths are decisive on the order.
*/
function compareCircularDependency(a: CircularDependency, b: CircularDependency): number {
// Go through nodes in both cycle paths and determine whether `a` should be ordered
// before `b`. The first nodes which don't match decide on the order.
for (let i = 0; i < Math.min(a.length, b.length); i++) {
const compareValue = a[i].localeCompare(b[i], 'en');
if (compareValue !== 0) {
return compareValue;
}
}
// If all nodes are equal in the cycles, the order is based on the length of both cycles.
return a.length - b.length;
}

View File

@ -44,4 +44,6 @@ export function getAngularDevConfig<K, T>(): DevInfraConfig<K, T> {
* Interface exressing the expected structure of the DevInfraConfig.
* Allows for providing a typing for a part of the config to read.
*/
export interface DevInfraConfig<K, T> { [K: string]: T; }
export interface DevInfraConfig<K, T> {
[K: string]: T;
}

File diff suppressed because it is too large Load Diff

View File

@ -1064,7 +1064,7 @@ export declare function ɵɵstyleSanitizer(sanitizer: StyleSanitizeFn | null): v
export declare function ɵɵtemplate(index: number, templateFn: ComponentTemplate<any> | null, decls: number, vars: number, tagName?: string | null, attrsIndex?: number | null, localRefsIndex?: number | null, localRefExtractor?: LocalRefExtractor): void;
export declare function ɵɵtemplateRefExtractor(tNode: TNode, currentView: ɵangular_packages_core_core_bp): TemplateRef<unknown> | null;
export declare function ɵɵtemplateRefExtractor(tNode: TNode, currentView: ɵangular_packages_core_core_bo): TemplateRef<unknown> | null;
export declare function ɵɵtext(index: number, value?: string): void;

View File

@ -500,7 +500,7 @@ export declare abstract class UrlHandlingStrategy {
abstract shouldProcessUrl(url: UrlTree): boolean;
}
export declare type UrlMatcher = (segments: UrlSegment[], group: UrlSegmentGroup, route: Route) => UrlMatchResult;
export declare type UrlMatcher = (segments: UrlSegment[], group: UrlSegmentGroup, route: Route) => UrlMatchResult | null;
export declare type UrlMatchResult = {
consumed: UrlSegment[];

View File

@ -5,8 +5,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# Fetch rules_nodejs so we can install our npm dependencies
http_archive(
name = "build_bazel_rules_nodejs",
sha256 = "d0c4bb8b902c1658f42eb5563809c70a06e46015d64057d25560b0eb4bdc9007",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/1.5.0/rules_nodejs-1.5.0.tar.gz"],
sha256 = "f9e7b9f42ae202cc2d2ce6d698ccb49a9f7f7ea572a78fd451696d03ef2ee116",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/1.6.0/rules_nodejs-1.6.0.tar.gz"],
)
# Fetch sass rules for compiling sass files

View File

@ -23,11 +23,11 @@
"@angular/compiler": "file:../../dist/packages-dist/compiler",
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
"@bazel/bazelisk": "file:../../node_modules/@bazel/bazelisk",
"@bazel/karma": "1.5.0",
"@bazel/protractor": "1.5.0",
"@bazel/rollup": "1.5.0",
"@bazel/terser": "1.5.0",
"@bazel/typescript": "1.5.0",
"@bazel/karma": "1.6.0",
"@bazel/protractor": "1.6.0",
"@bazel/rollup": "1.6.0",
"@bazel/terser": "1.6.0",
"@bazel/typescript": "1.6.0",
"@types/jasmine": "2.8.8",
"http-server": "0.12.0",
"karma": "4.4.1",

View File

@ -3,10 +3,10 @@
"@angular/animations@file:../../dist/packages-dist/animations":
version "9.1.0-rc.0"
version "10.0.0-next.1"
"@angular/bazel@file:../../dist/packages-dist/bazel":
version "9.1.0-rc.0"
version "10.0.0-next.1"
dependencies:
"@microsoft/api-extractor" "^7.3.9"
shelljs "0.8.2"
@ -22,10 +22,10 @@
parse5 "^5.0.0"
"@angular/common@file:../../dist/packages-dist/common":
version "9.1.0-rc.0"
version "10.0.0-next.1"
"@angular/compiler-cli@file:../../dist/packages-dist/compiler-cli":
version "9.1.0-rc.0"
version "10.0.0-next.1"
dependencies:
canonical-path "1.0.0"
chokidar "^3.0.0"
@ -41,13 +41,13 @@
yargs "15.3.0"
"@angular/compiler@file:../../dist/packages-dist/compiler":
version "9.1.0-rc.0"
version "10.0.0-next.1"
"@angular/core@file:../../dist/packages-dist/core":
version "9.1.0-rc.0"
version "10.0.0-next.1"
"@angular/forms@file:../../dist/packages-dist/forms":
version "9.1.0-rc.0"
version "10.0.0-next.1"
"@angular/material@8.0.1":
version "8.0.1"
@ -57,43 +57,43 @@
tslib "^1.7.1"
"@angular/platform-browser-dynamic@file:../../dist/packages-dist/platform-browser-dynamic":
version "9.1.0-rc.0"
version "10.0.0-next.1"
"@angular/platform-browser@file:../../dist/packages-dist/platform-browser":
version "9.1.0-rc.0"
version "10.0.0-next.1"
"@angular/router@file:../../dist/packages-dist/router":
version "9.1.0-rc.0"
version "10.0.0-next.1"
"@bazel/bazelisk@file:../../node_modules/@bazel/bazelisk":
version "1.3.0"
"@bazel/karma@1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@bazel/karma/-/karma-1.5.0.tgz#75ea27c3c2a8a7fadbb5c5ab644c3acd3bc22702"
integrity sha512-j5S2Xya4Rr7vK0DzTaZ8FKDHBydtTNldwlx+rihjKJgbEBt76wQM7ucXD6aSA23lC+JM/dPRSKkpIIGeWf2JdQ==
"@bazel/karma@1.6.0":
version "1.6.0"
resolved "https://registry.yarnpkg.com/@bazel/karma/-/karma-1.6.0.tgz#98950b71114dd9ec169e6778a35d31ae1f578655"
integrity sha512-9cX0E1SiMWwA70ZMFnMzeqSRn3biduGx03bGV77FSUYKocZpyfU2cOEygYGfxAqHnyM7x4cS8nflRv3+ZE0Aqg==
dependencies:
tmp "0.1.0"
"@bazel/protractor@1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@bazel/protractor/-/protractor-1.5.0.tgz#ac92442bf38f5cd718812e4cca41ba2e5ebf1fa5"
integrity sha512-nUwOOUjNGJUU18JiE3sPOBzIul0jvGApEEikntKTLLwQ7w7/1TnOdXDWvHXrXRW3nwit6flWIzEUoFtWgwtCeg==
"@bazel/protractor@1.6.0":
version "1.6.0"
resolved "https://registry.yarnpkg.com/@bazel/protractor/-/protractor-1.6.0.tgz#cf095a1dbc038def7031c513a3b87f4e79bedb00"
integrity sha512-gPiRv0oUJbVPpQ9nrwe5vjkffAc8VsYJhpTGgG+8aPdOaTLWgmBP/sy4BdfijU9O1Z/mNYojQCZgMzQz6kAvdg==
"@bazel/rollup@1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@bazel/rollup/-/rollup-1.5.0.tgz#d0933d167e682470b90f8149eecf4c5bd7511369"
integrity sha512-/FEJfNi9dbbH8oQbf7LHyd0uhGSB0CQQhOpz8d4b2WLnYLhK0NZhoNF4afFjju5kQkrbrOfKaho64BfVxvNppA==
"@bazel/rollup@1.6.0":
version "1.6.0"
resolved "https://registry.yarnpkg.com/@bazel/rollup/-/rollup-1.6.0.tgz#c0bdad0ad0ba5c5b2e21d1634dc2ce48840ca044"
integrity sha512-MLF7laHX3CSAJH+RbIEVWgnQdz3U8dPkdJWJqiX/z9mUSEgC47LNsMBPKlRy1TpOJOpw1j0vLaJv0qN/bgq9NQ==
"@bazel/terser@1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@bazel/terser/-/terser-1.5.0.tgz#141e1492043231001da3f3ef67b575dd9c2df0be"
integrity sha512-ajT2roE+tiW+xm2YOSfUG55MaUHv0hHYlQneNV1GI3lZoowWPbToOaZiuVza90ulHFHP7lDXn/5MC4UF5/piOQ==
"@bazel/terser@1.6.0":
version "1.6.0"
resolved "https://registry.yarnpkg.com/@bazel/terser/-/terser-1.6.0.tgz#63ccd20dd6c9793e7b3b23fb5ea82b55b3ef6eb2"
integrity sha512-csBrN4XfX/hYTtDVcH/ulVO9K4Ca/IlrCWk5o/l7JBJq/cHoTj5AWIA7PKJ4QgnxXeEjso4CmLFgUMEVKVYV3Q==
"@bazel/typescript@1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@bazel/typescript/-/typescript-1.5.0.tgz#d69324c08e7dbfe10b21a6fcb7b4d66c71c8d171"
integrity sha512-Vi8n1p35EhxGC22TEnmnVPlyakrALyH2ccVN5J6YeZXE1oWlSMSqQEhXKTjqUfQ3FT76nW1K91AdH4TG3me5nQ==
"@bazel/typescript@1.6.0":
version "1.6.0"
resolved "https://registry.yarnpkg.com/@bazel/typescript/-/typescript-1.6.0.tgz#8dfd29e71bcf917d5f9cb67f19ac4dcfc9082439"
integrity sha512-vAKuwy1Hgl+t3M3sH/G0oqHRYN35TdENj+0lsCI3x7EbSzyI6cbA3YQrLrlyvdScksqOpZa3PZ3UBGqfJJq2DA==
dependencies:
protobufjs "6.8.8"
semver "5.6.0"
@ -2084,7 +2084,7 @@ rollup@1.27.5:
acorn "^7.1.0"
"rxjs@file:../../node_modules/rxjs":
version "6.5.3"
version "6.5.4"
dependencies:
tslib "^1.9.0"
@ -2437,7 +2437,7 @@ tslib@^1.7.1, tslib@^1.8.1, tslib@^1.9.0:
integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==
"tslib@file:../../node_modules/tslib":
version "1.10.0"
version "1.11.1"
tsutils@2.27.2:
version "2.27.2"

View File

@ -8,77 +8,79 @@
(function(global: any) {
writeScriptTag('/all/benchmarks/vendor/core.js');
writeScriptTag('/all/benchmarks/vendor/zone.js');
writeScriptTag('/all/benchmarks/vendor/long-stack-trace-zone.js');
writeScriptTag('/all/benchmarks/vendor/system.src.js');
writeScriptTag('/all/benchmarks/vendor/Reflect.js', 'benchmarksBootstrap()');
writeScriptTag('/all/benchmarks/vendor/core.js');
writeScriptTag('/all/benchmarks/vendor/zone.js');
writeScriptTag('/all/benchmarks/vendor/long-stack-trace-zone.js');
writeScriptTag('/all/benchmarks/vendor/system.src.js');
writeScriptTag('/all/benchmarks/vendor/Reflect.js', 'benchmarksBootstrap()');
(<any>global).benchmarksBootstrap = benchmarksBootstrap;
(<any>global).benchmarksBootstrap = benchmarksBootstrap;
function benchmarksBootstrap() {
// check query param
const useBundles = location.search.indexOf('bundles=false') == -1;
if (useBundles) {
System.config({
defaultJSExtensions: true,
map: {
'@angular/core': '/packages-dist/core/bundles/core.umd.js',
'@angular/animations': '/packages-dist/common/bundles/animations.umd.js',
'@angular/platform-browser/animations':
'/packages-dist/platform-browser/bundles/platform-browser-animations.umd.js',
'@angular/common': '/packages-dist/common/bundles/common.umd.js',
'@angular/forms': '/packages-dist/forms/bundles/forms.umd.js',
'@angular/compiler': '/packages-dist/compiler/bundles/compiler.umd.js',
'@angular/platform-browser':
'/packages-dist/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic':
'/packages-dist/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': '/packages-dist/http/bundles/http.umd.js',
'@angular/upgrade': '/packages-dist/upgrade/bundles/upgrade.umd.js',
'@angular/router': '/packages-dist/router/bundles/router.umd.js',
'rxjs': '/all/benchmarks/vendor/rxjs',
},
packages: {
'rxjs/ajax': {main: 'index.js', defaultExtension: 'js'},
'rxjs/operators': {main: 'index.js', defaultExtension: 'js'},
'rxjs/testing': {main: 'index.js', defaultExtension: 'js'},
'rxjs/websocket': {main: 'index.js', defaultExtension: 'js'},
'rxjs': {main: 'index.js', defaultExtension: 'js'},
}
});
} else {
console.warn(
'Not using the Angular bundles. Don\'t use this configuration for e2e/performance tests!');
function benchmarksBootstrap() {
// check query param
const useBundles = location.search.indexOf('bundles=false') == -1;
if (useBundles) {
System.config({
defaultJSExtensions: true,
map: {
'@angular/core': '/packages-dist/core/bundles/core.umd.js',
'@angular/animations': '/packages-dist/common/bundles/animations.umd.js',
'@angular/platform-browser/animations':
'/packages-dist/platform-browser/bundles/platform-browser-animations.umd.js',
'@angular/common': '/packages-dist/common/bundles/common.umd.js',
'@angular/forms': '/packages-dist/forms/bundles/forms.umd.js',
'@angular/compiler': '/packages-dist/compiler/bundles/compiler.umd.js',
'@angular/platform-browser':
'/packages-dist/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic':
'/packages-dist/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': '/packages-dist/http/bundles/http.umd.js',
'@angular/upgrade': '/packages-dist/upgrade/bundles/upgrade.umd.js',
'@angular/router': '/packages-dist/router/bundles/router.umd.js',
'rxjs': '/all/benchmarks/vendor/rxjs',
},
packages: {
'rxjs/ajax': {main: 'index.js', defaultExtension: 'js'},
'rxjs/operators': {main: 'index.js', defaultExtension: 'js'},
'rxjs/testing': {main: 'index.js', defaultExtension: 'js'},
'rxjs/websocket': {main: 'index.js', defaultExtension: 'js'},
'rxjs': {main: 'index.js', defaultExtension: 'js'},
}
});
} else {
console.warn(
'Not using the Angular bundles. Don\'t use this configuration for e2e/performance tests!');
System.config({
defaultJSExtensions: true,
map: {'@angular': '/all/@angular', 'rxjs': '/all/benchmarks/vendor/rxjs'},
packages: {
'@angular/core': {main: 'index.js', defaultExtension: 'js'},
'@angular/animations': {main: 'index.js', defaultExtension: 'js'},
'@angular/platform-browser/animations': {main: 'index.js', defaultExtension: 'js'},
'@angular/compiler': {main: 'index.js', defaultExtension: 'js'},
'@angular/router': {main: 'index.js', defaultExtension: 'js'},
'@angular/common': {main: 'index.js', defaultExtension: 'js'},
'@angular/forms': {main: 'index.js', defaultExtension: 'js'},
'@angular/platform-browser': {main: 'index.js', defaultExtension: 'js'},
'@angular/platform-browser-dynamic': {main: 'index.js', defaultExtension: 'js'},
'@angular/upgrade': {main: 'index.js', defaultExtension: 'js'},
'rxjs/ajax': {main: 'index.js', defaultExtension: 'js'},
'rxjs/operators': {main: 'index.js', defaultExtension: 'js'},
'rxjs/testing': {main: 'index.js', defaultExtension: 'js'},
'rxjs/websocket': {main: 'index.js', defaultExtension: 'js'},
'rxjs': {main: 'index.js', defaultExtension: 'js'},
}
});
}
// BOOTSTRAP the app!
System.import('index').then(function(m: any) { m.main(); }, console.error.bind(console));
System.config({
defaultJSExtensions: true,
map: {'@angular': '/all/@angular', 'rxjs': '/all/benchmarks/vendor/rxjs'},
packages: {
'@angular/core': {main: 'index.js', defaultExtension: 'js'},
'@angular/animations': {main: 'index.js', defaultExtension: 'js'},
'@angular/platform-browser/animations': {main: 'index.js', defaultExtension: 'js'},
'@angular/compiler': {main: 'index.js', defaultExtension: 'js'},
'@angular/router': {main: 'index.js', defaultExtension: 'js'},
'@angular/common': {main: 'index.js', defaultExtension: 'js'},
'@angular/forms': {main: 'index.js', defaultExtension: 'js'},
'@angular/platform-browser': {main: 'index.js', defaultExtension: 'js'},
'@angular/platform-browser-dynamic': {main: 'index.js', defaultExtension: 'js'},
'@angular/upgrade': {main: 'index.js', defaultExtension: 'js'},
'rxjs/ajax': {main: 'index.js', defaultExtension: 'js'},
'rxjs/operators': {main: 'index.js', defaultExtension: 'js'},
'rxjs/testing': {main: 'index.js', defaultExtension: 'js'},
'rxjs/websocket': {main: 'index.js', defaultExtension: 'js'},
'rxjs': {main: 'index.js', defaultExtension: 'js'},
}
});
}
function writeScriptTag(scriptUrl: string, onload?: string) {
document.write(`<script src="${scriptUrl}" onload="${onload}"></script>`);
}
// BOOTSTRAP the app!
System.import('index').then(function(m: any) {
m.main();
}, console.error.bind(console));
}
function writeScriptTag(scriptUrl: string, onload?: string) {
document.write(`<script src="${scriptUrl}" onload="${onload}"></script>`);
}
}(window));

View File

@ -8,24 +8,24 @@
(function(global: any) {
writeScriptTag('/all/benchmarks/vendor/core.js');
writeScriptTag('/all/benchmarks/vendor/system.src.js', 'benchmarksBootstrap()');
writeScriptTag('/all/benchmarks/vendor/core.js');
writeScriptTag('/all/benchmarks/vendor/system.src.js', 'benchmarksBootstrap()');
(<any>global).benchmarksBootstrap = benchmarksBootstrap;
(<any>global).benchmarksBootstrap = benchmarksBootstrap;
function benchmarksBootstrap() {
System.config({
defaultJSExtensions: true,
map: {'incremental-dom': '/all/benchmarks/vendor/incremental-dom-cjs.js'}
});
function benchmarksBootstrap() {
System.config({
defaultJSExtensions: true,
map: {'incremental-dom': '/all/benchmarks/vendor/incremental-dom-cjs.js'}
});
// BOOTSTRAP the app!
System.import('index').then(function(m: any) {
m.main && m.main();
}, console.error.bind(console));
}
// BOOTSTRAP the app!
System.import('index').then(function(m: any) {
m.main && m.main();
}, console.error.bind(console));
}
function writeScriptTag(scriptUrl: string, onload?: string) {
document.write(`<script src="${scriptUrl}" onload="${onload}"></script>`);
}
function writeScriptTag(scriptUrl: string, onload?: string) {
document.write(`<script src="${scriptUrl}" onload="${onload}"></script>`);
}
}(window));

View File

@ -13,7 +13,7 @@ import {openBrowser, verifyNoBrowserErrors} from '../../../e2e_util/e2e_util';
describe('change detection benchmark', () => {
afterEach(verifyNoBrowserErrors);
it(`should render and update`, async() => {
it(`should render and update`, async () => {
openBrowser({
url: '',
ignoreBrowserSynchronization: true,

View File

@ -31,15 +31,14 @@ const UpdateWorker: Worker = {
// name. We determine the name of the Bazel package where this test runs from the current test
// target. The Bazel target
// looks like: "//modules/benchmarks/src/change_detection/{pkg_name}:{target_name}".
const testPackageName = process.env['BAZEL_TARGET'] !.split(':')[0].split('/').pop();
const testPackageName = process.env['BAZEL_TARGET']!.split(':')[0].split('/').pop();
describe('change detection benchmark perf', () => {
afterEach(verifyNoBrowserErrors);
[UpdateWorker].forEach((worker) => {
describe(worker.id, () => {
it(`should run benchmark for ${testPackageName}`, async() => {
it(`should run benchmark for ${testPackageName}`, async () => {
await runChangeDetectionBenchmark({
id: `change_detection.${testPackageName}.${worker.id}`,
url: '/',

View File

@ -35,7 +35,9 @@ export function init(moduleRef: NgModuleRef<TransplantedViewsModule>) {
appRef.tick();
}
function detectChanges() { appRef.tick(); }
function detectChanges() {
appRef.tick();
}
function noop() {}
}

View File

@ -40,10 +40,14 @@ export class InsertionComponent {
@Input() template !: TemplateRef<{}>;
views: any[] = [];
@Input()
set viewCount(n: number) { this.views = n > 0 ? newArray<any>(n) : []; }
set viewCount(n: number) {
this.views = n > 0 ? newArray<any>(n) : [];
}
// use trackBy to ensure profile isn't affected by the cost to refresh ngFor.
trackByIndex(index: number, item: any) { return index; }
trackByIndex(index: number, item: any) {
return index;
}
}
@NgModule({

View File

@ -15,7 +15,7 @@ export function newArray<T>(size: number, value: T): T[];
export function newArray<T>(size: number, value?: T): T[] {
const list: T[] = [];
for (let i = 0; i < size; i++) {
list.push(value !);
list.push(value!);
}
return list;
}

View File

@ -27,12 +27,16 @@ export class AppComponent {
}
}
create() { this.show = true; }
create() {
this.show = true;
}
update() {
this.msg = this.msg === 'hello' ? 'bye' : 'hello';
this.list[0].text = this.msg;
}
destroy() { this.show = false; }
destroy() {
this.show = false;
}
}

View File

@ -10,8 +10,7 @@ import {$, browser} from 'protractor';
import {runBenchmark} from '../../../e2e_util/perf_util';
describe('class bindings perf', () => {
it('should work for update', async() => {
it('should work for update', async () => {
browser.rootEl = '#root';
await runBenchmark({
id: 'create',
@ -23,7 +22,7 @@ describe('class bindings perf', () => {
});
});
it('should work for update', async() => {
it('should work for update', async () => {
browser.rootEl = '#root';
await runBenchmark({
id: 'update',
@ -34,5 +33,4 @@ describe('class bindings perf', () => {
work: () => $('#update').click()
});
});
});

View File

@ -31,23 +31,32 @@ import {BenchmarkableExpandingRowModule} from './benchmarkable_expanding_row_mod
</benchmark-area>`,
})
export class InitializationRoot implements AfterViewInit {
@ViewChild(BenchmarkableExpandingRow, {static: true})
expandingRow !: BenchmarkableExpandingRow;
@ViewChild(BenchmarkableExpandingRow, {static: true}) expandingRow!: BenchmarkableExpandingRow;
ngAfterViewInit() {}
reset() { this.expandingRow.reset(); }
init() { this.expandingRow.init(); }
async runAll() {
await execTimed('initialization_benchmark', async() => { await this.doInit(); });
reset() {
this.expandingRow.reset();
}
async handleInitClick() { await this.doInit(); }
init() {
this.expandingRow.init();
}
async runAll() {
await execTimed('initialization_benchmark', async () => {
await this.doInit();
});
}
async handleInitClick() {
await this.doInit();
}
private async doInit() {
await execTimed('initial_load', async() => { this.expandingRow.init(); });
await execTimed('initial_load', async () => {
this.expandingRow.init();
});
}
}
@ -74,5 +83,9 @@ export async function execTimed(description: string, func: () => Promise<void>)
}
export async function nextTick(delay = 1) {
return new Promise((res, rej) => { setTimeout(() => { res(); }, delay); });
return new Promise((res, rej) => {
setTimeout(() => {
res();
}, delay);
});
}

View File

@ -26,7 +26,9 @@ import {Component, ErrorHandler, Injectable, NgModule} from '@angular/core';
export class BenchmarkArea {
}
declare interface ExtendedWindow extends Window { benchmarkErrors?: string[]; }
declare interface ExtendedWindow extends Window {
benchmarkErrors?: string[];
}
const extendedWindow = window as ExtendedWindow;
@Injectable({providedIn: 'root'})

View File

@ -44,12 +44,12 @@ export interface MlbTeam {
})
export class BenchmarkableExpandingRow {
// TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
showExpandingRow !: boolean;
showExpandingRow!: boolean;
// TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
teams !: MlbTeam[];
teams!: MlbTeam[];
// TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
private fakeTeams !: MlbTeam[];
private fakeTeams!: MlbTeam[];
init(): void {
this.teams = this.fakeTeams;

View File

@ -112,15 +112,14 @@ export class ExpandingRow {
* The identifier for this node provided by the user code. We need this
* while we are emitting onToggle event.
*/
@Input() rowId !: string;
@Input() rowId!: string;
/**
* An ElementRef to the main element in this component. We need a reference
* to this element to compute the height. The height of cfc-expanding-row
* is used in [cfcExpandingRowHost] directive for scroll adjustments.
*/
@ViewChild('expandingRowMainElement', {static: true})
expandingRowMainElement !: ElementRef;
@ViewChild('expandingRowMainElement', {static: true}) expandingRowMainElement!: ElementRef;
/**
* This @Output event emitter will be triggered when the user expands or
@ -145,7 +144,9 @@ export class ExpandingRow {
}
/** TS getter for isExpanded property. */
get isExpanded(): boolean { return this.isExpandedInternal; }
get isExpanded(): boolean {
return this.isExpandedInternal;
}
/** Triggered when isExpanded property changes. */
isExpandedChange = new EventEmitter<void>();
@ -164,7 +165,9 @@ export class ExpandingRow {
}
/** TS getter for isFocused property. */
get isFocused(): boolean { return this.isFocusedInternal; }
get isFocused(): boolean {
return this.isFocusedInternal;
}
/** The index of the row in the context of the entire collection. */
set index(value: number) {
@ -178,7 +181,9 @@ export class ExpandingRow {
}
/** TS getter for index property. */
get index(): number { return this.indexInternal; }
get index(): number {
return this.indexInternal;
}
/**
* We should probably rename this to summaryContentChild. Because technically
@ -188,7 +193,7 @@ export class ExpandingRow {
* component is not in the same file as ExpandingRow.
*/
// TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
summaryViewChild !: ExpandingRowSummary;
summaryViewChild!: ExpandingRowSummary;
/**
* We compute the collapsed height (which is just height of
@ -205,7 +210,7 @@ export class ExpandingRow {
/** Internal storage for index public property. */
// TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
private indexInternal !: number;
private indexInternal!: number;
/**
* This holds a reference to [cfcExpandingRowHost] directive. We need
@ -233,7 +238,9 @@ export class ExpandingRow {
* When user tabs into child cfc-expanding-row-summary component. This method
* will make sure we focuse on this row, and blur on previously focused row.
*/
handleSummaryFocus(): void { this.focus(); }
handleSummaryFocus(): void {
this.focus();
}
/**
* cfc-expanding-row-details-caption component will call this function to
@ -256,7 +263,9 @@ export class ExpandingRow {
* Gets the height of this component. This height is used in parent
* [cfcExpandingRowHost] directive to compute scroll adjustment.
*/
getHeight(): number { return this.expandingRowMainElement.nativeElement.offsetHeight; }
getHeight(): number {
return this.expandingRowMainElement.nativeElement.offsetHeight;
}
/**
* Expands this row. This will notify the host so that it can collapse
@ -268,7 +277,9 @@ export class ExpandingRow {
this.expandingRowHost.handleRowExpand(this);
// setTimeout here makes sure we scroll this row into view after animation.
setTimeout(() => { this.expandingRowMainElement.nativeElement.focus(); });
setTimeout(() => {
this.expandingRowMainElement.nativeElement.focus();
});
this.onToggle.emit({rowId: this.rowId, isExpand: true});
}
@ -305,7 +316,9 @@ export class ExpandingRow {
// Summary child is not present currently. We need to NG2 to update the
// template.
setTimeout(() => { this.summaryViewChild.focus(); });
setTimeout(() => {
this.summaryViewChild.focus();
});
}
/**

View File

@ -49,5 +49,7 @@ export class ExpandingRowDetailsCaption implements OnDestroy {
}
/** When component is destroyed, unlisten to isExpanded. */
ngOnDestroy(): void { this.onDestroy.next(); }
ngOnDestroy(): void {
this.onDestroy.next();
}
}

View File

@ -35,10 +35,13 @@ export class ExpandingRowDetailsContent implements OnDestroy {
* hide this component if the row is collapsed.
*/
constructor(@Host() public expandingRow: ExpandingRow, changeDetectorRef: ChangeDetectorRef) {
this.isExpandedChangeSubscription =
this.expandingRow.isExpandedChange.subscribe(() => { changeDetectorRef.markForCheck(); });
this.isExpandedChangeSubscription = this.expandingRow.isExpandedChange.subscribe(() => {
changeDetectorRef.markForCheck();
});
}
/** Unsubscribe from changes in parent isExpanded property. */
ngOnDestroy(): void { this.isExpandedChangeSubscription.unsubscribe(); }
ngOnDestroy(): void {
this.isExpandedChangeSubscription.unsubscribe();
}
}

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {AfterContentInit, AfterViewInit, ChangeDetectionStrategy, Component, ContentChildren, ElementRef, EventEmitter, HostListener, Input, OnDestroy, Output, QueryList, ViewChild, forwardRef} from '@angular/core';
import {AfterContentInit, AfterViewInit, ChangeDetectionStrategy, Component, ContentChildren, ElementRef, EventEmitter, forwardRef, HostListener, Input, OnDestroy, Output, QueryList, ViewChild} from '@angular/core';
import {Subscription} from 'rxjs';
import {EXPANDING_ROW_HOST_INJECTION_TOKEN, ExpandingRow, ExpandingRowHostBase} from './expanding_row';
@ -26,7 +26,7 @@ export const EXPANDING_ROW_KEYPRESS_THORTTLE_MS = 50;
* This type union is created to make arguments of handleUpOrDownPress*
* methods in ExpandingRowHost class more readable.
*/
type UpOrDown = 'up' | 'down';
type UpOrDown = 'up'|'down';
/**
* This is the wrapper directive for the cfc-expanding-row components. Note that
@ -48,8 +48,7 @@ type UpOrDown = 'up' | 'down';
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [{provide: EXPANDING_ROW_HOST_INJECTION_TOKEN, useExisting: ExpandingRowHost}],
})
export class ExpandingRowHost implements AfterViewInit,
OnDestroy, ExpandingRowHostBase {
export class ExpandingRowHost implements AfterViewInit, OnDestroy, ExpandingRowHostBase {
/**
* An HTML selector (e.g. "body") for the scroll element. We need this to
* make some scroll adjustments.
@ -71,11 +70,10 @@ export class ExpandingRowHost implements AfterViewInit,
@Output() onPrepend = new EventEmitter<void>();
/** A reference to the last focusable element in list of expanding rows. */
@ViewChild('lastFocusable', {static: true}) lastFocusableElement !: ElementRef;
@ViewChild('lastFocusable', {static: true}) lastFocusableElement!: ElementRef;
/** A reference to the first focusable element in list of expanding rows. */
@ViewChild('firstFocusable', {static: true})
firstFocusableElement !: ElementRef;
@ViewChild('firstFocusable', {static: true}) firstFocusableElement!: ElementRef;
/**
* A reference to all child cfc-expanding-row elements. We will need for
@ -83,7 +81,7 @@ export class ExpandingRowHost implements AfterViewInit,
* which row is previous row when user presses "left arrow" on a focused row.
*/
@ContentChildren(forwardRef(() => ExpandingRow), {descendants: true})
contentRows !: QueryList<ExpandingRow>;
contentRows!: QueryList<ExpandingRow>;
/**
* Keeps track of the last row that had focus before focus left the list
@ -122,7 +120,7 @@ export class ExpandingRowHost implements AfterViewInit,
/** Subscription to changes in the expanding rows. */
// TODO(b/109816955): remove '!', see go/strict-prop-init-fix.
private rowChangeSubscription !: Subscription;
private rowChangeSubscription!: Subscription;
/**
* When component initializes we need to attach click listener to the root
@ -138,8 +136,9 @@ export class ExpandingRowHost implements AfterViewInit,
clickRootElement.addEventListener('mouseup', this.handleRootMouseUpBound);
this.rowChangeSubscription =
this.contentRows.changes.subscribe(() => { this.recalcRowIndexes(); });
this.rowChangeSubscription = this.contentRows.changes.subscribe(() => {
this.recalcRowIndexes();
});
this.recalcRowIndexes();
}
@ -256,13 +255,17 @@ export class ExpandingRowHost implements AfterViewInit,
* Function that is called by expanding row summary to focus on the last
* focusable element before the list of expanding rows.
*/
focusOnPreviousFocusableElement(): void { this.lastFocusedRow = this.focusedRow; }
focusOnPreviousFocusableElement(): void {
this.lastFocusedRow = this.focusedRow;
}
/**
* Function that is called by expanding row summary to focus on the next
* focusable element after the list of expanding rows.
*/
focusOnNextFocusableElement(): void { this.lastFocusedRow = this.focusedRow; }
focusOnNextFocusableElement(): void {
this.lastFocusedRow = this.focusedRow;
}
/**
* Handles keydown event on the host. We are just concerned with up,
@ -275,7 +278,8 @@ export class ExpandingRowHost implements AfterViewInit,
* - Enter: Expands the focused row.
*/
@HostListener('keydown', ['$event'])
handleKeyDown(event: KeyboardEvent) {}
handleKeyDown(event: KeyboardEvent) {
}
/**
* Recursively returns true if target HTMLElement is within a
@ -491,7 +495,10 @@ export class ExpandingRowHost implements AfterViewInit,
// Updates all of the rows with their new index.
private recalcRowIndexes() {
let index = 0;
setTimeout(
() => { this.contentRows.forEach((row: ExpandingRow) => { row.index = index++; }); });
setTimeout(() => {
this.contentRows.forEach((row: ExpandingRow) => {
row.index = index++;
});
});
}
}

View File

@ -48,8 +48,7 @@ export class ExpandingRowSummary implements OnDestroy {
* reference to compute collapsed height of the row. We also use this
* reference for focus and blur methods below.
*/
@ViewChild('expandingRowSummaryMainElement')
mainElementRef !: ElementRef;
@ViewChild('expandingRowSummaryMainElement') mainElementRef!: ElementRef;
/** Subscription for changes in parent isExpanded property. */
private isExpandedSubscription: Subscription;
@ -65,11 +64,13 @@ export class ExpandingRowSummary implements OnDestroy {
*/
constructor(@Host() public expandingRow: ExpandingRow, changeDetectorRef: ChangeDetectorRef) {
this.expandingRow.summaryViewChild = this;
this.isExpandedSubscription =
this.expandingRow.isExpandedChange.subscribe(() => { changeDetectorRef.markForCheck(); });
this.isExpandedSubscription = this.expandingRow.isExpandedChange.subscribe(() => {
changeDetectorRef.markForCheck();
});
this.indexSubscription =
this.expandingRow.indexChange.subscribe(() => { changeDetectorRef.markForCheck(); });
this.indexSubscription = this.expandingRow.indexChange.subscribe(() => {
changeDetectorRef.markForCheck();
});
}
@ -203,5 +204,7 @@ export class ExpandingRowSummary implements OnDestroy {
}
/** Returns array of focusable elements within this component. */
private getFocusableChildren(): HTMLElement[] { return []; }
private getFocusableChildren(): HTMLElement[] {
return [];
}
}

View File

@ -10,8 +10,7 @@ import {$, browser} from 'protractor';
import {runBenchmark} from '../../../e2e_util/perf_util';
describe('benchmarks', () => {
it('should work for create', async() => {
it('should work for create', async () => {
browser.rootEl = '#root';
await runBenchmark({
id: 'create',
@ -22,5 +21,4 @@ describe('benchmarks', () => {
work: () => $('#init').click()
});
});
});

View File

@ -18,5 +18,5 @@ enableProdMode();
platformBrowser().bootstrapModuleFactory(ExpandingRowBenchmarkModuleNgFactory);
function setMode(name: string): void {
document.querySelector('#rendererMode') !.textContent = `Render Mode: ${name}`;
document.querySelector('#rendererMode')!.textContent = `Render Mode: ${name}`;
}

View File

@ -24,19 +24,25 @@ const Create1KWorker: Worker = {
const Delete1KWorker: Worker = {
id: 'delete1K',
prepare: () => $('#create1KRows').click(),
work: () => { $('#deleteAll').click(); }
work: () => {
$('#deleteAll').click();
}
};
const UpdateWorker: Worker = {
id: 'update',
prepare: () => $('#create1KRows').click(),
work: () => { $('#update').click(); }
work: () => {
$('#update').click();
}
};
const SwapWorker: Worker = {
id: 'swap',
prepare: () => $('#create1KRows').click(),
work: () => { $('#swap').click(); }
work: () => {
$('#swap').click();
}
};
// In order to make sure that we don't change the ids of the benchmarks, we need to
@ -45,15 +51,14 @@ const SwapWorker: Worker = {
// name. e.g. "largeTable.ng2_switch.createDestroy". We determine the name of the
// Bazel package where this test runs from the current test target. The Bazel target
// looks like: "//modules/benchmarks/src/largetable/{pkg_name}:{target_name}".
const testPackageName = process.env['BAZEL_TARGET'] !.split(':')[0].split('/').pop();
const testPackageName = process.env['BAZEL_TARGET']!.split(':')[0].split('/').pop();
describe('js-web-frameworks benchmark perf', () => {
afterEach(verifyNoBrowserErrors);
[Create1KWorker, Delete1KWorker, UpdateWorker, SwapWorker].forEach((worker) => {
describe(worker.id, () => {
it(`should run benchmark for ${testPackageName}`, async() => {
it(`should run benchmark for ${testPackageName}`, async () => {
await runTableBenchmark({
id: `js-web-frameworks.${testPackageName}.${worker.id}`,
url: '/',

View File

@ -42,14 +42,16 @@ export class JsWebFrameworksComponent {
constructor(private _appRef: ApplicationRef) {}
itemById(index: number, item: RowData) { return item.id; }
itemById(index: number, item: RowData) {
return item.id;
}
select(itemId: number) {
this.selected = itemId;
this._appRef.tick();
}
delete (itemId: number) {
delete(itemId: number) {
const data = this.data;
for (let i = 0, l = data.length; i < l; i++) {
if (data[i].id === itemId) {

View File

@ -11,10 +11,9 @@ import {$, By, element} from 'protractor';
import {openBrowser, verifyNoBrowserErrors} from '../../../e2e_util/e2e_util';
describe('largeform benchmark', () => {
afterEach(verifyNoBrowserErrors);
it('should work for ng2', async() => {
it('should work for ng2', async () => {
openBrowser({
url: '/',
params: [{name: 'copies', value: 1}],

View File

@ -26,12 +26,11 @@ const CreateAndDestroyWorker = {
};
describe('largeform benchmark spec', () => {
afterEach(verifyNoBrowserErrors);
[CreateAndDestroyWorker].forEach((worker) => {
describe(worker.id, () => {
it('should run for ng2', async() => {
it('should run for ng2', async () => {
await runLargeFormBenchmark({url: '/', id: `largeform.ng2.${worker.id}`, worker: worker});
});
});

View File

@ -17,7 +17,9 @@ const {patch, elementOpen, elementClose, elementOpenStart, elementOpenEnd, attr,
export class TableComponent {
constructor(private _rootEl: any) {}
set data(data: TableCell[][]) { patch(this._rootEl, () => this._render(data)); }
set data(data: TableCell[][]) {
patch(this._rootEl, () => this._render(data));
}
private _render(data: TableCell[][]) {
elementOpen('table');

View File

@ -13,7 +13,7 @@ import {openBrowser, verifyNoBrowserErrors} from '../../../e2e_util/e2e_util';
describe('largetable benchmark', () => {
afterEach(verifyNoBrowserErrors);
it(`should render the table`, async() => {
it(`should render the table`, async () => {
openBrowser({
url: '',
ignoreBrowserSynchronization: true,

View File

@ -40,15 +40,14 @@ const UpdateWorker: Worker = {
// name. e.g. "largeTable.ng2_switch.createDestroy". We determine the name of the
// Bazel package where this test runs from the current test target. The Bazel target
// looks like: "//modules/benchmarks/src/largetable/{pkg_name}:{target_name}".
const testPackageName = process.env['BAZEL_TARGET'] !.split(':')[0].split('/').pop();
const testPackageName = process.env['BAZEL_TARGET']!.split(':')[0].split('/').pop();
describe('largetable benchmark perf', () => {
afterEach(verifyNoBrowserErrors);
[CreateOnlyWorker, CreateAndDestroyWorker, UpdateWorker].forEach((worker) => {
describe(worker.id, () => {
it(`should run benchmark for ${testPackageName}`, async() => {
it(`should run benchmark for ${testPackageName}`, async () => {
await runTableBenchmark({
id: `largeTable.${testPackageName}.${worker.id}`,
url: '/',

View File

@ -9,7 +9,7 @@
import {Component, Input, NgModule} from '@angular/core';
import {BrowserModule, DomSanitizer, SafeStyle} from '@angular/platform-browser';
import {TableCell, emptyTable} from '../util';
import {emptyTable, TableCell} from '../util';
let trustedEmptyColor: SafeStyle;
let trustedGreyColor: SafeStyle;
@ -25,12 +25,15 @@ let trustedGreyColor: SafeStyle;
</tbody></table>`,
})
export class TableComponent {
@Input()
data: TableCell[][] = emptyTable;
@Input() data: TableCell[][] = emptyTable;
trackByIndex(index: number, item: any) { return index; }
trackByIndex(index: number, item: any) {
return index;
}
getColor(row: number) { return row % 2 ? trustedEmptyColor : trustedGreyColor; }
getColor(row: number) {
return row % 2 ? trustedEmptyColor : trustedGreyColor;
}
}
@NgModule({imports: [BrowserModule], bootstrap: [TableComponent], declarations: [TableComponent]})

View File

@ -9,7 +9,7 @@
import {Component, Input, NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {TableCell, emptyTable} from '../util';
import {emptyTable, TableCell} from '../util';
@Component({
selector: 'largetable',
@ -22,10 +22,11 @@ import {TableCell, emptyTable} from '../util';
</tbody></table>`
})
export class TableComponent {
@Input()
data: TableCell[][] = emptyTable;
@Input() data: TableCell[][] = emptyTable;
trackByIndex(index: number, item: any) { return index; }
trackByIndex(index: number, item: any) {
return index;
}
}
@NgModule({imports: [BrowserModule], bootstrap: [TableComponent], declarations: [TableComponent]})

View File

@ -9,7 +9,7 @@ import {ɵrenderComponent as renderComponent} from '@angular/core';
import {bindAction, profile} from '../../util';
import {LargeTableComponent, createDom, destroyDom} from './table';
import {createDom, destroyDom, LargeTableComponent} from './table';
function noop() {}

View File

@ -9,7 +9,7 @@
import {CommonModule} from '@angular/common';
import {Component, Input, NgModule, ɵdetectChanges} from '@angular/core';
import {TableCell, buildTable, emptyTable} from '../util';
import {buildTable, emptyTable, TableCell} from '../util';
@Component({
selector: 'largetable',
@ -26,12 +26,15 @@ import {TableCell, buildTable, emptyTable} from '../util';
`,
})
export class LargeTableComponent {
@Input()
data: TableCell[][] = emptyTable;
@Input() data: TableCell[][] = emptyTable;
trackByIndex(index: number, item: any) { return index; }
trackByIndex(index: number, item: any) {
return index;
}
getColor(row: number) { return row % 2 ? '' : 'grey'; }
getColor(row: number) {
return row % 2 ? '' : 'grey';
}
}
@NgModule({declarations: [LargeTableComponent], imports: [CommonModule]})

View File

@ -6,28 +6,23 @@
* found in the LICENSE file at https://angular.io/license
*/
import {CompilerConfig, DirectiveResolver} from '@angular/compiler';
import {Component, ComponentResolver, Directive, ViewContainerRef,} from '@angular/core';
import {ViewMetadata} from '@angular/core/src/metadata/view';
import {PromiseWrapper} from '@angular/facade/src/async';
import {Type, print} from '@angular/facade/src/lang';
import {print, Type} from '@angular/facade/src/lang';
import {bootstrap} from '@angular/platform-browser';
import {BrowserDomAdapter} from '@angular/platform-browser/src/browser/browser_adapter';
import {DOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {ComponentResolver, Component, Directive, ViewContainerRef,} from '@angular/core';
import {ViewMetadata} from '@angular/core/src/metadata/view';
import {CompilerConfig, DirectiveResolver} from '@angular/compiler';
import {getIntParameter, bindAction} from '@angular/testing/src/benchmark_util';
import {bindAction, getIntParameter} from '@angular/testing/src/benchmark_util';
function _createBindings(): any[] {
const multiplyTemplatesBy = getIntParameter('elements');
return [
{
provide: DirectiveResolver,
useFactory:
() => new MultiplyDirectiveResolver(
multiplyTemplatesBy, [BenchmarkComponentNoBindings, BenchmarkComponentWithBindings]),
useFactory: () => new MultiplyDirectiveResolver(
multiplyTemplatesBy, [BenchmarkComponentNoBindings, BenchmarkComponentWithBindings]),
deps: []
},
// Use interpretative mode as Dart does not support JIT and
@ -57,7 +52,9 @@ function measureWrapper(func, desc) {
const elapsedMs = new Date().getTime() - begin.getTime();
print(`[${desc}] ...done, took ${elapsedMs} ms`);
};
const onError = function(e) { DOM.logError(e); };
const onError = function(e) {
DOM.logError(e);
};
PromiseWrapper.then(func(), onSuccess, onError);
};
}

View File

@ -47,7 +47,9 @@ export function main() {
function match() {
let matchCount = 0;
for (let i = 0; i < count; i++) {
fixedMatcher.match(fixedSelectors[i][0], (selector, selected) => { matchCount += selected; });
fixedMatcher.match(fixedSelectors[i][0], (selector, selected) => {
matchCount += selected;
});
}
return matchCount;
}

View File

@ -10,7 +10,7 @@ import {NgFor, NgIf} from '@angular/common';
import {Component, Directive, DynamicComponentLoader, ViewContainerRef} from '@angular/core';
import {ApplicationRef} from '@angular/core/src/application_ref';
import {ListWrapper} from '@angular/facade/src/lang';
import {BrowserModule, bootstrap} from '@angular/platform-browser';
import {bootstrap, BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {bindAction, getIntParameter} from '@angular/testing/src/benchmark_util';
@ -89,7 +89,9 @@ class AppComponent {
testingWithDirectives: boolean;
testingDynamicComponents: boolean;
constructor() { this.reset(); }
constructor() {
this.reset();
}
reset(): void {
this.list = [];

View File

@ -98,30 +98,42 @@ export function main() {
@Injectable()
class A {
constructor() { count++; }
constructor() {
count++;
}
}
@Injectable()
class B {
constructor(a: A) { count++; }
constructor(a: A) {
count++;
}
}
@Injectable()
class C {
constructor(b: B) { count++; }
constructor(b: B) {
count++;
}
}
@Injectable()
class D {
constructor(c: C, b: B) { count++; }
constructor(c: C, b: B) {
count++;
}
}
@Injectable()
class E {
constructor(d: D, c: C) { count++; }
constructor(d: D, c: C) {
count++;
}
}
@Injectable()
class F {
constructor(e: E, d: D) { count++; }
constructor(e: E, d: D) {
count++;
}
}

View File

@ -45,7 +45,9 @@ export class App {
for (let i = 0; i < appSize; i++) {
this.scrollAreas.push(i);
}
bindAction('#run-btn', () => { this.runBenchmark(); });
bindAction('#run-btn', () => {
this.runBenchmark();
});
bindAction('#reset-btn', () => {
this._getScrollDiv().scrollTop = 0;
const existingMarker = this._locateFinishedMarker();
@ -88,7 +90,11 @@ export class App {
}, 0);
}
private _locateFinishedMarker() { return DOM.querySelector(document.body, '#done'); }
private _locateFinishedMarker() {
return DOM.querySelector(document.body, '#done');
}
private _getScrollDiv() { return DOM.query('body /deep/ #scrollDiv'); }
private _getScrollDiv() {
return DOM.query('body /deep/ #scrollDiv');
}
}

View File

@ -16,7 +16,9 @@ export class HasStyle {
constructor() {}
set width(w: number) { this.cellWidth = w; }
set width(w: number) {
this.cellWidth = w;
}
}
@Component({
@ -74,7 +76,9 @@ export class StageButtonsComponent extends HasStyle {
private _offering: Offering;
stages: Stage[];
get offering(): Offering { return this._offering; }
get offering(): Offering {
return this._offering;
}
set offering(offering: Offering) {
this._offering = offering;

View File

@ -56,13 +56,17 @@ export class CustomDate {
return new CustomDate(newYear, newMonth, newDay);
}
static now(): CustomDate { return new CustomDate(2014, 1, 28); }
static now(): CustomDate {
return new CustomDate(2014, 1, 28);
}
}
export class RawEntity {
private _data: Map<any, any>;
constructor() { this._data = new Map(); }
constructor() {
this._data = new Map();
}
get(key: string) {
if (key.indexOf('.') == -1) {
@ -114,51 +118,107 @@ export class RawEntity {
}
export class Company extends RawEntity {
get name(): string { return this.get('name'); }
set name(val: string) { this.set('name', val); }
get name(): string {
return this.get('name');
}
set name(val: string) {
this.set('name', val);
}
}
export class Offering extends RawEntity {
get name(): string { return this.get('name'); }
set name(val: string) { this.set('name', val); }
get name(): string {
return this.get('name');
}
set name(val: string) {
this.set('name', val);
}
get company(): Company { return this.get('company'); }
set company(val: Company) { this.set('company', val); }
get company(): Company {
return this.get('company');
}
set company(val: Company) {
this.set('company', val);
}
get opportunity(): Opportunity { return this.get('opportunity'); }
set opportunity(val: Opportunity) { this.set('opportunity', val); }
get opportunity(): Opportunity {
return this.get('opportunity');
}
set opportunity(val: Opportunity) {
this.set('opportunity', val);
}
get account(): Account { return this.get('account'); }
set account(val: Account) { this.set('account', val); }
get account(): Account {
return this.get('account');
}
set account(val: Account) {
this.set('account', val);
}
get basePoints(): number { return this.get('basePoints'); }
set basePoints(val: number) { this.set('basePoints', val); }
get basePoints(): number {
return this.get('basePoints');
}
set basePoints(val: number) {
this.set('basePoints', val);
}
get kickerPoints(): number { return this.get('kickerPoints'); }
set kickerPoints(val: number) { this.set('kickerPoints', val); }
get kickerPoints(): number {
return this.get('kickerPoints');
}
set kickerPoints(val: number) {
this.set('kickerPoints', val);
}
get status(): string { return this.get('status'); }
set status(val: string) { this.set('status', val); }
get status(): string {
return this.get('status');
}
set status(val: string) {
this.set('status', val);
}
get bundles(): string { return this.get('bundles'); }
set bundles(val: string) { this.set('bundles', val); }
get bundles(): string {
return this.get('bundles');
}
set bundles(val: string) {
this.set('bundles', val);
}
get dueDate(): CustomDate { return this.get('dueDate'); }
set dueDate(val: CustomDate) { this.set('dueDate', val); }
get dueDate(): CustomDate {
return this.get('dueDate');
}
set dueDate(val: CustomDate) {
this.set('dueDate', val);
}
get endDate(): CustomDate { return this.get('endDate'); }
set endDate(val: CustomDate) { this.set('endDate', val); }
get endDate(): CustomDate {
return this.get('endDate');
}
set endDate(val: CustomDate) {
this.set('endDate', val);
}
get aatStatus(): string { return this.get('aatStatus'); }
set aatStatus(val: string) { this.set('aatStatus', val); }
get aatStatus(): string {
return this.get('aatStatus');
}
set aatStatus(val: string) {
this.set('aatStatus', val);
}
}
export class Opportunity extends RawEntity {
get name(): string { return this.get('name'); }
set name(val: string) { this.set('name', val); }
get name(): string {
return this.get('name');
}
set name(val: string) {
this.set('name', val);
}
}
export class Account extends RawEntity {
get accountId(): number { return this.get('accountId'); }
set accountId(val: number) { this.set('accountId', val); }
get accountId(): number {
return this.get('accountId');
}
set accountId(val: number) {
this.set('accountId', val);
}
}

View File

@ -9,7 +9,7 @@
import {NgFor} from '@angular/common';
import {Component, Directive} from '@angular/core';
import {HEIGHT, ITEMS, ITEM_HEIGHT, Offering, ROW_WIDTH, VIEW_PORT_HEIGHT, VISIBLE_ITEMS} from './common';
import {HEIGHT, ITEM_HEIGHT, ITEMS, Offering, ROW_WIDTH, VIEW_PORT_HEIGHT, VISIBLE_ITEMS} from './common';
import {generateOfferings} from './random_data';
import {ScrollItemComponent} from './scroll_item';

View File

@ -9,7 +9,7 @@
import {Component, Directive} from '@angular/core';
import {AccountCellComponent, CompanyNameComponent, FormattedCellComponent, OfferingNameComponent, OpportunityNameComponent, StageButtonsComponent} from './cells';
import {AAT_STATUS_WIDTH, ACCOUNT_CELL_WIDTH, BASE_POINTS_WIDTH, BUNDLES_WIDTH, COMPANY_NAME_WIDTH, DUE_DATE_WIDTH, END_DATE_WIDTH, ITEM_HEIGHT, KICKER_POINTS_WIDTH, OFFERING_NAME_WIDTH, OPPORTUNITY_NAME_WIDTH, Offering, STAGE_BUTTONS_WIDTH} from './common';
import {AAT_STATUS_WIDTH, ACCOUNT_CELL_WIDTH, BASE_POINTS_WIDTH, BUNDLES_WIDTH, COMPANY_NAME_WIDTH, DUE_DATE_WIDTH, END_DATE_WIDTH, ITEM_HEIGHT, KICKER_POINTS_WIDTH, Offering, OFFERING_NAME_WIDTH, OPPORTUNITY_NAME_WIDTH, STAGE_BUTTONS_WIDTH} from './common';
@Component({
selector: 'scroll-item',
@ -63,17 +63,41 @@ export class ScrollItemComponent {
itemHeight: number;
constructor() { this.itemHeight = ITEM_HEIGHT; }
constructor() {
this.itemHeight = ITEM_HEIGHT;
}
get companyNameWidth() { return COMPANY_NAME_WIDTH; }
get opportunityNameWidth() { return OPPORTUNITY_NAME_WIDTH; }
get offeringNameWidth() { return OFFERING_NAME_WIDTH; }
get accountCellWidth() { return ACCOUNT_CELL_WIDTH; }
get basePointsWidth() { return BASE_POINTS_WIDTH; }
get kickerPointsWidth() { return KICKER_POINTS_WIDTH; }
get stageButtonsWidth() { return STAGE_BUTTONS_WIDTH; }
get bundlesWidth() { return BUNDLES_WIDTH; }
get dueDateWidth() { return DUE_DATE_WIDTH; }
get endDateWidth() { return END_DATE_WIDTH; }
get aatStatusWidth() { return AAT_STATUS_WIDTH; }
get companyNameWidth() {
return COMPANY_NAME_WIDTH;
}
get opportunityNameWidth() {
return OPPORTUNITY_NAME_WIDTH;
}
get offeringNameWidth() {
return OFFERING_NAME_WIDTH;
}
get accountCellWidth() {
return ACCOUNT_CELL_WIDTH;
}
get basePointsWidth() {
return BASE_POINTS_WIDTH;
}
get kickerPointsWidth() {
return KICKER_POINTS_WIDTH;
}
get stageButtonsWidth() {
return STAGE_BUTTONS_WIDTH;
}
get bundlesWidth() {
return BUNDLES_WIDTH;
}
get dueDateWidth() {
return DUE_DATE_WIDTH;
}
get endDateWidth() {
return END_DATE_WIDTH;
}
get aatStatusWidth() {
return AAT_STATUS_WIDTH;
}
}

View File

@ -23,7 +23,7 @@ export function init(moduleRef: NgModuleRef<StylingModule>) {
const componentRef = appRef.components[0];
const component = componentRef.instance;
const componentHostEl = componentRef.location.nativeElement;
const select = document.querySelector('#scenario-select') !as HTMLSelectElement;
const select = document.querySelector('#scenario-select')! as HTMLSelectElement;
function create(tplRefIdx: number) {
component.tplRefIdx = tplRefIdx;
@ -41,7 +41,9 @@ export function init(moduleRef: NgModuleRef<StylingModule>) {
appRef.tick();
}
function detectChanges() { appRef.tick(); }
function detectChanges() {
appRef.tick();
}
function modifyExternally() {
const buttonEls = componentHostEl.querySelectorAll('button') as HTMLButtonElement[];

View File

@ -35,7 +35,9 @@ export class StylingComponent {
tplRefIdx: number = 0;
staticStyle = {width: '10px'};
getTplRef(...tplRefs): TemplateRef<any> { return tplRefs[this.tplRefIdx]; }
getTplRef(...tplRefs): TemplateRef<any> {
return tplRefs[this.tplRefIdx];
}
}
@NgModule({

View File

@ -28,7 +28,7 @@ const SCENARIOS = [
describe('styling benchmark spec', () => {
afterEach(verifyNoBrowserErrors);
it('should render and interact to update and detect changes', async() => {
it('should render and interact to update and detect changes', async () => {
openBrowser({url: '/', ignoreBrowserSynchronization: true});
create();
const items = element.all(by.css('styling-bindings button'));
@ -38,7 +38,7 @@ describe('styling benchmark spec', () => {
expect(await items.first().getAttribute('title')).toBe('baz');
});
it('should render and run noop change detection', async() => {
it('should render and run noop change detection', async () => {
openBrowser({url: '/', ignoreBrowserSynchronization: true});
create();
const items = element.all(by.css('styling-bindings button'));
@ -51,7 +51,7 @@ describe('styling benchmark spec', () => {
// Create benchmarks for each possible test scenario.
SCENARIOS.forEach(({optionIndex, id}) => {
describe(id, () => {
it('should run create benchmark', async() => {
it('should run create benchmark', async () => {
await runStylingBenchmark(`styling.${id}.create`, {
work: () => create(),
prepare: () => {
@ -61,7 +61,7 @@ describe('styling benchmark spec', () => {
});
});
it('should run update benchmark', async() => {
it('should run update benchmark', async () => {
await runStylingBenchmark(`styling.${id}.update`, {
work: () => update(),
prepare: () => {
@ -71,7 +71,7 @@ describe('styling benchmark spec', () => {
});
});
it('should run detect changes benchmark', async() => {
it('should run detect changes benchmark', async () => {
await runStylingBenchmark(`styling.${id}.noop_cd`, {
work: () => detectChanges(),
prepare: () => {

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {TreeNode, newArray} from '../util';
import {newArray, TreeNode} from '../util';
export class TreeComponent {
private _renderNodes: any[];

View File

@ -17,7 +17,9 @@ const {patch, elementOpen, elementClose, elementOpenStart, elementOpenEnd, text,
export class TreeComponent {
constructor(private _rootEl: any) {}
set data(data: TreeNode) { patch(this._rootEl, () => this._render(data)); }
set data(data: TreeNode) {
patch(this._rootEl, () => this._render(data));
}
private _render(data: TreeNode) {
elementOpenStart('span', '', null);

View File

@ -15,7 +15,7 @@ declare var angular: any;
function init() {
let detectChangesRuns = 0;
const numberOfChecksEl = document.getElementById('numberOfChecks') !;
const numberOfChecksEl = document.getElementById('numberOfChecks')!;
addTreeToModule(angular.module('app', [])).run([
'$rootScope',
@ -31,11 +31,15 @@ function init() {
function noop() {}
function destroyDom() {
$rootScope.$apply(() => { $rootScope.initData = emptyTree; });
$rootScope.$apply(() => {
$rootScope.initData = emptyTree;
});
}
function createDom() {
$rootScope.$apply(() => { $rootScope.initData = buildTree(); });
$rootScope.$apply(() => {
$rootScope.initData = buildTree();
});
}
bindAction('#destroyDom', destroyDom);

View File

@ -41,7 +41,6 @@ export function addTreeToModule(mod: any): any {
}
let childElement: any, childScope: any;
$scope.$watch($attr.data, function ngIfWatchAction(value: any) {
if (value) {
if (!childScope) {
childScope = $scope.$new();
@ -67,6 +66,8 @@ export function addTreeToModule(mod: any): any {
])
.config([
'$compileProvider',
function($compileProvider: any) { $compileProvider.debugInfoEnabled(false); }
function($compileProvider: any) {
$compileProvider.debugInfoEnabled(false);
}
]);
}

View File

@ -40,7 +40,7 @@ export function init(moduleRef: NgModuleRef<AppModule>) {
const injector = moduleRef.injector;
appRef = injector.get(ApplicationRef);
const numberOfChecksEl = document.getElementById('numberOfChecks') !;
const numberOfChecksEl = document.getElementById('numberOfChecks')!;
tree = appRef.components[0].instance;

View File

@ -9,7 +9,7 @@
import {Component, NgModule} from '@angular/core';
import {BrowserModule, DomSanitizer, SafeStyle} from '@angular/platform-browser';
import {TreeNode, emptyTree} from '../util';
import {emptyTree, TreeNode} from '../util';
let trustedEmptyColor: SafeStyle;
let trustedGreyColor: SafeStyle;
@ -22,7 +22,9 @@ let trustedGreyColor: SafeStyle;
})
export class TreeComponent {
data: TreeNode = emptyTree;
get bgColor() { return this.data.depth % 2 ? trustedEmptyColor : trustedGreyColor; }
get bgColor() {
return this.data.depth % 2 ? trustedEmptyColor : trustedGreyColor;
}
}
@NgModule({imports: [BrowserModule], bootstrap: [TreeComponent], declarations: [TreeComponent]})

View File

@ -7,17 +7,19 @@
*/
import {NgIf} from '@angular/common';
import {ComponentFactory, ComponentFactoryResolver, ComponentRef, ErrorHandler, Injector, NgModuleRef, RendererFactory2, Sanitizer, TemplateRef, ViewContainerRef, ɵArgumentType as ArgumentType, ɵBindingFlags as BindingFlags, ɵNodeFlags as NodeFlags, ɵViewDefinition as ViewDefinition, ɵViewFlags as ViewFlags, ɵand as anchorDef, ɵccf as createComponentFactory, ɵdid as directiveDef, ɵeld as elementDef, ɵinitServicesIfNeeded as initServicesIfNeeded, ɵted as textDef, ɵvid as viewDef} from '@angular/core';
import {ComponentFactory, ComponentFactoryResolver, ComponentRef, ErrorHandler, Injector, NgModuleRef, RendererFactory2, Sanitizer, TemplateRef, ViewContainerRef, ɵand as anchorDef, ɵArgumentType as ArgumentType, ɵBindingFlags as BindingFlags, ɵccf as createComponentFactory, ɵdid as directiveDef, ɵeld as elementDef, ɵinitServicesIfNeeded as initServicesIfNeeded, ɵNodeFlags as NodeFlags, ɵted as textDef, ɵvid as viewDef, ɵViewDefinition as ViewDefinition, ɵViewFlags as ViewFlags} from '@angular/core';
import {SafeStyle, ɵDomRendererFactory2 as DomRendererFactory2, ɵDomSanitizerImpl as DomSanitizerImpl} from '@angular/platform-browser';
import {TreeNode, emptyTree} from '../util';
import {emptyTree, TreeNode} from '../util';
let trustedEmptyColor: SafeStyle;
let trustedGreyColor: SafeStyle;
export class TreeComponent {
data: TreeNode = emptyTree;
get bgColor() { return this.data.depth % 2 ? trustedEmptyColor : trustedGreyColor; }
get bgColor() {
return this.data.depth % 2 ? trustedEmptyColor : trustedGreyColor;
}
}
let viewFlags = ViewFlags.None;
@ -120,11 +122,19 @@ export class AppModule implements Injector, NgModuleRef<any> {
this.componentFactory.create(Injector.NULL, [], this.componentFactory.selector, this);
}
tick() { this.componentRef.changeDetectorRef.detectChanges(); }
tick() {
this.componentRef.changeDetectorRef.detectChanges();
}
get injector() { return this; }
get componentFactoryResolver(): ComponentFactoryResolver { return null; }
get instance() { return this; }
get injector() {
return this;
}
get componentFactoryResolver(): ComponentFactoryResolver {
return null;
}
get instance() {
return this;
}
destroy() {}
onDestroy(callback: () => void) {}
}

View File

@ -9,24 +9,25 @@
import {Component, Input, NgModule} from '@angular/core';
import {BrowserModule, DomSanitizer, SafeStyle} from '@angular/platform-browser';
import {TreeNode, emptyTree, getMaxDepth} from '../util';
import {emptyTree, getMaxDepth, TreeNode} from '../util';
let trustedEmptyColor: SafeStyle;
let trustedGreyColor: SafeStyle;
function createTreeComponent(level: number, isLeaf: boolean) {
const nextTreeEl = `tree${level+1}`;
const nextTreeEl = `tree${level + 1}`;
let template = `<span [style.backgroundColor]="bgColor"> {{data.value}} </span>`;
if (!isLeaf) {
template +=
`<${nextTreeEl} [data]='data.right'></${nextTreeEl}><${nextTreeEl} [data]='data.left'></${nextTreeEl}>`;
template += `<${nextTreeEl} [data]='data.right'></${nextTreeEl}><${
nextTreeEl} [data]='data.left'></${nextTreeEl}>`;
}
@Component({selector: `tree${level}`, template: template})
class TreeComponent {
@Input()
data: TreeNode;
get bgColor() { return this.data.depth % 2 ? trustedEmptyColor : trustedGreyColor; }
@Input() data: TreeNode;
get bgColor() {
return this.data.depth % 2 ? trustedEmptyColor : trustedGreyColor;
}
}
return TreeComponent;
@ -34,8 +35,7 @@ function createTreeComponent(level: number, isLeaf: boolean) {
@Component({selector: 'tree', template: `<tree0 *ngIf="data.left != null" [data]='data'></tree0>`})
export class RootTreeComponent {
@Input()
data: TreeNode = emptyTree;
@Input() data: TreeNode = emptyTree;
}
function createModule(): any {

View File

@ -9,7 +9,7 @@
import {Component, Input, NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {TreeNode, emptyTree} from '../util';
import {emptyTree, TreeNode} from '../util';
@Component({
selector: 'tree',
@ -19,8 +19,7 @@ import {TreeNode, emptyTree} from '../util';
<tree *ngIf='data.right != null' [data]='data.right'></tree><tree *ngIf='data.left != null' [data]='data.left'></tree>`
})
export class TreeComponent {
@Input()
data: TreeNode = emptyTree;
@Input() data: TreeNode = emptyTree;
}
@NgModule({

View File

@ -7,8 +7,10 @@
*/
import {ɵrenderComponent as renderComponent} from '@angular/core';
import {bindAction, profile} from '../../util';
import {TreeComponent, createDom, destroyDom, detectChanges} from './tree';
import {createDom, destroyDom, detectChanges, TreeComponent} from './tree';
function noop() {}

View File

@ -21,7 +21,7 @@ export function createDom(component: TreeComponent) {
ɵdetectChanges(component);
}
const numberOfChecksEl = document.getElementById('numberOfChecks') !;
const numberOfChecksEl = document.getElementById('numberOfChecks')!;
let detectChangesRuns = 0;
export function detectChanges(component: TreeComponent) {
for (let i = 0; i < 10; i++) {
@ -42,7 +42,9 @@ export function detectChanges(component: TreeComponent) {
})
export class TreeComponent {
data: any = emptyTree;
get bgColor() { return this.data.depth % 2 ? '' : 'grey'; }
get bgColor() {
return this.data.depth % 2 ? '' : 'grey';
}
}
@NgModule({declarations: [TreeComponent], imports: [CommonModule]})

View File

@ -6,11 +6,11 @@
* found in the LICENSE file at https://angular.io/license
*/
import {ɵRenderFlags, ɵrenderComponent as renderComponent, ɵɵadvance, ɵɵcontainer, ɵɵcontainerRefreshEnd, ɵɵcontainerRefreshStart, ɵɵdefineComponent, ɵɵelementEnd, ɵɵelementStart, ɵɵembeddedViewEnd, ɵɵembeddedViewStart, ɵɵstyleProp, ɵɵtext, ɵɵtextInterpolate1} from '@angular/core';
import {ɵrenderComponent as renderComponent, ɵRenderFlags, ɵɵadvance, ɵɵcontainer, ɵɵcontainerRefreshEnd, ɵɵcontainerRefreshStart, ɵɵdefineComponent, ɵɵelementEnd, ɵɵelementStart, ɵɵembeddedViewEnd, ɵɵembeddedViewStart, ɵɵstyleProp, ɵɵtext, ɵɵtextInterpolate1} from '@angular/core';
import {bindAction, profile} from '../../util';
import {createDom, destroyDom, detectChanges} from '../render3/tree';
import {TreeNode, emptyTree} from '../util';
import {emptyTree, TreeNode} from '../util';
function noop() {}
@ -26,15 +26,16 @@ export class TreeFunction {
selectors: [['tree']],
decls: 5,
vars: 2,
template: function(rf: ɵRenderFlags, ctx: TreeFunction) {
// bit of a hack
TreeTpl(rf, ctx.data);
},
template:
function(rf: ɵRenderFlags, ctx: TreeFunction) {
// bit of a hack
TreeTpl(rf, ctx.data);
},
inputs: {data: 'data'}
});
}
const TreeFunctionCmpDef = TreeFunction.ɵcmp as{decls: number, vars: number};
const TreeFunctionCmpDef = TreeFunction.ɵcmp as {decls: number, vars: number};
export function TreeTpl(rf: ɵRenderFlags, ctx: TreeNode) {
if (rf & ɵRenderFlags.Create) {
ɵɵelementStart(0, 'tree');

View File

@ -11,7 +11,7 @@ import {$} from 'protractor';
import {openTreeBenchmark} from './test_utils';
describe('tree benchmark', () => {
it('should work for createDestroy', async() => {
it('should work for createDestroy', async () => {
openTreeBenchmark();
await $('#createDom').click();
expect($('#root').getText()).toContain('1');
@ -19,7 +19,7 @@ describe('tree benchmark', () => {
expect(await $('#root').getText()).toEqual('');
});
it('should work for update', async() => {
it('should work for update', async () => {
openTreeBenchmark();
await $('#createDom').click();
await $('#createDom').click();

View File

@ -10,7 +10,7 @@ import {$} from 'protractor';
import {runTreeBenchmark} from './test_utils';
describe('tree benchmark perf', () => {
it('should work for createOnly', async() => {
it('should work for createOnly', async () => {
await runTreeBenchmark({
// This cannot be called "createOnly" because the actual destroy benchmark
// has the "createOnly" id already. See: https://github.com/angular/angular/pull/21503
@ -20,7 +20,7 @@ describe('tree benchmark perf', () => {
});
});
it('should work for destroy', async() => {
it('should work for destroy', async () => {
await runTreeBenchmark({
// This is actually a benchmark for destroying the dom, but it has been accidentally
// named "createOnly". See https://github.com/angular/angular/pull/21503.
@ -30,7 +30,7 @@ describe('tree benchmark perf', () => {
});
});
it('should work for createDestroy', async() => {
it('should work for createDestroy', async () => {
await runTreeBenchmark({
id: 'createDestroy',
work: () => {
@ -40,7 +40,7 @@ describe('tree benchmark perf', () => {
});
});
it('should work for update', async() => {
it('should work for update', async () => {
await runTreeBenchmark({
id: 'update',
work: () => $('#createDom').click(),

View File

@ -11,7 +11,7 @@ import {$} from 'protractor';
import {openTreeBenchmark} from './test_utils';
describe('tree benchmark detect changes', () => {
it('should work for detectChanges', async() => {
it('should work for detectChanges', async () => {
openTreeBenchmark();
await $('#detectChanges').click();
expect($('#numberOfChecks').getText()).toContain('10');

View File

@ -10,7 +10,7 @@ import {$} from 'protractor';
import {runTreeBenchmark} from './test_utils';
describe('tree benchmark detect changes perf', () => {
it('should work for detectChanges', async() => {
it('should work for detectChanges', async () => {
await runTreeBenchmark({
id: 'detectChanges',
work: () => $('#detectChanges').click(),

View File

@ -16,12 +16,14 @@ export class TreeNode {
public value: string, public depth: number, public maxDepth: number,
public left: TreeNode|null, public right: TreeNode|null) {
this.transitiveChildCount = Math.pow(2, (this.maxDepth - this.depth + 1)) - 1;
this.children = this.left ? [this.left, this.right !] : [];
this.children = this.left ? [this.left, this.right!] : [];
}
// Needed for Polymer as it does not support ternary nor modulo operator
// in expressions
get style(): string { return this.depth % 2 === 0 ? 'background-color: grey' : ''; }
get style(): string {
return this.depth % 2 === 0 ? 'background-color: grey' : '';
}
}
let treeCreateCount: number;
@ -78,7 +80,7 @@ export function newArray<T>(size: number, value: T): T[];
export function newArray<T>(size: number, value?: T): T[] {
const list: T[] = [];
for (let i = 0; i < size; i++) {
list.push(value !);
list.push(value!);
}
return list;
}

View File

@ -35,7 +35,7 @@ export function getStringParameter(name: string) {
}
export function bindAction(selector: string, callback: () => void) {
document.querySelector(selector) !.addEventListener('click', callback);
document.querySelector(selector)!.addEventListener('click', callback);
}
@ -66,7 +66,8 @@ function reportProfileResults(durations: number[], count: number) {
Number.MAX_SAFE_INTEGER)
.toFixed(2);
window.console.log(
`Iterations: ${count}; cold time: ${durations[0].toFixed(2)} ms; average time: ${avgDuration} ms / iteration; best time: ${minDuration} ms`);
`Iterations: ${count}; cold time: ${durations[0].toFixed(2)} ms; average time: ${
avgDuration} ms / iteration; best time: ${minDuration} ms`);
}
// helper script that will read out the url parameters

View File

@ -20,7 +20,9 @@ export class ViewManipulationDirective {
}
}
clear() { this._vcRef.clear(); }
clear() {
this._vcRef.clear();
}
}
@Component({
@ -44,9 +46,13 @@ export class ViewsBenchmark {
constructor(private _cdRef: ChangeDetectorRef) {}
create(vm: ViewManipulationDirective) { vm.create(1000); }
create(vm: ViewManipulationDirective) {
vm.create(1000);
}
destroy(vm: ViewManipulationDirective) { vm.clear(); }
destroy(vm: ViewManipulationDirective) {
vm.clear();
}
check() {
for (let i = 0; i < 10000; i++) {

View File

@ -11,7 +11,6 @@ import {browser} from 'protractor';
import {verifyNoBrowserErrors} from '../../../e2e_util/e2e_util';
describe('hello world', function() {
afterEach(verifyNoBrowserErrors);
describe('hello world app', function() {
@ -30,7 +29,6 @@ describe('hello world', function() {
expect(getComponentText('hello-app', '.greeting')).toEqual('howdy world!');
});
});
});
function getComponentText(selector: string, innerSelector: string) {

View File

@ -11,7 +11,6 @@ import {browser} from 'protractor';
import {verifyNoBrowserErrors} from '../../../e2e_util/e2e_util';
describe('http', function() {
afterEach(verifyNoBrowserErrors);
describe('fetching', function() {
@ -25,6 +24,6 @@ describe('http', function() {
});
function getComponentText(selector: string, innerSelector: string) {
return browser.executeScript(
`return document.querySelector("${selector}").querySelector("${innerSelector}").textContent.trim()`);
return browser.executeScript(`return document.querySelector("${selector}").querySelector("${
innerSelector}").textContent.trim()`);
}

View File

@ -11,7 +11,6 @@ import {browser} from 'protractor';
import {verifyNoBrowserErrors} from '../../../e2e_util/e2e_util';
describe('jsonp', function() {
afterEach(verifyNoBrowserErrors);
describe('fetching', function() {
@ -25,6 +24,6 @@ describe('jsonp', function() {
});
function getComponentText(selector: string, innerSelector: string) {
return browser.executeScript(
`return document.querySelector("${selector}").querySelector("${innerSelector}").textContent.trim()`);
return browser.executeScript(`return document.querySelector("${selector}").querySelector("${
innerSelector}").textContent.trim()`);
}

View File

@ -13,11 +13,12 @@ import {verifyNoBrowserErrors} from '../../../e2e_util/e2e_util';
const Key = protractor.Key;
describe('key_events', function() {
const URL = '/';
afterEach(verifyNoBrowserErrors);
beforeEach(() => { browser.get(URL); });
beforeEach(() => {
browser.get(URL);
});
it('should display correct key names', function() {
const firstArea = element.all(by.css('.sample-area')).get(0);
@ -78,5 +79,4 @@ describe('key_events', function() {
secondArea.sendKeys(Key.CONTROL, Key.SHIFT, Key.ENTER);
expect(secondArea.getText()).toEqual('');
});
});

View File

@ -11,7 +11,6 @@ import {browser, by, element} from 'protractor';
import {verifyNoBrowserErrors} from '../../../e2e_util/e2e_util';
describe('Model-Driven Forms', function() {
afterEach(verifyNoBrowserErrors);
const URL = '/';

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {$, ExpectedConditions, browser, by, element} from 'protractor';
import {$, browser, by, element, ExpectedConditions} from 'protractor';
import {verifyNoBrowserErrors} from '../../../e2e_util/e2e_util';
@ -16,7 +16,6 @@ function waitForElement(selector: string) {
}
describe('relative assets relative-app', () => {
afterEach(verifyNoBrowserErrors);
const URL = '/';

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {$, ExpectedConditions, browser, by, element} from 'protractor';
import {$, browser, by, element, ExpectedConditions} from 'protractor';
import {verifyNoBrowserErrors} from '../../../e2e_util/e2e_util';
@ -16,7 +16,6 @@ function waitForElement(selector: string) {
}
describe('routing inbox-app', () => {
afterEach(verifyNoBrowserErrors);
describe('index view', () => {

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