Compare commits
409 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6acc73f3e0 | |||
| a4367ab00d | |||
| 2e0464fba4 | |||
| 6ffd53ee3c | |||
| 2395bf604d | |||
| 2e5fe846e3 | |||
| b6388b3f1d | |||
| 669e3aeaa8 | |||
| 55b2f0e862 | |||
| ca566d8d81 | |||
| b306babe29 | |||
| d9317cde4f | |||
| 23c8af232f | |||
| 2fcbd39d0b | |||
| 3ffbf202ce | |||
| 09367d88c2 | |||
| 369f69d67a | |||
| 9f43d02af8 | |||
| 08e6b88fb2 | |||
| 9227a5db94 | |||
| fc6ce59cd2 | |||
| 96a314766c | |||
| 6aa31e17ee | |||
| d18d5f57c2 | |||
| 2d9e96772f | |||
| bc2a5aaf05 | |||
| 4547c11dad | |||
| c0b360b993 | |||
| a659049893 | |||
| a3b9b1d205 | |||
| 3305f38db2 | |||
| 9be4e035d1 | |||
| 85ce5d0db9 | |||
| 5c99720934 | |||
| 8d26238664 | |||
| b7cb454546 | |||
| 199825ec26 | |||
| bcdd925c9d | |||
| 0bcace309e | |||
| 46c9c942df | |||
| 2ad439dfc5 | |||
| 3fbfe3f966 | |||
| 8ff671753c | |||
| 24092127d1 | |||
| f1c7240f04 | |||
| fcee3bea1a | |||
| ad08638c0a | |||
| 093e76fa15 | |||
| 28c0497524 | |||
| 88505d8029 | |||
| c241a57761 | |||
| b0e985fb67 | |||
| a0dbd95bb9 | |||
| 9fd5450ee8 | |||
| b5391fae8f | |||
| b635903ec4 | |||
| c9ee20b64b | |||
| 25ae98ca77 | |||
| adb5ee2e0a | |||
| 78954ffcde | |||
| 3b30a4b64a | |||
| 866057233c | |||
| ec1f4a8c9b | |||
| c94190139d | |||
| 4896a0b4d4 | |||
| 32bd990eda | |||
| 23723298f9 | |||
| edab80cddb | |||
| f4bb006e45 | |||
| cf3f709889 | |||
| e9ecd56dca | |||
| f107ef8bd8 | |||
| e7eab501db | |||
| 97fc47f39e | |||
| 6d1c67727a | |||
| 8ba78f08b9 | |||
| 02a3c31c23 | |||
| d4c3d5caaf | |||
| 279f98c4e3 | |||
| 5e548edf67 | |||
| acaf9be685 | |||
| bdd75c97ad | |||
| a3f1cba8ec | |||
| 4195b04072 | |||
| ccc8ec869b | |||
| 6d8abaedd8 | |||
| fd49d6634c | |||
| cecd5214df | |||
| c5e39c688b | |||
| 240608447a | |||
| bcb53deda8 | |||
| 9d4fa33e35 | |||
| de1461da78 | |||
| 2866daf7d6 | |||
| b3de37e418 | |||
| a4cc9e1944 | |||
| f8a1c56cad | |||
| 113850602d | |||
| e76105a320 | |||
| 14e9be202a | |||
| dd5215eceb | |||
| 497ba08775 | |||
| eaaf4967f9 | |||
| f440ac7492 | |||
| d566c4bc61 | |||
| 766b962eac | |||
| 0388eed7e5 | |||
| 82448b86b5 | |||
| fafcd6285a | |||
| 5319621afd | |||
| 32aa491588 | |||
| 31bdb60f0a | |||
| a8aae48bc0 | |||
| 517917f9fa | |||
| 1748abe8ef | |||
| 5f5bf07bb8 | |||
| 3d0b49c07f | |||
| b6aec5642e | |||
| e44e5f447b | |||
| ca273fd9da | |||
| 5ff453d422 | |||
| d9c75bee93 | |||
| e030e64196 | |||
| 7ba19cc355 | |||
| 21428e5cea | |||
| 9321a5f14c | |||
| 72421b2acf | |||
| c3fe170b8b | |||
| ed18b8c9da | |||
| 0cb276f7ac | |||
| cfccb8f64a | |||
| 0069f87007 | |||
| 9599234bae | |||
| d423117158 | |||
| 3c8a940686 | |||
| 9f8e30f550 | |||
| dcd94a23e1 | |||
| 9b79a00294 | |||
| 02058bfbe2 | |||
| 76647d3855 | |||
| 1f1cad8517 | |||
| e1f1d65d0c | |||
| a5df2d4e36 | |||
| b6514d9e1a | |||
| 1b1f94d8fe | |||
| 1362a9b456 | |||
| 6a26b2c38c | |||
| 9ab9bf6b41 | |||
| e7e56fe9bf | |||
| 85ea376da2 | |||
| 050aae3ceb | |||
| 79d9fd9d57 | |||
| 2dc2265e4f | |||
| 9cd33df50c | |||
| 1db20ce90f | |||
| 76cb5ce7c5 | |||
| 2a778d0038 | |||
| b04d3a8ec6 | |||
| 7839330b40 | |||
| 2d7cb14a16 | |||
| f20b06d26d | |||
| 109e5d1d39 | |||
| 227822dac3 | |||
| 92f6b45e02 | |||
| 24f7999bc1 | |||
| e0203660d3 | |||
| b6eb5fdb05 | |||
| 5bf6e50b40 | |||
| a7ccb7531c | |||
| 6bea059109 | |||
| fcdac65aed | |||
| 373078a94c | |||
| db07ad2d4c | |||
| 19d7a127c7 | |||
| f5a04f59cf | |||
| ab92da43b0 | |||
| 6782c45ddc | |||
| c55477fb2b | |||
| 2e2d62ca12 | |||
| e3141fe5f4 | |||
| 1ebed26678 | |||
| e987efd4c0 | |||
| ea72e5f881 | |||
| c550c12738 | |||
| 651caffe45 | |||
| 45855b8ba2 | |||
| feb54d68d2 | |||
| 2d0f6037f7 | |||
| ebd9a2a960 | |||
| fcfa6ebb6b | |||
| cf8ed01c6e | |||
| c352b92c40 | |||
| 369145467c | |||
| c3ec6ea226 | |||
| 291684c29c | |||
| d7615351df | |||
| a97a172ee9 | |||
| d53a787f0d | |||
| 9682bd0c4e | |||
| 34d0740350 | |||
| 4d9efa2f76 | |||
| f9a7b064a0 | |||
| 26ca443c10 | |||
| 0f37e49039 | |||
| 3fdcde73ae | |||
| d2dc77169b | |||
| d99b506885 | |||
| fef0cfc837 | |||
| 5de845506b | |||
| 38ea542662 | |||
| 2db66f5b69 | |||
| 55fe6d6331 | |||
| f4c08fee85 | |||
| 71bc451f95 | |||
| 7e4e696ec3 | |||
| 6da44a4410 | |||
| a81195c6ca | |||
| 102a3201c1 | |||
| 59244a7776 | |||
| 293cb1fc5d | |||
| 81395ac298 | |||
| ba66c4f3cc | |||
| 4ea57e7e96 | |||
| 6e420ff28d | |||
| 5393814756 | |||
| fab59e7515 | |||
| 553c252d5c | |||
| e145a8df72 | |||
| b49d0cc6e7 | |||
| 97b171ecb2 | |||
| 245de33c00 | |||
| 8d4d437e8c | |||
| 7287dbf71d | |||
| da88449f25 | |||
| eaf1f8546d | |||
| 20d926cc45 | |||
| 9ae9c1c0da | |||
| 8a5972461c | |||
| 35d635cbcb | |||
| db2a4c04d6 | |||
| 0d62257c5f | |||
| f911b84aef | |||
| 32c09c1d19 | |||
| 26064375ca | |||
| 7a294369ab | |||
| fbab287ea2 | |||
| 254dcee93d | |||
| 69e5c369d7 | |||
| c0ccbb7b6a | |||
| b87713687e | |||
| 950ffb5a84 | |||
| 259003056d | |||
| fedc4194d9 | |||
| 16862705e1 | |||
| c694c96e4c | |||
| 5ac8a6e74a | |||
| 0e5106ec2c | |||
| 9091b77fe6 | |||
| 849f998be3 | |||
| 8bc77b68b3 | |||
| 95bd046881 | |||
| bfce9126e1 | |||
| bf2264e2aa | |||
| 5ced7b20ff | |||
| 114cf9e418 | |||
| 1b61b73f28 | |||
| d657d63a21 | |||
| c5bb3a9098 | |||
| 77edce5ded | |||
| f37cd4e4ef | |||
| 2acc91098b | |||
| 5b1c89931e | |||
| 99a2ad381b | |||
| 300263abec | |||
| b0bcf18892 | |||
| ea3b6310c9 | |||
| 764a3beecc | |||
| a603330e7a | |||
| 1f842b1c63 | |||
| 3b09f1bf4e | |||
| 561ddc9ff1 | |||
| 512ecf8f1b | |||
| 6636f1d03f | |||
| 7cccb8b777 | |||
| a275d539f9 | |||
| 17fa2468bc | |||
| fb2ae5660e | |||
| 2c4b3573cc | |||
| b2363e3102 | |||
| edfca4c769 | |||
| a9b5a1087d | |||
| 87b18b9fbe | |||
| ad128e09ff | |||
| 187b4adbd2 | |||
| 375c47d0c0 | |||
| 8fd47a1cd5 | |||
| e48c28fe92 | |||
| 10d3e1e447 | |||
| 93d1c95c61 | |||
| 01a34f513b | |||
| 916e53ce14 | |||
| b91b3119a4 | |||
| 0d60f8d367 | |||
| ca69dc6f17 | |||
| 5b7f1bcc00 | |||
| 9ab594a66c | |||
| 6c82a497c6 | |||
| df804406fb | |||
| dadce485a7 | |||
| 344cdce136 | |||
| f0347d5efa | |||
| 1c27e5fc37 | |||
| 5fb298b90f | |||
| 483325a7b5 | |||
| a86cb7d794 | |||
| c7e60153a5 | |||
| c0416866f5 | |||
| 8ba452544e | |||
| 8f7f0d26ed | |||
| 98d825e10d | |||
| 57b0d91fd8 | |||
| 9226b36572 | |||
| 39635fd0d7 | |||
| cad307fa1f | |||
| 78bc84c497 | |||
| 1f2750136e | |||
| 5b93e5fcfc | |||
| 770fd5a917 | |||
| 4b29186696 | |||
| 7b5be9ee29 | |||
| eeb261bcd5 | |||
| ef88a8a020 | |||
| 86ab885fd9 | |||
| de07ddeac6 | |||
| dc149de936 | |||
| 320f6d1214 | |||
| 1517d6d2f2 | |||
| 6bb17af2e3 | |||
| 505ead7e58 | |||
| 1da4e89385 | |||
| 83f37d78ba | |||
| d4ac25496a | |||
| e84da2283c | |||
| 3dd9572754 | |||
| 922cb7e42f | |||
| 103cb513d9 | |||
| c24e4e4ed5 | |||
| 1b46a7dcdf | |||
| 8d28d65b36 | |||
| fbb125a3af | |||
| ca7336391a | |||
| 771bccc35c | |||
| c794b96bdc | |||
| f108a2a994 | |||
| 7cbf61cabb | |||
| dfdb72559f | |||
| d69793d93c | |||
| b068c8b605 | |||
| ec16352579 | |||
| aa4ba23350 | |||
| 25e639b474 | |||
| ee8e4a946e | |||
| a41a2a1d2c | |||
| eadd8d08d3 | |||
| 602a1142e8 | |||
| 0b7fef3d94 | |||
| 809d47ec77 | |||
| f3444d495d | |||
| 612c882b83 | |||
| f2a6be3129 | |||
| 465663ed77 | |||
| 1102ffaaf8 | |||
| 98f6a82390 | |||
| a43c6e1828 | |||
| 0db301f863 | |||
| 8e6d3875c6 | |||
| b9d77d46ff | |||
| 96f94d4347 | |||
| 63831f118f | |||
| ebe280eede | |||
| 95d6cdc7c7 | |||
| 9223215add | |||
| 309cfd109f | |||
| cfc6175aab | |||
| dc39f368c3 | |||
| c0f3400573 | |||
| 822d7e5ae9 | |||
| 5874db84ab | |||
| e9e8d49216 | |||
| 550fc21ce5 | |||
| a8aba8957b | |||
| ca0ac64997 | |||
| 7678501bc9 | |||
| dec5eb6e83 | |||
| 2eff326781 | |||
| 50ce5746a7 | |||
| 1537f80267 | |||
| 021d3aa21a | |||
| e8c8c5459e | |||
| 1c20aed318 | |||
| 4c4d24a338 | |||
| 8c7b9b8de4 | |||
| f39ac571c4 | |||
| 84f36701bc | |||
| 6d4ce240de | |||
| 229a155aef | |||
| 73250089cd | |||
| a72bc4e69f | |||
| 0812061274 |
@@ -1,21 +0,0 @@
|
||||
# http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[src/ngLocale/**]
|
||||
insert_final_newline = false
|
||||
|
||||
[dropdown-toggle.js]
|
||||
trim_trailing_whitespace = false
|
||||
insert_final_newline = false
|
||||
|
||||
[htmlparser.js]
|
||||
insert_final_newline = false
|
||||
+2
-3
@@ -1,5 +1,4 @@
|
||||
/build/
|
||||
/benchpress-build/
|
||||
.DS_Store
|
||||
gen_docs.disable
|
||||
test.disable
|
||||
@@ -10,11 +9,11 @@ performance/temp*.html
|
||||
*.swp
|
||||
angular.js.tmproj
|
||||
/node_modules/
|
||||
bower_components/
|
||||
/components/
|
||||
/bower_components/
|
||||
angular.xcodeproj
|
||||
.idea
|
||||
.agignore
|
||||
.lvimrc
|
||||
libpeerconnection.log
|
||||
npm-debug.log
|
||||
/tmp/
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
node_modules/**
|
||||
lib/htmlparser/**
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"bitwise": true,
|
||||
"immed": true,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"noempty": true,
|
||||
"nonew": true,
|
||||
"trailing": true,
|
||||
"maxlen": 200,
|
||||
"boss": true,
|
||||
"eqnull": true,
|
||||
"expr": true,
|
||||
"globalstrict": true,
|
||||
"laxbreak": true,
|
||||
"loopfunc": true,
|
||||
"sub": true,
|
||||
"undef": true,
|
||||
"indent": 2
|
||||
}
|
||||
+4
-8
@@ -1,6 +1,6 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- '0.10'
|
||||
- 0.10
|
||||
|
||||
branches:
|
||||
except:
|
||||
@@ -11,6 +11,7 @@ env:
|
||||
- JOB=unit
|
||||
- JOB=e2e TEST_TARGET=jqlite
|
||||
- JOB=e2e TEST_TARGET=jquery
|
||||
- JOB=e2e TEST_TARGET=doce2e
|
||||
global:
|
||||
- SAUCE_USERNAME=angular-ci
|
||||
- SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987
|
||||
@@ -18,13 +19,8 @@ env:
|
||||
- BROWSER_PROVIDER_READY_FILE=/tmp/sauce-connect-ready
|
||||
|
||||
install:
|
||||
# - npm config set registry http://23.251.144.68
|
||||
# Disable the spinner, it looks bad on Travis
|
||||
- npm config set spin false
|
||||
# Log HTTP requests
|
||||
- npm config set loglevel http
|
||||
- time ./scripts/travis/npm-bundle-deps.sh
|
||||
- time npm install
|
||||
- npm config set registry http://23.251.144.68
|
||||
- npm install
|
||||
|
||||
before_script:
|
||||
- mkdir -p $LOGS_DIR
|
||||
|
||||
+18
-3156
File diff suppressed because it is too large
Load Diff
+12
-14
@@ -40,13 +40,12 @@ would like to implement a new feature then consider what kind of change it is:
|
||||
[dev mailing list][angular-dev] or [IRC][irc] so that we can better coordinate our efforts, prevent
|
||||
duplication of work, and help you to craft the change so that it is successfully accepted into the
|
||||
project.
|
||||
* **Small Changes** can be crafted and submitted to the [GitHub Repository][github] as a Pull Request.
|
||||
* **Small Changes** can be crafted and submitted to [GitHub Repository][github] as a Pull Request.
|
||||
|
||||
|
||||
## <a name="docs"></a> Want a Doc Fix?
|
||||
If you want to help improve the docs, it's a good idea to let others know what you're working on to
|
||||
minimize duplication of effort. Before starting, check out the issue queue for
|
||||
[Milestone:Docs Only](https://github.com/angular/angular.js/issues?milestone=24&state=open).
|
||||
If you want to help improve the docs, it's a good idea to let others know what you're working on to
|
||||
minimize duplication of effort. Before starting, check out the issue queue for [Milestone:Docs Only](https://github.com/angular/angular.js/issues?milestone=24&state=open).
|
||||
Comment on an issue to let others know what you're working on, or create a new issue if your work
|
||||
doesn't fit within the scope of any of the existing doc fix projects.
|
||||
|
||||
@@ -54,7 +53,7 @@ For large fixes, please build and test the documentation before submitting the P
|
||||
accidentally introduced any layout or formatting issues. You should also make sure that your commit message
|
||||
is labeled "docs:" and follows the **Git Commit Guidelines** outlined below.
|
||||
|
||||
If you're just making a small change, don't worry about filing an issue first. Use the friendly blue "Improve this doc" button at the top right of the doc page to fork the repository in-place and make a quick change on the fly. When naming the commit, it is advised to still label it according to the commit guidelines below, by starting the commit message with **docs** and referencing the filename. Since this is not obvious and some changes are made on the fly, this is not strictly necessary and we will understand if this isn't done the first few times.
|
||||
If you're just making a small change, don't worry about filing an issue first. Use the friendly blue "Improve this doc" button at the top right of the doc page to fork the repository in-place and make a quick change on the fly.
|
||||
|
||||
## <a name="submit"></a> Submission Guidelines
|
||||
|
||||
@@ -66,13 +65,13 @@ Help us to maximize the effort we can spend fixing issues and adding new
|
||||
features, by not reporting duplicate issues. Providing the following information will increase the
|
||||
chances of your issue being dealt with quickly:
|
||||
|
||||
* **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps
|
||||
* **Overview of the issue** - if an error is being thrown a non-minified stack trace helps
|
||||
* **Motivation for or Use Case** - explain why this is a bug for you
|
||||
* **Angular Version(s)** - is it a regression?
|
||||
* **Browsers and Operating System** - is this a problem with all browsers or only IE8?
|
||||
* **Reproduce the Error** - provide a live example (using [Plunker][plunker] or
|
||||
* **Reproduce the error** - provide a live example (using [Plunker][plunker] or
|
||||
[JSFiddle][jsfiddle]) or a unambiguous set of steps.
|
||||
* **Related Issues** - has a similar issue been reported before?
|
||||
* **Related issues** - has a similar issue been reported before?
|
||||
* **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be
|
||||
causing the problem (line of code or commit)
|
||||
|
||||
@@ -85,7 +84,7 @@ Before you submit your pull request consider the following guidelines:
|
||||
|
||||
* Search [GitHub](https://github.com/angular/angular.js/pulls) for an open or closed Pull Request
|
||||
that relates to your submission. You don't want to duplicate effort.
|
||||
* Please sign our [Contributor License Agreement (CLA)](#cla) before sending pull
|
||||
* Please sign our [Contributor License Agreement (CLA)](#signing-the-cla) before sending pull
|
||||
requests. We cannot accept code without this.
|
||||
* Make your changes in a new git branch
|
||||
|
||||
@@ -94,7 +93,7 @@ Before you submit your pull request consider the following guidelines:
|
||||
```
|
||||
|
||||
* Create your patch, **including appropriate test cases**.
|
||||
* Follow our [Coding Rules](#rules).
|
||||
* Follow our [Coding Rules](#coding-rules).
|
||||
* Run the full Angular test suite, as described in the [developer documentation][dev-doc],
|
||||
and ensure that all tests pass.
|
||||
* Commit your changes using a descriptive commit message that follows our
|
||||
@@ -120,7 +119,7 @@ Before you submit your pull request consider the following guidelines:
|
||||
```
|
||||
|
||||
* In GitHub, send a pull request to `angular:master`.
|
||||
* If we suggest changes then
|
||||
* If we suggest changes then
|
||||
* Make the required updates.
|
||||
* Re-run the Angular test suite to ensure tests are still passing.
|
||||
* Rebase your branch and force push to your GitHub repository (this will update your Pull Request):
|
||||
@@ -238,7 +237,7 @@ reference GitHub issues that this commit **Closes**.
|
||||
|
||||
A detailed explanation can be found in this [document][commit-message-format].
|
||||
|
||||
## <a name="cla"></a> Signing the CLA
|
||||
## <a name="cla"></a> Signing the CLA
|
||||
|
||||
Please sign our Contributor License Agreement (CLA) before sending pull requests. For any code
|
||||
changes to be accepted, the CLA must be signed. It's a quick process, we promise!
|
||||
@@ -260,7 +259,6 @@ You can find out more detailed information about contributing in the
|
||||
[contribute]: http://docs.angularjs.org/misc/contribute
|
||||
[contributing]: http://docs.angularjs.org/misc/contribute
|
||||
[corporate-cla]: http://code.google.com/legal/corporate-cla-v1.0.html
|
||||
[dev-doc]: https://docs.angularjs.org/guide
|
||||
[github]: https://github.com/angular/angular.js
|
||||
[groups]: https://groups.google.com/forum/?fromgroups#!forum/angular
|
||||
[individual-cla]: http://code.google.com/legal/individual-cla-v1.0.html
|
||||
@@ -271,6 +269,6 @@ You can find out more detailed information about contributing in the
|
||||
[ngDocs]: https://github.com/angular/angular.js/wiki/Writing-AngularJS-Documentation
|
||||
[plunker]: http://plnkr.co/edit
|
||||
[stackoverflow]: http://stackoverflow.com/questions/tagged/angularjs
|
||||
[unit-testing]: https://docs.angularjs.org/guide/unit-testing
|
||||
[unit-testing]: http://docs.angularjs.org/guide/dev_guide.unit-testing
|
||||
|
||||
[](https://github.com/igrigorik/ga-beacon)
|
||||
|
||||
+7
-44
@@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
var files = require('./angularFiles').files;
|
||||
var util = require('./lib/grunt/utils.js');
|
||||
var versionInfo = require('./lib/versions/version-info');
|
||||
@@ -10,7 +8,6 @@ module.exports = function(grunt) {
|
||||
require('load-grunt-tasks')(grunt);
|
||||
|
||||
grunt.loadTasks('lib/grunt');
|
||||
grunt.loadNpmTasks('angular-benchpress');
|
||||
|
||||
var NG_VERSION = versionInfo.currentVersion;
|
||||
NG_VERSION.cdn = versionInfo.cdnVersion;
|
||||
@@ -23,12 +20,7 @@ module.exports = function(grunt) {
|
||||
//config
|
||||
grunt.initConfig({
|
||||
NG_VERSION: NG_VERSION,
|
||||
bp_build: {
|
||||
options: {
|
||||
buildPath: 'build/benchmarks',
|
||||
benchmarksPath: 'benchmarks'
|
||||
}
|
||||
},
|
||||
|
||||
parallel: {
|
||||
travis: {
|
||||
tasks: [
|
||||
@@ -47,7 +39,8 @@ module.exports = function(grunt) {
|
||||
keepalive: true,
|
||||
middleware: function(connect, options){
|
||||
return [
|
||||
util.conditionalCsp(),
|
||||
//uncomment to enable CSP
|
||||
// util.csp(),
|
||||
util.rewrite(),
|
||||
connect.favicon('images/favicon.ico'),
|
||||
connect.static(options.base),
|
||||
@@ -73,7 +66,6 @@ module.exports = function(grunt) {
|
||||
|
||||
next();
|
||||
},
|
||||
util.conditionalCsp(),
|
||||
connect.favicon('images/favicon.ico'),
|
||||
connect.static(options.base)
|
||||
];
|
||||
@@ -115,12 +107,6 @@ module.exports = function(grunt) {
|
||||
options: {
|
||||
jshintrc: true,
|
||||
},
|
||||
node: {
|
||||
files: { src: ['*.js', 'lib/**/*.js'] },
|
||||
},
|
||||
tests: {
|
||||
files: { src: 'test/**/*.js' },
|
||||
},
|
||||
ng: {
|
||||
files: { src: files['angularSrc'] },
|
||||
},
|
||||
@@ -133,9 +119,6 @@ module.exports = function(grunt) {
|
||||
ngLocale: {
|
||||
files: { src: 'src/ngLocale/**/*.js' },
|
||||
},
|
||||
ngMessages: {
|
||||
files: { src: 'src/ngMessages/**/*.js' },
|
||||
},
|
||||
ngMock: {
|
||||
files: { src: 'src/ngMock/**/*.js' },
|
||||
},
|
||||
@@ -153,9 +136,6 @@ module.exports = function(grunt) {
|
||||
},
|
||||
ngTouch: {
|
||||
files: { src: 'src/ngTouch/**/*.js' },
|
||||
},
|
||||
ngAria: {
|
||||
files: {src: 'src/ngAria/**/*.js'},
|
||||
}
|
||||
},
|
||||
|
||||
@@ -170,7 +150,7 @@ module.exports = function(grunt) {
|
||||
scenario: {
|
||||
dest: 'build/angular-scenario.js',
|
||||
src: [
|
||||
'bower_components/jquery/dist/jquery.js',
|
||||
'bower_components/jquery/jquery.js',
|
||||
util.wrap([files['angularSrc'], files['angularScenario']], 'ngScenario/angular')
|
||||
],
|
||||
styles: {
|
||||
@@ -207,10 +187,6 @@ module.exports = function(grunt) {
|
||||
dest: 'build/angular-resource.js',
|
||||
src: util.wrap(files['angularModules']['ngResource'], 'module')
|
||||
},
|
||||
messages: {
|
||||
dest: 'build/angular-messages.js',
|
||||
src: util.wrap(files['angularModules']['ngMessages'], 'module')
|
||||
},
|
||||
animate: {
|
||||
dest: 'build/angular-animate.js',
|
||||
src: util.wrap(files['angularModules']['ngAnimate'], 'module')
|
||||
@@ -223,10 +199,6 @@ module.exports = function(grunt) {
|
||||
dest: 'build/angular-cookies.js',
|
||||
src: util.wrap(files['angularModules']['ngCookies'], 'module')
|
||||
},
|
||||
aria: {
|
||||
dest: 'build/angular-aria.js',
|
||||
src: util.wrap(files['angularModules']['ngAria'], 'module')
|
||||
},
|
||||
"promises-aplus-adapter": {
|
||||
dest:'tmp/promises-aplus-adapter++.js',
|
||||
src:['src/ng/q.js','lib/promises-aplus/promises-aplus-test-adapter.js']
|
||||
@@ -239,22 +211,17 @@ module.exports = function(grunt) {
|
||||
animate: 'build/angular-animate.js',
|
||||
cookies: 'build/angular-cookies.js',
|
||||
loader: 'build/angular-loader.js',
|
||||
messages: 'build/angular-messages.js',
|
||||
touch: 'build/angular-touch.js',
|
||||
resource: 'build/angular-resource.js',
|
||||
route: 'build/angular-route.js',
|
||||
sanitize: 'build/angular-sanitize.js',
|
||||
aria: 'build/angular-aria.js'
|
||||
sanitize: 'build/angular-sanitize.js'
|
||||
},
|
||||
|
||||
|
||||
"ddescribe-iit": {
|
||||
files: [
|
||||
'src/**/*.js',
|
||||
'test/**/*.js',
|
||||
'!test/ngScenario/DescribeSpec.js',
|
||||
'!src/ng/directive/attrs.js', // legitimate xit here
|
||||
'!src/ngScenario/**/*.js'
|
||||
'!test/ngScenario/DescribeSpec.js'
|
||||
]
|
||||
},
|
||||
|
||||
@@ -279,11 +246,7 @@ module.exports = function(grunt) {
|
||||
compress: {
|
||||
build: {
|
||||
options: {archive: 'build/' + dist +'.zip', mode: 'zip'},
|
||||
src: ['**'],
|
||||
cwd: 'build',
|
||||
expand: true,
|
||||
dot: true,
|
||||
dest: dist + '/'
|
||||
src: ['**'], cwd: 'build', expand: true, dot: true, dest: dist + '/'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -6,17 +6,16 @@ use good old HTML (or HAML, Jade and friends!) as your template language and let
|
||||
syntax to express your application’s components clearly and succinctly. It automatically
|
||||
synchronizes data from your UI (view) with your JavaScript objects (model) through 2-way data
|
||||
binding. To help you structure your application better and make it easy to test, AngularJS teaches
|
||||
the browser how to do dependency injection and inversion of control.
|
||||
|
||||
Oh yeah and it helps with server-side communication, taming async callbacks with promises and
|
||||
deferreds. It also makes client-side navigation and deeplinking with hashbang urls or HTML5 pushState a
|
||||
piece of cake. The best of all: it makes development fun!
|
||||
the browser how to do dependency injection and inversion of control. Oh yeah and it also helps with
|
||||
server-side communication, taming async callbacks with promises and deferreds; and makes client-side
|
||||
navigation and deeplinking with hashbang urls or HTML5 pushState a piece of cake. The best of all:
|
||||
it makes development fun!
|
||||
|
||||
* Web site: http://angularjs.org
|
||||
* Tutorial: http://docs.angularjs.org/tutorial
|
||||
* API Docs: http://docs.angularjs.org/api
|
||||
* Developer Guide: http://docs.angularjs.org/guide
|
||||
* Contribution guidelines: [CONTRIBUTING.md](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md)
|
||||
* Contribution guidelines: http://docs.angularjs.org/misc/contribute
|
||||
* Dashboard: http://dashboard.angularjs.org
|
||||
|
||||
Building AngularJS
|
||||
@@ -38,7 +37,7 @@ To execute end-to-end (e2e) tests, use:
|
||||
grunt test:e2e
|
||||
|
||||
To learn more about the grunt tasks, run `grunt --help` and also read our
|
||||
[contribution guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md).
|
||||
[contribution guidelines](http://docs.angularjs.org/misc/contribute).
|
||||
|
||||
|
||||
[](https://github.com/igrigorik/ga-beacon)
|
||||
|
||||
+9
-6
@@ -26,6 +26,7 @@ This process based on the idea of minimizing user pain
|
||||
* You can triage older issues as well
|
||||
* Triage to your heart's content
|
||||
1. Assign yourself: Pick an issue that is not assigned to anyone and assign it to you
|
||||
|
||||
1. Understandable? - verify if the description of the request is clear.
|
||||
* If not, [close it][] according to the instructions below and go to the last step.
|
||||
1. Duplicate?
|
||||
@@ -33,8 +34,9 @@ This process based on the idea of minimizing user pain
|
||||
* Check if there are comments that link to a dupe. If so verify that this is indeed a dupe, [close it][], and go to the last step.
|
||||
1. Bugs:
|
||||
* Label `Type: Bug`
|
||||
* Reproducible? - Steps to reproduce the bug are clear. If they are not, ask for a clarification. If there's no reply after a week, [close it][].
|
||||
* Reproducible? - Steps to reproduce the bug are clear. If they are not,
|
||||
* Reproducible on master? - <http://code.angularjs.org/snapshot/>
|
||||
|
||||
1. Non bugs:
|
||||
* Label `Type: Feature`, `Type: Chore`, or `Type: Perf`
|
||||
* Belongs in core? – Often new features should be implemented as a third-party module rather than an addition to the core.
|
||||
@@ -42,11 +44,11 @@ This process based on the idea of minimizing user pain
|
||||
* Label `needs: breaking change` - if needed
|
||||
* Label `needs: public api` - if the issue requires introduction of a new public API
|
||||
1. Label `browser: *` - if the issue **only** affects a certain browser
|
||||
1. Label `frequency: *` – How often does this issue come up? How many developers does this affect? Chose just one of the following:
|
||||
1. Label `frequency: *` – How often does this issue come up? How many developers does this affect?
|
||||
* low - obscure issue affecting a handful of developers
|
||||
* moderate - impacts a common usage pattern
|
||||
* high - impacts most or all Angular apps
|
||||
1. Label `severity: *` - How bad is the issue? Chose just one of the following:
|
||||
1. Label `severity: *` - How bad is the issue?
|
||||
* security issue
|
||||
* regression
|
||||
* memory leak
|
||||
@@ -57,10 +59,11 @@ This process based on the idea of minimizing user pain
|
||||
* In rare cases, it's ok to have multiple components.
|
||||
1. Label `PRs plz!` - These issues are good targets for PRs from the open source community. Apply to issues where the problem and solution are well defined in the comments, and it's not too complex.
|
||||
1. Label `origin: google` for issues from Google
|
||||
1. Assign a milestone:
|
||||
* Backlog - triaged fixes and features, should be the default choice
|
||||
* Current 1.x.y milestone (e.g. 1.3.0-beta-2) - regressions and urgent bugs only
|
||||
|
||||
1. Assign a milestone:
|
||||
* Backlog - triaged fixes and features, should be the default choice
|
||||
* Current 1.x.y milestone (e.g. 1.3.0-beta-2) - regressions and urgent bugs only
|
||||
|
||||
|
||||
1. Unassign yourself from the issue
|
||||
|
||||
|
||||
Vendored
+7
-22
@@ -1,6 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
var angularFiles = {
|
||||
angularFiles = {
|
||||
'angularSrc': [
|
||||
'src/minErr.js',
|
||||
'src/Angular.js',
|
||||
@@ -34,8 +32,6 @@ var angularFiles = {
|
||||
'src/ng/sanitizeUri.js',
|
||||
'src/ng/sce.js',
|
||||
'src/ng/sniffer.js',
|
||||
'src/ng/templateRequest.js',
|
||||
'src/ng/testability.js',
|
||||
'src/ng/timeout.js',
|
||||
'src/ng/urlUtils.js',
|
||||
'src/ng/window.js',
|
||||
@@ -48,7 +44,7 @@ var angularFiles = {
|
||||
|
||||
'src/ng/directive/directives.js',
|
||||
'src/ng/directive/a.js',
|
||||
'src/ng/directive/attrs.js',
|
||||
'src/ng/directive/booleanAttrs.js',
|
||||
'src/ng/directive/form.js',
|
||||
'src/ng/directive/input.js',
|
||||
'src/ng/directive/ngBind.js',
|
||||
@@ -84,9 +80,6 @@ var angularFiles = {
|
||||
'ngCookies': [
|
||||
'src/ngCookies/cookies.js'
|
||||
],
|
||||
'ngMessages': [
|
||||
'src/ngMessages/messages.js'
|
||||
],
|
||||
'ngResource': [
|
||||
'src/ngResource/resource.js'
|
||||
],
|
||||
@@ -108,9 +101,6 @@ var angularFiles = {
|
||||
'src/ngTouch/directive/ngClick.js',
|
||||
'src/ngTouch/directive/ngSwipe.js'
|
||||
],
|
||||
'ngAria': [
|
||||
'src/ngAria/aria.js'
|
||||
]
|
||||
},
|
||||
|
||||
'angularScenario': [
|
||||
@@ -138,18 +128,16 @@ var angularFiles = {
|
||||
'test/auto/*.js',
|
||||
'test/ng/**/*.js',
|
||||
'test/ngAnimate/*.js',
|
||||
'test/ngMessages/*.js',
|
||||
'test/ngCookies/*.js',
|
||||
'test/ngResource/*.js',
|
||||
'test/ngRoute/**/*.js',
|
||||
'test/ngSanitize/**/*.js',
|
||||
'test/ngMock/*.js',
|
||||
'test/ngTouch/**/*.js',
|
||||
'test/ngAria/*.js'
|
||||
'test/ngTouch/**/*.js'
|
||||
],
|
||||
|
||||
'karma': [
|
||||
'bower_components/jquery/dist/jquery.js',
|
||||
'bower_components/jquery/jquery.js',
|
||||
'test/jquery_remove.js',
|
||||
'@angularSrc',
|
||||
'src/publishExternalApis.js',
|
||||
@@ -179,12 +167,11 @@ var angularFiles = {
|
||||
'test/ngRoute/**/*.js',
|
||||
'test/ngResource/*.js',
|
||||
'test/ngSanitize/**/*.js',
|
||||
'test/ngTouch/**/*.js',
|
||||
'test/ngAria/*.js'
|
||||
'test/ngTouch/**/*.js'
|
||||
],
|
||||
|
||||
'karmaJquery': [
|
||||
'bower_components/jquery/dist/jquery.js',
|
||||
'bower_components/jquery/jquery.js',
|
||||
'test/jquery_alias.js',
|
||||
'@angularSrc',
|
||||
'src/publishExternalApis.js',
|
||||
@@ -202,14 +189,12 @@ var angularFiles = {
|
||||
|
||||
angularFiles['angularSrcModules'] = [].concat(
|
||||
angularFiles['angularModules']['ngAnimate'],
|
||||
angularFiles['angularModules']['ngMessages'],
|
||||
angularFiles['angularModules']['ngCookies'],
|
||||
angularFiles['angularModules']['ngResource'],
|
||||
angularFiles['angularModules']['ngRoute'],
|
||||
angularFiles['angularModules']['ngSanitize'],
|
||||
angularFiles['angularModules']['ngMock'],
|
||||
angularFiles['angularModules']['ngTouch'],
|
||||
angularFiles['angularModules']['ngAria']
|
||||
angularFiles['angularModules']['ngTouch']
|
||||
);
|
||||
|
||||
if (exports) {
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
Instructions for using benchpress (how to create benchmarks, how to run, how to configure) can be
|
||||
found at: https://github.com/angular/benchpress/blob/master/README.md.
|
||||
|
||||
In this project, there is a configured grunt task for building the benchmarks,
|
||||
`grunt bp_build`, which places the runnable benchmarks in "/build/benchmarks/".
|
||||
The existing `grunt webserver` task can be used to serve the built benchmarks at `localhost:8000/build/benchmarks/<benchmark-name>`
|
||||
@@ -1,57 +0,0 @@
|
||||
var app = angular.module('eventDelegationBenchmark', []);
|
||||
|
||||
app.directive('noopDir', function() {
|
||||
return {
|
||||
compile: function($element, $attrs) {
|
||||
return function($scope, $element) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
app.directive('nativeClick', ['$parse', function($parse) {
|
||||
return {
|
||||
compile: function($element, $attrs) {
|
||||
var expr = $parse($attrs.tstEvent);
|
||||
return function($scope, $element) {
|
||||
$element[0].addEventListener('click', function() {
|
||||
console.log('clicked');
|
||||
}, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
app.directive('dlgtClick', function() {
|
||||
return {
|
||||
compile: function($element, $attrs) {
|
||||
var evt = $attrs.dlgtClick;
|
||||
// We don't setup the global event listeners as the costs are small and one time only...
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
app.controller('DataController', function($rootScope) {
|
||||
this.ngRepeatCount = 1000;
|
||||
this.rows = [];
|
||||
var self = this;
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: '$apply',
|
||||
fn: function() {
|
||||
var oldRows = self.rows;
|
||||
$rootScope.$apply(function() {
|
||||
self.rows = [];
|
||||
});
|
||||
self.rows = oldRows;
|
||||
if (self.rows.length !== self.ngRepeatCount) {
|
||||
self.rows = [];
|
||||
for (var i=0; i<self.ngRepeatCount; i++) {
|
||||
self.rows.push('row'+i);
|
||||
}
|
||||
}
|
||||
$rootScope.$apply();
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
scripts: [{
|
||||
id: 'angular',
|
||||
src: '/build/angular.js'
|
||||
},{
|
||||
src: 'app.js',
|
||||
}]
|
||||
});
|
||||
};
|
||||
@@ -1,139 +0,0 @@
|
||||
<div ng-app="eventDelegationBenchmark">
|
||||
<div ng-controller="DataController as ctrl">
|
||||
<div class="container-fluid">
|
||||
|
||||
<p>
|
||||
Impact of event delegation.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label>
|
||||
Number of ngRepeats:
|
||||
<input type="number" ng-model="ctrl.ngRepeatCount">
|
||||
</label>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="ngClick">ngClick</label></div>
|
||||
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="ngClickNoJqLite">ngClick without jqLite</label></div>
|
||||
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="ngShow">baseline: ng-show</label></div>
|
||||
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="textInterpolation">baseline: text interpolation</label></div>
|
||||
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="dlgtClick">delegate event directive (only compile)</label></div>
|
||||
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="noopDir">baseline: noop directive (compile and link)</label></div>
|
||||
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="noop">baseline: no directive</label></div>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
How to read the results:
|
||||
<ul>
|
||||
<li>The benchmark measures how long it takes to instantiate a given number of directives</li>
|
||||
<li>ngClick is compared against ngShow and text interpolation as baseline. The results show
|
||||
how expensive ngClick is compared to other very simple directives that touch the DOM.
|
||||
</li>
|
||||
<li>To measure the impact of jqLite.on vs element.addEventListener there is also a benchmark
|
||||
that as a modified version of ngClick that uses element.addEventListener.
|
||||
</li>
|
||||
<li>The delegate event directive is compared against a noop directive with a compile and link function and the case with no directives.
|
||||
The result shows how expensive it is to add a link function to a directive, as the delegate event directive has none.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Results as of 7/31/2014:
|
||||
<ul>
|
||||
<li>ngClick is very close to ngShow and text interpolation, especially when looking at a version of ngClick that does not use jqLite.on but element.addEventListener instead.</li>
|
||||
<li>A delegate event directive that has no link function has the same speed as a directive with link function. I.e. ngClick is slower compared to the delegate event directive only because ngClick touches
|
||||
the DOM for every element</li>
|
||||
<li>A delegate event directive could be about 50% faster than ngClick. However, the overall performance
|
||||
benefit depends on how many (and which) other directives are used on the same element
|
||||
and what other things are part of the measures use case.
|
||||
E.g. rows of a table with ngRepeat that use ngClick will probably also contain text interpolation.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
Debug output:
|
||||
<ng-switch on="benchmarkType">
|
||||
<div ng-switch-when="ngClick">
|
||||
<div>
|
||||
<span ng-repeat="row in ctrl.rows">
|
||||
<span ng-click="a()">1</span>
|
||||
<span ng-click="a()">1</span>
|
||||
<span ng-click="a()">1</span>
|
||||
<span ng-click="a()">1</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="ngClickNoJqLite">
|
||||
<div>
|
||||
<span ng-repeat="row in ctrl.rows">
|
||||
<span native-click="a()">1</span>
|
||||
<span native-click="a()">1</span>
|
||||
<span native-click="a()">1</span>
|
||||
<span native-click="a()">1</span>
|
||||
<span native-click="a()">1</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="ngShow">
|
||||
<div>
|
||||
<span ng-repeat="row in ctrl.rows">
|
||||
<span ng-show="true">1</span>
|
||||
<span ng-show="true">1</span>
|
||||
<span ng-show="true">1</span>
|
||||
<span ng-show="true">1</span>
|
||||
<span ng-show="true">1</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="textInterpolation">
|
||||
<div>
|
||||
<span ng-repeat="row in ctrl.rows">
|
||||
<span>{{row}}</span>
|
||||
<span>{{row}}</span>
|
||||
<span>{{row}}</span>
|
||||
<span>{{row}}</span>
|
||||
<span>{{row}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="dlgtClick">
|
||||
<div>
|
||||
<span ng-repeat="row in ctrl.rows">
|
||||
<span dlgt-click="a()">1</span>
|
||||
<span dlgt-click="a()">1</span>
|
||||
<span dlgt-click="a()">1</span>
|
||||
<span dlgt-click="a()">1</span>
|
||||
<span dlgt-click="a()">1</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="noopDir">
|
||||
<div>
|
||||
<span ng-repeat="row in ctrl.rows">
|
||||
<span noop-dir>1</span>
|
||||
<span noop-dir>1</span>
|
||||
<span noop-dir>1</span>
|
||||
<span noop-dir>1</span>
|
||||
<span noop-dir>1</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="noop">
|
||||
<div>
|
||||
<span ng-repeat="row in ctrl.rows">
|
||||
<span>1</span>
|
||||
<span>1</span>
|
||||
<span>1</span>
|
||||
<span>1</span>
|
||||
<span>1</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</ng-switch>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,183 +0,0 @@
|
||||
var app = angular.module('largetableBenchmark', []);
|
||||
|
||||
app.config(function($compileProvider) {
|
||||
if ($compileProvider.debugInfoEnabled) {
|
||||
$compileProvider.debugInfoEnabled(false);
|
||||
}
|
||||
});
|
||||
|
||||
app.filter('noop', function() {
|
||||
return function(input) {
|
||||
return input;
|
||||
};
|
||||
});
|
||||
|
||||
app.controller('DataController', function($scope, $rootScope) {
|
||||
var totalRows = 1000;
|
||||
var totalColumns = 20;
|
||||
|
||||
var data = $scope.data = [];
|
||||
$scope.digestDuration = '?';
|
||||
$scope.numberOfBindings = totalRows*totalColumns*2 + totalRows + 1;
|
||||
$scope.numberOfWatches = '?';
|
||||
|
||||
function iGetter() { return this.i; }
|
||||
function jGetter() { return this.j; }
|
||||
|
||||
for (var i=0; i<totalRows; i++) {
|
||||
data[i] = [];
|
||||
for (var j=0; j<totalColumns; j++) {
|
||||
data[i][j] = {
|
||||
i: i, j: j,
|
||||
iFn: iGetter,
|
||||
jFn: jGetter
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
var previousType;
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: 'destroy',
|
||||
fn: function() {
|
||||
$scope.$apply(function() {
|
||||
previousType = $scope.benchmarkType;
|
||||
$scope.benchmarkType = 'none';
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: 'create',
|
||||
fn: function() {
|
||||
$scope.$apply(function() {
|
||||
$scope.benchmarkType = previousType;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: '$apply',
|
||||
fn: function() {
|
||||
$rootScope.$apply();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var fn = function() { return 'x'};
|
||||
|
||||
|
||||
app.directive('baselineBindingTable', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function ($scope, $element) {
|
||||
var i, j, row, cell, comment;
|
||||
var template = document.createElement('span');
|
||||
template.setAttribute('ng-repeat', 'foo in foos');
|
||||
template.classList.add('ng-scope');
|
||||
template.appendChild(document.createElement('span'));
|
||||
template.appendChild(document.createTextNode(':'));
|
||||
template.appendChild(document.createElement('span'));
|
||||
template.appendChild(document.createTextNode('|'));
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
row = document.createElement('div');
|
||||
$element[0].appendChild(row);
|
||||
for (j = 0; j < 20; j++) {
|
||||
cell = template.cloneNode(true);
|
||||
row.appendChild(cell);
|
||||
cell.childNodes[0].textContent = i;
|
||||
cell.childNodes[2].textContent = j;
|
||||
cell.ng3992 = 'xxx';
|
||||
comment = document.createComment('ngRepeat end: bar in foo');
|
||||
row.appendChild(comment);
|
||||
}
|
||||
|
||||
comment = document.createComment('ngRepeat end: foo in foos');
|
||||
$element[0].appendChild(comment);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
app.directive('baselineInterpolationTable', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function ($scope, $element) {
|
||||
var i, j, row, cell, comment;
|
||||
var template = document.createElement('span');
|
||||
template.setAttribute('ng-repeat', 'foo in foos');
|
||||
template.classList.add('ng-scope');
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
row = document.createElement('div');
|
||||
$element[0].appendChild(row);
|
||||
for (j = 0; j < 20; j++) {
|
||||
cell = template.cloneNode(true);
|
||||
row.appendChild(cell);
|
||||
cell.textContent = '' + i + ':' + j + '|';
|
||||
cell.ng3992 = 'xxx';
|
||||
comment = document.createComment('ngRepeat end: bar in foo');
|
||||
row.appendChild(comment);
|
||||
}
|
||||
|
||||
comment = document.createComment('ngRepeat end: foo in foos');
|
||||
$element[0].appendChild(comment);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
the fastest
|
||||
240/44
|
||||
|
||||
app.directive('baselineTable', function() {
|
||||
return function($scope, $element) {
|
||||
var i, j, row, cell;
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
row = document.createElement('div');
|
||||
for (j = 0; j < 20; j++) {
|
||||
cell = document.createElement('span');
|
||||
cell.textContent = '' + i + ':' + j;
|
||||
row.appendChild(cell);
|
||||
}
|
||||
$element[0].appendChild(row);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
with comments and expando
|
||||
232/90
|
||||
|
||||
app.directive('baselineTable', function() {
|
||||
return function($scope, $element) {
|
||||
var i, j, row, cell, comment;
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
row = document.createElement('div');
|
||||
$element[0].appendChild(row);
|
||||
for (j = 0; j < 20; j++) {
|
||||
cell = document.createElement('span');
|
||||
row.appendChild(cell);
|
||||
cell.textContent = '' + i + ':' + j;
|
||||
cell.ng3992 = 'xxx';
|
||||
comment = document.createComment('ngRepeat end: bar in foo');
|
||||
row.appendChild(comment);
|
||||
}
|
||||
|
||||
comment = document.createComment('ngRepeat end: foo in foos');
|
||||
$element[0].appendChild(comment);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
*/
|
||||
@@ -1,15 +0,0 @@
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
scripts: [{
|
||||
id: 'jquery',
|
||||
src: 'jquery-noop.js'
|
||||
},
|
||||
{
|
||||
id: 'angular',
|
||||
src: '/build/angular.js'
|
||||
},
|
||||
{
|
||||
src: 'app.js',
|
||||
}]
|
||||
});
|
||||
};
|
||||
-1
@@ -1 +0,0 @@
|
||||
//Override me with ?jquery=/bower_components/jquery/dist/jquery.js
|
||||
@@ -1,76 +0,0 @@
|
||||
<style>
|
||||
[ng-cloak] { display: none; }
|
||||
</style>
|
||||
<div ng-app="largetableBenchmark" ng-cloak>
|
||||
<div ng-controller="DataController">
|
||||
<div class="container-fluid">
|
||||
<p>
|
||||
Large table rendered with AngularJS
|
||||
</p>
|
||||
|
||||
<div>none: <input type="radio" ng-model="benchmarkType" value="none"></div>
|
||||
<div>baseline binding: <input type="radio" ng-model="benchmarkType" value="baselineBinding"></div>
|
||||
<div>baseline interpolation: <input type="radio" ng-model="benchmarkType" value="baselineInterpolation"></div>
|
||||
<div>ngBind: <input type="radio" ng-model="benchmarkType" value="ngBind"></div>
|
||||
<div>ngBindOnce: <input type="radio" ng-model="benchmarkType" value="ngBindOnce"></div>
|
||||
<div>interpolation: <input type="radio" ng-model="benchmarkType" value="interpolation"></div>
|
||||
<div>ngBind + fnInvocation: <input type="radio" ng-model="benchmarkType" value="ngBindFn"></div>
|
||||
<div>interpolation + fnInvocation: <input type="radio" ng-model="benchmarkType" value="interpolationFn"></div>
|
||||
<div>ngBind + filter: <input type="radio" ng-model="benchmarkType" value="ngBindFilter"></div>
|
||||
<div>interpolation + filter: <input type="radio" ng-model="benchmarkType" value="interpolationFilter"></div>
|
||||
|
||||
<ng-switch on="benchmarkType">
|
||||
<baseline-binding-table ng-switch-when="baselineBinding">
|
||||
</baseline-binding-table>
|
||||
<baseline-interpolation-table ng-switch-when="baselineInterpolation">
|
||||
</baseline-interpolation-table>
|
||||
<div ng-switch-when="ngBind">
|
||||
<h2>baseline binding</h2>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">
|
||||
<span ng-bind="column.i"></span>:<span ng-bind="column.j"></span>|
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="ngBindOnce">
|
||||
<h2>baseline binding once</h2>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in ::row">
|
||||
<span ng-bind="::column.i"></span>:<span ng-bind="::column.j"></span>|
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="interpolation">
|
||||
<h2>baseline interpolation</h2>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">{{column.i}}:{{column.j}}|</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="ngBindFn">
|
||||
<h2>bindings with functions</h2>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row"><span ng-bind="column.iFn()"></span>:<span ng-bind="column.jFn()"></span>|</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="interpolationFn">
|
||||
<h2>interpolation with functions</h2>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">{{column.iFn()}}:{{column.jFn()}}|</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="ngBindFilter">
|
||||
<h2>bindings with filter</h2>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row"><span ng-bind="column.i | noop"></span>:<span ng-bind="column.j | noop"></span>|</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="interpolationFilter">
|
||||
<h2>interpolation with filter</h2>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">{{column.i | noop}}:{{column.j | noop}}|</span>
|
||||
</div>
|
||||
</div>
|
||||
</ng-switch>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,48 +0,0 @@
|
||||
var app = angular.module('orderByBenchmark', []);
|
||||
|
||||
app.controller('DataController', function($rootScope, $scope) {
|
||||
this.ngRepeatCount = 5000;
|
||||
this.rows = [];
|
||||
var self = this;
|
||||
|
||||
$scope.benchmarkType = 'basic';
|
||||
|
||||
$scope.rawProperty = function(key) {
|
||||
return function(item) {
|
||||
return item[key];
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a random integer between min (included) and max (excluded)
|
||||
function getRandomInt(min, max) {
|
||||
return Math.floor(Math.random() * (max - min)) + min;
|
||||
}
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: 'setup',
|
||||
description: 'Set rows to empty array and apply, then push new rows to be applied in next step',
|
||||
fn: function() {
|
||||
var oldRows = self.rows;
|
||||
$rootScope.$apply(function() {
|
||||
self.rows = [];
|
||||
});
|
||||
self.rows = oldRows;
|
||||
if (self.rows.length !== self.ngRepeatCount) {
|
||||
self.rows = [];
|
||||
for (var i = 0; i < self.ngRepeatCount; i++) {
|
||||
self.rows.push({
|
||||
'name': getRandomInt(i, (i + 40)),
|
||||
'index': i
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: '$apply',
|
||||
fn: function() {
|
||||
$rootScope.$apply();
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,14 +0,0 @@
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
scripts: [
|
||||
{
|
||||
"id": "jquery",
|
||||
"src": "jquery-noop.js"
|
||||
},{
|
||||
id: 'angular',
|
||||
src: '/build/angular.js'
|
||||
},{
|
||||
src: 'app.js',
|
||||
}]
|
||||
});
|
||||
};
|
||||
@@ -1,82 +0,0 @@
|
||||
<div class="container-fluid" ng-app="orderByBenchmark">
|
||||
<div class="row" ng-controller="DataController as ctrl">
|
||||
<div class="col-lg-8">
|
||||
<p>Filters</p>
|
||||
|
||||
<p>
|
||||
<label>Number of ngRepeats:</label>
|
||||
<input type="number" ng-model="ctrl.ngRepeatCount">
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" ng-model="benchmarkType" value="baseline">baseline
|
||||
</label>
|
||||
</div>
|
||||
<pre><code>ng-repeat="row in ctrl.rows"</code></pre>
|
||||
<br />
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" ng-model="benchmarkType" value="orderBy">orderBy
|
||||
</label>
|
||||
</div>
|
||||
<pre><code>ng-repeat="row in ctrl.rows | orderBy:'name'"</code></pre>
|
||||
<br />
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" ng-model="benchmarkType" value="orderByArray">orderBy array expression
|
||||
</label>
|
||||
</div>
|
||||
<pre><code>ng-repeat="row in ctrl.rows | orderBy:['name', 'index']"</code></pre>
|
||||
<br />
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" ng-model="benchmarkType"
|
||||
value="orderByFunction">orderBy function expression
|
||||
</label>
|
||||
</div>
|
||||
<pre><code>ng-repeat="row in ctrl.rows | orderBy:rawProperty('name')"</code></pre>
|
||||
<br />
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" ng-model="benchmarkType"
|
||||
value="orderByArrayFunction">orderBy array function expression
|
||||
</label>
|
||||
</div>
|
||||
<pre><code>ng-repeat="row in ctrl.rows | orderBy:[rawProperty('name'), rawProperty('index')]"</code></pre>
|
||||
</p>
|
||||
|
||||
|
||||
Debug output:
|
||||
<ng-switch on="benchmarkType">
|
||||
<div ng-switch-when="baseline">
|
||||
<span ng-repeat="row in ctrl.rows">
|
||||
<span ng-bind="row.name"></span>,
|
||||
</span>
|
||||
</div>
|
||||
<div ng-switch-when="orderBy">
|
||||
<span ng-repeat="row in ctrl.rows | orderBy:'name'">
|
||||
<span ng-bind="row.name"></span>,
|
||||
</span>
|
||||
</div>
|
||||
<div ng-switch-when="orderByArray">
|
||||
<span ng-repeat="row in ctrl.rows | orderBy:['name', 'index']">
|
||||
<span ng-bind="row.name"></span>,
|
||||
</span>
|
||||
</div>
|
||||
<div ng-switch-when="orderByFunction">
|
||||
<span ng-repeat="row in ctrl.rows | orderBy:rawProperty('name')">
|
||||
<span ng-bind="row.name"></span>,
|
||||
</span>
|
||||
</div>
|
||||
<div ng-switch-when="orderByArrayFunction">
|
||||
<span ng-repeat="row in ctrl.rows | orderBy:[rawProperty('name'), rawProperty('index')]">
|
||||
<span ng-bind="row.name"></span>,
|
||||
</span>
|
||||
</div>
|
||||
</ng-switch>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,86 +0,0 @@
|
||||
var app = angular.module('parsedExpressionBenchmark', []);
|
||||
|
||||
app.config(function($compileProvider) {
|
||||
if ($compileProvider.debugInfoEnabled) {
|
||||
$compileProvider.debugInfoEnabled(false);
|
||||
}
|
||||
});
|
||||
|
||||
app.filter('noop', function() {
|
||||
return function(input) {
|
||||
return input;
|
||||
};
|
||||
});
|
||||
|
||||
//Executes the specified expression as a watcher
|
||||
app.directive('bmPeWatch', function() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
compile: function($element, $attrs) {
|
||||
$element.text( $attrs.bmPeWatch );
|
||||
return function($scope, $element, $attrs) {
|
||||
$scope.$watch($attrs.bmPeWatch, function(val) {
|
||||
$element.text(val);
|
||||
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
//Executes the specified expression as a watcher
|
||||
//Adds a simple wrapper method to allow use of $watch instead of $watchCollection
|
||||
app.directive('bmPeWatchLiteral', function($parse) {
|
||||
function retZero() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
compile: function($element, $attrs) {
|
||||
$element.text( $attrs.bmPeWatchLiteral );
|
||||
return function($scope, $element, $attrs) {
|
||||
$scope.$watch( $parse($attrs.bmPeWatchLiteral, retZero) );
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
app.controller('DataController', function($scope, $rootScope) {
|
||||
var totalRows = 10000;
|
||||
|
||||
var data = $scope.data = [];
|
||||
|
||||
var star = '*';
|
||||
|
||||
$scope.func = function() { return star;};
|
||||
|
||||
for (var i=0; i<totalRows; i++) {
|
||||
data.push({
|
||||
index: i,
|
||||
odd: i%2 === 0,
|
||||
even: i%2 === 1,
|
||||
str0: "foo-" + Math.random()*Date.now(),
|
||||
str1: "bar-" + Math.random()*Date.now(),
|
||||
str2: "baz-" + Math.random()*Date.now(),
|
||||
num0: Math.random()*Date.now(),
|
||||
num1: Math.random()*Date.now(),
|
||||
num2: Math.random()*Date.now(),
|
||||
date0: new Date(Math.random()*Date.now()),
|
||||
date1: new Date(Math.random()*Date.now()),
|
||||
date2: new Date(Math.random()*Date.now()),
|
||||
func: function(){ return star; },
|
||||
obj: data[i-1],
|
||||
keys: data[i-1] && (data[i-1].keys || Object.keys(data[i-1]))
|
||||
});
|
||||
}
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: '$apply',
|
||||
fn: function() {
|
||||
for (var i=0; i<50; i++) {
|
||||
$rootScope.$digest();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
scripts: [ {
|
||||
id: 'angular',
|
||||
src: '/build/angular.js'
|
||||
},
|
||||
{
|
||||
src: 'app.js',
|
||||
}]
|
||||
});
|
||||
};
|
||||
@@ -1,209 +0,0 @@
|
||||
<div ng-app="parsedExpressionBenchmark" ng-cloak>
|
||||
<div ng-controller="DataController">
|
||||
<div class="container-fluid">
|
||||
<p>
|
||||
Tests the execution of $parse()ed expressions. Each test tries to isolate specific expression types. Expressions should (probably) not be constant so they get evaluated per digest.
|
||||
</p>
|
||||
|
||||
<ul style="list-style:none">
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="simplePath" id="simplePath">
|
||||
<label for="simplePath">Simple Paths</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="complexPath" id="complexPath">
|
||||
<label for="complexPath">Complex Paths</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="fieldAccess" id="fieldAccess">
|
||||
<label for="fieldAccess">Field Accessors</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="fieldIndex" id="fieldIndex">
|
||||
<label for="fieldIndex">Field Indexes</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="operators" id="operators">
|
||||
<label for="operators">Binary/Unary operators</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="shortCircuitingOperators" id="shortCircuitingOperators">
|
||||
<label for="shortCircuitingOperators">AND/OR short-circuiting operators</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="filters" id="filters">
|
||||
<label for="filters">Filters</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="functionCalls" id="functionCalls">
|
||||
<label for="functionCalls">Function calls</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="objectLiterals" id="objectLiterals">
|
||||
<label for="objectLiterals">Object Literals</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="arrayLiterals" id="arrayLiterals">
|
||||
<label for="arrayLiterals">Array Literals</label>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!--
|
||||
NOTES:
|
||||
- ensure each tested expression has at least one variable in it to avoid constant expressions
|
||||
-->
|
||||
|
||||
<ul ng-switch="expressionType">
|
||||
<li ng-switch-when="simplePath" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="rowIdx"></span>
|
||||
<span bm-pe-watch="row.index"></span>
|
||||
<span bm-pe-watch="row.num0"></span>
|
||||
<span bm-pe-watch="row.num1"></span>
|
||||
<span bm-pe-watch="row.num2"></span>
|
||||
<span bm-pe-watch="row.str0"></span>
|
||||
<span bm-pe-watch="row.str1"></span>
|
||||
<span bm-pe-watch="row.str2"></span>
|
||||
<span bm-pe-watch="row.date0"></span>
|
||||
<span bm-pe-watch="row.obj"></span>
|
||||
<span bm-pe-watch="row.keys"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="complexPath" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="row.index"></span>
|
||||
<span bm-pe-watch="row.num0"></span>
|
||||
<span bm-pe-watch="row.num1"></span>
|
||||
<span bm-pe-watch="row.str0"></span>
|
||||
<span bm-pe-watch="row.str1"></span>
|
||||
<span bm-pe-watch="row.obj.index"></span>
|
||||
<span bm-pe-watch="row.obj.index"></span>
|
||||
<span bm-pe-watch="row.obj.index"></span>
|
||||
<span bm-pe-watch="row.obj.obj.index"></span>
|
||||
<span bm-pe-watch="row.obj.obj.index"></span>
|
||||
<span bm-pe-watch="row.obj.obj.obj.index"></span>
|
||||
<span bm-pe-watch="row.obj.obj.obj.index"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="fieldAccess" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="data[rowIdx].index"></span>
|
||||
<span bm-pe-watch="data[rowIdx].num0"></span>
|
||||
<span bm-pe-watch="data[rowIdx].num1"></span>
|
||||
<span bm-pe-watch="data[rowIdx].str0"></span>
|
||||
<span bm-pe-watch="data[rowIdx].str1"></span>
|
||||
<span bm-pe-watch="data[rowIdx].obj.index"></span>
|
||||
<span bm-pe-watch="data[rowIdx].obj.index"></span>
|
||||
<span bm-pe-watch="data[rowIdx].obj.index"></span>
|
||||
<span bm-pe-watch="data[rowIdx].obj.obj.index"></span>
|
||||
<span bm-pe-watch="data[rowIdx].obj.obj.index"></span>
|
||||
<span bm-pe-watch="data[rowIdx].obj.obj.obj.index"></span>
|
||||
<span bm-pe-watch="data[rowIdx].obj.obj.obj.index"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="fieldIndex" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="data[rowIdx]"></span>
|
||||
<span bm-pe-watch="row['str0']"></span>
|
||||
<span bm-pe-watch="row['str1']"></span>
|
||||
<span bm-pe-watch="data[row['index']]['index']"></span>
|
||||
<span bm-pe-watch="data[rowIdx]['obj']"></span>
|
||||
<span bm-pe-watch="data[rowIdx]['obj']['obj']"></span>
|
||||
<span bm-pe-watch="row[row['keys'][0]]"></span>
|
||||
<span bm-pe-watch="row[row['keys'][1]]"></span>
|
||||
<span bm-pe-watch="row[row['keys'][2]]"></span>
|
||||
<span bm-pe-watch="row[row['keys'][3]]"></span>
|
||||
<span bm-pe-watch="row[row['keys'][4]]"></span>
|
||||
<span bm-pe-watch="row[row['keys'][5]]"></span>
|
||||
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="operators" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="+rowIdx"></span>
|
||||
<span bm-pe-watch="-rowIdx"></span>
|
||||
<span bm-pe-watch="rowIdx + 1"></span>
|
||||
<span bm-pe-watch="rowIdx - 1"></span>
|
||||
<span bm-pe-watch="rowIdx * 2"></span>
|
||||
<span bm-pe-watch="rowIdx + -1"></span>
|
||||
<span bm-pe-watch="rowIdx - -1"></span>
|
||||
<span bm-pe-watch="-rowIdx * 2 + 1"></span>
|
||||
<span bm-pe-watch="rowIdx % 2"></span>
|
||||
<span bm-pe-watch="rowIdx % 2 === 1"></span>
|
||||
<span bm-pe-watch="rowIdx % 2 === 0"></span>
|
||||
<span bm-pe-watch="rowIdx / 1"></span>
|
||||
<span bm-pe-watch="-rowIdx * 2 * rowIdx + rowIdx / rowIdx + 1"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="shortCircuitingOperators" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="rowIdx && row.odd"></span>
|
||||
<span bm-pe-watch="row.odd && row.even"></span>
|
||||
<span bm-pe-watch="row.odd && !row.even"></span>
|
||||
<span bm-pe-watch="row.odd || row.even"></span>
|
||||
<span bm-pe-watch="row.odd || row.even || row.index"></span>
|
||||
<span bm-pe-watch="row.index === 1 || row.index === 2"></span>
|
||||
<span bm-pe-watch="row.num0 < row.num1 && row.num1 < row.num2"></span>
|
||||
<span bm-pe-watch="row.num0 < row.num1 || row.num1 < row.num2"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="filters" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="rowIdx | noop"></span>
|
||||
<span bm-pe-watch="rowIdx | noop"></span>
|
||||
<span bm-pe-watch="rowIdx | noop"></span>
|
||||
<span bm-pe-watch="rowIdx | noop:1"></span>
|
||||
<span bm-pe-watch="rowIdx | noop:rowIdx"></span>
|
||||
<span bm-pe-watch="rowIdx | noop:1:2:3:4:5"></span>
|
||||
<span bm-pe-watch="rowIdx | noop:rowIdx:rowIdx:rowIdx"></span>
|
||||
<span bm-pe-watch="rowIdx | noop | noop"></span>
|
||||
<span bm-pe-watch="rowIdx | noop:1 | noop"></span>
|
||||
<span bm-pe-watch="rowIdx | noop | noop:null:undefined:0"></span>
|
||||
<span bm-pe-watch="rowIdx | noop | noop | noop"></span>
|
||||
<span bm-pe-watch="rowIdx | noop:1 | noop:2 | noop:3"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="functionCalls" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="func()"></span>
|
||||
<span bm-pe-watch="func(1)"></span>
|
||||
<span bm-pe-watch="func(1, 2)"></span>
|
||||
<span bm-pe-watch="func(1, 2, 3)"></span>
|
||||
<span bm-pe-watch="row.func()"></span>
|
||||
<span bm-pe-watch="row.func(1)"></span>
|
||||
<span bm-pe-watch="row.func(1, 2)"></span>
|
||||
<span bm-pe-watch="row.func(1, 2, 3)"></span>
|
||||
<span bm-pe-watch="func(func())"></span>
|
||||
<span bm-pe-watch="func(func(), func())"></span>
|
||||
<span bm-pe-watch="row.func(row.func())"></span>
|
||||
<span bm-pe-watch="row.func(row.func(), row.func())"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="objectLiterals" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch-literal="{foo: rowIdx}"></span>
|
||||
<span bm-pe-watch-literal="{foo: row, bar: rowIdx}"></span>
|
||||
<span bm-pe-watch-literal="{0: row, 1: rowIdx, 2: 3}"></span>
|
||||
<span bm-pe-watch-literal="{str: 'foo', num: rowIdx, b: true}"></span>
|
||||
<span bm-pe-watch-literal="{a: {b: {c: {d: {e: {f: rowIdx}}}}}}"></span>
|
||||
<span bm-pe-watch-literal="{a: rowIdx, b: 1, c: 2, d: 3, e: 4, f: 5, g: rowIdx, h: 6, i: 7, j: 8, k: rowIdx}"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="arrayLiterals" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch-literal="[rowIdx]"></span>
|
||||
<span bm-pe-watch-literal="[rowIdx, 0]"></span>
|
||||
<span bm-pe-watch-literal="[rowIdx, 0, 1]"></span>
|
||||
<span bm-pe-watch-literal="[rowIdx, 0, 1, 2]"></span>
|
||||
<span bm-pe-watch-literal="[rowIdx, 0, 1, 2, 3]"></span>
|
||||
<span bm-pe-watch-literal="[[], [rowIdx], [], [], [3], [[[]]]]"></span>
|
||||
<span bm-pe-watch-literal="[rowIdx, undefined, null, true, false]"></span>
|
||||
<span bm-pe-watch-literal="[[][0], [0][0], [][rowIdx]]"></span>
|
||||
<span bm-pe-watch-literal="[0, rowIdx]"></span>
|
||||
<span bm-pe-watch-literal="[0, 1, rowIdx]"></span>
|
||||
<span bm-pe-watch-literal="[0, 1, 2, rowIdx]"></span>
|
||||
<span bm-pe-watch-literal="[0, 1, 2, 3, rowIdx]"></span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
+7
-3
@@ -1,8 +1,12 @@
|
||||
{
|
||||
"name": "AngularJS",
|
||||
"devDependencies": {
|
||||
"jquery": "2.1.1",
|
||||
"closure-compiler": "https://dl.google.com/closure-compiler/compiler-20140814.zip",
|
||||
"ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.2.3/assets/ng-closure-runner.zip"
|
||||
"jquery": "1.10.2",
|
||||
"lunr.js": "0.4.3",
|
||||
"open-sans-fontface": "1.0.4",
|
||||
"google-code-prettify": "1.0.1",
|
||||
"closure-compiler": "https://closure-compiler.googlecode.com/files/compiler-20130603.zip",
|
||||
"ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.2.3/assets/ng-closure-runner.zip",
|
||||
"bootstrap": "3.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
+3
-6
@@ -3,8 +3,6 @@
|
||||
// TODO(vojta): pre-commit hook for validating messages
|
||||
// TODO(vojta): report errors, currently Q silence everything which really sucks
|
||||
|
||||
'use strict';
|
||||
|
||||
var child = require('child_process');
|
||||
var fs = require('fs');
|
||||
var util = require('util');
|
||||
@@ -112,7 +110,7 @@ var printSection = function(stream, title, section, printCommitLinks) {
|
||||
}
|
||||
stream.write(')\n');
|
||||
} else {
|
||||
stream.write(util.format('%s %s\n', prefix, commit.subject));
|
||||
stream.write(util.format('%s %s', prefix, commit.subject));
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -166,7 +164,7 @@ var writeChangelog = function(stream, commits, version) {
|
||||
hash: commit.hash,
|
||||
closes: []
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
stream.write(util.format(HEADER_TPL, version, version, currentDate()));
|
||||
@@ -174,7 +172,7 @@ var writeChangelog = function(stream, commits, version) {
|
||||
printSection(stream, 'Features', sections.feat);
|
||||
printSection(stream, 'Performance Improvements', sections.perf);
|
||||
printSection(stream, 'Breaking Changes', sections.breaks, false);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
var getPreviousTag = function() {
|
||||
@@ -188,7 +186,6 @@ var getPreviousTag = function() {
|
||||
|
||||
|
||||
var generate = function(version, file) {
|
||||
|
||||
getPreviousTag().then(function(tag) {
|
||||
console.log('Reading git log since', tag);
|
||||
readGitLog('^fix|^feat|^perf|BREAKING', tag).then(function(commits) {
|
||||
|
||||
+1
-5
@@ -1,7 +1,3 @@
|
||||
/* global describe: false, it: false, expect: false */
|
||||
|
||||
'use strict';
|
||||
|
||||
describe('changelog.js', function() {
|
||||
var ch = require('./changelog');
|
||||
|
||||
@@ -17,7 +13,7 @@ describe('changelog.js', function() {
|
||||
expect(msg.hash).toBe('9b1aff905b638aa274a5fc8f88662df446d374bd');
|
||||
expect(msg.subject).toBe('broadcast $destroy event on scope destruction');
|
||||
expect(msg.body).toBe('perf testing shows that in chrome this change adds 5-15% overhead\n' +
|
||||
'when destroying 10k nested scopes where each scope has a $destroy listener\n');
|
||||
'when destroying 10k nested scopes where each scope has a $destroy listener\n')
|
||||
expect(msg.component).toBe('scope');
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
#!/usr/local/bin/node
|
||||
|
||||
var util = require('util');
|
||||
var cp = require('child_process');
|
||||
@@ -123,12 +121,9 @@ then(function (tags) {
|
||||
value();
|
||||
}).
|
||||
then(function (tags) {
|
||||
var master = tags.pop();
|
||||
var stable = tags.pop();
|
||||
|
||||
return [
|
||||
{ name: stable.replace(/\d+$/, 'x'), tag: stable },
|
||||
{ name: 'master', tag: master}
|
||||
{ name: 'v1.0.x', tag: tags[0] },
|
||||
{ name: 'master', tag: tags[1] }
|
||||
];
|
||||
}).
|
||||
then(allInSeries(function (branch) {
|
||||
@@ -145,10 +140,10 @@ then(allInSeries(function (branch) {
|
||||
line = line.split(' ');
|
||||
var sha = line.shift();
|
||||
var msg = line.join(' ');
|
||||
return sha + ((/fix\([^\)]+\):/i.test(msg)) ? ' * ' : ' ') + msg;
|
||||
return sha + (msg.toLowerCase().indexOf('fix') === -1 ? ' ' : ' * ') + msg;
|
||||
});
|
||||
branch.log = log.map(function (line) {
|
||||
return line.substr(41);
|
||||
return line.substr(41)
|
||||
});
|
||||
return branch;
|
||||
});
|
||||
|
||||
+12
-1
@@ -2,10 +2,21 @@
|
||||
|
||||
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],
|
||||
.ng-cloak, .x-ng-cloak,
|
||||
.ng-hide:not(.ng-hide-animate) {
|
||||
.ng-hide {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
ng\:form {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ng-animate-block-transitions {
|
||||
transition:0s all!important;
|
||||
-webkit-transition:0s all!important;
|
||||
}
|
||||
|
||||
/* show the element during a show/hide animation when the
|
||||
* animation is ongoing, but the .ng-hide class is active */
|
||||
.ng-hide-add-active, .ng-hide-remove {
|
||||
display: block!important;
|
||||
}
|
||||
|
||||
@@ -211,10 +211,6 @@ code.highlighted {
|
||||
color:maroon;
|
||||
}
|
||||
|
||||
ul + p {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.docs-version-jump {
|
||||
min-width:100%;
|
||||
max-width:100%;
|
||||
@@ -316,10 +312,10 @@ iframe.example {
|
||||
}
|
||||
|
||||
.search-results-group.col-group-api { width:30%; }
|
||||
.search-results-group.col-group-guide,
|
||||
.search-results-group.col-group-tutorial { width:20%; }
|
||||
.search-results-group.col-group-guide { width:30%; }
|
||||
.search-results-group.col-group-tutorial { width:25%; }
|
||||
.search-results-group.col-group-misc,
|
||||
.search-results-group.col-group-error { width:15%; float: right; }
|
||||
.search-results-group.col-group-error { float:right; clear:both; width:15% }
|
||||
|
||||
|
||||
.search-results-group.col-group-api .search-result {
|
||||
@@ -391,6 +387,7 @@ iframe.example {
|
||||
position:fixed;
|
||||
top:120px;
|
||||
bottom:0;
|
||||
padding-bottom:120px;
|
||||
overflow:auto;
|
||||
}
|
||||
|
||||
@@ -411,7 +408,6 @@ iframe.example {
|
||||
|
||||
.main-body-grid .side-navigation {
|
||||
position:relative;
|
||||
padding-bottom:120px;
|
||||
}
|
||||
|
||||
.main-body-grid .side-navigation.ng-hide {
|
||||
@@ -635,14 +631,12 @@ ul.events > li {
|
||||
display:inline-block;
|
||||
padding:3px 0;
|
||||
}
|
||||
.nav-index-group .nav-index-listing:not(.nav-index-section):after {
|
||||
padding-right:5px;
|
||||
margin-left:-3px;
|
||||
content:", ";
|
||||
.nav-index-group .nav-index-listing:not(.nav-index-section) + .nav-index-listing:not(.nav-index-section):after {
|
||||
padding-right:5px;
|
||||
content:", ";
|
||||
}
|
||||
.nav-index-group .nav-index-listing:last-child:after {
|
||||
.nav-index-group .nav-index-listing:last-child {
|
||||
content:"";
|
||||
display:inline-block;
|
||||
}
|
||||
.nav-index-group .nav-index-section {
|
||||
display:block;
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.lang-text * {
|
||||
color: #333333!important;
|
||||
}
|
||||
|
||||
.pln {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ pre.prettyprint.linenums {
|
||||
}
|
||||
ol.linenums {
|
||||
margin: 0 0 0 33px; /* IE indents via margin-left */
|
||||
}
|
||||
}
|
||||
ol.linenums li {
|
||||
padding-left: 12px;
|
||||
font-size:12px;
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
'use strict';
|
||||
|
||||
var directive = {};
|
||||
var service = { value: {} };
|
||||
|
||||
var DEPENDENCIES = {
|
||||
'angular.js': 'http://code.angularjs.org/' + angular.version.full + '/angular.min.js',
|
||||
'angular-resource.js': 'http://code.angularjs.org/' + angular.version.full + '/angular-resource.min.js',
|
||||
'angular-route.js': 'http://code.angularjs.org/' + angular.version.full + '/angular-route.min.js',
|
||||
'angular-animate.js': 'http://code.angularjs.org/' + angular.version.full + '/angular-animate.min.js',
|
||||
'angular-sanitize.js': 'http://code.angularjs.org/' + angular.version.full + '/angular-sanitize.min.js',
|
||||
'angular-cookies.js': 'http://code.angularjs.org/' + angular.version.full + '/angular-cookies.min.js'
|
||||
};
|
||||
|
||||
|
||||
function escape(text) {
|
||||
return text.
|
||||
replace(/\&/g, '&').
|
||||
replace(/\</g, '<').
|
||||
replace(/\>/g, '>').
|
||||
replace(/"/g, '"');
|
||||
}
|
||||
|
||||
/**
|
||||
* http://stackoverflow.com/questions/451486/pre-tag-loses-line-breaks-when-setting-innerhtml-in-ie
|
||||
* http://stackoverflow.com/questions/195363/inserting-a-newline-into-a-pre-tag-ie-javascript
|
||||
*/
|
||||
function setHtmlIe8SafeWay(element, html) {
|
||||
var newElement = angular.element('<pre>' + html + '</pre>');
|
||||
|
||||
element.empty();
|
||||
element.append(newElement.contents());
|
||||
return element;
|
||||
}
|
||||
|
||||
|
||||
directive.jsFiddle = function(getEmbeddedTemplate, escape, script) {
|
||||
return {
|
||||
terminal: true,
|
||||
link: function(scope, element, attr) {
|
||||
var name = '',
|
||||
stylesheet = '<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">\n',
|
||||
fields = {
|
||||
html: '',
|
||||
css: '',
|
||||
js: ''
|
||||
};
|
||||
|
||||
angular.forEach(attr.jsFiddle.split(' '), function(file, index) {
|
||||
var fileType = file.split('.')[1];
|
||||
|
||||
if (fileType == 'html') {
|
||||
if (index == 0) {
|
||||
fields[fileType] +=
|
||||
'<div ng-app' + (attr.module ? '="' + attr.module + '"' : '') + '>\n' +
|
||||
getEmbeddedTemplate(file, 2);
|
||||
} else {
|
||||
fields[fileType] += '\n\n\n <!-- CACHE FILE: ' + file + ' -->\n' +
|
||||
' <script type="text/ng-template" id="' + file + '">\n' +
|
||||
getEmbeddedTemplate(file, 4) +
|
||||
' </script>\n';
|
||||
}
|
||||
} else {
|
||||
fields[fileType] += getEmbeddedTemplate(file) + '\n';
|
||||
}
|
||||
});
|
||||
|
||||
fields.html += '</div>\n';
|
||||
|
||||
setHtmlIe8SafeWay(element,
|
||||
'<form class="jsfiddle" method="post" action="http://jsfiddle.net/api/post/library/pure/" target="_blank">' +
|
||||
hiddenField('title', 'AngularJS Example: ' + name) +
|
||||
hiddenField('css', '</style> <!-- Ugly Hack due to jsFiddle issue: http://goo.gl/BUfGZ --> \n' +
|
||||
stylesheet +
|
||||
script.angular +
|
||||
(attr.resource ? script.resource : '') +
|
||||
'<style>\n' +
|
||||
fields.css) +
|
||||
hiddenField('html', fields.html) +
|
||||
hiddenField('js', fields.js) +
|
||||
'<button class="btn btn-primary"><i class="icon-white icon-pencil"></i> Edit Me</button>' +
|
||||
'</form>');
|
||||
|
||||
function hiddenField(name, value) {
|
||||
return '<input type="hidden" name="' + name + '" value="' + escape(value) + '">';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
directive.ngSetText = ['getEmbeddedTemplate', function(getEmbeddedTemplate) {
|
||||
return {
|
||||
restrict: 'CA',
|
||||
priority: 10,
|
||||
compile: function(element, attr) {
|
||||
setHtmlIe8SafeWay(element, escape(getEmbeddedTemplate(attr.ngSetText)));
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
||||
|
||||
directive.ngHtmlWrap = ['reindentCode', 'templateMerge', function(reindentCode, templateMerge) {
|
||||
return {
|
||||
compile: function(element, attr) {
|
||||
var properties = {
|
||||
head: '',
|
||||
module: '',
|
||||
body: element.text()
|
||||
},
|
||||
html = "<!doctype html>\n<html ng-app{{module}}>\n <head>\n{{head:4}} </head>\n <body>\n{{body:4}} </body>\n</html>";
|
||||
|
||||
angular.forEach((attr.ngHtmlWrap || '').split(' '), function(dep) {
|
||||
if (!dep) return;
|
||||
dep = DEPENDENCIES[dep] || dep;
|
||||
|
||||
var ext = dep.split(/\./).pop();
|
||||
|
||||
if (ext == 'css') {
|
||||
properties.head += '<link rel="stylesheet" href="' + dep + '" type="text/css">\n';
|
||||
} else if(ext == 'js') {
|
||||
properties.head += '<script src="' + dep + '"></script>\n';
|
||||
} else {
|
||||
properties.module = '="' + dep + '"';
|
||||
}
|
||||
});
|
||||
|
||||
setHtmlIe8SafeWay(element, escape(templateMerge(html, properties)));
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
|
||||
directive.ngSetHtml = ['getEmbeddedTemplate', function(getEmbeddedTemplate) {
|
||||
return {
|
||||
restrict: 'CA',
|
||||
priority: 10,
|
||||
compile: function(element, attr) {
|
||||
setHtmlIe8SafeWay(element, getEmbeddedTemplate(attr.ngSetHtml));
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
|
||||
directive.ngEvalJavascript = ['getEmbeddedTemplate', function(getEmbeddedTemplate) {
|
||||
return {
|
||||
compile: function (element, attr) {
|
||||
var fileNames = attr.ngEvalJavascript.split(' ');
|
||||
angular.forEach(fileNames, function(fileName) {
|
||||
var script = getEmbeddedTemplate(fileName);
|
||||
try {
|
||||
if (window.execScript) { // IE
|
||||
window.execScript(script || '""'); // IE complains when evaling empty string
|
||||
} else {
|
||||
window.eval(script + '//@ sourceURL=' + fileName);
|
||||
}
|
||||
} catch (e) {
|
||||
if (window.console) {
|
||||
window.console.log(script, '\n', e);
|
||||
} else {
|
||||
window.alert(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}];
|
||||
|
||||
|
||||
directive.ngEmbedApp = ['$templateCache', '$browser', '$rootScope', '$location', '$sniffer', '$animate',
|
||||
function($templateCache, $browser, docsRootScope, $location, $sniffer, $animate) {
|
||||
return {
|
||||
terminal: true,
|
||||
link: function(scope, element, attrs) {
|
||||
var modules = ['ngAnimate'],
|
||||
embedRootScope,
|
||||
deregisterEmbedRootScope;
|
||||
|
||||
modules.push(['$provide', function($provide) {
|
||||
$provide.value('$templateCache', $templateCache);
|
||||
$provide.value('$anchorScroll', angular.noop);
|
||||
$provide.value('$browser', $browser);
|
||||
$provide.value('$sniffer', $sniffer);
|
||||
$provide.value('$animate', $animate);
|
||||
$provide.provider('$location', function() {
|
||||
this.$get = ['$rootScope', function($rootScope) {
|
||||
docsRootScope.$on('$locationChangeSuccess', function(event, oldUrl, newUrl) {
|
||||
$rootScope.$broadcast('$locationChangeSuccess', oldUrl, newUrl);
|
||||
});
|
||||
return $location;
|
||||
}];
|
||||
this.html5Mode = angular.noop;
|
||||
});
|
||||
|
||||
$provide.decorator('$rootScope', ['$delegate', function($delegate) {
|
||||
embedRootScope = $delegate;
|
||||
|
||||
// Since we are teleporting the $animate service, which relies on the $$postDigestQueue
|
||||
// we need the embedded scope to use the same $$postDigestQueue as the outer scope
|
||||
embedRootScope.$$postDigestQueue = docsRootScope.$$postDigestQueue;
|
||||
|
||||
deregisterEmbedRootScope = docsRootScope.$watch(function embedRootScopeDigestWatch() {
|
||||
embedRootScope.$digest();
|
||||
});
|
||||
|
||||
return embedRootScope;
|
||||
}]);
|
||||
}]);
|
||||
if (attrs.ngEmbedApp) modules.push(attrs.ngEmbedApp);
|
||||
|
||||
element.on('click', function(event) {
|
||||
if (event.target.attributes.getNamedItem('ng-click')) {
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
element.bind('$destroy', function() {
|
||||
deregisterEmbedRootScope();
|
||||
embedRootScope.$destroy();
|
||||
});
|
||||
|
||||
element.data('$injector', null);
|
||||
angular.bootstrap(element, modules);
|
||||
}
|
||||
};
|
||||
}];
|
||||
|
||||
service.reindentCode = function() {
|
||||
return function (text, spaces) {
|
||||
if (!text) return text;
|
||||
var lines = text.split(/\r?\n/);
|
||||
var prefix = ' '.substr(0, spaces || 0);
|
||||
var i;
|
||||
|
||||
// remove any leading blank lines
|
||||
while (lines.length && lines[0].match(/^\s*$/)) lines.shift();
|
||||
// remove any trailing blank lines
|
||||
while (lines.length && lines[lines.length - 1].match(/^\s*$/)) lines.pop();
|
||||
var minIndent = 999;
|
||||
for (i = 0; i < lines.length; i++) {
|
||||
var line = lines[0];
|
||||
var reindentCode = line.match(/^\s*/)[0];
|
||||
if (reindentCode !== line && reindentCode.length < minIndent) {
|
||||
minIndent = reindentCode.length;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < lines.length; i++) {
|
||||
lines[i] = prefix + lines[i].substring(minIndent);
|
||||
}
|
||||
lines.push('');
|
||||
return lines.join('\n');
|
||||
}
|
||||
};
|
||||
|
||||
service.templateMerge = ['reindentCode', function(indentCode) {
|
||||
return function(template, properties) {
|
||||
return template.replace(/\{\{(\w+)(?:\:(\d+))?\}\}/g, function(_, key, indent) {
|
||||
var value = properties[key];
|
||||
|
||||
if (indent) {
|
||||
value = indentCode(value, indent);
|
||||
}
|
||||
|
||||
return value == undefined ? '' : value;
|
||||
});
|
||||
};
|
||||
}];
|
||||
|
||||
service.getEmbeddedTemplate = ['reindentCode', function(reindentCode) {
|
||||
return function (id) {
|
||||
var element = document.getElementById(id);
|
||||
|
||||
if (!element) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return reindentCode(angular.element(element).html(), 0);
|
||||
}
|
||||
}];
|
||||
|
||||
|
||||
angular.module('bootstrapPrettify', []).directive(directive).factory(service);
|
||||
+7
-7
@@ -11,7 +11,7 @@ directive.runnableExample = ['$templateCache', '$document', function($templateCa
|
||||
'ng-repeat="tab in tabs track by $index" ' +
|
||||
'href="" ' +
|
||||
'class="btn"' +
|
||||
'ng-click="setTab($index)">' +
|
||||
'ng-click="setTab($index)">' +
|
||||
' {{ tab }}' +
|
||||
' </a>' +
|
||||
'</nav>';
|
||||
@@ -103,7 +103,7 @@ directive.syntax = function() {
|
||||
restrict: 'A',
|
||||
link: function(scope, element, attrs) {
|
||||
function makeLink(type, text, link, icon) {
|
||||
return '<a href="' + link + '" class="btn syntax-' + type + '" target="_blank" rel="nofollow">' +
|
||||
return '<a href="' + link + '" class="btn syntax-' + type + '" target="_blank" rel="nofollow">' +
|
||||
'<span class="' + icon + '"></span> ' + text +
|
||||
'</a>';
|
||||
};
|
||||
@@ -274,13 +274,13 @@ var popoverElement = function() {
|
||||
this.contentElement = angular.element(inner.childNodes[1]);
|
||||
|
||||
//stop the click on the tooltip
|
||||
this.element.on('click', function(event) {
|
||||
this.element.bind('click', function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
var self = this;
|
||||
angular.element(document.body).on('click',function(event) {
|
||||
angular.element(document.body).bind('click',function(event) {
|
||||
if(self.visible()) self.hide();
|
||||
});
|
||||
},
|
||||
@@ -307,7 +307,7 @@ var popoverElement = function() {
|
||||
return this.titleElement.html(value);
|
||||
},
|
||||
|
||||
content : function(value) {
|
||||
content : function(value) {
|
||||
if(value && value.length > 0) {
|
||||
value = marked(value);
|
||||
}
|
||||
@@ -359,7 +359,7 @@ directive.popover = ['popoverElement', function(popover) {
|
||||
restrict: 'A',
|
||||
priority : 500,
|
||||
link: function(scope, element, attrs) {
|
||||
element.on('click',function(event) {
|
||||
element.bind('click',function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if(popover.isSituatedAt(element) && popover.visible()) {
|
||||
@@ -396,7 +396,7 @@ directive.foldout = ['$http', '$animate','$window', function($http, $animate, $w
|
||||
if(/\/build\//.test($window.location.href)) {
|
||||
url = '/build/docs' + url;
|
||||
}
|
||||
element.on('click',function() {
|
||||
element.bind('click',function() {
|
||||
scope.$apply(function() {
|
||||
if(!container) {
|
||||
if(loading) return;
|
||||
|
||||
+5
-5
@@ -35,8 +35,8 @@ angular.module('ui.bootstrap.dropdown', [])
|
||||
|
||||
this.open = function( dropdownScope ) {
|
||||
if ( !openScope ) {
|
||||
$document.on('click', closeDropdown);
|
||||
$document.on('keydown', escapeKeyBind);
|
||||
$document.bind('click', closeDropdown);
|
||||
$document.bind('keydown', escapeKeyBind);
|
||||
}
|
||||
|
||||
if ( openScope && openScope !== dropdownScope ) {
|
||||
@@ -49,8 +49,8 @@ angular.module('ui.bootstrap.dropdown', [])
|
||||
this.close = function( dropdownScope ) {
|
||||
if ( openScope === dropdownScope ) {
|
||||
openScope = null;
|
||||
$document.off('click', closeDropdown);
|
||||
$document.off('keydown', escapeKeyBind);
|
||||
$document.unbind('click', closeDropdown);
|
||||
$document.unbind('keydown', escapeKeyBind);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -124,7 +124,7 @@ angular.module('ui.bootstrap.dropdown', [])
|
||||
return;
|
||||
}
|
||||
|
||||
element.on('click', function(event) {
|
||||
element.bind('click', function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
"use strict";
|
||||
/* jshint browser: true */
|
||||
/* global importScripts, onmessage: true, postMessage, lunr */
|
||||
|
||||
// Load up the lunr library
|
||||
importScripts('../components/lunr.js-0.4.2/lunr.min.js');
|
||||
|
||||
// Create the lunr index - the docs should be an array of object, each object containing
|
||||
// the path and search terms for a page
|
||||
var index = lunr(function() {
|
||||
this.ref('path');
|
||||
this.field('titleWords', {boost: 50});
|
||||
this.field('members', { boost: 40});
|
||||
this.field('keywords', { boost : 20 });
|
||||
});
|
||||
|
||||
// Retrieve the searchData which contains the information about each page to be indexed
|
||||
var searchData = {};
|
||||
var searchDataRequest = new XMLHttpRequest();
|
||||
searchDataRequest.onload = function() {
|
||||
|
||||
// Store the pages data to be used in mapping query results back to pages
|
||||
searchData = JSON.parse(this.responseText);
|
||||
// Add search terms from each page to the search index
|
||||
searchData.forEach(function(page) {
|
||||
index.add(page);
|
||||
});
|
||||
postMessage({ e: 'index-ready' });
|
||||
};
|
||||
searchDataRequest.open('GET', 'search-data.json');
|
||||
searchDataRequest.send();
|
||||
|
||||
// The worker receives a message everytime the web app wants to query the index
|
||||
onmessage = function(oEvent) {
|
||||
var q = oEvent.data.q;
|
||||
var hits = index.search(q);
|
||||
var results = [];
|
||||
// Only return the array of paths to pages
|
||||
hits.forEach(function(hit) {
|
||||
results.push(hit.ref);
|
||||
});
|
||||
// The results of the query are sent back to the web app via a new message
|
||||
postMessage({ e: 'query-ready', q: q, d: results });
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
{
|
||||
"extends": "../../../.jshintrc-base",
|
||||
|
||||
"globals": {
|
||||
|
||||
/* jasmine / karma */
|
||||
"it": false,
|
||||
"iit": false,
|
||||
"describe": false,
|
||||
"ddescribe": false,
|
||||
"beforeEach": false,
|
||||
"afterEach": false,
|
||||
"expect": false,
|
||||
"jasmine": false,
|
||||
"spyOn": false,
|
||||
"waits": false,
|
||||
"waitsFor": false,
|
||||
"runs": false,
|
||||
"dump": false,
|
||||
|
||||
/* e2e */
|
||||
"browser": false,
|
||||
"element": false,
|
||||
"by": false,
|
||||
|
||||
/* testabilityPatch / matchers */
|
||||
"inject": false,
|
||||
"module": false,
|
||||
"dealoc": false,
|
||||
"_jQuery": false,
|
||||
"_jqLiteMode": false,
|
||||
"sortedHtml": false,
|
||||
"childrenTagsOf": false,
|
||||
"assertHidden": false,
|
||||
"assertVisible": false,
|
||||
"provideLog": false,
|
||||
"spyOnlyCallsWithArgs": false,
|
||||
"createMockStyleSheet": false,
|
||||
"browserTrigger": false,
|
||||
"jqLiteCacheSize": false
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe("doc.angularjs.org", function() {
|
||||
|
||||
describe("API pages", function() {
|
||||
|
||||
it("should display links to code on GitHub", function() {
|
||||
browser.get('index-debug.html#!/api/ng/service/$http');
|
||||
expect(element(by.css('.improve-docs')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/edit\/.+\/src\/ng\/http\.js/);
|
||||
|
||||
browser.get('index-debug.html#!/api/ng/service/$http');
|
||||
expect(element(by.css('.view-source')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/tree\/.+\/src\/ng\/http\.js#L\d+/);
|
||||
});
|
||||
|
||||
it('should change the page content when clicking a link to a service', function () {
|
||||
browser.get('');
|
||||
|
||||
var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]'));
|
||||
ngBindLink.click();
|
||||
|
||||
var pageBody = element(by.css('h1'));
|
||||
expect(pageBody.getText()).toEqual('ngClick');
|
||||
});
|
||||
|
||||
|
||||
it('should show the functioning input directive example', function () {
|
||||
browser.get('index-debug.html#!/api/ng/directive/input');
|
||||
|
||||
// Ensure that the page is loaded before trying to switch frames.
|
||||
browser.waitForAngular();
|
||||
|
||||
browser.switchTo().frame('example-input-directive');
|
||||
|
||||
var nameInput = element(by.model('user.name'));
|
||||
nameInput.sendKeys('!!!');
|
||||
|
||||
var code = element.all(by.css('tt')).first();
|
||||
expect(code.getText()).toContain('guest!!!');
|
||||
});
|
||||
|
||||
it("should trim indentation from code blocks", function() {
|
||||
browser.get('index-debug.html#!/api/ng/type/$rootScope.Scope');
|
||||
|
||||
var codeBlocks = element.all(by.css('pre > code.lang-js'));
|
||||
codeBlocks.each(function(codeBlock) {
|
||||
var firstSpan = codeBlock.all(by.css('span')).first();
|
||||
expect(firstSpan.getText()).not.toMatch(/^\W+$/);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,12 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe("provider pages", function() {
|
||||
|
||||
it("should show the related service", function() {
|
||||
browser.get('index-debug.html#!/api/ng/provider/$compileProvider');
|
||||
var serviceLink = element.all(by.css('ol.api-profile-header-structure li a')).first();
|
||||
expect(serviceLink.getText()).toEqual('- $compile');
|
||||
expect(serviceLink.getAttribute('href')).toMatch(/api\/ng\/service\/\$compile/);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,22 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe("service pages", function() {
|
||||
|
||||
it("should show the related provider if there is one", function() {
|
||||
browser.get('index-debug.html#!/api/ng/service/$compile');
|
||||
var providerLink = element.all(by.css('ol.api-profile-header-structure li a')).first();
|
||||
expect(providerLink.getText()).toEqual('- $compileProvider');
|
||||
expect(providerLink.getAttribute('href')).toMatch(/api\/ng\/provider\/\$compileProvider/);
|
||||
|
||||
browser.get('index-debug.html#!/api/ng/service/$q');
|
||||
providerLink = element.all(by.css('ol.api-profile-header-structure li a')).first();
|
||||
expect(providerLink.getText()).not.toEqual('- $qProvider');
|
||||
expect(providerLink.getAttribute('href')).not.toMatch(/api\/ng\/provider\/\$compileProvider/);
|
||||
});
|
||||
|
||||
it("should show parameter defaults", function() {
|
||||
browser.get('index-debug.html#!/api/ng/service/$timeout');
|
||||
expect(element.all(by.css('.input-arguments p em')).first().getText()).toContain('(default: 0)');
|
||||
});
|
||||
|
||||
});
|
||||
+4
-3
@@ -6,7 +6,6 @@ angular.module('docsApp', [
|
||||
'DocsController',
|
||||
'versionsData',
|
||||
'pagesData',
|
||||
'navData',
|
||||
'directives',
|
||||
'errors',
|
||||
'examples',
|
||||
@@ -14,9 +13,11 @@ angular.module('docsApp', [
|
||||
'tutorials',
|
||||
'versions',
|
||||
'bootstrap',
|
||||
'bootstrapPrettify',
|
||||
'ui.bootstrap.dropdown'
|
||||
])
|
||||
|
||||
.config(['$locationProvider', function($locationProvider) {
|
||||
|
||||
.config(function($locationProvider) {
|
||||
$locationProvider.html5Mode(true).hashPrefix('!');
|
||||
}]);
|
||||
});
|
||||
@@ -22,16 +22,11 @@ angular.module('directives', [])
|
||||
terminal: true,
|
||||
compile: function(element) {
|
||||
var linenums = element.hasClass('linenum');// || element.parent()[0].nodeName === 'PRE';
|
||||
var match = /lang-(\S+)/.exec(element[0].className);
|
||||
var match = /lang-(\S)+/.exec(element.className);
|
||||
var lang = match && match[1];
|
||||
var html = element.html();
|
||||
element.html(window.prettyPrintOne(html, lang, linenums));
|
||||
}
|
||||
};
|
||||
})
|
||||
});
|
||||
|
||||
.directive('scrollYOffsetElement', ['$anchorScroll', function($anchorScroll) {
|
||||
return function(scope, element) {
|
||||
$anchorScroll.yOffset = element;
|
||||
};
|
||||
}]);
|
||||
|
||||
+75
-10
@@ -6,33 +6,87 @@ angular.module('DocsController', [])
|
||||
function($scope, $rootScope, $location, $window, $cookies, openPlunkr,
|
||||
NG_PAGES, NG_NAVIGATION, NG_VERSION) {
|
||||
|
||||
|
||||
$scope.openPlunkr = openPlunkr;
|
||||
|
||||
$scope.docsVersion = NG_VERSION.isSnapshot ? 'snapshot' : NG_VERSION.version;
|
||||
|
||||
$scope.fold = function(url) {
|
||||
if(url) {
|
||||
$scope.docs_fold = '/notes/' + url;
|
||||
if(/\/build/.test($window.location.href)) {
|
||||
$scope.docs_fold = '/build/docs' + $scope.docs_fold;
|
||||
}
|
||||
window.scrollTo(0,0);
|
||||
}
|
||||
else {
|
||||
$scope.docs_fold = null;
|
||||
}
|
||||
};
|
||||
var OFFLINE_COOKIE_NAME = 'ng-offline',
|
||||
INDEX_PATH = /^(\/|\/index[^\.]*.html)$/;
|
||||
|
||||
|
||||
/**********************************
|
||||
Publish methods
|
||||
***********************************/
|
||||
|
||||
$scope.navClass = function(navItem) {
|
||||
return {
|
||||
active: navItem.href && this.currentPage && this.currentPage.path,
|
||||
active: navItem.href && this.currentPage.path,
|
||||
'nav-index-section': navItem.type === 'section'
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
$scope.$on('$includeContentLoaded', function() {
|
||||
$scope.afterPartialLoaded = function() {
|
||||
var pagePath = $scope.currentPage ? $scope.currentPage.path : $location.path();
|
||||
$window._gaq.push(['_trackPageview', pagePath]);
|
||||
});
|
||||
};
|
||||
|
||||
/** stores a cookie that is used by apache to decide which manifest ot send */
|
||||
$scope.enableOffline = function() {
|
||||
//The cookie will be good for one year!
|
||||
var date = new Date();
|
||||
date.setTime(date.getTime()+(365*24*60*60*1000));
|
||||
var expires = "; expires="+date.toGMTString();
|
||||
var value = angular.version.full;
|
||||
document.cookie = OFFLINE_COOKIE_NAME + "="+value+expires+"; path=" + $location.path;
|
||||
|
||||
//force the page to reload so server can serve new manifest file
|
||||
window.location.reload(true);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**********************************
|
||||
Watches
|
||||
***********************************/
|
||||
|
||||
|
||||
$scope.$watch(function docsPathWatch() {return $location.path(); }, function docsPathWatchAction(path) {
|
||||
|
||||
path = path.replace(/^\/?(.+?)(\/index)?\/?$/, '$1');
|
||||
var currentPage = $scope.currentPage = NG_PAGES[path];
|
||||
if ( !currentPage && path.charAt(0)==='/' ) {
|
||||
// Strip off leading slash
|
||||
path = path.substr(1);
|
||||
}
|
||||
|
||||
currentPage = $scope.currentPage = NG_PAGES[path];
|
||||
if ( !currentPage && path.charAt(path.length-1) === '/' && path.length > 1 ) {
|
||||
// Strip off trailing slash
|
||||
path = path.substr(0, path.length-1);
|
||||
}
|
||||
|
||||
currentPage = $scope.currentPage = NG_PAGES[path];
|
||||
if ( !currentPage && /\/index$/.test(path) ) {
|
||||
// Strip off index from the end
|
||||
path = path.substr(0, path.length - 6);
|
||||
}
|
||||
|
||||
currentPage = $scope.currentPage = NG_PAGES[path];
|
||||
|
||||
if ( currentPage ) {
|
||||
$scope.partialPath = 'partials/' + path + '.html';
|
||||
$scope.currentArea = NG_NAVIGATION[currentPage.area];
|
||||
$scope.currentArea = currentPage && NG_NAVIGATION[currentPage.area];
|
||||
var pathParts = currentPage.path.split('/');
|
||||
var breadcrumb = $scope.breadcrumb = [];
|
||||
var breadcrumbPath = '';
|
||||
@@ -44,7 +98,6 @@ angular.module('DocsController', [])
|
||||
} else {
|
||||
$scope.currentArea = NG_NAVIGATION['api'];
|
||||
$scope.breadcrumb = [];
|
||||
$scope.partialPath = 'Error404.html';
|
||||
}
|
||||
});
|
||||
|
||||
@@ -54,12 +107,24 @@ angular.module('DocsController', [])
|
||||
|
||||
$scope.versionNumber = angular.version.full;
|
||||
$scope.version = angular.version.full + " " + angular.version.codeName;
|
||||
$scope.subpage = false;
|
||||
$scope.offlineEnabled = ($cookies[OFFLINE_COOKIE_NAME] == angular.version.full);
|
||||
$scope.futurePartialTitle = null;
|
||||
$scope.loading = 0;
|
||||
$scope.$cookies = $cookies;
|
||||
|
||||
$cookies.platformPreference = $cookies.platformPreference || 'gitUnix';
|
||||
|
||||
var INDEX_PATH = /^(\/|\/index[^\.]*.html)$/;
|
||||
if (!$location.path() || INDEX_PATH.test($location.path())) {
|
||||
$location.path('/api').replace();
|
||||
}
|
||||
|
||||
// bind escape to hash reset callback
|
||||
angular.element(window).on('keydown', function(e) {
|
||||
if (e.keyCode === 27) {
|
||||
$scope.$apply(function() {
|
||||
$scope.subpage = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
}]);
|
||||
|
||||
@@ -59,4 +59,4 @@ angular.module('errors', ['ngSanitize'])
|
||||
element.html(errorLinkFilter(interpolate.apply(null, formatArgs), '_blank'));
|
||||
}
|
||||
};
|
||||
}]);
|
||||
}]);
|
||||
@@ -2,12 +2,7 @@ angular.module('examples', [])
|
||||
|
||||
.factory('formPostData', ['$document', function($document) {
|
||||
return function(url, fields) {
|
||||
/**
|
||||
* Form previously posted to target="_blank", but pop-up blockers were causing this to not work.
|
||||
* If a user chose to bypass pop-up blocker one time and click the link, they would arrive at
|
||||
* a new default plnkr, not a plnkr with the desired template.
|
||||
*/
|
||||
var form = angular.element('<form style="display: none;" method="post" action="' + url + '"></form>');
|
||||
var form = angular.element('<form style="display: none;" method="post" action="' + url + '" target="_blank"></form>');
|
||||
angular.forEach(fields, function(value, name) {
|
||||
var input = angular.element('<input type="hidden" name="' + name + '">');
|
||||
input.attr('value', value);
|
||||
@@ -74,4 +69,4 @@ angular.module('examples', [])
|
||||
formPostData('http://plnkr.co/edit/?p=preview', postData);
|
||||
});
|
||||
};
|
||||
}]);
|
||||
}]);
|
||||
@@ -0,0 +1,24 @@
|
||||
angular.module('docsApp.navigationService', [])
|
||||
|
||||
.factory('navigationService', function($window) {
|
||||
var service = {
|
||||
currentPage: null,
|
||||
currentVersion: null,
|
||||
changePage: function(newPage) {
|
||||
|
||||
},
|
||||
changeVersion: function(newVersion) {
|
||||
|
||||
//TODO =========
|
||||
// var currentPagePath = '';
|
||||
|
||||
// // preserve URL path when switching between doc versions
|
||||
// if (angular.isObject($rootScope.currentPage) && $rootScope.currentPage.section && $rootScope.currentPage.id) {
|
||||
// currentPagePath = '/' + $rootScope.currentPage.section + '/' + $rootScope.currentPage.id;
|
||||
// }
|
||||
|
||||
// $window.location = version.url + currentPagePath;
|
||||
|
||||
}
|
||||
};
|
||||
});
|
||||
+70
-131
@@ -10,35 +10,22 @@ angular.module('search', [])
|
||||
$scope.search = function(q) {
|
||||
var MIN_SEARCH_LENGTH = 2;
|
||||
if(q.length >= MIN_SEARCH_LENGTH) {
|
||||
docsSearch(q).then(function(hits) {
|
||||
var results = {};
|
||||
angular.forEach(hits, function(hit) {
|
||||
var area = hit.area;
|
||||
|
||||
var limit = (area == 'api') ? 40 : 14;
|
||||
results[area] = results[area] || [];
|
||||
if(results[area].length < limit) {
|
||||
results[area].push(hit);
|
||||
}
|
||||
});
|
||||
|
||||
var totalAreas = 0;
|
||||
for(var i in results) {
|
||||
++totalAreas;
|
||||
}
|
||||
if(totalAreas > 0) {
|
||||
$scope.colClassName = 'cols-' + totalAreas;
|
||||
}
|
||||
$scope.hasResults = totalAreas > 0;
|
||||
$scope.results = results;
|
||||
});
|
||||
var results = docsSearch(q);
|
||||
var totalAreas = 0;
|
||||
for(var i in results) {
|
||||
++totalAreas;
|
||||
}
|
||||
if(totalAreas > 0) {
|
||||
$scope.colClassName = 'cols-' + totalAreas;
|
||||
}
|
||||
$scope.hasResults = totalAreas > 0;
|
||||
$scope.results = results;
|
||||
}
|
||||
else {
|
||||
clearResults();
|
||||
}
|
||||
if(!$scope.$$phase) $scope.$apply();
|
||||
};
|
||||
|
||||
$scope.submit = function() {
|
||||
var result;
|
||||
for(var i in $scope.results) {
|
||||
@@ -52,125 +39,77 @@ angular.module('search', [])
|
||||
$scope.hideResults();
|
||||
}
|
||||
};
|
||||
|
||||
$scope.hideResults = function() {
|
||||
clearResults();
|
||||
$scope.q = '';
|
||||
};
|
||||
}])
|
||||
|
||||
|
||||
.controller('Error404SearchCtrl', ['$scope', '$location', 'docsSearch',
|
||||
function($scope, $location, docsSearch) {
|
||||
docsSearch($location.path().split(/[\/\.:]/).pop()).then(function(results) {
|
||||
$scope.results = {};
|
||||
angular.forEach(results, function(result) {
|
||||
var area = $scope.results[result.area] || [];
|
||||
area.push(result);
|
||||
$scope.results[result.area] = area;
|
||||
});
|
||||
});
|
||||
.controller('Error404SearchCtrl', ['$scope', '$location', 'docsSearch', function($scope, $location, docsSearch) {
|
||||
$scope.results = docsSearch($location.path().split(/[\/\.:]/).pop());
|
||||
}])
|
||||
|
||||
.factory('lunrSearch', function() {
|
||||
return function(properties) {
|
||||
if (window.RUNNING_IN_NG_TEST_RUNNER) return null;
|
||||
|
||||
.provider('docsSearch', function() {
|
||||
|
||||
// This version of the service builds the index in the current thread,
|
||||
// which blocks rendering and other browser activities.
|
||||
// It should only be used where the browser does not support WebWorkers
|
||||
function localSearchFactory($http, $timeout, NG_PAGES) {
|
||||
|
||||
console.log('Using Local Search Index');
|
||||
|
||||
// Create the lunr index
|
||||
var index = lunr(function() {
|
||||
this.ref('path');
|
||||
this.field('titleWords', {boost: 50});
|
||||
this.field('members', { boost: 40});
|
||||
this.field('keywords', { boost : 20 });
|
||||
});
|
||||
|
||||
// Delay building the index by loading the data asynchronously
|
||||
var indexReadyPromise = $http.get('js/search-data.json').then(function(response) {
|
||||
var searchData = response.data;
|
||||
// Delay building the index for 500ms to allow the page to render
|
||||
return $timeout(function() {
|
||||
// load the page data into the index
|
||||
angular.forEach(searchData, function(page) {
|
||||
index.add(page);
|
||||
});
|
||||
}, 500);
|
||||
});
|
||||
|
||||
// The actual service is a function that takes a query string and
|
||||
// returns a promise to the search results
|
||||
// (In this case we just resolve the promise immediately as it is not
|
||||
// inherently an async process)
|
||||
return function(q) {
|
||||
return indexReadyPromise.then(function() {
|
||||
var hits = index.search(q);
|
||||
var results = [];
|
||||
angular.forEach(hits, function(hit) {
|
||||
results.push(NG_PAGES[hit.ref]);
|
||||
});
|
||||
return results;
|
||||
});
|
||||
var engine = lunr(properties);
|
||||
return {
|
||||
store : function(values) {
|
||||
engine.add(values);
|
||||
},
|
||||
search : function(q) {
|
||||
return engine.search(q);
|
||||
}
|
||||
};
|
||||
}
|
||||
localSearchFactory.$inject = ['$http', '$timeout', 'NG_PAGES'];
|
||||
|
||||
// This version of the service builds the index in a WebWorker,
|
||||
// which does not block rendering and other browser activities.
|
||||
// It should only be used where the browser does support WebWorkers
|
||||
function webWorkerSearchFactory($q, $rootScope, NG_PAGES) {
|
||||
|
||||
console.log('Using WebWorker Search Index')
|
||||
|
||||
var searchIndex = $q.defer();
|
||||
var results;
|
||||
|
||||
var worker = new Worker('js/search-worker.js');
|
||||
|
||||
// The worker will send us a message in two situations:
|
||||
// - when the index has been built, ready to run a query
|
||||
// - when it has completed a search query and the results are available
|
||||
worker.onmessage = function(oEvent) {
|
||||
$rootScope.$apply(function() {
|
||||
|
||||
switch(oEvent.data.e) {
|
||||
case 'index-ready':
|
||||
searchIndex.resolve();
|
||||
break;
|
||||
case 'query-ready':
|
||||
var pages = oEvent.data.d.map(function(path) {
|
||||
return NG_PAGES[path];
|
||||
});
|
||||
results.resolve(pages);
|
||||
break;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// The actual service is a function that takes a query string and
|
||||
// returns a promise to the search results
|
||||
return function(q) {
|
||||
|
||||
// We only run the query once the index is ready
|
||||
return searchIndex.promise.then(function() {
|
||||
|
||||
results = $q.defer();
|
||||
worker.postMessage({ q: q });
|
||||
return results.promise;
|
||||
});
|
||||
};
|
||||
}
|
||||
webWorkerSearchFactory.$inject = ['$q', '$rootScope', 'NG_PAGES'];
|
||||
|
||||
return {
|
||||
$get: window.Worker ? webWorkerSearchFactory : localSearchFactory
|
||||
};
|
||||
})
|
||||
|
||||
.factory('docsSearch', ['$rootScope','lunrSearch', 'NG_PAGES',
|
||||
function($rootScope, lunrSearch, NG_PAGES) {
|
||||
if (window.RUNNING_IN_NG_TEST_RUNNER) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var index = lunrSearch(function() {
|
||||
this.ref('id');
|
||||
this.field('title', {boost: 50});
|
||||
this.field('keywords', { boost : 20 });
|
||||
});
|
||||
|
||||
angular.forEach(NG_PAGES, function(page, key) {
|
||||
if(page.searchTerms) {
|
||||
index.store({
|
||||
id : key,
|
||||
title : page.searchTerms.titleWords,
|
||||
keywords : page.searchTerms.keywords
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
return function(q) {
|
||||
var results = {
|
||||
api : [],
|
||||
tutorial : [],
|
||||
guide : [],
|
||||
error : [],
|
||||
misc : []
|
||||
};
|
||||
angular.forEach(index.search(q), function(result) {
|
||||
var key = result.ref;
|
||||
var item = NG_PAGES[key];
|
||||
var area = item.area;
|
||||
item.path = key;
|
||||
|
||||
var limit = area == 'api' ? 40 : 14;
|
||||
if(results[area].length < limit) {
|
||||
results[area].push(item);
|
||||
}
|
||||
});
|
||||
return results;
|
||||
};
|
||||
}])
|
||||
|
||||
.directive('focused', function($timeout) {
|
||||
return function(scope, element, attrs) {
|
||||
element[0].focus();
|
||||
@@ -192,7 +131,7 @@ angular.module('search', [])
|
||||
return function(scope, element, attrs) {
|
||||
var ESCAPE_KEY_KEYCODE = 27,
|
||||
FORWARD_SLASH_KEYCODE = 191;
|
||||
angular.element($document[0].body).on('keydown', function(event) {
|
||||
angular.element($document[0].body).bind('keydown', function(event) {
|
||||
var input = element[0];
|
||||
if(event.keyCode == FORWARD_SLASH_KEYCODE && document.activeElement != input) {
|
||||
event.stopPropagation();
|
||||
@@ -201,7 +140,7 @@ angular.module('search', [])
|
||||
}
|
||||
});
|
||||
|
||||
element.on('keydown', function(event) {
|
||||
element.bind('keydown', function(event) {
|
||||
if(event.keyCode == ESCAPE_KEY_KEYCODE) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
+16
-15
@@ -1,6 +1,6 @@
|
||||
angular.module('tutorials', [])
|
||||
|
||||
.directive('docTutorialNav', function() {
|
||||
.directive('docTutorialNav', function(templateMerge) {
|
||||
var pages = [
|
||||
'',
|
||||
'step_00', 'step_01', 'step_02', 'step_03', 'step_04',
|
||||
@@ -8,22 +8,23 @@ angular.module('tutorials', [])
|
||||
'step_10', 'step_11', 'step_12', 'the_end'
|
||||
];
|
||||
return {
|
||||
scope: {},
|
||||
template:
|
||||
'<a ng-href="tutorial/{{prev}}"><li class="btn btn-primary"><i class="glyphicon glyphicon-step-backward"></i> Previous</li></a>\n' +
|
||||
'<a ng-href="http://angular.github.io/angular-phonecat/step-{{seq}}/app"><li class="btn btn-primary"><i class="glyphicon glyphicon-play"></i> Live Demo</li></a>\n' +
|
||||
'<a ng-href="https://github.com/angular/angular-phonecat/compare/step-{{diffLo}}...step-{{diffHi}}"><li class="btn btn-primary"><i class="glyphicon glyphicon-search"></i> Code Diff</li></a>\n' +
|
||||
'<a ng-href="tutorial/{{next}}"><li class="btn btn-primary">Next <i class="glyphicon glyphicon-step-forward"></i></li></a>',
|
||||
link: function(scope, element, attrs) {
|
||||
var seq = 1 * attrs.docTutorialNav;
|
||||
scope.seq = seq;
|
||||
scope.prev = pages[seq];
|
||||
scope.next = pages[2 + seq];
|
||||
scope.diffLo = seq ? (seq - 1): '0~1';
|
||||
scope.diffHi = seq;
|
||||
compile: function(element, attrs) {
|
||||
var seq = 1 * attrs.docTutorialNav,
|
||||
props = {
|
||||
seq: seq,
|
||||
prev: pages[seq],
|
||||
next: pages[2 + seq],
|
||||
diffLo: seq ? (seq - 1): '0~1',
|
||||
diffHi: seq
|
||||
};
|
||||
|
||||
element.addClass('btn-group');
|
||||
element.addClass('tutorial-nav');
|
||||
element.append(templateMerge(
|
||||
'<a href="tutorial/{{prev}}"><li class="btn btn-primary"><i class="glyphicon glyphicon-step-backward"></i> Previous</li></a>\n' +
|
||||
'<a href="http://angular.github.io/angular-phonecat/step-{{seq}}/app"><li class="btn btn-primary"><i class="glyphicon glyphicon-play"></i> Live Demo</li></a>\n' +
|
||||
'<a href="https://github.com/angular/angular-phonecat/compare/step-{{diffLo}}...step-{{diffHi}}"><li class="btn btn-primary"><i class="glyphicon glyphicon-search"></i> Code Diff</li></a>\n' +
|
||||
'<a href="tutorial/{{next}}"><li class="btn btn-primary">Next <i class="glyphicon glyphicon-step-forward"></i></li></a>', props));
|
||||
}
|
||||
};
|
||||
})
|
||||
@@ -46,4 +47,4 @@ angular.module('tutorials', [])
|
||||
'<a ng-href="https://github.com/angular/angular-phonecat/compare/step-{{step ? (step - 1): \'0~1\'}}...step-{{step}}">GitHub</a>\n' +
|
||||
'</p>'
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,29 +1,15 @@
|
||||
angular.module('versions', [])
|
||||
|
||||
.controller('DocsVersionsCtrl', ['$scope', '$location', '$window', 'NG_VERSIONS', function($scope, $location, $window, NG_VERSIONS) {
|
||||
$scope.docs_versions = NG_VERSIONS;
|
||||
$scope.docs_version = NG_VERSIONS[0];
|
||||
|
||||
for(var i=0, minor = NaN; i < NG_VERSIONS.length; i++) {
|
||||
var version = NG_VERSIONS[i];
|
||||
// NaN will give false here
|
||||
if (minor <= version.minor) {
|
||||
continue;
|
||||
}
|
||||
version.isLatest = true;
|
||||
minor = version.minor;
|
||||
}
|
||||
|
||||
$scope.docs_versions = NG_VERSIONS;
|
||||
$scope.getGroupName = function(v) {
|
||||
return v.isLatest ? 'Latest' : (v.isStable ? 'Stable' : 'Unstable');
|
||||
};
|
||||
|
||||
$scope.jumpToDocsVersion = function(version) {
|
||||
var currentPagePath = $location.path().replace(/\/$/, '');
|
||||
var currentPagePath = $location.path();
|
||||
|
||||
// TODO: We need to do some munging of the path for different versions of the API...
|
||||
|
||||
|
||||
|
||||
$window.location = version.docsUrl + currentPagePath;
|
||||
};
|
||||
}]);
|
||||
}]);
|
||||
@@ -1,38 +0,0 @@
|
||||
describe("code", function() {
|
||||
var prettyPrintOne, oldPP;
|
||||
var compile, scope;
|
||||
|
||||
var any = jasmine.any;
|
||||
|
||||
beforeEach(module('directives'));
|
||||
|
||||
beforeEach(inject(function($rootScope, $compile) {
|
||||
// Provide stub for pretty print function
|
||||
oldPP = window.prettyPrintOne;
|
||||
prettyPrintOne = window.prettyPrintOne = jasmine.createSpy();
|
||||
|
||||
scope = $rootScope.$new();
|
||||
compile = $compile;
|
||||
}));
|
||||
|
||||
afterEach(function() {
|
||||
window.prettyPrintOne = oldPP;
|
||||
});
|
||||
|
||||
|
||||
it('should pretty print innerHTML', function() {
|
||||
compile('<code>var x;</code>')(scope);
|
||||
expect(prettyPrintOne).toHaveBeenCalledWith('var x;', null, false);
|
||||
});
|
||||
|
||||
it('should allow language declaration', function() {
|
||||
compile('<code class="lang-javascript"></code>')(scope);
|
||||
expect(prettyPrintOne).toHaveBeenCalledWith(any(String), 'javascript', false);
|
||||
});
|
||||
|
||||
it('supports allow line numbers', function() {
|
||||
compile('<code class="linenum"></code>')(scope);
|
||||
expect(prettyPrintOne).toHaveBeenCalledWith(any(String), null, true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@ describe("DocsController", function() {
|
||||
it("should update the Google Analytics with currentPage path if currentPage exists", inject(function($window) {
|
||||
$window._gaq = [];
|
||||
$scope.currentPage = { path: 'a/b/c' };
|
||||
$scope.$broadcast('$includeContentLoaded');
|
||||
$scope.afterPartialLoaded();
|
||||
expect($window._gaq.pop()).toEqual(['_trackPageview', 'a/b/c']);
|
||||
}));
|
||||
|
||||
@@ -27,8 +27,8 @@ describe("DocsController", function() {
|
||||
it("should update the Google Analytics with $location.path if currentPage is missing", inject(function($window, $location) {
|
||||
$window._gaq = [];
|
||||
spyOn($location, 'path').andReturn('x/y/z');
|
||||
$scope.$broadcast('$includeContentLoaded');
|
||||
$scope.afterPartialLoaded();
|
||||
expect($window._gaq.pop()).toEqual(['_trackPageview', 'x/y/z']);
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "AngularJS-docs-app",
|
||||
"dependencies": {
|
||||
"jquery": "2.1.1",
|
||||
"lunr.js": "0.4.3",
|
||||
"open-sans-fontface": "1.0.4",
|
||||
"google-code-prettify": "1.0.1",
|
||||
"bootstrap": "3.1.1"
|
||||
}
|
||||
}
|
||||
+32
-155
@@ -1,166 +1,43 @@
|
||||
"use strict";
|
||||
|
||||
var _ = require('lodash');
|
||||
var path = require('canonical-path');
|
||||
var packagePath = __dirname;
|
||||
|
||||
var Package = require('dgeni').Package;
|
||||
var basePackage = require('dgeni-packages/ngdoc');
|
||||
var examplesPackage = require('dgeni-packages/examples');
|
||||
|
||||
// Create and export a new Dgeni package called dgeni-example. This package depends upon
|
||||
// the jsdoc and nunjucks packages defined in the dgeni-packages npm module.
|
||||
module.exports = new Package('angularjs', [
|
||||
require('dgeni-packages/ngdoc'),
|
||||
require('dgeni-packages/nunjucks'),
|
||||
require('dgeni-packages/examples')
|
||||
])
|
||||
module.exports = function(config) {
|
||||
|
||||
config = basePackage(config);
|
||||
config = examplesPackage(config);
|
||||
|
||||
config.append('processing.processors', [
|
||||
require('./processors/git-data'),
|
||||
require('./processors/error-docs'),
|
||||
require('./processors/keywords'),
|
||||
require('./processors/versions-data'),
|
||||
require('./processors/pages-data'),
|
||||
require('./processors/protractor-generate'),
|
||||
require('./processors/index-page'),
|
||||
require('./processors/debug-dump')
|
||||
]);
|
||||
|
||||
.factory(require('./services/errorNamespaceMap'))
|
||||
.factory(require('./services/getMinerrInfo'))
|
||||
.factory(require('./services/getVersion'))
|
||||
.factory(require('./services/gitData'))
|
||||
config.append('processing.tagDefinitions', [
|
||||
require('./tag-defs/tutorial-step')
|
||||
]);
|
||||
|
||||
.factory(require('./services/deployments/debug'))
|
||||
.factory(require('./services/deployments/default'))
|
||||
.factory(require('./services/deployments/jquery'))
|
||||
.factory(require('./services/deployments/production'))
|
||||
config.append('processing.defaultTagTransforms', [
|
||||
require('dgeni-packages/jsdoc/tag-defs/transforms/trim-whitespace')
|
||||
]);
|
||||
|
||||
.factory(require('./inline-tag-defs/type'))
|
||||
config.append('processing.inlineTagDefinitions', [
|
||||
require('./inline-tag-defs/type')
|
||||
]);
|
||||
|
||||
config.set('processing.search.ignoreWordsFile', path.resolve(packagePath, 'ignore.words'));
|
||||
|
||||
.processor(require('./processors/error-docs'))
|
||||
.processor(require('./processors/index-page'))
|
||||
.processor(require('./processors/keywords'))
|
||||
.processor(require('./processors/pages-data'))
|
||||
.processor(require('./processors/versions-data'))
|
||||
config.prepend('rendering.templateFolders', [
|
||||
path.resolve(packagePath, 'templates')
|
||||
]);
|
||||
|
||||
|
||||
.config(function(dgeni, log, readFilesProcessor, writeFilesProcessor) {
|
||||
|
||||
dgeni.stopOnValidationError = true;
|
||||
dgeni.stopOnProcessingError = true;
|
||||
|
||||
log.level = 'info';
|
||||
|
||||
readFilesProcessor.basePath = path.resolve(__dirname,'../..');
|
||||
readFilesProcessor.sourceFiles = [
|
||||
{ include: 'src/**/*.js', basePath: 'src' },
|
||||
{ include: 'docs/content/**/*.ngdoc', basePath: 'docs/content' }
|
||||
];
|
||||
|
||||
writeFilesProcessor.outputFolder = 'build/docs';
|
||||
|
||||
})
|
||||
|
||||
|
||||
.config(function(parseTagsProcessor) {
|
||||
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/tutorial-step'));
|
||||
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/sortOrder'));
|
||||
})
|
||||
|
||||
|
||||
.config(function(inlineTagProcessor, typeInlineTagDef) {
|
||||
inlineTagProcessor.inlineTagDefinitions.push(typeInlineTagDef);
|
||||
})
|
||||
|
||||
|
||||
.config(function(templateFinder, renderDocsProcessor, gitData) {
|
||||
templateFinder.templateFolders.unshift(path.resolve(packagePath, 'templates'));
|
||||
renderDocsProcessor.extraData.git = gitData;
|
||||
})
|
||||
|
||||
|
||||
.config(function(computePathsProcessor, computeIdsProcessor) {
|
||||
|
||||
computePathsProcessor.pathTemplates.push({
|
||||
docTypes: ['error'],
|
||||
pathTemplate: 'error/${namespace}/${name}',
|
||||
outputPathTemplate: 'partials/error/${namespace}/${name}.html'
|
||||
});
|
||||
|
||||
computePathsProcessor.pathTemplates.push({
|
||||
docTypes: ['errorNamespace'],
|
||||
pathTemplate: 'error/${name}',
|
||||
outputPathTemplate: 'partials/error/${name}.html'
|
||||
});
|
||||
|
||||
computePathsProcessor.pathTemplates.push({
|
||||
docTypes: ['overview', 'tutorial'],
|
||||
getPath: function(doc) {
|
||||
var docPath = path.dirname(doc.fileInfo.relativePath);
|
||||
if ( doc.fileInfo.baseName !== 'index' ) {
|
||||
docPath = path.join(docPath, doc.fileInfo.baseName);
|
||||
}
|
||||
return docPath;
|
||||
},
|
||||
outputPathTemplate: 'partials/${path}.html'
|
||||
});
|
||||
|
||||
computePathsProcessor.pathTemplates.push({
|
||||
docTypes: ['e2e-test'],
|
||||
getPath: function() {},
|
||||
outputPathTemplate: 'ptore2e/${example.id}/${deployment.name}_test.js'
|
||||
});
|
||||
|
||||
computePathsProcessor.pathTemplates.push({
|
||||
docTypes: ['indexPage'],
|
||||
pathTemplate: '.',
|
||||
outputPathTemplate: '${id}.html'
|
||||
});
|
||||
|
||||
computePathsProcessor.pathTemplates.push({
|
||||
docTypes: ['module' ],
|
||||
pathTemplate: '${area}/${name}',
|
||||
outputPathTemplate: 'partials/${area}/${name}.html'
|
||||
});
|
||||
computePathsProcessor.pathTemplates.push({
|
||||
docTypes: ['componentGroup' ],
|
||||
pathTemplate: '${area}/${moduleName}/${groupType}',
|
||||
outputPathTemplate: 'partials/${area}/${moduleName}/${groupType}.html'
|
||||
});
|
||||
|
||||
computeIdsProcessor.idTemplates.push({
|
||||
docTypes: ['overview', 'tutorial', 'e2e-test', 'indexPage'],
|
||||
getId: function(doc) { return doc.fileInfo.baseName; },
|
||||
getAliases: function(doc) { return [doc.id]; }
|
||||
});
|
||||
|
||||
computeIdsProcessor.idTemplates.push({
|
||||
docTypes: ['error', 'errorNamespace'],
|
||||
getId: function(doc) { return 'error:' + doc.name; },
|
||||
getAliases: function(doc) { return [doc.id]; }
|
||||
});
|
||||
})
|
||||
|
||||
.config(function(checkAnchorLinksProcessor) {
|
||||
checkAnchorLinksProcessor.base = '/';
|
||||
// We are only interested in docs that have an area (i.e. they are pages)
|
||||
checkAnchorLinksProcessor.checkDoc = function(doc) { return doc.area; };
|
||||
})
|
||||
|
||||
|
||||
.config(function(
|
||||
generateIndexPagesProcessor,
|
||||
generateProtractorTestsProcessor,
|
||||
generateExamplesProcessor,
|
||||
debugDeployment, defaultDeployment,
|
||||
jqueryDeployment, productionDeployment) {
|
||||
|
||||
generateIndexPagesProcessor.deployments = [
|
||||
debugDeployment,
|
||||
defaultDeployment,
|
||||
jqueryDeployment,
|
||||
productionDeployment
|
||||
];
|
||||
|
||||
generateProtractorTestsProcessor.deployments = [
|
||||
defaultDeployment,
|
||||
jqueryDeployment
|
||||
];
|
||||
|
||||
generateExamplesProcessor.deployments = [
|
||||
debugDeployment,
|
||||
defaultDeployment,
|
||||
jqueryDeployment,
|
||||
productionDeployment
|
||||
];
|
||||
});
|
||||
return config;
|
||||
};
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
var typeClassFilter = require('dgeni-packages/ngdoc/rendering/filters/type-class');
|
||||
var encoder = new require('node-html-encoder').Encoder();
|
||||
|
||||
/**
|
||||
* @dgService typeInlineTagDef
|
||||
* @description
|
||||
* Replace with markup that displays a nice type
|
||||
*/
|
||||
module.exports = function typeInlineTagDef(getTypeClass) {
|
||||
return {
|
||||
name: 'type',
|
||||
handler: function(doc, tagName, tagDescription) {
|
||||
return '<a href="" class="' + getTypeClass(tagDescription) + '">'+encoder.htmlEncode(tagDescription) + '</a>';
|
||||
}
|
||||
};
|
||||
};
|
||||
module.exports = {
|
||||
name: 'type',
|
||||
description: 'Replace with markup that displays a nice type',
|
||||
handlerFactory: function() {
|
||||
return function(doc, tagName, tagDescription) {
|
||||
return '<a href="" class="' + typeClassFilter.process(tagDescription) + '">'+encoder.htmlEncode(tagDescription) + '</a>';
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
var fs = require('q-io/fs');
|
||||
var log = require('winston');
|
||||
var util = require("util");
|
||||
|
||||
module.exports = {
|
||||
name: 'debug-dump',
|
||||
runBefore: ['write-files'],
|
||||
description: 'This processor dumps docs that match a filter to a file',
|
||||
process: function(docs, config) {
|
||||
|
||||
var filter, outputPath, depth;
|
||||
|
||||
filter = config.get('processing.debug-dump.filter');
|
||||
outputPath = config.get('processing.debug-dump.outputPath');
|
||||
depth = config.get('processing.debug-dump.depth', 2);
|
||||
|
||||
|
||||
if ( filter && outputPath ) {
|
||||
log.info('Dumping docs:', filter, outputPath);
|
||||
var filteredDocs = filter(docs);
|
||||
var dumpedDocs = util.inspect(filteredDocs, depth);
|
||||
return writeFile(outputPath, dumpedDocs).then(function() {
|
||||
return docs;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function writeFile(file, content) {
|
||||
return fs.makeTree(fs.directory(file)).then(function() {
|
||||
return fs.write(file, content, 'wb');
|
||||
});
|
||||
}
|
||||
@@ -1,52 +1,59 @@
|
||||
"use strict";
|
||||
|
||||
var _ = require('lodash');
|
||||
var log = require('winston');
|
||||
var path = require('canonical-path');
|
||||
|
||||
/**
|
||||
* @dgProcessor errorDocsProcessor
|
||||
* @description
|
||||
* Process "error" docType docs and generate errorNamespace docs
|
||||
*/
|
||||
module.exports = function errorDocsProcessor(errorNamespaceMap, getMinerrInfo) {
|
||||
return {
|
||||
$runAfter: ['tags-extracted'],
|
||||
$runBefore: ['extra-docs-added'],
|
||||
$process: function(docs) {
|
||||
module.exports = {
|
||||
name: 'error-docs',
|
||||
description: 'Compute the various fields for docs in the Error area',
|
||||
runAfter: ['tags-extracted', 'compute-path'],
|
||||
runBefore: ['extra-docs-added'],
|
||||
exports: {
|
||||
errorNamespaces: ['factory', function() { return {}; }],
|
||||
minerrInfo: ['factory', function(config) {
|
||||
var minerrInfoPath = config.get('processing.errors.minerrInfoPath');
|
||||
if ( !minerrInfoPath ) {
|
||||
throw new Error('Error in configuration: Please provide a path to the minerr info file (errors.json) ' +
|
||||
'in the `config.processing.errors.minerrInfoPath` property');
|
||||
}
|
||||
return require(minerrInfoPath);
|
||||
}]
|
||||
},
|
||||
process: function(docs, partialNames, errorNamespaces, minerrInfo) {
|
||||
|
||||
// Create error namespace docs and attach error docs to each
|
||||
docs.forEach(function(doc) {
|
||||
var parts, namespaceDoc;
|
||||
// Create error namespace docs and attach error docs to each
|
||||
_.forEach(docs, function(doc) {
|
||||
if ( doc.docType === 'error' ) {
|
||||
|
||||
if ( doc.docType === 'error' ) {
|
||||
// Parse out the error info from the id
|
||||
parts = doc.name.split(':');
|
||||
doc.namespace = parts[0];
|
||||
doc.name = parts[1];
|
||||
|
||||
// Parse out the error info from the id
|
||||
parts = doc.name.split(':');
|
||||
doc.namespace = parts[0];
|
||||
doc.name = parts[1];
|
||||
|
||||
// Get or create the relevant errorNamespace doc
|
||||
namespaceDoc = errorNamespaceMap.get(doc.namespace);
|
||||
if ( !namespaceDoc ) {
|
||||
namespaceDoc = {
|
||||
area: 'error',
|
||||
name: doc.namespace,
|
||||
errors: [],
|
||||
docType: 'errorNamespace'
|
||||
};
|
||||
errorNamespaceMap.set(doc.namespace, namespaceDoc);
|
||||
}
|
||||
|
||||
// Link this error doc to its namespace doc
|
||||
namespaceDoc.errors.push(doc);
|
||||
doc.namespaceDoc = namespaceDoc;
|
||||
doc.formattedErrorMessage = getMinerrInfo().errors[doc.namespace][doc.name];
|
||||
var namespaceDoc = errorNamespaces[doc.namespace];
|
||||
if ( !namespaceDoc ) {
|
||||
// First time we came across this namespace, so create a new one
|
||||
namespaceDoc = errorNamespaces[doc.namespace] = {
|
||||
area: doc.area,
|
||||
name: doc.namespace,
|
||||
errors: [],
|
||||
path: path.dirname(doc.path),
|
||||
outputPath: path.dirname(doc.outputPath) + '.html',
|
||||
docType: 'errorNamespace'
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
errorNamespaceMap.forEach(function(errorNamespace) {
|
||||
docs.push(errorNamespace);
|
||||
});
|
||||
}
|
||||
};
|
||||
// Add this error to the namespace
|
||||
namespaceDoc.errors.push(doc);
|
||||
doc.namespace = namespaceDoc;
|
||||
|
||||
doc.formattedErrorMessage = minerrInfo.errors[doc.namespace.name][doc.name];
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
return docs.concat(_.values(errorNamespaces));
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
var gruntUtils = require('../../../lib/grunt/utils');
|
||||
var versionInfo = require('../../../lib/versions/version-info');
|
||||
|
||||
module.exports = {
|
||||
name: 'git-data',
|
||||
runBefore: ['reading-files'],
|
||||
description: 'This processor adds information from the local git repository to the extraData injectable',
|
||||
exports: {
|
||||
gitData: ['factory', function() {
|
||||
return {
|
||||
version: versionInfo.currentVersion,
|
||||
versions: versionInfo.previousVersions,
|
||||
info: versionInfo.gitRepoInfo
|
||||
};
|
||||
}]
|
||||
},
|
||||
process: function(extraData, gitData) {
|
||||
extraData.git = gitData;
|
||||
}
|
||||
};
|
||||
@@ -1,43 +1,40 @@
|
||||
"use strict";
|
||||
|
||||
var _ = require('lodash');
|
||||
var log = require('winston');
|
||||
var path = require('canonical-path');
|
||||
|
||||
/**
|
||||
* @dgProcessor generateIndexPagesProcessor
|
||||
* @description
|
||||
* This processor creates docs that will be rendered as the index page for the app
|
||||
*/
|
||||
module.exports = function generateIndexPagesProcessor() {
|
||||
return {
|
||||
deployments: [],
|
||||
$validate: {
|
||||
deployments: { presence: true }
|
||||
},
|
||||
$runAfter: ['adding-extra-docs'],
|
||||
$runBefore: ['extra-docs-added'],
|
||||
$process: function(docs) {
|
||||
module.exports = {
|
||||
name: 'index-page',
|
||||
runAfter: ['adding-extra-docs'],
|
||||
runBefore: ['extra-docs-added'],
|
||||
description: 'This processor creates docs that will be rendered as the index page for the app',
|
||||
process: function(docs, config) {
|
||||
|
||||
// Collect up all the areas in the docs
|
||||
var areas = {};
|
||||
docs.forEach(function(doc) {
|
||||
if ( doc.area ) {
|
||||
areas[doc.area] = doc.area;
|
||||
}
|
||||
});
|
||||
areas = _.keys(areas);
|
||||
|
||||
this.deployments.forEach(function(deployment) {
|
||||
|
||||
var indexDoc = _.defaults({
|
||||
docType: 'indexPage',
|
||||
areas: areas
|
||||
}, deployment);
|
||||
|
||||
indexDoc.id = 'index' + (deployment.name === 'default' ? '' : '-' + deployment.name);
|
||||
|
||||
docs.push(indexDoc);
|
||||
});
|
||||
var deployment = config.deployment;
|
||||
if ( !deployment || !deployment.environments ) {
|
||||
throw new Error('No deployment environments found in the config.');
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Collect up all the areas in the docs
|
||||
var areas = {};
|
||||
_.forEach(docs, function(doc) {
|
||||
if ( doc.area ) {
|
||||
areas[doc.area] = doc.area;
|
||||
}
|
||||
});
|
||||
areas = _.keys(areas);
|
||||
|
||||
_.forEach(deployment.environments, function(environment) {
|
||||
|
||||
var indexDoc = _.defaults({
|
||||
docType: 'indexPage',
|
||||
areas: areas
|
||||
}, environment);
|
||||
|
||||
indexDoc.id = 'index' + (environment.name === 'default' ? '' : '-' + environment.name);
|
||||
// Use .. to put it at the root of the build
|
||||
indexDoc.outputPath = indexDoc.id + '.html';
|
||||
|
||||
docs.push(indexDoc);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,64 +1,50 @@
|
||||
"use strict";
|
||||
|
||||
var _ = require('lodash');
|
||||
var log = require('winston');
|
||||
var fs = require('fs');
|
||||
var path = require('canonical-path');
|
||||
|
||||
/**
|
||||
* @dgProcessor generateKeywordsProcessor
|
||||
* @description
|
||||
* This processor extracts all the keywords from each document and creates
|
||||
* a new document that will be rendered as a JavaScript file containing all
|
||||
* this data.
|
||||
*/
|
||||
module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
|
||||
return {
|
||||
ignoreWordsFile: undefined,
|
||||
areasToSearch: ['api', 'guide', 'misc', 'error', 'tutorial'],
|
||||
propertiesToIgnore: [],
|
||||
$validate: {
|
||||
ignoreWordsFile: { },
|
||||
areasToSearch: { presence: true },
|
||||
propertiesToIgnore: { }
|
||||
},
|
||||
$runAfter: ['memberDocsProcessor'],
|
||||
$runBefore: ['rendering-docs'],
|
||||
$process: function(docs) {
|
||||
module.exports = {
|
||||
name: 'keywords',
|
||||
runAfter: ['docs-processed'],
|
||||
runBefore: ['adding-extra-docs'],
|
||||
description: 'This processor extracts all the keywords from the document',
|
||||
process: function(docs, config) {
|
||||
|
||||
// Keywords to ignore
|
||||
var wordsToIgnore = [];
|
||||
var propertiesToIgnore;
|
||||
var areasToSearch;
|
||||
// Keywords to ignore
|
||||
var wordsToIgnore = [];
|
||||
var propertiesToIgnore;
|
||||
var areasToSearch;
|
||||
|
||||
// Keywords start with "ng:" or one of $, _ or a letter
|
||||
var KEYWORD_REGEX = /^((ng:|[\$_a-z])[\w\-_]+)/;
|
||||
// Keywords start with "ng:" or one of $, _ or a letter
|
||||
var KEYWORD_REGEX = /^((ng:|[\$_a-z])[\w\-_]+)/;
|
||||
|
||||
// Load up the keywords to ignore, if specified in the config
|
||||
if ( this.ignoreWordsFile ) {
|
||||
// Load up the keywords to ignore, if specified in the config
|
||||
if ( config.processing.search && config.processing.search.ignoreWordsFile ) {
|
||||
|
||||
var ignoreWordsPath = path.resolve(readFilesProcessor.basePath, this.ignoreWordsFile);
|
||||
wordsToIgnore = fs.readFileSync(ignoreWordsPath, 'utf8').toString().split(/[,\s\n\r]+/gm);
|
||||
var ignoreWordsPath = path.resolve(config.basePath, config.processing.search.ignoreWordsFile);
|
||||
wordsToIgnore = fs.readFileSync(ignoreWordsPath, 'utf8').toString().split(/[,\s\n\r]+/gm);
|
||||
|
||||
log.debug('Loaded ignore words from "' + ignoreWordsPath + '"');
|
||||
log.silly(wordsToIgnore);
|
||||
log.debug('Loaded ignore words from "' + ignoreWordsPath + '"');
|
||||
log.silly(wordsToIgnore);
|
||||
|
||||
}
|
||||
|
||||
areasToSearch = _.indexBy(config.get('processing.search.areasToSearch', ['api', 'guide', 'misc', 'error', 'tutorial']));
|
||||
|
||||
propertiesToIgnore = _.indexBy(config.get('processing.search.propertiesToIgnore', []));
|
||||
log.debug('Properties to ignore', propertiesToIgnore);
|
||||
|
||||
var ignoreWordsMap = _.indexBy(wordsToIgnore);
|
||||
|
||||
// If the title contains a name starting with ng, e.g. "ngController", then add the module name
|
||||
// without the ng to the title text, e.g. "controller".
|
||||
function extractTitleWords(title) {
|
||||
var match = /ng([A-Z]\w*)/.exec(title);
|
||||
if ( match ) {
|
||||
title = title + ' ' + match[1].toLowerCase();
|
||||
}
|
||||
|
||||
areasToSearch = _.indexBy(this.areasToSearch);
|
||||
propertiesToIgnore = _.indexBy(this.propertiesToIgnore);
|
||||
log.debug('Properties to ignore', propertiesToIgnore);
|
||||
|
||||
var ignoreWordsMap = _.indexBy(wordsToIgnore);
|
||||
|
||||
// If the title contains a name starting with ng, e.g. "ngController", then add the module name
|
||||
// without the ng to the title text, e.g. "controller".
|
||||
function extractTitleWords(title) {
|
||||
var match = /ng([A-Z]\w*)/.exec(title);
|
||||
if ( match ) {
|
||||
title = title + ' ' + match[1].toLowerCase();
|
||||
}
|
||||
return title;
|
||||
}
|
||||
return title;
|
||||
}
|
||||
|
||||
function extractWords(text, words, keywordMap) {
|
||||
|
||||
@@ -66,49 +52,37 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
|
||||
_.forEach(tokens, function(token){
|
||||
var match = token.match(KEYWORD_REGEX);
|
||||
if (match){
|
||||
var key = match[1];
|
||||
key = match[1];
|
||||
if ( !keywordMap[key]) {
|
||||
keywordMap[key] = true;
|
||||
words.push(key);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// We are only interested in docs that live in the right area
|
||||
docs = _.filter(docs, function(doc) { return areasToSearch[doc.area]; });
|
||||
// We are only interested in docs that live in the right area
|
||||
docs = _.filter(docs, function(doc) { return areasToSearch[doc.area]; });
|
||||
|
||||
_.forEach(docs, function(doc) {
|
||||
_.forEach(docs, function(doc) {
|
||||
|
||||
var words = [];
|
||||
var keywordMap = _.clone(ignoreWordsMap);
|
||||
var members = [];
|
||||
var membersMap = {};
|
||||
|
||||
// Search each top level property of the document for search terms
|
||||
_.forEach(doc, function(value, key) {
|
||||
|
||||
if ( _.isString(value) && !propertiesToIgnore[key] ) {
|
||||
extractWords(value, words, keywordMap);
|
||||
}
|
||||
|
||||
if ( key === 'methods' || key === 'properties' || key === 'events' ) {
|
||||
_.forEach(value, function(member) {
|
||||
extractWords(member.name, members, membersMap);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
doc.searchTerms = {
|
||||
titleWords: extractTitleWords(doc.name),
|
||||
keywords: _.sortBy(words).join(' '),
|
||||
members: _.sortBy(members).join(' ')
|
||||
keywords: _.sortBy(words).join(' ')
|
||||
};
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
var _ = require('lodash');
|
||||
var path = require('canonical-path');
|
||||
var log = require('winston');
|
||||
|
||||
var AREA_NAMES = {
|
||||
api: 'API',
|
||||
@@ -34,206 +33,182 @@ function getNavGroup(pages, area, pageSorter, pageMapper) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dgProcessor generatePagesDataProcessor
|
||||
* @description
|
||||
* This processor will create a new doc that will be rendered as a JavaScript file
|
||||
* containing meta information about the pages and navigation
|
||||
*/
|
||||
module.exports = function generatePagesDataProcessor(log) {
|
||||
var navGroupMappers = {
|
||||
api: function(areaPages, area) {
|
||||
var navGroups = _(areaPages)
|
||||
.filter('module') // We are not interested in docs that are not in a module
|
||||
|
||||
.groupBy('module')
|
||||
|
||||
var navGroupMappers = {
|
||||
api: function(areaPages, area) {
|
||||
var navGroups = _(areaPages)
|
||||
.filter('module') // We are not interested in docs that are not in a module
|
||||
.map(function(modulePages, moduleName) {
|
||||
log.debug('moduleName: ' + moduleName);
|
||||
var navItems = [];
|
||||
var modulePage;
|
||||
|
||||
.groupBy('module')
|
||||
_(modulePages)
|
||||
|
||||
.map(function(modulePages, moduleName) {
|
||||
log.debug('moduleName: ' + moduleName);
|
||||
var navItems = [];
|
||||
var modulePage;
|
||||
.groupBy('docType')
|
||||
|
||||
_(modulePages)
|
||||
.tap(function(docTypes) {
|
||||
log.debug(_.keys(docTypes));
|
||||
// Extract the module page from the collection
|
||||
modulePage = docTypes.module[0];
|
||||
delete docTypes.module;
|
||||
})
|
||||
|
||||
.groupBy('docType')
|
||||
.tap(function(docTypes) {
|
||||
if ( docTypes.input ) {
|
||||
docTypes.directive = docTypes.directive || [];
|
||||
// Combine input docTypes into directive docTypes
|
||||
docTypes.directive = docTypes.directive.concat(docTypes.input);
|
||||
delete docTypes.input;
|
||||
}
|
||||
})
|
||||
|
||||
.tap(function(docTypes) {
|
||||
log.debug(moduleName, _.keys(docTypes));
|
||||
// Extract the module page from the collection
|
||||
modulePage = docTypes.module[0];
|
||||
delete docTypes.module;
|
||||
})
|
||||
.forEach(function(sectionPages, sectionName) {
|
||||
|
||||
.tap(function(docTypes) {
|
||||
if ( docTypes.input ) {
|
||||
docTypes.directive = docTypes.directive || [];
|
||||
// Combine input docTypes into directive docTypes
|
||||
docTypes.directive = docTypes.directive.concat(docTypes.input);
|
||||
delete docTypes.input;
|
||||
}
|
||||
})
|
||||
sectionPages = _.sortBy(sectionPages, 'name');
|
||||
|
||||
.forEach(function(sectionPages, sectionName) {
|
||||
if ( sectionPages.length > 0 ) {
|
||||
// Push a navItem for this section
|
||||
navItems.push({
|
||||
name: sectionName,
|
||||
type: 'section',
|
||||
href: path.dirname(sectionPages[0].path)
|
||||
});
|
||||
|
||||
sectionPages = _.sortBy(sectionPages, 'name');
|
||||
// Push the rest of the sectionPages for this section
|
||||
_.forEach(sectionPages, function(sectionPage) {
|
||||
|
||||
if ( sectionPages.length > 0 ) {
|
||||
// Push a navItem for this section
|
||||
navItems.push({
|
||||
name: sectionName,
|
||||
type: 'section',
|
||||
href: path.dirname(sectionPages[0].path)
|
||||
name: sectionPage.name,
|
||||
href: sectionPage.path,
|
||||
type: sectionPage.docType
|
||||
});
|
||||
|
||||
// Push the rest of the sectionPages for this section
|
||||
_.forEach(sectionPages, function(sectionPage) {
|
||||
|
||||
navItems.push({
|
||||
name: sectionPage.name,
|
||||
href: sectionPage.path,
|
||||
type: sectionPage.docType
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
return {
|
||||
name: moduleName,
|
||||
href: modulePage.path,
|
||||
type: 'group',
|
||||
navItems: navItems
|
||||
};
|
||||
})
|
||||
.value();
|
||||
return navGroups;
|
||||
},
|
||||
tutorial: function(pages, area) {
|
||||
return [getNavGroup(pages, area, 'step', function(page) {
|
||||
});
|
||||
}
|
||||
});
|
||||
return {
|
||||
name: page.name,
|
||||
step: page.step,
|
||||
href: page.path,
|
||||
type: 'tutorial'
|
||||
name: moduleName,
|
||||
href: modulePage.path,
|
||||
type: 'group',
|
||||
navItems: navItems
|
||||
};
|
||||
})];
|
||||
},
|
||||
error: function(pages, area) {
|
||||
return [getNavGroup(pages, area, 'path', function(page) {
|
||||
return {
|
||||
name: page.name,
|
||||
href: page.path,
|
||||
type: page.docType === 'errorNamespace' ? 'section' : 'error'
|
||||
};
|
||||
})];
|
||||
},
|
||||
pages: function(pages, area) {
|
||||
return [getNavGroup(
|
||||
pages,
|
||||
area,
|
||||
function(page) {
|
||||
return page.sortOrder || page.path;
|
||||
},
|
||||
function(page) {
|
||||
return {
|
||||
name: page.name,
|
||||
href: page.path,
|
||||
type: 'page'
|
||||
};
|
||||
}
|
||||
)];
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
$runAfter: ['paths-computed', 'generateKeywordsProcessor'],
|
||||
$runBefore: ['rendering-docs'],
|
||||
$process: function(docs) {
|
||||
|
||||
// We are only interested in docs that are in an area
|
||||
var pages = _.filter(docs, function(doc) {
|
||||
return doc.area;
|
||||
});
|
||||
|
||||
// We are only interested in pages that are not landing pages
|
||||
var navPages = _.filter(pages, function(page) {
|
||||
return page.docType != 'componentGroup';
|
||||
});
|
||||
|
||||
// Generate an object collection of pages that is grouped by area e.g.
|
||||
// - area "api"
|
||||
// - group "ng"
|
||||
// - section "directive"
|
||||
// - ngApp
|
||||
// - ngBind
|
||||
// - section "global"
|
||||
// - angular.element
|
||||
// - angular.bootstrap
|
||||
// - section "service"
|
||||
// - $compile
|
||||
// - group "ngRoute"
|
||||
// - section "directive"
|
||||
// - ngView
|
||||
// - section "service"
|
||||
// - $route
|
||||
//
|
||||
var areas = {};
|
||||
_(navPages)
|
||||
.groupBy('area')
|
||||
.forEach(function(pages, areaId) {
|
||||
var area = {
|
||||
id: areaId,
|
||||
name: AREA_NAMES[areaId]
|
||||
};
|
||||
areas[areaId] = area;
|
||||
|
||||
var navGroupMapper = navGroupMappers[area.id] || navGroupMappers['pages'];
|
||||
area.navGroups = navGroupMapper(pages, area);
|
||||
});
|
||||
|
||||
docs.push({
|
||||
docType: 'nav-data',
|
||||
id: 'nav-data',
|
||||
template: 'nav-data.template.js',
|
||||
outputPath: 'js/nav-data.js',
|
||||
areas: areas
|
||||
});
|
||||
|
||||
|
||||
|
||||
var searchData = _(pages)
|
||||
.filter(function(page) {
|
||||
return page.searchTerms;
|
||||
})
|
||||
.map(function(page) {
|
||||
return _.extend({ path: page.path }, page.searchTerms);
|
||||
})
|
||||
.value();
|
||||
|
||||
docs.push({
|
||||
docType: 'json-doc',
|
||||
id: 'search-data-json',
|
||||
template: 'json-doc.template.json',
|
||||
outputPath: 'js/search-data.json',
|
||||
data: searchData
|
||||
});
|
||||
|
||||
// Extract a list of basic page information for mapping paths to partials and for client side searching
|
||||
var pageData = _(docs)
|
||||
.map(function(doc) {
|
||||
return _.pick(doc, ['name', 'area', 'path']);
|
||||
})
|
||||
.indexBy('path')
|
||||
.value();
|
||||
|
||||
docs.push({
|
||||
docType: 'pages-data',
|
||||
id: 'pages-data',
|
||||
template: 'pages-data.template.js',
|
||||
outputPath: 'js/pages-data.js',
|
||||
pages: pageData
|
||||
});
|
||||
}
|
||||
};
|
||||
})
|
||||
.value();
|
||||
return navGroups;
|
||||
},
|
||||
tutorial: function(pages, area) {
|
||||
return [getNavGroup(pages, area, 'step', function(page) {
|
||||
return {
|
||||
name: page.name,
|
||||
step: page.step,
|
||||
href: page.path,
|
||||
type: 'tutorial'
|
||||
};
|
||||
})];
|
||||
},
|
||||
error: function(pages, area) {
|
||||
return [getNavGroup(pages, area, 'path', function(page) {
|
||||
return {
|
||||
name: page.name,
|
||||
href: page.path,
|
||||
type: page.docType === 'errorNamespace' ? 'section' : 'error'
|
||||
};
|
||||
})];
|
||||
},
|
||||
pages: function(pages, area) {
|
||||
return [getNavGroup(pages, area, 'path', function(page) {
|
||||
return {
|
||||
name: page.name,
|
||||
href: page.path,
|
||||
type: 'page'
|
||||
};
|
||||
})];
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
name: 'pages-data',
|
||||
description: 'This plugin will create a new doc that will be rendered as an angularjs module ' +
|
||||
'which will contain meta information about the pages and navigation',
|
||||
runAfter: ['adding-extra-docs', 'component-groups-generate', 'compute-path'],
|
||||
runBefore: ['extra-docs-added'],
|
||||
process: function(docs, config) {
|
||||
|
||||
var outputFolder = config.rendering.outputFolder;
|
||||
|
||||
_(docs)
|
||||
.filter(function(doc) { return doc.area === 'api'; })
|
||||
.filter(function(doc) { return doc.docType === 'module'; })
|
||||
.forEach(function(doc) { if ( !doc.path ) {
|
||||
log.warn('Missing path property for ', doc.id);
|
||||
}})
|
||||
.map(function(doc) { return _.pick(doc, ['id', 'module', 'docType', 'area']); })
|
||||
.tap(function(docs) {
|
||||
log.debug(docs);
|
||||
});
|
||||
|
||||
|
||||
// We are only interested in docs that are in a area and not landing pages
|
||||
var navPages = _.filter(docs, function(page) {
|
||||
return page.area &&
|
||||
page.docType != 'componentGroup';
|
||||
});
|
||||
|
||||
// Generate an object collection of pages that is grouped by area e.g.
|
||||
// - area "api"
|
||||
// - group "ng"
|
||||
// - section "directive"
|
||||
// - ngApp
|
||||
// - ngBind
|
||||
// - section "global"
|
||||
// - angular.element
|
||||
// - angular.bootstrap
|
||||
// - section "service"
|
||||
// - $compile
|
||||
// - group "ngRoute"
|
||||
// - section "directive"
|
||||
// - ngView
|
||||
// - section "service"
|
||||
// - $route
|
||||
//
|
||||
var areas = {};
|
||||
_(navPages)
|
||||
.groupBy('area')
|
||||
.forEach(function(pages, areaId) {
|
||||
var area = {
|
||||
id: areaId,
|
||||
name: AREA_NAMES[areaId]
|
||||
};
|
||||
areas[areaId] = area;
|
||||
|
||||
var navGroupMapper = navGroupMappers[area.id] || navGroupMappers['pages'];
|
||||
area.navGroups = navGroupMapper(pages, area);
|
||||
});
|
||||
|
||||
// Extract a list of basic page information for mapping paths to partials and for client side searching
|
||||
var pages = _(docs)
|
||||
.map(function(doc) {
|
||||
var page = _.pick(doc, [
|
||||
'docType', 'id', 'name', 'area', 'outputPath', 'path', 'searchTerms'
|
||||
]);
|
||||
return page;
|
||||
})
|
||||
.indexBy('path')
|
||||
.value();
|
||||
|
||||
|
||||
var docData = {
|
||||
docType: 'pages-data',
|
||||
id: 'pages-data',
|
||||
template: 'pages-data.template.js',
|
||||
outputPath: 'js/pages-data.js',
|
||||
|
||||
areas: areas,
|
||||
pages: pages
|
||||
};
|
||||
docs.push(docData);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
var _ = require('lodash');
|
||||
var path = require('canonical-path');
|
||||
|
||||
module.exports = {
|
||||
name: 'protractor-generate',
|
||||
description: 'Generate a protractor test file from the e2e tests in the examples',
|
||||
runAfter: ['adding-extra-docs'],
|
||||
runBefore: ['extra-docs-added'],
|
||||
process: function(docs, examples, config) {
|
||||
var protractorFolder = config.get('rendering.protractor.outputFolder', 'ptore2e');
|
||||
|
||||
_.forEach(examples, function(example) {
|
||||
|
||||
_.forEach(example.files, function(file) {
|
||||
|
||||
// Check if it's a Protractor test.
|
||||
if (file.type !== 'protractor') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create new files for the tests.
|
||||
docs.push(createProtractorDoc(example, file, 'jquery'));
|
||||
docs.push(createProtractorDoc(example, file, 'jqlite'));
|
||||
});
|
||||
});
|
||||
|
||||
function createProtractorDoc(example, file, env) {
|
||||
var protractorDoc = {
|
||||
docType: 'e2e-test',
|
||||
id: 'protractorTest' + '-' + example.id,
|
||||
template: 'protractorTests.template.js',
|
||||
outputPath: path.join(protractorFolder, example.id, env + '_test.js'),
|
||||
innerTest: file.fileContents,
|
||||
pathPrefix: '.', // Hold for if we test with full jQuery
|
||||
exampleId: example.id,
|
||||
description: example.doc.id
|
||||
};
|
||||
|
||||
if (env === 'jquery') {
|
||||
protractorDoc.examplePath = example.outputFolder + '/index-jquery.html';
|
||||
} else {
|
||||
protractorDoc.examplePath = example.outputFolder + '/index.html';
|
||||
}
|
||||
return protractorDoc;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
@@ -1,34 +1,38 @@
|
||||
"use strict";
|
||||
|
||||
var _ = require('lodash');
|
||||
|
||||
/**
|
||||
* @dgProcessor generateVersionDocProcessor
|
||||
* @description
|
||||
* This processor will create a new doc that will be rendered as a JavaScript file
|
||||
* containing meta information about the current versions of AngularJS
|
||||
*/
|
||||
module.exports = function generateVersionDocProcessor(gitData) {
|
||||
return {
|
||||
$runAfter: ['generatePagesDataProcessor'],
|
||||
$runBefore: ['rendering-docs'],
|
||||
$process: function(docs) {
|
||||
module.exports = {
|
||||
name: 'versions-data',
|
||||
description: 'This plugin will create a new doc that will be rendered as an angularjs module ' +
|
||||
'which will contain meta information about the versions of angular',
|
||||
runAfter: ['adding-extra-docs', 'pages-data'],
|
||||
runBefore: ['extra-docs-added'],
|
||||
process: function(docs, gitData) {
|
||||
|
||||
var versionDoc = {
|
||||
docType: 'versions-data',
|
||||
id: 'versions-data',
|
||||
template: 'versions-data.template.js',
|
||||
outputPath: 'js/versions-data.js',
|
||||
currentVersion: gitData.version
|
||||
};
|
||||
var version = gitData.version;
|
||||
var versions = gitData.versions;
|
||||
|
||||
versionDoc.versions = _(gitData.versions)
|
||||
.filter(function(version) { return version.major > 0; })
|
||||
.push(gitData.version)
|
||||
.reverse()
|
||||
.value();
|
||||
|
||||
docs.push(versionDoc);
|
||||
if ( !version ) {
|
||||
throw new Error('Invalid configuration. Please provide a valid `source.currentVersion` property');
|
||||
}
|
||||
};
|
||||
if ( !versions ) {
|
||||
throw new Error('Invalid configuration. Please provide a valid `source.previousVersions` property');
|
||||
}
|
||||
|
||||
var versionDoc = {
|
||||
docType: 'versions-data',
|
||||
id: 'versions-data',
|
||||
template: 'versions-data.template.js',
|
||||
outputPath: 'js/versions-data.js',
|
||||
};
|
||||
|
||||
versionDoc.currentVersion = version;
|
||||
|
||||
versionDoc.versions = _(versions)
|
||||
.filter(function(version) { return version.major > 0; })
|
||||
.push(version)
|
||||
.reverse()
|
||||
.value();
|
||||
|
||||
docs.push(versionDoc);
|
||||
}
|
||||
};
|
||||
@@ -1,39 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = function debugDeployment(getVersion) {
|
||||
return {
|
||||
name: 'debug',
|
||||
examples: {
|
||||
commonFiles: {
|
||||
scripts: [ '../../../angular.js' ]
|
||||
},
|
||||
dependencyPath: '../../../'
|
||||
},
|
||||
scripts: [
|
||||
'../angular.js',
|
||||
'../angular-resource.js',
|
||||
'../angular-route.js',
|
||||
'../angular-cookies.js',
|
||||
'../angular-sanitize.js',
|
||||
'../angular-touch.js',
|
||||
'../angular-animate.js',
|
||||
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
|
||||
'js/angular-bootstrap/bootstrap.js',
|
||||
'js/angular-bootstrap/dropdown-toggle.js',
|
||||
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js',
|
||||
'js/versions-data.js',
|
||||
'js/pages-data.js',
|
||||
'js/nav-data.js',
|
||||
'js/docs.js'
|
||||
],
|
||||
stylesheets: [
|
||||
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.css',
|
||||
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
|
||||
'css/prettify-theme.css',
|
||||
'css/docs.css',
|
||||
'css/animations.css'
|
||||
]
|
||||
};
|
||||
};
|
||||
@@ -1,39 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = function defaultDeployment(getVersion) {
|
||||
return {
|
||||
name: 'default',
|
||||
examples: {
|
||||
commonFiles: {
|
||||
scripts: [ '../../../angular.min.js' ]
|
||||
},
|
||||
dependencyPath: '../../../'
|
||||
},
|
||||
scripts: [
|
||||
'../angular.min.js',
|
||||
'../angular-resource.min.js',
|
||||
'../angular-route.min.js',
|
||||
'../angular-cookies.min.js',
|
||||
'../angular-sanitize.min.js',
|
||||
'../angular-touch.min.js',
|
||||
'../angular-animate.min.js',
|
||||
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
|
||||
'js/angular-bootstrap/bootstrap.min.js',
|
||||
'js/angular-bootstrap/dropdown-toggle.min.js',
|
||||
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.min.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js',
|
||||
'js/versions-data.js',
|
||||
'js/pages-data.js',
|
||||
'js/nav-data.js',
|
||||
'js/docs.min.js'
|
||||
],
|
||||
stylesheets: [
|
||||
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.min.css',
|
||||
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
|
||||
'css/prettify-theme.css',
|
||||
'css/docs.css',
|
||||
'css/animations.css'
|
||||
]
|
||||
};
|
||||
};
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = function jqueryDeployment(getVersion) {
|
||||
return {
|
||||
name: 'jquery',
|
||||
examples: {
|
||||
commonFiles: {
|
||||
scripts: [
|
||||
'../../components/jquery-' + getVersion('jquery') + '/jquery.js',
|
||||
'../../../angular.js'
|
||||
]
|
||||
},
|
||||
dependencyPath: '../../../'
|
||||
},
|
||||
scripts: [
|
||||
'components/jquery-' + getVersion('jquery') + '/jquery.js',
|
||||
'../angular.min.js',
|
||||
'../angular-resource.min.js',
|
||||
'../angular-route.min.js',
|
||||
'../angular-cookies.min.js',
|
||||
'../angular-sanitize.min.js',
|
||||
'../angular-touch.min.js',
|
||||
'../angular-animate.min.js',
|
||||
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
|
||||
'js/angular-bootstrap/bootstrap.min.js',
|
||||
'js/angular-bootstrap/dropdown-toggle.min.js',
|
||||
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.min.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js',
|
||||
'js/versions-data.js',
|
||||
'js/pages-data.js',
|
||||
'js/nav-data.js',
|
||||
'js/docs.min.js'
|
||||
],
|
||||
stylesheets: [
|
||||
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.min.css',
|
||||
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
|
||||
'css/prettify-theme.css',
|
||||
'css/docs.css',
|
||||
'css/animations.css'
|
||||
]
|
||||
};
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var versionInfo = require('../../../../lib/versions/version-info');
|
||||
var cdnUrl = "//ajax.googleapis.com/ajax/libs/angularjs/" + versionInfo.cdnVersion;
|
||||
|
||||
module.exports = function productionDeployment(getVersion) {
|
||||
return {
|
||||
name: 'production',
|
||||
examples: {
|
||||
commonFiles: {
|
||||
scripts: [ cdnUrl + '/angular.min.js' ]
|
||||
},
|
||||
dependencyPath: cdnUrl + '/'
|
||||
},
|
||||
scripts: [
|
||||
cdnUrl + '/angular.min.js',
|
||||
cdnUrl + '/angular-resource.min.js',
|
||||
cdnUrl + '/angular-route.min.js',
|
||||
cdnUrl + '/angular-cookies.min.js',
|
||||
cdnUrl + '/angular-sanitize.min.js',
|
||||
cdnUrl + '/angular-touch.min.js',
|
||||
cdnUrl + '/angular-animate.min.js',
|
||||
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
|
||||
'js/angular-bootstrap/bootstrap.min.js',
|
||||
'js/angular-bootstrap/dropdown-toggle.min.js',
|
||||
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.min.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js',
|
||||
'js/versions-data.js',
|
||||
'js/pages-data.js',
|
||||
'js/nav-data.js',
|
||||
'js/docs.min.js'
|
||||
],
|
||||
stylesheets: [
|
||||
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.min.css',
|
||||
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
|
||||
'css/prettify-theme.css',
|
||||
'css/docs.css',
|
||||
'css/animations.css'
|
||||
]
|
||||
};
|
||||
};
|
||||
@@ -1,10 +0,0 @@
|
||||
"use strict";
|
||||
var StringMap = require('stringmap');
|
||||
|
||||
/**
|
||||
* @dgService errorNamespaceMap
|
||||
* A map of error namespaces by name.
|
||||
*/
|
||||
module.exports = function errorNamespaceMap() {
|
||||
return new StringMap();
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var path = require('canonical-path');
|
||||
|
||||
/**
|
||||
* @dgService minErrInfo
|
||||
* @description
|
||||
* Load the error information that was generated during the AngularJS build.
|
||||
*/
|
||||
module.exports = function getMinerrInfo(readFilesProcessor) {
|
||||
return function() {
|
||||
var minerrInfoPath = path.resolve(readFilesProcessor.basePath, 'build/errors.json');
|
||||
return require(minerrInfoPath);
|
||||
};
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
"use strict";
|
||||
var path = require('canonical-path');
|
||||
|
||||
/**
|
||||
* dgService getVersion
|
||||
* @description
|
||||
* Find the current version of the bower component (or npm module)
|
||||
*/
|
||||
module.exports = function getVersion(readFilesProcessor) {
|
||||
var basePath = readFilesProcessor.basePath;
|
||||
|
||||
return function(component, sourceFolder, packageFile) {
|
||||
sourceFolder = path.resolve(basePath, sourceFolder || 'docs/bower_components');
|
||||
packageFile = packageFile || 'bower.json';
|
||||
return require(path.join(sourceFolder,component,packageFile)).version;
|
||||
};
|
||||
};
|
||||
@@ -1,16 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var versionInfo = require('../../../lib/versions/version-info');
|
||||
|
||||
/**
|
||||
* @dgService gitData
|
||||
* @description
|
||||
* Information from the local git repository
|
||||
*/
|
||||
module.exports = function gitData() {
|
||||
return {
|
||||
version: versionInfo.currentVersion,
|
||||
versions: versionInfo.previousVersions,
|
||||
info: versionInfo.gitRepoInfo
|
||||
};
|
||||
};
|
||||
@@ -1,6 +0,0 @@
|
||||
module.exports = {
|
||||
name: 'sortOrder',
|
||||
transforms: function(doc, tag, value) {
|
||||
return parseInt(value, 10);
|
||||
}
|
||||
};
|
||||
@@ -14,4 +14,4 @@
|
||||
{$ doc.description | marked $}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
@@ -25,4 +25,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
@@ -1,5 +1,5 @@
|
||||
<!doctype html>
|
||||
<html lang="en" ng-app="docsApp" ng-strict-di ng-controller="DocsController">
|
||||
<html lang="en" ng-app="docsApp" ng-controller="DocsController">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
@@ -56,6 +56,15 @@
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
// force page reload when new update is available
|
||||
window.applicationCache && window.applicationCache.addEventListener('updateready', function(e) {
|
||||
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
|
||||
window.applicationCache.swapCache();
|
||||
window.location.reload();
|
||||
}
|
||||
}, false);
|
||||
|
||||
// GA asynchronous tracker
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-8594346-3']);
|
||||
@@ -70,13 +79,13 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<header scroll-y-offset-element class="header header-fixed">
|
||||
<header class="header header-fixed">
|
||||
<section class="navbar navbar-inverse docs-navbar-primary" ng-controller="DocsSearchCtrl">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-9 header-branding">
|
||||
<a class="brand navbar-brand" href="http://angularjs.org">
|
||||
<img width="117" height="30" class="logo" ng-src="img/angularjs-for-header-only.svg">
|
||||
<img class="logo" src="img/angularjs-for-header-only.svg">
|
||||
</a>
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="divider-vertical"></li>
|
||||
@@ -146,6 +155,9 @@
|
||||
</div>
|
||||
<div class="search-results-container" ng-show="hasResults">
|
||||
<div class="container">
|
||||
<a href="" ng-click="hideResults()" class="search-close">
|
||||
<span class="glyphicon glyphicon-remove search-close-icon"></span> Close
|
||||
</a>
|
||||
<div class="search-results-frame">
|
||||
<div ng-repeat="(key, value) in results" class="search-results-group" ng-class="colClassName + ' col-group-' + key">
|
||||
<h4 class="search-results-group-heading">{{ key }}</h4>
|
||||
@@ -156,9 +168,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a href="" ng-click="hideResults()" class="search-close">
|
||||
<span class="glyphicon glyphicon-remove search-close-icon"></span> Close
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -166,7 +175,7 @@
|
||||
<div class="container main-grid main-header-grid">
|
||||
<div class="grid-left">
|
||||
<div ng-controller="DocsVersionsCtrl" class="picker version-picker">
|
||||
<select ng-options="v as ('v' + v.version + (v.isSnapshot ? ' (snapshot)' : '')) group by getGroupName(v) for v in docs_versions"
|
||||
<select ng-options="v as ('v' + v.version + (v.isSnapshot ? ' (snapshot)' : '')) group by (v.isStable?'Stable':'Unstable') for v in docs_versions"
|
||||
ng-model="docs_version"
|
||||
ng-change="jumpToDocsVersion(docs_version)"
|
||||
class="docs-version-jump">
|
||||
@@ -210,7 +219,7 @@
|
||||
</div>
|
||||
<div class="grid-right">
|
||||
<div id="loading" ng-show="loading">Loading...</div>
|
||||
<div ng-hide="loading" ng-include="partialPath" autoscroll></div>
|
||||
<div ng-hide="loading" ng-include="currentPage.outputPath || 'Error404.html'" onload="afterPartialLoaded()" autoscroll></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
{$ doc.data | json $}
|
||||
@@ -1,3 +0,0 @@
|
||||
// Meta data used by the AngularJS docs app
|
||||
angular.module('navData', [])
|
||||
.value('NG_NAVIGATION', {$ doc.areas | json $});
|
||||
@@ -1,3 +1,4 @@
|
||||
// Meta data used by the AngularJS docs app
|
||||
angular.module('pagesData', [])
|
||||
.value('NG_PAGES', {$ doc.pages | json $});
|
||||
.value('NG_PAGES', {$ doc.pages | json $})
|
||||
.value('NG_NAVIGATION', {$ doc.areas | json $});
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
describe("{$ doc.description $}", function() {
|
||||
beforeEach(function() {
|
||||
browser.get("{$ doc.pathPrefix $}/{$ doc.examplePath $}");
|
||||
});
|
||||
|
||||
{$ doc.innerTest $}
|
||||
});
|
||||
@@ -2,16 +2,15 @@
|
||||
is HTML and wrap each line in a <p> - thus breaking the HTML #}
|
||||
|
||||
<div>
|
||||
<a ng-click="openPlunkr('{$ doc.path $}')" class="btn pull-right">
|
||||
<a ng-click="openPlunkr('{$ doc.example.outputFolder $}')" class="btn pull-right">
|
||||
<i class="glyphicon glyphicon-edit"> </i>
|
||||
Edit in Plunker</a>
|
||||
|
||||
<div class="runnable-example"
|
||||
path="{$ doc.example.deployments.default.path $}"
|
||||
path="{$ doc.example.outputFolder $}"
|
||||
{%- for attrName, attrValue in doc.example.attributes %}
|
||||
{$ attrName $}="{$ attrValue $}"{% endfor %}>
|
||||
|
||||
{% for fileName, file in doc.example.files %}
|
||||
{% for fileName, file in doc.example.files %}
|
||||
<div class="runnable-example-file" {% for attrName, attrValue in file.attributes %}
|
||||
{$ attrName $}="{$ attrValue $}"{% endfor %}>
|
||||
{% code -%}
|
||||
@@ -20,9 +19,9 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<iframe class="runnable-example-frame" src="{$ doc.example.deployments.default.outputPath $}" name="{$ doc.example.id $}"></iframe>
|
||||
<iframe class="runnable-example-frame" src="{$ doc.example.outputFolder $}/index.html" name="{$ doc.example.id $}"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Be aware that we need these extra new lines here or marked will not realise that the <div>
|
||||
above is HTML and wrap each line in a <p> - thus breaking the HTML #}
|
||||
above is HTML and wrap each line in a <p> - thus breaking the HTML #}
|
||||
@@ -1 +1 @@
|
||||
{% include 'overview.template.html' %}
|
||||
{% include 'overview.template.html' %}
|
||||
@@ -6,17 +6,17 @@
|
||||
Welcome to the AngularJS API docs page. These pages contain the AngularJS reference materials for version <strong ng-bind="version"></strong>.
|
||||
|
||||
The documentation is organized into **{@link guide/module modules}** which contain various components of an AngularJS application.
|
||||
These components are {@link guide/directive directives}, {@link guide/services services}, {@link guide/filter filters}, {@link guide/providers providers}, {@link guide/templates templates}, global APIs, and testing mocks.
|
||||
These components are {@link guide/directive directives}, {@link guide/services services}, {@link guide/filter filters}, {@link guide/providers providers}, {@link guide/templates templates}, global APIs and testing mocks.
|
||||
|
||||
<div class="alert alert-info">
|
||||
**Angular Prefixes `$` and `$$`**:
|
||||
**Angular Namespaces `$` and `$$`**
|
||||
|
||||
To prevent accidental name collisions with your code,
|
||||
Angular prefixes names of public objects with `$` and names of private objects with `$$`.
|
||||
Please do not use the `$` or `$$` prefix in your code.
|
||||
</div>
|
||||
|
||||
## Angular Modules
|
||||
## Angular Namespace
|
||||
|
||||
|
||||
## {@link ng ng (core module)}
|
||||
@@ -212,7 +212,7 @@ Use ngTouch when developing for mobile browsers/devices.
|
||||
{@link ngTouch#service Services / Factories}
|
||||
</td>
|
||||
<td>
|
||||
The {@link ngTouch.$swipe $swipe} service is used to register and manage mobile DOM events.
|
||||
The {@link ngTouch.$swipe $swipe} service is used to register and manage mobile DOM events.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -242,7 +242,7 @@ Use ngSanitize to securely parse and manipulate HTML data in your application.
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{@link ngSanitize#filter Filters}
|
||||
{@link ngTouch#filter Filters}
|
||||
</td>
|
||||
<td>
|
||||
The {@link ngSanitize.filter:linky linky filter} is used to turn URLs into HTML links within the provided string.
|
||||
@@ -252,7 +252,7 @@ Use ngSanitize to securely parse and manipulate HTML data in your application.
|
||||
|
||||
## {@link ngMock ngMock}
|
||||
|
||||
Use ngMock to inject and mock modules, factories, services and providers within your unit tests
|
||||
Use ngMock to inject and mock modules, factories, services and providers within your unit tests
|
||||
|
||||
<div class="alert alert-info">Include the **angular-mocks.js** file into your test runner for this to work.</div>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
@fullName Missing Required Controller
|
||||
@description
|
||||
|
||||
This error occurs when {@link ng.$compile HTML compiler} tries to process a directive that specifies the {@link ng.$compile#directive-definition-object `require` option} in a {@link ng.$compile#comprehensive-directive-api directive definition},
|
||||
This error occurs when {@link ng.$compile HTML compiler} tries to process a directive that specifies the {@link ng.$compile#description_comprehensive-directive-api_directive-definition-object `require` option} in a {@link ng.$compile#description_comprehensive-directive-api directive definition},
|
||||
but the required directive controller is not present on the current DOM element (or its ancestor element, if `^` was specified).
|
||||
|
||||
To resolve this error ensure that there is no typo in the required controller name and that the required directive controller is present on the current element.
|
||||
|
||||
@@ -21,5 +21,5 @@ myModule.directive('directiveName', function factory() {
|
||||
});
|
||||
```
|
||||
|
||||
Please refer to the {@link ng.$compile#directive-definition-object
|
||||
Please refer to the {@link ng.$compile#description_comprehensive-directive-api_directive-definition-object
|
||||
`scope` option} of the directive definition documentation to learn more about the API.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
@description
|
||||
|
||||
This error occurs when a directive defines an isolate scope property
|
||||
(using the `=` mode in the {@link ng.$compile#directive-definition-object
|
||||
(using the `=` mode in the {@link ng.$compile#description_comprehensive-directive-api_directive-definition-object
|
||||
`scope` option} of a directive definition) but the directive is used with an expression that is not-assignable.
|
||||
|
||||
In order for the two-way data-binding to work, it must be possible to write new values back into the path defined with the expression.
|
||||
@@ -16,7 +16,7 @@ myModule.directive('myDirective', function factory() {
|
||||
return {
|
||||
...
|
||||
scope: {
|
||||
localValue: '=bind'
|
||||
'bind': '=localValue'
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
@@ -37,17 +37,3 @@ elements. For example:
|
||||
```
|
||||
<b>Hello</b> World!
|
||||
```
|
||||
|
||||
Watch out for html comments at the beginning or end of templates, as these can cause this error as
|
||||
well. Consider the following template:
|
||||
|
||||
```
|
||||
<div class='container'>
|
||||
<div class='wrapper>
|
||||
...
|
||||
</div> <!-- wrapper -->
|
||||
</div> <!-- container -->
|
||||
```
|
||||
|
||||
The `<!-- container -->` comment is interpreted as a second root element and causes the template to
|
||||
be invalid.
|
||||
|
||||
@@ -12,10 +12,10 @@ $controller(MyController);
|
||||
$controller(MyController, {scope: newScope});
|
||||
```
|
||||
|
||||
To fix the example above please provide a scope (using the `$scope` property in the locals object) to the $controller call:
|
||||
To fix the example above please provide a scope to the $controller call:
|
||||
|
||||
```
|
||||
$controller(MyController, {$scope: newScope});
|
||||
$controller(MyController, {$scope, newScope});
|
||||
```
|
||||
|
||||
Please consult the {@link ng.$controller $controller} service api docs to learn more.
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
@ngdoc error
|
||||
@name $httpBackend:noxhr
|
||||
@fullName Unsupported XHR
|
||||
@description
|
||||
|
||||
This error occurs in browsers that do not support XmlHttpRequest. AngularJS
|
||||
supports Safari, Chrome, Firefox, Opera, IE8 and higher, and mobile browsers
|
||||
(Android, Chrome Mobile, iOS Safari). To avoid this error, use an officially
|
||||
supported browser.
|
||||
|
||||
@@ -23,4 +23,4 @@ When an instance of `MyCtrl` is created, the service `myService` will be created
|
||||
by the `$injector`. `myService` depends on itself, which causes the `$injector`
|
||||
to detect a circular dependency and throw the error.
|
||||
|
||||
For more information, see the {@link guide/di Dependency Injection Guide}.
|
||||
For more information, see the {@link guide/di Dependency Injection Guide}.
|
||||
@@ -23,4 +23,4 @@ To avoid the error, always use string literals for dependency injection annotati
|
||||
tokens.
|
||||
|
||||
For an explanation of what injection annotations are and how to use them, refer
|
||||
to the {@link guide/di Dependency Injection Guide}.
|
||||
to the {@link guide/di Dependency Injection Guide}.
|
||||
@@ -7,5 +7,5 @@ This error occurs when a module fails to load due to some exception. The error
|
||||
message above should provide additional context.
|
||||
|
||||
In AngularJS `1.2.0` and later, `ngRoute` has been moved to its own module.
|
||||
If you are getting this error after upgrading to `1.2.x` or later, be sure that you've
|
||||
If you are getting this error after upgrading to `1.2.x`, be sure that you've
|
||||
installed {@link ngRoute `ngRoute`}.
|
||||
|
||||
@@ -23,4 +23,4 @@ angular.module("myApp", [])
|
||||
```
|
||||
|
||||
For more information, refer to the {@link auto.$provide#provider
|
||||
$provide.provider} api doc.
|
||||
$provide.provider} api doc.
|
||||
@@ -1,54 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $injector:strictdi
|
||||
@fullName Explicit annotation required
|
||||
@description
|
||||
|
||||
This error occurs when attempting to invoke a function or provider which
|
||||
has not been explicitly annotated, while the application is running with
|
||||
strict-di mode enabled.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
angular.module("myApp", [])
|
||||
// BadController cannot be invoked, because
|
||||
// the dependencies to be injected are not
|
||||
// explicitly listed.
|
||||
.controller("BadController", function($scope, $http, $filter) {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
To fix the error, explicitly annotate the function using either the inline
|
||||
bracket notation, or with the $inject property:
|
||||
|
||||
```
|
||||
function GoodController1($scope, $http, $filter) {
|
||||
// ...
|
||||
}
|
||||
GoodController1.$inject = ["$scope", "$http", "$filter"];
|
||||
|
||||
angular.module("myApp", [])
|
||||
// GoodController1 can be invoked because it
|
||||
// had an $inject property, which is an array
|
||||
// containing the dependency names to be
|
||||
// injected.
|
||||
.controller("GoodController1", GoodController1)
|
||||
|
||||
// GoodController2 can also be invoked, because
|
||||
// the dependencies to inject are listed, in
|
||||
// order, in the array, with the function to be
|
||||
// invoked trailing on the end.
|
||||
.controller("GoodController2", [
|
||||
"$scope",
|
||||
"$http",
|
||||
"$filter",
|
||||
function($scope, $http, $filter) {
|
||||
// ...
|
||||
}
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
For more information about strict-di mode, see {@link ng.directive:ngApp ngApp}
|
||||
and {@link angular.bootstrap angular.bootstrap}.
|
||||
@@ -1,33 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $injector:undef
|
||||
@fullName Undefined Value
|
||||
@description
|
||||
|
||||
This error results from registering a factory which does not return a value (or whose return value is undefined).
|
||||
|
||||
The following is an example of a factory which will throw this error upon injection:
|
||||
|
||||
```js
|
||||
angular.module("badModule", []).
|
||||
factory("badFactory", function() {
|
||||
doLotsOfThings();
|
||||
butDontReturnAValue();
|
||||
});
|
||||
```
|
||||
|
||||
In order to prevent the error, return a value of some sort, such as an object which exposes an API for working
|
||||
with the injected object.
|
||||
|
||||
```js
|
||||
angular.module("goodModule", []).
|
||||
factory("goodFactory", function() {
|
||||
doLotsOfThings();
|
||||
butDontReturnAValue();
|
||||
|
||||
return {
|
||||
doTheThing: function methodThatDoesAThing() {
|
||||
}
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
@@ -14,7 +14,7 @@ angular.module('myApp', [])
|
||||
}]);
|
||||
```
|
||||
|
||||
The above code will fail with `$injector:unpr` if `myService` is not defined.
|
||||
The above code will fail with `$injector:unpr` if `myService` is not defined.
|
||||
|
||||
Making sure each dependency is defined will fix the problem, as noted below.
|
||||
|
||||
@@ -25,47 +25,3 @@ angular.module('myApp', [])
|
||||
// Do something with myService
|
||||
}]);
|
||||
```
|
||||
|
||||
An unknown provider error can also be caused by accidentally redefining a
|
||||
module using the `angular.module` API, as shown in the following example.
|
||||
|
||||
```
|
||||
angular.module('myModule', [])
|
||||
.service('myCoolService', function () { /* ... */ });
|
||||
|
||||
angular.module('myModule', [])
|
||||
// myModule has already been created! This is not what you want!
|
||||
.directive('myDirective', ['myCoolService', function (myCoolService) {
|
||||
// This directive definition throws unknown provider, because myCoolService
|
||||
// has been destroyed.
|
||||
}]);
|
||||
```
|
||||
|
||||
To fix this problem, make sure you only define each module with the
|
||||
`angular.module(name, [requires])` syntax once across your entire project.
|
||||
Retrieve it for subsequent use with `angular.module(name)`. The fixed example
|
||||
is shown below.
|
||||
|
||||
```
|
||||
angular.module('myModule', [])
|
||||
.service('myCoolService', function () { /* ... */ });
|
||||
|
||||
angular.module('myModule')
|
||||
.directive('myDirective', ['myCoolService', function (myCoolService) {
|
||||
// This directive definition does not throw unknown provider.
|
||||
}]);
|
||||
```
|
||||
|
||||
|
||||
Attempting to inject one controller into another will also throw an `Unknown provider` error:
|
||||
|
||||
```
|
||||
angular.module('myModule', [])
|
||||
.controller('MyFirstController', function() { /* ... */ });
|
||||
.controller('MySecondController', ['MyFirstController', function(MyFirstController) {
|
||||
// This controller throws an unknown provider error because
|
||||
// MyFirstController cannot be injected.
|
||||
}]);
|
||||
```
|
||||
|
||||
Use the `$controller` service if you want to instantiate controllers yourself.
|
||||
|
||||
@@ -9,4 +9,4 @@ it hard to reason about whether some combination of concatenated values are
|
||||
unsafe to use and could easily lead to XSS.
|
||||
|
||||
For more information about how AngularJS helps keep your app secure, refer to
|
||||
the {@link ng.$sce $sce} API doc.
|
||||
the {@link ng.$sce $sce} API doc.
|
||||
@@ -1,63 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $location:nobase
|
||||
@fullName $location in HTML5 mode requires a <base> tag to be present!
|
||||
@description
|
||||
|
||||
If you configure {@link ng.$location `$location`} to use
|
||||
{@link $locationProvider `html5Mode`} (`history.pushState`), you need to specify the base URL for the application with a [`<base href="">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base) tag or configure
|
||||
`$locationProvider` to not require a base tag by passing a definition object with
|
||||
`requireBase:false` to `$locationProvider.html5Mode()`:
|
||||
|
||||
```javascript
|
||||
$locationProvider.html5Mode({
|
||||
enabled: true,
|
||||
requireBase: false
|
||||
});
|
||||
```
|
||||
|
||||
Note that removing the requirement for a <base> tag will have adverse side effects when resolving
|
||||
relative paths with `$location` in IE9.
|
||||
|
||||
The base URL is then used to resolve all relative URLs throughout the application regardless of the
|
||||
entry point into the app.
|
||||
|
||||
If you are deploying your app into the root context (e.g. `https://myapp.com/`), set the base URL to `/`:
|
||||
|
||||
```html
|
||||
<head>
|
||||
<base href="/">
|
||||
...
|
||||
</head>
|
||||
```
|
||||
|
||||
If you are deploying your app into a sub-context (e.g. `https://myapp.com/subapp/`), set the base URL to the
|
||||
URL of the subcontext:
|
||||
|
||||
```html
|
||||
<head>
|
||||
<base href="/subapp">
|
||||
...
|
||||
</head>
|
||||
```
|
||||
|
||||
Before Angular 1.3 we didn't have this hard requirement and it was easy to write apps that worked
|
||||
when deployed in the root context but were broken when moved to a sub-context because in the
|
||||
sub-context all absolute urls would resolve to the root context of the app. To prevent this,
|
||||
use relative URLs throughout your app:
|
||||
|
||||
```html
|
||||
<!-- wrong: -->
|
||||
<a href="/userProfile">User Profile</a>
|
||||
|
||||
|
||||
<!-- correct: -->
|
||||
<a href="userProfile">User Profile</a>
|
||||
|
||||
```
|
||||
|
||||
Additionally, if you want to support [browsers that don't have the `history.pushState`
|
||||
API](http://caniuse.com/#feat=history), the fallback mechanism provided by `$location`
|
||||
won't work well without specifying the base url of the application.
|
||||
|
||||
In order to make it easier to migrate from hashbang mode to html5 mode, we require that the base
|
||||
URL is always specified when `$location`'s `html5mode` is enabled.
|
||||
@@ -1,8 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $location:nostate
|
||||
@fullName History API state support is available only in HTML5 mode and only in browsers supporting HTML5 History API
|
||||
@description
|
||||
|
||||
This error occurs when the {@link ng.$location#state $location.state} method is used when {@link ng.$locationProvider#html5Mode $locationProvider.html5Mode} is not turned on or the browser used doesn't support the HTML5 History API (for example, IE9 or Android 2.3).
|
||||
|
||||
To avoid this error, either drop support for those older browsers or avoid using this method.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user