Compare commits

..

391 Commits

Author SHA1 Message Date
79fb9d449c build(docs-infra): use pinned dependencies when possible in ng-packages-installer (#28510)
Previously, `ng-packages-installer` would replace the version ranges for
all dependencies that were peer dependencies of an Angular package with
the version range used in the Angular package. This effectively meant
that the pinned version (from `yarn.lock`) for that dependency was
ignored (even if the pinned version satisfied the new version range).

This commit reduces non-determinism in CI jobs using the locally built
Angular packages by always using pinned versions of dependencies for
Angular package peer dependencies if possible.

For example, assuming the following versions for the RxJS dependency:

- **aio/package.json**: `rxjs: ^6.3.0`
- **aio/yarn.lock**: `rxjs@^6.3.0: 6.3.3`
- **@angular/core#peerDependencies**: `rxjs: ^6.0.0`

...the following versions would be used with `ng-packages-installer`:

- Before this commit:
  - **aio/package.json**: `rxjs: ^6.0.0`
  - **node_modules/rxjs/**: `6.4.0` (latest version satisfying `^6.0.0`)
- After this commit:
  - **aio/package.json**: `rxjs: ^6.3.0`
  - **node_modules/rxjs/**: `6.3.3` (because it satisfies `^6.0.0`)

PR Close #28510
2019-03-06 15:03:43 -08:00
73a93d3ab6 build(docs-infra): keep other dependencies pinned when installing local Angular packages (#28510)
`ng-packages-installer` can be used to replace Angular packages with
locally built ones (from `dist/packages-dist/`) along with their peer
dependencies.

Previously, in order to achieve this, `yarn install` was called with the
`--no-lockfile` option, which resulted in installing the latest versions
of all dependencies (including transitive ones) permitted by the
corresponding version ranges in `package.json` files. As a result, newly
released versions would be picked, resulting in unexpected,
non-deterministic breakages in CI.

This commit calls `yarn install` with the `--pure-lockfile` option
instead. As a result, only the Angular packages (for which the locally
built ones are used) and their peer dependencies are unpinned; the
pinned versions from `yarn.lock` are used for all other (direct and
transitive) dependencies.

While this does not eliminate non-determinism across builds, it
significantly reduces it.

PR Close #28510
2019-03-06 15:03:37 -08:00
8eda5a152b perf(docs-infra): avoid unnecessary I/O operation in ng-packages-installer (#28510)
PR Close #28510
2019-03-06 15:03:29 -08:00
7b82ce0c67 refactor(docs-infra): format package.json for readability in ng-packages-installer (#28510)
PR Close #28510
2019-03-06 15:03:19 -08:00
2eb5fe699f build(docs-infra): remove unnecessary workaround for RxJS in ng-packages-installer (#28510)
Since b43f8bc7d, RxJS does not need to be patched any more in the
top-level `node_modules/`, so we don't need to special-case RxJS in
`ng-package-installer` and use `node_modules/rxjs/`.

PR Close #28510
2019-03-06 15:03:12 -08:00
f99febcdf9 ci(docs-infra): fix deployment to Firebase
This is a backport of f1a860fbf to 6.1.x.
Related to #29029.
2019-03-06 15:03:00 -08:00
36cbfb1771 build(compiler-cli): upgrade chokidar to latest version
This is a backport of 745c9c5ca to 6.1.x.
Related to #28771.
2019-02-28 18:54:13 +02:00
1f5315f6f7 build(docs-infra): upgrade npm-run-all to latest version for security
This is a backport of f45aedcbf to 6.2.x.
See the original commit for details.
2019-02-28 18:54:13 +02:00
eeebe621fe docs: Indicate that PRs should have an associated issue (#25436)
PR Close #25436
2018-10-15 16:51:46 -07:00
05f279df49 test(docs-infra): improve logging output in test-pwa-score[-localhost] (#26459)
PR Close #26459
2018-10-15 15:23:37 -07:00
485d67bfed build(docs-infra): upgrade lighthouse to 3.2.1 (#26459)
PR Close #26459
2018-10-15 15:23:37 -07:00
a1592f5a20 ci(docs-infra): reduce flakyness (#26459)
PR Close #26459
2018-10-15 15:23:37 -07:00
a251374ecd docs: update process for cli tool and restructure doc (#25752)
PR Close #25752
2018-10-15 11:22:18 -07:00
2b00c17091 docs: minor wording correction. "use" to "user". (#26452)
PR Close #26452
2018-10-15 11:19:47 -07:00
81724f5790 ci(docs-infra): allow aio_local builds to fail on Travis
This job is flaky (up to 50%!) so let's allow it to fail while
we investigate the reason.
2018-10-15 10:28:09 -07:00
1f06b6c99b build: upgrade @types/jasminewd2 to 2.0.4 (#26432)
This commit also removes the extra jasminewd2 typings, since the
changes have been merged in the official typings with
DefinitelyTyped/DefinitelyTyped#28957.
2018-10-13 21:09:41 -07:00
6790709b93 fix(docs-infra): prevent unnecessary SideNav scrollbar (#26416)
Fixes #21508

PR Close #26416
2018-10-12 14:09:09 -07:00
9f7f67121c build(docs-infra): only show name in 'inherited from' section (#26387)
Closes #26181

PR Close #26387
2018-10-12 09:13:02 -07:00
db49beae15 build(docs-infra): upgrade @angular/material to 7.0.0-rc.1 (#26394)
PR Close #26394
2018-10-12 08:57:50 -07:00
97609daea9 build(docs-infra): upgrade @angular/* to 7.0.0-rc.1 (#26394)
PR Close #26394
2018-10-12 08:57:50 -07:00
abcb03cb82 build(docs-infra): upgrade @angular/cli to 7.0.0-rc.2 (#26394)
PR Close #26394
2018-10-12 08:57:47 -07:00
4f09f7db73 fix(upgrade): properly destroy upgraded component elements and descendants (#26209)
Fixes #26208

PR Close #26209
2018-10-11 21:07:49 -07:00
f1e14a3224 docs: add angularmix to events page (#26374)
PR Close #26374
2018-10-11 14:16:02 -07:00
50de03a83a docs: fix transpiles link in dependency injection (#26250)
fixed a double bracket that broke the link

PR Close #26250
2018-10-11 14:11:46 -07:00
65555fe35d Revert "fix(upgrade): properly destroy upgraded component elements and descendants (#26209)"
This reverts commit 6da3867d63. Revert is needed due to compilation failures due to this PR inside Google.
2018-10-10 14:46:20 -07:00
6da3867d63 fix(upgrade): properly destroy upgraded component elements and descendants (#26209)
Fixes #26208

PR Close #26209
2018-10-10 14:19:01 -07:00
c9488b5432 release: cut the v6.1.10 release 2018-10-10 11:23:23 -07:00
b22c376123 Revert "fix(upgrade): properly destroy upgraded component elements and descendants (#26209)"
This reverts commit 623adbbdf7.
2018-10-08 14:36:59 -07:00
8a6f3723ca build(docs-infra): upgrade Angular to 7.0.0-rc.0 and TypeScript to 3.1.1 (#26306)
PR Close #26306
2018-10-08 13:44:15 -07:00
ccb0ec9c35 build(docs-infra): upgrade webpack-cli to 3.1.2 (#26306)
This is necessary to avoid webpack/webpack#8082, when installing
dependencies without taking the lockfile into account (e.g. with
`yarn aio-use-local` - locally or on CI).

PR Close #26306
2018-10-08 13:44:15 -07:00
0c9a087809 ci(docs-infra): run tests against local Angular packages too (#26306)
PR Close #26306
2018-10-08 13:44:15 -07:00
2515ff660b test(docs-infra): fix tests (#26306)
PR Close #26306
2018-10-08 13:44:15 -07:00
70c79cb969 ci(docs-infra): remove unnecessary command (#26306)
This was accidentally merged with 4d506acba and 87f60bccf.
The build script is called in `scripts/ci/build.sh` (if necessary).

PR Close #26306
2018-10-08 13:44:15 -07:00
ed04e99c95 docs: update docs to reflect the changes in RxJS 6 (#26238)
PR Close #26238
2018-10-08 13:43:12 -07:00
623adbbdf7 fix(upgrade): properly destroy upgraded component elements and descendants (#26209)
Fixes #26208

PR Close #26209
2018-10-08 12:06:13 -07:00
3660ff80b7 ci(docs-infra): re-use env variable (#26138)
PR Close #26138
2018-10-08 11:56:53 -07:00
3b4d9dc576 fix(platform-browser): fix #22155, destroy hammer manager when off (#22156)
PR Close #22156
2018-10-05 15:44:06 -07:00
8c6c2fc80d docs: add fakeAsync test new feature document (#23117)
PR Close #23117
2018-10-05 15:43:37 -07:00
3886bfadb0 docs: Rename 'QuickStart' into 'Getting Started' (#25762)
Delete symlink

docs: Undo unwanted changes

docs: Rename 'QuickStart' into 'Getting Started'

Revert symlink commit
PR Close #25762
2018-10-05 15:43:17 -07:00
b35ab4f0e6 docs: clarify CurrencyPipe display property (#25852)
Clarify how to suppress the currency/code in the CurrencyPipe by passing an empty string.

PR Close #25852
2018-10-05 15:42:57 -07:00
39d979c5fa docs: add package doc files (#26047)
PR Close #26047
2018-10-05 15:42:14 -07:00
ff980032e7 fix(docs-infra): fix positioning of message for disabled JavaScript (#26198)
PR Close #26198
2018-10-05 15:39:23 -07:00
2fe401dfbb ci(docs-infra): show custom 404 page on preview server (for consistency) (#26199)
PR Close #26199
2018-10-05 15:39:02 -07:00
b4421bb96b docs: fix wording (#26207)
fix wording to sound better
PR Close #26207
2018-10-05 14:19:08 -07:00
ecb28bf5aa docs: fix spelling errors (#26213)
PR Close #26213
2018-10-05 14:17:22 -07:00
5c5164b6e7 docs: typo fixes (#26247)
PR Close #26247
2018-10-05 14:00:21 -07:00
b8a081a8a5 docs(service-worker): improve API docs for SwPush/SwUpdate (#23138)
PR Close #23138
2018-10-05 13:48:14 -07:00
59d80c471a refactor(service-worker): simplify/improve NgswCommChannel typings (#23138)
PR Close #23138
2018-10-05 13:48:14 -07:00
9e5b0794c5 docs(service-worker): add UpdateActivated/AvailableEvent to the public API (#23138)
PR Close #23138
2018-10-05 13:48:14 -07:00
1c1fd98591 docs: add Suguru Inatomi to GDE resources (#26219)
PR Close #26219
2018-10-04 10:10:52 -07:00
d815e4137f build(docs-infra): upgrade @angular/cli to 6.2.3 (#26145) (#25997)
PR Close #26145

PR Close #25997
2018-10-03 13:26:32 -07:00
fe0c5bfdb3 build(docs-infra): upgrade @angular/* to 7.0.0-beta.7 (#26145) (#25997)
PR Close #26145

PR Close #25997
2018-10-03 13:26:32 -07:00
1975c0a4d2 build(docs-infra): update payload size limits to reflect current status (#26145) (#25997)
PR Close #26145

PR Close #25997
2018-10-03 13:26:32 -07:00
efde073ab9 fix(docs-infra): configure Firebase to strip off the .html extension (#25999) (#25997)
Firebase used to do it automatically (with `cleanUrls: true`), but it
stopped doing it unless the resulting URL corresponds to an existing
file (which is not always the case in angular.io; e.g. the resulting URL
might be matched by a new redirect rule).
This change in Firebase hosting behavior resulted in some URLs not being
correctly redirected (e.g. URLs to the archived v2 site, or `.html`
suffixed URLs from 3rd-party sites).

This commit fixes it, by configuring Firebase hosting to strip off the
`.html` extension and redirect (if no other redirect rule matched).

PR Close #25999

PR Close #25997
2018-10-03 13:26:32 -07:00
a68c29da4b build(docs-infra): update size limits (#25997)
PR Close #25997
2018-10-03 13:26:32 -07:00
becb775d08 fix(docs-infra): ignore server-side redirected URLs in the SW (#25997)
This allows URLs to be passed through to the server (where they are
properly redirected), instead of serving `index.html` from the SW.

Known issue:
`/docs/` will be passed through to the server. `/docs` (without the
trailing slash) will be correctly treated as a navigation URL and
handled by the SW.
We don't link to `/docs/` from within the app, but if there are external
links to `/docs/` they will require a round-trip to the server and will
not work in offline mode.

PR Close #25997
2018-10-03 13:26:32 -07:00
a273491be0 build(docs-infra): downgrade @angular-devkit/build-angular to 0.6.7 (#25997)
The is a bug in versions 0.6.8+ that breaks when trying to use Jasmine's
mock clock.

Related to angular/angular-cli#11626.

PR Close #25997
2018-10-03 13:26:32 -07:00
7d45386262 build(docs-infra): upgrade @angular/* to 6.1.0-rc.3 and rxjs to 6.2.2 (#25997)
PR Close #25997
2018-10-03 13:26:32 -07:00
82fcb325a1 build(docs-infra): upgrade @angular/cli to 6.1.0-rc.3 and @angular-devkit/build-angular to 0.7.0-rc.3 (#25997)
PR Close #25997
2018-10-03 13:26:32 -07:00
115c874779 build(docs-infra): upgrade @angular/material to 6.0.2 (#25997)
PR Close #25997
2018-10-03 13:26:32 -07:00
8cbebc673d build(docs-infra): upgrade @angular/* to 6.0.2 and rxjs to 6.1.0 (#25997)
PR Close #25997
2018-10-03 13:26:32 -07:00
94b2673c1f build(docs-infra): upgrade @angular/cli to 6.0.3 (#25997)
PR Close #25997
2018-10-03 13:26:31 -07:00
bc73dcb448 build(docs-infra): remove unused dependencies (#25997)
PR Close #25997
2018-10-03 13:26:31 -07:00
fefa171d83 build(docs-infra): remove the dependency on rxjs-compat (#25997)
PR Close #25997
2018-10-03 13:26:31 -07:00
5c84b91543 build(docs-infra): enable ServiceWorker in cli config (#25997)
PR Close #25997
2018-10-03 13:26:31 -07:00
00b37310e1 fix(docs-infra): correctly show icon for fetch error when offline (#25997)
PR Close #25997
2018-10-03 13:26:31 -07:00
bc27b95771 refactor(docs-infra): move concept icons to more appropriate location (#25997)
PR Close #25997
2018-10-03 13:26:31 -07:00
31f352c043 refactor(docs-infra): remove unused images (#25997)
PR Close #25997
2018-10-03 13:26:31 -07:00
ad62eaa612 feat(docs-infra): Convert AIO to use the new Service Worker 5.0.0. (#25997)
AIO is currently using a beta version of @angular/service-worker.
Since that was implemented, the SW has been rewritten and released
as part of Angular 5.0.0. This commit updates AIO to use the latest
implementation, with an appropriate configuration file that caches
the various AIO assets in useful ways.

PR Close #25997
2018-10-03 13:26:31 -07:00
66c2d089f0 ci(docs-infra): run the script in the correct folder 2018-10-01 13:08:05 -07:00
c1bf82adb9 fix(docs-infra): remove unnecessary margin on short descriptions (#25768)
(This was added in 405d97431f but it is
not clear the reasoning. It looks better to remove it now.)

PR Close #25768
2018-10-01 09:36:37 -07:00
c05d24e0fe build(docs-infra): fix formatting of entry point export table (#25768)
Now that `list-table` cells are `pre` formatterd we must be careful
of what whitespace appears in text nodes.

PR Close #25768
2018-10-01 09:36:37 -07:00
adbb920ae8 build(docs-infra): simplify property syntax rendering (#25768)
PR Close #25768
2018-10-01 09:36:37 -07:00
f871fecf66 build(docs-infra): remove unused property table heading (#25768)
PR Close #25768
2018-10-01 09:36:37 -07:00
9f919f762a build(docs-infra): add short description "See more" link (#25768)
If there is additional (non-short) description then add in a
link to the short description to take the reader there.

PR Close #25768
2018-10-01 09:36:37 -07:00
6df45a6d47 build(docs-infra): pluralize NgModule(s) heading as appropriate (#25768)
PR Close #25768
2018-10-01 09:36:37 -07:00
71128e2392 build(docs-infra): improve directive selector rendering (#25768)
`:not(...)` blocks are now rendered as italic, while the
rest of the selector is bold.

PR Close #25768
2018-10-01 09:36:36 -07:00
38980f1813 build(docs-infra): move directive macros into memberHelpers.html (#25768)
PR Close #25768
2018-10-01 09:36:36 -07:00
76f30524be build(docs-infra): include directives etc in class descendants lists (#25768)
PR Close #25768
2018-10-01 09:36:36 -07:00
721343349b build(docs-infra): display inherited members on directives (#25768)
PR Close #25768
2018-10-01 09:36:36 -07:00
4c19a2dba9 build(docs-infra): directive inputs and outputs (#25768)
PR Close #25768
2018-10-01 09:36:36 -07:00
4aacbbe04b build(docs-infra): rename example template variable in directive pages (#25768)
PR Close #25768
2018-10-01 09:36:36 -07:00
19c2d5b3d4 build(docs-infra): remove class overview from directive pages (#25768)
PR Close #25768
2018-10-01 09:36:35 -07:00
2f79aab084 build(docs-infra): improve directive selector rendering (#25768)
If the documentation contains a `@selectors` tag then the content of that
is used to describe the selectors of a directive.

Otherwise the selector string is split and each selector is listed as
a list item in an unordered list.

PR Close #25768
2018-10-01 09:36:35 -07:00
63b178ec3d build(docs-infra): improve directive API doc templates (#25768)
Closes #22790
Closes #25530

PR Close #25768
2018-10-01 09:36:35 -07:00
a48bf0bdb6 docs: fix a typo in the Universal guide (#25853)
line 39: `highly-interactive` is the pre-qualifier of `Angular application`, which is the subject so the comma is not necessary (I think). I think this will make it easier for non-native speakers.

PR Close #25853
2018-09-28 09:36:10 -07:00
22dc8adae5 build: use separate tags for ivy builds in publish-build-artifacts.sh (#26159)
PR Close #26159
2018-09-28 09:35:33 -07:00
04a023c31a build: pass stripExportPattern as an array of RegExp (#26012)
This is a workaround for https://github.com/bazelbuild/rules_nodejs/issues/317

PR Close #26012
2018-09-27 12:07:04 -07:00
c12e553ff1 fix(docs-infra): use correct parameters for paginated requests to GitHub (#25671)
As it turns out, in GitHub API paginated requests, page numbering is
1-based. (https://developer.github.com/v3/#pagination)

Starting at page 0 (which returns the first page), results in making the
same request twice and logging incorrect numbers (since the first 100
items are listed twice).

PR Close #25671
2018-09-26 15:26:25 -07:00
c8eb6182bc fix(docs-infra): fix preview server periodic clean-up (#25671)
Includes the following fixes:

- Fix cron entry format for clean-up script.
  Crontabs in `/etc` should not have a user field. No idea why it used
  to work before, but it started giving errors recently:
  `/bin/sh: root: not found`.

- Set required env variable in clean-up script. (Broken in cc6f36a9d.)
  This was producing the following error:
  `ERROR: Missing required environment variable 'AIO_CIRCLE_CI_TOKEN'!`

- Use the correct path for downloads to be removed. (Broken in cc6f36a9d.)

PR Close #25671
2018-09-26 15:26:25 -07:00
0a7a542edd test(docs-infra): remove unnecessary test helpers (#25671)
`supertest.Request` extends `Promise` and can be used directly without
"promisifying".

PR Close #25671
2018-09-26 15:26:25 -07:00
9d7ad34873 docs(docs-infra): update preview server docs to account for recent changes (#25671)
Mostly (but not exclusively) a follow-up to #23576.

PR Close #25671
2018-09-26 15:26:25 -07:00
63c2a2a74a ci(docs-infra): test PR previews on CI (#25671)
The deployment of PR previews is triggered by the notification webhook
of the `aio_preview` CircleCI job (which creates and stores the build
artifacts).

This commit adds a new job (`test_aio_preview`), which waits for the
preview to be deployed (for PRs that do have a preview) and then runs
some tests against it (currently only PWA tests).

Fixes #23818

PR Close #25671
2018-09-26 15:26:25 -07:00
2e0de01372 feat(docs-infra): add API endpoint for checking if PR can have preview (#25671)
There several reasons why PRs cannot have (public) previews:
- The PR did not affect any relevant files (e.g. non-spec files in
  `aio/` or `packages/`).
- The PR cannot be automatically verified as "trusted" (based on its
  author or labels).

Note:
The endpoint does not check whether there currently is a (public)
preview for the specified PR; only whether there can be one.

PR Close #25671
2018-09-26 15:26:25 -07:00
88e080003d fix(docs-infra): correctly check PR files on preview server (#25671)
According to the docs, the response of GitHub's [PR files API][1]
_"includes a maximum of 300 files"_. This means that if a PR contains
more files, it is possible that not all files are retrieved (which
could, for example, give a false negative for the "significant files
touched" check - not likely but possible).

This commit fixes it by using paginated requests to retrieve all changed
files.

[1]: https://developer.github.com/v3/pulls/#list-pull-requests-files

PR Close #25671
2018-09-26 15:26:25 -07:00
8a62f0a36c test(docs-infra): fix test for preview server's GithubPullRequests (#25671)
PR Close #25671
2018-09-26 15:26:25 -07:00
6c8863aa09 test(docs-infra): fix test for preview server's BuildCleaner completing prematurely (#25671)
PR Close #25671
2018-09-26 15:26:25 -07:00
fe92614c91 test(docs-infra): fix preview server unit tests on Windows (#25671)
Some tests where comparing actual with expected paths, without taking
into account that paths will be different on Windows.

This commit uses `path.resolve()` to convert expected paths to their
OS-specific form.

PR Close #25671
2018-09-26 15:26:25 -07:00
166bb8e048 test(docs-infra): add support for source-maps in preview server tests (#25671)
PR Close #25671
2018-09-26 15:26:25 -07:00
c7da5d8cfd refactor(docs-infra): use mockable logger (#25671)
Related discussion:
https://github.com/angular/angular/pull/23576#discussion_r187925949.

PR Close #25671
2018-09-26 15:26:25 -07:00
153738dce9 refactor(docs-infra): fix method name (getPrfromBranch --> getPrFromBranch) (#25671)
PR Close #25671
2018-09-26 15:26:25 -07:00
ce4aa5cb93 build(docs-infra): upgrade preview server dependencies (#25671)
PR Close #25671
2018-09-26 15:26:25 -07:00
0647582292 build(docs-infra): replace concurrently with npm-run-all for preview server dev (#25671)
`npm-run-all` works just as well, but is better at handling termination on Windows.

PR Close #25671
2018-09-26 15:26:25 -07:00
c5620d1c7a build(docs-infra): do not exit preview server dev script when build fails (#25671)
PR Close #25671
2018-09-26 15:26:25 -07:00
e3a73dff45 build(docs-infra): avoid race condition in aio-builds-setup/ npm scripts (#25671)
Previously, due to multiple scripts re-building during `yarn dev`
initialization, there could be race conditions that led to errors.

This commit fixes it by ensuring `yarn build` is run once (before
the main `yarn dev` script).

PR Close #25671
2018-09-26 15:26:25 -07:00
5881f34787 docs: firefox web components info (#26118)
PR Close #26118
2018-09-26 15:25:46 -07:00
acffa22a35 release: cut the v6.1.9 release 2018-09-26 12:02:03 -07:00
159e8b4fda docs: update routing integration section based on feedback (#20023)
PR Close #20023
2018-09-26 10:14:53 -07:00
d52dd0a8d1 docs: add section on router integration (#20023)
PR Close #20023
2018-09-26 10:14:53 -07:00
05252769bf docs: clean up providedIn: 'root' syntax for router examples (#20023)
PR Close #20023
2018-09-26 10:14:53 -07:00
9c36a3520d docs: router guide review feedback changes (#20023)
PR Close #20023
2018-09-26 10:14:53 -07:00
1b282c278f docs: Update router guide to use Angular CLI (#20023)
PR Close #20023
2018-09-26 10:14:53 -07:00
c9fece997c docs: Refresh content on routable animations for router guide (#20023)
PR Close #20023
2018-09-26 10:14:53 -07:00
c8817f39a9 docs: cleanup minor changes for forms overview (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
2f1aec4744 docs: remove unused properties from forms overview example (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
e55127906a docs: fix typos from review feedback (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
789ff49bcf docs: update with forms overview review feedback (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
df02d6dd86 docs: more overview feedback changes (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
fb8028a130 docs: update nav descriptions based on feedback (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
29647bb815 docs: add updated reactive forms data flow image (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
2911e99baf docs: updates from review feedback (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
3952367bf3 docs: add updated forms overview images (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
ea6aade4ce docs: integrate forms diagrams into overview (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
26baf15b12 docs: add final thoughts to forms overview (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
25c5cba7b3 docs: incorporated forms overview review feedback (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
fb06037392 docs: forms overview review changes (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
90f8a1622e docs: add forms overview example for snippets (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
8c9edb8484 docs: more form overview edits (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
52cd20d4fe docs: incorporated forms overview feedback (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
c7567b65f2 docs(forms): add package overview for forms (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
0fdd1bb929 docs: add forms overview guide (#25663)
PR Close #25663
2018-09-25 18:48:22 -07:00
559c647db7 docs: fix issues related to tutorial. (#24445)
PR Close #24445
2018-09-25 18:45:21 -07:00
42e2e7cf57 build: remove obsolete comment in env.sh (#25819)
The comment is no longer true since #25602.

PR Close #25819
2018-09-25 11:04:34 -07:00
adad1706e0 docs: fix a typo (#26074)
PR Close #26074
2018-09-24 13:48:26 -07:00
a169743324 fix(service-worker): do not blow up when caches are unwritable (#26042)
In some cases, example when the user clears the caches in DevTools but
the SW remains active on another tab and keeps references to the deleted
caches, trying to write to the cache throws errors (e.g.
`Entry was not found`).

When this happens, the SW can no longer work correctly and should enter
a degraded mode allowing requests to be served from the network.

Possibly related:
- https://github.com/GoogleChrome/workbox/issues/792
- https://bugs.chromium.org/p/chromium/issues/detail?id=639034

This commits remedies this situation, by ensuring the SW can enter the
degraded `EXISTING_CLIENTS_ONLY` mode and forward requests to the
network.

PR Close #26042
2018-09-24 09:53:41 -07:00
cea7fbe93f docs: Fixes typo in FormArray (#26031)
PR Close #26031
2018-09-24 09:14:08 -07:00
b907e5a2bc docs: correct path reference in upgrade guide (#26072)
The incorrect path is referenced, this is confusing to users following the "Upgrading from AngularJS" guide.

PR Close #26072
2018-09-24 09:13:27 -07:00
77d2cbda4a docs: fix Sajee info in contributors (#26063)
PR Close #26063
2018-09-24 09:12:47 -07:00
a730fc703f build(docs-infra): fail doc-gen if a content rule fails (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
af26914ba9 build(docs-infra): allow usage notes on decorator option properties (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
7f7bc64186 docs(core): remove usage notes from ReflexiveInjector.parent property (#26039)
Properties are not allowed usage notes, and in this case the example
is so simple it didn't warrant moving it to the overall class documentation.

PR Close #26039
2018-09-24 09:11:05 -07:00
33af76929f docs(core): move headings to @usageNotes (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
edbf3d2fe3 docs(common): move KeyValuePipe example to @usageNotes (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
a39445fe09 docs(forms): move extended text to @usageNotes (#26039)
Headings are not allowed in the basic description block.

PR Close #26039
2018-09-24 09:11:05 -07:00
0b05448a7d docs(http): move examples to @usageNotes (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
852a73ef82 docs(platform-browser): move examples to @usageNotes (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
b8bfc03875 docs(router): move examples to @usageNotes (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
c4887ab10a docs(upgrade): move examples etc into @usageNotes (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
1abd3977be docs(common): move KeyValuePipe example to @usageNotes (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
98961e3d44 build(docs-infra): remove legacy jsdoc tag processing (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
3f89d3094b docs(common): remove legacy @whatItDoes tag (#26039)
PR Close #26039
2018-09-24 09:11:05 -07:00
484d3d9a64 build(docs-infra): add @nocollapse tag-def to prevent warning (#26039)
See https://github.com/angular/angular/blob/master/packages/compiler-cli/src/transformers/nocollapse_hack.ts

PR Close #26039
2018-09-24 09:11:05 -07:00
37f3b92ff5 build(docs-infra): sort NgModule exports by id (#26051)
PR Close #26051
2018-09-21 17:00:04 -07:00
50cd655c6c build(docs-infra): sort package exports by id (#26051)
Closes #26046

PR Close #26051
2018-09-21 17:00:04 -07:00
05d1b84f52 fix(docs-infra): ensure that only search is removed from URL on click (#26056)
When we have navigated to the site via a URL that contains a search
query param, the site shows the search results.

We want to remove that query param from the URL when the search
results are closed, but the current implementation is also removing
other query params unnecessarily.

Now only the search param is removed when the search results are
closed.

See https://github.com/angular/angular/pull/25479/files#r219497804
for more context.

PR Close #26056
2018-09-21 10:29:26 -07:00
69452231df build(docs-infra): expose deprecated status on items more clearly (#25750)
PR Close #25750
2018-09-21 10:26:51 -07:00
4f6bef5b32 fix(docs-infra): render security risk labels (#25750)
PR Close #25750
2018-09-21 10:26:51 -07:00
ec96332559 build(docs-infra): improve search quality (#25750)
PR Close #25750
2018-09-21 10:26:51 -07:00
ee9f0b5d9a build(docs-infra): do not include license comment in first API doc (#26050)
The default dgeni config is to concatenate leading comments in front of API items.

In the case that you have an API item that starts a file with no import statements,
the license comment at the top of the file was being added to the front of the
API item's comment. SInce the license comment includes the `@license` tag
and the API item's comment did not start with `@description` the content of
the API item's comment was being put inside the `@license` tag, and no
description was being extracted from the API item's comment.

This commit updates to a version of dgeni-packages that has a switch to turn off
this concatenation, and then also configures this switch.

Closes #26045

PR Close #26050
2018-09-21 10:25:46 -07:00
a135f48b6d docs: add Sajee to contributors (#26028)
PR Close #26028
2018-09-21 10:24:22 -07:00
61b4c26893 ci: correct github robot size check configuration (#26057)
PR Close #26057
2018-09-21 10:21:31 -07:00
f1cb46081c ci: only run aio_preview job on PR builds (#26030)
There can be no preview on non-PR builds, so there is no point in
running the job.

PR Close #26030
2018-09-20 09:32:46 -07:00
0ec925bd2f docs: copy-edit (#25732)
PR Close #25732
2018-09-19 18:22:47 -07:00
5f1b861525 docs: integrate material from cli wiki (#25732)
PR Close #25732
2018-09-19 18:22:47 -07:00
f0d70545e8 fix(forms): remove forms file from patch (#26025)
PR Close #26025
2018-09-19 17:18:31 -07:00
26341c7fd4 docs: add missing @ngModule tags (#25734)
PR Close #25734
2018-09-19 16:23:04 -07:00
e9f4f1b416 build(docs-infra): process and render ngmodule exports (#25734)
All directives and pipes must now be tagged with one ore more
public NgModule, from which they are exported.

If an item is exported transitively via a re-exported internal NgModule
then it may be that the item appears to be exported from more than
one public NgModule. For example, there are shared directives that
are exported in this way from `FormsModule` and `ReactiveFormsModule`.

The doc-gen will error and fail if a directive or pipe is not tagged correctly.

NgModule pages now list all the directives and pipes that are exported from it.
Directive and Pipe pages now list any NgModule from which they are exported.
Packages also now list any NgModules that are contained - previously they were
missed.

PR Close #25734
2018-09-19 16:21:02 -07:00
9cd534bd63 build(docs-infra): separate NgModules from Classes in API docs (#25734)
PR Close #25734
2018-09-19 16:20:56 -07:00
2f8e1fbab8 build(docs-infra): remove unused info-bar API template (#25734)
PR Close #25734
2018-09-19 16:20:48 -07:00
c7a6adc771 docs(forms): update form apis based on review feedback (#25724)
PR Close #25724
2018-09-19 16:09:03 -07:00
8fb2b473ca docs(forms): update API reference for forms interfaces and abstract classes (#25724)
PR Close #25724
2018-09-19 16:09:03 -07:00
5886090d50 feat(docs-infra): Add opensearch description (#25479)
Enables Chrome users to search angular.io and its subdomains from the browsers navigation bar.
Not sure if compatible with Firefox yet.
The queried term in the URL is removed after closing the search-results.

PR Close #25479
2018-09-19 15:33:28 -07:00
3988ebf432 release: cut the v6.1.8 release 2018-09-19 14:07:10 -07:00
5099b79545 docs: copy edit (#25582)
PR Close #25582
2018-09-19 10:43:07 -07:00
038d06d2e9 docs: clean up formats, add detail (#25582)
PR Close #25582
2018-09-19 10:43:07 -07:00
9e1aff9fe6 docs: update view-related api doc (#25582)
PR Close #25582
2018-09-19 10:43:07 -07:00
a41f331cb4 docs: add ngmodule api doc (#25618)
PR Close #25618
2018-09-19 10:40:59 -07:00
71628f1837 docs(animations): updated animation docs (#24206)
PR Close #24206
2018-09-19 10:37:31 -07:00
df878a6b60 docs: delete extra sentence (#25984)
PR Close #25984
2018-09-19 09:42:12 -07:00
48d7f4e8b5 fix(bazel): move bazel managed runtime deps for downstream usage (#25690)
PR Close #25690
2018-09-18 15:09:50 -07:00
66f5d27e50 build(bazel): fix typos in comments (#25172)
PR Close #25172
2018-09-18 15:05:29 -07:00
91dd160b21 fix(bazel): correct type concatenated to devmode_js (#25467)
PR Close #25467
2018-09-18 15:04:40 -07:00
1c44b71fd2 feat(ivy): enable .ngfactory.js generation in g3 only (#25392)
This turns on generation of ngfactory.js files when compiling in Ivy
mode in g3. They're not turned on for Bazel users as there appears to
be a strange interaction with the way our tests run in Bazel mode.

PR Close #25392
2018-09-18 15:04:31 -07:00
a5e0ae501d docs(bazel): add skydoc generation (#23544)
PR Close #23544
2018-09-18 15:04:26 -07:00
2d0e642dbe fix(bazel): allow compile_strategy to be (privately) imported (#25080)
compile_strategy() is used to decide whether to build Angular code
using ngc (legacy) or ngtsc (local). In order for g3 BUILD rules
to switch properly and allow testing of Ivy in g3, they need to
import this function.

This commit removes the _ prefix which allows the function to be
imported.

PR Close #25080
2018-09-18 15:00:32 -07:00
9ea656f20e build: use nodejs public api (#25940)
`nodejs_binary` and `nodejs_test` from `@build_bazel_rules_nodejs//:defs.bzl` and `@build_bazel_rules_nodejs//internal/node:node.bzl` are different as the first one uses a macro https://github.com/bazelbuild/rules_nodejs/blob/master/internal/node/node.bzl#L229 to wrap the `nodejs_binary` and `nodejs_test` as an `.exe` for Windows.

PR Close #25940
2018-09-18 14:47:43 -07:00
97ae7aed41 feat(bazel): add additional parameters to ts_api_guardian_test def (#25694)
Added `strip_export_pattern` and `allow_module_identifiers` so that these can be passed from downstream

PR Close #25694
2018-09-18 14:47:35 -07:00
678b4209c8 fix(bazel): specify the package and lock files using the workspace (#25694)
PR Close #25694
2018-09-18 14:47:30 -07:00
b7be4f55be build: add support for running builds outside of sandbox on Mac. (#25870)
Add following to your `~/.bazelrc`. This will run the build faster locally
(outside of sandbox), but continue running the builds with sandboxing
on CI.

```
build --spawn_strategy=standalone --strategy=ESM5=sandboxed
```
PR Close #25870
2018-09-18 14:43:39 -07:00
e7c72ab556 style: reformat bzl files on patch branch to match master 2018-09-18 14:43:05 -07:00
af785f9e91 ci: enforce formatting of .bzl files (#23544)
These are now enforced in google3 so we want to match, so that PRs don't get held up when we sync

PR Close #23544
2018-09-18 14:40:59 -07:00
1ac5d68827 build: bump the com_github_bazelbuild_buildtools version to 0.12.0 (#25917)
This is a preliminary fix to make buildifier work with Bazel 0.16.

See alexeagle/angular-bazel-example/issues/173

PR Close #25917
2018-09-18 14:36:38 -07:00
2c987625ae build(bazel): update to rules_typescript 0.17.0 & rules_nodejs 0.13.4 (#25920)
PR Close #25920
2018-09-18 14:36:28 -07:00
a77f567403 ci: update to bazel 0.17 (#25967)
this includes support for @ character in labels, which we need for fine-grained deps

PR Close #25967
2018-09-18 14:32:34 -07:00
110c81f359 build: ignore aio/docs-infra commits in changelog gulp task (#25838)
PR Close #25838
2018-09-18 13:23:06 -07:00
ef4b5c7e59 build: update conventional-changelog and simplify changelog gulp task (#25838)
The version prefix issue has been fixed with
conventional-changelog/conventional-changelog#179.

PR Close #25838
2018-09-18 13:23:00 -07:00
c69362442d build: update .nvmrc file to correct node version (#25992)
The version was updated in 34ec9244a6
but this file got missed.
PR Close #25992
2018-09-18 13:11:58 -07:00
6c8791ee32 docs(forms): change documentation of the FormGroup patchValue method (#25901)
Improve the grammar of the description to make it more readable.
PR Close #25901
2018-09-18 13:08:06 -07:00
274dc1e972 build(bazel): update to rules_typescript 0.17.0 & rules_nodejs 0.13.4 (#25977)
PR Close #25977
2018-09-18 13:03:37 -07:00
d9bd86050b docs: fix typo in bootstrapping guide (#25939)
Fixes #25938

PR Close #25939
2018-09-14 16:38:18 -07:00
076374ba4f docs: delete old comments from example (#25931)
PR Close #25931
2018-09-13 15:33:33 -07:00
e117b1ffd2 fix(router): mount correct component if router outlet was not instantiated and if using a route reuse strategy (#25313) (#25314)
This unsets 'attachRef' on outlet context if no route is to be reused in route activation.

Closes #25313

PR Close #25314
2018-09-11 16:26:42 -07:00
8d7fbb614b docs(router): change description of parameter usage for navigation functions (#21840)
PR Close #21840
2018-09-11 16:24:23 -07:00
a31cfc521c fix(compiler): Fix look up of entryComponents in AOT Summaries (#24892)
Previously, when you attempted to bootstrap a component that had a
router-outlet using ngsummaries, it would complain that the component
was not provided by any module even if it was. This commit fixes a
mistake (AFAICT) which caused the lookup of the component in the AOT
summaries to fail.

I believe this change is safe. I've run the affected tests within Google
and there were no breakages caused by this change.

PR Close #24892
2018-09-11 16:23:17 -07:00
55a1ce7adf docs: add disableTypeScriptVersionCheck documentation (#25537)
PR Close #25537
2018-09-11 12:25:55 -07:00
9f3da659aa docs(aio): add ng-sq-ui to resources (#25874)
PR Close #25874
2018-09-10 10:31:11 -07:00
8f9aeaaa67 docs: move compiler options to last section of the page (#22353)
PR Close #22353
2018-09-10 10:30:01 -07:00
b9a5ce1c06 docs(service-worker): update http-server command (#25845)
PR Close #25845
2018-09-06 14:59:51 -07:00
f67229efa3 build(docs-infra): ensure any stale generated content is deleted (#25841)
Since `aio/src/generated/` is git-ignored, it is easy for stale content
(e.g. removed images, examples, zips, etc.) to remain there on local
clones and then get copied into the `dist/` directory.

This commit ensures `aio/src/generated/` is cleaned up before generating
the new content.

PR Close #25841
2018-09-06 14:59:29 -07:00
f707f545aa build: update to Node 10 (#25822)
PR Close #25822
2018-09-06 14:58:30 -07:00
62f4ea5f0f test(docs-infra): fix double-slash in URL of aio_monitoring test (#25641) (#25820)
As part of the tests run in the CircleCI `aio_monitoring` job, we need
to retrieve `sitemap.xml` from the site under test. Previously, the URL
used to retrieve that contained a double-slash (`//`). At some point,
Firebase (which is used for hosting the site) stopped normalizing
double-slashes to a single slash, causing the test to fail.

This commit fixes the problem by ensuring that the constructed URLs do
not contain double-slashes.

PR Close #25641

PR Close #25820
2018-09-06 14:58:09 -07:00
ecc3406ca6 test(docs-infra): correctly extract sitemap URLs (#19795) (#25820)
`%%DEPLOYMENT_HOST%%` has been assumed to be the host prefix for sitemap
URLs since bf29936af, but afaict this was never the case.

PR Close #19795

PR Close #25820
2018-09-06 14:58:09 -07:00
e244b5180e build(bazel): update bazel integration to build angular from source (#25774)
PR Close #25774
2018-09-06 14:56:53 -07:00
f85d3d7857 build(bazel): make resolveTypeReferenceDirectives override work with both ts 2.9 & ts 3.0 (#25774)
PR Close #25774
2018-09-06 14:56:53 -07:00
b404d47b16 build(bazel): fix bazel types reference directive resolves (#25774)
PR Close #25774
2018-09-06 14:56:53 -07:00
815d1ffa19 release: cut the v6.1.7 release 2018-09-05 20:49:37 -07:00
d1063c62b3 build(docs-infra): restore correct dependency versions in package.json (#25827)
Accidentally broken in 46de203f8 (while cherry-picking #25806 into
6.1.x).
2018-09-05 17:57:27 -07:00
3a0b7355e5 build: upgrade Chromium and ChromeDriver to latest versions (#25602) (#25669)
PR Close #25602

PR Close #25669
2018-09-05 11:40:30 -07:00
3bdd4e249f build: check for latest Chromium version (#25602) (#25669)
Now that https://omahaproxy.appspot.com/all is back up, we can restore
the check for newer available version of Chromium.

Fixes #22231

PR Close #25602

PR Close #25669
2018-09-05 11:40:30 -07:00
2c1f55069f build: update ngcontainer to node 10.9.0 (#25812)
PR Close #25812
2018-09-05 11:37:26 -07:00
e72f741e78 docs: update event page (#25799)
docs: change reactiveconf event location
PR Close #25799
2018-09-05 11:37:03 -07:00
f0bcfd0e78 docs: fix showcase address truly-ui (#25757)
PR Close #25757
2018-09-05 11:36:39 -07:00
82e06766b8 fix(upgrade): trigger $destroy event on upgraded component element (#25357)
Fixes #25334

PR Close #25357
2018-09-05 11:35:15 -07:00
eea1600a38 refactor(upgrade): share code for destroying upgraded components between dynamic and static (#25357)
PR Close #25357
2018-09-05 11:35:14 -07:00
8f8c390c75 test: remove deprecated Buffer usage in sourcemap test (#25805)
PR Close #25805
2018-09-05 09:38:49 -07:00
23a96dca2d feat(router): warn if navigation triggered outside Angular zone (#24959)
closes #15770, closes #15946, closes #24728

PR Close #24959
2018-09-05 09:35:14 -07:00
6f7df8a1fa feat(docs-infra): disable "status" selector in API list when displaying only packages (#25718)
Closes #25708

PR Close #25718
2018-09-05 09:28:29 -07:00
92298e5271 build(docs-infra): do not render internals in package API pages (#25723)
Closes #24493

PR Close #25723
2018-09-05 09:28:06 -07:00
27f0817000 docs(changelog): fix version 6.1.5 typo (#25760)
PR Close #25760
2018-09-05 09:27:16 -07:00
4596fc0217 refactor(docs-infra): bump polyfills payload limit (#25806)
PR Close #25806
2018-09-05 09:26:10 -07:00
46de203f85 refactor(docs-infra): simplify custom-element polyfill setup (#25806)
PR Close #25806
2018-09-05 09:24:12 -07:00
d752a8907b build(docs-infra): ensure root node_modules exists (#25811)
Now that the doc-gen parses the imports of TS source
files we need to ensure that the root node_modules
exists. Otherwise running `yarn docs` produces an
obscure error:

```
Error: No SourceFile found with path node_modules/@types/jasmine/index.d.ts
```

Closes #25759

PR Close #25811
2018-09-05 09:22:46 -07:00
4fe369e188 docs: add pwa keyword to service worker page (#25725)
PR Close #25725
2018-09-04 12:09:56 -07:00
d8930bbdc2 docs: correct misspellings and add missing punctuation in tutorial (#25676)
PR Close #25676
2018-09-04 12:08:53 -07:00
ad7be5087c ci: ensure build-packages-dist works on OS/X bash (#25591)
PR Close #25591
2018-09-04 12:08:25 -07:00
a4405d7c6f docs(forms): update API reference for reactive and template-driven forms modules (#25687)
PR Close #25687
2018-08-31 13:39:24 -07:00
88f7ddb27d build: fix bad merge onto patch branch (#25729) 2018-08-31 09:51:21 -07:00
98f5acebdb test(docs-infra): test that the "suggest edit" buttons are visible where expected (#24378)
PR Close #24378
2018-08-31 09:42:11 -07:00
ff78149ec2 refactor(docs-infra): refactor templates (#24378)
PR Close #24378
2018-08-31 09:42:11 -07:00
66b7870da7 fix(docs-infra): show "suggest edits" only for /guide and /tutorial dirs (#24378)
PR Close #24378
2018-08-31 09:42:11 -07:00
82088a8489 feat(docs-infra): add "suggest edits" feature to all docs (#24378)
PR Close #24378
2018-08-31 09:42:11 -07:00
ebcf762132 fix(core): size regression with closure compiler (#25531)
By pulling in `compiler` into `core` the `compiler` was not
100% tree-shakable and about  8KB of code was retained
when tree-shaken with closure.

PR Close #25531
2018-08-30 21:32:10 -07:00
ed6b68babf fix(bazel): protractor rule should include *.e2e-spec.js (#25701)
PR Close #25701
2018-08-30 21:21:28 -07:00
2e09115c0c docs: edit and organize di guide (#21915)
PR Close #21915
2018-08-30 13:15:47 -04:00
4a8d56a820 release: cut the v6.1.6 release 2018-08-29 15:38:51 -07:00
0a3dd872e3 build: fix bad merge onto patch branch (#25729)
PR Close #25729
2018-08-29 18:34:22 -04:00
3e690e0062 fix(bazel): Cache fileNameToModuleName lookups (#25731)
This saves expensive re-parsing of the file when not run as a Bazel worker

PR Close #25731
2018-08-29 17:39:22 -04:00
7f8d6c1066 release: cut the v6.1.5 release 2018-08-28 21:39:18 -07:00
c6d502f7f8 docs: clarification of hero selection in routing section (#25634)
PR Close #25634
2018-08-28 22:16:18 -04:00
7aff3641a1 fix(bazel): only lookup amd module-name tags in .d.ts files (#25710)
PR Close #25710
2018-08-28 21:07:15 -04:00
2194b5a5c3 ci: remove vicb from pullapprove.yml (#25702)
PR Close #25702
2018-08-28 11:15:54 -07:00
8a35290686 build: update Bazel to 0.16 (#25646)
PR Close #25646
2018-08-27 18:20:32 -04:00
e40519c32a build(docs-infra): render all overloads if they are abstract (#25670)
In an overloaded method, the overload with the function body is the
actual method doc, and this doc is not included in the list of "additional"
overloads.

Moreover, the logic (all in dgeni-packages) is that if none of the items
has a body then we use the first overload as the actual method doc.

In the case of abstract methods, none of the methods have a body. So we
have a situation where the overloads collection does not contain the first
abstract method, even though it is not the "implementation" of the method.
Therefore we need to still render it.

Closes #25610

PR Close #25670
2018-08-27 18:19:08 -04:00
b560189c0e build(docs-infra): remove "annotations" section from API pages (#25677)
PR Close #25677
2018-08-27 18:18:42 -04:00
59cfc8a729 build(bazel): use value of /// <amd-module name=“”> directive to convert fileNameToModuleName in ngc-wrapped (#25650)
PR Close #25650
2018-08-27 12:21:19 -04:00
72ed2e90d0 build(bazel): esm5_outputs_aspect to work with targets such as ts_proto_library with no replay_params attribute (#25648)
PR Close #25648
2018-08-24 11:48:04 -04:00
4e82a76998 docs(elements): fix typo (tranformation --> transformation) (#25600)
PR Close #25600
2018-08-23 16:54:49 -04:00
51d5b433d0 fix(aio): show aio-themed 404 page for unknown resources (#23188)
Fixes #23179

PR Close #23188
2018-08-23 15:25:48 -04:00
cc0d0a9d1e fix(docs-infra): fix closure warning issue for improper internal flag (#25628)
PR Close #25628
2018-08-22 21:59:23 -04:00
82f26fe5f5 build(bazel): remove workaround no longer needed for module names for ngfactory & ngsummary files (#25604)
Workaround was added in https://github.com/angular/angular/pull/25335. It was necessary for .ngfactory & .ngsummary files to have proper AMD module names starting with @angular when building angular downstream from source using Bazel. The underlying issue has been resolved in the compiler and these files now get proper AMD module names without the need for this workaround. The workaround had an unexpected consequence https://github.com/angular/angular-cli/issues/11835 which is fixed by its removal.

PR Close #25604
2018-08-22 21:11:18 -04:00
8de57c9887 release: cut the v6.1.4 release 2018-08-22 15:05:02 -07:00
ace4e4ffa5 build: remove NGBUILDS_IO_KEY now that it is not used any more (#25601)
This is a follow-up to #25536.

PR Close #25601
2018-08-22 15:59:14 -04:00
1fa97903a3 docs: Improve docs for downgrading a service (#19371)
PR Close #19371
2018-08-21 10:49:00 -07:00
7e61645b82 fix(router): default scroll position restoration to disabled (#25586)
Fixes #25145
FW-305 #resolve

PR Close #25586
2018-08-21 10:48:14 -07:00
46b0ce9fc6 refactor(bazel): allow and ignore extra args for _ts_expected_outs (#25558)
This is needed to let ts_compile_actions take explicit list of srcs and deps to generate tsc actions from another rule. This is no-op for ngc for now.

PR Close #25558
2018-08-20 16:27:48 -07:00
78750a7fec docs: fix typo in service worker getting started guide (#25512)
PR Close #25512
2018-08-20 11:09:52 -07:00
77d9975eb2 build(aio): update dgeni-packages to 0.26.3 to fix reference types issue (#25528)
PR Close #25528
2018-08-20 11:09:24 -07:00
7eed4ee837 build: refactor ambient node & jasmine types so they are only included where needed (#25528)
PR Close #25528
2018-08-20 11:09:24 -07:00
292b435495 docs: fix typo in reactive forms guide (#25543)
PR Close #25543
2018-08-20 11:08:32 -07:00
5939c420ce docs: copy edit glossary (#25468)
PR Close #25468
2018-08-17 14:33:51 -07:00
a5cc9dbb53 ci: ensure aio_preview job has needed node_modules (#25536)
PR Close #25536
2018-08-17 13:48:27 -07:00
2b810a4e57 docs(docs-infra): the build.sh script was renamed to create-image.sh (#25554)
PR Close #25554
2018-08-17 13:47:54 -07:00
2acf369664 ci(docs-infra): rename 'upload-server' to 'preview-server' (#25554)
The server no longer has files uploaded to it. Instead it is more
accurate to refer to it as dealing with "previews" of PRs.

PR Close #25554
2018-08-17 13:47:54 -07:00
860b79289f ci(docs-infra): add explicit return types to methods (#25554)
PR Close #25554
2018-08-17 13:47:54 -07:00
b519d41f42 ci(docs-infra): improve preview-server logging (#25554)
PR Close #25554
2018-08-17 13:47:54 -07:00
faf184ad63 ci(docs-infra): change AIO preview server stuff to pull builds from CircleCI (#25554)
Previously, Travis pushed the build artitfacts to the preview server.
This required us to use JWT to secure the POST request from Travis, to
ensure we couldn't receive malicious builds.

JWT has been deprecated and we are moving our builds to CircleCI.

This commit rewrites the TypeScript part of the preview server that
handles converting build artifact into hosted previews of the docs.

PR Close #25554
2018-08-17 13:47:54 -07:00
1e0f455855 ci(docs-infra): factor out the aio-builds-setup environment variables (#25554)
PR Close #25554
2018-08-17 13:47:54 -07:00
ced30982df ci(docs-infra): move the payload-size check to the test job (#25554)
PR Close #25554
2018-08-17 13:47:54 -07:00
fed429b0cc ci(docs-infra): add helper scripts for running TDD in Docker (#25554)
PR Close #25554
2018-08-17 13:47:54 -07:00
9cb3107dda docs(docs-infra): update the preview server documentation (#25554)
PR Close #25554
2018-08-17 13:47:54 -07:00
548a972c2a ci(docs-infra): move AIO preview deployment to CircleCI (#25554)
Now instead of pushing the AIO build artifacts to the preview server
from inside a Travis job, the artifacts are built and hosted on the
CircleCI infrastructure. The preview server will then pull these
down after being triggered by a CircleCI build webhook.

PR Close #25554
2018-08-17 13:47:54 -07:00
20dcc25eed ci(docs-infra): update upload-server to run on node.js v10 (#25554)
PR Close #25554
2018-08-17 13:47:54 -07:00
620d1402fe docs: add HttpClientModule import code to services tutorial (#24854)
To be able to copy and paste.

PR Close #24854
2018-08-16 13:51:18 -07:00
36fb4f4fdb docs: reactive forms guide copy edits (#25417)
PR Close #25417
2018-08-16 13:50:51 -07:00
ea83445149 release: cut the v6.1.3 release 2018-08-15 14:28:58 -07:00
1319ff4376 fix(service-worker): Cache-Control: no-cache on assets breaks service worker (#25408)
At the moment `cacheAge` can we undefined when having `Cache-Control` set to `no-cache` due the mapping method in `needToRevalidate`

Closes #25442

PR Close #25408
2018-08-14 16:40:15 -07:00
9c1311c801 docs(core): Correct spelling error in directives docs (#25377)
Link to life-cycle hooks was spelt as "life-cycle hoooks".
PR Close #25377
2018-08-14 16:39:33 -07:00
2ce93482b9 docs: enable debug tools with current versions of Angular (#25361)
Updating code snippet in docs that shows how to enable debug tools.
PR Close #25361
2018-08-14 16:38:26 -07:00
ed2a47f822 build(bazel): update to rules_typescript 0.16.0 & update to tagged rules_webtesting 0.2.1 (#25486)
PR Close #25486
2018-08-14 16:37:48 -07:00
cdee9add01 build(docs-infra): remove stability labels from API docs (#25453)
PR Close #25453
2018-08-14 13:17:15 -07:00
2f85b1691a build(docs-infra): clean up API package template (#25453)
PR Close #25453
2018-08-14 13:17:15 -07:00
bf441e8b9e build(docs-infra): include packages in API template breadcrumbs (#25453)
PR Close #25453
2018-08-14 13:17:15 -07:00
1c86e9b3b2 build(docs-infra): change breadcrumb delimiter to > (#25453)
PR Close #25453
2018-08-14 13:17:15 -07:00
9d6e869899 docs: add api doc for programmatic animation classes (#24668)
PR Close #24668
2018-08-14 13:15:27 -07:00
e906bf4f31 docs: add Accelebrate to resources (#23204)
PR Close #23204
2018-08-14 11:58:04 -07:00
5f08bdf8b9 ci: github robot should enforce that all requested reviews are submitted (#25336)
See docs in the diff for justification.
PR Close #25336
2018-08-13 21:39:05 -07:00
f1ed022a4d docs: fix typo in Architecture overview page (#25438)
PR Close #25438
2018-08-13 21:38:22 -07:00
151e4b9fcc docs: add link to Yarn in README (#24856)
Remove the code markdown. It is not code, it is a name.

PR Close #24856
2018-08-13 21:36:13 -07:00
d0f089a55d docs(aio): add async validation chapter (#25189)
Closes #22881

PR Close #25189
2018-08-10 09:14:25 -07:00
cb05f9bbe9 docs: fix typo in testing guide (closes #25400) (#25418)
PR Close #25418
2018-08-10 09:11:35 -07:00
fda30cb3e3 build: stop printing source-map-support warning (#25339)
PR Close #25339
2018-08-08 19:02:58 -07:00
2951e721df build(bazel): update to rules_nodejs 0.11.2 and latest rules_typescript (#25365) 2018-08-08 13:19:37 -07:00
3449f1e256 docs: copy edit architecture guide (#25328)
PR Close #25328
2018-08-08 13:12:54 -07:00
6480d1b288 docs: make css multiline in styleguide for consistency (#25300)
PR Close #25300
2018-08-08 13:12:35 -07:00
e76211aa32 docs: add ngrx book to the docs (#23389)
PR Close #23389
2018-08-08 13:11:46 -07:00
a16de8f842 style: fix whitespace and indentation in the testing guide (#21669)
PR Close #21669
2018-08-08 13:11:17 -07:00
24f1dd3b81 docs: add docs for fakeAsync test with custom macroTask in aio (#21669)
PR Close #21669
2018-08-08 13:11:17 -07:00
f39551ce7e docs: Clarify breaking change in minor release (#25393)
The breaking change was in an experimental feature. Update to clarify the wording.

PR Close #25393
2018-08-08 13:06:59 -07:00
3beb7116af release: cut the v6.1.2 release 2018-08-08 11:00:23 -07:00
4b1a825efc Revert "build: update Bazel to 0.16 (#25316)" (#25391)
This reverts commit 4eb8ac6de9 because 0.16 is not
widely available yet (e.g. on Mac) and it is blocking the Angular release.

PR Close #25391
2018-08-08 10:52:25 -07:00
01e62551f5 build(bazel): update to rules_nodejs 0.11.2 and latest rules_typescript (#25365)
PR Close #25365
2018-08-07 21:01:46 -07:00
2f23533a25 docs(aio): Angular course in Portuguese #21836 2018-08-07 12:08:47 -07:00
054fbbe8b8 fix: add mappings for ngfactory & ngsummary files to their module names in aot summary resolver (#25335)
PR Close #25335
2018-08-07 11:13:29 -07:00
155d938e04 docs: refining code of tutorial 7 routing (#22151)
Removed the dead code from hero-detail.component.ts

Fixes #21908

PR Close #22151
2018-08-07 11:08:54 -07:00
94a2ac7884 docs: update resources to include UI-jar (#21200)
PR Close #21200
2018-08-07 11:07:40 -07:00
b75a98522a test(upgrade): reduce flaky-ness by increasing timeout (#24937)
PR Close #24937
2018-08-06 14:52:52 -07:00
d7dc1b5e44 refactor(upgrade): improve internal AngularJS typings (#24937)
PR Close #24937
2018-08-06 14:52:52 -07:00
e075ea7ae7 build(upgrade): use correct sources in BUILD.bazel (#24937)
PR Close #24937
2018-08-06 14:52:52 -07:00
415519acd3 docs: update to 2nd edition of Learning Angular (#20934)
PR Close #20934
2018-08-06 13:44:43 -07:00
8cbb836985 docs: clarify heroes example (#21216)
PR Close #21216
2018-08-06 13:44:18 -07:00
8d0f8bd657 docs: fix table in comparing observables guide (#22485)
PR Close #22485
2018-08-06 13:41:16 -07:00
66547d8fd0 docs(core): clarify supported ViewChild selectors (#22784)
PR Close #22784
2018-08-06 13:40:48 -07:00
6e7d5f0925 docs(core): fix tree-shakable spelling (#24057)
PR Close #24057
2018-08-06 13:40:17 -07:00
29dfa5570a docs: standardize spelling of tree-shakable (#24057)
PR Close #24057
2018-08-06 13:40:17 -07:00
0c028a03ec docs: remove code in universal hero detail component (#25215)
This reverts commit e9cc3dad8f39bc8dfabfb708a825f90fcd2ab697.

PR Close #25215
2018-08-06 13:39:24 -07:00
a54c049051 docs: replace npm with yarn in lockfile readme (#25309)
PR Close #25309
2018-08-06 13:38:15 -07:00
40904ce0c4 docs: add missing word in outputs description. (#25330)
PR Close #25330
2018-08-06 13:36:51 -07:00
88f01f5653 docs: fix typo (#25331)
PR Close #25331
2018-08-06 13:36:10 -07:00
c66794c265 docs: several fixes for NPM package guide (#20186)
PR Close #20186
2018-08-06 11:32:32 -07:00
e4acd83541 docs(http): fixed example unit test for error catching (#25306)
The example unit test should test the service when the backend
application is not available, by providing a mock error response.
Although, the test will
fail as the mock response from the server is valid (it does not simulate
a
error response, but valid response with an error status 404).
This merge request fix this issue by replacing MockResponse with
MockError

This PR resolves 19499 issue

PR Close #25306
2018-08-06 11:31:59 -07:00
a57f8a1301 build: update Bazel to 0.16 (#25316)
PR Close #25316
2018-08-06 11:30:25 -07:00
ae9b4e6fa7 fix(router): take base uri into account in setUpLocationSync() (#20244)
Normalize the full URL (including the base uri) before passing it to
`router.navigateByUrl()`.

Fixes #20061

PR Close #20244
2018-08-06 11:11:08 -07:00
478eca31c7 docs(aio): add Made with Angular (#21297)
PR Close #21297
2018-08-06 09:50:16 -07:00
2e1603938c build: skip ivy builds when not publishing (#25299)
PR Close #25299
2018-08-04 14:17:01 -07:00
0c9c2accc2 refactor(bazel): dont rely on language target to downlevel for loop (#24534)
PR Close #24534
2018-08-03 15:55:19 -07:00
0fb41e5ced test(docs-infra): log docs examples e2e spec paths to aid debugging (#25293)
It seems that occasionally the sharding of docs examples e2e tests gets
messed up resulting in some tests not being run. This can cause CI to be
green on a PR, when they shouldn't (because the failing tests didn't run
at all).

It is unclear under what circumstances this happens, so printing the
paths of found e2e specs will help debug the issue when it comes up
again.

PR Close #25293
2018-08-03 15:30:32 -07:00
3f43dbb642 style(common): fix short param names (#23667)
PR Close #23667
2018-08-03 14:09:29 -07:00
5069c06906 docs(common): fix content errors (#23667)
PR Close #23667
2018-08-03 14:09:29 -07:00
58698d7806 release: cut the v6.1.1 release 2018-08-02 14:02:59 -07:00
e26c25a062 Revert "docs: refactor http module import for style guide app.module (#25001)" (#25263)
This reverts commit 88da8f3d52.

PR Close #25263
2018-08-02 09:20:12 -07:00
0a6434b066 test(common): TokenExtractor should extend HttpXsrfTokenExtractor in xsrf spec (#24649)
PR Close #24649
2018-08-02 08:34:15 -07:00
ff3550c304 test(common): remove unused import in xsrf spec (#24649)
PR Close #24649
2018-08-02 08:34:15 -07:00
6d4a14082c docs(docs-infra): adds note according to Symlink problem (#24714)
docs: adds note according to Symlink problem

Closes #24709
docs(docs-infra): adds section "Developing on Windows"


Merge remote-tracking branch 'origin/aioREADME' into aioREADME


docs(docs-infra): adds information about admin rights


docs(docs-infra): adds hint


docs(docs-infra): Change to link


PR Close #24714
2018-08-02 08:33:24 -07:00
9ddf269c2c docs(elements): add section about custom element typings in elements guide (#25219)
PR Close #25219
2018-08-02 08:32:59 -07:00
25a76a1492 docs(elements): add link to full example in elements guide (#25219)
PR Close #25219
2018-08-02 08:32:59 -07:00
8439a6ec2a docs(elements): remove unnecessary whitespace in elements guide (#25219)
PR Close #25219
2018-08-02 08:32:59 -07:00
1ef2eae3aa feat(docs-infra): support sending Google Analytics events (#25042)
PR Close #25042
2018-08-01 17:04:19 -07:00
d5d034a0ff docs: update reactiveconf 2018 in events (#24739)
PR Close #24739
2018-08-01 16:15:18 -07:00
5ca35b3cd2 docs: Update the link to the Jasmine docs (#25175)
Solves #24462.

Also update the http part of the link to to https.

PR Close #25175
2018-08-01 16:12:44 -07:00
0a6a3f3163 ci: update pullapprove groups and add docs (#25257)
With this update to permissions the docs team can easily identify the technical reviewer for a particular doc, which should streamline the reviews.

I also added Jennifer into all groups that contain docs, so that she can approve changes that contain only editorial changes.

Closes #21692

PR Close #25257
2018-08-01 15:53:41 -07:00
3a601382e6 test(upgrade): run tests against AngularJS v1.7.x as well (#25231)
PR Close #25231
2018-08-01 14:10:21 -07:00
7a1fdde69e build(bazel): entry point file couldn't be resolved [ts-api-guardian] (#25052)
* When using `ts-api-guardian` on Windows, the input file can't be found due to wrong normalized path delimiters.

PR Close #25052
2018-08-01 13:29:27 -07:00
cbc2ea1b1a build: update hello_world__closure to google-closure-compiler 20180716.0.0 (#25236)
PR Close #25236
2018-08-01 13:25:40 -07:00
bdf801b0e8 build: revert yarn.lock rxjs version to 6.0.0 (#25236)
PR Close #25236
2018-08-01 13:23:35 -07:00
fe5e8b7177 docs(aio): update Kendo UI description in resource.json (#24845)
PR Close #24845
2018-08-01 10:59:16 -07:00
11f0f98ad8 docs: fix typos and missing word in tutorial (#20764)
PR Close #20764
2018-08-01 10:56:31 -07:00
801b534421 docs(core): remove experimental tag (#24032)
PR Close #24032
2018-08-01 10:56:07 -07:00
0fc83215e2 docs(core): remove experimental tag (#24032)
Remove experimental note on APP_INITIALIZER.

PR Close #24032
2018-08-01 10:56:07 -07:00
3d3a1a4642 docs(aio): add Kevin Yang to GDE resources (#24791)
Add files via upload
PR Close #24791
2018-08-01 10:55:41 -07:00
32a40ba5de docs: refactor http module import for style guide app.module (#25001)
PR Close #25001
2018-08-01 10:55:17 -07:00
045271230d docs: refactor lazy loading modules example (#25071)
PR Close #25071
2018-08-01 10:54:00 -07:00
ec31f6bf9a docs(router): clarify scroll position wording (#25077)
PR Close #25077
2018-08-01 10:53:35 -07:00
4798d77088 docs(core): replace ReflectiveInjector example with Static Injector example (#25162)
PR Close #25162
2018-08-01 10:52:32 -07:00
08c6762039 docs: replace ReflectiveInjector samples with Injector samples (#25162)
PR Close #25162
2018-08-01 10:52:32 -07:00
26516045e7 refactor(animations): do not use short parameter names (#25198)
PR Close #25198
2018-08-01 10:51:58 -07:00
a83b9f7911 docs(changelog): remove reverted feature entry (#25206)
PR Close #25206
2018-08-01 10:51:28 -07:00
1b7c77e49f docs(changelog): remove duplicate entries (#25206)
PR Close #25206
2018-08-01 10:51:28 -07:00
3ab31a4be6 docs: update to account for CLI changes (#25223)
This should help clarify the use of providedIn and correct the documentation where it was showing the use of a now depreciated CLI command flag.

I am openly looking for feedback on this change to figure out the best wording.

PR Close #25223
2018-08-01 10:51:05 -07:00
43dcf77123 build(bazel): fix typo in protractor test target definition (#25235)
PR Close #25235
2018-08-01 10:50:44 -07:00
d4bf2da3bd refactor(core): remove withBody from public testing API (#25171)
PR Close #25171
2018-07-31 15:09:33 -07:00
fa3882845a docs(aio): add short description for entryComponents (#21360)
PR Close #21360
2018-07-31 13:18:36 -07:00
fa59748e00 build: make postinstall script compatible with Windows (#25232)
PR Close #25232
2018-07-31 13:17:55 -07:00
c38ecb3b5b docs(forms): fix incorrect variables naming in the comments (#25150)
PR Close #25150
2018-07-31 11:42:16 -07:00
875efa8492 docs(docs-infra): fix topnav layout for smaller screens (#25181)
PR Close #25181
2018-07-31 11:41:22 -07:00
74964bde99 docs: fix link to "Override component providers" (#24967)
Closes #24966

PR Close #24967
2018-07-30 21:53:21 -07:00
785fb5cc5a docs(aio): add StrongBrew to the trainer list (#24891)
PR Close #24891
2018-07-30 16:48:17 -07:00
26d9f0278b ci: correctly encode quoted params passed as params to curl
Previously the auth token could have been split into three separate args in bash which resulted
in two bogus requests being sent out for each curl call. These requests had to time out before
the real request was made, but without the token.

I couldn't find a better way to quickly fix this without adding some duplication.
2018-07-30 16:46:50 -07:00
22ebd53c17 docs: update bootstrapping and entry component guide to use httpclient (#25178)
PR Close #25178
2018-07-30 16:00:19 -07:00
a972c039c3 docs: fix typo in dependency injection guide (#24972)
PR Close #24972
2018-07-30 15:56:36 -07:00
f5e18029fa docs: refactor pipe example to use the HttpClient (#22741)
PR Close #22741
2018-07-30 14:40:25 -07:00
317c7087c5 build(compiler-cli): update tsickle dependency to support TypeScript 2.9 (#25152)
The original range (`^0.30.0`) does not match `0.32.1`, which enables support for TypeScript 2.9.

Close #25141

PR Close #25152
2018-07-27 11:25:28 -07:00
39abe7b7c1 test: fix typings for DoneFn (#25163)
This also fixes CI tests, which were accidentally broken in #24663.

PR Close #25163
2018-07-27 11:13:33 -07:00
36a7705a44 feat(docs-infra): allow notification bar to show arbitrary content (#25020)
This change generalises the notification bar rendering to allow
more complex content to be displayed.

Now you must provide the full HTML of the notification message
when using `<aio-notification>`.

Also you can control whether clicking the content triggers the
notification to close or not.

This will support the new notification specified in "Other Items : 3" of
[#24140](https://github.com/angular/angular/issues/24140#issuecomment-397480410)

PR Close #25020
2018-07-27 09:29:40 -07:00
50a21885cf style(docs-infra): remove unnecessary call to console.log() (#25020)
PR Close #25020
2018-07-27 09:29:40 -07:00
e86f3d9a49 docs: refactor feature modules example (#25069)
PR Close #25069
2018-07-27 09:28:13 -07:00
738f2961ba docs: Change unnecessary step in ToH-Tutorial (#25059)
PR Close #25059
2018-07-27 09:25:59 -07:00
f2bf8287ba build(bazel): add comment about angular bazel rules API re-export from /index.bzl (#24663)
PR Close #24663
2018-07-26 17:02:21 -07:00
9d5b34e1e7 build(bazel): add comment for patch-types work-around (#24663)
PR Close #24663
2018-07-26 17:02:21 -07:00
d237f4014a build(bazel): show bazel progress in CircleCI to prevent 10m timeout with no output (#24663)
PR Close #24663
2018-07-26 17:02:21 -07:00
8743a9bfd6 build(bazel): use bazel managed node_modules for downstream angular from source build support (#24663)
PR Close #24663
2018-07-26 17:02:21 -07:00
514d03f2d0 docs(router): Removed unneeded trailing text. (#24894)
PR Close #24894
2018-07-26 17:01:03 -07:00
594 changed files with 15304 additions and 48477 deletions

View File

@ -20,6 +20,18 @@ build --announce_rc
# We use this when uploading artifacts after the build finishes
build --symlink_prefix=dist/
# Enable experimental CircleCI bazel remote cache proxy
# See remote cache documentation in /docs/BAZEL.md
build --experimental_remote_spawn_cache --remote_rest_cache=http://localhost:7643
# Prevent unstable environment variables from tainting cache keys
build --experimental_strict_action_env
# Save downloaded repositories such as the go toolchain
# This directory can then be included in the CircleCI cache
# It should save time running the first build
build --experimental_repository_cache=/home/circleci/bazel_repository_cache
# 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 CircleCI "xlarge" class
@ -28,6 +40,3 @@ build --local_resources=14336,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

@ -26,11 +26,6 @@ var_4: &setup-bazel-remote-cache
command: ~/bazel-remote-proxy -backend circleci://
background: true
var_5: &setup_bazel_remote_execution
run:
name: "Setup bazel RBE remote execution"
command: openssl aes-256-cbc -d -in .circleci/gcp_token -k "${CIRCLE_PROJECT_REPONAME}" -out /home/circleci/.gcp_credentials && echo "export GOOGLE_APPLICATION_CREDENTIALS=/home/circleci/.gcp_credentials" >> $BASH_ENV && sudo bash -c "cat .circleci/rbe-bazel.rc >> /etc/bazel.bazelrc"
# Settings common to each job
anchor_1: &job_defaults
working_directory: ~/ng
@ -47,18 +42,19 @@ version: 2
jobs:
lint:
<<: *job_defaults
resource_class: xlarge
steps:
- checkout:
<<: *post_checkout
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
# Check BUILD.bazel formatting before we have a node_modules directory
# Then we don't need any exclude pattern to avoid checking those files
- run: 'yarn buildifier -mode=check ||
- run: 'buildifier -mode=check $(find . -type f \( -name "*.bzl" -or -name BUILD.bazel -or -name BUILD \)) ||
(echo "BUILD files not formatted. Please run ''yarn buildifier''" ; exit 1)'
# Run the skylark linter to check our Bazel rules
- run: 'yarn skylint ||
# deprecated-api is disabled because we use actions.new_file(genfiles_dir)
# which has no replacement, see https://github.com/bazelbuild/bazel/issues/4858
- run: 'find . -type f -name "*.bzl" |
xargs java -jar /usr/local/bin/Skylint_deploy.jar --disable-checks=deprecated-api ||
(echo -e "\n.bzl files have lint errors. Please run ''yarn skylint''"; exit 1)'
- restore_cache:
@ -74,20 +70,22 @@ jobs:
- *define_env_vars
- checkout:
<<: *post_checkout
# See remote cache documentation in /docs/BAZEL.md
- run: .circleci/setup_cache.sh
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- *setup-bazel-remote-cache
- restore_cache:
key: *cache_key
- run: ls /home/circleci/bazel_repository_cache || true
- run: bazel info release
- run: bazel run @nodejs//:yarn
# Use bazel query so that we explicitly ask for all buildable targets to be built as well
# This avoids waiting for the slowest build target to finish before running the first test
# See https://github.com/bazelbuild/bazel/issues/4257
# NOTE: Angular developers should typically just bazel build //packages/... or bazel test //packages/...
# Setup remote execution and run RBE-compatible tests.
- *setup_bazel_remote_execution
- run: bazel query --output=label //... | xargs bazel test --build_tag_filters=-ivy-only --test_tag_filters=-manual,-ivy-only,-local
# Now run RBE incompatible tests locally.
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- run: bazel query --output=label //... | xargs bazel test --build_tag_filters=-ivy-only,local --test_tag_filters=-manual,-ivy-only,local
- run: bazel query --output=label //... | xargs bazel test --build_tag_filters=-ivy-only --test_tag_filters=-manual,-ivy-only
# CircleCI will allow us to go back and view/download these artifacts from past builds.
# Also we can use a service like https://buildsize.org/ to automatically track binary size of these artifacts.
@ -121,10 +119,15 @@ jobs:
- *define_env_vars
- checkout:
<<: *post_checkout
# See remote cache documentation in /docs/BAZEL.md
- run: .circleci/setup_cache.sh
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- *setup-bazel-remote-cache
- restore_cache:
key: *cache_key
- run: bazel run @yarn//:yarn
- *setup_bazel_remote_execution
- run: bazel query --output=label //... | xargs bazel test --define=compile=jit --build_tag_filters=ivy-jit --test_tag_filters=-manual,ivy-jit
test_ivy_aot:
@ -134,10 +137,15 @@ jobs:
- *define_env_vars
- checkout:
<<: *post_checkout
# See remote cache documentation in /docs/BAZEL.md
- run: .circleci/setup_cache.sh
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- *setup-bazel-remote-cache
- restore_cache:
key: *cache_key
- run: bazel run @yarn//:yarn
- *setup_bazel_remote_execution
- run: bazel query --output=label //... | xargs bazel test --define=compile=local --build_tag_filters=ivy-local --test_tag_filters=-manual,ivy-local
# This job should only be run on PR builds, where `CIRCLE_PR_NUMBER` is defined.
@ -187,9 +195,12 @@ jobs:
- *define_env_vars
- checkout:
<<: *post_checkout
# See remote cache documentation in /docs/BAZEL.md
- run: .circleci/setup_cache.sh
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- *setup-bazel-remote-cache
- run: bazel run @nodejs//:yarn
- *setup_bazel_remote_execution
- run: scripts/build-packages-dist.sh
# Save the npm packages from //packages/... for other workflow jobs to read
@ -256,7 +267,11 @@ jobs:
<<: *post_checkout
- restore_cache:
key: *cache_key
- run: xvfb-run --auto-servernum ./aio/scripts/test-production.sh
- run:
name: Run tests against the deployed apps
command: |
source "./scripts/ci/env.sh" print
xvfb-run --auto-servernum ./aio/scripts/test-production.sh $AIO_MIN_PWA_SCORE
workflows:
version: 2
@ -306,4 +321,4 @@ workflows:
notify:
webhooks:
- url: https://ngbuilds.io/circle-build
- url: https://ngbuilds.io/circle-build

Binary file not shown.

View File

@ -1,77 +0,0 @@
# These options are enabled when running on CI with Remote Build Execution.
################################################################
# Toolchain related flags for remote build execution. #
################################################################
# Remote Build Execution requires a strong hash function, such as SHA256.
startup --host_jvm_args=-Dbazel.DigestFunction=SHA256
# Depending on how many machines are in the remote execution instance, setting
# this higher can make builds faster by allowing more jobs to run in parallel.
# Setting it too high can result in jobs that timeout, however, while waiting
# for a remote machine to execute them.
build --jobs=150
# Set several flags related to specifying the platform, toolchain and java
# properties.
# These flags are duplicated rather than imported from (for example)
# %workspace%/configs/ubuntu16_04_clang/1.0/toolchain.bazelrc to make this
# bazelrc a standalone file that can be copied more easily.
# These flags should only be used as is for the rbe-ubuntu16-04 container
# and need to be adapted to work with other toolchain containers.
build --host_javabase=@bazel_toolchains//configs/ubuntu16_04_clang/1.0:jdk8
build --javabase=@bazel_toolchains//configs/ubuntu16_04_clang/1.0:jdk8
build --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_hostjdk8
build --java_toolchain=@bazel_tools//tools/jdk:toolchain_hostjdk8
build --crosstool_top=@bazel_toolchains//configs/ubuntu16_04_clang/1.0/bazel_0.15.0/default:toolchain
build --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1
# Platform flags:
# The toolchain container used for execution is defined in the target indicated
# by "extra_execution_platforms", "host_platform" and "platforms".
# If you are using your own toolchain container, you need to create a platform
# target with "constraint_values" that allow for the toolchain specified with
# "extra_toolchains" to be selected (given constraints defined in
# "exec_compatible_with").
# More about platforms: https://docs.bazel.build/versions/master/platforms.html
build --extra_toolchains=@bazel_toolchains//configs/ubuntu16_04_clang/1.0/bazel_0.15.0/cpp:cc-toolchain-clang-x86_64-default
build --extra_execution_platforms=//tools:rbe_ubuntu1604-angular
build --host_platform=//tools:rbe_ubuntu1604-angular
build --platforms=//tools:rbe_ubuntu1604-angular
# Set various strategies so that all actions execute remotely. Mixing remote
# and local execution will lead to errors unless the toolchain and remote
# machine exactly match the host machine.
build --spawn_strategy=remote
build --strategy=Javac=remote
build --strategy=Closure=remote
build --genrule_strategy=remote
build --define=EXECUTOR=remote
# Enable the remote cache so action results can be shared across machines,
# developers, and workspaces.
build --remote_cache=remotebuildexecution.googleapis.com
# Enable remote execution so actions are performed on the remote systems.
build --remote_executor=remotebuildexecution.googleapis.com
# Remote instance.
build --remote_instance_name=projects/internal-200822/instances/default_instance
# Enable encryption.
build --tls_enabled=true
# Enforce stricter environment rules, which eliminates some non-hermetic
# behavior and therefore improves both the remote cache hit rate and the
# correctness and repeatability of the build.
build --experimental_strict_action_env=true
# Set a higher timeout value, just in case.
build --remote_timeout=3600
# Enable authentication. This will pick up application default credentials by
# default. You can use --auth_credentials=some_file.json to use a service
# account credential instead.
build --auth_enabled=true
# Do not accept remote cache.
build --remote_accept_cached=false

View File

@ -49,12 +49,14 @@ env:
- CI_MODE=browserstack_optional
- CI_MODE=aio_tools_test
- CI_MODE=aio
- CI_MODE=aio_local
- CI_MODE=aio_e2e AIO_SHARD=0
- CI_MODE=aio_e2e AIO_SHARD=1
matrix:
fast_finish: true
allow_failures:
- env: "CI_MODE=aio_local"
- env: "CI_MODE=saucelabs_optional"
- env: "CI_MODE=browserstack_optional"

View File

@ -1,27 +1,11 @@
<a name="7.0.0-rc.0"></a>
# [7.0.0-rc.0](https://github.com/angular/angular/compare/7.0.0-beta.7...7.0.0-rc.0) (2018-09-28)
### Features
* add support for TypeScript 3.1 ([#26151](https://github.com/angular/angular/issues/26151)) ([9993c72](https://github.com/angular/angular/commit/9993c72))
<a name="7.0.0-beta.7"></a>
# [7.0.0-beta.7](https://github.com/angular/angular/compare/7.0.0-beta.6...7.0.0-beta.7) (2018-09-26)
<a name="6.1.10"></a>
## [6.1.10](https://github.com/angular/angular/compare/6.1.9...6.1.10) (2018-10-10)
### Bug Fixes
* **core:** add missing `peerDependency ` to `[@angular](https://github.com/angular)/compiler` ([#26033](https://github.com/angular/angular/issues/26033)) ([549de1e](https://github.com/angular/angular/commit/549de1e)), closes [/github.com/angular/angular/commit/919f42fea1df4b9e38b7d688aef5f2de668e9d3e#diff-58563046c4439699f2e6a89187099a54](https://github.com//github.com/angular/angular/commit/919f42fea1df4b9e38b7d688aef5f2de668e9d3e/issues/diff-58563046c4439699f2e6a89187099a54)
* **service-worker:** do not blow up when caches are unwritable ([#26042](https://github.com/angular/angular/issues/26042)) ([2bd767c](https://github.com/angular/angular/commit/2bd767c))
### Features
* **compiler-cli:** add support to extend `angularCompilerOptions` ([#22717](https://github.com/angular/angular/issues/22717)) ([d7e5bbf](https://github.com/angular/angular/commit/d7e5bbf)), closes [#22684](https://github.com/angular/angular/issues/22684)
* **platform-server:** update domino to v2.1.0 ([#25564](https://github.com/angular/angular/issues/25564)) ([3fb0da2](https://github.com/angular/angular/commit/3fb0da2))
* **platform-browser:** fix [#22155](https://github.com/angular/angular/issues/22155), destroy hammer manager when `HammerInstance.off()` is run ([#22156](https://github.com/angular/angular/issues/22156)) ([3b4d9dc](https://github.com/angular/angular/commit/3b4d9dc))
* **upgrade:** properly destroy upgraded component elements and descendants ([#26209](https://github.com/angular/angular/issues/26209)) ([623adbb](https://github.com/angular/angular/commit/623adbb)), closes [#26208](https://github.com/angular/angular/issues/26208)
@ -35,57 +19,24 @@
<a name="7.0.0-beta.6"></a>
# [7.0.0-beta.6](https://github.com/angular/angular/compare/7.0.0-beta.5...7.0.0-beta.6) (2018-09-19)
<a name="6.1.8"></a>
## [6.1.8](https://github.com/angular/angular/compare/6.1.7...6.1.8) (2018-09-19)
### Bug Fixes
* **bazel:** specify the package and lock files using the workspace ([#25694](https://github.com/angular/angular/issues/25694)) ([ddc1335](https://github.com/angular/angular/commit/ddc1335))
* **common:** register locale data for all equivalent closure locales ([#25867](https://github.com/angular/angular/issues/25867)) ([d83f9d4](https://github.com/angular/angular/commit/d83f9d4))
* **compiler:** Fix look up of entryComponents in AOT Summaries ([#24892](https://github.com/angular/angular/issues/24892)) ([00d3666](https://github.com/angular/angular/commit/00d3666))
* **ivy:** add [@nocollapse](https://github.com/nocollapse) when writing closure-annotated code ([#25775](https://github.com/angular/angular/issues/25775)) ([a0c4b2d](https://github.com/angular/angular/commit/a0c4b2d))
* **ivy:** don't accidently read the inherited definition ([#25736](https://github.com/angular/angular/issues/25736)) ([d5bd86a](https://github.com/angular/angular/commit/d5bd86a)), closes [#24011](https://github.com/angular/angular/issues/24011) [#25026](https://github.com/angular/angular/issues/25026)
* **ivy:** ensure Ivy *Ref classes derive from view engine equivalents ([#25775](https://github.com/angular/angular/issues/25775)) ([a9099e8](https://github.com/angular/angular/commit/a9099e8))
* **ivy:** events should not mark views dirty by default ([#25969](https://github.com/angular/angular/issues/25969)) ([5653874](https://github.com/angular/angular/commit/5653874))
* **ivy:** ngcc should compile entry-points in the correct order ([#25862](https://github.com/angular/angular/issues/25862)) ([9b1bb37](https://github.com/angular/angular/commit/9b1bb37))
* **ivy:** use proper sanitizer names ([#25817](https://github.com/angular/angular/issues/25817)) ([21009b0](https://github.com/angular/angular/commit/21009b0)), closes [#25816](https://github.com/angular/angular/issues/25816)
* **router:** mount correct component if router outlet was not instantiated and if using a route reuse strategy ([#25313](https://github.com/angular/angular/issues/25313)) ([#25314](https://github.com/angular/angular/issues/25314)) ([8dc2b11](https://github.com/angular/angular/commit/8dc2b11))
* **bazel:** allow compile_strategy to be (privately) imported ([#25080](https://github.com/angular/angular/issues/25080)) ([2d0e642](https://github.com/angular/angular/commit/2d0e642))
* **bazel:** correct type concatenated to devmode_js ([#25467](https://github.com/angular/angular/issues/25467)) ([91dd160](https://github.com/angular/angular/commit/91dd160))
* **bazel:** move bazel managed runtime deps for downstream usage ([#25690](https://github.com/angular/angular/issues/25690)) ([48d7f4e](https://github.com/angular/angular/commit/48d7f4e))
* **bazel:** specify the package and lock files using the workspace ([#25694](https://github.com/angular/angular/issues/25694)) ([678b420](https://github.com/angular/angular/commit/678b420))
* **compiler:** Fix look up of entryComponents in AOT Summaries ([#24892](https://github.com/angular/angular/issues/24892)) ([a31cfc5](https://github.com/angular/angular/commit/a31cfc5))
* **router:** mount correct component if router outlet was not instantiated and if using a route reuse strategy ([#25313](https://github.com/angular/angular/issues/25313)) ([#25314](https://github.com/angular/angular/issues/25314)) ([e117b1f](https://github.com/angular/angular/commit/e117b1f))
### Features
* **bazel:** add additional parameters to `ts_api_guardian_test` def ([#25694](https://github.com/angular/angular/issues/25694)) ([2a21ca0](https://github.com/angular/angular/commit/2a21ca0))
* **ivy:** allow combined context discovery for components, directives and elements ([#25754](https://github.com/angular/angular/issues/25754)) ([62be8c2](https://github.com/angular/angular/commit/62be8c2))
* **ivy:** patch animations into metadata ([#25828](https://github.com/angular/angular/issues/25828)) ([d2dfd48](https://github.com/angular/angular/commit/d2dfd48))
* **ivy:** resolve references to vars in .d.ts files ([#25775](https://github.com/angular/angular/issues/25775)) ([96d6b79](https://github.com/angular/angular/commit/96d6b79))
* **ivy:** support animation [@triggers](https://github.com/triggers) in templates ([#25849](https://github.com/angular/angular/issues/25849)) ([e363388](https://github.com/angular/angular/commit/e363388))
* **ivy:** support bootstrap in ngModuleDef ([#25775](https://github.com/angular/angular/issues/25775)) ([13ccdfd](https://github.com/angular/angular/commit/13ccdfd))
<a name="7.0.0-beta.5"></a>
# [7.0.0-beta.5](https://github.com/angular/angular/compare/7.0.0-beta.4...7.0.0-beta.5) (2018-09-06)
### Bug Fixes
* **bazel:** protractor rule should include *.e2e-spec.js ([#25701](https://github.com/angular/angular/issues/25701)) ([3809e0f](https://github.com/angular/angular/commit/3809e0f))
* **benchpress:** Use performance.mark() instead of console.time() ([#24114](https://github.com/angular/angular/issues/24114)) ([06d0400](https://github.com/angular/angular/commit/06d0400))
* **compiler:** add hostVars and support pure functions in host bindings ([#25626](https://github.com/angular/angular/issues/25626)) ([b424b31](https://github.com/angular/angular/commit/b424b31))
* **core:** do not clear element content when using shadow dom ([#24861](https://github.com/angular/angular/issues/24861)) ([6e828bb](https://github.com/angular/angular/commit/6e828bb))
* **core:** size regression with closure compiler ([#25531](https://github.com/angular/angular/issues/25531)) ([1f59f2f](https://github.com/angular/angular/commit/1f59f2f))
* **elements:** add compiler dependency ([#24861](https://github.com/angular/angular/issues/24861)) ([6143da6](https://github.com/angular/angular/commit/6143da6))
* **elements:** add compiler to integration ([#24861](https://github.com/angular/angular/issues/24861)) ([a080ffc](https://github.com/angular/angular/commit/a080ffc))
* **elements:** strict null checks ([#24861](https://github.com/angular/angular/issues/24861)) ([a8210d0](https://github.com/angular/angular/commit/a8210d0))
* **upgrade:** trigger `$destroy` event on upgraded component element ([#25357](https://github.com/angular/angular/issues/25357)) ([2a672a9](https://github.com/angular/angular/commit/2a672a9)), closes [#25334](https://github.com/angular/angular/issues/25334)
### Features
* **elements:** enable Shadow DOM v1 and slots ([#24861](https://github.com/angular/angular/issues/24861)) ([c9844a2](https://github.com/angular/angular/commit/c9844a2))
* **router:** warn if navigation triggered outside Angular zone ([#24959](https://github.com/angular/angular/issues/24959)) ([010e35d](https://github.com/angular/angular/commit/010e35d)), closes [#15770](https://github.com/angular/angular/issues/15770) [#15946](https://github.com/angular/angular/issues/15946) [#24728](https://github.com/angular/angular/issues/24728)
* **bazel:** add additional parameters to `ts_api_guardian_test` def ([#25694](https://github.com/angular/angular/issues/25694)) ([97ae7ae](https://github.com/angular/angular/commit/97ae7ae))
* **ivy:** enable .ngfactory.js generation in g3 only ([#25392](https://github.com/angular/angular/issues/25392)) ([1c44b71](https://github.com/angular/angular/commit/1c44b71))
@ -102,18 +53,6 @@
* **router:** warn if navigation triggered outside Angular zone ([#24959](https://github.com/angular/angular/issues/24959)) ([23a96dc](https://github.com/angular/angular/commit/23a96dc)), closes [#15770](https://github.com/angular/angular/issues/15770) [#15946](https://github.com/angular/angular/issues/15946) [#24728](https://github.com/angular/angular/issues/24728)
<a name="7.0.0-beta.4"></a>
# [7.0.0-beta.4](https://github.com/angular/angular/compare/7.0.0-beta.3...7.0.0-beta.4) (2018-08-29)
### Bug Fixes
* **bazel:** Cache fileNameToModuleName lookups ([#25731](https://github.com/angular/angular/issues/25731)) ([f394ba0](https://github.com/angular/angular/commit/f394ba0))
* **bazel:** move bazel managed runtime deps for downstream usage ([#25690](https://github.com/angular/angular/issues/25690)) ([6ed7993](https://github.com/angular/angular/commit/6ed7993))
* **bazel:** only lookup amd module-name tags in .d.ts files ([#25710](https://github.com/angular/angular/issues/25710)) ([42072c4](https://github.com/angular/angular/commit/42072c4))
* **compiler:** update compiler to generate new slot allocations ([#25607](https://github.com/angular/angular/issues/25607)) ([27e2039](https://github.com/angular/angular/commit/27e2039))
<a name="6.1.6"></a>
## [6.1.6](https://github.com/angular/angular/compare/6.1.5...6.1.6) (2018-08-29)
@ -127,16 +66,6 @@
Note: the 6.1.5 release on npm accidentally glitched-out midway, so we cut 6.1.6 instead. sorry! :-)
<a name="7.0.0-beta.3"></a>
# [7.0.0-beta.3](https://github.com/angular/angular/compare/7.0.0-beta.2...7.0.0-beta.3) (2018-08-22)
### Features
* **router:** add UrlSegment[] to CanLoad interface ([#13127](https://github.com/angular/angular/issues/13127)) ([07d8d39](https://github.com/angular/angular/commit/07d8d39)), closes [#12411](https://github.com/angular/angular/issues/12411)
<a name="6.1.4"></a>
## [6.1.4](https://github.com/angular/angular/compare/6.1.3...6.1.4) (2018-08-22)
@ -147,15 +76,6 @@ Note: the 6.1.5 release on npm accidentally glitched-out midway, so we cut 6.1.6
<a name="7.0.0-beta.2"></a>
# [7.0.0-beta.2](https://github.com/angular/angular/compare/7.0.0-beta.1...7.0.0-beta.2) (2018-08-15)
### Bug Fixes
* **bazel:** correct type concatenated to devmode_js ([#25467](https://github.com/angular/angular/issues/25467)) ([fb2c524](https://github.com/angular/angular/commit/fb2c524))
<a name="6.1.3"></a>
## [6.1.3](https://github.com/angular/angular/compare/6.1.2...6.1.3) (2018-08-15)
@ -166,24 +86,6 @@ Note: the 6.1.5 release on npm accidentally glitched-out midway, so we cut 6.1.6
<a name="7.0.0-beta.1"></a>
# [7.0.0-beta.1](https://github.com/angular/angular/compare/7.0.0-beta.0...7.0.0-beta.1) (2018-08-08)
### Bug Fixes
* **compiler-cli:** use the oldProgram option in watch mode ([#21364](https://github.com/angular/angular/issues/21364)) ([c6e5b97](https://github.com/angular/angular/commit/c6e5b97)), closes [#21361](https://github.com/angular/angular/issues/21361)
* **core:** In Testability.whenStable update callback, pass more complete ([#25010](https://github.com/angular/angular/issues/25010)) ([16c03c0](https://github.com/angular/angular/commit/16c03c0))
* add mappings for ngfactory & ngsummary files to their module names in aot summary resolver ([#25335](https://github.com/angular/angular/issues/25335)) ([02e201a](https://github.com/angular/angular/commit/02e201a))
* **router:** take base uri into account in `setUpLocationSync()` ([#20244](https://github.com/angular/angular/issues/20244)) ([ba1e25f](https://github.com/angular/angular/commit/ba1e25f)), closes [#20061](https://github.com/angular/angular/issues/20061)
### Features
* **core:** add DoBootstrap interface. ([#24558](https://github.com/angular/angular/issues/24558)) ([732026c](https://github.com/angular/angular/commit/732026c)), closes [#24557](https://github.com/angular/angular/issues/24557)
<a name="6.1.2"></a>
## [6.1.2](https://github.com/angular/angular/compare/6.1.1...6.1.2) (2018-08-08)
@ -194,26 +96,13 @@ Note: the 6.1.5 release on npm accidentally glitched-out midway, so we cut 6.1.6
* add mappings for ngfactory & ngsummary files to their module names in aot summary resolver ([#25335](https://github.com/angular/angular/issues/25335)) ([054fbbe](https://github.com/angular/angular/commit/054fbbe))
<a name="7.0.0-beta.0"></a>
# [7.0.0-beta.0](https://github.com/angular/angular/compare/6.1.0...7.0.0-beta.0) (2018-08-02)
### Bug Fixes
* **bazel:** allow compile_strategy to be (privately) imported ([#25080](https://github.com/angular/angular/issues/25080)) ([0d1d589](https://github.com/angular/angular/commit/0d1d589))
* **compiler:** update compiler to flatten nested template fns ([#24943](https://github.com/angular/angular/issues/24943)) ([fe14f18](https://github.com/angular/angular/commit/fe14f18))
* **compiler-cli:** correct realPath to realpath. ([#25023](https://github.com/angular/angular/issues/25023)) ([01e6dab](https://github.com/angular/angular/commit/01e6dab))
* **core:** throw error message when @Output not initialized ([#19116](https://github.com/angular/angular/issues/19116)) ([adf510f](https://github.com/angular/angular/commit/adf510f)), closes [#3664](https://github.com/angular/angular/issues/3664)
### Features
* **compiler:** add "original" placeholder value on extracted XMB ([#25079](https://github.com/angular/angular/issues/25079)) ([e99d860](https://github.com/angular/angular/commit/e99d860))
<a name="6.1.1"></a>
## [6.1.1](https://github.com/angular/angular/compare/6.1.0...6.1.1) (2018-08-02)
### Bug Fixes
* **compiler-cli:** correct tsickle dependency version to fix typescript 2.9 compatibility ([fec29fa](https://github.com/angular/angular/commit/317c7087c56b72aa74cd6d6a8f719e6e7fec29fa))

View File

@ -71,6 +71,8 @@ Before you submit your Pull Request (PR) consider the following guidelines:
1. Search [GitHub](https://github.com/angular/angular/pulls) for an open or closed PR
that relates to your submission. You don't want to duplicate effort.
1. Be sure that an issue describes the problem you're fixing, or documents the design for the feature you'd like to add.
Discussing the design up front helps to ensure that we're ready to accept your work.
1. Please sign our [Contributor License Agreement (CLA)](#cla) before sending PRs.
We cannot accept code without this. Make sure you sign with the primary email address of the Git identity that has been granted access to the Angular repository.
1. Fork the angular/angular repo.

View File

@ -5,30 +5,28 @@ workspace(name = "angular")
#
http_archive(
name = "build_bazel_rules_typescript",
sha256 = "1626ee2cc9770af6950bfc77dffa027f9aedf330fe2ea2ee7e504428927bd95d",
strip_prefix = "rules_typescript-0.17.0",
url = "https://github.com/bazelbuild/rules_typescript/archive/0.17.0.zip",
strip_prefix = "rules_typescript-0.17.0",
sha256 = "1626ee2cc9770af6950bfc77dffa027f9aedf330fe2ea2ee7e504428927bd95d",
)
load("@build_bazel_rules_typescript//:package.bzl", "rules_typescript_dependencies")
rules_typescript_dependencies()
http_archive(
name = "bazel_toolchains",
sha256 = "c3b08805602cd1d2b67ebe96407c1e8c6ed3d4ce55236ae2efe2f1948f38168d",
strip_prefix = "bazel-toolchains-5124557861ebf4c0b67f98180bff1f8551e0b421",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/5124557861ebf4c0b67f98180bff1f8551e0b421.tar.gz",
"https://github.com/bazelbuild/bazel-toolchains/archive/5124557861ebf4c0b67f98180bff1f8551e0b421.tar.gz",
],
name = "bazel_toolchains",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/5124557861ebf4c0b67f98180bff1f8551e0b421.tar.gz",
"https://github.com/bazelbuild/bazel-toolchains/archive/5124557861ebf4c0b67f98180bff1f8551e0b421.tar.gz",
],
strip_prefix = "bazel-toolchains-5124557861ebf4c0b67f98180bff1f8551e0b421",
sha256 = "c3b08805602cd1d2b67ebe96407c1e8c6ed3d4ce55236ae2efe2f1948f38168d",
)
http_archive(
name = "io_bazel_rules_sass",
sha256 = "dbe9fb97d5a7833b2a733eebc78c9c1e3880f676ac8af16e58ccf2139cbcad03",
strip_prefix = "rules_sass-1.11.0",
url = "https://github.com/bazelbuild/rules_sass/archive/1.11.0.zip",
strip_prefix = "rules_sass-1.11.0",
sha256 = "dbe9fb97d5a7833b2a733eebc78c9c1e3880f676ac8af16e58ccf2139cbcad03",
)
# This commit matches the version of buildifier in angular/ngcontainer
@ -38,25 +36,25 @@ BAZEL_BUILDTOOLS_VERSION = "49a6c199e3fbf5d94534b2771868677d3f9c6de9"
http_archive(
name = "com_github_bazelbuild_buildtools",
sha256 = "edf39af5fc257521e4af4c40829fffe8fba6d0ebff9f4dd69a6f8f1223ae047b",
strip_prefix = "buildtools-%s" % BAZEL_BUILDTOOLS_VERSION,
url = "https://github.com/bazelbuild/buildtools/archive/%s.zip" % BAZEL_BUILDTOOLS_VERSION,
strip_prefix = "buildtools-%s" % BAZEL_BUILDTOOLS_VERSION,
sha256 = "edf39af5fc257521e4af4c40829fffe8fba6d0ebff9f4dd69a6f8f1223ae047b",
)
# Fetching the Bazel source code allows us to compile the Skylark linter
http_archive(
name = "io_bazel",
sha256 = "ace8cced3b21e64a8fdad68508e9b0644201ec848ad583651719841d567fc66d",
strip_prefix = "bazel-0.17.1",
url = "https://github.com/bazelbuild/bazel/archive/0.17.1.zip",
strip_prefix = "bazel-0.17.1",
sha256 = "ace8cced3b21e64a8fdad68508e9b0644201ec848ad583651719841d567fc66d",
)
http_archive(
name = "io_bazel_skydoc",
sha256 = "7bfb5545f59792a2745f2523b9eef363f9c3e7274791c030885e7069f8116016",
strip_prefix = "skydoc-fe2e9f888d28e567fef62ec9d4a93c425526d701",
# TODO: switch to upstream when https://github.com/bazelbuild/skydoc/pull/103 is merged
url = "https://github.com/alexeagle/skydoc/archive/fe2e9f888d28e567fef62ec9d4a93c425526d701.zip",
strip_prefix = "skydoc-fe2e9f888d28e567fef62ec9d4a93c425526d701",
sha256 = "7bfb5545f59792a2745f2523b9eef363f9c3e7274791c030885e7069f8116016",
)
# We have a source dependency on the Devkit repository, because it's built with
@ -67,16 +65,16 @@ http_archive(
# ts_library rules in the devkit repository.
http_archive(
name = "angular_cli",
sha256 = "8cf320ea58c321e103f39087376feea502f20eaf79c61a4fdb05c7286c8684fd",
strip_prefix = "angular-cli-6.1.0-rc.0",
url = "https://github.com/angular/angular-cli/archive/v6.1.0-rc.0.zip",
strip_prefix = "angular-cli-6.1.0-rc.0",
sha256 = "8cf320ea58c321e103f39087376feea502f20eaf79c61a4fdb05c7286c8684fd",
)
http_archive(
name = "org_brotli",
sha256 = "774b893a0700b0692a76e2e5b7e7610dbbe330ffbe3fe864b4b52ca718061d5a",
strip_prefix = "brotli-1.0.5",
url = "https://github.com/google/brotli/archive/v1.0.5.zip",
strip_prefix = "brotli-1.0.5",
sha256 = "774b893a0700b0692a76e2e5b7e7610dbbe330ffbe3fe864b4b52ca718061d5a",
)
#
@ -106,24 +104,21 @@ If you are on a Mac and using Homebrew, there is a breaking change to the instal
See https://blog.bazel.build/2018/08/22/bazel-homebrew.html
""")
node_repositories(
node_version = "10.9.0",
package_json = ["//:package.json"],
preserve_symlinks = True,
node_version = "10.9.0",
yarn_version = "1.9.2",
)
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
go_rules_dependencies()
go_register_toolchains()
load("@io_bazel_rules_webtesting//web:repositories.bzl", "browser_repositories", "web_test_repositories")
web_test_repositories()
browser_repositories(
chromium = True,
firefox = True,
@ -141,20 +136,7 @@ ng_setup_workspace()
# Skylark documentation generation
load("@io_bazel_rules_sass//sass:sass_repositories.bzl", "sass_repositories")
sass_repositories()
load("@io_bazel_skydoc//skylark:skylark.bzl", "skydoc_repositories")
skydoc_repositories()
##################################
# Prevent Bazel from trying to build rxjs under angular devkit
local_repository(
name = "rxjs_ignore_nested_1",
path = "node_modules/@angular-devkit/core/node_modules/rxjs/src",
)
local_repository(
name = "rxjs_ignore_nested_2",
path = "node_modules/@angular-devkit/schematics/node_modules/rxjs/src",
)

View File

@ -36,6 +36,11 @@ server {
access_log {{$AIO_NGINX_LOGS_DIR}}/access.log;
error_log {{$AIO_NGINX_LOGS_DIR}}/error.log;
error_page 404 /404.html;
location "=/404.html" {
internal;
}
location "~/[^/]+\.[^/]+$" {
try_files $uri $uri/ =404;
}

View File

@ -46,7 +46,7 @@
"@types/shelljs": "^0.8.0",
"@types/supertest": "^2.0.5",
"nodemon": "^1.18.3",
"npm-run-all": "^4.1.3",
"npm-run-all": "^4.1.5",
"supertest": "^3.1.0",
"tslint": "^5.11.0",
"tslint-jasmine-noSkipOrFocus": "^1.0.9",

View File

@ -129,7 +129,7 @@ ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
ansi-styles@^3.2.0, ansi-styles@^3.2.1:
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
dependencies:
@ -384,7 +384,7 @@ chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0:
chalk@^2.0.1, chalk@^2.3.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
dependencies:
@ -392,6 +392,15 @@ chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chalk@^2.4.1:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
dependencies:
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
check-error@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
@ -532,9 +541,10 @@ cross-spawn@^5.0.1:
shebang-command "^1.2.0"
which "^1.2.9"
cross-spawn@^6.0.4:
cross-spawn@^6.0.5:
version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
dependencies:
nice-try "^1.0.4"
path-key "^2.0.1"
@ -1630,16 +1640,17 @@ npm-packlist@^1.1.6:
ignore-walk "^3.0.1"
npm-bundled "^1.0.1"
npm-run-all@^4.1.3:
version "4.1.3"
resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.3.tgz#49f15b55a66bb4101664ce270cb18e7103f8f185"
npm-run-all@^4.1.5:
version "4.1.5"
resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba"
integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==
dependencies:
ansi-styles "^3.2.0"
chalk "^2.1.0"
cross-spawn "^6.0.4"
ansi-styles "^3.2.1"
chalk "^2.4.1"
cross-spawn "^6.0.5"
memorystream "^0.3.1"
minimatch "^3.0.4"
ps-tree "^1.1.0"
pidtree "^0.3.0"
read-pkg "^3.0.0"
shell-quote "^1.6.1"
string.prototype.padend "^3.0.0"
@ -1786,6 +1797,11 @@ pause-stream@0.0.11:
dependencies:
through "~2.3"
pidtree@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.0.tgz#f6fada10fccc9f99bf50e90d0b23d72c9ebc2e6b"
integrity sha512-9CT4NFlDcosssyg8KVFltgokyKZIFjoBxw8CTGy+5F38Y1eQWrt8tRayiUOXE+zVKQnYu5BR8JjCtvK3BcnBhg==
pify@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"

View File

@ -1 +0,0 @@
yarn.lock

View File

@ -1,5 +0,0 @@
{
"dependencies": {
"@angular/cli": "https://github.com/angular/cli-builds#master"
}
}

View File

@ -1,83 +0,0 @@
<h1 class="no-toc">CLI Command Reference</h1>
The Angular CLI is a command-line tool that you use to initialize, develop, scaffold, and maintain Angular applications.
## Getting Started
### Installing Angular CLI
The current version of Angular CLI is 6.x.
* Both the CLI and the projects that you generate with the tool have dependencies that require Node 8.9 or higher, together with NPM 5.5.1 or higher.
* Install the CLI using npm:
`npm install -g @angular/cli`
* The CLI is an open-source tool:
https://github.com/angular/angular-cli/tree/master/packages/angular/cli
For details about changes between versions, and information about updating from previous releases, see the Releases tab on GitHub.
### Basic workflow
Invoke the tool on the command line through the ng executable. Online help is available on the command line:
```
> ng help Lists commands with short descriptions
> ng <command> --help Lists options for a command.
```
To create, build, and serve a new, basic Angular project on a development server, use the following commands:
```
cd <parent of new workspace>
ng new my-project
cd my-project
ng serve
```
In your browser, open http://localhost:4200/ to see the new app run.
### Workspaces and project files
Angular 6 introduced the workspace directory structure for Angular apps. A workspace defines a project. A project can contain multiple apps, as well as libraries that can be used in any of the apps.
Some commands (such as build) must be executed from within a workspace folder, and others (such as new) must be executed from outside any workspace. This requirement is called out in the description of each command where it applies.The `new` command creates a [workspace](guide/glossary#workspace) to contain [projects](guide/glossary#project). A project can be an app or a library, and a workspace can contain multiple apps and libraries.
A newly generated app project contains the source files for a root module, with a root component and template, which you can edit directly, or add to and modify using CLI commands. Use the generate command to add new files for additional components and services, and code for new pipes, directives, and so on.
* Commands such as `add` and `generate`, that create or operate on apps and libraries, must be executed from within a workspace folder.
* Apps in a workspace can use libraries in the same workspace.
* Each project has a `src` folder that contains the logic, data, and assets.
See an example of the [file structure](guide/quickstart#project-file-review) in [Getting Started](guide/quickstart).
When you use the `serve` command to build an app, the server automatically rebuilds the app and reloads the page when you change any of the source files.
### Configuring the CLI
Configuration files let you customize your project. The CLI configuration file, angular.json, is created at the top level of the project folder. This is where you can set CLI defaults for your project, and specify which files to include when the CLI builds the project.
The CLI config command lets you set and retrieve configuration values from the command line, or you can edit the angular.json file directly.
* See the complete schema for angular.json.
* Learn more about configuration options for Angular (link to new guide?)
### Command options and arguments
All commands and some options have aliases, as listed in the descriptions. Option names are prefixed with a double dash (--), but arguments and option aliases are not.
Typically, the name of a generated artifact can be given as an argument to the command or specified with the --name option. Most commands have additional options.
Command syntax is shown as follows:
```
ng commandNameOrAlias <arg> [options]
```
Options take either string or Boolean arguments. Defaults are shown in bold for Boolean or enumerated values, and are given with the description. For example:
```
--optionNameOrAlias=<filename>
--optionNameOrAlias=true|false
--optionNameOrAlias=allowedValue1|allowedValue2|allowedValue3
```
Boolean options can also be expressed with a prefix `no-` to indicate a value of false. For example, `--no-prod` is equivalent to `--prod=false`.

View File

@ -4,7 +4,7 @@ import { Observable, of } from 'rxjs';
// #docregion observer
// Create simple observable that emits three values
const myObservable = Observable.of(1, 2, 3);
const myObservable = of(1, 2, 3);
// Create observer object
const myObserver = {

View File

@ -1,8 +1,7 @@
// tslint:disable-next-line:no-unused-variable
import { async, fakeAsync, tick } from '@angular/core/testing';
import { of } from 'rxjs';
import { delay } from 'rxjs/operators';
import { interval, of } from 'rxjs';
import { delay, take } from 'rxjs/operators';
describe('Angular async helper', () => {
let actuallyDone = false;
@ -21,49 +20,120 @@ describe('Angular async helper', () => {
});
it('should run async test with task',
async(() => { setTimeout(() => { actuallyDone = true; }, 0); }));
async(() => { setTimeout(() => { actuallyDone = true; }, 0); }));
it('should run async test with task', async(() => {
const id = setInterval(() => {
actuallyDone = true;
clearInterval(id);
}, 100);
}));
it('should run async test with successful promise', async(() => {
const p = new Promise(resolve => { setTimeout(resolve, 10); });
p.then(() => { actuallyDone = true; });
}));
const p = new Promise(resolve => { setTimeout(resolve, 10); });
p.then(() => { actuallyDone = true; });
}));
it('should run async test with failed promise', async(() => {
const p = new Promise((resolve, reject) => { setTimeout(reject, 10); });
p.catch(() => { actuallyDone = true; });
}));
const p = new Promise((resolve, reject) => { setTimeout(reject, 10); });
p.catch(() => { actuallyDone = true; });
}));
// Use done. Cannot use setInterval with async or fakeAsync
// See https://github.com/angular/angular/issues/10127
// Use done. Can also use async or fakeAsync.
it('should run async test with successful delayed Observable', (done: DoneFn) => {
const source = of(true).pipe(delay(10));
source.subscribe(
val => actuallyDone = true,
err => fail(err),
done
);
const source = of (true).pipe(delay(10));
source.subscribe(val => actuallyDone = true, err => fail(err), done);
});
// Cannot use setInterval from within an async zone test
// See https://github.com/angular/angular/issues/10127
// xit('should run async test with successful delayed Observable', async(() => {
// const source = of(true).pipe(delay(10));
// source.subscribe(
// val => actuallyDone = true,
// err => fail(err)
// );
// }));
// #docregion fake-async-test-tick
it('should run timeout callback with delay after call tick with millis', fakeAsync(() => {
let called = false;
setTimeout(() => { called = true; }, 100);
tick(100);
expect(called).toBe(true);
}));
// #enddocregion fake-async-test-tick
// // Fail message: Error: 1 periodic timer(s) still in the queue
// // See https://github.com/angular/angular/issues/10127
// xit('should run async test with successful delayed Observable', fakeAsync(() => {
// const source = of(true).pipe(delay(10));
// source.subscribe(
// val => actuallyDone = true,
// err => fail(err)
// );
// #docregion fake-async-test-date
it('should get Date diff correctly in fakeAsync', fakeAsync(() => {
const start = Date.now();
tick(100);
const end = Date.now();
expect(end - start).toBe(100);
}));
// #enddocregion fake-async-test-date
// tick();
// }));
// #docregion fake-async-test-rxjs
it('should get Date diff correctly in fakeAsync with rxjs scheduler', fakeAsync(() => {
// need to add `import 'zone.js/dist/zone-patch-rxjs-fake-async'
// to patch rxjs scheduler
let result = null;
of ('hello').pipe(delay(1000)).subscribe(v => { result = v; });
expect(result).toBeNull();
tick(1000);
expect(result).toBe('hello');
const start = new Date().getTime();
let dateDiff = 0;
interval(1000).pipe(take(2)).subscribe(() => dateDiff = (new Date().getTime() - start));
tick(1000);
expect(dateDiff).toBe(1000);
tick(1000);
expect(dateDiff).toBe(2000);
}));
// #enddocregion fake-async-test-rxjs
// #docregion fake-async-test-clock
describe('use jasmine.clock()', () => {
// need to config __zone_symbol__fakeAsyncPatchLock flag
// before loading zone.js/dist/zone-testing
beforeEach(() => { jasmine.clock().install(); });
afterEach(() => { jasmine.clock().uninstall(); });
it('should auto enter fakeAsync', () => {
// is in fakeAsync now, don't need to call fakeAsync(testFn)
let called = false;
setTimeout(() => { called = true; }, 100);
jasmine.clock().tick(100);
expect(called).toBe(true);
});
});
// #enddocregion fake-async-test-clock
// #docregion async-test-promise-then
describe('test jsonp', () => {
function jsonp(url: string, callback: Function) {
// do a jsonp call which is not zone aware
}
// need to config __zone_symbol__supportWaitUnResolvedChainedPromise flag
// before loading zone.js/dist/zone-testing
it('should wait until promise.then is called', async(() => {
let finished = false;
new Promise((res, rej) => {
jsonp('localhost:8080/jsonp', () => {
// success callback and resolve the promise
finished = true;
res();
});
}).then(() => {
// async will wait until promise.then is called
// if __zone_symbol__supportWaitUnResolvedChainedPromise is set
expect(finished).toBe(true);
});
}));
});
// #enddocregion async-test-promise-then
it('should run async test with successful delayed Observable', async(() => {
const source = of (true).pipe(delay(10));
source.subscribe(val => actuallyDone = true, err => fail(err));
}));
it('should run async test with successful delayed Observable', fakeAsync(() => {
const source = of (true).pipe(delay(10));
source.subscribe(val => actuallyDone = true, err => fail(err));
tick(10);
}));
});

View File

@ -1241,7 +1241,7 @@ Chuck: After reviewing your PR comment I'm still at a loss. See [comment there](
### Non-null type assertion operator
Use the [non-null type assertion operator](guide/template-syntax#non-null-assertion-operator)
to suppress the `Object is possibly 'undefined'` error when it is incovienent to use
to suppress the `Object is possibly 'undefined'` error when it is inconvenient to use
`*ngIf` or when some constraint in the component ensures that the expression is always
non-null when the binding expression is interpolated.
@ -1308,28 +1308,6 @@ Chuck: After reviewing your PR comment I'm still at a loss. See [comment there](
}
```
{@a tsconfig-extends}
## Configuration inheritance with extends
Similar to TypeScript Compiler, Angular Compiler also supports `extends` in the `tsconfig.json` on `angularCompilerOptions`. A tsconfig file can inherit configurations from another file using the `extends` property.
The `extends` is a top level property parallel to `compilerOptions` and `angularCompilerOptions`.
The configuration from the base file are loaded first, then overridden by those in the inheriting config file.
Example:
```json
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"experimentalDecorators": true,
...
},
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"preserveWhitespaces": true,
...
}
}
```
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
@ -1366,7 +1344,7 @@ for example, the content of annotations (such as a component's template), which
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 recommeded to use `--outFile` with
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
@ -1461,7 +1439,7 @@ JavaScript with [JSDoc](http://usejsdoc.org/) comments needed by the
### *annotationsAs*
Use this option to modify how the Angular specific annotations are emitted to improve tree-shaking. Non-Angular
annotations and decorators are unnaffected. Default is `static fields`.
annotations and decorators are unaffected. Default is `static fields`.
<style>
td, th {vertical-align: top}

View File

@ -17,7 +17,7 @@ Here are some key features.
* [Server-side Rendering](guide/universal): Angular Universal generates static application pages on the server through server-side rendering (SSR). This allows you to run your Angular app on the server in order to improve performance and show the first page quickly on mobile and low-powered devices, and also facilitate web crawlers.
* [Service Workers](guide/service-worker-intro): Use a service worker to reduce dependency on the network
significantly improving the use experience.
significantly improving the user experience.
## Domain-specific libraries

View File

@ -15,7 +15,7 @@ There are three kinds of directives in Angular:
1. Attribute directives&mdash;change the appearance or behavior of an element, component, or another directive.
*Components* are the most common of the three directives.
You saw a component for the first time in the [QuickStart](guide/quickstart) guide.
You saw a component for the first time in the [Getting Started](guide/quickstart).
*Structural Directives* change the structure of the view.
Two examples are [NgFor](guide/template-syntax#ngFor) and [NgIf](guide/template-syntax#ngIf).

View File

@ -1,536 +0,0 @@
# Building and serving Angular apps
*intro - here are some topics of interest in the app development cycle*
{@a app-environments}
## Configuring application environments
You can define different named build configurations for your project, such as *stage* and *production*, with different defaults.
Each named build configuration can have defaults for any of the options that apply to the various build targets, such as `build`, `serve`, and `test`. The CLI `build`, `serve`, and `test` commands can then replace files with appropriate versions for your intended target environment.
The following figure shows how a project has multiple build targets, which can be executed using the named configurations that you define.
<figure>
<img src="generated/images/guide/build/build-config-targets.gif" alt="build configurations and targets">
</figure>
### Configure environment-specific defaults
A project's `src/environments/` folder contains the base configuration file, `environment.ts`, which provides a default environment.
You can add override defaults for additional environments, such as production and staging, in target-specific configuration files.
For example:
```
└──myProject/src/environments/
└──environment.ts
└──environment.prod.ts
└──environment.stage.ts
```
The base file `environment.ts`, contains the default environment settings. For example:
<code-example language="none" class="code-shell">
export const environment = {
production: false
};
</code-example>
The `build` command uses this as the build target when no environment is specified.
You can add further variables, either as additional properties on the environment object, or as separate objects.
For example, the following adds a default for a variable to the default environment:
```
export const environment = {
production: false,
apiUrl: 'http://my-api-url'
};
```
You can add target-specific configuration files, such as `environment.prod.ts`.
The following sets content sets default values for the production build target:
```
export const environment = {
production: true
apiUrl: 'http://my-prod-url'
};
```
### Using environment-specific variables in your app
The following application structure configures build targets for production and staging environments:
```
└── src
└── app
├── app.component.html
└── app.component.ts
└── environments
├── environment.prod.ts
├── environment.staging.ts
└── environment.ts
```
To use the environment configurations you have defined, your components must import the original environments file:
```
import { environment } from './../environments/environment';
```
This ensures that the build and serve commands can find the configurations for specific build targets.
The following code in the component file (`app.component.ts`) uses an environment variable defined in the configuration files.
```
import { Component } from '@angular/core';
import { environment } from './../environments/environment';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor() {
console.log(environment.production); // Logs false for default environment
}
title = 'app works!';
}
```
{@a file-replacement}
## Configure target-specific file replacements
The main CLI configuration file, `angular.json`, contains a `fileReplacements` section in the configuration for each build target, which allows you to replace any file with a target-specific version of that file.
This is useful for including target-specific code or variables in a build that targets a specific environment, such as production or staging.
By default no files are replaced.
You can add file replacements for specific build targets.
For example:
```
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
...
```
This means that when you build your production configuration (using `ng build --prod` or `ng build --configuration=production`), the `src/environments/environment.ts` file is replaced with the target-specific version of the file, `src/environments/environment.prod.ts`.
You can add additional configurations as required. To add a staging environment, create a copy of `src/environments/environment.ts` called `src/environments/environment.staging.ts`, then add a `staging` configuration to `angular.json`:
```
"configurations": {
"production": { ... },
"staging": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.staging.ts"
}
]
}
}
```
You can add more configuration options to this target environment as well.
Any option that your build supports can be overridden in a build target configuration.
To build using the staging configuration, run `ng build --configuration=staging`.
You can also configure the `serve` command to use the targeted build configuration if you add it to the "serve:configurations" section of `angular.json`:
```
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "your-project-name:build"
},
"configurations": {
"production": {
"browserTarget": "your-project-name:build:production"
},
"staging": {
"browserTarget": "your-project-name:build:staging"
}
}
},
```
{@a size-budgets}
## Configure size budgets
As applications grow in functionality, they also grow in size.
The CLI allows you to set size thresholds in your configuration to ensure that parts of your application stay within size boundaries that you define.
Define your size boundaries in the CLI configuration file, `angular.json`, in a `budgets` section for each [configured environment](#app-environments).
```
{
...
"configurations": {
"production": {
...
budgets: []
}
}
}
```
You can specify size budgets for the entire app, and for particular parts.
Each budget entry configures a budget of a given type.
Specify size values in the following formats:
* 123 or 123b: Size in bytes
* 123kb: Size in kilobytes
* 123mb: Size in megabytes
* 12%: Percentage of size relative to baseline. (Not valid for baseline values.)
When you configure a budget, the build system warns or reports and error when a given part of the app reaches or exceeds a boundary size that you set.
Each budget entry is a JSON object with the following properties:
<table>
<tr>
<th>Property</th>
<th>Value</th>
</tr>
<tr>
<td>type</td>
<td>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.
* anyScript - The size of any one script.
* any - The size of any file.
</td>
</tr>
<tr>
<td>name</td>
<td>
The name of the bundle (for `type=bundle`).
</td>
</tr>
<tr>
<td>baseline</td>
<td>An absolute baseline size for percentage values. </td>
</tr>
<tr>
<td>maximumWarning</td>
<td>Warns when a size exceeds this threshold percentage of the baseline.</td>
</tr>
<tr>
<td>maximumError</td>
<td>Reports an error when the size exceeds this threshold percentage of the baseline.</td>
</tr>
<tr>
<td>minimumWarning</td>
<td>Warns when the size reaches this threshold percentage of the baseline.</td>
</tr>
<tr>
<td>minimumError</td>
<td>Reports an error when the size reaches this threshold percentage of the baseline.</td>
</tr>
<tr>
<td>warning</td>
<td>Warns when the size ??reaches or exceeds?? this threshold percentage of the baseline.</td>
</tr>
<tr>
<td>error</td>
<td>Reports an error when the size ??reaches or exceeds?? this threshold percentage of the baseline.</td>
</tr>
</table>
{@a assets}
## Adding project assets
You can configure your project with a set of assets, such as images, to copy directly into the build for a particular build target.
Each build target section of the CLI configuration file, `angular.json`, has an `assets` section that lists files or folders you want to copy into the build for that target.
By default, the `src/assets/` folder and `src/favicon.ico` are copied into a build.
```
"assets": [
"src/assets",
"src/favicon.ico"
]
```
You can edit the assets configuration to extend it for assets outside your project.
For example, the following invokes the [node-glob pattern matcher](https://github.com/isaacs/node-glob) using input from a given base folder.
It sends output to a folder that is relative to `outDir`, a configuration value that defaults to `dist/`*project-name*).
The result in this cased is the same as for the default assets configuration.
```
"assets": [
{ "glob": "**/*", "input": "src/assets/", "output": "/assets/" },
{ "glob": "favicon.ico", "input": "/src", "output": "/" },
]
```
You can use this extended configuration to copy assets from outside your project.
For instance, you can copy assets from a node package with the following value:
```
"assets": [
{ "glob": "**/*", "input": "./node_modules/some-package/images", "output": "/some-package/" },
]
```
This makes the contents of `node_modules/some-package/images/` available in the output folder `dist/some-package/`.
<div class="alert is-critical">
For reasons of security, the CLI never writes files outside of the project output path.
</div>
{@a browser-compat}
## Configuring browser compatibility
The CLI uses [Autoprefixer](https://github.com/postcss/autoprefixer) to ensure compatibility with different browser and browser versions.
You may find it necessary to target specific browsers or exclude certain browser versions from your build.
Internally, Autoprefixer relies on a library called [Browserslist(https://github.com/ai/browserslist)] to figure out which browsers to support with prefixing.
Browserlist looks for configuration options in a `browserlist` property of the package configuration file, or in a configuration file named `.browserslistrc`.
Autoprefixer looks for the Browserlist configuration when it prefixes your CSS.
* You can tell Autoprefixer what browsers to target by adding a browserslist property to the package configuration file, `package.json`:
```
"browserslist": [
"> 1%",
"last 2 versions"
]
```
* Alternatively, you can add a new file, `.browserslistrc`, to the project directory, that specifies browsers you want to support:
```
### Supported Browsers
> 1%
last 2 versions
```
See the [browserslist repo](https://github.com/ai/browserslist) for more examples of how to target specific browsers and versions.
<div class="alert is-helpful">>
Backward compatibility
If you want to produce a progressive web app and are using [Lighthouse](https://developers.google.com/web/tools/lighthouse/) to grade the project, add the following browserslist entry to your `package.json` file, in order to eliminate the [old flexbox](https://developers.google.com/web/tools/lighthouse/audits/old-flexbox) prefixes:
```
"browserslist": [
"last 2 versions",
"not ie <= 10",
"not ie_mob <= 10"
]
```
</div>
{@a proxy}
## Proxying to a backend server
You can use the [proxying support](https://webpack.js.org/configuration/dev-server/#devserver-proxy) in the `webpack` dev server to divert certain URLs to a backend server, by passing a file to the `--proxy-config` build option.
For example, to divert all calls for http://localhost:4200/api to a server running on http://localhost:3000/api, take the following steps.
1. Create a file `proxy.conf.json` in the projects `src/` folder, next to `package.json`.
1. Add the following content to the new proxy file:
```
{
"/api": {
"target": "http://localhost:3000",
"secure": false
}
}
```
1. In the CLI configuration file, `angular.json`, add the `proxyConfig` option to the `serve` target:
```
...
"architect": {
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "your-application-name:build",
"proxyConfig": "src/proxy.conf.json"
},
...
```
1. To run the dev server with this proxy configuration, call `ng serve`.
You can edit the proxy configuration file to add configuration options; some examples are given below.
For a description of all options, see [webpack DevServer documentation](https://webpack.js.org/configuration/dev-server/#devserver-proxy).
Note that if you edit the proxy configuration file, you must relaunch the `ng serve` process to make your changes effective.
### Rewrite the URL path
The `pathRewrite` proxy configuration option lets you rewrite the URL path at run time.
For example, you can specify the following `pathRewrite` value to the proxy configuration to remove "api" from the end of a path.
```
{
"/api": {
"target": "http://localhost:3000",
"secure": false,
"pathRewrite": {
"^/api": ""
}
}
}
```
If you need to access a backend that is not on `localhost`, set the `changeOrigin` option as well. For example:
```
{
"/api": {
"target": "http://npmjs.org",
"secure": false,
"pathRewrite": {
"^/api": ""
},
"changeOrigin": true
}
}
```
To help determine whether your proxy is working as intended, set the `logLevel` option. For example:
```
{
"/api": {
"target": "http://localhost:3000",
"secure": false,
"pathRewrite": {
"^/api": ""
},
"logLevel": "debug"
}
}
```
Proxy log levels are `info` (the default), `debug`, `warn`, `error`, and `silent`.
### Proxy multiple entries
You can proxy multiple entries to the same target by defining the configuration in JavaScript.
Set the proxy configuration file to `proxy.conf.js` (instead of `proxy.conf.json`), and specify configuration files as in the following example.
```
const PROXY_CONFIG = [
{
context: [
"/my",
"/many",
"/endpoints",
"/i",
"/need",
"/to",
"/proxy"
],
target: "http://localhost:3000",
secure: false
}
]
module.exports = PROXY_CONFIG;
```
In the CLI configuration file, `angular.json`, point to the JavaScript proxy configuration file:
```
...
"architect": {
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "your-application-name:build",
"proxyConfig": "src/proxy.conf.js"
},
...
```
### Bypass the proxy
If you need to optionally bypass the proxy, or dynamically change the request before it's sent, add the bypass option, as shown in this JavaScript example.
```
const PROXY_CONFIG = {
"/api/proxy": {
"target": "http://localhost:3000",
"secure": false,
"bypass": function (req, res, proxyOptions) {
if (req.headers.accept.indexOf("html") !== -1) {
console.log("Skipping proxy for browser request.");
return "/index.html";
}
req.headers["X-Custom-Header"] = "yes";
}
}
}
module.exports = PROXY_CONFIG;
```
### Using corporate proxy
If you work behind a corporate proxy, the cannot directly proxy calls to any URL outside your local network.
In this case, you can configure the backend proxy to redirect calls through your corporate proxy using an agent:
<code-example language="none" class="code-shell">
npm install --save-dev https-proxy-agent
</code-example>
When you define an environment variable `http_proxy` or `HTTP_PROXY`, an agent is automatically added to pass calls through your corporate proxy when running `npm start`.
Use the following content in the JavaScript configuration file.
```
var HttpsProxyAgent = require('https-proxy-agent');
var proxyConfig = [{
context: '/api',
target: 'http://your-remote-server.com:3000',
secure: false
}];
function setupForCorporateProxy(proxyConfig) {
var proxyServer = process.env.http_proxy || process.env.HTTP_PROXY;
if (proxyServer) {
var agent = new HttpsProxyAgent(proxyServer);
console.log('Using corporate proxy server: ' + proxyServer);
proxyConfig.forEach(function(entry) {
entry.agent = agent;
});
}
return proxyConfig;
}
module.exports = setupForCorporateProxy(proxyConfig);
```

View File

@ -19,7 +19,7 @@ Observables are often compared to promises. Here are some key differences:
### Creation and subscription
* Observables are not executed until a consumer subcribes. The `subscribe()` executes the defined behavior once, and it can be called again. Each subscription has its own computation. Resubscription causes recomputation of values.
* Observables are not executed until a consumer subscribes. The `subscribe()` executes the defined behavior once, and it can be called again. Each subscription has its own computation. Resubscription causes recomputation of values.
<code-example hideCopy>
// declare a publishing operation

View File

@ -149,7 +149,7 @@ By default, the DI framework searches for a provider in the injector hierarchy,
starting at the component's local injector of the component, and if necessary bubbling up
through the injector tree until it reaches the root injector.
* The first injector configured with a provider supplies the the dependency (a service instance or value) to the constructor.
* The first injector configured with a provider supplies the dependency (a service instance or value) to the constructor.
* If no provider is found in the root injector, the DI framework returns null to the constructor.
@ -260,7 +260,7 @@ Using a custom provider allows you to provide a concrete implementation for impl
</code-example>
The `factory` function returns the `localStorage` property that is attached to the browser window object. The `Inject` decorator is a constructor parameter used to specify a custom provider of a dependency. This custom provider can now be overriden during testing with a mock API of `localStorage` instead of interactive with real browser APIs.
The `factory` function returns the `localStorage` property that is attached to the browser window object. The `Inject` decorator is a constructor parameter used to specify a custom provider of a dependency. This custom provider can now be overridden during testing with a mock API of `localStorage` instead of interactive with real browser APIs.
### Modify the provider search with `@Self` and `@SkipSelf`

View File

@ -112,7 +112,7 @@ The `CraigComponent` tries to inject `Base` into its `alex` constructor paramete
Unfortunately, this does'nt work.
Unfortunately, this doesn't work.
The <live-example name="dependency-injection-in-action"></live-example>
confirms that the `alex` parameter is null.
*You cannot inject a parent by its base class.*

View File

@ -240,7 +240,7 @@ The `@Injectable()` decorator is the standard decorator for service classes.
<div class="alert-is-helpful">
The decorator requirement is imposed by TypeScript. TypeScript normally discards parameter type information when it [transpiles]((guide/glossary#transpile) the code to JavaScript. TypeScript preserves this information if the class has a decorator and the `emitDecoratorMetadata` compiler option is set `true` in TypeScript's `tsconfig.json` configuration file. The CLI configures `tsconfig.json` with `emitDecoratorMetadata: true`.
The decorator requirement is imposed by TypeScript. TypeScript normally discards parameter type information when it [transpiles](guide/glossary#transpile) the code to JavaScript. TypeScript preserves this information if the class has a decorator and the `emitDecoratorMetadata` compiler option is set `true` in TypeScript's `tsconfig.json` configuration file. The CLI configures `tsconfig.json` with `emitDecoratorMetadata: true`.
This means you're responsible for putting `@Injectable()` on your service classes.

View File

@ -1,7 +1,6 @@
# Deployment
When you are ready to deploy your Angular application to a remote server, you have various options for
deployment. You may need to configure
This page describes techniques for deploying your Angular application to a remote server.
{@a dev-deploy}
{@a copy-files}
@ -19,214 +18,27 @@ For the simplest deployment, build for development and copy the output directory
2. Copy _everything_ within the output folder (`dist/` by default) to a folder on the server.
3. Configure the server to redirect requests for missing files to `index.html`.
3. If you copy the files into a server _sub-folder_, append the build flag, `--base-href` and set the `<base href>` appropriately.<br><br>
For example, if the `index.html` is on the server at `/my/app/index.html`, set the _base href_ to
`<base href="/my/app/">` like this.
<code-example language="none" class="code-shell">
ng build --base-href=/my/app/
</code-example>
You'll see that the `<base href>` is set properly in the generated `dist/index.html`.<br><br>
If you copy to the server's root directory, omit this step and leave the `<base href>` alone.<br><br>
Learn more about the role of `<base href>` [below](guide/deployment#base-tag).
4. Configure the server to redirect requests for missing files to `index.html`.
Learn more about server-side redirects [below](guide/deployment#fallback).
This is _not_ a production deployment. It's not optimized and it won't be fast for users.
It might be good enough for sharing your progress and ideas internally with managers, teammates, and other stakeholders. For the next steps in deployment, see [Optimize for production](#optimize).
{@a deploy-to-github}
## Deploy to GitHub pages
Another simple way to deploy your Angular app is to use [GitHub Pages](https://help.github.com/articles/what-is-github-pages/).
1. You will need to [create a GitHub account](https://github.com/join) if you don't have one, then [create a repository](https://help.github.com/articles/create-a-repo/) for your project.
Make a note of the user name and project name in GitHub.
1. Build your project using Github project name, with the following CLI command:
<code-example language="none" class="code-shell">
ng build --prod --output-path docs --base-href <project_name>
</code-example>
1. When the build is complete, make a copy of `docs/index.html` and name it `docs/404.html`.
1. Commit your changes and push.
1. On the GitHub project page, configure it to [publish from the docs folder](https://help.github.com/articles/configuring-a-publishing-source-for-github-pages/#publishing-your-github-pages-site-from-a-docs-folder-on-your-master-branch).
You can see your deployed page at `https://<user_name>.github.io/<project_name>/`.
<div class="alert-is-helpful>
Check out [angular-cli-ghpages](https://github.com/angular-buch/angular-cli-ghpages), a full featured package that does all this for you and has extra functionality.
</div>
<hr>
{@a server-configuration}
## Server configuration
This section covers changes you may have make to the server or to files deployed to the server.
{@a fallback}
### Routed apps must fallback to `index.html`
Angular apps are perfect candidates for serving with a simple static HTML server.
You don't need a server-side engine to dynamically compose application pages because
Angular does that on the client-side.
If the app uses the Angular router, you must configure the server
to return the application's host page (`index.html`) when asked for a file that it does not have.
{@a deep-link}
A routed application should support "deep links".
A _deep link_ is a URL that specifies a path to a component inside the app.
For example, `http://www.mysite.com/heroes/42` is a _deep link_ to the hero detail page
that displays the hero with `id: 42`.
There is no issue when the user navigates to that URL from within a running client.
The Angular router interprets the URL and routes to that page and hero.
But clicking a link in an email, entering it in the browser address bar,
or merely refreshing the browser while on the hero detail page &mdash;
all of these actions are handled by the browser itself, _outside_ the running application.
The browser makes a direct request to the server for that URL, bypassing the router.
A static server routinely returns `index.html` when it receives a request for `http://www.mysite.com/`.
But it rejects `http://www.mysite.com/heroes/42` and returns a `404 - Not Found` error *unless* it is
configured to return `index.html` instead.
#### Fallback configuration examples
There is no single configuration that works for every server.
The following sections describe configurations for some of the most popular servers.
The list is by no means exhaustive, but should provide you with a good starting point.
#### Development servers
During development, the `ng serve` command lets you run your app in a local browser.
The CLI recompiles the application each time you save a file,
and reloads the browser with the newly compiled application.
The app is hosted in local memory and served on `http://localhost:4200/`, using [webpack-dev-server](https://webpack.js.org/guides/development/#webpack-dev-server).
{@a serve-from-disk}
Later in development, you might want a closer approximation of how your app will behave when deployed.
You can output your distribution folder (`dist`) to disk, but you need to install a different web server.
Try installing [lite-server](https://github.com/johnpapa/lite-server); like `webpack-dev-server`, it can automatically reload your browser when you write new files.
To get the live-reload experience, you will need to run two terminals.
The first runs the build in a watch mode and compiles the application to the `dist` folder.
The second runs the web server against the `dist` folder.
The combination of these two processes provides the same behavior as `ng serve`.
1. Start the build in terminal A:
<code-example language="none" class="code-shell">
ng build --watch
</code-example>
1. Start the web server in terminal B:
<code-example language="none" class="code-shell">
lite-server --baseDir="dist"
</code-example>
The default browser opens to the appropriate URL.
* [Lite-Server](https://github.com/johnpapa/lite-server): the default dev server installed with the
[Quickstart repo](https://github.com/angular/quickstart) is pre-configured to fallback to `index.html`.
* [Webpack-Dev-Server](https://github.com/webpack/webpack-dev-server): setup the
`historyApiFallback` entry in the dev server options as follows:
<code-example>
historyApiFallback: {
disableDotRule: true,
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml']
}
</code-example>
#### Production servers
* [Apache](https://httpd.apache.org/): add a
[rewrite rule](http://httpd.apache.org/docs/current/mod/mod_rewrite.html) to the `.htaccess` file as shown
(https://ngmilk.rocks/2015/03/09/angularjs-html5-mode-or-pretty-urls-on-apache-using-htaccess/):
<code-example format=".">
RewriteEngine On
&#35 If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
&#35 If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
</code-example>
* [Nginx](http://nginx.org/): use `try_files`, as described in
[Front Controller Pattern Web Apps](https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#front-controller-pattern-web-apps),
modified to serve `index.html`:
<code-example format=".">
try_files $uri $uri/ /index.html;
</code-example>
* [IIS](https://www.iis.net/): add a rewrite rule to `web.config`, similar to the one shown
[here](http://stackoverflow.com/a/26152011/2116927):
<code-example format='.'>
&lt;system.webServer&gt;
&lt;rewrite&gt;
&lt;rules&gt;
&lt;rule name="Angular Routes" stopProcessing="true"&gt;
&lt;match url=".*" /&gt;
&lt;conditions logicalGrouping="MatchAll"&gt;
&lt;add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /&gt;
&lt;add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /&gt;
&lt;/conditions&gt;
&lt;action type="Rewrite" url="/index.html" /&gt;
&lt;/rule&gt;
&lt;/rules&gt;
&lt;/rewrite&gt;
&lt;/system.webServer&gt;
</code-example>
* [GitHub Pages](https://pages.github.com/): you can't
[directly configure](https://github.com/isaacs/github/issues/408)
the GitHub Pages server, but you can add a 404 page.
Copy `index.html` into `404.html`.
It will still be served as the 404 response, but the browser will process that page and load the app properly.
It's also a good idea to
[serve from `docs/` on master](https://help.github.com/articles/configuring-a-publishing-source-for-github-pages/#publishing-your-github-pages-site-from-a-docs-folder-on-your-master-branch)
and to
[create a `.nojekyll` file](https://www.bennadel.com/blog/3181-including-node-modules-and-vendors-folders-in-your-github-pages-site.htm)
* [Firebase hosting](https://firebase.google.com/docs/hosting/): add a
[rewrite rule](https://firebase.google.com/docs/hosting/url-redirects-rewrites#section-rewrites).
<code-example format=".">
"rewrites": [ {
"source": "**",
"destination": "/index.html"
} ]
</code-example>
{@a cors}
### Requesting services from a different server (CORS)
Angular developers may encounter a
<a href="https://en.wikipedia.org/wiki/Cross-origin_resource_sharing" title="Cross-origin resource sharing">
<i>cross-origin resource sharing</i></a> error when making a service request (typically a data service request)
to a server other than the application's own host server.
Browsers forbid such requests unless the server permits them explicitly.
There isn't anything the client application can do about these errors.
The server must be configured to accept the application's requests.
Read about how to enable CORS for specific servers at
<a href="http://enable-cors.org/server.html" title="Enabling CORS server">enable-cors.org</a>.
<hr>
It might be good enough for sharing your progress and ideas internally with managers, teammates, and other stakeholders.
{@a optimize}
@ -253,8 +65,14 @@ The `--prod` _meta-flag_ engages the following optimization features.
The remaining [copy deployment steps](#copy-files) are the same as before.
See [Building and serving Angular apps](guide/build)
for more about about CLI build options and what they do.
You may further reduce bundle sizes by adding the `build-optimizer` flag.
<code-example language="none" class="code-shell">
ng build --prod --build-optimizer
</code-example>
See the [CLI Documentation](https://github.com/angular/angular-cli/wiki/build)
for details about available build options and what they do.
{@a enable-prod-mode}
@ -284,24 +102,22 @@ Configure the Angular Router to defer loading of all other modules (and their as
or by [_lazy loading_](guide/router#asynchronous-routing "Lazy loading")
them on demand.
<div class="alert-is-helpful>
#### Don't eagerly import something from a lazy loaded module
#### Don't eagerly import something from a lazy-loaded module
If you mean to lazy-load a module, be careful not import it
in a file that's eagerly loaded when the app starts (such as the root `AppModule`).
It's a common mistake.
You've arranged to lazy load a module.
But you unintentionally import it, with a JavaScript `import` statement,
in a file that's eagerly loaded when the app starts, a file such as the root `AppModule`.
If you do that, the module will be loaded immediately.
The bundling configuration must take lazy loading into consideration.
Because lazy-loaded modules aren't imported in JavaScript, bundlers exclude them by default.
Bundlers don't know about the router configuration and can't create separate bundles for lazy-loaded modules.
You would have to create these bundles manually.
Because lazy loaded modules aren't imported in JavaScript (as just noted), bundlers exclude them by default.
Bundlers don't know about the router configuration and won't create separate bundles for lazy loaded modules.
You have to create these bundles manually.
The CLI runs the
[Angular Ahead-of-Time Webpack Plugin](https://github.com/angular/angular-cli/tree/master/packages/%40ngtools/webpack)
which automatically recognizes lazy-loaded `NgModules` and creates separate bundles for them.
</div>
which automatically recognizes lazy loaded `NgModules` and creates separate bundles for them.
{@a measure}
@ -387,12 +203,17 @@ the subfolder is `my/app/` and you should add `<base href="/my/app/">` to the se
When the `base` tag is mis-configured, the app fails to load and the browser console displays `404 - Not Found` errors
for the missing files. Look at where it _tried_ to find those files and adjust the base tag appropriately.
## Building and serving for deployment
## _build_ vs. _serve_
When you are designing and developing applications, you typically use `ng serve` to build your app for fast, local, iterative development.
When you are ready to deploy, however, you must use the `ng build` command to build the app and deploy the build artifacts elsewhere.
You'll probably prefer `ng build` for deployments.
Both `ng build` and `ng serve` clear the output folder before they build the project, but only the `build` command writes the generated build artifacts to the output folder.
The **ng build** command is intended for building the app and deploying the build artifacts elsewhere.
The **ng serve** command is intended for fast, local, iterative development.
Both `ng build` and `ng serve` **clear the output folder** before they build the project.
The `ng build` command writes generated build artifacts to the output folder.
The `ng serve` command does not.
It serves build artifacts from memory instead for a faster development experience.
<div class="alert is-helpful">
@ -401,13 +222,160 @@ To output to a different folder, change the `outputPath` in `angular.json`.
</div>
The`serve` command builds, watches, and serves the application from local memory, using a local development server.
When you have deployed your app to another server, however, you might still want to serve the app so that you can continue to see changes that you make in it.
You can do this by adding the `--watch` option to the `build` command.
The `ng serve` command builds, watches, and serves the application from a local CLI development server.
```
ng build --watch
```
Like the `serve` command, this regenerates output files when source files change.
The `ng build` command generates output files just once and does not serve them.
The `ng build --watch` command will regenerate output files when source files change.
This `--watch` flag is useful if you're building during development and
are automatically re-deploying changes to another server.
For complete details of the CLI commands and configuration options, see the *CLI Reference (link TBD)*.
See the [CLI `build` topic](https://github.com/angular/angular-cli/wiki/build) for more details and options.
<hr>
{@a server-configuration}
## Server configuration
This section covers changes you may have make to the server or to files deployed to the server.
{@a fallback}
### Routed apps must fallback to `index.html`
Angular apps are perfect candidates for serving with a simple static HTML server.
You don't need a server-side engine to dynamically compose application pages because
Angular does that on the client-side.
If the app uses the Angular router, you must configure the server
to return the application's host page (`index.html`) when asked for a file that it does not have.
{@a deep-link}
A routed application should support "deep links".
A _deep link_ is a URL that specifies a path to a component inside the app.
For example, `http://www.mysite.com/heroes/42` is a _deep link_ to the hero detail page
that displays the hero with `id: 42`.
There is no issue when the user navigates to that URL from within a running client.
The Angular router interprets the URL and routes to that page and hero.
But clicking a link in an email, entering it in the browser address bar,
or merely refreshing the browser while on the hero detail page &mdash;
all of these actions are handled by the browser itself, _outside_ the running application.
The browser makes a direct request to the server for that URL, bypassing the router.
A static server routinely returns `index.html` when it receives a request for `http://www.mysite.com/`.
But it rejects `http://www.mysite.com/heroes/42` and returns a `404 - Not Found` error *unless* it is
configured to return `index.html` instead.
#### Fallback configuration examples
There is no single configuration that works for every server.
The following sections describe configurations for some of the most popular servers.
The list is by no means exhaustive, but should provide you with a good starting point.
#### Development servers
* [Lite-Server](https://github.com/johnpapa/lite-server): the default dev server installed with the
[Quickstart repo](https://github.com/angular/quickstart) is pre-configured to fallback to `index.html`.
* [Webpack-Dev-Server](https://github.com/webpack/webpack-dev-server): setup the
`historyApiFallback` entry in the dev server options as follows:
<code-example>
historyApiFallback: {
disableDotRule: true,
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml']
}
</code-example>
#### Production servers
* [Apache](https://httpd.apache.org/): add a
[rewrite rule](http://httpd.apache.org/docs/current/mod/mod_rewrite.html) to the `.htaccess` file as shown
(https://ngmilk.rocks/2015/03/09/angularjs-html5-mode-or-pretty-urls-on-apache-using-htaccess/):
<code-example format=".">
RewriteEngine On
&#35 If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
&#35 If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
</code-example>
* [NGinx](http://nginx.org/): use `try_files`, as described in
[Front Controller Pattern Web Apps](https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#front-controller-pattern-web-apps),
modified to serve `index.html`:
<code-example format=".">
try_files $uri $uri/ /index.html;
</code-example>
* [IIS](https://www.iis.net/): add a rewrite rule to `web.config`, similar to the one shown
[here](http://stackoverflow.com/a/26152011/2116927):
<code-example format='.'>
&lt;system.webServer&gt;
&lt;rewrite&gt;
&lt;rules&gt;
&lt;rule name="Angular Routes" stopProcessing="true"&gt;
&lt;match url=".*" /&gt;
&lt;conditions logicalGrouping="MatchAll"&gt;
&lt;add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /&gt;
&lt;add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /&gt;
&lt;/conditions&gt;
&lt;action type="Rewrite" url="/index.html" /&gt;
&lt;/rule&gt;
&lt;/rules&gt;
&lt;/rewrite&gt;
&lt;/system.webServer&gt;
</code-example>
* [GitHub Pages](https://pages.github.com/): you can't
[directly configure](https://github.com/isaacs/github/issues/408)
the GitHub Pages server, but you can add a 404 page.
Copy `index.html` into `404.html`.
It will still be served as the 404 response, but the browser will process that page and load the app properly.
It's also a good idea to
[serve from `docs/` on master](https://help.github.com/articles/configuring-a-publishing-source-for-github-pages/#publishing-your-github-pages-site-from-a-docs-folder-on-your-master-branch)
and to
[create a `.nojekyll` file](https://www.bennadel.com/blog/3181-including-node-modules-and-vendors-folders-in-your-github-pages-site.htm)
* [Firebase hosting](https://firebase.google.com/docs/hosting/): add a
[rewrite rule](https://firebase.google.com/docs/hosting/url-redirects-rewrites#section-rewrites).
<code-example format=".">
"rewrites": [ {
"source": "**",
"destination": "/index.html"
} ]
</code-example>
{@a cors}
### Requesting services from a different server (CORS)
Angular developers may encounter a
<a href="https://en.wikipedia.org/wiki/Cross-origin_resource_sharing" title="Cross-origin resource sharing">
<i>cross-origin resource sharing</i></a> error when making a service request (typically a data service request)
to a server other than the application's own host server.
Browsers forbid such requests unless the server permits them explicitly.
There isn't anything the client application can do about these errors.
The server must be configured to accept the application's requests.
Read about how to enable CORS for specific servers at
<a href="http://enable-cors.org/server.html" title="Enabling CORS server">enable-cors.org</a>.

View File

@ -31,7 +31,7 @@ The easiest way to display a component property
is to bind the property name through interpolation.
With interpolation, you put the property name in the view template, enclosed in double curly braces: `{{myHero}}`.
Follow the [quickstart](guide/quickstart) instructions for creating a new project
Follow the [Getting Started](guide/quickstart) instructions for creating a new project
named <code>displaying-data</code>.
Delete the <code>app.component.html</code> file. It is not needed for this example.

View File

@ -1,382 +0,0 @@
# Workspace and project file structure
An Angular CLI project is the foundation for both quick experiments and enterprise solutions. The CLI command `ng new` creates an Angular workspace in your file system that is the root for new projects, which can be apps and libraries.
## Workspaces and project files
Angular 6 introduced the [workspace](guide/glossary#workspace) directory structure for Angular [projects](guide/glossary#project). A project can be a standalone *application* or a *library*, and a workspace can contain multiple applications, as well as libraries that can be used in any of the apps.
The CLI command `ng new my-workspace` creates a workspace folder and generates a new app skeleton in an `app` folder within that workspace.
Within the `app/` folder, a `src/` subfolder contains the logic, data, and assets.
A newly generated `app/` folder contains the source files for a root module, with a root component and template.
The `app/` folder also contains project-specific configuration files, end-to-end tests, and the Angular system modules.
```
my-workspace/
app/
e2e/
src/
node_modules/
src/
```
When this workspace file structure is in place, you can use the `ng generate` command on the command line to add functionality and data to the initial app.
<div class="alert-is-helpful>
Besides using the CLI on the command line, You can also use an interactive development environment like [Angular Console](https://angular.console.com), or manipulate files directly in the app's source folder and configuration files.
</div>
{@a global-config}
## Global workspace configuration
A workspace can contain additional apps and libraries, each with its own root folder under `projects/`.
```
my-workspace/
app/
projects/
my-app/
helpful-library/
my-other-app/
angular.json
```
At the top level of the workspace, the CLI configuration file, `angular.json`, let you set defaults for all projects in the workspace. You can configure a workspace, for example, such that all projects in it have global access to libraries, scripts, and CSS styles. (For more in this, see [Configuring global access](#global-access).)
You can also use `ng generate app` to create new Angular apps in the workspace, and use the `ng add` command to add libraries.
If you add libraries or generate more apps within a workspace, a `projects/` folder is created to contain the new libraries or apps.
Additional apps and library subfolders have the same file structure as the initial app.
All of the projects within a workspace share a CLI configuration context, controlled by the `angular.json` configuration file at the root level of the workspace.
| GLOBAL CONFIG FILES | PURPOSE |
| :------------- | :------------------------------------------|
| `angular.json` | Sets defaults for the CLI and configuration options for build, serve, and test tools that the CLI uses, such as [Karma](https://karma-runner.github.io/) and [Protractor](http://www.protractortest.org/). For complete details, see *CLI Reference (link TBD)*. |
## App source folder
The app-root source folder contains your app's logic and data. Angular components, templates, styles, images, and anything else your app needs go here. Files outside of the source folder support testing and building your app.
```
src/
app/
app.component.css
app.component.html
app.component.spec.ts
app.component.ts
app.module.ts
assets/...
favicon.ico
index.html
main.ts
test.ts
```
| APP SOURCE FILES | PURPOSE |
| :----------------------------- | :------------------------------------------|
| `app/app.component.ts` | Defines the logic for the app's root component, named AppComponent. The view associated with this root component becomes the root of the [view hierarchy](guide/glossary#view-hierarchy) as you add components and services to your app. |
| `app/app.component.html` | Defines the HTML template associated with the root AppComponent. |
| `app/app.component.css` | Defines the base CSS stylesheet for the root AppComponent. |
| `app/app.component.spec.ts` | Defines a unit test for the root AppComponent. |
| `app/app.module.ts` | Defines the root module, named AppModule, that tells Angular how to assemble the application. Initially declares only the AppComponent. As you add more components to the app, they must be declared here. |
| `assets/*` | Contains image files and other asset files to be copied as-is when you build your application. |
| PROJECT-LEVEL FILES | PURPOSE |
| :------------------------ | :------------------------------------------|
| `favicon.ico` | An icon to use for this app in the bookmark bar. |
| `index.html` | The main HTML page that is served when someone visits your site. The CLI automatically adds all JavaScript and CSS files when building your app, so you typically don't need to add any `<script>` or` <link>` tags here manually. |
| `main.ts` | The main entry point for your app. Compiles the application with the [JIT compiler](https://angular.io/guide/glossary#jit) and bootstraps the application's root module (AppModule) to run in the browser. You can also use the [AOT compiler](https://angular.io/guide/aot-compiler) without changing any code by appending the `--aot` flag to the CLI `build` and `serve` commands. |
| `test.ts` | The main entry point for your unit tests, with some Angular-specific configuration. You don't typically need to edit this file. |
## App support file structure
Additional files in a project's root folder help you build, test, maintain, document, and deploy the app. These files go in the app root folder next to `src/`.
```
workspace_root/
my-app/
e2e/
src/
app.e2e-spec.ts
app.po.ts
tsconfig.e2e.json
protractor.conf.js
node_modules/...
src/...
```
| FOLDERS | PURPOSE |
| :---------------- | :-------------------------------------------- |
| `e2e/` | This folder contains end-to-end tests for the app. This is a separate app that tests your main app. The folder and its contents are generated automatically when you create a new app with the CLI `new` or `generate` command. |
| `node_modules/` | Node.js creates this folder and puts all third party modules listed in `package.json` in it. *when? doesn't ng new create it?* |
### Project-level configuration
Each project uses the CLI configuration at the workspace root-level `angular.json` file.
Additional project-specific configuration files are found at the project root level of each app or library.
```
my-workspace/
app/
.editorconfig
.gitignore
package.json
README.md
tsconfig.json
tsconfig.test.json
tslint.json
projects/
helpful-library/
my-other-app/
.editorconfig
.gitignore
package.json
README.md
tsconfig.json
tsconfig.test.json
tslint.json
angular.json
```
| CONFIGURATION FILES | PURPOSE |
| :------------------ | :-------------------------------------------- |
| `.editorconfig` | Simple configuration for your editor to make sure everyone who uses your project has the same basic configuration. Supported by most editors. See http://editorconfig.org for more information. |
| `.gitignore` | Git configuration to make sure autogenerated files are not committed to source control. |
| `package.json` | Configures the `npm` package manager, listing the third party packages your project uses. You can also add your own custom scripts here. |
| `README.md` | Basic documentation for your project, pre-filled with CLI command information. We recommend that you keep this updated so that anyone checking out the repo can build your app. |
| `tsconfig.json` | TypeScript compiler configuration, that an IDE such as [Visual Studio Code](https://code.visualstudio.com/) uses to give you helpful tooling. |
| `tslint.json` | Linting configuration for [TSLint](https://palantir.github.io/tslint/) together with [Codelyzer](http://codelyzer.com/), used when running the CLI `lint` command. Linting helps keep your code style consistent. |
{@a global-access}
## Configuring global access
The CLI configuration scope is global for a workspace.
You can make scripts, libraries, and styles available to all projects in the workspace by setting options in the `angular.json` file in the root workspace folder.
### Adding global scripts
You can configure your project to add JavaScript files to the global scope.
This is especially useful for legacy libraries or analytic snippets.
In the CLI configuration file, `angular.json`, add the associated script files to the `scripts` array.
The scripts are loaded exactly as if you had added them in a `<script>` tag inside `index.html`.
For example:
```
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"scripts": [
"src/global-script.js",
],
```
You can also rename the output from a script and lazy load it by using the object format in the "scripts" entry.
For example:
```
"scripts": [
"src/global-script.js",
{ "input": "src/lazy-script.js", "lazy": true },
{ "input": "src/pre-rename-script.js", "bundleName": "renamed-script" },
],
```
If you need to add scripts for unit tests, specify them the same way in the "test" target.
{@a add-lib}
### Adding a global library
Some JavaScript libraries need to be added to the global scope and loaded as if they were in a script tag.
Configure the CLI to do this using the "scripts" and "styles" options of the build target in the CLI configuration file, `angular.json`.
For example, to use the [Bootstrap 4](https://getbootstrap.com/docs/4.0/getting-started/introduction/)
library, first install the library and its dependencies using the `npm` package manager:
```
npm install jquery --save
npm install popper.js --save
npm install bootstrap --save
```
In the `angular.json` configuration file, add the associated script files to the "scripts" array:
```
"scripts": [
"node_modules/jquery/dist/jquery.slim.js",
"node_modules/popper.js/dist/umd/popper.js",
"node_modules/bootstrap/dist/js/bootstrap.js"
],
```
Add the Bootstrap CSS file to the "styles" array:
```
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.css",
"src/styles.css"
],
```
Run or restart `ng serve` to see Bootstrap 4 working in your app.
#### Using global libraries inside your app
Once you import a library using the "scripts" array in the configuration file,
you should *not* import it using an `import` statement in your TypeScript code
(such as `import * as $ from 'jquery';`).
If you do, you'll end up with two different copies of the library:
one imported as a global library, and one imported as a module.
This is especially bad for libraries with plugins, like JQuery,
because each copy will have different plugins.
Instead, download typings for your library (`npm install @types/jquery`) and follow the installation steps
given above in [Adding a global library](#add-lib).
This gives you access to the global variables exposed by that library.
{@a define-types}
#### Defining typings for global libraries
If the global library you need to use does not have global typings,
you can declare them manually as `any` in `src/typings.d.ts`. For example:
```
declare var libraryName: any;
```
Some scripts extend other libraries; for instance with JQuery plugins:
```
$('.test').myPlugin();
```
In this case, the installed `@types/jquery` doesn't include `myPlugin`,
so you need to add an *interface* in `src/typings.d.ts`.
For example:
```
interface JQuery {
myPlugin(options?: any): any;
}
```
If you fail to add the interface for the script-defined extension, your IDE shows an error:
```
[TS][Error] Property 'myPlugin' does not exist on type 'JQuery'
```
### Adding global styles and style preprocessors
Angular CLI supports CSS imports and all major CSS preprocessors:
* [Sass/Scss](http://sass-lang.com/)
* [Less](http://lesscss.org/)
* [Stylus](http://stylus-lang.com/)
Angular assumes CSS styles by default, but when you create a project with the
CLI `new` command, you can specify the `--style` option to use SASS or STYL styles.
```
> ng new sassyproject --style=sass
> ng new scss-project --style=scss
> ng new less-project --style=less
> ng new styl-project --style=styl
```
You can also set the default style for an existing project by configuring `@schematics/angular`,
the default schematic for the Angular CLI:
```
> ng config schematics.@schematics/angular:component.styleext scss
```
#### Style configuration
By default, the `styles.css` configuration file lists CSS files that supply global styles for a project.
If you are using another style type, there is a similar configuration file for global style files of that type,
with the extension for that style type, such as `styles.sass`.
You can add more global styles by configuring the build options in the `angular.json` configuration file.
List the style files in the "styles" section in your project's "build" target
The files are loaded exactly as if you had added them in a `<link>` tag inside `index.html`.
```
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"styles": [
"src/styles.css",
"src/more-styles.css",
],
...
```
If you need the styles in your unit tests, add them to the "styles" option in the "test" target configuration as well.
You can specify styles in an object format to rename the output and lazy load it:
```
"styles": [
"src/styles.css",
"src/more-styles.css",
{ "input": "src/lazy-style.scss", "lazy": true },
{ "input": "src/pre-rename-style.scss", "bundleName": "renamed-style" },
],
```
In Sass and Stylus you can make use of the `includePaths` functionality for both component and global styles,
which allows you to add extra base paths to be checked for imports.
To add paths, use the `stylePreprocessorOptions` build-target option:
```
"stylePreprocessorOptions": {
"includePaths": [
"src/style-paths"
]
},
```
You can then import files in the given folder (such as `src/style-paths/_variables.scss`)
anywhere in your project without the need for a relative path:
```
// src/app/app.component.scss
// A relative path works
@import '../style-paths/variables';
// But now this works as well
@import 'variables';
```
#### CSS preprocessor integration
To use a supported CSS preprocessor, add the URL for the preprocessor
to your component's `styleUrls` in the `@Component()` metadata.
For example:
```
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'app works!';
}
```
<div class="alert-is-helpful>
Style strings added directly to the `@Component() styles array must be written in CSS.
The CLI cannot apply a pre-processor to inline styles.
</div>

View File

@ -84,7 +84,7 @@ The abstraction of the form model promotes simplicity over structure. The templa
## Data flow in forms
When building forms in Angular, it's important to understand how the the framework handles data flowing from the user or from programmatic changes. Reactive and template-driven forms follow two different strategies when handling form input. The data flow examples below begin with the favorite color input field example from above, and they show how changes to favorite color are handled in reactive forms compared to template-driven forms.
When building forms in Angular, it's important to understand how the framework handles data flowing from the user or from programmatic changes. Reactive and template-driven forms follow two different strategies when handling form input. The data flow examples below begin with the favorite color input field example from above, and they show how changes to favorite color are handled in reactive forms compared to template-driven forms.
### Data flow in reactive forms
@ -253,7 +253,7 @@ To learn more about reactive forms, see the following guides:
* [Form Validation](guide/form-validation#reactive-form-validation)
* [Dynamic forms](guide/dynamic-form)
To learn more about tempate-driven forms, see the following guides:
To learn more about template-driven forms, see the following guides:
* [Template-driven Forms](guide/forms)
* [Form Validation](guide/form-validation#template-driven-validation)

View File

@ -77,7 +77,7 @@ A way to initialize and launch an app or system.
In Angular, an app's root NgModule (`AppModule`) has a `bootstrap` property that identifies the app's top-level [components](guide/glossary#component).
During the bootstrap process, Angular creates and inserts these components into the `index.html` host web page.
You can bootstrap multiple apps in the same `index.html`. Each app ccontains its own components.
You can bootstrap multiple apps in the same `index.html`. Each app contains its own components.
Learn more in [Bootstrapping](guide/bootstrapping).
@ -132,7 +132,7 @@ A [decorator](guide/glossary#decorator) statement immediately before a field in
The [Angular CLI](https://cli.angular.io/) is a command-line tool for managing the Angular development cycle. Use it to create the initial filesystem scaffolding for a [workspace](guide/glossary#workspace) or [project](guide/glossary#project), and to run [schematics](guide/glossary#schematic) that add and modify code for initial generic versions of various elements. The CLI supports all stages of the development cycle, including building, testing, bundling, and deployment.
* To begin using the CLI for a new project, see [QuickStart](guide/quickstart).
* To begin using the CLI for a new project, see [Getting Started](guide/quickstart).
* To learn more about the full capabilities of the CLI, see the [Angular CLI documentation](https://github.com/angular/angular-cli/wiki).
{@a component}

View File

@ -936,7 +936,7 @@ setting up such mocking straightforward.
### Mocking philosophy
Angular's HTTP testing library is designed for a pattern of testing wherein
the the app executes code and makes requests first.
the app executes code and makes requests first.
Then a test expects that certain requests have or have not been made,
performs assertions against those requests,

View File

@ -359,7 +359,7 @@ Pluralization categories include (depending on the language):
After the pluralization category, put the default English text in braces (`{}`).
In the example above, the three options are specified according to that pluralization pattern. For
talking about about zero minutes, you use `=0 {just now}`. For one minute, you use `=1 {one minute}`.
talking about zero minutes, you use `=0 {just now}`. For one minute, you use `=1 {one minute}`.
Any unmatched cardinality uses `other {{{minutes}} minutes ago}`. You could choose to add patterns
for two, three, or any other number if the pluralization rules were different. For the example of
"minute", only these three patterns are necessary in English.
@ -542,7 +542,7 @@ This sample file is easy to translate without a special editor or knowledge of F
2. Duplicate the `<source/>` tag, rename it `target`, and then replace its content with the French
greeting. If you were working with a more complex translation, you could use the the information
greeting. If you were working with a more complex translation, you could use the information
and context provided by the source, description, and meaning elements to guide your selection of
the appropriate French translation.

View File

@ -1,3 +1,4 @@
# Observables
Observables provide support for passing messages between publishers and subscribers in your application. Observables offer significant benefits over other techniques for event handling, asynchronous programming, and handling multiple values.
@ -36,10 +37,10 @@ An `Observable` instance begins publishing values only when someone subscribes t
<div class="alert is-helpful">
In order to show how subscribing works, we need to create a new observable. There is a constructor that you use to create new instances, but for illustration, we can use some static methods on the `Observable` class that create simple observables of frequently used types:
In order to show how subscribing works, we need to create a new observable. There is a constructor that you use to create new instances, but for illustration, we can use some methods from the RxJS library that create simple observables of frequently used types:
* `Observable.of(...items)`&mdash;Returns an `Observable` instance that synchronously delivers the values provided as arguments.
* `Observable.from(iterable)`&mdash;Converts its argument to an `Observable` instance. This method is commonly used to convert an array to an observable.
* `of(...items)`&mdash;Returns an `Observable` instance that synchronously delivers the values provided as arguments.
* `from(iterable)`&mdash;Converts its argument to an `Observable` instance. This method is commonly used to convert an array to an observable.
</div>
@ -62,7 +63,7 @@ Note that a `next()` function could receive, for instance, message strings, or e
Use the `Observable` constructor to create an observable stream of any type. The constructor takes as its argument the subscriber function to run when the observables `subscribe()` method executes. A subscriber function receives an `Observer` object, and can publish values to the observer's `next()` method.
For example, to create an observable equivalent to the `Observable.of(1, 2, 3)` above, you could do something like this:
For example, to create an observable equivalent to the `of(1, 2, 3)` above, you could do something like this:
<code-example path="observables/src/creating.ts" region="subscriber" title="Create observable with constructor"></code-example>

View File

@ -1,4 +1,4 @@
# QuickStart
# Getting Started
Good tools make application development quicker and easier to maintain than
if you did everything by hand.
@ -147,7 +147,7 @@ Open `src/app/app.component.css` and give the component some style.
<figure>
<img src='generated/images/guide/cli-quickstart/my-first-app.png' alt="Output of QuickStart app">
<img src='generated/images/guide/cli-quickstart/my-first-app.png' alt="Output of Getting Started app">
</figure>

View File

@ -70,7 +70,7 @@ The following table contains our current target release dates for the next two m
September/October 2018 | 7.0.0 | ^6.0.0
March/April 2019 | 8.0.0 | ^7.0.0
Compatiblity note: The primary goal of the backwards compatibility promise is to ensure that changes in the core framework and tooling don't break the existing ecosystem of components and applications and don't put undue upgrade/migration burden on Angular application and component authors.
Compatibility note: The primary goal of the backward compatibility promise is to ensure that changes in the core framework and tooling don't break the existing ecosystem of components and applications and don't put undue upgrade/migration burden on Angular application and component authors.
{@a lts}

View File

@ -3918,7 +3918,7 @@ the `queryParamsHandling` and `preserveFragment` bindings respectively.
As you've worked through the milestones, the application has naturally gotten larger.
As you continue to build out feature areas, the overall application size will continue to grow.
At some point you'll reach a tipping point where the application takes long time to load.
At some point you'll reach a tipping point where the application takes a long time to load.
How do you combat this problem? With asynchronous routing, which loads feature modules _lazily_, on request.
Lazy loading has multiple benefits.

View File

@ -330,7 +330,7 @@ You may need [nvm](https://github.com/creationix/nvm) if you already have projec
Links on almost every documentation page open completed samples in the browser.
You can play with the sample code, share your changes with friends, and download and run the code on your own machine.
The [QuickStart](guide/quickstart "Angular QuickStart Playground") shows just the `AppComponent` file.
The [Getting Started](guide/quickstart "Angular QuickStart Playground") shows just the `AppComponent` file.
It creates the equivalent of `app.module.ts` and `main.ts` internally _for the playground only_.
so the reader can discover Angular without distraction.
The other samples are based on the QuickStart seed.
@ -356,3 +356,24 @@ If you develop angular locally with `ng serve`, there will be `websocket` connec
In windows, by default one application can only have 6 websocket connections, <a href="https://msdn.microsoft.com/library/ee330736%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396#websocket_maxconn" title="MSDN WebSocket settings">MSDN WebSocket Settings</a>.
So if IE was refreshed manunally or automatically by `ng serve`, sometimes, the websocket will not close properly, when websocket connections exceed limitations, `SecurityError` will be thrown, this error will not affect the angular application, you can just restart IE to clear this error, or modify the windows registry to update the limitations.
## Appendix: test using `fakeAsync()/async()`
If you use the `fakeAsync()/async()` helper function to run unit tests (for details, read [testing guide](guide/testing#async-test-with-fakeasync)), you need to import `zone.js/dist/zone-testing` in your test setup file.
<div class="alert is-important">
If you create project with `Angular/CLI`, it is already imported in `src/test.ts`.
</div>
And in the earlier versions of `Angular`, the following files were imported or added in your html file:
```
import 'zone.js/dist/long-stack-trace-zone';
import 'zone.js/dist/proxy';
import 'zone.js/dist/sync-test';
import 'zone.js/dist/jasmine-patch';
import 'zone.js/dist/async-test';
import 'zone.js/dist/fake-async-test';
```
You can still load those files separately, but the order is important, you must import `proxy` before `sync-test`, `async-test`, `fake-async-test` and `jasmine-patch`. And you also need to import `sync-test` before `jasmine-patch`, so it is recommended to just import `zone-testing` instead of loading those separated files.

View File

@ -45,7 +45,7 @@ If you fully understand the meaning behind the guideline and have a good reason
**Avoid** indicates something you should almost never do. Code examples to *avoid* have an unmistakeable red header.
**Avoid** indicates something you should almost never do. Code examples to *avoid* have an unmistakable red header.
</div>
@ -2865,7 +2865,7 @@ and more difficult in a flat structure.
**Why?** NgModules make it easier to isolate, test, and re-use features.
**Why?** NgModules make it easier to isolate, test, and reuse features.
</div>

View File

@ -89,189 +89,6 @@ The root file names (`app.component`) are the same for both files.
Adopt these two conventions in your own projects for _every kind_ of test file.
{@a ci}
## Set up continuous integration
One of the best ways to keep your project bug free is through a test suite, but it's easy to forget to run tests all the time.
Continuous integration (CI) servers let you set up your project repository so that your tests run on every commit and pull request.
There are paid CI services like Circle CI and Travis CI, and you can also host your own for free using Jenkins and others.
Although Circle CI and Travis CI are paid services, they are provided free for open source projects.
You can create a public project on GitHub and add these services without paying.
Contributions to the Angular repo are automatically run through a whole suite of Circle CI and Travis CI tests.
This article explains how to configure your project to run Circle CI and Travis CI, and also update your test configuration to be able to run tests in the Chrome browser in either environment.
### Configure project for Circle CI
Step 1: Create a folder called `.circleci` at the project root.
Step 2: In the new folder, create a file called `config.yml` with the following content:
```
version: 2
jobs:
build:
working_directory: ~/my-project
docker:
- image: circleci/node:8-browsers
steps:
- checkout
- restore_cache:
key: my-project-{{ .Branch }}-{{ checksum "package.json" }}
- run: npm install
- save_cache:
key: my-project-{{ .Branch }}-{{ checksum "package.json" }}
paths:
- "node_modules"
- run: xvfb-run -a npm run test -- --single-run --no-progress --browser=ChromeNoSandbox
- run: xvfb-run -a npm run e2e -- --no-progress --config=protractor-ci.conf.js
```
This configuration caches `node_modules/` and uses [`npm run`](https://docs.npmjs.com/cli/run-script) to run CLI commands, because `@angular/cli` is not installed globally.
The double dash (`--`) is needed to pass arguments into the `npm` script.
For Chrome, it uses `xvfb-run` to run the `npm run` command using a virtual screen.
Step 3: Commit your changes and push them to your repository.
Step 4: [Sign up for Circle CI](https://circleci.com/docs/2.0/first-steps/) and [add your project](https://circleci.com/add-projects).
Your project should start building.
* Learn more about Circle CI from [Circle CI documentation](https://circleci.com/docs/2.0/).
### Configure project for Travis CI
Step 1: Create a file called `.travis.yml` at the project root, with the following content:
```
dist: trusty
sudo: false
language: node_js
node_js:
- "8"
addons:
apt:
sources:
- google-chrome
packages:
- google-chrome-stable
cache:
directories:
- ./node_modules
install:
- npm install
script:
# Use Chromium instead of Chrome.
- export CHROME_BIN=chromium-browser
- xvfb-run -a npm run test -- --single-run --no-progress --browser=ChromeNoSandbox
- xvfb-run -a npm run e2e -- --no-progress --config=protractor-ci.conf.js
```
This does the same things as the Circle CI configuration, except that Travis doesn't come with Chrome, so we use Chromium instead.
Step 2: Commit your changes and push them to your repository.
Step 3: [Sign up for Travis CI](https://travis-ci.org/auth) and [add your project](https://travis-ci.org/profile).
You'll need to push a new commit to trigger a build.
* Learn more about Travis CI testing from [Travis CI documentation](https://docs.travis-ci.com/).
### Configure CLI for CI testing in Chrome
When the CLI commands `ng test` and `ng e2e` are generally running the CI tests in your environment, you might still need to adjust your configuration to run the Chrome browser tests.
There are configuration files for both the [Karma JavaScript test runner](http://karma-runner.github.io/2.0/config/configuration-file.html)
and [Protractor](https://www.protractortest.org/#/api-overview) end-to-end testing tool,
which you must adjust to start Chrome without sandboxing.
* In the Karma configuration file, `karma.conf.js`, add a custom launcher called ChromeNoSandbox below browsers:
```
browsers: ['Chrome'],
customLaunchers: {
ChromeNoSandbox: {
base: 'Chrome',
flags: ['--no-sandbox']
}
},
```
* Create a new file, `protractor-ci.conf.js`, in the root folder of your project, which extends the original `protractor.conf.js`:
```
const config = require('./protractor.conf').config;
config.capabilities = {
browserName: 'chrome',
chromeOptions: {
args: ['--no-sandbox']
}
};
exports.config = config;
```
Now you can run the following commands to use the `--no-sandbox` flag:
```
ng test --single-run --no-progress --browser=ChromeNoSandbox
ng e2e --no-progress --config=protractor-ci.conf.js
```
{@a code-coverage}
## Enable code coverage reports
The CLI can run unit tests and create code coverage reports.
Code coverage reports show you any parts of our code base that may not be properly tested by your unit tests.
To generate a coverage report run the following command in the root of your project.
```
ng test --watch=false --code-coverage
```
When the tests are complete, the command creates a new `/coverage` folder in the project. Open the `index.html` file to see a report with your source code and code coverage values.
If you want to create code-coverage reports every time you test, you can set the following option in the CLI configuration file, `angular.json`:
```
"test": {
"options": {
"codeCoverage": true
}
}
```
### Code coverage enforcement
The code coverage percentages let you estimate how much of your code is tested.
If your team decides on a set minimum amount to be unit tested, you can enforce this minimum with the Angular CLI.
For example, suppose you want the code base to have a minimum of 80% code coverage.
To enable this, open the [Karma](http://karma-runner.github.io/0.13/index.html) test platform configuration file, `karma.conf.js`, and add the following in the `coverageIstanbulReporter:` key.
```
coverageIstanbulReporter: {
reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: true,
thresholds: {
statements: 80,
lines: 80,
branches: 80,
functions: 80
}
}
```
The `thresholds` property causes the tool to enforce a minimum of 80% code coverage when the unit tests are run in the project.
## Service Tests
Services are often the easiest files to unit test.
@ -1237,6 +1054,8 @@ value becomes available. The test must become _asynchronous_.
#### Async test with _fakeAsync()_
To use `fakeAsync()` functionality, you need to import `zone-testing`, for details, please read [setup guide](guide/setup#appendix-test-using-fakeasyncasync).
The following test confirms the expected behavior when the service returns an `ErrorObservable`.
<code-example
@ -1250,7 +1069,7 @@ Note that the `it()` function receives an argument of the following form.
fakeAsync(() => { /* test body */ })`
```
The `fakeAsync` function enables a linear coding style by running the test body in a special _fakeAsync test zone_.
The `fakeAsync()` function enables a linear coding style by running the test body in a special `fakeAsync test zone`.
The test body appears to be synchronous.
There is no nested syntax (like a `Promise.then()`) to disrupt the flow of control.
@ -1263,12 +1082,55 @@ You do have to call `tick()` to advance the (virtual) clock.
Calling `tick()` simulates the passage of time until all pending asynchronous activities finish.
In this case, it waits for the error handler's `setTimeout()`;
The `tick` function is one of the Angular testing utilities that you import with `TestBed`.
It's a companion to `fakeAsync` and you can only call it within a `fakeAsync` body.
The `tick()` function accepts milliseconds as parameter (defaults to 0 if not provided). The parameter represents how much the virtual clock advances. For example, if you have a `setTimeout(fn, 100)` in a `fakeAsync()` test, you need to use tick(100) to trigger the fn callback.
<code-example
path="testing/src/app/demo/async-helper.spec.ts"
region="fake-async-test-tick">
</code-example>
The `tick()` function is one of the Angular testing utilities that you import with `TestBed`.
It's a companion to `fakeAsync()` and you can only call it within a `fakeAsync()` body.
#### Comparing dates inside fakeAsync()
`fakeAsync()` simulates passage of time, which allows you to calculate the difference between dates inside `fakeAsync()`.
<code-example
path="testing/src/app/demo/async-helper.spec.ts"
region="fake-async-test-date">
</code-example>
#### jasmine.clock with fakeAsync()
Jasmine also provides a `clock` feature to mock dates. Angular automatically runs tests that are run after
`jasmine.clock().install()` is called inside a `fakeAsync()` method until `jasmine.clock().uninstall()` is called. `fakeAsync()` is not needed and throws an error if nested.
By default, this feature is disabled. To enable it, set a global flag before import `zone-testing`.
If you use the Angular CLI, configure this flag in `src/test.ts`.
```
(window as any)['__zone_symbol__fakeAsyncPatchLock'] = true;
import 'zone.js/dist/zone-testing';
```
<code-example
path="testing/src/app/demo/async-helper.spec.ts"
region="fake-async-test-clock">
</code-example>
#### Using the RxJS scheduler inside fakeAsync()
You can also use RxJS scheduler in `fakeAsync()` just like using `setTimeout()` or `setInterval()`, but you need to import `zone.js/dist/zone-patch-rxjs-fake-async` to patch RxJS scheduler.
<code-example
path="testing/src/app/demo/async-helper.spec.ts"
region="fake-async-test-rxjs">
</code-example>
#### Support more macroTasks
By default `fakeAsync` supports the following `macroTasks`.
By default `fakeAsync()` supports the following `macroTasks`.
- setTimeout
- setInterval
@ -1289,7 +1151,7 @@ If you run other `macroTask` such as `HTMLCanvasElement.toBlob()`, `Unknown macr
</code-pane>
</code-tabs>
If you want to support such case, you need to define the `macroTask` you want to support in `beforeEach`.
If you want to support such case, you need to define the `macroTask` you want to support in `beforeEach()`.
For example:
```javascript
@ -1386,6 +1248,8 @@ Then you can assert that the quote element displays the expected text.
#### Async test with _async()_
To use `async()` functionality, you need to import `zone-testing`, for details, please read [setup guide](guide/setup#appendix-test-using-fakeasyncasync).
The `fakeAsync()` utility function has a few limitations.
In particular, it won't work if the test body makes an `XHR` call.
@ -1409,12 +1273,13 @@ Here's the previous `fakeAsync()` test, re-written with the `async()` utility.
The `async()` utility hides some asynchronous boilerplate by arranging for the tester's code
to run in a special _async test zone_.
You don't have to pass Jasmine's `done()` into the test and call `done()`
in promise or observable callbacks.
You don't need to pass Jasmine's `done()` into the test and call `done()` because it is `undefined` in promise or observable callbacks.
But the test's asynchronous nature is revealed by the call to `fixture.whenStable()`,
which breaks the linear flow of control.
When using an `intervalTimer()` such as `setInterval()` in `async()`, remember to cancel the timer with `clearInterval()` after the test, otherwise the `async()` never ends.
{@a when-stable}
#### _whenStable_
@ -1433,18 +1298,19 @@ update the quote element with the expected text.
#### Jasmine _done()_
While the `async` and `fakeAsync` functions greatly
While the `async()` and `fakeAsync()` functions greatly
simplify Angular asynchronous testing,
you can still fall back to the traditional technique
and pass `it` a function that takes a
[`done` callback](http://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support).
You can't call `done()` in `async()` or `fakeAsync()` functions, because the `done parameter`
is `undefined`.
Now you are responsible for chaining promises, handling errors, and calling `done()` at the appropriate moments.
Writing test functions with `done()`, is more cumbersome than `async`and `fakeAsync`.
But it is occasionally necessary.
For example, you can't call `async` or `fakeAsync` when testing
code that involves the `intervalTimer()` or the RxJS `delay()` operator.
Writing test functions with `done()`, is more cumbersome than `async()`and `fakeAsync()`.
But it is occasionally necessary when code involves the `intervalTimer()` like `setInterval`.
Here are two more versions of the previous test, written with `done()`.
The first one subscribes to the `Observable` exposed to the template by the component's `quote` property.
@ -2307,7 +2173,6 @@ Here are a few more `HeroDetailComponent` tests to reinforce the point.
{@a compile-components}
### Calling _compileComponents()_
<div class="alert is-helpful">
You can ignore this section if you _only_ run tests with the CLI `ng test` command
@ -2871,7 +2736,7 @@ Here's a summary of the stand-alone functions, in order of likely utility:
<td>
When a `fakeAsync` test ends with pending timer event _tasks_ (queued `setTimeOut` and `setInterval` callbacks),
When a `fakeAsync()` test ends with pending timer event _tasks_ (queued `setTimeOut` and `setInterval` callbacks),
the test fails with a clear error message.
In general, a test should end with no queued tasks.
@ -2888,7 +2753,7 @@ Here's a summary of the stand-alone functions, in order of likely utility:
<td>
When a `fakeAsync` test ends with pending _micro-tasks_ such as unresolved promises,
When a `fakeAsync()` test ends with pending _micro-tasks_ such as unresolved promises,
the test fails with a clear error message.
In general, a test should wait for micro-tasks to finish.

View File

@ -255,7 +255,7 @@ You can combine keyframes with `duration`, `delay`, and `easing` within a single
### Keyframes with a pulsation
Use ketframes to create a pulse effect in your animations by defining styles at specific offset throughout the animation.
Use keyframes to create a pulse effect in your animations by defining styles at specific offset throughout the animation.
Here's an example of using keyframes to create a pulse effect:
@ -305,4 +305,4 @@ You may also be interested in the following:
* [Introduction to Angular animations](guide/animations)
* [Complex animation sequences](guide/complex-animation-sequences)
* [Reusable animations](guide/reusable-animations)
* [Route transition animations](guide/route-animations)
* [Route transition animations](guide/route-animations)

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -671,5 +671,14 @@
"website": "https://sajeetharan.herokuapp.com/",
"bio": "Sajeetharan is a Developer, Top contributor on stackoverflow for #Angular, ng-SriLanka organizer. He makes use of his extensive knowledge over the past years to contribute to community to make the world a better place.",
"group": "GDE"
},
"lacolaco": {
"name": "Suguru Inatomi",
"picture": "lacolaco.jpg",
"twitter": "laco2net",
"website": "https://lacolaco.net",
"bio": "Suguru is a community-loving Frontend developer and a lead of Angular Japan User Group. He organizes the largest Angular event in Japan (ng-japan). And he is a contributor to Angular by sending patches, writing, speaking, and localizing resources in Japanese.",
"group": "GDE"
}
}

View File

@ -10,9 +10,9 @@ Angular is a platform that makes it easy to build applications with the web. Ang
<p class="card-footer">Angular in Action</p>
</a>
<a href="guide/quickstart" class="docs-card" title="Angular Quickstart">
<a href="guide/quickstart" class="docs-card" title="Angular Getting Started">
<section>Get Going with Angular</section>
<p>Get going on your own environment with the Quickstart.</p>
<p>Get going on your own environment with the Getting Started.</p>
<p class="card-footer">Quickstart</p>
</a>

View File

@ -13,6 +13,12 @@
</tr>
</thead>
<tbody>
<!-- AngularMix -->
<tr>
<th><a href="https://angularmix.com/" title="AngularMix">AngularMix</a></th>
<td>Orlando, Florida</td>
<td>October 10-12, 2018</td>
</tr>
<!-- ReactiveConf -->
<tr>
<th><a href="https://reactiveconf.com/" title="ReactiveConf">ReactiveConf</a></th>
@ -59,13 +65,13 @@
<!-- ngconf 2018-->
<tr>
<th><a href="https://www.ng-conf.org/" title="ng-conf">ng-conf</a></th>
<td>Salt Lake City, UT</td>
<td>Salt Lake City, Utah</td>
<td>April 18-20, 2018</td>
</tr>
<!-- WeRDevs-->
<tr>
<th><a href="https://www.wearedevelopers.com/" title="WeAreDevs">WeAreDevelopers</a></th>
<td>Vienna</td>
<td>Vienna, Austria</td>
<td>May 16-18, 2018</td>
</tr>
<!-- ngJapan-->

View File

@ -57,14 +57,14 @@
{
"url": "guide/docs-style-guide",
"title": "Doc authors style guide",
"tooltip": "Style guide for documentation authors.",
"tooltip": "Style guide for documentation authors",
"hidden": true
},
{
"url": "guide/quickstart",
"title": "Getting Started",
"tooltip": "A brief introduction to Angular and Angular CLI essentials."
"tooltip": "A gentle introduction to Angular."
},
{
@ -73,43 +73,43 @@
"children": [
{
"url": "tutorial",
"title": "Introduction",
"tooltip": "Introduction to the Tour of Heroes tutorial"
"title": "1. Introduction",
"tooltip": "Part 1: Introduction to the Tour of Heroes tutorial"
},
{
"url": "tutorial/toh-pt0",
"title": "The Application Shell",
"tooltip": "Creating the application shell"
"title": "2. The Application Shell",
"tooltip": "Part 2: Creating the application shell"
},
{
"url": "tutorial/toh-pt1",
"title": "1. The Hero Editor",
"tooltip": "Part 1: Build a simple hero editor"
"title": "3. The Hero Editor",
"tooltip": "Part 3: Build a simple hero editor"
},
{
"url": "tutorial/toh-pt2",
"title": "2. Displaying a List",
"tooltip": "Part 2: Build a master/detail page with a list of heroes."
"title": "4. Displaying a List",
"tooltip": "Part 4: Build a master/detail page with a list of heroes."
},
{
"url": "tutorial/toh-pt3",
"title": "3. Master/Detail Components",
"tooltip": "Part 3: Refactor the master/detail view into separate components."
"title": "5. Master/Detail Components",
"tooltip": "Part 5: Refactor the master/detail view into separate components."
},
{
"url": "tutorial/toh-pt4",
"title": "4. Services",
"tooltip": "Part 4: Create a reusable service to manage hero data."
"title": "6. Services",
"tooltip": "Part 6: Create a reusable service to manage hero data."
},
{
"url": "tutorial/toh-pt5",
"title": "5. Routing",
"tooltip": "Part 5: Add the Angular router and navigate among the views."
"title": "7. Routing",
"tooltip": "Part 7: Add the Angular router and navigate among the views."
},
{
"url": "tutorial/toh-pt6",
"title": "6. HTTP",
"tooltip": "Part 6: Use HTTP to retrieve and save hero data."
"title": "8. HTTP",
"tooltip": "Part 8: Use HTTP to retrieve and save hero data."
}
]
},
@ -210,13 +210,14 @@
}
]
},
{
"title": "Forms",
"tooltip": "Angular Forms",
"children": [
{
"url": "guide/forms-overview",
"title": "Introduction",
"title": "Forms Overview",
"tooltip": "A form creates a cohesive, effective, and compelling data entry experience. An Angular form coordinates a set of data-bound user controls, tracks changes, validates input, and presents errors."
},
{
@ -240,8 +241,8 @@
"tooltip": "Render dynamic forms with FormGroup."
}
]
},
{
},
{
"title": "Observables & RxJS",
"tooltip": "Observables & RxJS",
"children": [
@ -417,29 +418,84 @@
"tooltip": "Animate route transitions."
}
]
}
]
},
},
{
"url": "guide/testing",
"title": "Testing",
"tooltip": "Techniques and practices for testing an Angular app."
},
{
"url": "guide/cheatsheet",
"title": "Cheat Sheet",
"tooltip": "A quick guide to common Angular coding techniques."
}
]},
{
"title": "Techniques",
"tooltip": "Techniques for putting Angular to work in your environment",
"children": [
{
"url": "guide/i18n",
"title": "Internationalization (i18n)",
"tooltip": "Translate the app's template text into multiple languages."
},
{
"url": "guide/language-service",
"title": "Language Service",
"tooltip": "Use Angular Language Service to speed up dev time."
},
{
"url": "guide/security",
"title": "Security",
"tooltip": "Developing for content security in Angular applications."
},
{
"url": "guide/i18n",
"title": "Internationalization (i18n)",
"tooltip": "Translate the app's template text into multiple languages."
},
"title": "Setup & Deployment",
"tooltip": "Setup and Deployment",
"children": [
{
"url": "guide/setup",
"title": "Setup for local development",
"tooltip": "Install the Angular QuickStart seed for faster, more efficient development on your machine."
},
{
"url": "guide/setup-systemjs-anatomy",
"title": "Anatomy of the Setup",
"tooltip": "Inside the local development environment for SystemJS."
},
{
"url": "guide/browser-support",
"title": "Browser Support",
"tooltip": "Browser support and polyfills guide."
},
{
"url": "guide/npm-packages",
"title": "Npm Packages",
"tooltip": "Recommended npm packages, and how to specify package dependencies."
},
{
"url": "guide/typescript-configuration",
"title": "TypeScript Configuration",
"tooltip": "TypeScript configuration for Angular developers."
},
{
"url": "guide/aot-compiler",
"title": "Ahead-of-Time Compilation",
"tooltip": "Learn why and how to use the Ahead-of-Time (AOT) compiler."
},
{
"url": "guide/deployment",
"title": "Deployment",
"tooltip": "Learn how to deploy your Angular app."
}
]
},
{
"title": "Service Workers & PWA",
"title": "Service Workers",
"tooltip": "Angular service workers: Controlling caching of application resources.",
"children": [
{
@ -469,108 +525,24 @@
}
]
},
{
"url": "guide/universal",
"title": "Server-side Rendering",
"tooltip": "Render HTML server-side with Angular Universal."
}
]
},
{
"title": "Setup & Deployment",
"tooltip": "Setup, build, testing, and deployment environment and tool information.",
"children": [
{
"url": "guide/setup",
"title": "Setup for local development",
"tooltip": "Install the Angular QuickStart seed for faster, more efficient development on your machine.",
"hidden": true
},
{
"url": "guide/file-structure",
"title": "Project File Structure",
"tooltip": "Inside the local development environment for SystemJS."
},
{
"url": "guide/npm-packages",
"title": "Packages",
"tooltip": "Explanation of npm packages installed into a project by default."
},
{
"url": "guide/typescript-configuration",
"title": "TypeScript Configuration",
"tooltip": "TypeScript configuration for Angular developers."
},
{
"url": "guide/aot-compiler",
"title": "Ahead-of-Time Compilation",
"tooltip": "Learn why and how to use the Ahead-of-Time (AOT) compiler."
},
{
"url": "guide/build",
"title": "Building & Serving",
"tooltip": "Building and serving Angular apps."
},
{
"url": "guide/testing",
"title": "Testing",
"tooltip": "Techniques and practices for testing an Angular app."
},
{
"url": "guide/deployment",
"title": "Deployment",
"tooltip": "Learn how to deploy your Angular app."
},
{
"url": "guide/browser-support",
"title": "Browser Support",
"tooltip": "Browser support and polyfills guide."
},
{
"title": "Dev Tool Integration",
"tooltip": "Integration with your development environment and tool information.",
"title": "Keeping Up-to-Date",
"tooltip": "Angular release practices, planning for updates, and update resources.",
"children": [
{
"url": "guide/language-service",
"title": "Language Service",
"tooltip": "Use Angular Language Service to speed up dev time."
},
{
"url": "guide/visual-studio-2015",
"title": "Visual Studio 2015 QuickStart",
"tooltip": "Use Visual Studio 2015 with the QuickStart files."
}
{
"url": "guide/updating",
"title": "Updating Your Projects",
"tooltip": "Information about updating Angular applications and libraries to the latest version."
},
{
"url": "guide/releases",
"title": "Angular Releases",
"tooltip": "Angular versioning, release, support, and deprecation policies and practices."
}
]
},
{
"url": "guide/setup-systemjs-anatomy",
"title": "Anatomy of the Setup",
"tooltip": "Inside the local development environment for SystemJS.",
"hidden": true
}
]
},
{
"title": "Release Information",
"tooltip": "Angular release practices, updating, and upgrading.",
"children": [
{
"url": "guide/releases",
"title": "Angular Releases",
"tooltip": "Angular versioning, release, support, and deprecation policies and practices."
},
{
"url": "guide/updating",
"title": "Keeping Up-to-Date",
"tooltip": "Information about updating Angular applications and libraries to the latest version."
},
{
"title": "Upgrading from AngularJS",
"tooltip": "Incrementally upgrade an AngularJS application to Angular.",
@ -580,25 +552,27 @@
"title": "Upgrading Instructions",
"tooltip": "Incrementally upgrade an AngularJS application to Angular."
},
{
"url": "guide/upgrade-performance",
"title": "Upgrading for Performance",
"tooltip": "Upgrade from AngularJS to Angular in a more flexible way."
},
{
"url": "guide/ajs-quick-reference",
"title": "AngularJS-Angular Concepts",
"tooltip": "Learn how AngularJS concepts and techniques map to Angular."
}
]
}
]
},
{
"title": "Quick Reference",
"tooltip": "Summaries of Angular syntax, coding, and terminology.",
"children": [
},
{
"url": "guide/cheatsheet",
"title": "Cheat Sheet",
"tooltip": "A quick guide to common Angular coding techniques."
"url": "guide/universal",
"title": "Server-side Rendering",
"tooltip": "Render HTML server-side with Angular Universal."
},
{
"url": "guide/visual-studio-2015",
"title": "Visual Studio 2015 QuickStart",
"tooltip": "Use Visual Studio 2015 with the QuickStart files."
},
{
"url": "guide/styleguide",
@ -615,20 +589,9 @@
{
"title": "API",
"tooltip": "Details of the Angular packages, classes, interfaces, and other types.",
"tooltip": "Details of the Angular classes and values.",
"url": "api"
},
{
"title": "CLI Commands",
"tooltip": "Angular CLI command reference.",
"children": [
{
"title": "Using the CLI",
"tooltip": "An overview of how to use the CLI tool",
"url": "cli"
}
]
},
{
"url": "guide/change-log",
"title": "Change Log",

View File

@ -18,20 +18,19 @@
"build-for": "yarn ~~build --configuration",
"prebuild-local": "yarn setup-local",
"build-local": "yarn ~~build --configuration=stable",
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js",
"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",
"postsetup": "yarn boilerplate:add && yarn build-ie-polyfills && yarn extract-cli-command-docs && yarn docs",
"postsetup": "yarn boilerplate:add && yarn build-ie-polyfills && yarn docs",
"presetup-local": "yarn presetup",
"setup-local": "yarn aio-use-local && yarn example-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');\"",
"test-pwa-score-localhost": "concurrently --kill-others --success first \"http-server dist -p 4200 --silent\" \"yarn test-pwa-score http://localhost:4200 90\"",
"test-pwa-score": "node scripts/test-pwa-score",
"test-pwa-score-localhost": "run-p --race \"~~http-server dist -p 4200 --silent\" \"test-pwa-score http://localhost:4200 {1} {2}\" --",
"example-e2e": "yarn example-check-local && node ./tools/examples/run-example-e2e",
"example-lint": "tslint -c \"content/examples/tslint.json\" \"content/examples/**/*.ts\" -e \"content/examples/styleguide/**/*.avoid.ts\"",
"example-use-local": "node tools/ng-packages-installer overwrite ./tools/examples/shared --debug",
@ -42,8 +41,7 @@
"postcheck-env": "yarn aio-check-local",
"payload-size": "scripts/payload.sh",
"predocs": "yarn generate-stackblitz && yarn generate-zips",
"docs": "yarn docs-only",
"docs-only": "dgeni ./tools/transforms/angular.io-package",
"docs": "dgeni ./tools/transforms/angular.io-package",
"docs-watch": "node tools/transforms/authors-package/watchr.js",
"docs-lint": "eslint --ignore-path=\"tools/transforms/.eslintignore\" tools/transforms",
"docs-test": "node tools/transforms/test.js",
@ -52,7 +50,7 @@
"tools-lint": "tslint -c \"tools/tslint.json\" \"tools/firebase-test-utils/**/*.ts\"",
"tools-test": "./scripts/deploy-to-firebase.test.sh && yarn docs-test && yarn boilerplate:test && jasmine tools/ng-packages-installer/index.spec.js && yarn firebase-utils-test",
"preserve-and-sync": "yarn docs",
"serve-and-sync": "concurrently --kill-others \"yarn docs-watch --watch-only\" \"yarn start\"",
"serve-and-sync": "run-p \"start\" \"docs-watch --watch-only\"",
"boilerplate:add": "node ./tools/examples/example-boilerplate add",
"boilerplate:remove": "node ./tools/examples/example-boilerplate remove",
"boilerplate:test": "node tools/examples/test.js",
@ -64,7 +62,8 @@
"~~check-env": "node scripts/check-environment",
"~~clean-generated": "node --eval \"require('shelljs').rm('-rf', 'src/generated')\"",
"~~build": "ng build",
"post~~build": "yarn build-404-page"
"post~~build": "yarn build-404-page",
"~~http-server": "http-server"
},
"engines": {
"node": ">=10.9.0 <11.0.0",
@ -72,40 +71,40 @@
},
"private": true,
"dependencies": {
"@angular/animations": "6.1.0-rc.3",
"@angular/cdk": "6.0.2",
"@angular/common": "6.1.0-rc.3",
"@angular/core": "6.1.0-rc.3",
"@angular/elements": "6.1.0-rc.3",
"@angular/forms": "6.1.0-rc.3",
"@angular/material": "6.0.2",
"@angular/platform-browser": "6.1.0-rc.3",
"@angular/platform-browser-dynamic": "6.1.0-rc.3",
"@angular/router": "6.1.0-rc.3",
"@angular/service-worker": "6.1.0-rc.3",
"@angular/animations": "^7.0.0-rc.1",
"@angular/cdk": "7.0.0-rc.1",
"@angular/common": "^7.0.0-rc.1",
"@angular/core": "^7.0.0-rc.1",
"@angular/elements": "^7.0.0-rc.1",
"@angular/forms": "^7.0.0-rc.1",
"@angular/material": "7.0.0-rc.1",
"@angular/platform-browser": "^7.0.0-rc.1",
"@angular/platform-browser-dynamic": "^7.0.0-rc.1",
"@angular/router": "^7.0.0-rc.1",
"@angular/service-worker": "^7.0.0-rc.1",
"@webcomponents/custom-elements": "^1.2.0",
"classlist.js": "^1.1.20150312",
"core-js": "^2.4.1",
"rxjs": "^6.3.0",
"rxjs": "6.2.2",
"tslib": "^1.9.0",
"web-animations-js": "^2.2.5",
"zone.js": "^0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "0.6.7",
"@angular/cli": "^6.1.0-rc.3",
"@angular/compiler": "6.1.0-rc.3",
"@angular/compiler-cli": "6.1.0-rc.3",
"@angular/language-service": "6.1.0-rc.3",
"@angular-devkit/build-angular": "~0.9.0-rc.1",
"@angular/cli": "^7.0.0-rc.2",
"@angular/compiler": "^7.0.0-rc.1",
"@angular/compiler-cli": "^7.0.0-rc.1",
"@angular/language-service": "^7.0.0-rc.1",
"@types/jasmine": "^2.5.52",
"@types/jasminewd2": "^2.0.3",
"@types/jasminewd2": "^2.0.4",
"@types/node": "~6.0.60",
"@yarnpkg/lockfile": "^1.1.0",
"archiver": "^1.3.0",
"canonical-path": "^0.0.2",
"chalk": "^2.1.0",
"cjson": "^0.5.0",
"codelyzer": "~4.2.1",
"concurrently": "^3.4.0",
"cross-spawn": "^5.1.0",
"css-selector-parser": "^1.3.0",
"dgeni": "^0.4.7",
@ -113,7 +112,7 @@
"entities": "^1.1.1",
"eslint": "^3.19.0",
"eslint-plugin-jasmine": "^2.2.0",
"firebase-tools": "^3.2.1",
"firebase-tools": "^5.1.1",
"fs-extra": "^2.1.2",
"globby": "^6.1.0",
"hast-util-is-element": "^1.0.0",
@ -128,17 +127,16 @@
"jasmine-spec-reporter": "^4.1.0",
"jasmine-ts": "^0.2.1",
"jsdom": "^9.12.0",
"json-schema-traverse": "^0.4.1",
"json5": "^1.0.1",
"karma": "^1.7.0",
"karma-chrome-launcher": "^2.1.1",
"karma-cli": "^1.0.1",
"karma-coverage-istanbul-reporter": "^1.3.0",
"karma-jasmine": "^1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"lighthouse": "^2.5.0",
"lighthouse": "^3.2.1",
"lodash": "^4.17.4",
"lunr": "^2.1.0",
"npm-run-all": "^4.1.5",
"protractor": "^5.2.0",
"rehype": "^4.0.0",
"rehype-slug": "^2.0.0",
@ -150,7 +148,7 @@
"tree-kill": "^1.1.0",
"ts-node": "^3.3.0",
"tslint": "~5.9.1",
"typescript": "^2.9.2",
"typescript": "^3.1.2",
"uglify-js": "^3.0.15",
"unist-util-filter": "^0.2.1",
"unist-util-source": "^1.0.1",
@ -158,7 +156,7 @@
"unist-util-visit-parents": "^1.1.1",
"vrsource-tslint-rules": "^5.8.2",
"watchr": "^3.0.1",
"webpack-cli": "^2.0.14",
"webpack-cli": "^3.1.2",
"xregexp": "^4.0.0",
"yargs": "^7.0.2"
}

View File

@ -2,10 +2,10 @@
"aio": {
"master": {
"uncompressed": {
"runtime": 2768,
"main": 476338,
"polyfills": 53922,
"prettify": 14913
"runtime": 3173,
"main": 494475,
"polyfills": 53926,
"prettify": 14917
}
}
}

View File

@ -100,8 +100,8 @@ fi
yarn payload-size
# Deploy to Firebase
firebase use "$projectId" --token "$firebaseToken"
firebase deploy --message "Commit: $TRAVIS_COMMIT" --non-interactive --token "$firebaseToken"
yarn firebase use "$projectId" --token "$firebaseToken"
yarn firebase deploy --message "Commit: $TRAVIS_COMMIT" --non-interactive --token "$firebaseToken"
# Run PWA-score tests
yarn test-pwa-score "$deployedUrl" "$AIO_MIN_PWA_SCORE"

View File

@ -6,7 +6,7 @@ set +x -eu -o pipefail
readonly aioDir="$(realpath $thisDir/..)"
readonly protractorConf="$aioDir/tests/deployment/e2e/protractor.conf.js"
readonly minPwaScore="95"
readonly minPwaScore="$1"
readonly urls=(
"https://angular.io/"
"https://next.angular.io/"

View File

@ -11,13 +11,15 @@
*/
// Imports
const chromeLauncher = require('chrome-launcher');
const lighthouse = require('lighthouse');
const chromeLauncher = require('lighthouse/chrome-launcher');
const printer = require('lighthouse/lighthouse-cli/printer');
const config = require('lighthouse/lighthouse-core/config/default.js');
const config = require('lighthouse/lighthouse-core/config/default-config.js');
const logger = require('lighthouse-logger');
// Constants
const CHROME_LAUNCH_OPTS = {};
const LIGHTHOUSE_FLAGS = {logLevel: 'info'};
const SKIPPED_HTTPS_AUDITS = ['redirects-http'];
const VIEWER_URL = 'https://googlechrome.github.io/lighthouse/viewer/';
@ -26,6 +28,7 @@ const VIEWER_URL = 'https://googlechrome.github.io/lighthouse/viewer/';
if (process.env.TRAVIS) {
process.env.LIGHTHOUSE_CHROMIUM_PATH = process.env.CHROME_BIN;
CHROME_LAUNCH_OPTS.chromeFlags = ['--no-sandbox'];
LIGHTHOUSE_FLAGS.logLevel = 'error';
}
// Run
@ -42,18 +45,20 @@ function _main(args) {
skipHttpsAudits(config);
}
launchChromeAndRunLighthouse(url, {}, config).
logger.setLevel(LIGHTHOUSE_FLAGS.logLevel);
launchChromeAndRunLighthouse(url, LIGHTHOUSE_FLAGS, config).
then(results => processResults(results, logFile)).
then(score => evaluateScore(minScore, score)).
catch(onError);
}
function evaluateScore(expectedScore, actualScore) {
console.log('Lighthouse PWA score:');
console.log(` - Expected: ${expectedScore} / 100 (or higher)`);
console.log(` - Actual: ${actualScore} / 100`);
console.log('\nLighthouse PWA score:');
console.log(` - Expected: ${expectedScore.toFixed(0).padStart(3)} / 100 (or higher)`);
console.log(` - Actual: ${actualScore.toFixed(0).padStart(3)} / 100\n`);
if (actualScore < expectedScore) {
if (isNaN(actualScore) || (actualScore < expectedScore)) {
throw new Error(`PWA score is too low. (${actualScore} < ${expectedScore})`);
}
}
@ -87,20 +92,30 @@ function parseInput(args) {
}
function processResults(results, logFile) {
let promise = Promise.resolve();
const categories = results.lhr.categories;
const report = results.report;
if (logFile) {
console.log(`Saving results in '${logFile}'...`);
console.log(`(LightHouse viewer: ${VIEWER_URL})`);
return Promise.resolve().
then(() => {
if (logFile) {
console.log(`Saving results in '${logFile}'...`);
console.log(`(LightHouse viewer: ${VIEWER_URL})`);
// Remove the artifacts, which are not necessary for the report.
// (Saves ~1,500,000 lines of formatted JSON output \o/)
results.artifacts = undefined;
return printer.write(report, printer.OutputMode.json, logFile);
}
}).
then(() => {
const categoryData = Object.keys(categories).map(name => categories[name]);
const maxTitleLen = Math.max(...categoryData.map(({title}) => title.length));
promise = printer.write(results, 'json', logFile);
}
return promise.then(() => Math.round(results.score));
console.log('\nAudit scores:');
categoryData.forEach(({title, score}) => {
const paddedTitle = `${title}:`.padEnd(maxTitleLen + 1);
const paddedScore = (score * 100).toFixed(0).padStart(3);
console.log(` - ${paddedTitle} ${paddedScore} / 100`);
});
}).
then(() => categories.pwa.score * 100);
}
function skipHttpsAudits(config) {

View File

@ -164,10 +164,10 @@ describe('AppComponent', () => {
describe('onScroll', () => {
it('should update `tocMaxHeight` accordingly', () => {
expect(component.tocMaxHeight).toBeUndefined();
component.tocMaxHeight = '';
component.onScroll();
expect(component.tocMaxHeight).toBeGreaterThan(0);
expect(component.tocMaxHeight).toMatch(/^\d+\.\d{2}$/);
});
});
@ -654,12 +654,13 @@ describe('AppComponent', () => {
it('should update the TOC container\'s `maxHeight` based on `tocMaxHeight`', () => {
setHasFloatingToc(true);
expect(tocContainer!.style['max-height']).toBe('');
component.tocMaxHeight = '100';
fixture.detectChanges();
expect(tocContainer!.style['max-height']).toBe('100px');
component.tocMaxHeight = '200';
fixture.detectChanges();
expect(tocContainer!.style['max-height']).toBe('200px');
});
it('should restrain scrolling inside the ToC container', () => {

View File

@ -349,12 +349,17 @@ export class AppComponent implements OnInit {
@HostListener('window:scroll')
onScroll() {
if (!this.tocMaxHeightOffset) {
// Must wait until now for mat-toolbar to be measurable.
// Must wait until `mat-toolbar` is measurable.
const el = this.hostElement.nativeElement as Element;
this.tocMaxHeightOffset =
el.querySelector('footer')!.clientHeight +
el.querySelector('.app-toolbar')!.clientHeight +
24; // fudge margin
const headerEl = el.querySelector('.app-toolbar');
const footerEl = el.querySelector('footer');
if (headerEl && footerEl) {
this.tocMaxHeightOffset =
headerEl.clientHeight +
footerEl.clientHeight +
24; // fudge margin
}
}
this.tocMaxHeight = (document.body.scrollHeight - window.pageYOffset - this.tocMaxHeightOffset).toFixed(2);

View File

@ -44,7 +44,7 @@ describe('ContributorService', () => {
it('contributors observable should complete', () => {
let completed = false;
contribService.contributors.subscribe(undefined, undefined, () => completed = true);
expect(true).toBe(true, 'observable completed');
expect(completed).toBe(true, 'observable completed');
});
it('should reshape the contributor json to expected result', () => {

View File

@ -44,7 +44,7 @@ describe('ResourceService', () => {
it('categories observable should complete', () => {
let completed = false;
resourceService.categories.subscribe(undefined, undefined, () => completed = true);
expect(true).toBe(true, 'observable completed');
expect(completed).toBe(true, 'observable completed');
});
it('should reshape contributors.json to sorted category array', () => {

View File

@ -138,9 +138,6 @@ describe('TocComponent', () => {
});
it('should have more than 4 displayed items', () => {
let tocList: TocItem[];
tocService.tocList.subscribe(v => tocList = v);
expect(page.listItems.length).toBeGreaterThan(4);
});

View File

@ -180,10 +180,8 @@ describe('DocumentService', () => {
describe('computeMap', () => {
it('should map the "empty" location to the correct document request', () => {
let latestDocument: DocumentContents;
const { docService } = getServices();
docService.currentDocument.subscribe(doc => latestDocument = doc);
docService.currentDocument.subscribe();
httpMock.expectOne(CONTENT_URL_PREFIX + 'index.json');
});

View File

@ -2,7 +2,9 @@ import { HttpClientTestingModule, HttpTestingController } from '@angular/common/
import { Injector } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { CurrentNodes, NavigationService, NavigationViews, NavigationNode, VersionInfo } from 'app/navigation/navigation.service';
import {
CurrentNodes, NavigationNode, navigationPath, NavigationService, NavigationViews, VersionInfo,
} from 'app/navigation/navigation.service';
import { LocationService } from 'app/shared/location.service';
import { MockLocationService } from 'testing/location.service';
@ -46,10 +48,9 @@ describe('NavigationService', () => {
it('navigationViews observable should complete', () => {
let completed = false;
navService.navigationViews.subscribe(undefined, undefined, () => completed = true);
expect(true).toBe(true, 'observable completed');
// Stop `$httpMock.verify()` from complaining.
httpMock.expectOne({});
httpMock.expectOne({method: 'get', url: navigationPath}).flush({});
expect(completed).toBe(true, 'observable completed');
});
it('should return the same object to all subscribers', () => {

View File

@ -11,7 +11,7 @@ import { CONTENT_URL_PREFIX } from 'app/documents/document.service';
import { CurrentNodes, NavigationNode, NavigationResponse, NavigationViews, VersionInfo } from './navigation.model';
export { CurrentNodes, CurrentNode, NavigationNode, NavigationResponse, NavigationViews, VersionInfo } from './navigation.model';
const navigationPath = CONTENT_URL_PREFIX + 'navigation.json';
export const navigationPath = CONTENT_URL_PREFIX + 'navigation.json';
@Injectable()
export class NavigationService {
@ -95,11 +95,8 @@ export class NavigationService {
this.location.currentPath,
(navMap, url) => {
const matchSpecialUrls = /^api|^cli/.exec(url);
if (matchSpecialUrls) {
url = matchSpecialUrls[0];
}
return navMap.get(url) || { '' : { view: '', url: url, nodes: [] }};
const urlKey = url.startsWith('api/') ? 'api' : url;
return navMap.get(urlKey) || { '' : { view: '', url: urlKey, nodes: [] }};
})
.pipe(publishReplay(1));
(currentNodes as ConnectableObservable<CurrentNodes>).connect();

View File

@ -16,7 +16,8 @@ export class CopierService {
* and makes a selection on it.
*/
createFake(text: string) {
const isRTL = document.documentElement.getAttribute('dir') === 'rtl';
const docElem = document.documentElement!;
const isRTL = docElem.getAttribute('dir') === 'rtl';
// Create a fake element to hold the contents to copy
this.fakeElem = document.createElement('textarea');
@ -34,7 +35,7 @@ export class CopierService {
this.fakeElem.style[ isRTL ? 'right' : 'left' ] = '-9999px';
// Move element to the same position vertically
const yPosition = window.pageYOffset || document.documentElement.scrollTop;
const yPosition = window.pageYOffset || docElem.scrollTop;
this.fakeElem.style.top = yPosition + 'px';
this.fakeElem.setAttribute('readonly', '');

View File

@ -91,7 +91,7 @@
<noscript>
<div class="background-sky hero"></div>
<section id="intro">
<section id="intro" style="text-shadow: 1px 1px #1976d2;">
<div class="hero-logo">
<img src="assets/images/logos/angular/angular.svg" width="250" height="250">
</div>
@ -99,7 +99,7 @@
<div class="hero-headline">One framework.<br>Mobile &amp; desktop.</div>
</div>
</section>
<h2 style="color: red; text-align: center; margin-top: -50px;">
<h2 style="color: red; margin-top: 40px; position: relative; text-align: center; text-shadow: 1px 1px #fafafa;">
<b><i>This website requires JavaScript.</i></b>
</h2>
</noscript>

View File

@ -135,6 +135,17 @@ th {
text-align: left;
}
p > code, li > code, td > code, th > code {
font-family: $code-font;
font-size: 85%;
color: $darkgray;
letter-spacing: 0;
line-height: 1;
padding: 2px 0;
background-color: $backgroundgray;
border-radius: 4px;
}
code {
font-family: $code-font;
font-size: 90%;

View File

@ -115,6 +115,7 @@ button.vertical-menu-item {
}
.heading-children.collapsed {
overflow: hidden; // Needed to prevent unnecessary sidenav scrollbar.
visibility: hidden;
opacity: 0;
max-height: 1px; // Must have measurement to transition height.

View File

@ -31,6 +31,11 @@
}
.method-table, .option-table, .list-table {
td > code {
background-color: inherit;
white-space: pre;
}
.with-github-links {
align-items: center;
display: flex;
@ -66,23 +71,6 @@
font-weight: bold;
}
.short-description {
margin: 6px 0 0 10px;
}
.properties-table {
font-size: 14px;
thead th {
&:nth-child(1) {
width: 20%;
}
&:nth-child(2) {
width: 20%;
}
}
}
.parameters-table {
margin-top: 0;
font-size: 14px;
@ -104,7 +92,7 @@
}
}
.from-constructor, .read-only-property {
.from-constructor, .read-only-property, .write-only-property {
font-style: italic;
color: $blue;
}
@ -113,6 +101,29 @@
list-style: none;
padding: 0;
}
.selector-list, .inherited-members-list {
ul {
padding: 0;
li {
list-style: none;
margin-bottom: 12px;
}
}
}
.selector-list {
li, a {
font-weight: bold;
i {
font-weight: normal;
}
}
}
.member-name {
font-weight: bold;
}
}
.deprecated-api-item {

View File

@ -1,7 +0,0 @@
.cli-name, .cli-default {
font-weight: bold;
}
.cli-option-syntax {
white-space: pre;
}

View File

@ -137,6 +137,7 @@ aio-code pre {
.sidenav-content code a {
color: inherit;
font-size: inherit;
font-weight: inherit;
}
/* PRETTY PRINTING STYLES for prettify.js. */

View File

@ -8,7 +8,6 @@
@import 'buttons';
@import 'callout';
@import 'card';
@import 'cli-pages';
@import 'code';
@import 'contribute';
@import 'contributor';

View File

@ -1,5 +1,9 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
// Reflect.metadata polyfill is only needed in the JIT mode which we use only for unit tests
import 'core-js/es6/reflect';
import 'core-js/es7/reflect';
import 'zone.js/dist/zone-testing';
import { getTestBed } from '@angular/core/testing';
import {
@ -9,10 +13,6 @@ import {
declare const require: any;
// Reflect.metadata polyfill is only needed in the JIT mode which we use only for unit tests
import 'core-js/es6/reflect';
import 'core-js/es7/reflect';
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,

View File

@ -8,7 +8,19 @@ describe('Api pages', function() {
it('should show direct and indirect subclasses of a class', () => {
const page = new ApiPage('api/forms/AbstractControlDirective');
expect(page.getDescendants('class')).toEqual(['ControlContainer', 'AbstractFormGroupDirective', 'NgControl']);
expect(page.getDescendants('class')).toEqual([
'ControlContainer',
'AbstractFormGroupDirective',
'NgModelGroup',
'FormGroupName',
'NgForm',
'FormGroupDirective',
'FormArrayName',
'NgControl',
'NgModel',
'FormControlDirective',
'FormControlName'
]);
});
it('should show child interfaces that extend an interface', () => {
@ -26,14 +38,9 @@ describe('Api pages', function() {
expect(page.getOverview('type-alias').getText()).toContain('type HttpEvent<T>');
});
it('should show readonly properties as getters', () => {
const page = new ApiPage('api/common/http/HttpRequest');
expect(page.getOverview('class').getText()).toContain('get body: T | null');
});
it('should not show parenthesis for getters', () => {
const page = new ApiPage('api/core/NgModuleRef');
expect(page.getOverview('class').getText()).toContain('get injector: Injector');
expect(page.getOverview('class').getText()).toContain('injector: Injector');
});
it('should show both type and initializer if set', () => {

View File

@ -35,7 +35,7 @@
"angular-in-memory-web-api": "^0.6.0",
"core-js": "^2.5.4",
"express": "^4.14.1",
"rxjs": "^6.3.0",
"rxjs": "^6.0.0",
"systemjs": "0.19.39",
"web-animations-js": "^2.3.1",
"zone.js": "^0.8.24"
@ -53,7 +53,7 @@
"@types/angular-route": "^1.3.5",
"@types/express": "^4.0.35",
"@types/jasmine": "~2.8.0",
"@types/jasminewd2": "^2.0.3",
"@types/jasminewd2": "^2.0.4",
"@types/jquery": "^3.3.4",
"@types/node": "^6.0.45",
"canonical-path": "0.0.2",

View File

@ -341,10 +341,10 @@
resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-2.8.4.tgz#5528fb5e53f1b27594f81f18debb7eab8dc532cb"
integrity sha512-sVK48Oni/wTt4J0MBvZs2vjObZTAL8qGt2pHPEuj5OVXEkN5983OcHvGqBOR4rvLneFBOYV+RFp6r71fRvjoNA==
"@types/jasminewd2@^2.0.3":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@types/jasminewd2/-/jasminewd2-2.0.3.tgz#0d2886b0cbdae4c0eeba55e30792f584bf040a95"
integrity sha512-hYDVmQZT5VA2kigd4H4bv7vl/OhlympwREUemqBdOqtrYTo5Ytm12a5W5/nGgGYdanGVxj0x/VhZ7J3hOg/YKg==
"@types/jasminewd2@^2.0.4":
version "2.0.5"
resolved "https://registry.yarnpkg.com/@types/jasminewd2/-/jasminewd2-2.0.5.tgz#0910db4bd50202dea9fe6ec37517b0ae6a01a9e6"
integrity sha512-1awkm/O4pQCR9hI2F80HmIOda/L+ogkSL8Arj1k00eue5VLY5ooewhSOyF/cUJE0S+/34uD5EYY3zmd6fu2OCA==
dependencies:
"@types/jasmine" "*"
@ -8366,13 +8366,6 @@ rxjs@^6.0.0:
dependencies:
tslib "^1.9.0"
rxjs@^6.3.0:
version "6.3.3"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55"
integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==
dependencies:
tslib "^1.9.0"
safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
@ -9580,16 +9573,11 @@ tsickle@^0.27.2:
source-map "^0.6.0"
source-map-support "^0.5.0"
tslib@^1.8.0, tslib@^1.8.1:
tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8"
integrity sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==
tslib@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
tslint@^5.9.1:
version "5.9.1"
resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.9.1.tgz#1255f87a3ff57eb0b0e1f0e610a8b4748046c9ae"

View File

@ -2,11 +2,14 @@
const chalk = require('chalk');
const fs = require('fs-extra');
const lockfile = require('@yarnpkg/lockfile');
const path = require('canonical-path');
const semver = require('semver');
const shelljs = require('shelljs');
const yargs = require('yargs');
const PACKAGE_JSON = 'package.json';
const YARN_LOCK = 'yarn.lock';
const LOCAL_MARKER_PATH = 'node_modules/_local_.json';
const PACKAGE_JSON_REGEX = /^[^/]+\/package\.json$/;
@ -62,8 +65,10 @@ class NgPackagesInstaller {
* contents and acts as an indicator that dependencies have been overridden.
*/
installLocalDependencies() {
if (this._checkLocalMarker() !== true || this.force) {
if (this.force || !this._checkLocalMarker()) {
const pathToPackageConfig = path.resolve(this.projectDir, PACKAGE_JSON);
const pathToLockfile = path.resolve(this.projectDir, YARN_LOCK);
const parsedLockfile = this._parseLockfile(pathToLockfile);
const packages = this._getDistPackages();
try {
@ -88,17 +93,17 @@ class NgPackagesInstaller {
});
});
fs.writeFileSync(pkg.packageJsonPath, JSON.stringify(tmpConfig));
fs.writeFileSync(pkg.packageJsonPath, JSON.stringify(tmpConfig, null, 2));
});
const packageConfigFile = fs.readFileSync(pathToPackageConfig);
const packageConfigFile = fs.readFileSync(pathToPackageConfig, 'utf8');
const packageConfig = JSON.parse(packageConfigFile);
const [dependencies, peers] = this._collectDependencies(packageConfig.dependencies || {}, packages);
const [devDependencies, devPeers] = this._collectDependencies(packageConfig.devDependencies || {}, packages);
this._assignPeerDependencies(peers, dependencies, devDependencies);
this._assignPeerDependencies(devPeers, dependencies, devDependencies);
this._assignPeerDependencies(peers, dependencies, devDependencies, parsedLockfile);
this._assignPeerDependencies(devPeers, dependencies, devDependencies, parsedLockfile);
const localPackageConfig = Object.assign(Object.create(null), packageConfig, { dependencies, devDependencies });
localPackageConfig.__angular = { local: true };
@ -107,7 +112,7 @@ class NgPackagesInstaller {
try {
this._log(`Writing temporary local ${PACKAGE_JSON} to ${pathToPackageConfig}`);
fs.writeFileSync(pathToPackageConfig, localPackageConfigJson);
this._installDeps('--no-lockfile', '--check-files');
this._installDeps('--pure-lockfile', '--check-files');
this._setLocalMarker(localPackageConfigJson);
} finally {
this._log(`Restoring original ${PACKAGE_JSON} to ${pathToPackageConfig}`);
@ -118,7 +123,7 @@ class NgPackagesInstaller {
this._log(`Restoring original ${PACKAGE_JSON} for local Angular packages.`);
Object.keys(packages).forEach(key => {
const pkg = packages[key];
fs.writeFileSync(pkg.packageJsonPath, JSON.stringify(pkg.config));
fs.writeFileSync(pkg.packageJsonPath, JSON.stringify(pkg.config, null, 2));
});
}
}
@ -134,15 +139,23 @@ class NgPackagesInstaller {
// Protected helpers
_assignPeerDependencies(peerDependencies, dependencies, devDependencies) {
_assignPeerDependencies(peerDependencies, dependencies, devDependencies, parsedLockfile) {
Object.keys(peerDependencies).forEach(key => {
const peerDepRange = peerDependencies[key];
// Ignore peerDependencies whose range is already satisfied by current version in lockfile.
const originalRange = dependencies[key] || devDependencies[key];
const lockfileVersion = originalRange && parsedLockfile[`${key}@${originalRange}`].version;
if (lockfileVersion && semver.satisfies(lockfileVersion, peerDepRange)) return;
// If there is already an equivalent dependency then override it - otherwise assign/override the devDependency
if (dependencies[key]) {
this._log(`Overriding dependency with peerDependency: ${key}: ${peerDependencies[key]}`);
dependencies[key] = peerDependencies[key];
this._log(`Overriding dependency with peerDependency: ${key}: ${peerDepRange}`);
dependencies[key] = peerDepRange;
} else {
this._log(`${devDependencies[key] ? 'Overriding' : 'Assigning'} devDependency with peerDependency: ${key}: ${peerDependencies[key]}`);
devDependencies[key] = peerDependencies[key];
this._log(`${devDependencies[key] ? 'Overriding' : 'Assigning'} devDependency with peerDependency: ${key}: ${peerDepRange}`);
devDependencies[key] = peerDepRange;
}
});
}
@ -166,11 +179,6 @@ class NgPackagesInstaller {
}
});
// FIXME: Temporarily use RxJS from root `node_modules/`.
if (peerDependencies.rxjs) {
peerDependencies.rxjs = `file:${ANGULAR_ROOT_DIR}/node_modules/rxjs`;
}
return [mergedDependencies, peerDependencies];
}
@ -226,6 +234,20 @@ class NgPackagesInstaller {
}
}
/**
* Parse and return a `yarn.lock` file.
*/
_parseLockfile(lockfilePath) {
const lockfileContent = fs.readFileSync(lockfilePath, 'utf8');
const parsed = lockfile.parse(lockfileContent);
if (parsed.type !== 'success') {
throw new Error(`[${NgPackagesInstaller.name}]: Error parsing lockfile '${lockfilePath}' (result type: ${parsed.type}).`);
}
return parsed.object;
}
_printWarning() {
const relativeScriptPath = path.relative('.', __filename.replace(/\.js$/, ''));
const absoluteProjectDir = path.resolve(this.projectDir);

View File

@ -1,6 +1,7 @@
'use strict';
const fs = require('fs-extra');
const lockfile = require('@yarnpkg/lockfile');
const path = require('canonical-path');
const shelljs = require('shelljs');
@ -11,6 +12,7 @@ describe('NgPackagesInstaller', () => {
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'));
let installer;
@ -52,13 +54,26 @@ describe('NgPackagesInstaller', () => {
beforeEach(() => {
spyOn(installer, '_checkLocalMarker');
spyOn(installer, '_installDeps');
spyOn(installer, '_setLocalMarker');
spyOn(installer, '_parseLockfile').and.returnValue({
'rxjs@^6.3.0': {version: '6.3.3'},
'zone.js@^0.8.26': {version: '0.8.27'}
});
// These are the packages that are "found" in the dist directory
dummyNgPackages = {
'@angular/core': {
parentDir: packagesDir,
packageJsonPath: `${packagesDir}/core/package.json`,
config: { peerDependencies: { 'some-package': '5.0.1' } }
config: {
peerDependencies: {
'rxjs': '^6.4.0',
'some-package': '5.0.1',
'zone.js': '~0.8.26'
}
}
},
'@angular/common': {
parentDir: packagesDir,
@ -93,10 +108,12 @@ describe('NgPackagesInstaller', () => {
dummyPackage = {
dependencies: {
'@angular/core': '4.4.1',
'@angular/common': '4.4.1'
'@angular/common': '4.4.1',
rxjs: '^6.3.0'
},
devDependencies: {
'@angular/compiler-cli': '4.4.1'
'@angular/compiler-cli': '4.4.1',
'zone.js': '^0.8.26'
}
};
dummyPackageJson = JSON.stringify(dummyPackage);
@ -104,14 +121,23 @@ describe('NgPackagesInstaller', () => {
// This is the package.json that is temporarily written to the "test" folder
// Note that the Angular (dev)dependencies have been modified to use a "file:" path
// And that the peerDependencies from `dummyNgPackages` have been added as (dev)dependencies.
// And that the peerDependencies from `dummyNgPackages` have been updated or added as
// (dev)dependencies (unless the current version in lockfile satisfies semver).
//
// For example, `zone.js@0.8.27` (from lockfile) satisfies `zone.js@~0.8.26` (from
// `@angular/core`), thus `zone.js: ^0.8.26` (from original `package.json`) is retained.
// In contrast, `rxjs@6.3.3` (from lockfile) does not satisfy `rxjs@^6.4.0 (from
// `@angular/core`), thus `rxjs: ^6.3.0` (from original `package.json`) is replaced with
// `rxjs: ^6.4.0` (from `@angular/core`).
expectedModifiedPackage = {
dependencies: {
'@angular/core': `file:${packagesDir}/core`,
'@angular/common': `file:${packagesDir}/common`
'@angular/common': `file:${packagesDir}/common`,
'rxjs': '^6.4.0'
},
devDependencies: {
'@angular/compiler-cli': `file:${toolsDir}/compiler-cli`,
'zone.js': '^0.8.26',
'some-package': '5.0.1',
typescript: '^2.4.2'
},
@ -121,12 +147,20 @@ describe('NgPackagesInstaller', () => {
});
describe('when there is a local package marker', () => {
beforeEach(() => installer._checkLocalMarker.and.returnValue(true));
it('should not continue processing', () => {
installer._checkLocalMarker.and.returnValue(true);
installer.installLocalDependencies();
expect(installer._checkLocalMarker).toHaveBeenCalled();
expect(installer._getDistPackages).not.toHaveBeenCalled();
});
it('should continue processing (without checking for local marker) if `force` is true', () => {
installer.force = true;
installer.installLocalDependencies();
expect(installer._checkLocalMarker).not.toHaveBeenCalled();
expect(installer._getDistPackages).toHaveBeenCalled();
});
});
describe('when there is no local package marker', () => {
@ -135,14 +169,14 @@ describe('NgPackagesInstaller', () => {
beforeEach(() => {
log = [];
fs.writeFileSync.and.callFake((filePath, contents) => filePath === packageJsonPath && log.push(`writeFile: ${contents}`));
spyOn(installer, '_installDeps').and.callFake(() => log.push('installDeps:'));
spyOn(installer, '_setLocalMarker');
installer._installDeps.and.callFake((...args) => log.push(`installDeps: ${args.join(' ')}`));
installer._checkLocalMarker.and.returnValue(false);
installer.installLocalDependencies();
});
it('should get the dist packages', () => {
it('should parse the lockfile and get the dist packages', () => {
expect(installer._checkLocalMarker).toHaveBeenCalled();
expect(installer._parseLockfile).toHaveBeenCalledWith(yarnLockPath);
expect(installer._getDistPackages).toHaveBeenCalled();
});
@ -150,31 +184,32 @@ describe('NgPackagesInstaller', () => {
const pkgJsonFor = pkgName => dummyNgPackages[`@angular/${pkgName}`].packageJsonPath;
const pkgConfigFor = pkgName => copyJsonObj(dummyNgPackages[`@angular/${pkgName}`].config);
const overwriteConfigFor = (pkgName, newProps) => Object.assign(pkgConfigFor(pkgName), newProps);
const stringifyConfig = config => JSON.stringify(config, null, 2);
const allArgs = fs.writeFileSync.calls.allArgs();
const firstFiveArgs = allArgs.slice(0, 5);
const lastFiveArgs = allArgs.slice(-5);
expect(firstFiveArgs).toEqual([
[pkgJsonFor('core'), JSON.stringify(overwriteConfigFor('core', {private: true}))],
[pkgJsonFor('common'), JSON.stringify(overwriteConfigFor('common', {private: true}))],
[pkgJsonFor('compiler'), JSON.stringify(overwriteConfigFor('compiler', {private: true}))],
[pkgJsonFor('compiler-cli'), JSON.stringify(overwriteConfigFor('compiler-cli', {
[pkgJsonFor('core'), stringifyConfig(overwriteConfigFor('core', {private: true}))],
[pkgJsonFor('common'), stringifyConfig(overwriteConfigFor('common', {private: true}))],
[pkgJsonFor('compiler'), stringifyConfig(overwriteConfigFor('compiler', {private: true}))],
[pkgJsonFor('compiler-cli'), stringifyConfig(overwriteConfigFor('compiler-cli', {
private: true,
dependencies: { '@angular/tsc-wrapped': `file:${toolsDir}/tsc-wrapped` }
}))],
[pkgJsonFor('tsc-wrapped'), JSON.stringify(overwriteConfigFor('tsc-wrapped', {
[pkgJsonFor('tsc-wrapped'), stringifyConfig(overwriteConfigFor('tsc-wrapped', {
private: true,
devDependencies: { '@angular/common': `file:${packagesDir}/common` }
}))],
]);
expect(lastFiveArgs).toEqual(['core', 'common', 'compiler', 'compiler-cli', 'tsc-wrapped']
.map(pkgName => [pkgJsonFor(pkgName), JSON.stringify(pkgConfigFor(pkgName))]));
.map(pkgName => [pkgJsonFor(pkgName), stringifyConfig(pkgConfigFor(pkgName))]));
});
it('should load the package.json', () => {
expect(fs.readFileSync).toHaveBeenCalledWith(packageJsonPath);
expect(fs.readFileSync).toHaveBeenCalledWith(packageJsonPath, 'utf8');
});
it('should overwrite package.json with modified config', () => {
@ -188,7 +223,7 @@ describe('NgPackagesInstaller', () => {
it('should overwrite package.json, then install deps, then restore original package.json', () => {
expect(log).toEqual([
`writeFile: ${expectedModifiedPackageJson}`,
`installDeps:`,
`installDeps: --pure-lockfile --check-files`,
`writeFile: ${dummyPackageJson}`
]);
});
@ -264,6 +299,42 @@ describe('NgPackagesInstaller', () => {
});
});
describe('_parseLockfile()', () => {
let originalLockfileParseDescriptor;
beforeEach(() => {
// Workaround for `lockfile.parse()` being non-writable.
let parse = lockfile.parse;
originalLockfileParseDescriptor = Object.getOwnPropertyDescriptor(lockfile, 'parse');
Object.defineProperty(lockfile, 'parse', {
get() { return parse; },
set(newParse) { parse = newParse; },
});
fs.readFileSync.and.returnValue('mock content');
spyOn(lockfile, 'parse').and.returnValue({type: 'success', object: {foo: {version: 'bar'}}});
});
afterEach(() => Object.defineProperty(lockfile, 'parse', originalLockfileParseDescriptor));
it('should parse the specified lockfile', () => {
installer._parseLockfile('/foo/bar/yarn.lock');
expect(fs.readFileSync).toHaveBeenCalledWith('/foo/bar/yarn.lock', 'utf8');
expect(lockfile.parse).toHaveBeenCalledWith('mock content');
});
it('should throw if parsing the lockfile fails', () => {
lockfile.parse.and.returnValue({type: 'not success'});
expect(() => installer._parseLockfile('/foo/bar/yarn.lock')).toThrowError(
'[NgPackagesInstaller]: Error parsing lockfile \'/foo/bar/yarn.lock\' (result type: not success).');
});
it('should return the parsed lockfile content as an object', () => {
const parsed = installer._parseLockfile('/foo/bar/yarn.lock');
expect(parsed).toEqual({foo: {version: 'bar'}});
});
});
describe('_printWarning()', () => {
it('should mention the message passed in the warning', () => {
installer._printWarning();

View File

@ -21,64 +21,63 @@ module.exports = function matchUpDirectiveDecorators() {
if (doc.docType === 'directive') {
doc.selector = stripQuotes(doc.directiveOptions.selector);
doc.selectorArray = doc.selector ? doc.selector.split(',') : [];
doc.exportAs = stripQuotes(doc.directiveOptions.exportAs);
doc.exportAsArray = doc.exportAs ? doc.exportAs.split(',') : [];
doc.inputs = getBindingInfo(doc.directiveOptions.inputs, doc.members, 'Input');
doc.outputs = getBindingInfo(doc.directiveOptions.outputs, doc.members, 'Output');
attachBindingInfo(doc.directiveOptions.inputs, doc.members, 'Input');
attachBindingInfo(doc.directiveOptions.outputs, doc.members, 'Output');
}
});
}
};
};
function getBindingInfo(directiveBindings, members, bindingType) {
function attachBindingInfo(directiveBindings, members, bindingType) {
const bindings = {};
// Parse the bindings from the directive decorator
if (directiveBindings) {
directiveBindings.forEach(function(binding) {
const bindingInfo = parseBinding(binding);
bindings[bindingInfo.propertyName] = bindingInfo;
});
}
if (members) {
// Parse the bindings from the directive decorator
if (directiveBindings) {
directiveBindings.forEach(function(binding) {
const bindingInfo = parseBinding(bindingType, binding);
bindings[bindingInfo.propertyName] = bindingInfo;
});
}
members.forEach(function(member) {
if (member.decorators) {
// Search for members with binding decorators
member.decorators.forEach(function(decorator) {
if (decorator.name === bindingType) {
bindings[member.name] = createBindingInfo(member.name, decorator.arguments[0] || member.name);
bindings[member.name] = createBindingInfo(bindingType, member.name, decorator.arguments[0] || member.name);
}
});
}
// Now ensure that any bindings have the associated member attached
// Note that this binding could have come from the directive decorator
// Attach binding info to the member
// Note: this may have come from the `@Directive` decorator or from a property decorator such as `@Input`.
if (bindings[member.name]) {
bindings[member.name].memberDoc = member;
member.boundTo = bindings[member.name];
}
});
}
// Convert the map back to an array
return Object.keys(bindings).map(function(key) { return bindings[key]; });
}
function stripQuotes(value) {
return (typeof(value) === 'string') ? value.trim().replace(/^(['"])(.*)\1$/, '$2') : value;
}
function parseBinding(option) {
function parseBinding(bindingType, option) {
// Directive decorator bindings are of the form: "propName : bindingName" (bindingName is optional)
const optionPair = option.split(':');
const propertyName = optionPair[0].trim();
const bindingName = (optionPair[1] || '').trim() || propertyName;
return createBindingInfo(propertyName, bindingName);
return createBindingInfo(bindingType, propertyName, bindingName);
}
function createBindingInfo(propertyName, bindingName) {
function createBindingInfo(bindingType, propertyName, bindingName) {
return {
type: bindingType,
propertyName: stripQuotes(propertyName),
bindingName: stripQuotes(bindingName)
};

View File

@ -59,7 +59,7 @@ describe('matchUpDirectiveDecorators processor', () => {
});
it('should extract inputs and outputs from the directive decorator', () => {
const docs = [{
const doc = {
docType: 'directive',
directiveOptions: {
inputs: ['in1:in2', 'in3', ' in4:in5 ', ' in6 '],
@ -70,28 +70,30 @@ describe('matchUpDirectiveDecorators processor', () => {
{ name: 'in3' },
{ name: 'in4' },
{ name: 'in6' },
{ name: 'prop1' },
{ name: 'out1' },
{ name: 'out2' },
{ name: 'out4' }
{ name: 'out4' },
{ name: 'prop2' },
]
}];
processorFactory().$process(docs);
expect(docs[0].inputs).toEqual([
{ propertyName: 'in1', bindingName: 'in2', memberDoc: docs[0].members[0] },
{ propertyName: 'in3', bindingName: 'in3', memberDoc: docs[0].members[1] },
{ propertyName: 'in4', bindingName: 'in5', memberDoc: docs[0].members[2] },
{ propertyName: 'in6', bindingName: 'in6', memberDoc: docs[0].members[3] }
]);
};
expect(docs[0].outputs).toEqual([
{ propertyName: 'out1', bindingName: 'out1', memberDoc: docs[0].members[4] },
{ propertyName: 'out2', bindingName: 'out3', memberDoc: docs[0].members[5] },
{ propertyName: 'out4', bindingName: 'out4', memberDoc: docs[0].members[6] }
processorFactory().$process([doc]);
expect(doc.members).toEqual([
{ name: 'in1', boundTo: { type: 'Input', propertyName: 'in1', bindingName: 'in2' } },
{ name: 'in3', boundTo: { type: 'Input', propertyName: 'in3', bindingName: 'in3' } },
{ name: 'in4', boundTo: { type: 'Input', propertyName: 'in4', bindingName: 'in5' } },
{ name: 'in6', boundTo: { type: 'Input', propertyName: 'in6', bindingName: 'in6' }},
{ name: 'prop1' },
{ name: 'out1', boundTo: { type: 'Output', propertyName: 'out1', bindingName: 'out1' } },
{ name: 'out2', boundTo: { type: 'Output', propertyName: 'out2', bindingName: 'out3' } },
{ name: 'out4', boundTo: { type: 'Output', propertyName: 'out4', bindingName: 'out4' }},
{ name: 'prop2' },
]);
});
it('should extract inputs and outputs from decorated properties', () => {
const docs = [{
const doc = {
docType: 'directive',
directiveOptions: {},
members: [
@ -100,21 +102,18 @@ describe('matchUpDirectiveDecorators processor', () => {
{ name: 'c1', decorators: [{ name: 'Input', arguments: [] }] },
{ name: 'd1', decorators: [{ name: 'Output', arguments: [] }] },
]
}];
processorFactory().$process(docs);
expect(docs[0].inputs).toEqual([
{ propertyName: 'a1', bindingName: 'a2', memberDoc: docs[0].members[0] },
{ propertyName: 'c1', bindingName: 'c1', memberDoc: docs[0].members[2] }
]);
expect(docs[0].outputs).toEqual([
{ propertyName: 'b1', bindingName: 'b2', memberDoc: docs[0].members[1] },
{ propertyName: 'd1', bindingName: 'd1', memberDoc: docs[0].members[3] }
};
processorFactory().$process([doc]);
expect(doc.members).toEqual([
{ name: 'a1', decorators: [{ name: 'Input', arguments: ['a2'] }], boundTo: { type: 'Input', propertyName: 'a1', bindingName: 'a2' } },
{ name: 'b1', decorators: [{ name: 'Output', arguments: ['b2'] }], boundTo: { type: 'Output', propertyName: 'b1', bindingName: 'b2' } },
{ name: 'c1', decorators: [{ name: 'Input', arguments: [] }], boundTo: { type: 'Input', propertyName: 'c1', bindingName: 'c1' } },
{ name: 'd1', decorators: [{ name: 'Output', arguments: [] }], boundTo: { type: 'Output', propertyName: 'd1', bindingName: 'd1' } },
]);
});
it('should merge directive inputs/outputs with decorator property inputs/outputs', () => {
const docs = [{
const doc = {
docType: 'directive',
directiveOptions: {
inputs: ['a1:a2'],
@ -126,16 +125,13 @@ describe('matchUpDirectiveDecorators processor', () => {
{ name: 'b1' },
{ name: 'b3', decorators: [{ name: 'Output', arguments: ['b4'] }] },
]
}];
processorFactory().$process(docs);
expect(docs[0].inputs).toEqual([
{ propertyName: 'a1', bindingName: 'a2', memberDoc: docs[0].members[0] },
{ propertyName: 'a3', bindingName: 'a4', memberDoc: docs[0].members[1] }
]);
expect(docs[0].outputs).toEqual([
{ propertyName: 'b1', bindingName: 'b2', memberDoc: docs[0].members[2] },
{ propertyName: 'b3', bindingName: 'b4', memberDoc: docs[0].members[3] }
};
processorFactory().$process([doc]);
expect(doc.members).toEqual([
{ name: 'a1', boundTo: { type: 'Input', propertyName: 'a1', bindingName: 'a2' } },
{ name: 'a3', boundTo: { type: 'Input', propertyName: 'a3', bindingName: 'a4' }, decorators: [{ name: 'Input', arguments: ['a4'] }] },
{ name: 'b1', boundTo: { type: 'Output', propertyName: 'b1', bindingName: 'b2' } },
{ name: 'b3', boundTo: { type: 'Output', propertyName: 'b3', bindingName: 'b4' }, decorators: [{ name: 'Output', arguments: ['b4'] }] },
]);
});
});

View File

@ -0,0 +1,3 @@
module.exports = function() {
return {name: 'selectors'};
};

View File

@ -3,7 +3,12 @@ module.exports = function filterBy() {
name: 'filterByPropertyValue',
process: function(list, property, value) {
if (!list) return list;
return list.filter(item => item[property] === value);
const values = Array.isArray(value) ? value : [value];
return list.filter(item => values.some(value => compare(item[property], value)));
}
};
};
};
function compare(actual, expected) {
return expected instanceof(RegExp) ? expected.test(actual) : actual === expected;
}

View File

@ -7,8 +7,19 @@ describe('filterByPropertyValue filter', () => {
it('should be called "filterByPropertyValue"', function() { expect(filter.name).toEqual('filterByPropertyValue'); });
it('should filter out items that do not match the given property value', function() {
it('should filter out items that do not match the given property string value', function() {
expect(filter.process([{ a: 1 }, { a: 2 }, { b: 1 }, { a: 1, b: 2 }, { a: null }, { a: undefined }], 'a', 1))
.toEqual([{ a: 1 }, { a: 1, b: 2 }]);
});
it('should filter out items that do not match the given property regex value', function() {
expect(filter.process([{ a: '1' }, { a: '12' }, { b: '1' }, { a: 'a' }, { a: '1', b: '2' }, { a: null }, { a: undefined }], 'a', /\d/))
.toEqual([{ a: '1' }, { a: '12' }, { a: '1', b: '2' }]);
});
it('should filter out items that do not match the given array of property regex/string values', function() {
expect(filter.process([{ a: '1' }, { a: '12' }, { b: '1' }, { a: 'a' }, { a: '1', b: '2' }, { a: null }, { a: undefined }], 'a', [/\d/, 'a']))
.toEqual([{ a: '1' }, { a: '12' }, { a: 'a' }, { a: '1', b: '2' }]);
});
});

View File

@ -3,7 +3,21 @@ module.exports = function hasValues() {
name: 'hasValues',
process: function(list, property) {
if (!list || !Array.isArray(list)) return false;
return list.some(item => item[property]);
return list.some(item => readProperty(item, property.split('.'), 0));
}
};
};
};
/**
* Search deeply into an object via a collection of property segments, starting at the
* indexed segment.
*
* E.g. if `obj = { a: { b: { c: 10 }}}` then
* `readProperty(obj, ['a', 'b', 'c'], 0)` will return true;
* but
* `readProperty(obj, ['a', 'd'], 0)` will return false;
*/
function readProperty(obj, propertySegments, index) {
const value = obj[propertySegments[index]];
return !!value && (index === propertySegments.length - 1 || readProperty(value, propertySegments, index + 1));
}

View File

@ -7,13 +7,37 @@ describe('hasValues filter', () => {
it('should be called "hasValues"', function() { expect(filter.name).toEqual('hasValues'); });
it('should return true if the specified property is truthy on any item in the list', function() {
expect(filter.process([], 'a')).toEqual(false);
expect(filter.process(0, 'a')).toEqual(false);
expect(filter.process({}, 'a')).toEqual(false);
it('should return true if the specified property path is truthy on any item in the list', function() {
expect(filter.process([{a: 1}], 'a')).toEqual(true);
expect(filter.process([{b: 2}], 'a')).toEqual(false);
expect(filter.process([{a: 1, b: 2}], 'a')).toEqual(true);
expect(filter.process([{b: 2}, {a: 1}], 'a')).toEqual(true);
expect(filter.process([{a:{b:1}}], 'a.b')).toEqual(true);
expect(filter.process([{a:{b:1}, b: 2}], 'a.b')).toEqual(true);
expect(filter.process([{b: 2}, {a:{b:1}}], 'a.b')).toEqual(true);
});
it('should return false if the value is not an object', () => {
expect(filter.process([], 'a')).toEqual(false);
expect(filter.process(0, 'a')).toEqual(false);
expect(filter.process([], 'a.b')).toEqual(false);
expect(filter.process(0, 'a.b')).toEqual(false);
});
it('should return false if the property exists but is falsy', () => {
expect(filter.process([{a: false}], 'a')).toEqual(false);
expect(filter.process([{a: ''}], 'a')).toEqual(false);
expect(filter.process([{a: 0}], 'a')).toEqual(false);
expect(filter.process([{a: null}], 'a')).toEqual(false);
expect(filter.process([{a: undefined}], 'a')).toEqual(false);
});
it('should return false if any of the properties in the path do not exist', () => {
expect(filter.process({}, 'a')).toEqual(false);
expect(filter.process({}, 'a.b')).toEqual(false);
expect(filter.process([{b: 2}], 'a')).toEqual(false);
expect(filter.process([{a: 2}], 'a.b')).toEqual(false);
expect(filter.process([{a: {}}], 'a.b.c')).toEqual(false);
});
});

View File

@ -9,12 +9,11 @@ const Package = require('dgeni').Package;
const gitPackage = require('dgeni-packages/git');
const apiPackage = require('../angular-api-package');
const contentPackage = require('../angular-content-package');
const cliDocsPackage = require('../cli-docs-package');
const { extname, resolve } = require('canonical-path');
const { existsSync } = require('fs');
const { SRC_PATH } = require('../config');
module.exports = new Package('angular.io', [gitPackage, apiPackage, contentPackage, cliDocsPackage])
module.exports = new Package('angular.io', [gitPackage, apiPackage, contentPackage])
// This processor relies upon the versionInfo. See below...
.processor(require('./processors/processNavigationMap'))

View File

@ -1,7 +0,0 @@
const shelljs = require('shelljs');
const {resolve} = require('canonical-path');
const {CONTENTS_PATH} = require('../config');
shelljs.cd(resolve(CONTENTS_PATH, 'cli-src'));
shelljs.exec('git clean -Xfd');
shelljs.exec('yarn install');

View File

@ -1,48 +0,0 @@
const {resolve} = require('canonical-path');
const Package = require('dgeni').Package;
const basePackage = require('../angular-base-package');
const contentPackage = require('../content-package');
const {CONTENTS_PATH, TEMPLATES_PATH, requireFolder} = require('../config');
// Define the dgeni package for generating the docs
module.exports = new Package('cli-docs', [basePackage, contentPackage])
// Register the services and file readers
.factory(require('./readers/cli-command'))
// Register the processors
.processor(require('./processors/processCliContainerDoc'))
.processor(require('./processors/processCliCommands'))
.processor(require('./processors/filterHiddenCommands'))
// Configure file reading
.config(function(readFilesProcessor, cliCommandFileReader) {
const CLI_SOURCE_PATH = resolve(CONTENTS_PATH, 'cli-src/node_modules/@angular/cli/help');
readFilesProcessor.fileReaders.push(cliCommandFileReader);
readFilesProcessor.sourceFiles = readFilesProcessor.sourceFiles.concat([
{
basePath: CLI_SOURCE_PATH,
include: resolve(CLI_SOURCE_PATH, '*.json'),
fileReader: 'cliCommandFileReader'
},
{
basePath: CONTENTS_PATH,
include: resolve(CONTENTS_PATH, 'cli/**'),
fileReader: 'contentFileReader'
},
]);
})
.config(function(templateFinder, templateEngine, getInjectables) {
// Where to find the templates for the CLI doc rendering
templateFinder.templateFolders.unshift(resolve(TEMPLATES_PATH, 'cli'));
// Add in templating filters and tags
templateEngine.filters = templateEngine.filters.concat(getInjectables(requireFolder(__dirname, './rendering')));
})
.config(function(convertToJsonProcessor, postProcessHtml) {
convertToJsonProcessor.docTypes = convertToJsonProcessor.docTypes.concat(['cli-command', 'cli-overview']);
postProcessHtml.docTypes = postProcessHtml.docTypes.concat(['cli-command', 'cli-overview']);
});

View File

@ -1,9 +0,0 @@
module.exports = function filterHiddenCommands() {
return {
$runAfter: ['files-read'],
$runBefore: ['processCliContainerDoc'],
$process(docs) {
return docs.filter(doc => doc.docType !== 'cli-command' || doc.hidden !== true);
}
};
};

View File

@ -1,40 +0,0 @@
const testPackage = require('../../helpers/test-package');
const processorFactory = require('./filterHiddenCommands');
const Dgeni = require('dgeni');
describe('filterHiddenCommands processor', () => {
it('should be available on the injector', () => {
const dgeni = new Dgeni([testPackage('cli-docs-package')]);
const injector = dgeni.configureInjector();
const processor = injector.get('filterHiddenCommands');
expect(processor.$process).toBeDefined();
});
it('should run after the correct processor', () => {
const processor = processorFactory();
expect(processor.$runAfter).toEqual(['files-read']);
});
it('should run before the correct processor', () => {
const processor = processorFactory();
expect(processor.$runBefore).toEqual(['processCliContainerDoc']);
});
it('should remove CLI command docs that are hidden', () => {
const processor = processorFactory();
const filtered = processor.$process([
{ docType: 'cli-command', id: 'one' },
{ docType: 'cli-command', id: 'two', hidden: true },
{ docType: 'cli-command', id: 'three', hidden: false },
{ docType: 'other-doc', id: 'four', hidden: true },
{ docType: 'other-doc', id: 'five', hidden: false },
]);
expect(filtered).toEqual([
{ docType: 'cli-command', id: 'one' },
{ docType: 'cli-command', id: 'three', hidden: false },
{ docType: 'other-doc', id: 'four', hidden: true },
{ docType: 'other-doc', id: 'five', hidden: false },
]);
});
});

View File

@ -1,68 +0,0 @@
module.exports = function processCliCommands() {
return {
$runAfter: ['extra-docs-added'],
$runBefore: ['rendering-docs'],
$process(docs) {
const navigationDoc = docs.find(doc => doc.docType === 'navigation-json');
const navigationNode = navigationDoc && navigationDoc.data['SideNav'].find(node => node.title === 'CLI Commands');
docs.forEach(doc => {
if (doc.docType === 'cli-command') {
doc.names = collectNames(doc.name, doc.commandAliases);
// Recursively process the options
processOptions(doc, doc.options);
// Add to navigation doc
if (navigationNode) {
navigationNode.children.push({ url: doc.path, title: `ng ${doc.name}` });
}
}
});
}
};
};
function processOptions(container, options) {
container.positionalOptions = [];
container.namedOptions = [];
options.forEach(option => {
if (option.type === 'boolean' && option.default === undefined) {
option.default = false;
}
// Ignore any hidden options
if (option.hidden) { return; }
option.types = option.types || [option.type];
option.names = collectNames(option.name, option.aliases);
// Now work out what kind of option it is: positional/named
if (option.positional !== undefined) {
container.positionalOptions[option.positional] = option;
} else {
container.namedOptions.push(option);
}
// Recurse if there are subcommands
if (option.subcommands) {
option.subcommands = getValues(option.subcommands);
option.subcommands.forEach(subcommand => {
subcommand.names = collectNames(subcommand.name, subcommand.aliases);
processOptions(subcommand, subcommand.options);
});
}
});
container.namedOptions.sort((a, b) => a.name > b.name ? 1 : -1);
}
function collectNames(name, aliases) {
return [name].concat(aliases);
}
function getValues(obj) {
return Object.keys(obj).map(key => obj[key]);
}

View File

@ -1,264 +0,0 @@
const testPackage = require('../../helpers/test-package');
const processorFactory = require('./processCliCommands');
const Dgeni = require('dgeni');
describe('processCliCommands processor', () => {
it('should be available on the injector', () => {
const dgeni = new Dgeni([testPackage('cli-docs-package')]);
const injector = dgeni.configureInjector();
const processor = injector.get('processCliCommands');
expect(processor.$process).toBeDefined();
});
it('should run after the correct processor', () => {
const processor = processorFactory();
expect(processor.$runAfter).toEqual(['extra-docs-added']);
});
it('should run before the correct processor', () => {
const processor = processorFactory();
expect(processor.$runBefore).toEqual(['rendering-docs']);
});
it('should collect the names (name + aliases)', () => {
const processor = processorFactory();
const doc = {
docType: 'cli-command',
name: 'name',
commandAliases: ['alias1', 'alias2'],
options: [],
};
processor.$process([doc]);
expect(doc.names).toEqual(['name', 'alias1', 'alias2']);
});
describe('options', () => {
it('should remove the hidden options', () => {
const processor = processorFactory();
const doc = {
docType: 'cli-command',
name: 'name',
commandAliases: [],
options: [
{ name: 'option1' },
{ name: 'option2', hidden: true },
{ name: 'option3' },
{ name: 'option4', hidden: true },
],
};
processor.$process([doc]);
expect(doc.namedOptions).toEqual([
jasmine.objectContaining({ name: 'option1' }),
jasmine.objectContaining({ name: 'option3' }),
]);
});
it('should collect the non-hidden positional and named options', () => {
const processor = processorFactory();
const doc = {
docType: 'cli-command',
name: 'name',
commandAliases: [],
options: [
{ name: 'named1' },
{ name: 'positional1', positional: 0},
{ name: 'named2', hidden: true },
{ name: 'positional2', hidden: true, positional: 1},
],
};
processor.$process([doc]);
expect(doc.positionalOptions).toEqual([
jasmine.objectContaining({ name: 'positional1', positional: 0}),
]);
expect(doc.namedOptions).toEqual([
jasmine.objectContaining({ name: 'named1' }),
]);
});
it('should sort the named options into order by name', () => {
const processor = processorFactory();
const doc = {
docType: 'cli-command',
name: 'name',
commandAliases: [],
options: [
{ name: 'c' },
{ name: 'a' },
{ name: 'b' },
],
};
processor.$process([doc]);
expect(doc.namedOptions).toEqual([
jasmine.objectContaining({ name: 'a' }),
jasmine.objectContaining({ name: 'b' }),
jasmine.objectContaining({ name: 'c' }),
]);
});
});
describe('subcommands', () => {
it('should convert subcommands hash into a collection', () => {
const processor = processorFactory();
const doc = {
docType: 'cli-command',
name: 'name',
commandAliases: [],
options: [{
name: 'supercommand',
subcommands: {
subcommand1: {
name: 'subcommand1',
options: [
{ name: 'subcommand1-option1' },
{ name: 'subcommand1-option2' },
],
},
subcommand2: {
name: 'subcommand2',
options: [
{ name: 'subcommand2-option1' },
{ name: 'subcommand2-option2' },
],
}
},
}],
};
processor.$process([doc]);
expect(doc.options[0].subcommands).toEqual([
jasmine.objectContaining({ name: 'subcommand1' }),
jasmine.objectContaining({ name: 'subcommand2' }),
]);
});
it('should remove the hidden subcommand options', () => {
const processor = processorFactory();
const doc = {
docType: 'cli-command',
name: 'name',
commandAliases: [],
options: [{
name: 'supercommand',
subcommands: {
subcommand1: {
name: 'subcommand1',
options: [
{ name: 'subcommand1-option1' },
{ name: 'subcommand1-option2', hidden: true },
],
},
subcommand2: {
name: 'subcommand2',
options: [
{ name: 'subcommand2-option1', hidden: true },
{ name: 'subcommand2-option2' },
],
}
},
}],
};
processor.$process([doc]);
expect(doc.options[0].subcommands[0].namedOptions).toEqual([
jasmine.objectContaining({ name: 'subcommand1-option1' }),
]);
expect(doc.options[0].subcommands[1].namedOptions).toEqual([
jasmine.objectContaining({ name: 'subcommand2-option2' }),
]);
});
it('should collect the non-hidden positional arguments and named options', () => {
const processor = processorFactory();
const doc = {
docType: 'cli-command',
name: 'name',
commandAliases: [],
options: [{
name: 'supercommand',
subcommands: {
subcommand1: {
name: 'subcommand1',
options: [
{ name: 'subcommand1-option1' },
{ name: 'subcommand1-option2', positional: 0 },
],
},
subcommand2: {
name: 'subcommand2',
options: [
{ name: 'subcommand2-option1', hidden: true },
{ name: 'subcommand2-option2', hidden: true, positional: 1 },
],
}
},
}],
};
processor.$process([doc]);
expect(doc.options[0].subcommands[0].positionalOptions).toEqual([
jasmine.objectContaining({ name: 'subcommand1-option2', positional: 0}),
]);
expect(doc.options[0].subcommands[0].namedOptions).toEqual([
jasmine.objectContaining({ name: 'subcommand1-option1' }),
]);
expect(doc.options[0].subcommands[1].positionalOptions).toEqual([]);
expect(doc.options[0].subcommands[1].namedOptions).toEqual([]);
});
it('should sort the named subcommand options into order by name', () => {
const processor = processorFactory();
const doc = {
docType: 'cli-command',
name: 'name',
commandAliases: [],
options: [{
name: 'supercommand',
subcommands: {
subcommand1: {
name: 'subcommand1',
options: [
{ name: 'c' },
{ name: 'a' },
{ name: 'b' },
]
}
}
}],
};
processor.$process([doc]);
expect(doc.options[0].subcommands[0].namedOptions).toEqual([
jasmine.objectContaining({ name: 'a' }),
jasmine.objectContaining({ name: 'b' }),
jasmine.objectContaining({ name: 'c' }),
]);
});
});
it('should add the command to the CLI node in the navigation doc', () => {
const processor = processorFactory();
const command = {
docType: 'cli-command',
name: 'command1',
commandAliases: ['alias1', 'alias2'],
options: [],
path: 'cli/command1',
};
const navigation = {
docType: 'navigation-json',
data: {
SideNav: [
{ url: 'some/page', title: 'Some Page' },
{ url: 'cli', title: 'CLI Commands', children: [
{ url: 'cli', title: 'Using the CLI' },
]},
{ url: 'other/page', title: 'Other Page' },
]
}
};
processor.$process([command, navigation]);
expect(navigation.data.SideNav[1].title).toEqual('CLI Commands');
expect(navigation.data.SideNav[1].children).toEqual([
{ url: 'cli', title: 'Using the CLI' },
{ url: 'cli/command1', title: 'ng command1' },
]);
});
});

View File

@ -1,11 +0,0 @@
module.exports = function processCliContainerDoc() {
return {
$runAfter: ['extra-docs-added'],
$runBefore: ['rendering-docs'],
$process(docs) {
const cliDoc = docs.find(doc => doc.id === 'cli/index');
cliDoc.id = 'cli-container';
cliDoc.commands = docs.filter(doc => doc.docType === 'cli-command');
}
};
};

View File

@ -1,23 +0,0 @@
const testPackage = require('../../helpers/test-package');
const processorFactory = require('./processCliContainerDoc');
const Dgeni = require('dgeni');
describe('processCliContainerDoc processor', () => {
it('should be available on the injector', () => {
const dgeni = new Dgeni([testPackage('cli-docs-package')]);
const injector = dgeni.configureInjector();
const processor = injector.get('processCliContainerDoc');
expect(processor.$process).toBeDefined();
});
it('should run after the correct processor', () => {
const processor = processorFactory();
expect(processor.$runAfter).toEqual(['extra-docs-added']);
});
it('should run before the correct processor', () => {
const processor = processorFactory();
expect(processor.$runBefore).toEqual(['rendering-docs']);
});
});

View File

@ -1,47 +0,0 @@
/**
* This file reader will pull the contents from a cli command json file
*
* The doc will initially have the form:
* ```
* {
* startingLine: 1,
* ...
* }
* ```
*/
module.exports = function cliCommandFileReader(log) {
const json5 = require('json5');
return {
name: 'cliCommandFileReader',
defaultPattern: /\.json$/,
getDocs(fileInfo) {
try {
const doc = json5.parse(fileInfo.content);
const name = fileInfo.baseName;
const path = `cli/${name}`;
// We return a single element array because content files only contain one document
const result = Object.assign(doc, {
content: doc.description,
docType: 'cli-command',
startingLine: 1,
id: `cli-${doc.name}`,
commandAliases: doc.aliases || [],
aliases: computeAliases(doc),
path,
outputPath: `${path}.json`,
breadCrumbs: [
{ text: 'CLI', path: 'cli' },
{ text: name, path },
]
});
return [result];
} catch (e) {
log.warn(`Failed to read cli command file: "${fileInfo.relativePath}" - ${e.message}`);
}
}
};
};
function computeAliases(doc) {
return [doc.name].concat(doc.aliases || []).map(alias => `cli-${alias}`);
}

View File

@ -1,124 +0,0 @@
const cliCommandReaderFactory = require('./cli-command');
const reader = cliCommandReaderFactory();
const content = `
{
"name": "add",
"description": "Add support for a library to your project.",
"longDescription": "Add support for a library in your project, for example adding \`@angular/pwa\` which would configure\\nyour project for PWA support.\\n",
"hidden": false,
"type": "custom",
"options": [
{
"name": "collection",
"description": "The package to be added.",
"type": "string",
"required": false,
"aliases": [],
"hidden": false,
"positional": 0
},
{
"name": "help",
"description": "Shows a help message.",
"type": "boolean",
"required": false,
"aliases": [],
"hidden": false
},
{
"name": "helpJson",
"description": "Shows the metadata associated with each flags, in JSON format.",
"type": "boolean",
"required": false,
"aliases": [],
"hidden": false
}
],
"aliases": ['a'],
"scope": "in"
}
`;
const fileInfo = {content, baseName: 'add'};
describe('cli-command reader', () => {
describe('getDocs', () => {
it('should return an array containing a single doc', () => {
const docs = reader.getDocs(fileInfo);
expect(docs.length).toEqual(1);
});
it('should return a cli-command doc', () => {
const docs = reader.getDocs(fileInfo);
expect(docs[0]).toEqual(jasmine.objectContaining({
id: 'cli-add',
docType: 'cli-command',
}));
});
it('should extract the name from the fileInfo', () => {
const docs = reader.getDocs(fileInfo);
expect(docs[0].name).toEqual('add');
});
it('should compute the id and aliases', () => {
const docs = reader.getDocs(fileInfo);
expect(docs[0].id).toEqual('cli-add');
expect(docs[0].aliases).toEqual(['cli-add', 'cli-a']);
});
it('should compute the path and outputPath', () => {
const docs = reader.getDocs(fileInfo);
expect(docs[0].path).toEqual('cli/add');
expect(docs[0].outputPath).toEqual('cli/add.json');
});
it('should compute the bread crumbs', () => {
const docs = reader.getDocs(fileInfo);
expect(docs[0].breadCrumbs).toEqual([
{ text: 'CLI', path: 'cli' },
{ text: 'add', path: 'cli/add' },
]);
});
it('should start at line 1', () => {
const docs = reader.getDocs(fileInfo);
expect(docs[0].startingLine).toEqual(1);
});
it('should extract the short description into the content', () => {
const docs = reader.getDocs(fileInfo);
expect(docs[0].content).toEqual('Add support for a library to your project.');
});
it('should extract the long description', () => {
const docs = reader.getDocs(fileInfo);
expect(docs[0].longDescription).toEqual('Add support for a library in your project, for example adding `@angular/pwa` which would configure\nyour project for PWA support.\n');
});
it('should extract the command type', () => {
const docs = reader.getDocs(fileInfo);
expect(docs[0].type).toEqual('custom');
});
it('should extract the command scope', () => {
const docs = reader.getDocs(fileInfo);
expect(docs[0].scope).toEqual('in');
});
it('should extract the command aliases', () => {
const docs = reader.getDocs(fileInfo);
expect(docs[0].commandAliases).toEqual(['a']);
});
it('should extract the options', () => {
const docs = reader.getDocs(fileInfo);
expect(docs[0].options).toEqual([
jasmine.objectContaining({ name: 'collection' }),
jasmine.objectContaining({ name: 'help' }),
jasmine.objectContaining({ name: 'helpJson' }),
]);
});
});
});

View File

@ -1,6 +0,0 @@
module.exports = function cliNegate() {
return {
name: 'cliNegate',
process: function(str) { return 'no' + str.charAt(0).toUpperCase() + str.slice(1); }
};
};

View File

@ -1,17 +0,0 @@
var factory = require('./cliNegate');
describe('cliNegate filter', function() {
var filter;
beforeEach(function() { filter = factory(); });
it('should be called "cliNegate"', function() { expect(filter.name).toEqual('cliNegate'); });
it('should make the first char uppercase and add `no` to the front', function() {
expect(filter.process('abc')).toEqual('noAbc');
});
it('should make leave the rest of the chars alone', function() {
expect(filter.process('abCdE')).toEqual('noAbCdE');
});
});

View File

@ -1,21 +1,9 @@
{% import "lib/memberHelpers.html" as memberHelpers -%}
{% import "lib/descendants.html" as descendants -%}
{% import "lib/paramList.html" as params -%}
{% extends 'export-base.template.html' -%}
{% block overview %}
{% include "includes/class-overview.html" %}
{% endblock %}
{% block details %}
{% block additional %}{% endblock %}
{% include "includes/description.html" %}
{$ memberHelpers.renderProperties(doc.staticProperties, 'static-properties', 'static-property', 'Static properties') $}
{$ memberHelpers.renderMethodDetails(versionInfo, doc.staticMethods, 'static-methods', 'static-method', 'Static methods') $}
{% if doc.constructorDoc %}
<h2>Constructor</h2>
{$ memberHelpers.renderMethodDetail(versionInfo, doc.constructorDoc, 'constructor') $}{% endif %}
{$ memberHelpers.renderProperties(doc.properties, 'instance-properties', 'instance-property', 'Properties') $}
{$ memberHelpers.renderMethodDetails(versionInfo, doc.methods, 'instance-methods', 'instance-method', 'Methods') $}
{% include "includes/class-members.html" %}
{% endblock %}

View File

@ -1,14 +1,28 @@
{% import "lib/directiveHelpers.html" as directiveHelper -%}
{% import "lib/paramList.html" as params -%}
{% import "lib/memberHelpers.html" as memberHelpers -%}
{% extends 'class.template.html' -%}
{% block overview %}{% include "includes/directive-overview.html" %}{% endblock %}
{% block additional -%}
{% include "includes/ngmodule.html" %}
{% include "includes/selectors.html" %}
{$ directiveHelper.renderBindings(doc.inputs, 'inputs', 'input', 'Inputs') $}
{$ directiveHelper.renderBindings(doc.outputs, 'outputs', 'output', 'Outputs') $}
{% include "includes/export-as.html" %}
{% endblock %}
{% block overview %}{% endblock %}
{% block annotations %}{% endblock %}
{% block details -%}
{% include "includes/ngmodule.html" %}
{% include "includes/selectors.html" %}
{$ memberHelpers.renderDirectiveProperties(doc, 'Properties') $}
{% include "includes/export-as.html" %}
{% if doc.description or doc.usageNotes %}
<section class="description">
<h2>Description</h2>
{$ (doc.description or '') | trimBlankLines | marked $}
{$ (doc.usageNotes or '') | trimBlankLines | marked $}
</section>
{% endif %}
{$ memberHelpers.renderProperties(doc.staticProperties, 'static-properties', 'static-property', 'Static properties') $}
{$ memberHelpers.renderMethodDetails(versionInfo, doc.staticMethods, 'static-methods', 'static-method', 'Static methods') $}
{$ memberHelpers.renderMethodDetails(versionInfo, doc.methods, 'instance-methods', 'instance-method', 'Methods') $}
{$ memberHelpers.renderDirectiveAncestors(doc, 'methods') $}
{% endblock %}
{% block endNotes %}{% endblock %}

View File

@ -10,5 +10,5 @@ enum {$ doc.name $} {{$ memberHelpers.renderMembers(doc) $}
</section>
{% include "includes/description.html" %}
{$ memberHelpers.renderProperties(doc.properties, 'members', 'member', 'Members', ['Member', 'Value']) $}
{$ memberHelpers.renderProperties(doc.properties, 'members', 'member', 'Members', ['Member']) $}
{% endblock %}

View File

@ -1,11 +1,14 @@
{% extends 'base.template.html' -%}
{% block body %}
<p class="short-description">{$ doc.shortDescription | marked $}</p>
<section class="short-description">
{$ doc.shortDescription | marked $}
{% if doc.description %}<p><a href="#description">See more...</a></p>{% endif %}
</section>
{% include "includes/security-notes.html" %}
{% include "includes/deprecation.html" %}
{% block overview %}{% endblock %}
{% include "includes/see-also.html" %}
{% block details %}{% endblock %}
{% include "includes/usageNotes.html" %}
{% block endNotes %}{% include "includes/usageNotes.html" %}{% endblock %}
{% endblock %}

View File

@ -0,0 +1,14 @@
{% import "lib/memberHelpers.html" as memberHelpers -%}
{$ memberHelpers.renderProperties(doc.staticProperties, 'static-properties', 'static-property', 'Static properties') $}
{$ memberHelpers.renderMethodDetails(versionInfo, doc.staticMethods, 'static-methods', 'static-method', 'Static methods') $}
{% if doc.constructorDoc %}
<h2>Constructor</h2>
{$ memberHelpers.renderMethodDetail(versionInfo, doc.constructorDoc, 'constructor') $}
{% endif %}
{$ memberHelpers.renderProperties(doc.properties, 'instance-properties', 'instance-property', 'Properties') $}
{$ memberHelpers.renderMethodDetails(versionInfo, doc.methods, 'instance-methods', 'instance-method', 'Methods') $}

View File

@ -1,9 +1,10 @@
{% import "lib/memberHelpers.html" as memberHelper -%}
{% import "lib/descendants.html" as descendants -%}
<section class="{$ doc.docType $}-overview">
<code-example language="ts" hideCopy="true" linenums="false">
{% if doc.isAbstract %}abstract {% endif%}class {$ doc.name $}{$ doc.typeParams | escape $}{$ memberHelper.renderHeritage(doc) $} {{$ memberHelper.renderMembers(doc) $}
}
</code-example>
{$ descendants.renderDescendants(doc, 'class', 'Subclasses') $}
{$ descendants.renderDescendants(doc, 'class', 'Subclasses', true, r/class|directive|pipe|decorator/) $}
</section>

View File

@ -1,12 +0,0 @@
{% import "lib/memberHelpers.html" as memberHelper -%}
<section class="{$ doc.docType $}-overview">
<code-example language="ts" hideCopy="true">{% for decorator in doc.decorators %}
@{$ decorator.name $}({$ decorator.arguments $}){% endfor %}
class {$ doc.name $}{$ doc.typeParams | escape $}{$ memberHelper.renderHeritage(doc) $} {
{%- if doc.statics.length %}{% for member in doc.statics %}{% if not member.internal %}
<a class="code-anchor" href="#{$ member.anchor | urlencode $}">{$ memberHelper.renderMemberSyntax(member, 1) $}</a>{% endif %}{% endfor %}{% endif -%}
{$ memberHelper.renderMembers(doc) $}
}
</code-example>
</section>

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