Compare commits

..

231 Commits

Author SHA1 Message Date
818f4a751e release: cut the 4.4.1 release 2017-09-15 15:35:25 -07:00
4e7d2bd5bf docs: add changelog for 4.4.0 2017-09-15 14:58:32 -07:00
395ac510f7 release: cut the 4.4.0 release 2017-09-15 14:51:21 -07:00
b20c5d2c37 fix(upgrade): remove code setting id attribute. (#19182)
The id was leftover from previous iterations of ngUpgrade and is
no longer needed. Moreover, setting it can clash with CSS usage of id.

Fixes #18446

PR Close #19182
2017-09-15 17:19:50 -04:00
ea02b1ccfa fix(upgrade): remove code setting id attribute.
The id was leftover from previous iterations of ngUpgrade and is
no longer needed. Moreover, setting it can clash with CSS usage of id.

Fixes #18446
2017-09-15 17:19:50 -04:00
0bafd03e85 revert: test(packaging): added test for source map correctness
This reverts commit 86f7b4170c.
2017-09-15 11:55:29 -07:00
e8d1858c64 revert: build(platform-browser): fix typo
This reverts commit 991a802a8e.
2017-09-15 13:47:07 -04:00
d1efc5ae90 revert: fix(upgrade): remove code setting id attribute
This reverts commit 1302e54947.
2017-09-13 13:19:19 -07:00
86f7b4170c test(packaging): added test for source map correctness 2017-09-13 13:48:36 -04:00
9d93c859d7 build(aio): auto-link more code items
We now parse all code blocks, after they have been rendered by dgeni
and insert links to API docs that match "words" in the code.
2017-09-12 14:06:26 -04:00
5baa069b16 docs(aio): fix typo 2017-09-12 14:06:14 -04:00
12b7d00747 fix(aio): relax search on titles further
This change will now match `ControlValueAccessor` for the query `accessor`.

Closes #18872
2017-09-12 14:06:02 -04:00
d777d79c61 build(aio): do not render annotations block for directives 2017-09-12 14:05:46 -04:00
062a772e48 build(aio): improve rendering of directive selectors 2017-09-12 14:05:41 -04:00
3618cc6d34 build(aio): do not render comments in decorators
Closes #18873
2017-09-12 14:05:35 -04:00
9413ca8a2e build(aio): update karma & systemjs config for HttpClient
While adding the references to the `HttpClient` packages it also crucially
adds ref to new “tslib” library required by `HttpClient`.
2017-09-12 13:46:12 -04:00
1302e54947 fix(upgrade): remove code setting id attribute.
The id was leftover from previous iterations of ngUpgrade and is
no longer needed. Moreover, setting it can clash with CSS usage of id.

Fixes #18446
2017-09-08 16:30:18 -07:00
edf423af3d build(aio): update package.json for angular-in-mem-web-api 0.4.0 2017-09-08 18:25:20 -04:00
37086748bf docs(aio): provide link text for AbstractControl references in reactive directives for forms
Closes #17484
2017-09-08 18:25:14 -04:00
6c3f1f70ba build(aio): render metadata members from decorator ancestors 2017-09-08 18:25:08 -04:00
8a8c4d37aa build(aio): render ancestor members in directives
See `CheckBoxRequiredValidator` for an example.
2017-09-08 18:25:00 -04:00
f6a7183c52 fix(tsc-wrapped): fix metadata symbol reference 2017-09-08 17:26:28 -04:00
c86e16db5f feat(aio): include more API results in search
By adding a more relaxed search on the title
of docs, we are more likely to catch API docs.

The additional search terms match anything
with a word in the title that starts with the
characters of the first term in the search.

E.g. if the search is "ngCont guide" then
search for "ngCont guide titleWords:ngCont*"
2017-09-08 17:01:39 -04:00
c3907893c1 build(aio): don't show constructor detail if there is none 2017-09-08 17:01:39 -04:00
d61c6f996a build(aio): support rendering of constructor overloads in API docs
Closes #18258
2017-09-08 17:01:39 -04:00
bd04cd61f8 docs(aio): change Stack Overflow link 2017-09-08 16:29:17 -04:00
96dcfafe45 docs(aio): Updated jqwidgets resource desc and url
Updated the description and url of the jqwidgets item in the resources page
2017-09-07 16:07:52 -04:00
991a802a8e build(platform-browser): fix typo
fixes #19033
2017-09-07 16:07:27 -04:00
48ae1a6574 fix(tsc-wrapped): deduplicate metadata for re-exported modules 2017-09-07 16:06:12 -04:00
dd2d1be006 fix(aio): align footer background image repeat (#19035)
Refs #17465
PR Close #19035
2017-09-05 23:25:06 -05:00
5369de80d6 docs(aio): add changelog, as hidden, to navigation (#19028)
This ensures that the changelog page is formatted correctly.

Closes #17604

PR Close #19028
2017-09-05 23:25:06 -05:00
552dbfc2f1 docs(aio): add Nir Kaufman to GDE resources (#19012)
PR Close #19012
2017-09-05 23:25:06 -05:00
0aa4cbdbc8 docs(forms): clarify ControlValueAccessor docs (#19008)
Closes #18174

PR Close #19008
2017-09-05 23:25:06 -05:00
9f16c2620c docs(aio): updating about page for team changes (#19003)
PR Close #19003
2017-09-05 23:25:06 -05:00
9b256a9144 build(aio): render the extends ancestors of classes in API docs (#18927)
PR Close #18927
2017-09-05 23:25:06 -05:00
0f1476be33 build(aio): ensure dgeni can load all angular Typescript modules (#18927)
PR Close #18927
2017-09-05 23:25:06 -05:00
769b2aada2 docs(aio): add new lib to Data Libraries (#18656)
add AngularCommerse, set of components to build e-commerce solutions with Angular + Firebase

PR Close #18656
2017-09-05 23:25:06 -05:00
301236e1a5 docs(aio): Updated usage of Observables in router guide. Added section for advanced redirects (#18197)
PR Close #18197
2017-09-05 23:25:06 -05:00
aeb98dbcdf docs: add changelog for 4.4.0-RC.0 2017-09-01 22:01:41 -07:00
8036d05412 release: cut the 4.4.0-RC.0 release 2017-09-01 23:49:51 -05:00
7d137d7f88 fix(core): complete EventEmitter in QueryList on component destroy (#18902)
Fixes #18741

PR Close #18902
2017-09-01 22:52:03 -05:00
b8b551cf2b perf(core): add option to remove blank text nodes from compiled templates (#18823)
PR Close #18823
2017-09-01 13:30:04 -05:00
7ec28fe9af feat(compiler): allow multiple exportAs names (#18723)
This change allows users to specify multiple exportAs names for a
directive by giving a comma-delimited list inside the string.

The primary motivation for this change is to allow these names to be
changed in a backwards compatible way.

PR Close #18723
2017-09-01 13:26:10 -05:00
1cc3fe21b6 fix(animations): do not leak DOM nodes/styling for host triggered animations (#18853)
Closes #18606

PR Close #18853
2017-09-01 10:24:14 -07:00
ba7d70e5e0 build: fix changelog to remove AIO line items (#18956)
fixes 18740

PR Close #18956
2017-08-30 18:10:56 -07:00
497e0178cc fix(compiler): normalize the locale name (#18963)
PR Close #18963
2017-08-30 17:48:08 -07:00
8821723526 fix(common): fix XSSI prefix stripping by using JSON.parse always (#18466)
Currently HttpClient sends requests for JSON data with the
XMLHttpRequest.responseType set to 'json'. With this flag, the browser
will attempt to parse the response as JSON, but will return 'null' on
any errors. If the JSON response contains an XSSI-prevention prefix,
this will cause the browser's parsing to fail, which is unrecoverable.

The only compelling reason to use the responseType 'json' is for
performance (especially if the browser offloads JSON parsing to a
separate thread). I'm not aware of any browser which does this currently,
nor of any plans to do so. JSON.parse and responseType 'json' both
end up using the same V8 code path in Chrome to implement the parse.

Thus, this change switches all JSON parsing in HttpClient to use
JSON.parse directly.

Fixes #18396, #18453.

PR Close #18466
2017-08-29 17:19:02 -07:00
a203a959ae fix(common): fix improper packaging for @angular/common/http (#18613)
PR Close #18613
2017-08-29 17:16:56 -07:00
dfe2bad663 build: Add GitHub scripts for rebasing PRs (#18359)
PR Close #18359
2017-08-28 18:33:11 -05:00
f09a266e01 docs: add changelog for 4.3.6 2017-08-23 15:01:42 -05:00
3853fff795 release: cut the 4.3.6 release 2017-08-23 14:59:49 -05:00
641be64544 docs(aio): add info about --local option in the readme (#18824)
PR Close #18824
2017-08-23 13:19:23 -05:00
bcf211bdb3 docs(aio): fix "Error handling" section in "HttpClient" (#18821)
Removed additional curly brackets to fix blocks. Also replaced tab with 2 spaces.

PR Close #18821
2017-08-23 13:19:15 -05:00
ee5591d583 fix(core): make sure onStable runs in the right zone (#18706)
Make sure the callbacks to the NgZone callbacks run in the right zone
with or without the rxjs Zone patch -
1ed83d08ac.

PR Close #18706
2017-08-23 13:18:47 -05:00
1f43713506 fix(aio): do not redirect API pages on archive and next deployments (#18791)
PR Close #18791
2017-08-21 18:34:55 -05:00
325b9b4562 docs(aio): add ngAtlanta to the events page (#18649)
PR Close #18649
2017-08-21 18:34:25 -05:00
88abdbd50b docs(aio): update resources to include NinjaCodeGen Angular CRUD generator (#18518)
PR Close #18518
2017-08-21 18:34:17 -05:00
14d34c9bdf style(animations): format integration spec (#18805)
PR Close #18805
2017-08-21 17:09:53 -05:00
e1f45a33b7 fix(animations): restore auto-style support for removed DOM nodes (#18787)
PR Close #18787
2017-08-18 23:32:41 -05:00
9a754f9f0f fix(animations): make sure animation cancellations respect AUTO style values (#18787)
Closes #17450

PR Close #18787
2017-08-18 23:32:34 -05:00
c3dcbf9cb3 fix(animations): make sure @.disabled respects disabled parent/sub animation sequences (#18715)
Prior to this fix if @parent and @child animations ran at the same
time within a disabled region then there was a chance that a @child
sub animation would never complete. This would cause *directives to
never close a removal when a @child trigger was placed on them. This
patch fixes this issue.

PR Close #18715
2017-08-18 23:32:28 -05:00
5d68c830d2 fix(animations): ensure animations are disabled on the element containing the @.disabled flag (#18714)
Prior to fix this fix, @.disabled would only work to disable child
animations. Now it will also disable animations for the element that has
the @.disabled flag (which makes more sense).

PR Close #18714
2017-08-18 23:32:21 -05:00
ac58914b97 feat(animations): allow @.disabled property to work without an expression (#18713)
PR Close #18713
2017-08-18 23:32:13 -05:00
Joe
77ebd2b020 docs(aio): fix card inconsistency (#18726)
PR Close #18726
2017-08-18 23:15:36 -05:00
fec3b1a0e9 fix(core): correct order in ContentChildren query result (#18326)
Fixes #16568

PR Close #18326
2017-08-18 23:15:17 -05:00
3b571a4f3d build(aio): do not auto-link code elements already inside a link (#18776)
Closes #18769

PR Close #18776
2017-08-18 13:38:43 -05:00
Tea
efee81eb57 docs(aio): typo in template-syntax guide (#18765)
PR Close #18765
2017-08-18 13:38:16 -05:00
a7a698c36f docs(aio): update resource for codelyzer (#18742)
PR Close #18742
2017-08-18 13:22:11 -05:00
b5f1dc32d1 test(aio): fix error logged during tests (#18659)
The fixed test expected there to be a doc version without a URL. This used to be
the case but not any more. As a result, an error was logged in the test output
(but no failure).

This commit fixes it by ensuring that a version without a URL exists.

PR Close #18659
2017-08-18 13:20:22 -05:00
eef28144ce docs(aio): move code snippet to appropriate location (#18650)
PR Close #18650
2017-08-18 13:19:15 -05:00
f9b290570e fix(animations): resolve error when using AnimationBuilder with platform-server (#18642)
Use an injected DOCUMENT instead of assuming the global 'document'
exists.

Fixes #18635.

PR Close #18642
2017-08-18 13:15:05 -05:00
4852f55875 build(packaging): increase node memory for tests (#18731)
PR Close #18731
2017-08-18 13:15:05 -05:00
793f31b9b3 feat(common): add an empty DeprecatedI18NPipesModule module
Adding an empty module to ease the migration to the i18n pipes.
2017-08-18 13:15:05 -05:00
7e94405271 docs: add changelog for 4.3.5 2017-08-16 10:51:23 -07:00
6076a8d7bb release: cut the 4.3.5 release 2017-08-16 10:49:38 -07:00
a1624f217c fix(forms): re-assigning options should not clear select
Fixes #18330
2017-08-16 10:34:23 -07:00
b2f4d53bf0 docs(forms): fix reactive-forms guide typo
closes #17943
2017-08-15 16:43:21 -07:00
7662cefe6f docs: remove TypeScript to JavaScript guide & sample 2017-08-15 16:35:01 -07:00
1cb607697a build(aio): switch from @angular/http to @angular/common/http
```
$ ls -l dist/*.js

 14942            dist/0.b19e913fbdd6507d346b.chunk.js
  1535            dist/inline.a1b446562b36eebb766d.bundle.js
524385  (+  682)  dist/main.19fec4390ff7837ee6ef.bundle.js
 37402            dist/polyfills.9f7e0e53bce2a6c8326e.bundle.js
 54001            dist/worker-basic.min.js

632265  (+  682)  total
```
2017-08-15 15:16:10 -07:00
1990c3c722 build(aio): upgrade zone.js to 0.8.16
```
$ ls -l dist/*.js

 14942            dist/0.b19e913fbdd6507d346b.chunk.js
  1535            dist/inline.a1b446562b36eebb766d.bundle.js
523703            dist/main.19fec4390ff7837ee6ef.bundle.js
 37402  (+ 3088)  dist/polyfills.9f7e0e53bce2a6c8326e.bundle.js
 54001            dist/worker-basic.min.js

631583  (+ 3088)  total
```
2017-08-15 15:16:10 -07:00
b589d85d6f build(aio): upgrade @angular/* to 5.0.0-beta.3
```
$ ls -l dist/*.js

 14942            dist/0.b19e913fbdd6507d346b.chunk.js
  1535            dist/inline.7813f9128903f164bc00.bundle.js
523703  (-18484)  dist/main.19fec4390ff7837ee6ef.bundle.js
 34314            dist/polyfills.9b05df3b6c9270ebf575.bundle.js
 54001            dist/worker-basic.min.js

628495  (-18484)  total
```
2017-08-15 15:16:10 -07:00
03ec3a2169 build(aio): upgrade @angular/* to 4.3.4
```
$ ls -l dist/*.js

 14942            dist/0.b19e913fbdd6507d346b.chunk.js
  1535            dist/inline.dd77b84267809087d225.bundle.js
542187  (+ 2191)  dist/main.f3ffdb5bb1a5bcec2163.bundle.js
 34314            dist/polyfills.9b05df3b6c9270ebf575.bundle.js
 54001            dist/worker-basic.min.js

646979  (+ 2191)  total
```
2017-08-15 15:16:10 -07:00
a5baed6b97 build(aio): upgrade @angular/cli to 1.3.0
```
$ ls -l dist/*.js

 14942  (+    4)  dist/0.b19e913fbdd6507d346b.chunk.js
  1535            dist/inline.e07e02e29b7fc93816c6.bundle.js
539996  (-56433)  dist/main.f466098a873c1169a6dc.bundle.js
 34314  (-   33)  dist/polyfills.9b05df3b6c9270ebf575.bundle.js
 54001            dist/worker-basic.min.js

644788  (-56462)  total
```
2017-08-15 15:16:10 -07:00
259fc91305 docs(core): correct code examples for ChangeDetectorRef 2017-08-15 15:12:35 -07:00
a618d6e4ce docs(forms): add api docs for AbstractControlDirective 2017-08-15 15:07:44 -07:00
b315a84ba0 docs(aio): add Metadata guide based on Chuck’s docs
Chuck’s gist
https://gist.github.com/chuckjaz/65dcc2fd5f4f5463e492ed0cb93bca60#file-Angular%20Metadata-md
Also chuck’s doc on metadata-related errors (link needed)
2017-08-15 12:21:23 -07:00
972538be7a fix(core): forbid destroyed views to be inserted or moved in VC
Fixes #18615
2017-08-14 12:09:22 -07:00
d7be4f12b5 perf(aio): update to new version of build-optimizer 2017-08-11 13:29:01 -07:00
b9c1c913c1 fix(aio): skip PWA test when redeploying non-public commit 2017-08-11 13:29:01 -07:00
06e479ff66 docs: add changelog for 4.3.4 2017-08-10 09:40:01 -07:00
0065868f37 release: cut the 4.3.4 release 2017-08-10 09:38:13 -07:00
77fa3c3e48 test(aio): fix tests for example-boilerplate (#18619)
PR #18520 was accidentally merged into 4.3.x, which uses a different
location for building `tsc-wrapped`. This commit reverts the changes
from #18520 that were not compatible with 4.3.x.
2017-08-09 20:28:43 -07:00
f4cb45345d test(aio): fix running docs examples against local builds (#18520)
This commit also updates the version of `@angular/cli` used for docs examples.
The previous (transient) dependency `@ngtools/webpack` was not compatible with
`@angular/compiler-cli@>=5` and was breaking when running against the local
builds (currently at 5.0.0-beta.2). The version of `@ngtools/webpack` used by
the latest `@angular/cli` version is compatible with `@angular/compiler-cli@5`.
2017-08-09 14:21:39 -07:00
9329bfb86a fix(aio): add missing code snippet (#18547)
The snippet got lost some time during the migration from the old version (it is
[present in v2][1]).

[1]: https://v2.angular.io/docs/ts/latest/cookbook/aot-compiler.html#!#running-the-application

Fixes #18544
2017-08-09 14:20:50 -07:00
3efc88fb81 test(aio): fix the deploy-to-firebase tests
This commit also ensures that if the tests fail, the script exits with an error.

closes #18595
2017-08-09 14:18:07 -07:00
954b09022a ci(aio): fix deploying the stable branch to Firebase
The `deploy-to-firebase.sh` always expects there to be a
`src/extra-files/<mode>` directory and breaks if it doesn't exist.
2017-08-09 14:17:47 -07:00
71f5e78bcb test(animations): disable buggy test in Chrome 39 (#18483)
Fixes #15793
2017-08-09 14:16:03 -07:00
f0c3ed0f14 ci(aio): fix deploying to firebase (#18590) 2017-08-08 14:00:59 -07:00
c8fd3f5237 docs(common): fix the DatePipe API docs (#18548) 2017-08-07 11:47:38 -07:00
e0660b1b72 fix(animations): support persisting dynamic styles within animation states (#18468)
Closes #18423
Closes #17505
2017-08-07 11:40:34 -07:00
5a165ebcef fix(animations): revert container/queried animations accordingly during cancel (#18516) 2017-08-07 11:39:04 -07:00
3212f8c826 docs(aio): typo & update the bio (#18559) 2017-08-07 10:20:52 -07:00
c421ccaae9 ci(aio): compute AIO deployment mode
There are now 3 modes for deployment: next, stable, archive.
We compute which mode (and other deployment properties)
from the `TRAVIS_BRANCH` and the `STABLE_BRANCH`.

If the TRAVIS_BRANCH is master we deploy as "next".
If the `TRAVIS_BRANCH` matches the `STABLE_BRANCH` we deploy as "stable".

Otherwise if the branch has a major version lower than the stable version
and its minor version is highest of similar branches we deploy as "archive".

For "archive" deployments we compute the firebase project and deployment
url based on the major version of the `TRAVIS_BRANCH`.

As well as choosing where to deploy the build, we also use this
to select the environment file for the AIO Angular app.
This will enable the app to change its rendering and behaviour
based on its mode.

See #18287
2017-08-04 09:15:38 -07:00
bbec7db7ba feat(aio): add "archive" and "next" color themes 2017-08-04 09:15:38 -07:00
00134ae4e0 feat(aio): redirect marketing pages to docs if deploy mode is archive
See #18287
2017-08-04 09:15:38 -07:00
07bd459baa feat(aio): add deploy mode to version picker
See #18287
2017-08-04 09:15:38 -07:00
302adf1081 feat(aio): enable deployment mode to be set via URL query
The deployment mode set from the environment provided at build time;
or overridden by the `mode` query parameter: e.g. `...?mode=archive`

See #18287
2017-08-04 09:15:38 -07:00
1a6a13425b feat(aio): update UI based on deployment mode
* Add a banner if the mode is "archive"
* Add a `mode-...` class to the `aio-shell` element to enable
mode based theming.

See #18287
2017-08-04 09:15:38 -07:00
072a772ca6 ci(aio): include extra files in AIO deployment based on mode
Any files that are inside the `extra-files/{mode}` folder
will be copied over to the `dist` folder before deployment
to Firebase.

See #18287
2017-08-04 09:15:38 -07:00
5f0e0a46fd ci(aio): compute AIO deployment mode
There are now 3 modes for deployment: next, stable, archive.
We compute which mode (and other deployment properties)
from the `TRAVIS_BRANCH` and the `STABLE_BRANCH`.

If the TRAVIS_BRANCH is master we deploy as "next".
Otherwise if the branch is the highest of its minor versions
we deploy as "stable" if the `TRAVIS_BRANCH` matches the `STABLE_BRANCH` or
else "archive".

For "archive" deployments we compute the firebase project and deployment
url based on the major version of the `TRAVIS_BRANCH`.

As well as choosing where to deploy the build, we also use this
to select the environment file for the AIO Angular app.
This will enable the app to change its rendering and behaviour
based on its mode.

See #18287
2017-08-04 09:15:38 -07:00
c7b72aa575 docs(aio): tech edits to form validation (PR #18495) 2017-08-03 13:58:22 -07:00
732eb61957 docs(forms): update and re-organize validation guide 2017-08-03 13:57:58 -07:00
e7e7622971 fix(compiler): ignore @import in multi-line css (#18452)
Fixes #18038
2017-08-03 11:01:24 -07:00
4176832266 refactor(router): compile router cleanly with TypeScript 2.4 (#18465) 2017-08-02 17:32:27 -07:00
71de92a189 docs(router): fix typo (#18479) 2017-08-02 17:31:33 -07:00
e0021d4cf5 refactor(platform-browser): compiler platform-browser packages cleanly (#18464) 2017-08-02 16:31:14 -07:00
4e44102e31 refactor(forms): compile forms cleanly with TypeScript 2.4 (#18462) 2017-08-02 16:29:57 -07:00
111b70d108 refactor(upgrade): compile upgrade cleanly with TypeScript 2.4 (#18461) 2017-08-02 16:28:38 -07:00
5e4054b8f3 fix(compiler): cleanly compile with TypeScript 2.4 (#18456) 2017-08-02 16:27:14 -07:00
5afc7abcb0 fix(benchpress): compile cleanly with TS 2.4 (#18455) 2017-08-02 16:24:33 -07:00
65d0888708 fix(aio): fix layout of the webpack guide (#18493)
This is possibly a temporary fix for the layout, until we decide whether we want
to remove the guide or properly add it to the SideNav menu.

Fixes #17912
2017-08-02 16:01:02 -07:00
adfd2373b8 ci(aio): Add commit message to payload data (#18137) 2017-08-02 15:59:54 -07:00
3a82af3bde docs(aio): fix missing anchor-open in i18n documentation (#18476)
The Internationalisation documentation, "Translate text nodes" section, has an incomplete
markdown anchor, and leaks markdown into the page. Fix the anchor by adding the opening bracket.
2017-08-02 15:56:25 -07:00
3af62306b4 fix(aio): correctly redirect cookbook/a1-a2-quick-reference.html (#18418)
Fixes #18415
2017-08-02 15:54:49 -07:00
afe339396f test(common): skip some DatePipe tests in old Chrome where Intl is buggy (#15784) 2017-08-02 15:52:27 -07:00
c4b51bf689 docs(aio): replace old blog link in footer (#18448)
Fixes #18233
2017-08-02 15:46:25 -07:00
b65fe3e44e ci: remove chromium fold reference (#18445) 2017-08-02 15:44:26 -07:00
116ee334fb build(aio): use cli 1.3.0-rc (#18290) 2017-08-02 15:37:39 -07:00
dbc5c5817a docs: improve github labels by introducing "PR target" labels (#18436)
I also renamed all "pr_*" lables to "PR *" lables, removed obsolete
"chore" label, and added docs label.
2017-08-02 15:31:56 -07:00
baf4ce0dd0 build: enable TSLint on the packages folder (#18459)
porting PRs #18392 and #18441 to 4.x
2017-08-02 15:23:33 -07:00
24db1ed938 docs: add changelog for 4.3.3 2017-08-02 13:00:35 -07:00
82798e9d04 release: cut the 4.3.3 release 2017-08-02 12:57:34 -07:00
da8bb1b45b docs(aio): fixed list format in FormArray section 2017-07-31 11:40:27 -07:00
f5cbc2ee25 fix(compiler): fix for element needing implicit parent placed in top-level ng-container
fixes #18314
2017-07-31 11:40:20 -07:00
cbc1986c6f fix(aio): fix links to source for paths with symlinks
Fixes #18353
2017-07-31 11:39:47 -07:00
0982f993cb ci: short-circuit npm install for aio builds that use yarn only 2017-07-31 11:39:41 -07:00
a5a29b0591 docs(aio): delay ngUpgrade e2e test to avoid flakes 2017-07-31 11:39:36 -07:00
a8f3197f24 build: short-circuit build for AIO tasks 2017-07-31 11:39:31 -07:00
e6f37120fe docs(aio): fix deprecated protractor API usage
`browser.getLocationAbsUrl()` is deprecated.
We should use `browser.getCurrentUrl()` instead.
2017-07-31 11:39:25 -07:00
6840b7bda9 ci(aio): test the example e2e files using local build of Angular 2017-07-31 11:39:21 -07:00
68f458909a build(aio): ignore generated aot files
Assets such as images and data which are generated
by the aot build were not being ignored.
2017-07-31 11:39:14 -07:00
12acecf756 docs(aio): remove generated styles.css file
This file should have been ignored as it is created
during the build of the example
2017-07-31 11:39:10 -07:00
cfbed40ab6 build(aio): support overriding the Angular packages in examples with locally built ones 2017-07-31 11:39:03 -07:00
fe1a6b8e42 build(aio): refactor and test the example-boilerplate tool 2017-07-31 11:38:59 -07:00
13e29c4e89 ci: shard the aio example e2e tests 2017-07-31 11:38:53 -07:00
fd52b178ed ci(aio): support sharding of example e2e tests 2017-07-31 11:38:48 -07:00
ca1f071b2e build(aio): upgrade @angular/material to 2.0.0-meta.8 2017-07-31 11:38:43 -07:00
296adbbb72 build(aio): upgrade @angular/* to 4.3.1 2017-07-31 11:38:37 -07:00
c795ee1176 docs(aio): fix URLSearchParams interface link to MDN
Fixes #18367
2017-07-31 11:38:33 -07:00
b550618afd refactor(aio): move content-specific images to content/images/
Fixes #17053
2017-07-31 11:38:28 -07:00
d08d6eebff refactor(aio): rename unused directories to _unused 2017-07-31 11:38:23 -07:00
e9789abd05 fix(aio): fix link to logo in example 2017-07-31 11:38:17 -07:00
f2ec2cbb99 refactor(aio): move unused images to unused directories
This prevents the ServiceWorker from prefetching unnecessary files.
2017-07-31 11:38:09 -07:00
8de2ace80a docs: add changelog for 4.3.2 2017-07-27 15:51:46 -05:00
c977994864 release: cut the 4.3.2 release 2017-07-27 15:51:46 -05:00
12b8e1af55 Revert "fix(router): should throw when lazy loaded module doesn't define any routes (#15001)"
This reverts commit be49e0ee93.
2017-07-27 13:05:36 -07:00
9a188485f5 ci: correct bad bazel merge 2017-07-27 12:43:29 -07:00
45a10419bc Revert "build: Bazel builds ngfactories for packages/core (#18289)"
This reverts commit bcea196530.
2017-07-27 10:51:41 -07:00
2245748c14 test(compiler): fix xliff2 integration test for the 4.3 branch (#18363)
Closes #18363
2017-07-27 10:20:34 -07:00
bcea196530 build: Bazel builds ngfactories for packages/core (#18289)
PR Close #18289
2017-07-26 16:31:26 -07:00
b9e32c833a fix(router): child CanActivate guard should wait for parent to complete (#18110)
Closes #15670

PR Close #18110
2017-07-26 17:52:47 -05:00
be49e0ee93 fix(router): should throw when lazy loaded module doesn't define any routes (#15001)
Closes #14596

PR Close #15001
2017-07-26 16:49:50 -05:00
bf95655a1a docs(aio): add my details as a contributor (#18315)
PR Close #18315
2017-07-26 16:49:50 -05:00
6bf5b84fa4 fix(aio): correctly process markdown link in "Browser Support" (#18349)
The markdown processor expects an empty line between an opening tag and the
markdown content. (If there is no empty line, the content is interpreted as
plain HTML.)
Previously, the line between the opening `<td>` and the content contained
whitespace, which caused the content to be interpreted as HTML and not markdown.

Fixes #18312

PR Close #18349
2017-07-26 16:11:11 -05:00
4836565ca7 docs(aio): update examples to 4.3 2017-07-26 12:08:29 -05:00
750e4e8156 docs(aio) - Fixed link to the glossary dash-case term (#18311)
PR Close #18311
2017-07-26 12:08:29 -05:00
a0846194b7 fix(compiler): add equiv & disp attributes to Xliff2 ICU placeholders (#18283)
Fixes #17344

PR Close #18283
2017-07-26 12:08:29 -05:00
bcf6b90c95 docs(platform-server): inline PlatformOptions and add doc strings (#18264)
Fix documentation for the options passed into renderModule and
renderModuleFactory.

PR Close #18264
2017-07-26 12:08:29 -05:00
3ca2a0aa37 refactor(compiler-cli): add support for browser compiler bundle (#17979)
PR Close #17979
2017-07-26 12:08:29 -05:00
b4be96c65d ci: use chrome stable (#18307) 2017-07-26 12:08:29 -05:00
434ff5fecb build: update bazel rules to latest (#18289) 2017-07-26 12:08:24 -05:00
a1bb9c2d42 fix(core): invoke error handler outside of the Angular Zone (#18269)
In Node.JS console.log/error/warn functions actually resuls in a socket
write which in turn is considered by Zone.js as an async task.

This means that if there is any exception during change detection in a platform-server
application the error handler will make the Angular Zone unstable which
in turn will cause change detection to run on next tick and cause an
infinite loop.

It is also better to run the error handler outside of the Angular Zone
in general on all platforms so that an error in the error handler itself doesn't cause an
infinite loop.

Fixes #17073, #7774.

PR Close #18269
2017-07-26 12:04:47 -05:00
7e626bef0a ci: force precise on Travis (#18282)
PR Close #18282
2017-07-26 12:04:47 -05:00
a1e83a8ed2 test: fix bad merge (#18267)
PR Close #18267
2017-07-26 12:04:47 -05:00
cbeb197aa5 fix(animations): export BrowserModule as apart of BrowserAnimationsModule (#18263)
PR Close #18263
2017-07-26 12:04:47 -05:00
0330fa6b82 docs(aio): pngcrush all pngs (#18243)
PR Close #18243
2017-07-26 12:04:47 -05:00
97135e8fd5 fix(platform-server): don't clobber parse5 properties when setting (#18237)
element properties.

Fixes #17050.

We now store all element properties in a separate 'properties' bag.

PR Close #18237
2017-07-26 12:04:47 -05:00
35bd07fc7b refactor(common): CleanUp HttpClient's imports (#18120)
PR Close #18120
2017-07-26 12:04:47 -05:00
a8ac77b645 fix(compiler): allow numbers for ICU message cases in lexer (#18095)
Closes #18095
Fixes #17799
2017-07-26 12:04:47 -05:00
9ecd377a51 ci(aio): fix aio payload script 2017-07-26 12:04:47 -05:00
76171bd8b4 test(upgrade): fail tests when there are AngularJS errors (#18209) 2017-07-26 12:04:47 -05:00
1f106d75bc fix(upgrade): throw error if trying to get injector before setting (#18209)
Previously, `undefined` would be returned.
This change makes it easier to identify incorrect uses/bugs.
(Discussed in https://github.com/angular/angular/pull/18213#issuecomment-316191308.)
2017-07-26 12:04:47 -05:00
a4fae8c405 aio: debounce search and delay index building (#18134)
* feat(aio): debounce search requests

* feat(aio): delay loading search worker and index
2017-07-26 12:04:46 -05:00
33c07b3394 fix(aio): invalid formatting in architecure.md (#18159)
Introduced in e110a80caf (diff-9ac9c6a9277eea9856d75249a7c0a40aL127)
2017-07-26 12:00:01 -05:00
c9d06e676f docs(aio): replace old blog link (#18252)
Fixes #18233
* Docs(aio): Replaced old blog link Now with the Link to the new Angular.io Blog
* Removed double braces
2017-07-26 12:00:01 -05:00
c7c65d9fda docs: fixing invisible tag in README (#18245) 2017-07-26 12:00:01 -05:00
257a9e3e6f ci: test bazel builds on travis (#18240) 2017-07-26 12:00:01 -05:00
c7c0a1688e docs(aio): Fixed typo with closing div 2017-07-26 12:00:00 -05:00
7e95e2b0ba docs(aio): Fix http guide 2017-07-26 12:00:00 -05:00
ddc286f4b5 docs: fix wrong link in CONTRIBUTING.md (#18228)
The link to the CONTRIBUTING.md file was not correct
2017-07-26 12:00:00 -05:00
3d17a3672e docs(router): minor typo (#18226)
Fix a minor typo in the description of a router spec.
2017-07-26 12:00:00 -05:00
61d253f5fd docs(aio): fix typo in NgModule FAQs (#18211)
Fix #18133. Fix typo 'added' to 'add' in the 'Why does lazy loading create a child injector' section.
2017-07-26 12:00:00 -05:00
54be25a7a1 docs: add changelog for 4.3.1 2017-07-19 12:54:45 -07:00
b1757037fb release: cut the 4.3.1 release 2017-07-19 12:53:17 -07:00
f0476fcff0 fix(compiler-cli): don't generate empty <target/> when extracting xliff
Fixes #15754
2017-07-19 09:50:09 -07:00
a5c4bb5b96 fix(animations): make sure @.disabled works in non-animation components
Note 4.3 only!

Prior to this fix when [@.disabled] was used in a component that
contained zero animation code it wouldn't register properly because the
renderer associated with that component was not an animation renderer.
This patch ensures that it gets registered even when there are no
animations set.
2017-07-19 09:50:03 -07:00
4c1f32b0db fix(animations): do not crash animations if a nested component fires CD during CD
Closes #18193
2017-07-19 09:49:57 -07:00
383d8969ab fix(animations): always camelcase style property names that contain auto styles
Closes #17938
2017-07-19 09:49:47 -07:00
333ffd8d32 fix(animations): capture cancelled animation styles within grouped animations
Closes #17170
2017-07-19 09:49:42 -07:00
d4679a0bc2 docs(aio): fix typo in Router documentation
Fix title and link to RouteConfigLoadEnd documentation
2017-07-19 15:02:14 +01:00
4ce29f3a5b fix(platform-server): provide XhrFactory for HttpClient 2017-07-18 14:19:18 -07:00
17b7bc3e06 fix(common): send flushed body as error instead of null
fix #18181
2017-07-18 10:58:27 -07:00
f19bd5f4f3 docs(http): Make name of injected HttpTestingController consistent 2017-07-18 10:54:42 -07:00
d503d25f29 docs(platform-server): add doc string for PlatformOptions 2017-07-18 10:54:37 -07:00
5d275e994a fix(router): terminal route in custom matcher 2017-07-18 10:54:32 -07:00
d8c8b13bb8 docs: fix typo 2017-07-18 10:54:26 -07:00
4671168635 fix(compiler): ensure jit external id arguments names are unique
Fixes: #17558, #17378, #8676
2017-07-18 10:54:21 -07:00
1ac78bfd5d fix(router): canDeactivate guards should run from bottom to top
Closes #15657.
2017-07-18 10:54:15 -07:00
4340beacea fix(router): should navigate to the same url when config changes
Closes #15535
2017-07-18 10:54:09 -07:00
ec89f378fc fix(router): should run resolvers for the same route concurrently
Fixes #14279
2017-07-18 10:54:04 -07:00
4dd6863bc2 docs(aio): fix HttpClient setting new header sample 2017-07-18 10:53:58 -07:00
37c626e673 fix(aio): remove title attribute from CodeExampleComponent
This was causing browser to add an unwanted tooltip that appeared
when the user hovers over the code.

See #17524
2017-07-18 17:55:54 +01:00
f0a110928b fix(aio): add quote to module 2017-07-18 17:54:51 +01:00
c39e7d1eb2 fix(aio): do not wrap <code-tabs> tab labels
Fixes #17751
2017-07-18 17:45:20 +01:00
799bffb431 docs(aio): fix cheatsheet layout for narrow screens
* Tell the app that this will have no Table of Contents, since we have no
h2 headings anyway.
* Remove all the `nbsp;` from the code since that doesn't help with layout
* Remove side padding from sidenav-content when screen is narrow
* Restyle the cheatsheet table when the screen is narrow
2017-07-18 17:33:36 +01:00
fda607cc2f build(aio): fail doc-gen if referenced images are missing 2017-07-18 11:46:15 +01:00
cc3aa68123 docs(aio): fix broken image sources 2017-07-18 11:46:15 +01:00
306621d2d6 docs(aio): fix up broken links 2017-07-18 11:46:15 +01:00
d204f7aa2a build(aio): abort doc-gen on dangling links 2017-07-18 11:46:14 +01:00
a94f5e8cbb build(aio): abort doc-gen if an example is missing
Closes #16936
2017-07-18 11:46:14 +01:00
1390afef23 docs: fix HttpClient sample 2017-07-17 14:18:41 -07:00
b0346a6e45 docs(aio): fix HttpClient's interceptor sample 2017-07-17 14:18:41 -07:00
e5da059994 docs(http): fix "Expecting and answering requests" example mistake
Possibly overlooked testing documentation mistake fixed:
- `http.get('/data')` probably ought to be paired with `httpMock.expectOne('/data')` instead of `httpMock.expectOne('/data')`.
2017-07-17 14:18:41 -07:00
ac92c3bb26 docs: fix HttpClient logging's sample 2017-07-17 14:18:41 -07:00
87157d7089 docs(http): fixed syntax error in AuthInterceptor example 2017-07-17 14:18:41 -07:00
611dd12f0f ci: add GK and PBD to aio content and marketing groups 2017-07-17 14:18:41 -07:00
969ce9dc2b fix(aio): remove title from callout 2017-07-15 15:39:40 +01:00
34834a9e79 fix(aio): remove unused news.html file
Although outdated and not used, the file would be picked up and showed in search
results.
2017-07-15 15:29:59 +01:00
6e2ddccc2c build(aio): render type parameters of API function exports
Fixes #18123
2017-07-15 08:54:34 +01:00
55742e4737 Revert "revert: revert: ci(aio): exclude changes in aio/content folder"
This reverts commit 3d85f72652.

Still causing repeated flakes on master.
2017-07-14 14:55:56 -07:00
0091b1e8db refactor(upgrade): clean up some types 2017-07-14 14:55:46 -07:00
1613 changed files with 9620 additions and 57659 deletions

View File

@ -41,8 +41,8 @@ jobs:
- restore_cache:
key: angular-{{ .Branch }}-{{ checksum "npm-shrinkwrap.json" }}
- run: bazel run @nodejs//:npm install
- run: bazel build packages/...
- run: bazel run @build_bazel_rules_typescript_node//:bin/npm install
- run: bazel build ...
- save_cache:
key: angular-{{ .Branch }}-{{ checksum "npm-shrinkwrap.json" }}
paths:

1
.gitignore vendored
View File

@ -5,7 +5,6 @@ bazel-*
e2e_test.*
node_modules
bower_components
tools/gulp-tasks/cldr/cldr-data/
# Include when developing application packages.
pubspec.lock

View File

@ -69,6 +69,7 @@ groups:
- "*.lock"
- "tools/*"
exclude:
- "tools/@angular/tsc-wrapped/*"
- "tools/public_api_guard/*"
- "aio/*"
users:
@ -135,9 +136,8 @@ groups:
compiler-cli:
conditions:
files:
- "packages/tsc-wrapped/*"
- "tools/@angular/tsc-wrapped/*"
- "packages/compiler-cli/*"
- "packages/bazel/*"
users:
- alexeagle
- chuckjaz

View File

@ -1,11 +1,63 @@
<a name="4.4.0"></a>
# [4.4.0](https://github.com/angular/angular/compare/4.4.0-RC.0...4.4.0) (2017-09-15)
### Bug Fixes
* **tsc-wrapped:** deduplicate metadata for re-exported modules ([48ae1a6](https://github.com/angular/angular/commit/48ae1a6))
* **tsc-wrapped:** fix metadata symbol reference ([f6a7183](https://github.com/angular/angular/commit/f6a7183))
* **upgrade:** remove code setting id attribute. ([#19182](https://github.com/angular/angular/issues/19182)) ([b20c5d2](https://github.com/angular/angular/commit/b20c5d2)), closes [#18446](https://github.com/angular/angular/issues/18446)
<a name="4.4.0-RC.0"></a>
# [4.4.0-RC.0](https://github.com/angular/angular/compare/4.3.6...4.4.0-RC.0) (2017-09-02)
### Bug Fixes
* **animations:** do not leak DOM nodes/styling for host triggered animations ([#18853](https://github.com/angular/angular/issues/18853)) ([1cc3fe2](https://github.com/angular/angular/commit/1cc3fe2)), closes [#18606](https://github.com/angular/angular/issues/18606)
* **common:** fix improper packaging for [@angular](https://github.com/angular)/common/http ([#18613](https://github.com/angular/angular/issues/18613)) ([a203a95](https://github.com/angular/angular/commit/a203a95))
* **common:** fix XSSI prefix stripping by using JSON.parse always ([#18466](https://github.com/angular/angular/issues/18466)) ([8821723](https://github.com/angular/angular/commit/8821723)), closes [#18396](https://github.com/angular/angular/issues/18396) [#18453](https://github.com/angular/angular/issues/18453)
* **compiler:** normalize the locale name ([#18963](https://github.com/angular/angular/issues/18963)) ([497e017](https://github.com/angular/angular/commit/497e017))
* **core:** complete EventEmitter in QueryList on component destroy ([#18902](https://github.com/angular/angular/issues/18902)) ([7d137d7](https://github.com/angular/angular/commit/7d137d7)), closes [#18741](https://github.com/angular/angular/issues/18741)
### Features
* **compiler:** allow multiple exportAs names ([#18723](https://github.com/angular/angular/issues/18723)) ([7ec28fe](https://github.com/angular/angular/commit/7ec28fe))
* **core:** add option to remove blank text nodes from compiled templates ([#18823](https://github.com/angular/angular/issues/18823)) ([b8b551c](https://github.com/angular/angular/commit/b8b551c))
<a name="4.3.6"></a>
## [4.3.6](https://github.com/angular/angular/compare/4.3.5...4.3.6) (2017-08-23)
### Bug Fixes
* **animations:** ensure animations are disabled on the element containing the @.disabled flag ([#18714](https://github.com/angular/angular/issues/18714)) ([5d68c83](https://github.com/angular/angular/commit/5d68c83))
* **animations:** make sure @.disabled respects disabled parent/sub animation sequences ([#18715](https://github.com/angular/angular/issues/18715)) ([c3dcbf9](https://github.com/angular/angular/commit/c3dcbf9))
* **animations:** make sure animation cancellations respect AUTO style values ([#18787](https://github.com/angular/angular/issues/18787)) ([9a754f9](https://github.com/angular/angular/commit/9a754f9)), closes [#17450](https://github.com/angular/angular/issues/17450)
* **animations:** resolve error when using AnimationBuilder with platform-server ([#18642](https://github.com/angular/angular/issues/18642)) ([f9b2905](https://github.com/angular/angular/commit/f9b2905)), closes [#18635](https://github.com/angular/angular/issues/18635)
* **animations:** restore auto-style support for removed DOM nodes ([#18787](https://github.com/angular/angular/issues/18787)) ([e1f45a3](https://github.com/angular/angular/commit/e1f45a3))
* **core:** correct order in ContentChildren query result ([#18326](https://github.com/angular/angular/issues/18326)) ([fec3b1a](https://github.com/angular/angular/commit/fec3b1a)), closes [#16568](https://github.com/angular/angular/issues/16568)
* **core:** make sure onStable runs in the right zone ([#18706](https://github.com/angular/angular/issues/18706)) ([ee5591d](https://github.com/angular/angular/commit/ee5591d))
### Features
* **animations:** allow @.disabled property to work without an expression ([#18713](https://github.com/angular/angular/issues/18713)) ([ac58914](https://github.com/angular/angular/commit/ac58914))
* **common:** add an empty DeprecatedI18NPipesModule module ([793f31b](https://github.com/angular/angular/commit/793f31b))
<a name="5.0.0-beta.4"></a>
# [5.0.0-beta.4](https://github.com/angular/angular/compare/5.0.0-beta.3...5.0.0-beta.4) (2017-08-16)
### Bug Fixes
* **aio:** fix compilation error by using the correct type for `providers` ([4d523fd](https://github.com/angular/angular/commit/4d523fd))
* **aio:** skip PWA test when redeploying non-public commit ([06faac8](https://github.com/angular/angular/commit/06faac8))
* **compiler:** Don't strip CSS source maps ([64b4be9](https://github.com/angular/angular/commit/64b4be9))
* **forms:** re-assigning options should not clear select ([32ff21c](https://github.com/angular/angular/commit/32ff21c)), closes [#18330](https://github.com/angular/angular/issues/18330)
* **language-service:** remove tsickle dependency ([bc22ff1](https://github.com/angular/angular/commit/bc22ff1))
@ -20,7 +72,6 @@
### Performance Improvements
* **aio:** update to new version of build-optimizer ([088532b](https://github.com/angular/angular/commit/088532b))
* **core:** add option to remove blank text nodes from compiled templates ([d2c0d98](https://github.com/angular/angular/commit/d2c0d98))
* **core:** Remove decorator DSL which depends on Reflect ([cac130e](https://github.com/angular/angular/commit/cac130e))
@ -32,17 +83,10 @@
### Bug Fixes
* **aio:** skip PWA test when redeploying non-public commit ([b9c1c91](https://github.com/angular/angular/commit/b9c1c91))
* **core:** forbid destroyed views to be inserted or moved in VC ([972538b](https://github.com/angular/angular/commit/972538b)), closes [#18615](https://github.com/angular/angular/issues/18615)
* **forms:** re-assigning options should not clear select ([a1624f2](https://github.com/angular/angular/commit/a1624f2)), closes [#18330](https://github.com/angular/angular/issues/18330)
### Performance Improvements
* **aio:** update to new version of build-optimizer ([d7be4f1](https://github.com/angular/angular/commit/d7be4f1))
<a name="4.3.4"></a>
## [4.3.4](https://github.com/angular/angular/compare/4.3.3...4.3.4) (2017-08-10)
@ -54,90 +98,6 @@
* **compiler:** cleanly compile with TypeScript 2.4 ([#18456](https://github.com/angular/angular/issues/18456)) ([5e4054b](https://github.com/angular/angular/commit/5e4054b))
* **compiler:** ignore [@import](https://github.com/import) in multi-line css ([#18452](https://github.com/angular/angular/issues/18452)) ([e7e7622](https://github.com/angular/angular/commit/e7e7622)), closes [#18038](https://github.com/angular/angular/issues/18038)
<a name="5.0.0-beta.3"></a>
# [5.0.0-beta.3](https://github.com/angular/angular/compare/5.0.0-beta.2...5.0.0-beta.3) (2017-08-09)
### Bug Fixes
* **animations:** revert container/queried animations accordingly during cancel ([#18516](https://github.com/angular/angular/issues/18516)) ([c0c03dc](https://github.com/angular/angular/commit/c0c03dc))
* **animations:** support persisting dynamic styles within animation states ([#18468](https://github.com/angular/angular/issues/18468)) ([05472cb](https://github.com/angular/angular/commit/05472cb)), closes [#18423](https://github.com/angular/angular/issues/18423) [#17505](https://github.com/angular/angular/issues/17505)
* **benchpress:** compile cleanly with TS 2.4 ([#18455](https://github.com/angular/angular/issues/18455)) ([e25b3dd](https://github.com/angular/angular/commit/e25b3dd))
* **common:** don't recreate view when context shape doesn't change ([#18277](https://github.com/angular/angular/issues/18277)) ([685cc26](https://github.com/angular/angular/commit/685cc26)), closes [#13407](https://github.com/angular/angular/issues/13407)
* **compiler:** cleanly compile with TypeScript 2.4 ([#18456](https://github.com/angular/angular/issues/18456)) ([7c47b62](https://github.com/angular/angular/commit/7c47b62))
* **compiler:** ignore [@import](https://github.com/import) in multi-line css ([#18452](https://github.com/angular/angular/issues/18452)) ([1dca575](https://github.com/angular/angular/commit/1dca575)), closes [#18038](https://github.com/angular/angular/issues/18038)
* **compiler-cli:** disable buggy expression lowering ([#18513](https://github.com/angular/angular/issues/18513)) ([ca695e0](https://github.com/angular/angular/commit/ca695e0))
* **compiler-cli:** fix and re-enable expression lowering ([#18570](https://github.com/angular/angular/issues/18570)) ([6f2038c](https://github.com/angular/angular/commit/6f2038c)), closes [#18388](https://github.com/angular/angular/issues/18388)
* **compiler-cli:** modified ngc to throw all errors, not just syntax ([#18388](https://github.com/angular/angular/issues/18388)) ([5651e4a](https://github.com/angular/angular/commit/5651e4a))
* **compiler-cli:** remove minimist dependency of compiler-cli/index ([#18532](https://github.com/angular/angular/issues/18532)) ([5b7432b](https://github.com/angular/angular/commit/5b7432b))
* **core:** fix platform-browser-dynamic ([#18576](https://github.com/angular/angular/issues/18576)) ([f0a5501](https://github.com/angular/angular/commit/f0a5501))
* **core:** forbid destroyed views to be inserted or moved in VC ([#18568](https://github.com/angular/angular/issues/18568)) ([e54bd59](https://github.com/angular/angular/commit/e54bd59)), closes [#17780](https://github.com/angular/angular/issues/17780)
### Features
* **core:** Create StaticInjector which does not depend on Reflect polyfill. ([d9d00bd](https://github.com/angular/angular/commit/d9d00bd))
* **forms:** add default updateOn values for groups and arrays ([#18536](https://github.com/angular/angular/issues/18536)) ([ff5c58b](https://github.com/angular/angular/commit/ff5c58b))
* **forms:** add updateOn blur option to FormControls ([#18408](https://github.com/angular/angular/issues/18408)) ([333a708](https://github.com/angular/angular/commit/333a708)), closes [#7113](https://github.com/angular/angular/issues/7113)
* **forms:** add updateOn submit option to FormControls ([#18514](https://github.com/angular/angular/issues/18514)) ([f69561b](https://github.com/angular/angular/commit/f69561b))
### Performance Improvements
* switch angular to use StaticInjector instead of ReflectiveInjector ([fcadbf4](https://github.com/angular/angular/commit/fcadbf4)), closes [#18496](https://github.com/angular/angular/issues/18496)
### BREAKING CHANGES
* `platformXXXX()` no longer accepts providers which depend on reflection.
Specifically the method signature when from `Provider[]` to
`StaticProvider[]`.
Example:
Before:
```
[
MyClass,
{provide: ClassA, useClass: SubClassA}
]
```
After:
```
[
{provide: MyClass, deps: [Dep1,...]},
{provide: ClassA, useClass: SubClassA, deps: [Dep1,...]}
]
```
NOTE: This only applies to platform creation and providers for the JIT
compiler. It does not apply to `@Component` or `@NgModule` provides
declarations.
Benchpress note: Previously Benchpress also supported reflective
provides, which now require static providers.
DEPRECATION:
- `ReflectiveInjector` is now deprecated as it will be remove. Use
`Injector.create` as a replacement.
<a name="5.0.0-beta.2"></a>
# [5.0.0-beta.2](https://github.com/angular/angular/compare/5.0.0-beta.1...5.0.0-beta.2) (2017-08-02)
### Bug Fixes
* **compiler:** do not consider arguments when determining recursion ([e64b54b](https://github.com/angular/angular/commit/e64b54b))
* **compiler:** fix for element needing implicit parent placed in top-level ng-container ([381471d](https://github.com/angular/angular/commit/381471d)), closes [#18314](https://github.com/angular/angular/issues/18314)
### Features
* **forms:** add options arg to abstract controls ([ebef5e6](https://github.com/angular/angular/commit/ebef5e6))
* **router:** add events tracking activation of individual routes ([49cd851](https://github.com/angular/angular/commit/49cd851))
<a name="4.3.3"></a>
## [4.3.3](https://github.com/angular/angular/compare/4.3.2...4.3.3) (2017-08-02)
@ -145,36 +105,6 @@ DEPRECATION:
* **compiler:** fix for element needing implicit parent placed in top-level ng-container ([f5cbc2e](https://github.com/angular/angular/commit/f5cbc2e)), closes [#18314](https://github.com/angular/angular/issues/18314)
<a name="5.0.0-beta.1"></a>
# [5.0.0-beta.1](https://github.com/angular/angular/compare/5.0.0-beta.0...5.0.0-beta.1) (2017-07-27)
### Bug Fixes
* **animations:** export BrowserModule as apart of BrowserAnimationsModule ([#18263](https://github.com/angular/angular/issues/18263)) ([fd0cc01](https://github.com/angular/angular/commit/fd0cc01))
* **compiler:** add equiv & disp attributes to Xliff2 ICU placeholders ([#18283](https://github.com/angular/angular/issues/18283)) ([38ec05f](https://github.com/angular/angular/commit/38ec05f)), closes [#17344](https://github.com/angular/angular/issues/17344)
* **compiler:** allow numbers for ICU message cases in lexer ([#18095](https://github.com/angular/angular/issues/18095)) ([a3a5429](https://github.com/angular/angular/commit/a3a5429)), closes [#17799](https://github.com/angular/angular/issues/17799)
* **core:** invoke error handler outside of the Angular Zone ([#18269](https://github.com/angular/angular/issues/18269)) ([7ae7573](https://github.com/angular/angular/commit/7ae7573)), closes [#17073](https://github.com/angular/angular/issues/17073) [#7774](https://github.com/angular/angular/issues/7774)
* **platform-server:** don't clobber parse5 properties when setting ([#18237](https://github.com/angular/angular/issues/18237)) ([a094769](https://github.com/angular/angular/commit/a094769)), closes [#17050](https://github.com/angular/angular/issues/17050)
* **router:** child CanActivate guard should wait for parent to complete ([#18110](https://github.com/angular/angular/issues/18110)) ([086f4aa](https://github.com/angular/angular/commit/086f4aa)), closes [#15670](https://github.com/angular/angular/issues/15670)
* **router:** should throw when lazy loaded module doesn't define any routes ([#15001](https://github.com/angular/angular/issues/15001)) ([82923a3](https://github.com/angular/angular/commit/82923a3)), closes [#14596](https://github.com/angular/angular/issues/14596)
* **upgrade:** ensure downgraded components are created in the Angular zone ([#18209](https://github.com/angular/angular/issues/18209)) ([43c33d5](https://github.com/angular/angular/commit/43c33d5))
* **upgrade:** throw error if trying to get injector before setting ([#18209](https://github.com/angular/angular/issues/18209)) ([d31dc7b](https://github.com/angular/angular/commit/d31dc7b))
### Features
* **compiler:** add representation of placeholders to xliff & xmb ([b3085e9](https://github.com/angular/angular/commit/b3085e9)), closes [#17345](https://github.com/angular/angular/issues/17345)
### Performance Improvements
* latest tsickle to tree shake: abstract class methods & interfaces ([#18236](https://github.com/angular/angular/issues/18236)) ([b7a6f52](https://github.com/angular/angular/commit/b7a6f52))
* **core:** use native addEventListener for faster rendering. ([#18107](https://github.com/angular/angular/issues/18107)) ([6279e50](https://github.com/angular/angular/commit/6279e50))
<a name="4.3.2"></a>
## [4.3.2](https://github.com/angular/angular/compare/4.3.1...4.3.2) (2017-07-26)
@ -192,35 +122,6 @@ DEPRECATION:
<a name="5.0.0-beta.0"></a>
# [5.0.0-beta.0](https://github.com/angular/angular/compare/4.3.0...5.0.0-beta.0) (2017-07-19)
### Bug Fixes
* **animations:** always camelcase style property names that contain auto styles ([d22f8f5](https://github.com/angular/angular/commit/d22f8f5)), closes [#17938](https://github.com/angular/angular/issues/17938)
* **animations:** capture cancelled animation styles within grouped animations ([23146c9](https://github.com/angular/angular/commit/23146c9)), closes [#17170](https://github.com/angular/angular/issues/17170)
* **animations:** do not crash animations if a nested component fires CD during CD ([5db6f38](https://github.com/angular/angular/commit/5db6f38)), closes [#18193](https://github.com/angular/angular/issues/18193)
* **animations:** make sure @.disabled works in non-animation components ([5344be5](https://github.com/angular/angular/commit/5344be5))
* **common:** send flushed body as error instead of null ([5c62e30](https://github.com/angular/angular/commit/5c62e30)), closes [#18181](https://github.com/angular/angular/issues/18181)
* **compiler:** ensure jit external id arguments names are unique ([95635c1](https://github.com/angular/angular/commit/95635c1))
* **compiler-cli:** don't generate empty <target/> when extracting xliff ([65c9e13](https://github.com/angular/angular/commit/65c9e13)), closes [#15754](https://github.com/angular/angular/issues/15754)
* **platform-server:** provide XhrFactory for HttpClient ([8076482](https://github.com/angular/angular/commit/8076482))
* **router:** canDeactivate guards should run from bottom to top ([e20cfe1](https://github.com/angular/angular/commit/e20cfe1)), closes [#15657](https://github.com/angular/angular/issues/15657)
* **router:** should navigate to the same url when config changes ([eb6fb5f](https://github.com/angular/angular/commit/eb6fb5f)), closes [#15535](https://github.com/angular/angular/issues/15535)
* **router:** should run resolvers for the same route concurrently ([ad3029e](https://github.com/angular/angular/commit/ad3029e)), closes [#14279](https://github.com/angular/angular/issues/14279)
* **router:** terminal route in custom matcher ([b399cb2](https://github.com/angular/angular/commit/b399cb2))
* **upgrade:** allow accessing AngularJS injector from downgraded module ([a5205c6](https://github.com/angular/angular/commit/a5205c6))
### Features
* **animations:** support :increment and :decrement transition aliases ([6f45519](https://github.com/angular/angular/commit/6f45519))
* **upgrade:** propagate touched state of NgModelController ([59c23c7](https://github.com/angular/angular/commit/59c23c7))
* **upgrade:** support lazy-loading Angular module into AngularJS app ([30e76fc](https://github.com/angular/angular/commit/30e76fc))
<a name="4.3.1"></a>
## [4.3.1](https://github.com/angular/angular/compare/4.3.0...4.3.1) (2017-07-19)
@ -1292,7 +1193,6 @@ templates is unaffected. We expect no or little impact on apps from this change,
### Features
* **aio:** add initial angular-cli scaffold ([#14118](https://github.com/angular/angular/issues/14118)) ([e130bc1](https://github.com/angular/angular/commit/e130bc1))
* **common:** rename underlying `NgFor` class and add a type parameter ([#14104](https://github.com/angular/angular/issues/14104)) ([86b2b25](https://github.com/angular/angular/commit/86b2b25))
* **compiler:** allow missing translations ([#14113](https://github.com/angular/angular/issues/14113)) ([8775ab9](https://github.com/angular/angular/commit/8775ab9)), closes [#13861](https://github.com/angular/angular/issues/13861)
* **compiler:** do not parse xtb messages not needed by angular ([#14111](https://github.com/angular/angular/issues/14111)) ([f7fba74](https://github.com/angular/angular/commit/f7fba74)), closes [#14046](https://github.com/angular/angular/issues/14046)

View File

@ -1,21 +1,17 @@
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
git_repository(
name = "build_bazel_rules_nodejs",
remote = "https://github.com/bazelbuild/rules_nodejs.git",
tag = "0.0.2",
name = "build_bazel_rules_typescript",
remote = "https://github.com/bazelbuild/rules_typescript.git",
tag = "0.0.5",
)
load("@build_bazel_rules_nodejs//:defs.bzl", "node_repositories")
load("@build_bazel_rules_typescript//:defs.bzl", "node_repositories")
node_repositories(package_json = ["//:package.json"])
node_repositories(package_json = "//:package.json")
local_repository(
name = "build_bazel_rules_typescript",
path = "node_modules/@bazel/typescript",
)
local_repository(
name = "angular",
path = "packages/bazel",
git_repository(
name = "build_bazel_rules_angular",
remote = "https://github.com/bazelbuild/rules_angular.git",
tag = "0.0.1",
)

View File

@ -1,6 +0,0 @@
// #docregion import-locale
import { registerLocaleData } from '@angular/common';
import localeFr from '@angular/common/i18n_data/locale_fr';
registerLocaleData(localeFr);
// #enddocregion import-locale

View File

@ -1,7 +0,0 @@
// #docregion import-locale-extra
import { registerLocaleData } from '@angular/common';
import localeEnGB from '@angular/common/i18n_data/locale_en-GB';
import localeEnGBExtra from '@angular/common/i18n_data/extra/locale_en-GB';
registerLocaleData(localeEnGB, localeEnGBExtra);
// #enddocregion import-locale-extra

View File

@ -1,15 +1,15 @@
// #docplaster
// #docregion without-missing-translation
import { TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID, MissingTranslationStrategy, StaticProvider } from '@angular/core';
import { TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID, MissingTranslationStrategy } from '@angular/core';
import { CompilerConfig } from '@angular/compiler';
export function getTranslationProviders(): Promise<StaticProvider[]> {
export function getTranslationProviders(): Promise<Object[]> {
// Get the locale id from the global
const locale = document['locale'] as string;
// return no providers if fail to get translation file for locale
const noProviders: StaticProvider[] = [];
const noProviders: Object[] = [];
// No locale or U.S. English: no translation providers
if (!locale || locale === 'en-US') {

View File

@ -28,7 +28,7 @@ describe('Pipes', function () {
it('should be able to toggle birthday formats', function () {
let birthDayEle = element(by.css('hero-birthday2 > p'));
expect(birthDayEle.getText()).toEqual(`The hero's birthday is 4/15/88`);
expect(birthDayEle.getText()).toEqual(`The hero's birthday is 4/15/1988`);
let buttonEle = element(by.cssContainingText('hero-birthday2 > button', 'Toggle Format'));
expect(buttonEle.isDisplayed()).toBe(true);
buttonEle.click().then(function() {

View File

@ -12,13 +12,13 @@ describe('Router', () => {
beforeAll(() => browser.get(''));
function getPageStruct() {
const hrefEles = element.all(by.css('my-app a'));
const hrefEles = element.all(by.css('my-app > nav a'));
const crisisDetail = element.all(by.css('my-app > ng-component > ng-component > ng-component > div')).first();
const heroDetail = element(by.css('my-app > ng-component > div'));
return {
hrefs: hrefEles,
activeHref: element(by.css('my-app a.active')),
activeHref: element(by.css('my-app > nav a.active')),
crisisHref: hrefEles.get(0),
crisisList: element.all(by.css('my-app > ng-component > ng-component li')),

View File

@ -15,6 +15,10 @@
height: 1.6em;
border-radius: 4px;
}
.items li a {
display: block;
text-decoration: none;
}
.items li:hover {
color: #607D8B;
background-color: #DDD;

View File

@ -28,7 +28,7 @@ const appRoutes: Routes = [
data: { preload: true }
},
// #enddocregion preload-v2
{ path: '', redirectTo: '/heroes', pathMatch: 'full' },
{ path: '', redirectTo: '/superheroes', pathMatch: 'full' },
{ path: '**', component: PageNotFoundComponent }
];

View File

@ -0,0 +1,23 @@
// #docplaster
// #docregion
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
// #docregion template
template: `
<h1 class="title">Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
<a routerLink="/admin" routerLinkActive="active">Admin</a>
<a routerLink="/login" routerLinkActive="active">Login</a>
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
</nav>
<router-outlet></router-outlet>
<router-outlet name="popup"></router-outlet>
`
// #enddocregion template
})
export class AppComponent {
}

View File

@ -9,7 +9,7 @@ import { Component } from '@angular/core';
<h1 class="title">Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
<a routerLink="/superheroes" routerLinkActive="active">Heroes</a>
<a routerLink="/admin" routerLinkActive="active">Admin</a>
<a routerLink="/login" routerLinkActive="active">Login</a>
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>

View File

@ -1,5 +1,6 @@
// #docregion
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { CanDeactivate,
ActivatedRouteSnapshot,
RouterStateSnapshot } from '@angular/router';
@ -13,7 +14,7 @@ export class CanDeactivateGuard implements CanDeactivate<CrisisDetailComponent>
component: CrisisDetailComponent,
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Promise<boolean> | boolean {
): Observable<boolean> | boolean {
// Get the Crisis Center ID
console.log(route.paramMap.get('id'));
@ -25,7 +26,7 @@ export class CanDeactivateGuard implements CanDeactivate<CrisisDetailComponent>
return true;
}
// Otherwise ask the user with the dialog service and return its
// promise which resolves to true or false when the user decides
// observable which resolves to true or false when the user decides
return component.dialogService.confirm('Discard changes?');
}
}

View File

@ -1,18 +1,21 @@
// #docregion
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Router, Resolve, RouterStateSnapshot,
ActivatedRouteSnapshot } from '@angular/router';
import { Crisis, CrisisService } from './crisis.service';
import { Crisis, CrisisService } from './crisis.service';
@Injectable()
export class CrisisDetailResolver implements Resolve<Crisis> {
constructor(private cs: CrisisService, private router: Router) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<Crisis> {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Crisis> {
let id = route.paramMap.get('id');
return this.cs.getCrisis(id).then(crisis => {
return this.cs.getCrisis(id).take(1).map(crisis => {
if (crisis) {
return crisis;
} else { // id not found

View File

@ -1,8 +1,9 @@
// #docplaster
// #docregion
import 'rxjs/add/operator/switchMap';
import { Component, OnInit, HostBinding } from '@angular/core';
import { Component, OnInit, HostBinding } from '@angular/core';
import { ActivatedRoute, Router, ParamMap } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { slideInDownAnimation } from '../animations';
import { Crisis, CrisisService } from './crisis.service';
@ -45,7 +46,8 @@ export class CrisisDetailComponent implements OnInit {
// #docregion ngOnInit
ngOnInit() {
this.route.paramMap
.switchMap((params: ParamMap) => this.service.getCrisis(params.get('id')))
.switchMap((params: ParamMap) =>
this.service.getCrisis(params.get('id')))
.subscribe((crisis: Crisis) => {
if (crisis) {
this.editName = crisis.name;
@ -66,13 +68,13 @@ export class CrisisDetailComponent implements OnInit {
this.gotoCrises();
}
canDeactivate(): Promise<boolean> | boolean {
canDeactivate(): Observable<boolean> | boolean {
// Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged
if (!this.crisis || this.crisis.name === this.editName) {
return true;
}
// Otherwise ask the user with the dialog service and return its
// promise which resolves to true or false when the user decides
// observable which resolves to true or false when the user decides
return this.dialogService.confirm('Discard changes?');
}

View File

@ -2,6 +2,7 @@
// #docregion
import { Component, OnInit, HostBinding } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { slideInDownAnimation } from '../animations';
import { Crisis } from './crisis.service';
@ -62,13 +63,13 @@ export class CrisisDetailComponent implements OnInit {
// #enddocregion cancel-save
// #docregion canDeactivate
canDeactivate(): Promise<boolean> | boolean {
canDeactivate(): Observable<boolean> | boolean {
// Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged
if (!this.crisis || this.crisis.name === this.editName) {
return true;
}
// Otherwise ask the user with the dialog service and return its
// promise which resolves to true or false when the user decides
// observable which resolves to true or false when the user decides
return this.dialogService.confirm('Discard changes?');
}
// #enddocregion canDeactivate

View File

@ -1,7 +1,7 @@
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/switchMap';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router, ParamMap } from '@angular/router';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { Crisis, CrisisService } from './crisis.service';
import { Observable } from 'rxjs/Observable';
@ -10,35 +10,34 @@ import { Observable } from 'rxjs/Observable';
// #docregion relative-navigation-router-link
template: `
<ul class="items">
<li *ngFor="let crisis of crises | async">
<a [routerLink]="[crisis.id]"
[class.selected]="isSelected(crisis)">
<span class="badge">{{ crisis.id }}</span>
{{ crisis.name }}
<li *ngFor="let crisis of crises$ | async"
[class.selected]="crisis.id === selectedId">
<a [routerLink]="[crisis.id]">
<span class="badge">{{ crisis.id }}</span>{{ crisis.name }}
</a>
</li>
</ul>`
</ul>
<router-outlet></router-outlet>
`
// #enddocregion relative-navigation-router-link
})
export class CrisisListComponent implements OnInit {
crises: Observable<Crisis[]>;
crises$: Observable<Crisis[]>;
selectedId: number;
constructor(
private service: CrisisService,
private route: ActivatedRoute,
private router: Router
private route: ActivatedRoute
) {}
ngOnInit() {
this.crises = this.route.paramMap
this.crises$ = this.route.paramMap
.switchMap((params: ParamMap) => {
this.selectedId = +params.get('id');
return this.service.getCrises();
});
}
isSelected(crisis: Crisis) {
return crisis.id === this.selectedId;
}
}

View File

@ -1,20 +1,19 @@
// #docregion
import 'rxjs/add/operator/switchMap';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router, ParamMap } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { Crisis, CrisisService } from './crisis.service';
import { Observable } from 'rxjs/Observable';
@Component({
template: `
<ul class="items">
<li *ngFor="let crisis of crises | async"
(click)="onSelect(crisis)"
[class.selected]="isSelected(crisis)">
<span class="badge">{{ crisis.id }}</span>
{{ crisis.name }}
<li *ngFor="let crisis of crises$ | async"
[class.selected]="crisis.id === selectedId">
<a [routerLink]="[crisis.id]">
<span class="badge">{{ crisis.id }}</span>{{ crisis.name }}
</a>
</li>
</ul>
@ -22,35 +21,21 @@ import { Crisis, CrisisService } from './crisis.service';
`
})
export class CrisisListComponent implements OnInit {
crises: Observable<Crisis[]>;
crises$: Observable<Crisis[]>;
selectedId: number;
// #docregion ctor
constructor(
private service: CrisisService,
private route: ActivatedRoute,
private router: Router
private route: ActivatedRoute
) {}
// #enddocregion ctor
isSelected(crisis: Crisis) {
return crisis.id === this.selectedId;
}
ngOnInit() {
this.crises = this.route.paramMap
this.crises$ = this.route.paramMap
.switchMap((params: ParamMap) => {
this.selectedId = +params.get('id');
return this.service.getCrises();
});
}
// #docregion onSelect
onSelect(crisis: Crisis) {
this.selectedId = crisis.id;
// Navigate with relative link
this.router.navigate([crisis.id], { relativeTo: this.route });
}
// #enddocregion onSelect
}

View File

@ -1,5 +1,9 @@
// #docplaster
// #docregion , mock-crises
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
export class Crisis {
constructor(public id: number, public name: string) { }
}
@ -12,20 +16,18 @@ const CRISES = [
];
// #enddocregion mock-crises
let crisesPromise = Promise.resolve(CRISES);
import { Injectable } from '@angular/core';
@Injectable()
export class CrisisService {
static nextCrisisId = 100;
private crises$: BehaviorSubject<Crisis[]> = new BehaviorSubject<Crisis[]>(CRISES);
getCrises() { return crisesPromise; }
getCrises() { return this.crises$; }
getCrisis(id: number | string) {
return crisesPromise
.then(crises => crises.find(crisis => crisis.id === +id));
return this.getCrises()
.map(crises => crises.find(crisis => crisis.id === +id));
}
// #enddocregion
@ -33,7 +35,8 @@ export class CrisisService {
name = name.trim();
if (name) {
let crisis = new Crisis(CrisisService.nextCrisisId++, name);
crisesPromise.then(crises => crises.push(crisis));
CRISES.push(crisis);
this.crises$.next(CRISES);
}
}
// #docregion

View File

@ -1,5 +1,8 @@
// #docregion
import 'rxjs/add/observable/of';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
/**
* Async modal dialog service
* DialogService makes this app easier to test by faking this service.
@ -9,11 +12,11 @@ import { Injectable } from '@angular/core';
export class DialogService {
/**
* Ask user to confirm an action. `message` explains the action and choices.
* Returns promise resolving to `true`=confirm or `false`=cancel
* Returns observable resolving to `true`=confirm or `false`=cancel
*/
confirm(message?: string) {
return new Promise<boolean>(resolve => {
return resolve(window.confirm(message || 'Is it OK?'));
});
confirm(message?: string): Observable<boolean> {
const confirmation = window.confirm(message || 'Is it OK?');
return Observable.of(confirmation);
};
}

View File

@ -4,6 +4,7 @@
import 'rxjs/add/operator/switchMap';
// #enddocregion rxjs-operator-import
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
// #docregion imports
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
// #enddocregion imports
@ -13,7 +14,7 @@ import { Hero, HeroService } from './hero.service';
@Component({
template: `
<h2>HEROES</h2>
<div *ngIf="hero">
<div *ngIf="hero$ | async as hero">
<h3>"{{ hero.name }}"</h3>
<div>
<label>Id: </label>{{ hero.id }}</div>
@ -28,7 +29,7 @@ import { Hero, HeroService } from './hero.service';
`
})
export class HeroDetailComponent implements OnInit {
hero: Hero;
hero$: Observable<Hero>;
// #docregion ctor
constructor(
@ -40,10 +41,9 @@ export class HeroDetailComponent implements OnInit {
// #docregion ngOnInit
ngOnInit() {
this.route.paramMap
this.hero$ = this.route.paramMap
.switchMap((params: ParamMap) =>
this.service.getHero(params.get('id')))
.subscribe((hero: Hero) => this.hero = hero);
this.service.getHero(params.get('id')));
}
// #enddocregion ngOnInit

View File

@ -2,13 +2,14 @@
// #docregion
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Hero, HeroService } from './hero.service';
@Component({
template: `
<h2>HEROES</h2>
<div *ngIf="hero">
<div *ngIf="hero$ | async as hero">
<h3>"{{ hero.name }}"</h3>
<div>
<label>Id: </label>{{ hero.id }}</div>
@ -23,7 +24,7 @@ import { Hero, HeroService } from './hero.service';
`
})
export class HeroDetailComponent implements OnInit {
hero: Hero;
hero$: Observable<Hero>;
constructor(
private route: ActivatedRoute,
@ -35,8 +36,7 @@ export class HeroDetailComponent implements OnInit {
ngOnInit() {
let id = this.route.snapshot.paramMap.get('id');
this.service.getHero(id)
.then((hero: Hero) => this.hero = hero);
this.hero$ = this.service.getHero(id);
}
// #enddocregion snapshot

View File

@ -4,6 +4,7 @@
import 'rxjs/add/operator/switchMap';
// #enddocregion rxjs-operator-import
import { Component, OnInit, HostBinding } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
import { slideInDownAnimation } from '../animations';
@ -13,7 +14,7 @@ import { Hero, HeroService } from './hero.service';
@Component({
template: `
<h2>HEROES</h2>
<div *ngIf="hero">
<div *ngIf="hero$ | async as hero">
<h3>"{{ hero.name }}"</h3>
<div>
<label>Id: </label>{{ hero.id }}</div>
@ -22,7 +23,7 @@ import { Hero, HeroService } from './hero.service';
<input [(ngModel)]="hero.name" placeholder="name"/>
</div>
<p>
<button (click)="gotoHeroes()">Back</button>
<button (click)="gotoHeroes(hero)">Back</button>
</p>
</div>
`,
@ -35,7 +36,7 @@ export class HeroDetailComponent implements OnInit {
@HostBinding('style.position') position = 'absolute';
// #enddocregion host-bindings
hero: Hero;
hero$: Observable<Hero>;
// #docregion ctor
constructor(
@ -47,16 +48,15 @@ export class HeroDetailComponent implements OnInit {
// #docregion ngOnInit
ngOnInit() {
this.route.paramMap
this.hero$ = this.route.paramMap
.switchMap((params: ParamMap) =>
this.service.getHero(params.get('id')))
.subscribe((hero: Hero) => this.hero = hero);
this.service.getHero(params.get('id')));
}
// #enddocregion ngOnInit
// #docregion gotoHeroes
gotoHeroes() {
let heroId = this.hero ? this.hero.id : null;
gotoHeroes(hero: Hero) {
let heroId = hero ? hero.id : null;
// Pass along the hero id if available
// so that the HeroList component can select that hero.
// Include a junk 'foo' property for fun.

View File

@ -3,6 +3,7 @@
// TODO SOMEDAY: Feature Componetized like HeroCenter
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Hero, HeroService } from './hero.service';
@ -11,9 +12,12 @@ import { Hero, HeroService } from './hero.service';
template: `
<h2>HEROES</h2>
<ul class="items">
<li *ngFor="let hero of heroes | async"
(click)="onSelect(hero)">
<span class="badge">{{ hero.id }}</span> {{ hero.name }}
<li *ngFor="let hero of heroes$ | async">
// #docregion nav-to-detail
<a [routerLink]="['/hero', hero.id]">
<span class="badge">{{ hero.id }}</span>{{ hero.name }}
</a>
// #enddocregion nav-to-detail
</li>
</ul>
@ -22,7 +26,7 @@ import { Hero, HeroService } from './hero.service';
// #enddocregion template
})
export class HeroListComponent implements OnInit {
heroes: Promise<Hero[]>;
heroes$: Observable<Hero[]>;
// #docregion ctor
constructor(
@ -32,16 +36,8 @@ export class HeroListComponent implements OnInit {
// #enddocregion ctor
ngOnInit() {
this.heroes = this.service.getHeroes();
this.heroes$ = this.service.getHeroes();
}
// #docregion select
onSelect(hero: Hero) {
// #docregion nav-to-detail
this.router.navigate(['/hero', hero.id]);
// #enddocregion nav-to-detail
}
// #enddocregion select
}
// #enddocregion

View File

@ -7,7 +7,7 @@ import { Observable } from 'rxjs/Observable';
// #enddocregion rxjs-imports
import { Component, OnInit } from '@angular/core';
// #docregion import-router
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
import { ActivatedRoute, ParamMap } from '@angular/router';
// #enddocregion import-router
import { Hero, HeroService } from './hero.service';
@ -17,10 +17,11 @@ import { Hero, HeroService } from './hero.service';
template: `
<h2>HEROES</h2>
<ul class="items">
<li *ngFor="let hero of heroes | async"
[class.selected]="isSelected(hero)"
(click)="onSelect(hero)">
<span class="badge">{{ hero.id }}</span> {{ hero.name }}
<li *ngFor="let hero of heroes$ | async"
[class.selected]="hero.id === selectedId">
<a [routerLink]="['/hero', hero.id]">
<span class="badge">{{ hero.id }}</span>{{ hero.name }}
</a>
</li>
</ul>
@ -30,18 +31,17 @@ import { Hero, HeroService } from './hero.service';
})
// #docregion ctor
export class HeroListComponent implements OnInit {
heroes: Observable<Hero[]>;
heroes$: Observable<Hero[]>;
private selectedId: number;
constructor(
private service: HeroService,
private route: ActivatedRoute,
private router: Router
private route: ActivatedRoute
) {}
ngOnInit() {
this.heroes = this.route.paramMap
this.heroes$ = this.route.paramMap
.switchMap((params: ParamMap) => {
// (+) before `params.get()` turns the string into a number
this.selectedId = +params.get('id');
@ -49,16 +49,6 @@ export class HeroListComponent implements OnInit {
});
}
// #enddocregion ctor
// #docregion isSelected
isSelected(hero: Hero) { return hero.id === this.selectedId; }
// #enddocregion isSelected
// #docregion select
onSelect(hero: Hero) {
this.router.navigate(['/hero', hero.id]);
}
// #enddocregion select
// #docregion ctor
}
// #enddocregion

View File

@ -1,11 +1,14 @@
// #docregion
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
export class Hero {
constructor(public id: number, public name: string) { }
}
let HEROES = [
const HEROES = [
new Hero(11, 'Mr. Nice'),
new Hero(12, 'Narco'),
new Hero(13, 'Bombasto'),
@ -14,15 +17,13 @@ let HEROES = [
new Hero(16, 'RubberMan')
];
let heroesPromise = Promise.resolve(HEROES);
@Injectable()
export class HeroService {
getHeroes() { return heroesPromise; }
getHeroes() { return Observable.of(HEROES); }
getHero(id: number | string) {
return heroesPromise
return this.getHeroes()
// (+) before `id` turns the string into a number
.then(heroes => heroes.find(hero => hero.id === +id));
.map(heroes => heroes.find(hero => hero.id === +id));
}
}

View File

@ -0,0 +1,24 @@
// #docregion
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HeroListComponent } from './hero-list.component';
import { HeroDetailComponent } from './hero-detail.component';
const heroesRoutes: Routes = [
{ path: 'heroes', component: HeroListComponent },
// #docregion hero-detail-route
{ path: 'hero/:id', component: HeroDetailComponent }
// #enddocregion hero-detail-route
];
@NgModule({
imports: [
RouterModule.forChild(heroesRoutes)
],
exports: [
RouterModule
]
})
export class HeroRoutingModule { }
// #enddocregion

View File

@ -6,10 +6,10 @@ import { HeroListComponent } from './hero-list.component';
import { HeroDetailComponent } from './hero-detail.component';
const heroesRoutes: Routes = [
{ path: 'heroes', component: HeroListComponent },
// #docregion hero-detail-route
{ path: 'hero/:id', component: HeroDetailComponent }
// #enddocregion hero-detail-route
{ path: 'heroes', redirectTo: '/superheroes' },
{ path: 'hero/:id', redirectTo: '/superhero/:id' },
{ path: 'superheroes', component: HeroListComponent },
{ path: 'superhero/:id', component: HeroDetailComponent }
];
@NgModule({

View File

@ -35,7 +35,7 @@ export class HeroDetailComponent {
@Input() prefix = '';
// #docregion deleteRequest
// This component make a request but it can't actually delete a hero.
// This component makes a request but it can't actually delete a hero.
deleteRequest = new EventEmitter<Hero>();
delete() {

View File

@ -44,6 +44,7 @@ System.config({
map: {
'@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
'@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
'@angular/common/http/testing': 'npm:@angular/common/bundles/common-http-testing.umd.js',
'@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
'@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
'@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',

View File

@ -52,6 +52,10 @@ module.exports = function(config) {
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
{ pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false },
// tslib (TS helper fns such as `__extends`)
{ pattern: 'node_modules/tslib/**/*.js', included: false, watched: false },
{ pattern: 'node_modules/tslib/**/*.js.map', included: false, watched: false },
// Paths loaded via module imports:
// Angular itself
{ pattern: 'node_modules/@angular/**/*.js', included: false, watched: false },

View File

@ -347,7 +347,7 @@ Here are the features which may require additional polyfills:
<td>
If you use the following deprecated i18n pipes: [date](api/common/DeprecatedDatePipe), [currency](api/common/DeprecatedCurrencyPipe), [decimal](api/common/DeprecatedDecimalPipe) and [percent](api/common/DeprecatedPercentPipe)
[Date](api/common/DatePipe), [currency](api/common/CurrencyPipe), [decimal](api/common/DecimalPipe) and [percent](api/common/PercentPipe) pipes
</td>
<td>

View File

@ -40,28 +40,6 @@ You need to build and deploy a separate version of the application for each supp
{@a i18n-attribute}
## i18n pipes
Angular pipes can help you with internationalization: the `DatePipe`, `CurrencyPipe`, `DecimalPipe`
and `PercentPipe` use locale data to format your data based on your `LOCALE_ID`.
By default Angular only contains locale data for the language `en-US`, if you set the value of
`LOCALE_ID` to another locale, you will have to import new locale data for this language:
<code-example path="i18n/src/app/app.locale_data.ts" region="import-locale" title="src/app/app.locale_data.ts" linenums="false">
</code-example>
<div class="l-sub-section">
Note that the files in `@angular/common/i18n_data` contain most of the locale data that you will
need, but some advanced formatting options might only be available in the extra dataset that you can
import from `@angular/common/i18n_data/extra`:
<code-example path="i18n/src/app/app.locale_data_extra.ts" region="import-locale-extra" title="src/app/app.locale_data_extra.ts" linenums="false">
</code-example>
</div>
## Mark text with the _i18n_ attribute
The Angular `i18n` attribute is a marker for translatable content.

View File

@ -1,176 +0,0 @@
# Angular Language Service
The Angular Language Service is a way to get completions, errors,
hints, and navigation inside your Angular templates whether they
are external in an HTML file or embedded in annotations/decorators
in a string. The Angular Language Service autodetects that you are
opening an Angular file, reads your `tsconfig.json` file, finds all the
templates you have in your application, and then provides language
services for any templates that you open.
## Autocompletion
Autocompletion can speed up your development time by providing you with
contextual possibilities and hints as you type. This example shows
autocomplete in an interpolation. As you type it out,
you can hit tab to complete.
<figure>
<img src="generated/images/guide/language-service/language-completion.gif" alt="autocompletion">
</figure>
There are also completions within
elements. Any elements you have as a component selector will
show up in the completion list.
## Error checking
The Angular Language Service can also forewarn you of mistakes in your code.
In this example, Angular doesn't know what `orders` is or where it comes from.
<figure>
<img src="generated/images/guide/language-service/language-error.gif" alt="error checking">
</figure>
## Navigation
Navigation allows you to hover to
see where a component, directive, module, etc. is from and then
click and press F12 to go directly to its definition.
<figure>
<img src="generated/images/guide/language-service/language-navigation.gif" alt="navigation">
</figure>
## Angular Language Service in your editor
Angular Language Service is currently available for [Visual Studio Code](https://code.visualstudio.com/) and
[WebStorm](https://www.jetbrains.com/webstorm).
### Visual Studio Code
In Visual Studio Code, install Angular Language Service from the store,
which is accessible from the bottom icon on the left menu pane.
You can also use the VS Quick Open (⌘+P) to search for the extension. When you've opened it,
enter the following command:
```sh
ext install ng-template
```
Then click the install button to install the Angular Language Service.
### WebStorm
In webstorm, you have to install the language service as a dev dependency.
When Angular sees this dev dependency, it provides the
language service inside of WebStorm. Webstorm then gives you
colorization inside the template and autocomplete in addition to the Angular Language Service.
Here's the dev dependency
you need to have in `package.json`:
```json
devDependencies {
"@angular/language-service": "^4.0.0"
}
```
Then in the terminal window at the root of your project,
install the `devDependencies` with `npm` or `yarn`:
```sh
npm install
```
*OR*
```sh
yarn
```
*OR*
```sh
yarn install
```
### Sublime Text
In [Sublime Text](https://www.sublimetext.com/), you first need an extension to allow Typescript.
Install the latest version of typescript in a local `node_modules` directory:
```sh
npm install --save-dev typescript
```
Then install the Angular Language Service in the same location:
```sh
npm install --save-dev @angular/language-service
```
Starting with TypeScript 2.3, TypeScript has a language service plugin model that the language service can use.
Next, in your user preferences (`Cmd+,` or `Ctrl+,`), add:
```json
"typescript-tsdk": "<path to your folder>/node_modules/typescript/lib"
```
## Installing in your project
You can also install Angular Language Service in your project with the
following `npm` command:
```sh
npm install --save-dev @angular/language-service
```
Additionally, add the following to the `"compilerOptions"` section of
your project's `tsconfig.json`.
```json
"plugins": [
{"name": "@angular/language-service"}
]
```
Note that this only provides diagnostics and completions in `.ts`
files. You need a custom sublime plugin (or modifications to the current plugin)
for completions in HTML files.
## How the Language Service works
When you use an editor with a language service, there's an
editor process which starts a separate language process/service
to which it speaks through an [RPC](https://en.wikipedia.org/wiki/Remote_procedure_call).
Any time you type inside of the editor, it sends information to the other process to
track the state of your project. When you trigger a completion list within a template, the editor process first parses the template into an HTML AST, or [abstract syntax tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree). Then the Angular compiler interprets
what module the template is part of, the scope you're in, and the component selector. Then it figures out where in the template AST your cursor is. When it determines the
context, it can then determine what the children can be.
It's a little more involved if you are in an interpolation. If you have an interpolation of `{{data.---}}` inside a `div` and need the completion list after `data.---`, the compiler can't use the HTML AST to find the answer. The HTML AST can only tell the compiler that there is some text with the characters "`{{data.---}}`". That's when the template parser produces an expression AST, which resides within the template AST. The Angular Language Services then looks at `data.---` within its context and asks the TypeScript Language Service what the members of data are. TypeScript then returns the list of possibilities.
For more in-depth information, see the
[Angular Language Service API](https://github.com/angular/angular/blob/master/packages/language-service/src/types.ts)
<hr>
## More on Information
For more information, see [Chuck Jazdzewski's presentation](https://www.youtube.com/watch?v=ez3R0Gi4z5A&t=368s) on the Angular Language
Service from [ng-conf](https://www.ng-conf.org/) 2017.

View File

@ -16,7 +16,7 @@ In the following example, the `@Component()` metadata object and the class const
```typescript
@Component({
selector: 'app-typical',
template: '<div>A typical component for {{data.name}}</div>'
template: 'div>A typical component for {{data.name}}</div>
)}
export class TypicalComponent {
@Input() data: TypicalData;

View File

@ -46,6 +46,24 @@ Inside the interpolation expression, you flow the component's `birthday` value t
function on the right. All pipes work this way.
<div class="l-sub-section">
The `Date` and `Currency` pipes need the *ECMAScript Internationalization API*.
Safari and other older browsers don't support it. You can add support with a polyfill.
<code-example language="html">
&lt;script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en"&gt;&lt;/script&gt;
</code-example>
</div>
## Built-in pipes

View File

@ -204,6 +204,149 @@ application using the `Router` service and the `routerState` property.
Each `ActivatedRoute` in the `RouterState` provides methods to traverse up and down the route tree
to get information from parent, child and sibling routes.
{@a activated-route}
### Activated route
The route path and parameters are available through an injected router service called the
[ActivatedRoute](api/router/ActivatedRoute).
It has a great deal of useful information including:
<table>
<tr>
<th>
Property
</th>
<th>
Description
</th>
</tr>
<tr>
<td>
<code>url</code>
</td>
<td>
An `Observable` of the route path(s), represented as an array of strings for each part of the route path.
</td>
</tr>
<tr>
<td>
<code>data</code>
</td>
<td>
An `Observable` that contains the `data` object provided for the route. Also contains any resolved values from the [resolve guard](#resolve-guard).
</td>
</tr>
<tr>
<td>
<code>paramMap</code>
</td>
<td>
An `Observable` that contains a [map](api/router/ParamMap) of the required and [optional parameters](#optional-route-parameters) specific to the route. The map supports retrieving single and multiple values from the same parameter.
</td>
</tr>
<tr>
<td>
<code>queryParamMap</code>
</td>
<td>
An `Observable` that contains a [map](api/router/ParamMap) of the [query parameters](#query-parameters) available to all routes.
The map supports retrieving single and multiple values from the query parameter.
</td>
</tr>
<tr>
<td>
<code>fragment</code>
</td>
<td>
An `Observable` of the URL [fragment](#fragment) available to all routes.
</td>
</tr>
<tr>
<td>
<code>outlet</code>
</td>
<td>
The name of the `RouterOutlet` used to render the route. For an unnamed outlet, the outlet name is _primary_.
</td>
</tr>
<tr>
<td>
<code>routeConfig</code>
</td>
<td>
The route configuration used for the route that contains the origin path.
</td>
</tr>
<tr>
<td>
<code>parent</code>
</td>
<td>
The route's parent `ActivatedRoute` when this route is a [child route](#child-routing-component).
</td>
</tr>
<tr>
<td>
<code>firstChild</code>
</td>
<td>
Contains the first `ActivatedRoute` in the list of this route's child routes.
</td>
</tr>
<tr>
<td>
<code>children</code>
</td>
<td>
Contains all the [child routes](#child-routing-component) activated under the current route.
</td>
</tr>
</table>
<div class="l-sub-section">
Two older properties are still available. They are less capable than their replacements, discouraged, and may be deprecated in a future Angular version.
**`params`** &mdash; An `Observable` that contains the required and [optional parameters](#optional-route-parameters) specific to the route. Use `paramMap` instead.
**`queryParams`** &mdash; An `Observable` that contains the [query parameters](#query-parameters) available to all routes.
Use `queryParamMap` instead.
</div>
### Router events
During each navigation, the `Router` emits navigation events through the `Router.events` property. These events range from when the navigation starts and ends to many points in between. The full list of navigation events is displayed in the table below.
@ -1333,7 +1476,7 @@ Create a new `heroes-routing.module.ts` in the `heroes` folder
using the same techniques you learned while creating the `AppRoutingModule`.
<code-example path="router/src/app/heroes/heroes-routing.module.ts" title="src/app/heroes/heroes-routing.module.ts">
<code-example path="router/src/app/heroes/heroes-routing.module.1.ts" title="src/app/heroes/heroes-routing.module.ts">
</code-example>
@ -1503,7 +1646,7 @@ Return to the `HeroesRoutingModule` and look at the route definitions again.
The route to `HeroDetailComponent` has a twist.
<code-example path="router/src/app/heroes/heroes-routing.module.ts" linenums="false" title="src/app/heroes/heroes-routing.module.ts (excerpt)" region="hero-detail-route">
<code-example path="router/src/app/heroes/heroes-routing.module.1.ts" linenums="false" title="src/app/heroes/heroes-routing.module.ts (excerpt)" region="hero-detail-route">
</code-example>
@ -1547,52 +1690,6 @@ a route for some other hero.
</div>
{@a navigate}
### Navigate to hero detail imperatively
Users *will not* navigate to the detail component by clicking a link
so you won't add a new `RouterLink` anchor tag to the shell.
Instead, when the user *clicks* a hero in the list, you'll ask the router
to navigate to the hero detail view for the selected hero.
Start in the `HeroListComponent`.
Revise its constructor so that it acquires the `Router` and the `HeroService` by dependency injection:
<code-example path="router/src/app/heroes/hero-list.component.1.ts" linenums="false" title="src/app/heroes/hero-list.component.ts (constructor)" region="ctor">
</code-example>
Make the following few changes to the component's template:
<code-example path="router/src/app/heroes/hero-list.component.1.ts" linenums="false" title="src/app/heroes/hero-list.component.ts (template)" region="template">
</code-example>
The template defines an `*ngFor` repeater such as [you've seen before](guide/displaying-data#ngFor).
There's a `(click)` [event binding](guide/template-syntax#event-binding) to the component's
`onSelect` method which you implement as follows:
<code-example path="router/src/app/heroes/hero-list.component.1.ts" linenums="false" title="src/app/heroes/hero-list.component.ts (select)" region="select">
</code-example>
The component's `onSelect` calls the router's **`navigate`** method with a _link parameters array_.
You can use this same syntax in a `RouterLink` if you decide later to navigate in HTML template rather than in component code.
{@a route-parameters}
@ -1629,152 +1726,9 @@ the `HeroDetailComponent` via the `ActivatedRoute` service.
</div>
{@a activated-route}
### ActivatedRoute: the one-stop-shop for route information
The route path and parameters are available through an injected router service called the
[ActivatedRoute](api/router/ActivatedRoute).
It has a great deal of useful information including:
<table>
<tr>
<th>
Property
</th>
<th>
Description
</th>
</tr>
<tr>
<td>
<code>url</code>
</td>
<td>
An `Observable` of the route path(s), represented as an array of strings for each part of the route path.
</td>
</tr>
<tr>
<td>
<code>data</code>
</td>
<td>
An `Observable` that contains the `data` object provided for the route. Also contains any resolved values from the [resolve guard](#resolve-guard).
</td>
</tr>
<tr>
<td>
<code>paramMap</code>
</td>
<td>
An `Observable` that contains a [map](api/router/ParamMap) of the required and [optional parameters](#optional-route-parameters) specific to the route. The map supports retrieving single and multiple values from the same parameter.
</td>
</tr>
<tr>
<td>
<code>queryParamMap</code>
</td>
<td>
An `Observable` that contains a [map](api/router/ParamMap) of the [query parameters](#query-parameters) available to all routes.
The map supports retrieving single and multiple values from the query parameter.
</td>
</tr>
<tr>
<td>
<code>fragment</code>
</td>
<td>
An `Observable` of the URL [fragment](#fragment) available to all routes.
</td>
</tr>
<tr>
<td>
<code>outlet</code>
</td>
<td>
The name of the `RouterOutlet` used to render the route. For an unnamed outlet, the outlet name is _primary_.
</td>
</tr>
<tr>
<td>
<code>routeConfig</code>
</td>
<td>
The route configuration used for the route that contains the origin path.
</td>
</tr>
<tr>
<td>
<code>parent</code>
</td>
<td>
The route's parent `ActivatedRoute` when this route is a [child route](#child-routing-component).
</td>
</tr>
<tr>
<td>
<code>firstChild</code>
</td>
<td>
Contains the first `ActivatedRoute` in the list of this route's child routes.
</td>
</tr>
<tr>
<td>
<code>children</code>
</td>
<td>
Contains all the [child routes](#child-routing-component) activated under the current route.
</td>
</tr>
</table>
<div class="l-sub-section">
Two older properties are still available. They are less capable than their replacements, discouraged, and may be deprecated in a future Angular version.
**`params`** &mdash; An `Observable` that contains the required and [optional parameters](#optional-route-parameters) specific to the route. Use `paramMap` instead.
**`queryParams`** &mdash; An `Observable` that contains the [query parameters](#query-parameters) available to all routes.
Use `queryParamMap` instead.
</div>
#### _Activated Route_ in action
### _Activated Route_ in action
Import the `Router`, `ActivatedRoute`, and `ParamMap` tokens from the router package.
@ -1820,13 +1774,12 @@ Then you tell the `HeroService` to fetch the hero with that `id` and return the
You might think to use the RxJS `map` operator.
But the `HeroService` returns an `Observable<Hero>`.
Your subscription wants the `Hero`, not an `Observable<Hero>`.
So you flatten the `Observable` with the `switchMap` operator instead.
The `switchMap` operator also cancels previous in-flight requests. If the user re-navigates to this route
with a new `id` while the `HeroService` is still retrieving the old `id`, `switchMap` discards that old request and returns the hero for the new `id`.
Finally, you activate the observable with `subscribe` method and (re)set the component's `hero` property with the retrieved hero.
The observable `Subscription` will be handled by the `AsyncPipe` and the component's `hero` property will be (re)set with the retrieved hero.
#### _ParamMap_ API
@ -2054,7 +2007,7 @@ The router embedded the `id` value in the navigation URL because you had defined
as a route parameter with an `:id` placeholder token in the route `path`:
<code-example path="router/src/app/heroes/heroes-routing.module.ts" linenums="false" title="src/app/heroes/heroes-routing.module.ts (hero-detail-route)" region="hero-detail-route">
<code-example path="router/src/app/heroes/heroes-routing.module.1.ts" linenums="false" title="src/app/heroes/heroes-routing.module.ts (hero-detail-route)" region="hero-detail-route">
</code-example>
@ -2190,17 +2143,9 @@ Then you inject the `ActivatedRoute` in the `HeroListComponent` constructor.
The `ActivatedRoute.paramMap` property is an `Observable` map of route parameters. The `paramMap` emits a new map of values that includes `id`
when the user navigates to the component. In `ngOnInit` you subscribe to those values, set the `selectedId`, and get the heroes.
Add an `isSelected` method that returns `true` when a hero's `id` matches the selected `id`.
<code-example path="router/src/app/heroes/hero-list.component.ts" linenums="false" title="src/app/heroes/hero-list.component.ts (isSelected)" region="isSelected">
</code-example>
Finally, update the template with a [class binding](guide/template-syntax#class-binding) to that `isSelected` method.
The binding adds the `selected` CSS class when the method returns `true` and removes it when `false`.
Update the template with a [class binding](guide/template-syntax#class-binding).
The binding adds the `selected` CSS class when the comparison returns `true` and removes it when `false`.
Look for it within the repeated `<li>` tag as shown here:
@ -2439,7 +2384,7 @@ Here are the relevant files for this version of the sample application.
</code-pane>
<code-pane title="heroes-routing.module.ts" path="router/src/app/heroes/heroes-routing.module.ts">
<code-pane title="heroes-routing.module.ts" path="router/src/app/heroes/heroes-routing.module.1.ts">
</code-pane>
@ -2693,40 +2638,15 @@ The router then calculates the target URL based on the active route's location.
{@a nav-to-crisis}
### Navigate to crisis detail with a relative URL
Update the *Crisis List* `onSelect` method to use relative navigation so you don't have
to start from the top of the route configuration.
### Navigate to crisis list with a relative URL
You've already injected the `ActivatedRoute` that you need to compose the relative navigation path.
<code-example path="router/src/app/crisis-center/crisis-list.component.ts" linenums="false" title="src/app/crisis-center/crisis-list.component.ts (constructor)" region="ctor">
</code-example>
When you visit the *Crisis Center*, the ancestor path is `/crisis-center`,
so you only need to add the `id` of the *Crisis Center* to the existing path.
<code-example path="router/src/app/crisis-center/crisis-list.component.ts" linenums="false" title="src/app/crisis-center/crisis-list.component.ts (relative navigation)" region="onSelect">
</code-example>
If you were using a `RouterLink` to navigate instead of the `Router` service, you'd use the _same_
When using a `RouterLink` to navigate instead of the `Router` service, you'd use the _same_
link parameters array, but you wouldn't provide the object with the `relativeTo` property.
The `ActivatedRoute` is implicit in a `RouterLink` directive.
<code-example path="router/src/app/crisis-center/crisis-list.component.1.ts" linenums="false" title="src/app/crisis-center/crisis-list.component.ts (relative routerLink)" region="relative-navigation-router-link">
</code-example>
Update the `gotoCrises` method of the `CrisisDetailComponent` to navigate back to the *Crisis Center* list using relative path navigation.
@ -2735,7 +2655,6 @@ Update the `gotoCrises` method of the `CrisisDetailComponent` to navigate back t
</code-example>
Notice that the path goes up a level using the `../` syntax.
If the current crisis `id` is `3`, the resulting path back to the crisis list is `/crisis-center/;id=3;foo=foo`.
@ -3415,8 +3334,7 @@ is like waiting for the server asynchronously.
The `DialogService`, provided in the `AppModule` for app-wide use, does the asking.
It returns a [promise](http://exploringjs.com/es6/ch_promises.html) that
*resolves* when the user eventually decides what to do: either
It returns an `Observable` that *resolves* when the user eventually decides what to do: either
to discard changes and navigate away (`true`) or to preserve the pending changes and stay in the crisis editor (`false`).
@ -3541,8 +3459,12 @@ Be explicit. Implement the `Resolve` interface with a type of `Crisis`.
Inject the `CrisisService` and `Router` and implement the `resolve()` method.
That method could return a `Promise`, an `Observable`, or a synchronous return value.
The `CrisisService.getCrisis` method returns a promise.
Return that promise to prevent the route from loading until the data is fetched.
The `CrisisService.getCrisis` method returns an Observable.
Return that observable to prevent the route from loading until the data is fetched.
The `Router` guards require an Observable to `complete`, meaning it has emitted all
of its values. You use the `take` operator with an argument of `1` to ensure that the
Observable completes after retrieving the first value from the Observable returned by the
`getCrisis` method.
If it doesn't return a valid `Crisis`, navigate the user back to the `CrisisListComponent`,
canceling the previous in-flight navigation to the `CrisisDetailComponent`.
@ -3580,12 +3502,15 @@ The router looks for that method and calls it if found.
Don't worry about all the ways that the user could navigate away.
That's the router's job. Write this class and let the router take it from there.
1. The Observable provided to the Router _must_ complete.
If the Observable does not complete, the navigation will not continue.
The relevant *Crisis Center* code for this milestone follows.
<code-tabs>
<code-pane title="app.component.ts" path="router/src/app/app.component.ts">
<code-pane title="app.component.ts" path="router/src/app/app.component.6.ts">
</code-pane>
@ -4041,6 +3966,52 @@ Verify this by logging in to the `Admin` feature area and noting that the `crisi
It's also logged to the browser's console.
{@a redirect-advanced}
## Migrating URLs with Redirects
You've setup the routes for navigating around your application. You've used navigation imperatively and declaratively to many different routes. But like any application, requirements change over time. You've setup links and navigation to `/heroes` and `/hero/:id` from the `HeroListComponent` and `HeroDetailComponent` components. If there was a requirement that links to `heroes` become `superheroes`, you still want the previous URLs to navigate correctly. You also don't want to go and update every link in your application, so redirects makes refactoring routes trivial.
{@a url-refactor}
### Changing /heroes to /superheroes
Let's take the `Hero` routes and migrate them to new URLs. The `Router` checks for redirects in your configuration before navigating, so each redirect is triggered when needed. To support this change, you'll add redirects from the old routes to the new routes in the `heroes-routing.module`.
<code-example path="router/src/app/heroes/heroes-routing.module.ts" linenums="false" title="src/app/heroes/heroes-routing.module.ts (heroes redirects)">
</code-example>
You'll notice two different types of redirects. The first change is from `/heroes` to `/superheroes` without any parameters. This is a straightforward redirect, unlike the change from `/hero/:id` to `/superhero/:id`, which includes the `:id` route parameter. Router redirects also use powerful pattern matching, so the `Router` inspects the URL and replaces route parameters in the `path` with their appropriate destination. Previously, you navigated to a URL such as `/hero/15` with a route parameter `id` of `15`.
<div class="l-sub-section">
The `Router` also supports [query parameters](#query-parameters) and the [fragment](#fragment) when using redirects.
* When using absolute redirects, the `Router` will use the query parameters and the fragment from the redirectTo in the route config.
* When using relative redirects, the `Router` use the query params and the fragment from the source URL.
</div>
Before updating the `app-routing.module.ts`, you'll need to consider an important rule. Currently, our empty path route redirects to `/heroes`, which redirects to `/superheroes`. This _won't_ work and is by design as the `Router` handles redirects once at each level of routing configuration. This prevents chaining of redirects, which can lead to endless redirect loops.
So instead, you'll update the empty path route in `app-routing.module.ts` to redirect to `/superheroes`.
<code-example path="router/src/app/app-routing.module.ts" linenums="false" title="src/app/app-routing.module.ts (superheroes redirect)">
</code-example>
Since `RouterLink`s aren't tied to route configuration, you'll need to update the associated router links so they remain active when the new route is active. You'll update the `app.component.ts` template for the `/heroes` routerLink.
<code-example path="router/src/app/app.component.ts" linenums="false" title="src/app/app.component.ts (superheroes active routerLink)">
</code-example>
With the redirects setup, all previous routes now point to their new destinations and both URLs still function as intended.
{@a inspect-config}

View File

@ -313,7 +313,7 @@ It's intended source is implicit.
Angular sets `let-hero` to the value of the context's `$implicit` property
which `NgFor` has initialized with the hero for the current iteration.
* The [API guide](api/common/NgForOf "API: NgFor")
* The [API guide](api/common/NgFor "API: NgFor")
describes additional `NgFor` directive properties and context properties.
These microsyntax mechanisms are available to you when you write your own structural directives.

View File

@ -1361,8 +1361,8 @@ to group elements when there is no suitable host element for the directive.
_This_ section is an introduction to the common structural directives:
* [`NgIf`](guide/template-syntax#ngIf) - conditionally add or remove an element from the DOM
* [`NgFor`](guide/template-syntax#ngFor) - repeat a template for each item in a list
* [`NgSwitch`](guide/template-syntax#ngSwitch) - a set of directives that switch among alternative views
* [NgForOf](guide/template-syntax#ngFor) - repeat a template for each item in a list
<hr/>
@ -1437,18 +1437,18 @@ described below.
{@a ngFor}
### NgForOf
### NgFor
`NgForOf` is a _repeater_ directive &mdash; a way to present a list of items.
`NgFor` is a _repeater_ directive &mdash; a way to present a list of items.
You define a block of HTML that defines how a single item should be displayed.
You tell Angular to use that block as a template for rendering each item in the list.
Here is an example of `NgForOf` applied to a simple `<div>`:
Here is an example of `NgFor` applied to a simple `<div>`:
<code-example path="template-syntax/src/app/app.component.html" region="NgFor-1" title="src/app/app.component.html" linenums="false">
</code-example>
You can also apply an `NgForOf` to a component element, as in this example:
You can also apply an `NgFor` to a component element, as in this example:
<code-example path="template-syntax/src/app/app.component.html" region="NgFor-2" title="src/app/app.component.html" linenums="false">
</code-example>
@ -1485,10 +1485,10 @@ Learn about the _microsyntax_ in the [_Structural Directives_](guide/structural-
### Template input variables
The `let` keyword before `hero` creates a _template input variable_ called `hero`.
The `NgForOf` directive iterates over the `heroes` array returned by the parent component's `heroes` property
The `ngFor` directive iterates over the `heroes` array returned by the parent component's `heroes` property
and sets `hero` to the current item from the array during each iteration.
You reference the `hero` input variable within the `NgForOf` host element
You reference the `hero` input variable within the `ngFor` host element
(and within its descendents) to access the hero's properties.
Here it is referenced first in an interpolation
and then passed in a binding to the `hero` property of the `<hero-detail>` component.
@ -1501,7 +1501,7 @@ Learn more about _template input variables_ in the
#### *ngFor with _index_
The `index` property of the `NgForOf` directive context returns the zero-based index of the item in each iteration.
The `index` property of the `NgFor` directive context returns the zero-based index of the item in each iteration.
You can capture the `index` in a template input variable and use it in the template.
The next example captures the `index` in a variable named `i` and displays it with the hero name like this.
@ -1511,8 +1511,8 @@ The next example captures the `index` in a variable named `i` and displays it wi
<div class="l-sub-section">
Learn about the other `NgForOf` context values such as `last`, `even`,
and `odd` in the [NgForOf API reference](api/common/NgForOf).
Learn about the other `NgFor` context values such as `last`, `even`,
and `odd` in the [NgFor API reference](api/common/NgFor).
</div>
@ -1520,7 +1520,7 @@ and `odd` in the [NgForOf API reference](api/common/NgForOf).
#### *ngFor with _trackBy_
The `NgForOf` directive may perform poorly, especially with large lists.
The `NgFor` directive may perform poorly, especially with large lists.
A small change to one item, an item removed, or an item added can trigger a cascade of DOM manipulations.
For example, re-querying the server could reset the list with all new hero objects.
@ -1531,7 +1531,7 @@ But Angular sees only a fresh list of new object references.
It has no choice but to tear down the old DOM elements and insert all new DOM elements.
Angular can avoid this churn with `trackBy`.
Add a method to the component that returns the value `NgForOf` _should_ track.
Add a method to the component that returns the value `NgFor` _should_ track.
In this case, that value is the hero's `id`.
<code-example path="template-syntax/src/app/app.component.ts" region="trackByHeroes" title="src/app/app.component.ts" linenums="false">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 857 KiB

View File

@ -80,15 +80,6 @@
"group": "Angular"
},
"aaronzhang": {
"name": "Aaron Zhang (章小飞)",
"picture": "xiaofei.jpg",
"twitter": "",
"website": "http://github.com/damoqiongqiu",
"bio": "Aaron is Angular's developer PM in China. He is the lead for angular.cn and social channels in China, and helps developers in China's enterprise and open source communities to be successful with Angular. One of the earliest Angular developers in China since Angular 2012, he translated the first books on Angular into Chinese. Aaron joined the Google team in 2016.",
"group": "Angular"
},
"tobias": {
"name": "Tobias Bosch",
"picture": "tobias.jpg",
@ -582,5 +573,23 @@
"website": "https://medium.com/@gerard.sans",
"bio": "Gerard is very excited about the future of the Web and JavaScript. Always happy Computer Science Engineer and humble Google Developer Expert. He loves to share his learnings by giving talks, trainings and writing about cool technologies. He loves running AngularZone and GraphQL London, mentoring students and giving back to the community.",
"group": "GDE"
}
},
"amcdnl": {
"name": "Austin McDaniel",
"picture": "amcdnl.jpg",
"twitter": "amcdnl",
"website": "https://amcdnl.com",
"bio": "Austin is an software architect with a passion for JavaScript and Angular. Austin loves to share his experiences with other like-minded developers by giving talks, blogging, podcasting and open-sourcing.",
"group": "Angular"
},
"nirkaufman": {
"name": "Nir Kaufman",
"picture": "nirkaufman.jpg",
"twitter": "nirkaufman",
"website": "http://ngnir.life/",
"bio": "Nir is a Principal Frontend Consultant & Head of the Angular department at 500Tech, Google Developer Expert and community leader. He organizes the largest Angular meetup group in Israel (Angular-IL), talks and teaches about front-end technologies around the world. He is also the author of two books about Angular and the founder of the 'Frontend Band'.",
"group": "GDE"
}
}

View File

@ -1,10 +1,10 @@
<!-- FULL HEADER BLOCK -->
<!--FULL HEADER BLOCK-->
<header>
<!-- BACKGROUND IMAGE -->
<!--BACKGROUND IMAGE-->
<div class="background-sky hero"></div>
<!-- INTRO SECTION -->
<!--INTRO SECTION -->
<section id="intro">
<!-- LOGO -->
@ -12,33 +12,31 @@
<img src="assets/images/logos/angular/angular.svg"/>
</div>
<!-- CONTAINER -->
<!-- CONTAINER -->
<div class="homepage-container">
<!-- container content starts -->
<div class="hero-headline no-toc">One framework.<br>Mobile &amp; desktop.</div>
<a class="button hero-cta" href="guide/quickstart">Get Started</a>
</div>
</div><!-- CONTAINER END -->
</section>
</header>
<!-- MAIN CONTENT -->
<article>
<h1 class="no-toc" style="display: none"></h1>
<div class="home-rows">
<!-- Announcement Bar -->
<!--Announcement Bar-->
<div class="homepage-container">
<div class="announcement-bar">
<img src="generated/images/marketing/home/angular-mix.png" height="40" width="151">
<p>Join us at our newest event, October 2017</p>
<a class="button" href="https://angularmix.com/">Learn More</a>
</div>
</div>
</div>
<!-- Group 1 -->
<!-- Group 1-->
<div layout="row" layout-xs="column" class="home-row homepage-container">
<div class="promo-img-container promo-1">
<div>
@ -55,8 +53,7 @@
</div>
</div>
<hr>
<!-- Group 2 -->
<!-- Group 2-->
<div layout="row" layout-xs="column" class="home-row">
<div class="text-container">
<div class="text-block">
@ -74,7 +71,7 @@
</div>
<hr>
<!-- Group 3 -->
<!-- Group 3-->
<div layout="row" layout-xs="column" class="home-row">
<div class="promo-img-container promo-3">
<div><img src="generated/images/marketing/home/joyful-development.svg" alt="IDE example"></div>
@ -91,8 +88,9 @@
</div>
<hr>
<!-- Group 4 -->
<!-- Group 4-->
<div layout="row" layout-xs="column" class="home-row">
<div class="text-container">
<div class="text-block l-pad-top-2">
<div class="text-headline">Loved by Millions</div>
@ -107,19 +105,20 @@
</div>
</div>
<!-- CTA CARDS -->
<div layout="row" layout-xs="column" class="home-row">
<a href="guide/quickstart">
<div class="card">
<!-- CTA CARDS -->
<div layout="row" layout-xs="column" class="home-row">
<a href="guide/quickstart">
<div class="card">
<img src="generated/images/marketing/home/code-icon.svg" height="70px">
<div class="card-text-container">
<div class="text-headline">Get Started</div>
<p>Start building your Angular application.</p>
</div>
</div>
</a>
</div>
</div>
</a>
</div>
</div><!-- end of home rows -->
</div> <!-- end of home rows -->
</article>

View File

@ -130,6 +130,13 @@
"rev": true,
"title": "Apollo",
"url": "http://docs.apollostack.com/apollo-client/angular2.html"
},
"ab4": {
"desc": "Angular Commerce is a solution for building modern e-commerce applications with power of Google Firebase. Set of components is design agnostic and allows to easily extend functionality.",
"logo": "",
"rev": true,
"title": "AngularCommerce",
"url": "https://github.com/NodeArt/angular-commerce"
}
}
},
@ -320,10 +327,10 @@
"url": "https://www.ag-grid.com/best-angular-2-data-grid/"
},
"jqwidgets": {
"desc": "Angular UI Components including Grids, Charts, Scheduling and more.",
"desc": "Angular UI Components including data grid, tree grid, pivot grid, scheduler, charts, editors and other multi-purpose components",
"rev": true,
"title": "jQWidgets",
"url": "http://www.jqwidgets.com/angular/"
"url": "https://www.jqwidgets.com/angular/"
},
"amexio": {
"desc": "Amexio (Angular MetaMagic EXtensions for Inputs and Outputs) is a rich set of Angular components powered by Bootstrap for Responsive Design. UI Components include Standard Form Components, Data Grids, Tree Grids, Tabs etc. Open Source (Apache 2 License) & Free and backed by MetaMagic Global Inc",

View File

@ -288,11 +288,6 @@
"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",
@ -385,6 +380,12 @@
"title": "API",
"tooltip": "Details of the Angular classes and values.",
"url": "api"
},
{
"url": "guide/change-log",
"title": "Change Log",
"tooltip": "Angular Documentation Change Log",
"hidden": true
}
],
@ -418,7 +419,7 @@
"title": "Help",
"children": [
{
"url": "http://stackoverflow.com/questions/tagged/angular2",
"url": "https://stackoverflow.com/questions/tagged/angular",
"title": "Stack Overflow",
"tooltip": "Stack Overflow: where the community answers your technical Angular questions."
},

View File

@ -92,4 +92,12 @@ describe('site App', function() {
// Todo: add test to confirm tracking URL when navigate.
});
describe('search', () => {
it('should find pages when searching by a partial word in the title', () => {
page.enterSearch('ngCont');
expect(page.getSearchResults().map(link => link.getText())).toContain('NgControl');
page.enterSearch('accessor');
expect(page.getSearchResults().map(link => link.getText())).toContain('ControlValueAccessor');
});
});
});

View File

@ -1,4 +1,4 @@
import { browser, element, by, promise, ElementFinder } from 'protractor';
import { browser, element, by, promise, ElementFinder, ExpectedConditions } from 'protractor';
const githubRegex = /https:\/\/github.com\/angular\/angular\//;
@ -50,6 +50,18 @@ export class SitePage {
return browser.executeScript('window.scrollTo(0, document.body.scrollHeight)');
}
enterSearch(query: string) {
const input = element(by.css('.search-container input[type=search]'));
input.clear();
input.sendKeys(query);
}
getSearchResults() {
const results = element.all(by.css('.search-results li'));
browser.wait(ExpectedConditions.presenceOf(results.first()), 8000);
return results;
}
/**
* Replace the ambient Google Analytics tracker with homebrew spy
* don't send commands to GA during e2e testing!

View File

@ -82,7 +82,7 @@
"concurrently": "^3.4.0",
"cross-spawn": "^5.1.0",
"dgeni": "^0.4.7",
"dgeni-packages": "^0.20.0",
"dgeni-packages": "^0.21.2",
"entities": "^1.1.1",
"eslint": "^3.19.0",
"eslint-plugin-jasmine": "^2.2.0",

View File

@ -2,13 +2,9 @@
set -u -e -o pipefail
declare -A payloadLimits
payloadLimits["aio", "uncompressed", "inline"]=1600
payloadLimits["aio", "uncompressed", "main"]=525000
payloadLimits["aio", "uncompressed", "polyfills"]=38000
payloadLimits["aio", "gzip7", "inline"]=1000
payloadLimits["aio", "gzip7", "main"]=127000
payloadLimits["aio", "gzip7", "polyfills"]=12500
payloadLimits["aio", "gzip9", "inline"]=1000
payloadLimits["aio", "gzip9", "main"]=127000
payloadLimits["aio", "gzip9", "polyfills"]=12500
declare -A limitUncompressed
limitUncompressed=(["inline"]=1600 ["main"]=525000 ["polyfills"]=38000)
declare -A limitGzip7
limitGzip7=(["inline"]=1000 ["main"]=127000 ["polyfills"]=12500)
declare -A limitGzip9
limitGzip9=(["inline"]=1000 ["main"]=127000 ["polyfills"]=12500)

View File

@ -4,10 +4,79 @@ set -eu -o pipefail
readonly thisDir=$(cd $(dirname $0); pwd)
readonly parentDir=$(dirname $thisDir)
readonly PROJECT_NAME="angular-payload-size"
# Track payload size functions
source ../scripts/ci/payload-size.sh
source ${thisDir}/_payload-limits.sh
trackPayloadSize "aio" "dist/*.bundle.js" true true
failed=false
payloadData=""
for filename in dist/*.bundle.js; do
size=$(stat -c%s "$filename")
label=$(echo "$filename" | sed "s/.*\///" | sed "s/\..*//")
payloadData="$payloadData\"uncompressed/$label\": $size, "
gzip -7 $filename -c >> "${filename}7.gz"
size7=$(stat -c%s "${filename}7.gz")
payloadData="$payloadData\"gzip7/$label\": $size7, "
gzip -9 $filename -c >> "${filename}9.gz"
size9=$(stat -c%s "${filename}9.gz")
payloadData="$payloadData\"gzip9/$label\": $size9, "
if [[ $size -gt ${limitUncompressed[$label]} ]]; then
failed=true
echo "Uncompressed $label size is $size which is greater than ${limitUncompressed[$label]}"
elif [[ $size7 -gt ${limitGzip7[$label]} ]]; then
failed=true
echo "Gzip7 $label size is $size7 which is greater than ${limitGzip7[$label]}"
elif [[ $size9 -gt ${limitGzip9[$label]} ]]; then
failed=true
echo "Gzip9 $label size is $size9 which is greater than ${limitGzip9[$label]}"
fi
done
# Add Timestamp
timestamp=$(date +%s)
payloadData="$payloadData\"timestamp\": $timestamp, "
# Add change source: application, dependencies, or 'application+dependencies'
applicationChanged=false
dependenciesChanged=false
if [[ $(git diff --name-only $TRAVIS_COMMIT_RANGE $parentDir | grep -v aio/yarn.lock | grep -v content) ]]; then
applicationChanged=true
fi
if [[ $(git diff --name-only $TRAVIS_COMMIT_RANGE $parentDir/yarn.lock) ]]; then
dependenciesChanged=true
fi
if $dependenciesChanged && $applicationChanged; then
change='application+dependencies'
elif $dependenciesChanged; then
# only yarn.lock changed
change='dependencies'
elif $applicationChanged; then
change='application'
else
# Nothing changed in aio/
exit 0
fi
message=$(echo $TRAVIS_COMMIT_MESSAGE | sed 's/"/\\"/g' | sed 's/\\/\\\\/g')
payloadData="$payloadData\"change\": \"$change\", \"message\": \"$message\""
payloadData="{${payloadData}}"
echo $payloadData
if [[ "$TRAVIS_PULL_REQUEST" == "false" ]]; then
readonly safeBranchName=$(echo $TRAVIS_BRANCH | sed -e 's/\./_/g')
readonly dbPath=/payload/aio/$safeBranchName/$TRAVIS_COMMIT
# WARNING: FIREBASE_TOKEN should NOT be printed.
set +x
firebase database:update --data "$payloadData" --project $PROJECT_NAME --confirm --token "$ANGULAR_PAYLOAD_FIREBASE_TOKEN" $dbPath
fi
if [[ $failed = true ]]; then
exit 1
fi

View File

@ -9,7 +9,18 @@ var SEARCH_TERMS_URL = '/generated/docs/app/search-data.json';
importScripts('/assets/js/lunr.min.js');
var index;
var pages = {};
var pages /* : SearchInfo */ = {};
// interface SearchInfo {
// [key: string]: PageInfo;
// }
// interface PageInfo {
// path: string;
// type: string,
// titleWords: string;
// keyWords: string;
// }
self.onmessage = handleMessage;
@ -49,15 +60,7 @@ function handleMessage(message) {
// Use XHR to make a request to the server
function makeRequest(url, callback) {
// The JSON file that is loaded should be an array of SearchTerms:
//
// export interface SearchTerms {
// path: string;
// type: string,
// titleWords: string;
// keyWords: string;
// }
// The JSON file that is loaded should be an array of PageInfo:
var searchDataRequest = new XMLHttpRequest();
searchDataRequest.onload = function() {
callback(JSON.parse(this.responseText));
@ -68,11 +71,11 @@ function makeRequest(url, callback) {
// Create the search index from the searchInfo which contains the information about each page to be indexed
function loadIndex(searchInfo) {
function loadIndex(searchInfo /*: SearchInfo */) {
return function(index) {
// Store the pages data to be used in mapping query results back to pages
// Add search terms from each page to the search index
searchInfo.forEach(function(page) {
searchInfo.forEach(function(page /*: PageInfo */) {
index.add(page);
pages[page.path] = page;
});
@ -81,7 +84,19 @@ function loadIndex(searchInfo) {
// Query the index and return the processed results
function queryIndex(query) {
var results = index.search(query);
// Only return the array of paths to pages
return results.map(function(hit) { return pages[hit.ref]; });
try {
if (query.length) {
// Add a relaxed search in the title for the first word in the query
// E.g. if the search is "ngCont guide" then we search for "ngCont guide titleWords:ngCont*"
var titleQuery = 'titleWords:*' + query.split(' ', 1)[0] + '*';
var results = index.search(query + ' ' + titleQuery);
// Map the hits into info about each page to be returned as results
return results.map(function(hit) { return pages[hit.ref]; });
}
} catch(e) {
// If the search query cannot be parsed the index throws an error
// Log it and recover
console.log(e);
}
return [];
}

View File

@ -104,7 +104,7 @@ footer::after {
right: 0;
background:
url('../src/assets/images/logos/angular/angular_whiteTransparent_withMargin.png') top 0 left 0 repeat,
url('../src/assets/images/logos/angular/angular_whiteTransparent_withMargin.png') top 80px left 168px repeat;
url('../src/assets/images/logos/angular/angular_whiteTransparent_withMargin.png') top 80px left 160px repeat;
opacity: 0.05;
background-size: 320px auto;
}

View File

@ -41,9 +41,12 @@ const ANGULAR_PACKAGES = [
'platform-browser-dynamic',
'platform-server',
'router',
'tsc-wrapped',
'upgrade',
];
const ANGULAR_TOOLS_PACKAGES_PATH = path.resolve(ANGULAR_DIST_PATH, 'tools', '@angular');
const ANGULAR_TOOLS_PACKAGES = [
'tsc-wrapped'
];
const EXAMPLE_CONFIG_FILENAME = 'example-config.json';
@ -60,6 +63,7 @@ class ExampleBoilerPlate {
// Replace the Angular packages with those from the dist folder, if necessary
if (useLocal) {
ANGULAR_PACKAGES.forEach(packageName => this.overridePackage(ANGULAR_PACKAGES_PATH, packageName));
ANGULAR_TOOLS_PACKAGES.forEach(packageName => this.overridePackage(ANGULAR_TOOLS_PACKAGES_PATH, packageName));
}
// Get all the examples folders, indicated by those that contain a `example-config.json` file

View File

@ -32,7 +32,7 @@ describe('example-boilerplate tool', () => {
// for example
expect(exampleBoilerPlate.overridePackage).toHaveBeenCalledWith(path.resolve(__dirname, '../../../dist/packages-dist'), 'common');
expect(exampleBoilerPlate.overridePackage).toHaveBeenCalledWith(path.resolve(__dirname, '../../../dist/packages-dist'), 'core');
expect(exampleBoilerPlate.overridePackage).toHaveBeenCalledWith(path.resolve(__dirname, '../../../dist/packages-dist'), 'tsc-wrapped');
expect(exampleBoilerPlate.overridePackage).toHaveBeenCalledWith(path.resolve(__dirname, '../../../dist/tools/@angular'), 'tsc-wrapped');
});
it('should process all the example folders', () => {

View File

@ -18,6 +18,7 @@
'@angular/animations/browser': 'npm:@angular/animations/bundles/animations-browser.umd.js',
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/common/http': 'npm:@angular/common/bundles/common-http.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser/animations': 'npm:@angular/platform-browser/bundles/platform-browser-animations.umd.js',
@ -31,6 +32,7 @@
// other libraries
'rxjs': 'npm:rxjs',
'tslib': 'npm:tslib/tslib.js',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
},
// packages tells the System loader how to load when no filename and/or no extension

View File

@ -42,6 +42,7 @@
'@angular/animations/browser': 'ng:animations-builds/master/bundles/animations-browser.umd.js',
'@angular/core': 'ng:core-builds/master/bundles/core.umd.js',
'@angular/common': 'ng:common-builds/master/bundles/common.umd.js',
'@angular/common/http': 'ng:common-builds/master/bundles/common-http.umd.js',
'@angular/compiler': 'ng:compiler-builds/master/bundles/compiler.umd.js',
'@angular/platform-browser': 'ng:platform-browser-builds/master/bundles/platform-browser.umd.js',
'@angular/platform-browser/animations': 'ng:animations-builds/master/bundles/platform-browser-animations.umd.js',
@ -56,6 +57,7 @@
// angular testing umd bundles (overwrite the shim mappings)
'@angular/core/testing': 'ng:core-builds/master/bundles/core-testing.umd.js',
'@angular/common/testing': 'ng:common-builds/master/bundles/common-testing.umd.js',
'@angular/common/http/testing': 'ng:common-builds/master/bundles/common-http-testing.umd.js',
'@angular/compiler/testing': 'ng:compiler-builds/master/bundles/compiler-testing.umd.js',
'@angular/platform-browser/testing': 'ng:platform-browser-builds/master/bundles/platform-browser-testing.umd.js',
'@angular/platform-browser-dynamic/testing': 'ng:platform-browser-dynamic-builds/master/bundles/platform-browser-dynamic-testing.umd.js',
@ -65,6 +67,7 @@
// other libraries
'rxjs': 'npm:rxjs@5.0.1',
'tslib': 'npm:tslib/tslib.js',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
'ts': 'npm:plugin-typescript@5.2.7/lib/plugin.js',
'typescript': 'npm:typescript@2.3.2/lib/typescript.js',

View File

@ -39,6 +39,7 @@
'@angular/animations/browser': 'npm:@angular/animations/bundles/animations-browser.umd.js',
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/common/http': 'npm:@angular/common/bundles/common-http.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser/animations': 'npm:@angular/platform-browser/bundles/platform-browser-animations.umd.js',
@ -52,6 +53,7 @@
// other libraries
'rxjs': 'npm:rxjs@5.0.1',
'tslib': 'npm:tslib/tslib.js',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
'ts': 'npm:plugin-typescript@5.2.7/lib/plugin.js',
'typescript': 'npm:typescript@2.3.2/lib/typescript.js',

View File

@ -25,7 +25,7 @@
"@angular/router": "~4.3.1",
"@angular/tsc-wrapped": "~4.3.1",
"@angular/upgrade": "~4.3.1",
"angular-in-memory-web-api": "~0.3.2",
"angular-in-memory-web-api": "~0.4.0",
"core-js": "^2.4.1",
"rxjs": "^5.1.0",
"systemjs": "0.19.39",

View File

@ -325,9 +325,9 @@ amdefine@>=0.0.4:
version "1.0.1"
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
angular-in-memory-web-api@~0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/angular-in-memory-web-api/-/angular-in-memory-web-api-0.3.2.tgz#8836d9e2534d37b728f3cb5a1caf6fe1e7fbbecd"
angular-in-memory-web-api@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/angular-in-memory-web-api/-/angular-in-memory-web-api-0.4.0.tgz#996715f37d8a4e659e154fedf76c4726470cb8d8"
angular2-template-loader@^0.6.0:
version "0.6.2"
@ -5163,18 +5163,18 @@ request-progress@~2.0.1:
dependencies:
throttleit "^1.0.0"
request@2, request@^2.72.0, request@^2.79.0, request@^2.81.0:
version "2.81.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
request@2, request@^2.72.0, request@^2.78.0, request@^2.79.0, request@~2.79.0:
version "2.79.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de"
dependencies:
aws-sign2 "~0.6.0"
aws4 "^1.2.1"
caseless "~0.12.0"
caseless "~0.11.0"
combined-stream "~1.0.5"
extend "~3.0.0"
forever-agent "~0.6.1"
form-data "~2.1.1"
har-validator "~4.2.1"
har-validator "~2.0.6"
hawk "~3.1.3"
http-signature "~1.1.0"
is-typedarray "~1.0.0"
@ -5182,12 +5182,10 @@ request@2, request@^2.72.0, request@^2.79.0, request@^2.81.0:
json-stringify-safe "~5.0.1"
mime-types "~2.1.7"
oauth-sign "~0.8.1"
performance-now "^0.2.0"
qs "~6.4.0"
safe-buffer "^5.0.1"
qs "~6.3.0"
stringstream "~0.0.4"
tough-cookie "~2.3.0"
tunnel-agent "^0.6.0"
tunnel-agent "~0.4.1"
uuid "^3.0.0"
request@2.78.0:
@ -5215,18 +5213,18 @@ request@2.78.0:
tough-cookie "~2.3.0"
tunnel-agent "~0.4.1"
request@^2.78.0, request@~2.79.0:
version "2.79.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de"
request@^2.81.0:
version "2.81.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
dependencies:
aws-sign2 "~0.6.0"
aws4 "^1.2.1"
caseless "~0.11.0"
caseless "~0.12.0"
combined-stream "~1.0.5"
extend "~3.0.0"
forever-agent "~0.6.1"
form-data "~2.1.1"
har-validator "~2.0.6"
har-validator "~4.2.1"
hawk "~3.1.3"
http-signature "~1.1.0"
is-typedarray "~1.0.0"
@ -5234,10 +5232,12 @@ request@^2.78.0, request@~2.79.0:
json-stringify-safe "~5.0.1"
mime-types "~2.1.7"
oauth-sign "~0.8.1"
qs "~6.3.0"
performance-now "^0.2.0"
qs "~6.4.0"
safe-buffer "^5.0.1"
stringstream "~0.0.4"
tough-cookie "~2.3.0"
tunnel-agent "~0.4.1"
tunnel-agent "^0.6.0"
uuid "^3.0.0"
require-directory@^2.1.1:

View File

@ -27,7 +27,11 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
.processor(require('./processors/simplifyMemberAnchors'))
// Where do we get the source files?
.config(function(readTypeScriptModules, readFilesProcessor, collectExamples) {
.config(function(readTypeScriptModules, readFilesProcessor, collectExamples, tsParser) {
// Tell TypeScript how to load modules that start with with `@angular`
tsParser.options.paths = { '@angular/*': [API_SOURCE_PATH + '/*'] };
tsParser.options.baseUrl = '.';
// API files are typescript
readTypeScriptModules.basePath = API_SOURCE_PATH;
@ -124,4 +128,5 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
convertToJsonProcessor.docTypes = convertToJsonProcessor.docTypes.concat(DOCS_TO_CONVERT);
postProcessHtml.docTypes = convertToJsonProcessor.docTypes.concat(DOCS_TO_CONVERT);
autoLinkCode.docTypes = DOCS_TO_CONVERT;
autoLinkCode.codeElements = ['code', 'code-example', 'code-pane'];
});

View File

@ -3,34 +3,69 @@ const is = require('hast-util-is-element');
const textContent = require('hast-util-to-string');
/**
* Automatically add in a link to the relevant document for simple
* code blocks, e.g. `<code>MyClass</code>` becomes
* `<code><a href="path/to/myclass">MyClass</a></code>`
* Automatically add in a link to the relevant document for code blocks.
* E.g. `<code>MyClass</code>` becomes `<code><a href="path/to/myclass">MyClass</a></code>`
*
* @property docTypes an array of strings. Only docs that have one of these docTypes
* will be linked to.
* @property docTypes an array of strings.
* Only docs that have one of these docTypes will be linked to.
* Usually set to the API exported docTypes, e.g. "class", "function", "directive", etc.
*
* @property codeElements an array of strings.
* Only text contained in these elements will be linked to.
* Usually set to "code" but also "code-example" for angular.io.
*/
module.exports = function autoLinkCode(getDocFromAlias) {
autoLinkCodeImpl.docTypes = [];
autoLinkCodeImpl.codeElements = ['code'];
return autoLinkCodeImpl;
function autoLinkCodeImpl() {
return (ast) => {
visit(ast, (node, ancestors) => {
if (is(node, 'code') && ancestors.every(ancestor => !is(ancestor, 'a'))) {
const docs = getDocFromAlias(textContent(node));
if (docs.length === 1 && autoLinkCodeImpl.docTypes.indexOf(docs[0].docType) !== -1) {
const link = {
type: 'element',
tagName: 'a',
properties: { href: docs[0].path },
children: node.children
};
node.children = [link];
}
visit(ast, 'element', (node, ancestors) => {
// Only interested in code elements that are not inside links
if (autoLinkCodeImpl.codeElements.some(elementType => is(node, elementType)) &&
ancestors.every(ancestor => !is(ancestor, 'a'))) {
visit(node, 'text', (node, ancestors) => {
// Only interested in text nodes that are not inside links
if (ancestors.every(ancestor => !is(ancestor, 'a'))) {
const parent = ancestors[ancestors.length-1];
const index = parent.children.indexOf(node);
// Can we convert the whole text node into a doc link?
const docs = getDocFromAlias(node.value);
if (foundValidDoc(docs)) {
parent.children.splice(index, 1, createLinkNode(docs[0], node.value));
} else {
// Parse the text for words that we can convert to links
const nodes = textContent(node).split(/([A-Za-z0-9_]+)/)
.filter(word => word.length)
.map(word => {
const docs = getDocFromAlias(word);
return foundValidDoc(docs) ?
createLinkNode(docs[0], word) : // Create a link wrapping the text node.
{ type: 'text', value: word }; // this is just text so push a new text node
});
// Replace the text node with the links and leftover text nodes
Array.prototype.splice.apply(parent.children, [index, 1].concat(nodes));
}
}
});
}
});
};
}
function foundValidDoc(docs) {
return docs.length === 1 && autoLinkCodeImpl.docTypes.indexOf(docs[0].docType) !== -1;
}
function createLinkNode(doc, text) {
return {
type: 'element',
tagName: 'a',
properties: { href: doc.path, class: 'code-anchor' },
children: [{ type: 'text', value: text }]
};
}
};

View File

@ -9,7 +9,7 @@ describe('autoLinkCode post-processor', () => {
const dgeni = new Dgeni([testPackage]);
const injector = dgeni.configureInjector();
autoLinkCode = injector.get('autoLinkCode');
autoLinkCode.docTypes = ['class', 'pipe'];
autoLinkCode.docTypes = ['class', 'pipe', 'function', 'const'];
aliasMap = injector.get('aliasMap');
processor = injector.get('postProcessHtml');
processor.docTypes = ['test-doc'];
@ -20,14 +20,14 @@ describe('autoLinkCode post-processor', () => {
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
const doc = { docType: 'test-doc', renderedContent: '<code>MyClass</code>' };
processor.$process([doc]);
expect(doc.renderedContent).toEqual('<code><a href="a/b/myclass">MyClass</a></code>');
expect(doc.renderedContent).toEqual('<code><a href="a/b/myclass" class="code-anchor">MyClass</a></code>');
});
it('should insert an anchor into every code item that matches an alias of an API doc', () => {
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass', 'foo.MyClass'], path: 'a/b/myclass' });
const doc = { docType: 'test-doc', renderedContent: '<code>foo.MyClass</code>' };
processor.$process([doc]);
expect(doc.renderedContent).toEqual('<code><a href="a/b/myclass">foo.MyClass</a></code>');
expect(doc.renderedContent).toEqual('<code><a href="a/b/myclass" class="code-anchor">foo.MyClass</a></code>');
});
it('should ignore code items that do not match a link to an API doc', () => {
@ -43,4 +43,35 @@ describe('autoLinkCode post-processor', () => {
processor.$process([doc]);
expect(doc.renderedContent).toEqual('<a href="..."><div><code>MyClass</code></div></a>');
});
it('should ignore code items match an API doc but are not in the list of acceptable docTypes', () => {
aliasMap.addDoc({ docType: 'directive', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
const doc = { docType: 'test-doc', renderedContent: '<code>MyClass</code>' };
processor.$process([doc]);
expect(doc.renderedContent).toEqual('<code>MyClass</code>');
});
it('should insert anchors for individual text nodes within a code block', () => {
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
const doc = { docType: 'test-doc', renderedContent: '<code><span>MyClass</span><span>MyClass</span></code>' };
processor.$process([doc]);
expect(doc.renderedContent).toEqual('<code><span><a href="a/b/myclass" class="code-anchor">MyClass</a></span><span><a href="a/b/myclass" class="code-anchor">MyClass</a></span></code>');
});
it('should insert anchors for words that match within text nodes in a code block', () => {
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
aliasMap.addDoc({ docType: 'function', id: 'myFunc', aliases: ['myFunc'], path: 'ng/myfunc' });
aliasMap.addDoc({ docType: 'const', id: 'MY_CONST', aliases: ['MY_CONST'], path: 'ng/my_const' });
const doc = { docType: 'test-doc', renderedContent: '<code>myFunc() {\n return new MyClass(MY_CONST);\n}</code>' };
processor.$process([doc]);
expect(doc.renderedContent).toEqual('<code><a href="ng/myfunc" class="code-anchor">myFunc</a>() {\n return new <a href="a/b/myclass" class="code-anchor">MyClass</a>(<a href="ng/my_const" class="code-anchor">MY_CONST</a>);\n}</code>');
});
it('should work with custom elements', () => {
autoLinkCode.codeElements = ['code-example'];
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
const doc = { docType: 'test-doc', renderedContent: '<code-example>MyClass</code-example>' };
processor.$process([doc]);
expect(doc.renderedContent).toEqual('<code-example><a href="a/b/myclass" class="code-anchor">MyClass</a></code-example>');
});
});

View File

@ -34,5 +34,5 @@ function getText(h1) {
(node.properties.ariaHidden === 'true' || node.properties['aria-hidden'] === 'true')
));
return cleaned ? toString(cleaned) : '';
return toString(cleaned);
}

View File

@ -69,14 +69,4 @@ describe('h1Checker postprocessor', () => {
processor.$process([doc]);
expect(doc.vFile.title).toEqual('What is Angular?');
});
it('should not break if the h1 is empty (except for an aria-hidden anchor)', () => {
const doc = {
docType: 'a',
renderedContent: `
<h1><a aria-hidden="true"></a></h1>
`
};
expect(() => processor.$process([doc])).not.toThrow();
});
});

View File

@ -7,8 +7,8 @@
{% block additional %}{% endblock %}
{% include "includes/description.html" %}
{$ memberHelpers.renderMemberDetails(doc.statics, 'static-members', 'static-member', 'Static Members') $}
{% include "includes/constructor.html" %}
{% if doc.constructorDoc %}{$ memberHelpers.renderMemberDetails([doc.constructorDoc], 'constructors', 'constructor', 'Constructor') $}{% endif %}
{$ memberHelpers.renderMemberDetails(doc.members, 'instance-members', 'instance-member', 'Members') $}
{% include "includes/annotations.html" %}
{% block annotations %}{% include "includes/annotations.html" %}{% endblock %}
{% endblock %}

View File

@ -9,3 +9,5 @@
{$ directiveHelper.renderBindings(doc.outputs, 'outputs', 'output', 'Outputs') $}
{% include "includes/export-as.html" %}
{% endblock %}
{% block annotations %}{% endblock %}

View File

@ -2,7 +2,7 @@
<section class="annotations">
<h2>Annotations</h2>
{%- for decorator in doc.decorators %}
<code-example hideCopy="true" class="no-box api-heading">@{$ decorator.name $}{$ params.paramList(decorator.arguments) $}</code-example>
<code-example hideCopy="true" class="no-box api-heading">@{$ decorator.name $}({$ decorator.arguments $})</code-example>
{% if not decorator.notYetDocumented %}{$ decorator.description | marked $}{% endif %}
{% endfor %}
</section>

View File

@ -4,10 +4,11 @@
<h2>Overview</h2>
<code-example language="ts" hideCopy="true">
{$ doc.docType $} {$ doc.name $}{$ doc.typeParams | escape $}{$ memberHelper.renderHeritage(doc) $} {
{%- if doc.constructorDoc %}{% if not doc.constructorDoc.internal %}
<a class="code-anchor" href="#{$ doc.constructorDoc.anchor $}">{$ memberHelper.renderMember(doc.constructorDoc, 1) $}</a>{% endif %}{% endif -%}
{%- if doc.statics.length %}{% for member in doc.statics %}{% if not member.internal %}
<a class="code-anchor" href="#{$ member.anchor $}">{$ memberHelper.renderMember(member, 1) $}</a>{% endif %}{% endfor %}{% endif %}
{%- if doc.members.length %}{% for member in doc.members %}{% if not member.internal %}
<a class="code-anchor" href="#{$ member.anchor $}">{$ memberHelper.renderMember(member, 1) $}</a>{% endif %}{% endfor %}{% endif %}
<a class="code-anchor" href="#{$ member.anchor $}">{$ memberHelper.renderMember(member, 1) $}</a>{% endif %}{% endfor %}{% endif -%}
{$ memberHelper.renderMembers(doc) $}
}
</code-example>
</section>

View File

@ -1,8 +0,0 @@
{%- if doc.constructorDoc and not doc.constructorDoc.internal %}
<section class="constructor">
<a id="{$ doc.constructorDoc.name $}"></a>
<h2>Constructor</h2>
<code-example hideCopy="true" class="no-box api-heading">{$ doc.constructorDoc.name $}{$ params.paramList(doc.constructorDoc.parameters) $}</code-example>
{% if not doc.constructorDoc.notYetDocumented %}{$ doc.constructorDoc.description | marked $}{% endif %}
</section>
{% endif %}

View File

@ -3,8 +3,7 @@
<section class="decorator-overview">
<h2>Metadata Overview</h2>
<code-example language="ts" hideCopy="true">
@{$ doc.name $}{$ doc.typeParams | escape $}({ {% if doc.members.length %}{% for member in doc.members %}{% if not member.internal %}
<a class="code-anchor" href="#{$ member.anchor $}">{$ memberHelper.renderMember(member, 1) $}</a>{% endif %}{% endfor %}{% endif %}
@{$ doc.name $}{$ doc.typeParams | escape $}({ {$ memberHelper.renderMembers(doc) $}
})
</code-example>
</section>

View File

@ -3,12 +3,11 @@
<section class="{$ doc.docType $}-overview">
<h2>Overview</h2>
<code-example language="ts" hideCopy="true">{% for decorator in doc.decorators %}
<a href="#annotations">@{$ decorator.name $}{$ params.paramList(decorator.arguments) $}</a>{% endfor %}
@{$ 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 $}">{$ memberHelper.renderMember(member, 1) $}</a>{% endif %}{% endfor %}{% endif %}
{%- if doc.members.length %}{% for member in doc.members %}{% if not member.internal %}
<a class="code-anchor" href="#{$ member.anchor $}">{$ memberHelper.renderMember(member, 1) $}</a>{% endif %}{% endfor %}{% endif %}
<a class="code-anchor" href="#{$ member.anchor $}">{$ memberHelper.renderMember(member, 1) $}</a>{% endif %}{% endfor %}{% endif -%}
{$ memberHelper.renderMembers(doc) $}
}
</code-example>
</section>

View File

@ -1,10 +1,9 @@
{%- if doc.selector %}
<section class="selectors">
<h2>Selectors</h2>
{% for selector in doc.selector.split(',') %}
<div class="selector">
<code>{$ selector $}</code>
</div>
{% endfor %}
<code-example hideCopy="true" class="no-box api-heading selector">
{%- for selector in doc.selector.split(',') %}
{$ selector $}{% endfor %}
</code-example>
</section>
{% endif %}

View File

@ -2,13 +2,20 @@
{%- macro renderHeritage(exportDoc) -%}
{%- if exportDoc.extendsClauses.length %} extends {% for clause in exportDoc.extendsClauses -%}
{$ clause $}{% if not loop.last %}, {% endif -%}
<a class="code-anchor" href="{$ clause.doc.path $}">{$ clause.text $}</a>{% if not loop.last %}, {% endif -%}
{% endfor %}{% endif %}
{%- if exportDoc.implementsClauses.length %} implements {% for clause in exportDoc.implementsClauses -%}
{$ clause $}{% if not loop.last %}, {% endif -%}
<a class="code-anchor" href="{$ clause.doc.path $}">{$ clause.text $}</a>{% if not loop.last %}, {% endif -%}
{% endfor %}{% endif %}
{%- endmacro -%}
{%- macro renderMembers(doc) -%}
{%- if doc.members.length %}{% for member in doc.members %}{% if not member.internal %}
<a class="code-anchor" href="{$ doc.path $}#{$ member.anchor $}">{$ renderMember(member, 1) $}</a>{% endif %}{% endfor %}{% endif %}
{%- for ancestor in doc.extendsClauses %}{% if ancestor.doc %}
// inherited from <a class="code-anchor" href="{$ ancestor.doc.path $}">{$ ancestor.doc.id $}</a>{$ renderMembers(ancestor.doc) $}{% endif %}{% endfor %}
{%- endmacro -%}
{%- macro renderMember(member, truncateLines) -%}
{%- if member.accessibility !== 'public' %}{$ member.accessibility $} {% endif -%}
{%- if member.isGetAccessor %}get {% endif -%}

View File

@ -2002,9 +2002,9 @@ devtools-timeline-model@1.1.6:
chrome-devtools-frontend "1.0.401423"
resolve "1.1.7"
dgeni-packages@^0.20.0:
version "0.20.0"
resolved "https://registry.yarnpkg.com/dgeni-packages/-/dgeni-packages-0.20.0.tgz#e7da99b0a119ee2eb584202d054a5aa01f23e208"
dgeni-packages@^0.21.2:
version "0.21.2"
resolved "https://registry.yarnpkg.com/dgeni-packages/-/dgeni-packages-0.21.2.tgz#b031194176507b7c7d1c9735ea14664970763866"
dependencies:
canonical-path "0.0.2"
catharsis "^0.8.1"
@ -2026,7 +2026,7 @@ dgeni-packages@^0.20.0:
source-map-support "^0.4.15"
spdx-license-list "^2.1.0"
stringmap "^0.2.2"
typescript "^2.3.4"
typescript "2.4"
dgeni@^0.4.7:
version "0.4.7"
@ -7619,7 +7619,7 @@ typescript@2.3.2, "typescript@>=2.0.0 <2.5.0":
version "2.3.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.3.2.tgz#f0f045e196f69a72f06b25fd3bd39d01c3ce9984"
typescript@^2.3.3, typescript@^2.3.4:
typescript@2.4, typescript@^2.3.3:
version "2.4.1"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.4.1.tgz#c3ccb16ddaa0b2314de031e7e6fee89e5ba346bc"

View File

@ -86,7 +86,7 @@ done
#######################################
isIgnoredDirectory() {
name=$(basename ${1})
if [[ -f "${1}" || "${name}" == "src" || "${name}" == "test" || "${name}" == "integrationtest" || "${name}" == "i18n_data" ]]; then
if [[ -f "${1}" || "${name}" == "src" || "${name}" == "test" || "${name}" == "integrationtest" ]]; then
return 0
else
return 1
@ -327,23 +327,13 @@ mapSources() {
fi
}
updateVersionReferences() {
NPM_DIR="$1"
(
echo "====== VERSION: Updating version references in ${NPM_DIR}"
cd ${NPM_DIR}
echo "====== EXECUTE: perl -p -i -e \"s/0\.0\.0\-PLACEHOLDER/${VERSION}/g\" $""(grep -ril 0\.0\.0\-PLACEHOLDER .)"
perl -p -i -e "s/0\.0\.0\-PLACEHOLDER/${VERSION}/g" $(grep -ril 0\.0\.0\-PLACEHOLDER .) < /dev/null 2> /dev/null
)
}
VERSION="${VERSION_PREFIX}${VERSION_SUFFIX}"
echo "====== BUILDING: Version ${VERSION}"
N="
"
TSC=`pwd`/node_modules/.bin/tsc
NGC="node --max-old-space-size=3000 dist/packages-dist/tsc-wrapped/src/main"
NGC="node --max-old-space-size=3000 dist/tools/@angular/tsc-wrapped/src/main"
MAP_SOURCES="node `pwd`/scripts/build/map_sources.js "
UGLIFYJS=`pwd`/node_modules/.bin/uglifyjs
TSCONFIG=./tools/tsconfig.json
@ -355,6 +345,8 @@ if [[ ${BUILD_TOOLS} == true ]]; then
rm -rf ./dist/tools/
mkdir -p ./dist/tools/
$(npm bin)/tsc -p ${TSCONFIG}
cp ./tools/@angular/tsc-wrapped/package.json ./dist/tools/@angular/tsc-wrapped
travisFoldEnd "build tools"
fi
@ -406,11 +398,11 @@ if [[ ${BUILD_ALL} == true && ${TYPECHECK_ALL} == true ]]; then
TSCONFIG="packages/tsconfig.json"
travisFoldStart "tsc -p ${TSCONFIG}" "no-xtrace"
$TSC -p ${TSCONFIG}
$NGC -p ${TSCONFIG}
travisFoldEnd "tsc -p ${TSCONFIG}"
TSCONFIG="modules/tsconfig.json"
travisFoldStart "tsc -p ${TSCONFIG}" "no-xtrace"
$TSC -p ${TSCONFIG}
$NGC -p ${TSCONFIG}
travisFoldEnd "tsc -p ${TSCONFIG}"
fi
@ -422,22 +414,6 @@ if [[ ${BUILD_ALL} == true ]]; then
fi
fi
if [[ ${BUILD_TOOLS} == true || ${BUILD_ALL} == true ]]; then
echo "====== (tsc-wrapped)COMPILING: \$(npm bin)/tsc -p packages/tsc-wrapped/tsconfig.json ====="
$(npm bin)/tsc -p packages/tsc-wrapped/tsconfig.json
echo "====== (tsc-wrapped)COMPILING: \$(npm bin)/tsc -p packages/tsc-wrapped/tsconfig-build.json ====="
$(npm bin)/tsc -p packages/tsc-wrapped/tsconfig-build.json
cp ./packages/tsc-wrapped/package.json ./dist/packages-dist/tsc-wrapped
cp ./packages/tsc-wrapped/README.md ./dist/packages-dist/tsc-wrapped
updateVersionReferences dist/packages-dist/tsc-wrapped
rsync -a packages/bazel/ ./dist/packages-dist/bazel
# Remove BEGIN-INTERNAL...END-INTERAL blocks
# https://stackoverflow.com/questions/24175271/how-can-i-match-multi-line-patterns-in-the-command-line-with-perl-style-regex
perl -0777 -n -i -e "s/(?m)^.*BEGIN-INTERNAL[\w\W]*END-INTERNAL.*\n//g; print" $(grep -ril BEGIN-INTERNAL dist/packages-dist/bazel) < /dev/null 2> /dev/null
updateVersionReferences dist/packages-dist/bazel
fi
for PACKAGE in ${PACKAGES[@]}
do
travisFoldStart "build package: ${PACKAGE}" "no-xtrace"
@ -482,11 +458,6 @@ do
minify ${BUNDLES_DIR}
) 2>&1 | grep -v "as external dependency"
if [[ ${PACKAGE} == "common" ]]; then
echo "====== Copy i18n locale data"
rsync -a --exclude=*.d.ts --exclude=*.metadata.json ${OUT_DIR}/i18n_data/ ${NPM_DIR}/i18n_data
fi
else
echo "====== Copy ${PACKAGE} node tool"
rsync -a ${OUT_DIR}/ ${NPM_DIR}
@ -501,7 +472,12 @@ do
if [[ -d ${NPM_DIR} ]]; then
updateVersionReferences ${NPM_DIR}
(
echo "====== VERSION: Updating version references"
cd ${NPM_DIR}
echo "====== EXECUTE: perl -p -i -e \"s/0\.0\.0\-PLACEHOLDER/${VERSION}/g\" $""(grep -ril 0\.0\.0\-PLACEHOLDER .)"
perl -p -i -e "s/0\.0\.0\-PLACEHOLDER/${VERSION}/g" $(grep -ril 0\.0\.0\-PLACEHOLDER .) < /dev/null 2> /dev/null
)
fi
travisFoldEnd "build package: ${PACKAGE}"

92
docs/CARETAKER.md Normal file
View File

@ -0,0 +1,92 @@
# Caretaker
Caretaker is responsible for merging PRs into the individual branches and internally at Google.
## Responsibilities
- Draining the queue of PRs ready to be merged. (PRs with [`PR action: merge`](https://github.com/angular/angular/pulls?q=is%3Aopen+is%3Apr+label%3A%22PR+action%3A+merge%22) label)
- Assigining [new issues](https://github.com/angular/angular/issues?q=is%3Aopen+is%3Aissue+no%3Alabel) to individual component authors.
## Setup
### Set `upstream` to fetch PRs into your local repo
Use this conmmands to configure your `git` to fetch PRs into your local repo.
```
git remote add upstream git@github.com:angular/angular.git
git config --add remote.upstream.fetch +refs/pull/*/head:refs/remotes/upstream/pr/*
```
## Merging the PR
A PR needs to have `PR action: merge` and `PR target: *` labels to be considered
ready to merge. Merging is performed by running `merge-pr` with a PR number to merge.
NOTE: before running `merge-pr` ensure that you have synced all of the PRs
locally by running:
```
$ git fetch upstream
```
To merge a PR run:
```
$ ./scripts/github/merge-pr 1234
```
The `merge-pr` script will:
- Ensure that all approriate labels are on the PR.
- That the current branch (`master` or `?.?.x` patch) mathches the `PR target: *` label.
- It will `cherry-pick` all of the SHAs from the PR into the current branch.
- It will rewrite commit history by automatically adding `Close #1234` and `(#1234)` into the commit message.
### Recovering from failed `merge-pr` due to conflicts
When running `merge-pr` the script will output the commands which it is about to run.
```
$ ./scripts/github/merge-pr 1234
======================
GitHub Merge PR Steps
======================
git cherry-pick upstream/pr/1234~1..upstream/pr/1234
git filter-branch -f --msg-filter "/usr/local/google/home/misko/angular-pr/scripts/github/utils/github.closes 1234" HEAD~1..HEAD
```
If the `cherry-pick` command fails than resolve conflicts and use `git cherry-pick --continue` once ready. After the `cherry-pick` is done cut&paste and run the `filter-branch` command to properly rewrite the messages
## Cherry-picking PRs into patch branch
In addition to merging PRs into the master branch, many PRs need to be also merged into a patch branch.
Follow these steps to get path brach up to date.
1. Check out the most recent patch branch: `git checkout 4.3.x`
2. Get a list of PRs merged into master: `git log master --oneline -n10`
3. For each PR number in the commit message run: `././scripts/github/merge-pr 1234`
- The PR will only merge if the `PR target:` matches the branch.
Once all of the PRs are in patch branch, push the all branches and tags to github using `push-upstream` script.
## Pushing merged PRs into github
Use `push-upstream` script to push all of the branch and tags to github.
```
$ ./scripts/github/push-upstream
git push git@github.com:angular/angular.git master:master 4.3.x:4.3.x
Counting objects: 25, done.
Delta compression using up to 6 threads.
Compressing objects: 100% (17/17), done.
Writing objects: 100% (25/25), 2.22 KiB | 284.00 KiB/s, done.
Total 25 (delta 22), reused 8 (delta 7)
remote: Resolving deltas: 100% (22/22), completed with 18 local objects.
To github.com:angular/angular.git
079d884b6..d1c4a94bb master -> master
git push --tags -f git@github.com:angular/angular.git patch_sync:patch_sync
Everything up-to-date
```

View File

@ -13,8 +13,8 @@ Change approvals in our monorepo are managed via [pullapprove.com](https://about
# Merging
Once a change has all the approvals either the last approver or the PR author (if PR author has the project collaborator status) should mark the PR with "PR: merge" label.
This signals to the caretaker that the PR should be merged.
Once a change has all the approvals either the last approver or the PR author (if PR author has the project collaborator status) should mark the PR with `PR: merge` as well as `PR target: *` labels.
This signals to the caretaker that the PR should be merged. See [merge instructions](../CARETAKER.md).
# Who is the Caretaker?

View File

@ -42,5 +42,3 @@ gulp.task('serve', loadTask('serve', 'default'));
gulp.task('serve-examples', loadTask('serve', 'examples'));
gulp.task('changelog', loadTask('changelog'));
gulp.task('check-env', () => {/* this is a noop because the env test ran already above */});
gulp.task('cldr:extract', loadTask('cldr', 'extract'));
gulp.task('cldr:download', loadTask('cldr', 'download'));

View File

@ -1,13 +1,10 @@
built/
dist/
vendor/
yarn.lock
.ng-cli/
cli-*/**
*/src/*.d.ts
*/src/*.js
**/*.ngfactory.ts
**/*.ngsummary.json
**/*.ngsummary.ts
*/yarn*
**/.yarn_local_cache*
*/.yarn_local_cache*

View File

@ -1,19 +0,0 @@
#!/bin/bash
set -u -e -o pipefail
declare -A payloadLimits
payloadLimits["hello_world__closure", "uncompressed", "bundle"]=106000
payloadLimits["hello_world__closure", "gzip7", "bundle"]=35000
payloadLimits["hello_world__closure", "gzip9", "bundle"]=35000
payloadLimits["cli-hello-world", "uncompressed", "inline"]=1500
payloadLimits["cli-hello-world", "uncompressed", "main"]=183000
payloadLimits["cli-hello-world", "uncompressed", "polyfills"]=63000
payloadLimits["cli-hello-world", "gzip7", "inline"]=900
payloadLimits["cli-hello-world", "gzip7", "main"]=48000
payloadLimits["cli-hello-world", "gzip7", "polyfills"]=21000
payloadLimits["cli-hello-world", "gzip9", "inline"]=900
payloadLimits["cli-hello-world", "gzip9", "main"]=48000
payloadLimits["cli-hello-world", "gzip9", "polyfills"]=21000

View File

@ -1,10 +0,0 @@
package(default_visibility = ["//visibility:public"])
filegroup(
name = "node_modules",
srcs = glob([
"node_modules/**/*.js",
"node_modules/**/*.d.ts",
"node_modules/**/*.json",
])
)

View File

@ -1,30 +0,0 @@
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
git_repository(
name = "build_bazel_rules_nodejs",
remote = "https://github.com/bazelbuild/rules_nodejs.git",
tag = "0.0.2",
)
load("@build_bazel_rules_nodejs//:defs.bzl", "node_repositories")
node_repositories(package_json = ["//:package.json"])
local_repository(
name = "build_bazel_rules_typescript",
path = "node_modules/@bazel/typescript",
)
local_repository(
name = "angular",
path = "node_modules/@angular/bazel",
)
git_repository(
name = "io_bazel_rules_sass",
remote = "https://github.com/bazelbuild/rules_sass.git",
tag = "0.0.2",
)
load("@io_bazel_rules_sass//sass:sass.bzl", "sass_repositories")
sass_repositories()

View File

@ -1,23 +0,0 @@
// WORKAROUND https://github.com/angular/angular/issues/18810
// This file is required to run ngc on angular libraries, to write files like
// node_modules/@angular/core/core.ngsummary.json
{
"compilerOptions": {
"lib": [
"dom",
"es2015"
],
"experimentalDecorators": true,
"types": []
},
"include": [
"node_modules/@angular/**/*"
],
"exclude": [
"node_modules/@angular/bazel/**",
"node_modules/@angular/compiler-cli/**",
// Workaround bug introduced by 079d884
"node_modules/@angular/common/i18n_data*",
"node_modules/@angular/tsc-wrapped/**"
]
}

View File

@ -1,25 +0,0 @@
{
"name": "angular-bazel",
"description": "example and integration test for building Angular apps with Bazel",
"version": "0.0.0",
"license": "MIT",
"dependencies": {
"@angular/animations": "file:../../dist/packages-dist/animations",
"@angular/common": "file:../../dist/packages-dist/common",
"@angular/compiler": "file:../../dist/packages-dist/compiler",
"@angular/core": "file:../../dist/packages-dist/core",
"@angular/platform-browser": "file:../../dist/packages-dist/platform-browser",
"rxjs": "5.3.1",
"zone.js": "0.8.6"
},
"devDependencies": {
"@angular/bazel": "file:../../dist/packages-dist/bazel",
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
"@bazel/typescript": "0.0.7",
"typescript": "~2.3.1"
},
"scripts": {
"postinstall": "ngc -p angular.tsconfig.json",
"test": "bazel build ..."
}
}

View File

@ -1,11 +0,0 @@
load("@angular//:index.bzl", "ng_module")
# Allow targets under sub-packages to reference the tsconfig.json file
exports_files(["tsconfig.json"])
ng_module(
name = "app",
srcs = ["app.module.ts"],
deps = ["//src/hello-world"],
tsconfig = ":tsconfig.json",
)

View File

@ -1,9 +0,0 @@
import {HelloWorldModule} from './hello-world/hello-world.module';
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
@NgModule({
imports: [BrowserModule, HelloWorldModule]
})
export class AppModule {}

View File

@ -1,19 +0,0 @@
package(default_visibility = ["//visibility:public"])
load("@angular//:index.bzl", "ng_module")
load("@io_bazel_rules_sass//sass:sass.bzl", "sass_binary")
sass_binary(
name = "styles",
src = "hello-world.component.scss",
deps = [
"//src/shared:colors",
"//src/shared:fonts",
],
)
ng_module(
name = "hello-world",
srcs = glob(["*.ts"]),
tsconfig = "//src:tsconfig.json",
assets = [":styles"],
)

View File

@ -1,12 +0,0 @@
@import "src/shared/fonts";
@import "src/shared/colors";
html {
body {
font-family: $default-font-stack;
h1 {
font-family: $modern-font-stack;
color: $example-red;
}
}
}

View File

@ -1,15 +0,0 @@
import {Component, NgModule} from '@angular/core';
@Component({
selector: 'hello-world-app',
template: `
<div>Hello {{ name }}!</div>
<input type="text" [value]="name" (input)="name = $event.target.value"/>
`,
// TODO: might be better to point to .scss so this looks valid at design-time
styleUrls: ['./styles.css']
})
export class HelloWorldComponent {
name: string = 'world';
}

View File

@ -1,8 +0,0 @@
import {HelloWorldComponent} from './hello-world.component';
import {NgModule} from '@angular/core';
@NgModule({
declarations: [HelloWorldComponent],
bootstrap: [HelloWorldComponent],
})
export class HelloWorldModule {}

View File

@ -1,13 +0,0 @@
package(default_visibility = ["//visibility:public"])
load("@io_bazel_rules_sass//sass:sass.bzl", "sass_library")
sass_library(
name = "colors",
srcs = ["_colors.scss"],
)
sass_library(
name = "fonts",
srcs = ["_fonts.scss"],
)

View File

@ -1,2 +0,0 @@
$example-blue: #0000ff;
$example-red: #ff0000;

View File

@ -1,2 +0,0 @@
$default-font-stack: Cambria, "Hoefler Text", Utopia, "Liberation Serif", "Nimbus Roman No9 L Regular", Times, "Times New Roman", serif;
$modern-font-stack: Constantia, "Lucida Bright", Lucidabright, "Lucida Serif", Lucida, "DejaVu Serif", "Bitstream Vera Serif", "Liberation Serif", Georgia, serif;

View File

@ -1,12 +0,0 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"lib": [
"dom",
"es5",
"es2015.collection",
"es2015.iterable",
"es2015.promise"
]
}
}

View File

@ -10,10 +10,10 @@
"@angular/core": "file:../../dist/packages-dist/core",
"@angular/platform-browser": "file:../../dist/packages-dist/platform-browser",
"@angular/platform-server": "file:../../dist/packages-dist/platform-server",
"@angular/tsc-wrapped": "file:../../dist/packages-dist/tsc-wrapped",
"@angular/tsc-wrapped": "file:../../dist/tools/@angular/tsc-wrapped",
"google-closure-compiler": "20170409.0.0",
"rxjs": "5.3.1",
"typescript": "~2.3.1",
"typescript": "2.1.6",
"zone.js": "0.8.6"
},
"devDependencies": {

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