Compare commits

..

47 Commits
9.1.1 ... 9.1.2

Author SHA1 Message Date
793a001d7c release: cut the v9.1.2 release 2020-04-15 15:45:54 -07:00
5c3774cfe6 Revert "fix(common): locales/global/*.js are not ES5 compliant (#36342)" (#36648)
This reverts commit c8f3fa9f3e.

PR Close #36648
2020-04-15 15:33:59 -07:00
12266b2042 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
e385abc83c 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
933cbfb828 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
c5e725111d 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
93993864b1 build: update to latest version of yarn (#36464)
PR Close #36464
2020-04-14 12:47:31 -07:00
26f49151e7 build: reformat repo to new clang@1.4.0 (#36628)
PR Close #36628
2020-04-14 12:07:43 -07:00
4b3f9ac739 refactor(language-service): clean up and exports and consolidate types (#36533)
PR Close #36533
2020-04-14 10:17:43 -07:00
80604d3a76 style: lint (#36580)
PR Close #36580
2020-04-14 10:12:59 -07:00
e615a10371 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
c8f2ca2349 docs: edit to setup-local (#36168)
PR Close #36168
2020-04-13 17:33:35 -07:00
a67afcc932 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
fd7698253e docs: move ng-conf 2020 to the already presented section (#36413)
PR Close #36413
2020-04-13 08:20:04 -07:00
32de025dce 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
a4e1768a74 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
b336871303 docs: fix typo in Tests guide (#36592)
PR Close #36592
2020-04-13 08:17:27 -07:00
92fa6399f7 docs(zone.js): fix typos in NgZone guide code example (#36597)
Fixes #36594

PR Close #36597
2020-04-13 08:16:59 -07:00
3992341d34 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
8c559ef104 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
0bac2b062c 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
58d028178f 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:28 -07:00
e06512b22f perf(ngcc): only load if it is needed (#36486)
PR Close #36486
2020-04-09 11:33:29 -07:00
603b0944d5 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:29 -07:00
918e628f9b 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
468cf69c55 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:22 -07:00
c8f3fa9f3e 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
78136cc3a7 style: format forms validators to fix lint error (#36546)
PR Close #36546
2020-04-09 11:18:22 -07:00
66724fd159 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
8e7f9033a3 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
c8f9092364 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:19 -07:00
bc995835b9 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:57 -07:00
1bfa908ab3 style: typescript lint fix (#36531)
PR Close #36531
2020-04-09 00:59:22 +00:00
2479f7d7ef Revert "refactor(bazel): use runfiles helper in ts-api-guardian (#36471)" (#36531)
This reverts commit 92c4f3d508.

PR Close #36531
2020-04-09 00:59:22 +00:00
333b8679ad 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
5da621d3dd fix(language-service): remove circular dependency instance (#36463)
PR Close #36463
2020-04-08 15:29:09 -07:00
cbed582a1a 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
d5aa6b5bd6 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
33eee43263 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
72053b0f27 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
d20ef47b16 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:59 -07:00
bdc05aef64 docs: update the Support policy and schedule (#35390)
PR Close #35359

PR Close #35390
2020-04-08 12:12:32 -07:00
798d959bee 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:29 -07:00
3570aaa363 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
421b6a97d6 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:35 -07:00
b28a5f6eef 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
52ab9397a0 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
1675 changed files with 50055 additions and 39215 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,28 @@
<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="9.1.1"></a>
## [9.1.1](https://github.com/angular/angular/compare/9.1.0...9.1.1) (2020-04-07)

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

@ -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

@ -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

@ -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

@ -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', () => {

View File

@ -11,15 +11,15 @@ import {browser, by, element} from 'protractor';
import {verifyNoBrowserErrors} from '../../../e2e_util/e2e_util';
describe('SVG', function() {
const URL = '/';
afterEach(verifyNoBrowserErrors);
beforeEach(() => { browser.get(URL); });
beforeEach(() => {
browser.get(URL);
});
it('should display SVG component contents', function() {
const svgText = element.all(by.css('g text')).get(0);
expect(svgText.getText()).toEqual('Hello');
});
});

View File

@ -11,7 +11,6 @@ import {browser, by, element} from 'protractor';
import {verifyNoBrowserErrors} from '../../../e2e_util/e2e_util';
describe('Template-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, protractor} from 'protractor';
import {browser, by, element, ExpectedConditions, protractor} from 'protractor';
import {verifyNoBrowserErrors} from '../../../../e2e_util/e2e_util';

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