Compare commits
292 Commits
merge_pr_m
...
5.2.9
Author | SHA1 | Date | |
---|---|---|---|
5298b2bda3 | |||
25ae886cad | |||
fc6dfc2e08 | |||
c0670ef52d | |||
fe96cafd03 | |||
ad674dad37 | |||
86517f2ad5 | |||
6d9a4f8aea | |||
a1efc27ff2 | |||
311232004c | |||
2a236b4066 | |||
bdee824292 | |||
4aeb04dcb0 | |||
5876fb0125 | |||
5b7b208637 | |||
789a47ec44 | |||
984a13e45b | |||
a3f7e30153 | |||
ff7e2e3f1e | |||
fe0d53f3a9 | |||
27962f8949 | |||
855e3a65db | |||
f8e70fb0c6 | |||
697d31a38c | |||
1593bff1b0 | |||
0ec11e3223 | |||
089769d5c3 | |||
9137650dba | |||
eccce1772d | |||
4aef9de37e | |||
f2fa7a289f | |||
e1fbe20d98 | |||
38bd8d49a5 | |||
d033106adb | |||
de02a7a5de | |||
c30a942329 | |||
2a38d93171 | |||
a9a0e27e94 | |||
66383901a6 | |||
1eb54132e4 | |||
6c9c173e1e | |||
1e08a945e1 | |||
4a08745d3e | |||
cf91906d8f | |||
0723c04a01 | |||
2b7188906b | |||
17c1577de9 | |||
150bac310f | |||
8f0a0641e2 | |||
17762390c9 | |||
da1b4d5ea7 | |||
aa100f69f2 | |||
9cca5a8c9c | |||
7c3b95b4ab | |||
e4e8a68c06 | |||
6460ac0add | |||
ee91de9d5a | |||
5ec38f2f47 | |||
612cfeca14 | |||
dfdade25ea | |||
c2f78e1ca3 | |||
484802cd2a | |||
ee535777bb | |||
94756eb4bd | |||
23b0707707 | |||
a2cb0109f1 | |||
d20a08bc48 | |||
5bdb3acace | |||
c5418c7abe | |||
09b4612bdd | |||
a346d28df6 | |||
bf07837d5d | |||
cdfedc1e49 | |||
af6a0563de | |||
c726d1d6d3 | |||
2030846df7 | |||
9dae97c5d9 | |||
228eb9feef | |||
debf01d7a6 | |||
51abe69b60 | |||
396bc0d9e9 | |||
861250b4e2 | |||
81c1e0a3c3 | |||
ce5e8fad9e | |||
185a6ab562 | |||
6b457843b9 | |||
5f52ea3d06 | |||
6c1e7ac40e | |||
6597616aac | |||
6a57264d38 | |||
1e3e0fad49 | |||
0c88d5dedd | |||
0b8b06ee8b | |||
edd6cd4e29 | |||
fdbfd21bcd | |||
0a5283da1a | |||
3237f1dbfc | |||
106b435297 | |||
ca69dfde31 | |||
1b8ea1005a | |||
da6ab91095 | |||
c4f841f031 | |||
e576b69d10 | |||
f938774748 | |||
c0b78067c4 | |||
2931018b84 | |||
e97afae67a | |||
c6bdc831c1 | |||
1a897e4f48 | |||
603e50d3bf | |||
ca5b72461c | |||
a616dd6c17 | |||
0ed64af5bc | |||
d57fd0b84f | |||
9b280eef63 | |||
d4a9db2af5 | |||
2740b69023 | |||
15ff7ba880 | |||
615bb95138 | |||
2b67400652 | |||
ac815f7281 | |||
854f0ff33a | |||
c55523466f | |||
f80b9da18a | |||
c5ec8d952a | |||
de561f36e1 | |||
47b71d98ae | |||
22d548f4ed | |||
799edd1e2f | |||
ffcb5dd264 | |||
75897d4977 | |||
eb0da530a7 | |||
0b23573573 | |||
47b73fd153 | |||
07769e5caa | |||
9fdb804b63 | |||
9d02db3254 | |||
920b0df32a | |||
b313976ac1 | |||
2d19e7bbea | |||
c3c92d7796 | |||
a887c9339f | |||
89051a0452 | |||
97dafa8460 | |||
56b9591746 | |||
b0ddb5ad0e | |||
103727aadf | |||
44ea80b797 | |||
41046e4a90 | |||
530b824faa | |||
e22d3a605c | |||
c6645e7a04 | |||
f0396f1e54 | |||
adb1d62967 | |||
cfe83939a4 | |||
973607fe9d | |||
664f7fa477 | |||
b155ae116b | |||
ce51ea93a1 | |||
d38e08812e | |||
aa9ba7f9fe | |||
102d06b974 | |||
11ec80a053 | |||
75eecdc351 | |||
965eecc587 | |||
c4fb696189 | |||
72df747dd6 | |||
579bed1a7a | |||
b59fb23f4a | |||
2aa460b30e | |||
e0022ae9cd | |||
f2e923edd8 | |||
c2f5ed545c | |||
5d75df8fb1 | |||
ed2b71799c | |||
fad99cca0e | |||
3f5ead3845 | |||
a89e709515 | |||
6a7689d4ea | |||
696ba01a4e | |||
81d64d6bec | |||
7410941a7c | |||
d159ad8b88 | |||
250c8da768 | |||
778e6e759f | |||
35a0721217 | |||
ba045e88d7 | |||
67806a7b25 | |||
9778a23be8 | |||
87e06d765e | |||
56f3e18c1c | |||
637515e71b | |||
27ecd077d4 | |||
4db1be0292 | |||
a0dbef9ea4 | |||
3aaf43f73c | |||
d952ae24dd | |||
da9e57b3d5 | |||
44d4f82dae | |||
bde2b4425c | |||
2a3de802a0 | |||
71f9eaa743 | |||
a62c186d15 | |||
c8bf281174 | |||
de6c6445af | |||
54238822e6 | |||
8b3fbb5bf4 | |||
2f61d3c320 | |||
5894f6ee1c | |||
6d9fcd62de | |||
0cbccc06dd | |||
ed670a36fb | |||
8e44577df3 | |||
6921c20ea1 | |||
52970c09e1 | |||
eecdf3414e | |||
21f766968d | |||
4b68fdce6f | |||
c12ea3a1f0 | |||
d7dbdc5c36 | |||
0112a903f9 | |||
66bbc84127 | |||
554129d6fe | |||
e32a0cabfe | |||
c828e5627b | |||
1626e74c59 | |||
a15a2b46d1 | |||
379ed75593 | |||
0f619896b3 | |||
7060655806 | |||
b5fc3eb9de | |||
451bdb9a75 | |||
983ccc02ad | |||
00f99b3c4c | |||
ba4ea82f68 | |||
982eb7bba8 | |||
3606c55410 | |||
2c65027391 | |||
4ee92f14a6 | |||
c9b65914d3 | |||
02352bcd9e | |||
0d55600fd8 | |||
af4eb00c91 | |||
d3e7ebb3b4 | |||
420f5c4275 | |||
b773a4ab98 | |||
55f15c54d9 | |||
4556532c26 | |||
54e75766ad | |||
d3333f04ba | |||
75f8522b8d | |||
a771ee5d90 | |||
a4cbe3542a | |||
cc9419d1ca | |||
d5393c7f91 | |||
71dd92bbb8 | |||
977978edb5 | |||
eb70966065 | |||
cf4bea587d | |||
8e9cd57951 | |||
f23896f519 | |||
0e59d18fc2 | |||
54c8a321a9 | |||
9005a6f3cd | |||
3c6a5063f7 | |||
b49d54e606 | |||
55fd82e587 | |||
7f3d0bbf97 | |||
3db02d244a | |||
50b605686e | |||
64d4aafbc7 | |||
a931a419fa | |||
6a97b5b722 | |||
aad1126446 | |||
7b463df52b | |||
a2432c9f10 | |||
e500484ccc | |||
a0dcb0b828 | |||
c4b71920d1 | |||
650f5fb5c7 | |||
c32e83334b | |||
7bdd9aecbd | |||
5ede67c345 | |||
31b671ab54 | |||
3804d20b6d | |||
0a5a87887e | |||
c46afce0f5 | |||
76c781fd37 | |||
51eb3d418e | |||
48c18985cc | |||
167cbed266 | |||
70e8802540 |
@ -15,11 +15,16 @@ build --experimental_remote_spawn_cache --remote_rest_cache=http://localhost:764
|
||||
# Prevent unstable environment variables from tainting cache keys
|
||||
build --experimental_strict_action_env
|
||||
|
||||
# Save downloaded repositories such as the go toolchain
|
||||
# This directory can then be included in the CircleCI cache
|
||||
# It should save time running the first build
|
||||
build --experimental_repository_cache=/home/circleci/bazel_repository_cache
|
||||
|
||||
# Workaround https://github.com/bazelbuild/bazel/issues/3645
|
||||
# Bazel doesn't calculate the memory ceiling correctly when running under Docker.
|
||||
# Limit Bazel to consuming resources that fit in CircleCI "medium" class which is the default:
|
||||
# Limit Bazel to consuming resources that fit in CircleCI "xlarge" class
|
||||
# https://circleci.com/docs/2.0/configuration-reference/#resource_class
|
||||
build --local_resources=3072,2.0,1.0
|
||||
build --local_resources=14336,8.0,1.0
|
||||
|
||||
# Retry in the event of flakes, eg. https://circleci.com/gh/angular/angular/31309
|
||||
test --flaky_test_attempts=2
|
||||
|
@ -13,7 +13,7 @@
|
||||
# If you change the `docker_image` version, also change the `cache_key` suffix and the version of
|
||||
# `com_github_bazelbuild_buildtools` in the `/WORKSPACE` file.
|
||||
var_1: &docker_image angular/ngcontainer:0.1.0
|
||||
var_2: &cache_key angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.1.0
|
||||
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.1.0
|
||||
|
||||
# See remote cache documentation in /docs/BAZEL.md
|
||||
var_3: &setup-bazel-remote-cache
|
||||
@ -41,14 +41,14 @@ jobs:
|
||||
steps:
|
||||
- checkout:
|
||||
<<: *post_checkout
|
||||
# See remote cache documentation in /docs/BAZEL.md
|
||||
- run: .circleci/setup_cache.sh
|
||||
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
|
||||
- *setup-bazel-remote-cache
|
||||
|
||||
- run: 'yarn buildifier -mode=check ||
|
||||
(echo -e "\nBUILD files not formatted. Please run ''yarn buildifier''" ; exit 1)'
|
||||
- run: 'yarn skylint ||
|
||||
# Check BUILD.bazel formatting before we have a node_modules directory
|
||||
# Then we don't need any exclude pattern to avoid checking those files
|
||||
- run: 'buildifier -mode=check $(find . -type f \( -name BUILD.bazel -or -name BUILD \)) ||
|
||||
(echo "BUILD files not formatted. Please run ''yarn buildifier''" ; exit 1)'
|
||||
# Run the skylark linter to check our Bazel rules
|
||||
- run: 'find . -type f -name "*.bzl" |
|
||||
xargs java -jar /usr/local/bin/Skylint_deploy.jar ||
|
||||
(echo -e "\n.bzl files have lint errors. Please run ''yarn skylint''"; exit 1)'
|
||||
|
||||
- restore_cache:
|
||||
@ -59,7 +59,7 @@ jobs:
|
||||
|
||||
build:
|
||||
<<: *job_defaults
|
||||
resource_class: large
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout:
|
||||
<<: *post_checkout
|
||||
@ -71,6 +71,7 @@ jobs:
|
||||
- restore_cache:
|
||||
key: *cache_key
|
||||
|
||||
- run: ls /home/circleci/bazel_repository_cache || true
|
||||
- run: bazel info release
|
||||
- run: bazel run @yarn//:yarn
|
||||
# Use bazel query so that we explicitly ask for all buildable targets to be built as well
|
||||
@ -78,19 +79,11 @@ jobs:
|
||||
# See https://github.com/bazelbuild/bazel/issues/4257
|
||||
- run: bazel query --output=label '//modules/... union //packages/... union //tools/...' | xargs bazel test
|
||||
|
||||
# CircleCI will allow us to go back and view/download these artifacts from past builds.
|
||||
# Also we can use a service like https://buildsize.org/ to automatically track binary size of these artifacts.
|
||||
- store_artifacts:
|
||||
path: dist/bin/packages/core/test/bundling/hello_world/bundle.min.js
|
||||
destination: packages/core/test/bundling/hello_world/bundle.min.js
|
||||
- store_artifacts:
|
||||
path: dist/bin/packages/core/test/bundling/hello_world/bundle.min.js.brotli
|
||||
destination: packages/core/test/bundling/hello_world/bundle.min.js.brotli
|
||||
|
||||
- save_cache:
|
||||
key: *cache_key
|
||||
paths:
|
||||
- "node_modules"
|
||||
- "~/bazel_repository_cache"
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
|
4
.github/angular-robot.yml
vendored
4
.github/angular-robot.yml
vendored
@ -80,14 +80,12 @@ merge:
|
||||
|
||||
# options for the triage plugin
|
||||
triage:
|
||||
# number of the milestone to apply when the issue has not been triaged yet
|
||||
needsTriageMilestone: 83,
|
||||
# number of the milestone to apply when the issue is triaged
|
||||
defaultMilestone: 82,
|
||||
# arrays of labels that determine if an issue is triaged
|
||||
triagedLabels:
|
||||
-
|
||||
- "type: bug/fix"
|
||||
- "type: bug"
|
||||
- "severity*"
|
||||
- "freq*"
|
||||
- "comp: *"
|
||||
|
@ -207,12 +207,6 @@ groups:
|
||||
conditions:
|
||||
files:
|
||||
- "packages/forms/*"
|
||||
- "aio/content/guide/forms.md"
|
||||
- "aio/content/guide/form-validation.md"
|
||||
- "aio/content/guide/reactive-forms.md"
|
||||
- "aio/content/examples/forms/*"
|
||||
- "aio/content/examples/form-validation/*"
|
||||
- "aio/content/examples/reactive-forms/*"
|
||||
users:
|
||||
- kara #primary
|
||||
- tinayuangao #secondary
|
||||
|
194
CHANGELOG.md
194
CHANGELOG.md
@ -1,69 +1,42 @@
|
||||
<a name="6.0.0-beta.5"></a>
|
||||
# [6.0.0-beta.5](https://github.com/angular/angular/compare/6.0.0-beta.4...6.0.0-beta.5) (2018-02-22)
|
||||
<a name="5.2.9"></a>
|
||||
## [5.2.9](https://github.com/angular/angular/compare/5.2.8...5.2.9) (2018-03-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **animations:** report correct totalTime value even during noOp animations ([#22225](https://github.com/angular/angular/issues/22225)) ([e1bf067](https://github.com/angular/angular/commit/e1bf067))
|
||||
* **common:** correct mapping of Observable methods ([#20518](https://github.com/angular/angular/issues/20518)) ([2639b4b](https://github.com/angular/angular/commit/2639b4b)), closes [#20516](https://github.com/angular/angular/issues/20516)
|
||||
* **common:** then and else template might be set to null ([#22298](https://github.com/angular/angular/issues/22298)) ([8115edc](https://github.com/angular/angular/commit/8115edc))
|
||||
* **compiler-cli:** add missing entry point to package, update tsickle ([#22295](https://github.com/angular/angular/issues/22295)) ([28ac244](https://github.com/angular/angular/commit/28ac244))
|
||||
* **core:** properly handle function without prototype in reflector ([#22284](https://github.com/angular/angular/issues/22284)) ([a7ebf5a](https://github.com/angular/angular/commit/a7ebf5a)), closes [#19978](https://github.com/angular/angular/issues/19978)
|
||||
* **core:** require factory to be provided for shakeable InjectionToken ([#22207](https://github.com/angular/angular/issues/22207)) ([f755db7](https://github.com/angular/angular/commit/f755db7)), closes [#22205](https://github.com/angular/angular/issues/22205)
|
||||
* **forms:** set state before emitting a value from ngModelChange ([#21514](https://github.com/angular/angular/issues/21514)) ([3e6a86f](https://github.com/angular/angular/commit/3e6a86f)), closes [#21513](https://github.com/angular/angular/issues/21513)
|
||||
* **core:** set `preserveWhitespaces` to false by default ([#22046](https://github.com/angular/angular/issues/22046)) ([f1a0632](https://github.com/angular/angular/commit/f1a0632)), closes [#22027](https://github.com/angular/angular/issues/22027)
|
||||
* **platform-server:** add styles to elements correctly ([#22527](https://github.com/angular/angular/issues/22527)) ([fc6dfc2](https://github.com/angular/angular/commit/fc6dfc2))
|
||||
* **router:** correct over-encoding of URL fragment ([#22687](https://github.com/angular/angular/issues/22687)) ([86517f2](https://github.com/angular/angular/commit/86517f2))
|
||||
|
||||
### Features
|
||||
|
||||
* **common:** better error message when non-template element used in NgIf ([#22274](https://github.com/angular/angular/issues/22274)) ([67cf11d](https://github.com/angular/angular/commit/67cf11d)), closes [#16410](https://github.com/angular/angular/issues/16410)
|
||||
* **compiler-cli:** Check unvalidated combination of ngc and TypeScript ([#22293](https://github.com/angular/angular/issues/22293)) ([3ceee99](https://github.com/angular/angular/commit/3ceee99)), closes [#20669](https://github.com/angular/angular/issues/20669)
|
||||
* **core:** support metadata reflection for native class types ([#22356](https://github.com/angular/angular/issues/22356)) ([5c89d6b](https://github.com/angular/angular/commit/5c89d6b)), closes [#21731](https://github.com/angular/angular/issues/21731)
|
||||
* **platform-browser:** do not throw error when Hammer.js not loaded ([#22257](https://github.com/angular/angular/issues/22257)) ([991300b](https://github.com/angular/angular/commit/991300b)), closes [#16992](https://github.com/angular/angular/issues/16992)
|
||||
* **platform-browser:** fix [#19604](https://github.com/angular/angular/issues/19604), can config hammerOptions ([#21979](https://github.com/angular/angular/issues/21979)) ([1d571b2](https://github.com/angular/angular/commit/1d571b2))
|
||||
|
||||
### BREAKING CHANGES
|
||||
<a name="5.2.8"></a>
|
||||
## [5.2.8](https://github.com/angular/angular/compare/5.2.7...5.2.8) (2018-03-07)
|
||||
|
||||
* **animations:** When animation is triggered within a disabled zone, the
|
||||
associated event (which an instance of AnimationEvent) will no longer
|
||||
report the totalTime as 0 (it will emit the actual time of the
|
||||
animation). To detect if an animation event is reporting a disabled
|
||||
animation then the `event.disabled` property can be used instead.
|
||||
|
||||
* **forms:** ngModelChange is now emitted after the value/validity is updated on its control.
|
||||
### Bug Fixes
|
||||
|
||||
Previously, ngModelChange was emitted before its underlying control was updated.
|
||||
This was fine if you passed through the value directly through the $event keyword, e.g.
|
||||
* **platform-server:** generate correct stylings for camel case names ([#22263](https://github.com/angular/angular/issues/22263)) ([de02a7a](https://github.com/angular/angular/commit/de02a7a)), closes [#19235](https://github.com/angular/angular/issues/19235)
|
||||
* **router:** don't mutate route configs ([#22358](https://github.com/angular/angular/issues/22358)) ([8f0a064](https://github.com/angular/angular/commit/8f0a064)), closes [#22203](https://github.com/angular/angular/issues/22203)
|
||||
* **router:** fix URL serialization so special characters are only encoded where needed ([#22337](https://github.com/angular/angular/issues/22337)) ([789a47e](https://github.com/angular/angular/commit/789a47e)), closes [#10280](https://github.com/angular/angular/issues/10280)
|
||||
* **upgrade:** correctly destroy nested downgraded component ([#22400](https://github.com/angular/angular/issues/22400)) ([4aef9de](https://github.com/angular/angular/commit/4aef9de)), closes [#22392](https://github.com/angular/angular/issues/22392)
|
||||
* **upgrade:** correctly handle `=` bindings in `[@angular](https://github.com/angular)/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([6638390](https://github.com/angular/angular/commit/6638390))
|
||||
* **upgrade:** fix empty transclusion content with AngularJS@>=1.5.8 ([#22167](https://github.com/angular/angular/issues/22167)) ([a9a0e27](https://github.com/angular/angular/commit/a9a0e27)), closes [#22175](https://github.com/angular/angular/issues/22175)
|
||||
|
||||
```
|
||||
<input [(ngModel)]="name" (ngModelChange)="onChange($event)">
|
||||
|
||||
onChange(value) {
|
||||
console.log(value); // would log updated value
|
||||
}
|
||||
```
|
||||
|
||||
However, if you had a handler for the ngModelChange event that checked the value through the control,
|
||||
you would get the old value rather than the updated value. e.g:
|
||||
<a name="5.2.7"></a>
|
||||
## [5.2.7](https://github.com/angular/angular/compare/5.2.6...5.2.7) (2018-02-28)
|
||||
|
||||
```
|
||||
<input #modelDir="ngModel" [(ngModel)]="name" (ngModelChange)="onChange(modelDir)">
|
||||
|
||||
onChange(ngModel: NgModel) {
|
||||
console.log(ngModel.value); // would log old value, not updated value
|
||||
}
|
||||
```
|
||||
### Bug Fixes
|
||||
|
||||
Now the value and validity will be updated before the ngModelChange event is emitted,
|
||||
so the same setup will log the updated value.
|
||||
* **platform-server:** generate correct stylings for camel case names ([#22263](https://github.com/angular/angular/issues/22263)) ([de02a7a](https://github.com/angular/angular/commit/de02a7a)), closes [#19235](https://github.com/angular/angular/issues/19235)
|
||||
* **router:** don't mutate route configs ([#22358](https://github.com/angular/angular/issues/22358)) ([8f0a064](https://github.com/angular/angular/commit/8f0a064)), closes [#22203](https://github.com/angular/angular/issues/22203)
|
||||
* **upgrade:** correctly destroy nested downgraded component ([#22400](https://github.com/angular/angular/issues/22400)) ([4aef9de](https://github.com/angular/angular/commit/4aef9de)), closes [#22392](https://github.com/angular/angular/issues/22392)
|
||||
* **upgrade:** correctly handle `=` bindings in `[@angular](https://github.com/angular)/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([6638390](https://github.com/angular/angular/commit/6638390))
|
||||
* **upgrade:** fix empty transclusion content with AngularJS@>=1.5.8 ([#22167](https://github.com/angular/angular/issues/22167)) ([a9a0e27](https://github.com/angular/angular/commit/a9a0e27)), closes [#22175](https://github.com/angular/angular/issues/22175)
|
||||
|
||||
```
|
||||
onChange(ngModel: NgModel) {
|
||||
console.log(ngModel.value); // will log updated value
|
||||
}
|
||||
```
|
||||
|
||||
We think this order will be less confusing when the control is checked directly.
|
||||
You will only need to update your app if it has relied on this bug to keep track of the old control value.
|
||||
If that is the case, you should be able to track the old value directly by saving it on your component.
|
||||
|
||||
<a name="5.2.6"></a>
|
||||
## [5.2.6](https://github.com/angular/angular/compare/5.2.5...5.2.6) (2018-02-22)
|
||||
@ -76,35 +49,6 @@ If that is the case, you should be able to track the old value directly by savin
|
||||
* **core:** properly handle function without prototype in reflector ([#22284](https://github.com/angular/angular/issues/22284)) ([5ec38f2](https://github.com/angular/angular/commit/5ec38f2)), closes [#19978](https://github.com/angular/angular/issues/19978)
|
||||
* **core:** support metadata reflection for native class types ([#22356](https://github.com/angular/angular/issues/22356)) ([ee91de9](https://github.com/angular/angular/commit/ee91de9)), closes [#21731](https://github.com/angular/angular/issues/21731)
|
||||
|
||||
<a name="6.0.0-beta.4"></a>
|
||||
# [6.0.0-beta.4](https://github.com/angular/angular/compare/6.0.0-beta.3...6.0.0-beta.4) (2018-02-14)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bazel:** allow TS to read ambient typings ([#21876](https://github.com/angular/angular/issues/21876)) ([b081dfe](https://github.com/angular/angular/commit/b081dfe)), closes [#21872](https://github.com/angular/angular/issues/21872)
|
||||
* **bazel:** improve error message for missing assets ([#22096](https://github.com/angular/angular/issues/22096)) ([dcf64a0](https://github.com/angular/angular/commit/dcf64a0)), closes [#22095](https://github.com/angular/angular/issues/22095)
|
||||
* **common:** add locale currency values ([#21783](https://github.com/angular/angular/issues/21783)) ([420cc7a](https://github.com/angular/angular/commit/420cc7a)), closes [#20385](https://github.com/angular/angular/issues/20385)
|
||||
* **common:** round currencies based on decimal digits in `CurrencyPipe` ([#21783](https://github.com/angular/angular/issues/21783)) ([44154e7](https://github.com/angular/angular/commit/44154e7)), closes [#10189](https://github.com/angular/angular/issues/10189)
|
||||
* **common:** weaken AsyncPipe transform signature ([#22169](https://github.com/angular/angular/issues/22169)) ([be59c3a](https://github.com/angular/angular/commit/be59c3a))
|
||||
* **compiler:** make unary plus operator consistent to JavaScript ([#22154](https://github.com/angular/angular/issues/22154)) ([72f8abd](https://github.com/angular/angular/commit/72f8abd)), closes [#22089](https://github.com/angular/angular/issues/22089)
|
||||
* **core:** add stacktrace in log when error during cleanup component in TestBed ([#22162](https://github.com/angular/angular/issues/22162)) ([16d1700](https://github.com/angular/angular/commit/16d1700))
|
||||
* **core:** ensure initial value of QueryList length ([#21980](https://github.com/angular/angular/issues/21980)) ([#21982](https://github.com/angular/angular/issues/21982)) ([e56de10](https://github.com/angular/angular/commit/e56de10)), closes [#21980](https://github.com/angular/angular/issues/21980)
|
||||
* **core:** use appropriate inert document strategy for Firefox & Safari ([#17019](https://github.com/angular/angular/issues/17019)) ([a751649](https://github.com/angular/angular/commit/a751649))
|
||||
* **forms:** make Validators.email support optional controls ([#20869](https://github.com/angular/angular/issues/20869)) ([140e7c0](https://github.com/angular/angular/commit/140e7c0))
|
||||
* **forms:** prevent event emission on enable/disable when emitEvent is false ([#12366](https://github.com/angular/angular/issues/12366)) ([#21018](https://github.com/angular/angular/issues/21018)) ([0bcfae7](https://github.com/angular/angular/commit/0bcfae7))
|
||||
* **forms:** set state before emitting a value from ngModelChange ([#21514](https://github.com/angular/angular/issues/21514)) ([9744a1c](https://github.com/angular/angular/commit/9744a1c)), closes [#21513](https://github.com/angular/angular/issues/21513)
|
||||
* **language-service:** correct instructions to install the language service ([#22000](https://github.com/angular/angular/issues/22000)) ([b37cee3](https://github.com/angular/angular/commit/b37cee3))
|
||||
* **platform-browser:** add @Injectable where it was missing ([#22005](https://github.com/angular/angular/issues/22005)) ([0a1a397](https://github.com/angular/angular/commit/0a1a397))
|
||||
* **platform-browser:** support 0/false/null values in transfer_state ([#22179](https://github.com/angular/angular/issues/22179)) ([6435ecd](https://github.com/angular/angular/commit/6435ecd))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **bazel:** allow explicit specification of factories ([#22003](https://github.com/angular/angular/issues/22003)) ([e442881](https://github.com/angular/angular/commit/e442881))
|
||||
* **compiler:** mark @NgModules in provider lists for identification at runtime ([#22005](https://github.com/angular/angular/issues/22005)) ([2d5e7d1](https://github.com/angular/angular/commit/2d5e7d1))
|
||||
* **forms:** multiple validators for array method ([#20766](https://github.com/angular/angular/issues/20766)) ([941e88f](https://github.com/angular/angular/commit/941e88f)), closes [#20665](https://github.com/angular/angular/issues/20665)
|
||||
* change @Injectable() to support tree-shakeable tokens ([#22005](https://github.com/angular/angular/issues/22005)) ([235a235](https://github.com/angular/angular/commit/235a235))
|
||||
|
||||
<a name="5.2.5"></a>
|
||||
## [5.2.5](https://github.com/angular/angular/compare/5.2.4...5.2.5) (2018-02-14)
|
||||
|
||||
@ -122,33 +66,6 @@ If that is the case, you should be able to track the old value directly by savin
|
||||
* **language-service:** correct instructions to install the language service ([#22000](https://github.com/angular/angular/issues/22000)) ([0b23573](https://github.com/angular/angular/commit/0b23573))
|
||||
* **platform-browser:** support 0/false/null values in transfer_state ([#22179](https://github.com/angular/angular/issues/22179)) ([da6ab91](https://github.com/angular/angular/commit/da6ab91))
|
||||
|
||||
<a name="6.0.0-beta.3"></a>
|
||||
# [6.0.0-beta.3](https://github.com/angular/angular/compare/6.0.0-beta.2...6.0.0-beta.3) (2018-02-07)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **common:** don't convert null to a string when flushing a mock request ([#21417](https://github.com/angular/angular/issues/21417)) ([8b14488](https://github.com/angular/angular/commit/8b14488)), closes [#20744](https://github.com/angular/angular/issues/20744)
|
||||
* **core:** fix [#20582](https://github.com/angular/angular/issues/20582), don't need to wrap zone in location change listener ([#20640](https://github.com/angular/angular/issues/20640)) ([f791e9f](https://github.com/angular/angular/commit/f791e9f))
|
||||
* **core:** fix proper propagation of subscriptions in EventEmitter ([#22016](https://github.com/angular/angular/issues/22016)) ([e81606c](https://github.com/angular/angular/commit/e81606c)), closes [#21999](https://github.com/angular/angular/issues/21999)
|
||||
* **core:** should check Zone existance when scheduleMicroTask ([#20656](https://github.com/angular/angular/issues/20656)) ([3a86940](https://github.com/angular/angular/commit/3a86940))
|
||||
* **forms:** publish missing types ([#19941](https://github.com/angular/angular/issues/19941)) ([2707012](https://github.com/angular/angular/commit/2707012))
|
||||
* **ivy:** generate correct interpolations ([#21946](https://github.com/angular/angular/issues/21946)) ([3cc1d76](https://github.com/angular/angular/commit/3cc1d76))
|
||||
* **ivy:** generate lifecycle pattern ([#21865](https://github.com/angular/angular/issues/21865)) ([f816666](https://github.com/angular/angular/commit/f816666))
|
||||
* **ivy:** improve `bindV` perf and memory usage ([#21881](https://github.com/angular/angular/issues/21881)) ([0846784](https://github.com/angular/angular/commit/0846784))
|
||||
* **ivy:** remove unnecessary parameter of NgOnChangesFeature ([#21879](https://github.com/angular/angular/issues/21879)) ([65cf1ad](https://github.com/angular/angular/commit/65cf1ad))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **compiler-cli:** reflect static methods added to classes in metadata ([#21926](https://github.com/angular/angular/issues/21926)) ([eb8ddd2](https://github.com/angular/angular/commit/eb8ddd2))
|
||||
* **ivy:** add canonical example of a pipe. ([#21834](https://github.com/angular/angular/issues/21834)) ([743d8bc](https://github.com/angular/angular/commit/743d8bc))
|
||||
* **ivy:** add support for attributes on ng-content nodes ([#21935](https://github.com/angular/angular/issues/21935)) ([1aa2947](https://github.com/angular/angular/commit/1aa2947))
|
||||
* **ivy:** memoize array literals in render3 ([#21973](https://github.com/angular/angular/issues/21973)) ([4d62be6](https://github.com/angular/angular/commit/4d62be6))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **ivy:** improve Uglify configuration in hello world integration test ([#21985](https://github.com/angular/angular/issues/21985)) ([7e51e52](https://github.com/angular/angular/commit/7e51e52))
|
||||
|
||||
|
||||
|
||||
@ -165,17 +82,6 @@ If that is the case, you should be able to track the old value directly by savin
|
||||
|
||||
|
||||
|
||||
<a name="6.0.0-beta.2"></a>
|
||||
# [6.0.0-beta.2](https://github.com/angular/angular/compare/6.0.0-beta.1...6.0.0-beta.2) (2018-01-31)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **router:** add navigationSource and restoredState to NavigationStart event ([#21728](https://github.com/angular/angular/issues/21728)) ([c40ae7f](https://github.com/angular/angular/commit/c40ae7f))
|
||||
* **service-worker:** add helper script which will uninstall SW ([#21863](https://github.com/angular/angular/issues/21863)) ([b10540a](https://github.com/angular/angular/commit/b10540a))
|
||||
|
||||
|
||||
|
||||
<a name="5.2.3"></a>
|
||||
## [5.2.3](https://github.com/angular/angular/compare/5.2.2...5.2.3) (2018-01-31)
|
||||
|
||||
@ -193,32 +99,6 @@ If that is the case, you should be able to track the old value directly by savin
|
||||
|
||||
|
||||
|
||||
<a name="6.0.0-beta.1"></a>
|
||||
# [6.0.0-beta.1](https://github.com/angular/angular/compare/6.0.0-beta.0...6.0.0-beta.1) (2018-01-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **common:** A null value should remove the style on IE ([#21679](https://github.com/angular/angular/issues/21679)) ([7d49443](https://github.com/angular/angular/commit/7d49443)), closes [#21064](https://github.com/angular/angular/issues/21064)
|
||||
* avoid triggering a cli bug ([#21611](https://github.com/angular/angular/issues/21611)) ([0eabd07](https://github.com/angular/angular/commit/0eabd07))
|
||||
* **common:** don't remove special characters when extracting CLDR data ([#21626](https://github.com/angular/angular/issues/21626)) ([135a282](https://github.com/angular/angular/commit/135a282))
|
||||
* **common:** extract plural function from i18n locale data files for TS 2.6 ([#21626](https://github.com/angular/angular/issues/21626)) ([97b18b2](https://github.com/angular/angular/commit/97b18b2)), closes [#21608](https://github.com/angular/angular/issues/21608)
|
||||
* **common:** fallback to last defined value for named date and time formats ([#21299](https://github.com/angular/angular/issues/21299)) ([879756d](https://github.com/angular/angular/commit/879756d)), closes [#21282](https://github.com/angular/angular/issues/21282)
|
||||
* **compiler:** add support for marker tags in xliff serializers ([#21250](https://github.com/angular/angular/issues/21250)) ([f74130c](https://github.com/angular/angular/commit/f74130c)), closes [#21078](https://github.com/angular/angular/issues/21078)
|
||||
* **compiler:** Don't strip `/*# sourceURL ... */` ([#16088](https://github.com/angular/angular/issues/16088)) ([5f681f9](https://github.com/angular/angular/commit/5f681f9))
|
||||
* **compiler:** fix ICU select messages to use male/female/other ([#21713](https://github.com/angular/angular/issues/21713)) ([cb5090c](https://github.com/angular/angular/commit/cb5090c))
|
||||
* **compiler-cli:** do not fold errors past calls in the collector ([#21708](https://github.com/angular/angular/issues/21708)) ([dd86790](https://github.com/angular/angular/commit/dd86790))
|
||||
* **compiler-cli:** do not lower expressions in non-modules ([#21649](https://github.com/angular/angular/issues/21649)) ([7f93aad](https://github.com/angular/angular/commit/7f93aad))
|
||||
* **router:** don't use ParamsInheritanceStrategy in declarations ([#21574](https://github.com/angular/angular/issues/21574)) ([925e654](https://github.com/angular/angular/commit/925e654)), closes [#21456](https://github.com/angular/angular/issues/21456)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **compiler:** implement "enableIvy" compiler option ([#21427](https://github.com/angular/angular/issues/21427)) ([64d16de](https://github.com/angular/angular/commit/64d16de))
|
||||
* **core:** optional generic type for ElementRef ([#20765](https://github.com/angular/angular/issues/20765)) ([d3d9aac](https://github.com/angular/angular/commit/d3d9aac)), closes [#13139](https://github.com/angular/angular/issues/13139)
|
||||
|
||||
|
||||
|
||||
<a name="5.2.2"></a>
|
||||
## [5.2.2](https://github.com/angular/angular/compare/5.2.1...5.2.2) (2018-01-25)
|
||||
|
||||
@ -238,36 +118,6 @@ If that is the case, you should be able to track the old value directly by savin
|
||||
|
||||
|
||||
|
||||
<a name="6.0.0-beta.0"></a>
|
||||
# [6.0.0-beta.0](https://github.com/angular/angular/compare/5.2.0...6.0.0-beta.0) (2018-01-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **animations:** fix increment/decrement aliases example ([#18323](https://github.com/angular/angular/issues/18323)) ([d2aa8ac](https://github.com/angular/angular/commit/d2aa8ac))
|
||||
* **benchpress:** should still support selenium_webdriver < 3.6.0 ([#21477](https://github.com/angular/angular/issues/21477)) ([9b84a32](https://github.com/angular/angular/commit/9b84a32))
|
||||
* **common:** set correct timezone for ISO8601 dates in Safari ([#21506](https://github.com/angular/angular/issues/21506)) ([05208b8](https://github.com/angular/angular/commit/05208b8)), closes [#21491](https://github.com/angular/angular/issues/21491)
|
||||
* **compiler:** cache external reference resolution ([#21359](https://github.com/angular/angular/issues/21359)) ([e3e2fc0](https://github.com/angular/angular/commit/e3e2fc0))
|
||||
* **compiler:** make `.ngsummary.json` files idempotent ([#21448](https://github.com/angular/angular/issues/21448)) ([e64b1e9](https://github.com/angular/angular/commit/e64b1e9))
|
||||
* **core:** fix chained http call ([#20924](https://github.com/angular/angular/issues/20924)) ([7e3f9a4](https://github.com/angular/angular/commit/7e3f9a4)), closes [#20921](https://github.com/angular/angular/issues/20921)
|
||||
* **ivy:** Add workaround for AJD in google3 ([#21488](https://github.com/angular/angular/issues/21488)) ([6af3672](https://github.com/angular/angular/commit/6af3672))
|
||||
* **language-service:** Clear caches when program changes ([#21337](https://github.com/angular/angular/issues/21337)) ([43e1520](https://github.com/angular/angular/commit/43e1520)), closes [#19405](https://github.com/angular/angular/issues/19405)
|
||||
* **service-worker:** properly handle invalid hashes in all scenarios ([#21288](https://github.com/angular/angular/issues/21288)) ([3951098](https://github.com/angular/angular/commit/3951098))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **bazel:** allow ng_module rules to control whether type checking is enabled ([#21460](https://github.com/angular/angular/issues/21460)) ([cffa0fe](https://github.com/angular/angular/commit/cffa0fe))
|
||||
* **core:** add binding name to content changed error ([#20352](https://github.com/angular/angular/issues/20352)) ([d3bf54b](https://github.com/angular/angular/commit/d3bf54b))
|
||||
* **forms:** handle string with and without line boundary on pattern validator ([#19256](https://github.com/angular/angular/issues/19256)) ([54bf179](https://github.com/angular/angular/commit/54bf179))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **ivy:** add missing dom element in render3_function tree benchmark ([#21476](https://github.com/angular/angular/issues/21476)) ([9b5a485](https://github.com/angular/angular/commit/9b5a485))
|
||||
|
||||
|
||||
|
||||
<a name="5.2.1"></a>
|
||||
## [5.2.1](https://github.com/angular/angular/compare/5.2.0...5.2.1) (2018-01-17)
|
||||
|
||||
|
38
WORKSPACE
38
WORKSPACE
@ -1,14 +1,10 @@
|
||||
workspace(name = "angular")
|
||||
|
||||
# Using a pre-release snapshot to pick up a commit that makes all nodejs_binary
|
||||
# programs produce source-mapped stack traces and uglify sourcemaps.
|
||||
RULES_NODEJS_VERSION = "4303cbef12e5e252ad66cc35cff1123e3a44ee83"
|
||||
|
||||
http_archive(
|
||||
name = "build_bazel_rules_nodejs",
|
||||
url = "https://github.com/bazelbuild/rules_nodejs/archive/%s.zip" % RULES_NODEJS_VERSION,
|
||||
strip_prefix = "rules_nodejs-%s" % RULES_NODEJS_VERSION,
|
||||
sha256 = "fccb9a7122f339d89c9994dc0fea33c737dd76e66281d0da0cb841da5f1edec7",
|
||||
url = "https://github.com/bazelbuild/rules_nodejs/archive/0.5.0.zip",
|
||||
strip_prefix = "rules_nodejs-0.5.0",
|
||||
sha256 = "06aabb253c3867d51724386ac5622a0a238bbd82e2c70ce1d09ee3ceac4c31d6",
|
||||
)
|
||||
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories")
|
||||
@ -16,13 +12,11 @@ load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_reposi
|
||||
check_bazel_version("0.9.0")
|
||||
node_repositories(package_json = ["//:package.json"])
|
||||
|
||||
RULES_TYPESCRIPT_VERSION = "d3cc5cd72d89aee0e4c2553ae1b99c707ecbef4e"
|
||||
|
||||
http_archive(
|
||||
name = "build_bazel_rules_typescript",
|
||||
url = "https://github.com/bazelbuild/rules_typescript/archive/%s.zip" % RULES_TYPESCRIPT_VERSION,
|
||||
strip_prefix = "rules_typescript-%s" % RULES_TYPESCRIPT_VERSION,
|
||||
sha256 = "a233fcca41c3e59f639ac71c396edb30e9e9716cf8ed5fb20b51ff8910d5d895",
|
||||
url = "https://github.com/bazelbuild/rules_typescript/archive/0.11.0.zip",
|
||||
strip_prefix = "rules_typescript-0.11.0",
|
||||
sha256 = "ce7bac7b5287d5162fcbe4f7c14ff507ae7d506ceb44626ad09f6b7e27d3260b",
|
||||
)
|
||||
|
||||
load("@build_bazel_rules_typescript//:defs.bzl", "ts_setup_workspace")
|
||||
@ -65,23 +59,3 @@ http_archive(
|
||||
strip_prefix = "bazel-9755c72b48866ed034bd28aa033e9abd27431b1e",
|
||||
sha256 = "5b8443fc3481b5fcd9e7f348e1dd93c1397f78b223623c39eb56494c55f41962",
|
||||
)
|
||||
|
||||
# We have a source dependency on the Devkit repository, because it's built with
|
||||
# Bazel.
|
||||
# This allows us to edit sources and have the effect appear immediately without
|
||||
# re-packaging or "npm link"ing.
|
||||
# Even better, things like aspects will visit the entire graph including
|
||||
# ts_library rules in the devkit repository.
|
||||
http_archive(
|
||||
name = "angular_devkit",
|
||||
url = "https://github.com/angular/devkit/archive/v0.3.1.zip",
|
||||
strip_prefix = "devkit-0.3.1",
|
||||
sha256 = "31d4b597fe9336650acf13df053c1c84dcbe9c29c6a833bcac3819cd3fd8cad3",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "org_brotli",
|
||||
url = "https://github.com/google/brotli/archive/v1.0.2.zip",
|
||||
strip_prefix = "brotli-1.0.2",
|
||||
sha256 = "b43d5d6bc40f2fa6c785b738d86c6bbe022732fe25196ebbe43b9653a025920d",
|
||||
)
|
||||
|
@ -39,7 +39,7 @@
|
||||
],
|
||||
"e2e": {
|
||||
"protractor": {
|
||||
"config": "tests/e2e/protractor.conf.js"
|
||||
"config": "./protractor.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": [
|
||||
@ -50,12 +50,12 @@
|
||||
"project": "src/tsconfig.spec.json"
|
||||
},
|
||||
{
|
||||
"project": "tests/e2e/tsconfig.e2e.json"
|
||||
"project": "e2e/tsconfig.e2e.json"
|
||||
}
|
||||
],
|
||||
"test": {
|
||||
"karma": {
|
||||
"config": "src/karma.conf.js"
|
||||
"config": "./karma.conf.js"
|
||||
}
|
||||
},
|
||||
"defaults": {
|
||||
|
@ -1,20 +1,19 @@
|
||||
<!--The content below is only a placeholder and can be replaced.-->
|
||||
<div style="text-align:center">
|
||||
<h1>
|
||||
Welcome to {{title}}!!
|
||||
Welcome to {{ title }}!
|
||||
</h1>
|
||||
<img width="300" alt="Angular logo" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOS4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyNTAgMjUwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyNTAgMjUwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDojREQwMDMxO30NCgkuc3Qxe2ZpbGw6I0MzMDAyRjt9DQoJLnN0MntmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxnPg0KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBvaW50cz0iMTI1LDMwIDEyNSwzMCAxMjUsMzAgMzEuOSw2My4yIDQ2LjEsMTg2LjMgMTI1LDIzMCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAJIi8+DQoJPHBvbHlnb24gY2xhc3M9InN0MSIgcG9pbnRzPSIxMjUsMzAgMTI1LDUyLjIgMTI1LDUyLjEgMTI1LDE1My40IDEyNSwxNTMuNCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAxMjUsMzAgCSIvPg0KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0xMjUsNTIuMUw2Ni44LDE4Mi42aDBoMjEuN2gwbDExLjctMjkuMmg0OS40bDExLjcsMjkuMmgwaDIxLjdoMEwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMQ0KCQlMMTI1LDUyLjF6IE0xNDIsMTM1LjRIMTA4bDE3LTQwLjlMMTQyLDEzNS40eiIvPg0KPC9nPg0KPC9zdmc+DQo=">
|
||||
<img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
|
||||
</div>
|
||||
<h2>Here are some links to help you start: </h2>
|
||||
<ul>
|
||||
<li>
|
||||
<h2><a target="_blank" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
|
||||
<h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
|
||||
</li>
|
||||
<li>
|
||||
<h2><a target="_blank" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>
|
||||
<h2><a target="_blank" rel="noopener" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>
|
||||
</li>
|
||||
<li>
|
||||
<h2><a target="_blank" href="http://angularjs.blogspot.ca/">Angular blog</a></h2>
|
||||
<h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { TestBed, async } from '@angular/core/testing';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
@ -20,13 +18,13 @@ describe('AppComponent', () => {
|
||||
it(`should have as title 'app'`, async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app.title).toEqual('app');
|
||||
expect(app.title).toMatch(/app/i);
|
||||
}));
|
||||
|
||||
it('should render title in a h1 tag', async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!!');
|
||||
expect(compiled.querySelector('h1').textContent).toMatch(/app/i);
|
||||
}));
|
||||
});
|
||||
|
@ -11,6 +11,6 @@ import { Component } from '@angular/core';
|
||||
// #enddocregion metadata
|
||||
// #docregion title, class
|
||||
export class AppComponent {
|
||||
title = 'My First Angular App';
|
||||
title = 'My First Angular App!';
|
||||
}
|
||||
// #enddocregion title, class
|
||||
|
@ -6,32 +6,38 @@ import { BrowserModule } from '@angular/platform-browser';
|
||||
import { ReactiveFormsModule } from '@angular/forms'; // <-- #1 import module
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { HeroDetailComponent } from './hero-detail/hero-detail.component'; // <-- #1 import component
|
||||
import { HeroDetailComponent } from './hero-detail/hero-detail.component';
|
||||
// #enddocregion v1
|
||||
// #docregion hero-service-list
|
||||
// add JavaScript imports
|
||||
import { HeroListComponent } from './hero-list/hero-list.component';
|
||||
|
||||
import { HeroService } from './hero.service'; // <-- #1 import service
|
||||
import { HeroService } from './hero.service';
|
||||
// #docregion v1
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
ReactiveFormsModule // <-- #2 add to @NgModule imports
|
||||
],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
HeroDetailComponent,
|
||||
// #enddocregion v1
|
||||
HeroListComponent
|
||||
HeroListComponent // <--declare HeroListComponent
|
||||
// #docregion v1
|
||||
],
|
||||
// #enddocregion v1
|
||||
exports: [ // export for the DemoModule
|
||||
// #enddocregion hero-service-list
|
||||
imports: [
|
||||
BrowserModule,
|
||||
ReactiveFormsModule // <-- #2 add to @NgModule imports
|
||||
],
|
||||
// #enddocregion v1
|
||||
// export for the DemoModule
|
||||
// #docregion hero-service-list
|
||||
// ...
|
||||
exports: [
|
||||
AppComponent,
|
||||
HeroDetailComponent,
|
||||
HeroListComponent
|
||||
HeroListComponent // <-- export HeroListComponent
|
||||
],
|
||||
providers: [ HeroService ], // <-- #4 provide HeroService
|
||||
providers: [ HeroService ], // <-- provide HeroService
|
||||
// #enddocregion hero-service-list
|
||||
// #docregion v1
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
|
@ -1,7 +1,7 @@
|
||||
<!-- #docregion basic-form-->
|
||||
<h2>Hero Detail</h2>
|
||||
<h3><i>FormControl in a FormGroup</i></h3>
|
||||
<form [formGroup]="heroForm" novalidate>
|
||||
<form [formGroup]="heroForm">
|
||||
<div class="form-group">
|
||||
<label class="center-block">Name:
|
||||
<input class="form-control" formControlName="name">
|
||||
|
@ -1,7 +1,7 @@
|
||||
<!-- #docregion basic-form-->
|
||||
<h2>Hero Detail</h2>
|
||||
<h3><i>A FormGroup with a single FormControl using FormBuilder</i></h3>
|
||||
<form [formGroup]="heroForm" novalidate>
|
||||
<form [formGroup]="heroForm">
|
||||
<div class="form-group">
|
||||
<label class="center-block">Name:
|
||||
<input class="form-control" formControlName="name">
|
||||
|
@ -1,7 +1,7 @@
|
||||
<!-- #docregion -->
|
||||
<h2>Hero Detail</h2>
|
||||
<h3><i>A FormGroup with multiple FormControls</i></h3>
|
||||
<form [formGroup]="heroForm" novalidate>
|
||||
<form [formGroup]="heroForm">
|
||||
<div class="form-group">
|
||||
<label class="center-block">Name:
|
||||
<input class="form-control" formControlName="name">
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
<form [formGroup]="heroForm" novalidate>
|
||||
<form [formGroup]="heroForm">
|
||||
<div class="form-group">
|
||||
<label class="center-block">Name:
|
||||
<input class="form-control" formControlName="name">
|
||||
|
@ -1,7 +1,7 @@
|
||||
<!-- #docregion -->
|
||||
<h2>Hero Detail</h2>
|
||||
<h3><i>PatchValue to initialize a value</i></h3>
|
||||
<form [formGroup]="heroForm" novalidate>
|
||||
<form [formGroup]="heroForm">
|
||||
<div class="form-group">
|
||||
<label class="center-block">Name:
|
||||
<input class="form-control" formControlName="name">
|
||||
|
@ -44,7 +44,13 @@ export class HeroDetailComponent6 implements OnChanges {
|
||||
}
|
||||
|
||||
// #docregion patch-value-on-changes
|
||||
ngOnChanges() { // <-- wrap patchValue in ngOnChanges
|
||||
ngOnChanges() { // <-- call rebuildForm in ngOnChanges
|
||||
this.rebuildForm();
|
||||
}
|
||||
// #enddocregion patch-value-on-changes
|
||||
|
||||
// #docregion patch-value-rebuildform
|
||||
rebuildForm() { // <-- wrap patchValue in rebuildForm
|
||||
this.heroForm.reset();
|
||||
// #docregion patch-value
|
||||
this.heroForm.patchValue({
|
||||
@ -52,7 +58,9 @@ export class HeroDetailComponent6 implements OnChanges {
|
||||
});
|
||||
// #enddocregion patch-value
|
||||
}
|
||||
// #enddocregion patch-value-on-changes
|
||||
// #enddocregion patch-value-rebuildform
|
||||
}
|
||||
|
||||
|
||||
|
||||
// #enddocregion v6
|
||||
|
@ -1,7 +1,7 @@
|
||||
<!-- #docregion -->
|
||||
<h2>Hero Detail</h2>
|
||||
<h3><i>A FormGroup with multiple FormControls</i></h3>
|
||||
<form [formGroup]="heroForm" novalidate>
|
||||
<form [formGroup]="heroForm">
|
||||
<div class="form-group">
|
||||
<label class="center-block">Name:
|
||||
<input class="form-control" formControlName="name">
|
||||
|
@ -38,32 +38,31 @@ export class HeroDetailComponent7 implements OnChanges {
|
||||
|
||||
// #docregion ngOnChanges
|
||||
ngOnChanges() {
|
||||
this.heroForm.reset({
|
||||
name: this.hero.name,
|
||||
address: this.hero.addresses[0] || new Address()
|
||||
});
|
||||
this.rebuildForm();
|
||||
}
|
||||
// #enddocregion ngOnChanges
|
||||
|
||||
/* First version of ngOnChanges
|
||||
// #docregion ngOnChanges-1
|
||||
ngOnChanges()
|
||||
// #enddocregion ngOnChanges-1
|
||||
*/
|
||||
ngOnChanges1() {
|
||||
// #docregion reset
|
||||
this.heroForm.reset();
|
||||
// #enddocregion reset
|
||||
// #docregion ngOnChanges-1
|
||||
// #docregion set-value
|
||||
this.heroForm.setValue({
|
||||
// #docregion rebuildForm
|
||||
rebuildForm() {
|
||||
this.heroForm.reset({
|
||||
name: this.hero.name,
|
||||
// #docregion set-value-address
|
||||
address: this.hero.addresses[0] || new Address()
|
||||
// #enddocregion set-value-address
|
||||
});
|
||||
}
|
||||
// #enddocregion rebuildForm
|
||||
|
||||
/* First version of rebuildForm */
|
||||
rebuildForm1() {
|
||||
// #docregion reset
|
||||
this.heroForm.reset();
|
||||
// #enddocregion reset
|
||||
// #docregion set-value
|
||||
this.heroForm.setValue({
|
||||
name: this.hero.name,
|
||||
address: this.hero.addresses[0] || new Address()
|
||||
});
|
||||
// #enddocregion set-value
|
||||
}
|
||||
// #enddocregion ngOnChanges-1
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<!-- #docplaster-->
|
||||
<h3><i>Using FormArray to add groups</i></h3>
|
||||
|
||||
<form [formGroup]="heroForm" novalidate>
|
||||
<form [formGroup]="heroForm">
|
||||
<p>Form Changed: {{ heroForm.dirty }}</p>
|
||||
|
||||
<div class="form-group">
|
||||
@ -11,7 +11,9 @@
|
||||
</div>
|
||||
<!-- #docregion form-array-->
|
||||
<!-- #docregion form-array-skeleton -->
|
||||
<!-- #docregion form-array-name -->
|
||||
<div formArrayName="secretLairs" class="well well-lg">
|
||||
<!-- #enddocregion form-array-name -->
|
||||
<div *ngFor="let address of secretLairs.controls; let i=index" [formGroupName]="i" >
|
||||
<!-- The repeated address template -->
|
||||
<!-- #enddocregion form-array-skeleton -->
|
||||
|
@ -39,12 +39,18 @@ export class HeroDetailComponent8 implements OnChanges {
|
||||
|
||||
// #docregion onchanges
|
||||
ngOnChanges() {
|
||||
this.rebuildForm();
|
||||
}
|
||||
// #enddocregion onchanges
|
||||
|
||||
// #docregion rebuildform
|
||||
rebuildForm() {
|
||||
this.heroForm.reset({
|
||||
name: this.hero.name
|
||||
});
|
||||
this.setAddresses(this.hero.addresses);
|
||||
}
|
||||
// #enddocregion onchanges
|
||||
// #enddocregion rebuildform
|
||||
|
||||
// #docregion get-secret-lairs
|
||||
get secretLairs(): FormArray {
|
||||
|
@ -1,11 +1,11 @@
|
||||
<!-- #docplaster -->
|
||||
<!-- #docregion -->
|
||||
<!-- #docregion buttons -->
|
||||
<form [formGroup]="heroForm" (ngSubmit)="onSubmit()" novalidate>
|
||||
<form [formGroup]="heroForm" (ngSubmit)="onSubmit()">
|
||||
<div style="margin-bottom: 1em">
|
||||
<button type="submit"
|
||||
[disabled]="heroForm.pristine" class="btn btn-success">Save</button>
|
||||
<button type="reset" (click)="revert()"
|
||||
<button type="button" (click)="revert()"
|
||||
[disabled]="heroForm.pristine" class="btn btn-danger">Revert</button>
|
||||
</div>
|
||||
|
||||
|
@ -13,7 +13,10 @@ import { HeroService } from '../hero.service';
|
||||
templateUrl: './hero-detail.component.html',
|
||||
styleUrls: ['./hero-detail.component.css']
|
||||
})
|
||||
|
||||
// #docregion onchanges-implementation
|
||||
export class HeroDetailComponent implements OnChanges {
|
||||
// #enddocregion onchanges-implementation
|
||||
@Input() hero: Hero;
|
||||
|
||||
heroForm: FormGroup;
|
||||
@ -42,6 +45,10 @@ export class HeroDetailComponent implements OnChanges {
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
this.rebuildForm();
|
||||
}
|
||||
|
||||
rebuildForm() {
|
||||
this.heroForm.reset({
|
||||
name: this.hero.name
|
||||
});
|
||||
@ -66,7 +73,7 @@ export class HeroDetailComponent implements OnChanges {
|
||||
onSubmit() {
|
||||
this.hero = this.prepareSaveHero();
|
||||
this.heroService.updateHero(this.hero).subscribe(/* error handling */);
|
||||
this.ngOnChanges();
|
||||
this.rebuildForm();
|
||||
}
|
||||
// #enddocregion on-submit
|
||||
|
||||
@ -92,7 +99,7 @@ export class HeroDetailComponent implements OnChanges {
|
||||
// #enddocregion prepare-save-hero
|
||||
|
||||
// #docregion revert
|
||||
revert() { this.ngOnChanges(); }
|
||||
revert() { this.rebuildForm(); }
|
||||
// #enddocregion revert
|
||||
|
||||
// #docregion log-name-change
|
||||
|
@ -197,20 +197,21 @@ function heroModuleSetup() {
|
||||
|
||||
// #docregion title-case-pipe
|
||||
it('should convert hero name to Title Case', () => {
|
||||
const inputName = 'quick BROWN fox';
|
||||
const titleCaseName = 'Quick Brown Fox';
|
||||
const { nameInput, nameDisplay } = page;
|
||||
// get the name's input and display elements from the DOM
|
||||
const hostElement = fixture.nativeElement;
|
||||
const nameInput: HTMLInputElement = hostElement.querySelector('input');
|
||||
const nameDisplay: HTMLElement = hostElement.querySelector('span');
|
||||
|
||||
// simulate user entering new name into the input box
|
||||
nameInput.value = inputName;
|
||||
// simulate user entering a new name into the input box
|
||||
nameInput.value = 'quick BROWN fOx';
|
||||
|
||||
// dispatch a DOM event so that Angular learns of input value change.
|
||||
nameInput.dispatchEvent(newEvent('input'));
|
||||
|
||||
// Tell Angular to update the output span through the title pipe
|
||||
// Tell Angular to update the display binding through the title pipe
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(nameDisplay.textContent).toBe(titleCaseName);
|
||||
expect(nameDisplay.textContent).toBe('Quick Brown Fox');
|
||||
});
|
||||
// #enddocregion title-case-pipe
|
||||
// #enddocregion selected-tests
|
||||
|
@ -16,10 +16,8 @@ animation logic with the rest of your application code, for ease of control.
|
||||
Angular animations are built on top of the standard [Web Animations API](https://w3c.github.io/web-animations/)
|
||||
and run natively on [browsers that support it](http://caniuse.com/#feat=web-animation).
|
||||
|
||||
As of Angular 6, If the Web Animations API is not supported natively by the browser, then Angular will use CSS
|
||||
keyframes as a fallback instead (automatically). This means that the polyfill is no longer required unless any
|
||||
code uses [AnimationBuilder](/api/animations/AnimationBuilder). If your code does use AnimationBuilder, then
|
||||
uncomment the `web-animations-js` polyfill from the `polyfills.ts` file generated by Angular CLI.
|
||||
For other browsers, a polyfill is required. Uncomment the `web-animations-js` polyfill from the `polyfills.ts` file.
|
||||
|
||||
</div>
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
@ -92,7 +92,7 @@ You can control your app compilation by providing template compiler options in t
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"fullTemplateTypeCheck": true,
|
||||
"preserveWhitespaces": true,
|
||||
"preserveWhitespaces": false,
|
||||
...
|
||||
}
|
||||
}
|
||||
@ -234,7 +234,9 @@ done manually.
|
||||
### *preserveWhitespaces*
|
||||
|
||||
This option tells the compiler whether to remove blank text nodes from compiled templates.
|
||||
As of v6, this option is `false` by default, which results in smaller emitted template factory modules.
|
||||
This option is `true` by default.
|
||||
|
||||
*Note*: It is recommended to set this explicitly to `false` as it emits smaller template factory modules and might be set to `false` by default in the future.
|
||||
|
||||
### *allowEmptyCodegenFiles*
|
||||
|
||||
@ -243,16 +245,6 @@ Tells the compiler to generate all the possible generated files even if they are
|
||||
how `bazel` rules track file dependencies. It is not recommended to use this option outside of the `bazel`
|
||||
rules.
|
||||
|
||||
### *enableIvy*
|
||||
|
||||
Tells the compiler to generate definitions using the Render3 style code generation. This option defaults to `false`.
|
||||
|
||||
Not all features are supported with this option enabled. It is only supported
|
||||
for experimentation and testing of Render3 style code generation.
|
||||
|
||||
*Note*: Is it not recommended to use this option as it is not yet feature complete with the Render2 code generation.
|
||||
|
||||
|
||||
## Angular Metadata and AOT
|
||||
|
||||
The Angular **AOT compiler** extracts and interprets **metadata** about the parts of the application that Angular is supposed to manage.
|
||||
|
@ -1,175 +0,0 @@
|
||||
<div class="breadcrumb">
|
||||
<a href="#">API<a> / <a href="#">@core<a>
|
||||
</div>
|
||||
<header class="api-header">
|
||||
<h1><label class="api-status-label experimental">experimental</label><label class="api-type-label class">class</label>Class Name</h1>
|
||||
</header>
|
||||
<div class="page-actions">
|
||||
<a href="#"><label class="raised page-label"><i class="material-icons">mode_edit</i>suggest edits</label></a>
|
||||
<a href="#"><label class="raised page-label"><i class="material-icons">code</i>view source</label></a>
|
||||
</div>
|
||||
<p>Class description goes here. This is a short and to the point one or two sentence description that easily introduces the reader to the class.</p>
|
||||
<div class="api-body">
|
||||
<section>
|
||||
<h2>Overview</h2>
|
||||
<code-example language="ts" hidecopy="true" ng-version="5.2.0"><aio-code class="simple-code" ng-reflect-ng-class="[object Object]" ng-reflect-code="
|
||||
class <a href="api/core/Compi" ng-reflect-hide-copy="true" ng-reflect-language="ts" ng-reflect-linenums="" ng-reflect-path="" ng-reflect-region="" ng-reflect-title=""><pre class="prettyprint lang-ts">
|
||||
<code class="animated fadeIn"><span class="kwd">class</span><span class="pln"> </span><a href="api/core/Compiler" class="code-anchor"><span class="typ">Compiler</span></a><span class="pln"> </span><span class="pun">{</span><span class="pln">
|
||||
</span><a class="code-anchor" href="api/core/Compiler#compileModuleSync"><span class="pln">compileModuleSync</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>):</span><span class="pln"> </span><span class="typ">NgModuleFactory</span><span class="pun"><</span><span class="pln">T</span><span class="pun">></span></a><span class="pln">
|
||||
</span><a class="code-anchor" href="api/core/Compiler#compileModuleAsync"><span class="pln">compileModuleAsync</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>):</span><span class="pln"> </span><span class="typ">Promise</span><span class="pun"><</span><span class="typ">NgModuleFactory</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>></span></a><span class="pln">
|
||||
</span><a class="code-anchor" href="api/core/Compiler#compileModuleAndAllComponentsSync"><span class="pln">compileModuleAndAllComponentsSync</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>):</span><span class="pln"> </span><span class="typ">ModuleWithComponentFactories</span><span class="pun"><</span><span class="pln">T</span><span class="pun">></span></a><span class="pln">
|
||||
</span><a class="code-anchor" href="api/core/Compiler#compileModuleAndAllComponentsAsync"><span class="pln">compileModuleAndAllComponentsAsync</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>):</span><span class="pln"> </span><span class="typ">Promise</span><span class="pun"><</span><span class="typ">ModuleWithComponentFactories</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>></span></a><span class="pln">
|
||||
</span><a class="code-anchor" href="api/core/Compiler#clearCache"><span class="pln">clearCache</span><span class="pun">():</span><span class="pln"> </span><span class="kwd">void</span></a><span class="pln">
|
||||
</span><a class="code-anchor" href="api/core/Compiler#clearCacheFor"><span class="pln">clearCacheFor</span><span class="pun">(</span><span class="pln">type</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun"><</span><span class="pln">any</span><span class="pun">>)</span></a><span class="pln">
|
||||
</span><span class="pun">}</span></code>
|
||||
</pre></aio-code></code-example>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Description</h2>
|
||||
<p>The longer class description goes here which can include multiple paragraphs.</p>
|
||||
</p>Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.</p>
|
||||
<h3>Subclasses</h3>
|
||||
<ul>
|
||||
<li><a href="#">Subclass1</a></li>
|
||||
<li><a href="#">Subclass2</a></li>
|
||||
<li><a href="#">Subclass3</a></li>
|
||||
</ul>
|
||||
<h3>See Also</h3>
|
||||
<ul>
|
||||
<li><a href="#">Link1</a></li>
|
||||
<li><a href="#">Link2</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Constructor</h2>
|
||||
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
|
||||
<aio-code class="simple-code"><pre class="prettyprint lang-">
|
||||
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
|
||||
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
|
||||
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
|
||||
</pre></aio-code></code-example>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Properties</h2>
|
||||
<table class="is-full-width list-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Property</th>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<code><strong>Property1</strong></code>
|
||||
</td>
|
||||
<td><label class="property-type-label type">Type</label></td>
|
||||
<td>Description goes here</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code><strong>Property2</strong></code>
|
||||
</td>
|
||||
<td>Type</td>
|
||||
<td>Description goes here</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code><strong>Property3</strong></code>
|
||||
</td>
|
||||
<td>Type</td>
|
||||
<td>Description goes here</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<section class="api-method">
|
||||
<h2>Methods</h2>
|
||||
<table class="is-full-width item-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Method1Name( )</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<p>Description goes here</p>
|
||||
<br>
|
||||
<p>Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="is-full-width api-method item-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Method2Name( )</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<p>Description goes here</p>
|
||||
<hr>
|
||||
<h5>Declaration</h5>
|
||||
<code-example language="ts" hidecopy="true" ng-version="5.2.0">
|
||||
<aio-code class="simple-code"><pre class="prettyprint lang-ts">
|
||||
<code class="animated fadeIn"><span class="kwd">class</span><span class="pln"> </span><a href="api/animations/AnimationBuilder" class="code-anchor"><span class="typ">AnimationBuilder</span></a><span class="pln"> </span><span class="pun">{</span><span class="pln"></span><a class="code-anchor" href="api/animations/AnimationBuilder#build"><span class="pln">build</span><span class="pun">(</span><span class="pln">animation</span><span class="pun">:</span><span class="pln"> </span><span class="typ">AnimationMetadata</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="typ">AnimationMetadata</span><span class="pun">[]):</span><span class="pln"> </span><span class="typ">AnimationFactory</span></a><span class="pln"></span><span class="pun">}</span></code></pre>
|
||||
</aio-code>
|
||||
</code-example>
|
||||
<h6>Parameters</h6>
|
||||
<h6>Returns</h6>
|
||||
<p>Returns information and results goes here.</p>
|
||||
<h6>Errors</h6>
|
||||
<p>Error information goes here</p>
|
||||
<hr>
|
||||
<p>Further details provided as needed. Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball.</p><hr>
|
||||
<h6>Overloads</h6>
|
||||
<table class="is-full-width">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
|
||||
<aio-code class="simple-code"><pre class="prettyprint lang-">
|
||||
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
|
||||
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
|
||||
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
|
||||
</pre></aio-code></code-example>
|
||||
</td>
|
||||
<td>Description goes here</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
|
||||
<aio-code class="simple-code"><pre class="prettyprint lang-">
|
||||
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
|
||||
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
|
||||
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
|
||||
</pre></aio-code></code-example>
|
||||
</td>
|
||||
<td>Description goes here</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<hr>
|
||||
<h5>Example: Descriptive Title of Method Example</h5>
|
||||
<p>Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Example: Descriptive Title of Combined Example Goes Here</h2>
|
||||
<p>Intro description text about what the example is and how it can be used.</p>
|
||||
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
|
||||
<aio-code class="simple-code"><pre class="prettyprint lang-">
|
||||
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
|
||||
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
|
||||
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
|
||||
</pre></aio-code></code-example>
|
||||
<p>Further explanation provided as needed. Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball.</p>
|
||||
</section>
|
||||
</div>
|
@ -133,8 +133,6 @@ But if you need an optional polyfill, you'll have to install its npm package.
|
||||
For example, [if you need the web animations polyfill](http://caniuse.com/#feat=web-animation), you could install it with `npm`, using the following command (or the `yarn` equivalent):
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
# note that the web-animations-js polyfill is only here as an example
|
||||
# it isn't a strict requirement of Angular anymore (more below)
|
||||
npm install --save web-animations-js
|
||||
</code-example>
|
||||
|
||||
@ -228,8 +226,7 @@ These are the polyfills required to run an Angular application on each supported
|
||||
|
||||
Some features of Angular may require additional polyfills.
|
||||
|
||||
For example, the animations library relies on the standard web animation API, which is only available in Chrome and Firefox today.
|
||||
(note that the dependency of web-animations-js in Angular is only necessary if `AnimationBuilder` is used.)
|
||||
For example, the animations library relies on the standard web animation API, which is only available in Chrome and Firefox today. You'll need a polyfill to use animations in other browsers.
|
||||
|
||||
Here are the features which may require additional polyfills:
|
||||
|
||||
@ -279,8 +276,6 @@ Here are the features which may require additional polyfills:
|
||||
<td>
|
||||
|
||||
[Animations](guide/animations)
|
||||
<br>Only if `Animation Builder` is used within the application--standard
|
||||
animation support in Angular doesn't require any polyfills (as of NG6).
|
||||
|
||||
</td>
|
||||
|
||||
@ -291,8 +286,7 @@ Here are the features which may require additional polyfills:
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<p>If AnimationBuilder is used then the polyfill will enable scrubbing
|
||||
support for IE/Edge and Safari (Chrome and Firefox support this natively).</p>
|
||||
All but Chrome and Firefox<br>Not supported in IE9
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
@ -89,11 +89,11 @@ promise.then(() => {
|
||||
The following code snippets illustrate how the same kind of operation is defined using observables and promises.
|
||||
|
||||
<table>
|
||||
<th>
|
||||
<td>Operation</td>
|
||||
<td>Observable</td>
|
||||
<td>Promise</td>
|
||||
</th>
|
||||
<tr>
|
||||
<th>Operation</th>
|
||||
<th>Observable</th>
|
||||
<th>Promise</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Creation</td>
|
||||
<td>
|
||||
@ -141,10 +141,11 @@ Using observables to handle events and asynchronous operations can have the adva
|
||||
Here are some code samples that illustrate how the same kind of operation is defined using observables and the events API.
|
||||
|
||||
<table>
|
||||
<th>
|
||||
<td>Observable</td>
|
||||
<td>Events API</td>
|
||||
</th>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Observable</th>
|
||||
<th>Events API</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Creation & cancellation</td>
|
||||
<td>
|
||||
@ -203,10 +204,11 @@ button.removeEventListener(‘click’, handler);
|
||||
An observable produces values over time. An array is created as a static set of values. In a sense, observables are asynchronous where arrays are synchronous. In the following examples, ➞ implies asynchronous value delivery.
|
||||
|
||||
<table>
|
||||
<th>
|
||||
<td>Observable</td>
|
||||
<td>Array</td>
|
||||
</th>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Observable</th>
|
||||
<th>Array</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Given</td>
|
||||
<td>
|
||||
|
@ -126,7 +126,7 @@ This is the _root component_ and it is named `app-root`.
|
||||
You can find it in `./src/app/app.component.ts`.
|
||||
|
||||
|
||||
Open the component file and change the `title` property from _Welcome to app!!_ to _Welcome to My First Angular App!!_:
|
||||
Open the component file and change the `title` property from `'app'` to `'My First Angular App!'`.
|
||||
|
||||
|
||||
<code-example path="cli-quickstart/src/app/app.component.ts" region="title" title="src/app/app.component.ts" linenums="false"></code-example>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -290,42 +290,20 @@ out of date. Right click the Cache Storage title and refresh the caches.
|
||||
Stopping and starting the service worker in the Service Worker
|
||||
pane triggers a check for updates.
|
||||
|
||||
## Service Worker Safety
|
||||
## Fail-safe
|
||||
|
||||
Like any complex system, bugs or broken configurations can cause
|
||||
the Angular service worker to act in unforeseen ways. While its
|
||||
design attempts to minimize the impact of such problems, the
|
||||
Angular service worker contains several failsafe mechanisms in case
|
||||
Angular service worker contains a failsafe mechanism in case
|
||||
an administrator ever needs to deactivate the service worker quickly.
|
||||
|
||||
## Fail-safe
|
||||
|
||||
To deactivate the service worker, remove or rename the
|
||||
`ngsw-config.json` file. When the service worker's request
|
||||
for `ngsw.json` returns a `404`, then the service worker
|
||||
removes all of its caches and de-registers itself,
|
||||
essentially self-destructing.
|
||||
|
||||
### Safety Worker
|
||||
|
||||
Also included in the `@angular/service-worker` NPM package is a small
|
||||
script `safety-worker.js`, which when loaded will unregister itself
|
||||
from the browser. This script can be used as a last resort to get rid
|
||||
of unwanted service workers already installed on client pages.
|
||||
|
||||
It's important to note that you cannot register this worker directly,
|
||||
as old clients with cached state may not see a new `index.html` which
|
||||
installs the different worker script. Instead, you must serve the
|
||||
contents of `safety-worker.js` at the URL of the Service Worker script
|
||||
you are trying to unregister, and must continue to do so until you are
|
||||
certain all users have successfully unregistered the old worker. For
|
||||
most sites, this means that you should serve the safety worker at the
|
||||
old Service Worker URL forever.
|
||||
|
||||
This script can be used both to deactivate `@angular/service-worker`
|
||||
as well as any other Service Workers which might have been served in
|
||||
the past on your site.
|
||||
|
||||
## More on Angular service workers
|
||||
|
||||
You may also be interested in the following:
|
||||
|
@ -785,6 +785,25 @@ There is no harm in calling `detectChanges()` more often than is strictly necess
|
||||
|
||||
<hr>
|
||||
|
||||
{@a dispatch-event}
|
||||
|
||||
#### Change an input value with _dispatchEvent()_
|
||||
|
||||
To simulate user input, you can find the input element and set its `value` property.
|
||||
|
||||
You will call `fixture.detectChanges()` to trigger Angular's change detection.
|
||||
But there is an essential, intermediate step.
|
||||
|
||||
Angular doesn't know that you set the input element's `value` property.
|
||||
It won't read that property until you raise the element's `input` event by calling `dispatchEvent()`.
|
||||
_Then_ you call `detectChanges()`.
|
||||
|
||||
The following example demonstrates the proper sequence.
|
||||
|
||||
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="title-case-pipe" title="app/hero/hero-detail.component.spec.ts (pipe test)"></code-example>
|
||||
|
||||
<hr>
|
||||
|
||||
### Component with external files
|
||||
|
||||
The `BannerComponent` above is defined with an _inline template_ and _inline css_, specified in the `@Component.template` and `@Component.styles` properties respectively.
|
||||
|
@ -210,10 +210,10 @@ You can get runtime information about the current platform and the `appId` by in
|
||||
|
||||
#### Absolute HTTP URLs
|
||||
|
||||
The tutorial's `HeroService` and `HeroSearchService` delegate to the Angular `Http` module to fetch application data.
|
||||
The tutorial's `HeroService` and `HeroSearchService` delegate to the Angular `HttpClient` module to fetch application data.
|
||||
These services send requests to _relative_ URLs such as `api/heroes`.
|
||||
|
||||
In a Universal app, `Http` URLs must be _absolute_ (e.g., `https://my-server.com/api/heroes`)
|
||||
In a Universal app, HTTP URLs must be _absolute_, for example, `https://my-server.com/api/heroes`
|
||||
even when the Universal web server is capable of handling those requests.
|
||||
|
||||
You'll have to change the services to make requests with absolute URLs when running on the server
|
||||
@ -416,7 +416,7 @@ Create a `tsconfig.server.json` file in the project root directory to configure
|
||||
|
||||
This config extends from the root's `tsconfig.json` file. Certain settings are noteworthy for their differences.
|
||||
|
||||
* The `module` property must be **commonjs** which can be require()'d into our server application.
|
||||
* The `module` property must be **commonjs** which can be required into our server application.
|
||||
|
||||
* The `angularCompilerOptions` section guides the AOT compiler:
|
||||
* `entryModule` - the root module of the server application, expressed as `path/to/file#ClassName`.
|
||||
|
@ -49,6 +49,12 @@
|
||||
<td>Vienna</td>
|
||||
<td>May 16-18, 2018</td>
|
||||
</tr>
|
||||
<!-- ngJapan-->
|
||||
<tr>
|
||||
<th><a href="https://ngjapan.org/en.html" title="ng-japan">ng-japan</a></th>
|
||||
<td>Tokyo, Japan</td>
|
||||
<td>Jun 16, 2018</td>
|
||||
</tr>
|
||||
<!-- AngularConnect-->
|
||||
<tr>
|
||||
<th><a href="http://angularconnect.com" title="AngularConnect">AngularConnect</a></th>
|
||||
|
@ -15,7 +15,7 @@ When you’re done, users will be able to navigate the app like this:
|
||||
|
||||
</figure>
|
||||
|
||||
## Add the _AppRoutingModule_
|
||||
## Add the `AppRoutingModule`
|
||||
|
||||
An Angular best practice is to load and configure the router in a separate, top-level module
|
||||
that is dedicated to routing and imported by the root `AppModule`.
|
||||
@ -138,7 +138,7 @@ You should see the familiar heroes master/detail view.
|
||||
|
||||
{@a routerlink}
|
||||
|
||||
## Add a navigation link (_routerLink_)
|
||||
## Add a navigation link (`routerLink`)
|
||||
|
||||
Users shouldn't have to paste a route URL into the address bar.
|
||||
They should be able to click a link to navigate.
|
||||
@ -283,7 +283,7 @@ The user should be able to get to these details in three ways.
|
||||
In this section, you'll enable navigation to the `HeroDetailsComponent`
|
||||
and liberate it from the `HeroesComponent`.
|
||||
|
||||
### Delete _hero details_ from _HeroesComponent_
|
||||
### Delete _hero details_ from `HeroesComponent`
|
||||
|
||||
When the user clicks a hero item in the `HeroesComponent`,
|
||||
the app should navigate to the `HeroDetailComponent`,
|
||||
@ -325,7 +325,7 @@ At this point, all application routes are in place.
|
||||
title="src/app/app-routing.module.ts (all routes)">
|
||||
</code-example>
|
||||
|
||||
### _DashboardComponent_ hero links
|
||||
### `DashboardComponent` hero links
|
||||
|
||||
The `DashboardComponent` hero links do nothing at the moment.
|
||||
|
||||
@ -343,7 +343,7 @@ to insert the current interation's `hero.id` into each
|
||||
[`routerLink`](#routerlink).
|
||||
|
||||
{@a heroes-component-links}
|
||||
### _HeroesComponent_ hero links
|
||||
### `HeroesComponent` hero links
|
||||
|
||||
The hero items in the `HeroesComponent` are `<li>` elements whose click events
|
||||
are bound to the component's `onSelect()` method.
|
||||
@ -446,7 +446,7 @@ The browser refreshes and the app crashes with a compiler error.
|
||||
`HeroService` doesn't have a `getHero()` method.
|
||||
Add it now.
|
||||
|
||||
### Add *HeroService.getHero()*
|
||||
### Add `HeroService.getHero()`
|
||||
|
||||
Open `HeroService` and add this `getHero()` method
|
||||
|
||||
@ -518,7 +518,7 @@ Here are the code files discussed on this page and your app should look like thi
|
||||
|
||||
{@a approutingmodule}
|
||||
{@a appmodule}
|
||||
#### _AppRoutingModule_ and _AppModule_
|
||||
#### _AppRoutingModule_, _AppModule_, and _HeroService_
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
@ -529,6 +529,10 @@ Here are the code files discussed on this page and your app should look like thi
|
||||
title="src/app/app.module.ts"
|
||||
path="toh-pt5/src/app/app.module.ts">
|
||||
</code-pane>
|
||||
<code-pane
|
||||
title="src/app/hero.service.ts"
|
||||
path="toh-pt5/src/app/hero.service.ts">
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
{@a appcomponent}
|
||||
@ -565,6 +569,7 @@ Here are the code files discussed on this page and your app should look like thi
|
||||
|
||||
{@a heroescomponent}
|
||||
#### _HeroesComponent_
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
title="src/app/heroes/heroes.component.html" path="toh-pt5/src/app/heroes/heroes.component.html">
|
||||
|
@ -40,14 +40,4 @@ describe('Api pages', function() {
|
||||
const page = new ApiPage('api/common/HashLocationStrategy');
|
||||
expect(page.getOverview('class').getText()).toContain('path(includeHash: boolean = false): string');
|
||||
});
|
||||
|
||||
it('should show a "Properties" section if there are public properties', () => {
|
||||
const page = new ApiPage('api/core/ViewContainerRef');
|
||||
expect(page.getSection('instance-properties').isPresent()).toBe(true);
|
||||
});
|
||||
|
||||
it('should not show a "Properties" section if there are only internal properties', () => {
|
||||
const page = new ApiPage('api/forms/FormControl');
|
||||
expect(page.getSection('instance-properties').isPresent()).toBe(false);
|
||||
});
|
||||
});
|
@ -24,15 +24,11 @@ export class ApiPage extends SitePage {
|
||||
//
|
||||
// and we want to be able to pull out the code elements from only the first level
|
||||
// if `onlyDirect` is set to `true`.
|
||||
const selector = `.descendants.${docType} ${onlyDirect ? '>' : ''} ul > li > code`;
|
||||
const selector = `.descendants.${docType} ${onlyDirect ? '>' : ''} li > :not(ul) code`;
|
||||
return element.all(by.css(selector)).map<string>(item => item && item.getText());
|
||||
}
|
||||
|
||||
getOverview(docType) {
|
||||
return element(by.css(`.${docType}-overview`));
|
||||
}
|
||||
|
||||
getSection(cls) {
|
||||
return element(by.css(`section.${cls}`));
|
||||
}
|
||||
}
|
@ -107,7 +107,7 @@
|
||||
"cross-spawn": "^5.1.0",
|
||||
"css-selector-parser": "^1.3.0",
|
||||
"dgeni": "^0.4.7",
|
||||
"dgeni-packages": "^0.24.3",
|
||||
"dgeni-packages": "^0.25.0",
|
||||
"entities": "^1.1.1",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-plugin-jasmine": "^2.2.0",
|
||||
|
@ -6,7 +6,7 @@ const { SpecReporter } = require('jasmine-spec-reporter');
|
||||
exports.config = {
|
||||
allScriptsTimeout: 11000,
|
||||
specs: [
|
||||
'./*.e2e-spec.ts'
|
||||
'./e2e/**/*.e2e-spec.ts'
|
||||
],
|
||||
capabilities: {
|
||||
browserName: 'chrome',
|
||||
@ -26,7 +26,7 @@ exports.config = {
|
||||
},
|
||||
beforeLaunch: function() {
|
||||
require('ts-node').register({
|
||||
project: 'tests/e2e/tsconfig.e2e.json'
|
||||
project: 'e2e/tsconfig.e2e.json'
|
||||
});
|
||||
},
|
||||
onPrepare() {
|
@ -69,15 +69,20 @@ describe('DocumentService', () => {
|
||||
it('should emit the not-found document if the document is not found on the server', () => {
|
||||
let currentDocument: DocumentContents|undefined;
|
||||
const notFoundDoc = { id: FILE_NOT_FOUND_ID, contents: '<h1>Page Not Found</h1>' };
|
||||
const { docService } = getServices('missing/doc');
|
||||
const { docService, logger } = getServices('missing/doc');
|
||||
docService.currentDocument.subscribe(doc => currentDocument = doc);
|
||||
|
||||
// Initial request return 404.
|
||||
httpMock.expectOne({}).flush(null, {status: 404, statusText: 'NOT FOUND'});
|
||||
expect(logger.output.error).toEqual([
|
||||
[jasmine.any(Error)]
|
||||
]);
|
||||
expect(logger.output.error[0][0].message).toEqual(`Document file not found at 'missing/doc'`);
|
||||
|
||||
// Subsequent request for not-found document.
|
||||
logger.output.error = [];
|
||||
httpMock.expectOne(CONTENT_URL_PREFIX + 'file-not-found.json').flush(notFoundDoc);
|
||||
|
||||
expect(logger.output.error).toEqual([]); // does not report repeate errors
|
||||
expect(currentDocument).toEqual(notFoundDoc);
|
||||
});
|
||||
|
||||
@ -102,12 +107,17 @@ describe('DocumentService', () => {
|
||||
let latestDocument: DocumentContents|undefined;
|
||||
const doc1 = { contents: 'doc 1' };
|
||||
const doc2 = { contents: 'doc 2' };
|
||||
const { docService, locationService } = getServices('initial/doc');
|
||||
const { docService, locationService, logger } = getServices('initial/doc');
|
||||
|
||||
docService.currentDocument.subscribe(doc => latestDocument = doc);
|
||||
|
||||
httpMock.expectOne({}).flush(null, {status: 500, statusText: 'Server Error'});
|
||||
expect(latestDocument!.id).toEqual(FETCHING_ERROR_ID);
|
||||
expect(logger.output.error).toEqual([
|
||||
[jasmine.any(Error)]
|
||||
]);
|
||||
expect(logger.output.error[0][0].message)
|
||||
.toEqual(`Error fetching document 'initial/doc': (Http failure response for generated/docs/initial/doc.json: 500 Server Error)`);
|
||||
|
||||
locationService.go('new/doc');
|
||||
httpMock.expectOne({}).flush(doc1);
|
||||
|
@ -78,7 +78,7 @@ export class DocumentService {
|
||||
|
||||
private getFileNotFoundDoc(id: string): Observable<DocumentContents> {
|
||||
if (id !== FILE_NOT_FOUND_ID) {
|
||||
this.logger.error(`Document file not found at '${id}'`);
|
||||
this.logger.error(new Error(`Document file not found at '${id}'`));
|
||||
// using `getDocument` means that we can fetch the 404 doc contents from the server and cache it
|
||||
return this.getDocument(FILE_NOT_FOUND_ID);
|
||||
} else {
|
||||
@ -90,7 +90,7 @@ export class DocumentService {
|
||||
}
|
||||
|
||||
private getErrorDoc(id: string, error: HttpErrorResponse): Observable<DocumentContents> {
|
||||
this.logger.error('Error fetching document', error);
|
||||
this.logger.error(new Error(`Error fetching document '${id}': (${error.message})`));
|
||||
this.cache.delete(id);
|
||||
return Observable.of({
|
||||
id: FETCHING_ERROR_ID,
|
||||
|
@ -66,7 +66,10 @@ describe('AnnouncementBarComponent', () => {
|
||||
const request = httpMock.expectOne('generated/announcements.json');
|
||||
request.flush('some random response');
|
||||
expect(component.announcement).toBeUndefined();
|
||||
expect(mockLogger.output.error[0][0]).toContain('generated/announcements.json contains invalid data:');
|
||||
expect(mockLogger.output.error).toEqual([
|
||||
[jasmine.any(Error)]
|
||||
]);
|
||||
expect(mockLogger.output.error[0][0].message).toMatch(/^generated\/announcements\.json contains invalid data:/);
|
||||
});
|
||||
|
||||
it('should handle a failed request for `announcements.json`', () => {
|
||||
@ -74,7 +77,10 @@ describe('AnnouncementBarComponent', () => {
|
||||
const request = httpMock.expectOne('generated/announcements.json');
|
||||
request.error(new ErrorEvent('404'));
|
||||
expect(component.announcement).toBeUndefined();
|
||||
expect(mockLogger.output.error[0][0]).toContain('generated/announcements.json request failed:');
|
||||
expect(mockLogger.output.error).toEqual([
|
||||
[jasmine.any(Error)]
|
||||
]);
|
||||
expect(mockLogger.output.error[0][0].message).toMatch(/^generated\/announcements\.json request failed:/);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -59,12 +59,12 @@ export class AnnouncementBarComponent implements OnInit {
|
||||
ngOnInit() {
|
||||
this.http.get<Announcement[]>(announcementsPath)
|
||||
.catch(error => {
|
||||
this.logger.error(`${announcementsPath} request failed: ${error.message}`);
|
||||
this.logger.error(new Error(`${announcementsPath} request failed: ${error.message}`));
|
||||
return [];
|
||||
})
|
||||
.map(announcements => this.findCurrentAnnouncement(announcements))
|
||||
.catch(error => {
|
||||
this.logger.error(`${announcementsPath} contains invalid data: ${error.message}`);
|
||||
this.logger.error(new Error(`${announcementsPath} contains invalid data: ${error.message}`));
|
||||
return [];
|
||||
})
|
||||
.subscribe(announcement => this.announcement = announcement);
|
||||
|
@ -254,10 +254,14 @@ describe('CodeComponent', () => {
|
||||
it('should display an error when copy fails', () => {
|
||||
const snackBar: MatSnackBar = TestBed.get(MatSnackBar);
|
||||
const copierService: CopierService = TestBed.get(CopierService);
|
||||
const logger: TestLogger = TestBed.get(Logger);
|
||||
spyOn(snackBar, 'open');
|
||||
spyOn(copierService, 'copyText').and.returnValue(false);
|
||||
getButton().click();
|
||||
expect(snackBar.open).toHaveBeenCalledWith('Copy failed. Please try again!', '', { duration: 800 });
|
||||
expect(logger.error).toHaveBeenCalledTimes(1);
|
||||
expect(logger.error).toHaveBeenCalledWith(jasmine.any(Error));
|
||||
expect(logger.error.calls.mostRecent().args[0].message).toMatch(/^ERROR copying code to clipboard:/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -148,7 +148,7 @@ export class CodeComponent implements OnChanges {
|
||||
duration: 800,
|
||||
});
|
||||
} else {
|
||||
this.logger.error('ERROR copying code to clipboard:', code);
|
||||
this.logger.error(new Error(`ERROR copying code to clipboard: "${code}"`));
|
||||
// failure snackbar alert
|
||||
this.snackbar.open('Copy failed. Please try again!', '', {
|
||||
duration: 800,
|
||||
|
@ -33,8 +33,8 @@ export class PrettyPrinter {
|
||||
.then(
|
||||
() => (window as any)['prettyPrintOne'],
|
||||
err => {
|
||||
const msg = 'Cannot get prettify.js from server';
|
||||
this.logger.error(msg, err);
|
||||
const msg = `Cannot get prettify.js from server: ${err.message}`;
|
||||
this.logger.error(new Error(msg));
|
||||
// return a pretty print fn that always fails.
|
||||
return () => { throw new Error(msg); };
|
||||
});
|
||||
|
@ -555,8 +555,9 @@ describe('DocViewerComponent', () => {
|
||||
expect(swapViewsSpy).not.toHaveBeenCalled();
|
||||
expect(docViewer.nextViewContainer.innerHTML).toBe('');
|
||||
expect(logger.output.error).toEqual([
|
||||
[`[DocViewer] Error preparing document 'foo': ${error.stack}`],
|
||||
[jasmine.any(Error)]
|
||||
]);
|
||||
expect(logger.output.error[0][0].message).toEqual(`[DocViewer] Error preparing document 'foo': ${error.stack}`);
|
||||
expect(TestBed.get(Meta).addTag).toHaveBeenCalledWith({ name: 'googlebot', content: 'noindex' });
|
||||
expect(TestBed.get(Meta).addTag).toHaveBeenCalledWith({ name: 'robots', content: 'noindex' });
|
||||
});
|
||||
@ -576,8 +577,9 @@ describe('DocViewerComponent', () => {
|
||||
expect(swapViewsSpy).not.toHaveBeenCalled();
|
||||
expect(docViewer.nextViewContainer.innerHTML).toBe('');
|
||||
expect(logger.output.error).toEqual([
|
||||
[`[DocViewer] Error preparing document 'bar': ${error.stack}`],
|
||||
[jasmine.any(Error)]
|
||||
]);
|
||||
expect(logger.output.error[0][0].message).toEqual(`[DocViewer] Error preparing document 'bar': ${error.stack}`);
|
||||
expect(TestBed.get(Meta).addTag).toHaveBeenCalledWith({ name: 'googlebot', content: 'noindex' });
|
||||
expect(TestBed.get(Meta).addTag).toHaveBeenCalledWith({ name: 'robots', content: 'noindex' });
|
||||
});
|
||||
@ -597,8 +599,9 @@ describe('DocViewerComponent', () => {
|
||||
expect(swapViewsSpy).not.toHaveBeenCalled();
|
||||
expect(docViewer.nextViewContainer.innerHTML).toBe('');
|
||||
expect(logger.output.error).toEqual([
|
||||
[`[DocViewer] Error preparing document 'baz': ${error.stack}`],
|
||||
[jasmine.any(Error)]
|
||||
]);
|
||||
expect(logger.output.error[0][0].message).toEqual(`[DocViewer] Error preparing document 'baz': ${error.stack}`);
|
||||
expect(TestBed.get(Meta).addTag).toHaveBeenCalledWith({ name: 'googlebot', content: 'noindex' });
|
||||
expect(TestBed.get(Meta).addTag).toHaveBeenCalledWith({ name: 'robots', content: 'noindex' });
|
||||
});
|
||||
@ -618,8 +621,9 @@ describe('DocViewerComponent', () => {
|
||||
expect(swapViewsSpy).toHaveBeenCalledTimes(1);
|
||||
expect(docViewer.nextViewContainer.innerHTML).toBe('');
|
||||
expect(logger.output.error).toEqual([
|
||||
[`[DocViewer] Error preparing document 'qux': ${error.stack}`],
|
||||
[jasmine.any(Error)]
|
||||
]);
|
||||
expect(logger.output.error[0][0].message).toEqual(`[DocViewer] Error preparing document 'qux': ${error.stack}`);
|
||||
expect(TestBed.get(Meta).addTag).toHaveBeenCalledWith({ name: 'googlebot', content: 'noindex' });
|
||||
expect(TestBed.get(Meta).addTag).toHaveBeenCalledWith({ name: 'robots', content: 'noindex' });
|
||||
});
|
||||
@ -636,8 +640,9 @@ describe('DocViewerComponent', () => {
|
||||
expect(swapViewsSpy).toHaveBeenCalledTimes(1);
|
||||
expect(docViewer.nextViewContainer.innerHTML).toBe('');
|
||||
expect(logger.output.error).toEqual([
|
||||
[`[DocViewer] Error preparing document 'qux': ${error}`],
|
||||
[jasmine.any(Error)]
|
||||
]);
|
||||
expect(logger.output.error[0][0].message).toEqual(`[DocViewer] Error preparing document 'qux': ${error}`);
|
||||
expect(TestBed.get(Meta).addTag).toHaveBeenCalledWith({ name: 'googlebot', content: 'noindex' });
|
||||
expect(TestBed.get(Meta).addTag).toHaveBeenCalledWith({ name: 'robots', content: 'noindex' });
|
||||
});
|
||||
|
@ -157,7 +157,7 @@ export class DocViewerComponent implements DoCheck, OnDestroy {
|
||||
.do(() => this.docRendered.emit())
|
||||
.catch(err => {
|
||||
const errorMessage = (err instanceof Error) ? err.stack : err;
|
||||
this.logger.error(`[DocViewer] Error preparing document '${doc.id}': ${errorMessage}`);
|
||||
this.logger.error(new Error(`[DocViewer] Error preparing document '${doc.id}': ${errorMessage}`));
|
||||
this.nextViewContainer.innerHTML = '';
|
||||
this.setNoIndex(true);
|
||||
return this.void$;
|
||||
|
@ -34,8 +34,9 @@ describe('logger service', () => {
|
||||
|
||||
describe('error', () => {
|
||||
it('should delegate to ErrorHandler', () => {
|
||||
logger.error('param1', 'param2', 'param3');
|
||||
expect(errorHandler.handleError).toHaveBeenCalledWith('param1 param2 param3');
|
||||
const err = new Error('some error message');
|
||||
logger.error(err);
|
||||
expect(errorHandler.handleError).toHaveBeenCalledWith(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -13,9 +13,8 @@ export class Logger {
|
||||
}
|
||||
}
|
||||
|
||||
error(value: any, ...rest: any[]) {
|
||||
const message = [value, ...rest].join(' ');
|
||||
this.errorHandler.handleError(message);
|
||||
error(error: Error) {
|
||||
this.errorHandler.handleError(error);
|
||||
}
|
||||
|
||||
warn(value: any, ...rest: any[]) {
|
||||
|
@ -12,10 +12,16 @@ h1 {
|
||||
font-size: 24px;
|
||||
font-weight: 500;
|
||||
margin: 8px 0px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
margin-top: 0;
|
||||
}
|
||||
h1:after {
|
||||
content: "";
|
||||
display: block;
|
||||
height: 1px;
|
||||
width: 40%;
|
||||
margin: 24px 0px 10px;
|
||||
background: $lightgray;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
h2 {
|
||||
@ -54,7 +60,13 @@ h6 {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
h2, h3, h4, h5, h6 {
|
||||
h1 {
|
||||
@media screen and (max-width: 600px) {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
h1:after, h2, h3, h4, h5, h6 {
|
||||
@media screen and (max-width: 600px) {
|
||||
margin: 8px 0;
|
||||
}
|
||||
@ -131,13 +143,13 @@ th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
p > code, li > code, td > code, th > code {
|
||||
p > code, li > code, table code {
|
||||
font-family: $code-font;
|
||||
font-size: 85%;
|
||||
color: $darkgray;
|
||||
letter-spacing: 0;
|
||||
line-height: 1;
|
||||
padding: 2px 0;
|
||||
padding: 2px 6px;
|
||||
background-color: $backgroundgray;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
@ -36,44 +36,34 @@
|
||||
}
|
||||
}
|
||||
|
||||
.api-body {
|
||||
|
||||
max-width: 1200px;
|
||||
.api-header label {
|
||||
border-radius: 4px;
|
||||
padding: 4px 16px;
|
||||
display: inline;
|
||||
font-size: 14px;
|
||||
color: white;
|
||||
margin: 0 8px 0 16px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
|
||||
table {
|
||||
|
||||
th {
|
||||
text-transform: none;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
@media screen and (max-width: 600px) {
|
||||
display: block;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
tr {
|
||||
border-bottom: 1px solid $lightgray;
|
||||
&.api-status-label {
|
||||
background-color: $mediumgray;
|
||||
}
|
||||
|
||||
td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
&.api-type-label {
|
||||
background-color: $accentblue;
|
||||
|
||||
hr {
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
tr:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&.item-table {
|
||||
td {
|
||||
padding: 32px;
|
||||
@each $name, $symbol in $api-symbols {
|
||||
&.#{$name} {
|
||||
background: map-get($symbol, background);
|
||||
}
|
||||
}
|
||||
|
||||
&.list-table {
|
||||
td {
|
||||
padding: 16px 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -37,11 +37,3 @@ aio-shell.page-docs {
|
||||
margin: 24px 0px;
|
||||
background: $lightgray;
|
||||
}
|
||||
|
||||
.page-actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
top: 80px;
|
||||
right: 24px;
|
||||
}
|
@ -20,6 +20,10 @@
|
||||
transform: none;
|
||||
}
|
||||
|
||||
h1:after {
|
||||
content: none;
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
display: inline-block;
|
||||
font-size: 28px;
|
||||
|
@ -1,71 +1,23 @@
|
||||
.api-body {
|
||||
.api-info-bar {
|
||||
max-width: 800px;
|
||||
text-align: left;
|
||||
|
||||
.class-overview {
|
||||
position: relative;
|
||||
span {
|
||||
margin: 0 16px 0 0;
|
||||
|
||||
code-example {
|
||||
clear: left;
|
||||
}
|
||||
@media screen and (max-width: 600px) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.method-table {
|
||||
h3 {
|
||||
margin: 6px 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
margin-top: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.api-heading {
|
||||
padding: 5px 0;
|
||||
.api-heading {
|
||||
margin-top: 24px;
|
||||
margin-bottom: 18px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.properties-table {
|
||||
font-size: 14px;
|
||||
|
||||
thead th {
|
||||
&:nth-child(1) {
|
||||
width: 20%;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
width: 20%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.parameters-table {
|
||||
margin-top: 0;
|
||||
font-size: 14px;
|
||||
td:nth-child(1) {
|
||||
width: 20%;
|
||||
}
|
||||
}
|
||||
|
||||
details.overloads {
|
||||
margin-left: -8px;
|
||||
|
||||
summary {
|
||||
height: inherit;
|
||||
padding: 8px 12px;
|
||||
h4 {
|
||||
margin: 0;
|
||||
clear: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.api-section aio-code {
|
||||
background-color: rgba(241, 241, 241, 0.2);
|
||||
}
|
||||
|
||||
.from-constructor {
|
||||
font-style: italic;
|
||||
color: $blue;
|
||||
}
|
||||
.overloads .detail-contents {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
25
aio/src/styles/2-modules/_banner.scss
Normal file
25
aio/src/styles/2-modules/_banner.scss
Normal file
@ -0,0 +1,25 @@
|
||||
/* BANNER */
|
||||
|
||||
.info-banner {
|
||||
margin: 16px 0;
|
||||
justify-content: center;
|
||||
background: $white;
|
||||
border: 1px solid rgba($lightgray, 0.5);
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
padding: 16px;
|
||||
background: $white;
|
||||
height: auto;
|
||||
overflow: visible;
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p, .text-body {
|
||||
color: $darkgray;
|
||||
line-height: 32px;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
@ -69,7 +69,7 @@ code-tabs mat-tab-body-content .fadeIn {
|
||||
aio-code pre {
|
||||
display: flex;
|
||||
min-height: 32px;
|
||||
margin: 16px 24px;
|
||||
margin: 16px 32px;
|
||||
white-space: pre-wrap;
|
||||
align-items: center;
|
||||
|
||||
|
@ -25,13 +25,16 @@ summary {
|
||||
display: none; // Remove the built in details marker in webkit
|
||||
}
|
||||
|
||||
&::before {
|
||||
&::after {
|
||||
content: '\E5CE'; // See https://material.io/icons/#ic_expand_less
|
||||
font-family: 'Material Icons';
|
||||
font-size: 24px;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
@include rotate(0deg); // We will rotate 180 degrees when details is open
|
||||
float: right;
|
||||
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,7 +45,7 @@ details {
|
||||
padding: 16px 24px;
|
||||
}
|
||||
|
||||
&[open] > summary::before {
|
||||
&[open] > summary::after {
|
||||
@include rotate(180deg); // Rotate the icon
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,48 @@
|
||||
.sidenav-content {
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
|
||||
&.no-anchor .header-link {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.header-link {
|
||||
box-sizing: border-box;
|
||||
color: $mediumgray;
|
||||
margin-left: 8px;
|
||||
display: inline-block;
|
||||
margin-left: -42px;
|
||||
padding: 0 8px;
|
||||
text-decoration: none;
|
||||
user-select: none;
|
||||
vertical-align: middle;
|
||||
visibility: hidden;
|
||||
display: inline-block;
|
||||
vertical-align: text-top;
|
||||
width: 40px;
|
||||
|
||||
@media (max-width: 600px) {
|
||||
float: right;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover .header-link {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.l-sub-section {
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
a {
|
||||
padding-right: 64px;
|
||||
margin-left: -74px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.alert {
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
a {
|
||||
padding-right: 80px;
|
||||
margin-left: -90px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,55 +0,0 @@
|
||||
label.raised, .api-header label {
|
||||
border-radius: 4px;
|
||||
padding: 4px 16px;
|
||||
display: inline;
|
||||
font-size: 14px;
|
||||
color: white;
|
||||
margin-right: 8px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
display: block;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
&.page-label {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: $mist;
|
||||
color: $mediumgray;
|
||||
margin-bottom: 8px;
|
||||
width: 140px;
|
||||
|
||||
.material-icons {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&.property-type-label {
|
||||
font-size: 12px;
|
||||
background-color: $darkgray;
|
||||
color: $white;
|
||||
text-transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
.api-header label {
|
||||
|
||||
&.api-status-label {
|
||||
background-color: $mediumgray;
|
||||
}
|
||||
|
||||
&.api-type-label {
|
||||
background-color: $accentblue;
|
||||
|
||||
@each $name, $symbol in $api-symbols {
|
||||
&.#{$name} {
|
||||
background: map-get($symbol, background);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
@import 'alert';
|
||||
@import 'api-pages';
|
||||
@import 'api-list';
|
||||
@import 'banner';
|
||||
@import 'buttons';
|
||||
@import 'callout';
|
||||
@import 'card';
|
||||
@ -29,4 +30,3 @@
|
||||
@import 'select-menu';
|
||||
@import 'deploy-theme';
|
||||
@import 'notification';
|
||||
@import 'label';
|
||||
|
@ -12,7 +12,7 @@ table {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
thead > {
|
||||
thead {
|
||||
vertical-align: middle;
|
||||
border-color: inherit;
|
||||
|
||||
@ -21,20 +21,20 @@ table {
|
||||
border-color: inherit;
|
||||
}
|
||||
|
||||
tr > th {
|
||||
th {
|
||||
background: rgba($lightgray, 0.2);
|
||||
border-bottom: 1px solid $lightgray;
|
||||
color: $darkgray;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
padding: 8px 24px;
|
||||
padding: 8px 32px;
|
||||
text-align: left;
|
||||
text-transform: uppercase;
|
||||
line-height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
tbody > tr > {
|
||||
tbody {
|
||||
th,
|
||||
td {
|
||||
border-bottom: 1px solid $lightgray;
|
||||
@ -70,7 +70,7 @@ table {
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
&:last-child td {
|
||||
tr:last-child td {
|
||||
border: none;
|
||||
|
||||
@media (max-width: 480px) {
|
||||
|
@ -30,7 +30,7 @@
|
||||
box-shadow: 0 2px 2px rgba(0,0,0,0.24), 0 0 2px rgba(0,0,0,0.12);
|
||||
}
|
||||
|
||||
table > tbody > tr > th {
|
||||
table tbody th{
|
||||
border: 1px solid rgba(mat-color($foreground, secondary-text), .03);
|
||||
}
|
||||
|
||||
|
@ -1,14 +0,0 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/e2e",
|
||||
"baseUrl": "./",
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"jasminewd2",
|
||||
"node"
|
||||
]
|
||||
}
|
||||
}
|
@ -14,8 +14,6 @@ const { API_SOURCE_PATH, API_TEMPLATES_PATH, requireFolder } = require('../confi
|
||||
module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
|
||||
|
||||
// Register the processors
|
||||
.processor(require('./processors/migrateLegacyJSDocTags'))
|
||||
.processor(require('./processors/splitDescription'))
|
||||
.processor(require('./processors/convertPrivateClassesToInterfaces'))
|
||||
.processor(require('./processors/generateApiListDoc'))
|
||||
.processor(require('./processors/addNotYetDocumentedProperty'))
|
||||
@ -23,9 +21,7 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
|
||||
.processor(require('./processors/extractDecoratedClasses'))
|
||||
.processor(require('./processors/matchUpDirectiveDecorators'))
|
||||
.processor(require('./processors/addMetadataAliases'))
|
||||
.processor(require('./processors/computeApiBreadCrumbs'))
|
||||
.processor(require('./processors/filterContainedDocs'))
|
||||
.processor(require('./processors/processClassLikeMembers'))
|
||||
.processor(require('./processors/markBarredODocsAsPrivate'))
|
||||
.processor(require('./processors/filterPrivateDocs'))
|
||||
.processor(require('./processors/computeSearchTitle'))
|
||||
@ -90,12 +86,17 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
|
||||
// Load up all the tag definitions in the tag-defs folder
|
||||
parseTagsProcessor.tagDefinitions =
|
||||
parseTagsProcessor.tagDefinitions.concat(getInjectables(requireFolder(__dirname, './tag-defs')));
|
||||
|
||||
// We actually don't want to parse param docs in this package as we are getting the data out using TS
|
||||
// TODO: rewire the param docs to the params extracted from TS
|
||||
parseTagsProcessor.tagDefinitions.forEach(function(tagDef) {
|
||||
if (tagDef.name === 'param') {
|
||||
tagDef.docProperty = 'paramData';
|
||||
tagDef.transforms = [];
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
.config(function(splitDescription, EXPORT_DOC_TYPES) {
|
||||
// Only split the description on the API docs
|
||||
splitDescription.docTypes = EXPORT_DOC_TYPES;
|
||||
})
|
||||
|
||||
.config(function(computePathsProcessor, EXPORT_DOC_TYPES, generateApiListDoc) {
|
||||
|
||||
@ -130,6 +131,6 @@ 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.docTypes = DOCS_TO_CONVERT.concat(['member']);
|
||||
autoLinkCode.codeElements = ['code', 'code-example', 'code-pane'];
|
||||
});
|
||||
|
@ -1,19 +0,0 @@
|
||||
module.exports = function computeApiBreadCrumbs(EXPORT_DOC_TYPES) {
|
||||
return {
|
||||
$runAfter: ['paths-computed'],
|
||||
$runBefore: ['rendering-docs'],
|
||||
$process(docs) {
|
||||
// Compute the breadcrumb for each doc by processing its containers
|
||||
docs.forEach(doc => {
|
||||
if (EXPORT_DOC_TYPES.indexOf(doc.docType) !== -1) {
|
||||
doc.breadCrumbs = [
|
||||
{ text: 'API', path: '/api' },
|
||||
{ text: '@angular/' + doc.moduleDoc.id, path: doc.moduleDoc.path },
|
||||
{ text: doc.name, path: doc.path }
|
||||
];
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -1,39 +0,0 @@
|
||||
const testPackage = require('../../helpers/test-package');
|
||||
const processorFactory = require('./computeApiBreadCrumbs');
|
||||
const Dgeni = require('dgeni');
|
||||
|
||||
describe('angular-api-package: computeApiBreadCrumbs processor', () => {
|
||||
|
||||
it('should be available on the injector', () => {
|
||||
const dgeni = new Dgeni([testPackage('angular-api-package')]);
|
||||
const injector = dgeni.configureInjector();
|
||||
const processor = injector.get('computeApiBreadCrumbs');
|
||||
expect(processor.$process).toBeDefined();
|
||||
expect(processor.$runAfter).toEqual(['paths-computed']);
|
||||
expect(processor.$runBefore).toEqual(['rendering-docs']);
|
||||
});
|
||||
|
||||
it('should attach a breadCrumbs property to each of the EXPORT_DOC_TYPES docs', () => {
|
||||
const EXPORT_DOC_TYPES = ['class', 'interface'];
|
||||
const processor = processorFactory(EXPORT_DOC_TYPES);
|
||||
|
||||
const docs = [
|
||||
{ docType: 'class', name: 'ClassA', path: 'module-1/class-a', moduleDoc: { id: 'moduleOne', path: 'module-1' } },
|
||||
{ docType: 'interface', name: 'InterfaceB', path: 'module-2/interface-b', moduleDoc: { id: 'moduleTwo', path: 'module-2' } },
|
||||
{ docType: 'guide', name: 'Guide One', path: 'guide/guide-1' },
|
||||
];
|
||||
processor.$process(docs);
|
||||
|
||||
expect(docs[0].breadCrumbs).toEqual([
|
||||
{ text: 'API', path: '/api' },
|
||||
{ text: '@angular/moduleOne', path: 'module-1' },
|
||||
{ text: 'ClassA', path: 'module-1/class-a' },
|
||||
]);
|
||||
expect(docs[1].breadCrumbs).toEqual([
|
||||
{ text: 'API', path: '/api' },
|
||||
{ text: '@angular/moduleTwo', path: 'module-2' },
|
||||
{ text: 'InterfaceB', path: 'module-2/interface-b' },
|
||||
]);
|
||||
expect(docs[2].breadCrumbs).toBeUndefined();
|
||||
});
|
||||
});
|
@ -1,36 +0,0 @@
|
||||
module.exports = function migrateLegacyJSDocTags(log, createDocMessage) {
|
||||
return {
|
||||
$runAfter: ['tags-extracted'],
|
||||
$runBefore: ['processing-docs'],
|
||||
$process(docs) {
|
||||
let migrated = false;
|
||||
docs.forEach(doc => {
|
||||
if (doc.howToUse) {
|
||||
if (doc.usageNotes) {
|
||||
throw new Error(createDocMessage('`@usageNotes` and the deprecated `@howToUse` are not allowed on the same doc', doc));
|
||||
}
|
||||
log.debug(createDocMessage('Using deprecated `@howToUse` tag as though it was `@usageNotes` tag', doc));
|
||||
doc.usageNotes = doc.howToUse;
|
||||
doc.howToUse = null;
|
||||
migrated = true;
|
||||
}
|
||||
|
||||
if (doc.whatItDoes) {
|
||||
log.debug(createDocMessage('Merging the content of `@whatItDoes` tag into the description.', doc));
|
||||
if (doc.description) {
|
||||
doc.description = `${doc.whatItDoes}\n\n${doc.description}`;
|
||||
} else {
|
||||
doc.description = doc.whatItDoes;
|
||||
}
|
||||
doc.whatItDoes = null;
|
||||
migrated = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (migrated) {
|
||||
log.warn('Some deprecated tags were migrated.');
|
||||
log.warn('This automatic handling will be removed in a future version of the doc generation.\n');
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
@ -1,66 +0,0 @@
|
||||
const testPackage = require('../../helpers/test-package');
|
||||
const processorFactory = require('./migrateLegacyJSDocTags');
|
||||
const log = require('dgeni/lib/mocks/log')(false);
|
||||
const createDocMessage = require('dgeni-packages/base/services/createDocMessage')();
|
||||
const Dgeni = require('dgeni');
|
||||
|
||||
describe('migrateLegacyJSDocTags processor', () => {
|
||||
|
||||
it('should be available on the injector', () => {
|
||||
const dgeni = new Dgeni([testPackage('angular-api-package')]);
|
||||
const injector = dgeni.configureInjector();
|
||||
const processor = injector.get('migrateLegacyJSDocTags');
|
||||
expect(processor.$process).toBeDefined();
|
||||
});
|
||||
|
||||
it('should run before the correct processor', () => {
|
||||
const processor = processorFactory(log, createDocMessage);
|
||||
expect(processor.$runBefore).toEqual(['processing-docs']);
|
||||
});
|
||||
|
||||
it('should run after the correct processor', () => {
|
||||
const processor = processorFactory(log, createDocMessage);
|
||||
expect(processor.$runAfter).toEqual(['tags-extracted']);
|
||||
});
|
||||
|
||||
it('should migrate `howToUse` property to `usageNotes` property', () => {
|
||||
const processor = processorFactory(log, createDocMessage);
|
||||
const docs = [
|
||||
{ howToUse: 'this is how to use it' }
|
||||
];
|
||||
processor.$process(docs);
|
||||
expect(docs[0].howToUse).toBe(null);
|
||||
expect(docs[0].usageNotes).toEqual('this is how to use it');
|
||||
});
|
||||
|
||||
it('should migrate `whatItDoes` property to the `description`', () => {
|
||||
const processor = processorFactory(log, createDocMessage);
|
||||
const docs = [
|
||||
{ whatItDoes: 'what it does' },
|
||||
{ whatItDoes: 'what it does', description: 'the description' },
|
||||
{ description: 'the description' }
|
||||
];
|
||||
processor.$process(docs);
|
||||
expect(docs[0].whatItDoes).toBe(null);
|
||||
expect(docs[0].description).toEqual('what it does');
|
||||
|
||||
expect(docs[1].whatItDoes).toBe(null);
|
||||
expect(docs[1].description).toEqual('what it does\n\nthe description');
|
||||
|
||||
expect(docs[2].whatItDoes).toBeUndefined();
|
||||
expect(docs[2].description).toEqual('the description');
|
||||
});
|
||||
|
||||
it('should ignore docs that have neither `howToUse` nor `whatItDoes` properties', () => {
|
||||
const processor = processorFactory(log, createDocMessage);
|
||||
const docs = [
|
||||
{ },
|
||||
{ description: 'the description' }
|
||||
];
|
||||
processor.$process(docs);
|
||||
expect(docs).toEqual([
|
||||
{ },
|
||||
{ description: 'the description' }
|
||||
]);
|
||||
});
|
||||
});
|
@ -1,59 +0,0 @@
|
||||
/**
|
||||
* A class like API doc contains members, but these can be either properties or method.
|
||||
* Separate the members into two new collections: `doc.properties` and `doc.methods`.
|
||||
*/
|
||||
module.exports = function processClassLikeMembers() {
|
||||
return {
|
||||
$runAfter: ['filterContainedDocs'],
|
||||
$runBefore: ['rendering-docs'],
|
||||
$process(docs) {
|
||||
docs.forEach(doc => {
|
||||
if (doc.members) {
|
||||
doc.properties = [];
|
||||
doc.methods = [];
|
||||
doc.members.forEach(member => {
|
||||
if (isMethod(member)) {
|
||||
doc.methods.push(member);
|
||||
computeMemberDescription(member);
|
||||
} else {
|
||||
doc.properties.push(member);
|
||||
|
||||
if (!member.description) {
|
||||
// Is this property defined as a constructor parameter e.g. `constructor(public property: string) { ... }`?
|
||||
const constructorDoc = member.containerDoc.constructorDoc;
|
||||
if (constructorDoc) {
|
||||
const matchingParameterDoc = constructorDoc.parameterDocs.filter(doc => doc.declaration === member.declaration)[0];
|
||||
member.constructorParamDoc = matchingParameterDoc;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (doc.statics) {
|
||||
doc.staticProperties = [];
|
||||
doc.staticMethods = [];
|
||||
doc.statics.forEach(member => {
|
||||
if (isMethod(member)) {
|
||||
doc.staticMethods.push(member);
|
||||
computeMemberDescription(member);
|
||||
} else {
|
||||
doc.staticProperties.push(member);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
function isMethod(doc) {
|
||||
return doc.hasOwnProperty('parameters') && !doc.isGetAccessor && !doc.isSetAccessor;
|
||||
}
|
||||
|
||||
function computeMemberDescription(member) {
|
||||
if (!member.description && member.overloads) {
|
||||
// Perhaps the description is on one of the overloads - take the first non-empty one
|
||||
member.description = member.overloads.map(overload => overload.description).filter(description => !!description)[0];
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
const testPackage = require('../../helpers/test-package');
|
||||
const processorFactory = require('./processClassLikeMembers');
|
||||
const Dgeni = require('dgeni');
|
||||
|
||||
const property1 = { description: 'property 1' };
|
||||
const property2 = { description: 'property 2' };
|
||||
const getter1 = { parameters: [], isGetAccessor: true, description: 'getter 1' };
|
||||
const setter1 = { parameters: [], isSetAccessor: true, description: 'setter 1' };
|
||||
const method1 = { parameters: [] };
|
||||
const method2 = { parameters: [] };
|
||||
const method3 = { parameters: [] };
|
||||
|
||||
describe('angular-api-packge: processClassLikeMembers processor', () => {
|
||||
|
||||
it('should be available on the injector', () => {
|
||||
const dgeni = new Dgeni([testPackage('angular-api-package')]);
|
||||
const injector = dgeni.configureInjector();
|
||||
const processor = injector.get('processClassLikeMembers');
|
||||
expect(processor.$process).toBeDefined();
|
||||
expect(processor.$runAfter).toEqual(['filterContainedDocs']);
|
||||
expect(processor.$runBefore).toEqual(['rendering-docs']);
|
||||
});
|
||||
|
||||
it('should copy instance members into properties and methods', () => {
|
||||
const processor = processorFactory();
|
||||
const docs = [
|
||||
{ members: [ property1, method1, getter1] },
|
||||
{ members: [ method2, property2, method3, setter1] },
|
||||
{ }
|
||||
];
|
||||
processor.$process(docs);
|
||||
|
||||
expect(docs[0].properties).toEqual([property1, getter1]);
|
||||
expect(docs[0].methods).toEqual([method1]);
|
||||
|
||||
expect(docs[1].properties).toEqual([property2, setter1]);
|
||||
expect(docs[1].methods).toEqual([method2, method3]);
|
||||
|
||||
expect(docs[2].properties).toBeUndefined();
|
||||
expect(docs[2].methods).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should copy static members into properties and methods', () => {
|
||||
const processor = processorFactory();
|
||||
const docs = [
|
||||
{ statics: [ property1, method1, getter1] },
|
||||
{ statics: [ method2, property2, method3, setter1] },
|
||||
{ }
|
||||
];
|
||||
processor.$process(docs);
|
||||
|
||||
expect(docs[0].staticProperties).toEqual([property1, getter1]);
|
||||
expect(docs[0].staticMethods).toEqual([method1]);
|
||||
|
||||
expect(docs[1].staticProperties).toEqual([property2, setter1]);
|
||||
expect(docs[1].staticMethods).toEqual([method2, method3]);
|
||||
|
||||
expect(docs[2].staticProperties).toBeUndefined();
|
||||
expect(docs[2].staticMethods).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should wire up properties that are declared as parameters on the constructor to its associated parameter doc', () => {
|
||||
const processor = processorFactory();
|
||||
const propertyDeclaration = {};
|
||||
const parameterDoc1 = { declaration: {} };
|
||||
const parameterDoc2 = { declaration: propertyDeclaration };
|
||||
const parameterDoc3 = { declaration: {} };
|
||||
const property = {
|
||||
declaration: propertyDeclaration,
|
||||
containerDoc: {
|
||||
constructorDoc: {
|
||||
parameterDocs: [ parameterDoc1, parameterDoc2, parameterDoc3 ]
|
||||
}
|
||||
}
|
||||
};
|
||||
const docs = [{ members: [ property] }];
|
||||
processor.$process(docs);
|
||||
|
||||
expect(property.constructorParamDoc).toEqual(parameterDoc2);
|
||||
});
|
||||
});
|
@ -5,15 +5,21 @@
|
||||
*/
|
||||
module.exports = function simplifyMemberAnchors() {
|
||||
return {
|
||||
$runAfter: ['extra-docs-added'],
|
||||
$runBefore: ['computing-paths'],
|
||||
$runAfter: ['paths-computed'],
|
||||
$runBefore: ['rendering-docs'],
|
||||
$process: function(docs) {
|
||||
return docs.forEach(doc => {
|
||||
if (doc.members) {
|
||||
doc.members.forEach(member => member.anchor = computeAnchor(member));
|
||||
doc.members.forEach(member => {
|
||||
member.anchor = computeAnchor(member);
|
||||
member.path = doc.path + '#' + member.anchor;
|
||||
});
|
||||
}
|
||||
if (doc.statics) {
|
||||
doc.statics.forEach(member => member.anchor = computeAnchor(member));
|
||||
doc.statics.forEach(member => {
|
||||
member.anchor = computeAnchor(member);
|
||||
member.path = doc.path + '#' + member.anchor;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -0,0 +1,72 @@
|
||||
const testPackage = require('../../helpers/test-package');
|
||||
const processorFactory = require('./simplifyMemberAnchors');
|
||||
const Dgeni = require('dgeni');
|
||||
|
||||
describe('simplifyMemberAnchors processor', () => {
|
||||
|
||||
it('should be available on the injector', () => {
|
||||
const dgeni = new Dgeni([testPackage('angular-api-package')]);
|
||||
const injector = dgeni.configureInjector();
|
||||
const processor = injector.get('simplifyMemberAnchors');
|
||||
expect(processor.$process).toBeDefined();
|
||||
expect(processor.$runAfter).toEqual(['paths-computed']);
|
||||
expect(processor.$runBefore).toEqual(['rendering-docs']);
|
||||
});
|
||||
|
||||
describe('$process', () => {
|
||||
describe('docs without members', () => {
|
||||
it('should ignore the docs', () => {
|
||||
const processor = processorFactory();
|
||||
const docs = [
|
||||
{ id: 'some-doc' },
|
||||
{ id: 'some-other' }
|
||||
];
|
||||
processor.$process(docs);
|
||||
expect(docs).toEqual([
|
||||
{ id: 'some-doc' },
|
||||
{ id: 'some-other' }
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('docs with members', () => {
|
||||
it('should compute an anchor for each instance member', () => {
|
||||
const processor = processorFactory();
|
||||
const docs = [
|
||||
{ id: 'some-doc', members: [ { name: 'foo' }, { name: 'new' }, { name: '' } ] }
|
||||
];
|
||||
processor.$process(docs);
|
||||
expect(docs[0].members.map(member => member.anchor)).toEqual(['foo', 'new', 'call']);
|
||||
});
|
||||
|
||||
it('should compute a path for each instance member', () => {
|
||||
const processor = processorFactory();
|
||||
const docs = [
|
||||
{ id: 'some-doc', path: 'a/b/c', members: [ { name: 'foo' }, { name: 'new' }, { name: '' } ] }
|
||||
];
|
||||
processor.$process(docs);
|
||||
expect(docs[0].members.map(member => member.path)).toEqual(['a/b/c#foo', 'a/b/c#new', 'a/b/c#call']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('docs with static members', () => {
|
||||
it('should compute an anchor for each static member', () => {
|
||||
const processor = processorFactory();
|
||||
const docs = [
|
||||
{ id: 'some-doc', statics: [ { name: 'foo' }, { name: 'new' }, { name: '' } ] }
|
||||
];
|
||||
processor.$process(docs);
|
||||
expect(docs[0].statics.map(member => member.anchor)).toEqual(['foo', 'new', 'call']);
|
||||
});
|
||||
|
||||
it('should compute a path for each static member', () => {
|
||||
const processor = processorFactory();
|
||||
const docs = [
|
||||
{ id: 'some-doc', path: 'a/b/c', statics: [ { name: 'foo' }, { name: 'new' }, { name: '' } ] }
|
||||
];
|
||||
processor.$process(docs);
|
||||
expect(docs[0].statics.map(member => member.path)).toEqual(['a/b/c#foo', 'a/b/c#new', 'a/b/c#call']);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -1,28 +0,0 @@
|
||||
/**
|
||||
* Split the descripton (of selected docs) into:
|
||||
* * `shortDescription`: the first paragraph
|
||||
* * `description`: the rest of the paragraphs
|
||||
*/
|
||||
module.exports = function splitDescription() {
|
||||
return {
|
||||
$runAfter: ['tags-extracted', 'migrateLegacyJSDocTags'],
|
||||
$runBefore: ['processing-docs'],
|
||||
docTypes: [],
|
||||
$process(docs) {
|
||||
docs.forEach(doc => {
|
||||
if (this.docTypes.indexOf(doc.docType) !== -1 && doc.description !== undefined) {
|
||||
const description = doc.description.trim();
|
||||
const endOfParagraph = description.search(/\n\s*\n/);
|
||||
if (endOfParagraph === -1) {
|
||||
doc.shortDescription = description;
|
||||
doc.description = '';
|
||||
} else {
|
||||
doc.shortDescription = description.substr(0, endOfParagraph).trim();
|
||||
doc.description = description.substr(endOfParagraph).trim();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -1,71 +0,0 @@
|
||||
const testPackage = require('../../helpers/test-package');
|
||||
const processorFactory = require('./splitDescription');
|
||||
const Dgeni = require('dgeni');
|
||||
|
||||
describe('splitDescription processor', () => {
|
||||
|
||||
it('should be available on the injector', () => {
|
||||
const dgeni = new Dgeni([testPackage('angular-api-package')]);
|
||||
const injector = dgeni.configureInjector();
|
||||
const processor = injector.get('splitDescription');
|
||||
expect(processor.$process).toBeDefined();
|
||||
});
|
||||
|
||||
it('should run before the correct processor', () => {
|
||||
const processor = processorFactory();
|
||||
expect(processor.$runBefore).toEqual(['processing-docs']);
|
||||
});
|
||||
|
||||
it('should run after the correct processor', () => {
|
||||
const processor = processorFactory();
|
||||
expect(processor.$runAfter).toEqual(['tags-extracted', 'migrateLegacyJSDocTags']);
|
||||
});
|
||||
|
||||
it('should split the `description` property into the first paragraph and other paragraphs', () => {
|
||||
const processor = processorFactory();
|
||||
processor.docTypes = ['test'];
|
||||
const docs = [
|
||||
{ docType: 'test' },
|
||||
{ docType: 'test', description: '' },
|
||||
{ docType: 'test', description: 'abc' },
|
||||
{ docType: 'test', description: 'abc\n' },
|
||||
{ docType: 'test', description: 'abc\n\n' },
|
||||
{ docType: 'test', description: 'abc\ncde' },
|
||||
{ docType: 'test', description: 'abc\ncde\n' },
|
||||
{ docType: 'test', description: 'abc\n\ncde' },
|
||||
{ docType: 'test', description: 'abc\n \ncde' },
|
||||
{ docType: 'test', description: 'abc\n\n\ncde' },
|
||||
{ docType: 'test', description: 'abc\n\ncde\nfgh' },
|
||||
{ docType: 'test', description: 'abc\n\ncde\n\nfgh' },
|
||||
];
|
||||
processor.$process(docs);
|
||||
expect(docs).toEqual([
|
||||
{ docType: 'test' },
|
||||
{ docType: 'test', shortDescription: '', description: '' },
|
||||
{ docType: 'test', shortDescription: 'abc', description: '' },
|
||||
{ docType: 'test', shortDescription: 'abc', description: '' },
|
||||
{ docType: 'test', shortDescription: 'abc', description: '' },
|
||||
{ docType: 'test', shortDescription: 'abc\ncde', description: '' },
|
||||
{ docType: 'test', shortDescription: 'abc\ncde', description: '' },
|
||||
{ docType: 'test', shortDescription: 'abc', description: 'cde' },
|
||||
{ docType: 'test', shortDescription: 'abc', description: 'cde' },
|
||||
{ docType: 'test', shortDescription: 'abc', description: 'cde' },
|
||||
{ docType: 'test', shortDescription: 'abc', description: 'cde\nfgh' },
|
||||
{ docType: 'test', shortDescription: 'abc', description: 'cde\n\nfgh' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should ignore docs that do not match the specified doc types', () => {
|
||||
const processor = processorFactory();
|
||||
processor.docTypes = ['test'];
|
||||
const docs = [
|
||||
{ docType: 'test', description: 'abc\n\ncde' },
|
||||
{ docType: 'other', description: 'abc\n\ncde' }
|
||||
];
|
||||
processor.$process(docs);
|
||||
expect(docs).toEqual([
|
||||
{ docType: 'test', shortDescription: 'abc', description: 'cde' },
|
||||
{ docType: 'other', description: 'abc\n\ncde' }
|
||||
]);
|
||||
});
|
||||
});
|
@ -1,10 +1,3 @@
|
||||
module.exports = function(log, createDocMessage) {
|
||||
return {
|
||||
name: 'howToUse',
|
||||
transforms(doc, tag, value) {
|
||||
log.warn(createDocMessage('Deprecated `@howToUse` tag found', doc));
|
||||
log.warn('PLEASE FIX by renaming to `@usageNotes.');
|
||||
return value;
|
||||
}
|
||||
};
|
||||
module.exports = function() {
|
||||
return {name: 'howToUse'};
|
||||
};
|
||||
|
@ -1,8 +0,0 @@
|
||||
module.exports = function(extractTypeTransform, wholeTagTransform) {
|
||||
return {
|
||||
name: 'throws',
|
||||
aliases: ['exception'],
|
||||
multi: true,
|
||||
transforms: [ extractTypeTransform, wholeTagTransform ]
|
||||
};
|
||||
};
|
@ -1,5 +0,0 @@
|
||||
module.exports = function() {
|
||||
return {
|
||||
name: 'usageNotes'
|
||||
};
|
||||
};
|
@ -1,10 +1,3 @@
|
||||
module.exports = function(log, createDocMessage) {
|
||||
return {
|
||||
name: 'whatItDoes',
|
||||
transforms(doc, tag, value) {
|
||||
log.warn(createDocMessage('Deprecated `@whatItDoes` tag found', doc));
|
||||
log.warn('PLEASE FIX by adding the content of this tag as the first paragraph of the `@description` tag.');
|
||||
return value;
|
||||
}
|
||||
};
|
||||
module.exports = function() {
|
||||
return {name: 'whatItDoes'};
|
||||
};
|
||||
|
@ -45,7 +45,7 @@ module.exports = function autoLinkCode(getDocFromAlias) {
|
||||
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_-]+)/)
|
||||
const nodes = textContent(node).split(/([A-Za-z0-9_.-]+)/)
|
||||
.filter(word => word.length)
|
||||
.map((word, index, words) => {
|
||||
// remove docs that fail the custom filter tests
|
||||
|
@ -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', 'function', 'const'];
|
||||
autoLinkCode.docTypes = ['class', 'pipe', 'function', 'const', 'member'];
|
||||
aliasMap = injector.get('aliasMap');
|
||||
processor = injector.get('postProcessHtml');
|
||||
processor.docTypes = ['test-doc'];
|
||||
@ -31,6 +31,13 @@ describe('autoLinkCode post-processor', () => {
|
||||
expect(doc.renderedContent).toEqual('<code><a href="a/b/myclass" class="code-anchor">foo.MyClass</a></code>');
|
||||
});
|
||||
|
||||
it('should match code items within a block of code that contain a dot in their identifier', () => {
|
||||
aliasMap.addDoc({ docType: 'member', id: 'MyEnum.Value', aliases: ['Value', 'MyEnum.Value'], path: 'a/b/myenum' });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<code>someFn(): MyEnum.Value</code>' };
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code>someFn(): <a href="a/b/myenum" class="code-anchor">MyEnum.Value</a></code>');
|
||||
});
|
||||
|
||||
it('should ignore code items that do not match a link to an API doc', () => {
|
||||
aliasMap.addDoc({ docType: 'guide', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<code>MyClass</code>' };
|
||||
|
@ -20,7 +20,7 @@ const hasClass = (node, cls) => {
|
||||
const link = options =>
|
||||
tree => visit(tree, node => {
|
||||
if (is(node, HEADINGS) && has(node, 'id') && !hasClass(node, NO_ANCHOR_CLASS)) {
|
||||
node.children.push({
|
||||
node.children.unshift({
|
||||
type: 'element',
|
||||
tagName: 'a',
|
||||
properties: Object.assign(clone(options.properties), {href: `#${node.properties.id}`}),
|
||||
|
@ -20,9 +20,9 @@ describe('autolink-headings postprocessor', () => {
|
||||
<h3>Heading with encoded chars &</h3>
|
||||
`;
|
||||
const processedContent = `
|
||||
<h1 id="heading-1">Heading 1<a title="Link to this heading" class="header-link" aria-hidden="true" href="#heading-1"><i class="material-icons">link</i></a></h1>
|
||||
<h2 id="heading-with-bold">Heading with <strong>bold</strong><a title="Link to this heading" class="header-link" aria-hidden="true" href="#heading-with-bold"><i class="material-icons">link</i></a></h2>
|
||||
<h3 id="heading-with-encoded-chars-">Heading with encoded chars &<a title="Link to this heading" class="header-link" aria-hidden="true" href="#heading-with-encoded-chars-"><i class="material-icons">link</i></a></h3>
|
||||
<h1 id="heading-1"><a title="Link to this heading" class="header-link" aria-hidden="true" href="#heading-1"><i class="material-icons">link</i></a>Heading 1</h1>
|
||||
<h2 id="heading-with-bold"><a title="Link to this heading" class="header-link" aria-hidden="true" href="#heading-with-bold"><i class="material-icons">link</i></a>Heading with <strong>bold</strong></h2>
|
||||
<h3 id="heading-with-encoded-chars-"><a title="Link to this heading" class="header-link" aria-hidden="true" href="#heading-with-encoded-chars-"><i class="material-icons">link</i></a>Heading with encoded chars &</h3>
|
||||
`;
|
||||
|
||||
const docs = [{docType: 'a', renderedContent: originalContent}];
|
||||
|
@ -12,7 +12,6 @@ describe('authors-package (integration tests)', () => {
|
||||
originalJasmineTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
|
||||
});
|
||||
|
||||
afterAll(() => jasmine.DEFAULT_TIMEOUT_INTERVAL = originalJasmineTimeout);
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -27,6 +27,7 @@ module.exports = function collectExamples(exampleMap, regionParser, log, createD
|
||||
},
|
||||
$process(docs) {
|
||||
const exampleFolders = this.exampleFolders;
|
||||
exampleFolders.forEach(folder => exampleMap[folder] = exampleMap[folder] || {});
|
||||
const regionDocs = [];
|
||||
docs = docs.filter((doc) => {
|
||||
if (doc.docType === 'example-file') {
|
||||
@ -36,7 +37,6 @@ module.exports = function collectExamples(exampleMap, regionParser, log, createD
|
||||
if (doc.fileInfo.relativePath.indexOf(folder) === 0) {
|
||||
const relativePath =
|
||||
doc.fileInfo.relativePath.substr(folder.length).replace(/^\//, '');
|
||||
exampleMap[folder] = exampleMap[folder] || {};
|
||||
exampleMap[folder][relativePath] = doc;
|
||||
|
||||
// We treat files that end in `.annotated` specially
|
||||
|
@ -25,6 +25,12 @@ describe('collectExampleRegions processor', () => {
|
||||
|
||||
describe('$process', () => {
|
||||
|
||||
it('should initialise the `exampleMap` even if there are no examples to collect', () => {
|
||||
processor.$process([]);
|
||||
expect(exampleMap['examples-1']).toEqual(jasmine.any(Object));
|
||||
expect(exampleMap['examples-2']).toEqual(jasmine.any(Object));
|
||||
});
|
||||
|
||||
it('should identify example files that are in the exampleFolders', () => {
|
||||
const docs = [
|
||||
createDoc('A', 'examples-1/x/app.js'), createDoc('B', 'examples-1/y/index.html'),
|
||||
|
@ -8,15 +8,16 @@ module.exports =
|
||||
.factory(require('./services/getAliases'))
|
||||
.factory(require('./services/getDocFromAlias'))
|
||||
.factory(require('./services/getLinkInfo'))
|
||||
.factory(require('./services/moduleScopeLinkDisambiguator'))
|
||||
.factory(require('./services/deprecatedDocsLinkDisambiguator'))
|
||||
.factory(require('./services/disambiguators/disambiguateByDeprecated'))
|
||||
.factory(require('./services/disambiguators/disambiguateByModule'))
|
||||
|
||||
.config(function(inlineTagProcessor, linkInlineTagDef) {
|
||||
inlineTagProcessor.inlineTagDefinitions.push(linkInlineTagDef);
|
||||
})
|
||||
|
||||
.config(function(
|
||||
getLinkInfo, moduleScopeLinkDisambiguator, deprecatedDocsLinkDisambiguator) {
|
||||
getLinkInfo.disambiguators.push(moduleScopeLinkDisambiguator);
|
||||
getLinkInfo.disambiguators.push(deprecatedDocsLinkDisambiguator);
|
||||
.config(function(getDocFromAlias, disambiguateByDeprecated, disambiguateByModule) {
|
||||
getDocFromAlias.disambiguators = [
|
||||
disambiguateByDeprecated,
|
||||
disambiguateByModule
|
||||
];
|
||||
});
|
||||
|
@ -1,12 +0,0 @@
|
||||
var _ = require('lodash');
|
||||
|
||||
module.exports = function deprecatedDocsLinkDisambiguator() {
|
||||
return function(url, title, currentDoc, docs) {
|
||||
if (docs.length != 2) return docs;
|
||||
|
||||
var filteredDocs = _.filter(
|
||||
docs, function(doc) { return !doc.fileInfo.relativePath.match(/\/(\w+)-deprecated\//); });
|
||||
|
||||
return filteredDocs.length > 0 ? filteredDocs : docs;
|
||||
};
|
||||
};
|
@ -0,0 +1,3 @@
|
||||
module.exports = function disambiguateByDeprecated() {
|
||||
return (alias, originatingDoc, docs) => docs.filter(doc => doc.deprecated === undefined);
|
||||
};
|
@ -0,0 +1,17 @@
|
||||
const disambiguateByDeprecated = require('./disambiguateByDeprecated')();
|
||||
const docs = [
|
||||
{ id: 'doc1' },
|
||||
{ id: 'doc2', deprecated: true },
|
||||
{ id: 'doc3', deprecated: '' },
|
||||
{ id: 'doc4' },
|
||||
{ id: 'doc5', deprecated: 'Some text' },
|
||||
];
|
||||
|
||||
describe('disambiguateByDeprecated', () => {
|
||||
it('should filter out docs whose `deprecated` property is defined', () => {
|
||||
expect(disambiguateByDeprecated('alias', {}, docs)).toEqual([
|
||||
{ id: 'doc1' },
|
||||
{ id: 'doc4' },
|
||||
]);
|
||||
});
|
||||
});
|
@ -0,0 +1,12 @@
|
||||
module.exports = function disambiguateByModule() {
|
||||
return (alias, originatingDoc, docs) => {
|
||||
const originatingModule = originatingDoc && originatingDoc.moduleDoc;
|
||||
if (originatingModule) {
|
||||
const filteredDocs = docs.filter(doc => doc.moduleDoc === originatingModule);
|
||||
if (filteredDocs.length > 0) {
|
||||
return filteredDocs;
|
||||
}
|
||||
}
|
||||
return docs;
|
||||
};
|
||||
};
|
@ -0,0 +1,29 @@
|
||||
const disambiguateByModule = require('./disambiguateByModule')();
|
||||
const moduleA = { name: 'a' };
|
||||
const moduleB = { name: 'b' };
|
||||
const docs = [
|
||||
{ id: 'doc1', moduleDoc: moduleA },
|
||||
{ id: 'doc2', moduleDoc: moduleA },
|
||||
{ id: 'doc3', moduleDoc: moduleB },
|
||||
];
|
||||
|
||||
describe('disambiguateByModule', () => {
|
||||
it('should return all docs if the originating doc has no moduleDoc', () => {
|
||||
expect(disambiguateByModule('alias', { }, docs)).toEqual(docs);
|
||||
});
|
||||
|
||||
it('should return all docs if no docs match the originating doc moduleDoc', () => {
|
||||
expect(disambiguateByModule('alias', { moduleDoc: { name: 'c' } }, docs)).toEqual(docs);
|
||||
});
|
||||
|
||||
it('should return only docs that match the moduleDoc of the originating doc', () => {
|
||||
expect(disambiguateByModule('alias', { moduleDoc: moduleA }, docs)).toEqual([
|
||||
{ id: 'doc1', moduleDoc: moduleA },
|
||||
{ id: 'doc2', moduleDoc: moduleA },
|
||||
]);
|
||||
|
||||
expect(disambiguateByModule('alias', { moduleDoc: moduleB }, docs)).toEqual([
|
||||
{ id: 'doc3', moduleDoc: moduleB },
|
||||
]);
|
||||
});
|
||||
});
|
@ -1,31 +1,23 @@
|
||||
var _ = require('lodash');
|
||||
|
||||
/**
|
||||
* @dgService getDocFromAlias
|
||||
* @description Get an array of docs that match this alias, relative to the originating doc.
|
||||
*
|
||||
* @property {Array<(alias: string, originatingDoc: Doc, ambiguousDocs: Doc[]) => Doc[]>} disambiguators
|
||||
* a collection of functions that attempt to resolve ambiguous links. Each disambiguator returns
|
||||
* a new collection of docs with unwanted ambiguous docs removed (see links-package/service/disambiguators
|
||||
* for examples).
|
||||
*/
|
||||
module.exports = function getDocFromAlias(aliasMap) {
|
||||
|
||||
return function getDocFromAlias(alias, originatingDoc) {
|
||||
var docs = aliasMap.getDocs(alias);
|
||||
getDocFromAlias.disambiguators = [];
|
||||
return getDocFromAlias;
|
||||
|
||||
// If there is more than one item with this name then try to filter them by the originatingDoc's
|
||||
// area
|
||||
if (docs.length > 1 && originatingDoc && originatingDoc.area) {
|
||||
docs = _.filter(docs, function(doc) { return doc.area === originatingDoc.area; });
|
||||
function getDocFromAlias(alias, originatingDoc) {
|
||||
return getDocFromAlias.disambiguators.reduce(
|
||||
// Run the disambiguators while there is more than 1 doc found
|
||||
(docs, disambiguater) => docs.length > 1 ? disambiguater(alias, originatingDoc, docs) : docs,
|
||||
// Start with the docs that match the alias
|
||||
aliasMap.getDocs(alias)
|
||||
);
|
||||
}
|
||||
|
||||
// If filtering by area left us with none then let's start again
|
||||
if (docs.length === 0) {
|
||||
docs = aliasMap.getDocs(alias);
|
||||
}
|
||||
|
||||
// If there is more than one item with this name then try to filter them by the originatingDoc's
|
||||
// module
|
||||
if (docs.length > 1 && originatingDoc && originatingDoc.module) {
|
||||
docs = _.filter(docs, function(doc) { return doc.module === originatingDoc.module; });
|
||||
}
|
||||
|
||||
return docs;
|
||||
};
|
||||
};
|
||||
|
@ -3,15 +3,15 @@ var Dgeni = require('dgeni');
|
||||
|
||||
var getDocFromAlias, aliasMap;
|
||||
|
||||
describe('getDocFromAlias', function() {
|
||||
beforeEach(function() {
|
||||
describe('getDocFromAlias', () => {
|
||||
beforeEach(() => {
|
||||
var dgeni = new Dgeni([testPackage('links-package', true)]);
|
||||
var injector = dgeni.configureInjector();
|
||||
aliasMap = injector.get('aliasMap');
|
||||
getDocFromAlias = injector.get('getDocFromAlias');
|
||||
});
|
||||
|
||||
it('should return an array of docs that match the alias', function() {
|
||||
it('should return an array of docs that match the alias', () => {
|
||||
var doc1 = {aliases: ['a', 'b', 'c']};
|
||||
var doc2 = {aliases: ['a', 'b']};
|
||||
var doc3 = {aliases: ['a']};
|
||||
@ -24,25 +24,24 @@ describe('getDocFromAlias', function() {
|
||||
expect(getDocFromAlias('c')).toEqual([doc1]);
|
||||
});
|
||||
|
||||
it('should return docs that match the alias and originating doc\'s area', function() {
|
||||
var doc1 = {aliases: ['a'], area: 'api'};
|
||||
var doc2 = {aliases: ['a'], area: 'api'};
|
||||
var doc3 = {aliases: ['a'], area: 'other'};
|
||||
it('should filter ambiguous docs by calling each disambiguator', () => {
|
||||
getDocFromAlias.disambiguators = [
|
||||
(alias, originatingDoc, docs) => docs.filter(doc => doc.name.indexOf('X') !== -1), // only if X appears in name
|
||||
(alias, originatingDoc, docs) => docs.filter(doc => doc.name.indexOf('Y') !== -1) // only if Y appears in name
|
||||
];
|
||||
|
||||
var doc1 = {name: 'X', aliases: ['a', 'b', 'c']};
|
||||
var doc2 = {name: 'Y', aliases: ['a', 'b']};
|
||||
var doc3 = {name: 'XY', aliases: ['a', 'c']};
|
||||
aliasMap.addDoc(doc1);
|
||||
aliasMap.addDoc(doc2);
|
||||
aliasMap.addDoc(doc3);
|
||||
|
||||
expect(getDocFromAlias('a', {area: 'api'})).toEqual([doc1, doc2]);
|
||||
});
|
||||
|
||||
it('should return docs that match the alias and originating doc\'s area and module', function() {
|
||||
var doc1 = {aliases: ['a'], area: 'api', module: 'ng'};
|
||||
var doc2 = {aliases: ['a'], area: 'api', module: 'ngMock'};
|
||||
var doc3 = {aliases: ['a'], area: 'other', module: 'ng'};
|
||||
aliasMap.addDoc(doc1);
|
||||
aliasMap.addDoc(doc2);
|
||||
aliasMap.addDoc(doc3);
|
||||
|
||||
expect(getDocFromAlias('a', {area: 'api', module: 'ng'})).toEqual([doc1]);
|
||||
// doc1 and doc2 get removed as they don't both have X and Y in name
|
||||
expect(getDocFromAlias('a')).toEqual([doc3]);
|
||||
// doc2 gets removed as it has no X; then we have only one doc left so second disambiguator never runs
|
||||
expect(getDocFromAlias('b')).toEqual([doc1]);
|
||||
// doc1 gets removed as it has no Y; then we have only one doc left (which would anyway pass 2nd disambiguator)
|
||||
expect(getDocFromAlias('c')).toEqual([doc3]);
|
||||
});
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user