Compare commits

...

63 Commits
9.0.1 ... 8.2.2

Author SHA1 Message Date
033fc3e6e5 release: cut the v8.2.2 release 2019-08-12 13:19:30 -07:00
76854287e5 Revert "fix(compiler): do not remove whitespace wrapping i18n expansions (#31962)" (#32110)
This reverts commit 6ec91dd4ca because it contains
a breaking change (and thus should only be on the master branch).

PR Close #32110
2019-08-12 13:15:19 -07:00
972550ee08 style: fix inline comment typo (#32090)
PR Close #32090
2019-08-12 07:06:01 -07:00
c67f490d28 build: ensure fixup commits match an earlier, unmerged commit (#32023)
Previously, `validate-commit-message` would treat `fixup! `-prefixed
commits like this:
- It would strip the `fixup! ` prefix.
- It would validate the rest of the commit message header as any other
  commit.

However, fixup commits are special in that they need to exactly match an
earlier commit message header (sans the `fixup! ` prefix) in order for
git to treat them correctly. Otherwise, they will not be squashed into
the original commits and will be merged as is. Fixup commits can end up
not matching their original commit for several reasons (e.g. accidental
typo, changing the original commit message, etc.).

This commit prevents invalid fixup commits to pass validation by
ensuring that they match an earlier (unmerged) commit (i.e. a commit
between the current HEAD and the BASE commit).

NOTE: This new behavior is currently not activated in the pre-commit git
      hook, that is used to validate commit messages (because the
      preceding, unmerged commits are not available there). It _is_
      activated in `gulp validate-commit-message`, which is run as part
      of the `lint` job on CI and thus will detect invalid commits,
      before their getting merged.

PR Close #32023
2019-08-09 15:12:38 -07:00
edd6cb5865 fix: do not allow squash! commits when merging (#32023)
While `fixup! ` is fine, `squash! ` means that the commit message needs
tweaking, which cannot be done automatically during merging (i.e. it
should be done by the PR author).

Previously, `validate-commit-message` would always allow
`squash! `-prefixed commits, which would cause problems during merging.

This commit changes `validate-commit-message` to make it configurable
whether such commits are allowed and configures the
`gulp validate-commit-message` task, which is run as part of the `lint`
job on CI, to not allow them.

NOTE: This new check is disabled in the pre-commit git hook that is used
      to validate commit messages, because these commits might still be
      useful during development.

PR Close #32023
2019-08-09 15:12:38 -07:00
7b2617f087 refactor: clean up validate-commit-message script (#32023)
This sets the ground for adding stricter rules for fixup commits in a
follow-up PR.

PR Close #32023
2019-08-09 15:12:38 -07:00
d9d06899f4 test: clean up and re-organize validate-commit-message tests (#32023)
Mainly making the tests more closely follow the order of checks in the
function implementation, so that it is easier to follow.

PR Close #32023
2019-08-09 15:12:38 -07:00
eccb60cd6e test: update golden files (#32069)
PR Close #32069
2019-08-09 14:15:25 -07:00
3420d2923a fix(bazel): disable treeshaking when generating FESM and UMD bundles (#32069)
There has been a regression where enabling rollup treeshaking causes errors during runtime because it will drop const access which will always evaluate to true or false. However, such `const` in `@angular/core` cannot be dropped because their value is changed when NGCC is run on `@angular/core`

VE
```
const SWITCH_IVY_ENABLED__POST_R3__ = true;
const SWITCH_IVY_ENABLED__PRE_R3__ = false;
const ivyEnabled = SWITCH_IVY_ENABLED__PRE_R3__;
```

Ivy (After NGCC)
```
const SWITCH_IVY_ENABLED__POST_R3__ = true;
const SWITCH_IVY_ENABLED__PRE_R3__ = false;
const ivyEnabled = SWITCH_IVY_ENABLED__POST_R3__;
```

FESM2015
```
load(path) {
	/** @type {?} */
	const legacyOfflineMode = this._compiler instanceof Compiler;
	return legacyOfflineMode ? this.loadFactory(path) : this.loadAndCompile(path);
}
```

ESM2015
```
 load(path) {
	/** @type {?} */
	const legacyOfflineMode = !ivyEnabled && this._compiler instanceof Compiler;
	return legacyOfflineMode ? this.loadFactory(path) : this.loadAndCompile(path);
}
```

From the above we can see that `ivyEnabled ` is being treeshaken away when generating the FESM bundle which is causing runtime errors such as `Cannot find module './lazy/lazy.module.ngfactory'` since in Ivy we will always load the factories.

PR Close #32069
2019-08-09 14:15:25 -07:00
6ec91dd4ca fix(compiler): do not remove whitespace wrapping i18n expansions (#31962)
Similar to interpolation, we do not want to completely remove whitespace
nodes that are siblings of an expansion.

For example, the following template

```html
<div>
  <strong>items left<strong> {count, plural, =1 {item} other {items}}
</div>
```

was being collapsed to

```html
<div><strong>items left<strong>{count, plural, =1 {item} other {items}}</div>
```

which results in the text looking like

```
items left4
```

instead it should be collapsed to

```html
<div><strong>items left<strong> {count, plural, =1 {item} other {items}}</div>
```

which results in the text looking like

```
items left 4
```

---

**Analysis of the code and manual testing has shown that this does not cause
the generated ids to change, so there is no breaking change here.**

PR Close #31962
2019-08-09 12:03:51 -07:00
90ddee7a71 ci: remove codefresh config and supporting files (#32058)
PR Close #32058
2019-08-09 10:53:21 -07:00
3300331691 docs: clarify pipe naming (#31806)
PR Close #31806
2019-08-09 10:45:49 -07:00
6f3414bd68 docs: fix cli builder doc (#31305)
PR Close #31305
2019-08-09 10:42:23 -07:00
1b0bd6b706 release: cut the v8.2.1 release 2019-08-08 13:42:58 -07:00
cfaefa9964 fix(ivy): set LOCALE_ID when using the injector (#31983)
In `BrowserModule` the value of `LOCALE_ID` is defined in the `APPLICATION_MODULE_PROVIDERS` after `APP_INITIALIZER` has run.
This PR ensures that `LOCALE_ID` is also set for ivy at the same moment which allows the application to fetch the locale from a backend (for example).

Fixes #31465

FW-1436 #resolve

PR Close #31983
2019-08-08 12:49:58 -07:00
a48376b26a docs(router): rename incorrect class names (#31815)
PR Close #31815
2019-08-08 12:16:47 -07:00
e6d8274c38 docs: correct description of output decorator and add links to guide (#31780)
PR Close #31780
2019-08-08 12:15:29 -07:00
40df016390 docs: update rxjs refs (#31780)
PR Close #31780
2019-08-08 12:15:29 -07:00
eee75c2eea docs: add note on compatibility mode (#31808)
PR Close #31808
2019-08-08 12:13:57 -07:00
96aefc5019 docs: remove download for testing examples (#31949)
Examples for testing are designed specifically to run in StackBlitz and
are not regular cli projects (e.g. their `main.ts` files may load and run
tests instead of bootstrapping an app). They are not intended to be
downloaded and built/run locally using the cli.

In order to avoid confusing users, this commit removes the download links
from the guide. If desired, the projects can still be exported locally
via StackBlitz's UI.

Related to #31020 and #31937.

PR Close #31949
2019-08-08 12:13:29 -07:00
038d823943 docs: remove extraneous word from sentence in styleguide (#32038)
PR Close #32038
2019-08-08 11:43:12 -07:00
19095835a4 docs: add missing Oxford comma in styleguide (#32040)
PR Close #32040
2019-08-08 11:42:37 -07:00
b560207bf5 build(docs-infra): ensure the locally built packages exist and are up-to-date in yarn setup-local (#31985)
The `setup-local` npm script uses `NgPackagesInstaller` to replace the
Angular packages with the locally built ones. Previously, it would (a)
assume that the packages were built and (b) it would do anything if the
currently installed versions already correspond to locally built
packages (even if not the latest version).
This could lead to all sorts of errors, such as:
- Confusing error messages, `dist/packages-dist/` was missing.
- Using outdated build artifacts from `dist/packages-dist/` without a
  warning.
- Not installing the latest locally built packages, because the ones
  installed already corresponded to locally built (but older) ones.

This commit fixes these issues by ensuring that:
- The local packages are always built before being used by
  `NgPackagesInstaller`.
- The local packages are installed, even if the ones install already
  correspond to local packages.

NOTE: Special `*-ci` scripts are introduced (for use on CI) that skip
      building the local packages, since that step would have been taken
      care of (in a more efficient way) in a previous CI step.

PR Close #31985
2019-08-08 11:30:38 -07:00
c5de1fb05f fix(docs-infra): correctly handle multiple occurrences of an option in NgPackagesInstaller (#31985)
PR Close #31985
2019-08-08 11:30:38 -07:00
62a9843ed0 feat(docs-infra): support building the local Angular packages in NgPackagesInstaller (#31985)
Previously, when `NgPackagesInstaller` needed to install the local
Angular packages to a project, it assumed the `dist/packages-dist/`
would exist and contain up-to-date built packages. I.e. it was up to the
user to have built the packages first (by running the appropriate
script).
However, many people not familiar with the `aio/` infrastructure assumed
that `yarn build-local` or `yarn build-with-ivy` would take care of all
the necessary steps.

To avoid getting confusing errors (or worse yet, using outdated local
packages), `NgPackagesInstaller` now has an option to build the packages
before using them.
One caveat is that the build script does not currently work on Windows,
so a warning is printed instead, letting the user know they need to
(somehow) take care of it themselves.

NOTE 1: Since the build script is using bazel, running it should not be
        expensive if the directory is up-to-date (i.e. no changes have
        been made to source code after the last build).
NOTE 2: This commit adds support for `--build-packages`, but does not
        change the default behavior (not building the packages). It will
        be turned on in a subsequent commit.

PR Close #31985
2019-08-08 11:30:38 -07:00
75a162575f refactor(docs-infra): minor refactorings and code simplification in NgPackagesInstaller (#31985)
PR Close #31985
2019-08-08 11:30:38 -07:00
5bf912599f docs: remove duplicate sentence in toh-pt5 (#32021)
PR Close #32021
2019-08-08 11:19:37 -07:00
afd76a80da docs: use proper case in styleguide sentence (#32039)
PR Close #32039
2019-08-08 11:15:52 -07:00
bb4627786d docs: update node:8-browsers to 10 in testing (#32049)
Fixes #31993

PR Close #32049
2019-08-08 11:15:23 -07:00
83d67b4a83 docs: add doc for compiler options (#31829)
PR Close #31829
2019-08-05 13:01:11 -07:00
6ba31b9b84 docs: updated doc for timezone param in DatePipe (#31827)
PR Close #31827
2019-08-05 13:00:26 -07:00
a1c43b39a2 docs: updated doc for timezone param in DatePipe (#31827)
PR Close #31827
2019-08-05 13:00:26 -07:00
af91c21fd9 docs: fix typo in Workspace Config guide code snippet (sourceMaps --> sourceMap) (#31957)
PR Close #31957
2019-08-05 12:57:18 -07:00
c00e7ff128 fix(docs-infra): ui polish (#31013)
- Change margin to the header so that the the label aligns with the header
- Make code in API pages pre-wrap so that you can see the actual text on the screen - helps with issue #27296
- Modified text to be title case in label API to be consistent with rest of app labels
- Removed unused table of contents SCSS file
- TOC SCSS file reorg cleanup
- Soften headers font-weight in API pages
- Make linenums ordered list inside code examples always show as numbers

PR Close #31013
2019-08-05 12:53:02 -07:00
3bf2f98c35 refactor(upgrade): avoid using static inherited method (#31986)
Using `ParentInjectorPromise.all()` (which is a static method inherited
from `SyncPromise`) causes Closure Compiler (or some related tool) to
complain:

```
TypeError: ...$packages$upgrade$src$common$src$downgrade_component_ParentInjectorPromise.all is not a function
```

Switching to `SyncPromise.all()` (the static method on the parent class)
to avoid this error.

PR Close #31986
2019-08-05 10:01:33 -07:00
2cabced9fc build(docs-infra): fix StackBlitz projects and ZIPs for testing guide examples (#31937)
- Update the `stackblitz.json` config files (used for generating
  Stackblitz projects and ZIP archives) to include the correct files
  (taking into account the current layout of the example projects).
- Update the boilerplate files for `testing` examples to match the
  current layout of the example projects.

PR Close #31937
2019-08-05 09:54:52 -07:00
b38e8674bc build(docs-infra): correct list of files included in ZIPs to match current layout (#31937)
PR Close #31937
2019-08-05 09:54:52 -07:00
553f335705 build(docs-infra): remove unused StackBlitz/ZIP configurations for setup example (#31937)
The generated StackBlitz project and ZIP archives are no longer used
(and they are broken anyway), so removing them altogether to avoid
confusion.

Note: Still keeping the example project, because that is referenced in
the `setup` guide.

PR Close #31937
2019-08-05 09:54:52 -07:00
dde0a32946 build(zone.js): update gulp task to gen changelog automatically (#31915)
PR Close #31915
2019-08-02 14:28:50 -07:00
9789cb6507 build(zone.js): update changelog of zone.js (#31915)
PR Close #31915
2019-08-02 14:28:49 -07:00
bb1fdb6c0f docs: add anyComponentStyle budget description (#31955)
In CLI 8.2 we introduced a new budget see: https://github.com/angular/angular-cli/pull/15127

PR Close #31955
2019-08-02 09:35:38 -07:00
44b5bf486f docs: add links to web.dev/angular guides (#31804)
This PR adds the following links to web.dev/angular:

1. Link to the guides in the resource section under "Online Training"
2. Links to code-splitting & preloading in the lazy-loading guide
3. Link to the accessibility guide on web.dev/angular

PR Close #31804
2019-08-01 17:45:43 -07:00
14bfcfb731 docs: update Zenika trainings URL in resources.json (#31910)
PR Close #31910
2019-08-01 10:09:49 -07:00
04ebd59961 fix(upgrade): compile downgraded components synchronously (if possible) (#31840)
AngularJS compilation is a synchronous operation (unless having to fetch
a template, which is not supported for downgraded components).
Previously, ngUpgrade tried to retain the synchronous nature of the
compilation for downgraded components (when possible), by using a
synchronous thenable implementation (`ParentInjectorPromise`). This was
accidentally broken in #27217 by replacing a call to
`ParentInjectorPromise#then()` (which can be synchronous) with a call to
`Promise.all()` (which is asynchronous).

This commit fixes this by introducing a `SyncPromise.all()` static
method; similar to `Promise.all()` but retaining the synchronous
capabilities of `SyncPromise` (which `ParentInjectorPromise` inherits
from).

Fixes #30330

PR Close #31840
2019-08-01 10:09:02 -07:00
6129cfa269 refactor(upgrade): extract promise-related utilities to separate file and add tests (#31840)
PR Close #31840
2019-08-01 10:09:02 -07:00
b8f269414e fix(ivy): speed up ngtsc if project has no templates to check (#31922)
If a project being built with ngtsc has no templates to check, then ngtsc
previously generated an empty typecheck file. This seems to trigger some
pathological behavior in TS where the entire user program is re-checked,
which is extremely expensive. This likely has to do with the fact that the
empty file is not considered an ES module, meaning the module structure of
the program has changed.

This commit causes an export to be produced in the typecheck file regardless
of its other contents, which guarantees that it will be an ES module. The
pathological behavior is avoided and template type-checking is fast once
again.

PR Close #31922
2019-07-31 16:20:38 -07:00
8ed83caa19 build(docs-infra): upgrade cli command docs sources to de49294bf (#31926)
Updating [angular#8.2.x](https://github.com/angular/angular/tree/8.2.x) from [cli-builds#8.2.x](https://github.com/angular/cli-builds/tree/8.2.x).

##
Relevant changes in [commit range](6b6b8f828...de49294bf):

**Modified**
- help/generate.json

##

PR Close #31926
2019-07-31 11:39:33 -07:00
aebf65d0ef docs: add ReactiveConf 2019 to events (#31895)
PR Close #31895
2019-07-31 11:37:44 -07:00
b667bd2224 release: cut the v8.2.0 release 2019-07-31 10:25:50 -07:00
03e8a31bf5 Revert "fix(zone.js): don't wrap uncaught promise error. (#31443)" (#31918)
This reverts commit 2bb9a65351.

It breaks tests in google3 which rely on the error handling behavior.

PR Close #31918
2019-07-30 15:03:49 -07:00
800e90e4ed fix(zone.js): don't rely on global node typings outside of node/ directory (#31783)
PR Close #31783
2019-07-30 12:59:40 -07:00
7290053952 docs: fix typo in Animation guide (#31888)
PR Close #31888
2019-07-30 12:58:53 -07:00
14890e9117 docs: change Angular Material Design to Material Design in animations guide (#31889)
PR Close #31889
2019-07-30 12:56:23 -07:00
06c49b4a6b build: secure yarn lock files (#31640)
See https://yarnpkg.com/blog/2019/07/12/recommended-security-update/

PR Close #31640
2019-07-29 16:10:23 -07:00
d269b111dd fix(zone.js): should expose some other internal intefaces (#31866)
PR Close #31866
2019-07-29 16:08:56 -07:00
46b160e925 fix(core): DebugElement.listeners not cleared on destroy (#31820)
Currently the `DebugElement.listeners` array are retained after the node is destroyed. This means that they'll continue to fire through `triggerEventHandler` and can cause memory leaks. This has already been fixed in Ivy, but these changes fix it in ViewEngine for consistency.

PR Close #31820
2019-07-29 10:05:20 -07:00
dcbc28f729 build: update to nodejs rules 0.34.0 and bazel 0.28.1 (#31824)
nodejs rules 0.34.0 now includes protractor_web_test_suite rule (via new @bazel/protractor rule) so we switch to that location for that rule in this PR so that /packages/bazel/src/protractor can be removed in a future PR

this PR also brings in node toolchain support which was released in nodejs rules 0.33.0. this is a prerequisite for RBE for mac & windows users

bazel schematics also updated with the same. @bazel/bazel 0.28.1 npm package includes transitive dep on hide-bazel-files so we're able to remove an explicit dep on that as well.

PR Close #31824
2019-07-26 15:01:26 -07:00
9bdffb1e5c docs(core): clarify @ContentChild(ren) behavior (#31846)
Describe that @ContentChild(ren) doesn't search within other component templates (doesn't go across "component boundaries").
PR Close #31846
2019-07-26 14:02:11 -07:00
155f40c175 docs: fix header mistake (#31811)
The code example refers to `src/app/heroes/heroes.component.html` but its header was `src/app/hero.service.ts` which was obviously a mistake.
PR Close #31811
2019-07-26 14:01:28 -07:00
8c446b05d0 test(ivy): fix broken testcase in Windows (#31860)
In #30181, several testcases were added that were failing in Windows.
The reason was that a recent rebase missed a required change to interact
with the compiler's virtualized filesystems. This commit introduces the
required usage of the VFS layer to fix the testcase.

PR Close #31860
2019-07-26 12:22:12 -07:00
2647f708b7 build(docs-infra): upgrade cli command docs sources to 6b6b8f828 (#31856)
Updating [angular#8.2.x](https://github.com/angular/angular/tree/8.2.x) from [cli-builds#8.1.x](https://github.com/angular/cli-builds/tree/8.1.x).

##
Relevant changes in [commit range](a8fe15cb6...6b6b8f828):

**Modified**
- help/build.json

##

PR Close #31856
2019-07-26 12:15:28 -07:00
fa15814d75 build(zone.js): add changelog gulptask for zone.js (#31852)
PR Close #31852
2019-07-26 11:30:09 -07:00
7a62530ed1 release: cut the v8.2.0-rc.0 release 2019-07-26 10:20:21 -07:00
122 changed files with 2217 additions and 1508 deletions

View File

@ -321,7 +321,7 @@ jobs:
- *attach_workspace
- *init_environment
# Build aio (with local Angular packages)
- run: yarn --cwd aio build-local --progress=false
- run: yarn --cwd aio build-local-ci
# Run unit tests
- run: yarn --cwd aio test --progress=false --watch=false
# Run e2e tests
@ -340,7 +340,7 @@ jobs:
- *attach_workspace
- *init_environment
# Build aio with Ivy (using local Angular packages)
- run: yarn --cwd aio build-with-ivy --progress=false
- run: yarn --cwd aio build-with-ivy-ci
# Run unit tests
- run: yarn --cwd aio test --progress=false --watch=false
# Run e2e tests

View File

@ -1,126 +0,0 @@
# escape=`
ARG core=mcr.microsoft.com/windows/servercore:1809
ARG target=mcr.microsoft.com/powershell:windowsservercore-1809
FROM $core as download
ARG node_version=10.13.0
ARG yarn_version=1.13.0
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
ENV GPG_VERSION 2.3.4
RUN Invoke-WebRequest $('https://files.gpg4win.org/gpg4win-vanilla-{0}.exe' -f $env:GPG_VERSION) -OutFile 'gpg4win.exe' -UseBasicParsing ; `
Start-Process .\gpg4win.exe -ArgumentList '/S' -NoNewWindow -Wait
RUN @( `
'94AE36675C464D64BAFA68DD7434390BDBE9B9C5', `
'FD3A5288F042B6850C66B31F09FE44734EB7990E', `
'71DCFD284A79C3B38668286BC97EC7A07EDE3FC1', `
'DD8F2338BAE7501E3DD5AC78C273792F7D83545D', `
'C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8', `
'B9AE9905FFD7803F25714661B63B535A4C206CA9', `
'77984A986EBC2AA786BC0F66B01FBB92821C587A', `
'8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600', `
'4ED778F539E3634C779C87C6D7062848A1AB005C', `
'A48C2BEE680E841632CD4E44F07496B3EB3C1762', `
'B9E2F5981AA6E0CD28160D9FF13993A75599653C' `
) | foreach { `
gpg --keyserver ha.pool.sks-keyservers.net --recv-keys $_ ; `
}
ENV NODE_VERSION=$node_version
RUN Invoke-WebRequest $('https://nodejs.org/dist/v{0}/SHASUMS256.txt.asc' -f $env:NODE_VERSION) -OutFile 'SHASUMS256.txt.asc' -UseBasicParsing ; `
gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc
RUN Invoke-WebRequest $('https://nodejs.org/dist/v{0}/node-v{0}-win-x64.zip' -f $env:NODE_VERSION) -OutFile 'node.zip' -UseBasicParsing ; `
$sum = $(cat SHASUMS256.txt.asc | sls $(' node-v{0}-win-x64.zip' -f $env:NODE_VERSION)) -Split ' ' ; `
if ((Get-FileHash node.zip -Algorithm sha256).Hash -ne $sum[0]) { Write-Error 'SHA256 mismatch' } ; `
Expand-Archive node.zip -DestinationPath C:\ ; `
Rename-Item -Path $('C:\node-v{0}-win-x64' -f $env:NODE_VERSION) -NewName 'C:\nodejs'
ENV YARN_VERSION=$yarn_version
RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; `
Invoke-WebRequest $('https://yarnpkg.com/downloads/{0}/yarn-{0}.msi' -f $env:YARN_VERSION) -OutFile yarn.msi -UseBasicParsing ; `
$sig = Get-AuthenticodeSignature yarn.msi ; `
if ($sig.Status -ne 'Valid') { Write-Error 'Authenticode signature is not valid' } ; `
Write-Output $sig.SignerCertificate.Thumbprint ; `
if (@( `
'7E253367F8A102A91D04829E37F3410F14B68A5F', `
'AF764E1EA56C762617BDC757C8B0F3780A0CF5F9' `
) -notcontains $sig.SignerCertificate.Thumbprint) { Write-Error 'Unknown signer certificate' } ; `
Start-Process msiexec.exe -ArgumentList '/i', 'yarn.msi', '/quiet', '/norestart' -NoNewWindow -Wait
ENV GIT_VERSION 2.20.1
ENV GIT_DOWNLOAD_URL https://github.com/git-for-windows/git/releases/download/v${GIT_VERSION}.windows.1/MinGit-${GIT_VERSION}-busybox-64-bit.zip
ENV GIT_SHA256 9817ab455d9cbd0b09d8664b4afbe4bbf78d18b556b3541d09238501a749486c
RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; `
Invoke-WebRequest -UseBasicParsing $env:GIT_DOWNLOAD_URL -OutFile git.zip; `
if ((Get-FileHash git.zip -Algorithm sha256).Hash -ne $env:GIT_SHA256) {exit 1} ; `
Expand-Archive git.zip -DestinationPath C:\git; `
Remove-Item git.zip
FROM $target as baseimage
ENV NPM_CONFIG_LOGLEVEL info
COPY --from=download /nodejs /nodejs
COPY --from=download [ "/Program Files (x86)/yarn", "/yarn" ]
COPY --from=download /git /git
ARG SETX=/M
RUN setx %SETX% PATH "%PATH%;C:\nodejs;C:\yarn\bin;C:\git\cmd;C:\git\mingw64\bin;C:\git\usr\bin"
CMD [ "node.exe" ]
FROM baseimage
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
# Install Bazel prereqs on Windows (https://docs.bazel.build/versions/master/install-windows.html)
# Install MSYS2
RUN Invoke-WebRequest -UseBasicParsing 'https://www.7-zip.org/a/7z1805-x64.exe' -OutFile 7z.exe; `
Start-Process -FilePath 'C:\\7z.exe' -ArgumentList '/S', '/D=C:\\7zip0' -NoNewWindow -Wait; `
Invoke-WebRequest -UseBasicParsing 'http://repo.msys2.org/distrib/x86_64/msys2-base-x86_64-20180531.tar.xz' -OutFile msys2.tar.xz; `
Start-Process -FilePath 'C:\\7zip\\7z' -ArgumentList 'e', 'msys2.tar.xz' -Wait; `
Start-Process -FilePath 'C:\\7zip\\7z' -ArgumentList 'x', 'msys2.tar', '-oC:\\' -Wait; `
Remove-Item msys2.tar.xz; `
Remove-Item msys2.tar; `
Remove-Item 7z.exe; `
Remove-Item -Recurse 7zip; `
[Environment]::SetEnvironmentVariable('Path', $env:Path + ';C:\msys64\usr\bin', [System.EnvironmentVariableTarget]::Machine); `
[Environment]::SetEnvironmentVariable('BAZEL_SH', 'C:\msys64\usr\bin\bash.exe', [System.EnvironmentVariableTarget]::Machine)
# Install MSYS2 packages
RUN C:\msys64\usr\bin\bash.exe -l -c \"pacman --needed --noconfirm -S zip unzip patch diffutils git\"
# Install VS Build Tools (required to build C++ targets)
RUN Invoke-WebRequest -UseBasicParsing https://download.visualstudio.microsoft.com/download/pr/df649173-11e9-4af2-8eb7-0eb02ba8958a/cadb5bdac41e55bb8f6a6b7c45273370/vs_buildtools.exe -OutFile vs_BuildTools.exe; `
# Installer won't detect DOTNET_SKIP_FIRST_TIME_EXPERIENCE if ENV is used, must use setx /M
setx /M DOTNET_SKIP_FIRST_TIME_EXPERIENCE 1; `
Start-Process vs_BuildTools.exe `
-ArgumentList `
'--add', 'Microsoft.VisualStudio.Workload.VCTools', `
'--add', 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64', `
'--add', 'Microsoft.Component.VC.Runtime.UCRTSDK', `
'--add', 'Microsoft.VisualStudio.Component.Windows10SDK.17763', `
'--quiet', '--norestart', '--nocache' `
-NoNewWindow -Wait; `
Remove-Item -Force vs_buildtools.exe; `
Remove-Item -Force -Recurse \"${Env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\"; `
Remove-Item -Force -Recurse ${Env:TEMP}\*; `
Remove-Item -Force -Recurse \"${Env:ProgramData}\Package Cache\"; `
[Environment]::SetEnvironmentVariable('BAZEL_VC', \"${Env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\BuildTools\VC\", [System.EnvironmentVariableTarget]::Machine)
# Install Python (required to build Python targets)
RUN Invoke-WebRequest -UseBasicParsing https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe -OutFile python-3.5.1.exe; `
Start-Process python-3.5.1.exe -ArgumentList '/quiet InstallAllUsers=1 PrependPath=1' -Wait; `
Remove-Item -Force python-3.5.1.exe
CMD ["cmd.exe"]

View File

@ -1,33 +0,0 @@
# CodeFresh configuration
[![Codefresh build status](https://g.codefresh.io/api/badges/pipeline/angular/angular%2Fangular%2Fangular?type=cf-1)](https://g.codefresh.io/public/accounts/angular/pipelines/angular/angular/angular)
This folder contains configuration for the [CodeFresh](<https://codefresh.io/>) based CI checks for this repository.
## The build pipeline
CodeFresh uses a several pipeline for each repository. The `codefresh.yml` file defines pipeline [build steps](https://codefresh.io/docs/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) for this repository.
Run results can be seen in the GitHub checks interface and in the [public pipeline](https://g.codefresh.io/public/accounts/angular/pipelines/angular/angular/angular)
Although most configuration is done via `pipeline.yml`, some options are only available in the online [pipeline settings](https://g.codefresh.io/pipelines/angular/services?repoOwner=angular&repoName=angular&project=angular%2Fangular&context=github&serviceName=angular%2Fangular), which needs a login to access.
## Caretaker
CodeFresh status can be found at <http://status.codefresh.io/>.
Issues related to the CodeFresh setup should be escalated to the Tools Team via the current caretaker, followed by Alex Eagle and Filipe Silva.
## Rollout strategy
Currently it is only used for tests on Windows platforms, on the master branch, and without pushing user-facing reports. It's only possible to see current builds in the [public pipeline dashboard](https://g.codefresh.io/public/accounts/angular/pipelines/angular/angular/angular).
After a week or two of running like this, we should reassess how stable and reliable it is.
Next steps include:
- building PRs
- showing build status publicly
- blocking PRs that break the build
- expanding the test suite

View File

@ -1,38 +0,0 @@
# These options are enabled when running on CI
# We do this by copying this file to /etc/bazel.bazelrc at the start of the build.
# See documentation in /docs/BAZEL.md
# Save built files and downloaded repositories in a location that can be cached by CodeFresh and
# shared between builds. This helps speed up the analysis time significantly with Bazel managed node
# dependencies on the CI.
# https://codefresh.io/docs/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/#caching-the-artifacts-of-your-build-system
build --repository_cache=C:/codefresh/volume/bazel_repository_cache
# Setting the output_base to a Docker volume is currently broken because of a Docker bug on Windows:
# https://github.com/moby/moby/issues/37024
# This affects Bazel because bazel_output_base\external\bazel_tools is an absolute path junction.
# When its fixed we can uncomment this line, and use a different output_base for Ivy tests (they
# use a separate compiler and destructively replace the cache).
# startup --output_base=C:/codefresh/volume/bazel_output_base
# Don't be spammy in the logs
# TODO(gmagolan): Hide progress again once build performance improves
# Presently, CircleCI can timeout during bazel test ... with the following
# error: Too long with no output (exceeded 10m0s)
build --noshow_progress
# Print all the options that apply to the build.
# This helps us diagnose which options override others
# (e.g. /etc/bazel.bazelrc vs. tools/bazel.rc)
build --announce_rc
# Workaround https://github.com/bazelbuild/bazel/issues/3645
# Bazel doesn't calculate the memory ceiling correctly when running under Docker.
# Limit Bazel to consuming resources that fit in CodeFresh VMs
# TODO(filipesilva): determine the correct memory limit
build --local_resources=10240,8.0,1.0
# Retry in the event of flakes, eg. https://circleci.com/gh/angular/angular/31309
test --flaky_test_attempts=2
# More details on failures
build --verbose_failures=true

View File

@ -1,28 +0,0 @@
version: '1.0'
steps:
BuildImage:
title: Build Docker image
type: build
image_name: node-bazel-windows
working_directory: ./.codefresh
no_cf_cache: true
build_arguments:
- node_version=10.13.0
- yarn_version=1.13.0
dockerfile: ./Dockerfile.win-1809
RunTests:
title: Run Bazel tests
image: ${{BuildImage}}
commands:
# Install dependencies
- yarn install --frozen-lockfile --non-interactive --network-timeout 100000 --no-progress
# Add Bazel CI config
- copy .codefresh\bazel.rc %ProgramData%\bazel.bazelrc
# Run tests
# At the moment 'browser:chromium-local' are broken in CI while locally they work
# VE
- yarn bazel test --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only,-browser:chromium-local //...
# Ivy
- yarn bazel test --define=compile=aot --build_tag_filters=-no-ivy-aot,-fixme-ivy-aot --test_tag_filters=-no-ivy-aot,-fixme-ivy-aot,-browser:chromium-local //...

1
.github/CODEOWNERS vendored
View File

@ -884,7 +884,6 @@ testing/** @angular/fw-test
/* @angular/fw-dev-infra
/.buildkite/** @angular/fw-dev-infra
/.circleci/** @angular/fw-dev-infra
/.codefresh/** @angular/fw-dev-infra
/.devcontainer/** @angular/fw-dev-infra
/.github/** @angular/fw-dev-infra
/.vscode/** @angular/fw-dev-infra

View File

@ -1,3 +1,70 @@
<a name="8.2.2"></a>
## [8.2.2](https://github.com/angular/angular/compare/8.2.1...8.2.2) (2019-08-12)
### Bug Fixes
* **bazel:** disable treeshaking when generating FESM and UMD bundles ([#32069](https://github.com/angular/angular/issues/32069)) ([3420d29](https://github.com/angular/angular/commit/3420d29))
<a name="8.2.1"></a>
## [8.2.1](https://github.com/angular/angular/compare/8.2.0...8.2.1) (2019-08-08)
### Bug Fixes
* **upgrade:** compile downgraded components synchronously (if possible) ([#31840](https://github.com/angular/angular/issues/31840)) ([04ebd59](https://github.com/angular/angular/commit/04ebd59)), closes [#27217](https://github.com/angular/angular/issues/27217) [#30330](https://github.com/angular/angular/issues/30330)
<a name="8.2.0"></a>
# [8.2.0](https://github.com/angular/angular/compare/8.2.0-rc.0...8.2.0) (2019-07-31)
### Bug Fixes
* **core:** DebugElement.listeners not cleared on destroy ([#31820](https://github.com/angular/angular/issues/31820)) ([46b160e](https://github.com/angular/angular/commit/46b160e))
<a name="8.2.0-rc.0"></a>
# [8.2.0-rc.0](https://github.com/angular/angular/compare/8.2.0-next.2...8.2.0-rc.0) (2019-07-26)
### Bug Fixes
* **bazel:** increase memory limit of ngc under bazel from 2 to 4 GB ([#31784](https://github.com/angular/angular/issues/31784)) ([5a8eb92](https://github.com/angular/angular/commit/5a8eb92))
* **core:** allow Z variations of CSS transforms in sanitizer ([#29264](https://github.com/angular/angular/issues/29264)) ([78e7fdd](https://github.com/angular/angular/commit/78e7fdd))
* **elements:** handle falsy initial value ([#31604](https://github.com/angular/angular/issues/31604)) ([7151eae](https://github.com/angular/angular/commit/7151eae)), closes [angular/angular#30834](https://github.com/angular/angular/issues/30834)
* **platform-browser:** debug element query predicates not compatible with strictFunctionTypes ([#30993](https://github.com/angular/angular/issues/30993)) ([10a1e19](https://github.com/angular/angular/commit/10a1e19))
### Features
* **bazel:** compile targets used for indexing by Kythe with Ivy ([#31786](https://github.com/angular/angular/issues/31786)) ([82055b2](https://github.com/angular/angular/commit/82055b2))
* **upgrade:** support $element in upgraded component template/templateUrl functions ([#31637](https://github.com/angular/angular/issues/31637)) ([29e1c53](https://github.com/angular/angular/commit/29e1c53))
### Performance Improvements
* **compiler:** avoid copying from prototype while cloning an object ([#31638](https://github.com/angular/angular/issues/31638)) ([24ca582](https://github.com/angular/angular/commit/24ca582)), closes [#31627](https://github.com/angular/angular/issues/31627)
<a name="8.1.3"></a>
## [8.1.3](https://github.com/angular/angular/compare/8.1.2...8.1.3) (2019-07-26)
### Bug Fixes
* **elements:** handle falsy initial value ([#31604](https://github.com/angular/angular/issues/31604)) ([434b796](https://github.com/angular/angular/commit/434b796)), closes [angular/angular#30834](https://github.com/angular/angular/issues/30834)
### Performance Improvements
* **compiler:** avoid copying from prototype while cloning an object ([#31638](https://github.com/angular/angular/issues/31638)) ([1f3daa0](https://github.com/angular/angular/commit/1f3daa0)), closes [#31627](https://github.com/angular/angular/issues/31627)
<a name="8.2.0-next.2"></a>
# [8.2.0-next.2](https://github.com/angular/angular/compare/8.2.0-next.1...8.2.0-next.2) (2019-07-17)

View File

@ -21,8 +21,8 @@ http_archive(
patch_args = ["-p1"],
# Patch https://github.com/bazelbuild/rules_nodejs/pull/903
patches = ["//tools:rollup_bundle_commonjs_ignoreGlobal.patch"],
sha256 = "6d4edbf28ff6720aedf5f97f9b9a7679401bf7fca9d14a0fff80f644a99992b4",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.32.2/rules_nodejs-0.32.2.tar.gz"],
sha256 = "7c4a690268be97c96f04d505224ec4cb1ae53c2c2b68be495c9bd2634296a5cd",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.34.0/rules_nodejs-0.34.0.tar.gz"],
)
# Check the bazel version and download npm dependencies
@ -53,7 +53,8 @@ Try running `yarn bazel` instead.
# - 0.32.0 yarn_install and npm_install no longer puts build files under symlinked node_modules
# - 0.32.1 remove override of @bazel/tsetse & exclude typescript lib declarations in node_module_library transitive_declarations
# - 0.32.2 resolves bug in @bazel/hide-bazel-files postinstall step
check_rules_nodejs_version(minimum_version_string = "0.32.2")
# - 0.34.0 introduces protractor rule
check_rules_nodejs_version(minimum_version_string = "0.34.0")
# Setup the Node.js toolchain
node_repositories(
@ -91,6 +92,11 @@ load("//packages/bazel:package.bzl", "rules_angular_dev_dependencies")
rules_angular_dev_dependencies()
# Load protractor dependencies
load("@npm_bazel_protractor//:package.bzl", "npm_bazel_protractor_dependencies")
npm_bazel_protractor_dependencies()
# Load karma dependencies
load("@npm_bazel_karma//:package.bzl", "rules_karma_dependencies")

View File

@ -14,10 +14,12 @@ Here are the most important tasks you might need to use:
* `yarn` - install all the dependencies.
* `yarn setup` - install all the dependencies, boilerplate, stackblitz, zips and run dgeni on the docs.
* `yarn setup-local` - same as `setup`, but use the locally built Angular packages for aio and docs examples boilerplate.
* `yarn setup-local` - same as `setup`, but build the Angular packages from the source code and use these locally built versions (instead of the ones fetched from npm) for aio and docs examples boilerplate.
* `yarn build` - create a production build of the application (after installing dependencies, boilerplate, etc).
* `yarn build-local` - same as `build`, but use `setup-local` instead of `setup`.
* `yarn build-with-ivy` - same as `build-local`, but in addition also turns on `ivy` mode in aio.
(Note: To turn on `ivy` mode in examples, see `yarn boilerplate:add` below.)
* `yarn start` - run a development web server that watches the files; then builds the doc-viewer and reloads the page, as necessary.
* `yarn serve-and-sync` - run both the `docs-watch` and `start` in the same console.
@ -31,7 +33,10 @@ Here are the most important tasks you might need to use:
* `yarn docs-lint` - check that the doc gen code follows our style rules.
* `yarn docs-test` - run the unit tests for the doc generation code.
* `yarn boilerplate:add` - generate all the boilerplate code for the examples, so that they can be run locally. Add the option `--local` to use your local version of Angular contained in the "dist" folder.
* `yarn boilerplate:add` - generate all the boilerplate code for the examples, so that they can be run locally.
- Add the option `--local` to use your local version of Angular contained in the "dist" folder.
- Add the option `--ivy` to turn on `ivy` mode.
* `yarn boilerplate:remove` - remove all the boilerplate code that was added via `yarn boilerplate:add`.
* `yarn generate-stackblitz` - generate the stackblitz files that are used by the `live-example` tags in the docs.
* `yarn generate-zips` - generate the zip files from the examples. Zip available via the `live-example` tags in the docs.

View File

@ -1,12 +0,0 @@
{
"description": "Quickstart AppComponent Testing",
"files":[
"src/browser-test-shim.js",
"src/app/app.component.ts",
"src/app/app.component.spec.ts",
"src/quickstart-specs.html"
],
"main": "src/quickstart-specs.html",
"file": "src/app/app.component.spec.ts",
"tags": ["quickstart", "setup", "testing"]
}

View File

@ -1,36 +0,0 @@
<!-- Run application specs in a browser -->
<!-- #docregion -->
<!DOCTYPE html>
<html>
<head>
<base href="/">
<title>1st Specs</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="node_modules/jasmine-core/lib/jasmine-core/jasmine.css">
</head>
<body>
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/boot.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/zone.js/dist/zone-testing.js"></script>
<!-- #docregion files -->
<script>
var __spec_files__ = [
'app/app.component.spec'
];
</script>
<!-- #enddocregion files-->
<script src="browser-test-shim.js"></script>
</body>
</html>

View File

@ -1,12 +0,0 @@
{
"description": "QuickStart Setup",
"files": [
"src/app/app.component.ts",
"src/app/app.module.ts",
"src/index.html",
"src/main.ts",
"src/styles.css"
],
"file": "src/app/app.component.ts",
"tags": ["quickstart", "setup", "seed"]
}

View File

@ -1,24 +1,22 @@
{
"description": "Testing - specs",
"files":[
"src/expected.ts",
"src/index-specs.html",
"src/main-specs.ts",
"src/styles.css",
"src/test.css",
"src/tests.sb.ts",
"e2e/src/**/*.ts",
"src/app/**/*.css",
"src/app/**/*.html",
"src/app/**/*.ts",
"src/app/**/*.spec.ts",
"src/testing/*.ts",
"src/testing/**/*",
"!src/main.ts",
"!src/app/bag/*.*",
"!src/app/1st.spec.ts",
"src/expected.ts",
"src/test.css",
"src/tests.sb.ts",
"src/main-specs.ts",
"src/index-specs.html"
"src/**/*.spec.ts"
],
"main": "src/index-specs.html",
"tags": ["testing"]

View File

@ -1,3 +1,3 @@
const jasmineRequire = require('jasmine-core/lib/jasmine-core/jasmine.js');
import jasmineRequire from 'jasmine-core/lib/jasmine-core/jasmine.js';
window['jasmineRequire'] = jasmineRequire;

View File

@ -1,19 +1,18 @@
{
"description": "Heroes Test App",
"files":[
"src/index.html",
"src/main.ts",
"src/styles.css",
"src/test.css",
"e2e/src/**/*.ts",
"src/app/**/*.css",
"src/app/**/*.html",
"src/app/**/*.ts",
"!src/app/bag/*.*",
"!src/test.ts",
"src/test.css",
"src/main.ts",
"src/index.html"
"!src/**/*.spec.ts"
],
"tags": ["testing"]
}

View File

@ -179,3 +179,8 @@ Books
* "A Web for Everyone: Designing Accessible User Experiences", Sarah Horton and Whitney Quesenbery
* "Inclusive Design Patterns", Heydon Pickering
## More on accessibility
You may also be interested in the following:
* [Audit your Angular app's accessibility with codelyzer](https://web.dev/accessible-angular-with-codelyzer/).

View File

@ -0,0 +1,148 @@
# Angular compiler options
When you use [AOT compilation](guide/aot-compiler), you can control how your application is compiled by specifying *template* compiler options in the `tsconfig.json` [TypeScript configuration file](guide/typescript-configuration).
The template options object, `angularCompilerOptions`, is a sibling to the `compilerOptions` object that supplies standard options to the TypeScript compiler.
```json
{
"compilerOptions": {
"experimentalDecorators": true,
...
},
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"preserveWhitespaces": true,
...
}
}
```
This page describes the available Angular template compiler options.
### `allowEmptyCodegenFiles`
When true, generate all possible files even if they are empty. Default is false. Used by the Bazel build rules to simplify how Bazel rules track file dependencies. Do not use this option outside of the Bazel rules.
### `annotationsAs`
Modifies how Angular-specific annotations are emitted to improve tree-shaking. Non-Angular annotations are not affected. One of `static fields` (the default) or `decorators`.
* By default, the compiler replaces decorators with a static field in the class, which allows advanced tree-shakers like [Closure compiler](https://github.com/google/closure-compiler) to remove unused classes.
* The `decorators` value leaves the decorators in place, which makes compilation faster. TypeScript emits calls to the` __decorate` helper. Use `--emitDecoratorMetadata` for runtime reflection (but note taht the resulting code will not properly tree-shake.
### `annotateForClosureCompiler`
When true, use [Tsickle](https://github.com/angular/tsickle) to annotate the emitted JavaScript with [JSDoc](http://usejsdoc.org/) comments needed by the
[Closure Compiler](https://github.com/google/closure-compiler). Default is false.
### `disableExpressionLowering`
When true (the default), transforms code that is or could be used in an annotation, to allow it to be imported from template factory modules. See [metadata rewriting](guide/aot-compiler#metadata-rewriting) for more information.
When `false`, disables this rewriting, requiring the rewriting to be done manually.
### `disableTypeScriptVersionCheck`
When `true`, the compiler does not check the TypeScript version and does not report an error when an unsupported version of TypeScript is used. Not recommended, as unsupported versions of TypeScript might have undefined behavior. Default is false.
### `enableResourceInlining`
When true, replaces the `templateUrl` and `styleUrls` property in all `@Component` decorators with inlined contents in `template` and `styles` properties.
When enabled, the `.js` output of `ngc` does not include any lazy-loaded template or style URLs.
{@a enablelegacytemplate}
### `enableLegacyTemplate`
When true, enables use of the `<template>` element, which was deprecated in Angular 4.0, in favor of `<ng-template>` (to avoid colliding with the DOM's element of the same name). Default is false. Might be required by some third-party Angular libraries. |
### `flatModuleId`
The module ID to use for importing a flat module (when `flatModuleOutFile` is true). References generated by the template compiler use this module name when importing symbols
from the flat module. Ignored if `flatModuleOutFile` is false.
### `flatModuleOutFile`
When true, generates a flat module index of the given file name and the corresponding flat module metadata. Use to create flat modules that are packaged similarly to `@angular/core` and `@angular/common`. When this option is used, the `package.json` for the library should refer
to the generated flat module index instead of the library index file.
Produces only one `.metadata.json` file, which contains all the metadata necessary
for symbols exported from the library index. In the generated `.ngfactory.js` files, the flat
module index is used to import symbols that includes both the public API from the library index
as well as shrowded internal symbols.
By default the `.ts` file supplied in the `files` field is assumed to be the library index.
If more than one `.ts` file is specified, `libraryIndex` is used to select the file to use.
If more than one `.ts` file is supplied without a `libraryIndex`, an error is produced.
A flat module index `.d.ts` and `.js` is created with the given `flatModuleOutFile` name in the same location as the library index `.d.ts` file.
For example, if a library uses the `public_api.ts` file as the library index of the module, the `tsconfig.json` `files` field would be `["public_api.ts"]`.
The `flatModuleOutFile` options could then be set to (for example) `"index.js"`, which produces `index.d.ts` and `index.metadata.json` files.
The `module` field of the library's `package.json` would be `"index.js"` and the `typings` field
would be `"index.d.ts"`.
### `fullTemplateTypeCheck`
When true (recommended), enables the [binding expression validation](guide/aot-compiler#binding-expression-validation) phase of the template compiler, which uses TypeScript to validate binding expressions.
Default is currently false.
### `generateCodeForLibraries`
When true (the default), generates factory files (`.ngfactory.js` and `.ngstyle.js`)
for `.d.ts` files with a corresponding `.metadata.json` file.
When false, factory files are generated only for `.ts` files. Do this when using factory summaries.
### `preserveWhitespaces`
When false (the default), removes blank text nodes from compiled templates, which results in smaller emitted template factory modules. Set to true to preserve blank text nodes.
### `skipMetadataEmit`
When true, does not to produce `.metadata.json` files. Default is `false`.
The `.metadata.json` files contain information needed by the template compiler from a `.ts`
file that is not included in the `.d.ts` file produced by the TypeScript compiler.
This information includes, for example, the content of annotations (such as a component's template), which TypeScript emits to the `.js` file but not to the `.d.ts` file.
You can set to `true` when using factory summaries, because the factory summaries
include a copy of the information that is in the `.metadata.json` file.
Set to `true` if you are using TypeScript's `--outFile` option, because the metadata files
are not valid for this style of TypeScript output. However, we do not recommend using `--outFile` with Angular. Use a bundler, such as [webpack](https://webpack.js.org/), instead.
### `skipTemplateCodegen`
When true, does not emit `.ngfactory.js` and `.ngstyle.js` files. This turns off most of the template compiler and disables the reporting of template diagnostics.
Can be used to instruct the template compiler to produce `.metadata.json` files for distribution with an `npm` package while avoiding the production of `.ngfactory.js` and `.ngstyle.js` files that cannot be distributed to `npm`.
### `strictMetadataEmit`
When true, reports an error to the `.metadata.json` file if `"skipMetadataEmit"` is `false`.
Default is false. Use only when `"skipMetadataEmit"` is false and `"skipTemplateCodeGen"` is true.
This option is intended to validate the `.metadata.json` files emitted for bundling with an `npm` package. The validation is strict and can emit errors for metadata that would never produce an error when used by the template compiler. You can choose to suppress the error emitted by this option for an exported symbol by including `@dynamic` in the comment documenting the symbol.
It is valid for `.metadata.json` files to contain errors.
The template compiler reports these errors if the metadata is used to determine the contents of an annotation.
The metadata collector cannot predict the symbols that are designed for use in an annotation, so it preemptively includes error nodes in the metadata for the exported symbols.
The template compiler can then use the error nodes to report an error if these symbols are used.
If the client of a library intends to use a symbol in an annotation, the template compiler does not normally report this until the client uses the symbol.
This option allows detection of these errors during the build phase of
the library and is used, for example, in producing Angular libraries themselves.
### `strictInjectionParameters`
When true (recommended), reports an error for a supplied parameter whose injection type cannot be determined. When false (currently the default), constructor parameters of classes marked with `@Injectable` whose type cannot be resolved produce a warning.
### `trace`
When true, prints extra information while compiling templates. Default is false.

View File

@ -128,7 +128,7 @@ The third argument, `easing`, controls how the animation [accelerates and decele
<div class="alert is-helpful">
**Note:** See the Angular Material Design website's topic on [Natural easing curves](https://material.io/design/motion/speed.html#easing) for general information on easing curves.
**Note:** See the Material Design website's topic on [Natural easing curves](https://material.io/design/motion/speed.html#easing) for general information on easing curves.
</div>
This example provides a state transition from `open` to `closed` with a one second transition between states.

View File

@ -79,11 +79,9 @@ there are fewer opportunities for injection attacks.
When you use the Angular AOT compiler, you can control your app compilation in two ways:
* By providing template compiler options in the `tsconfig.json` file.
* By [specifying Angular metadata](#metadata-aot), as described below.
For more information, see [Angular template compiler options](#compiler-options).
* By [specifying Angular metadata](#metadata-aot).
* By providing options in the `tsconfig.json` [TypeScript configuration file](guide/typescript-configuration). See [Angular compiler options](guide/angular-compiler-options).
{@a metadata-aot}
@ -1165,7 +1163,7 @@ Chuck: After reviewing your PR comment I'm still at a loss. See [comment there](
In the validation phase, the Angular template compiler uses the TypeScript compiler to validate the
binding expressions in templates. Enable this phase explicitly by adding the compiler
option `"fullTemplateTypeCheck"` in the `"angularCompilerOptions"` of the project's `tsconfig.json` (see
[Angular Compiler Options](#compiler-options)).
[Angular Compiler Options](guide/angular-compiler-options)).
Template validation produces error messages when a type error is detected in a template binding
expression, similar to how type errors are reported by the TypeScript compiler against code in a `.ts`
@ -1329,198 +1327,3 @@ Similar to TypeScript Compiler, Angular Compiler also supports `extends` in the
}
```
More information about tsconfig extends can be found in the [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html).
{@a compiler-options}
## Angular template compiler options
The template compiler options are specified as members of the `"angularCompilerOptions"` object in the `tsconfig.json` file. Specify template compiler options along with the options supplied to the TypeScript compiler as shown here:
```json
{
"compilerOptions": {
"experimentalDecorators": true,
...
},
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"preserveWhitespaces": true,
...
}
}
```
The following section describes the Angular's template compiler options.
### *enableResourceInlining*
This option instructs the compiler to replace the `templateUrl` and `styleUrls` property in all `@Component` decorators with inlined contents in `template` and `styles` properties.
When enabled, the `.js` output of `ngc` will have no lazy-loaded `templateUrl` or `styleUrls`.
### *skipMetadataEmit*
This option tells the compiler not to produce `.metadata.json` files.
The option is `false` by default.
`.metadata.json` files contain information needed by the template compiler from a `.ts`
file that is not included in the `.d.ts` file produced by the TypeScript compiler. This information contains,
for example, the content of annotations (such as a component's template), which TypeScript
emits to the `.js` file but not to the `.d.ts` file.
This option should be set to `true` if you are using TypeScript's `--outFile` option, because the metadata files
are not valid for this style of TypeScript output. It is not recommended to use `--outFile` with
Angular. Use a bundler, such as [webpack](https://webpack.js.org/), instead.
This option can also be set to `true` when using factory summaries because the factory summaries
include a copy of the information that is in the `.metadata.json` file.
### *strictMetadataEmit*
This option tells the template compiler to report an error to the `.metadata.json`
file if `"skipMetadataEmit"` is `false`. This option is `false` by default. This should only be used when `"skipMetadataEmit"` is `false` and `"skipTemplateCodeGen"` is `true`.
This option is intended to validate the `.metadata.json` files emitted for bundling with an `npm` package. The validation is strict and can emit errors for metadata that would never produce an error when used by the template compiler. You can choose to suppress the error emitted by this option for an exported symbol by including `@dynamic` in the comment documenting the symbol.
It is valid for `.metadata.json` files to contain errors. The template compiler reports these errors
if the metadata is used to determine the contents of an annotation. The metadata
collector cannot predict the symbols that are designed for use in an annotation, so it will preemptively
include error nodes in the metadata for the exported symbols. The template compiler can then use the error
nodes to report an error if these symbols are used. If the client of a library intends to use a symbol in an annotation, the template compiler will not normally report
this until the client uses the symbol. This option allows detecting these errors during the build phase of
the library and is used, for example, in producing Angular libraries themselves.
### *skipTemplateCodegen*
This option tells the compiler to suppress emitting `.ngfactory.js` and `.ngstyle.js` files. When set,
this turns off most of the template compiler and disables reporting template diagnostics.
This option can be used to instruct the
template compiler to produce `.metadata.json` files for distribution with an `npm` package while
avoiding the production of `.ngfactory.js` and `.ngstyle.js` files that cannot be distributed to
`npm`.
### *strictInjectionParameters*
When set to `true`, this options tells the compiler to report an error for a parameter supplied
whose injection type cannot be determined. When this option is not provided or is `false`, constructor parameters of classes marked with `@Injectable` whose type cannot be resolved will
produce a warning.
*Note*: It is recommended to change this option explicitly to `true` as this option will default to `true` in the future.
### *flatModuleOutFile*
When set to `true`, this option tells the template compiler to generate a flat module
index of the given file name and the corresponding flat module metadata. Use this option when creating
flat modules that are packaged similarly to `@angular/core` and `@angular/common`. When this option
is used, the `package.json` for the library should refer
to the generated flat module index instead of the library index file. With this
option only one `.metadata.json` file is produced, which contains all the metadata necessary
for symbols exported from the library index. In the generated `.ngfactory.js` files, the flat
module index is used to import symbols that includes both the public API from the library index
as well as shrowded internal symbols.
By default the `.ts` file supplied in the `files` field is assumed to be the library index.
If more than one `.ts` file is specified, `libraryIndex` is used to select the file to use.
If more than one `.ts` file is supplied without a `libraryIndex`, an error is produced. A flat module
index `.d.ts` and `.js` will be created with the given `flatModuleOutFile` name in the same
location as the library index `.d.ts` file. For example, if a library uses the
`public_api.ts` file as the library index of the module, the `tsconfig.json` `files` field
would be `["public_api.ts"]`. The `flatModuleOutFile` options could then be set to, for
example `"index.js"`, which produces `index.d.ts` and `index.metadata.json` files. The
library's `package.json`'s `module` field would be `"index.js"` and the `typings` field
would be `"index.d.ts"`.
### *flatModuleId*
This option specifies the preferred module id to use for importing a flat module.
References generated by the template compiler will use this module name when importing symbols
from the flat module.
This is only meaningful when `flatModuleOutFile` is also supplied. Otherwise the compiler ignores
this option.
### *generateCodeForLibraries*
This option tells the template compiler to generate factory files (`.ngfactory.js` and `.ngstyle.js`)
for `.d.ts` files with a corresponding `.metadata.json` file. This option defaults to
`true`. When this option is `false`, factory files are generated only for `.ts` files.
This option should be set to `false` when using factory summaries.
### *fullTemplateTypeCheck*
This option tells the compiler to enable the [binding expression validation](#binding-expression-validation)
phase of the template compiler which uses TypeScript to validate binding expressions.
This option is `false` by default.
*Note*: It is recommended to set this to `true` because this option will default to `true` in the future.
### *annotateForClosureCompiler*
This option tells the compiler to use [Tsickle](https://github.com/angular/tsickle) to annotate the emitted
JavaScript with [JSDoc](http://usejsdoc.org/) comments needed by the
[Closure Compiler](https://github.com/google/closure-compiler). This option defaults to `false`.
### *annotationsAs*
Use this option to modify how the Angular specific annotations are emitted to improve tree-shaking. Non-Angular
annotations and decorators are unaffected. Default is `static fields`.
<style>
td, th {vertical-align: top}
</style>
<table>
<tr>
<th>Value</th>
<th>Description</th>
</tr>
<tr>
<td><code>decorators</code></td>
<td>Leave the decorators in place. This makes compilation faster. TypeScript will emit calls to the __decorate helper. Use <code>--emitDecoratorMetadata</code> for runtime reflection. However, the resulting code will not properly tree-shake.</td>
</tr>
<tr>
<td><code>static fields</code></td>
<td>Replace decorators with a static field in the class. Allows advanced tree-shakers like
<a href="https://github.com/google/closure-compiler">Closure compiler</a> to remove unused classes.</td>
</tr>
</table>
### *trace*
This tells the compiler to print extra information while compiling templates.
### *enableLegacyTemplate*
Use of the `<template>` element was deprecated starting in Angular 4.0 in favor of using
`<ng-template>` to avoid colliding with the DOM's element of the same name. Setting this option to
`true` enables the use of the deprecated `<template>` element. This option
is `false` by default. This option might be required by some third-party Angular libraries.
### *disableExpressionLowering*
The Angular template compiler transforms code that is used, or could be used, in an annotation
to allow it to be imported from template factory modules. See
[metadata rewriting](#metadata-rewriting) for more information.
Setting this option to `false` disables this rewriting, requiring the rewriting to be
done manually.
### *disableTypeScriptVersionCheck*
When `true`, this option tells the compiler not to check the TypeScript version.
The compiler will skip checking and will not error out when an unsupported version of TypeScript is used.
Setting this option to `true` is not recommended because unsupported versions of TypeScript might have undefined behavior.
This option is `false` by default.
### *preserveWhitespaces*
This option tells the compiler whether to remove blank text nodes from compiled templates.
As of v6, this option is `false` by default, which results in smaller emitted template factory modules.
### *allowEmptyCodegenFiles*
Tells the compiler to generate all the possible generated files even if they are empty. This option is
`false` by default. This is an option used by the Bazel build rules and is needed to simplify
how Bazel rules track file dependencies. It is not recommended to use this option outside of the Bazel
rules.

View File

@ -53,7 +53,7 @@ Angular supports most recent browsers. This includes the following specific vers
IE
</td>
<td>
11, 10, 9
11, 10, 9 ("compatibility view" mode not supported)
</td>
</tr>
<tr>
@ -183,7 +183,7 @@ These are the polyfills required to run an Angular application on each supported
<td>
Chrome, Firefox, Edge, <br>
Safari, Android, IE10+
Safari, Android, IE 10+
</td>
<td>
@ -197,7 +197,7 @@ These are the polyfills required to run an Angular application on each supported
<tr style="vertical-align: top">
<td>
IE9
IE 9
</td>
<td>
@ -275,7 +275,7 @@ Some features of Angular may require additional polyfills.
</td>
<td>
All but Chrome, Firefox, Edge, IE11 and Safari 10
All but Chrome, Firefox, Edge, IE 11 and Safari 10
</td>
</tr>
@ -294,7 +294,7 @@ Some features of Angular may require additional polyfills.
</td>
<td>
IE10, IE11
IE 10, IE 11
</td>
</tr>

View File

@ -214,14 +214,17 @@ Each budget entry is a JSON object with the following properties:
<tr>
<td>type</td>
<td>The type of budget. One of:
<td>
* bundle - The size of a specific bundle.
* initial - The initial size of the app.
* allScript - The size of all scripts.
* all - The size of the entire app.
* anyScript - The size of any one script.
* any - The size of any file.
The type of budget. One of:
* `bundle` - The size of a specific bundle.
* `initial` - The initial size of the app.
* `allScript` - The size of all scripts.
* `all` - The size of the entire app.
* `anyComponentStyle` - This size of any one component stylesheet.
* `anyScript` - The size of any one script.
* `any` - The size of any file.
</td>
</tr>

View File

@ -253,7 +253,7 @@ In the `package.json` file, add a `builders` key that tells the Architect tool w
</code-example>
The official name of our builder is now ` @example/command-runner:command`.
The first part of this is the package name (resolved using node resolution), and the second part is the builder name (resolved using the `builder.json` file).
The first part of this is the package name (resolved using node resolution), and the second part is the builder name (resolved using the `builders.json` file).
Using one of our `options` is very straightforward, we did this in the previous section when we accessed `options.command`.
@ -279,28 +279,28 @@ By default, for example, the `build` command runs the builder `@angular-devkit/
"myApp": {
...
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/myApp",
"index": "src/index.html",
...
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
...
}
}
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/myApp",
"index": "src/index.html",
...
},
...
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
...
}
}
},
...
</code-example>
@ -419,15 +419,13 @@ We need to update the `angular.json` file to add a target for this builder to th
"projects": {
"builder-test": {
"architect": {
"builder-test": {
"touch": {
"builder": "@example/command-runner:command",
"options": {
"command": "touch",
"args": [
"src/main.ts"
]
}
"touch": {
"builder": "@example/command-runner:command",
"options": {
"command": "touch",
"args": [
"src/main.ts"
]
}
},
"build": {
@ -497,14 +495,14 @@ The test uses the builder to run the `ls` command, then validates that it ran su
<code-example language="typescript">
import { Architect, ArchitectHost } from '@angular-devkit/architect';
import { Architect } from '@angular-devkit/architect';
import { TestingArchitectHost } from '@angular-devkit/architect/testing';
// Our builder forwards the STDOUT of the command to the logger.
import { logging, schema } from '@angular-devkit/core';
describe('Command Runner Builder', () => {
let architect: Architect;
let architectHost: ArchitectHost;
let architectHost: TestingArchitectHost;
beforeEach(async () => {
const registry = new schema.CoreSchemaRegistry();

View File

@ -178,7 +178,7 @@ For more information, see [/deep/, >>>, and ::ng-deep](guide/component-styles#de
{@a template-tag}
### &lt;template&gt; tag
The `<template>` tag was deprecated in v4 to avoid colliding with the DOM's element of the same name (such as when using web components). Use `<ng-template>` instead. For more information, see the [Ahead-of-Time Compilation](guide/aot-compiler#enablelegacytemplate) guide.
The `<template>` tag was deprecated in v4 to avoid colliding with the DOM's element of the same name (such as when using web components). Use `<ng-template>` instead. For more information, see the [Ahead-of-Time Compilation](guide/angular-compiler-options#enablelegacytemplate) guide.

View File

@ -207,3 +207,6 @@ You may also be interested in the following:
* [Routing and Navigation](guide/router).
* [Providers](guide/providers).
* [Types of Feature Modules](guide/module-types).
* [Route-level code-splitting in Angular](https://web.dev/route-level-code-splitting-in-angular/)
* [Route preloading strategies in Angular](https://web.dev/route-preloading-in-angular/)

View File

@ -2,15 +2,17 @@
Angular makes use of observables as an interface to handle a variety of common asynchronous operations. For example:
* The `EventEmitter` class extends `Observable`.
* You can define [custom events](guide/template-syntax#custom-events-with-eventemitter) that send observable output data from a child to a parent component.
* The HTTP module uses observables to handle AJAX requests and responses.
* The Router and Forms modules use observables to listen for and respond to user-input events.
## Event emitter
## Transmitting data between components
Angular provides an `EventEmitter` class that is used when publishing values from a component through the `@Output()` decorator. `EventEmitter` extends `Observable`, adding an `emit()` method so it can send arbitrary values. When you call `emit()`, it passes the emitted value to the `next()` method of any subscribed observer.
Angular provides an `EventEmitter` class that is used when publishing values from a component through the [`@Output()` decorator](guide/template-syntax#how-to-use-output).
`EventEmitter` extends [RxJS `Subject`](https://rxjs.dev/api/index/class/Subject), adding an `emit()` method so it can send arbitrary values.
When you call `emit()`, it passes the emitted value to the `next()` method of any subscribed observer.
A good example of usage can be found on the [EventEmitter](https://angular.io/api/core/EventEmitter) documentation. Here is the example component that listens for open and close events:
A good example of usage can be found in the [EventEmitter](https://angular.io/api/core/EventEmitter) documentation. Here is the example component that listens for open and close events:
`<zippy (open)="onOpen($event)" (close)="onClose($event)"></zippy>`

View File

@ -1,6 +1,6 @@
# The RxJS library
Reactive programming is an asynchronous programming paradigm concerned with data streams and the propagation of change ([Wikipedia](https://en.wikipedia.org/wiki/Reactive_programming)). RxJS (Reactive Extensions for JavaScript) is a library for reactive programming using observables that makes it easier to compose asynchronous or callback-based code ([RxJS Docs](http://reactivex.io/rxjs/)).
Reactive programming is an asynchronous programming paradigm concerned with data streams and the propagation of change ([Wikipedia](https://en.wikipedia.org/wiki/Reactive_programming)). RxJS (Reactive Extensions for JavaScript) is a library for reactive programming using observables that makes it easier to compose asynchronous or callback-based code. See ([RxJS Docs](https://rxjs.dev/guide/overview)).
RxJS provides an implementation of the `Observable` type, which is needed until the type becomes part of the language and until browsers support it. The library also provides utility functions for creating and working with observables. These utility functions can be used for:
@ -45,7 +45,7 @@ The `pipe()` function is also a method on the RxJS `Observable`, so you use this
### Common operators
RxJS provides many operators, but only a handful are used frequently. For a list of operators and usage samples, visit the [RxJS API Documentation](https://rxjs-dev.firebaseapp.com/api).
RxJS provides many operators, but only a handful are used frequently. For a list of operators and usage samples, visit the [RxJS API Documentation](https://rxjs.dev/api).
<div class="alert is-helpful">
Note that, for Angular apps, we prefer combining operators with pipes, rather than chaining. Chaining is used in many RxJS examples.

View File

@ -927,7 +927,7 @@ As always, strive for consistency.
<div class="s-rule do">
**Do** use a custom prefix for a component selector.
For example, the prefix `toh` represents from **T**our **o**f **H**eroes and the prefix `admin` represents an admin feature area.
For example, the prefix `toh` represents **T**our **o**f **H**eroes and the prefix `admin` represents an admin feature area.
</div>
@ -1080,6 +1080,10 @@ For example, the prefix `toh` represents from **T**our **o**f **H**eroes and the
**Do** use consistent names for all pipes, named after their feature.
The pipe class name should use [UpperCamelCase](guide/glossary#case-types)
(the general convention for class names),
and the corresponding `name` string should use *lowerCamelCase*.
The `name` string cannot use hyphens ("dash-case" or "kebab-case").
</div>
@ -1670,7 +1674,7 @@ keep the **F**lattest structure you can, and
**Why?** LIFT Provides a consistent structure that scales well, is modular, and makes it easier to increase developer efficiency by finding code quickly.
**Why?** LIFT provides a consistent structure that scales well, is modular, and makes it easier to increase developer efficiency by finding code quickly.
To confirm your intuition about a particular structure, ask:
_can I quickly open and start work in all of the related files for this feature_?
@ -1690,7 +1694,7 @@ _can I quickly open and start work in all of the related files for this feature_
**Do** make locating code intuitive, simple and fast.
**Do** make locating code intuitive, simple, and fast.
</div>

View File

@ -6,14 +6,14 @@ This guide offers tips and techniques for unit and integration testing Angular a
The guide presents tests of a sample application created with the [Angular CLI](cli). This sample application is much like the one created in the [_Tour of Heroes_ tutorial](tutorial).
The sample application and all tests in this guide are available for inspection and experimentation:
- <live-example embedded-style>Sample app</live-example>
- <live-example stackblitz="specs">Tests</live-example>
- <live-example embedded-style noDownload>Sample app</live-example>
- <live-example stackblitz="specs" noDownload>Tests</live-example>
<hr>
## Setup
The Angular CLI downloads and install everything you need to test an Angular application with the [Jasmine test framework](https://jasmine.github.io/).
The Angular CLI downloads and installs everything you need to test an Angular application with the [Jasmine test framework](https://jasmine.github.io/).
The project you create with the CLI is immediately ready to test.
Just run the [`ng test`](cli/test) CLI command:
@ -116,7 +116,7 @@ jobs:
build:
working_directory: ~/my-project
docker:
- image: circleci/node:8-browsers
- image: circleci/node:10-browsers
steps:
- checkout
- restore_cache:

View File

@ -2,7 +2,7 @@
You learned the basics of Angular animations in the [introduction](guide/animations) page.
In this guide, we go into greater depth on special transition states such as `*` (wildcard) and `void`, and show how these special states are used for elements entering and leaving a view. The chapter also explores on multiple animation triggers, animation callbacks and sequence-based animation using keyframes.
In this guide, we go into greater depth on special transition states such as `*` (wildcard) and `void`, and show how these special states are used for elements entering and leaving a view. The chapter also explores multiple animation triggers, animation callbacks and sequence-based animation using keyframes.
## Predefined states and wildcard matching

View File

@ -348,7 +348,7 @@ For example:
<code-example language="json">
"sourceMaps": { "scripts": true, "styles": false, "hidden": true, "vendor": true }
"sourceMap": { "scripts": true, "styles": false, "hidden": true, "vendor": true }
</code-example>

View File

@ -43,6 +43,12 @@
<td>Berlin, Germany</td>
<td>August 29th workshops, 30-31 conference, 2019</td>
</tr>
<!-- ReactiveConf 2019 -->
<tr>
<th><a href="https://reactiveconf.com/" title="ReactiveConf">ReactiveConf</a></th>
<td>Prague, Czech Republic</td>
<td>October 30 - November 1, 2019</td>
</tr>
</tbody>
</table>

View File

@ -637,6 +637,12 @@
"rev": true,
"title": "Loiane Training (Português)",
"url": "https://loiane.training/course/angular/"
},
"web-dev-angular": {
"desc": "Build performant and progressive Angular applications.",
"rev": true,
"title": "web.dev/angular",
"url": "https://web.dev/angular"
}
}
},
@ -728,7 +734,7 @@
"desc": "Angular trainings delivered by Zenika (FRANCE)",
"rev": true,
"title": "Angular Trainings (French)",
"url": "https://training.zenika.com/fr/training/angular2/description"
"url": "https://training.zenika.com/fr/training/angular/description"
},
"formationjs": {
"desc": "Angular onsite training in Paris (France). Monthly Angular workshops and custom onsite classes. We are focused on Angular, so we are always up to date.",

View File

@ -597,6 +597,11 @@
"title": "Ahead-of-Time Compilation",
"tooltip": "Learn why and how to use the Ahead-of-Time (AOT) compiler."
},
{
"url": "guide/angular-compiler-options",
"title": "Compiler Options",
"tooltip": "Configuration options for the AOT compiler."
},
{
"url": "guide/build",
"title": "Building & Serving",

View File

@ -91,8 +91,6 @@ configures it with the `routes` in one step by calling
Next, `AppRoutingModule` exports `RouterModule` so it will be available throughout the app.
Open the `AppComponent` template and replace the `<app-heroes>` element with a `<router-outlet>` element.
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts (exports array)" region="export-routermodule">
</code-example>

View File

@ -317,7 +317,7 @@ Each hero in the heroes list should have a delete button.
Add the following button element to the `HeroesComponent` template, after the hero
name in the repeated `<li>` element.
<code-example path="toh-pt6/src/app/heroes/heroes.component.html" header="src/app/hero.service.ts" region="delete"></code-example>
<code-example path="toh-pt6/src/app/heroes/heroes.component.html" header="src/app/heroes/heroes.component.html" region="delete"></code-example>
The HTML for the list of heroes should look like this:

View File

@ -8,7 +8,7 @@
"scripts": {
"preinstall": "node ../tools/yarn/check-yarn.js",
"postinstall": "node tools/cli-patches/patch.js",
"aio-use-local": "node tools/ng-packages-installer overwrite . --debug",
"aio-use-local": "node tools/ng-packages-installer overwrite . --debug --force --build-packages",
"aio-use-npm": "node tools/ng-packages-installer restore .",
"aio-check-local": "node tools/ng-packages-installer check .",
"ng": "yarn check-env && ng",
@ -17,18 +17,22 @@
"build": "yarn ~~build",
"prebuild-local": "yarn setup-local",
"build-local": "yarn ~~build",
"prebuild-local-ci": "yarn setup-local --no-build-packages",
"build-local-ci": "yarn ~~build --progress=false",
"prebuild-with-ivy": "yarn setup-local && node scripts/switch-to-ivy",
"build-with-ivy": "yarn ~~build",
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js a8fe15cb6",
"prebuild-with-ivy-ci": "yarn setup-local --no-build-packages && node scripts/switch-to-ivy",
"build-with-ivy-ci": "yarn ~~build --progress=false",
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js de49294bf",
"lint": "yarn check-env && yarn docs-lint && ng lint && yarn example-lint && yarn tools-lint",
"test": "yarn check-env && ng test",
"pree2e": "yarn check-env && yarn update-webdriver",
"e2e": "ng e2e --no-webdriver-update",
"presetup": "yarn --cwd .. install && yarn install --frozen-lockfile && yarn ~~check-env && yarn ~~clean-generated && yarn boilerplate:remove",
"setup": "yarn aio-use-npm && yarn example-use-npm",
"setup": "yarn example-use-npm && yarn aio-use-npm",
"postsetup": "yarn boilerplate:add && yarn extract-cli-command-docs && yarn docs",
"presetup-local": "yarn presetup",
"setup-local": "yarn aio-use-local && yarn example-use-local",
"setup-local": "yarn example-use-local && yarn aio-use-local",
"postsetup-local": "yarn postsetup",
"set-opensearch-url": "node --eval \"const sh = require('shelljs'); sh.set('-e'); sh.sed('-i', /PLACEHOLDER_URL/g, process.argv[1], 'dist/assets/opensearch.xml');\"",
"presmoke-tests": "yarn update-webdriver",
@ -39,7 +43,7 @@
"test-pwa-score-localhost": "run-p --race \"~~light-server -s dist -p 4200 --quiet\" \"test-pwa-score http://localhost:4200 {1} {2}\" --",
"example-e2e": "yarn example-check-local && node ./tools/examples/run-example-e2e",
"example-lint": "tslint --config \"content/examples/tslint.json\" \"content/examples/**/*.ts\" --exclude \"content/examples/styleguide/**/*.avoid.ts\"",
"example-use-local": "node tools/ng-packages-installer overwrite ./tools/examples/shared --debug",
"example-use-local": "node tools/ng-packages-installer overwrite ./tools/examples/shared --debug --force",
"example-use-npm": "node tools/ng-packages-installer restore ./tools/examples/shared",
"example-check-local": "node tools/ng-packages-installer check ./tools/examples/shared",
"deploy-production": "scripts/deploy-to-firebase.sh",

View File

@ -9,5 +9,4 @@
@import 'marketing-layout';
@import 'not-found';
@import 'sidenav';
@import 'table-of-contents';
@import 'top-menu';

View File

@ -1,10 +0,0 @@
nav#main-table-of-contents {
width: 200px;
height: 900px;
position: fixed;
right: 0;
top: 50px;
bottom: 100px;
margin-left: 32px;
background-color: $blue;
}

View File

@ -2,112 +2,96 @@
max-width: 1200px;
table {
margin: 12px 0 24px;
margin: 12px 0 24px;
th {
text-transform: none;
@include font-size(16);
font-weight: bold;
th {
text-transform: none;
@include font-size(16);
font-weight: bold;
}
tr {
border-bottom: 1px solid $lightgray;
}
td {
vertical-align: middle;
}
// This is overriding a style here:
// https://github.com/angular/angular/blob/95993e1/aio/src/styles/2-modules/_table.scss#L58-L62
tbody > tr > td tr td:first-child {
@media screen and (max-width: 480px) {
background-color: inherit;
}
}
hr {
margin: 16px 0;
}
tr:last-child {
border-bottom: none;
}
&.item-table {
td {
padding: 32px;
}
}
&.list-table {
td {
padding: 16px 24px;
}
}
.short-description {
margin-left: 0;
}
&.parameters-table {
margin-top: 0;
@include font-size(14);
box-shadow: none;
tr {
border-bottom: 1px solid $lightgray;
@media screen and (max-width: 480px) {
display: flex;
flex-direction: column;
}
td:first-child {
font-weight: 600;
padding-left: 16px;
width: 20%;
}
}
td {
vertical-align: middle;
padding: 8px 8px 8px 0;
border: 0;
vertical-align: top;
}
}
// This is overriding a style here:
// https://github.com/angular/angular/blob/95993e1/aio/src/styles/2-modules/_table.scss#L58-L62
tbody > tr > td tr td:first-child {
@media screen and (max-width: 480px) {
background-color: inherit;
}
}
hr {
margin: 16px 0;
}
tr:last-child {
border-bottom: none;
}
&.item-table {
td {
padding: 32px;
}
}
&.list-table {
td {
padding: 16px 24px;
}
}
.short-description {
margin-left: 0;
}
&.parameters-table {
margin-top: 0;
@include font-size(14);
box-shadow: none;
tr {
@media screen and (max-width: 480px) {
display: flex;
flex-direction: column;
}
td:first-child {
font-weight: 600;
padding-left: 16px;
width: 20%;
}
}
td {
padding: 8px 8px 8px 0;
border: 0;
vertical-align: top;
}
}
&.property-table {
td {
vertical-align: top;
}
&.property-table {
td {
vertical-align: top;
}
}
}
.class-overview {
position: relative;
code-example {
clear: left;
clear: left;
}
}
.short-description {
margin: 6px 0 0 10px;
}
}
.breadcrumb-container {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.api-header {
display: flex;
align-items: center;
@media screen and (max-width: 600px) {
flex-direction: column;
align-items: flex-start;
margin-top: 8px;
}
h1 {
@ -117,10 +101,12 @@
.github-links {
float: right;
.material-icons {
border-radius: 4px;
padding: 4px;
@include font-size(20);
&:hover {
background-color: $mist;
}
@ -128,19 +114,20 @@
}
.api-body {
.class-overview {
position: relative;
code-example {
clear: left;
clear: left;
}
}
.method-table, .option-table, .list-table {
.method-table,
.option-table,
.list-table {
td > code {
background-color: inherit;
white-space: pre;
white-space: pre-wrap;
}
.with-github-links {
@ -161,7 +148,7 @@
h3 {
margin: 6px 0;
font-weight: bold;
font-weight: 500;
clear: left;
}
@ -172,10 +159,9 @@
}
}
.api-heading {
padding: 5px 0;
@include font-size(14);
margin: 16px;
}
.parameters-table {
@ -244,7 +230,9 @@
}
.from-constructor, .read-only-property, .write-only-property {
.from-constructor,
.read-only-property,
.write-only-property {
@include font-size(12);
font-weight: 600;
@include letter-spacing(0.5);
@ -259,7 +247,8 @@
padding: 0;
}
.selector-list, .inherited-members-list {
.selector-list,
.inherited-members-list {
ul {
padding: 0;
li {
@ -270,7 +259,8 @@
}
.selector-list {
li, a {
li,
a {
font-weight: bold;
i {
font-weight: normal;
@ -279,6 +269,39 @@
}
}
.breadcrumb-container {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.api-header {
display: flex;
align-items: center;
margin-top: -4px;
@media screen and (max-width: 600px) {
flex-direction: column;
align-items: flex-start;
}
h1 {
margin: 0;
}
}
.github-links {
float: right;
.material-icons {
border-radius: 4px;
padding: 4px;
font-size: 20px;
&:hover {
background-color: $mist;
}
}
}
.deprecated-api-item {
text-decoration: line-through;
}

View File

@ -1,6 +1,11 @@
code-example, code-tabs {
code-example,
code-tabs {
clear: both;
display: block;
ol {
list-style: decimal;
}
}
code-example {

View File

@ -30,159 +30,160 @@
&:hover {
color: $accentblue;
}
}
}
button.toc-heading,
button.toc-more-items {
cursor: pointer;
display: inline-block;
background: 0;
background-color: transparent;
border: none;
box-shadow: none;
padding: 0;
text-align: start;
button {
&.toc-heading,
&.toc-more-items {
cursor: pointer;
display: inline-block;
background: 0;
background-color: transparent;
border: none;
box-shadow: none;
padding: 0;
text-align: start;
&.embedded:focus {
outline: none;
background: $lightgray;
}
}
button.toc-heading {
mat-icon.rotating-icon {
height: 18px;
width: 18px;
position: relative;
left: -4px;
top: 5px;
}
&:hover:not(.embedded) {
color: $accentblue;
}
}
button.toc-more-items {
color: $mediumgray;
top: 10px;
position: relative;
&:hover {
color: $accentblue;
}
&::after {
content: 'expand_less';
}
&.collapsed::after {
content: 'more_horiz';
}
}
.mat-icon {
&.collapsed {
@include rotate(0deg);
}
&:not(.collapsed) {
@include rotate(90deg);
}
}
ul.toc-list {
list-style-type: none;
margin: 0;
padding: 0 8px 0 0;
@media (max-width: 800px) {
width: auto;
}
li {
box-sizing: border-box;
@include font-size(12);
@include line-height(16);
padding: 3px 0 3px 12px;
position: relative;
transition: all 0.3s ease-in-out;
&.h1:after {
content: '';
display: block;
height: 1px;
width: 40%;
margin: 7px 0 4px 0;
&.embedded:focus {
outline: none;
background: $lightgray;
clear: both;
}
}
&.toc-heading {
mat-icon.rotating-icon {
height: 18px;
width: 18px;
position: relative;
left: -4px;
top: 5px;
}
&.h3 {
padding-left: 24px;
&:hover:not(.embedded) {
color: $accentblue;
}
}
a {
color: lighten($darkgray, 10);
overflow: visible;
@include font-size(12);
display: table-cell;
}
&.toc-more-items {
color: $mediumgray;
top: 10px;
position: relative;
&:hover {
* {
color: $accentblue;
}
color: $accentblue;
}
&.active {
* {
color: $blue;
font-weight: 500;
&::after {
content: 'expand_less';
}
&:before {
content: '';
border-radius: 50%;
left: -3px;
top: 12px;
background: $blue;
position: absolute;
width: 6px;
height: 6px;
&.collapsed::after {
content: 'more_horiz';
}
}
.mat-icon {
&.collapsed {
@include rotate(0deg);
}
&:not(.collapsed) {
@include rotate(90deg);
}
}
ul.toc-list {
list-style-type: none;
margin: 0;
padding: 0 8px 0 0;
@media (max-width: 800px) {
width: auto;
}
li {
box-sizing: border-box;
@include font-size(12);
@include line-height(16);
padding: 3px 0 3px 12px;
position: relative;
transition: all 0.3s ease-in-out;
&.h1:after {
content: '';
display: block;
height: 1px;
width: 40%;
margin: 7px 0 4px 0;
background: $lightgray;
clear: both;
}
&.h3 {
padding-left: 24px;
}
a {
color: lighten($darkgray, 10);
overflow: visible;
@include font-size(12);
display: table-cell;
}
&:hover {
* {
color: $accentblue;
}
}
&.active {
* {
color: $blue;
font-weight: 500;
&:before {
content: '';
border-radius: 50%;
left: -3px;
top: 12px;
background: $blue;
position: absolute;
width: 6px;
height: 6px;
}
}
}
}
}
&:not(.embedded) li {
&:before {
border-left: 1px solid $lightgray;
bottom: 0;
content: '';
left: 0;
position: absolute;
top: 0;
}
&:not(.embedded) li {
&:before {
border-left: 1px solid $lightgray;
bottom: 0;
content: '';
left: 0;
position: absolute;
top: 0;
}
&:first-child:before {
top: 13px;
}
&:first-child:before {
top: 13px;
}
&:last-child:before {
bottom: calc(100% - 14px);
}
&:last-child:before {
bottom: calc(100% - 14px);
}
&:not(.active):hover a:before {
content: '';
border-radius: 50%;
left: -3px;
top: 12px;
background: $lightgray;
position: absolute;
width: 6px;
height: 6px;
&:not(.active):hover a:before {
content: '';
border-radius: 50%;
left: -3px;
top: 12px;
background: $lightgray;
position: absolute;
width: 6px;
height: 6px;
}
}
}
}

View File

@ -84,25 +84,23 @@ class ExampleZipper {
const outputFileName = path.join(outputDirName, relativeDirName, exampleZipName + '.zip');
let defaultIncludes = ['**/*.ts', '**/*.js', '**/*.es6', '**/*.css', '**/*.html', '**/*.md', '**/*.json', '**/*.png', '**/*.svg'];
let alwaysIncludes = [
'bs-config.json',
'e2e/protractor.conf.js',
'angular.json',
'.editorconfig',
'.gitignore',
'tslint.json',
'angular.json',
'browserslist',
'bs-config.json',
'karma.conf.js',
'karma-test-shim.js',
'tsconfig.json',
'src/testing/**/*',
'src/.babelrc',
'src/browserslist',
'tsconfig.*',
'tslint.*',
'e2e/protractor.conf.js',
'e2e/tsconfig.json',
'src/favicon.ico',
'src/karma.conf.js',
'src/polyfills.ts',
'src/test.ts',
'src/typings.d.ts',
'src/environments/**/*',
'src/tsconfig.*',
'src/tslint.*',
'src/testing/**/*',
// Only ignore root package.json
'!package.json'
];

View File

@ -46,6 +46,8 @@ if (argv.ivy) {
* Must be used in conjunction with --setup as this is when the packages are copied.
* e.g. --setup --local
*
* --ivy to turn on `ivy` mode
*
* --shard to shard the specs into groups to allow you to run them in parallel
* e.g. --shard=0/2 // the even specs: 0, 2, 4, etc
* e.g. --shard=1/2 // the odd specs: 1, 3, 5, etc

View File

@ -1,5 +1,5 @@
{
"extends": "../tsconfig.json",
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"types": []

View File

@ -1,5 +1,5 @@
{
"extends": "../tsconfig.json",
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/spec",
"types": [
@ -8,8 +8,8 @@
]
},
"files": [
"test.ts",
"polyfills.ts"
"src/test.ts",
"src/polyfills.ts"
],
"include": [
"src/**/*.spec.ts",

View File

@ -471,7 +471,7 @@
"@types/node@~8.9.4":
version "8.9.5"
resolved "http://registry.npmjs.org/@types/node/-/node-8.9.5.tgz#162b864bc70be077e6db212b322754917929e976"
resolved "https://registry.npmjs.org/@types/node/-/node-8.9.5.tgz#162b864bc70be077e6db212b322754917929e976"
"@types/q@^0.0.32":
version "0.0.32"
@ -2820,7 +2820,7 @@ express@2.5.x:
express@^4.14.1:
version "4.16.3"
resolved "http://registry.npmjs.org/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53"
resolved "https://registry.npmjs.org/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53"
dependencies:
accepts "~1.3.5"
array-flatten "1.1.1"
@ -3039,7 +3039,7 @@ finalhandler@1.0.6:
finalhandler@1.1.1:
version "1.1.1"
resolved "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105"
resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105"
dependencies:
debug "2.6.9"
encodeurl "~1.0.2"
@ -5592,7 +5592,7 @@ p-finally@^1.0.0:
p-is-promise@^1.1.0:
version "1.1.0"
resolved "http://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e"
resolved "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e"
p-limit@^2.0.0:
version "2.0.0"

View File

@ -14,7 +14,8 @@ const LOCAL_MARKER_PATH = 'node_modules/_local_.json';
const PACKAGE_JSON_REGEX = /^[^/]+\/package\.json$/;
const ANGULAR_ROOT_DIR = path.resolve(__dirname, '../../..');
const ANGULAR_DIST_PACKAGES = path.resolve(ANGULAR_ROOT_DIR, 'dist/packages-dist');
const ANGULAR_DIST_PACKAGES = path.join(ANGULAR_ROOT_DIR, 'dist/packages-dist');
const ANGULAR_DIST_PACKAGES_BUILD_CMD = path.join(ANGULAR_ROOT_DIR, 'scripts/build-packages-dist.sh');
/**
* A tool that can install Angular dependencies for a project from NPM or from the
@ -29,16 +30,17 @@ class NgPackagesInstaller {
* Create a new installer for a project in the specified directory.
*
* @param {string} projectDir - the path to the directory containing the project.
* @param {object} options - a hash of options for the install
* * `debug` (`boolean`) - whether to display debug messages.
* * `force` (`boolean`) - whether to force a local installation
* even if there is a local marker file.
* * `ignorePackages` (`string[]`) - a collection of names of packages
* that should not be copied over.
* @param {object} options - a hash of options for the install:
* * `debug` (`boolean`) - whether to display debug messages.
* * `force` (`boolean`) - whether to force a local installation even if there is a local marker file.
* * `buildPackages` (`boolean`) - whether to build the local Angular packages before using them.
* (NOTE: Building the packages is currently not supported on Windows, so a message is printed instead.)
* * `ignorePackages` (`string[]`) - a collection of names of packages that should not be copied over.
*/
constructor(projectDir, options = {}) {
this.debug = options.debug;
this.force = options.force;
this.debug = this._parseBooleanArg(options.debug);
this.force = this._parseBooleanArg(options.force);
this.buildPackages = this._parseBooleanArg(options.buildPackages);
this.ignorePackages = options.ignorePackages || [];
this.projectDir = path.resolve(projectDir);
this.localMarkerPath = path.resolve(this.projectDir, LOCAL_MARKER_PATH);
@ -160,6 +162,31 @@ class NgPackagesInstaller {
});
}
/**
* Build the local Angular packages.
*
* NOTE:
* Building the packages is currently not supported on Windows, so a message is printed instead, prompting the user to
* do it themselves (e.g. using Windows Subsystem for Linux or a docker container).
*/
_buildDistPackages() {
const canBuild = process.platform !== 'win32';
if (canBuild) {
this._log(`Building the Angular packages with: ${ANGULAR_DIST_PACKAGES_BUILD_CMD}`);
shelljs.exec(ANGULAR_DIST_PACKAGES_BUILD_CMD);
} else {
this._warn([
'Automatically building the local Angular packages is currently not supported on Windows.',
`Please, ensure '${ANGULAR_DIST_PACKAGES}' exists and is up-to-date (e.g. by running ` +
`'${ANGULAR_DIST_PACKAGES_BUILD_CMD}' in Git Bash for Windows, Windows Subsystem for Linux or a Linux ` +
'docker container or VM).',
'',
'Proceeding anyway...',
].join('\n'));
}
}
_collectDependencies(dependencies, packages) {
const peerDependencies = Object.create(null);
const mergedDependencies = Object.assign(Object.create(null), dependencies);
@ -184,32 +211,35 @@ class NgPackagesInstaller {
/**
* A hash of Angular package configs.
* (Detected as directories in '/packages/' that contain a top-level 'package.json' file.)
* (Detected as directories in '/dist/packages-dist/' that contain a top-level 'package.json' file.)
*/
_getDistPackages() {
const packageConfigs = Object.create(null);
const distDir = ANGULAR_DIST_PACKAGES;
[ANGULAR_DIST_PACKAGES].forEach(distDir => {
this._log(`Angular distributable directory: ${distDir}.`);
shelljs
.find(distDir)
.map(filePath => filePath.slice(distDir.length + 1))
.filter(filePath => PACKAGE_JSON_REGEX.test(filePath))
.forEach(packagePath => {
const packageName = `@angular/${packagePath.slice(0, -PACKAGE_JSON.length -1)}`;
if (this.ignorePackages.indexOf(packageName) === -1) {
const packageConfig = require(path.resolve(distDir, packagePath));
packageConfigs[packageName] = {
parentDir: distDir,
packageJsonPath: path.resolve(distDir, packagePath),
config: packageConfig
};
} else {
this._log('Ignoring package', packageName);
}
});
this._log(`Angular distributable directory: ${distDir}.`);
});
if (this.buildPackages) {
this._buildDistPackages();
}
shelljs
.find(distDir)
.map(filePath => filePath.slice(distDir.length + 1))
.filter(filePath => PACKAGE_JSON_REGEX.test(filePath))
.forEach(packagePath => {
const packageName = `@angular/${packagePath.slice(0, -PACKAGE_JSON.length -1)}`;
if (this.ignorePackages.indexOf(packageName) === -1) {
const packageConfig = require(path.resolve(distDir, packagePath));
packageConfigs[packageName] = {
parentDir: distDir,
packageJsonPath: path.resolve(distDir, packagePath),
config: packageConfig
};
} else {
this._log('Ignoring package', packageName);
}
});
this._log('Found the following Angular distributables:', Object.keys(packageConfigs).map(key => `\n - ${key}`));
return packageConfigs;
@ -234,6 +264,21 @@ class NgPackagesInstaller {
}
}
/**
* Extract the value for a boolean cli argument/option. When passing an option multiple times, `yargs` parses it as an
* array of boolean values. In that case, we only care about the last occurrence.
*
* This can be useful, for example, when one has a base command with the option turned on and another command
* (building on top of the first one) turning the option off:
* ```
* "base-command": "my-script --foo --bar",
* "no-bar-command": "yarn base-command --no-bar",
* ```
*/
_parseBooleanArg(value) {
return Array.isArray(value) ? value.pop() : value;
}
/**
* Parse and return a `yarn.lock` file.
*/
@ -254,17 +299,28 @@ class NgPackagesInstaller {
const restoreCmd = `node ${relativeScriptPath} restore ${absoluteProjectDir}`;
// Log a warning.
this._warn([
`The project at "${absoluteProjectDir}" is running against the local Angular build.`,
'',
'To restore the npm packages run:',
'',
` "${restoreCmd}"`,
].join('\n'));
}
/**
* Log a warning message do draw user's attention.
* @param {...string[]} messages - The messages to be logged.
*/
_warn(...messages) {
const lines = messages.join(' ').split('\n');
console.warn(chalk.yellow([
'',
'!'.repeat(110),
'!!!',
'!!! WARNING',
'!!!',
`!!! The project at "${absoluteProjectDir}" is running against the local Angular build.`,
'!!!',
'!!! To restore the npm packages run:',
'!!!',
`!!! "${restoreCmd}"`,
...lines.map(line => `!!! ${line}`),
'!!!',
'!'.repeat(110),
'',
@ -287,24 +343,27 @@ class NgPackagesInstaller {
function main() {
shelljs.set('-e');
const createInstaller = argv => {
const {projectDir, ...options} = argv;
return new NgPackagesInstaller(projectDir, options);
};
yargs
.usage('$0 <cmd> [args]')
.option('debug', { describe: 'Print additional debug information.', default: false })
.option('force', { describe: 'Force the command to execute even if not needed.', default: false })
.option('build-packages', { describe: 'Build the local Angular packages, before using them.', default: false })
.option('ignore-packages', { describe: 'List of Angular packages that should not be used in local mode.', default: [], array: true })
.command('overwrite <projectDir> [--force] [--debug] [--ignore-packages package1 package2]', 'Install dependencies from the locally built Angular distributables.', () => {}, argv => {
const installer = new NgPackagesInstaller(argv.projectDir, argv);
installer.installLocalDependencies();
createInstaller(argv).installLocalDependencies();
})
.command('restore <projectDir> [--debug]', 'Install dependencies from the npm registry.', () => {}, argv => {
const installer = new NgPackagesInstaller(argv.projectDir, argv);
installer.restoreNpmDependencies();
createInstaller(argv).restoreNpmDependencies();
})
.command('check <projectDir> [--debug]', 'Check that dependencies came from npm. Otherwise display a warning message.', () => {}, argv => {
const installer = new NgPackagesInstaller(argv.projectDir, argv);
installer.checkDependencies();
createInstaller(argv).checkDependencies();
})
.demandCommand(1, 'Please supply a command from the list above.')
.strict()

View File

@ -8,13 +8,14 @@ const shelljs = require('shelljs');
const NgPackagesInstaller = require('./index');
describe('NgPackagesInstaller', () => {
const rootDir = 'root/dir';
const absoluteRootDir = path.resolve(rootDir);
const nodeModulesDir = path.resolve(absoluteRootDir, 'node_modules');
const packageJsonPath = path.resolve(absoluteRootDir, 'package.json');
const yarnLockPath = path.resolve(absoluteRootDir, 'yarn.lock');
const packagesDir = path.resolve(path.resolve(__dirname, '../../../dist/packages-dist'));
const toolsDir = path.resolve(path.resolve(__dirname, '../../../dist/tools/@angular'));
const projectDir = 'root/dir';
const absoluteProjectDir = path.resolve(projectDir);
const nodeModulesDir = path.resolve(absoluteProjectDir, 'node_modules');
const packageJsonPath = path.resolve(absoluteProjectDir, 'package.json');
const yarnLockPath = path.resolve(absoluteProjectDir, 'yarn.lock');
const ngRootDir = path.resolve(__dirname, '../../..');
const packagesDir = path.join(ngRootDir, 'dist/packages-dist');
const toolsDir = path.join(ngRootDir, 'dist/tools/@angular');
let installer;
beforeEach(() => {
@ -25,7 +26,7 @@ describe('NgPackagesInstaller', () => {
spyOn(shelljs, 'rm');
spyOn(console, 'log');
spyOn(console, 'warn');
installer = new NgPackagesInstaller(rootDir);
installer = new NgPackagesInstaller(projectDir);
});
describe('checkDependencies()', () => {
@ -36,14 +37,14 @@ describe('NgPackagesInstaller', () => {
it('should not print a warning if there is no _local_.json file', () => {
fs.existsSync.and.returnValue(false);
installer.checkDependencies();
expect(fs.existsSync).toHaveBeenCalledWith(path.resolve(rootDir, 'node_modules/_local_.json'));
expect(fs.existsSync).toHaveBeenCalledWith(path.resolve(projectDir, 'node_modules/_local_.json'));
expect(installer._printWarning).not.toHaveBeenCalled();
});
it('should print a warning if there is a _local_.json file', () => {
fs.existsSync.and.returnValue(true);
installer.checkDependencies();
expect(fs.existsSync).toHaveBeenCalledWith(path.resolve(rootDir, 'node_modules/_local_.json'));
expect(fs.existsSync).toHaveBeenCalledWith(path.resolve(projectDir, 'node_modules/_local_.json'));
expect(installer._printWarning).toHaveBeenCalled();
});
});
@ -242,7 +243,68 @@ describe('NgPackagesInstaller', () => {
});
});
describe('_buildDistPackages()', () => {
// Call `_buildDistPackages()` with a mock `process.platform` value.
const buildDistPackagesOnPlatform = platform => {
const originalDescriptor = Object.getOwnPropertyDescriptor(process, 'platform');
Object.defineProperty(process, 'platform', {...originalDescriptor, value: platform});
installer._buildDistPackages();
Object.defineProperty(process, 'platform', originalDescriptor);
};
it('should build the local packages, when not on Windows', () => {
const buildScript = path.join(ngRootDir, 'scripts/build-packages-dist.sh');
buildDistPackagesOnPlatform('linux');
expect(shelljs.exec).toHaveBeenCalledWith(buildScript);
shelljs.exec.calls.reset();
buildDistPackagesOnPlatform('darwin');
expect(shelljs.exec).toHaveBeenCalledWith(buildScript);
shelljs.exec.calls.reset();
buildDistPackagesOnPlatform('anythingButWindows :(');
expect(shelljs.exec).toHaveBeenCalledWith(buildScript);
// Ensure that the script does actually exist (e.g. it was not renamed/moved).
fs.existsSync.and.callThrough();
expect(fs.existsSync(buildScript)).toBe(true);
});
it('should print a warning, when on Windows', () => {
buildDistPackagesOnPlatform('win32');
const warning = console.warn.calls.argsFor(0)[0];
expect(shelljs.exec).not.toHaveBeenCalled();
expect(warning).toContain(
'Automatically building the local Angular packages is currently not supported on Windows.');
expect(warning).toContain('Git Bash for Windows');
expect(warning).toContain('Windows Subsystem for Linux');
expect(warning).toContain('Linux docker container or VM');
});
});
describe('_getDistPackages()', () => {
beforeEach(() => spyOn(NgPackagesInstaller.prototype, '_buildDistPackages'));
it('should not build the local packages by default', () => {
installer._getDistPackages();
expect(installer._buildDistPackages).not.toHaveBeenCalled();
});
it('should build the local packages, if `buildPackages` is true', () => {
installer = new NgPackagesInstaller(projectDir, {buildPackages: true});
installer._getDistPackages();
expect(installer._buildDistPackages).toHaveBeenCalledTimes(1);
});
it('should not build the local packages by default', () => {
installer._getDistPackages();
expect(installer._buildDistPackages).not.toHaveBeenCalled();
});
it('should include top level Angular packages', () => {
const ngPackages = installer._getDistPackages();
const expectedValue = jasmine.objectContaining({
@ -269,7 +331,7 @@ describe('NgPackagesInstaller', () => {
});
it('should not include packages that have been ignored', () => {
installer = new NgPackagesInstaller(rootDir, { ignorePackages: ['@angular/router'] });
installer = new NgPackagesInstaller(projectDir, { ignorePackages: ['@angular/router'] });
const ngPackages = installer._getDistPackages();
expect(ngPackages['@angular/common']).toBeDefined();
@ -283,9 +345,9 @@ describe('NgPackagesInstaller', () => {
});
it('should assign the debug property from the options', () => {
installer = new NgPackagesInstaller(rootDir, { debug: true });
installer = new NgPackagesInstaller(projectDir, { debug: true });
expect(installer.debug).toBe(true);
installer = new NgPackagesInstaller(rootDir, { });
installer = new NgPackagesInstaller(projectDir, { });
expect(installer.debug).toBe(undefined);
});
@ -350,7 +412,7 @@ describe('NgPackagesInstaller', () => {
expect(console.warn.calls.argsFor(0)[0]).toMatch(restoreCmdRe1);
// When run for a different directory...
const dir2 = rootDir;
const dir2 = projectDir;
const restoreCmdRe2 = RegExp(`\\bnode .*?ng-packages-installer/index restore .*?${path.resolve(dir1)}\\b`);
installer = new NgPackagesInstaller(dir2);
installer._printWarning('');
@ -361,14 +423,14 @@ describe('NgPackagesInstaller', () => {
describe('_installDeps()', () => {
it('should run yarn install with the given options', () => {
installer._installDeps('option-1', 'option-2');
expect(shelljs.exec).toHaveBeenCalledWith('yarn install option-1 option-2', { cwd: absoluteRootDir });
expect(shelljs.exec).toHaveBeenCalledWith('yarn install option-1 option-2', { cwd: absoluteProjectDir });
});
});
describe('local marker helpers', () => {
let installer;
beforeEach(() => {
installer = new NgPackagesInstaller(rootDir);
installer = new NgPackagesInstaller(projectDir);
});
describe('_checkLocalMarker', () => {

View File

@ -208,9 +208,9 @@
<code>{$ renderMemberSyntax(property) $}</code>
</td>
<td>
{%- if (property.isGetAccessor or property.isReadonly) and not property.isSetAccessor %}<span class='read-only-property'>Read-only.</span>{% endif %}
{%- if property.isSetAccessor and not property.isGetAccessor %}<span class='write-only-property'>Write-only.</span>{% endif %}
{% if property.constructorParamDoc %} <span class='from-constructor'>Declared in constructor.</span>{% endif %}
{%- if (property.isGetAccessor or property.isReadonly) and not property.isSetAccessor %}<span class='read-only-property'>Read-Only</span>{% endif %}
{%- if property.isSetAccessor and not property.isGetAccessor %}<span class='write-only-property'>Write-Only</span>{% endif %}
{% if property.constructorParamDoc %} <span class='from-constructor'>Declared in Constructor</span>{% endif %}
{% if property.shortDescription %}{$ property.shortDescription | marked $}{% endif %}
{$ (property.description or property.constructorParamDoc.description) | marked $}
{%- if property.see.length %}

View File

@ -53,6 +53,7 @@ gulp.task('tools:build', loadTask('tools-build'));
gulp.task('check-cycle', loadTask('check-cycle'));
gulp.task('serve', loadTask('serve', 'default'));
gulp.task('changelog', loadTask('changelog'));
gulp.task('changelog:zonejs', loadTask('changelog-zonejs'));
gulp.task('check-env', () => {/* this is a noop because the env test ran already above */});
gulp.task('cldr:extract', loadTask('cldr', 'extract'));
gulp.task('cldr:download', loadTask('cldr', 'download'));

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 = "6d4edbf28ff6720aedf5f97f9b9a7679401bf7fca9d14a0fff80f644a99992b4",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.32.2/rules_nodejs-0.32.2.tar.gz"],
sha256 = "7c4a690268be97c96f04d505224ec4cb1ae53c2c2b68be495c9bd2634296a5cd",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.34.0/rules_nodejs-0.34.0.tar.gz"],
)
# Fetch sass rules for compiling sass files
@ -62,6 +62,11 @@ load("@npm//:install_bazel_dependencies.bzl", "install_bazel_dependencies")
install_bazel_dependencies()
# Load protractor dependencies
load("@npm_bazel_protractor//:package.bzl", "npm_bazel_protractor_dependencies")
npm_bazel_protractor_dependencies()
# Load karma dependencies
load("@npm_bazel_karma//:package.bzl", "rules_karma_dependencies")

View File

@ -23,11 +23,10 @@
"@angular/compiler": "file:../../dist/packages-dist/compiler",
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
"@bazel/bazel": "file:../../node_modules/@bazel/bazel",
"@bazel/hide-bazel-files": "0.32.2",
"@bazel/karma": "0.32.2",
"@bazel/typescript": "0.32.2",
"@bazel/karma": "0.34.0",
"@bazel/protractor": "0.34.0",
"@bazel/typescript": "0.34.0",
"@types/jasmine": "2.8.8",
"protractor": "5.1.2",
"typescript": "3.4.2"
},
"scripts": {

View File

@ -1,5 +1,5 @@
load("@npm_bazel_protractor//:index.bzl", "protractor_web_test_suite")
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm_angular_bazel//:index.bzl", "protractor_web_test_suite")
ts_library(
name = "e2e",
@ -7,7 +7,7 @@ ts_library(
srcs = ["app.spec.ts"],
tsconfig = ":tsconfig.json",
deps = [
"@npm//@types",
"@npm//@types/jasmine",
"@npm//protractor",
],
)
@ -18,8 +18,8 @@ ts_library(
srcs = ["on-prepare.ts"],
tsconfig = ":tsconfig.json",
deps = [
"@npm//@angular/bazel",
"@npm//@types",
"@npm//@bazel/protractor",
"@npm//@types/node",
"@npm//protractor",
],
)
@ -27,10 +27,6 @@ ts_library(
protractor_web_test_suite(
name = "devserver_test",
configuration = "//:protractor.conf.js",
data = [
"@npm//@angular/bazel",
"@npm//protractor",
],
on_prepare = ":ts_on_prepare",
server = "//src:devserver",
deps = [":e2e"],
@ -39,10 +35,6 @@ protractor_web_test_suite(
protractor_web_test_suite(
name = "prodserver_test",
configuration = "//:protractor.conf.js",
data = [
"@npm//@angular/bazel",
"@npm//protractor",
],
on_prepare = ":ts_on_prepare",
server = "//src:prodserver",
deps = [":e2e"],

View File

@ -1,5 +1,5 @@
import { browser } from 'protractor';
import {OnPrepareConfig, runServer} from '@angular/bazel/protractor-utils';
import {OnPrepareConfig, runServer} from '@bazel/protractor/protractor-utils';
export = function(config: OnPrepareConfig) {
const portFlag = /prodserver(\.exe)?$/.test(config.server) ? '-p' : '-port';

View File

@ -30,12 +30,12 @@
rxjs "6.4.0"
"@angular/animations@file:../../dist/packages-dist/animations":
version "8.1.0-next.3"
version "8.2.0-next.2"
dependencies:
tslib "^1.9.0"
"@angular/bazel@file:../../dist/packages-dist/bazel":
version "8.1.0-next.3"
version "8.2.0-next.2"
dependencies:
"@angular-devkit/architect" "^0.800.0-beta.15"
"@angular-devkit/core" "^8.0.0-beta.15"
@ -57,12 +57,12 @@
parse5 "^5.0.0"
"@angular/common@file:../../dist/packages-dist/common":
version "8.1.0-next.3"
version "8.2.0-next.2"
dependencies:
tslib "^1.9.0"
"@angular/compiler-cli@file:../../dist/packages-dist/compiler-cli":
version "8.1.0-next.3"
version "8.2.0-next.2"
dependencies:
canonical-path "1.0.0"
chokidar "^2.1.1"
@ -76,17 +76,17 @@
yargs "13.1.0"
"@angular/compiler@file:../../dist/packages-dist/compiler":
version "8.1.0-next.3"
version "8.2.0-next.2"
dependencies:
tslib "^1.9.0"
"@angular/core@file:../../dist/packages-dist/core":
version "8.1.0-next.3"
version "8.2.0-next.2"
dependencies:
tslib "^1.9.0"
"@angular/forms@file:../../dist/packages-dist/forms":
version "8.1.0-next.3"
version "8.2.0-next.2"
dependencies:
tslib "^1.9.0"
@ -98,51 +98,53 @@
tslib "^1.7.1"
"@angular/platform-browser-dynamic@file:../../dist/packages-dist/platform-browser-dynamic":
version "8.1.0-next.3"
version "8.2.0-next.2"
dependencies:
tslib "^1.9.0"
"@angular/platform-browser@file:../../dist/packages-dist/platform-browser":
version "8.1.0-next.3"
version "8.2.0-next.2"
dependencies:
tslib "^1.9.0"
"@angular/router@file:../../dist/packages-dist/router":
version "8.1.0-next.3"
version "8.2.0-next.2"
dependencies:
tslib "^1.9.0"
"@bazel/bazel-darwin_x64@0.27.0":
version "0.27.0"
resolved "https://registry.yarnpkg.com/@bazel/bazel-darwin_x64/-/bazel-darwin_x64-0.27.0.tgz#83a03c92d52ae60e48e86a1ee697e69e12ddbdf6"
integrity sha512-CyavIbRKRa/55aMyfEM9hjbt4TVISfv7HLeymHTGTLWzS8uQokQ8W9tR/pgc7YJn8F0x64dd7nQKxhbYHM1Qfg==
"@bazel/bazel-darwin_x64@0.28.1":
version "0.28.1"
resolved "https://registry.yarnpkg.com/@bazel/bazel-darwin_x64/-/bazel-darwin_x64-0.28.1.tgz#415658785e1dbd6f7ab5c8f2b98c1c99c614e1d5"
integrity sha512-VDKWmplAfa4uCAbkIQ5nRn04MFQqtsPNuc2HkluJ8OIum773yC2dPR+OlLBKxrlBuKJYB27TtbOwOa6w/uK7aw==
"@bazel/bazel-linux_x64@0.27.0":
version "0.27.0"
resolved "https://registry.yarnpkg.com/@bazel/bazel-linux_x64/-/bazel-linux_x64-0.27.0.tgz#2358292aa4901f526ba9b90874256f63d6d6608c"
integrity sha512-hO04v7C6M3Jf+qNlLE+IticZZKkkS7Nv6+pXDnENgFWrqLV2H93un6kNQnk83B0hP2cEqRQ8rw5yrIcqXNNuSQ==
"@bazel/bazel-linux_x64@0.28.1":
version "0.28.1"
resolved "https://registry.yarnpkg.com/@bazel/bazel-linux_x64/-/bazel-linux_x64-0.28.1.tgz#f78006089e17660261088272a0e04fc886572e34"
integrity sha512-n4XfNxagYhejQD32V4XSxT/qzuH1l/2jxslbKSak66/uQ+wad8Ew9rjNb4JUin3xtrfFtzmxx2jpQkybZsRVGA==
"@bazel/bazel-win32_x64@0.27.0":
version "0.27.0"
resolved "https://registry.yarnpkg.com/@bazel/bazel-win32_x64/-/bazel-win32_x64-0.27.0.tgz#0e5e498de5ccccc9a6cf481cd46904ee938ab6c2"
integrity sha512-7hIGNhdgaxRt9ceSOCs3eSTtCNi4GXz3nu6OjfgSp+QiqLbW/iAVWa8M8vD5aemZ1BSHek4/LISdWUTncLJk+w==
"@bazel/bazel-win32_x64@0.28.1":
version "0.28.1"
resolved "https://registry.yarnpkg.com/@bazel/bazel-win32_x64/-/bazel-win32_x64-0.28.1.tgz#60a2819618cf7582cc35ac16c01763a5e807b414"
integrity sha512-T4xksGfKikaHS4zxnGT6r5R436mz9j2lz//L1vc5sJnaEF/1e2Gv6MLl86vfZW2Xxo6iIEi6ntSzgYxP2Blohw==
"@bazel/bazel@file:../../node_modules/@bazel/bazel":
version "0.27.0"
version "0.28.1"
dependencies:
"@bazel/hide-bazel-files" latest
optionalDependencies:
"@bazel/bazel-darwin_x64" "0.27.0"
"@bazel/bazel-linux_x64" "0.27.0"
"@bazel/bazel-win32_x64" "0.27.0"
"@bazel/bazel-darwin_x64" "0.28.1"
"@bazel/bazel-linux_x64" "0.28.1"
"@bazel/bazel-win32_x64" "0.28.1"
"@bazel/hide-bazel-files@0.32.2":
version "0.32.2"
resolved "https://registry.yarnpkg.com/@bazel/hide-bazel-files/-/hide-bazel-files-0.32.2.tgz#a482855eafbccb56b1fce0d92ff922c2c6e0a90c"
integrity sha512-585XY53mhMZaCjEQJ+aDqkmydWZbuXsKrZsSpoW9YeAVEH0poQY3YhdyCPmMVBo7/l1mkrqpFuOK5BpECfwdtA==
"@bazel/hide-bazel-files@latest":
version "0.34.0"
resolved "https://registry.yarnpkg.com/@bazel/hide-bazel-files/-/hide-bazel-files-0.34.0.tgz#368ea84db2756ff80ead23bb9eb179e9ed24b462"
integrity sha512-suyO6cZf8iV6W2LkM1X1spWBt7CsRRXH7gU1wYNuAuHYkkfI0A6qj84yPiIXiOt/2G44kbioGyC1bUsI3fKv7A==
"@bazel/karma@0.32.2":
version "0.32.2"
resolved "https://registry.yarnpkg.com/@bazel/karma/-/karma-0.32.2.tgz#0f6adf0cf1970c50cfdcf9cb2b10a8d3e21731fe"
integrity sha512-iWb8aqE+llpZhlreDweM7llwnSAQ9QTYdz4VvIcZBGVD0KtHxHaKiqK4Zo4Qrmr9H0kcOhT7nvRBg3QOUJVrUw==
"@bazel/karma@0.34.0":
version "0.34.0"
resolved "https://registry.yarnpkg.com/@bazel/karma/-/karma-0.34.0.tgz#ee468501a408244a2c1844b48ca5a938874d9444"
integrity sha512-9EziieE3Zkf7D5tBuX4rO+hhpI4ypNAWReiO/fykjj5oYpLYhhhGGUyFQ8PCIfduPcGZooCTMsctmwZJUb3rRA==
dependencies:
jasmine-core "2.8.0"
karma "^4.0.0"
@ -156,10 +158,17 @@
semver "5.6.0"
tmp "0.0.33"
"@bazel/typescript@0.32.2":
version "0.32.2"
resolved "https://registry.yarnpkg.com/@bazel/typescript/-/typescript-0.32.2.tgz#c296bb44cb6362a0e3a08ca88752852bc9591ecf"
integrity sha512-32zDyvHdYjIa63vtImhl6wy5ErOFVWPkjMT2T035D0UPSKI1tvENW/bRZ3QFlFHqfmJZRBpaI3GiUpO3vUvzmw==
"@bazel/protractor@0.34.0":
version "0.34.0"
resolved "https://registry.yarnpkg.com/@bazel/protractor/-/protractor-0.34.0.tgz#af166306518bf1319e8ca255f798712c8714b5e9"
integrity sha512-U6O8hRlerkQ/WfnEVct1yipVQr5epdYaLiOW1eLpmiRMM4RuMhIpIyKkpum5xqFlYP5kwqwje8BS8NHvBfvZnQ==
dependencies:
protractor "^5.4.2"
"@bazel/typescript@0.34.0":
version "0.34.0"
resolved "https://registry.yarnpkg.com/@bazel/typescript/-/typescript-0.34.0.tgz#ca0fdf15343a930fc1418dbbf7d6cae49e6bc89b"
integrity sha512-GXVSADXdbPyWLskIYAzQsBB1LhZgWF5+M6WCQGOvRWjZfXgRP5QDG5pKJavRGzVd6ofigLPA1xT6Vc7dUEDNtg==
dependencies:
protobufjs "6.8.8"
semver "5.6.0"
@ -327,20 +336,15 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.9.tgz#2e8d678039d27943ce53a1913386133227fd9066"
integrity sha512-NelG/dSahlXYtSoVPErrp06tYFrvzj8XLWmKA+X8x0W//4MqbUyZu++giUG/v0bjAT6/Qxa8IjodrfdACyb0Fg==
"@types/node@^6.0.46":
version "6.14.6"
resolved "https://registry.yarnpkg.com/@types/node/-/node-6.14.6.tgz#31df045b4c7618ff74d84f542fc3d29445dd566b"
integrity sha512-rFs9zCFtSHuseiNXxYxFlun8ibu+jtZPgRM+2ILCmeLiGeGLiIGxuOzD+cNyHegI1GD+da3R/cIbs9+xCLp13w==
"@types/q@^0.0.32":
version "0.0.32"
resolved "https://registry.yarnpkg.com/@types/q/-/q-0.0.32.tgz#bd284e57c84f1325da702babfc82a5328190c0c5"
integrity sha1-vShOV8hPEyXacCur/IKlMoGQwMU=
"@types/selenium-webdriver@^2.53.35", "@types/selenium-webdriver@~2.53.39":
version "2.53.43"
resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-2.53.43.tgz#2de3d718819bc20165754c4a59afb7e9833f6707"
integrity sha512-UBYHWph6P3tutkbXpW6XYg9ZPbTKjw/YC2hGG1/GEvWwTbvezBUv3h+mmUFw79T3RFPnmedpiXdOBbXX+4l0jg==
"@types/selenium-webdriver@^3.0.0":
version "3.0.16"
resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-3.0.16.tgz#50a4755f8e33edacd9c406729e9b930d2451902a"
integrity sha512-lMC2G0ItF2xv4UCiwbJGbnJlIuUixHrioOhNGHSCsYCJ8l4t9hMCUimCytvFv7qy6AfSzRxhRHoGa+UqaqwyeA==
"@types/z-schema@3.16.31":
version "3.16.31"
@ -360,12 +364,7 @@ accepts@~1.3.4:
mime-types "~2.1.24"
negotiator "0.6.2"
adm-zip@0.4.4:
version "0.4.4"
resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.4.tgz#a61ed5ae6905c3aea58b3a657d25033091052736"
integrity sha1-ph7VrmkFw66lizplfSUDMJEFJzY=
adm-zip@^0.4.7, adm-zip@^0.4.9, adm-zip@~0.4.3:
adm-zip@^0.4.9, adm-zip@~0.4.3:
version "0.4.13"
resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.13.tgz#597e2f8cc3672151e1307d3e95cddbc75672314a"
integrity sha512-fERNJX8sOXfel6qCBCMPvZLzENBEhZTzKqg6vrOW5pvoEaQuJhRU4ndTAh6lHOxn1I6jnz2NHra56ZODM751uw==
@ -375,14 +374,6 @@ after@0.8.2:
resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=
agent-base@2:
version "2.1.1"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.1.1.tgz#d6de10d5af6132d5bd692427d46fc538539094c7"
integrity sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=
dependencies:
extend "~3.0.0"
semver "~5.0.1"
agent-base@^4.1.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
@ -601,10 +592,10 @@ blob@0.0.5:
resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683"
integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==
blocking-proxy@0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/blocking-proxy/-/blocking-proxy-0.0.5.tgz#462905e0dcfbea970f41aa37223dda9c07b1912b"
integrity sha1-RikF4Nz76pcPQao3Ij3anAexkSs=
blocking-proxy@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/blocking-proxy/-/blocking-proxy-1.0.1.tgz#81d6fd1fe13a4c0d6957df7f91b75e98dac40cb2"
integrity sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA==
dependencies:
minimist "^1.2.0"
@ -653,6 +644,13 @@ braces@^2.3.1, braces@^2.3.2:
split-string "^3.0.2"
to-regex "^3.0.1"
browserstack@^1.5.1:
version "1.5.2"
resolved "https://registry.yarnpkg.com/browserstack/-/browserstack-1.5.2.tgz#17d8bb76127a1cc0ea416424df80d218f803673f"
integrity sha512-+6AFt9HzhKykcPF79W6yjEUJcdvZOV0lIXdkORXMJftGrDl0OKWqRF4GHqpDNkxiceDT/uB7Fb/aDwktvXX7dg==
dependencies:
https-proxy-agent "^2.2.1"
buffer-alloc-unsafe@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
@ -905,7 +903,7 @@ date-format@^2.0.0:
resolved "https://registry.yarnpkg.com/date-format/-/date-format-2.0.0.tgz#7cf7b172f1ec564f0003b39ea302c5498fb98c8f"
integrity sha512-M6UqVvZVgFYqZL1SfHsRGIQSz3ZL+qgbsV5Lp1Vj61LZVYuEwcMXYay7DRDtYs2HQQBK5hQtQ0fD9aEJ89V0LA==
debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
@ -1171,7 +1169,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2:
assign-symbols "^1.0.0"
is-extendable "^1.0.1"
extend@3, extend@^3.0.0, extend@~3.0.0, extend@~3.0.2:
extend@^3.0.0, extend@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
@ -1486,15 +1484,6 @@ http-signature@~1.2.0:
jsprim "^1.2.2"
sshpk "^1.7.0"
https-proxy-agent@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz#35f7da6c48ce4ddbfa264891ac593ee5ff8671e6"
integrity sha1-NffabEjOTdv6JkiRrFk+5f+GceY=
dependencies:
agent-base "2"
debug "2"
extend "3"
https-proxy-agent@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0"
@ -1748,7 +1737,7 @@ isstream@~0.1.2:
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
jasmine-core@2.8.0:
jasmine-core@2.8.0, jasmine-core@~2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.8.0.tgz#bcc979ae1f9fd05701e45e52e65d3a5d63f1a24e"
integrity sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=
@ -1758,19 +1747,14 @@ jasmine-core@^3.3:
resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.4.0.tgz#2a74618e966026530c3518f03e9f845d26473ce3"
integrity sha512-HU/YxV4i6GcmiH4duATwAbJQMlE0MsDIR5XmSVxURxKHn3aGAdbY1/ZJFmVRbKtnLwIxxMJD7gYaPsypcbYimg==
jasmine-core@~2.99.0:
version "2.99.1"
resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.99.1.tgz#e6400df1e6b56e130b61c4bcd093daa7f6e8ca15"
integrity sha1-5kAN8ea1bhMLYcS80JPap/boyhU=
jasmine@^2.5.3:
version "2.99.0"
resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-2.99.0.tgz#8ca72d102e639b867c6489856e0e18a9c7aa42b7"
integrity sha1-jKctEC5jm4Z8ZImFbg4YqceqQrc=
jasmine@2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-2.8.0.tgz#6b089c0a11576b1f16df11b80146d91d4e8b8a3e"
integrity sha1-awicChFXax8W3xG4AUbZHU6Lij4=
dependencies:
exit "^0.1.2"
glob "^7.0.6"
jasmine-core "~2.99.0"
jasmine-core "~2.8.0"
jasminewd2@^2.1.0:
version "2.2.0"
@ -1819,6 +1803,16 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.10.0"
jszip@^3.1.3:
version "3.2.2"
resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.2.2.tgz#b143816df7e106a9597a94c77493385adca5bd1d"
integrity sha512-NmKajvAFQpbg3taXQXr/ccS2wcucR1AZ+NtyWp2Nq7HHVsXhcJFR8p0Baf32C2yVvBylFWVeKf+WI2AnvlPhpA==
dependencies:
lie "~3.3.0"
pako "~1.0.2"
readable-stream "~2.3.6"
set-immediate-shim "~1.0.1"
jszip@^3.1.5:
version "3.2.1"
resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.2.1.tgz#c5d32df7274042282b157efb16e522b43435e01a"
@ -2308,11 +2302,6 @@ optimist@^0.6.1, optimist@~0.6.0:
minimist "~0.0.1"
wordwrap "~0.0.2"
options@>=0.0.5:
version "0.0.6"
resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f"
integrity sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=
os-homedir@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
@ -2489,25 +2478,25 @@ protobufjs@6.8.8:
"@types/node" "^10.1.0"
long "^4.0.0"
protractor@5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/protractor/-/protractor-5.1.2.tgz#9b221741709a4c62d5cd53c6aadd54a71137e95f"
integrity sha1-myIXQXCaTGLVzVPGqt1UpxE36V8=
protractor@^5.4.2:
version "5.4.2"
resolved "https://registry.yarnpkg.com/protractor/-/protractor-5.4.2.tgz#329efe37f48b2141ab9467799be2d4d12eb48c13"
integrity sha512-zlIj64Cr6IOWP7RwxVeD8O4UskLYPoyIcg0HboWJL9T79F1F0VWtKkGTr/9GN6BKL+/Q/GmM7C9kFVCfDbP5sA==
dependencies:
"@types/node" "^6.0.46"
"@types/q" "^0.0.32"
"@types/selenium-webdriver" "~2.53.39"
blocking-proxy "0.0.5"
"@types/selenium-webdriver" "^3.0.0"
blocking-proxy "^1.0.0"
browserstack "^1.5.1"
chalk "^1.1.3"
glob "^7.0.3"
jasmine "^2.5.3"
jasmine "2.8.0"
jasminewd2 "^2.1.0"
optimist "~0.6.0"
q "1.4.1"
saucelabs "~1.3.0"
selenium-webdriver "3.0.1"
saucelabs "^1.5.0"
selenium-webdriver "3.6.0"
source-map-support "~0.4.0"
webdriver-js-extender "^1.0.0"
webdriver-js-extender "2.1.0"
webdriver-manager "^12.0.6"
pseudomap@^1.0.2:
@ -2774,44 +2763,21 @@ saucelabs@^1.5.0:
dependencies:
https-proxy-agent "^2.2.1"
saucelabs@~1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/saucelabs/-/saucelabs-1.3.0.tgz#d240e8009df7fa87306ec4578a69ba3b5c424fee"
integrity sha1-0kDoAJ33+ocwbsRXimm6O1xCT+4=
dependencies:
https-proxy-agent "^1.0.0"
sax@0.6.x:
version "0.6.1"
resolved "https://registry.yarnpkg.com/sax/-/sax-0.6.1.tgz#563b19c7c1de892e09bfc4f2fc30e3c27f0952b9"
integrity sha1-VjsZx8HeiS4Jv8Ty/DDjwn8JUrk=
sax@>=0.6.0, sax@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
selenium-webdriver@3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-3.0.1.tgz#a2dea5da4a97f6672e89e7ca7276cefa365147a7"
integrity sha1-ot6l2kqX9mcuiefKcnbO+jZRR6c=
selenium-webdriver@3.6.0, selenium-webdriver@^3.0.1:
version "3.6.0"
resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz#2ba87a1662c020b8988c981ae62cb2a01298eafc"
integrity sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==
dependencies:
adm-zip "^0.4.7"
jszip "^3.1.3"
rimraf "^2.5.4"
tmp "0.0.30"
xml2js "^0.4.17"
selenium-webdriver@^2.53.2:
version "2.53.3"
resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-2.53.3.tgz#d29ff5a957dff1a1b49dc457756e4e4bfbdce085"
integrity sha1-0p/1qVff8aG0ncRXdW5OS/vc4IU=
dependencies:
adm-zip "0.4.4"
rimraf "^2.2.8"
tmp "0.0.24"
ws "^1.0.1"
xml2js "0.4.4"
selenium-webdriver@^4.0.0-alpha.1:
version "4.0.0-alpha.3"
resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.0.0-alpha.3.tgz#fb974f29696a6801ecaf203e38a65c3dbe7e363a"
@ -2832,11 +2798,6 @@ semver@^5.3.0, semver@^5.5.0, semver@^5.6.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b"
integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==
semver@~5.0.1:
version "5.0.3"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.0.3.tgz#77466de589cd5d3c95f138aa78bc569a3cb5d27a"
integrity sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=
set-blocking@^2.0.0, set-blocking@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
@ -3158,11 +3119,6 @@ tar@^4:
safe-buffer "^5.1.2"
yallist "^3.0.3"
tmp@0.0.24:
version "0.0.24"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.24.tgz#d6a5e198d14a9835cc6f2d7c3d9e302428c8cf12"
integrity sha1-1qXhmNFKmDXMby18PZ4wJCjIzxI=
tmp@0.0.30:
version "0.0.30"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.30.tgz#72419d4a8be7d6ce75148fd8b324e593a711c2ed"
@ -3276,11 +3232,6 @@ typescript@~3.4.3:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.4.5.tgz#2d2618d10bb566572b8d7aad5180d84257d70a99"
integrity sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==
ultron@1.0.x:
version "1.0.2"
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa"
integrity sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=
ultron@~1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
@ -3378,13 +3329,13 @@ void-elements@^2.0.0:
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=
webdriver-js-extender@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/webdriver-js-extender/-/webdriver-js-extender-1.0.0.tgz#81c533a9e33d5bfb597b4e63e2cdb25b54777515"
integrity sha1-gcUzqeM9W/tZe05j4s2yW1R3dRU=
webdriver-js-extender@2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz#57d7a93c00db4cc8d556e4d3db4b5db0a80c3bb7"
integrity sha512-lcUKrjbBfCK6MNsh7xaY2UAUmZwe+/ib03AjVOpFobX4O7+83BUveSrLfU0Qsyb1DaKJdQRbuU+kM9aZ6QUhiQ==
dependencies:
"@types/selenium-webdriver" "^2.53.35"
selenium-webdriver "^2.53.2"
"@types/selenium-webdriver" "^3.0.0"
selenium-webdriver "^3.0.1"
webdriver-manager@^12.0.6:
version "12.1.5"
@ -3440,14 +3391,6 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
ws@^1.0.1:
version "1.1.5"
resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.5.tgz#cbd9e6e75e09fc5d2c90015f21f0c40875e0dd51"
integrity sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==
dependencies:
options ">=0.0.5"
ultron "1.0.x"
ws@~3.3.1:
version "3.3.3"
resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2"
@ -3457,14 +3400,6 @@ ws@~3.3.1:
safe-buffer "~5.1.0"
ultron "~1.1.0"
xml2js@0.4.4:
version "0.4.4"
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.4.tgz#3111010003008ae19240eba17497b57c729c555d"
integrity sha1-MREBAAMAiuGSQOuhdJe1fHKcVV0=
dependencies:
sax "0.6.x"
xmlbuilder ">=1.0.0"
xml2js@^0.4.17, xml2js@^0.4.19:
version "0.4.19"
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7"
@ -3473,11 +3408,6 @@ xml2js@^0.4.17, xml2js@^0.4.19:
sax ">=0.6.0"
xmlbuilder "~9.0.1"
xmlbuilder@>=1.0.0:
version "13.0.2"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-13.0.2.tgz#02ae33614b6a047d1c32b5389c1fdacb2bce47a7"
integrity sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ==
xmlbuilder@~9.0.1:
version "9.0.7"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"

View File

@ -8084,7 +8084,7 @@ through2@^2.0.0:
"through@>=2.2.7 <3", through@X.X.X, through@^2.3.6:
version "2.3.8"
resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
thunkify@~2.1.1:

View File

@ -1,4 +1,4 @@
load("//packages/bazel:index.bzl", "protractor_web_test_suite")
load("@npm_bazel_protractor//:index.bzl", "protractor_web_test_suite")
"""
Macro that can be used to define a benchmark test. This differentiates from
@ -18,7 +18,6 @@ def benchmark_test(name, server, deps, tags = []):
server = server,
tags = tags,
deps = [
"@npm//protractor",
"@npm//yargs",
] + deps,
)

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
const protractorUtils = require('@angular/bazel/protractor-utils');
const protractorUtils = require('@bazel/protractor/protractor-utils');
const protractor = require('protractor');
module.exports = async function(config) {

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
const protractorUtils = require('@angular/bazel/protractor-utils');
const protractorUtils = require('@bazel/protractor/protractor-utils');
const protractor = require('protractor');
module.exports = async function(config) {

View File

@ -1,4 +1,4 @@
load("//packages/bazel:index.bzl", "protractor_web_test_suite")
load("@npm_bazel_protractor//:index.bzl", "protractor_web_test_suite")
load("//tools:defaults.bzl", "ts_library")
def example_test(name, srcs, server, data = [], **kwargs):
@ -18,12 +18,11 @@ def example_test(name, srcs, server, data = [], **kwargs):
protractor_web_test_suite(
name = "protractor_tests",
data = ["//packages/bazel/src/protractor/utils"] + data,
data = data,
on_prepare = "//modules/playground/e2e_test:start-server.js",
server = server,
deps = [
":%s_lib" % name,
"@npm//protractor",
"@npm//selenium-webdriver",
"@npm//yargs",
"@npm//source-map",

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
const protractorUtils = require('@angular/bazel/protractor-utils');
const protractorUtils = require('@bazel/protractor/protractor-utils');
const protractor = require('protractor');
module.exports = async function(config) {

View File

@ -1,6 +1,6 @@
{
"name": "angular-srcs",
"version": "8.2.0-next.2",
"version": "8.2.2",
"private": true,
"description": "Angular - a web framework for modern web apps",
"homepage": "https://github.com/angular/angular",
@ -35,10 +35,10 @@
"@angular-devkit/core": "^8.0.0-beta.15",
"@angular-devkit/schematics": "^8.0.0-beta.15",
"@angular/bazel": "file:./tools/npm/@angular_bazel",
"@bazel/jasmine": "0.32.2",
"@bazel/hide-bazel-files": "0.32.2",
"@bazel/karma": "0.32.2",
"@bazel/typescript": "0.32.2",
"@bazel/jasmine": "0.34.0",
"@bazel/karma": "0.34.0",
"@bazel/protractor": "0.34.0",
"@bazel/typescript": "0.34.0",
"@microsoft/api-extractor": "^7.0.21",
"@schematics/angular": "^8.0.0-beta.15",
"@types/angular": "^1.6.47",
@ -120,7 +120,7 @@
"// 3": "when updating @bazel/bazel version you also need to update the RBE settings in .bazelrc (see https://github.com/angular/angular/pull/27935)",
"devDependencies": {
"@angular/cli": "^8.0.0-beta.15",
"@bazel/bazel": "0.27.0",
"@bazel/bazel": "0.28.1",
"@bazel/buildifier": "^0.26.0",
"@bazel/ibazel": "~0.9.0",
"@types/minimist": "^1.2.0",

View File

@ -25,12 +25,13 @@ def rules_angular_dev_dependencies():
"""
# Needed for Remote Execution
# https://github.com/bazelbuild/bazel-toolchains/releases
_maybe(
http_archive,
name = "bazel_toolchains",
sha256 = "4598bf5a8b4f5ced82c782899438a7ba695165d47b3bf783ce774e89a8c6e617",
strip_prefix = "bazel-toolchains-0.27.0",
url = "https://github.com/bazelbuild/bazel-toolchains/archive/0.27.0.tar.gz",
sha256 = "dcb58e7e5f0b4da54c6c5f8ebc65e63fcfb37414466010cf82ceff912162296e",
strip_prefix = "bazel-toolchains-0.28.2",
url = "https://github.com/bazelbuild/bazel-toolchains/archive/0.28.2.tar.gz",
)
#############################################

View File

@ -15,8 +15,8 @@ workspace(
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
RULES_NODEJS_VERSION = "0.32.2"
RULES_NODEJS_SHA256 = "6d4edbf28ff6720aedf5f97f9b9a7679401bf7fca9d14a0fff80f644a99992b4"
RULES_NODEJS_VERSION = "0.34.0"
RULES_NODEJS_SHA256 = "7c4a690268be97c96f04d505224ec4cb1ae53c2c2b68be495c9bd2634296a5cd"
http_archive(
name = "build_bazel_rules_nodejs",
sha256 = RULES_NODEJS_SHA256,
@ -63,8 +63,6 @@ node_repositories(
yarn_install(
name = "npm",
# TODO(gregmagolan): fix rules_nodejs so that if @bazel/hide-bazel-files is detected then this is forced true
always_hide_bazel_files = True,
package_json = "//:package.json",
yarn_lock = "//:yarn.lock",
)
@ -72,6 +70,9 @@ yarn_install(
load("@npm//:install_bazel_dependencies.bzl", "install_bazel_dependencies")
install_bazel_dependencies()
load("@npm_bazel_protractor//:package.bzl", "npm_bazel_protractor_dependencies")
npm_bazel_protractor_dependencies()
load("@npm_bazel_karma//:package.bzl", "rules_karma_dependencies")
rules_karma_dependencies()

View File

@ -1,5 +1,5 @@
load("@npm_bazel_protractor//:index.bzl", "protractor_web_test_suite")
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm_angular_bazel//:index.bzl", "protractor_web_test_suite")
ts_library(
name = "e2e_lib",
@ -21,10 +21,6 @@ ts_library(
protractor_web_test_suite(
name = "prodserver_test",
data = [
"@npm//@angular/bazel",
"@npm//protractor",
],
on_prepare = ":protractor.on-prepare.js",
server = "//src:prodserver",
deps = [":e2e_lib"],
@ -32,10 +28,6 @@ protractor_web_test_suite(
protractor_web_test_suite(
name = "devserver_test",
data = [
"@npm//@angular/bazel",
"@npm//protractor",
],
on_prepare = ":protractor.on-prepare.js",
server = "//src:devserver",
deps = [":e2e_lib"],

View File

@ -112,11 +112,13 @@ def _rollup(ctx, bundle_name, rollup_config, entry_point, inputs, js_output, for
args.add("--amd.id", package_name)
# After updating to build_bazel_rules_nodejs 0.27.0+, rollup has been updated to v1.3.1
# which tree shakes @__PURE__ annotations by default. We turn this feature off
# for ng_package as Angular bundles contain these annotations and there are
# test failures if they are removed. See comments in
# https://github.com/angular/angular/pull/29210 for more information.
args.add("--no-treeshake.annotations")
# which tree shakes @__PURE__ annotations and const variables which are later amended by NGCC.
# We turn this feature off for ng_package as Angular bundles contain these and there are
# test failures if they are removed.
# See comments in:
# https://github.com/angular/angular/pull/29210
# https://github.com/angular/angular/pull/32069
args.add("--no-treeshake")
# Note: if the input has external source maps then we need to also install and use
# `rollup-plugin-sourcemaps`, which will require us to use rollup.config.js file instead

View File

@ -5,11 +5,11 @@
// If the function returns a promise, as it does here, protractor will wait
// for the promise to resolve before running tests.
const protractorUtils = require('@angular/bazel/protractor-utils');
const protractorUtils = require('@bazel/protractor/protractor-utils');
const protractor = require('protractor');
module.exports = function(config) {
// In this example, `@angular/bazel/protractor-utils` is used to run
// In this example, `@bazel/protractor/protractor-utils` is used to run
// the server. protractorUtils.runServer() runs the server on a randomly
// selected port (given a port flag to pass to the server as an argument).
// The port used is returned in serverSpec and the protractor serverUrl

View File

@ -48,11 +48,11 @@ function addDevDependenciesToPackageJson(options: Schema) {
const devDependencies: {[k: string]: string} = {
'@angular/bazel': angularCoreVersion,
'@bazel/bazel': '^0.27.0',
'@bazel/hide-bazel-files': '0.32.2',
'@bazel/bazel': '^0.28.1',
'@bazel/ibazel': '^0.10.2',
'@bazel/karma': '0.32.2',
'@bazel/typescript': '0.32.2',
'@bazel/karma': '0.34.0',
'@bazel/protractor': '0.34.0',
'@bazel/typescript': '0.34.0',
};
const recorder = host.beginUpdate(packageJson);

View File

@ -113,9 +113,10 @@ describe('ng-add schematic', () => {
const json = JSON.parse(content);
const devDeps = Object.keys(json.devDependencies);
expect(devDeps).toContain('@bazel/bazel');
expect(devDeps).toContain('@bazel/hide-bazel-files');
expect(devDeps).toContain('@bazel/ibazel');
expect(devDeps).toContain('@bazel/karma');
expect(devDeps).toContain('@bazel/protractor');
expect(devDeps).toContain('@bazel/typescript');
});
it('should replace an existing dev dependency', async() => {

View File

@ -133,6 +133,10 @@ describe('@angular/core ng_package', () => {
} else {
it('should have decorators',
() => { expect(shx.cat('fesm5/core.js')).toContain('__decorate'); });
// See: https://github.com/angular/angular/pull/32069
it('should retain access to const',
() => { expect(shx.cat('fesm5/core.js')).toContain('!ivyEnabled'); });
}
it('should load tslib from external bundle', () => {

View File

@ -111,6 +111,41 @@ Hello
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
}
function __decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@ -119,6 +154,136 @@ Hello
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
function __param(paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
}
function __metadata(metadataKey, metadataValue) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
}
function __awaiter(thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}
function __exportStar(m, exports) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
function __values(o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
}
function __spread() {
for (var ar = [], i = 0; i < arguments.length; i++)
ar = ar.concat(__read(arguments[i]));
return ar;
}
function __await(v) {
return this instanceof __await ? (this.v = v, this) : new __await(v);
}
function __asyncGenerator(thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
function fulfill(value) { resume("next", value); }
function reject(value) { resume("throw", value); }
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
}
function __asyncDelegator(o) {
var i, p;
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
}
function __asyncValues(o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
}
function __makeTemplateObject(cooked, raw) {
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
return cooked;
};
function __importStar(mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result.default = mod;
return result;
}
function __importDefault(mod) {
return (mod && mod.__esModule) ? mod : { default: mod };
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
@ -210,6 +375,41 @@ e.SecondaryModule=o,e.a=1,Object.defineProperty(e,"__esModule",{value:!0})});
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
}
function __decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@ -218,6 +418,136 @@ e.SecondaryModule=o,e.a=1,Object.defineProperty(e,"__esModule",{value:!0})});
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
function __param(paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
}
function __metadata(metadataKey, metadataValue) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
}
function __awaiter(thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}
function __exportStar(m, exports) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
function __values(o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
}
function __spread() {
for (var ar = [], i = 0; i < arguments.length; i++)
ar = ar.concat(__read(arguments[i]));
return ar;
}
function __await(v) {
return this instanceof __await ? (this.v = v, this) : new __await(v);
}
function __asyncGenerator(thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
function fulfill(value) { resume("next", value); }
function reject(value) { resume("throw", value); }
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
}
function __asyncDelegator(o) {
var i, p;
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
}
function __asyncValues(o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
}
function __makeTemplateObject(cooked, raw) {
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
return cooked;
};
function __importStar(mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result.default = mod;
return result;
}
function __importDefault(mod) {
return (mod && mod.__esModule) ? mod : { default: mod };
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.

View File

@ -161,8 +161,8 @@ export class DatePipe implements PipeTransform {
* @param format The date/time components to include, using predefined options or a
* custom format string.
* @param timezone A timezone offset (such as `'+0430'`), or a standard
* UTC/GMT or continental US timezone abbreviation. Default is
* the local system timezone of the end-user's machine.
* UTC/GMT or continental US timezone abbreviation.
* When not supplied, uses the end-user's local system timezone.
* @param locale A locale code for the locale format rules to use.
* When not supplied, uses the value of `LOCALE_ID`, which is `en-US` by default.
* See [Setting your app locale](guide/i18n#setting-up-the-locale-of-your-app).

View File

@ -15,6 +15,7 @@ import localeHu from '@angular/common/locales/hu';
import localeSr from '@angular/common/locales/sr';
import localeTh from '@angular/common/locales/th';
import {isDate, toDate, formatDate} from '@angular/common/src/i18n/format_date';
import {ɵDEFAULT_LOCALE_ID as DEFAULT_LOCALE_ID} from '@angular/core';
describe('Format date', () => {
describe('toDate', () => {
@ -46,13 +47,12 @@ describe('Format date', () => {
describe('formatDate', () => {
const isoStringWithoutTime = '2015-01-01';
const defaultLocale = 'en-US';
const defaultFormat = 'mediumDate';
let date: Date;
// Check the transformation of a date into a pattern
function expectDateFormatAs(date: Date | string, pattern: any, output: string): void {
expect(formatDate(date, pattern, defaultLocale)).toEqual(output, `pattern: "${pattern}"`);
expect(formatDate(date, pattern, DEFAULT_LOCALE_ID)).toEqual(output, `pattern: "${pattern}"`);
}
beforeAll(() => {
@ -209,7 +209,8 @@ describe('Format date', () => {
};
Object.keys(dateFixtures).forEach((pattern: string) => {
expect(formatDate(date, pattern, defaultLocale, '+0430')).toMatch(dateFixtures[pattern]);
expect(formatDate(date, pattern, DEFAULT_LOCALE_ID, '+0430'))
.toMatch(dateFixtures[pattern]);
});
});
@ -253,22 +254,22 @@ describe('Format date', () => {
};
Object.keys(dateFixtures).forEach((pattern: string) => {
expect(formatDate(date, pattern, defaultLocale)).toMatch(dateFixtures[pattern]);
expect(formatDate(date, pattern, DEFAULT_LOCALE_ID)).toMatch(dateFixtures[pattern]);
});
});
it('should format invalid in IE ISO date',
() => expect(formatDate('2017-01-11T12:00:00.014-0500', defaultFormat, defaultLocale))
() => expect(formatDate('2017-01-11T12:00:00.014-0500', defaultFormat, DEFAULT_LOCALE_ID))
.toEqual('Jan 11, 2017'));
it('should format invalid in Safari ISO date',
() => expect(formatDate('2017-01-20T12:00:00+0000', defaultFormat, defaultLocale))
() => expect(formatDate('2017-01-20T12:00:00+0000', defaultFormat, DEFAULT_LOCALE_ID))
.toEqual('Jan 20, 2017'));
// https://github.com/angular/angular/issues/9524
// https://github.com/angular/angular/issues/9524
it('should format correctly with iso strings that contain time',
() => expect(formatDate('2017-05-07T22:14:39', 'dd-MM-yyyy HH:mm', defaultLocale))
() => expect(formatDate('2017-05-07T22:14:39', 'dd-MM-yyyy HH:mm', DEFAULT_LOCALE_ID))
.toMatch(/07-05-2017 \d{2}:\d{2}/));
// https://github.com/angular/angular/issues/21491
@ -276,22 +277,22 @@ describe('Format date', () => {
// this test only works if the timezone is not in UTC
// which is the case for BrowserStack when we test Safari
if (new Date().getTimezoneOffset() !== 0) {
expect(formatDate('2018-01-11T13:00:00', 'HH', defaultLocale))
.not.toEqual(formatDate('2018-01-11T13:00:00Z', 'HH', defaultLocale));
expect(formatDate('2018-01-11T13:00:00', 'HH', DEFAULT_LOCALE_ID))
.not.toEqual(formatDate('2018-01-11T13:00:00Z', 'HH', DEFAULT_LOCALE_ID));
}
});
// https://github.com/angular/angular/issues/16624
// https://github.com/angular/angular/issues/17478
it('should show the correct time when the timezone is fixed', () => {
expect(formatDate('2017-06-13T10:14:39+0000', 'shortTime', defaultLocale, '+0000'))
expect(formatDate('2017-06-13T10:14:39+0000', 'shortTime', DEFAULT_LOCALE_ID, '+0000'))
.toEqual('10:14 AM');
expect(formatDate('2017-06-13T10:14:39+0000', 'h:mm a', defaultLocale, '+0000'))
expect(formatDate('2017-06-13T10:14:39+0000', 'h:mm a', DEFAULT_LOCALE_ID, '+0000'))
.toEqual('10:14 AM');
});
it('should remove bidi control characters',
() => expect(formatDate(date, 'MM/dd/yyyy', defaultLocale) !.length).toEqual(10));
() => expect(formatDate(date, 'MM/dd/yyyy', DEFAULT_LOCALE_ID) !.length).toEqual(10));
it(`should format the date correctly in various locales`, () => {
expect(formatDate(date, 'short', 'de')).toEqual('15.06.15, 09:03');

View File

@ -12,10 +12,9 @@ import localeFr from '@angular/common/locales/fr';
import localeAr from '@angular/common/locales/ar';
import {formatCurrency, formatNumber, formatPercent, registerLocaleData} from '@angular/common';
import {describe, expect, it} from '@angular/core/testing/src/testing_internal';
import {ɵDEFAULT_LOCALE_ID as DEFAULT_LOCALE_ID} from '@angular/core';
describe('Format number', () => {
const defaultLocale = 'en-US';
beforeAll(() => {
registerLocaleData(localeEn);
registerLocaleData(localeEsUS);
@ -26,18 +25,18 @@ describe('Format number', () => {
describe('Number', () => {
describe('transform', () => {
it('should return correct value for numbers', () => {
expect(formatNumber(12345, defaultLocale)).toEqual('12,345');
expect(formatNumber(123, defaultLocale, '.2')).toEqual('123.00');
expect(formatNumber(1, defaultLocale, '3.')).toEqual('001');
expect(formatNumber(1.1, defaultLocale, '3.4-5')).toEqual('001.1000');
expect(formatNumber(1.123456, defaultLocale, '3.4-5')).toEqual('001.12346');
expect(formatNumber(1.1234, defaultLocale)).toEqual('1.123');
expect(formatNumber(1.123456, defaultLocale, '.2')).toEqual('1.123');
expect(formatNumber(1.123456, defaultLocale, '.4')).toEqual('1.1235');
expect(formatNumber(12345, DEFAULT_LOCALE_ID)).toEqual('12,345');
expect(formatNumber(123, DEFAULT_LOCALE_ID, '.2')).toEqual('123.00');
expect(formatNumber(1, DEFAULT_LOCALE_ID, '3.')).toEqual('001');
expect(formatNumber(1.1, DEFAULT_LOCALE_ID, '3.4-5')).toEqual('001.1000');
expect(formatNumber(1.123456, DEFAULT_LOCALE_ID, '3.4-5')).toEqual('001.12346');
expect(formatNumber(1.1234, DEFAULT_LOCALE_ID)).toEqual('1.123');
expect(formatNumber(1.123456, DEFAULT_LOCALE_ID, '.2')).toEqual('1.123');
expect(formatNumber(1.123456, DEFAULT_LOCALE_ID, '.4')).toEqual('1.1235');
});
it('should throw if minFractionDigits is explicitly higher than maxFractionDigits', () => {
expect(() => formatNumber(1.1, defaultLocale, '3.4-2'))
expect(() => formatNumber(1.1, DEFAULT_LOCALE_ID, '3.4-2'))
.toThrowError(/is higher than the maximum/);
});
});
@ -51,27 +50,27 @@ describe('Format number', () => {
describe('Percent', () => {
describe('transform', () => {
it('should return correct value for numbers', () => {
expect(formatPercent(1.23, defaultLocale)).toEqual('123%');
expect(formatPercent(1.2, defaultLocale, '.2')).toEqual('120.00%');
expect(formatPercent(1.2, defaultLocale, '4.2')).toEqual('0,120.00%');
expect(formatPercent(1.23, DEFAULT_LOCALE_ID)).toEqual('123%');
expect(formatPercent(1.2, DEFAULT_LOCALE_ID, '.2')).toEqual('120.00%');
expect(formatPercent(1.2, DEFAULT_LOCALE_ID, '4.2')).toEqual('0,120.00%');
expect(formatPercent(1.2, 'fr', '4.2')).toEqual('0 120,00 %');
expect(formatPercent(1.2, 'ar', '4.2')).toEqual('0,120.00%');
// see issue #20136
expect(formatPercent(0.12345674, defaultLocale, '0.0-10')).toEqual('12.345674%');
expect(formatPercent(0, defaultLocale, '0.0-10')).toEqual('0%');
expect(formatPercent(0.00, defaultLocale, '0.0-10')).toEqual('0%');
expect(formatPercent(1, defaultLocale, '0.0-10')).toEqual('100%');
expect(formatPercent(0.1, defaultLocale, '0.0-10')).toEqual('10%');
expect(formatPercent(0.12, defaultLocale, '0.0-10')).toEqual('12%');
expect(formatPercent(0.123, defaultLocale, '0.0-10')).toEqual('12.3%');
expect(formatPercent(12.3456, defaultLocale, '0.0-10')).toEqual('1,234.56%');
expect(formatPercent(12.345600, defaultLocale, '0.0-10')).toEqual('1,234.56%');
expect(formatPercent(12.345699999, defaultLocale, '0.0-6')).toEqual('1,234.57%');
expect(formatPercent(12.345699999, defaultLocale, '0.4-6')).toEqual('1,234.5700%');
expect(formatPercent(100, defaultLocale, '0.4-6')).toEqual('10,000.0000%');
expect(formatPercent(100, defaultLocale, '0.0-10')).toEqual('10,000%');
expect(formatPercent(1.5e2, defaultLocale)).toEqual('15,000%');
expect(formatPercent(1e100, defaultLocale)).toEqual('1E+102%');
expect(formatPercent(0.12345674, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('12.345674%');
expect(formatPercent(0, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('0%');
expect(formatPercent(0.00, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('0%');
expect(formatPercent(1, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('100%');
expect(formatPercent(0.1, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('10%');
expect(formatPercent(0.12, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('12%');
expect(formatPercent(0.123, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('12.3%');
expect(formatPercent(12.3456, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('1,234.56%');
expect(formatPercent(12.345600, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('1,234.56%');
expect(formatPercent(12.345699999, DEFAULT_LOCALE_ID, '0.0-6')).toEqual('1,234.57%');
expect(formatPercent(12.345699999, DEFAULT_LOCALE_ID, '0.4-6')).toEqual('1,234.5700%');
expect(formatPercent(100, DEFAULT_LOCALE_ID, '0.4-6')).toEqual('10,000.0000%');
expect(formatPercent(100, DEFAULT_LOCALE_ID, '0.0-10')).toEqual('10,000%');
expect(formatPercent(1.5e2, DEFAULT_LOCALE_ID)).toEqual('15,000%');
expect(formatPercent(1e100, DEFAULT_LOCALE_ID)).toEqual('1E+102%');
});
});
});
@ -80,16 +79,16 @@ describe('Format number', () => {
const defaultCurrencyCode = 'USD';
describe('transform', () => {
it('should return correct value for numbers', () => {
expect(formatCurrency(123, defaultLocale, '$')).toEqual('$123.00');
expect(formatCurrency(12, defaultLocale, 'EUR', 'EUR', '.1')).toEqual('EUR12.0');
expect(
formatCurrency(5.1234, defaultLocale, defaultCurrencyCode, defaultCurrencyCode, '.0-3'))
expect(formatCurrency(123, DEFAULT_LOCALE_ID, '$')).toEqual('$123.00');
expect(formatCurrency(12, DEFAULT_LOCALE_ID, 'EUR', 'EUR', '.1')).toEqual('EUR12.0');
expect(formatCurrency(
5.1234, DEFAULT_LOCALE_ID, defaultCurrencyCode, defaultCurrencyCode, '.0-3'))
.toEqual('USD5.123');
expect(formatCurrency(5.1234, defaultLocale, defaultCurrencyCode)).toEqual('USD5.12');
expect(formatCurrency(5.1234, defaultLocale, '$')).toEqual('$5.12');
expect(formatCurrency(5.1234, defaultLocale, 'CA$')).toEqual('CA$5.12');
expect(formatCurrency(5.1234, defaultLocale, '$')).toEqual('$5.12');
expect(formatCurrency(5.1234, defaultLocale, '$', defaultCurrencyCode, '5.2-2'))
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, defaultCurrencyCode)).toEqual('USD5.12');
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, '$')).toEqual('$5.12');
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, 'CA$')).toEqual('CA$5.12');
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, '$')).toEqual('$5.12');
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, '$', defaultCurrencyCode, '5.2-2'))
.toEqual('$00,005.12');
expect(formatCurrency(5.1234, 'fr', '$', defaultCurrencyCode, '5.2-2'))
.toEqual('00 005,12 $');
@ -98,20 +97,21 @@ describe('Format number', () => {
it('should support any currency code name', () => {
// currency code is unknown, default formatting options will be used
expect(formatCurrency(5.1234, defaultLocale, 'unexisting_ISO_code'))
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, 'unexisting_ISO_code'))
.toEqual('unexisting_ISO_code5.12');
// currency code is USD, the pipe will format based on USD but will display "Custom name"
expect(formatCurrency(5.1234, defaultLocale, 'Custom name')).toEqual('Custom name5.12');
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, 'Custom name')).toEqual('Custom name5.12');
});
it('should round to the default number of digits if no digitsInfo', () => {
// IDR has a default number of digits of 0
expect(formatCurrency(5.1234, defaultLocale, 'IDR', 'IDR')).toEqual('IDR5');
expect(formatCurrency(5.1234, defaultLocale, 'IDR', 'IDR', '.2')).toEqual('IDR5.12');
expect(formatCurrency(5.1234, defaultLocale, 'Custom name', 'IDR')).toEqual('Custom name5');
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, 'IDR', 'IDR')).toEqual('IDR5');
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, 'IDR', 'IDR', '.2')).toEqual('IDR5.12');
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, 'Custom name', 'IDR'))
.toEqual('Custom name5');
// BHD has a default number of digits of 3
expect(formatCurrency(5.1234, defaultLocale, 'BHD', 'BHD')).toEqual('BHD5.123');
expect(formatCurrency(5.1234, defaultLocale, 'BHD', 'BHD', '.1-2')).toEqual('BHD5.12');
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, 'BHD', 'BHD')).toEqual('BHD5.123');
expect(formatCurrency(5.1234, DEFAULT_LOCALE_ID, 'BHD', 'BHD', '.1-2')).toEqual('BHD5.12');
});
});
});

View File

@ -11,9 +11,28 @@ const shx = require('shelljs');
const os = require('os');
const {runCommand, setupTestDirectory} = require('./test_helpers');
// Nodejs toolchains were included in nodejs rules 0.33.0 so the
// repository name for the nodejs toolchain now depends on the platform
// being run on. The following function returns the nodejs repository
// name of the runtime platform platform. These come from
// https://github.com/bazelbuild/rules_nodejs/blob/2a0be492c5d506665798f04673ab1a646c883626/internal/node/node_repositories.bzl#L598.
function nodejs_repository() {
switch (os.platform()) {
case 'darwin':
return 'nodejs_darwin_amd64';
case 'linux':
return 'nodejs_linux_amd64';
case 'win32':
return 'nodejs_windows_amd64';
default:
throw 'Platform not supported';
}
}
const ngcBin = require.resolve('./ngc_bin');
const xi18nBin = require.resolve('./ng_xi18n');
const nodeBin = require.resolve(`nodejs/bin/node${(os.platform() === 'win32' ? '.cmd' : '')}`);
const nodeBin =
require.resolve(`${nodejs_repository()}/bin/node${(os.platform() === 'win32' ? '.cmd' : '')}`);
const jasmineBin = require.resolve('npm/node_modules/jasmine/bin/jasmine.js');
// Prepare the test directory before building the integration test output. This ensures that

View File

@ -59,6 +59,11 @@ export class TypeCheckFile extends Environment {
source += printer.printNode(ts.EmitHint.Unspecified, stmt, this.contextFile) + '\n';
}
// Ensure the template type-checking file is an ES module. Otherwise, it's interpreted as some
// kind of global namespace in TS, which forces a full re-typecheck of the user's program that
// is somehow more expensive than the initial parse.
source += '\nexport const IS_A_MODULE = true;\n';
return ts.createSourceFile(
this.fileName, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
}

View File

@ -11,7 +11,7 @@ import * as ts from 'typescript';
import {Diagnostic} from '../src/diagnostics';
import {NGFOR_DECLARATION, TestDeclaration, ngForDts, typecheck} from './test_utils';
import {TestDeclaration, ngForDeclaration, ngForDts, typecheck} from './test_utils';
runInEachFileSystem(() => {
describe('template diagnostics', () => {
@ -46,7 +46,7 @@ runInEachFileSystem(() => {
render(input: string): string { return input; }
}`,
[NGFOR_DECLARATION], [ngForDts()]);
[ngForDeclaration()], [ngForDts()]);
expect(messages).toEqual([
`synthetic.html(61, 64): Argument of type 'number' is not assignable to parameter of type 'string'.`,
@ -61,7 +61,7 @@ runInEachFileSystem(() => {
render(input: string): string { return input; }
}`,
[NGFOR_DECLARATION], [ngForDts()]);
[ngForDeclaration()], [ngForDts()]);
expect(messages).toEqual([]);
});
@ -127,7 +127,7 @@ runInEachFileSystem(() => {
name: string;
}[];
}`,
[NGFOR_DECLARATION], [ngForDts()]);
[ngForDeclaration()], [ngForDts()]);
expect(messages).toEqual([
`synthetic.html(39, 52): Property 'namme' does not exist on type '{ name: string; }'. Did you mean 'name'?`,

View File

@ -77,14 +77,16 @@ export function angularCoreDts(): TestFile {
};
}
export const NGFOR_DECLARATION: TestDeclaration = {
type: 'directive',
file: 'ngfor.d.ts',
selector: '[ngForOf]',
name: 'NgForOf',
inputs: {ngForOf: 'ngForOf'},
hasNgTemplateContextGuard: true,
};
export function ngForDeclaration(): TestDeclaration {
return {
type: 'directive',
file: absoluteFrom('/ngfor.d.ts'),
selector: '[ngForOf]',
name: 'NgForOf',
inputs: {ngForOf: 'ngForOf'},
hasNgTemplateContextGuard: true,
};
}
export function ngForDts(): TestFile {
return {
@ -124,10 +126,10 @@ export const ALL_ENABLED_CONFIG: TypeCheckingConfig = {
// Remove 'ref' from TypeCheckableDirectiveMeta and add a 'selector' instead.
export type TestDirective =
Partial<Pick<TypeCheckableDirectiveMeta, Exclude<keyof TypeCheckableDirectiveMeta, 'ref'>>>&
{selector: string, name: string, file?: string, type: 'directive'};
{selector: string, name: string, file?: AbsoluteFsPath, type: 'directive'};
export type TestPipe = {
name: string,
file?: string,
file?: AbsoluteFsPath,
pipeName: string,
type: 'pipe',
};
@ -185,7 +187,7 @@ export function typecheck(
...additionalSources,
];
const {program, host, options} = makeProgram(files, {strictNullChecks: true}, undefined, false);
const sf = program.getSourceFile('main.ts') !;
const sf = program.getSourceFile(absoluteFrom('/main.ts')) !;
const checker = program.getTypeChecker();
const logicalFs = new LogicalFileSystem(getRootDirs(host, options));
const emitter = new ReferenceEmitter([

View File

@ -13,12 +13,14 @@ import {TypeScriptReflectionHost, isNamedClassDeclaration} from '../../reflectio
import {getDeclaration, makeProgram} from '../../testing';
import {getRootDirs} from '../../util/src/typescript';
import {TypeCheckContext} from '../src/context';
import {TypeCheckFile} from '../src/type_check_file';
import {ALL_ENABLED_CONFIG} from './test_utils';
runInEachFileSystem(() => {
describe('ngtsc typechecking', () => {
let _: typeof absoluteFrom;
let LIB_D_TS: TestFile;
let TYPE_CHECK_TS: TestFile;
beforeEach(() => {
_ = absoluteFrom;
@ -29,12 +31,25 @@ runInEachFileSystem(() => {
type Pick<T, K extends keyof T> = { [P in K]: T[P]; };
type NonNullable<T> = T extends null | undefined ? never : T;`
};
TYPE_CHECK_TS = {
name: _('/_typecheck_.ts'),
contents: `
export const IS_A_MODULE = true;
`
};
});
it('should not produce an empty SourceFile when there is nothing to typecheck', () => {
const file =
new TypeCheckFile(_('/_typecheck_.ts'), ALL_ENABLED_CONFIG, new ReferenceEmitter([]));
const sf = file.render();
expect(sf.statements.length).toBe(1);
});
describe('ctors', () => {
it('compiles a basic type constructor', () => {
const files: TestFile[] = [
LIB_D_TS, {
LIB_D_TS, TYPE_CHECK_TS, {
name: _('/main.ts'),
contents: `
class TestClass<T extends string> {
@ -72,7 +87,7 @@ TestClass.ngTypeCtor({value: 'test'});
it('should not consider query fields', () => {
const files: TestFile[] = [
LIB_D_TS, {
LIB_D_TS, TYPE_CHECK_TS, {
name: _('/main.ts'),
contents: `class TestClass { value: any; }`,
}

View File

@ -14,11 +14,14 @@ import {Console} from './console';
import {Injector, StaticProvider} from './di';
import {Inject, Optional, SkipSelf} from './di/metadata';
import {ErrorHandler} from './error_handler';
import {DEFAULT_LOCALE_ID} from './i18n/localization';
import {LOCALE_ID} from './i18n/tokens';
import {ivyEnabled} from './ivy_switch';
import {ComponentFactoryResolver} from './linker';
import {Compiler} from './linker/compiler';
import {NgModule} from './metadata';
import {SCHEDULER} from './render3/component_ref';
import {setLocaleId} from './render3/i18n';
import {NgZone} from './zone';
export function _iterableDiffersFactory() {
@ -31,15 +34,21 @@ export function _keyValueDiffersFactory() {
export function _localeFactory(locale?: string): string {
if (locale) {
if (ivyEnabled) {
setLocaleId(locale);
}
return locale;
}
// Use `goog.LOCALE` as default value for `LOCALE_ID` token for Closure Compiler.
// Note: default `goog.LOCALE` value is `en`, when Angular used `en-US`. In order to preserve
// backwards compatibility, we use Angular default value over Closure Compiler's one.
if (ngI18nClosureMode && typeof goog !== 'undefined' && goog.LOCALE !== 'en') {
if (ivyEnabled) {
setLocaleId(goog.LOCALE);
}
return goog.LOCALE;
}
return 'en-US';
return DEFAULT_LOCALE_ID;
}
/**

View File

@ -8,15 +8,16 @@
import {Observable, Observer, Subscription, merge} from 'rxjs';
import {share} from 'rxjs/operators';
import {ApplicationInitStatus} from './application_init';
import {APP_BOOTSTRAP_LISTENER, PLATFORM_INITIALIZER} from './application_tokens';
import {getCompilerFacade} from './compiler/compiler_facade';
import {Console} from './console';
import {Injectable, InjectionToken, Injector, StaticProvider} from './di';
import {ErrorHandler} from './error_handler';
import {DEFAULT_LOCALE_ID} from './i18n/localization';
import {LOCALE_ID} from './i18n/tokens';
import {Type} from './interface/type';
import {ivyEnabled} from './ivy_switch';
import {COMPILER_OPTIONS, CompilerFactory, CompilerOptions} from './linker/compiler';
import {ComponentFactory, ComponentRef} from './linker/component_factory';
import {ComponentFactoryBoundToModule, ComponentFactoryResolver} from './linker/component_factory_resolver';
@ -26,7 +27,7 @@ import {isComponentResourceResolutionQueueEmpty, resolveComponentResources} from
import {WtfScopeFn, wtfCreateScope, wtfLeave} from './profile/profile';
import {assertNgModuleType} from './render3/assert';
import {ComponentFactory as R3ComponentFactory} from './render3/component_ref';
import {DEFAULT_LOCALE_ID, setLocaleId} from './render3/i18n';
import {setLocaleId} from './render3/i18n';
import {NgModuleFactory as R3NgModuleFactory} from './render3/ng_module_ref';
import {Testability, TestabilityRegistry} from './testability/testability';
import {isDevMode} from './util/is_dev_mode';
@ -264,8 +265,10 @@ export class PlatformRef {
throw new Error('No ErrorHandler. Is platform module (BrowserModule) included?');
}
// If the `LOCALE_ID` provider is defined at bootstrap we set the value for runtime i18n (ivy)
const localeId = moduleRef.injector.get(LOCALE_ID, DEFAULT_LOCALE_ID);
setLocaleId(localeId);
if (ivyEnabled) {
const localeId = moduleRef.injector.get(LOCALE_ID, DEFAULT_LOCALE_ID);
setLocaleId(localeId || DEFAULT_LOCALE_ID);
}
moduleRef.onDestroy(() => remove(this._modules, moduleRef));
ngZone !.runOutsideAngular(
() => ngZone !.onError.subscribe(

View File

@ -16,6 +16,7 @@ export {Console as ɵConsole} from './console';
export {inject, setCurrentInjector as ɵsetCurrentInjector, ɵɵinject} from './di/injector_compatibility';
export {getInjectableDef as ɵgetInjectableDef, ɵɵInjectableDef, ɵɵInjectorDef} from './di/interface/defs';
export {APP_ROOT as ɵAPP_ROOT} from './di/scope';
export {DEFAULT_LOCALE_ID as ɵDEFAULT_LOCALE_ID} from './i18n/localization';
export {ivyEnabled as ɵivyEnabled} from './ivy_switch';
export {ComponentFactory as ɵComponentFactory} from './linker/component_factory';
export {CodegenComponentFactoryResolver as ɵCodegenComponentFactoryResolver} from './linker/component_factory_resolver';
@ -27,7 +28,6 @@ export {_sanitizeHtml as ɵ_sanitizeHtml} from './sanitization/html_sanitizer';
export {_sanitizeStyle as ɵ_sanitizeStyle} from './sanitization/style_sanitizer';
export {_sanitizeUrl as ɵ_sanitizeUrl} from './sanitization/url_sanitizer';
export {global as ɵglobal} from './util/global';
export {looseIdentical as ɵlooseIdentical,} from './util/comparison';
export {stringify as ɵstringify} from './util/stringify';
export {makeDecorator as ɵmakeDecorator} from './util/decorators';

View File

@ -173,7 +173,6 @@ export {
i18nConfigureLocalize as ɵi18nConfigureLocalize,
ɵɵi18nLocalize,
setLocaleId as ɵsetLocaleId,
DEFAULT_LOCALE_ID as ɵDEFAULT_LOCALE_ID,
setClassMetadata as ɵsetClassMetadata,
ɵɵresolveWindow,
ɵɵresolveDocument,

View File

@ -11,12 +11,16 @@
import {Subject, Subscription} from 'rxjs';
/**
* Use in directives and components to emit custom events synchronously
* or asynchronously, and register handlers for those events by subscribing
* to an instance.
* Use in components with the `@Output` directive to emit custom events
* synchronously or asynchronously, and register handlers for those events
* by subscribing to an instance.
*
* @usageNotes
*
* Extends
* [RxJS `Subject`](https://rxjs.dev/api/index/class/Subject)
* for Angular by adding the `emit()` method.
*
* In the following example, a component defines two output properties
* that create event emitters. When the title is clicked, the emitter
* emits an open or close event to toggle the current visibility state.
@ -54,6 +58,7 @@ import {Subject, Subscription} from 'rxjs';
* <zippy (open)="onOpen($event)" (close)="onClose($event)"></zippy>
* ```
*
* @see [Observables in Angular](guide/observables-in-angular)
* @publicApi
*/
export class EventEmitter<T extends any> extends Subject<T> {

View File

@ -29,3 +29,8 @@ export function getPluralCase(value: any, locale: string): string {
return 'other';
}
}
/**
* The locale id that the application is using by default (for translations and ICU expressions).
*/
export const DEFAULT_LOCALE_ID = 'en-US';

View File

@ -132,6 +132,9 @@ export interface ContentChildrenDecorator {
*
* Content queries are set before the `ngAfterContentInit` callback is called.
*
* Does not retrieve elements or directives that are in other components' templates,
* since a component's template is always a black box to its ancestors.
*
* **Metadata Properties**:
*
* * **selector** - The directive type or the name used for querying.
@ -194,6 +197,9 @@ export interface ContentChildDecorator {
*
* Content queries are set before the `ngAfterContentInit` callback is called.
*
* Does not retrieve elements or directives that are in other components' templates,
* since a component's template is always a black box to its ancestors.
*
* **Metadata Properties**:
*
* * **selector** - The directive type or the name used for querying.

View File

@ -589,6 +589,8 @@ export interface PipeDecorator {
* to a template. To make it a member of an NgModule,
* list it in the `declarations` field of the `NgModule` metadata.
*
* @see [Style Guide: Pipe Names](guide/styleguide#02-09)
*
*/
(obj: Pipe): TypeDecorator;
@ -606,7 +608,8 @@ export interface PipeDecorator {
export interface Pipe {
/**
* The pipe name to use in template bindings.
*
* Typically uses [lowerCamelCase](guide/glossary#case-types)
* because the name cannot contain hyphens.
*/
name: string;
@ -678,6 +681,8 @@ export interface InputDecorator {
* })
* class App {}
* ```
*
* @see [Input and Output properties](guide/template-syntax#input-and-output-properties)
*/
(bindingPropertyName?: string): any;
new (bindingPropertyName?: string): any;
@ -721,6 +726,8 @@ export interface OutputDecorator {
*
* See `Input` decorator for an example of providing a binding name.
*
* @see [Input and Output properties](guide/template-syntax#input-and-output-properties)
*
*/
(bindingPropertyName?: string): any;
new (bindingPropertyName?: string): any;

View File

@ -7,14 +7,12 @@
*/
import '../util/ng_i18n_closure_mode';
import {getPluralCase} from '../i18n/localization';
import {DEFAULT_LOCALE_ID, getPluralCase} from '../i18n/localization';
import {SRCSET_ATTRS, URI_ATTRS, VALID_ATTRS, VALID_ELEMENTS, getTemplateContent} from '../sanitization/html_sanitizer';
import {InertBodyHelper} from '../sanitization/inert_body';
import {_sanitizeUrl, sanitizeSrcset} from '../sanitization/url_sanitizer';
import {addAllToArray} from '../util/array_utils';
import {assertDataInRange, assertDefined, assertEqual, assertGreaterThan} from '../util/assert';
import {attachPatchData} from './context_discovery';
import {bind, setDelayProjection, ɵɵload} from './instructions/all';
import {attachI18nOpCodesDebug} from './instructions/lview_debug';
@ -1358,7 +1356,6 @@ export function ɵɵi18nLocalize(input: string, placeholders?: {[key: string]: s
* This is the ivy version of `LOCALE_ID` that was defined as an injection token for the view engine
* but is now defined as a global value.
*/
export const DEFAULT_LOCALE_ID = 'en-US';
let LOCALE_ID = DEFAULT_LOCALE_ID;
/**
@ -1369,7 +1366,10 @@ let LOCALE_ID = DEFAULT_LOCALE_ID;
* @param localeId
*/
export function setLocaleId(localeId: string) {
LOCALE_ID = localeId.toLowerCase().replace(/_/g, '-');
assertDefined(localeId, `Expected localeId to be defined`);
if (typeof localeId === 'string') {
LOCALE_ID = localeId.toLowerCase().replace(/_/g, '-');
}
}
/**

View File

@ -142,7 +142,6 @@ export {
} from './state';
export {
DEFAULT_LOCALE_ID,
ɵɵi18n,
ɵɵi18nAttributes,
ɵɵi18nExp,

View File

@ -688,7 +688,11 @@ export class DebugRenderer2 implements Renderer2 {
constructor(private delegate: Renderer2) { this.data = this.delegate.data; }
destroyNode(node: any) {
removeDebugNodeFromIndex(getDebugNode(node) !);
const debugNode = getDebugNode(node) !;
removeDebugNodeFromIndex(debugNode);
if (debugNode instanceof DebugNode__PRE_R3__) {
debugNode.listeners.length = 0;
}
if (this.delegate.destroyNode) {
this.delegate.destroyNode(node);
}

View File

@ -7,7 +7,7 @@
*/
import {CommonModule} from '@angular/common';
import {Attribute, ChangeDetectorRef, Component, Directive, ElementRef, EventEmitter, Host, HostBinding, INJECTOR, Inject, Injectable, InjectionToken, Injector, Input, LOCALE_ID, ModuleWithProviders, NgModule, Optional, Output, Pipe, PipeTransform, Self, SkipSelf, TemplateRef, ViewChild, ViewContainerRef, forwardRef} from '@angular/core';
import {Attribute, ChangeDetectorRef, Component, Directive, ElementRef, EventEmitter, Host, HostBinding, INJECTOR, Inject, Injectable, InjectionToken, Injector, Input, LOCALE_ID, ModuleWithProviders, NgModule, Optional, Output, Pipe, PipeTransform, Self, SkipSelf, TemplateRef, ViewChild, ViewContainerRef, forwardRef, ɵDEFAULT_LOCALE_ID as DEFAULT_LOCALE_ID} from '@angular/core';
import {ViewRef} from '@angular/core/src/render3/view_ref';
import {TestBed} from '@angular/core/testing';
import {ivyEnabled, onlyInIvy} from '@angular/private/testing';
@ -1508,7 +1508,7 @@ describe('di', () => {
const fixture = TestBed.createComponent(MyComp);
fixture.detectChanges();
// takes `LOCALE_ID` from module injector, since we skip Component level with @SkipSelf
expect(fixture.componentInstance.localeId).toBe('en-US');
expect(fixture.componentInstance.localeId).toBe(DEFAULT_LOCALE_ID);
});
it('should work when injecting dependency in Directives', () => {

View File

@ -343,6 +343,21 @@ class SomeComponent {
expect(getLocaleId()).toEqual('ro');
});
it('should wait for APP_INITIALIZER to set providers for `LOCALE_ID`', async() => {
let locale: string = '';
const promise = Promise.resolve().then(() => { locale = 'fr-FR'; });
const testModule = createModule({
providers: [
{provide: APP_INITIALIZER, useValue: () => promise, multi: true},
{provide: LOCALE_ID, useFactory: () => locale}
]
});
const app = await defaultPlatform.bootstrapModule(testModule);
expect(app.injector.get(LOCALE_ID)).toEqual('fr-FR');
});
});
describe('bootstrapModuleFactory', () => {

View File

@ -8,7 +8,7 @@
import {CommonModule, NgIfContext} from '@angular/common';
import {Component, DebugNode, Directive, ElementRef, EmbeddedViewRef, EventEmitter, HostBinding, Injectable, Input, NO_ERRORS_SCHEMA, Renderer2, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core';
import {Component, DebugNode, Directive, ElementRef, EmbeddedViewRef, EventEmitter, HostBinding, Injectable, Input, NO_ERRORS_SCHEMA, Output, Renderer2, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core';
import {ComponentFixture, TestBed, async} from '@angular/core/testing';
import {By} from '@angular/platform-browser/src/dom/debug/by';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
@ -927,5 +927,40 @@ class TestCmptWithPropBindings {
expect(div.attributes.foo).toBe('bar');
});
it('should clear event listeners when node is destroyed', () => {
let calls = 0;
@Component({
selector: 'cancel-button',
template: '',
})
class CancelButton {
@Output() cancel = new EventEmitter<void>();
}
@Component({
template: '<cancel-button *ngIf="visible" (cancel)="cancel()"></cancel-button>',
})
class App {
visible = true;
cancel() { calls++; }
}
TestBed.configureTestingModule({declarations: [App, CancelButton]});
const fixture = TestBed.createComponent(App);
fixture.detectChanges();
const button = fixture.debugElement.query(By.directive(CancelButton));
button.triggerEventHandler('cancel', {});
expect(calls).toBe(1, 'Expected calls to be 1 after one event.');
fixture.componentInstance.visible = false;
fixture.detectChanges();
button.triggerEventHandler('cancel', {});
expect(calls).toBe(1, 'Expected calls to stay 1 after destroying the node.');
});
});
}

View File

@ -7,7 +7,7 @@ ts_config(
name = "tsconfig",
src = "tsconfig.json",
deps = [
"//tools:tsconfig-test",
"//packages:tsconfig-test",
],
)

View File

@ -1,7 +1,7 @@
package(default_visibility = ["//visibility:public"])
load("//packages/bazel:index.bzl", "protractor_web_test_suite")
load("//tools:defaults.bzl", "ng_module", "ts_library")
load("@npm_bazel_protractor//:index.bzl", "protractor_web_test_suite")
load("@npm_bazel_typescript//:index.bzl", "ts_devserver")
ng_module(

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
const protractorUtils = require('@angular/bazel/protractor-utils');
const protractorUtils = require('@bazel/protractor/protractor-utils');
const protractor = require('protractor');
module.exports = async function(config) {

View File

@ -1,7 +1,7 @@
package(default_visibility = ["//visibility:public"])
load("//packages/bazel:index.bzl", "protractor_web_test_suite")
load("//tools:defaults.bzl", "jasmine_node_test", "ng_module", "ts_library")
load("@npm_bazel_protractor//:index.bzl", "protractor_web_test_suite")
load("@npm_bazel_typescript//:index.bzl", "ts_devserver")
ng_module(

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
const protractorUtils = require('@angular/bazel/protractor-utils');
const protractorUtils = require('@bazel/protractor/protractor-utils');
const protractor = require('protractor');
module.exports = async function(config) {

View File

@ -1,7 +1,7 @@
package(default_visibility = ["//visibility:public"])
load("//packages/bazel:index.bzl", "protractor_web_test_suite")
load("//tools:defaults.bzl", "ng_module", "ts_library")
load("@npm_bazel_protractor//:index.bzl", "protractor_web_test_suite")
load("@npm_bazel_typescript//:index.bzl", "ts_devserver")
ng_module(

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
const protractorUtils = require('@angular/bazel/protractor-utils');
const protractorUtils = require('@bazel/protractor/protractor-utils');
const protractor = require('protractor');
module.exports = async function(config) {

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