Compare commits
415 Commits
2.0.0-beta
...
2.0.0-beta
Author | SHA1 | Date | |
---|---|---|---|
06ad112998 | |||
cfa1d17afe | |||
3ca6df87b8 | |||
e310bee9e2 | |||
4902244cce | |||
8db97b0b7a | |||
9be04f8d38 | |||
74e2bd7e3e | |||
52d3980d02 | |||
4e9809bcb2 | |||
bd8a4215dd | |||
d23b973e7a | |||
0dbf959548 | |||
20812f446f | |||
27a4d0ce11 | |||
9dec4c7485 | |||
90c87fa6ad | |||
291928feb1 | |||
c9c52fb353 | |||
0bcfcde63d | |||
1c20a62611 | |||
8430927e6b | |||
d2ca7d81c8 | |||
756121acc1 | |||
d7e1175df0 | |||
66cd84e0d5 | |||
506f4ce1e5 | |||
a0387d2835 | |||
9bdd5951d9 | |||
111afcdff1 | |||
85f3dc2fb5 | |||
430f367c2f | |||
d272f96e23 | |||
73a84a7098 | |||
17c8ec8a5d | |||
a1880c3576 | |||
91999e016e | |||
aa966f5de2 | |||
3e593b8221 | |||
440aca86a3 | |||
09f4d6f52d | |||
3f57fa6e0e | |||
ae876d1317 | |||
6de68e2f1f | |||
49527ab495 | |||
0898bca939 | |||
d940387beb | |||
27c45b05cf | |||
90f09d551f | |||
3739588e97 | |||
0730b753f2 | |||
cad693de0f | |||
bf911fc992 | |||
fb6d791ce9 | |||
0f8efce799 | |||
69c1405196 | |||
980491b08f | |||
72e24663ad | |||
363ed5140e | |||
b0f585ab08 | |||
8b67b07580 | |||
5c330ea492 | |||
06eaaf0ac5 | |||
9820271243 | |||
b6507e37ef | |||
c194f6695d | |||
967ae3e1b8 | |||
a5e6eaaebc | |||
d4e9b55fb6 | |||
048bd280dd | |||
8326ab3240 | |||
a7fe983be2 | |||
e1f8e54e34 | |||
2b165944ea | |||
ea11b3f1f8 | |||
3bd87147ab | |||
2f581ffc88 | |||
d61aaac400 | |||
310620fd12 | |||
f9fb72fb0e | |||
095db673c5 | |||
70d18b5b53 | |||
f1796d67f4 | |||
cb38d72ff4 | |||
b72bab49aa | |||
201475e8d8 | |||
c25b9fcf97 | |||
8755a8e188 | |||
127fbfd5a6 | |||
f33dda79e9 | |||
293fa5505b | |||
df1f78e302 | |||
43bb31c6c6 | |||
169869a195 | |||
b691da26af | |||
8e3e45097a | |||
aa43d2f87b | |||
128acbb6eb | |||
5824866a83 | |||
0d58b137a7 | |||
b5c769e1e4 | |||
7f22bd62ab | |||
83f0e7c975 | |||
adef68b4d6 | |||
14f0e9ada8 | |||
ef9e40e82b | |||
41e38e4330 | |||
2c7c3e3c69 | |||
756f5d884f | |||
45fd6f0a41 | |||
75ae4a9159 | |||
37d18d0112 | |||
773fe8f8c5 | |||
4da2b19ea0 | |||
9f3547e35d | |||
5a79358727 | |||
85bfbc13c1 | |||
1a01af9e68 | |||
dd95e901df | |||
9782d8c32e | |||
80764c6f71 | |||
d9e78e4fa8 | |||
10fedd0dfc | |||
315e73c47c | |||
912717ff31 | |||
b857fd1eeb | |||
6dce4f49c2 | |||
15e16148f4 | |||
ae49085481 | |||
11e8aa26f6 | |||
81beb1c788 | |||
6402d61f69 | |||
5a59e44765 | |||
7455b907d1 | |||
579b890446 | |||
19a08f3a43 | |||
a3d7629134 | |||
bc9644e86e | |||
a10c02cb41 | |||
9936e347ff | |||
7d44b8230e | |||
75343eb340 | |||
2548ce86db | |||
5586c29492 | |||
1174473e9c | |||
1d49b3e36b | |||
2830df4190 | |||
143cf89b5f | |||
69c1694900 | |||
01fe7f5fac | |||
9aedef208f | |||
39b6e0efba | |||
f60fa14767 | |||
d900f5c075 | |||
391a9edabb | |||
28a78117eb | |||
eeb594c010 | |||
0bb10d6bb6 | |||
59629a0801 | |||
b5e6319fa9 | |||
c9a3df970b | |||
f72f137261 | |||
ee3c580e88 | |||
05c185a7b1 | |||
b47f80ec76 | |||
ebd438ff5e | |||
331b9c1317 | |||
4a93f58b8b | |||
ebe531bf92 | |||
1779caf5f8 | |||
6ef2121e6a | |||
38cb526f60 | |||
f6a8d04c32 | |||
4b3b5d7c53 | |||
abff302e52 | |||
e1f6679c75 | |||
aaafdf03ce | |||
ee298baa1b | |||
d1abada5b7 | |||
ab36ea097b | |||
8bb66a5eb3 | |||
cfc1e56dd8 | |||
a1c3be21ec | |||
edad8e3f56 | |||
d4a4d81173 | |||
e7470d557d | |||
b634a25ae0 | |||
c1a0af514f | |||
c6afea61f1 | |||
ce10fe92b2 | |||
b81b1fb81c | |||
280b86ec55 | |||
2f5a2ba671 | |||
c45ec6f1be | |||
530470e0ce | |||
ce72ccf9e8 | |||
46d9c87ddc | |||
d736c31fea | |||
a7e9bc97f6 | |||
265703b950 | |||
ae275fa4e4 | |||
3478d5d450 | |||
e72dc16dbe | |||
40a043275d | |||
f161b5cc28 | |||
117d57e121 | |||
3dcce706fd | |||
efb89b83e1 | |||
3d96c2337f | |||
19cfb4eb12 | |||
3d715a2f7b | |||
c7261c295c | |||
1a26f8edd6 | |||
fc887774da | |||
7cbf88a691 | |||
1cb1c139cf | |||
1fd924f7d5 | |||
eb688f2c8e | |||
61cf499b0b | |||
f1f5b45361 | |||
50548fb565 | |||
8f47aa3530 | |||
df7885c9f5 | |||
0f10624b08 | |||
6f1ef33e32 | |||
231773ea76 | |||
e725542703 | |||
2337469753 | |||
55122cd57a | |||
7e0f02f96e | |||
e7ad03cba6 | |||
74be3d3fde | |||
a15ca23469 | |||
de77700da0 | |||
e73fee7156 | |||
72ab35bceb | |||
0f22dce036 | |||
c6036435f0 | |||
d86be245b8 | |||
a26053d3ff | |||
24d5b665e1 | |||
aa98fad338 | |||
9cb6dbbbab | |||
e21718faa9 | |||
b0f7d59e64 | |||
b86829f492 | |||
22929a1671 | |||
86c40f8474 | |||
16b521794c | |||
2a70f4e4c7 | |||
2f31c4c1c5 | |||
1435763383 | |||
05238df89b | |||
772d60d9fe | |||
24086bf0bb | |||
9b0e10e9a7 | |||
995a9e0cf8 | |||
b55f1764b5 | |||
5e9daed2e8 | |||
aa8c5aa2e2 | |||
f2c7946cca | |||
da1fcfd820 | |||
dbeff6f548 | |||
26e60d658a | |||
c2ceb7fba4 | |||
4bfe49cd42 | |||
cee2318110 | |||
cfef76f683 | |||
f56df65d48 | |||
3a40cd79f0 | |||
6acc99729c | |||
99e6500a2d | |||
5c782d6ba8 | |||
4e43d6f769 | |||
3529ee9973 | |||
29aa6a6c1c | |||
7918f3c1fc | |||
2f4e176054 | |||
d4565fdaf3 | |||
2a302aa73a | |||
31b819e9c2 | |||
27daeaff5e | |||
3e9b532409 | |||
c5aa6d17ef | |||
e480b0798e | |||
8a645d5e44 | |||
321193889f | |||
566d3ede04 | |||
8c36aa866a | |||
ed2dbf2db7 | |||
36a0e04604 | |||
8867afdaab | |||
a199772508 | |||
b008f542fa | |||
a78dcfa5f3 | |||
e1bf3d33f8 | |||
ae7d2ab515 | |||
c6adbf602c | |||
1f7a41c963 | |||
f4f614f3a9 | |||
94139c351f | |||
fc5b128b43 | |||
68a799af2e | |||
16d9c60a0e | |||
c0b5e7a672 | |||
6932b29acb | |||
c2a38c05aa | |||
8bea667a0b | |||
800c8f196f | |||
42231f5719 | |||
db87baeb98 | |||
c4c43f5a77 | |||
0ae77753f3 | |||
5f0baaac73 | |||
b5b6ece65a | |||
4282297c24 | |||
9c96b8affc | |||
132829e5e2 | |||
4a414420e9 | |||
fb6335ab60 | |||
89bd008445 | |||
caafb41eb5 | |||
31b81a7439 | |||
f7b1973358 | |||
32f01da49a | |||
59684c97b0 | |||
a32a0a3a97 | |||
96f5b0929d | |||
8e6cf7fca8 | |||
fdbe8741c9 | |||
775fb2c340 | |||
b60f594798 | |||
cc49790bdb | |||
a4bc19c530 | |||
f7985dbdb7 | |||
0bdcb5c1e0 | |||
a0d25db4a5 | |||
625474c4e2 | |||
1cd2a6328a | |||
d6bafe4fe3 | |||
6a2ef15355 | |||
a8ca560503 | |||
ad361808ec | |||
c47639f2b1 | |||
ba90a85f7b | |||
d3b569557f | |||
c9090ffa31 | |||
341bf39d23 | |||
3778ac26aa | |||
6cfc6f5bb2 | |||
47a3b4d56b | |||
c72ed991ad | |||
78bfdf78ea | |||
a24ee6add4 | |||
df3074fdfe | |||
f7424d5aeb | |||
a593ffa6f3 | |||
761c6d0df7 | |||
3e65d1458e | |||
a4b5cb8376 | |||
c785a1e474 | |||
3adc472f06 | |||
e7081b8b7c | |||
9b3a548f6f | |||
90b3502bb8 | |||
e19b31db29 | |||
bd015f14e8 | |||
ca7ba12fc6 | |||
ae05ec69c4 | |||
92dc3b91d8 | |||
8bd697b316 | |||
eda4c3eb4c | |||
4d0c2ed1f6 | |||
eda6a5d52a | |||
c1c54ed0f2 | |||
6b73d09ba1 | |||
ac85cbb28a | |||
b0cebdba6b | |||
933a9112da | |||
8c37b7e8f2 | |||
c8e909f8c9 | |||
69ae3634c7 | |||
95248f46a1 | |||
b3c7df1783 | |||
c56679e8e1 | |||
041c599511 | |||
6343f71be5 | |||
89f32f808f | |||
7ae23adaff | |||
a08f50badd | |||
0b6e75a85e | |||
4291758079 | |||
b44d36cf95 | |||
a038bb9ae3 | |||
9d28147acb | |||
d116861c8e | |||
9a70f1a1d9 | |||
8516473340 | |||
cab69f689f | |||
822e83ebb0 | |||
b2bc50dbd1 | |||
e748adda2e | |||
630d93150a | |||
76f1f9f1e3 | |||
c47d85b038 | |||
197cf09689 | |||
e67ebb7f70 | |||
3524946581 | |||
9276dad42c | |||
2a2f9a9a19 | |||
909e70bd61 | |||
8ac9719832 | |||
3eff7c6f59 | |||
17fbbfba91 | |||
b232dded77 |
16
.github/ISSUE_TEMPLATE.md
vendored
Normal file
16
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
**IMPORTANT**: This repository's issues are reserved for feature requests and bug reports. Do not submit support requests here, see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question.
|
||||
|
||||
|
||||
**Steps to reproduce and a minimal demo of the problem**
|
||||
|
||||
_Use https://plnkr.co or similar -- try this template as a starting point: http://plnkr.co/edit/tpl:AvJOMERrnz94ekVua0u5_
|
||||
|
||||
_What steps should we try in your demo to see the problem?_
|
||||
|
||||
**Current behavior**
|
||||
|
||||
|
||||
**Expected/desired behavior**
|
||||
|
||||
|
||||
**Other information**
|
24
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
24
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
* **Please check if the PR fulfills these requirements**
|
||||
- [ ] The commit message follows our guidelines: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit-message-format
|
||||
- [ ] Tests for the changes have been added (for bug fixes / features)
|
||||
- [ ] Docs have been added / updated (for bug fixes / features)
|
||||
|
||||
|
||||
* **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...)
|
||||
|
||||
|
||||
|
||||
* **What is the current behavior?** (You can also link to an open issue here)
|
||||
|
||||
|
||||
|
||||
* **What is the new behavior (if this is a feature change)?**
|
||||
|
||||
|
||||
|
||||
* **Does this PR introduce a breaking change?** (What changes might users need to make in their application due to this PR?)
|
||||
|
||||
|
||||
|
||||
* **Other information**:
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -22,6 +22,7 @@ tmp
|
||||
*.js.map
|
||||
|
||||
# Or type definitions we mirror from github
|
||||
# (NB: these lines are removed in publish-build-artifacts.sh)
|
||||
**/typings/**/*.d.ts
|
||||
**/typings/tsd.cached.json
|
||||
|
||||
|
183
.travis.yml
183
.travis.yml
@ -1,132 +1,137 @@
|
||||
language: node_js
|
||||
sudo: false
|
||||
node_js:
|
||||
- '4.2.1'
|
||||
- '5.4.1'
|
||||
|
||||
branches:
|
||||
except:
|
||||
- g3sync
|
||||
- g3_v2_0
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
- $HOME/.pub-cache
|
||||
- $HOME/.chrome/chromium
|
||||
|
||||
before_cache:
|
||||
# Undo the pollution of the typescript_next build before the cache is primed for future use
|
||||
- if [[ "$MODE" == "typescript_next" ]]; then npm install typescript; fi
|
||||
|
||||
env:
|
||||
global:
|
||||
- KARMA_BROWSERS=DartiumWithWebPlatform
|
||||
- E2E_BROWSERS=Dartium
|
||||
- LOGS_DIR=/tmp/angular-build/logs
|
||||
- SAUCE_USERNAME=angular-ci
|
||||
- SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987
|
||||
- BROWSER_STACK_USERNAME=angularteam1
|
||||
- BROWSER_STACK_ACCESS_KEY=BWCd4SynLzdDcv8xtzsB
|
||||
- ARCH=linux-x64
|
||||
- DART_DEV_VERSION=latest
|
||||
- DART_STABLE_VERSION=latest
|
||||
# Token for tsd to increase github rate limit
|
||||
# See https://github.com/DefinitelyTyped/tsd#tsdrc
|
||||
# This does not use http://docs.travis-ci.com/user/environment-variables/#Secure-Variables
|
||||
# because those are not visible for pull requests, and those should also be reliable.
|
||||
# This SSO token belongs to github account angular-github-ratelimit-token which has no access
|
||||
# (password is in Valentine)
|
||||
- TSDRC='{"token":"ef474500309daea53d5991b3079159a29520a40b"}'
|
||||
# GITHUB_TOKEN_ANGULAR
|
||||
- secure: "fq/U7VDMWO8O8SnAQkdbkoSe2X92PVqg4d044HmRYVmcf6YbO48+xeGJ8yOk0pCBwl3ISO4Q2ot0x546kxfiYBuHkZetlngZxZCtQiFT9kyId8ZKcYdXaIW9OVdw3Gh3tQyUwDucfkVhqcs52D6NZjyE2aWZ4/d1V4kWRO/LMgo="
|
||||
# Use newer verison of GCC to that is required to compile native npm modules for Node v4+ on Ubuntu Precise
|
||||
# more info: https://docs.travis-ci.com/user/languages/javascript-with-nodejs#Node.js-v4-(or-io.js-v3)-compiler-requirements
|
||||
- CXX=g++-4.8
|
||||
- KARMA_DART_BROWSERS=DartiumWithWebPlatform
|
||||
# No sandbox mode is needed for Chromium in Travis, it crashes otherwise: https://sites.google.com/a/chromium.org/chromedriver/help/chrome-doesn-t-start
|
||||
- KARMA_JS_BROWSERS=ChromeNoSandbox
|
||||
- E2E_BROWSERS=ChromeOnTravis
|
||||
- LOGS_DIR=/tmp/angular-build/logs
|
||||
- SAUCE_USERNAME=angular-ci
|
||||
- SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987
|
||||
- BROWSER_STACK_USERNAME=angularteam1
|
||||
- BROWSER_STACK_ACCESS_KEY=BWCd4SynLzdDcv8xtzsB
|
||||
- ARCH=linux-x64
|
||||
- DART_DEV_VERSION=latest
|
||||
- DART_STABLE_VERSION=latest
|
||||
- DART_CHANNEL=stable
|
||||
- DART_VERSION=$DART_STABLE_VERSION
|
||||
# Token for tsd to increase github rate limit
|
||||
# See https://github.com/DefinitelyTyped/tsd#tsdrc
|
||||
# This does not use http://docs.travis-ci.com/user/environment-variables/#Secure-Variables
|
||||
# because those are not visible for pull requests, and those should also be reliable.
|
||||
# This SSO token belongs to github account angular-github-ratelimit-token which has no access
|
||||
# (password is in Valentine)
|
||||
- TSDRC='{"token":"ef474500309daea53d5991b3079159a29520a40b"}'
|
||||
# GITHUB_TOKEN_ANGULAR
|
||||
- secure: "fq/U7VDMWO8O8SnAQkdbkoSe2X92PVqg4d044HmRYVmcf6YbO48+xeGJ8yOk0pCBwl3ISO4Q2ot0x546kxfiYBuHkZetlngZxZCtQiFT9kyId8ZKcYdXaIW9OVdw3Gh3tQyUwDucfkVhqcs52D6NZjyE2aWZ4/d1V4kWRO/LMgo="
|
||||
matrix:
|
||||
# Order: a slower build first, so that we don't occupy an idle travis worker waiting for others to complete.
|
||||
- MODE=dart DART_CHANNEL=stable DART_VERSION=$DART_STABLE_VERSION
|
||||
- MODE=dart DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
|
||||
- MODE=saucelabs DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
|
||||
- MODE=browserstack DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
|
||||
- MODE=dart_experimental DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
|
||||
- MODE=js DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
|
||||
- MODE=router DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
|
||||
- MODE=build_only DART_CHANNEL=stable DART_VERSION=$DART_STABLE_VERSION
|
||||
- MODE=lint DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
|
||||
- MODE=payload DART_CHANNEL=stable DART_VERSION=$DART_STABLE_VERSION
|
||||
- MODE=dart
|
||||
- MODE=dart DART_CHANNEL=dev
|
||||
- MODE=saucelabs_required
|
||||
- MODE=browserstack_required
|
||||
- MODE=saucelabs_optional
|
||||
- MODE=browserstack_optional
|
||||
- MODE=dart_ddc
|
||||
- MODE=js
|
||||
- MODE=router
|
||||
- MODE=build_only
|
||||
- MODE=typescript_next
|
||||
- MODE=lint
|
||||
- MODE=payload
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- env: "MODE=saucelabs DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION"
|
||||
- env: "MODE=browserstack DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION"
|
||||
- env: "MODE=dart_experimental DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION"
|
||||
# TODO(alxhub): remove when dartdoc #1039 is in dev channel
|
||||
- env: "MODE=dart DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION"
|
||||
- env: "MODE=saucelabs_optional"
|
||||
- env: "MODE=browserstack_optional"
|
||||
# Tracked in https://github.com/angular/angular/issues/7050
|
||||
- env: "MODE=typescript_next"
|
||||
|
||||
addons:
|
||||
firefox: "38.0"
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-4.8
|
||||
|
||||
before_install:
|
||||
- node tools/analytics/build-analytics start ci job
|
||||
- node tools/analytics/build-analytics start ci before_install
|
||||
- echo ${TSDRC} > .tsdrc
|
||||
- export DISPLAY=:99.0
|
||||
- export GIT_SHA=$(git rev-parse HEAD)
|
||||
- ./scripts/ci/init_android.sh
|
||||
- ./scripts/ci/install_dart.sh ${DART_CHANNEL} ${DART_VERSION} ${ARCH}
|
||||
- sh -e /etc/init.d/xvfb start
|
||||
- if [[ -e SKIP_TRAVIS_TESTS ]]; then { cat SKIP_TRAVIS_TESTS ; exit 0; } fi
|
||||
- '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && [ "${TRAVIS_BRANCH}" = "master" ] && SAUCE_USERNAME="angular2-ci" && SAUCE_ACCESS_KEY="693ebc16208a-0b5b-1614-8d66-a2662f4e" || true'
|
||||
- node tools/analytics/build-analytics success ci before_install
|
||||
- node tools/analytics/build-analytics start ci job
|
||||
- node tools/analytics/build-analytics start ci before_install
|
||||
- echo ${TSDRC} > .tsdrc
|
||||
- export CHROME_BIN=$HOME/.chrome/chromium/chrome-linux/chrome
|
||||
- export DISPLAY=:99.0
|
||||
- export GIT_SHA=$(git rev-parse HEAD)
|
||||
- ./scripts/ci/init_android.sh
|
||||
- sh -e /etc/init.d/xvfb start
|
||||
# Use a separate SauseLabs account for upstream/master builds in order for Sauce to create a badge representing the status of just upstream/master
|
||||
- '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && [ "${TRAVIS_BRANCH}" = "master" ] && SAUCE_USERNAME="angular2-ci" && SAUCE_ACCESS_KEY="693ebc16208a-0b5b-1614-8d66-a2662f4e" || true'
|
||||
- node tools/analytics/build-analytics success ci before_install
|
||||
|
||||
install:
|
||||
- node tools/analytics/build-analytics start ci install
|
||||
# Check the size of caches
|
||||
# Install version of npm that we are locked against
|
||||
- npm install -g npm@3.5.3
|
||||
# Install version of Chromium that we are locked against
|
||||
- ./scripts/ci/install_chromium.sh
|
||||
# Install version of Dart based on the matrix build variables
|
||||
- ./scripts/ci/install_dart.sh ${DART_CHANNEL} ${DART_VERSION} ${ARCH}
|
||||
# Print the size of caches to ease debugging
|
||||
- du -sh ./node_modules || true
|
||||
# Install npm dependecies
|
||||
- npm install
|
||||
# check-node-modules will exit(1) if we don't need to install
|
||||
# we need to manually kick off the postinstall script if check-node-modules exit(0)s
|
||||
- node tools/npm/check-node-modules --purge && npm install || npm run postinstall
|
||||
- node tools/analytics/build-analytics success ci install
|
||||
|
||||
before_script:
|
||||
- node tools/analytics/build-analytics start ci before_script
|
||||
- mkdir -p $LOGS_DIR
|
||||
- ./scripts/ci/presubmit-queue-setup.sh
|
||||
- node tools/analytics/build-analytics success ci before_script
|
||||
- node tools/analytics/build-analytics start ci before_script
|
||||
- mkdir -p $LOGS_DIR
|
||||
- ./scripts/ci/presubmit-queue-setup.sh
|
||||
- node tools/analytics/build-analytics success ci before_script
|
||||
|
||||
script:
|
||||
- node tools/analytics/build-analytics start ci script
|
||||
- ./scripts/ci/build_and_test.sh ${MODE}
|
||||
- node tools/analytics/build-analytics success ci script
|
||||
- node tools/analytics/build-analytics start ci script
|
||||
- ./scripts/ci/build_and_test.sh ${MODE}
|
||||
- node tools/analytics/build-analytics success ci script
|
||||
|
||||
after_script:
|
||||
- node tools/analytics/build-analytics start ci after_script
|
||||
- ./scripts/ci/print-logs.sh
|
||||
- ./scripts/ci/after-script.sh
|
||||
- ./scripts/publish/publish-build-artifacts.sh
|
||||
- node tools/analytics/build-analytics success ci after_script
|
||||
- if [[ $TRAVIS_TEST_RESULT -eq 0 ]]; then node tools/analytics/build-analytics success ci job; else node tools/analytics/build-analytics error ci job; fi
|
||||
- node tools/analytics/build-analytics start ci after_script
|
||||
- ./scripts/ci/print-logs.sh
|
||||
- ./scripts/ci/after-script.sh
|
||||
- ./scripts/publish/publish-build-artifacts.sh
|
||||
- node tools/analytics/build-analytics success ci after_script
|
||||
- tools/analytics/build-analytics $TRAVIS_TEST_RESULT ci job
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/1ef62e23078036f9cee4
|
||||
# trigger Buildtime Trend Service to parse Travis CI log
|
||||
- https://buildtimetrend.herokuapp.com/travis
|
||||
- https://webhooks.gitter.im/e/1ef62e23078036f9cee4
|
||||
# trigger Buildtime Trend Service to parse Travis CI log
|
||||
- https://buildtimetrend.herokuapp.com/travis
|
||||
- http://104.197.9.155:8484/hubot/travis/activity
|
||||
on_success: always # options: [always|never|change] default: always
|
||||
on_failure: always # options: [always|never|change] default: always
|
||||
on_start: false # default: false
|
||||
on_start: never # default: never
|
||||
slack:
|
||||
secure: EP4MzZ8JMyNQJ4S3cd5LEPWSMjC7ZRdzt3veelDiOeorJ6GwZfCDHncR+4BahDzQAuqyE/yNpZqaLbwRWloDi15qIUsm09vgl/1IyNky1Sqc6lEknhzIXpWSalo4/T9ZP8w870EoDvM/UO+LCV99R3wS8Nm9o99eLoWVb2HIUu0=
|
||||
|
||||
deploy:
|
||||
- provider: gcs
|
||||
# This is for project angular-github-babysitter
|
||||
access_key_id: GOOGIOQTDBEOPBUAWFZQ
|
||||
secret_access_key:
|
||||
secure: "MEDggllZ5fw4wI9CEUi8WR6jKsKXqdRF/DLxSNC2JpzM5RlVeBm0uqjntYT1Cf1dASvQ2/+vZCUikL/3A48NcoEYRHXGmxu8D6t/SvleQD8Xv434xFOdsa2QqP/HiCtqCLOI5jJz1JVoB5nNyKKZ33ogTUL1LV1TfcrAioyizW8="
|
||||
# this bucket has a lifecycle to delete after 90 days:
|
||||
# $ echo '{"rule": [{"action": {"type": "Delete"}, "condition": {"age": 90}}]}' > lifecycle.json
|
||||
# $ gsutil lifecycle set lifecycle.json gs://angular2-snapshots
|
||||
bucket: angular2-snapshots
|
||||
# don't delete generated files
|
||||
skip_cleanup: true
|
||||
# serve to public at https://storage.googleapis.com/angular2-snapshots/SHA/dist.tgz
|
||||
acl: public-read
|
||||
# upload the .tgz archive created in scripts/ci/build_and_test.sh
|
||||
local-dir: deploy
|
||||
# create a "subdirectory" for each commit
|
||||
upload-dir: $TRAVIS_COMMIT
|
||||
on:
|
||||
repo: angular/angular
|
||||
condition: "$MODE = build_only"
|
||||
|
530
CHANGELOG.md
530
CHANGELOG.md
@ -1,5 +1,520 @@
|
||||
<a name="2.0.0-beta.14"></a>
|
||||
# 2.0.0-beta.14 (2016-04-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **forms:** support both value and ng-value ([8db97b0](https://github.com/angular/angular/commit/8db97b0))
|
||||
* **router:** allow forward slashes in query parameters ([4902244](https://github.com/angular/angular/commit/4902244)), closes [#7824](https://github.com/angular/angular/issues/7824)
|
||||
* **select:** support objects as select values ([74e2bd7](https://github.com/angular/angular/commit/74e2bd7)), closes [#4843](https://github.com/angular/angular/issues/4843) [#7842](https://github.com/angular/angular/issues/7842)
|
||||
* **select:** update name from ng-value to ngValue ([3ca6df8](https://github.com/angular/angular/commit/3ca6df8)), closes [#7939](https://github.com/angular/angular/issues/7939)
|
||||
* **upgrade:** leak when angular1 destroys element ([9be04f8](https://github.com/angular/angular/commit/9be04f8)), closes [#6401](https://github.com/angular/angular/issues/6401) [#7935](https://github.com/angular/angular/issues/7935)
|
||||
|
||||
### Features
|
||||
|
||||
* **dart/transform:** Avoid `print` in transformer code. ([e310bee](https://github.com/angular/angular/commit/e310bee)), closes [#7855](https://github.com/angular/angular/issues/7855)
|
||||
* **static-reflector:** Added StaticReflector ([0dbf959](https://github.com/angular/angular/commit/0dbf959))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="2.0.0-beta.13"></a>
|
||||
# 2.0.0-beta.13 (2016-03-31)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **build:** MetadataCollector correctly collects property metadata ([111afcd](https://github.com/angular/angular/commit/111afcd)), closes [#7772](https://github.com/angular/angular/issues/7772) [#7773](https://github.com/angular/angular/issues/7773)
|
||||
* **codegen:** stringify using an opaque ID when toString contains parens. ([90c87fa](https://github.com/angular/angular/commit/90c87fa)), closes [#7825](https://github.com/angular/angular/issues/7825)
|
||||
* **ngFor:** give more instructive error when binding to non-iterable ([49527ab](https://github.com/angular/angular/commit/49527ab))
|
||||
* **Router:** handling of special chars in dynamic segments ([0bcfcde](https://github.com/angular/angular/commit/0bcfcde)), closes [#7804](https://github.com/angular/angular/issues/7804)
|
||||
* **upgrade:** make ngUpgrade work with testability API ([430f367](https://github.com/angular/angular/commit/430f367)), closes [#7603](https://github.com/angular/angular/issues/7603)
|
||||
|
||||
### Features
|
||||
|
||||
* **build:** Persisting decorator metadata ([ae876d1](https://github.com/angular/angular/commit/ae876d1))
|
||||
* **compiler:** assert that Component.style is an array ([6de68e2](https://github.com/angular/angular/commit/6de68e2)), closes [#7559](https://github.com/angular/angular/issues/7559)
|
||||
* **compiler:** Resolvers now use DI to create reflector ([506f4ce](https://github.com/angular/angular/commit/506f4ce)), closes [#7762](https://github.com/angular/angular/issues/7762)
|
||||
* **Compiler:** Allow overriding the projection selector ([aa966f5](https://github.com/angular/angular/commit/aa966f5)), closes [#6303](https://github.com/angular/angular/issues/6303) [#7742](https://github.com/angular/angular/issues/7742)
|
||||
* **dart:** Add a dev-mode check for undeclared lifecycle interfaces ([1c20a62](https://github.com/angular/angular/commit/1c20a62)), closes [#6849](https://github.com/angular/angular/issues/6849)
|
||||
* **facade:** add ListWrapper.flatten ([a1880c3](https://github.com/angular/angular/commit/a1880c3))
|
||||
* **facade:** add RegExpWrapper.replaceAll to replace all matches using the provided function ([91999e0](https://github.com/angular/angular/commit/91999e0))
|
||||
* **html_parser:** change HtmlElementAst to store both the start and the end positions ([17c8ec8](https://github.com/angular/angular/commit/17c8ec8))
|
||||
* **i18n:** implement an i18n-aware html parser ([d272f96](https://github.com/angular/angular/commit/d272f96)), closes [#7738](https://github.com/angular/angular/issues/7738)
|
||||
* **i18n:** implement xmb deserialization ([d7e1175](https://github.com/angular/angular/commit/d7e1175))
|
||||
* **i18n:** reexport I18nHtmlParser through the i18n barrel ([d2ca7d8](https://github.com/angular/angular/commit/d2ca7d8))
|
||||
* **i18n:** update I18nHtmlParser to accept parsed messages ([756121a](https://github.com/angular/angular/commit/756121a))
|
||||
* **i18n:** update transformers to read a xmb file when provided and use I18nHtmlParser in t ([8430927](https://github.com/angular/angular/commit/8430927)), closes [#7790](https://github.com/angular/angular/issues/7790)
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* For static content projection, elements with *-directives are now matched against the element itself vs the template before.
|
||||
|
||||
`<p *ngIf="condition" foo></p>`
|
||||
|
||||
Before:
|
||||
```html
|
||||
// Use the implicit template for projection
|
||||
<ng-content select="template"></ng-content>
|
||||
```
|
||||
|
||||
After:
|
||||
```html
|
||||
// Use the actual element for projection
|
||||
<ng-content select="p[foo]"></ng-content>
|
||||
```
|
||||
|
||||
<a name="2.0.0-beta.12"></a>
|
||||
# 2.0.0-beta.12 (2016-03-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular_1_router:** ng-link is generating wrong hrefs ([69c1405](https://github.com/angular/angular/commit/69c1405)), closes [#7423](https://github.com/angular/angular/issues/7423)
|
||||
* **angular1_router:** support link generation with custom hashPrefixes ([0f8efce](https://github.com/angular/angular/commit/0f8efce))
|
||||
* **package.json:** remove es6-promise from the peerDependency list ([8b67b07](https://github.com/angular/angular/commit/8b67b07))
|
||||
|
||||
### Features
|
||||
|
||||
* **dart/transform:** Use angular2/platform/browser as bootstrap lib ([b6507e3](https://github.com/angular/angular/commit/b6507e3)), closes [#7647](https://github.com/angular/angular/issues/7647)
|
||||
|
||||
|
||||
<a name="2.0.0-beta.11"></a>
|
||||
# 2.0.0-beta.11 (2016-03-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* make sure that Zone does not show up in angular2.d.ts ([d4e9b55](https://github.com/angular/angular/commit/d4e9b55fb69d87f948d02905d34fc78221adb11a))
|
||||
* **common:** remove @internal annotation on SwitchView ([967ae3e](https://github.com/angular/angular/commit/967ae3e)), closes [#7657](https://github.com/angular/angular/issues/7657)
|
||||
* **router:** RouterOutlet loads component twice in a race condition ([2f581ff](https://github.com/angular/angular/commit/2f581ff)), closes [#7497](https://github.com/angular/angular/issues/7497) [#7545](https://github.com/angular/angular/issues/7545)
|
||||
|
||||
### Features
|
||||
|
||||
* **i18n:** add a simple dart script extracting all i18n messages from a package ([8326ab3](https://github.com/angular/angular/commit/8326ab3)), closes [#7620](https://github.com/angular/angular/issues/7620)
|
||||
* **i18n:** create i18n barrel ([a7fe983](https://github.com/angular/angular/commit/a7fe983))
|
||||
* **i18n:** implement xmb serializer ([e1f8e54](https://github.com/angular/angular/commit/e1f8e54))
|
||||
|
||||
|
||||
<a name="2.0.0-beta.10"></a>
|
||||
# 2.0.0-beta.10 (2016-03-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **change_detection:** fix a memory leak ([128acbb](https://github.com/angular/angular/commit/128acbb))
|
||||
* **closure:** don't throw from top-level ([5824866](https://github.com/angular/angular/commit/5824866))
|
||||
* **router:** handle URL that does not match a route ([8e3e450](https://github.com/angular/angular/commit/8e3e450)), closes [#7349](https://github.com/angular/angular/issues/7349) [#7203](https://github.com/angular/angular/issues/7203)
|
||||
* **router/instruction:** ensure toLinkUrl includes extra params ([0d58b13](https://github.com/angular/angular/commit/0d58b13)), closes [#7367](https://github.com/angular/angular/issues/7367)
|
||||
|
||||
### Features
|
||||
|
||||
* **compiler:** change html parser to preserve comments ([70d18b5](https://github.com/angular/angular/commit/70d18b5))
|
||||
* **core:** introduce a CSS lexer/parser ([b72bab4](https://github.com/angular/angular/commit/b72bab4))
|
||||
* **core:** introduce a CSS lexer/parser ([293fa55](https://github.com/angular/angular/commit/293fa55))
|
||||
* **facade:** add .values to StringMapWrapper ([f1796d6](https://github.com/angular/angular/commit/f1796d6))
|
||||
* **i18n:** add ngPlural directive ([df1f78e](https://github.com/angular/angular/commit/df1f78e))
|
||||
* **i18n:** implement a simple version of message extractor ([095db67](https://github.com/angular/angular/commit/095db67)), closes [#7454](https://github.com/angular/angular/issues/7454)
|
||||
* **shadow_css:** support `/deep/` and `>>>` ([cb38d72](https://github.com/angular/angular/commit/cb38d72)), closes [#7562](https://github.com/angular/angular/issues/7562) [#7563](https://github.com/angular/angular/issues/7563)
|
||||
* **TAG_DEFINITIONS:** include <meta> and <base> ([2c7c3e3](https://github.com/angular/angular/commit/2c7c3e3)), closes [#7455](https://github.com/angular/angular/issues/7455)
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
Removed deprecated API from NgZone
|
||||
- `NgZone.overrideOnTurnStart`
|
||||
- `NgZone.overrideOnTurnDone`
|
||||
- `NgZone.overrideOnEventDone`
|
||||
- `NgZone.overrideOnErrorHandler`
|
||||
|
||||
Rename NgZone API
|
||||
- `NgZone.onTurnStart` => `NgZone.onUnstable`
|
||||
- `NgZone.onTurnDone` => `NgZone.onMicrotaskEmpty`
|
||||
- `NgZone.onEventDone` => `NgZone.onStable`
|
||||
|
||||
|
||||
<a name="2.0.0-beta.9"></a>
|
||||
# 2.0.0-beta.9 (2016-03-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular_1_router:** Renamed require statements after TypeScript files are transpiled ([ae49085](https://github.com/angular/angular/commit/ae49085)), closes [#7049](https://github.com/angular/angular/issues/7049)
|
||||
* **angular1_router:** rename `router` component binding to `$router` ([2548ce8](https://github.com/angular/angular/commit/2548ce8))
|
||||
* **angular1_router:** rename `router` component binding to `$router` ([1174473](https://github.com/angular/angular/commit/1174473))
|
||||
* **angular1_router:** support templateUrl components ([5586c29](https://github.com/angular/angular/commit/5586c29))
|
||||
* **build:** Use fixed version of Chromium Canary that will be updated manually instead of au ([1d49b3e](https://github.com/angular/angular/commit/1d49b3e))
|
||||
* **router:** support outlets within dynamic components ([7d44b82](https://github.com/angular/angular/commit/7d44b82))
|
||||
|
||||
### Features
|
||||
|
||||
* **angular1_router:** Add ng-link-active class to active ng-link ([11e8aa2](https://github.com/angular/angular/commit/11e8aa2)), closes [#6882](https://github.com/angular/angular/issues/6882)
|
||||
* **compiler:** Added spans to HTML parser errors ([19a08f3](https://github.com/angular/angular/commit/19a08f3))
|
||||
* **dart:** Add a dev-mode check for undeclared lifecycle interfaces ([a3d7629](https://github.com/angular/angular/commit/a3d7629)), closes [#6849](https://github.com/angular/angular/issues/6849)
|
||||
* **dart/transform:** Create standalone transformers for phases ([15e1614](https://github.com/angular/angular/commit/15e1614))
|
||||
* **iterable_differ:** support immutable lists ([a10c02c](https://github.com/angular/angular/commit/a10c02c)), closes [#7127](https://github.com/angular/angular/issues/7127)
|
||||
* **router:** add regex matchers ([75343eb](https://github.com/angular/angular/commit/75343eb)), closes [#7325](https://github.com/angular/angular/issues/7325) [#7126](https://github.com/angular/angular/issues/7126)
|
||||
* **router:** Added method to get current instruction ([6dce4f4](https://github.com/angular/angular/commit/6dce4f4))
|
||||
* **transformers:** change 'Missing Identifier' to be an error ([45fd6f0](https://github.com/angular/angular/commit/45fd6f0)), closes [#7403](https://github.com/angular/angular/issues/7403)
|
||||
* **transformers:** collect provider information ([81beb1c](https://github.com/angular/angular/commit/81beb1c))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* The recently added binding of the current router to the current component
|
||||
has been renamed from `router` to `$router`.
|
||||
So now the recommended set up for your bindings in your routed component
|
||||
is:
|
||||
```js
|
||||
{
|
||||
...
|
||||
bindings: {
|
||||
$router: '<'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* The recently added binding of the current router to the current component
|
||||
has been renamed from `router` to `$router`.
|
||||
So now the recommended set up for your bindings in your routed component
|
||||
is:
|
||||
```js
|
||||
{
|
||||
...
|
||||
bindings: {
|
||||
$router: '<'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
<a name="2.0.0-beta.8"></a>
|
||||
# 2.0.0-beta.8 (2016-03-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular1_router:** rename `$route` service to `$rootRouter` ([a1c3be2](https://github.com/angular/angular/commit/a1c3be2))
|
||||
* **angular1_router:** rename `router` component binding to `$router` ([edad8e3](https://github.com/angular/angular/commit/edad8e3))
|
||||
* **angular1_router:** support templateUrl components ([d4a4d81](https://github.com/angular/angular/commit/d4a4d81))
|
||||
* **change_detection:** allow to destroy `OnPush` components inside of a host event. ([280b86e](https://github.com/angular/angular/commit/280b86e))
|
||||
* **change_detection:** allow to destroy `OnPush` components inside of a host event. ([ebd438f](https://github.com/angular/angular/commit/ebd438f)), closes [#7192](https://github.com/angular/angular/issues/7192)
|
||||
* **core:** support `ngFor` that has an `ngIf` as last node ([1779caf](https://github.com/angular/angular/commit/1779caf)), closes [#6304](https://github.com/angular/angular/issues/6304) [#6878](https://github.com/angular/angular/issues/6878)
|
||||
* **dart/payload:** Fix runtime error in hello_world payload app ([eeb594c](https://github.com/angular/angular/commit/eeb594c)), closes [#7358](https://github.com/angular/angular/issues/7358)
|
||||
* **differ:** clean up stale identity change refs ([ab36ea0](https://github.com/angular/angular/commit/ab36ea0)), closes [#7193](https://github.com/angular/angular/issues/7193)
|
||||
* **DomRenderer:** correctly handle namespaced attributes ([c6afea6](https://github.com/angular/angular/commit/c6afea6))
|
||||
* **Router:** Query strings are copied for HashLocationStrategy ([b47f80e](https://github.com/angular/angular/commit/b47f80e)), closes [#7298](https://github.com/angular/angular/issues/7298)
|
||||
* **test:** fix a broken test ([9aedef2](https://github.com/angular/angular/commit/9aedef2))
|
||||
* **transformers:** record reflection info about abstract classes ([05c185a](https://github.com/angular/angular/commit/05c185a)), closes [#7347](https://github.com/angular/angular/issues/7347)
|
||||
* **transformers:** replace an error with a warning when cannot resolve a symbol ([ee3c580](https://github.com/angular/angular/commit/ee3c580))
|
||||
* **transformers:** special case types some built-in types, so they can be resolved ([331b9c1](https://github.com/angular/angular/commit/331b9c1))
|
||||
* **web_worker:** wait for bindings in kitchen sink spec ([4a93f58](https://github.com/angular/angular/commit/4a93f58))
|
||||
* **web_workers:** make waitForElementText function more stable ([f6a8d04](https://github.com/angular/angular/commit/f6a8d04))
|
||||
* **WebWorker:** Fix PostMessageBusSink and Source undefined error. ([01fe7f5](https://github.com/angular/angular/commit/01fe7f5)), closes [#7156](https://github.com/angular/angular/issues/7156)
|
||||
* **WebWorker:** Make MessageBus EventEmitter synchronous ([69c1694](https://github.com/angular/angular/commit/69c1694))
|
||||
|
||||
### Features
|
||||
|
||||
* **core:** Add `QueryList.forEach` to public api. ([e7470d5](https://github.com/angular/angular/commit/e7470d5))
|
||||
* **core:** Add `QueryList#forEach` ([b634a25](https://github.com/angular/angular/commit/b634a25))
|
||||
* **core:** add more debug APIs to inspect the application form a browser ([b5e6319](https://github.com/angular/angular/commit/b5e6319)), closes [#7045](https://github.com/angular/angular/issues/7045) [#7161](https://github.com/angular/angular/issues/7161)
|
||||
* **core:** drop `ChangeDetectionStrategy.OnPushObserve` ([f60fa14](https://github.com/angular/angular/commit/f60fa14))
|
||||
* **di:** drop support for injecting types with generics in Dart ([c9a3df9](https://github.com/angular/angular/commit/c9a3df9)), closes [#7262](https://github.com/angular/angular/issues/7262)
|
||||
* **forms/validators:** pattern validator ([38cb526](https://github.com/angular/angular/commit/38cb526)), closes [#5561](https://github.com/angular/angular/issues/5561)
|
||||
* **i18n:** added i18nPlural and i18nSelect pipes ([59629a0](https://github.com/angular/angular/commit/59629a0)), closes [#7268](https://github.com/angular/angular/issues/7268)
|
||||
* **pipes:** add ReplacePipe for string manipulation ([6ef2121](https://github.com/angular/angular/commit/6ef2121))
|
||||
* **test:** add withProviders for per test providers ([c1a0af5](https://github.com/angular/angular/commit/c1a0af5)), closes [#5128](https://github.com/angular/angular/issues/5128)
|
||||
* **transformers:** collect data needed for the template compiler ([ebe531b](https://github.com/angular/angular/commit/ebe531b)), closes [#7299](https://github.com/angular/angular/issues/7299)
|
||||
* **transformers:** collect information for CompileDiDependencyMetadata ([39b6e0e](https://github.com/angular/angular/commit/39b6e0e))
|
||||
* **transformers:** makes the map of resolved identifiers configurable ([0bb10d6](https://github.com/angular/angular/commit/0bb10d6)), closes [#7359](https://github.com/angular/angular/issues/7359)
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* `OnPushObserve` was an experimental
|
||||
feature for Dart and had
|
||||
conceptual performance problems,
|
||||
as setting up observables is slow.
|
||||
Use `OnPush` instead.
|
||||
|
||||
* In Dart we used to support injecting types with generics. As this feature is hard to implement with the upcoming codegen we are dropping it.
|
||||
Merge cl/115454020 in G3 with this change.
|
||||
|
||||
* The `$router` injectable service has been renamed to `$rootRouter`
|
||||
|
||||
* The recently added binding of the current router to the current component
|
||||
has been renamed from `router` to `$router`.
|
||||
So now the recommended set up for your bindings in your routed component
|
||||
is:
|
||||
```js
|
||||
{
|
||||
...
|
||||
bindings: {
|
||||
$router: '<'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<a name="2.0.0-beta.7"></a>
|
||||
# 2.0.0-beta.7 (2016-02-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular_1_router:** Added DI string tokens ([3478d5d](https://github.com/angular/angular/commit/3478d5d)), closes [#4269](https://github.com/angular/angular/issues/4269) [#7031](https://github.com/angular/angular/issues/7031)
|
||||
* **typing:** Remove re-export of the Promise built-in type. ([265703b](https://github.com/angular/angular/commit/265703b)), closes [#6468](https://github.com/angular/angular/issues/6468)
|
||||
|
||||
<a name="2.0.0-beta.6"></a>
|
||||
# 2.0.0-beta.6 (2016-02-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular1-router:** add missing wrapper methods ([55122cd](https://github.com/angular/angular/commit/55122cd)), closes [#6763](https://github.com/angular/angular/issues/6763) [#6861](https://github.com/angular/angular/issues/6861) [#6861](https://github.com/angular/angular/issues/6861)
|
||||
* **angular1-router:** add support for using the component helper ([d86be24](https://github.com/angular/angular/commit/d86be24)), closes [angular/angular.js#13860](https://github.com/angular/angular.js/issues/13860) [#6076](https://github.com/angular/angular/issues/6076) [#5278](https://github.com/angular/angular/issues/5278)
|
||||
* **async:** handle synchronous initial value in async pipe ([26e60d6](https://github.com/angular/angular/commit/26e60d6)), closes [#5996](https://github.com/angular/angular/issues/5996)
|
||||
* **build:** don't try to copy .d.ts files into the npm distro ([16b5217](https://github.com/angular/angular/commit/16b5217)), closes [#6921](https://github.com/angular/angular/issues/6921)
|
||||
* **compiler:** fix interpolation regexp ([9b0e10e](https://github.com/angular/angular/commit/9b0e10e)), closes [#6056](https://github.com/angular/angular/issues/6056)
|
||||
* **compiler:** use event names for matching directives ([231773e](https://github.com/angular/angular/commit/231773e)), closes [#6870](https://github.com/angular/angular/issues/6870)
|
||||
* **core:** add detail to dehydrated detector exception ([e7ad03c](https://github.com/angular/angular/commit/e7ad03c)), closes [#6939](https://github.com/angular/angular/issues/6939)
|
||||
* **core:** mute mode printing in console in prod mode ([74be3d3](https://github.com/angular/angular/commit/74be3d3)), closes [#6873](https://github.com/angular/angular/issues/6873)
|
||||
* **di:** throw if a token uses more than 20 dependencies. ([de77700](https://github.com/angular/angular/commit/de77700)), closes [#6690](https://github.com/angular/angular/issues/6690) [#6869](https://github.com/angular/angular/issues/6869)
|
||||
* **forms:** add RadioButtonValueAccessor to the list of default value accessors ([8f47aa3](https://github.com/angular/angular/commit/8f47aa3))
|
||||
* **forms:** add support for radio buttons ([e725542](https://github.com/angular/angular/commit/e725542)), closes [#6877](https://github.com/angular/angular/issues/6877)
|
||||
* **forms:** use strict runtimeType checks instead of instanceof ([50548fb](https://github.com/angular/angular/commit/50548fb)), closes [#6981](https://github.com/angular/angular/issues/6981)
|
||||
* **Headers:** serializable toJSON ([b55f176](https://github.com/angular/angular/commit/b55f176)), closes [#6073](https://github.com/angular/angular/issues/6073) [#6714](https://github.com/angular/angular/issues/6714)
|
||||
* **ngFor:** update view locals if identity changes ([0f10624](https://github.com/angular/angular/commit/0f10624)), closes [#6923](https://github.com/angular/angular/issues/6923)
|
||||
* **router:** Added route data to normalized async route ([df7885c](https://github.com/angular/angular/commit/df7885c)), closes [#6802](https://github.com/angular/angular/issues/6802)
|
||||
* **router:** don't prepend `/` unnecessarily to Location paths ([c603643](https://github.com/angular/angular/commit/c603643)), closes [#6729](https://github.com/angular/angular/issues/6729) [#5502](https://github.com/angular/angular/issues/5502)
|
||||
* **router:** fix incorrect url param value coercion of 1 to true ([995a9e0](https://github.com/angular/angular/commit/995a9e0)), closes [#5346](https://github.com/angular/angular/issues/5346) [#6286](https://github.com/angular/angular/issues/6286)
|
||||
* **router:** fix url path for star segment in path recognizer ([6f1ef33](https://github.com/angular/angular/commit/6f1ef33)), closes [#6976](https://github.com/angular/angular/issues/6976)
|
||||
* **router:** fixed the location wrapper for angular1 ([e73fee7](https://github.com/angular/angular/commit/e73fee7)), closes [#6943](https://github.com/angular/angular/issues/6943)
|
||||
* **typings:** Don't expose typing dependencies to users. ([2a70f4e](https://github.com/angular/angular/commit/2a70f4e)), closes [#5973](https://github.com/angular/angular/issues/5973) [#5807](https://github.com/angular/angular/issues/5807) [#6266](https://github.com/angular/angular/issues/6266) [#5242](https://github.com/angular/angular/issues/5242) [#6817](https://github.com/angular/angular/issues/6817) [#6267](https://github.com/angular/angular/issues/6267)
|
||||
* **upgrade:** fix infinite $rootScope.$digest() ([7e0f02f](https://github.com/angular/angular/commit/7e0f02f)), closes [#6385](https://github.com/angular/angular/issues/6385) [#6386](https://github.com/angular/angular/issues/6386)
|
||||
* **Validators:** fix Validators.required marking number zero as invalid ([c2ceb7f](https://github.com/angular/angular/commit/c2ceb7f)), closes [#6617](https://github.com/angular/angular/issues/6617)
|
||||
* **WebWorkers:** Fix flaky WebWorker test ([da1fcfd](https://github.com/angular/angular/commit/da1fcfd)), closes [#6851](https://github.com/angular/angular/issues/6851)
|
||||
|
||||
### Features
|
||||
|
||||
* **angular1_router:** allow component to bind to router ([0f22dce](https://github.com/angular/angular/commit/0f22dce))
|
||||
* **typings:** install es6-shim typings to a location users can reference. ([f1f5b45](https://github.com/angular/angular/commit/f1f5b45))
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
Transitive typings are no longer included in the distribution.
|
||||
|
||||
If you use `--target=es5`, you will need to add a line somewhere in your
|
||||
application (for example, at the top of the `.ts` file where you call `bootstrap`):
|
||||
```
|
||||
///<reference path="node_modules/angular2/typings/browser.d.ts"/>
|
||||
```
|
||||
(Note that if your file is not in the same directory as `node_modules`, you'll
|
||||
need to add one or more `../` to the start of that path.)
|
||||
|
||||
If you have unit tests, you need to install typings in your project using
|
||||
http://github.com/typings/typings
|
||||
And install typings such as `jasmine`, `angular-protractor`, or `selenium-webdriver`
|
||||
to satisfy the type-checker.
|
||||
|
||||
If you rely on es6 APIs other than Promises and Collections, you will need to
|
||||
install the es6-shim typing instead of using the <reference> tag above.
|
||||
Angular previously exposed typings for the entire ES6 API.
|
||||
|
||||
<a name="2.0.0-beta.5"></a>
|
||||
# 2.0.0-beta.5 (2016-02-10)
|
||||
|
||||
This release was incorrect; replaced with beta.6.
|
||||
|
||||
<a name="2.0.0-beta.4"></a>
|
||||
# 2.0.0-beta.4 (2016-02-10)
|
||||
|
||||
This release was incorrect; replaced with beta.6.
|
||||
|
||||
<a name="2.0.0-beta.3"></a>
|
||||
# 2.0.0-beta.3 (2016-02-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bundle:** add angular2/platform/testing/browser to SystemJS testing bundle ([ae7d2ab](https://github.com/angular/angular/commit/ae7d2ab))
|
||||
* **circle:** pre-dependencies `npm install npm` ([36a0e04](https://github.com/angular/angular/commit/36a0e04)), closes [#6777](https://github.com/angular/angular/issues/6777)
|
||||
* **dart/transform:** Handle edge cases in ReflectionRemover ([3e9b532](https://github.com/angular/angular/commit/3e9b532)), closes [#6749](https://github.com/angular/angular/issues/6749)
|
||||
* **docs:** `rxjs/add/operators/map` -> `rxjs/add/operator/map` (no 's'). ([2a302aa](https://github.com/angular/angular/commit/2a302aa))
|
||||
* **karma:** fix running karma via gulp ([27daeaf](https://github.com/angular/angular/commit/27daeaf))
|
||||
* **query:** don’t cross component boundaries ([c6adbf6](https://github.com/angular/angular/commit/c6adbf6)), closes [#6759](https://github.com/angular/angular/issues/6759)
|
||||
* **query:** update view queries that query directives in embedded views ([1f7a41c](https://github.com/angular/angular/commit/1f7a41c)), closes [#6747](https://github.com/angular/angular/issues/6747)
|
||||
* **WebWorkers:** Add support for transitionend events. ([c2a38c0](https://github.com/angular/angular/commit/c2a38c0)), closes [#6649](https://github.com/angular/angular/issues/6649)
|
||||
* **zone:** correct incorrect calls to zone ([3211938](https://github.com/angular/angular/commit/3211938))
|
||||
|
||||
### Features
|
||||
|
||||
* **change_detection:** allow all legal programs in the dev mode ([42231f5](https://github.com/angular/angular/commit/42231f5))
|
||||
* **dart/transform:** Generate all code into <file>.template.dart ([8c36aa8](https://github.com/angular/angular/commit/8c36aa8))
|
||||
* **debug:** replace DebugElement with new Debug DOM ([e1bf3d3](https://github.com/angular/angular/commit/e1bf3d3))
|
||||
* **ngFor:** add custom trackBy function support ([cee2318](https://github.com/angular/angular/commit/cee2318)), closes [#6779](https://github.com/angular/angular/issues/6779)
|
||||
* **upgrade:** support bindToController with binding definitions ([99e6500](https://github.com/angular/angular/commit/99e6500)), closes [#4784](https://github.com/angular/angular/issues/4784)
|
||||
* **WebWorker:** Add Router Support for WebWorker Apps ([8bea667](https://github.com/angular/angular/commit/8bea667)), closes [#3563](https://github.com/angular/angular/issues/3563)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **dart/transform:** Only process deferred libs when necessary ([f56df65](https://github.com/angular/angular/commit/f56df65)), closes [#6745](https://github.com/angular/angular/issues/6745)
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
This is a breaking change for unit tests. The API for the DebugElement
|
||||
has changed. Now, there is a DebugElement or DebugNode for every node
|
||||
in the DOM, not only nodes with an ElementRef. `componentViewChildren` is
|
||||
removed, and `childNodes` is a list of ElementNodes corresponding to every
|
||||
child in the DOM. `query` no longer takes a scope parameter, since
|
||||
the entire rendered DOM is included in the `childNodes`.
|
||||
|
||||
Before:
|
||||
|
||||
```
|
||||
componentFixture.debugElement.componentViewChildren[0];
|
||||
```
|
||||
|
||||
After
|
||||
```
|
||||
// Depending on the DOM structure of your component, the
|
||||
// index may have changed or the first component child
|
||||
// may be a sub-child.
|
||||
componentFixture.debugElement.children[0];
|
||||
```
|
||||
|
||||
Before:
|
||||
|
||||
```
|
||||
debugElement.query(By.css('div'), Scope.all());
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```
|
||||
debugElement.query(By.css('div'));
|
||||
```
|
||||
|
||||
Before:
|
||||
|
||||
```
|
||||
componentFixture.debugElement.elementRef;
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```
|
||||
componentFixture.elementRef;
|
||||
```
|
||||
|
||||
<a name="2.0.0-beta.2"></a>
|
||||
# 2.0.0-beta.2 (2016-01-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bundles:** testing bundle should include browser platform ([4a41442](https://github.com/angular/angular/commit/4a41442)), closes [#6626](https://github.com/angular/angular/issues/6626)
|
||||
* **ChangeDetection:** chain expressions evaluate to the last expression (codegen) ([933a911](https://github.com/angular/angular/commit/933a911)), closes [#4782](https://github.com/angular/angular/issues/4782) [#5892](https://github.com/angular/angular/issues/5892)
|
||||
* **core:** always remove DOM listeners and stream subscriptions ([0ae7775](https://github.com/angular/angular/commit/0ae7775))
|
||||
* **Dart:** make some playground samples run with Dart Dev Compiler ([3e65d14](https://github.com/angular/angular/commit/3e65d14)), closes [#6441](https://github.com/angular/angular/issues/6441)
|
||||
* **dart/transform:** Ensure template codegen is completed sync ([5f0baaa](https://github.com/angular/angular/commit/5f0baaa)), closes [#6603](https://github.com/angular/angular/issues/6603)
|
||||
* **ddc:** router, compiler, web worker fixes for DDC ([db87bae](https://github.com/angular/angular/commit/db87bae)), closes [#6693](https://github.com/angular/angular/issues/6693)
|
||||
* **ddc:** type fixes necessary to bring DDC severe count to 0 ([4282297](https://github.com/angular/angular/commit/4282297))
|
||||
* **ddc:** use dynamic types in reflection typedefs ([c785a1e](https://github.com/angular/angular/commit/c785a1e)), closes [#6437](https://github.com/angular/angular/issues/6437)
|
||||
* **directive:** throw if output the same event more than once ([8c37b7e](https://github.com/angular/angular/commit/8c37b7e))
|
||||
* **HtmlLexer:** fix for unicode chars ([a24ee6a](https://github.com/angular/angular/commit/a24ee6a)), closes [#6036](https://github.com/angular/angular/issues/6036) [#6061](https://github.com/angular/angular/issues/6061)
|
||||
* **perf:** faster looseIdentical implementation ([761c6d0](https://github.com/angular/angular/commit/761c6d0)), closes [#6364](https://github.com/angular/angular/issues/6364)
|
||||
* **template_compiler:** Fix erroneous cycle detection ([eda4c3e](https://github.com/angular/angular/commit/eda4c3e)), closes [#6404](https://github.com/angular/angular/issues/6404) [#6474](https://github.com/angular/angular/issues/6474)
|
||||
* **testing:** remove test zone for now and rely on returned promises ([c72ed99](https://github.com/angular/angular/commit/c72ed99)), closes [#6359](https://github.com/angular/angular/issues/6359) [#6601](https://github.com/angular/angular/issues/6601)
|
||||
* **transformer:** record HostBinding annotations applied to getters ([a593ffa](https://github.com/angular/angular/commit/a593ffa)), closes [#6283](https://github.com/angular/angular/issues/6283)
|
||||
* **web_workers:** support @AngularEntrypoint in web workers ([ac85cbb](https://github.com/angular/angular/commit/ac85cbb)), closes [#6013](https://github.com/angular/angular/issues/6013)
|
||||
|
||||
### Features
|
||||
|
||||
* **core/application_ref:** Allow asyncronous app initializers. ([df3074f](https://github.com/angular/angular/commit/df3074f)), closes [#5929](https://github.com/angular/angular/issues/5929) [#6063](https://github.com/angular/angular/issues/6063)
|
||||
* **dart/transform:** DirectiveProcessor: do not process generated files ([78bfdf7](https://github.com/angular/angular/commit/78bfdf7)), closes [#6517](https://github.com/angular/angular/issues/6517)
|
||||
* **dart/transform:** Promote missing Directive warning to error ([47a3b4d](https://github.com/angular/angular/commit/47a3b4d)), closes [#6519](https://github.com/angular/angular/issues/6519) [#6568](https://github.com/angular/angular/issues/6568)
|
||||
* **test:** allow tests to specify the platform and application providers used ([b0cebdb](https://github.com/angular/angular/commit/b0cebdb)), closes [#5351](https://github.com/angular/angular/issues/5351) [#5585](https://github.com/angular/angular/issues/5585) [#5975](https://github.com/angular/angular/issues/5975)
|
||||
* **testability:** Expose function frameworkStabilizers ([69ae363](https://github.com/angular/angular/commit/69ae363)), closes [#5485](https://github.com/angular/angular/issues/5485)
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* `Renderer.listen` now has to return a function that
|
||||
removes the event listener.
|
||||
|
||||
* TemplateRef.elementRef is now read-only.
|
||||
|
||||
* Tests are now required to use `setBaseTestProviders`
|
||||
to set up. Assuming your tests are run on a browser, setup would change
|
||||
as follows.
|
||||
Before:
|
||||
```js
|
||||
// Somewhere in test setup
|
||||
import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter';
|
||||
BrowserDomAdapter.makeCurrent
|
||||
```
|
||||
After:
|
||||
```js
|
||||
// Somewhere in the test setup
|
||||
import {setBaseTestProviders} from 'angular2/testing';
|
||||
import {
|
||||
TEST_BROWSER_PLATFORM_PROVIDERS,
|
||||
TEST_BROWSER_APPLICATION_PROVIDERS
|
||||
} from 'angular2/platform/testing/browser';
|
||||
setBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS,
|
||||
TEST_BROWSER_APPLICATION_PROVIDERS);
|
||||
```
|
||||
|
||||
|
||||
<a name="2.0.0-beta.1"></a>
|
||||
# 2.0.0-beta.1 catamorphic-involution (2016-01-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **benchpress:** fix flake ([9d28147](https://github.com/angular/angular/commit/9d28147)), closes [#6161](https://github.com/angular/angular/issues/6161)
|
||||
* **CHANGELOG:** typo ([d116861](https://github.com/angular/angular/commit/d116861)), closes [#6075](https://github.com/angular/angular/issues/6075) [#6078](https://github.com/angular/angular/issues/6078)
|
||||
* **code size:** revert previous devMode change to restore size targets ([c47d85b](https://github.com/angular/angular/commit/c47d85b))
|
||||
* **core:** IE only supports parentNode ([630d931](https://github.com/angular/angular/commit/630d931)), closes [#5994](https://github.com/angular/angular/issues/5994)
|
||||
* **docs:** fix an import in TOOLS_DART.md ([3524946](https://github.com/angular/angular/commit/3524946)), closes [#5923](https://github.com/angular/angular/issues/5923)
|
||||
* **forms:** fix SelectControlValueAccessor not to call onChange twice ([b44d36c](https://github.com/angular/angular/commit/b44d36c)), closes [#5969](https://github.com/angular/angular/issues/5969)
|
||||
* **router:** correctly sort route matches with children by specificity ([b2bc50d](https://github.com/angular/angular/commit/b2bc50d)), closes [#5848](https://github.com/angular/angular/issues/5848) [#6011](https://github.com/angular/angular/issues/6011)
|
||||
* **router:** preserve specificity for redirects ([a038bb9](https://github.com/angular/angular/commit/a038bb9)), closes [#5933](https://github.com/angular/angular/issues/5933)
|
||||
* **TemplateParser:** do not match on attrs that are bindings ([9a70f1a](https://github.com/angular/angular/commit/9a70f1a)), closes [#5914](https://github.com/angular/angular/issues/5914)
|
||||
|
||||
### Features
|
||||
|
||||
* **core:** improve NoAnnotationError message ([197cf09](https://github.com/angular/angular/commit/197cf09)), closes [#4866](https://github.com/angular/angular/issues/4866) [#5927](https://github.com/angular/angular/issues/5927)
|
||||
* **core:** improve stringify for dart to handle closures ([e67ebb7](https://github.com/angular/angular/commit/e67ebb7))
|
||||
* **core:** speed up view creation via code gen for view factories. ([7ae23ad](https://github.com/angular/angular/commit/7ae23ad)), closes [#5993](https://github.com/angular/angular/issues/5993)
|
||||
* **router:** support links with just auxiliary routes ([2a2f9a9](https://github.com/angular/angular/commit/2a2f9a9)), closes [#5930](https://github.com/angular/angular/issues/5930)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **dart/transform:** Avoid unnecessary reads for files with no view ([89f32f8](https://github.com/angular/angular/commit/89f32f8)), closes [#6183](https://github.com/angular/angular/issues/6183)
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* Platform pipes can only contain types and arrays of types,
|
||||
but no bindings any more.
|
||||
* When using transformers, platform pipes need to be specified explicitly
|
||||
in the pubspec.yaml via the new config option
|
||||
`platform_pipes`.
|
||||
* `Compiler.compileInHost` now returns a `HostViewFactoryRef`
|
||||
* Component view is not yet created when component constructor is called.
|
||||
-> use `onInit` lifecycle callback to access the view of a component
|
||||
* `ViewRef#setLocal` has been moved to new type `EmbeddedViewRef`
|
||||
* `internalView` is gone, use `EmbeddedViewRef.rootNodes` to access
|
||||
the root nodes of an embedded view
|
||||
* `renderer.setElementProperty`, `..setElementStyle`, `..setElementAttribute` now
|
||||
take a native element instead of an ElementRef
|
||||
* `Renderer` interface now operates on plain native nodes,
|
||||
instead of `RenderElementRef`s or `RenderViewRef`s
|
||||
|
||||
<a name="2.0.0-beta.0"></a>
|
||||
# 2.0.0-beta.0 sonambulent-inauguration (2015-12-15)
|
||||
# 2.0.0-beta.0 somnambulant-inauguration (2015-12-15)
|
||||
|
||||
**Enjoy!**
|
||||
|
||||
@ -19,10 +534,7 @@
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* Before
|
||||
Previously Angular would run in dev prod mode by default, and you could enable the dev mode by calling enableDevMode.
|
||||
After
|
||||
Now, Angular runs in the dev mode by default, and you can enable the prod mode by calling enableProdMode.
|
||||
* Previously, Angular would run in dev prod mode by default, and you could enable the dev mode by calling enableDevMode. Now, Angular runs in the dev mode by default, and you can enable the prod mode by calling enableProdMode.
|
||||
|
||||
|
||||
|
||||
@ -99,11 +611,11 @@ bundle. `ngUpgrade` has a dedicated `upgrade.js` bundle now.
|
||||
|
||||
* `Observable` are no more re-exported from `angular2/core`
|
||||
|
||||
Before
|
||||
Before
|
||||
```
|
||||
import {Observable} from 'angular2/core'
|
||||
```
|
||||
After
|
||||
After
|
||||
```
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
```
|
||||
@ -154,7 +666,7 @@ Use imports from `angular2/compiler` instead.
|
||||
<my-cmp (myEvent)="action()">
|
||||
<my-cmp [(myProp)]="prop">
|
||||
<input #myInput>`,
|
||||
<template ngFor="#myItem" [ngForOf]=items #myIndex="index">
|
||||
<template ngFor "#myItem" [ngForOf]=items #myIndex="index">
|
||||
```
|
||||
|
||||
The full migration instruction can be found at [angular2/docs/migration/kebab-case.md](https://github.com/angular/angular/blob/master/modules/angular2/docs/migration/kebab-case.md).
|
||||
@ -324,7 +836,7 @@ import * as core from 'angular2/core';
|
||||
* Operators and Observables from RxJS (e.g. .map(), .toArray(), .toPromise(), etc ) now need to be explicitly imported (once per operator in your app)
|
||||
```
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
import 'rxjs/add/operators/map';
|
||||
import 'rxjs/add/operator/map';
|
||||
import 'rxjs/add/observable/interval';
|
||||
|
||||
Observable.interval(1000).subscribe(...);
|
||||
|
@ -11,8 +11,11 @@ Someone with committer access will do the rest.
|
||||
We have automated the process for merging pull requests into master. Our goal is to minimize the disruption for
|
||||
Angular committers and also prevent breakages on master.
|
||||
|
||||
When a PR is ready to merge, a project member in the CoreTeamMember list (see below) can add the special label,
|
||||
`PR: merge`.
|
||||
When a PR has `pr_state: LGTM` and is ready to merge, you should add the `pr_action: merge` label.
|
||||
Currently (late 2015), we need to ensure that each PR will cleanly merge into the Google-internal version control,
|
||||
so the caretaker reviews the changes manually.
|
||||
|
||||
After this review, the caretaker adds `zomg_admin: do_merge` which is restricted to admins only.
|
||||
A robot running as [mary-poppins](https://github.com/mary-poppins)
|
||||
is notified that the label was added by an authorized person,
|
||||
and will create a new branch in the angular project, using the convention `presubmit-{username}-pr-{number}`.
|
||||
@ -26,6 +29,6 @@ Finally, after merge `mary-poppins` removes the presubmit branch.
|
||||
|
||||
## Administration
|
||||
|
||||
The list of users who can trigger a merge by adding the label is stored in our appengine app datastore.
|
||||
The list of users who can trigger a merge by adding the `zomg_admin: do_merge` label is stored in our appengine app datastore.
|
||||
Edit the contents of the [CoreTeamMember Table](
|
||||
https://console.developers.google.com/project/angular2-automation/datastore/query?queryType=KindQuery&namespace=&kind=CoreTeamMember)
|
||||
|
@ -180,7 +180,8 @@ Must be one of the following:
|
||||
* **refactor**: A code change that neither fixes a bug nor adds a feature
|
||||
* **perf**: A code change that improves performance
|
||||
* **test**: Adding missing tests or correcting existing tests
|
||||
* **build** Changes that affect the build system, CI configuration or external dependencies (example scopes: gulp, broccoli, npm)
|
||||
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
|
||||
* **ci**: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
|
||||
* **chore**: Other changes that don't modify `src` or `test` files
|
||||
|
||||
### Scope
|
||||
|
44
DEVELOPER.md
44
DEVELOPER.md
@ -9,7 +9,7 @@ JS and Dart versions. It also explains the basic mechanics of using `git`, `node
|
||||
* [Installing NPM Modules and Dart Packages](#installing-npm-modules-and-dart-packages)
|
||||
* [Build commands](#build-commands)
|
||||
* [Running Tests Locally](#running-tests-locally)
|
||||
* [Formatting](#clang-format)
|
||||
* [Code Style](#code-style)
|
||||
* [Project Information](#project-information)
|
||||
* [CI using Travis](#ci-using-travis)
|
||||
* [Transforming Dart code](#transforming-dart-code)
|
||||
@ -23,7 +23,16 @@ if you'd like to contribute to Angular.
|
||||
Before you can build and test Angular, you must install and configure the
|
||||
following products on your development machine:
|
||||
|
||||
* [Dart](https://www.dartlang.org) (version ` >=1.12.0 <2.0.0`), specifically the Dart-SDK and
|
||||
* [Git](http://git-scm.com) and/or the **GitHub app** (for [Mac](http://mac.github.com) or
|
||||
[Windows](http://windows.github.com)); [GitHub's Guide to Installing
|
||||
Git](https://help.github.com/articles/set-up-git) is a good source of information.
|
||||
|
||||
* [Node.js](http://nodejs.org), (version `>=5.4.1 <6`) which is used to run a development web server,
|
||||
run tests, and generate distributable files. We also use Node's Package Manager, `npm`
|
||||
(version `>=3.5.3 <4.0`), which comes with Node. Depending on your system, you can install Node either from
|
||||
source or as a pre-packaged bundle.
|
||||
|
||||
* *Optional*: [Dart](https://www.dartlang.org) (version ` >=1.13.2 <2.0.0`), specifically the Dart-SDK and
|
||||
Dartium (a version of [Chromium](http://www.chromium.org) with native support for Dart through
|
||||
the Dart VM). One of the **simplest** ways to get both is to install the **Dart Editor bundle**,
|
||||
which includes the editor, SDK and Dartium. See the [Dart tools](https://www.dartlang.org/tools)
|
||||
@ -33,19 +42,6 @@ following products on your development machine:
|
||||
to the `Path` (e.g. `path-to-dart-sdk-folder\bin`) and a new `DARTIUM_BIN` environment variable must be
|
||||
created, pointing to the executable (e.g. `path-to-dartium-folder\chrome.exe).`
|
||||
|
||||
* [Git](http://git-scm.com) and/or the **GitHub app** (for [Mac](http://mac.github.com) or
|
||||
[Windows](http://windows.github.com)); [GitHub's Guide to Installing
|
||||
Git](https://help.github.com/articles/set-up-git) is a good source of information.
|
||||
|
||||
* [Node.js](http://nodejs.org), (version `>=4.2.1 <5`) which is used to run a development web server,
|
||||
run tests, and generate distributable files. We also use Node's Package Manager, `npm`
|
||||
(version `>=2.14.7 <3.0`), which comes with Node. Depending on your system, you can install Node either from
|
||||
source or as a pre-packaged bundle.
|
||||
|
||||
* [Chrome Canary](https://www.google.com/chrome/browser/canary.html), a version of Chrome with
|
||||
bleeding edge functionality, built especially for developers (and early adopters).
|
||||
|
||||
* [Bower](http://bower.io/).
|
||||
|
||||
|
||||
## Getting the Sources
|
||||
@ -200,15 +196,15 @@ Then, in another terminal:
|
||||
export SAUCE_USERNAME='my_user'; export SAUCE_ACCESS_KEY='my_key';
|
||||
export BROWSER_STACK_USERNAME='my_user'; export BROWSER_STACK_ACCESS_KEY='my_key';
|
||||
```
|
||||
- Then run `gulp test.unit.js.(saucelabs|browserstack) --browsers=option1,option2,..,optionN`
|
||||
- Then run `gulp test.unit.js.(sauce|browserstack) --browsers=option1,option2,..,optionN`
|
||||
The options are any mix of browsers and aliases which are defined in the [browser-providers.conf.js](https://github.com/angular/angular/blob/master/browser-providers.conf.js) file.
|
||||
They are case insensitive, and the `SL_` or `BS_` prefix must not be added for browsers.
|
||||
|
||||
Some examples of commands:
|
||||
```
|
||||
gulp test.unit.js.saucelabs --browsers=Safari8,ie11 //run in Sauce Labs with Safari 8 and IE11
|
||||
gulp test.unit.js.sauce --browsers=Safari8,ie11 //run in Sauce Labs with Safari 8 and IE11
|
||||
gulp test.unit.js.browserstack --browsers=Safari,IE //run in Browser Stack with Safari 7, Safari 8, Safari 9, IE 9, IE 10 and IE 11
|
||||
gulp test.unit.js.saucelabs --browsers=IOS,safari8,android5.1 //run in Sauce Labs with iOS 7, iOS 8, iOs 9, Safari 8 and Android 5.1
|
||||
gulp test.unit.js.sauce --browsers=IOS,safari8,android5.1 //run in Sauce Labs with iOS 7, iOS 8, iOs 9, Safari 8 and Android 5.1
|
||||
```
|
||||
|
||||
### E2E tests
|
||||
@ -231,7 +227,9 @@ Angular specific command line options when running protractor:
|
||||
Angular specific command line options when running protractor (e.g. force gc, ...):
|
||||
`$(npm bin)/protractor protractor-{js|dart2js}-conf.js --ng-help`
|
||||
|
||||
## Formatting with <a name="clang-format">clang-format</a>
|
||||
## Code Style
|
||||
|
||||
### Formatting with <a name="clang-format">clang-format</a>
|
||||
|
||||
We use [clang-format](http://clang.llvm.org/docs/ClangFormat.html) to automatically enforce code
|
||||
style for our TypeScript code. This allows us to focus our code reviews more on the content, and
|
||||
@ -277,6 +275,14 @@ to some whitespace difference.
|
||||
* `clang-format` integrations are also available for many popular editors (`vim`, `emacs`,
|
||||
`Sublime Text`, etc.).
|
||||
|
||||
### Linting
|
||||
|
||||
We use [tslint](https://github.com/palantir/tslint) for linting. See linting rules in [gulpfile](gulpfile.js). To lint, run
|
||||
|
||||
```shell
|
||||
$ gulp lint
|
||||
```
|
||||
|
||||
## Generating the API documentation
|
||||
|
||||
The following gulp task will generate the API docs in the `dist/angular.io/partials/api/angular2`:
|
||||
|
215
LICENSE
215
LICENSE
@ -1,202 +1,21 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
The MIT License
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
Copyright (c) 2014-2016 Google, Inc. http://angular.io
|
||||
|
||||
1. Definitions.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
13
README.md
13
README.md
@ -12,20 +12,12 @@ Angular
|
||||
Angular is a development platform for building mobile and desktop web applications. This is the
|
||||
repository for [Angular 2][ng2], both the JavaScript (JS) and [Dart][dart] versions.
|
||||
|
||||
Angular 2 is currently in **Developer Preview**. We recommend using Angular 1.X for production
|
||||
applications:
|
||||
|
||||
* [AngularJS][ngJS]: [angular/angular.js](http://github.com/angular/angular.js).
|
||||
* [AngularDart][ngDart]: [angular/angular.dart](http://github.com/angular/angular.dart).
|
||||
Angular 2 is currently in **Beta**.
|
||||
|
||||
## Quickstart
|
||||
|
||||
[Get started in 5 minutes][quickstart].
|
||||
|
||||
## Setup & Install Angular 2
|
||||
|
||||
Follow the instructions given on the [Angular download page][download].
|
||||
|
||||
|
||||
## Want to help?
|
||||
|
||||
@ -36,8 +28,7 @@ guidelines for [contributing][contributing] and then check out one of our issues
|
||||
[contributing]: http://github.com/angular/angular/blob/master/CONTRIBUTING.md
|
||||
[dart]: http://www.dartlang.org
|
||||
[dartium]: http://www.dartlang.org/tools/dartium
|
||||
[download]: http://angular.io/download/
|
||||
[quickstart]: https://angular.io/docs/js/latest/quickstart.html
|
||||
[quickstart]: https://angular.io/docs/ts/latest/quickstart.html
|
||||
[ng2]: http://angular.io
|
||||
[ngDart]: http://angulardart.org
|
||||
[ngJS]: http://angularjs.org
|
||||
|
@ -21,7 +21,7 @@ By default the debugging tools are disabled.
|
||||
Enable the debugging tools as follows:
|
||||
|
||||
```dart
|
||||
import 'package:angular2/tools.dart';
|
||||
import 'package:angular2/platform/browser.dart';
|
||||
|
||||
main() async {
|
||||
var appRef = await bootstrap(Application);
|
||||
|
@ -117,7 +117,7 @@ speed things up is to use plain class fields in your expressions and avoid any
|
||||
kinds of computation. Example:
|
||||
|
||||
```typescript
|
||||
@View({
|
||||
@Component({
|
||||
template: '<button [enabled]="isEnabled">{{title}}</button>'
|
||||
})
|
||||
class FancyButton {
|
||||
|
@ -1,3 +1,33 @@
|
||||
// Unique place to configure the browsers which are used in the different CI jobs in Sauce Labs (SL) and BrowserStack (BS).
|
||||
// If the target is set to null, then the browser is not run anywhere during CI.
|
||||
// If a category becomes empty (e.g. BS and required), then the corresponding job must be commented out in Travis configuration.
|
||||
var CIconfiguration = {
|
||||
'Chrome': { unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
|
||||
'Firefox': { unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
|
||||
// FirefoxBeta should be required:true
|
||||
// https://github.com/angular/angular/issues/7560
|
||||
'FirefoxBeta': { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: false}},
|
||||
'ChromeDev': { unitTest: {target: null, required: true}, e2e: {target: null, required: true}},
|
||||
'FirefoxDev': { unitTest: {target: null, required: true}, e2e: {target: null, required: true}},
|
||||
'IE9': { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
|
||||
'IE10': { unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
|
||||
'IE11': { unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
|
||||
'Edge': { unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
|
||||
'Android4.1': { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
|
||||
'Android4.2': { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
|
||||
'Android4.3': { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
|
||||
'Android4.4': { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
|
||||
'Android5': { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
|
||||
'Safari7': { unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
|
||||
'Safari8': { unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
|
||||
'Safari9': { unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
|
||||
'iOS7': { unitTest: {target: 'BS', required: true}, e2e: {target: null, required: true}},
|
||||
'iOS8': { unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
|
||||
// TODO(mlaval): iOS9 deactivated as not reliable, reactivate after https://github.com/angular/angular/issues/5408
|
||||
'iOS9': { unitTest: {target: null, required: false}, e2e: {target: null, required: true}},
|
||||
'WindowsPhone': { unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}}
|
||||
};
|
||||
|
||||
var customLaunchers = {
|
||||
'DartiumWithWebPlatform': {
|
||||
base: 'Dartium',
|
||||
@ -47,7 +77,7 @@ var customLaunchers = {
|
||||
platform: 'OS X 10.10',
|
||||
version: '8'
|
||||
},
|
||||
'SL_SAFARI9.0': {
|
||||
'SL_SAFARI9': {
|
||||
base: 'SauceLabs',
|
||||
browserName: 'safari',
|
||||
platform: 'OS X 10.11',
|
||||
@ -119,7 +149,7 @@ var customLaunchers = {
|
||||
platform: 'Linux',
|
||||
version: '4.4'
|
||||
},
|
||||
'SL_ANDROID5.1': {
|
||||
'SL_ANDROID5': {
|
||||
base: 'SauceLabs',
|
||||
browserName: 'android',
|
||||
platform: 'Linux',
|
||||
@ -239,21 +269,18 @@ var customLaunchers = {
|
||||
}
|
||||
};
|
||||
|
||||
// iOS9 deactivated as not reliable in both providers
|
||||
// TODO(mlaval): reactivate after https://github.com/angular/angular/issues/5408
|
||||
|
||||
var sauceAliases = {
|
||||
'ALL': Object.keys(customLaunchers).filter(function(item) {return customLaunchers[item].base == 'SauceLabs';}),
|
||||
'DESKTOP': ['SL_CHROME', 'SL_FIREFOX', 'SL_IE9', 'SL_IE10', 'SL_IE11', 'SL_EDGE', 'SL_SAFARI7', 'SL_SAFARI8', 'SL_SAFARI9.0'],
|
||||
'MOBILE': ['SL_ANDROID4.1', 'SL_ANDROID4.2', 'SL_ANDROID4.3', 'SL_ANDROID4.4', 'SL_ANDROID5.1', 'SL_IOS7', 'SL_IOS8', 'SL_IOS9'],
|
||||
'ANDROID': ['SL_ANDROID4.1', 'SL_ANDROID4.2', 'SL_ANDROID4.3', 'SL_ANDROID4.4', 'SL_ANDROID5.1'],
|
||||
'DESKTOP': ['SL_CHROME', 'SL_FIREFOX', 'SL_IE9', 'SL_IE10', 'SL_IE11', 'SL_EDGE', 'SL_SAFARI7', 'SL_SAFARI8', 'SL_SAFARI9'],
|
||||
'MOBILE': ['SL_ANDROID4.1', 'SL_ANDROID4.2', 'SL_ANDROID4.3', 'SL_ANDROID4.4', 'SL_ANDROID5', 'SL_IOS7', 'SL_IOS8', 'SL_IOS9'],
|
||||
'ANDROID': ['SL_ANDROID4.1', 'SL_ANDROID4.2', 'SL_ANDROID4.3', 'SL_ANDROID4.4', 'SL_ANDROID5'],
|
||||
'IE': ['SL_IE9', 'SL_IE10', 'SL_IE11'],
|
||||
'IOS': ['SL_IOS7', 'SL_IOS8', 'SL_IOS9'],
|
||||
'SAFARI': ['SL_SAFARI7', 'SL_SAFARI8', 'SL_SAFARI9.0'],
|
||||
'SAFARI': ['SL_SAFARI7', 'SL_SAFARI8', 'SL_SAFARI9'],
|
||||
'BETA': ['SL_CHROMEBETA', 'SL_FIREFOXBETA'],
|
||||
'DEV': ['SL_CHROMEDEV', 'SL_FIREFOXDEV'],
|
||||
'CI': ['SL_CHROME',' SL_FIREFOX', 'SL_CHROMEDEV', 'SL_FIREFOXBETA', 'SL_IE9', 'SL_IE10', 'SL_IE11', 'SL_EDGE',
|
||||
'SL_ANDROID4.1', 'SL_ANDROID4.2', 'SL_ANDROID4.3', 'SL_ANDROID4.4', 'SL_ANDROID5.1']
|
||||
'CI_REQUIRED': buildConfiguration('unitTest', 'SL', true),
|
||||
'CI_OPTIONAL': buildConfiguration('unitTest', 'SL', false)
|
||||
};
|
||||
|
||||
var browserstackAliases = {
|
||||
@ -264,7 +291,8 @@ var browserstackAliases = {
|
||||
'IE': ['BS_IE9', 'BS_IE10', 'BS_IE11'],
|
||||
'IOS': ['BS_IOS7', 'BS_IOS8', 'BS_IOS9'],
|
||||
'SAFARI': ['BS_SAFARI7', 'BS_SAFARI8', 'BS_SAFARI9'],
|
||||
'CI': ['BS_SAFARI7', 'BS_SAFARI8', 'BS_SAFARI9', 'BS_IOS7', 'BS_IOS8', 'BS_WINDOWSPHONE']
|
||||
'CI_REQUIRED': buildConfiguration('unitTest', 'BS', true),
|
||||
'CI_OPTIONAL': buildConfiguration('unitTest', 'BS', false)
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
@ -277,3 +305,14 @@ if (process.env.TRAVIS) {
|
||||
process.env.SAUCE_ACCESS_KEY = process.env.SAUCE_ACCESS_KEY.split('').reverse().join('');
|
||||
process.env.BROWSER_STACK_ACCESS_KEY = process.env.BROWSER_STACK_ACCESS_KEY.split('').reverse().join('');
|
||||
}
|
||||
|
||||
function buildConfiguration(type, target, required) {
|
||||
return Object.keys(CIconfiguration)
|
||||
.filter((item) => {
|
||||
var conf = CIconfiguration[item][type];
|
||||
return conf.required === required && conf.target === target;
|
||||
})
|
||||
.map((item) => {
|
||||
return target + '_' + item.toUpperCase();
|
||||
});
|
||||
}
|
||||
|
21
circle.yml
Normal file
21
circle.yml
Normal file
@ -0,0 +1,21 @@
|
||||
machine:
|
||||
node:
|
||||
version: 5.4.1
|
||||
|
||||
dependencies:
|
||||
pre:
|
||||
- npm install -g npm
|
||||
override:
|
||||
- npm install:
|
||||
environment:
|
||||
# Token for tsd to increase github rate limit
|
||||
# See https://github.com/DefinitelyTyped/tsd#tsdrc
|
||||
# This is not hidden using https://circleci.com/docs/fork-pr-builds#details
|
||||
# because those are not visible for pull requests, and those should also be reliable.
|
||||
# This SSO token belongs to github account angular-github-ratelimit-token which has no access
|
||||
# (password is in Valentine)
|
||||
TSD_GITHUB_TOKEN: ef474500309daea53d5991b3079159a29520a40b
|
||||
|
||||
test:
|
||||
override:
|
||||
- npm run build
|
482
gulpfile.js
482
gulpfile.js
@ -3,10 +3,10 @@
|
||||
// THIS CHECK SHOULD BE THE FIRST THING IN THIS FILE
|
||||
// This is to ensure that we catch env issues before we error while requiring other dependencies.
|
||||
require('./tools/check-environment')(
|
||||
{requiredNpmVersion: '>=2.14.7 <3.0.0', requiredNodeVersion: '>=4.2.1 <5.0.0'});
|
||||
{requiredNpmVersion: '>=3.5.3 <4.0.0', requiredNodeVersion: '>=5.4.1 <6.0.0'});
|
||||
|
||||
|
||||
var del = require('del');
|
||||
var fse = require('fs-extra');
|
||||
var gulp = require('gulp');
|
||||
var gulpPlugins = require('gulp-load-plugins')();
|
||||
var merge = require('merge');
|
||||
@ -40,9 +40,9 @@ if (cliArgs.projects) {
|
||||
cliArgs.projects.split(',').sort().join(',');
|
||||
}
|
||||
|
||||
// --projects=angular2,angular2_material => {angular2: true, angular2_material: true}
|
||||
// --projects=angular2 => {angular2: true}
|
||||
var allProjects =
|
||||
'angular1_router,angular2,angular2_material,benchmarks,benchmarks_external,benchpress,playground,bundle_deps';
|
||||
'angular1_router,angular2,benchmarks,benchmarks_external,benchpress,playground,payload_tests,bundle_deps';
|
||||
var cliArgsProjects = (cliArgs.projects || allProjects)
|
||||
.split(',')
|
||||
.reduce((map, projectName) => {
|
||||
@ -57,7 +57,7 @@ function printModulesWarning() {
|
||||
console.warn(
|
||||
"Pro Tip: Did you know that you can speed up your build by specifying project name(s)?");
|
||||
console.warn(" It's like pressing the turbo button in the old days, but better!");
|
||||
console.warn(" Examples: --project=angular2 or --project=angular2,angular2_material");
|
||||
console.warn(" Examples: --project=angular2 or --project=angular2");
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,7 +132,8 @@ var CONFIG = {
|
||||
dev: {es6: 'dist/js/dev/es6', es5: 'dist/js/dev/es5'},
|
||||
prod: {es6: 'dist/js/prod/es6', es5: 'dist/js/prod/es5'},
|
||||
cjs: 'dist/js/cjs',
|
||||
dart2js: 'dist/js/dart2js'
|
||||
dart2js: 'dist/js/dart2js',
|
||||
dart_dev_compiler: 'dist/js/ddc'
|
||||
},
|
||||
dart: 'dist/dart',
|
||||
docs: 'dist/docs',
|
||||
@ -155,7 +156,7 @@ var HTTP_BUNDLE_CONTENT = 'angular2/http - rxjs/* - ' + ANGULAR2_BUNDLE_CONFIG.j
|
||||
var ROUTER_BUNDLE_CONTENT = 'angular2/router + angular2/router/router_link_dsl - rxjs/* - ' +
|
||||
ANGULAR2_BUNDLE_CONFIG.join(' - ');
|
||||
var TESTING_BUNDLE_CONTENT =
|
||||
'angular2/testing + angular2/http/testing + angular2/router/testing - rxjs/* - ' +
|
||||
'angular2/testing + angular2/http/testing + angular2/router/testing + angular2/platform/testing/browser - rxjs/* - ' +
|
||||
ANGULAR2_BUNDLE_CONFIG.join(' - ');
|
||||
var UPGRADE_BUNDLE_CONTENT = 'angular2/upgrade - rxjs/* - ' + ANGULAR2_BUNDLE_CONFIG.join(' - ');
|
||||
|
||||
@ -168,24 +169,36 @@ var BENCHPRESS_BUNDLE_CONFIG = {
|
||||
dest: CONFIG.dest.bundles.benchpress
|
||||
};
|
||||
|
||||
var PAYLOAD_TESTS_CONFIG = {
|
||||
ts: {
|
||||
bundleName: 'app-bundle-deps.min.js',
|
||||
cases: ['hello_world'],
|
||||
dist: function(caseName, packaging) {
|
||||
return path.join(__dirname, CONFIG.dest.js.prod.es5, 'payload_tests', caseName,
|
||||
'ts/' + packaging);
|
||||
},
|
||||
systemjs: {sizeLimits: {'uncompressed': 850 * 1024, 'gzip level=9': 165 * 1024}},
|
||||
webpack: {sizeLimits: {'uncompressed': 550 * 1024, 'gzip level=9': 120 * 1024}}
|
||||
}
|
||||
};
|
||||
|
||||
// ------------
|
||||
// clean
|
||||
|
||||
gulp.task('build/clean.tools', function() { del(path.join('dist', 'tools')); });
|
||||
gulp.task('build/clean.tools', (done) => fse.remove(path.join('dist', 'tools'), done));
|
||||
|
||||
gulp.task('build/clean.js', function(done) { del(CONFIG.dest.js.all, done); });
|
||||
gulp.task('build/clean.js', (done) => fse.remove(CONFIG.dest.js.all, done));
|
||||
|
||||
gulp.task('build/clean.dart', function(done) { del(CONFIG.dest.dart, done); });
|
||||
gulp.task('build/clean.dart', (done) => fse.remove(CONFIG.dest.dart, done));
|
||||
|
||||
gulp.task('build/clean.docs', function(done) { del(CONFIG.dest.docs, done); });
|
||||
gulp.task('build/clean.docs', (done) => fse.remove(CONFIG.dest.docs, done));
|
||||
|
||||
gulp.task('build/clean.docs_angular_io',
|
||||
function(done) { del(CONFIG.dest.docs_angular_io, done); });
|
||||
gulp.task('build/clean.docs_angular_io', (done) => fse.remove(CONFIG.dest.docs_angular_io, done));
|
||||
|
||||
gulp.task('build/clean.bundles', function(done) { del(CONFIG.dest.bundles.all, done); });
|
||||
gulp.task('build/clean.bundles', (done) => fse.remove(CONFIG.dest.bundles.all, done));
|
||||
|
||||
gulp.task('build/clean.bundles.benchpress',
|
||||
function(done) { del(CONFIG.dest.bundles.benchpress, done); });
|
||||
(done) => fse.remove(CONFIG.dest.bundles.benchpress, done));
|
||||
|
||||
// ------------
|
||||
// transpile
|
||||
@ -313,7 +326,9 @@ gulp.task('lint', ['build.tools'], function() {
|
||||
"requireParameterType": true,
|
||||
"requireReturnType": true,
|
||||
"semicolon": true,
|
||||
"variable-name": [true, "ban-keywords"]
|
||||
|
||||
// TODO: find a way to just screen for reserved names
|
||||
"variable-name": false
|
||||
}
|
||||
};
|
||||
return gulp.src(['modules/angular2/src/**/*.ts', '!modules/angular2/src/testing/**'])
|
||||
@ -330,9 +345,8 @@ gulp.task('lint', ['build.tools'], function() {
|
||||
gulp.task('build/checkCircularDependencies', function(done) {
|
||||
var madge = require('madge');
|
||||
|
||||
var dependencyObject = madge(CONFIG.dest.js.dev.es5, {
|
||||
var dependencyObject = madge([CONFIG.dest.js.dev.es5], {
|
||||
format: 'cjs',
|
||||
paths: [CONFIG.dest.js.dev.es5],
|
||||
extensions: ['.js'],
|
||||
onParseFile: function(data) { data.src = data.src.replace(/\/\* circular \*\//g, "//"); }
|
||||
});
|
||||
@ -356,6 +370,10 @@ function jsServeDartJs() {
|
||||
return jsserve(gulp, gulpPlugins, {path: CONFIG.dest.js.dart2js, port: 8002})();
|
||||
}
|
||||
|
||||
function jsServeDartDevCompiler() {
|
||||
return jsserve(gulp, gulpPlugins, {path: CONFIG.dest.js.dart_dev_compiler, port: 8003})();
|
||||
}
|
||||
|
||||
function proxyServeDart() {
|
||||
return jsserve(gulp, gulpPlugins, {
|
||||
port: 8002,
|
||||
@ -369,7 +387,7 @@ function proxyServeDart() {
|
||||
|
||||
// ------------------
|
||||
// web servers
|
||||
gulp.task('serve.js.dev', ['build.js'], function(neverDone) {
|
||||
gulp.task('serve.js.dev', ['build.js.dev', 'build.js.cjs'], function(neverDone) {
|
||||
var watch = require('./tools/build/watch');
|
||||
|
||||
watch('modules/**', {ignoreInitial: true}, '!broccoli.js.dev');
|
||||
@ -378,24 +396,24 @@ gulp.task('serve.js.dev', ['build.js'], function(neverDone) {
|
||||
|
||||
gulp.task('serve.js.prod', jsServeProd);
|
||||
|
||||
gulp.task('serve.e2e.dev', ['build.js.dev', 'build.js.cjs', 'build.css.material'],
|
||||
function(neverDone) {
|
||||
var watch = require('./tools/build/watch');
|
||||
gulp.task('serve.e2e.dev', ['build.js.dev', 'build.js.cjs'], function(neverDone) {
|
||||
var watch = require('./tools/build/watch');
|
||||
|
||||
watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.dev', '!build.js.cjs']);
|
||||
jsServeDev();
|
||||
});
|
||||
watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.dev', '!build.js.cjs']);
|
||||
jsServeDev();
|
||||
});
|
||||
|
||||
gulp.task('serve.e2e.prod', ['build.js.prod', 'build.js.cjs', 'build.css.material'],
|
||||
function(neverDone) {
|
||||
var watch = require('./tools/build/watch');
|
||||
gulp.task('serve.e2e.prod', ['build.js.prod', 'build.js.cjs'], function(neverDone) {
|
||||
var watch = require('./tools/build/watch');
|
||||
|
||||
watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.prod', '!build.js.cjs']);
|
||||
jsServeProd();
|
||||
});
|
||||
watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.prod', '!build.js.cjs']);
|
||||
jsServeProd();
|
||||
});
|
||||
|
||||
gulp.task('serve.js.dart2js', jsServeDartJs);
|
||||
|
||||
gulp.task('serve.js.ddc', jsServeDartDevCompiler);
|
||||
|
||||
gulp.task('!proxyServeDart', proxyServeDart);
|
||||
|
||||
gulp.task('serve.dart', function(done) {
|
||||
@ -427,7 +445,7 @@ gulp.task('serve.e2e.dart', ['build.js.cjs'], function(neverDone) {
|
||||
|
||||
// Note: we are not using build.dart as the dart analyzer takes too long...
|
||||
watch('modules/**', {ignoreInitial: true}, ['!build/tree.dart', '!build.js.cjs']);
|
||||
runSequence('build/packages.dart', 'build/pubspec.dart', 'build.dart.material.css', 'serve.dart');
|
||||
runSequence('build/packages.dart', 'build/pubspec.dart', 'serve.dart');
|
||||
});
|
||||
|
||||
|
||||
@ -449,12 +467,12 @@ function runKarma(configFile, done) {
|
||||
|
||||
gulp.task('test.js', function(done) {
|
||||
runSequence('test.unit.tools/ci', 'test.transpiler.unittest', 'test.unit.js/ci',
|
||||
'test.unit.cjs/ci', 'test.typings', sequenceComplete(done));
|
||||
'test.unit.cjs/ci', 'test.typings', 'check-public-api', sequenceComplete(done));
|
||||
});
|
||||
|
||||
gulp.task('test.dart', function(done) {
|
||||
runSequence('versions.dart', 'test.transpiler.unittest', 'test.unit.dart/ci',
|
||||
'test.dart.angular2_testing/ci', sequenceComplete(done));
|
||||
sequenceComplete(done));
|
||||
});
|
||||
|
||||
gulp.task('versions.dart', function() { dartSdk.logVersion(DART_SDK); });
|
||||
@ -613,13 +631,16 @@ gulp.task('!test.unit.router/karma-run', function(done) {
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('buildRouter.dev', function() { buildRouter(); });
|
||||
gulp.task('buildRouter.dev', function() {
|
||||
var modulesSrcDir = __dirname + '/modules';
|
||||
var distDir = __dirname + '/dist';
|
||||
buildRouter(modulesSrcDir, distDir);
|
||||
});
|
||||
|
||||
gulp.task('test.unit.dart', function(done) {
|
||||
printModulesWarning();
|
||||
runSequence('build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart',
|
||||
'!build/change_detect.dart', '!build/remove-pub-symlinks', 'build.dart.material.css',
|
||||
'!test.unit.dart/karma-server', '!test.unit.dart/karma-run', function(error) {
|
||||
'!build/change_detect.dart', '!build/remove-pub-symlinks', function(error) {
|
||||
var watch = require('./tools/build/watch');
|
||||
|
||||
// if initial build failed (likely due to build or formatting step) then exit
|
||||
@ -628,9 +649,10 @@ gulp.task('test.unit.dart', function(done) {
|
||||
done(error);
|
||||
return;
|
||||
}
|
||||
// treatTestErrorsAsFatal = false;
|
||||
|
||||
watch(['modules/angular2/**'], {ignoreInitial: true},
|
||||
['!build/tree.dart', '!test.unit.dart/karma-run']);
|
||||
watch(['modules/angular2/**'],
|
||||
['!build/tree.dart', '!test.unit.dart/run/angular2']);
|
||||
});
|
||||
});
|
||||
|
||||
@ -638,7 +660,7 @@ gulp.task('test.unit.dart', function(done) {
|
||||
// This test will fail if the size of our hello_world app goes beyond one of
|
||||
// these values when compressed at the specified level.
|
||||
// Measure in bytes.
|
||||
var _DART_PAYLOAD_SIZE_LIMITS = {'uncompressed': 375 * 1024, 'gzip level=6': 105 * 1024};
|
||||
var _DART_PAYLOAD_SIZE_LIMITS = {'uncompressed': 320 * 1024, 'gzip level=9': 90 * 1024};
|
||||
gulp.task('test.payload.dart/ci', function(done) {
|
||||
runSequence('build/packages.dart', '!pubget.payload.dart', '!pubbuild.payload.dart',
|
||||
'!checkAndReport.payload.dart', done);
|
||||
@ -658,10 +680,106 @@ gulp.task('!checkAndReport.payload.dart', function() {
|
||||
{failConditions: _DART_PAYLOAD_SIZE_LIMITS, prefix: 'hello_world'});
|
||||
});
|
||||
|
||||
// JS payload size tracking
|
||||
gulp.task('test.payload.js/ci', function(done) {
|
||||
runSequence('build.payload.js', '!checkAndReport.payload.js', sequenceComplete(done));
|
||||
});
|
||||
|
||||
gulp.task('build.payload.js', ['build.js'], function(done) {
|
||||
runSequence('!build.payload.js.webpack', '!build.payload.js.systemjs', sequenceComplete(done));
|
||||
});
|
||||
|
||||
gulp.task('!build.payload.js.webpack', function() {
|
||||
var q = require('q');
|
||||
var webpack = q.denodeify(require('webpack'));
|
||||
|
||||
var ES5_PROD_ROOT = __dirname + '/' + CONFIG.dest.js.prod.es5;
|
||||
|
||||
return q.all(PAYLOAD_TESTS_CONFIG.ts.cases.map(function(caseName) {
|
||||
var CASE_PATH = PAYLOAD_TESTS_CONFIG.ts.dist(caseName, 'webpack');
|
||||
|
||||
return webpack({
|
||||
// bundle app + framework
|
||||
entry: CASE_PATH + '/index.js',
|
||||
output: {path: CASE_PATH, filename: "app-bundle.js"},
|
||||
resolve: {
|
||||
extensions: ['', '.js'],
|
||||
packageAlias: '', // option added to ignore "broken" package.json in our dist folder
|
||||
root: [ES5_PROD_ROOT]
|
||||
}
|
||||
})
|
||||
.then(function() { // pad bundle with mandatory dependencies
|
||||
return new Promise(function(resolve, reject) {
|
||||
gulp.src([
|
||||
'node_modules/zone.js/dist/zone.js',
|
||||
'node_modules/zone.js/dist/long-stack-trace-zone.js',
|
||||
'node_modules/reflect-metadata/Reflect.js',
|
||||
CASE_PATH + '/app-bundle.js'
|
||||
])
|
||||
.pipe(gulpPlugins.concat(PAYLOAD_TESTS_CONFIG.ts.bundleName))
|
||||
.pipe(gulpPlugins.uglify())
|
||||
.pipe(gulp.dest(CASE_PATH))
|
||||
.on('end', resolve)
|
||||
.on('error', reject);
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
gulp.task('!build.payload.js.systemjs', function() {
|
||||
var bundler = require('./tools/build/bundle');
|
||||
|
||||
return Promise.all(PAYLOAD_TESTS_CONFIG.ts.cases.map(function(caseName) {
|
||||
var CASE_PATH = PAYLOAD_TESTS_CONFIG.ts.dist(caseName, 'systemjs');
|
||||
|
||||
return bundler
|
||||
.bundle(
|
||||
{
|
||||
paths: {'index': CASE_PATH + '/index.js'},
|
||||
meta: {'angular2/core': {build: false}, 'angular2/platform/browser': {build: false}}
|
||||
},
|
||||
'index', CASE_PATH + '/index.register.js', {})
|
||||
.then(function() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
gulp.src([
|
||||
'node_modules/systemjs/dist/system.src.js',
|
||||
'dist/js/prod/es5/bundle/angular2-polyfills.js',
|
||||
'dist/js/prod/es5/bundle/angular2.js',
|
||||
'dist/js/prod/es5//rxjs/bundles/Rx.js',
|
||||
CASE_PATH + '/index.register.js',
|
||||
'tools/build/systemjs/payload_tests_import.js'
|
||||
])
|
||||
.pipe(gulpPlugins.concat(PAYLOAD_TESTS_CONFIG.ts.bundleName))
|
||||
.pipe(gulpPlugins.uglify())
|
||||
.pipe(gulp.dest(CASE_PATH))
|
||||
.on('end', resolve)
|
||||
.on('error', reject);
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
gulp.task('!checkAndReport.payload.js', function() {
|
||||
var reportSize = require('./tools/analytics/reportsize');
|
||||
|
||||
function caseSizeStream(caseName, packaging) {
|
||||
return reportSize(PAYLOAD_TESTS_CONFIG.ts.dist(caseName, packaging) + '/' +
|
||||
PAYLOAD_TESTS_CONFIG.ts.bundleName,
|
||||
{
|
||||
failConditions: PAYLOAD_TESTS_CONFIG.ts[packaging].sizeLimits,
|
||||
prefix: caseName + '_' + packaging
|
||||
})
|
||||
}
|
||||
|
||||
return PAYLOAD_TESTS_CONFIG.ts.cases.reduce(function(sizeReportingStreams, caseName) {
|
||||
sizeReportingStreams.add(caseSizeStream(caseName, 'systemjs'));
|
||||
sizeReportingStreams.add(caseSizeStream(caseName, 'webpack'));
|
||||
}, merge2());
|
||||
});
|
||||
|
||||
gulp.task('watch.dart.dev', function(done) {
|
||||
runSequence('build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart',
|
||||
'!build/change_detect.dart', '!build/remove-pub-symlinks', 'build.dart.material.css',
|
||||
function(error) {
|
||||
'!build/change_detect.dart', '!build/remove-pub-symlinks', function(error) {
|
||||
var watch = require('./tools/build/watch');
|
||||
|
||||
// if initial build failed (likely due to build or formatting step) then exit
|
||||
@ -675,20 +793,6 @@ gulp.task('watch.dart.dev', function(done) {
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('!test.unit.dart/karma-run', function(done) {
|
||||
// run the run command in a new process to avoid duplicate logging by both server and runner from
|
||||
// a single process
|
||||
runKarma('karma-dart.conf.js', done);
|
||||
});
|
||||
|
||||
|
||||
gulp.task('!test.unit.dart/karma-server', function() {
|
||||
var karma = require('karma');
|
||||
|
||||
new karma.Server({configFile: __dirname + '/karma-dart.conf.js', reporters: 'dots'}).start();
|
||||
});
|
||||
|
||||
|
||||
gulp.task('test.unit.router/ci', function(done) {
|
||||
var karma = require('karma');
|
||||
|
||||
@ -715,39 +819,84 @@ gulp.task('test.unit.js/ci', function(done) {
|
||||
reporters: ['dots'],
|
||||
browsers: browserConf.browsersToRun
|
||||
},
|
||||
done)
|
||||
function(err) { done(); })
|
||||
.start();
|
||||
});
|
||||
|
||||
gulp.task('test.unit.js.sauce/ci', function(done) {
|
||||
launchKarmaWithExternalBrowsers(['dots', 'saucelabs'], browserProvidersConf.sauceAliases.CI,
|
||||
done);
|
||||
var browsers = browserProvidersConf.sauceAliases.CI_REQUIRED;
|
||||
if (cliArgs.mode && cliArgs.mode == 'saucelabs_optional') {
|
||||
browsers = browserProvidersConf.sauceAliases.CI_OPTIONAL;
|
||||
}
|
||||
launchKarmaWithExternalBrowsers(['dots', 'saucelabs'], browsers, done);
|
||||
});
|
||||
|
||||
gulp.task('test.unit.js.browserstack/ci', function(done) {
|
||||
launchKarmaWithExternalBrowsers(['dots'], browserProvidersConf.browserstackAliases.CI, done);
|
||||
var browsers = browserProvidersConf.browserstackAliases.CI_REQUIRED;
|
||||
if (cliArgs.mode && cliArgs.mode == 'browserstack_optional') {
|
||||
browsers = browserProvidersConf.browserstackAliases.CI_OPTIONAL;
|
||||
}
|
||||
launchKarmaWithExternalBrowsers(['dots'], browsers, done);
|
||||
});
|
||||
|
||||
gulp.task('test.unit.dart/ci', function(done) {
|
||||
var karma = require('karma');
|
||||
|
||||
var browserConf = getBrowsersFromCLI(null, true);
|
||||
new karma.Server(
|
||||
{
|
||||
configFile: __dirname + '/karma-dart.conf.js',
|
||||
singleRun: true,
|
||||
reporters: ['dots'],
|
||||
browsers: browserConf.browsersToRun
|
||||
},
|
||||
done)
|
||||
.start();
|
||||
runSequence('test.dart.dartium_symlink', '!test.unit.dart/run/angular2',
|
||||
'!test.unit.dart/run/angular2_testing', '!test.unit.dart/run/benchpress',
|
||||
sequenceComplete(done));
|
||||
});
|
||||
|
||||
// At the moment, dart test requires dartium to be an executable on the path.
|
||||
// Make a temporary directory and symlink dartium from there (just for this command)
|
||||
// so that it can run.
|
||||
// TODO(juliemr): this won't work with windows - remove the hack and make this platform agnostic.
|
||||
var dartiumTmpdir = path.join(os.tmpdir(), 'dartium' + new Date().getTime().toString());
|
||||
var dartiumPathPrefix = 'PATH=$PATH:' + dartiumTmpdir + ' ';
|
||||
gulp.task(
|
||||
'test.dart.dartium_symlink',
|
||||
shell.task(['mkdir ' + dartiumTmpdir, 'ln -s $DARTIUM_BIN ' + dartiumTmpdir + '/dartium']));
|
||||
|
||||
gulp.task('!test.unit.dart/run/angular2', function() {
|
||||
var pubtest = require('./tools/build/pubtest');
|
||||
return pubtest({
|
||||
dir: path.join(CONFIG.dest.dart, 'angular2'),
|
||||
dartiumTmpdir: dartiumTmpdir,
|
||||
command: DART_SDK.PUB,
|
||||
files: '**/*_spec.dart',
|
||||
bunchFiles: true,
|
||||
useExclusiveTests: true
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('!test.unit.dart/run/angular2_testing', function() {
|
||||
var pubtest = require('./tools/build/pubtest');
|
||||
|
||||
return pubtest({
|
||||
dir: path.join(CONFIG.dest.dart, 'angular2_testing'),
|
||||
dartiumTmpdir: dartiumTmpdir,
|
||||
command: DART_SDK.PUB,
|
||||
files: '**/*_test.dart',
|
||||
useExclusiveTests: true
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('!test.unit.dart/run/benchpress', function() {
|
||||
var pubtest = require('./tools/build/pubtest');
|
||||
|
||||
return pubtest({
|
||||
dir: path.join(CONFIG.dest.dart, 'benchpress'),
|
||||
dartiumTmpdir: dartiumTmpdir,
|
||||
command: DART_SDK.PUB,
|
||||
files: '**/*_spec.dart',
|
||||
useExclusiveTests: true
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('test.unit.cjs/ci', function(done) {
|
||||
runJasmineTests(['dist/js/cjs/{angular2,benchpress}/test/**/*_spec.js'], done);
|
||||
});
|
||||
|
||||
gulp.task('check-public-api',
|
||||
function(done) { runJasmineTests(['dist/tools/public_api_guard/**/*_spec.js'], done); });
|
||||
|
||||
gulp.task('test.unit.cjs', ['build/clean.js', 'build.tools'], function(neverDone) {
|
||||
var watch = require('./tools/build/watch');
|
||||
@ -807,24 +956,6 @@ gulp.task('test.server.dart', runServerDartTests(gulp, gulpPlugins, {dest: 'dist
|
||||
gulp.task('test.transpiler.unittest',
|
||||
function(done) { runJasmineTests(['tools/transpiler/unittest/**/*.js'], done); });
|
||||
|
||||
// At the moment, dart test requires dartium to be an executable on the path.
|
||||
// Make a temporary directory and symlink dartium from there (just for this command)
|
||||
// so that it can run.
|
||||
var dartiumTmpdir = path.join(os.tmpdir(), 'dartium' + new Date().getTime().toString());
|
||||
gulp.task('test.dart.angular2_testing/ci', ['build/pubspec.dart'], function(done) {
|
||||
runSequence('test.dart.angular2_testing_symlink', 'test.dart.angular2_testing',
|
||||
sequenceComplete(done));
|
||||
});
|
||||
|
||||
gulp.task(
|
||||
'test.dart.angular2_testing_symlink',
|
||||
shell.task(['mkdir ' + dartiumTmpdir, 'ln -s $DARTIUM_BIN ' + dartiumTmpdir + '/dartium']));
|
||||
|
||||
gulp.task('test.dart.angular2_testing',
|
||||
shell.task(['PATH=$PATH:' + dartiumTmpdir + ' pub run test -p dartium'],
|
||||
{'cwd': 'dist/dart/angular2_testing'}));
|
||||
|
||||
|
||||
// -----------------
|
||||
// Pre-test checks
|
||||
|
||||
@ -853,19 +984,37 @@ gulp.task('static-checks', ['!build.tools'], function(done) {
|
||||
// Make sure the two typings tests are isolated, by running this one in a tempdir
|
||||
var tmpdir = path.join(os.tmpdir(), 'test.typings', new Date().getTime().toString());
|
||||
gulp.task('!pre.test.typings.layoutNodeModule', ['build.js.cjs'], function() {
|
||||
return gulp.src(['dist/js/cjs/angular2/**/*', 'node_modules/rxjs/**'], {base: 'dist/js/cjs'})
|
||||
return gulp.src(['dist/js/cjs/angular2/**/*', 'node_modules/rxjs/**/*'], {base: 'dist/js/cjs'})
|
||||
.pipe(gulp.dest(path.join(tmpdir, 'node_modules')));
|
||||
});
|
||||
gulp.task('!pre.test.typings.copyTypingsSpec', function() {
|
||||
return gulp.src(['typing_spec/*.ts'], {base: 'typing_spec'}).pipe(gulp.dest(path.join(tmpdir)));
|
||||
|
||||
gulp.task('!pre.test.typings.copyDeps', function() {
|
||||
return gulp.src(
|
||||
[
|
||||
'modules/angular2/typings/angular-protractor/*.ts',
|
||||
'modules/angular2/typings/jasmine/*.ts',
|
||||
'modules/angular2/typings/selenium-webdriver/*.ts',
|
||||
],
|
||||
{base: 'modules/angular2/typings'})
|
||||
.pipe(gulp.dest(tmpdir));
|
||||
});
|
||||
|
||||
gulp.task('!pre.test.typings.copyTypingsSpec', function() {
|
||||
return gulp.src(['modules/angular2/examples/**/*.ts']).pipe(gulp.dest(tmpdir));
|
||||
});
|
||||
|
||||
gulp.task('test.typings',
|
||||
['!pre.test.typings.layoutNodeModule', '!pre.test.typings.copyTypingsSpec'], function() {
|
||||
[
|
||||
'!pre.test.typings.layoutNodeModule',
|
||||
'!pre.test.typings.copyTypingsSpec',
|
||||
'!pre.test.typings.copyDeps'
|
||||
],
|
||||
function() {
|
||||
var tsc = require('gulp-typescript');
|
||||
|
||||
return gulp.src([tmpdir + '/**'])
|
||||
return gulp.src([tmpdir + '/**/*.ts', '!' + tmpdir + '/node_modules/**/*'])
|
||||
.pipe(tsc({
|
||||
target: 'ES5',
|
||||
target: 'ES6',
|
||||
module: 'commonjs',
|
||||
experimentalDecorators: true,
|
||||
noImplicitAny: true,
|
||||
@ -893,30 +1042,27 @@ gulp.task('build/pure-packages.dart/standalone', function() {
|
||||
'modules_dart/**/*',
|
||||
'!modules_dart/**/*.proto',
|
||||
'!modules_dart/**/packages{,/**}',
|
||||
'!modules_dart/**/.packages',
|
||||
'!modules_dart/payload{,/**}',
|
||||
'!modules_dart/transform{,/**}',
|
||||
])
|
||||
.pipe(gulp.dest(CONFIG.dest.dart));
|
||||
});
|
||||
|
||||
gulp.task('build/pure-packages.dart/license',
|
||||
function() {
|
||||
return gulp.src(['LICENSE'])
|
||||
.pipe(gulp.dest(path.join(CONFIG.dest.dart, 'angular2_testing')));
|
||||
})
|
||||
gulp.task('build/pure-packages.dart/license', function() {
|
||||
return gulp.src(['LICENSE']).pipe(gulp.dest(path.join(CONFIG.dest.dart, 'angular2_testing')));
|
||||
});
|
||||
|
||||
|
||||
gulp.task('build/pure-packages.dart/angular2', function() {
|
||||
var yaml = require('js-yaml');
|
||||
|
||||
return gulp.src([
|
||||
'modules_dart/transform/**/*',
|
||||
'!modules_dart/transform/**/*.proto',
|
||||
'!modules_dart/transform/pubspec.yaml',
|
||||
'!modules_dart/transform/**/packages{,/**}',
|
||||
])
|
||||
.pipe(gulp.dest(path.join(CONFIG.dest.dart, 'angular2')));
|
||||
});
|
||||
gulp.task('build/pure-packages.dart/angular2', function() {
|
||||
return gulp.src([
|
||||
'modules_dart/transform/**/*',
|
||||
'!modules_dart/transform/**/*.proto',
|
||||
'!modules_dart/transform/pubspec.yaml',
|
||||
'!modules_dart/transform/**/packages{,/**}',
|
||||
])
|
||||
.pipe(gulp.dest(path.join(CONFIG.dest.dart, 'angular2')));
|
||||
});
|
||||
|
||||
// Builds all Dart packages, but does not compile them
|
||||
gulp.task('build/packages.dart', function(done) {
|
||||
@ -928,7 +1074,7 @@ gulp.task('build/packages.dart', function(done) {
|
||||
// Builds and compiles all Dart packages
|
||||
gulp.task('build.dart', function(done) {
|
||||
runSequence('build/packages.dart', 'build/pubspec.dart', 'build/analyze.dart',
|
||||
'build/check.apidocs.dart', 'build.dart.material.css', sequenceComplete(done));
|
||||
'build/check.apidocs.dart', sequenceComplete(done));
|
||||
});
|
||||
|
||||
|
||||
@ -947,25 +1093,26 @@ gulp.task('!build.tools', function() {
|
||||
.pipe(tsc({
|
||||
target: 'ES5',
|
||||
module: 'commonjs',
|
||||
declaration: true,
|
||||
// Don't use the version of typescript that gulp-typescript depends on
|
||||
// see https://github.com/ivogabe/gulp-typescript#typescript-version
|
||||
typescript: require('typescript')
|
||||
}))
|
||||
.on('error',
|
||||
function(error) {
|
||||
// nodejs doesn't propagate errors from the src stream into the final
|
||||
// stream so we are
|
||||
// forwarding the error into the final stream
|
||||
stream.emit('error', error);
|
||||
})
|
||||
.pipe(sourcemaps.write('.'))
|
||||
.pipe(gulp.dest('dist/tools'))
|
||||
.on('end', function() {
|
||||
var AngularBuilder =
|
||||
require('./dist/tools/broccoli/angular_builder').AngularBuilder;
|
||||
angularBuilder =
|
||||
new AngularBuilder({outputPath: 'dist', dartSDK: DART_SDK, logs: logs});
|
||||
});
|
||||
}));
|
||||
stream =
|
||||
merge2([stream.js.pipe(gulp.dest('dist/tools')), stream.dts.pipe(gulp.dest('dist/tools'))])
|
||||
.on('error',
|
||||
function(error) {
|
||||
// nodejs doesn't propagate errors from the src stream into the final
|
||||
// stream so we are
|
||||
// forwarding the error into the final stream
|
||||
stream.emit('error', error);
|
||||
})
|
||||
.pipe(sourcemaps.write('.'))
|
||||
.on('end', function() {
|
||||
var AngularBuilder = require('./dist/tools/broccoli/angular_builder').AngularBuilder;
|
||||
angularBuilder =
|
||||
new AngularBuilder({outputPath: 'dist', dartSDK: DART_SDK, logs: logs});
|
||||
});
|
||||
|
||||
return stream;
|
||||
});
|
||||
@ -973,19 +1120,22 @@ gulp.task('!build.tools', function() {
|
||||
gulp.task('broccoli.js.dev', ['build.tools'],
|
||||
function(done) { runSequence('!broccoli.js.dev', sequenceComplete(done)); });
|
||||
|
||||
gulp.task(
|
||||
'!broccoli.js.dev',
|
||||
() => angularBuilder.rebuildBrowserDevTree(
|
||||
{generateEs6: generateEs6, projects: cliArgsProjects, noTypeChecks: cliArgs.noTypeChecks}));
|
||||
gulp.task('!broccoli.js.dev', () => angularBuilder.rebuildBrowserDevTree({
|
||||
generateEs6: generateEs6,
|
||||
projects: cliArgsProjects,
|
||||
noTypeChecks: cliArgs.noTypeChecks,
|
||||
useBundles: cliArgs.useBundles
|
||||
}));
|
||||
|
||||
gulp.task(
|
||||
'!broccoli.js.prod',
|
||||
() => angularBuilder.rebuildBrowserProdTree(
|
||||
{generateEs6: generateEs6, projects: cliArgsProjects, noTypeChecks: cliArgs.noTypeChecks}));
|
||||
gulp.task('!broccoli.js.prod', () => angularBuilder.rebuildBrowserProdTree({
|
||||
generateEs6: generateEs6,
|
||||
projects: cliArgsProjects,
|
||||
noTypeChecks: cliArgs.noTypeChecks,
|
||||
useBundles: cliArgs.useBundles
|
||||
}));
|
||||
|
||||
gulp.task('build.js.dev', ['build/clean.js'], function(done) {
|
||||
runSequence('broccoli.js.dev', 'build.css.material', sequenceComplete(done));
|
||||
});
|
||||
gulp.task('build.js.dev', ['build/clean.js'],
|
||||
function(done) { runSequence('broccoli.js.dev', sequenceComplete(done)); });
|
||||
|
||||
gulp.task('build.js.prod', ['build.tools'],
|
||||
function(done) { runSequence('!broccoli.js.prod', sequenceComplete(done)); });
|
||||
@ -1004,9 +1154,12 @@ var firstBuildJsCjs = true;
|
||||
* private task
|
||||
*/
|
||||
gulp.task('!build.js.cjs', function() {
|
||||
return angularBuilder
|
||||
.rebuildNodeTree(
|
||||
{generateEs6: generateEs6, projects: cliArgsProjects, noTypeChecks: cliArgs.noTypeChecks})
|
||||
return angularBuilder.rebuildNodeTree({
|
||||
generateEs6: generateEs6,
|
||||
projects: cliArgsProjects,
|
||||
noTypeChecks: cliArgs.noTypeChecks,
|
||||
useBundles: cliArgs.useBundles
|
||||
})
|
||||
.then(function() {
|
||||
if (firstBuildJsCjs) {
|
||||
firstBuildJsCjs = false;
|
||||
@ -1113,8 +1266,8 @@ gulp.task('!bundle.testing', ['build.js.dev'], function() {
|
||||
{sourceMaps: true});
|
||||
});
|
||||
|
||||
gulp.task('!bundles.js.docs', function() {
|
||||
gulp.src('modules/angular2/docs/bundles/*').pipe(gulp.dest('dist/js/bundle'));
|
||||
gulp.task('!bundles.js.docs', ['clean'], function() {
|
||||
return gulp.src('modules/angular2/docs/bundles/*').pipe(gulp.dest('dist/js/bundle'));
|
||||
});
|
||||
|
||||
gulp.task('!bundles.js.umd', ['build.js.dev'], function() {
|
||||
@ -1223,7 +1376,7 @@ gulp.task('!bundle.ng.polyfills', ['clean'],
|
||||
|
||||
var JS_DEV_DEPS = [
|
||||
licenseWrap('node_modules/zone.js/LICENSE', true),
|
||||
'node_modules/zone.js/dist/zone-microtask.js',
|
||||
'node_modules/zone.js/dist/zone.js',
|
||||
'node_modules/zone.js/dist/long-stack-trace-zone.js',
|
||||
licenseWrap('node_modules/reflect-metadata/LICENSE', true),
|
||||
'node_modules/reflect-metadata/Reflect.js'
|
||||
@ -1262,7 +1415,7 @@ gulp.task('!bundle.copy', function() {
|
||||
|
||||
gulp.task('!bundles.js.checksize', function(done) {
|
||||
var reportSize = require('./tools/analytics/reportsize');
|
||||
return reportSize('dist/js/bundle/**', {printToConsole: ['gzip level=2']});
|
||||
return reportSize('dist/js/bundle/**/*.js', {printToConsole: ['gzip level=2']});
|
||||
});
|
||||
|
||||
gulp.task('bundles.js',
|
||||
@ -1339,41 +1492,6 @@ gulp.task('!build/change_detect.dart', function(done) {
|
||||
});
|
||||
|
||||
// ------------
|
||||
// angular material testing rules
|
||||
gulp.task('build.css.material', function() {
|
||||
var autoprefixer = require('gulp-autoprefixer');
|
||||
var sass = require('gulp-sass');
|
||||
|
||||
return gulp.src('modules/*/src/**/*.scss')
|
||||
.pipe(sass())
|
||||
.pipe(autoprefixer())
|
||||
.pipe(gulp.dest(CONFIG.dest.js.prod.es5))
|
||||
.pipe(gulp.dest(CONFIG.dest.js.dev.es5))
|
||||
.pipe(gulp.dest(CONFIG.dest.js.dart2js + '/examples/packages'));
|
||||
});
|
||||
|
||||
|
||||
gulp.task('build.js.material', function(done) {
|
||||
runSequence('build.js.dev', 'build.css.material', sequenceComplete(done));
|
||||
});
|
||||
|
||||
gulp.task('build.dart2js.material', function(done) {
|
||||
runSequence('build.dart', 'build.css.material', sequenceComplete(done));
|
||||
});
|
||||
|
||||
gulp.task('build.dart.material.css', function() {
|
||||
var autoprefixer = require('gulp-autoprefixer');
|
||||
var sass = require('gulp-sass');
|
||||
|
||||
return gulp.src('dist/dart/angular2_material/src/**/*.scss')
|
||||
.pipe(sass())
|
||||
.pipe(autoprefixer())
|
||||
.pipe(gulp.dest('dist/dart/angular2_material/lib/src'));
|
||||
});
|
||||
|
||||
gulp.task('build.dart.material', ['build/packages.dart'], function(done) {
|
||||
runSequence('build/packages.dart', 'build.dart.material.css', sequenceComplete(done));
|
||||
});
|
||||
|
||||
gulp.task('cleanup.builder', function() { return angularBuilder.cleanup(); });
|
||||
|
||||
|
@ -1,86 +0,0 @@
|
||||
// This module provides a customFileHandler for karma
|
||||
// that serves files with urls like /packages_<timestamp>/...
|
||||
// with maximum cache.
|
||||
// We are using these urls when we spawn isolates
|
||||
// so that the isolates don't reload files every time.
|
||||
|
||||
var common = require('karma/lib/middleware/common');
|
||||
var fs = require('fs');
|
||||
|
||||
var DART_EVAL_PATH_RE = /.*\/packages_\d+\/(.*)$/;
|
||||
|
||||
module.exports = createFactory;
|
||||
|
||||
function createFactory(proxyPaths) {
|
||||
return {
|
||||
'framework:dart-evalcache': ['factory', dartEvalCacheFactory]
|
||||
};
|
||||
|
||||
function dartEvalCacheFactory(emitter, logger, customFileHandlers) {
|
||||
var filesPromise = new common.PromiseContainer();
|
||||
emitter.on('file_list_modified', function(files) {
|
||||
filesPromise.set(Promise.resolve(files));
|
||||
});
|
||||
|
||||
var serveFile = common.createServeFile(fs);
|
||||
var log = logger.create('dart-evalcache');
|
||||
|
||||
customFileHandlers.push({
|
||||
urlRegex: DART_EVAL_PATH_RE,
|
||||
handler: handler
|
||||
});
|
||||
|
||||
// See source_files handler
|
||||
function handler(request, response, fa, fb, basePath) {
|
||||
return filesPromise.then(function(files) {
|
||||
try {
|
||||
var requestedFilePath = mapUrlToFile(request.url, proxyPaths, basePath, log);
|
||||
// TODO(vojta): change served to be a map rather then an array
|
||||
var file = findByPath(files.served, requestedFilePath);
|
||||
if (file) {
|
||||
serveFile(file.contentPath || file.path, response, function() {
|
||||
common.setHeavyCacheHeaders(response);
|
||||
}, file.content);
|
||||
} else {
|
||||
response.writeHead(404);
|
||||
response.end('Not found');
|
||||
}
|
||||
} catch (e) {
|
||||
log.error(e.stack);
|
||||
response.writeHead(500);
|
||||
response.end('Error', e.stack);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function mapUrlToFile(url, proxyPaths, basePath, log) {
|
||||
var originalUrl = url;
|
||||
url = url.indexOf('?') > -1 ? url.substring(0, url.indexOf('?')) : url;
|
||||
var match = DART_EVAL_PATH_RE.exec(url);
|
||||
var packagePath = match[1];
|
||||
var result = null;
|
||||
var lastProxyFromLength = 0;
|
||||
Object.keys(proxyPaths).forEach(function(proxyFrom) {
|
||||
if (startsWith(packagePath, proxyFrom) && proxyFrom.length > lastProxyFromLength) {
|
||||
lastProxyFromLength = proxyFrom.length;
|
||||
result = proxyPaths[proxyFrom] + packagePath.substring(proxyFrom.length);
|
||||
}
|
||||
});
|
||||
return basePath + '/' + result;
|
||||
}
|
||||
|
||||
function startsWith(string, subString) {
|
||||
return string.length >= subString.length && string.slice(0, subString.length) === subString;
|
||||
}
|
||||
|
||||
function findByPath(files, path) {
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
if (files[i].path === path) {
|
||||
return files[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
var browserProvidersConf = require('./browser-providers.conf.js');
|
||||
|
||||
var packageSources = {
|
||||
// Dependencies installed with `pub install`.
|
||||
'unittest': 'packages/unittest',
|
||||
'guinness': 'packages/guinness',
|
||||
'matcher': 'packages/matcher',
|
||||
'stack_trace': 'packages/stack_trace',
|
||||
'collection': 'packages/collection',
|
||||
'path': 'packages/path',
|
||||
'observe': 'packages/observe',
|
||||
'quiver': 'packages/quiver',
|
||||
'intl': 'packages/intl',
|
||||
'smoke': 'packages/smoke',
|
||||
'logging': 'packages/logging',
|
||||
'utf': 'packages/utf',
|
||||
|
||||
// Local dependencies, transpiled from the source.
|
||||
'angular2': 'dist/dart/angular2/lib',
|
||||
'angular2/test/': 'dist/dart/angular2/test/',
|
||||
'http': 'dist/dart/http/lib',
|
||||
'angular2_material': 'dist/dart/angular2_material/lib',
|
||||
'benchpress': 'dist/dart/benchpress/lib',
|
||||
'examples': 'dist/dart/examples/lib'
|
||||
};
|
||||
|
||||
var proxyPaths = {};
|
||||
Object.keys(packageSources).map(function(packageName) {
|
||||
var filePath = packageSources[packageName];
|
||||
proxyPaths['/packages/'+packageName] = '/base/'+filePath;
|
||||
});
|
||||
|
||||
// Karma configuration
|
||||
// Generated on Thu Sep 25 2014 11:52:02 GMT-0700 (PDT)
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
|
||||
frameworks: ['dart-unittest', 'dart-evalcache'],
|
||||
|
||||
files: [
|
||||
// Init and configure guiness.
|
||||
{pattern: 'test-init.dart', included: true},
|
||||
// Unit test files needs to be included.
|
||||
{pattern: 'dist/dart/**/*_spec.dart', included: true, watched: false},
|
||||
|
||||
// Karma-dart via the dart-unittest framework generates
|
||||
// `__adapter_unittest.dart` that imports these files.
|
||||
{pattern: 'dist/dart/**', included: false, watched: false},
|
||||
|
||||
// Dependencies, installed with `pub install`.
|
||||
{pattern: 'packages/**/*.dart', included: false, watched: false},
|
||||
|
||||
// Init and configure guiness.
|
||||
{pattern: 'test-main.dart', included: true},
|
||||
{pattern: 'modules/**/test/**/static_assets/**', included: false, watched: false},
|
||||
],
|
||||
|
||||
exclude: [
|
||||
'dist/dart/**/packages/**',
|
||||
'modules/angular1_router/**'
|
||||
],
|
||||
|
||||
karmaDartImports: {
|
||||
guinness: 'package:guinness/guinness_html.dart'
|
||||
},
|
||||
|
||||
// Map packages to the correct urls where Karma serves them.
|
||||
proxies: proxyPaths,
|
||||
|
||||
customLaunchers: browserProvidersConf.customLaunchers,
|
||||
browsers: ['DartiumWithWebPlatform'],
|
||||
|
||||
port: 9877,
|
||||
|
||||
plugins: [
|
||||
require('karma-dart'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-sauce-launcher'),
|
||||
require('./karma-dart-evalcache')(packageSources)
|
||||
]
|
||||
});
|
||||
};
|
@ -17,8 +17,7 @@ module.exports = function(config) {
|
||||
// include Angular v1 for upgrade module testing
|
||||
'node_modules/angular/angular.min.js',
|
||||
|
||||
// zone-microtask must be included first as it contains a Promise monkey patch
|
||||
'node_modules/zone.js/dist/zone-microtask.js',
|
||||
'node_modules/zone.js/dist/zone.js',
|
||||
'node_modules/zone.js/dist/long-stack-trace-zone.js',
|
||||
'node_modules/zone.js/dist/jasmine-patch.js',
|
||||
|
||||
@ -79,7 +78,7 @@ module.exports = function(config) {
|
||||
|
||||
if (process.env.TRAVIS) {
|
||||
var buildId = 'TRAVIS #' + process.env.TRAVIS_BUILD_NUMBER + ' (' + process.env.TRAVIS_BUILD_ID + ')';
|
||||
if (process.env.MODE === 'saucelabs') {
|
||||
if (process.env.MODE.startsWith('saucelabs')) {
|
||||
config.sauceLabs.build = buildId;
|
||||
config.sauceLabs.tunnelIdentifier = process.env.TRAVIS_JOB_NUMBER;
|
||||
|
||||
@ -89,7 +88,7 @@ module.exports = function(config) {
|
||||
config.transports = ['polling'];
|
||||
}
|
||||
|
||||
if (process.env.MODE === 'browserstack') {
|
||||
if (process.env.MODE.startsWith('browserstack')) {
|
||||
config.browserStack.build = buildId;
|
||||
config.browserStack.tunnelIdentifier = process.env.TRAVIS_JOB_NUMBER;
|
||||
}
|
||||
|
85
modules/angular1_router/build.js
vendored
85
modules/angular1_router/build.js
vendored
@ -4,35 +4,47 @@ var fs = require('fs');
|
||||
var ts = require('typescript');
|
||||
|
||||
var files = [
|
||||
'lifecycle_annotations_impl.ts',
|
||||
'utils.ts',
|
||||
'url_parser.ts',
|
||||
'route_recognizer.ts',
|
||||
'route_config_impl.ts',
|
||||
'async_route_handler.ts',
|
||||
'sync_route_handler.ts',
|
||||
'component_recognizer.ts',
|
||||
'lifecycle/lifecycle_annotations_impl.ts',
|
||||
'lifecycle/route_lifecycle_reflector.ts',
|
||||
'route_config/route_config_impl.ts',
|
||||
'route_config/route_config_normalizer.ts',
|
||||
'rules/route_handlers/async_route_handler.ts',
|
||||
'rules/route_handlers/sync_route_handler.ts',
|
||||
'rules/rules.ts',
|
||||
'rules/rule_set.ts',
|
||||
'rules/route_paths/route_path.ts',
|
||||
'rules/route_paths/param_route_path.ts',
|
||||
'rules/route_paths/regex_route_path.ts',
|
||||
'instruction.ts',
|
||||
'path_recognizer.ts',
|
||||
'route_config_nomalizer.ts',
|
||||
'route_lifecycle_reflector.ts',
|
||||
'route_registry.ts',
|
||||
'router.ts'
|
||||
];
|
||||
|
||||
var PRELUDE = '(function(){\n';
|
||||
var POSTLUDE = '\n}());\n';
|
||||
var FACADES = fs.readFileSync(__dirname + '/lib/facades.es5', 'utf8');
|
||||
var DIRECTIVES = fs.readFileSync(__dirname + '/src/ng_outlet.ts', 'utf8');
|
||||
var moduleTemplate = fs.readFileSync(__dirname + '/src/module_template.js', 'utf8');
|
||||
|
||||
function main() {
|
||||
var dir = __dirname + '/../angular2/src/router/';
|
||||
function main(modulesDirectory) {
|
||||
var angular1RouterModuleDirectory = modulesDirectory + '/angular1_router';
|
||||
|
||||
var facades = fs.readFileSync(
|
||||
angular1RouterModuleDirectory + '/lib/facades.es5', 'utf8');
|
||||
var directives = fs.readFileSync(
|
||||
angular1RouterModuleDirectory + '/src/ng_outlet.ts', 'utf8');
|
||||
var moduleTemplate = fs.readFileSync(
|
||||
angular1RouterModuleDirectory + '/src/module_template.js', 'utf8');
|
||||
|
||||
var dir = modulesDirectory + '/angular2/src/router/';
|
||||
var sharedCode = files.reduce(function (prev, file) {
|
||||
return prev + transform(fs.readFileSync(dir + file, 'utf8'));
|
||||
}, '');
|
||||
|
||||
var out = moduleTemplate.replace('//{{FACADES}}', FACADES).replace('//{{SHARED_CODE}}', sharedCode);
|
||||
return PRELUDE + transform(DIRECTIVES) + out + POSTLUDE;
|
||||
// we have to use a function callback for replace to prevent it from interpreting `$`
|
||||
// as a replacement command character
|
||||
var out = moduleTemplate.replace('//{{FACADES}}', function() { return facades; })
|
||||
.replace('//{{SHARED_CODE}}', function() { return sharedCode; });
|
||||
return PRELUDE + transform(directives) + out + POSTLUDE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -41,9 +53,10 @@ function main() {
|
||||
*/
|
||||
var IMPORT_RE = new RegExp("import \\{?([\\w\\n_, ]+)\\}? from '(.+)';?", 'g');
|
||||
var INJECT_RE = new RegExp("@Inject\\(ROUTER_PRIMARY_COMPONENT\\)", 'g');
|
||||
var IMJECTABLE_RE = new RegExp("@Injectable\\(\\)", 'g');
|
||||
var INJECTABLE_RE = new RegExp("@Injectable\\(\\)", 'g');
|
||||
var REQUIRE_RE = new RegExp("require\\('(.*?)'\\);", 'g');
|
||||
function transform(contents) {
|
||||
contents = contents.replace(INJECT_RE, '').replace(IMJECTABLE_RE, '');
|
||||
contents = contents.replace(INJECT_RE, '').replace(INJECTABLE_RE, '');
|
||||
contents = contents.replace(IMPORT_RE, function (match, imports, includePath) {
|
||||
//TODO: remove special-case
|
||||
if (isFacadeModule(includePath) || includePath === './router_outlet') {
|
||||
@ -51,10 +64,15 @@ function transform(contents) {
|
||||
}
|
||||
return match;
|
||||
});
|
||||
return ts.transpile(contents, {
|
||||
contents = ts.transpile(contents, {
|
||||
target: ts.ScriptTarget.ES5,
|
||||
module: ts.ModuleKind.CommonJS
|
||||
});
|
||||
|
||||
// Rename require functions from transpiled imports
|
||||
contents = contents.replace(REQUIRE_RE, 'routerRequire(\'$1\');');
|
||||
|
||||
return contents;
|
||||
}
|
||||
|
||||
function isFacadeModule(modulePath) {
|
||||
@ -62,10 +80,29 @@ function isFacadeModule(modulePath) {
|
||||
modulePath === 'angular2/src/core/reflection/reflection';
|
||||
}
|
||||
|
||||
module.exports = function () {
|
||||
var dist = __dirname + '/../../dist';
|
||||
if (!fs.existsSync(dist)) {
|
||||
fs.mkdirSync(dist);
|
||||
module.exports = function(modulesDirectory, outputDirectory) {
|
||||
if (!fs.existsSync(outputDirectory)) {
|
||||
fs.mkdirSync(outputDirectory);
|
||||
}
|
||||
fs.writeFileSync(dist + '/angular_1_router.js', main());
|
||||
fs.writeFileSync(
|
||||
outputDirectory + '/angular_1_router.js', main(modulesDirectory));
|
||||
};
|
||||
|
||||
// CLI entry point
|
||||
if (require.main === module) {
|
||||
try {
|
||||
var args = process.argv;
|
||||
args.shift(); // node
|
||||
args.shift(); // scriptfile.js
|
||||
if (args.length < 2) {
|
||||
console.log("usage: $0 outFile path/to/modules");
|
||||
process.exit(1);
|
||||
}
|
||||
var outfile = args.shift();
|
||||
var directory = args.shift();
|
||||
fs.writeFileSync(outfile, main(directory));
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
@ -12,9 +12,9 @@
|
||||
<script src="../../dist/angular_1_router.js"></script>
|
||||
<script>
|
||||
angular.module('myApp', ['ngComponentRouter'])
|
||||
.controller('MyCtrl', ['$router', function ($router) {
|
||||
console.log($router);
|
||||
$router.navigateByUrl('/')
|
||||
.controller('MyCtrl', ['$rootRouter', function ($rootRouter) {
|
||||
console.log($rootRouter);
|
||||
$rootRouter.navigateByUrl('/')
|
||||
.then(console.log.bind(console, 'resolve'), console.log.bind(console, 'reject'));
|
||||
}]);
|
||||
</script>
|
||||
|
@ -173,6 +173,10 @@ var StringMapWrapper = {
|
||||
|
||||
var List = Array;
|
||||
var ListWrapper = {
|
||||
toJSON: function(l) {
|
||||
return JSON.stringify(l);
|
||||
},
|
||||
|
||||
clear: function (l) {
|
||||
l.length = 0;
|
||||
},
|
||||
@ -195,6 +199,10 @@ var ListWrapper = {
|
||||
return array[0];
|
||||
},
|
||||
|
||||
last: function(array) {
|
||||
return (array && array.length) > 0 ? array[array.length - 1] : null;
|
||||
},
|
||||
|
||||
map: function (l, fn) {
|
||||
return l.map(fn);
|
||||
},
|
||||
@ -243,6 +251,10 @@ var ListWrapper = {
|
||||
};
|
||||
|
||||
var StringWrapper = {
|
||||
charCodeAt: function(s, i) {
|
||||
return s.charCodeAt(i);
|
||||
},
|
||||
|
||||
equals: function (s1, s2) {
|
||||
return s1 === s2;
|
||||
},
|
||||
@ -299,8 +311,14 @@ Location.prototype.subscribe = function () {
|
||||
//TODO: implement
|
||||
};
|
||||
Location.prototype.path = function () {
|
||||
return $location.path();
|
||||
return $location.url();
|
||||
};
|
||||
Location.prototype.go = function (url) {
|
||||
return $location.path(url);
|
||||
Location.prototype.go = function (path, query) {
|
||||
return $location.url(path + query);
|
||||
};
|
||||
Location.prototype.prepareExternalUrl = function(url) {
|
||||
if (url.length > 0 && !url.startsWith('/')) {
|
||||
url = '/' + url;
|
||||
}
|
||||
return $location.$$html5 ? '.' + url : '#' + $locationHashPrefix + url;
|
||||
};
|
||||
|
82
modules/angular1_router/src/module_template.js
vendored
82
modules/angular1_router/src/module_template.js
vendored
@ -4,9 +4,33 @@ angular.module('ngComponentRouter').
|
||||
// Because Angular 1 has no notion of a root component, we use an object with unique identity
|
||||
// to represent this. Can be overloaded with a component name
|
||||
value('$routerRootComponent', new Object()).
|
||||
factory('$router', ['$q', '$location', '$$directiveIntrospector', '$browser', '$rootScope', '$injector', '$routerRootComponent', routerFactory]);
|
||||
|
||||
function routerFactory($q, $location, $$directiveIntrospector, $browser, $rootScope, $injector, $routerRootComponent) {
|
||||
// Unfortunately, $location doesn't expose what the current hashPrefix is
|
||||
// So we have to monkey patch the $locationProvider to capture this value
|
||||
provider('$locationHashPrefix', ['$locationProvider', $locationHashPrefixProvider]).
|
||||
factory('$rootRouter', ['$q', '$location', '$browser', '$rootScope', '$injector', '$routerRootComponent', '$locationHashPrefix', routerFactory]);
|
||||
|
||||
function $locationHashPrefixProvider($locationProvider) {
|
||||
|
||||
// Get hold of the original hashPrefix method
|
||||
var hashPrefixFn = $locationProvider.hashPrefix.bind($locationProvider);
|
||||
|
||||
// Read the current hashPrefix (in case it was set before this monkey-patch occurred)
|
||||
var hashPrefix = hashPrefixFn();
|
||||
|
||||
// Override the helper so that we can read any changes to the prefix (after this monkey-patch)
|
||||
$locationProvider.hashPrefix = function(prefix) {
|
||||
if (angular.isDefined(prefix)) {
|
||||
hashPrefix = prefix;
|
||||
}
|
||||
return hashPrefixFn(prefix);
|
||||
}
|
||||
|
||||
// Return the final hashPrefix as the value of this service
|
||||
this.$get = function() { return hashPrefix; };
|
||||
}
|
||||
|
||||
function routerFactory($q, $location, $browser, $rootScope, $injector, $routerRootComponent, $locationHashPrefix) {
|
||||
|
||||
// When this file is processed, the line below is replaced with
|
||||
// the contents of `../lib/facades.es5`.
|
||||
@ -17,17 +41,30 @@ function routerFactory($q, $location, $$directiveIntrospector, $browser, $rootSc
|
||||
OpaqueToken: function () {},
|
||||
Inject: function () {}
|
||||
};
|
||||
var require = function () {return exports;};
|
||||
var routerRequire = function () {return exports;};
|
||||
|
||||
// When this file is processed, the line below is replaced with
|
||||
// the contents of the compiled TypeScript classes.
|
||||
//{{SHARED_CODE}}
|
||||
|
||||
function getComponentConstructor(name) {
|
||||
var serviceName = name + 'Directive';
|
||||
if ($injector.has(serviceName)) {
|
||||
var definitions = $injector.get(serviceName);
|
||||
if (definitions.length > 1) {
|
||||
throw new BaseException('too many directives named "' + name + '"');
|
||||
}
|
||||
return definitions[0].controller;
|
||||
} else {
|
||||
throw new BaseException('directive "' + name + '" is not registered');
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: this is a hack to replace the exiting implementation at run-time
|
||||
exports.getCanActivateHook = function (directiveName) {
|
||||
var factory = $$directiveIntrospector.getTypeByName(directiveName);
|
||||
return factory && factory.$canActivate && function (next, prev) {
|
||||
return $injector.invoke(factory.$canActivate, null, {
|
||||
var controller = getComponentConstructor(directiveName);
|
||||
return controller.$canActivate && function (next, prev) {
|
||||
return $injector.invoke(controller.$canActivate, null, {
|
||||
$nextInstruction: next,
|
||||
$prevInstruction: prev
|
||||
});
|
||||
@ -45,19 +82,34 @@ function routerFactory($q, $location, $$directiveIntrospector, $browser, $rootSc
|
||||
var RouteRegistry = exports.RouteRegistry;
|
||||
var RootRouter = exports.RootRouter;
|
||||
|
||||
// Override this method to actually get hold of the child routes
|
||||
RouteRegistry.prototype.configFromComponent = function (component) {
|
||||
var that = this;
|
||||
if (isString(component)) {
|
||||
// Don't read the annotations component a type more than once –
|
||||
// this prevents an infinite loop if a component routes recursively.
|
||||
if (this._rules.has(component)) {
|
||||
return;
|
||||
}
|
||||
var controller = getComponentConstructor(component);
|
||||
if (angular.isArray(controller.$routeConfig)) {
|
||||
controller.$routeConfig.forEach(function (config) {
|
||||
var loader = config.loader;
|
||||
if (isPresent(loader)) {
|
||||
config = angular.extend({}, config, { loader: () => $injector.invoke(loader) });
|
||||
}
|
||||
that.config(component, config);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var registry = new RouteRegistry($routerRootComponent);
|
||||
var location = new Location();
|
||||
|
||||
$$directiveIntrospector(function (name, factory) {
|
||||
if (angular.isArray(factory.$routeConfig)) {
|
||||
factory.$routeConfig.forEach(function (config) {
|
||||
registry.config(name, config);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var router = new RootRouter(registry, location, $routerRootComponent);
|
||||
$rootScope.$watch(function () { return $location.path(); }, function (path) {
|
||||
$rootScope.$watch(function () { return $location.url(); }, function (path) {
|
||||
if (router.lastNavigationAttempt !== path) {
|
||||
router.navigateByUrl(path);
|
||||
}
|
||||
|
@ -1,51 +1,6 @@
|
||||
///<reference path="../typings/angularjs/angular.d.ts"/>
|
||||
|
||||
/*
|
||||
* decorates $compileProvider so that we have access to routing metadata
|
||||
*/
|
||||
function compilerProviderDecorator($compileProvider,
|
||||
$$directiveIntrospectorProvider: DirectiveIntrospectorProvider) {
|
||||
let directive = $compileProvider.directive;
|
||||
$compileProvider.directive = function(name: string, factory: Function) {
|
||||
$$directiveIntrospectorProvider.register(name, factory);
|
||||
return directive.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* private service that holds route mappings for each controller
|
||||
*/
|
||||
class DirectiveIntrospectorProvider {
|
||||
private directiveBuffer: any[] = [];
|
||||
private directiveFactoriesByName: {[name: string]: Function} = {};
|
||||
private onDirectiveRegistered: (name: string, factory: Function) => any = null;
|
||||
|
||||
register(name: string, factory: Function) {
|
||||
if (angular.isArray(factory)) {
|
||||
factory = factory[factory.length - 1];
|
||||
}
|
||||
this.directiveFactoriesByName[name] = factory;
|
||||
if (this.onDirectiveRegistered) {
|
||||
this.onDirectiveRegistered(name, factory);
|
||||
} else {
|
||||
this.directiveBuffer.push({name: name, factory: factory});
|
||||
}
|
||||
}
|
||||
|
||||
$get() {
|
||||
let fn: any = newOnControllerRegistered => {
|
||||
this.onDirectiveRegistered = newOnControllerRegistered;
|
||||
while (this.directiveBuffer.length > 0) {
|
||||
let directive = this.directiveBuffer.pop();
|
||||
this.onDirectiveRegistered(directive.name, directive.factory);
|
||||
}
|
||||
};
|
||||
|
||||
fn.getTypeByName = name => this.directiveFactoriesByName[name];
|
||||
|
||||
return fn;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @name ngOutlet
|
||||
@ -61,8 +16,8 @@ class DirectiveIntrospectorProvider {
|
||||
*
|
||||
* The value for the `ngOutlet` attribute is optional.
|
||||
*/
|
||||
function ngOutletDirective($animate, $q: ng.IQService, $router) {
|
||||
let rootRouter = $router;
|
||||
function ngOutletDirective($animate, $q: ng.IQService, $rootRouter) {
|
||||
let rootRouter = $rootRouter;
|
||||
|
||||
return {
|
||||
restrict: 'AE',
|
||||
@ -145,7 +100,7 @@ function ngOutletDirective($animate, $q: ng.IQService, $router) {
|
||||
}
|
||||
|
||||
activate(instruction) {
|
||||
let previousInstruction = this.currentInstruction;
|
||||
this.previousInstruction = this.currentInstruction;
|
||||
this.currentInstruction = instruction;
|
||||
|
||||
let componentName = this.controller.$$componentName = instruction.componentType;
|
||||
@ -154,11 +109,14 @@ function ngOutletDirective($animate, $q: ng.IQService, $router) {
|
||||
throw new Error('Component is not a string for ' + instruction.urlPath);
|
||||
}
|
||||
|
||||
this.controller.$$routeParams = instruction.params;
|
||||
this.controller.$$template = '<div ' + dashCase(componentName) + '></div>';
|
||||
this.controller.$$template = '<' + dashCase(componentName) + ' $router="::$$router"></' +
|
||||
dashCase(componentName) + '>';
|
||||
this.controller.$$router = this.router.childRouter(instruction.componentType);
|
||||
this.controller.$$outlet = this;
|
||||
|
||||
let newScope = scope.$new();
|
||||
newScope.$$router = this.controller.$$router;
|
||||
this.deferredActivation = $q.defer();
|
||||
|
||||
let clone = $transclude(newScope, clone => {
|
||||
$animate.enter(clone, null, this.currentElement || element);
|
||||
@ -167,15 +125,7 @@ function ngOutletDirective($animate, $q: ng.IQService, $router) {
|
||||
|
||||
this.currentElement = clone;
|
||||
this.currentScope = newScope;
|
||||
|
||||
// TODO: prefer the other directive retrieving the controller
|
||||
// by debug mode
|
||||
this.currentController = this.currentElement.children().eq(0).controller(componentName);
|
||||
|
||||
if (this.currentController && this.currentController.$routerOnActivate) {
|
||||
return this.currentController.$routerOnActivate(instruction, previousInstruction);
|
||||
}
|
||||
return $q.when();
|
||||
return this.deferredActivation.promise;
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,21 +148,32 @@ function ngOutletFillContentDirective($compile) {
|
||||
link: (scope, element, attrs, ctrl) => {
|
||||
let template = ctrl.$$template;
|
||||
element.html(template);
|
||||
let link = $compile(element.contents());
|
||||
link(scope);
|
||||
|
||||
// TODO: move to primary directive
|
||||
let componentInstance = scope[ctrl.$$componentName];
|
||||
if (componentInstance) {
|
||||
ctrl.$$currentComponent = componentInstance;
|
||||
|
||||
componentInstance.$router = ctrl.$$router;
|
||||
componentInstance.$routeParams = ctrl.$$routeParams;
|
||||
}
|
||||
$compile(element.contents())(scope);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
function routerTriggerDirective($q) {
|
||||
return {
|
||||
require: '^ngOutlet',
|
||||
priority: -1000,
|
||||
link: function(scope, element, attr, ngOutletCtrl) {
|
||||
var promise = $q.when();
|
||||
var outlet = ngOutletCtrl.$$outlet;
|
||||
var currentComponent = outlet.currentController =
|
||||
element.controller(ngOutletCtrl.$$componentName);
|
||||
if (currentComponent.$routerOnActivate) {
|
||||
promise = $q.when(currentComponent.$routerOnActivate(outlet.currentInstruction,
|
||||
outlet.previousInstruction));
|
||||
}
|
||||
promise.then(outlet.deferredActivation.resolve, outlet.deferredActivation.reject);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @name ngLink
|
||||
* @description
|
||||
@ -225,8 +186,8 @@ function ngOutletFillContentDirective($compile) {
|
||||
*
|
||||
* ```js
|
||||
* angular.module('myApp', ['ngComponentRouter'])
|
||||
* .controller('AppController', ['$router', function($router) {
|
||||
* $router.config({ path: '/user/:id', component: 'user' });
|
||||
* .controller('AppController', ['$rootRouter', function($rootRouter) {
|
||||
* $rootRouter.config({ path: '/user/:id', component: 'user' });
|
||||
* this.user = { name: 'Brian', id: 123 };
|
||||
* });
|
||||
* ```
|
||||
@ -237,23 +198,32 @@ function ngOutletFillContentDirective($compile) {
|
||||
* </div>
|
||||
* ```
|
||||
*/
|
||||
function ngLinkDirective($router, $parse) {
|
||||
let rootRouter = $router;
|
||||
|
||||
function ngLinkDirective($rootRouter, $parse) {
|
||||
return {require: '?^^ngOutlet', restrict: 'A', link: ngLinkDirectiveLinkFn};
|
||||
|
||||
function ngLinkDirectiveLinkFn(scope, element, attrs, ctrl) {
|
||||
let router = (ctrl && ctrl.$$router) || rootRouter;
|
||||
let router = (ctrl && ctrl.$$router) || $rootRouter;
|
||||
if (!router) {
|
||||
return;
|
||||
}
|
||||
|
||||
let instruction = null;
|
||||
let navigationInstruction = null;
|
||||
let link = attrs.ngLink || '';
|
||||
|
||||
function getLink(params) {
|
||||
instruction = router.generate(params);
|
||||
return './' + angular.stringifyInstruction(instruction);
|
||||
navigationInstruction = router.generate(params);
|
||||
|
||||
scope.$watch(function() { return router.isRouteActive(navigationInstruction); },
|
||||
function(active) {
|
||||
if (active) {
|
||||
element.addClass('ng-link-active');
|
||||
} else {
|
||||
element.removeClass('ng-link-active');
|
||||
}
|
||||
});
|
||||
|
||||
const navigationHref = navigationInstruction.toLinkUrl();
|
||||
return $rootRouter._location.prepareExternalUrl(navigationHref);
|
||||
}
|
||||
|
||||
let routeParamsGetter = $parse(link);
|
||||
@ -267,11 +237,11 @@ function ngLinkDirective($router, $parse) {
|
||||
}
|
||||
|
||||
element.on('click', event => {
|
||||
if (event.which !== 1 || !instruction) {
|
||||
if (event.which !== 1 || !navigationInstruction) {
|
||||
return;
|
||||
}
|
||||
|
||||
$router.navigateByInstruction(instruction);
|
||||
$rootRouter.navigateByInstruction(navigationInstruction);
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
@ -285,13 +255,7 @@ function dashCase(str: string): string {
|
||||
* A module for adding new a routing system Angular 1.
|
||||
*/
|
||||
angular.module('ngComponentRouter', [])
|
||||
.directive('ngOutlet', ngOutletDirective)
|
||||
.directive('ngOutlet', ngOutletFillContentDirective)
|
||||
.directive('ngLink', ngLinkDirective);
|
||||
|
||||
/*
|
||||
* A module for inspecting controller constructors
|
||||
*/
|
||||
angular.module('ng')
|
||||
.provider('$$directiveIntrospector', DirectiveIntrospectorProvider)
|
||||
.config(compilerProviderDecorator);
|
||||
.directive('ngOutlet', ['$animate', '$q', '$rootRouter', ngOutletDirective])
|
||||
.directive('ngOutlet', ['$compile', ngOutletFillContentDirective])
|
||||
.directive('ngLink', ['$rootRouter', '$parse', ngLinkDirective])
|
||||
.directive('$router', ['$q', routerTriggerDirective]);
|
||||
|
54
modules/angular1_router/src/ng_route_shim.js
vendored
54
modules/angular1_router/src/ng_route_shim.js
vendored
@ -1,4 +1,4 @@
|
||||
/** @license Copyright 2014-2015 Google, Inc. http://github.com/angular/angular/LICENSE */
|
||||
/** @license Copyright 2014-2016 Google, Inc. http://github.com/angular/angular/LICENSE */
|
||||
(function () {
|
||||
|
||||
'use strict';
|
||||
@ -24,12 +24,12 @@
|
||||
.directive('a', anchorLinkDirective)
|
||||
|
||||
// Connects the legacy $routeProvider config shim to Component Router's config.
|
||||
.run(['$route', '$router', function ($route, $router) {
|
||||
.run(['$route', '$rootRouter', function ($route, $rootRouter) {
|
||||
$route.$$subscribe(function (routeDefinition) {
|
||||
if (!angular.isArray(routeDefinition)) {
|
||||
routeDefinition = [routeDefinition];
|
||||
}
|
||||
$router.config(routeDefinition);
|
||||
$rootRouter.config(routeDefinition);
|
||||
});
|
||||
}]);
|
||||
|
||||
@ -116,53 +116,41 @@
|
||||
console.warn('Route for "' + path + '" should use "controllerAs".');
|
||||
}
|
||||
|
||||
var directiveName = routeObjToRouteName(routeCopy, path);
|
||||
var componentName = routeObjToRouteName(routeCopy, path);
|
||||
|
||||
if (!directiveName) {
|
||||
if (!componentName) {
|
||||
throw new Error('Could not determine a name for route "' + path + '".');
|
||||
}
|
||||
|
||||
routeDefinition.component = directiveName;
|
||||
routeDefinition.name = route.name || upperCase(directiveName);
|
||||
routeDefinition.component = componentName;
|
||||
routeDefinition.name = route.name || upperCase(componentName);
|
||||
|
||||
var directiveController = routeCopy.controller;
|
||||
|
||||
var directiveDefinition = {
|
||||
scope: false,
|
||||
var componentDefinition = {
|
||||
controller: directiveController,
|
||||
controllerAs: routeCopy.controllerAs,
|
||||
templateUrl: routeCopy.templateUrl,
|
||||
template: routeCopy.template
|
||||
};
|
||||
controllerAs: routeCopy.controllerAs
|
||||
|
||||
var directiveFactory = function () {
|
||||
return directiveDefinition;
|
||||
};
|
||||
if (routeCopy.templateUrl) componentDefinition.templateUrl = routeCopy.templateUrl;
|
||||
if (routeCopy.template) componentDefinition.template = routeCopy.template;
|
||||
|
||||
|
||||
// if we have route resolve options, prepare a wrapper controller
|
||||
if (directiveController && routeCopy.resolve) {
|
||||
var originalController = directiveController;
|
||||
var resolvedLocals = {};
|
||||
|
||||
directiveDefinition.controller = ['$injector', '$scope', function ($injector, $scope) {
|
||||
componentDefinition.controller = ['$injector', '$scope', function ($injector, $scope) {
|
||||
var locals = angular.extend({
|
||||
$scope: $scope
|
||||
}, resolvedLocals);
|
||||
|
||||
var ctrl = $injector.instantiate(originalController, locals);
|
||||
|
||||
if (routeCopy.controllerAs) {
|
||||
locals.$scope[routeCopy.controllerAs] = ctrl;
|
||||
}
|
||||
|
||||
return ctrl;
|
||||
return $injector.instantiate(originalController, locals);
|
||||
}];
|
||||
|
||||
// we take care of controllerAs in the directive controller wrapper
|
||||
delete directiveDefinition.controllerAs;
|
||||
|
||||
// we resolve the locals in a canActivate block
|
||||
directiveFactory.$canActivate = function() {
|
||||
componentDefinition.controller.$canActivate = function() {
|
||||
var locals = angular.extend({}, routeCopy.resolve);
|
||||
|
||||
angular.forEach(locals, function(value, key) {
|
||||
@ -179,7 +167,7 @@
|
||||
}
|
||||
|
||||
// register the dynamically created directive
|
||||
$compileProvider.directive(directiveName, directiveFactory);
|
||||
$compileProvider.component(componentName, componentDefinition);
|
||||
}
|
||||
if (subscriptionFn) {
|
||||
subscriptionFn(routeDefinition);
|
||||
@ -253,12 +241,12 @@
|
||||
|
||||
}
|
||||
|
||||
function $routeParamsFactory($router, $rootScope) {
|
||||
function $routeParamsFactory($rootRouter, $rootScope) {
|
||||
// the identity of this object cannot change
|
||||
var paramsObj = {};
|
||||
|
||||
$rootScope.$on('$routeChangeSuccess', function () {
|
||||
var newParams = $router._currentInstruction && $router._currentInstruction.component.params;
|
||||
var newParams = $rootRouter.currentInstruction && $rootRouter.currentInstruction.component.params;
|
||||
|
||||
angular.forEach(paramsObj, function (val, name) {
|
||||
delete paramsObj[name];
|
||||
@ -274,7 +262,7 @@
|
||||
/**
|
||||
* Allows normal anchor links to kick off routing.
|
||||
*/
|
||||
function anchorLinkDirective($router) {
|
||||
function anchorLinkDirective($rootRouter) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function (scope, element) {
|
||||
@ -293,8 +281,8 @@
|
||||
}
|
||||
|
||||
var href = element.attr(hrefAttrName);
|
||||
if (href && $router.recognize(href)) {
|
||||
$router.navigateByUrl(href);
|
||||
if (href && $rootRouter.recognize(href)) {
|
||||
$rootRouter.navigateByUrl(href);
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
|
@ -1,38 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('$$directiveIntrospector', function () {
|
||||
|
||||
var $compileProvider;
|
||||
|
||||
beforeEach(function() {
|
||||
module('ng');
|
||||
module('ngComponentRouter');
|
||||
module(function(_$compileProvider_) {
|
||||
$compileProvider = _$compileProvider_;
|
||||
});
|
||||
});
|
||||
|
||||
it('should call the introspector function whenever a directive factory is registered', inject(function ($$directiveIntrospector) {
|
||||
var spy = jasmine.createSpy();
|
||||
$$directiveIntrospector(spy);
|
||||
function myDir(){}
|
||||
$compileProvider.directive('myDir', myDir);
|
||||
|
||||
expect(spy).toHaveBeenCalledWith('myDir', myDir);
|
||||
}));
|
||||
|
||||
it('should call the introspector function whenever a directive factory is registered with array annotations', inject(function ($$directiveIntrospector) {
|
||||
var spy = jasmine.createSpy();
|
||||
$$directiveIntrospector(spy);
|
||||
function myDir(){}
|
||||
$compileProvider.directive('myDir', ['foo', myDir]);
|
||||
|
||||
expect(spy).toHaveBeenCalledWith('myDir', myDir);
|
||||
}));
|
||||
|
||||
it('should retrieve a factory based on directive name', inject(function ($$directiveIntrospector) {
|
||||
function myDir(){}
|
||||
$compileProvider.directive('myDir', ['foo', myDir]);
|
||||
expect($$directiveIntrospector.getTypeByName('myDir')).toBe(myDir);
|
||||
}));
|
||||
});
|
@ -5,7 +5,7 @@ describe('ngOutlet animations', function () {
|
||||
$animate,
|
||||
$compile,
|
||||
$rootScope,
|
||||
$router,
|
||||
$rootRouter,
|
||||
$compileProvider;
|
||||
|
||||
beforeEach(function () {
|
||||
@ -17,15 +17,18 @@ describe('ngOutlet animations', function () {
|
||||
$compileProvider = _$compileProvider_;
|
||||
});
|
||||
|
||||
inject(function (_$animate_, _$compile_, _$rootScope_, _$router_) {
|
||||
inject(function (_$animate_, _$compile_, _$rootScope_, _$rootRouter_) {
|
||||
$animate = _$animate_;
|
||||
$compile = _$compile_;
|
||||
$rootScope = _$rootScope_;
|
||||
$router = _$router_;
|
||||
$rootRouter = _$rootRouter_;
|
||||
});
|
||||
|
||||
registerComponent('userCmp', {
|
||||
template: '<div>hello {{userCmp.$routeParams.name}}</div>'
|
||||
template: '<div>hello {{userCmp.$routeParams.name}}</div>',
|
||||
$routerOnActivate: function(next) {
|
||||
this.$routeParams = next.params;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -38,11 +41,11 @@ describe('ngOutlet animations', function () {
|
||||
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/user/:name', component: 'userCmp' }
|
||||
]);
|
||||
|
||||
$router.navigateByUrl('/user/brian');
|
||||
$rootRouter.navigateByUrl('/user/brian');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('hello brian');
|
||||
|
||||
@ -51,7 +54,7 @@ describe('ngOutlet animations', function () {
|
||||
expect(item.event).toBe('enter');
|
||||
|
||||
// navigate to pete
|
||||
$router.navigateByUrl('/user/pete');
|
||||
$rootRouter.navigateByUrl('/user/pete');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('hello pete');
|
||||
|
||||
|
@ -4,7 +4,7 @@ describe('Navigation lifecycle', function () {
|
||||
var elt,
|
||||
$compile,
|
||||
$rootScope,
|
||||
$router,
|
||||
$rootRouter,
|
||||
$compileProvider;
|
||||
|
||||
beforeEach(function () {
|
||||
@ -14,10 +14,10 @@ describe('Navigation lifecycle', function () {
|
||||
$compileProvider = _$compileProvider_;
|
||||
});
|
||||
|
||||
inject(function (_$compile_, _$rootScope_, _$router_) {
|
||||
inject(function (_$compile_, _$rootScope_, _$rootRouter_) {
|
||||
$compile = _$compile_;
|
||||
$rootScope = _$rootScope_;
|
||||
$router = _$router_;
|
||||
$rootRouter = _$rootRouter_;
|
||||
});
|
||||
|
||||
registerComponent('oneCmp', {
|
||||
@ -38,12 +38,12 @@ describe('Navigation lifecycle', function () {
|
||||
$routerOnActivate: spy
|
||||
});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/a', component: 'activateCmp' }
|
||||
]);
|
||||
compile('<div>outer { <div ng-outlet></div> }</div>');
|
||||
|
||||
$router.navigateByUrl('/a');
|
||||
$rootRouter.navigateByUrl('/a');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(spy).toHaveBeenCalled();
|
||||
@ -56,12 +56,12 @@ describe('Navigation lifecycle', function () {
|
||||
$routerOnActivate: spy
|
||||
});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/user/:name', component: 'userCmp' }
|
||||
]);
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$router.navigateByUrl('/user/brian');
|
||||
$rootRouter.navigateByUrl('/user/brian');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(spy).toHaveBeenCalledWith(instructionFor('userCmp'), undefined);
|
||||
@ -75,15 +75,15 @@ describe('Navigation lifecycle', function () {
|
||||
$routerOnActivate: spy
|
||||
});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/user/:name', component: 'oneCmp' },
|
||||
{ path: '/post/:id', component: 'activateCmp' }
|
||||
]);
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$router.navigateByUrl('/user/brian');
|
||||
$rootRouter.navigateByUrl('/user/brian');
|
||||
$rootScope.$digest();
|
||||
$router.navigateByUrl('/post/123');
|
||||
$rootRouter.navigateByUrl('/post/123');
|
||||
$rootScope.$digest();
|
||||
expect(spy).toHaveBeenCalledWith(instructionFor('activateCmp'),
|
||||
instructionFor('oneCmp'));
|
||||
@ -98,12 +98,12 @@ describe('Navigation lifecycle', function () {
|
||||
}
|
||||
});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/user', component: 'userCmp' }
|
||||
]);
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$router.navigateByUrl('/user');
|
||||
$rootRouter.navigateByUrl('/user');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(injectedScope).toBeDefined();
|
||||
@ -116,15 +116,15 @@ describe('Navigation lifecycle', function () {
|
||||
$routerOnDeactivate: spy
|
||||
});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/a', component: 'deactivateCmp' },
|
||||
{ path: '/b', component: 'oneCmp' }
|
||||
]);
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$router.navigateByUrl('/a');
|
||||
$rootRouter.navigateByUrl('/a');
|
||||
$rootScope.$digest();
|
||||
$router.navigateByUrl('/b');
|
||||
$rootRouter.navigateByUrl('/b');
|
||||
$rootScope.$digest();
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
@ -136,15 +136,15 @@ describe('Navigation lifecycle', function () {
|
||||
$routerOnDeactivate: spy
|
||||
});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/user/:name', component: 'deactivateCmp' },
|
||||
{ path: '/post/:id', component: 'oneCmp' }
|
||||
]);
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$router.navigateByUrl('/user/brian');
|
||||
$rootRouter.navigateByUrl('/user/brian');
|
||||
$rootScope.$digest();
|
||||
$router.navigateByUrl('/post/123');
|
||||
$rootRouter.navigateByUrl('/post/123');
|
||||
$rootScope.$digest();
|
||||
expect(spy).toHaveBeenCalledWith(instructionFor('oneCmp'),
|
||||
instructionFor('deactivateCmp'));
|
||||
@ -166,15 +166,15 @@ describe('Navigation lifecycle', function () {
|
||||
}
|
||||
});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/a', component: 'deactivateCmp' },
|
||||
{ path: '/b', component: 'activateCmp' }
|
||||
]);
|
||||
compile('outer { <div ng-outlet></div> }');
|
||||
|
||||
$router.navigateByUrl('/a');
|
||||
$rootRouter.navigateByUrl('/a');
|
||||
$rootScope.$digest();
|
||||
$router.navigateByUrl('/b');
|
||||
$rootRouter.navigateByUrl('/b');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(log).toEqual(['deactivate', 'activate']);
|
||||
@ -203,19 +203,19 @@ describe('Navigation lifecycle', function () {
|
||||
}
|
||||
});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/on-reuse/:number/...', component: 'reuseCmp' },
|
||||
{ path: '/two', component: 'twoCmp', name: 'Two'}
|
||||
]);
|
||||
compile('outer { <div ng-outlet></div> }');
|
||||
|
||||
$router.navigateByUrl('/on-reuse/1/a');
|
||||
$rootRouter.navigateByUrl('/on-reuse/1/a');
|
||||
$rootScope.$digest();
|
||||
expect(log).toEqual([]);
|
||||
expect(cmpInstanceCount).toBe(1);
|
||||
expect(elt.text()).toBe('outer { reuse {one} }');
|
||||
|
||||
$router.navigateByUrl('/on-reuse/2/b');
|
||||
$rootRouter.navigateByUrl('/on-reuse/2/b');
|
||||
$rootScope.$digest();
|
||||
expect(log).toEqual(['reuse: on-reuse/1 -> on-reuse/2']);
|
||||
expect(cmpInstanceCount).toBe(1);
|
||||
@ -245,19 +245,19 @@ describe('Navigation lifecycle', function () {
|
||||
}
|
||||
});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/never-reuse/:number/...', component: 'reuseCmp' },
|
||||
{ path: '/two', component: 'twoCmp', name: 'Two'}
|
||||
]);
|
||||
compile('outer { <div ng-outlet></div> }');
|
||||
|
||||
$router.navigateByUrl('/never-reuse/1/a');
|
||||
$rootRouter.navigateByUrl('/never-reuse/1/a');
|
||||
$rootScope.$digest();
|
||||
expect(log).toEqual([]);
|
||||
expect(cmpInstanceCount).toBe(1);
|
||||
expect(elt.text()).toBe('outer { reuse {one} }');
|
||||
|
||||
$router.navigateByUrl('/never-reuse/2/b');
|
||||
$rootRouter.navigateByUrl('/never-reuse/2/b');
|
||||
$rootScope.$digest();
|
||||
expect(log).toEqual([]);
|
||||
expect(cmpInstanceCount).toBe(2);
|
||||
@ -274,12 +274,12 @@ describe('Navigation lifecycle', function () {
|
||||
$routerOnActivate: spy
|
||||
});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/a', component: 'activateCmp' }
|
||||
]);
|
||||
compile('outer { <div ng-outlet></div> }');
|
||||
|
||||
$router.navigateByUrl('/a');
|
||||
$rootRouter.navigateByUrl('/a');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
@ -296,12 +296,12 @@ describe('Navigation lifecycle', function () {
|
||||
$routerOnActivate: activateSpy
|
||||
});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/a', component: 'activateCmp' }
|
||||
]);
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$router.navigateByUrl('/a');
|
||||
$rootRouter.navigateByUrl('/a');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(canActivateSpy).toHaveBeenCalled();
|
||||
@ -320,12 +320,12 @@ describe('Navigation lifecycle', function () {
|
||||
$routerOnActivate: spy
|
||||
});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/a', component: 'activateCmp' }
|
||||
]);
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$router.navigateByUrl('/a');
|
||||
$rootRouter.navigateByUrl('/a');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(spy).toHaveBeenCalled();
|
||||
@ -341,17 +341,17 @@ describe('Navigation lifecycle', function () {
|
||||
|
||||
spy.$inject = ['$nextInstruction', '$http'];
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/user/:name', component: 'activateCmp' }
|
||||
]);
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$router.navigateByUrl('/user/brian');
|
||||
$rootRouter.navigateByUrl('/user/brian');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(spy).toHaveBeenCalled();
|
||||
var args = spy.calls.mostRecent().args;
|
||||
expect(args[0].params).toEqual({name: 'brian'});
|
||||
expect(args[0].params).toEqual(jasmine.objectContaining({name: 'brian'}));
|
||||
expect(args[1]).toBe($http);
|
||||
}));
|
||||
|
||||
@ -364,17 +364,17 @@ describe('Navigation lifecycle', function () {
|
||||
}
|
||||
});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/a', component: 'activateCmp' },
|
||||
{ path: '/b', component: 'oneCmp' }
|
||||
]);
|
||||
compile('outer { <div ng-outlet></div> }');
|
||||
|
||||
$router.navigateByUrl('/a');
|
||||
$rootRouter.navigateByUrl('/a');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('outer { hi }');
|
||||
|
||||
$router.navigateByUrl('/b');
|
||||
$rootRouter.navigateByUrl('/b');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('outer { hi }');
|
||||
});
|
||||
@ -388,17 +388,17 @@ describe('Navigation lifecycle', function () {
|
||||
}
|
||||
});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/a', component: 'activateCmp' },
|
||||
{ path: '/b', component: 'oneCmp' }
|
||||
]);
|
||||
compile('outer { <div ng-outlet></div> }');
|
||||
|
||||
$router.navigateByUrl('/a');
|
||||
$rootRouter.navigateByUrl('/a');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('outer { hi }');
|
||||
|
||||
$router.navigateByUrl('/b');
|
||||
$rootRouter.navigateByUrl('/b');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('outer { one }');
|
||||
});
|
||||
@ -414,12 +414,12 @@ describe('Navigation lifecycle', function () {
|
||||
$routerOnActivate: spy
|
||||
});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/a', component: 'activateCmp' }
|
||||
]);
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$router.navigateByUrl('/a');
|
||||
$rootRouter.navigateByUrl('/a');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(spy).toHaveBeenCalled();
|
||||
@ -433,15 +433,15 @@ describe('Navigation lifecycle', function () {
|
||||
$routerCanDeactivate: spy
|
||||
});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/user/:name', component: 'deactivateCmp' },
|
||||
{ path: '/post/:id', component: 'oneCmp' }
|
||||
]);
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$router.navigateByUrl('/user/brian');
|
||||
$rootRouter.navigateByUrl('/user/brian');
|
||||
$rootScope.$digest();
|
||||
$router.navigateByUrl('/post/123');
|
||||
$rootRouter.navigateByUrl('/post/123');
|
||||
$rootScope.$digest();
|
||||
expect(spy).toHaveBeenCalledWith(instructionFor('oneCmp'),
|
||||
instructionFor('deactivateCmp'));
|
||||
@ -466,10 +466,10 @@ describe('Navigation lifecycle', function () {
|
||||
}
|
||||
|
||||
if (options.$canActivate) {
|
||||
factory.$canActivate = options.$canActivate;
|
||||
controller.$canActivate = options.$canActivate;
|
||||
}
|
||||
if (options.$routeConfig) {
|
||||
factory.$routeConfig = options.$routeConfig;
|
||||
controller.$routeConfig = options.$routeConfig;
|
||||
}
|
||||
|
||||
$compileProvider.directive(name, factory);
|
||||
|
@ -5,7 +5,7 @@ describe('navigation', function () {
|
||||
var elt,
|
||||
$compile,
|
||||
$rootScope,
|
||||
$router,
|
||||
$rootRouter,
|
||||
$compileProvider;
|
||||
|
||||
beforeEach(function () {
|
||||
@ -15,49 +15,79 @@ describe('navigation', function () {
|
||||
$compileProvider = _$compileProvider_;
|
||||
});
|
||||
|
||||
inject(function (_$compile_, _$rootScope_, _$router_) {
|
||||
inject(function (_$compile_, _$rootScope_, _$rootRouter_) {
|
||||
$compile = _$compile_;
|
||||
$rootScope = _$rootScope_;
|
||||
$router = _$router_;
|
||||
$rootRouter = _$rootRouter_;
|
||||
});
|
||||
|
||||
registerComponent('userCmp', {
|
||||
template: '<div>hello {{userCmp.$routeParams.name}}</div>'
|
||||
registerDirective('userCmp', {
|
||||
template: '<div>hello {{userCmp.$routeParams.name}}</div>',
|
||||
$routerOnActivate: function(next) {
|
||||
this.$routeParams = next.params;
|
||||
}
|
||||
});
|
||||
registerComponent('oneCmp', {
|
||||
registerDirective('oneCmp', {
|
||||
template: '<div>{{oneCmp.number}}</div>',
|
||||
controller: function () {this.number = 'one'}
|
||||
});
|
||||
registerComponent('twoCmp', {
|
||||
registerDirective('twoCmp', {
|
||||
template: '<div>{{twoCmp.number}}</div>',
|
||||
controller: function () {this.number = 'two'}
|
||||
});
|
||||
registerComponent('threeCmp', {
|
||||
template: '<div>{{$ctrl.number}}</div>',
|
||||
controller: function () {this.number = 'three'}
|
||||
});
|
||||
registerComponent('getParams', {
|
||||
template: '<div>{{$ctrl.params.x}}</div>',
|
||||
controller: function () {
|
||||
this.$routerOnActivate = function(next) {
|
||||
this.params = next.params;
|
||||
};
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
it('should work in a simple case', function () {
|
||||
compile('<ng-outlet></ng-outlet>');
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/', component: 'oneCmp' }
|
||||
]);
|
||||
|
||||
$router.navigateByUrl('/');
|
||||
$rootRouter.navigateByUrl('/');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(elt.text()).toBe('one');
|
||||
});
|
||||
|
||||
|
||||
it('should work with components created by the `mod.component()` helper', function () {
|
||||
compile('<ng-outlet></ng-outlet>');
|
||||
|
||||
$rootRouter.config([
|
||||
{ path: '/', component: 'threeCmp' }
|
||||
]);
|
||||
|
||||
$rootRouter.navigateByUrl('/');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(elt.text()).toBe('three');
|
||||
});
|
||||
|
||||
|
||||
it('should navigate between components with different parameters', function () {
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/user/:name', component: 'userCmp' }
|
||||
]);
|
||||
compile('<ng-outlet></ng-outlet>');
|
||||
|
||||
$router.navigateByUrl('/user/brian');
|
||||
$rootRouter.navigateByUrl('/user/brian');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('hello brian');
|
||||
|
||||
$router.navigateByUrl('/user/igor');
|
||||
$rootRouter.navigateByUrl('/user/igor');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('hello igor');
|
||||
});
|
||||
@ -68,7 +98,7 @@ describe('navigation', function () {
|
||||
function ParentController() {
|
||||
instanceCount += 1;
|
||||
}
|
||||
registerComponent('parentCmp', {
|
||||
registerDirective('parentCmp', {
|
||||
template: 'parent { <ng-outlet></ng-outlet> }',
|
||||
$routeConfig: [
|
||||
{ path: '/user/:name', component: 'userCmp' }
|
||||
@ -76,17 +106,17 @@ describe('navigation', function () {
|
||||
controller: ParentController
|
||||
});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/parent/...', component: 'parentCmp' }
|
||||
]);
|
||||
compile('<ng-outlet></ng-outlet>');
|
||||
|
||||
$router.navigateByUrl('/parent/user/brian');
|
||||
$rootRouter.navigateByUrl('/parent/user/brian');
|
||||
$rootScope.$digest();
|
||||
expect(instanceCount).toBe(1);
|
||||
expect(elt.text()).toBe('parent { hello brian }');
|
||||
|
||||
$router.navigateByUrl('/parent/user/igor');
|
||||
$rootRouter.navigateByUrl('/parent/user/igor');
|
||||
$rootScope.$digest();
|
||||
expect(instanceCount).toBe(1);
|
||||
expect(elt.text()).toBe('parent { hello igor }');
|
||||
@ -94,6 +124,25 @@ describe('navigation', function () {
|
||||
|
||||
|
||||
it('should work with nested outlets', function () {
|
||||
registerDirective('childCmp', {
|
||||
template: '<div>inner { <div ng-outlet></div> }</div>',
|
||||
$routeConfig: [
|
||||
{ path: '/b', component: 'oneCmp' }
|
||||
]
|
||||
});
|
||||
|
||||
$rootRouter.config([
|
||||
{ path: '/a/...', component: 'childCmp' }
|
||||
]);
|
||||
compile('<div>outer { <div ng-outlet></div> }</div>');
|
||||
|
||||
$rootRouter.navigateByUrl('/a/b');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(elt.text()).toBe('outer { inner { one } }');
|
||||
});
|
||||
|
||||
it('should work when parent route has empty path', inject(function ($location) {
|
||||
registerComponent('childCmp', {
|
||||
template: '<div>inner { <div ng-outlet></div> }</div>',
|
||||
$routeConfig: [
|
||||
@ -101,61 +150,77 @@ describe('navigation', function () {
|
||||
]
|
||||
});
|
||||
|
||||
$router.config([
|
||||
{ path: '/a/...', component: 'childCmp' }
|
||||
$rootRouter.config([
|
||||
{ path: '/...', component: 'childCmp' }
|
||||
]);
|
||||
compile('<div>outer { <div ng-outlet></div> }</div>');
|
||||
|
||||
$router.navigateByUrl('/a/b');
|
||||
$rootRouter.navigateByUrl('/b');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(elt.text()).toBe('outer { inner { one } }');
|
||||
});
|
||||
expect($location.path()).toBe('/b');
|
||||
}));
|
||||
|
||||
|
||||
it('should work with recursive nested outlets', function () {
|
||||
registerComponent('recurCmp', {
|
||||
registerDirective('recurCmp', {
|
||||
template: '<div>recur { <div ng-outlet></div> }</div>',
|
||||
$routeConfig: [
|
||||
{ path: '/recur', component: 'recurCmp' },
|
||||
{ path: '/end', component: 'oneCmp' }
|
||||
]});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/recur', component: 'recurCmp' },
|
||||
{ path: '/', component: 'oneCmp' }
|
||||
]);
|
||||
|
||||
compile('<div>root { <div ng-outlet></div> }</div>');
|
||||
$router.navigateByUrl('/recur/recur/end');
|
||||
$rootRouter.navigateByUrl('/recur/recur/end');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('root { one }');
|
||||
});
|
||||
|
||||
|
||||
it('should change location path', inject(function ($location) {
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/user', component: 'userCmp' }
|
||||
]);
|
||||
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$router.navigateByUrl('/user');
|
||||
$rootRouter.navigateByUrl('/user');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect($location.path()).toBe('/user');
|
||||
}));
|
||||
|
||||
|
||||
it('should pass through query terms to the location', inject(function ($location) {
|
||||
$rootRouter.config([
|
||||
{ path: '/user', component: 'userCmp' }
|
||||
]);
|
||||
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$rootRouter.navigateByUrl('/user?x=y');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect($location.path()).toBe('/user');
|
||||
expect($location.search()).toEqual({ x: 'y'});
|
||||
}));
|
||||
|
||||
|
||||
it('should change location to the canonical route', inject(function ($location) {
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/', redirectTo: ['/User'] },
|
||||
{ path: '/user', component: 'userCmp', name: 'User' }
|
||||
]);
|
||||
|
||||
$router.navigateByUrl('/');
|
||||
$rootRouter.navigateByUrl('/');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect($location.path()).toBe('/user');
|
||||
@ -163,7 +228,7 @@ describe('navigation', function () {
|
||||
|
||||
|
||||
it('should change location to the canonical route with nested components', inject(function ($location) {
|
||||
registerComponent('childRouter', {
|
||||
registerDirective('childRouter', {
|
||||
template: '<div>inner { <div ng-outlet></div> }</div>',
|
||||
$routeConfig: [
|
||||
{ path: '/new-child', component: 'oneCmp', name: 'NewChild'},
|
||||
@ -171,7 +236,7 @@ describe('navigation', function () {
|
||||
]
|
||||
});
|
||||
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/old-parent/old-child', redirectTo: ['/NewParent', 'NewChild'] },
|
||||
{ path: '/old-parent/old-child-two', redirectTo: ['/NewParent', 'NewChildTwo'] },
|
||||
{ path: '/new-parent/...', component: 'childRouter', name: 'NewParent' }
|
||||
@ -179,13 +244,13 @@ describe('navigation', function () {
|
||||
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$router.navigateByUrl('/old-parent/old-child');
|
||||
$rootRouter.navigateByUrl('/old-parent/old-child');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect($location.path()).toBe('/new-parent/new-child');
|
||||
expect(elt.text()).toBe('inner { one }');
|
||||
|
||||
$router.navigateByUrl('/old-parent/old-child-two');
|
||||
$rootRouter.navigateByUrl('/old-parent/old-child-two');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect($location.path()).toBe('/new-parent/new-child-two');
|
||||
@ -194,7 +259,7 @@ describe('navigation', function () {
|
||||
|
||||
|
||||
it('should navigate when the location path changes', inject(function ($location) {
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/one', component: 'oneCmp' }
|
||||
]);
|
||||
compile('<div ng-outlet></div>');
|
||||
@ -206,36 +271,42 @@ describe('navigation', function () {
|
||||
}));
|
||||
|
||||
|
||||
it('should expose a "navigating" property on $router', inject(function ($q) {
|
||||
it('should navigate when the location query changes', inject(function ($location) {
|
||||
$rootRouter.config([
|
||||
{ path: '/get/params', component: 'getParams' }
|
||||
]);
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$location.url('/get/params?x=y');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(elt.text()).toBe('y');
|
||||
}));
|
||||
|
||||
|
||||
it('should expose a "navigating" property on $rootRouter', inject(function ($q) {
|
||||
var defer;
|
||||
registerComponent('pendingActivate', {
|
||||
registerDirective('pendingActivate', {
|
||||
$canActivate: function () {
|
||||
defer = $q.defer();
|
||||
return defer.promise;
|
||||
}
|
||||
});
|
||||
$router.config([
|
||||
$rootRouter.config([
|
||||
{ path: '/pending-activate', component: 'pendingActivate' }
|
||||
]);
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$router.navigateByUrl('/pending-activate');
|
||||
$rootRouter.navigateByUrl('/pending-activate');
|
||||
$rootScope.$digest();
|
||||
expect($router.navigating).toBe(true);
|
||||
expect($rootRouter.navigating).toBe(true);
|
||||
defer.resolve();
|
||||
$rootScope.$digest();
|
||||
expect($router.navigating).toBe(false);
|
||||
expect($rootRouter.navigating).toBe(false);
|
||||
}));
|
||||
|
||||
function registerComponent(name, options) {
|
||||
var controller = options.controller || function () {};
|
||||
|
||||
['$routerOnActivate', '$routerOnDeactivate', '$routerOnReuse', '$routerCanReuse', '$routerCanDeactivate'].forEach(function (hookName) {
|
||||
if (options[hookName]) {
|
||||
controller.prototype[hookName] = options[hookName];
|
||||
}
|
||||
});
|
||||
|
||||
function registerDirective(name, options) {
|
||||
var controller = getController(options);
|
||||
function factory() {
|
||||
return {
|
||||
template: options.template || '',
|
||||
@ -243,20 +314,46 @@ describe('navigation', function () {
|
||||
controller: controller
|
||||
};
|
||||
}
|
||||
|
||||
if (options.$canActivate) {
|
||||
factory.$canActivate = options.$canActivate;
|
||||
}
|
||||
if (options.$routeConfig) {
|
||||
factory.$routeConfig = options.$routeConfig;
|
||||
}
|
||||
|
||||
applyStaticProperties(controller, options);
|
||||
$compileProvider.directive(name, factory);
|
||||
}
|
||||
|
||||
function registerComponent(name, options) {
|
||||
|
||||
var definition = {
|
||||
template: options.template || '',
|
||||
controller: getController(options),
|
||||
}
|
||||
applyStaticProperties(definition.controller, options);
|
||||
$compileProvider.component(name, definition);
|
||||
}
|
||||
|
||||
function compile(template) {
|
||||
elt = $compile('<div>' + template + '</div>')($rootScope);
|
||||
$rootScope.$digest();
|
||||
return elt;
|
||||
}
|
||||
|
||||
function getController(options) {
|
||||
var controller = options.controller || function () {};
|
||||
[
|
||||
'$routerOnActivate', '$routerOnDeactivate',
|
||||
'$routerOnReuse', '$routerCanReuse',
|
||||
'$routerCanDeactivate'
|
||||
].forEach(function (hookName) {
|
||||
if (options[hookName]) {
|
||||
controller.prototype[hookName] = options[hookName];
|
||||
}
|
||||
});
|
||||
return controller;
|
||||
}
|
||||
|
||||
function applyStaticProperties(target, options) {
|
||||
['$canActivate', '$routeConfig'].forEach(function(property) {
|
||||
if (options[property]) {
|
||||
target[property] = options[property];
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -2,30 +2,14 @@
|
||||
|
||||
describe('router', function () {
|
||||
|
||||
var elt,
|
||||
$compile,
|
||||
$rootScope,
|
||||
$router,
|
||||
$compileProvider;
|
||||
|
||||
var elt, testMod;
|
||||
beforeEach(function () {
|
||||
module('ng');
|
||||
module('ngComponentRouter');
|
||||
module(function($provide) {
|
||||
$provide.value('$routerRootComponent', 'app');
|
||||
});
|
||||
module(function (_$compileProvider_) {
|
||||
$compileProvider = _$compileProvider_;
|
||||
});
|
||||
|
||||
inject(function (_$compile_, _$rootScope_, _$router_) {
|
||||
$compile = _$compile_;
|
||||
$rootScope = _$rootScope_;
|
||||
$router = _$router_;
|
||||
});
|
||||
testMod = angular.module('testMod', ['ngComponentRouter'])
|
||||
.value('$routerRootComponent', 'app');
|
||||
});
|
||||
|
||||
it('should work with a provided root component', inject(function($location) {
|
||||
it('should work with a provided root component', function() {
|
||||
|
||||
registerComponent('homeCmp', {
|
||||
template: 'Home'
|
||||
});
|
||||
@ -37,43 +21,197 @@ describe('router', function () {
|
||||
]
|
||||
});
|
||||
|
||||
compile('<app></app>');
|
||||
module('testMod');
|
||||
compileApp();
|
||||
|
||||
$location.path('/');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('Home');
|
||||
}));
|
||||
inject(function($location, $rootScope) {
|
||||
$location.path('/');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('Home');
|
||||
});
|
||||
});
|
||||
|
||||
it('should bind the component to the current router', function() {
|
||||
var router;
|
||||
registerComponent('homeCmp', {
|
||||
bindings: { $router: '=' },
|
||||
controller: function($scope, $element) {
|
||||
this.$routerOnActivate = function() {
|
||||
router = this.$router;
|
||||
};
|
||||
},
|
||||
template: 'Home'
|
||||
});
|
||||
|
||||
registerComponent('app', {
|
||||
template: '<div ng-outlet></div>',
|
||||
$routeConfig: [
|
||||
{ path: '/', component: 'homeCmp' }
|
||||
]
|
||||
});
|
||||
|
||||
module('testMod');
|
||||
compileApp();
|
||||
|
||||
inject(function($location, $rootScope) {
|
||||
$location.path('/');
|
||||
$rootScope.$digest();
|
||||
var homeElement = elt.find('home-cmp');
|
||||
expect(homeElement.text()).toBe('Home');
|
||||
expect(homeElement.isolateScope().$ctrl.$router).toBeDefined();
|
||||
expect(router).toBeDefined();
|
||||
})
|
||||
});
|
||||
|
||||
it('should work when an async route is provided route data', function() {
|
||||
registerComponent('homeCmp', {
|
||||
template: 'Home ({{$ctrl.isAdmin}})',
|
||||
$routerOnActivate: function(next, prev) {
|
||||
this.isAdmin = next.routeData.data.isAdmin;
|
||||
}
|
||||
});
|
||||
|
||||
registerComponent('app', {
|
||||
template: '<div ng-outlet></div>',
|
||||
$routeConfig: [
|
||||
{ path: '/', loader: function($q) { return $q.when('homeCmp'); }, data: { isAdmin: true } }
|
||||
]
|
||||
});
|
||||
|
||||
module('testMod');
|
||||
compileApp();
|
||||
|
||||
inject(function($location, $rootScope) {
|
||||
$location.path('/');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('Home (true)');
|
||||
});
|
||||
});
|
||||
|
||||
it('should work with a templateUrl component', function() {
|
||||
|
||||
var $routerOnActivate = jasmine.createSpy('$routerOnActivate');
|
||||
|
||||
registerComponent('homeCmp', {
|
||||
templateUrl: 'homeCmp.html',
|
||||
$routerOnActivate: $routerOnActivate
|
||||
});
|
||||
|
||||
registerComponent('app', {
|
||||
template: '<div ng-outlet></div>',
|
||||
$routeConfig: [
|
||||
{ path: '/', component: 'homeCmp' }
|
||||
]
|
||||
});
|
||||
|
||||
module('testMod');
|
||||
|
||||
inject(function($location, $rootScope, $httpBackend) {
|
||||
|
||||
$httpBackend.expectGET('homeCmp.html').respond('Home');
|
||||
|
||||
compileApp();
|
||||
|
||||
$location.path('/');
|
||||
$rootScope.$digest();
|
||||
$httpBackend.flush();
|
||||
var homeElement = elt.find('home-cmp');
|
||||
expect(homeElement.text()).toBe('Home');
|
||||
expect($routerOnActivate).toHaveBeenCalled();
|
||||
})
|
||||
});
|
||||
|
||||
it('should provide the current instruction', function() {
|
||||
registerComponent('homeCmp', {
|
||||
template: 'Home ({{homeCmp.isAdmin}})'
|
||||
});
|
||||
|
||||
registerComponent('app', {
|
||||
template: '<div ng-outlet></div>',
|
||||
$routeConfig: [
|
||||
{ path: '/', component: 'homeCmp', name: 'Home' }
|
||||
]
|
||||
});
|
||||
|
||||
module('testMod');
|
||||
|
||||
inject(function($rootScope, $rootRouter, $location) {
|
||||
compileApp();
|
||||
|
||||
$location.path('/');
|
||||
$rootScope.$digest();
|
||||
var instruction = $rootRouter.generate(['/Home']);
|
||||
expect($rootRouter.currentInstruction).toEqual(instruction);
|
||||
});
|
||||
});
|
||||
|
||||
it('should provide the root level router', function() {
|
||||
registerComponent('homeCmp', {
|
||||
template: 'Home ({{homeCmp.isAdmin}})',
|
||||
bindings: {
|
||||
$router: '<'
|
||||
}
|
||||
});
|
||||
|
||||
registerComponent('app', {
|
||||
template: '<div ng-outlet></div>',
|
||||
$routeConfig: [
|
||||
{ path: '/', component: 'homeCmp', name: 'Home' }
|
||||
]
|
||||
});
|
||||
|
||||
module('testMod');
|
||||
|
||||
inject(function($rootScope, $rootRouter, $location) {
|
||||
compileApp();
|
||||
|
||||
$location.path('/');
|
||||
$rootScope.$digest();
|
||||
var homeElement = elt.find('home-cmp');
|
||||
expect(homeElement.isolateScope().$ctrl.$router.root).toEqual($rootRouter);
|
||||
});
|
||||
});
|
||||
|
||||
function registerComponent(name, options) {
|
||||
var controller = options.controller || function () {};
|
||||
|
||||
['$onActivate', '$onDeactivate', '$onReuse', '$canReuse', '$canDeactivate'].forEach(function (hookName) {
|
||||
var definition = {
|
||||
bindings: options.bindings,
|
||||
controller: getController(options),
|
||||
};
|
||||
if (options.template) definition.template = options.template;
|
||||
if (options.templateUrl) definition.templateUrl = options.templateUrl;
|
||||
|
||||
applyStaticProperties(definition.controller, options);
|
||||
angular.module('testMod').component(name, definition);
|
||||
}
|
||||
|
||||
function compileApp() {
|
||||
inject(function($compile, $rootScope) {
|
||||
elt = $compile('<div><app></app</div>')($rootScope);
|
||||
$rootScope.$digest();
|
||||
});
|
||||
return elt;
|
||||
}
|
||||
|
||||
function getController(options) {
|
||||
var controller = options.controller || function () {};
|
||||
[
|
||||
'$routerOnActivate', '$routerOnDeactivate',
|
||||
'$routerOnReuse', '$routerCanReuse',
|
||||
'$routerCanDeactivate'
|
||||
].forEach(function (hookName) {
|
||||
if (options[hookName]) {
|
||||
controller.prototype[hookName] = options[hookName];
|
||||
}
|
||||
});
|
||||
|
||||
function factory() {
|
||||
return {
|
||||
template: options.template || '',
|
||||
controllerAs: name,
|
||||
controller: controller
|
||||
};
|
||||
}
|
||||
|
||||
if (options.$canActivate) {
|
||||
factory.$canActivate = options.$canActivate;
|
||||
}
|
||||
if (options.$routeConfig) {
|
||||
factory.$routeConfig = options.$routeConfig;
|
||||
}
|
||||
|
||||
$compileProvider.directive(name, factory);
|
||||
return controller;
|
||||
}
|
||||
|
||||
function compile(template) {
|
||||
elt = $compile('<div>' + template + '</div>')($rootScope);
|
||||
$rootScope.$digest();
|
||||
return elt;
|
||||
function applyStaticProperties(target, options) {
|
||||
['$canActivate', '$routeConfig'].forEach(function(property) {
|
||||
if (options[property]) {
|
||||
target[property] = options[property];
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -5,7 +5,7 @@ describe('ngRoute shim', function () {
|
||||
var elt,
|
||||
$compile,
|
||||
$rootScope,
|
||||
$router,
|
||||
$rootRouter,
|
||||
$compileProvider,
|
||||
$routeProvider;
|
||||
|
||||
@ -18,10 +18,10 @@ describe('ngRoute shim', function () {
|
||||
$routeProvider = _$routeProvider_;
|
||||
});
|
||||
|
||||
inject(function (_$compile_, _$rootScope_, _$router_) {
|
||||
inject(function (_$compile_, _$rootScope_, _$rootRouter_) {
|
||||
$compile = _$compile_;
|
||||
$rootScope = _$rootScope_;
|
||||
$router = _$router_;
|
||||
$rootRouter = _$rootRouter_;
|
||||
});
|
||||
});
|
||||
|
||||
@ -36,7 +36,7 @@ describe('ngRoute shim', function () {
|
||||
|
||||
compile('<ng-outlet></ng-outlet>');
|
||||
|
||||
$router.navigateByUrl('/');
|
||||
$rootRouter.navigateByUrl('/');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(elt.text()).toBe('one');
|
||||
@ -55,7 +55,7 @@ describe('ngRoute shim', function () {
|
||||
|
||||
compile('root {<ng-outlet></ng-outlet>}');
|
||||
|
||||
$router.navigateByUrl('/');
|
||||
$rootRouter.navigateByUrl('/');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('root {one}');
|
||||
}));
|
||||
@ -76,7 +76,7 @@ describe('ngRoute shim', function () {
|
||||
|
||||
compile('<ng-outlet></ng-outlet>');
|
||||
|
||||
$router.navigateByUrl('/');
|
||||
$rootRouter.navigateByUrl('/');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(elt.text()).toBe('value: 42');
|
||||
@ -94,11 +94,11 @@ describe('ngRoute shim', function () {
|
||||
|
||||
compile('<ng-outlet></ng-outlet>');
|
||||
|
||||
$router.navigateByUrl('/user/brian');
|
||||
$rootRouter.navigateByUrl('/user/brian');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('hello brian');
|
||||
|
||||
$router.navigateByUrl('/user/igor');
|
||||
$rootRouter.navigateByUrl('/user/igor');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('hello igor');
|
||||
});
|
||||
@ -115,7 +115,7 @@ describe('ngRoute shim', function () {
|
||||
|
||||
compile('<ng-outlet></ng-outlet>');
|
||||
|
||||
$router.navigateByUrl('/home/foo/bar/123');
|
||||
$rootRouter.navigateByUrl('/home/foo/bar/123');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('rest: foo/bar/123');
|
||||
});
|
||||
@ -129,7 +129,7 @@ describe('ngRoute shim', function () {
|
||||
|
||||
compile('root {<ng-outlet></ng-outlet>}');
|
||||
|
||||
$router.navigateByUrl('/home/test');
|
||||
$rootRouter.navigateByUrl('/home/test');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('root {}');
|
||||
expect(console.warn)
|
||||
@ -150,7 +150,7 @@ describe('ngRoute shim', function () {
|
||||
|
||||
compile('root {<ng-outlet></ng-outlet>}');
|
||||
|
||||
$router.navigateByUrl('/');
|
||||
$rootRouter.navigateByUrl('/');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('root {welcome home!}');
|
||||
expect($location.path()).toBe('/home');
|
||||
@ -169,7 +169,7 @@ describe('ngRoute shim', function () {
|
||||
|
||||
compile('root {<ng-outlet></ng-outlet>}');
|
||||
|
||||
$router.navigateByUrl('/somewhere');
|
||||
$rootRouter.navigateByUrl('/somewhere');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('root {welcome home!}');
|
||||
expect($location.path()).toBe('/home');
|
||||
|
304
modules/angular1_router/test/ng_link_spec.js
vendored
304
modules/angular1_router/test/ng_link_spec.js
vendored
@ -2,169 +2,191 @@
|
||||
|
||||
describe('ngLink', function () {
|
||||
|
||||
var elt,
|
||||
$compile,
|
||||
$rootScope,
|
||||
$router,
|
||||
$compileProvider;
|
||||
describe('html5Mode enabled', function () {
|
||||
runHrefTestsAndExpectPrefix('/', true);
|
||||
});
|
||||
|
||||
beforeEach(function () {
|
||||
module('ng');
|
||||
module('ngComponentRouter');
|
||||
module(function (_$compileProvider_) {
|
||||
$compileProvider = _$compileProvider_;
|
||||
describe('html5Mode disabled', function () {
|
||||
runHrefTestsAndExpectPrefix('', false, '');
|
||||
});
|
||||
|
||||
describe('html5Mode disabled, with hash prefix', function () {
|
||||
runHrefTestsAndExpectPrefix('', false, '!');
|
||||
});
|
||||
|
||||
describe('html5Mode enabled', function () {
|
||||
runHrefTestsAndExpectPrefix('/moo', true);
|
||||
});
|
||||
|
||||
describe('html5Mode disabled', function () {
|
||||
runHrefTestsAndExpectPrefix('/moo', false, '');
|
||||
});
|
||||
|
||||
describe('html5Mode disabled, with hash prefix', function () {
|
||||
runHrefTestsAndExpectPrefix('/moo', false, '!');
|
||||
});
|
||||
|
||||
function runHrefTestsAndExpectPrefix(baseHref, html5Mode, hashPrefix) {
|
||||
var prefix = html5Mode ? '.' : '#' + hashPrefix;
|
||||
|
||||
it('should allow linking from the parent to the child', function () {
|
||||
setup({baseHref: baseHref, html5Mode: html5Mode, hashPrefix: hashPrefix});
|
||||
configureRouter([
|
||||
{ path: '/a', component: 'oneCmp' },
|
||||
{ path: '/b', component: 'twoCmp', name: 'Two' }
|
||||
]);
|
||||
|
||||
var elt = compile('<a ng-link="[\'/Two\']">link</a> | outer { <div ng-outlet></div> }');
|
||||
navigateTo('/a');
|
||||
expect(elt.find('a').attr('href')).toBe(prefix + '/b');
|
||||
});
|
||||
|
||||
inject(function (_$compile_, _$rootScope_, _$router_) {
|
||||
$compile = _$compile_;
|
||||
$rootScope = _$rootScope_;
|
||||
$router = _$router_;
|
||||
it('should allow linking from the child and the parent', function () {
|
||||
setup({baseHref: baseHref, html5Mode: html5Mode, hashPrefix: hashPrefix});
|
||||
configureRouter([
|
||||
{ path: '/a', component: 'oneCmp' },
|
||||
{ path: '/b', component: 'twoCmp', name: 'Two' }
|
||||
]);
|
||||
|
||||
var elt = compile('outer { <div ng-outlet></div> }');
|
||||
navigateTo('/b');
|
||||
expect(elt.find('a').attr('href')).toBe(prefix + '/b');
|
||||
});
|
||||
|
||||
registerComponent('userCmp', '<div>hello {{userCmp.$routeParams.name}}</div>', function () {});
|
||||
registerComponent('oneCmp', '<div>{{oneCmp.number}}</div>', function () {this.number = 'one'});
|
||||
registerComponent('twoCmp', '<div><a ng-link="[\'/Two\']">{{twoCmp.number}}</a></div>', function () {this.number = 'two'});
|
||||
});
|
||||
|
||||
it('should allow params in routerLink directive', function () {
|
||||
setup({baseHref: baseHref, html5Mode: html5Mode, hashPrefix: hashPrefix});
|
||||
registerComponent('twoLinkCmp', '<div><a ng-link="[\'/Two\', {param: \'lol\'}]">{{twoLinkCmp.number}}</a></div>', function () {this.number = 'two'});
|
||||
configureRouter([
|
||||
{ path: '/a', component: 'twoLinkCmp' },
|
||||
{ path: '/b/:param', component: 'twoCmp', name: 'Two' }
|
||||
]);
|
||||
|
||||
var elt = compile('<div ng-outlet></div>');
|
||||
navigateTo('/a');
|
||||
expect(elt.find('a').attr('href')).toBe(prefix + '/b/lol');
|
||||
});
|
||||
|
||||
|
||||
it('should allow linking from the parent to the child', function () {
|
||||
$router.config([
|
||||
{ path: '/a', component: 'oneCmp' },
|
||||
{ path: '/b', component: 'twoCmp', name: 'Two' }
|
||||
]);
|
||||
compile('<a ng-link="[\'/Two\']">link</a> | outer { <div ng-outlet></div> }');
|
||||
it('should update the href of links with bound params', function () {
|
||||
setup({baseHref: baseHref, html5Mode: html5Mode, hashPrefix: hashPrefix});
|
||||
registerComponent('twoLinkCmp', '<div><a ng-link="[\'/Two\', {param: $ctrl.number}]">{{$ctrl.number}}</a></div>', function () {this.number = 43});
|
||||
configureRouter([
|
||||
{ path: '/a', component: 'twoLinkCmp' },
|
||||
{ path: '/b/:param', component: 'twoCmp', name: 'Two' }
|
||||
]);
|
||||
|
||||
$router.navigateByUrl('/a');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(elt.find('a').attr('href')).toBe('./b');
|
||||
});
|
||||
|
||||
it('should allow linking from the child and the parent', function () {
|
||||
$router.config([
|
||||
{ path: '/a', component: 'oneCmp' },
|
||||
{ path: '/b', component: 'twoCmp', name: 'Two' }
|
||||
]);
|
||||
compile('outer { <div ng-outlet></div> }');
|
||||
|
||||
$router.navigateByUrl('/b');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(elt.find('a').attr('href')).toBe('./b');
|
||||
});
|
||||
var elt = compile('<div ng-outlet></div>');
|
||||
navigateTo('/a');
|
||||
expect(elt.find('a').text()).toBe('43');
|
||||
expect(elt.find('a').attr('href')).toBe(prefix + '/b/43');
|
||||
});
|
||||
|
||||
|
||||
it('should allow params in routerLink directive', function () {
|
||||
registerComponent('twoLinkCmp', '<div><a ng-link="[\'/Two\', {param: \'lol\'}]">{{twoLinkCmp.number}}</a></div>', function () {this.number = 'two'});
|
||||
it('should navigate on left-mouse click when a link url matches a route', function () {
|
||||
setup({baseHref: baseHref, html5Mode: html5Mode, hashPrefix: hashPrefix});
|
||||
configureRouter([
|
||||
{ path: '/', component: 'oneCmp' },
|
||||
{ path: '/two', component: 'twoCmp', name: 'Two'}
|
||||
]);
|
||||
|
||||
$router.config([
|
||||
{ path: '/a', component: 'twoLinkCmp' },
|
||||
{ path: '/b/:param', component: 'twoCmp', name: 'Two' }
|
||||
]);
|
||||
compile('<div ng-outlet></div>');
|
||||
var elt = compile('<a ng-link="[\'/Two\']">link</a> | <div ng-outlet></div>');
|
||||
expect(elt.text()).toBe('link | one');
|
||||
expect(elt.find('a').attr('href')).toBe(prefix + '/two');
|
||||
|
||||
$router.navigateByUrl('/a');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(elt.find('a').attr('href')).toBe('./b/lol');
|
||||
});
|
||||
|
||||
|
||||
it('should update the href of links with bound params', function () {
|
||||
registerComponent('twoLinkCmp', '<div><a ng-link="[\'/Two\', {param: twoLinkCmp.number}]">{{twoLinkCmp.number}}</a></div>', function () {this.number = 'param'});
|
||||
$router.config([
|
||||
{ path: '/a', component: 'twoLinkCmp' },
|
||||
{ path: '/b/:param', component: 'twoCmp', name: 'Two' }
|
||||
]);
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$router.navigateByUrl('/a');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(elt.find('a').attr('href')).toBe('./b/param');
|
||||
});
|
||||
|
||||
|
||||
it('should navigate on left-mouse click when a link url matches a route', function () {
|
||||
$router.config([
|
||||
{ path: '/', component: 'oneCmp' },
|
||||
{ path: '/two', component: 'twoCmp', name: 'Two'}
|
||||
]);
|
||||
|
||||
compile('<a ng-link="[\'/Two\']">link</a> | <div ng-outlet></div>');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('link | one');
|
||||
|
||||
expect(elt.find('a').attr('href')).toBe('./two');
|
||||
|
||||
elt.find('a')[0].click();
|
||||
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('link | two');
|
||||
});
|
||||
|
||||
|
||||
it('should not navigate on non-left mouse click when a link url matches a route', inject(function ($router) {
|
||||
$router.config([
|
||||
{ path: '/', component: 'oneCmp' },
|
||||
{ path: '/two', component: 'twoCmp', name: 'Two'}
|
||||
]);
|
||||
|
||||
compile('<a ng-link="[\'/Two\']">link</a> | <div ng-outlet></div>');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('link | one');
|
||||
elt.find('a').triggerHandler({ type: 'click', which: 3 });
|
||||
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('link | one');
|
||||
}));
|
||||
|
||||
|
||||
// See https://github.com/angular/router/issues/206
|
||||
it('should not navigate a link without an href', function () {
|
||||
$router.config([
|
||||
{ path: '/', component: 'oneCmp' },
|
||||
{ path: '/two', component: 'twoCmp', name: 'Two'}
|
||||
]);
|
||||
expect(function () {
|
||||
compile('<a>link</a>');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('link');
|
||||
elt.find('a')[0].click();
|
||||
$rootScope.$digest();
|
||||
}).not.toThrow();
|
||||
});
|
||||
inject(function($rootScope) { $rootScope.$digest(); });
|
||||
expect(elt.text()).toBe('link | two');
|
||||
});
|
||||
|
||||
|
||||
function registerComponent(name, template, config) {
|
||||
var controller = function () {};
|
||||
it('should not navigate on non-left mouse click when a link url matches a route', function() {
|
||||
setup({baseHref: baseHref, html5Mode: html5Mode, hashPrefix: hashPrefix});
|
||||
configureRouter([
|
||||
{ path: '/', component: 'oneCmp' },
|
||||
{ path: '/two', component: 'twoCmp', name: 'Two'}
|
||||
]);
|
||||
|
||||
function factory() {
|
||||
return {
|
||||
var elt = compile('<a ng-link="[\'/Two\']">link</a> | <div ng-outlet></div>');
|
||||
expect(elt.text()).toBe('link | one');
|
||||
elt.find('a').triggerHandler({ type: 'click', which: 3 });
|
||||
inject(function($rootScope) { $rootScope.$digest(); });
|
||||
expect(elt.text()).toBe('link | one');
|
||||
});
|
||||
|
||||
|
||||
// See https://github.com/angular/router/issues/206
|
||||
it('should not navigate a link without an href', function () {
|
||||
setup({baseHref: baseHref, html5Mode: html5Mode, hashPrefix: hashPrefix});
|
||||
configureRouter([
|
||||
{ path: '/', component: 'oneCmp' },
|
||||
{ path: '/two', component: 'twoCmp', name: 'Two'}
|
||||
]);
|
||||
expect(function () {
|
||||
var elt = compile('<a>link</a>');
|
||||
expect(elt.text()).toBe('link');
|
||||
elt.find('a')[0].click();
|
||||
inject(function($rootScope) { $rootScope.$digest(); });
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should add an ng-link-active class on the current link', function() {
|
||||
setup({baseHref: baseHref, html5Mode: html5Mode, hashPrefix: hashPrefix});
|
||||
configureRouter([
|
||||
{ path: '/', component: 'oneCmp', name: 'One' }
|
||||
]);
|
||||
|
||||
var elt = compile('<a ng-link="[\'/One\']">one</a> | <div ng-outlet></div>');
|
||||
navigateTo('/');
|
||||
expect(elt.find('a').attr('class')).toBe('ng-link-active');
|
||||
});
|
||||
}
|
||||
|
||||
function registerComponent(name, template, controller) {
|
||||
module(function($compileProvider) {
|
||||
$compileProvider.component(name, {
|
||||
template: template,
|
||||
controllerAs: name,
|
||||
controller: controller
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (!template) {
|
||||
template = '';
|
||||
}
|
||||
if (angular.isArray(config)) {
|
||||
factory.annotations = [new angular.annotations.RouteConfig(config)];
|
||||
} else if (typeof config === 'function') {
|
||||
controller = config;
|
||||
} else if (typeof config === 'object') {
|
||||
if (config.canActivate) {
|
||||
controller.$canActivate = config.canActivate;
|
||||
}
|
||||
}
|
||||
$compileProvider.directive(name, factory);
|
||||
function setup(config) {
|
||||
module(function($provide) {
|
||||
$provide.decorator('$browser', function($delegate) {
|
||||
$delegate.baseHref = function() { return config.baseHref; };
|
||||
return $delegate;
|
||||
});
|
||||
});
|
||||
module('ngComponentRouter');
|
||||
module(function($locationProvider) {
|
||||
$locationProvider.html5Mode(config.html5Mode);
|
||||
$locationProvider.hashPrefix(config.hashPrefix);
|
||||
});
|
||||
registerComponent('userCmp', '<div>hello {{$ctrl.$routeParams.name}}</div>', function () {});
|
||||
registerComponent('oneCmp', '<div>{{$ctrl.number}}</div>', function () {this.number = 'one'});
|
||||
registerComponent('twoCmp', '<div><a ng-link="[\'/Two\']">{{$ctrl.number}}</a></div>', function () {this.number = 'two'});
|
||||
}
|
||||
|
||||
function configureRouter(routeConfig) {
|
||||
inject(function($rootRouter) {
|
||||
$rootRouter.config(routeConfig);
|
||||
});
|
||||
}
|
||||
|
||||
function compile(template) {
|
||||
elt = $compile('<div>' + template + '</div>')($rootScope);
|
||||
$rootScope.$digest();
|
||||
var elt;
|
||||
inject(function($compile, $rootScope) {
|
||||
elt = $compile('<div>' + template + '</div>')($rootScope);
|
||||
$rootScope.$digest();
|
||||
});
|
||||
return elt;
|
||||
}
|
||||
|
||||
function navigateTo(url) {
|
||||
inject(function($rootRouter, $rootScope) {
|
||||
$rootRouter.navigateByUrl(url);
|
||||
$rootScope.$digest();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -22,7 +22,7 @@ function provideHelpers(fn, preInject) {
|
||||
var elt,
|
||||
$compile,
|
||||
$rootScope,
|
||||
$router,
|
||||
$rootRouter,
|
||||
$templateCache,
|
||||
$controllerProvider;
|
||||
|
||||
@ -32,10 +32,10 @@ function provideHelpers(fn, preInject) {
|
||||
$controllerProvider = _$controllerProvider_;
|
||||
});
|
||||
|
||||
inject(function(_$compile_, _$rootScope_, _$router_, _$templateCache_) {
|
||||
inject(function(_$compile_, _$rootScope_, _$rootRouter_, _$templateCache_) {
|
||||
$compile = _$compile_;
|
||||
$rootScope = _$rootScope_;
|
||||
$router = _$router_;
|
||||
$rootRouter = _$rootRouter_;
|
||||
$templateCache = _$templateCache_;
|
||||
});
|
||||
|
||||
@ -72,7 +72,7 @@ function provideHelpers(fn, preInject) {
|
||||
|
||||
fn({
|
||||
registerComponent: registerComponent,
|
||||
$router: $router,
|
||||
$rootRouter: $rootRouter,
|
||||
put: put,
|
||||
compile: compile
|
||||
})
|
||||
|
@ -1,12 +1,12 @@
|
||||
{
|
||||
"version": "v4",
|
||||
"repo": "angular/DefinitelyTyped",
|
||||
"repo": "DefinitelyTyped/DefinitelyTyped",
|
||||
"ref": "master",
|
||||
"path": "typings",
|
||||
"bundle": "typings/tsd.d.ts",
|
||||
"installed": {
|
||||
"angularjs/angular.d.ts": {
|
||||
"commit": "746b9a892629060bc853e792afff536e0ec4655e"
|
||||
"commit": "6eebd5e90a1cbd6b47b0705ba72dbcd5baf846f3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,7 @@ library angular2;
|
||||
*
|
||||
* This library does not include `bootstrap`. Import `bootstrap.dart` instead.
|
||||
*/
|
||||
export 'package:angular2/core.dart'
|
||||
hide forwardRef, resolveForwardRef, ForwardRefFn;
|
||||
export 'package:angular2/core.dart';
|
||||
export 'package:angular2/common.dart';
|
||||
export 'package:angular2/instrumentation.dart';
|
||||
export 'package:angular2/src/core/angular_entrypoint.dart' show AngularEntrypoint;
|
||||
|
@ -1,5 +1,6 @@
|
||||
library angular2.core;
|
||||
|
||||
export './src/core/angular_entrypoint.dart' show AngularEntrypoint;
|
||||
export './src/core/metadata.dart';
|
||||
export './src/core/util.dart';
|
||||
export 'package:angular2/src/facade/lang.dart' show enableProdMode;
|
||||
@ -14,9 +15,8 @@ export './src/core/application_tokens.dart' show APP_ID,
|
||||
export './src/core/zone.dart';
|
||||
export './src/core/render.dart';
|
||||
export './src/core/linker.dart';
|
||||
export './src/core/debug/debug_element.dart' show DebugElement,
|
||||
Scope,
|
||||
inspectElement,
|
||||
export './src/core/debug/debug_node.dart' show DebugElement,
|
||||
DebugNode,
|
||||
asNativeElements;
|
||||
export './src/core/testability/testability.dart';
|
||||
export './src/core/change_detection.dart';
|
||||
|
@ -20,12 +20,7 @@ export {
|
||||
export * from './src/core/zone';
|
||||
export * from './src/core/render';
|
||||
export * from './src/core/linker';
|
||||
export {
|
||||
DebugElement,
|
||||
Scope,
|
||||
inspectElement,
|
||||
asNativeElements
|
||||
} from './src/core/debug/debug_element';
|
||||
export {DebugElement, DebugNode, asNativeElements} from './src/core/debug/debug_node';
|
||||
export * from './src/core/testability/testability';
|
||||
export * from './src/core/change_detection';
|
||||
export * from './src/core/platform_directives_and_pipes';
|
||||
|
@ -8,7 +8,7 @@
|
||||
# Modules, barrels and bundles
|
||||
|
||||
Angular2 source code is authored using the ES2015 standardized module format where one module corresponds to exactly one file. Multiple modules (files) can be logically grouped into so-called "barrels".
|
||||
A bundle is a file the contains all the code for one or more barrels.
|
||||
A bundle is a file that contains all the code for one or more barrels.
|
||||
|
||||
Most bundles come in several flavors:
|
||||
* regular and minified (got `.min` in their name);
|
||||
@ -32,7 +32,7 @@ filename | list of barrels | dev/prod | minified?
|
||||
`angular2-all.umd.js` | `angular2/core`, `angular2/common`, `angular2/compiler`, `angular2/platform/browser`, `angular2/platform/common_dom`, `angular2/http`, `angular2/router`, `angular2/instrumentation`, `angular2/upgrade`| prod | no
|
||||
`angular2-all.umd.min.js` | `angular2/core`, `angular2/common`, `angular2/compiler`, `angular2/platform/browser`, `angular2/platform/common_dom`, `angular2/http`, `angular2/router`, `angular2/instrumentation`, `angular2/upgrade` | prod | yes
|
||||
`angular2-all.umd.dev.js` | `angular2/core`, `angular2/common`, `angular2/compiler`, `angular2/platform/browser`, `angular2/platform/common_dom`, `angular2/http`, `angular2/router`, `angular2/instrumentation`, `angular2/upgrade` | dev | no
|
||||
`angular2-all-testing.umd.dev.js` | `angular2/core`, `angular2/common`, `angular2/compiler`, `angular2/platform/browser`, `angular2/platform/common_dom`, `angular2/http`, `angular2/router`, `angular2/instrumentation`, `angular2/upgrade`, `angular2/testing`, `angular2/http/testing`, `angular2/router/testing` | dev | no
|
||||
`angular2-all-testing.umd.dev.js` | `angular2/core`, `angular2/common`, `angular2/compiler`, `angular2/platform/browser`, `angular2/platform/common_dom`, `angular2/http`, `angular2/router`, `angular2/instrumentation`, `angular2/upgrade`, `angular2/testing`, `angular2/http/testing`, `angular2/router/testing`, `angular2/platform/testing/browser` | dev | no
|
||||
|
||||
**Warning**: bundles in the `UMD` format are _not_ "additive". A single application should use only one bundle from the above list.
|
||||
|
||||
@ -55,7 +55,7 @@ filename | list of barrels | dev/prod | minified?
|
||||
`upgrade.js` | `angular2/upgrade` | prod | no
|
||||
`upgrade.min.js` | `angular2/upgrade` | prod | yes
|
||||
`upgrade.dev.js` | `angular2/upgrade` | dev | no
|
||||
`testing.dev.js` | `angular2/testing`, `angular2/http/testing`, `angular2/router/testing` | dev | no
|
||||
`testing.dev.js` | `angular2/testing`, `angular2/http/testing`, `angular2/router/testing`, `angular2/platform/testing/browser` | dev | no
|
||||
|
||||
**Note**: bundles in the `System.register` format are "additive" - it is quite common to include several bundles in one application.
|
||||
For example people using Angular 2 with `http` and `router` would include: `angular2.js`, `http.js` and `router.js`.
|
||||
@ -72,7 +72,7 @@ An example of an Angular 2 project built with WebPack can be found in the [angul
|
||||
|
||||
Polyfills are required for Angular 2 to function properly (the exact list depends on the browser used) and external dependencies ([zone.js](https://github.com/angular/zone.js)).
|
||||
To ease setup of Angular 2 applications there is one file - `angular2-polyfills.js` - that combines:
|
||||
* a pollyfill mandatory for all browsers: [reflect-metadata](https://www.npmjs.com/package/reflect-metadata)
|
||||
* a polyfill mandatory for all browsers: [reflect-metadata](https://www.npmjs.com/package/reflect-metadata)
|
||||
* [zone.js](https://github.com/angular/zone.js)
|
||||
|
||||
**Note**: `angular2-polyfills.js` contains code that should be loaded into the browser as the very first code of the web application even before the module loader. The preferred solution is to load the mentioned file in a `script` tag as early as possible.
|
||||
@ -89,4 +89,4 @@ Depending on if you are using Angular bundles or not you can either use RxJS bun
|
||||
|
||||
## ES6 shims (optional)
|
||||
|
||||
Users of pre-ES6 browsers might need to add an ES6 shim (e.g. [es6-shim](https://github.com/paulmillr/es6-shim))
|
||||
Users of pre-ES6 browsers might need to add an ES6 shim (e.g. [es6-shim](https://github.com/paulmillr/es6-shim))
|
||||
|
@ -2,9 +2,9 @@
|
||||
Bootstrapping
|
||||
@cheatsheetIndex 0
|
||||
@description
|
||||
{@target ts}`import {bootstrap} from 'angular2/angular2';`{@endtarget}
|
||||
{@target js}Available from the `ng.platform.browser` namespace.{@endtarget}
|
||||
{@target dart}`import 'package:angular2/bootstrap.dart';`{@endtarget}
|
||||
{@target ts}`import {bootstrap} from 'angular2/platform/browser';`{@endtarget}
|
||||
{@target js}Available from the `ng.platform.browser` namespace{@endtarget}
|
||||
{@target dart}`import 'package:angular2/platform/browser.dart';`{@endtarget}
|
||||
|
||||
@cheatsheetItem
|
||||
syntax(ts dart):
|
||||
|
@ -4,7 +4,7 @@ Built-in directives
|
||||
@description
|
||||
{@target ts}`import {NgIf, ...} from 'angular2/common';`{@endtarget}
|
||||
{@target js}Available from the `ng.common` namespace{@endtarget}
|
||||
{@target dart}`import 'package:angular2/common.dart';`{@endtarget}
|
||||
{@target dart}Available using `platform_directives` in pubspec{@endtarget}
|
||||
|
||||
@cheatsheetItem
|
||||
syntax:
|
||||
|
@ -4,7 +4,7 @@ Class decorators
|
||||
@description
|
||||
{@target ts}`import {Directive, ...} from 'angular2/core';`{@endtarget}
|
||||
{@target js}Available from the `ng.core` namespace{@endtarget}
|
||||
{@target dart}`import 'package:angular2/core.dart';`{@endtarget}
|
||||
{@target dart}`import 'package:angular2/angular2.dart';`{@endtarget}
|
||||
|
||||
@cheatsheetItem
|
||||
syntax(ts):
|
||||
|
@ -4,7 +4,7 @@ Dependency injection configuration
|
||||
@description
|
||||
{@target ts}`import {provide} from 'angular2/core';`{@endtarget}
|
||||
{@target js}Available from the `ng.core` namespace{@endtarget}
|
||||
{@target dart}`import 'package:angular2/core.dart';`{@endtarget}
|
||||
{@target dart}`import 'package:angular2/angular2.dart';`{@endtarget}
|
||||
|
||||
@cheatsheetItem
|
||||
syntax(ts dart):
|
||||
|
@ -4,7 +4,7 @@ Class field decorators for directives and components
|
||||
@description
|
||||
{@target ts}`import {Input, ...} from 'angular2/core';`{@endtarget}
|
||||
{@target js}Available from the `ng.core` namespace{@endtarget}
|
||||
{@target dart}`import 'package:angular2/core.dart';`{@endtarget}
|
||||
{@target dart}`import 'package:angular2/angular2.dart';`{@endtarget}
|
||||
|
||||
@cheatsheetItem
|
||||
syntax(ts dart):
|
||||
|
@ -4,7 +4,7 @@ Forms
|
||||
@description
|
||||
{@target ts}`import {FORM_DIRECTIVES} from 'angular2/common';`{@endtarget}
|
||||
{@target js}Available from `ng.common.FORM_DIRECTIVES`{@endtarget}
|
||||
{@target dart}`import 'package:angular2/common.dart';`{@endtarget}
|
||||
{@target dart}Available using `platform_directives` in pubspec{@endtarget}
|
||||
|
||||
@cheatsheetItem
|
||||
syntax:
|
||||
|
@ -4,22 +4,22 @@ Routing and navigation
|
||||
@description
|
||||
{@target ts}`import {RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, ...} from 'angular2/router';`{@endtarget}
|
||||
{@target js}Available from the `ng.router` namespace{@endtarget}
|
||||
{@target dart}`import 'package:angular2/router.dart';`{@endtarget}
|
||||
{@target dart}`import 'package:angular2/angular2.dart';`{@endtarget}
|
||||
|
||||
|
||||
@cheatsheetItem
|
||||
syntax(ts):
|
||||
`@RouteConfig([
|
||||
{ path: '/:myParam', component: MyComponent, as: 'MyCmp' },
|
||||
{ path: '/staticPath', component: ..., as: ...},
|
||||
{ path: '/*wildCardParam', component: ..., as: ...}
|
||||
{ path: '/:myParam', component: MyComponent, name: 'MyCmp' },
|
||||
{ path: '/staticPath', component: ..., name: ...},
|
||||
{ path: '/*wildCardParam', component: ..., name: ...}
|
||||
])
|
||||
class MyComponent() {}`|`@RouteConfig`
|
||||
syntax(js):
|
||||
`var MyComponent = ng.router.RouteConfig([
|
||||
{ path: '/:myParam', component: MyComponent, as: 'MyCmp' },
|
||||
{ path: '/staticPath', component: ..., as: ...},
|
||||
{ path: '/*wildCardParam', component: ..., as: ...}
|
||||
{ path: '/:myParam', component: MyComponent, name: 'MyCmp' },
|
||||
{ path: '/staticPath', component: ..., name: ...},
|
||||
{ path: '/*wildCardParam', component: ..., name: ...}
|
||||
]).Class({
|
||||
constructor: function() {}
|
||||
});`|`ng.router.RouteConfig`
|
||||
|
@ -62,16 +62,16 @@ Creates a local variable `movieplayer` that provides access to the `video` eleme
|
||||
|
||||
@cheatsheetItem
|
||||
syntax:
|
||||
`<p *my-unless="myExpression">...</p>`|`*my-unless`
|
||||
`<p *myUnless="myExpression">...</p>`|`*myUnless`
|
||||
description:
|
||||
The `*` symbol means that the current element will be turned into an embedded template. Equivalent to:
|
||||
`<template [myless]="myExpression"><p>...</p></template>`
|
||||
`<template [myUnless]="myExpression"><p>...</p></template>`
|
||||
|
||||
@cheatsheetItem
|
||||
syntax:
|
||||
`<p>Card No.: {{cardNumber | myCreditCardNumberFormatter}}</p>`|`{{cardNumber | myCreditCardNumberFormatter}}`
|
||||
description:
|
||||
Transforms the current value of expression `cardNumber` via the pipe called `creditCardNumberFormatter`.
|
||||
Transforms the current value of expression `cardNumber` via the pipe called `myCreditCardNumberFormatter`.
|
||||
|
||||
@cheatsheetItem
|
||||
syntax:
|
||||
|
@ -456,7 +456,7 @@ Where
|
||||
* `local` is a local identifier for local variables.
|
||||
* `internal` is an internal variable which the directive exports for binding.
|
||||
* `key` is an attribute name usually only used to trigger a specific directive.
|
||||
* `keyExpression` is an property name to which the expression will be bound to.
|
||||
* `keyExpression` is a property name to which the expression will be bound to.
|
||||
* `varExport` allows exporting of directive internal state as variables for further binding. If no `internal` name
|
||||
is specified, the exporting is to an implicit variable.
|
||||
* `microsyntax` allows you to build a simple microsyntax which can still clearly identify which expressions bind to
|
||||
|
@ -112,9 +112,7 @@ Example of a component:
|
||||
'title', | - title mapped to component title
|
||||
'open' | - open attribute mapped to component's open property
|
||||
], |
|
||||
}) |
|
||||
@View({ | View annotation
|
||||
templateUrl: 'pane.html' | - URL of template HTML
|
||||
templateUrl: 'pane.html' | URL of template HTML
|
||||
}) |
|
||||
class Pane { | Component controller class
|
||||
title:string; | - title property
|
||||
@ -227,11 +225,9 @@ class MyService {} | Assume a service which needs to be inject
|
||||
|
|
||||
@Component({ | Assume a top level application component which
|
||||
selector: 'my-app', | configures the services to be injected.
|
||||
viewBindings: [MyService] |
|
||||
}) |
|
||||
@View({ | Assume we have a template that needs to be
|
||||
templateUrl: 'my_app.html', | configured with directives to be injected.
|
||||
directives: [House] |
|
||||
viewBindings: [MyService], |
|
||||
templateUrl: 'my_app.html', | Assume we have a template that needs to be
|
||||
directives: [House] | configured with directives to be injected.
|
||||
}) |
|
||||
class MyApp {} |
|
||||
|
|
||||
@ -273,8 +269,6 @@ Here is an example of the kinds of injections which can be achieved:
|
||||
```
|
||||
@Component({ |
|
||||
selector: 'my-app' |
|
||||
}) |
|
||||
@View({ |
|
||||
templateUrl: 'my_app.html', |
|
||||
directives: [Form, FieldSet, |
|
||||
Field, Primary] |
|
||||
@ -329,8 +323,6 @@ Shadow DOM provides an encapsulation for components, so as a general rule it doe
|
||||
```
|
||||
@Component({
|
||||
selector: '[kid]'
|
||||
})
|
||||
@View({
|
||||
templateUrl: 'kid.html',
|
||||
directives: []
|
||||
})
|
||||
@ -347,8 +339,6 @@ class Kid {
|
||||
|
||||
@Component({
|
||||
selector: '[dad]'
|
||||
})
|
||||
@View({
|
||||
templateUrl: 'dad.html',
|
||||
directives: [Kid]
|
||||
})
|
||||
@ -361,9 +351,7 @@ class Dad {
|
||||
|
||||
@Component({
|
||||
selector: '[grandpa]',
|
||||
viewBindings: []
|
||||
})
|
||||
@View({
|
||||
viewBindings: [],
|
||||
templateUrl: 'grandpa.html',
|
||||
directives: [Dad]
|
||||
})
|
||||
|
@ -179,9 +179,7 @@ Both `MyComponent` and `MyDirective` are created on the same element.
|
||||
],
|
||||
viewBindings: [
|
||||
bind('viewService').toValue('View_MyComponentService')
|
||||
]
|
||||
})
|
||||
@View({
|
||||
],
|
||||
template: `<needs-view-service></needs-view-service>`,
|
||||
directives: [NeedsViewService]
|
||||
})
|
||||
|
@ -371,14 +371,14 @@ In TypeScript:
|
||||
import {platform, Provider, APP_INITIALIZER, Injector} from 'angular2/core';
|
||||
import {
|
||||
WORKER_RENDER_PLATFORM,
|
||||
WORKER_RENDER_APP_COMMON,
|
||||
WORKER_RENDER_APPLICATION_COMMON,
|
||||
initializeGenericWorkerRenderer,
|
||||
MessageBus
|
||||
} from 'angular2/platform/worker_render';
|
||||
|
||||
var bus = new MyAwesomeMessageBus();
|
||||
platform([WORKER_RENDER_PLATFORM])
|
||||
.application([WORKER_RENDER_APP_COMMON, new Provider(MessageBus, {useValue: bus}),
|
||||
.application([WORKER_RENDER_APPLICATION_COMMON, new Provider(MessageBus, {useValue: bus}),
|
||||
new Provider(APP_INITIALIZER, {
|
||||
useFactory: (injector) => () => initializeGenericWorkerRenderer(injector),
|
||||
deps: [Injector],
|
||||
@ -419,7 +419,7 @@ import 'package:angular2/platform/worker_render.dart';
|
||||
main() {
|
||||
var bus = new MyAwesomeMessageBus();
|
||||
platform([WORKER_RENDER_PLATFORM])
|
||||
.application([WORKER_RENDER_APP_COMMON, new Provider(MessageBus, useValue: bus),
|
||||
.application([WORKER_RENDER_APPLICATION_COMMON, new Provider(MessageBus, useValue: bus),
|
||||
new Provider(APP_INITIALIZER,
|
||||
useFactory: (injector) => () => initializeGenericWorkerRenderer(injector),
|
||||
deps: [Injector],
|
||||
@ -456,9 +456,9 @@ void initAppThread(NgZone zone) {
|
||||
*/
|
||||
}
|
||||
```
|
||||
Notice how we use the `WORKER_RENDER_APP_COMMON` providers instead of the `WORKER_RENDER_APP` providers on the render thread.
|
||||
This is because the `WORKER_RENDER_APP` providers include an application initializer that starts a new WebWorker/Isolate.
|
||||
The `WORKER_RENDER_APP_COMMON` providers make no assumption about where your application code lives.
|
||||
Notice how we use the `WORKER_RENDER_APPLICTION_COMMON` providers instead of the `WORKER_RENDER_APPLICATION` providers on the render thread.
|
||||
This is because the `WORKER_RENDER_APPLICATION` providers include an application initializer that starts a new WebWorker/Isolate.
|
||||
The `WORKER_RENDER_APPLICATION_COMMON` providers make no assumption about where your application code lives.
|
||||
However, we now need to provide our own app initializer. At the very least this initializer needs to call `initializeGenericWorkerRenderer`.
|
||||
|
||||
## MessageBroker
|
||||
|
@ -1,8 +1,8 @@
|
||||
import {provide} from 'angular2/core';
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {bootstrap} from 'angular2/platform/browser';
|
||||
import {UrlResolver} from 'angular2/compiler';
|
||||
|
||||
var MyApp;
|
||||
var MyApp: any;
|
||||
|
||||
// #docregion url_resolver
|
||||
class MyUrlResolver extends UrlResolver {
|
||||
|
@ -1,16 +1,8 @@
|
||||
import {DebugElement, Scope} from 'angular2/core';
|
||||
import {DebugElement} from 'angular2/core';
|
||||
|
||||
var debugElement: DebugElement;
|
||||
var predicate;
|
||||
var predicate: any;
|
||||
|
||||
// #docregion scope_all
|
||||
debugElement.query(predicate, Scope.all);
|
||||
// #enddocregion
|
||||
|
||||
// #docregion scope_light
|
||||
debugElement.query(predicate, Scope.light);
|
||||
// #enddocregion
|
||||
|
||||
// #docregion scope_view
|
||||
debugElement.query(predicate, Scope.view);
|
||||
debugElement.query(predicate);
|
||||
// #enddocregion
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {bootstrap} from 'angular2/platform/browser';
|
||||
import {NG_VALIDATORS} from 'angular2/common';
|
||||
import {Provider} from 'angular2/core';
|
||||
|
||||
let MyApp = null;
|
||||
let myValidator = null;
|
||||
let MyApp: Function = null;
|
||||
let myValidator: any = null;
|
||||
|
||||
// #docregion ng_validators
|
||||
bootstrap(MyApp, [new Provider(NG_VALIDATORS, {useValue: myValidator, multi: true})]);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {Component, provide} from 'angular2/core';
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
import {bootstrap} from 'angular2/platform/browser';
|
||||
import {Observable, Subscriber} from 'rxjs/Rx';
|
||||
|
||||
// #docregion AsyncPipe
|
||||
@Component({
|
||||
@ -37,8 +37,9 @@ export class AsyncPipeExample {
|
||||
// #docregion AsyncPipeObservable
|
||||
@Component({selector: "task-cmp", template: "Time: {{ time | async }}"})
|
||||
class Task {
|
||||
time = new Observable<number>(
|
||||
observer => { setInterval(_ => observer.next(new Date().getTime()), 500); });
|
||||
time = new Observable<number>((observer: Subscriber<number>) => {
|
||||
setInterval(() => observer.next(new Date().getTime()), 500);
|
||||
});
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {Component, provide} from 'angular2/core';
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {bootstrap} from 'angular2/platform/browser';
|
||||
|
||||
// #docregion DatePipe
|
||||
@Component({
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {Component, provide} from 'angular2/core';
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {bootstrap} from 'angular2/platform/browser';
|
||||
|
||||
// #docregion JsonPipe
|
||||
@Component({
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {Component, provide} from 'angular2/core';
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {bootstrap} from 'angular2/platform/browser';
|
||||
|
||||
// #docregion LowerUpperPipe
|
||||
@Component({
|
||||
@ -12,7 +12,7 @@ import {bootstrap} from 'angular2/bootstrap';
|
||||
})
|
||||
export class LowerUpperPipeExample {
|
||||
value: string;
|
||||
change(value) { this.value = value; }
|
||||
change(value: string) { this.value = value; }
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {Component, provide} from 'angular2/core';
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {bootstrap} from 'angular2/platform/browser';
|
||||
|
||||
// #docregion NumberPipe
|
||||
@Component({
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {Component, provide} from 'angular2/core';
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {bootstrap} from 'angular2/platform/browser';
|
||||
|
||||
// #docregion SlicePipe_string
|
||||
@Component({
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {Component, Attribute, Directive, Pipe} from 'angular2/core';
|
||||
|
||||
var CustomDirective;
|
||||
var CustomDirective: Function;
|
||||
|
||||
// #docregion component
|
||||
@Component({selector: 'greet', template: 'Hello {{name}}!', directives: [CustomDirective]})
|
||||
@ -20,7 +20,7 @@ class Page {
|
||||
// #docregion attributeMetadata
|
||||
@Directive({selector: 'input'})
|
||||
class InputAttrDirective {
|
||||
constructor(@Attribute('type') type) {
|
||||
constructor(@Attribute('type') type: string) {
|
||||
// type would be 'text' in this example
|
||||
}
|
||||
}
|
||||
@ -38,6 +38,6 @@ class InputDirective {
|
||||
// #docregion pipe
|
||||
@Pipe({name: 'lowercase'})
|
||||
class Lowercase {
|
||||
transform(v, args) { return v.toLowerCase(); }
|
||||
transform(v: string, args: any[]) { return v.toLowerCase(); }
|
||||
}
|
||||
// #enddocregion
|
||||
|
@ -1,7 +1,7 @@
|
||||
// #docregion enableProdMode
|
||||
import {enableProdMode} from 'angular2/core';
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {MyComponent} from 'my_component';
|
||||
import {bootstrap} from 'angular2/platform/browser';
|
||||
import {MyComponent} from './my_component';
|
||||
|
||||
enableProdMode();
|
||||
bootstrap(MyComponent);
|
||||
|
@ -1,8 +1,8 @@
|
||||
// #docregion Observable
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
var obs = new Observable<number>(obs => {
|
||||
import {Observable, Subscriber} from 'rxjs/Rx';
|
||||
var obs = new Observable<number>((obs: Subscriber<number>) => {
|
||||
var i = 0;
|
||||
setInterval(_ => { obs.next(++i); }, 1000);
|
||||
setInterval(() => { obs.next(++i); }, 1000);
|
||||
});
|
||||
obs.subscribe(i => console.log(`${i} seconds elapsed`));
|
||||
// #enddocregion
|
||||
|
@ -1,10 +1,10 @@
|
||||
// #docregion Observable
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
import {Observable, Subscriber} from 'rxjs/Rx';
|
||||
import 'rxjs/add/operator/map';
|
||||
|
||||
var obs = new Observable(obs => {
|
||||
var obs = new Observable<number>((obs: Subscriber<any>) => {
|
||||
var i = 0;
|
||||
setInterval(_ => obs.next(++i), 1000);
|
||||
setInterval(() => obs.next(++i), 1000);
|
||||
});
|
||||
obs.map(i => `${i} seconds elapsed`).subscribe(msg => console.log(msg));
|
||||
obs.map((i: number) => `${i} seconds elapsed`).subscribe(msg => console.log(msg));
|
||||
// #enddocregion
|
||||
|
@ -1,10 +1,10 @@
|
||||
// #docregion Observable
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
import {Observable, Subscriber} from 'rxjs/Rx';
|
||||
import {map} from 'rxjs/operator/map';
|
||||
|
||||
var obs = new Observable(obs => {
|
||||
var obs = new Observable<number>((sub: Subscriber<number>) => {
|
||||
var i = 0;
|
||||
setInterval(_ => obs.next(++i), 1000);
|
||||
setInterval(() => sub.next(++i), 1000);
|
||||
});
|
||||
map.call(obs, i => `${i} seconds elapsed`).subscribe(msg => console.log(msg));
|
||||
map.call(obs, (i: number) => `${i} seconds elapsed`).subscribe((msg: string) => console.log(msg));
|
||||
// #enddocregion
|
||||
|
@ -1,17 +1,17 @@
|
||||
import {By} from 'angular2/platform/browser';
|
||||
import {DebugElement, Scope} from 'angular2/core';
|
||||
import {DebugElement} from 'angular2/core';
|
||||
|
||||
var debugElement: DebugElement;
|
||||
class MyDirective {}
|
||||
|
||||
// #docregion by_all
|
||||
debugElement.query(By.all(), Scope.all);
|
||||
debugElement.query(By.all());
|
||||
// #enddocregion
|
||||
|
||||
// #docregion by_css
|
||||
debugElement.query(By.css('[attribute]'), Scope.all);
|
||||
debugElement.query(By.css('[attribute]'));
|
||||
// #enddocregion
|
||||
|
||||
// #docregion by_directive
|
||||
debugElement.query(By.directive(MyDirective), Scope.all);
|
||||
debugElement.query(By.directive(MyDirective));
|
||||
// #enddocregion
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {provide, Component} from 'angular2/core';
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {bootstrap} from 'angular2/platform/browser';
|
||||
import {
|
||||
CanActivate,
|
||||
RouteConfig,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
import {Promise} from 'angular2/src/facade/async';
|
||||
import {verifyNoBrowserErrors, browser} from 'angular2/src/testing/e2e_util';
|
||||
import {expect} from 'angular2/testing';
|
||||
|
||||
function waitForElement(selector) {
|
||||
function waitForElement(selector: string) {
|
||||
var EC = (<any>protractor).ExpectedConditions;
|
||||
// Waits for the element with id 'abc' to be present on the dom.
|
||||
browser.wait(EC.presenceOf($(selector)), 20000);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {provide, Component} from 'angular2/core';
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {bootstrap} from 'angular2/platform/browser';
|
||||
import {
|
||||
CanDeactivate,
|
||||
RouteConfig,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
import {Promise} from 'angular2/src/facade/async';
|
||||
import {verifyNoBrowserErrors, browser} from 'angular2/src/testing/e2e_util';
|
||||
import {expect} from 'angular2/testing';
|
||||
|
||||
function waitForElement(selector) {
|
||||
function waitForElement(selector: string) {
|
||||
var EC = (<any>protractor).ExpectedConditions;
|
||||
// Waits for the element with id 'abc' to be present on the dom.
|
||||
browser.wait(EC.presenceOf($(selector)), 20000);
|
||||
|
@ -1,24 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Routing Reuse Lifecycle Example</title>
|
||||
<base href="/">
|
||||
|
||||
<script src="http://cdn.rawgit.com/google/traceur-compiler/90da568c7aa8e53ea362db1fc211fbb4f65b5e94/bin/traceur-runtime.js"></script>
|
||||
<script src="http://cdnjs.cloudflare.com/ajax/libs/systemjs/0.18.4/system.js"></script>
|
||||
<script>System.config({ baseURL: '/', defaultJSExtensions: true});</script>
|
||||
<script src="/bundle/angular2.dev.js"></script>
|
||||
<script src="/bundle/router.dev.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<example-app>
|
||||
Loading...
|
||||
</example-app>
|
||||
<script>
|
||||
var filename = 'angular2/examples/router/ts/on_activate/on_activate_example';
|
||||
System.import(filename).then(function(m) {
|
||||
m.main();
|
||||
}, console.error.bind(console));
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,5 +1,5 @@
|
||||
import {Component, provide} from 'angular2/core';
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {bootstrap} from 'angular2/platform/browser';
|
||||
import {
|
||||
OnActivate,
|
||||
ComponentInstruction,
|
||||
@ -8,14 +8,28 @@ import {
|
||||
APP_BASE_HREF
|
||||
} from 'angular2/router';
|
||||
|
||||
|
||||
// #docregion routerOnActivate
|
||||
@Component({selector: 'my-cmp', template: `<div>routerOnActivate: {{log}}</div>`})
|
||||
class MyCmp implements OnActivate {
|
||||
@Component({template: `Child`})
|
||||
class ChildCmp {
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<h2>Parent</h2> (<router-outlet></router-outlet>)
|
||||
<p>{{log}}</p>`,
|
||||
directives: [ROUTER_DIRECTIVES]
|
||||
})
|
||||
@RouteConfig([{path: '/child', name: 'Child', component: ChildCmp}])
|
||||
class ParentCmp implements OnActivate {
|
||||
log: string = '';
|
||||
|
||||
routerOnActivate(next: ComponentInstruction, prev: ComponentInstruction) {
|
||||
this.log = `Finished navigating from "${prev ? prev.urlPath : 'null'}" to "${next.urlPath}"`;
|
||||
|
||||
return new Promise(resolve => {
|
||||
// The ChildCmp gets instantiated only when the Promise is resolved
|
||||
setTimeout(() => resolve(null), 1000);
|
||||
});
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
||||
@ -24,23 +38,19 @@ class MyCmp implements OnActivate {
|
||||
@Component({
|
||||
selector: 'example-app',
|
||||
template: `
|
||||
<h1>My App</h1>
|
||||
<h1>My app</h1>
|
||||
|
||||
<nav>
|
||||
<a [routerLink]="['/HomeCmp']" id="home-link">Navigate Home</a> |
|
||||
<a [routerLink]="['/ParamCmp', {param: 1}]" id="param-link">Navigate with a Param</a>
|
||||
<a [routerLink]="['Parent', 'Child']">Child</a>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
`,
|
||||
directives: [ROUTER_DIRECTIVES]
|
||||
})
|
||||
@RouteConfig([
|
||||
{path: '/', component: MyCmp, name: 'HomeCmp'},
|
||||
{path: '/:param', component: MyCmp, name: 'ParamCmp'}
|
||||
])
|
||||
class AppCmp {
|
||||
@RouteConfig([{path: '/parent/...', name: 'Parent', component: ParentCmp}])
|
||||
export class AppCmp {
|
||||
}
|
||||
|
||||
|
||||
export function main() {
|
||||
return bootstrap(
|
||||
AppCmp, [provide(APP_BASE_HREF, {useValue: '/angular2/examples/router/ts/on_activate'})]);
|
||||
|
@ -1,34 +0,0 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
import {Promise} from 'angular2/src/facade/async';
|
||||
|
||||
function waitForElement(selector) {
|
||||
var EC = (<any>protractor).ExpectedConditions;
|
||||
// Waits for the element with id 'abc' to be present on the dom.
|
||||
browser.wait(EC.presenceOf($(selector)), 20000);
|
||||
}
|
||||
|
||||
describe('on activate example app', function() {
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
var URL = 'angular2/examples/router/ts/on_activate/';
|
||||
|
||||
it('should update the text when navigating between routes', function() {
|
||||
browser.get(URL);
|
||||
waitForElement('my-cmp');
|
||||
|
||||
expect(element(by.css('my-cmp')).getText())
|
||||
.toContain('routerOnActivate: Finished navigating from "null" to ""');
|
||||
|
||||
element(by.css('#param-link')).click();
|
||||
waitForElement('my-cmp');
|
||||
|
||||
expect(element(by.css('my-cmp')).getText())
|
||||
.toContain('routerOnActivate: Finished navigating from "" to "1"');
|
||||
|
||||
browser.navigate().back();
|
||||
waitForElement('my-cmp');
|
||||
|
||||
expect(element(by.css('my-cmp')).getText())
|
||||
.toContain('routerOnActivate: Finished navigating from "1" to ""');
|
||||
});
|
||||
});
|
@ -1,5 +1,5 @@
|
||||
import {Component, Injectable, provide} from 'angular2/core';
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {bootstrap} from 'angular2/platform/browser';
|
||||
import {
|
||||
OnDeactivate,
|
||||
ComponentInstruction,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
import {Promise} from 'angular2/src/facade/async';
|
||||
import {verifyNoBrowserErrors, browser} from 'angular2/src/testing/e2e_util';
|
||||
import {expect} from 'angular2/testing';
|
||||
|
||||
function waitForElement(selector) {
|
||||
function waitForElement(selector: string) {
|
||||
var EC = (<any>protractor).ExpectedConditions;
|
||||
// Waits for the element with id 'abc' to be present on the dom.
|
||||
browser.wait(EC.presenceOf($(selector)), 20000);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {Component, provide} from 'angular2/core';
|
||||
import {bootstrap} from 'angular2/bootstrap';
|
||||
import {bootstrap} from 'angular2/platform/browser';
|
||||
import {
|
||||
CanActivate,
|
||||
RouteConfig,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
|
||||
import {Promise} from 'angular2/src/facade/async';
|
||||
import {verifyNoBrowserErrors, browser} from 'angular2/src/testing/e2e_util';
|
||||
import {expect} from 'angular2/testing';
|
||||
|
||||
function waitForElement(selector) {
|
||||
function waitForElement(selector: string) {
|
||||
var EC = (<any>protractor).ExpectedConditions;
|
||||
// Waits for the element with id 'abc' to be present on the dom.
|
||||
browser.wait(EC.presenceOf($(selector)), 20000);
|
||||
|
@ -73,7 +73,7 @@ describe('some component', () => {
|
||||
// #docregion beforeEachProviders
|
||||
describe('some component', () => {
|
||||
beforeEachProviders(() => [provide(MyService, {useClass: MyMockService})]);
|
||||
it('uses MyService', inject([MyService], (service) => {
|
||||
it('uses MyService', inject([MyService], (service: MyMockService) => {
|
||||
// service is an instance of MyMockService.
|
||||
}));
|
||||
});
|
||||
@ -81,7 +81,7 @@ describe('some component', () => {
|
||||
|
||||
// #docregion afterEach
|
||||
describe('some component', () => {
|
||||
afterEach((done) => { db.reset().then((_) => done()); });
|
||||
afterEach((done: Function) => { db.reset().then((_: any) => done()); });
|
||||
it('uses the db', () => {
|
||||
// This test can leave the database in a dirty state.
|
||||
// The afterEach will ensure it gets reset.
|
||||
|
@ -141,7 +141,8 @@ export {URLSearchParams} from './src/http/url_search_params';
|
||||
* // Send a response to the request
|
||||
* connection.mockRespond(response);
|
||||
* });
|
||||
* });
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* http.get('people.json').observer({
|
||||
* next: res => {
|
||||
@ -156,7 +157,8 @@ export const HTTP_PROVIDERS: any[] = [
|
||||
// issue: https://github.com/angular/angular/issues/3183
|
||||
provide(Http,
|
||||
{
|
||||
useFactory: (xhrBackend, requestOptions) => new Http(xhrBackend, requestOptions),
|
||||
useFactory: (xhrBackend: XHRBackend, requestOptions: RequestOptions) =>
|
||||
new Http(xhrBackend, requestOptions),
|
||||
deps: [XHRBackend, RequestOptions]
|
||||
}),
|
||||
BrowserXhr,
|
||||
@ -268,7 +270,8 @@ export const HTTP_BINDINGS = HTTP_PROVIDERS;
|
||||
* // Send a response to the request
|
||||
* connection.mockRespond(response);
|
||||
* });
|
||||
* });
|
||||
* }
|
||||
* });
|
||||
|
||||
* jsonp.get('people.json').observer({
|
||||
* next: res => {
|
||||
@ -283,7 +286,8 @@ export const JSONP_PROVIDERS: any[] = [
|
||||
// issue: https://github.com/angular/angular/issues/3183
|
||||
provide(Jsonp,
|
||||
{
|
||||
useFactory: (jsonpBackend, requestOptions) => new Jsonp(jsonpBackend, requestOptions),
|
||||
useFactory: (jsonpBackend: JSONPBackend, requestOptions: RequestOptions) =>
|
||||
new Jsonp(jsonpBackend, requestOptions),
|
||||
deps: [JSONPBackend, RequestOptions]
|
||||
}),
|
||||
BrowserJsonp,
|
||||
|
9
modules/angular2/i18n.ts
Normal file
9
modules/angular2/i18n.ts
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* @module
|
||||
* @description
|
||||
* Entry point to i18n
|
||||
*/
|
||||
export * from './src/i18n/message';
|
||||
export * from './src/i18n/xmb_serializer';
|
||||
export * from './src/i18n/message_extractor';
|
||||
export * from './src/i18n/i18n_html_parser';
|
37
modules/angular2/manual_typings/globals-es6.d.ts
vendored
37
modules/angular2/manual_typings/globals-es6.d.ts
vendored
@ -1,37 +0,0 @@
|
||||
/**
|
||||
* Declarations angular depends on for compilation to ES6.
|
||||
* This file is also used to propagate our transitive typings
|
||||
* to users.
|
||||
*/
|
||||
|
||||
/// <reference path="../typings/zone/zone.d.ts"/>
|
||||
/// <reference path="../typings/hammerjs/hammerjs.d.ts"/>
|
||||
/// <reference path="../typings/jasmine/jasmine.d.ts"/>
|
||||
/// <reference path="../typings/angular-protractor/angular-protractor.d.ts"/>
|
||||
|
||||
// TODO: ideally the node.d.ts reference should be scoped only for files that need and not to all
|
||||
// the code including client code
|
||||
/// <reference path="../typings/node/node.d.ts" />
|
||||
|
||||
declare var assert: any;
|
||||
|
||||
|
||||
interface BrowserNodeGlobal {
|
||||
Object: typeof Object;
|
||||
Array: typeof Array;
|
||||
Map: typeof Map;
|
||||
Set: typeof Set;
|
||||
Date: typeof Date;
|
||||
RegExp: typeof RegExp;
|
||||
JSON: typeof JSON;
|
||||
Math: typeof Math;
|
||||
assert(condition: any): void;
|
||||
Reflect: any;
|
||||
zone: Zone;
|
||||
getAngularTestability: Function;
|
||||
getAllAngularTestabilities: Function;
|
||||
setTimeout: Function;
|
||||
clearTimeout: Function;
|
||||
setInterval: Function;
|
||||
clearInterval: Function;
|
||||
}
|
55
modules/angular2/manual_typings/globals.d.ts
vendored
55
modules/angular2/manual_typings/globals.d.ts
vendored
@ -1,7 +1,52 @@
|
||||
/**
|
||||
* Declarations angular depends on for compilation to ES6.
|
||||
* This file is also used to propagate our transitive typings
|
||||
* to users.
|
||||
* Subset of es6-shim typings.
|
||||
* Angular should not require use of ES6 runtime but some API usages are already present.
|
||||
* See https://github.com/angular/angular/issues/5242
|
||||
* TODO(alexeagle): remove methods below which may not be present in targeted browser
|
||||
*/
|
||||
/// <reference path="../typings/es6-shim/es6-shim.d.ts"/>
|
||||
/// <reference path="./globals-es6.d.ts"/>
|
||||
|
||||
declare type PromiseConstructor = typeof Promise;
|
||||
|
||||
interface String {
|
||||
/**
|
||||
* Returns true if the sequence of elements of searchString converted to a String is the
|
||||
* same as the corresponding elements of this object (converted to a String) starting at
|
||||
* position. Otherwise returns false.
|
||||
*/
|
||||
startsWith(searchString: string, position?: number): boolean;
|
||||
|
||||
/**
|
||||
* Returns true if the sequence of elements of searchString converted to a String is the
|
||||
* same as the corresponding elements of this object (converted to a String) starting at
|
||||
* endPosition – length(this). Otherwise returns false.
|
||||
*/
|
||||
endsWith(searchString: string, endPosition?: number): boolean;
|
||||
}
|
||||
interface Array<T> {
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
* otherwise.
|
||||
* @param predicate find calls predicate once for each element of the array, in ascending
|
||||
* order, until it finds one where predicate returns true. If such an element is found, find
|
||||
* immediately returns that element value. Otherwise, find returns undefined.
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (value: T, index: number, obj: Array<T>) => boolean, thisArg?: any): T;
|
||||
/**
|
||||
* Returns the this object after filling the section identified by start and end with value
|
||||
* @param value value to fill array section with
|
||||
* @param start index to start filling the array at. If start is negative, it is treated as
|
||||
* length+start where length is the length of the array.
|
||||
* @param end index to stop filling the array at. If end is negative, it is treated as
|
||||
* length+end.
|
||||
*/
|
||||
fill(value: T, start?: number, end?: number): T[];
|
||||
}
|
||||
interface NumberConstructor {
|
||||
/**
|
||||
* Returns true if the value passed is an integer, false otherwise.
|
||||
* @param number A numeric value.
|
||||
*/
|
||||
isInteger(number: number): boolean;
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
"repository": <%= JSON.stringify(packageJson.repository) %>,
|
||||
"devDependencies": <%= JSON.stringify(packageJson.defaultDevDependencies) %>,
|
||||
"peerDependencies": {
|
||||
"es6-promise": "<%= packageJson.dependencies['es6-promise'] %>",
|
||||
"es6-shim": "<%= packageJson.dependencies['es6-shim'] %>",
|
||||
"reflect-metadata": "<%= packageJson.dependencies['reflect-metadata'] %>",
|
||||
"rxjs": "<%= packageJson.dependencies['rxjs'] %>",
|
||||
|
@ -1,8 +1,8 @@
|
||||
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';
|
||||
export {
|
||||
BROWSER_PROVIDERS,
|
||||
ELEMENT_PROBE_BINDINGS,
|
||||
ELEMENT_PROBE_PROVIDERS,
|
||||
ELEMENT_PROBE_PROVIDERS_PROD_MODE,
|
||||
inspectNativeElement,
|
||||
BrowserDomAdapter,
|
||||
By,
|
||||
@ -13,7 +13,6 @@ export {
|
||||
} from 'angular2/src/platform/browser_common';
|
||||
|
||||
import {Type, isPresent, CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
import {Promise} from 'angular2/src/facade/promise';
|
||||
import {
|
||||
BROWSER_PROVIDERS,
|
||||
BROWSER_APP_COMMON_PROVIDERS
|
||||
|
@ -1,8 +1,8 @@
|
||||
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';
|
||||
export {
|
||||
BROWSER_PROVIDERS,
|
||||
ELEMENT_PROBE_BINDINGS,
|
||||
ELEMENT_PROBE_PROVIDERS,
|
||||
ELEMENT_PROBE_PROVIDERS_PROD_MODE,
|
||||
inspectNativeElement,
|
||||
BrowserDomAdapter,
|
||||
By,
|
||||
@ -12,7 +12,6 @@ export {
|
||||
} from 'angular2/src/platform/browser_common';
|
||||
|
||||
import {Type, isPresent} from 'angular2/src/facade/lang';
|
||||
import {Promise} from 'angular2/src/facade/promise';
|
||||
import {
|
||||
BROWSER_PROVIDERS,
|
||||
BROWSER_APP_COMMON_PROVIDERS
|
||||
|
@ -12,4 +12,4 @@ export {
|
||||
EventManagerPlugin
|
||||
} from 'angular2/src/platform/dom/events/event_manager';
|
||||
export * from 'angular2/src/platform/dom/debug/by';
|
||||
export * from 'angular2/src/platform/dom/debug/debug_element_view_listener';
|
||||
export * from 'angular2/src/platform/dom/debug/ng_probe';
|
||||
|
21
modules/angular2/platform/testing/browser.ts
Normal file
21
modules/angular2/platform/testing/browser.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import {
|
||||
TEST_BROWSER_STATIC_PLATFORM_PROVIDERS,
|
||||
ADDITIONAL_TEST_BROWSER_PROVIDERS
|
||||
} from 'angular2/platform/testing/browser_static';
|
||||
|
||||
import {BROWSER_APP_PROVIDERS} from 'angular2/platform/browser';
|
||||
|
||||
|
||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
|
||||
/**
|
||||
* Default patform providers for testing.
|
||||
*/
|
||||
export const TEST_BROWSER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
CONST_EXPR([TEST_BROWSER_STATIC_PLATFORM_PROVIDERS]);
|
||||
|
||||
/**
|
||||
* Default application providers for testing.
|
||||
*/
|
||||
export const TEST_BROWSER_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
CONST_EXPR([BROWSER_APP_PROVIDERS, ADDITIONAL_TEST_BROWSER_PROVIDERS]);
|
69
modules/angular2/platform/testing/browser_static.ts
Normal file
69
modules/angular2/platform/testing/browser_static.ts
Normal file
@ -0,0 +1,69 @@
|
||||
import {
|
||||
APP_ID,
|
||||
DirectiveResolver,
|
||||
NgZone,
|
||||
Provider,
|
||||
ViewResolver,
|
||||
PLATFORM_COMMON_PROVIDERS,
|
||||
PLATFORM_INITIALIZER
|
||||
} from 'angular2/core';
|
||||
import {BROWSER_APP_COMMON_PROVIDERS} from 'angular2/src/platform/browser_common';
|
||||
import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter';
|
||||
|
||||
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
|
||||
import {MockAnimationBuilder} from 'angular2/src/mock/animation_builder_mock';
|
||||
import {MockDirectiveResolver} from 'angular2/src/mock/directive_resolver_mock';
|
||||
import {MockViewResolver} from 'angular2/src/mock/view_resolver_mock';
|
||||
import {MockLocationStrategy} from 'angular2/src/mock/mock_location_strategy';
|
||||
import {LocationStrategy} from 'angular2/src/router/location/location_strategy';
|
||||
import {MockNgZone} from 'angular2/src/mock/ng_zone_mock';
|
||||
|
||||
import {XHRImpl} from "angular2/src/platform/browser/xhr_impl";
|
||||
import {XHR} from 'angular2/compiler';
|
||||
|
||||
import {TestComponentBuilder} from 'angular2/src/testing/test_component_builder';
|
||||
|
||||
import {BrowserDetection} from 'angular2/src/testing/utils';
|
||||
|
||||
import {ELEMENT_PROBE_PROVIDERS} from 'angular2/platform/common_dom';
|
||||
|
||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
|
||||
import {Log} from 'angular2/src/testing/utils';
|
||||
|
||||
function initBrowserTests() {
|
||||
BrowserDomAdapter.makeCurrent();
|
||||
BrowserDetection.setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Default patform providers for testing without a compiler.
|
||||
*/
|
||||
export const TEST_BROWSER_STATIC_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
CONST_EXPR([
|
||||
PLATFORM_COMMON_PROVIDERS,
|
||||
new Provider(PLATFORM_INITIALIZER, {useValue: initBrowserTests, multi: true})
|
||||
]);
|
||||
|
||||
export const ADDITIONAL_TEST_BROWSER_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
CONST_EXPR([
|
||||
new Provider(APP_ID, {useValue: 'a'}),
|
||||
ELEMENT_PROBE_PROVIDERS,
|
||||
new Provider(DirectiveResolver, {useClass: MockDirectiveResolver}),
|
||||
new Provider(ViewResolver, {useClass: MockViewResolver}),
|
||||
Log,
|
||||
TestComponentBuilder,
|
||||
new Provider(NgZone, {useClass: MockNgZone}),
|
||||
new Provider(LocationStrategy, {useClass: MockLocationStrategy}),
|
||||
new Provider(AnimationBuilder, {useClass: MockAnimationBuilder}),
|
||||
]);
|
||||
|
||||
/**
|
||||
* Default application providers for testing without a compiler.
|
||||
*/
|
||||
export const TEST_BROWSER_STATIC_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
CONST_EXPR([
|
||||
BROWSER_APP_COMMON_PROVIDERS,
|
||||
new Provider(XHR, {useClass: XHRImpl}),
|
||||
ADDITIONAL_TEST_BROWSER_PROVIDERS
|
||||
]);
|
1
modules/angular2/platform/testing/server.dart
Normal file
1
modules/angular2/platform/testing/server.dart
Normal file
@ -0,0 +1 @@
|
||||
// Intentionally blank, the Parse5Adapater bindings for JavaScript don't apply.
|
90
modules/angular2/platform/testing/server.ts
Normal file
90
modules/angular2/platform/testing/server.ts
Normal file
@ -0,0 +1,90 @@
|
||||
import {
|
||||
APP_ID,
|
||||
DirectiveResolver,
|
||||
NgZone,
|
||||
Provider,
|
||||
ViewResolver,
|
||||
PLATFORM_COMMON_PROVIDERS,
|
||||
PLATFORM_INITIALIZER,
|
||||
APPLICATION_COMMON_PROVIDERS,
|
||||
Renderer
|
||||
} from 'angular2/core';
|
||||
import {Parse5DomAdapter} from 'angular2/src/platform/server/parse5_adapter';
|
||||
|
||||
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
|
||||
import {MockAnimationBuilder} from 'angular2/src/mock/animation_builder_mock';
|
||||
import {MockDirectiveResolver} from 'angular2/src/mock/directive_resolver_mock';
|
||||
import {MockViewResolver} from 'angular2/src/mock/view_resolver_mock';
|
||||
import {MockLocationStrategy} from 'angular2/src/mock/mock_location_strategy';
|
||||
import {LocationStrategy} from 'angular2/src/router/location/location_strategy';
|
||||
import {MockNgZone} from 'angular2/src/mock/ng_zone_mock';
|
||||
|
||||
import {TestComponentBuilder} from 'angular2/src/testing/test_component_builder';
|
||||
import {XHR} from 'angular2/src/compiler/xhr';
|
||||
import {BrowserDetection} from 'angular2/src/testing/utils';
|
||||
|
||||
import {COMPILER_PROVIDERS} from 'angular2/src/compiler/compiler';
|
||||
import {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
import {RootRenderer} from 'angular2/src/core/render/api';
|
||||
import {DomRootRenderer, DomRootRenderer_} from 'angular2/src/platform/dom/dom_renderer';
|
||||
import {DomSharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host';
|
||||
|
||||
import {
|
||||
EventManager,
|
||||
EVENT_MANAGER_PLUGINS,
|
||||
ELEMENT_PROBE_PROVIDERS
|
||||
} from 'angular2/platform/common_dom';
|
||||
import {DomEventsPlugin} from 'angular2/src/platform/dom/events/dom_events';
|
||||
|
||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
|
||||
import {Log} from 'angular2/src/testing/utils';
|
||||
|
||||
function initServerTests() {
|
||||
Parse5DomAdapter.makeCurrent();
|
||||
BrowserDetection.setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Default patform providers for testing.
|
||||
*/
|
||||
export const TEST_SERVER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = CONST_EXPR([
|
||||
PLATFORM_COMMON_PROVIDERS,
|
||||
new Provider(PLATFORM_INITIALIZER, {useValue: initServerTests, multi: true})
|
||||
]);
|
||||
|
||||
function appDoc() {
|
||||
try {
|
||||
return DOM.defaultDoc();
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default application providers for testing.
|
||||
*/
|
||||
export const TEST_SERVER_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
CONST_EXPR([
|
||||
// TODO(julie): when angular2/platform/server is available, use that instead of making our own
|
||||
// list here.
|
||||
APPLICATION_COMMON_PROVIDERS,
|
||||
COMPILER_PROVIDERS,
|
||||
new Provider(DOCUMENT, {useFactory: appDoc}),
|
||||
new Provider(DomRootRenderer, {useClass: DomRootRenderer_}),
|
||||
new Provider(RootRenderer, {useExisting: DomRootRenderer}),
|
||||
EventManager,
|
||||
new Provider(EVENT_MANAGER_PLUGINS, {useClass: DomEventsPlugin, multi: true}),
|
||||
new Provider(XHR, {useClass: XHR}),
|
||||
new Provider(APP_ID, {useValue: 'a'}),
|
||||
DomSharedStylesHost,
|
||||
ELEMENT_PROBE_PROVIDERS,
|
||||
new Provider(DirectiveResolver, {useClass: MockDirectiveResolver}),
|
||||
new Provider(ViewResolver, {useClass: MockViewResolver}),
|
||||
Log,
|
||||
TestComponentBuilder,
|
||||
new Provider(NgZone, {useClass: MockNgZone}),
|
||||
new Provider(LocationStrategy, {useClass: MockLocationStrategy}),
|
||||
new Provider(AnimationBuilder, {useClass: MockAnimationBuilder}),
|
||||
]);
|
@ -12,3 +12,5 @@ export 'package:angular2/src/web_workers/shared/service_message_broker.dart'
|
||||
show ReceivedMessage, ServiceMessageBroker, ServiceMessageBrokerFactory;
|
||||
export 'package:angular2/src/web_workers/shared/serializer.dart' show PRIMITIVE;
|
||||
export 'package:angular2/src/web_workers/shared/message_bus.dart';
|
||||
export 'package:angular2/src/web_workers/worker/router_providers.dart'
|
||||
show WORKER_APP_ROUTER;
|
||||
|
@ -8,12 +8,13 @@ export {
|
||||
ClientMessageBrokerFactory,
|
||||
FnArg,
|
||||
UiArguments
|
||||
} from '../src/web_workers/shared/client_message_broker';
|
||||
} from 'angular2/src/web_workers/shared/client_message_broker';
|
||||
export {
|
||||
ReceivedMessage,
|
||||
ServiceMessageBroker,
|
||||
ServiceMessageBrokerFactory
|
||||
} from '../src/web_workers/shared/service_message_broker';
|
||||
export {PRIMITIVE} from '../src/web_workers/shared/serializer';
|
||||
export * from '../src/web_workers/shared/message_bus';
|
||||
} from 'angular2/src/web_workers/shared/service_message_broker';
|
||||
export {PRIMITIVE} from 'angular2/src/web_workers/shared/serializer';
|
||||
export * from 'angular2/src/web_workers/shared/message_bus';
|
||||
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';
|
||||
export {WORKER_APP_ROUTER} from 'angular2/src/web_workers/worker/router_providers';
|
||||
|
@ -4,11 +4,11 @@ export 'package:angular2/src/platform/worker_render_common.dart'
|
||||
show
|
||||
WORKER_SCRIPT,
|
||||
WORKER_RENDER_PLATFORM,
|
||||
WORKER_RENDER_APP_COMMON,
|
||||
WORKER_RENDER_APPLICATION_COMMON,
|
||||
initializeGenericWorkerRenderer;
|
||||
|
||||
export 'package:angular2/src/platform/worker_render.dart'
|
||||
show WORKER_RENDER_APP, initIsolate, WebWorkerInstance;
|
||||
show WORKER_RENDER_APPLICATION, initIsolate, WebWorkerInstance;
|
||||
|
||||
export '../src/web_workers/shared/client_message_broker.dart'
|
||||
show ClientMessageBroker, ClientMessageBrokerFactory, FnArg, UiArguments;
|
||||
@ -18,3 +18,9 @@ export '../src/web_workers/shared/service_message_broker.dart'
|
||||
|
||||
export '../src/web_workers/shared/serializer.dart' show PRIMITIVE;
|
||||
export '../src/web_workers/shared/message_bus.dart';
|
||||
export '../src/web_workers/ui/router_providers.dart' show WORKER_RENDER_ROUTER;
|
||||
|
||||
import 'package:angular2/src/platform/worker_render_common.dart';
|
||||
|
||||
const WORKER_RENDER_APP = WORKER_RENDER_APPLICATION_COMMON;
|
||||
|
||||
|
@ -2,9 +2,9 @@ export {
|
||||
WORKER_SCRIPT,
|
||||
WORKER_RENDER_PLATFORM,
|
||||
initializeGenericWorkerRenderer,
|
||||
WORKER_RENDER_APP_COMMON
|
||||
WORKER_RENDER_APPLICATION_COMMON
|
||||
} from 'angular2/src/platform/worker_render_common';
|
||||
export * from 'angular2/src/platform/worker_render';
|
||||
export {WORKER_RENDER_APPLICATION, WebWorkerInstance} from 'angular2/src/platform/worker_render';
|
||||
export {
|
||||
ClientMessageBroker,
|
||||
ClientMessageBrokerFactory,
|
||||
@ -18,3 +18,10 @@ export {
|
||||
} from '../src/web_workers/shared/service_message_broker';
|
||||
export {PRIMITIVE} from '../src/web_workers/shared/serializer';
|
||||
export * from '../src/web_workers/shared/message_bus';
|
||||
import {WORKER_RENDER_APPLICATION} from 'angular2/src/platform/worker_render';
|
||||
|
||||
/**
|
||||
* @deprecated Use WORKER_RENDER_APPLICATION
|
||||
*/
|
||||
export const WORKER_RENDER_APP = WORKER_RENDER_APPLICATION;
|
||||
export {WORKER_RENDER_ROUTER} from 'angular2/src/web_workers/ui/router_providers';
|
||||
|
@ -9,23 +9,27 @@ homepage: <%= packageJson.homepage %>
|
||||
environment:
|
||||
sdk: '>=1.10.0 <2.0.0'
|
||||
dependencies:
|
||||
analyzer: '>=0.24.4 <0.27.0'
|
||||
analyzer: '>=0.24.4 <0.28.0'
|
||||
barback: '^0.15.2+2'
|
||||
code_transformers: '0.2.9+4'
|
||||
dart_style: '>=0.1.8 <0.3.0'
|
||||
glob: '^1.0.0'
|
||||
html: '^0.12.0'
|
||||
intl: '^0.12.4'
|
||||
logging: '>=0.9.0 <0.12.0'
|
||||
observe: '^0.13.1'
|
||||
path: '^1.0.0'
|
||||
protobuf: '^0.5.0'
|
||||
quiver: '^0.21.4'
|
||||
source_span: '^1.0.0'
|
||||
stack_trace: '^1.1.1'
|
||||
build: '>=0.0.1'
|
||||
dev_dependencies:
|
||||
transformer_test: '^0.2.0'
|
||||
guinness: '^0.1.18'
|
||||
guinness2: '0.0.5'
|
||||
quiver: '^0.21.4'
|
||||
test: '^0.12.6'
|
||||
transformers:
|
||||
- angular2
|
||||
- angular2/transform/codegen
|
||||
- $dart2js:
|
||||
commandLineOptions:
|
||||
- --show-package-warnings
|
||||
|
@ -5,33 +5,27 @@
|
||||
*/
|
||||
|
||||
export {Router} from './src/router/router';
|
||||
export {RouterOutlet} from './src/router/router_outlet';
|
||||
export {RouterLink} from './src/router/router_link';
|
||||
export {RouterOutlet} from './src/router/directives/router_outlet';
|
||||
export {RouterLink} from './src/router/directives/router_link';
|
||||
export {RouteParams, RouteData} from './src/router/instruction';
|
||||
export {PlatformLocation} from './src/router/platform_location';
|
||||
export {PlatformLocation} from './src/router/location/platform_location';
|
||||
export {RouteRegistry, ROUTER_PRIMARY_COMPONENT} from './src/router/route_registry';
|
||||
export {LocationStrategy, APP_BASE_HREF} from './src/router/location_strategy';
|
||||
export {HashLocationStrategy} from './src/router/hash_location_strategy';
|
||||
export {PathLocationStrategy} from './src/router/path_location_strategy';
|
||||
export {Location} from './src/router/location';
|
||||
export * from './src/router/route_config_decorator';
|
||||
export {LocationStrategy, APP_BASE_HREF} from './src/router/location/location_strategy';
|
||||
export {HashLocationStrategy} from './src/router/location/hash_location_strategy';
|
||||
export {PathLocationStrategy} from './src/router/location/path_location_strategy';
|
||||
export {Location} from './src/router/location/location';
|
||||
export * from './src/router/route_config/route_config_decorator';
|
||||
export * from './src/router/route_definition';
|
||||
export {OnActivate, OnDeactivate, OnReuse, CanDeactivate, CanReuse} from './src/router/interfaces';
|
||||
export {CanActivate} from './src/router/lifecycle_annotations';
|
||||
export {CanActivate} from './src/router/lifecycle/lifecycle_annotations';
|
||||
export {Instruction, ComponentInstruction} from './src/router/instruction';
|
||||
export {OpaqueToken} from 'angular2/core';
|
||||
export {ROUTER_PROVIDERS_COMMON} from 'angular2/src/router/router_providers_common';
|
||||
export {ROUTER_PROVIDERS, ROUTER_BINDINGS} from 'angular2/src/router/router_providers';
|
||||
|
||||
import {PlatformLocation} from './src/router/platform_location';
|
||||
import {LocationStrategy} from './src/router/location_strategy';
|
||||
import {PathLocationStrategy} from './src/router/path_location_strategy';
|
||||
import {Router, RootRouter} from './src/router/router';
|
||||
import {RouterOutlet} from './src/router/router_outlet';
|
||||
import {RouterLink} from './src/router/router_link';
|
||||
import {RouteRegistry, ROUTER_PRIMARY_COMPONENT} from './src/router/route_registry';
|
||||
import {Location} from './src/router/location';
|
||||
import {ApplicationRef, provide, OpaqueToken, Provider} from 'angular2/core';
|
||||
import {RouterOutlet} from './src/router/directives/router_outlet';
|
||||
import {RouterLink} from './src/router/directives/router_link';
|
||||
import {CONST_EXPR} from './src/facade/lang';
|
||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||
|
||||
/**
|
||||
* A list of directives. To use the router directives like {@link RouterOutlet} and
|
||||
@ -56,63 +50,3 @@ import {BaseException} from 'angular2/src/facade/exceptions';
|
||||
* ```
|
||||
*/
|
||||
export const ROUTER_DIRECTIVES: any[] = CONST_EXPR([RouterOutlet, RouterLink]);
|
||||
|
||||
/**
|
||||
* A list of {@link Provider}s. To use the router, you must add this to your application.
|
||||
*
|
||||
* ### Example ([live demo](http://plnkr.co/edit/iRUP8B5OUbxCWQ3AcIDm))
|
||||
*
|
||||
* ```
|
||||
* import {Component} from 'angular2/core';
|
||||
* import {
|
||||
* ROUTER_DIRECTIVES,
|
||||
* ROUTER_PROVIDERS,
|
||||
* RouteConfig
|
||||
* } from 'angular2/router';
|
||||
*
|
||||
* @Component({directives: [ROUTER_DIRECTIVES]})
|
||||
* @RouteConfig([
|
||||
* {...},
|
||||
* ])
|
||||
* class AppCmp {
|
||||
* // ...
|
||||
* }
|
||||
*
|
||||
* bootstrap(AppCmp, [ROUTER_PROVIDERS]);
|
||||
* ```
|
||||
*/
|
||||
export const ROUTER_PROVIDERS: any[] = CONST_EXPR([
|
||||
RouteRegistry,
|
||||
CONST_EXPR(new Provider(LocationStrategy, {useClass: PathLocationStrategy})),
|
||||
PlatformLocation,
|
||||
Location,
|
||||
CONST_EXPR(new Provider(
|
||||
Router,
|
||||
{
|
||||
useFactory: routerFactory,
|
||||
deps: CONST_EXPR([RouteRegistry, Location, ROUTER_PRIMARY_COMPONENT, ApplicationRef])
|
||||
})),
|
||||
CONST_EXPR(new Provider(
|
||||
ROUTER_PRIMARY_COMPONENT,
|
||||
{useFactory: routerPrimaryComponentFactory, deps: CONST_EXPR([ApplicationRef])}))
|
||||
]);
|
||||
|
||||
/**
|
||||
* Use {@link ROUTER_PROVIDERS} instead.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
export const ROUTER_BINDINGS = ROUTER_PROVIDERS;
|
||||
|
||||
function routerFactory(registry, location, primaryComponent, appRef) {
|
||||
var rootRouter = new RootRouter(registry, location, primaryComponent);
|
||||
appRef.registerDisposeListener(() => rootRouter.dispose());
|
||||
return rootRouter;
|
||||
}
|
||||
|
||||
function routerPrimaryComponentFactory(app) {
|
||||
if (app.componentTypes.length == 0) {
|
||||
throw new BaseException("Bootstrap at least one component before injecting Router.");
|
||||
}
|
||||
return app.componentTypes[0];
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {TEMPLATE_TRANSFORMS} from 'angular2/compiler';
|
||||
import {Provider} from 'angular2/core';
|
||||
import {RouterLinkTransform} from 'angular2/src/router/router_link_transform';
|
||||
import {RouterLinkTransform} from 'angular2/src/router/directives/router_link_transform';
|
||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
|
||||
export {RouterLinkTransform} from 'angular2/src/router/router_link_transform';
|
||||
export {RouterLinkTransform} from 'angular2/src/router/directives/router_link_transform';
|
||||
|
||||
/**
|
||||
* Enables the router link DSL.
|
||||
|
@ -52,7 +52,7 @@ export class Animation {
|
||||
this.startTime = DateWrapper.toMillis(DateWrapper.now());
|
||||
this._stringPrefix = DOM.getAnimationPrefix();
|
||||
this.setup();
|
||||
this.wait(timestamp => this.start());
|
||||
this.wait((timestamp: any) => this.start());
|
||||
}
|
||||
|
||||
wait(callback: Function) {
|
||||
@ -97,7 +97,7 @@ export class Animation {
|
||||
* @param styles
|
||||
*/
|
||||
applyStyles(styles: {[key: string]: any}): void {
|
||||
StringMapWrapper.forEach(styles, (value, key) => {
|
||||
StringMapWrapper.forEach(styles, (value: any, key: string) => {
|
||||
var dashCaseKey = camelCaseToDashCase(key);
|
||||
if (isPresent(DOM.getStyle(this.element, dashCaseKey))) {
|
||||
DOM.setStyle(this.element, dashCaseKey, value.toString());
|
||||
|
@ -17,7 +17,7 @@ export class BrowserDetails {
|
||||
DOM.setAttribute(div, 'style', `position: absolute; top: -9999px; left: -9999px; width: 1px;
|
||||
height: 1px; transition: all 1ms linear 1ms;`);
|
||||
// Firefox requires that we wait for 2 frames for some reason
|
||||
this.raf(timestamp => {
|
||||
this.raf((timestamp: any) => {
|
||||
DOM.on(div, 'transitionend', (event: any) => {
|
||||
var elapsed = Math.round(event.elapsedTime * 1000);
|
||||
this.elapsedTimeIncludesDelay = elapsed == 2;
|
||||
@ -37,7 +37,8 @@ class RafQueue {
|
||||
currentFrameId: number;
|
||||
constructor(public callback: Function, public frames: number) { this._raf(); }
|
||||
private _raf() {
|
||||
this.currentFrameId = DOM.requestAnimationFrame(timestamp => this._nextFrame(timestamp));
|
||||
this.currentFrameId =
|
||||
DOM.requestAnimationFrame((timestamp: number) => this._nextFrame(timestamp));
|
||||
}
|
||||
private _nextFrame(timestamp: number) {
|
||||
this.frames--;
|
||||
|
@ -9,7 +9,7 @@ import {CORE_DIRECTIVES} from './directives';
|
||||
* NgModel).
|
||||
*
|
||||
* This collection can be used to quickly enumerate all the built-in directives in the `directives`
|
||||
* property of the `@Component` or `@View` decorators.
|
||||
* property of the `@Component` decorator.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
|
@ -8,5 +8,6 @@ export {NgFor} from './directives/ng_for';
|
||||
export {NgIf} from './directives/ng_if';
|
||||
export {NgStyle} from './directives/ng_style';
|
||||
export {NgSwitch, NgSwitchWhen, NgSwitchDefault} from './directives/ng_switch';
|
||||
export {NgPlural, NgPluralCase, NgLocalization} from './directives/ng_plural';
|
||||
export * from './directives/observable_list_diff';
|
||||
export {CORE_DIRECTIVES} from './directives/core_directives';
|
||||
export {CORE_DIRECTIVES} from './directives/core_directives';
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user