Compare commits
321 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8302981a08 | |||
| d2a7b5162f | |||
| 2ecd85b989 | |||
| 2bdf712687 | |||
| 0de02973c1 | |||
| 55516da2df | |||
| e8adbf8d5a | |||
| c169c60535 | |||
| 0b6ec6b3ab | |||
| d2511cfac0 | |||
| 155efa421b | |||
| f33d95cfcf | |||
| 57b626a673 | |||
| b168aef861 | |||
| 6c4d2707b7 | |||
| 9c95f6d5e0 | |||
| cab9ebfd5a | |||
| 8a739fb4fa | |||
| c4003fd034 | |||
| ab856d8ae3 | |||
| 83e6eef68e | |||
| 87270cb79f | |||
| e06ebfdbb5 | |||
| ddeb1df15a | |||
| 358a69fa8b | |||
| 417aefd45d | |||
| 6ad4c8d1b4 | |||
| 3ef612afa0 | |||
| cc8486f994 | |||
| b990fa91cd | |||
| 17f7d8c5c8 | |||
| 1e8dd0e65c | |||
| b1a18ef381 | |||
| 3470ab5696 | |||
| 5d39a118df | |||
| 421a5856f8 | |||
| 85f40a15fb | |||
| b919a2737e | |||
| a675ea0343 | |||
| 8fb8d52664 | |||
| d60d904747 | |||
| 62afb6204c | |||
| 1eaf4ab414 | |||
| 1de5d181da | |||
| 73088bb7ee | |||
| 898140edb7 | |||
| dab60352e5 | |||
| df4955fe78 | |||
| 14519488ce | |||
| 569e906a58 | |||
| 18b8a63a3c | |||
| 6e78fee732 | |||
| 6a99eaf1c8 | |||
| c94e44b9f8 | |||
| bbca6b0893 | |||
| 1555a4911a | |||
| dbba98b9ae | |||
| 3e2cb6c15c | |||
| 1391e99c7f | |||
| 7a5f06d55d | |||
| bf78beeb6d | |||
| 2e892e4072 | |||
| 8f88ea57dc | |||
| 24b0b516b6 | |||
| 1fcf5949d2 | |||
| 46ccaee9be | |||
| 86c9990813 | |||
| 4a34c8e1b8 | |||
| fec2ea8c1b | |||
| 7566c7d26f | |||
| 02a19c0f39 | |||
| 6e6e4eec9d | |||
| 46f14fa4b8 | |||
| bad2249bcd | |||
| c2148ec15c | |||
| 474e40498e | |||
| e9a6792d7f | |||
| adc1501caa | |||
| 7a53707c8f | |||
| 57fe5b320d | |||
| 671bebde0a | |||
| b51ded6736 | |||
| 3ec1819b91 | |||
| 009ebec64c | |||
| 9256dbc420 | |||
| 7504656a26 | |||
| e74cdf4b59 | |||
| 9d6c3f3ec2 | |||
| ac0e260765 | |||
| 28c0213ee5 | |||
| 8b4d85c015 | |||
| 2aeda67909 | |||
| ad68ee192e | |||
| 970ba117eb | |||
| 30e097b389 | |||
| e8e02b8bce | |||
| e36a3e89f5 | |||
| 1102c41196 | |||
| e970c8fce9 | |||
| 04271d6b2c | |||
| 2e1163ef5c | |||
| 75befe723a | |||
| 5e2bc5bbf3 | |||
| 079c485b92 | |||
| 19a0c9324c | |||
| 9ef02e72ab | |||
| 2101126ce7 | |||
| a222d0b452 | |||
| 1b8eb231c9 | |||
| 06baf1869b | |||
| 82597fc12b | |||
| ff52b188a7 | |||
| dc41f465ba | |||
| 6e3b5a57cd | |||
| f003d93a3d | |||
| aac5623247 | |||
| aa03812fd0 | |||
| bcb6a494de | |||
| a1e3f8728e | |||
| 9e8e3e187d | |||
| c6554433cf | |||
| 43d2a75f4e | |||
| 37d2b50812 | |||
| 8f31f1ff43 | |||
| cf84fcf544 | |||
| f63bc3cfde | |||
| a77943110e | |||
| ec97686f2f | |||
| 4ff7b7aa48 | |||
| 57b837bd5c | |||
| 6daca023e4 | |||
| 91b4eb0f69 | |||
| e50ed4da9e | |||
| fe5dd1da8f | |||
| df4c03fa33 | |||
| 8d4e626326 | |||
| 92aef5d456 | |||
| eed13cf732 | |||
| e90200b4de | |||
| 7f36ba77a0 | |||
| 457c58827b | |||
| aae768611f | |||
| ce5ffbf667 | |||
| ab114af850 | |||
| 2759788737 | |||
| c643323c17 | |||
| 9b97a033b0 | |||
| a3226d01fa | |||
| 510d0f946f | |||
| 0b962d4881 | |||
| 71b4daa4e1 | |||
| e0b02a5040 | |||
| a0dd9b0fdd | |||
| 498bef199a | |||
| 17d34b7a98 | |||
| 72359fd097 | |||
| 72882190f2 | |||
| fd2d8a5755 | |||
| fbe84f95a1 | |||
| 3671a43be4 | |||
| f6a1ad528d | |||
| d9128e7b23 | |||
| 0b54c1d4a9 | |||
| 608d623b55 | |||
| 9f30bb5475 | |||
| 182fb18f00 | |||
| 3a9fdceeee | |||
| ee4ac72170 | |||
| eb9fc571a0 | |||
| b4d1e5e492 | |||
| 60394a9d91 | |||
| f5ddb10b56 | |||
| 6a448d3459 | |||
| 6a8c0f5f4a | |||
| 584308fc06 | |||
| 48ad2c44bf | |||
| 100998330a | |||
| b9e85c62be | |||
| 77fad099d2 | |||
| e1f8a6e82b | |||
| 132d767647 | |||
| 9cde98cbc7 | |||
| 1ddbb3ec3e | |||
| 34f40266b2 | |||
| b8c06e3f1b | |||
| a6cf648b3c | |||
| aebde27f1b | |||
| c9be327d53 | |||
| 3dc7d22d90 | |||
| c10c6cac74 | |||
| cee2c4c569 | |||
| a5160c82dc | |||
| 8853312197 | |||
| 049b24de21 | |||
| a9f987a0c9 | |||
| ad4a20d3d2 | |||
| b3972d1b65 | |||
| c3e0d58b3c | |||
| f08156ea9b | |||
| 4bacf5a5da | |||
| df88873bb7 | |||
| c4b1c5e8f1 | |||
| 9822711ad2 | |||
| 30cd764b6d | |||
| 38b75cdb2d | |||
| 6cb8b39af8 | |||
| ebaa336614 | |||
| ef5f567f91 | |||
| 64e5afc478 | |||
| 1e582e4fa4 | |||
| 7421235f24 | |||
| 09ba69078d | |||
| 3536e83d8a | |||
| 3bb1dd5d7f | |||
| 95f964b827 | |||
| c8f78a8ca9 | |||
| f34d48087b | |||
| 2c9ecd01b1 | |||
| a584fb6e15 | |||
| 1f13313f40 | |||
| 5b60303781 | |||
| 10e2552a7d | |||
| ef48b0aa55 | |||
| f57872bca0 | |||
| 2deaf2877e | |||
| 7a146c9cd5 | |||
| 2796ec172b | |||
| 6997c1bf0c | |||
| 4a030f3834 | |||
| f78d8b8ff3 | |||
| f27d19ed60 | |||
| 4a5eaf7bec | |||
| 8513674911 | |||
| 97b74ad6fb | |||
| a47ea79023 | |||
| 5ca0de6487 | |||
| 50a449f053 | |||
| d7422da7d7 | |||
| c7cbc978c6 | |||
| 27146e8a7f | |||
| 5e418b1145 | |||
| f4bb973eb7 | |||
| 848857aa5b | |||
| ee8a05d3f1 | |||
| 275ebbf0ec | |||
| 0f23df4c06 | |||
| 11f700f7bd | |||
| 5785f2a991 | |||
| 2546c29f81 | |||
| 19ea708c9d | |||
| 5cf05d67f2 | |||
| 0377c6f0e8 | |||
| 9c13866824 | |||
| 419a4813e3 | |||
| 131af8272d | |||
| c219a46f59 | |||
| 25f008f541 | |||
| 4a593db79b | |||
| ad4fef0431 | |||
| 8a15fcc1f5 | |||
| f01212ab52 | |||
| 28693a1a67 | |||
| 29fd499552 | |||
| 2f97d9d647 | |||
| 4146b38459 | |||
| 05aab660ce | |||
| 5ecb64849e | |||
| 59dfe1b5a0 | |||
| 50ebfb735c | |||
| 0bdbfe5069 | |||
| 3fc4d6028c | |||
| 2eb12a052b | |||
| bd63b2235c | |||
| f418ffd083 | |||
| 6ab5f8ce4b | |||
| becfeb5aa3 | |||
| eb968c4a68 | |||
| 7f2af3f923 | |||
| cce98ff53a | |||
| b607618342 | |||
| fa50fbaf57 | |||
| f135e2dc05 | |||
| 780351db5e | |||
| a50bb0bfec | |||
| 4d86df6f48 | |||
| bb464d16b4 | |||
| 85b2eb1472 | |||
| 7608f92c6a | |||
| c0bf8db63c | |||
| c95a6737fb | |||
| cd43d24402 | |||
| 086c5d0354 | |||
| 2a2ac5f53a | |||
| 21deaf637a | |||
| 72e15a3a83 | |||
| 174cb4a8c8 | |||
| 33f769b0a1 | |||
| c8abf20558 | |||
| 6dbb183e75 | |||
| bc4844d3b2 | |||
| 708f8b47de | |||
| 5518126d42 | |||
| 5fe73fdc3a | |||
| 394c496bf2 | |||
| 8e1aeba715 | |||
| 0e6e7eb477 | |||
| 183f636816 | |||
| 5f8ed63f2a | |||
| e4f3c94e31 | |||
| 1e5cbcbd93 | |||
| dcf3ec160f | |||
| a7beb5b6d3 | |||
| 1d3b65adc2 | |||
| d528644fe3 | |||
| 6f1bcfc14e | |||
| 996914c6b0 | |||
| fff048d099 | |||
| dcb0da8225 | |||
| b664e20d12 | |||
| 3d68b95028 | |||
| 163aca336d |
+1
-1
@@ -1,4 +1,4 @@
|
||||
# https://editorconfig.org
|
||||
# http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
|
||||
+2
-1
@@ -1,4 +1,6 @@
|
||||
bower_components/**
|
||||
build/**
|
||||
docs/bower_components/**
|
||||
docs/app/assets/js/angular-bootstrap/**
|
||||
docs/config/templates/**
|
||||
node_modules/**
|
||||
@@ -7,4 +9,3 @@ src/angular.bind.js
|
||||
src/ngParseExt/ucd.js
|
||||
i18n/closure/**
|
||||
tmp/**
|
||||
vendor/**
|
||||
|
||||
+2
-7
@@ -1,13 +1,8 @@
|
||||
{
|
||||
"extends": "./.eslintrc-base.json",
|
||||
|
||||
"env": {
|
||||
"browser": false,
|
||||
"node": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2017
|
||||
},
|
||||
"plugins": [
|
||||
"promise"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ https://plnkr.co or similar (you can use this template as a starting point: http
|
||||
<!-- Check whether this is still an issue in the most recent stable or in the snapshot AngularJS
|
||||
version (https://code.angularjs.org/snapshot/) -->
|
||||
|
||||
**Browser:** [all | Chrome XX | Firefox XX | Edge XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView | Opera XX ]
|
||||
**Browser:** [all | Chrome XX | Firefox XX | Edge XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
|
||||
<!-- All browsers where this could be reproduced (and Operating System if relevant) -->
|
||||
|
||||
**Anything else:**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!-- General PR submission guidelines https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#submit-pr -->
|
||||
<!-- General PR submission guidelines https://github.com/angular/angular.js/CONTRIBUTING.md#submit-pr -->
|
||||
**What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)**
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
|
||||
**Please check if the PR fulfills these requirements**
|
||||
- [ ] The commit message follows our [guidelines](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#commits)
|
||||
- [ ] Fix/Feature: [Docs](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#documentation) have been added/updated
|
||||
- [ ] The commit message follows our [guidelines](../DEVELOPERS.md#commits)
|
||||
- [ ] Fix/Feature: [Docs](../DEVELOPERS.md#documentation) have been added/updated
|
||||
- [ ] Fix/Feature: Tests have been added; existing tests pass
|
||||
|
||||
**Other information**:
|
||||
|
||||
+3
-2
@@ -1,5 +1,4 @@
|
||||
/build/
|
||||
/deploy/
|
||||
/benchpress-build/
|
||||
.DS_Store
|
||||
gen_docs.disable
|
||||
@@ -11,6 +10,7 @@ performance/temp*.html
|
||||
*.swp
|
||||
angular.js.tmproj
|
||||
node_modules/
|
||||
bower_components/
|
||||
angular.xcodeproj
|
||||
.idea
|
||||
*.iml
|
||||
@@ -19,6 +19,7 @@ angular.xcodeproj
|
||||
libpeerconnection.log
|
||||
npm-debug.log
|
||||
/tmp/
|
||||
/scripts/bower/bower-*
|
||||
.vscode
|
||||
*.log
|
||||
*.stackdump
|
||||
*.stackdump
|
||||
+6
-5
@@ -5,6 +5,8 @@ node_js:
|
||||
|
||||
cache:
|
||||
yarn: true
|
||||
directories:
|
||||
- bower_components
|
||||
|
||||
branches:
|
||||
except:
|
||||
@@ -15,7 +17,6 @@ env:
|
||||
- JOB=ci-checks
|
||||
- JOB=unit-core BROWSER_PROVIDER=saucelabs
|
||||
- JOB=unit-jquery BROWSER_PROVIDER=saucelabs
|
||||
- JOB=unit-modules BROWSER_PROVIDER=saucelabs
|
||||
- JOB=docs-app BROWSER_PROVIDER=saucelabs
|
||||
- JOB=e2e TEST_TARGET=jqlite BROWSER_PROVIDER=saucelabs
|
||||
- JOB=e2e TEST_TARGET=jquery BROWSER_PROVIDER=saucelabs
|
||||
@@ -27,12 +28,13 @@ env:
|
||||
- secure: oTBjhnOKhs0qDSKTf7fE4f6DYiNDPycvB7qfSF5QRIbJK/LK/J4UtFwetXuXj79HhUZG9qnoT+5e7lPaiaMlpsIKn9ann7ffqFWN1E8TMtpJF+AGigx3djYElwfgf5nEnFUFhwjFzvbfpZNnxVGgX5YbIZpe/WUbHkP4ffU0Wks=
|
||||
|
||||
before_install:
|
||||
- curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.10.1
|
||||
- curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.3.2
|
||||
- export PATH="$HOME/.yarn/bin:$PATH"
|
||||
|
||||
before_script:
|
||||
- du -sh ./node_modules || true
|
||||
- du -sh ./node_modules ./bower_components/ || true
|
||||
- "./scripts/travis/before_build.sh"
|
||||
|
||||
script:
|
||||
- "./scripts/travis/build.sh"
|
||||
|
||||
@@ -82,7 +84,6 @@ jobs:
|
||||
- provider: firebase
|
||||
# the upload folder for firebase is configured in /firebase.json
|
||||
skip_cleanup: true
|
||||
project: docs-angularjs-org-9p2
|
||||
token:
|
||||
secure: $FIREBASE_TOKEN
|
||||
on:
|
||||
@@ -95,7 +96,7 @@ jobs:
|
||||
secret_access_key:
|
||||
secure: tHIFdSq55qkyZf9zT/3+VkhUrTvOTMuswxXU3KyWaBrSieZqG0UnUDyNm+n3lSfX95zEl/+rJAWbfvhVSxZi13ndOtvRF+MdI1cvow2JynP0aDSiPffEvVrZOmihD6mt2SlMfhskr5FTduQ69kZG6DfLcve1PPDaIwnbOv3phb8=
|
||||
bucket: code-angularjs-org-338b8.appspot.com
|
||||
local-dir: deploy/code
|
||||
local-dir: uploadCode
|
||||
detect_encoding: true # detects gzip compression
|
||||
on:
|
||||
repo: angular/angular.js
|
||||
|
||||
+2
-2073
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
# Contributor Code of Conduct
|
||||
|
||||
The AngularJS project follows the Code of Conduct defined in [the angular/code-of-conduct repository](https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md). Please read it.
|
||||
+10
-13
@@ -1,7 +1,6 @@
|
||||
# Developing AngularJS
|
||||
|
||||
* [Development Setup](#setup)
|
||||
* [Running Tests](#tests)
|
||||
* [Coding Rules](#rules)
|
||||
* [Commit Message Guidelines](#commits)
|
||||
* [Writing Documentation](#documentation)
|
||||
@@ -9,7 +8,7 @@
|
||||
## <a name="setup"> Development Setup
|
||||
|
||||
This document describes how to set up your development environment to build and test AngularJS, and
|
||||
explains the basic mechanics of using `git`, `node`, `yarn` and `grunt`.
|
||||
explains the basic mechanics of using `git`, `node`, `yarn`, `grunt`, and `bower`.
|
||||
|
||||
### Installing Dependencies
|
||||
|
||||
@@ -19,7 +18,7 @@ machine:
|
||||
* [Git](http://git-scm.com/): The [Github Guide to
|
||||
Installing Git][git-setup] is a good source of information.
|
||||
|
||||
* [Node.js v8.x (LTS)](http://nodejs.org): We use Node to generate the documentation, run a
|
||||
* [Node.js v6.x (LTS)](http://nodejs.org): We use Node to generate the documentation, run a
|
||||
development web server, run tests, and generate distributable files. Depending on your system,
|
||||
you can install Node either from source or as a pre-packaged bundle.
|
||||
|
||||
@@ -64,10 +63,10 @@ cd angular.js
|
||||
# Add the main AngularJS repository as an upstream remote to your repository:
|
||||
git remote add upstream "https://github.com/angular/angular.js.git"
|
||||
|
||||
# Install JavaScript dependencies:
|
||||
# Install node.js dependencies:
|
||||
yarn install
|
||||
|
||||
# Build AngularJS:
|
||||
# Build AngularJS (which will install `bower` dependencies automatically):
|
||||
yarn grunt package
|
||||
```
|
||||
|
||||
@@ -108,8 +107,6 @@ HTTP server. For this purpose, we have made available a local web server based o
|
||||
http://localhost:8000/build/docs/
|
||||
```
|
||||
|
||||
## <a name="tests"> Running Tests
|
||||
|
||||
### <a name="unit-tests"></a> Running the Unit Test Suite
|
||||
|
||||
We write unit and integration tests with Jasmine and execute them with Karma. To run all of the
|
||||
@@ -119,7 +116,7 @@ tests once on Chrome run:
|
||||
yarn grunt test:unit
|
||||
```
|
||||
|
||||
To run the tests on other browsers use the command line flag:
|
||||
To run the tests on other browsers (Chrome, ChromeCanary, Firefox and Safari are pre-configured) use:
|
||||
|
||||
```shell
|
||||
yarn grunt test:unit --browsers=Chrome,Firefox
|
||||
@@ -128,15 +125,15 @@ yarn grunt test:unit --browsers=Chrome,Firefox
|
||||
**Note:** there should be _no spaces between browsers_. `Chrome, Firefox` is INVALID.
|
||||
|
||||
If you have a Saucelabs or Browserstack account, you can also run the unit tests on these services
|
||||
via our pre-defined customLaunchers. See the [karma config file](/karma-shared.conf.js) for all pre-configured browsers.
|
||||
via our pre-defined customLaunchers.
|
||||
|
||||
For example, to run the whole unit test suite on selected browsers:
|
||||
For example, to run the whole unit test suite:
|
||||
|
||||
```shell
|
||||
# Browserstack
|
||||
yarn grunt test:unit --browsers=BS_Chrome,BS_Firefox,BS_Safari,BS_IE_9,BS_IE_10,BS_IE_11,BS_EDGE,BS_iOS_10
|
||||
yarn grunt test:unit --browsers=BS_Chrome,BS_Firefox,BS_Safari,BS_IE_9,BS_IE_10,BS_IE_11,BS_EDGE,BS_iOS_8,BS_iOS_9,BS_iOS_10
|
||||
# Saucelabs
|
||||
yarn grunt test:unit --browsers=SL_Chrome,SL_Firefox,SL_Safari,SL_IE_9,SL_IE_10,SL_IE_11,SL_EDGE,SL_iOS_10
|
||||
yarn grunt test:unit --browsers=BS_Chrome,BS_Firefox,BS_Safari,BS_IE_9,BS_IE_10,BS_IE_11,BS_EDGE,BS_iOS_8,BS_iOS_9,BS_iOS_10
|
||||
```
|
||||
|
||||
Running these commands requires you to set up [Karma Browserstack][karma-browserstack] or
|
||||
@@ -486,4 +483,4 @@ You can see an example of a well-defined example [in the `ngRepeat` documentatio
|
||||
[karma-browserstack]: https://github.com/karma-runner/karma-browserstack-launcher
|
||||
[karma-saucelabs]: https://github.com/karma-runner/karma-sauce-launcher
|
||||
[unit-testing]: https://docs.angularjs.org/guide/unit-testing
|
||||
[yarn-install]: https://yarnpkg.com/en/docs/install
|
||||
[yarn-install]: https://yarnpkg.com/en/docs/install
|
||||
+26
-100
@@ -4,7 +4,6 @@ var serveFavicon = require('serve-favicon');
|
||||
var serveStatic = require('serve-static');
|
||||
var serveIndex = require('serve-index');
|
||||
var files = require('./angularFiles').files;
|
||||
var mergeFilesFor = require('./angularFiles').mergeFilesFor;
|
||||
var util = require('./lib/grunt/utils.js');
|
||||
var versionInfo = require('./lib/versions/version-info');
|
||||
var path = require('path');
|
||||
@@ -14,8 +13,6 @@ var semver = require('semver');
|
||||
var exec = require('shelljs').exec;
|
||||
var pkg = require(__dirname + '/package.json');
|
||||
|
||||
var docsScriptFolder = 'scripts/docs.angularjs.org-firebase';
|
||||
|
||||
// Node.js version checks
|
||||
if (!semver.satisfies(process.version, pkg.engines.node)) {
|
||||
reportOrFail('Invalid node version (' + process.version + '). ' +
|
||||
@@ -31,7 +28,7 @@ if (!semver.satisfies(currentYarnVersion, expectedYarnVersion)) {
|
||||
}
|
||||
|
||||
// Grunt CLI version checks
|
||||
var expectedGruntVersion = pkg.engines['grunt-cli'];
|
||||
var expectedGruntVersion = pkg.engines.grunt;
|
||||
var currentGruntVersions = exec('grunt --version', {silent: true}).stdout;
|
||||
var match = /^grunt-cli v(.+)$/m.exec(currentGruntVersions);
|
||||
if (!match) {
|
||||
@@ -142,9 +139,7 @@ module.exports = function(grunt) {
|
||||
'jquery-2.2': 'karma-jquery-2.2.conf.js',
|
||||
'jquery-2.1': 'karma-jquery-2.1.conf.js',
|
||||
docs: 'karma-docs.conf.js',
|
||||
modules: 'karma-modules.conf.js',
|
||||
'modules-ngAnimate': 'karma-modules-ngAnimate.conf.js',
|
||||
'modules-ngMock': 'karma-modules-ngMock.conf.js'
|
||||
modules: 'karma-modules.conf.js'
|
||||
},
|
||||
|
||||
|
||||
@@ -167,12 +162,7 @@ module.exports = function(grunt) {
|
||||
|
||||
clean: {
|
||||
build: ['build'],
|
||||
tmp: ['tmp'],
|
||||
deploy: [
|
||||
'deploy/docs',
|
||||
'deploy/code',
|
||||
docsScriptFolder + '/functions/html'
|
||||
]
|
||||
tmp: ['tmp']
|
||||
},
|
||||
|
||||
eslint: {
|
||||
@@ -183,11 +173,11 @@ module.exports = function(grunt) {
|
||||
'docs/**/*.js',
|
||||
'lib/**/*.js',
|
||||
'scripts/**/*.js',
|
||||
'!scripts/*/*/node_modules/**',
|
||||
'src/**/*.js',
|
||||
'test/**/*.js',
|
||||
'i18n/**/*.js',
|
||||
'!docs/app/assets/js/angular-bootstrap/**',
|
||||
'!docs/bower_components/**',
|
||||
'!docs/config/templates/**',
|
||||
'!src/angular.bind.js',
|
||||
'!i18n/closure/**',
|
||||
@@ -197,6 +187,16 @@ module.exports = function(grunt) {
|
||||
},
|
||||
|
||||
build: {
|
||||
scenario: {
|
||||
dest: 'build/angular-scenario.js',
|
||||
src: [
|
||||
'bower_components/jquery/dist/jquery.js',
|
||||
util.wrap([files['angularSrc'], files['angularScenario']], 'ngScenario/angular')
|
||||
],
|
||||
styles: {
|
||||
css: ['css/angular.css', 'css/angular-scenario.css']
|
||||
}
|
||||
},
|
||||
angular: {
|
||||
dest: 'build/angular.js',
|
||||
src: util.wrap([files['angularSrc']], 'angular'),
|
||||
@@ -214,12 +214,6 @@ module.exports = function(grunt) {
|
||||
dest: 'build/angular-touch.js',
|
||||
src: util.wrap(files['angularModules']['ngTouch'], 'module')
|
||||
},
|
||||
touchModuleTestBundle: {
|
||||
dest: 'build/test-bundles/angular-touch.js',
|
||||
prefix: 'src/module.prefix',
|
||||
src: mergeFilesFor('karmaModules-ngTouch'),
|
||||
suffix: 'src/module.suffix'
|
||||
},
|
||||
mocks: {
|
||||
dest: 'build/angular-mocks.js',
|
||||
src: util.wrap(files['angularModules']['ngMock'], 'module'),
|
||||
@@ -229,42 +223,18 @@ module.exports = function(grunt) {
|
||||
dest: 'build/angular-sanitize.js',
|
||||
src: util.wrap(files['angularModules']['ngSanitize'], 'module')
|
||||
},
|
||||
sanitizeModuleTestBundle: {
|
||||
dest: 'build/test-bundles/angular-sanitize.js',
|
||||
prefix: 'src/module.prefix',
|
||||
src: mergeFilesFor('karmaModules-ngSanitize'),
|
||||
suffix: 'src/module.suffix'
|
||||
},
|
||||
resource: {
|
||||
dest: 'build/angular-resource.js',
|
||||
src: util.wrap(files['angularModules']['ngResource'], 'module')
|
||||
},
|
||||
resourceModuleTestBundle: {
|
||||
dest: 'build/test-bundles/angular-resource.js',
|
||||
prefix: 'src/module.prefix',
|
||||
src: mergeFilesFor('karmaModules-ngResource'),
|
||||
suffix: 'src/module.suffix'
|
||||
},
|
||||
messageformat: {
|
||||
dest: 'build/angular-message-format.js',
|
||||
src: util.wrap(files['angularModules']['ngMessageFormat'], 'module')
|
||||
},
|
||||
messageformatModuleTestBundle: {
|
||||
dest: 'build/test-bundles/angular-message-format.js',
|
||||
prefix: 'src/module.prefix',
|
||||
src: mergeFilesFor('karmaModules-ngMessageFormat'),
|
||||
suffix: 'src/module.suffix'
|
||||
},
|
||||
messages: {
|
||||
dest: 'build/angular-messages.js',
|
||||
src: util.wrap(files['angularModules']['ngMessages'], 'module')
|
||||
},
|
||||
messagesModuleTestBundle: {
|
||||
dest: 'build/test-bundles/angular-messages.js',
|
||||
prefix: 'src/module.prefix',
|
||||
src: mergeFilesFor('karmaModules-ngMessages'),
|
||||
suffix: 'src/module.suffix'
|
||||
},
|
||||
animate: {
|
||||
dest: 'build/angular-animate.js',
|
||||
src: util.wrap(files['angularModules']['ngAnimate'], 'module')
|
||||
@@ -273,32 +243,14 @@ module.exports = function(grunt) {
|
||||
dest: 'build/angular-route.js',
|
||||
src: util.wrap(files['angularModules']['ngRoute'], 'module')
|
||||
},
|
||||
routeModuleTestBundle: {
|
||||
dest: 'build/test-bundles/angular-route.js',
|
||||
prefix: 'src/module.prefix',
|
||||
src: mergeFilesFor('karmaModules-ngRoute'),
|
||||
suffix: 'src/module.suffix'
|
||||
},
|
||||
cookies: {
|
||||
dest: 'build/angular-cookies.js',
|
||||
src: util.wrap(files['angularModules']['ngCookies'], 'module')
|
||||
},
|
||||
cookiesModuleTestBundle: {
|
||||
dest: 'build/test-bundles/angular-cookies.js',
|
||||
prefix: 'src/module.prefix',
|
||||
src: mergeFilesFor('karmaModules-ngCookies'),
|
||||
suffix: 'src/module.suffix'
|
||||
},
|
||||
aria: {
|
||||
dest: 'build/angular-aria.js',
|
||||
src: util.wrap(files['angularModules']['ngAria'], 'module')
|
||||
},
|
||||
ariaModuleTestBundle: {
|
||||
dest: 'build/test-bundles/angular-aria.js',
|
||||
prefix: 'src/module.prefix',
|
||||
src: mergeFilesFor('karmaModules-ngAria'),
|
||||
suffix: 'src/module.suffix'
|
||||
},
|
||||
parseext: {
|
||||
dest: 'build/angular-parse-ext.js',
|
||||
src: util.wrap(files['angularModules']['ngParseExt'], 'module')
|
||||
@@ -330,7 +282,9 @@ module.exports = function(grunt) {
|
||||
files: [
|
||||
'src/**/*.js',
|
||||
'test/**/*.js',
|
||||
'!test/ngScenario/DescribeSpec.js',
|
||||
'!src/ng/directive/attrs.js', // legitimate xit here
|
||||
'!src/ngScenario/**/*.js',
|
||||
'!test/helpers/privateMocks*.js'
|
||||
],
|
||||
options: {
|
||||
@@ -370,44 +324,19 @@ module.exports = function(grunt) {
|
||||
}
|
||||
]
|
||||
},
|
||||
deployFirebaseCode: {
|
||||
files: [
|
||||
// copy files that are not handled by compress
|
||||
{
|
||||
cwd: 'build',
|
||||
src: '**/*.{zip,jpg,jpeg,png}',
|
||||
dest: 'deploy/code/' + deployVersion + '/',
|
||||
expand: true
|
||||
}
|
||||
]
|
||||
},
|
||||
deployFirebaseDocs: {
|
||||
files: [
|
||||
// The source files are needed by the embedded examples in the docs app.
|
||||
{
|
||||
src: ['build/angular*.{js,js.map,min.js}', 'build/sitemap.xml'],
|
||||
dest: 'deploy/docs/',
|
||||
src: 'build/angular*.{js.map,min.js}',
|
||||
dest: 'uploadDocs/',
|
||||
expand: true,
|
||||
flatten: true
|
||||
},
|
||||
{
|
||||
cwd: 'build/docs',
|
||||
src: ['**', '!ptore2e/**', '!index*.html'],
|
||||
dest: 'deploy/docs/',
|
||||
expand: true
|
||||
},
|
||||
{
|
||||
src: 'build/docs/index-production.html',
|
||||
dest: 'deploy/docs/index.html'
|
||||
},
|
||||
{
|
||||
src: 'build/docs/index-production.html',
|
||||
dest: docsScriptFolder + '/functions/content/index.html'
|
||||
},
|
||||
{
|
||||
cwd: 'build/docs',
|
||||
src: 'partials/**',
|
||||
dest: docsScriptFolder + '/functions/content',
|
||||
src: '**',
|
||||
dest: 'uploadDocs/',
|
||||
expand: true
|
||||
}
|
||||
]
|
||||
@@ -428,11 +357,10 @@ module.exports = function(grunt) {
|
||||
options: {
|
||||
mode: 'gzip'
|
||||
},
|
||||
// Already compressed files should not be compressed again
|
||||
src: ['**', '!**/*.{zip,png,jpeg,jpg}'],
|
||||
src: ['**'],
|
||||
cwd: 'build',
|
||||
expand: true,
|
||||
dest: 'deploy/code/' + deployVersion + '/'
|
||||
dest: 'uploadCode/' + deployVersion + '/'
|
||||
}
|
||||
},
|
||||
|
||||
@@ -481,9 +409,7 @@ module.exports = function(grunt) {
|
||||
grunt.registerTask('test:jquery-2.1', 'Run the jQuery 2.1 unit tests with Karma', ['tests:jquery-2.1']);
|
||||
grunt.registerTask('test:modules', 'Run the Karma module tests with Karma', [
|
||||
'build',
|
||||
'tests:modules',
|
||||
'tests:modules-ngAnimate',
|
||||
'tests:modules-ngMock'
|
||||
'tests:modules'
|
||||
]);
|
||||
grunt.registerTask('test:docs', 'Run the doc-page tests with Karma', ['package', 'tests:docs']);
|
||||
grunt.registerTask('test:unit', 'Run unit, jQuery and Karma module tests with Karma', [
|
||||
@@ -513,12 +439,14 @@ module.exports = function(grunt) {
|
||||
'shell:promises-aplus-tests'
|
||||
]);
|
||||
grunt.registerTask('minify', [
|
||||
'bower',
|
||||
'clean',
|
||||
'build',
|
||||
'minall'
|
||||
]);
|
||||
grunt.registerTask('webserver', ['connect:devserver']);
|
||||
grunt.registerTask('package', [
|
||||
'bower',
|
||||
'validate-angular-files',
|
||||
'clean',
|
||||
'buildall',
|
||||
@@ -534,11 +462,9 @@ module.exports = function(grunt) {
|
||||
'merge-conflict',
|
||||
'eslint'
|
||||
]);
|
||||
grunt.registerTask('prepareDeploy', [
|
||||
grunt.registerTask('prepareFirebaseDeploy', [
|
||||
'package',
|
||||
'compress:deployFirebaseCode',
|
||||
'copy:deployFirebaseCode',
|
||||
'firebaseDocsJsonForTravis',
|
||||
'copy:deployFirebaseDocs'
|
||||
]);
|
||||
grunt.registerTask('default', ['package']);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2010-2018 Google, Inc. http://angularjs.org
|
||||
Copyright (c) 2010-2017 Google, Inc. http://angularjs.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ in its `contrib/externs` directory.
|
||||
The definitions contain externs for use with the Closure compiler (aka
|
||||
JSCompiler). Passing these files to the --externs parameter of a compiler
|
||||
pass allows using type annotations for AngularJS objects. For example,
|
||||
AngularJS's $scope objects can be annotated as:
|
||||
Angular's $scope objects can be annotated as:
|
||||
```js
|
||||
/** @type {angular.Scope} */
|
||||
var scope = $scope;
|
||||
|
||||
@@ -12,14 +12,6 @@ It also helps with server-side communication, taming async callbacks with promis
|
||||
and it makes client-side navigation and deep linking with hashbang urls or HTML5 pushState a
|
||||
piece of cake. Best of all? It makes development fun!
|
||||
|
||||
--------------------
|
||||
|
||||
**On July 1, 2018 AngularJS entered a 3 year Long Term Support period:** [Find out more](https://docs.angularjs.org/misc/version-support-status)
|
||||
|
||||
**Looking for the new Angular? Go here:** https://github.com/angular/angular
|
||||
|
||||
--------------------
|
||||
|
||||
* Web site: https://angularjs.org
|
||||
* Tutorial: https://docs.angularjs.org/tutorial
|
||||
* API Docs: https://docs.angularjs.org/api
|
||||
@@ -28,6 +20,7 @@ piece of cake. Best of all? It makes development fun!
|
||||
* Core Development: [DEVELOPERS.md](DEVELOPERS.md)
|
||||
* Dashboard: https://dashboard.angularjs.org
|
||||
|
||||
##### Looking for Angular 2? Go here: https://github.com/angular/angular
|
||||
|
||||
Documentation
|
||||
--------------------
|
||||
@@ -79,7 +72,7 @@ HTML is also used to determine the wiring of the app. Special attributes in the
|
||||
to load the app, which components or controllers to use for each element, etc. We specify "what"
|
||||
gets loaded, but not "how". This declarative approach greatly simplifies app development in a sort
|
||||
of WYSIWYG way. Rather than spending time on how the program flows and orchestrating the various
|
||||
moving parts, we simply define what we want and AngularJS will take care of the dependencies.
|
||||
moving parts, we simply define what we want and Angular will take care of the dependencies.
|
||||
|
||||
#### Data Handling made simple
|
||||
Data and Data Models in AngularJS are plain JavaScript objects and one can add and change properties
|
||||
|
||||
-98
@@ -1,98 +0,0 @@
|
||||
# AngularJS Release instructions
|
||||
|
||||
|
||||
## Compare the list of commits between stable and unstable
|
||||
|
||||
There is a script - compare-master-to-stable.js - that helps with this.
|
||||
We just want to make sure that good commits (low risk fixes + docs fixes) got cherry-picked into stable branch and nothing interesting got merged only into stable branch.
|
||||
|
||||
|
||||
## Pick a release name (for this version)
|
||||
|
||||
A super-heroic power (adverb-verb phrase).
|
||||
|
||||
|
||||
## Generate release notes
|
||||
|
||||
Example Commit: https://github.com/angular/angular.js/commit/7ab5098c14ee4f195dbfe2681e402fe2dfeacd78
|
||||
|
||||
1) Run
|
||||
|
||||
```bash
|
||||
node_modules/.bin/changez -o changes.md -v <new version> <base branch>
|
||||
```
|
||||
|
||||
2) Review the generated file and manually fix typos, group and reorder stuff if needed.
|
||||
3) Move the content into CHANGELOG.md add release code-names to headers.
|
||||
4) Push the changes to your private github repo and review.
|
||||
5) cherry-pick the release notes commit to the appropriate branches.
|
||||
|
||||
|
||||
## Pick a commit to release (for this version)
|
||||
|
||||
Usually this will be the commit containing the release notes, but it may also be in the past.
|
||||
|
||||
|
||||
## Run "release" script
|
||||
|
||||
```bash
|
||||
scripts/jenkins/release.sh --git-push-dryrun=false --commit-sha=8822a4f --version-number=1.7.6 --version-name=gravity-manipulation
|
||||
```
|
||||
|
||||
1) The SHA is of the commit to release (could be in the past).
|
||||
|
||||
2) The version number and code-name that should be released, not the next version number (e.g. to release 1.2.12 you enter 1.2.12 as release version and the code-name that was picked for 1.2.12, cauliflower-eradication).
|
||||
|
||||
3) You will need to have write access to all the AngularJS github dist repositories and publish rights for the AngularJS packages on npm.
|
||||
|
||||
|
||||
## Update GitHub milestones
|
||||
|
||||
1) Create the next milestone if it doesn't exist yet-giving ita due date.
|
||||
2) Move all open issues and PRs for the current milestone to the next milestone<br>
|
||||
You can do this by filtering the current milestone, selecting via checklist, and moving to the next milestone within the GH issues page.
|
||||
|
||||
3) Close the current milestone click the milestones tab and close from there.
|
||||
4) Create a new holding milestone for the release after next-but don't give it a due date otherwise that will mess up the dashboard.
|
||||
|
||||
|
||||
## Push build artifacts to CDN
|
||||
|
||||
Google CDNs are fed with data from google3 every day at 11:15am PT it takes only few minutes for the import to propagate).
|
||||
If we want to make our files available, we need submit our CLs before this time on the day of the release.
|
||||
|
||||
|
||||
## Don't update the package.json (branchVersion) until the CDN has updated
|
||||
|
||||
This is the version used to compute what version to link to in the CDN. If you update this too early then the CDN lookup fails and you end up with 'null, for the version, which breaks the docs.
|
||||
|
||||
|
||||
## Verify angularjs.org download modal has latest version (updates via Travis job)
|
||||
|
||||
The versions in the modal are updated (based on the versions available on CDN) as part of the Travis deploy stage: https://github.com/angular/angularjs.org/blob/a4d25c5abcd39e8ce19d31cb1c78073d13c4c974/.travis.yml#L26
|
||||
(You may need to explicitly trigger the Travis job. e.g. re-running the last job.)
|
||||
|
||||
|
||||
## Announce the release (via official Google accounts)
|
||||
|
||||
Double check that angularjs.org is up to date with the new release version before sharing.
|
||||
|
||||
1) Collect a list of contributors
|
||||
|
||||
use: `git log --format='%aN' v1.2.12..v1.2.13 | sort -u`
|
||||
|
||||
2) Write a blog post (for minor releases, not patch releases) and publish it with the "release" tag
|
||||
3) Post on twitter as yourself (tweet from your heart; there is no template for this), retweet as @AngularJS
|
||||
|
||||
|
||||
## Party!
|
||||
|
||||
|
||||
## Major Release Tasks
|
||||
|
||||
1) Update angularjs.org to use the latest branch.
|
||||
2) Write up a migration document.
|
||||
3) Create a new git branch for the version that has been released (e.g. 1.8.x).
|
||||
4) Check that the build and release scripts still work.
|
||||
5) Update the dist-tag of the old branch, see https://github.com/angular/angular.js/pull/12722.
|
||||
6) Write a blog post.
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
# Triage new issues/PRs on github
|
||||
|
||||
This document shows the steps the AngularJS team is using to triage issues.
|
||||
This document shows the steps the Angular team is using to triage issues.
|
||||
The labels are used later on for [planning releases](#assigning-work).
|
||||
|
||||
|
||||
@@ -45,12 +45,12 @@ This process based on the idea of minimizing user pain
|
||||
1. Label `frequency: *` – How often does this issue come up? How many developers does this affect? Chose just one of the following:
|
||||
* low - obscure issue affecting a handful of developers
|
||||
* moderate - impacts a common usage pattern
|
||||
* high - impacts most or all AngularJS apps
|
||||
* high - impacts most or all Angular apps
|
||||
1. Label `severity: *` - How bad is the issue? Chose just one of the following:
|
||||
* security issue
|
||||
* regression
|
||||
* memory leak
|
||||
* broken expected use - it's hard or impossible for a developer using AngularJS to accomplish something that AngularJS should be able to do
|
||||
* broken expected use - it's hard or impossible for a developer using Angular to accomplish something that Angular should be able to do
|
||||
* confusing - unexpected or inconsistent behavior; hard-to-debug
|
||||
* inconvenience - causes ugly/boilerplate code in apps
|
||||
1. Label `component: *`
|
||||
@@ -95,7 +95,7 @@ You can mention him in the relevant thread like this: `@btford`.
|
||||
|
||||
> Thanks for submitting this issue!
|
||||
> Unfortunately, we don't think this functionality belongs in core.
|
||||
> The good news is that you could easily implement this as a third-party module and publish it to the npm registry.
|
||||
> The good news is that you could easily implement this as a third-party module and publish it on Bower and/or to the npm repository.
|
||||
|
||||
|
||||
## Assigning Work
|
||||
|
||||
Vendored
+46
-84
@@ -28,7 +28,6 @@ var angularFiles = {
|
||||
'src/ng/httpBackend.js',
|
||||
'src/ng/interpolate.js',
|
||||
'src/ng/interval.js',
|
||||
'src/ng/intervalFactory.js',
|
||||
'src/ng/jsonpCallbacks.js',
|
||||
'src/ng/locale.js',
|
||||
'src/ng/location.js',
|
||||
@@ -41,7 +40,6 @@ var angularFiles = {
|
||||
'src/ng/sanitizeUri.js',
|
||||
'src/ng/sce.js',
|
||||
'src/ng/sniffer.js',
|
||||
'src/ng/taskTrackerFactory.js',
|
||||
'src/ng/templateRequest.js',
|
||||
'src/ng/testability.js',
|
||||
'src/ng/timeout.js',
|
||||
@@ -76,7 +74,6 @@ var angularFiles = {
|
||||
'src/ng/directive/ngNonBindable.js',
|
||||
'src/ng/directive/ngOptions.js',
|
||||
'src/ng/directive/ngPluralize.js',
|
||||
'src/ng/directive/ngRef.js',
|
||||
'src/ng/directive/ngRepeat.js',
|
||||
'src/ng/directive/ngShowHide.js',
|
||||
'src/ng/directive/ngStyle.js',
|
||||
@@ -106,13 +103,13 @@ var angularFiles = {
|
||||
'src/ngAnimate/animateJs.js',
|
||||
'src/ngAnimate/animateJsDriver.js',
|
||||
'src/ngAnimate/animateQueue.js',
|
||||
'src/ngAnimate/animateCache.js',
|
||||
'src/ngAnimate/animation.js',
|
||||
'src/ngAnimate/ngAnimateSwap.js',
|
||||
'src/ngAnimate/module.js'
|
||||
],
|
||||
'ngCookies': [
|
||||
'src/ngCookies/cookies.js',
|
||||
'src/ngCookies/cookieStore.js',
|
||||
'src/ngCookies/cookieWriter.js'
|
||||
],
|
||||
'ngMessageFormat': [
|
||||
@@ -134,7 +131,6 @@ var angularFiles = {
|
||||
],
|
||||
'ngRoute': [
|
||||
'src/shallowCopy.js',
|
||||
'src/routeToRegExp.js',
|
||||
'src/ngRoute/route.js',
|
||||
'src/ngRoute/routeParams.js',
|
||||
'src/ngRoute/directive/ngView.js'
|
||||
@@ -144,13 +140,13 @@ var angularFiles = {
|
||||
'src/ngSanitize/filter/linky.js'
|
||||
],
|
||||
'ngMock': [
|
||||
'src/routeToRegExp.js',
|
||||
'src/ngMock/angular-mocks.js',
|
||||
'src/ngMock/browserTrigger.js'
|
||||
],
|
||||
'ngTouch': [
|
||||
'src/ngTouch/touch.js',
|
||||
'src/ngTouch/swipe.js',
|
||||
'src/ngTouch/directive/ngClick.js',
|
||||
'src/ngTouch/directive/ngSwipe.js'
|
||||
],
|
||||
'ngAria': [
|
||||
@@ -158,8 +154,26 @@ var angularFiles = {
|
||||
]
|
||||
},
|
||||
|
||||
'angularScenario': [
|
||||
'src/ngScenario/Scenario.js',
|
||||
'src/ngScenario/Application.js',
|
||||
'src/ngScenario/Describe.js',
|
||||
'src/ngScenario/Future.js',
|
||||
'src/ngScenario/ObjectModel.js',
|
||||
'src/ngScenario/Runner.js',
|
||||
'src/ngScenario/SpecRunner.js',
|
||||
'src/ngScenario/dsl.js',
|
||||
'src/ngScenario/matchers.js',
|
||||
'src/ngScenario/output/Html.js',
|
||||
'src/ngScenario/output/Json.js',
|
||||
'src/ngScenario/output/Xml.js',
|
||||
'src/ngScenario/output/Object.js'
|
||||
],
|
||||
|
||||
'angularTest': [
|
||||
'test/helpers/*.js',
|
||||
'test/ngScenario/*.js',
|
||||
'test/ngScenario/output/*.js',
|
||||
'test/*.js',
|
||||
'test/auto/*.js',
|
||||
'test/ng/**/*.js',
|
||||
@@ -176,97 +190,55 @@ var angularFiles = {
|
||||
],
|
||||
|
||||
'karma': [
|
||||
'node_modules/jquery/dist/jquery.js',
|
||||
'bower_components/jquery/dist/jquery.js',
|
||||
'test/jquery_remove.js',
|
||||
'@angularSrc',
|
||||
'@angularSrcModules',
|
||||
'@angularScenario',
|
||||
'@angularTest'
|
||||
],
|
||||
|
||||
'karmaExclude': [
|
||||
'test/jquery_alias.js',
|
||||
'src/angular-bootstrap.js',
|
||||
'src/ngScenario/angular-bootstrap.js',
|
||||
'src/angular.bind.js'
|
||||
],
|
||||
|
||||
'karmaModules-ngAnimate': [
|
||||
'karmaScenario': [
|
||||
'build/angular-scenario.js',
|
||||
'build/docs/docs-scenario.js'
|
||||
],
|
||||
|
||||
'karmaModules': [
|
||||
'build/angular.js',
|
||||
'build/angular-mocks.js',
|
||||
'@angularSrcModules',
|
||||
'test/modules/no_bootstrap.js',
|
||||
'test/helpers/matchers.js',
|
||||
'test/helpers/privateMocks.js',
|
||||
'test/helpers/support.js',
|
||||
'test/helpers/testabilityPatch.js',
|
||||
'@angularSrcModuleNgAnimate',
|
||||
'test/ngAnimate/**/*.js'
|
||||
],
|
||||
|
||||
'karmaModules-ngAria': [
|
||||
'@angularSrcModuleNgAria',
|
||||
'test/ngAria/**/*.js'
|
||||
],
|
||||
|
||||
'karmaModules-ngCookies': [
|
||||
'@angularSrcModuleNgCookies',
|
||||
'test/ngCookies/**/*.js'
|
||||
],
|
||||
|
||||
'karmaModules-ngMessageFormat': [
|
||||
'@angularSrcModuleNgMessageFormat',
|
||||
'test/ngMessageFormat/**/*.js'
|
||||
],
|
||||
|
||||
'karmaModules-ngMessages': [
|
||||
'build/angular-animate.js',
|
||||
'@angularSrcModuleNgMessages',
|
||||
'test/ngMessages/**/*.js'
|
||||
],
|
||||
|
||||
// ngMock doesn't include the base because it must use the ngMock src files
|
||||
'karmaModules-ngMock': [
|
||||
'build/angular.js',
|
||||
'src/ngMock/*.js',
|
||||
'test/modules/no_bootstrap.js',
|
||||
'test/helpers/matchers.js',
|
||||
'test/helpers/privateMocks.js',
|
||||
'test/helpers/support.js',
|
||||
'test/helpers/testabilityPatch.js',
|
||||
'src/routeToRegExp.js',
|
||||
'build/angular-animate.js',
|
||||
'test/ngMock/**/*.js'
|
||||
],
|
||||
|
||||
'karmaModules-ngResource': [
|
||||
'@angularSrcModuleNgResource',
|
||||
'test/ngResource/**/*.js'
|
||||
],
|
||||
|
||||
'karmaModules-ngRoute': [
|
||||
'build/angular-animate.js',
|
||||
'@angularSrcModuleNgRoute',
|
||||
'test/ngRoute/**/*.js'
|
||||
],
|
||||
|
||||
'karmaModules-ngSanitize': [
|
||||
'@angularSrcModuleNgSanitize',
|
||||
'test/ngSanitize/**/*.js'
|
||||
],
|
||||
|
||||
'karmaModules-ngTouch': [
|
||||
'@angularSrcModuleNgTouch',
|
||||
'test/ngTouch/**/*.js'
|
||||
'test/helpers/*.js',
|
||||
'test/ngAnimate/*.js',
|
||||
'test/ngMessageFormat/*.js',
|
||||
'test/ngMessages/*.js',
|
||||
'test/ngMock/*.js',
|
||||
'test/ngCookies/*.js',
|
||||
'test/ngRoute/**/*.js',
|
||||
'test/ngResource/*.js',
|
||||
'test/ngSanitize/**/*.js',
|
||||
'test/ngTouch/**/*.js',
|
||||
'test/ngAria/*.js'
|
||||
],
|
||||
|
||||
'karmaJquery': [
|
||||
'node_modules/jquery/dist/jquery.js',
|
||||
'bower_components/jquery/dist/jquery.js',
|
||||
'test/jquery_alias.js',
|
||||
'@angularSrc',
|
||||
'@angularSrcModules',
|
||||
'@angularScenario',
|
||||
'@angularTest'
|
||||
],
|
||||
|
||||
'karmaJqueryExclude': [
|
||||
'src/angular-bootstrap.js',
|
||||
'src/ngScenario/angular-bootstrap.js',
|
||||
'test/jquery_remove.js',
|
||||
'src/angular.bind.js'
|
||||
]
|
||||
@@ -276,23 +248,13 @@ var angularFiles = {
|
||||
angularFiles['karmaJquery' + jQueryVersion] = []
|
||||
.concat(angularFiles.karmaJquery)
|
||||
.map(function(path) {
|
||||
if (path.startsWith('node_modules/jquery')) {
|
||||
return path.replace(/^node_modules\/jquery/, 'node_modules/jquery-' + jQueryVersion);
|
||||
if (path.startsWith('bower_components/jquery')) {
|
||||
return path.replace(/^bower_components\/jquery/, 'bower_components/jquery-' + jQueryVersion);
|
||||
}
|
||||
return path;
|
||||
});
|
||||
});
|
||||
|
||||
angularFiles['angularSrcModuleNgAnimate'] = angularFiles['angularModules']['ngAnimate'];
|
||||
angularFiles['angularSrcModuleNgAria'] = angularFiles['angularModules']['ngAria'];
|
||||
angularFiles['angularSrcModuleNgCookies'] = angularFiles['angularModules']['ngCookies'];
|
||||
angularFiles['angularSrcModuleNgMessageFormat'] = angularFiles['angularModules']['ngMessageFormat'];
|
||||
angularFiles['angularSrcModuleNgMessages'] = angularFiles['angularModules']['ngMessages'];
|
||||
angularFiles['angularSrcModuleNgResource'] = angularFiles['angularModules']['ngResource'];
|
||||
angularFiles['angularSrcModuleNgRoute'] = angularFiles['angularModules']['ngRoute'];
|
||||
angularFiles['angularSrcModuleNgSanitize'] = angularFiles['angularModules']['ngSanitize'];
|
||||
angularFiles['angularSrcModuleNgTouch'] = angularFiles['angularModules']['ngTouch'];
|
||||
|
||||
angularFiles['angularSrcModules'] = [].concat(
|
||||
angularFiles['angularModules']['ngAnimate'],
|
||||
angularFiles['angularModules']['ngMessageFormat'],
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
|
||||
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
|
||||
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
|
||||
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
|
||||
|
||||
@@ -29,16 +29,19 @@ app.directive('bmPeWatch', function() {
|
||||
};
|
||||
});
|
||||
|
||||
//Executes the specified expression as a collection watcher
|
||||
app.directive('bmPeWatchCollection', function() {
|
||||
//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.bmPeWatchCollection);
|
||||
$element.text($attrs.bmPeWatchLiteral);
|
||||
return function($scope, $element, $attrs) {
|
||||
$scope.$watchCollection($attrs.bmPeWatchCollection, function(val) {
|
||||
$element.text(val);
|
||||
});
|
||||
$scope.$watch($parse($attrs.bmPeWatchLiteral, retZero));
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -69,7 +72,8 @@ app.controller('DataController', function($scope, $rootScope) {
|
||||
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]))
|
||||
keys: data[i - 1] && (data[i - 1].keys || Object.keys(data[i - 1])),
|
||||
constructor: data[i - 1]
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,12 @@
|
||||
<label for="complexPath">Complex Paths</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="constructorPath" id="constructorPath">
|
||||
<label for="constructorPath">Constructor Paths</label>
|
||||
($parse special cases "constructor" for security)
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="fieldAccess" id="fieldAccess">
|
||||
<label for="fieldAccess">Field Accessors</label>
|
||||
@@ -60,16 +66,6 @@
|
||||
<input type="radio" ng-model="expressionType" value="arrayLiterals" id="arrayLiterals">
|
||||
<label for="arrayLiterals">Array Literals</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="watchCollection" id="watchCollection">
|
||||
<label for="watchCollection">$watchCollection</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="watchCollectionLiterals" id="watchCollectionLiterals">
|
||||
<label for="watchCollectionLiterals">$watchCollection Literals</label>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!--
|
||||
@@ -92,6 +88,17 @@
|
||||
<span bm-pe-watch="row.keys"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="constructorPath" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="row.index"></span>
|
||||
<span bm-pe-watch="row.constructor.index"></span>
|
||||
<span bm-pe-watch="row.constructor.index"></span>
|
||||
<span bm-pe-watch="row.constructor.index"></span>
|
||||
<span bm-pe-watch="row.constructor.constructor.index"></span>
|
||||
<span bm-pe-watch="row.constructor.constructor.index"></span>
|
||||
<span bm-pe-watch="row.constructor.constructor.constructor.index"></span>
|
||||
<span bm-pe-watch="row.constructor.constructor.constructor.index"></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>
|
||||
@@ -208,44 +215,27 @@
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="objectLiterals" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="{foo: rowIdx}"></span>
|
||||
<span bm-pe-watch="{foo: row, bar: rowIdx}"></span>
|
||||
<span bm-pe-watch="{0: row, 1: rowIdx, 2: 3}"></span>
|
||||
<span bm-pe-watch="{str: 'foo', num: rowIdx, b: true}"></span>
|
||||
<span bm-pe-watch="{a: {b: {c: {d: {e: {f: rowIdx}}}}}}"></span>
|
||||
<span bm-pe-watch="{a: rowIdx, b: 1, c: 2, d: 3, e: 4, f: 5, g: rowIdx, h: 6, i: 7, j: 8, k: rowIdx}"></span>
|
||||
<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="[rowIdx]"></span>
|
||||
<span bm-pe-watch="[rowIdx, 0]"></span>
|
||||
<span bm-pe-watch="[rowIdx, 0, 1]"></span>
|
||||
<span bm-pe-watch="[rowIdx, 0, 1, 2]"></span>
|
||||
<span bm-pe-watch="[rowIdx, 0, 1, 2, 3]"></span>
|
||||
<span bm-pe-watch="[[], [rowIdx], [], [], [3], [[[]]]]"></span>
|
||||
<span bm-pe-watch="[rowIdx, undefined, null, true, false]"></span>
|
||||
<span bm-pe-watch="[[][0], [0][0], [][rowIdx]]"></span>
|
||||
<span bm-pe-watch="[0, rowIdx]"></span>
|
||||
<span bm-pe-watch="[0, 1, rowIdx]"></span>
|
||||
<span bm-pe-watch="[0, 1, 2, rowIdx]"></span>
|
||||
<span bm-pe-watch="[0, 1, 2, 3, rowIdx]"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="watchCollection" ng-repeat="(rowIdx, row) in data">
|
||||
<span bm-pe-watch-collection="data"></span>
|
||||
<span bm-pe-watch-collection="row.keys"></span>
|
||||
<span bm-pe-watch-collection="thisProbablyDoesntHaveAValue"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="watchCollectionLiterals" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch-collection="[rowIdx, row]"></span>
|
||||
<span bm-pe-watch-collection="[rowIdx, row, num0, str0, date0, obj, g, h, i, j, k, l, m, n, o, p]"></span>
|
||||
<span bm-pe-watch-collection="{a: rowIdx, b: row, c: num0, d: str0, e: date0, f: obj, g: g, h: h, i: i, j: j, k: k, l: l, m: m, n: n, o: o, p: p}"></span>
|
||||
|
||||
<!-- primitive/valueOf-compatible -->
|
||||
<span bm-pe-watch-collection="[rowIdx, row]"></span>
|
||||
<span bm-pe-watch-collection="[rowIdx, num0, str0, date0, date1, h, i, j, k, l, m, n, o, p]"></span>
|
||||
<span bm-pe-watch-collection="{a: rowIdx, c: num0, d: str0, e: date0, g: date1, h: h, i: i, j: j, k: k, l: l, m: m, n: n, o: o, p: p}"></span>
|
||||
<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>
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('repeatAnimateBenchmark', ['ngAnimate'])
|
||||
.config(function($animateProvider) {
|
||||
$animateProvider.classNameFilter(/animate-/);
|
||||
})
|
||||
.run(function($rootScope) {
|
||||
$rootScope.fileType = 'classfilter';
|
||||
});
|
||||
@@ -1,6 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('repeatAnimateBenchmark', [])
|
||||
.run(function($rootScope) {
|
||||
$rootScope.fileType = 'noanimate';
|
||||
});
|
||||
@@ -1,7 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('repeatAnimateBenchmark', ['ngAnimate'])
|
||||
.run(function($rootScope) {
|
||||
$rootScope.fileType = 'default';
|
||||
});
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
/* eslint-env node */
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
scripts: [
|
||||
{
|
||||
id: 'angular',
|
||||
src: '/build/angular.js'
|
||||
},
|
||||
{
|
||||
id: 'angular-animate',
|
||||
src: '/build/angular-animate.js'
|
||||
},
|
||||
{
|
||||
id: 'app',
|
||||
src: 'app.js'
|
||||
},
|
||||
{
|
||||
src: 'common.js'
|
||||
}]
|
||||
});
|
||||
};
|
||||
@@ -1,120 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
var app = angular.module('repeatAnimateBenchmark');
|
||||
|
||||
app.config(function($compileProvider, $animateProvider) {
|
||||
if ($compileProvider.debugInfoEnabled) {
|
||||
$compileProvider.debugInfoEnabled(false);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
app.run(function($animate) {
|
||||
if ($animate.enabled) {
|
||||
$animate.enabled(true);
|
||||
}
|
||||
});
|
||||
|
||||
app.controller('DataController', function($scope, $rootScope, $animate) {
|
||||
var totalRows = 500;
|
||||
var totalColumns = 20;
|
||||
|
||||
var data = $scope.data = [];
|
||||
|
||||
function fillData() {
|
||||
if ($animate.enabled) {
|
||||
$animate.enabled($scope.benchmarkType !== 'globallyDisabled');
|
||||
}
|
||||
|
||||
for (var i = 0; i < totalRows; i++) {
|
||||
data[i] = [];
|
||||
for (var j = 0; j < totalColumns; j++) {
|
||||
data[i][j] = {
|
||||
i: i
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: 'enter',
|
||||
fn: function() {
|
||||
$scope.$apply(function() {
|
||||
fillData();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: 'leave',
|
||||
fn: function() {
|
||||
$scope.$apply(function() {
|
||||
data = $scope.data = [];
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.directive('disableAnimations', function($animate) {
|
||||
return {
|
||||
link: {
|
||||
pre: function(s, e) {
|
||||
$animate.enabled(e, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
app.directive('noop', function($animate) {
|
||||
return {
|
||||
link: {
|
||||
pre: angular.noop
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
app.directive('baseline', function($document) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function($scope, $element) {
|
||||
var document = $document[0];
|
||||
|
||||
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(':'));
|
||||
|
||||
function createList() {
|
||||
for (i = 0; i < $scope.data.length; i++) {
|
||||
row = document.createElement('div');
|
||||
$element[0].appendChild(row);
|
||||
for (j = 0; j < $scope.data[i].length; j++) {
|
||||
cell = template.cloneNode(true);
|
||||
row.appendChild(cell);
|
||||
cell.childNodes[0].textContent = i;
|
||||
cell.ng339 = 'xxx';
|
||||
comment = document.createComment('ngRepeat end: bar in foo');
|
||||
row.appendChild(comment);
|
||||
}
|
||||
|
||||
comment = document.createComment('ngRepeat end: foo in foos');
|
||||
$element[0].appendChild(comment);
|
||||
}
|
||||
}
|
||||
|
||||
$scope.$watch('data.length', function(newVal) {
|
||||
if (newVal === 0) {
|
||||
while ($element[0].firstChild) {
|
||||
$element[0].removeChild($element[0].firstChild);
|
||||
}
|
||||
} else {
|
||||
createList();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
})();
|
||||
@@ -1,70 +0,0 @@
|
||||
<div ng-app="repeatAnimateBenchmark" ng-cloak>
|
||||
<div ng-controller="DataController">
|
||||
<div class="container-fluid">
|
||||
<p>
|
||||
Tests rendering of an ngRepeat with 500 elements.<br>
|
||||
Animations can be enabled / disabled in different ways.<br>
|
||||
Two tests require reloading the app with different module / app configurations.
|
||||
</p>
|
||||
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="none">none: </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="baseline">baseline (vanilla Javascript): </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'default'" value="enabled">enabled : </label> (requires <a href="./">app.js</a>)</div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'default' && fileType !== 'classfilter'" value="globallyDisabled">globally disabled:</label> (requires <a href="./">app.js</a> or <a href="?app=app-classfilter.js">app-classfilter.js</a>)</div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'default'" value="disabledParentElement">disabled by $animate.enabled() on parent element: </label> (requires <a href="./">app.js</a>)</div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'noanimate'" value="noanimate">Without ngAnimate:</label> (requires <a href="?app=app-noanimate.js">app-noanimate.js</a>)</div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'classfilter'" value="disabledClassFilter">disabled by classNameFilter on element:</label> (requires <a href="?app=app-classfilter.js">app-classfilter.js</a>)</div>
|
||||
|
||||
<ng-switch on="benchmarkType">
|
||||
<baseline ng-switch-when="baseline">
|
||||
</baseline>
|
||||
<div ng-switch-when="noanimate">
|
||||
<div noop>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">
|
||||
<span>{{column.i}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="enabled">
|
||||
<div noop>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">
|
||||
<span>{{column.i}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="globallyDisabled">
|
||||
<div noop>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">
|
||||
<span>{{column.i}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="disabledClassFilter">
|
||||
<div noop>
|
||||
<div ng-repeat="row in data">
|
||||
<span class="disable-animations" ng-repeat="column in row">
|
||||
<span>{{column.i}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="disabledParentElement">
|
||||
<div disable-animations>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">
|
||||
<span>{{column.i}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-switch>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "angularjs",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"jquery": "3.2.1",
|
||||
"jquery-2.2": "jquery#2.2.4",
|
||||
"jquery-2.1": "jquery#2.1.4",
|
||||
"closure-compiler": "https://dl.google.com/closure-compiler/compiler-20140814.zip",
|
||||
"ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.2.4/assets/ng-closure-runner.zip"
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,7 @@ body {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#json,
|
||||
#xml {
|
||||
#json, #xml {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
+2
-6
@@ -1,11 +1,7 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
[ng\:cloak],
|
||||
[ng-cloak],
|
||||
[data-ng-cloak],
|
||||
[x-ng-cloak],
|
||||
.ng-cloak,
|
||||
.x-ng-cloak,
|
||||
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],
|
||||
.ng-cloak, .x-ng-cloak,
|
||||
.ng-hide:not(.ng-hide-animate) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@@ -713,14 +713,14 @@ ul.events > li {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
@media only screen and (min-width: 769px) {
|
||||
[ng-include="partialPath"].ng-hide {
|
||||
display: block !important;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) and (max-width: 991px) {
|
||||
@media only screen and (min-width: 769px) and (max-width: 991px) {
|
||||
.main-body-grid {
|
||||
margin-top: 160px;
|
||||
}
|
||||
@@ -729,7 +729,7 @@ ul.events > li {
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 767px) {
|
||||
@media only screen and (max-width : 768px) {
|
||||
.picker, .picker select {
|
||||
width: auto;
|
||||
display: block;
|
||||
@@ -934,14 +934,6 @@ toc-container > div > toc-tree > ul > li > toc-tree > ul > li toc-tree > ul li {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.dev-status span {
|
||||
padding: 2px 8px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.security span { background-color: orange; }
|
||||
.stable span { background-color: green; color: white; }
|
||||
.current span { background-color: blue; color: white; }
|
||||
|
||||
@media handheld and (max-width:800px), screen and (max-device-width:800px), screen and (max-width:800px) {
|
||||
.navbar {
|
||||
min-height: auto;
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
User-agent: *
|
||||
|
||||
# The map files are not required by the app
|
||||
Disallow: /*.map$
|
||||
@@ -9,7 +9,6 @@
|
||||
},
|
||||
|
||||
"globals": {
|
||||
"angular": false,
|
||||
/* testabilityPatch / matchers */
|
||||
"inject": false,
|
||||
"module": false,
|
||||
|
||||
@@ -21,9 +21,6 @@ describe('docs.angularjs.org', function() {
|
||||
console.log('browser console errors: ' + require('util').inspect(filteredLog));
|
||||
}
|
||||
});
|
||||
|
||||
browser.ignoreSynchronization = false;
|
||||
browser.clearMockModules();
|
||||
});
|
||||
|
||||
|
||||
@@ -105,66 +102,6 @@ describe('docs.angularjs.org', function() {
|
||||
expect(mainHeader.getText()).toEqual('Oops!');
|
||||
});
|
||||
|
||||
it('should set "noindex" if the page does not exist', function() {
|
||||
browser.get('build/docs/index-production.html#!/api/does/not/exist');
|
||||
var robots = element(by.css('meta[name="robots"][content="noindex"]'));
|
||||
var googleBot = element(by.css('meta[name="googlebot"][content="noindex"]'));
|
||||
expect(robots.isPresent()).toBe(true);
|
||||
expect(googleBot.isPresent()).toBe(true);
|
||||
});
|
||||
|
||||
it('should remove "noindex" if the page exists', function() {
|
||||
browser.get('build/docs/index-production.html#!/api');
|
||||
var robots = element(by.css('meta[name="robots"][content="noindex"]'));
|
||||
var googleBot = element(by.css('meta[name="googlebot"][content="noindex"]'));
|
||||
expect(robots.isPresent()).toBe(false);
|
||||
expect(googleBot.isPresent()).toBe(false);
|
||||
});
|
||||
|
||||
describe('template request error', function() {
|
||||
beforeEach(function() {
|
||||
browser.addMockModule('httpMocker', function() {
|
||||
angular.module('httpMocker', ['ngMock'])
|
||||
.run(['$httpBackend', function($httpBackend) {
|
||||
$httpBackend.whenGET('localhost:8000/build/docs/partials/api.html').respond(500, '');
|
||||
}]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should set "noindex" for robots if the request fails', function() {
|
||||
// index-test includes ngMock
|
||||
browser.get('build/docs/index-test.html#!/api');
|
||||
var robots = element(by.css('meta[name="robots"][content="noindex"]'));
|
||||
var googleBot = element(by.css('meta[name="googlebot"][content="noindex"]'));
|
||||
expect(robots.isPresent()).toBe(true);
|
||||
expect(googleBot.isPresent()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('page bootstrap error', function() {
|
||||
beforeEach(function() {
|
||||
browser.addMockModule('httpMocker', function() {
|
||||
// Require a module that does not exist to break the bootstrapping
|
||||
angular.module('httpMocker', ['doesNotExist']);
|
||||
});
|
||||
});
|
||||
|
||||
it('should have "noindex" for robots if bootstrapping fails', function() {
|
||||
browser.get('build/docs/index.html#!/api').catch(function() {
|
||||
// get() will fail on AngularJS bootstrap, but if we continue here, protractor
|
||||
// will assume the app is ready
|
||||
browser.ignoreSynchronization = true;
|
||||
var robots = element(by.css('meta[name="robots"][content="noindex"]'));
|
||||
var googleBot = element(by.css('meta[name="googlebot"][content="noindex"]'));
|
||||
expect(robots.isPresent()).toBe(true);
|
||||
expect(googleBot.isPresent()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
describe('table of contents', function() {
|
||||
|
||||
it('on provider pages', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/provider/$controllerProvider');
|
||||
browser.get('build/docs/index.html#!/api/ng/provider/$interpolateProvider');
|
||||
|
||||
var toc = element.all(by.css('toc-container > div > toc-tree'));
|
||||
toc.getText().then(function(text) {
|
||||
@@ -19,7 +19,7 @@ describe('table of contents', function() {
|
||||
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
|
||||
|
||||
tocFirstLevel.then(function(match) {
|
||||
expect(match.length).toBe(2);
|
||||
expect(match.length).toBe(3);
|
||||
|
||||
expect(match[1].all(by.css('li')).count()).toBe(2);
|
||||
});
|
||||
|
||||
@@ -91,16 +91,13 @@ directivesModule
|
||||
.component('tocTree', {
|
||||
template: '<ul>' +
|
||||
'<li ng-repeat="item in $ctrl.items">' +
|
||||
'<a ng-href="{{ $ctrl.path }}#{{item.fragment}}">{{item.title}}</a>' +
|
||||
'<a ng-href="#{{item.fragment}}">{{item.title}}</a>' +
|
||||
'<toc-tree ng-if="::item.children.length > 0" items="item.children"></toc-tree>' +
|
||||
'</li>' +
|
||||
'</ul>',
|
||||
bindings: {
|
||||
items: '<'
|
||||
},
|
||||
controller: ['$location', /** @this */ function($location) {
|
||||
this.path = $location.path().replace(/^\/?(.+?)(\/index)?\/?$/, '$1');
|
||||
}]
|
||||
}
|
||||
})
|
||||
.directive('tocContainer', function() {
|
||||
return {
|
||||
|
||||
+5
-11
@@ -8,8 +8,6 @@ angular.module('DocsController', ['currentVersionData'])
|
||||
function($scope, $rootScope, $location, $window, $cookies,
|
||||
NG_PAGES, NG_NAVIGATION, CURRENT_NG_VERSION) {
|
||||
|
||||
var errorPartialPath = 'Error404.html';
|
||||
|
||||
$scope.navClass = function(navItem) {
|
||||
return {
|
||||
active: navItem.href && this.currentPage && this.currentPage.path,
|
||||
@@ -18,6 +16,8 @@ angular.module('DocsController', ['currentVersionData'])
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
$scope.$on('$includeContentLoaded', function() {
|
||||
var pagePath = $scope.currentPage ? $scope.currentPage.path : $location.path();
|
||||
$window._gaq.push(['_trackPageview', pagePath]);
|
||||
@@ -26,7 +26,6 @@ angular.module('DocsController', ['currentVersionData'])
|
||||
|
||||
$scope.$on('$includeContentError', function() {
|
||||
$scope.loading = false;
|
||||
$scope.loadingError = true;
|
||||
});
|
||||
|
||||
$scope.$watch(function docsPathWatch() {return $location.path(); }, function docsPathWatchAction(path) {
|
||||
@@ -36,7 +35,6 @@ angular.module('DocsController', ['currentVersionData'])
|
||||
var currentPage = $scope.currentPage = NG_PAGES[path];
|
||||
|
||||
$scope.loading = true;
|
||||
$scope.loadingError = false;
|
||||
|
||||
if (currentPage) {
|
||||
$scope.partialPath = 'partials/' + path + '.html';
|
||||
@@ -52,22 +50,18 @@ angular.module('DocsController', ['currentVersionData'])
|
||||
} else {
|
||||
$scope.currentArea = NG_NAVIGATION['api'];
|
||||
$scope.breadcrumb = [];
|
||||
$scope.partialPath = errorPartialPath;
|
||||
$scope.partialPath = 'Error404.html';
|
||||
}
|
||||
});
|
||||
|
||||
$scope.hasError = function() {
|
||||
return $scope.partialPath === errorPartialPath || $scope.loadingError;
|
||||
};
|
||||
|
||||
/**********************************
|
||||
Initialize
|
||||
***********************************/
|
||||
|
||||
$scope.versionNumber = CURRENT_NG_VERSION.full;
|
||||
$scope.version = CURRENT_NG_VERSION.full + ' ' + CURRENT_NG_VERSION.codeName;
|
||||
$scope.loading = false;
|
||||
$scope.loadingError = false;
|
||||
$scope.loading = 0;
|
||||
|
||||
|
||||
var INDEX_PATH = /^(\/|\/index[^.]*.html)$/;
|
||||
if (!$location.path() || INDEX_PATH.test($location.path())) {
|
||||
|
||||
@@ -22,7 +22,6 @@ module.exports = new Package('angularjs', [
|
||||
.factory(require('./services/deployments/debug'))
|
||||
.factory(require('./services/deployments/default'))
|
||||
.factory(require('./services/deployments/jquery'))
|
||||
.factory(require('./services/deployments/test'))
|
||||
.factory(require('./services/deployments/production'))
|
||||
|
||||
.factory(require('./inline-tag-defs/type'))
|
||||
@@ -32,7 +31,6 @@ module.exports = new Package('angularjs', [
|
||||
.processor(require('./processors/keywords'))
|
||||
.processor(require('./processors/pages-data'))
|
||||
.processor(require('./processors/versions-data'))
|
||||
.processor(require('./processors/sitemap'))
|
||||
|
||||
|
||||
.config(function(dgeni, log, readFilesProcessor, writeFilesProcessor) {
|
||||
@@ -148,7 +146,6 @@ module.exports = new Package('angularjs', [
|
||||
|
||||
.config(function(checkAnchorLinksProcessor) {
|
||||
checkAnchorLinksProcessor.base = '/';
|
||||
checkAnchorLinksProcessor.errorOnUnmatchedLinks = true;
|
||||
// We are only interested in docs that have an area (i.e. they are pages)
|
||||
checkAnchorLinksProcessor.checkDoc = function(doc) { return doc.area; };
|
||||
})
|
||||
@@ -159,14 +156,12 @@ module.exports = new Package('angularjs', [
|
||||
generateProtractorTestsProcessor,
|
||||
generateExamplesProcessor,
|
||||
debugDeployment, defaultDeployment,
|
||||
jqueryDeployment, testDeployment,
|
||||
productionDeployment) {
|
||||
jqueryDeployment, productionDeployment) {
|
||||
|
||||
generateIndexPagesProcessor.deployments = [
|
||||
debugDeployment,
|
||||
defaultDeployment,
|
||||
jqueryDeployment,
|
||||
testDeployment,
|
||||
productionDeployment
|
||||
];
|
||||
|
||||
|
||||
@@ -5,36 +5,18 @@
|
||||
* @description
|
||||
* Process "error" docType docs and generate errorNamespace docs
|
||||
*/
|
||||
module.exports = function errorDocsProcessor(log, errorNamespaceMap, getMinerrInfo) {
|
||||
module.exports = function errorDocsProcessor(errorNamespaceMap, getMinerrInfo) {
|
||||
return {
|
||||
$runAfter: ['tags-extracted'],
|
||||
$runBefore: ['extra-docs-added'],
|
||||
$process: function(docs) {
|
||||
|
||||
// Get the extracted min errors to compare with the error docs, and report any mismatch
|
||||
var collectedErrors = require('../../../build/errors.json').errors;
|
||||
var flatErrors = [];
|
||||
|
||||
for (var namespace in collectedErrors) {
|
||||
for (var error in collectedErrors[namespace]) {
|
||||
flatErrors.push(namespace + ':' + error);
|
||||
}
|
||||
}
|
||||
|
||||
// Create error namespace docs and attach error docs to each
|
||||
docs.forEach(function(doc) {
|
||||
var parts, namespaceDoc;
|
||||
|
||||
if (doc.docType === 'error') {
|
||||
|
||||
var matchingMinErr = flatErrors.indexOf(doc.name);
|
||||
|
||||
if (matchingMinErr === -1) {
|
||||
log.warn('Error doc: ' + doc.name + ' has no matching min error');
|
||||
} else {
|
||||
flatErrors.splice(matchingMinErr, 1);
|
||||
}
|
||||
|
||||
// Parse out the error info from the id
|
||||
parts = doc.name.split(':');
|
||||
doc.namespace = parts[0];
|
||||
@@ -59,10 +41,6 @@ module.exports = function errorDocsProcessor(log, errorNamespaceMap, getMinerrIn
|
||||
}
|
||||
});
|
||||
|
||||
flatErrors.forEach(function(value) {
|
||||
log.warn('No error doc exists for min error: ' + value);
|
||||
});
|
||||
|
||||
errorNamespaceMap.forEach(function(errorNamespace) {
|
||||
docs.push(errorNamespace);
|
||||
});
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var exclusionRegex = /^index|examples\/|ptore2e\//;
|
||||
|
||||
module.exports = function createSitemap() {
|
||||
return {
|
||||
$runAfter: ['paths-computed'],
|
||||
$runBefore: ['rendering-docs'],
|
||||
$process: function(docs) {
|
||||
docs.push({
|
||||
id: 'sitemap.xml',
|
||||
path: 'sitemap.xml',
|
||||
outputPath: '../sitemap.xml',
|
||||
template: 'sitemap.template.xml',
|
||||
urls: docs.filter(function(doc) {
|
||||
return doc.path &&
|
||||
doc.outputPath &&
|
||||
!exclusionRegex.test(doc.outputPath);
|
||||
}).map(function(doc) {
|
||||
return doc.path;
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -55,6 +55,9 @@ module.exports = function generateVersionDocProcessor(gitData) {
|
||||
|
||||
if (missesCurrentVersion) versions.push(currentVersion.version);
|
||||
|
||||
// Get the stable release with the highest version
|
||||
var highestStableRelease = versions.reverse().find(semverIsStable);
|
||||
|
||||
versions = versions
|
||||
.filter(function(versionStr) {
|
||||
return blacklist.indexOf(versionStr) === -1;
|
||||
@@ -82,9 +85,6 @@ module.exports = function generateVersionDocProcessor(gitData) {
|
||||
var latest = sortObject(latestMap, reverse(semver.compare))
|
||||
.map(function(version) { return makeOption(version, 'Latest'); });
|
||||
|
||||
// Get the stable release with the highest version
|
||||
var highestStableRelease = versions.find(semverIsStable);
|
||||
|
||||
// Generate master and stable snapshots
|
||||
var snapshots = [
|
||||
makeOption(
|
||||
@@ -130,15 +130,14 @@ module.exports = function generateVersionDocProcessor(gitData) {
|
||||
return Object.keys(obj).map(function(key) { return obj[key]; }).sort(cmp);
|
||||
}
|
||||
|
||||
// Adapted from
|
||||
// https://github.com/kaelzhang/node-semver-stable/blob/34dd29842409295d49889d45871bec55a992b7f6/index.js#L25
|
||||
function semverIsStable(version) {
|
||||
var semverObj = version.version;
|
||||
var semverObj = semver.parse(version);
|
||||
return semverObj === null ? false : !semverObj.prerelease.length;
|
||||
}
|
||||
|
||||
function createSnapshotStableLabel(version) {
|
||||
var label = version.label.replace(/.$/, 'x') + '-snapshot';
|
||||
var label = 'v' + version.replace(/.$/, 'x') + '-snapshot';
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ var cdnUrl = googleCdnUrl + versionInfo.cdnVersion;
|
||||
// docs.angularjs.org and code.angularjs.org need them.
|
||||
var versionPath = versionInfo.currentVersion.isSnapshot ?
|
||||
'snapshot' :
|
||||
versionInfo.currentVersion.version;
|
||||
(versionInfo.currentVersion.version || versionInfo.currentVersion.version);
|
||||
var examplesDependencyPath = angularCodeUrl + versionPath + '/';
|
||||
|
||||
module.exports = function productionDeployment(getVersion) {
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function testDeployment(getVersion) {
|
||||
return {
|
||||
name: 'test',
|
||||
examples: {
|
||||
commonFiles: {
|
||||
scripts: ['../../../angular.js']
|
||||
},
|
||||
dependencyPath: '../../../'
|
||||
},
|
||||
scripts: [
|
||||
'../angular.js',
|
||||
'../angular-resource.js',
|
||||
'../angular-route.js',
|
||||
'../angular-cookies.js',
|
||||
'../angular-mocks.js',
|
||||
'../angular-sanitize.js',
|
||||
'../angular-touch.js',
|
||||
'../angular-animate.js',
|
||||
'components/marked-' + getVersion('marked') + '/lib/marked.js',
|
||||
'js/angular-bootstrap/dropdown-toggle.js',
|
||||
'components/lunr-' + getVersion('lunr') + '/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/current-version-data.js',
|
||||
'js/all-versions-data.js',
|
||||
'js/pages-data.js',
|
||||
'js/nav-data.js',
|
||||
'js/docs.js'
|
||||
],
|
||||
stylesheets: [
|
||||
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.css',
|
||||
'css/prettify-theme.css',
|
||||
'css/angular-topnav.css',
|
||||
'css/docs.css',
|
||||
'css/animations.css'
|
||||
]
|
||||
};
|
||||
};
|
||||
@@ -4,13 +4,14 @@ var path = require('canonical-path');
|
||||
/**
|
||||
* dgService getVersion
|
||||
* @description
|
||||
* Find the current version of the node module
|
||||
* Find the current version of the bower component (or node module)
|
||||
*/
|
||||
module.exports = function getVersion(readFilesProcessor) {
|
||||
var sourceFolder = path.resolve(readFilesProcessor.basePath, 'node_modules');
|
||||
var packageFile = 'package.json';
|
||||
var basePath = readFilesProcessor.basePath;
|
||||
|
||||
return function(component) {
|
||||
return require(path.join(sourceFolder, component, packageFile)).version;
|
||||
return function(component, sourceFolder, packageFile) {
|
||||
sourceFolder = path.resolve(basePath, sourceFolder || 'node_modules');
|
||||
packageFile = packageFile || 'package.json';
|
||||
return require(path.join(sourceFolder,component,packageFile)).version;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -11,18 +11,6 @@
|
||||
<meta name="fragment" content="!">
|
||||
<title ng-bind-template="AngularJS: {{ currentArea.name }}: {{ currentPage.name || 'Error: Page not found'}}">AngularJS</title>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
// Dynamically, pre-emptively, add `noindex`, which will be removed when the doc is ready and valid
|
||||
['googlebot', 'robots'].forEach(function(bot) {
|
||||
var tag = document.createElement('meta');
|
||||
tag.name = bot;
|
||||
tag.content = 'noindex';
|
||||
tag.setAttribute('ng-if', 'hasError()');
|
||||
document.head.appendChild(tag);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
// dynamically add base tag as well as css and javascript files.
|
||||
// we can't add css/js the usual way, because some browsers (FF) eagerly prefetch resources
|
||||
@@ -139,7 +127,7 @@
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<div class="search-results-container" ng-show="hasResults" ng-cloak>
|
||||
<div class="search-results-container" ng-show="hasResults">
|
||||
<div class="container">
|
||||
<div class="search-results-frame">
|
||||
<div ng-repeat="(key, value) in results track by key" class="search-results-group" ng-class="colClassName + ' col-group-' + key" ng-show="value.length > 0">
|
||||
@@ -169,7 +157,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<nav id="navbar-sub" class="sup-header navbar navbar-fixed-top" scroll-y-offset-element ng-cloak>
|
||||
<nav id="navbar-sub" class="sup-header navbar navbar-fixed-top" scroll-y-offset-element>
|
||||
<div class="container main-grid main-header-grid">
|
||||
<div class="grid-left">
|
||||
<version-picker></version-picker>
|
||||
@@ -186,7 +174,7 @@
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<section role="main" class="container main-body" ng-cloak>
|
||||
<section role="main" class="container main-body">
|
||||
<div class="main-grid main-body-grid">
|
||||
<div class="grid-left">
|
||||
<a class="btn toc-toggle visible-xs" ng-click="toc=!toc">Show / Hide Table of Contents</a>
|
||||
@@ -210,8 +198,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-right">
|
||||
<div ng-show="loading">Loading …</div>
|
||||
<div ng-show="loadingError">There was an error loading this resource. Please try again later.</div>
|
||||
<div id="loading" ng-show="loading">Loading...</div>
|
||||
<div ng-hide="loading" ng-include="partialPath" toc-collector autoscroll></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -222,10 +209,10 @@
|
||||
<p class="pull-right"><a back-to-top>Back to top</a></p>
|
||||
|
||||
<p>
|
||||
Super-powered by Google ©2010-2018
|
||||
Super-powered by Google ©2010-2017
|
||||
(<a id="version"
|
||||
ng-href="https://github.com/angular/angular.js/blob/master/CHANGELOG.md#{{versionNumber}}"
|
||||
ng-bind-template="v{{version}}" title="Changelog of this version of AngularJS">
|
||||
ng-bind-template="v{{version}}" title="Changelog of this version of Angular JS">
|
||||
</a>)
|
||||
</p>
|
||||
<p>
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
{%- for url in doc.urls %}
|
||||
<url>
|
||||
<loc>https://docs.angularjs.org/{$ url $}</loc>
|
||||
</url>{% endfor %}
|
||||
</urlset>
|
||||
@@ -17,7 +17,7 @@
|
||||
{% endif %}
|
||||
|
||||
{% if method.this %}
|
||||
<h4>Method's `this`</h4>
|
||||
<h4>Method's {% code %}this{% endcode %}</h4>
|
||||
{$ method.this | marked $}
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{% if doc.this %}
|
||||
<h3>Method's `this`</h3>
|
||||
<h3>Method's {% code %}this{% endcode %}</h3>
|
||||
{$ doc.this | marked $}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
@@ -3,15 +3,7 @@
|
||||
@description
|
||||
|
||||
# AngularJS API Docs
|
||||
|
||||
<div class="alert alert-warning">
|
||||
**On July 1, 2018 AngularJS entered a 3 year Long Term Support period:** [Find out more](misc/version-support-status).
|
||||
</div>
|
||||
|
||||
## Welcome to the AngularJS API docs page.
|
||||
|
||||
These pages contain the AngularJS reference materials for version <strong ng-bind="version"></strong>.
|
||||
|
||||
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.
|
||||
@@ -19,14 +11,14 @@ These components are {@link guide/directive directives}, {@link guide/services s
|
||||
There is also a {@link guide/index guide} with articles on various topics, and a list of external resources.
|
||||
|
||||
<div class="alert alert-info">
|
||||
**AngularJS Prefixes `$` and `$$`**:
|
||||
**Angular Prefixes `$` and `$$`**:
|
||||
|
||||
To prevent accidental name collisions with your code,
|
||||
AngularJS prefixes names of public objects with `$` and names of private objects with `$$`.
|
||||
Angular prefixes names of public objects with `$` and names of private objects with `$$`.
|
||||
Please do not use the `$` or `$$` prefix in your code.
|
||||
</div>
|
||||
|
||||
## AngularJS Modules
|
||||
## Angular Modules
|
||||
|
||||
|
||||
## {@link ng ng (core module)}
|
||||
@@ -91,7 +83,7 @@ This module is provided by default and contains the core components of AngularJS
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
The core global API functions are attached to the `angular` object. These core functions are useful for low level JavaScript operations within your application.
|
||||
The core global API functions are attached to the angular object. These core functions are useful for low level JavaScript operations within your application.
|
||||
</p>
|
||||
<p>
|
||||
Some examples include:
|
||||
@@ -138,7 +130,7 @@ Use ngRoute to enable URL routing to your application. The ngRoute module suppor
|
||||
|
||||
## {@link ngAnimate ngAnimate}
|
||||
|
||||
Use ngAnimate to enable animation features within your application. Various core AngularJS directives will provide
|
||||
Use ngAnimate to enable animation features within your application. Various core ng directives will provide
|
||||
animation hooks into your application when ngAnimate is included. Animations are defined by using CSS transitions/animations
|
||||
or JavaScript callbacks.
|
||||
|
||||
@@ -222,7 +214,11 @@ Use the ngCookies module to handle cookie management within your application.
|
||||
{@link ngCookies#service Services / Factories}
|
||||
</td>
|
||||
<td>
|
||||
The {@link ngCookies.$cookies $cookies} service is a convenient wrapper to store simple data within browser cookies.
|
||||
The following services are used for cookie management:
|
||||
<ul>
|
||||
<li>The {@link ngCookies.$cookies $cookie} service is a convenient wrapper to store simple data within browser cookies.</li>
|
||||
<li>{@link ngCookies.$cookieStore $cookieStore} is used to store more complex data using serialization.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:ctxoverride
|
||||
@fullName DOM Property Security Context Override
|
||||
@description
|
||||
|
||||
This error occurs when the security context for a property is defined via {@link ng.$compileProvider#addPropertySecurityContext addPropertySecurityContext()} multiple times under different security contexts.
|
||||
|
||||
For example:
|
||||
|
||||
```js
|
||||
$compileProvider.addPropertySecurityContext("my-element", "src", $sce.MEDIA_URL);
|
||||
$compileProvider.addPropertySecurityContext("my-element", "src", $sce.RESOURCE_URL); //throws
|
||||
```
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
This error occurs when the application's model becomes unstable because some `$onChanges` hooks are causing updates which then trigger
|
||||
further calls to `$onChanges` that can never complete.
|
||||
AngularJS detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
|
||||
Angular detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
|
||||
|
||||
For example, the situation can occur by setting up a `$onChanges()` hook which triggers an event on the component, which subsequently
|
||||
triggers the component's bound inputs to be updated:
|
||||
|
||||
@@ -10,15 +10,13 @@ myModule.directive('directiveName', function factory() {
|
||||
return {
|
||||
...
|
||||
scope: {
|
||||
'localName': '@', // OK
|
||||
'localName2': '&attr', // OK
|
||||
'localName3': '<?attr', // OK
|
||||
'localName4': ' = attr', // OK
|
||||
'localName5': ' =*attr', // OK
|
||||
'localName6': 'attr', // ERROR: missing mode @&=<
|
||||
'localName7': 'attr=', // ERROR: must be prefixed with @&=<
|
||||
'localName8': '=attr?', // ERROR: ? must come directly after the mode
|
||||
'localName9': '<*' // ERROR: * is only valid with =
|
||||
'attrName': '@', // OK
|
||||
'attrName2': '=localName', // OK
|
||||
'attrName3': '<?localName', // OK
|
||||
'attrName4': ' = name', // OK
|
||||
'attrName5': 'name', // ERROR: missing mode @&=
|
||||
'attrName6': 'name=', // ERROR: must be prefixed with @&=
|
||||
'attrName7': '=name?', // ERROR: ? must come directly after the mode
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
@@ -3,34 +3,6 @@
|
||||
@fullName Missing required attribute
|
||||
@description
|
||||
|
||||
This error may occur only when {@link $compileProvider#strictComponentBindingsEnabled `$compileProvider.strictComponentBindingsEnabled`} is set to `true`.
|
||||
|
||||
If that is the case, then all {@link $compileProvider#component component} controller bindings and
|
||||
{@link $compileProvider#directive directive} scope / controller bindings that are non-optional,
|
||||
must be provided when the directive is instantiated.
|
||||
|
||||
To make a binding optional, add '?' to the definition.
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
|
||||
app.component('myTest', {
|
||||
bindings: {
|
||||
first: '=?', // optional
|
||||
second: '='
|
||||
},
|
||||
controller: function() {
|
||||
...
|
||||
},
|
||||
template: '...'
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
This component will throw `missingattr` for the `second` binding when used as follows:
|
||||
|
||||
```html
|
||||
<my-test></my-test>
|
||||
```
|
||||
|
||||
This error may occur only when `$compileProvider.strictComponentBindingsEnabled` is set to `true`.
|
||||
Then all attributes mentioned in `bindings` without `?` must be set. If one or more aren't set,
|
||||
the first one will throw an error.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
@ngdoc error
|
||||
@name $compile:nodomevents
|
||||
@fullName Event Attribute/Property Binding
|
||||
@fullName Interpolated Event Attributes
|
||||
@description
|
||||
|
||||
This error occurs when one tries to create a binding for event handler attributes or properties like `onclick`, `onload`, `onsubmit`, etc.
|
||||
This error occurs when one tries to create a binding for event handler attributes like `onclick`, `onload`, `onsubmit`, etc.
|
||||
|
||||
There is no practical value in binding to these attributes/properties and doing so only exposes your application to security vulnerabilities like XSS.
|
||||
For these reasons binding to event handler attributes and properties (`formaction` and all starting with `on`) is not supported.
|
||||
There is no practical value in binding to these attributes and doing so only exposes your application to security vulnerabilities like XSS.
|
||||
For these reasons binding to event handler attributes (all attributes that start with `on` and `formaction` attribute) is not supported.
|
||||
|
||||
|
||||
An example code that would allow XSS vulnerability by evaluating user input in the window context could look like this:
|
||||
@@ -17,4 +17,4 @@ An example code that would allow XSS vulnerability by evaluating user input in t
|
||||
|
||||
Since the `onclick` evaluates the value as JavaScript code in the window context, setting the `username` model to a value like `javascript:alert('PWND')` would result in script injection when the `div` is clicked.
|
||||
|
||||
Please use the `ng-*` or `ng-on-*` versions instead (such as `ng-click` or `ng-on-click` rather than `onclick`).
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:srcset
|
||||
@fullName Invalid value passed to `attr.$set('srcset', value)`
|
||||
@description
|
||||
|
||||
This error occurs if you try to programmatically set the `srcset` attribute with a non-string value.
|
||||
|
||||
This can be the case if you tried to avoid the automatic sanitization of the `srcset` value by
|
||||
passing a "trusted" value provided by calls to `$sce.trustAsMediaUrl(value)`.
|
||||
|
||||
If you want to programmatically set explicitly trusted unsafe URLs, you should use `$sce.trustAsHtml`
|
||||
on the whole `img` tag and inject it into the DOM using the `ng-bind-html` directive.
|
||||
@@ -0,0 +1,11 @@
|
||||
@ngdoc error
|
||||
@name $compile:tpload
|
||||
@fullName Error Loading Template
|
||||
@description
|
||||
|
||||
This error occurs when {@link ng.$compile `$compile`} attempts to fetch a template from some URL, and the request fails.
|
||||
|
||||
To resolve this error, ensure that the URL of the template is spelled correctly and resolves to correct absolute URL.
|
||||
The [Chrome Developer Tools](https://developers.google.com/chrome-developer-tools/docs/network#network_panel_overview) might also be helpful in determining why the request failed.
|
||||
|
||||
If you are using {@link ng.$templateCache} to pre-load templates, ensure that the cache was populated with the template.
|
||||
@@ -9,9 +9,9 @@ value is `JSON_CALLBACK`.
|
||||
|
||||
`$http` JSONP requests need to attach a callback query parameter to the URL. The name of this
|
||||
parameter is specified in the configuration object (or in the defaults) via the `jsonpCallbackParam`
|
||||
property. You must not provide your own parameter with this name in the configuration of the request.
|
||||
property. You must not provide your own parameter with this name in the configuratio of the request.
|
||||
|
||||
In previous versions of AngularJS, you specified where to add the callback parameter value via the
|
||||
In previous versions of Angular, you specified where to add the callback parameter value via the
|
||||
`JSON_CALLBACK` placeholder. This is no longer allowed.
|
||||
|
||||
To resolve this error, remove any parameters that have the same name as the `jsonpCallbackParam`;
|
||||
|
||||
@@ -15,7 +15,7 @@ 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
|
||||
installed {@link ngRoute `ngRoute`}.
|
||||
|
||||
### Monkey-patching AngularJS's `ng` module
|
||||
### Monkey-patching Angular's `ng` module
|
||||
|
||||
This error can also occur if you have tried to add your own components to the `ng` module.
|
||||
This has never been supported and from `1.3.0` it will actually trigger this error.
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
@fullName Expecting end operator
|
||||
@description
|
||||
|
||||
The AngularJS expression is missing the corresponding closing operator.
|
||||
The Angular expression is missing the corresponding closing operator.
|
||||
|
||||
@@ -8,4 +8,4 @@ extension in your interpolation expression. The different choices have to be un
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -9,4 +9,4 @@ bug mentioning the exact version of AngularJS used and we will fix it!
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -14,4 +14,4 @@ future commit and the github issue will help gauge urgency.
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
@description
|
||||
|
||||
You must specify the MessageFormat function that you're using right after the
|
||||
comma following the AngularJS expression. Currently, the supported functions are
|
||||
comma following the Angular expression. Currently, the supported functions are
|
||||
"plural" and "select" (for gender selections.)
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -8,4 +8,4 @@ extension keyword in the extended interpolation syntax.
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -8,4 +8,4 @@ brace to mark the end of the message.
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -9,4 +9,4 @@ braces.
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -10,4 +10,4 @@ extensions require that you provide a message for the selection "other".
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -9,4 +9,4 @@ unsupported or invalid.
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -7,4 +7,4 @@ You have attempted to use a MessageFormat extension in your interpolation expres
|
||||
|
||||
Read more about secure contexts at {@link ng.$sce Strict Contextual Escaping
|
||||
(SCE)} and about the MessageFormat extensions at {@link
|
||||
guide/i18n#MessageFormat AngularJS i18n MessageFormat}.
|
||||
guide/i18n#MessageFormat Angular i18n MessageFormat}.
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
@fullName Unterminated string literal
|
||||
@description
|
||||
|
||||
The string literal was not terminated in your AngularJS expression.
|
||||
The string literal was not terminated in your Angular expression.
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $interval:badprom
|
||||
@fullName Non-$interval promise
|
||||
@description
|
||||
|
||||
This error occurs when calling {@link ng.$interval#cancel $interval.cancel()} with a promise that
|
||||
was not generated by the {@link ng.$interval $interval} service. This can, for example, happen when
|
||||
calling {@link ng.$q#the-promise-api then()/catch()} on the returned promise, which creates a new
|
||||
promise, and pass that new promise to {@link ng.$interval#cancel $interval.cancel()}.
|
||||
|
||||
Example of incorrect usage that leads to this error:
|
||||
|
||||
```js
|
||||
var promise = $interval(doSomething, 1000, 5).then(doSomethingElse);
|
||||
$interval.cancel(promise);
|
||||
```
|
||||
|
||||
To fix the example above, keep a reference to the promise returned by
|
||||
{@link ng.$interval $interval()} and pass that to {@link ng.$interval#cancel $interval.cancel()}:
|
||||
|
||||
```js
|
||||
var promise = $interval(doSomething, 1000, 5);
|
||||
var newPromise = promise.then(doSomethingElse);
|
||||
$interval.cancel(promise);
|
||||
```
|
||||
@@ -40,7 +40,7 @@ URL of the subcontext:
|
||||
</head>
|
||||
```
|
||||
|
||||
Before AngularJS 1.3 we didn't have this hard requirement and it was easy to write apps that worked
|
||||
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:
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $parse:esc
|
||||
@fullName Value cannot be escaped
|
||||
@description
|
||||
|
||||
Occurs when the parser tries to escape a value that is not known.
|
||||
|
||||
This should never occur in practice. If it does then that indicates a programming
|
||||
error in the AngularJS `$parse` service itself and should be reported as an issue
|
||||
at https://github.com/angular/angular.js/issues.
|
||||
@@ -7,4 +7,4 @@ Occurs when an expression has a lexical error, for example a malformed number (0
|
||||
|
||||
The error message contains a more precise error.
|
||||
|
||||
To resolve, learn more about {@link guide/expression AngularJS expressions}, identify the error and fix the expression's syntax.
|
||||
To resolve, learn more about {@link guide/expression Angular expressions}, identify the error and fix the expression's syntax.
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $parse:lval
|
||||
@fullName Trying to assign a value to a non l-value
|
||||
@description
|
||||
|
||||
Occurs when an expression is trying to assign a value to a non-assignable expression.
|
||||
|
||||
This can happen if the left side of an assigment is not a valid reference to a variable
|
||||
or property. E.g. In the following snippet `1+2` is not assignable.
|
||||
|
||||
```
|
||||
(1+2) = 'hello';
|
||||
```
|
||||
@@ -6,4 +6,4 @@
|
||||
Occurs when there is a syntax error in an expression. These errors are thrown while compiling the expression.
|
||||
The error message contains a more precise description of the error, including the location (column) in the expression where the error occurred.
|
||||
|
||||
To resolve, learn more about {@link guide/expression AngularJS expressions}, identify the error and fix the expression's syntax.
|
||||
To resolve, learn more about {@link guide/expression Angular expressions}, identify the error and fix the expression's syntax.
|
||||
|
||||
@@ -8,5 +8,5 @@ Occurs when an expression is missing tokens at the end of the expression.
|
||||
For example, forgetting to close a bracket or failing to properly escape quotes in an expression
|
||||
will trigger this error.
|
||||
|
||||
To resolve, learn more about {@link guide/expression AngularJS expressions}, identify the error and
|
||||
To resolve, learn more about {@link guide/expression Angular expressions}, identify the error and
|
||||
fix the expression's syntax.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
@description
|
||||
|
||||
This error occurs when the application's model becomes unstable and each `$digest` cycle triggers a state change and subsequent `$digest` cycle.
|
||||
AngularJS detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
|
||||
Angular detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
|
||||
|
||||
For example, the situation can occur by setting up a watch on a path and subsequently updating the same path when the value changes.
|
||||
|
||||
@@ -26,7 +26,7 @@ $scope.getUsers = function() {
|
||||
};
|
||||
```
|
||||
|
||||
Since `getUsers()` returns a new array, AngularJS determines that the model is different on each `$digest`
|
||||
Since `getUsers()` returns a new array, Angular determines that the model is different on each `$digest`
|
||||
cycle, resulting in the error. The solution is to return the same array object if the elements have
|
||||
not changed:
|
||||
|
||||
|
||||
@@ -10,17 +10,17 @@ the error.
|
||||
|
||||
## Background
|
||||
|
||||
AngularJS uses a dirty-checking digest mechanism to monitor and update values of the scope during
|
||||
Angular uses a dirty-checking digest mechanism to monitor and update values of the scope during
|
||||
the processing of your application. The digest works by checking all the values that are being
|
||||
watched against their previous value and running any watch handlers that have been defined for those
|
||||
values that have changed.
|
||||
|
||||
This digest mechanism is triggered by calling `$digest` on a scope object. Normally you do not need
|
||||
to trigger a digest manually, because every external action that can trigger changes in your
|
||||
application, such as mouse events, timeouts or server responses, wrap the AngularJS application code
|
||||
application, such as mouse events, timeouts or server responses, wrap the Angular application code
|
||||
in a block of code that will run `$digest` when the code completes.
|
||||
|
||||
You wrap AngularJS code in a block that will be followed by a `$digest` by calling `$apply` on a scope
|
||||
You wrap Angular code in a block that will be followed by a `$digest` by calling `$apply` on a scope
|
||||
object. So, in pseudo-code, the process looks like this:
|
||||
|
||||
```
|
||||
@@ -45,20 +45,20 @@ $apply = function(fn) {
|
||||
|
||||
## Digest Phases
|
||||
|
||||
AngularJS keeps track of what phase of processing we are in, the relevant ones being `$apply` and
|
||||
Angular keeps track of what phase of processing we are in, the relevant ones being `$apply` and
|
||||
`$digest`. Trying to reenter a `$digest` or `$apply` while one of them is already in progress is
|
||||
typically a sign of programming error that needs to be fixed. So AngularJS will throw this error when
|
||||
typically a sign of programming error that needs to be fixed. So Angular will throw this error when
|
||||
that occurs.
|
||||
|
||||
In most situations it should be well defined whether a piece of code will be run inside an `$apply`,
|
||||
in which case you should not be calling `$apply` or `$digest`, or it will be run outside, in which
|
||||
case you should wrap any code that will be interacting with AngularJS scope or services, in a call to
|
||||
case you should wrap any code that will be interacting with Angular scope or services, in a call to
|
||||
`$apply`.
|
||||
|
||||
As an example, all Controller code should expect to be run within AngularJS, so it should have no need
|
||||
As an example, all Controller code should expect to be run within Angular, so it should have no need
|
||||
to call `$apply` or `$digest`. Conversely, code that is being trigger directly as a call back to
|
||||
some external event, from the DOM or 3rd party library, should expect that it is never called from
|
||||
within AngularJS, and so any AngularJS application code that it calls should first be wrapped in a call
|
||||
within Angular, and so any Angular application code that it calls should first be wrapped in a call
|
||||
to $apply.
|
||||
|
||||
## Common Causes
|
||||
@@ -84,8 +84,8 @@ function MyController($scope, thirdPartyComponent) {
|
||||
}
|
||||
```
|
||||
|
||||
We expect that our callback will be called asynchronously, and so from outside AngularJS. Therefore, we
|
||||
correctly wrap our application code that interacts with AngularJS in a call to `$apply`.
|
||||
We expect that our callback will be called asynchronously, and so from outside Angular. Therefore, we
|
||||
correctly wrap our application code that interacts with Angular in a call to `$apply`.
|
||||
|
||||
The problem comes if `getData()` decides to call the callback handler synchronously; perhaps it has
|
||||
the data already cached in memory and so it immediately calls the callback to return the data,
|
||||
@@ -116,7 +116,7 @@ that the code will be called in a single `$apply` block.
|
||||
### Triggering Events Programmatically
|
||||
|
||||
The other situation that often leads to this error is when you trigger code (such as a DOM event)
|
||||
programmatically (from within AngularJS), which is normally called by an external trigger.
|
||||
programmatically (from within Angular), which is normally called by an external trigger.
|
||||
|
||||
For example, consider a directive that will set focus on an input control when a value in the scope
|
||||
is true:
|
||||
@@ -161,7 +161,7 @@ In this second scenario, we are already inside a `$digest` when the ngFocus dire
|
||||
call to `$apply()`, causing this error to be thrown.
|
||||
|
||||
It is possible to workaround this problem by moving the call to set the focus outside of the digest,
|
||||
by using `$timeout(fn, 0, false)`, where the `false` value tells AngularJS not to wrap this `fn` in an
|
||||
by using `$timeout(fn, 0, false)`, where the `false` value tells Angular not to wrap this `fn` in an
|
||||
`$apply` block:
|
||||
|
||||
```
|
||||
@@ -203,7 +203,7 @@ Once you have identified this call you work your way up the stack to see what th
|
||||
called from within an `$apply`/`$digest`. It may be a simple oversight or maybe it fits with the
|
||||
sync/async scenario described earlier.
|
||||
|
||||
* If the second call was made inside an AngularJS directive then it is likely that it matches the second
|
||||
* If the second call was made inside an Angular directive then it is likely that it matches the second
|
||||
programmatic event trigger scenario described earlier. In this case you may need to look further up
|
||||
the tree to what triggered the event in the first place.
|
||||
|
||||
@@ -259,11 +259,11 @@ $get.g.$apply angular.js:12742 <--- $apply
|
||||
q angular.js:320
|
||||
```
|
||||
|
||||
We can see (even though the AngularJS code is minified) that there were two calls to `$apply`, first
|
||||
We can see (even though the Angular code is minified) that there were two calls to `$apply`, first
|
||||
on line `19833`, then on line `12738` of `angular.js`.
|
||||
|
||||
It is this second call that caused the error. If we look at the angular.js code, we can see that
|
||||
this call is made by an AngularJS directive.
|
||||
this call is made by an Angular directive.
|
||||
|
||||
```
|
||||
var ngEventDirectives = {};
|
||||
@@ -308,5 +308,5 @@ We can now see that the second `$apply` was caused by us programmatically trigge
|
||||
`$timeout` as described above.
|
||||
|
||||
## Further Reading
|
||||
To learn more about AngularJS processing model please check out the
|
||||
To learn more about Angular processing model please check out the
|
||||
{@link guide/concepts concepts doc} as well as the {@link ng.$rootScope.Scope api} doc.
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $route:norout
|
||||
@fullName Tried updating route with no current route
|
||||
@description
|
||||
|
||||
Occurs when an attempt is made to update the parameters on the current route when
|
||||
there is no current route. This can happen if you try to call `$route.updateParams();`
|
||||
before the first route transition has completed.
|
||||
@@ -7,4 +7,4 @@ This error occurs when `$sanitize` sanitizer determines that `document.implement
|
||||
|
||||
This api is necessary for safe parsing of HTML strings into DOM trees and without it the sanitizer can't sanitize the input.
|
||||
|
||||
The api is present in all supported browsers including IE 9.0, so the presence of this error usually indicates that AngularJS's `$sanitize` is being used on an unsupported platform.
|
||||
The api is present in all supported browsers including IE 9.0, so the presence of this error usually indicates that Angular's `$sanitize` is being used on an unsupported platform.
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
AngularJS' {@link ng.$sce Strict Contextual Escaping (SCE)} mode (enabled by default) has blocked loading a resource from an insecure URL.
|
||||
|
||||
Typically, this would occur if you're attempting to load an AngularJS template from an untrusted source.
|
||||
Typically, this would occur if you're attempting to load an Angular template from an untrusted source.
|
||||
It's also possible that a custom directive threw this error for a similar reason.
|
||||
|
||||
AngularJS only loads templates from trusted URLs (by calling {@link ng.$sce#getTrustedResourceUrl $sce.getTrustedResourceUrl} on the template URL).
|
||||
Angular only loads templates from trusted URLs (by calling {@link ng.$sce#getTrustedResourceUrl $sce.getTrustedResourceUrl} on the template URL).
|
||||
|
||||
By default, only URLs that belong to the same origin are trusted. These are urls with the same domain, protocol and port as the application document.
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
The value provided for use in a specific context was not found to be safe/trusted for use.
|
||||
|
||||
AngularJS's {@link ng.$sce Strict Contextual Escaping (SCE)} mode
|
||||
Angular's {@link ng.$sce Strict Contextual Escaping (SCE)} mode
|
||||
(enabled by default), requires bindings in certain
|
||||
contexts to result in a value that is trusted as safe for use in such a context. (e.g. loading an
|
||||
AngularJS template from a URL requires that the URL is one considered safe for loading resources.)
|
||||
Angular template from a URL requires that the URL is one considered safe for loading resources.)
|
||||
|
||||
This helps prevent XSS and other security issues. Read more at
|
||||
{@link ng.$sce Strict Contextual Escaping (SCE)}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $templateRequest:tpload
|
||||
@fullName Error Loading Template
|
||||
@description
|
||||
|
||||
This error occurs when {@link $templateRequest} attempts to fetch a template from some URL, and
|
||||
the request fails.
|
||||
|
||||
The template URL might be defined in a directive/component definition, an instance of `ngInclude`,
|
||||
an instance of `ngMessagesInclude` or a templated route in a `$route` route definition.
|
||||
|
||||
To resolve this error, ensure that the URL of the template is spelled correctly and resolves to
|
||||
correct absolute URL.
|
||||
The [Chrome Developer Tools](https://developers.google.com/chrome-developer-tools/docs/network#network_panel_overview)
|
||||
might also be helpful in determining why the request failed.
|
||||
|
||||
If you are using {@link ng.$templateCache} to pre-load templates, ensure that the cache was
|
||||
populated with the template.
|
||||
@@ -1,25 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $timeout:badprom
|
||||
@fullName Non-$timeout promise
|
||||
@description
|
||||
|
||||
This error occurs when calling {@link ng.$timeout#cancel $timeout.cancel()} with a promise that
|
||||
was not generated by the {@link ng.$timeout $timeout} service. This can, for example, happen when
|
||||
calling {@link ng.$q#the-promise-api then()/catch()} on the returned promise, which creates a new
|
||||
promise, and pass that new promise to {@link ng.$timeout#cancel $timeout.cancel()}.
|
||||
|
||||
Example of incorrect usage that leads to this error:
|
||||
|
||||
```js
|
||||
var promise = $timeout(doSomething, 1000).then(doSomethingElse);
|
||||
$timeout.cancel(promise);
|
||||
```
|
||||
|
||||
To fix the example above, keep a reference to the promise returned by
|
||||
{@link ng.$timeout $timeout()} and pass that to {@link ng.$timeout#cancel $timeout.cancel()}:
|
||||
|
||||
```js
|
||||
var promise = $timeout(doSomething, 1000);
|
||||
var newPromise = promise.then(doSomethingElse);
|
||||
$timeout.cancel(promise);
|
||||
```
|
||||
@@ -3,9 +3,9 @@
|
||||
@fullName Unsupported Selector Lookup
|
||||
@description
|
||||
|
||||
In order to keep AngularJS small, AngularJS implements only a subset of the selectors in {@link angular.element#angularjs-s-jqlite jqLite}.
|
||||
In order to keep Angular small, Angular implements only a subset of the selectors in {@link angular.element#angular-s-jqlite jqLite}.
|
||||
This error occurs when a jqLite instance is invoked with a selector other than this subset.
|
||||
|
||||
In order to resolve this error, rewrite your code to only use tag name selectors and manually traverse the DOM using the APIs provided by jqLite.
|
||||
|
||||
Alternatively, you can include a full version of jQuery, which AngularJS will automatically use and that will make all selectors available.
|
||||
Alternatively, you can include a full version of jQuery, which Angular will automatically use and that will make all selectors available.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
@fullName Testability Not Found
|
||||
@description
|
||||
|
||||
AngularJS's testability helper, getTestability, requires a root element to be
|
||||
passed in. This helps differentiate between different AngularJS apps on the same
|
||||
Angular's testability helper, getTestability, requires a root element to be
|
||||
passed in. This helps differentiate between different Angular apps on the same
|
||||
page. This error is thrown when no injector is found for root element. It is
|
||||
often because the root element is outside of the ng-app.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
All date-related inputs like `<input type="date">` require the model to be a `Date` object.
|
||||
If the model is something else, this error will be thrown.
|
||||
AngularJS does not set validation errors on the `<input>` in this case
|
||||
Angular does not set validation errors on the `<input>` in this case
|
||||
as those errors are shown to the user, but the erroneous state was
|
||||
caused by incorrect application logic and not by the user.
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ The `input[number]` and `input[range]` directives require the model to be a `num
|
||||
|
||||
If the model is something else, this error will be thrown.
|
||||
|
||||
AngularJS does not set validation errors on the `<input>` in this case
|
||||
Angular does not set validation errors on the `<input>` in this case
|
||||
as this error is caused by incorrect application logic and not by bad input from the user.
|
||||
|
||||
If your model does not contain actual numbers then it is up to the application developer
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
@ngdoc error
|
||||
@name ngRef:noctrl
|
||||
@fullName A controller for the value of `ngRefRead` could not be found on the element.
|
||||
@description
|
||||
|
||||
This error occurs when the {@link ng.ngRef ngRef directive} specifies
|
||||
a value in `ngRefRead` that cannot be resolved to a directive / component controller.
|
||||
|
||||
Causes for this error can be:
|
||||
|
||||
1. Your `ngRefRead` value has a typo.
|
||||
2. You have a typo in the *registered* directive / component name.
|
||||
3. The directive / component does not have a controller.
|
||||
|
||||
Note that `ngRefRead` takes the name of the component / directive, not the name of controller, and
|
||||
also not the combination of directive and 'Controller'. For example, for a directive called 'myDirective',
|
||||
the correct declaration is `<div ng-ref="$ctrl.ref" ng-ref-read="myDirective">`.
|
||||
@@ -1,27 +0,0 @@
|
||||
@ngdoc error
|
||||
@name ngRef:nonassign
|
||||
@fullName Non-Assignable Expression
|
||||
@description
|
||||
|
||||
This error occurs when ngRef defines an expression that is not-assignable.
|
||||
|
||||
In order for ngRef to work, it must be possible to write the reference into the path defined with the expression.
|
||||
|
||||
For example, the following expressions are non-assignable:
|
||||
|
||||
```
|
||||
<my-directive ng-ref="{}"></my-directive>
|
||||
|
||||
<my-directive ng-ref="myFn()"></my-directive>
|
||||
|
||||
<!-- missing attribute value is also invalid -->
|
||||
<my-directive ng-ref></my-directive>
|
||||
|
||||
```
|
||||
|
||||
To resolve this error, use a path expression that is assignable:
|
||||
|
||||
```
|
||||
<my-directive ng-ref="$ctrl.reference"></my-directive>
|
||||
|
||||
```
|
||||
@@ -3,7 +3,7 @@
|
||||
@sortOrder 500
|
||||
@description
|
||||
|
||||
# Using the `$location` service
|
||||
# What does it do?
|
||||
|
||||
The `$location` service parses the URL in the browser address bar (based on [`window.location`](https://developer.mozilla.org/en/window.location)) and makes the URL available to
|
||||
your application. Changes to the URL in the address bar are reflected into the `$location` service and
|
||||
@@ -48,7 +48,7 @@ changes to `$location` are reflected into the browser address bar.
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="head">integration with AngularJS application life-cycle</td>
|
||||
<td class="head">integration with angular application life-cycle</td>
|
||||
<td>none</td>
|
||||
<td>knows about all internal life-cycle phases, integrates with {@link ng.$rootScope.Scope#$watch $watch}, ...</td>
|
||||
</tr>
|
||||
@@ -76,7 +76,7 @@ the current URL in the browser.
|
||||
It does not cause a full page reload when the browser URL is changed. To reload the page after
|
||||
changing the URL, use the lower-level API, `$window.location.href`.
|
||||
|
||||
## General overview of the API
|
||||
# General overview of the API
|
||||
|
||||
The `$location` service can behave differently, depending on the configuration that was provided to
|
||||
it when it was instantiated. The default configuration is suitable for many applications, for
|
||||
@@ -85,7 +85,7 @@ others customizing the configuration can enable new features.
|
||||
Once the `$location` service is instantiated, you can interact with it via jQuery-style getter and
|
||||
setter methods that allow you to get or change the current URL in the browser.
|
||||
|
||||
### `$location` service configuration
|
||||
## `$location` service configuration
|
||||
|
||||
To configure the `$location` service, retrieve the
|
||||
{@link ng.$locationProvider $locationProvider} and set the parameters as follows:
|
||||
@@ -113,12 +113,12 @@ To configure the `$location` service, retrieve the
|
||||
Prefix used for Hashbang URLs (used in Hashbang mode or in legacy browsers in HTML5 mode).<br />
|
||||
Default: `'!'`
|
||||
|
||||
#### Example configuration
|
||||
### Example configuration
|
||||
```js
|
||||
$locationProvider.html5Mode(true).hashPrefix('*');
|
||||
```
|
||||
|
||||
### Getter and setter methods
|
||||
## Getter and setter methods
|
||||
|
||||
`$location` service provides getter methods for read-only parts of the URL (absUrl, protocol, host,
|
||||
port) and getter / setter methods for url, path, search, hash:
|
||||
@@ -137,7 +137,7 @@ change multiple segments in one go, chain setters like this:
|
||||
$location.path('/newValue').search({key: value});
|
||||
```
|
||||
|
||||
### Replace method
|
||||
## Replace method
|
||||
|
||||
There is a special `replace` method which can be used to tell the $location service that the next
|
||||
time the $location service is synced with the browser, the last history record should be replaced
|
||||
@@ -173,7 +173,7 @@ encoded.
|
||||
`/path?search=a&b=c#hash`. The segments are encoded as well.
|
||||
|
||||
|
||||
## Hashbang and HTML5 Modes
|
||||
# Hashbang and HTML5 Modes
|
||||
|
||||
`$location` service has two configuration modes which control the format of the URL in the browser
|
||||
address bar: **Hashbang mode** (the default) and the **HTML5 mode** which is based on using the
|
||||
@@ -221,15 +221,15 @@ facilitate the browser URL change and history management.
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Hashbang mode (default mode)
|
||||
## Hashbang mode (default mode)
|
||||
|
||||
In this mode, `$location` uses Hashbang URLs in all browsers.
|
||||
AngularJS also does not intercept and rewrite links in this mode. I.e. links work
|
||||
Angular also does not intercept and rewrite links in this mode. I.e. links work
|
||||
as expected and also perform full page reloads when other parts of the url
|
||||
than the hash fragment was changed.
|
||||
|
||||
|
||||
#### Example
|
||||
### Example
|
||||
|
||||
```js
|
||||
it('should show example', function() {
|
||||
@@ -255,7 +255,7 @@ it('should show example', function() {
|
||||
});
|
||||
```
|
||||
|
||||
### HTML5 mode
|
||||
## HTML5 mode
|
||||
|
||||
In HTML5 mode, the `$location` service getters and setters interact with the browser URL address
|
||||
through the HTML5 history API. This allows for use of regular URL path and search segments,
|
||||
@@ -267,11 +267,11 @@ having to worry about whether the browser displaying your app supports the histo
|
||||
- Opening a regular URL in a legacy browser -> redirects to a hashbang URL
|
||||
- Opening hashbang URL in a modern browser -> rewrites to a regular URL
|
||||
|
||||
Note that in this mode, AngularJS intercepts all links (subject to the "Html link rewriting" rules below)
|
||||
Note that in this mode, Angular intercepts all links (subject to the "Html link rewriting" rules below)
|
||||
and updates the url in a way that never performs a full page reload.
|
||||
|
||||
|
||||
#### Example
|
||||
### Example
|
||||
|
||||
```js
|
||||
it('should show example', function() {
|
||||
@@ -320,14 +320,14 @@ it('should show example (when browser doesn\'t support HTML5 mode', function() {
|
||||
});
|
||||
```
|
||||
|
||||
#### Fallback for legacy browsers
|
||||
### Fallback for legacy browsers
|
||||
|
||||
For browsers that support the HTML5 history API, `$location` uses the HTML5 history API to write
|
||||
path and search. If the history API is not supported by a browser, `$location` supplies a Hashbang
|
||||
URL. This frees you from having to worry about whether the browser viewing your app supports the
|
||||
history API or not; the `$location` service makes this transparent to you.
|
||||
|
||||
#### HTML link rewriting
|
||||
### HTML link rewriting
|
||||
|
||||
When you use HTML5 history API mode, you will not need special hashbang links. All you have to do
|
||||
is specify regular URL links, such as: `<a href="/some?foo=bar">link</a>`
|
||||
@@ -361,9 +361,9 @@ Note that [attribute name normalization](guide/directive#normalization) does not
|
||||
`'internalLink'` will **not** match `'internal-link'`.
|
||||
|
||||
|
||||
#### Relative links
|
||||
### Relative links
|
||||
|
||||
Be sure to check all relative links, images, scripts etc. AngularJS requires you to specify the url
|
||||
Be sure to check all relative links, images, scripts etc. Angular requires you to specify the url
|
||||
base in the head of your main html file (`<base href="/my-base/index.html">`) unless `html5Mode.requireBase`
|
||||
is set to `false` in the html5Mode definition object passed to `$locationProvider.html5Mode()`. With
|
||||
that, relative urls will always be resolved to this base url, even if the initial url of the
|
||||
@@ -374,14 +374,14 @@ will only change `$location.hash()` and not modify the url otherwise. This is us
|
||||
to anchors on the same page without needing to know on which page the user currently is.
|
||||
|
||||
|
||||
#### Server side
|
||||
### Server side
|
||||
|
||||
Using this mode requires URL rewriting on server side, basically you have to rewrite all your links
|
||||
to entry point of your application (e.g. index.html). Requiring a `<base>` tag is also important for
|
||||
this case, as it allows AngularJS to differentiate between the part of the url that is the application
|
||||
this case, as it allows Angular to differentiate between the part of the url that is the application
|
||||
base and the path that should be handled by the application.
|
||||
|
||||
#### Base href constraints
|
||||
### Base href constraints
|
||||
|
||||
The `$location` service is not able to function properly if the current URL is outside the URL given
|
||||
as the base href. This can have subtle confusing consequences...
|
||||
@@ -391,7 +391,7 @@ called `/base`). The URL `/base` is actually outside the application (it refers
|
||||
in the root `/` folder).
|
||||
|
||||
If you wish to be able to navigate to the application via a URL such as `/base` then you should ensure that
|
||||
your server is setup to redirect such requests to `/base/`.
|
||||
you server is setup to redirect such requests to `/base/`.
|
||||
|
||||
See https://github.com/angular/angular.js/issues/14018 for more information.
|
||||
|
||||
@@ -403,7 +403,7 @@ legacy browsers and hashbang links in modern browser:
|
||||
- Modern browser will rewrite hashbang URLs to regular URLs.
|
||||
- Older browsers will redirect regular URLs to hashbang URLs.
|
||||
|
||||
#### Example
|
||||
### Example
|
||||
|
||||
Here you can see two `$location` instances that show the difference between **Html5 mode** and **Html5 Fallback mode**.
|
||||
Note that to simulate different levels of browser support, the `$location` instances are connected to
|
||||
@@ -415,7 +415,7 @@ redirect to regular / hashbang url, as this conversion happens only during parsi
|
||||
|
||||
In these examples we use `<base href="/base/index.html" />`. The inputs represent the address bar of the browser.
|
||||
|
||||
##### Browser in HTML5 mode
|
||||
#### Browser in HTML5 mode
|
||||
<example module="html5-mode" name="location-html5-mode">
|
||||
<file name="index.html">
|
||||
<div ng-controller="LocationController">
|
||||
@@ -565,7 +565,7 @@ In these examples we use `<base href="/base/index.html" />`. The inputs represen
|
||||
|
||||
</example>
|
||||
|
||||
##### Browser in HTML5 Fallback mode (Hashbang mode)
|
||||
#### Browser in HTML5 Fallback mode (Hashbang mode)
|
||||
<example module="hashbang-mode" name="location-hashbang-mode">
|
||||
<file name="index.html">
|
||||
<div ng-controller="LocationController">
|
||||
@@ -718,27 +718,27 @@ In these examples we use `<base href="/base/index.html" />`. The inputs represen
|
||||
|
||||
</example>
|
||||
|
||||
## Caveats
|
||||
# Caveats
|
||||
|
||||
### Page reload navigation
|
||||
## Page reload navigation
|
||||
|
||||
The `$location` service allows you to change only the URL; it does not allow you to reload the
|
||||
page. When you need to change the URL and reload the page or navigate to a different page, please
|
||||
use a lower level API, {@link ng.$window $window.location.href}.
|
||||
|
||||
### Using $location outside of the scope life-cycle
|
||||
## Using $location outside of the scope life-cycle
|
||||
|
||||
`$location` knows about AngularJS's {@link ng.$rootScope.Scope scope} life-cycle. When a URL changes in
|
||||
`$location` knows about Angular's {@link ng.$rootScope.Scope scope} life-cycle. When a URL changes in
|
||||
the browser it updates the `$location` and calls `$apply` so that all
|
||||
{@link ng.$rootScope.Scope#$watch $watchers} /
|
||||
{@link ng.$compile.directive.Attributes#$observe $observers} are notified.
|
||||
When you change the `$location` inside the `$digest` phase everything is ok; `$location` will
|
||||
propagate this change into browser and will notify all the {@link ng.$rootScope.Scope#$watch $watchers} /
|
||||
{@link ng.$compile.directive.Attributes#$observe $observers}.
|
||||
When you want to change the `$location` from outside AngularJS (for example, through a DOM Event or
|
||||
When you want to change the `$location` from outside Angular (for example, through a DOM Event or
|
||||
during testing) - you must call `$apply` to propagate the changes.
|
||||
|
||||
### $location.path() and ! or / prefixes
|
||||
## $location.path() and ! or / prefixes
|
||||
|
||||
A path should always begin with forward slash (`/`); the `$location.path()` setter will add the
|
||||
forward slash if it is missing.
|
||||
@@ -746,17 +746,22 @@ forward slash if it is missing.
|
||||
Note that the `!` prefix in the hashbang mode is not part of `$location.path()`; it is actually
|
||||
`hashPrefix`.
|
||||
|
||||
### Crawling your app
|
||||
## Crawling your app
|
||||
|
||||
Most modern search engines are able to crawl AJAX applications with dynamic content, provided all
|
||||
included resources are available to the crawler bots.
|
||||
To allow indexing of your AJAX application, you have to add special meta tag in the head section of
|
||||
your document:
|
||||
|
||||
There also exists a special
|
||||
[AJAX crawling scheme](http://code.google.com/web/ajaxcrawling/docs/specification.html) developed by
|
||||
Google that allows bots to crawl the static equivalent of a dynamically generated page,
|
||||
but this schema has been deprecated, and support for it may vary by search engine.
|
||||
```html
|
||||
<meta name="fragment" content="!" />
|
||||
```
|
||||
|
||||
## Testing with the $location service
|
||||
This will cause crawler bot to request links with `_escaped_fragment_` param so that your server
|
||||
can recognize the crawler and serve a HTML snapshots. For more information about this technique,
|
||||
see [Making AJAX Applications
|
||||
Crawlable](http://code.google.com/web/ajaxcrawling/docs/specification.html).
|
||||
|
||||
|
||||
# Testing with the $location service
|
||||
|
||||
When using `$location` service during testing, you are outside of the angular's {@link
|
||||
ng.$rootScope.Scope scope} life-cycle. This means it's your responsibility to call `scope.$apply()`.
|
||||
@@ -779,6 +784,85 @@ describe('serviceUnderTest', function() {
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
# Migrating from earlier AngularJS releases
|
||||
|
||||
In earlier releases of Angular, `$location` used `hashPath` or `hashSearch` to process path and
|
||||
search methods. With this release, the `$location` service processes path and search methods and
|
||||
then uses the information it obtains to compose hashbang URLs (such as
|
||||
`http://server.com/#!/path?search=a`), when necessary.
|
||||
|
||||
## Changes to your code
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr class="head">
|
||||
<th>Navigation inside the app</th>
|
||||
<th>Change to</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>$location.href = value<br />$location.hash = value<br />$location.update(value)<br
|
||||
/>$location.updateHash(value)</td>
|
||||
<td>$location.path(path).search(search)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>$location.hashPath = path</td>
|
||||
<td>$location.path(path)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>$location.hashSearch = search</td>
|
||||
<td>$location.search(search)</td>
|
||||
</tr>
|
||||
|
||||
<tr class="head">
|
||||
<th>Navigation outside the app</td>
|
||||
<th>Use lower level API</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>$location.href = value<br />$location.update(value)</td>
|
||||
<td>$window.location.href = value</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>$location[protocol | host | port | path | search]</td>
|
||||
<td>$window.location[protocol | host | port | path | search]</td>
|
||||
</tr>
|
||||
|
||||
<tr class="head">
|
||||
<th>Read access</td>
|
||||
<th>Change to</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>$location.hashPath</td>
|
||||
<td>$location.path()</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>$location.hashSearch</td>
|
||||
<td>$location.search()</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>$location.href<br />$location.protocol<br />$location.host<br />$location.port<br
|
||||
/>$location.hash</td>
|
||||
<td>$location.absUrl()<br />$location.protocol()<br />$location.host()<br />$location.port()<br
|
||||
/>$location.path() + $location.search()</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>$location.path<br />$location.search</td>
|
||||
<td>$window.location.path<br />$window.location.search</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Two-way binding to $location
|
||||
|
||||
Because `$location` uses getters/setters, you can use `ng-model-options="{ getterSetter: true }"`
|
||||
@@ -800,6 +884,6 @@ angular.module('locationExample', [])
|
||||
</file>
|
||||
</example>
|
||||
|
||||
## Related API
|
||||
# Related API
|
||||
|
||||
* {@link ng.$location `$location` API}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
# Accessibility with ngAria
|
||||
|
||||
The goal of ngAria is to improve AngularJS's default accessibility by enabling common
|
||||
The goal of ngAria is to improve Angular's default accessibility by enabling common
|
||||
[ARIA](http://www.w3.org/TR/wai-aria/) attributes that convey state or semantic information for
|
||||
assistive technologies used by persons with disabilities.
|
||||
|
||||
@@ -109,11 +109,11 @@ attributes (if they have not been explicitly specified by the developer):
|
||||
function isEmpty(value) {
|
||||
return !value;
|
||||
}
|
||||
|
||||
|
||||
function render() {
|
||||
elem[ctrl.$viewValue ? 'addClass' : 'removeClass']('checked');
|
||||
}
|
||||
|
||||
|
||||
function toggleCheckbox() {
|
||||
ctrl.$setViewValue(!ctrl.$viewValue);
|
||||
ctrl.$render();
|
||||
@@ -420,7 +420,7 @@ tell ngAria to ignore the attribute globally.
|
||||
|
||||
## Common Accessibility Patterns
|
||||
|
||||
Accessibility best practices that apply to web apps in general also apply to AngularJS.
|
||||
Accessibility best practices that apply to web apps in general also apply to Angular.
|
||||
|
||||
* **Text alternatives**: Add alternate text content to make visual information accessible using
|
||||
[these W3C guidelines](http://www.w3.org/TR/html-alt-techniques/). The appropriate technique
|
||||
|
||||
@@ -66,7 +66,7 @@ You may also want to setup a separate CSS file for defining CSS-based animations
|
||||
## How they work
|
||||
|
||||
Animations in AngularJS are completely based on CSS classes. As long as you have a CSS class
|
||||
attached to an HTML element within your application, you can apply animations to it. Let's say for
|
||||
attached to a HTML element within your application, you can apply animations to it. Lets say for
|
||||
example that we have an HTML template with a repeater like so:
|
||||
|
||||
```html
|
||||
@@ -222,26 +222,22 @@ triggered:
|
||||
|
||||
| Directive | Supported Animations |
|
||||
|-------------------------------------------------------------------------------|---------------------------------------------------------------------------|
|
||||
| {@link ng.directive:form#animations form / ngForm} | add and remove ({@link ng.directive:form#css-classes various classes}) |
|
||||
| {@link ngAnimate.directive:ngAnimateSwap#animations ngAnimateSwap} | enter and leave |
|
||||
| {@link ng.directive:ngClass#animations ngClass / {{class}​}} | add and remove |
|
||||
| {@link ng.directive:ngClassEven#animations ngClassEven} | add and remove |
|
||||
| {@link ng.directive:ngClassOdd#animations ngClassOdd} | add and remove |
|
||||
| {@link ng.directive:ngHide#animations ngHide} | add and remove (the `ng-hide` class) |
|
||||
| {@link ng.directive:ngIf#animations ngIf} | enter and leave |
|
||||
| {@link ng.directive:ngInclude#animations ngInclude} | enter and leave |
|
||||
| {@link module:ngMessages#animations ngMessage / ngMessageExp} | enter and leave |
|
||||
| {@link module:ngMessages#animations ngMessages} | add and remove (the `ng-active`/`ng-inactive` classes) |
|
||||
| {@link ng.directive:ngModel#animations ngModel} | add and remove ({@link ng.directive:ngModel#css-classes various classes}) |
|
||||
| {@link ng.directive:ngRepeat#animations ngRepeat} | enter, leave, and move |
|
||||
| {@link ng.directive:ngShow#animations ngShow} | add and remove (the `ng-hide` class) |
|
||||
| {@link ng.directive:ngIf#animations ngIf} | enter and leave |
|
||||
| {@link ng.directive:ngSwitch#animations ngSwitch} | enter and leave |
|
||||
| {@link ng.directive:ngInclude#animations ngInclude} | enter and leave |
|
||||
| {@link ngRoute.directive:ngView#animations ngView} | enter and leave |
|
||||
|
||||
(More information can be found by visiting the documentation associated with each directive.)
|
||||
| {@link module:ngMessages#animations ngMessage / ngMessageExp} | enter and leave |
|
||||
| {@link ng.directive:ngClass#animations ngClass / {{class}​}} | add and remove |
|
||||
| {@link ng.directive:ngClass#animations ngClassEven / ngClassOdd} | add and remove |
|
||||
| {@link ng.directive:ngHide#animations ngHide} | add and remove (the `ng-hide` class) |
|
||||
| {@link ng.directive:ngShow#animations ngShow} | add and remove (the `ng-hide` class) |
|
||||
| {@link ng.directive:ngModel#animations ngModel} | add and remove ({@link ng.directive:ngModel#css-classes various classes}) |
|
||||
| {@link ng.directive:form#animations form / ngForm} | add and remove ({@link ng.directive:form#css-classes various classes}) |
|
||||
| {@link module:ngMessages#animations ngMessages} | add and remove (the `ng-active`/`ng-inactive` classes) |
|
||||
|
||||
For a full breakdown of the steps involved during each animation event, refer to the
|
||||
{@link ng.$animate `$animate` API docs}.
|
||||
{@link ng.$animate API docs}.
|
||||
|
||||
## How do I use animations in my own directives?
|
||||
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
# Bootstrap
|
||||
|
||||
This page explains the AngularJS initialization process and how you can manually initialize AngularJS
|
||||
This page explains the Angular initialization process and how you can manually initialize Angular
|
||||
if necessary.
|
||||
|
||||
|
||||
## AngularJS `<script>` Tag
|
||||
## Angular `<script>` Tag
|
||||
|
||||
This example shows the recommended path for integrating AngularJS with what we call automatic
|
||||
This example shows the recommended path for integrating Angular with what we call automatic
|
||||
initialization.
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ initialization.
|
||||
* Choose: `angular-[version].min.js` for a compressed and obfuscated file, suitable for use in
|
||||
production.
|
||||
2. Place `ng-app` to the root of your application, typically on the `<html>` tag if you want
|
||||
AngularJS to auto-bootstrap your application.
|
||||
angular to auto-bootstrap your application.
|
||||
|
||||
<html ng-app>
|
||||
|
||||
@@ -51,16 +51,16 @@ initialization.
|
||||
|
||||
<img class="pull-right" style="padding-left: 3em;" src="img/guide/concepts-startup.png">
|
||||
|
||||
AngularJS initializes automatically upon `DOMContentLoaded` event or when the `angular.js` script is
|
||||
evaluated if at that time `document.readyState` is set to `'complete'`. At this point AngularJS looks
|
||||
Angular initializes automatically upon `DOMContentLoaded` event or when the `angular.js` script is
|
||||
evaluated if at that time `document.readyState` is set to `'complete'`. At this point Angular looks
|
||||
for the {@link ng.directive:ngApp `ngApp`} directive which designates your application root.
|
||||
If the {@link ng.directive:ngApp `ngApp`} directive is found then AngularJS will:
|
||||
If the {@link ng.directive:ngApp `ngApp`} directive is found then Angular will:
|
||||
|
||||
* load the {@link guide/module module} associated with the directive.
|
||||
* create the application {@link auto.$injector injector}
|
||||
* compile the DOM treating the {@link ng.directive:ngApp
|
||||
`ngApp`} directive as the root of the compilation. This allows you to tell it to treat only a
|
||||
portion of the DOM as an AngularJS application.
|
||||
portion of the DOM as an Angular application.
|
||||
|
||||
|
||||
```html
|
||||
@@ -96,9 +96,9 @@ for more.
|
||||
|
||||
If you need to have more control over the initialization process, you can use a manual
|
||||
bootstrapping method instead. Examples of when you'd need to do this include using script loaders
|
||||
or the need to perform an operation before AngularJS compiles a page.
|
||||
or the need to perform an operation before Angular compiles a page.
|
||||
|
||||
Here is an example of manually initializing AngularJS:
|
||||
Here is an example of manually initializing Angular:
|
||||
|
||||
```html
|
||||
<!doctype html>
|
||||
|
||||
@@ -10,15 +10,15 @@
|
||||
|
||||
If you're just getting started, we recommend the {@link tutorial/ tutorial} first.
|
||||
If you just want to create custom directives, we recommend the {@link guide/directive directives guide}.
|
||||
If you want a deeper look into AngularJS's compilation process, you're in the right place.
|
||||
If you want a deeper look into Angular's compilation process, you're in the right place.
|
||||
</div>
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
AngularJS's {@link ng.$compile HTML compiler} allows the developer to teach the
|
||||
Angular's {@link ng.$compile HTML compiler} allows the developer to teach the
|
||||
browser new HTML syntax. The compiler allows you to attach behavior to any HTML element or attribute
|
||||
and even create new HTML elements or attributes with custom behavior. AngularJS calls these behavior
|
||||
and even create new HTML elements or attributes with custom behavior. Angular calls these behavior
|
||||
extensions {@link ng.$compileProvider#directive directives}.
|
||||
|
||||
HTML has a lot of constructs for formatting the HTML for static documents in a declarative fashion.
|
||||
@@ -31,7 +31,7 @@ However, the declarative language is also limited, as it does not allow you to t
|
||||
syntax. For example, there is no easy way to get the browser to align the text at 1/3 the position
|
||||
instead of 1/2. What is needed is a way to teach the browser new HTML syntax.
|
||||
|
||||
AngularJS comes pre-bundled with common directives which are useful for building any app. We also
|
||||
Angular comes pre-bundled with common directives which are useful for building any app. We also
|
||||
expect that you will create directives that are specific to your app. These extensions become a
|
||||
Domain Specific Language for building your application.
|
||||
|
||||
@@ -41,7 +41,7 @@ involved.
|
||||
|
||||
## Compiler
|
||||
|
||||
Compiler is an AngularJS service which traverses the DOM looking for attributes. The compilation
|
||||
Compiler is an Angular service which traverses the DOM looking for attributes. The compilation
|
||||
process happens in two phases.
|
||||
|
||||
1. **Compile:** traverse the DOM and collect all of the directives. The result is a linking
|
||||
@@ -142,16 +142,16 @@ This means that any changes to the data need to be re-merged with the template a
|
||||
3. managing the whole update process
|
||||
4. lack of behavior expressiveness
|
||||
|
||||
AngularJS is different. The AngularJS compiler consumes the DOM, not string templates.
|
||||
Angular is different. The Angular compiler consumes the DOM, not string templates.
|
||||
The result is a linking function, which when combined with a scope model results in a live view. The
|
||||
view and scope model bindings are transparent. The developer does not need to make any special calls to update
|
||||
the view. And because `innerHTML` is not used, you won't accidentally clobber user input.
|
||||
Furthermore, AngularJS directives can contain not just text bindings, but behavioral constructs as
|
||||
Furthermore, Angular directives can contain not just text bindings, but behavioral constructs as
|
||||
well.
|
||||
|
||||
<img src="img/Two_Way_Data_Binding.png">
|
||||
|
||||
The AngularJS approach produces a stable DOM. The DOM element instance bound to a model
|
||||
The Angular approach produces a stable DOM. The DOM element instance bound to a model
|
||||
item instance does not change for the lifetime of the binding. This means that the code can get
|
||||
hold of the elements and register event handlers and know that the reference will not be destroyed
|
||||
by template data merge.
|
||||
@@ -160,7 +160,7 @@ by template data merge.
|
||||
|
||||
## How directives are compiled
|
||||
|
||||
It's important to note that AngularJS operates on DOM nodes rather than strings. Usually, you don't
|
||||
It's important to note that Angular operates on DOM nodes rather than strings. Usually, you don't
|
||||
notice this restriction because when a page loads, the web browser parses HTML into the DOM automatically.
|
||||
|
||||
HTML compilation happens in three phases:
|
||||
@@ -186,7 +186,7 @@ The result of this is a live binding between the scope and the DOM. So at this p
|
||||
a model on the compiled scope will be reflected in the DOM.
|
||||
|
||||
Below is the corresponding code using the `$compile` service.
|
||||
This should help give you an idea of what AngularJS does internally.
|
||||
This should help give you an idea of what Angular does internally.
|
||||
|
||||
```js
|
||||
var $compile = ...; // injected into your code
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
We are investigating backporting the new Angular Router to AngularJS, but alternatively, use the {@link ngRoute} module or community developed projects (e.g. [ui-router](https://github.com/angular-ui/ui-router)).
|
||||
</div>
|
||||
|
||||
This guide describes the Component Router for AngularJS.
|
||||
This guide describes the new Component Router for AngularJS 1.5.
|
||||
|
||||
<div class="alert alert-info">
|
||||
If you are looking for information about the default router for AngularJS have a look at the {@link ngRoute} module.
|
||||
@@ -28,7 +28,7 @@ Here is a table of the main concepts used in the Component Router.
|
||||
| Router | Displays the Routing Components for the active Route. Manages navigation from one component to the next. |
|
||||
| RootRouter | The top level Router that interacts with the current URL location |
|
||||
| RouteConfig | Configures a Router with RouteDefinitions, each mapping a URL path to a component. |
|
||||
| Routing Component | An AngularJS component with a RouteConfig and an associated Router. |
|
||||
| Routing Component | An Angular component with a RouteConfig and an associated Router. |
|
||||
| RouteDefinition | Defines how the router should navigate to a component based on a URL pattern. |
|
||||
| ngOutlet | The directive (`<ng-outlet>`) that marks where the router should display a view. |
|
||||
| ngLink | The directive (`ng-link="..."`) for binding a clickable HTML element to a route, via a Link Parameters Array. |
|
||||
@@ -138,7 +138,7 @@ The result is that we end up with a hierarchy of **Routing Components** rendered
|
||||

|
||||
|
||||
|
||||
## Example Heroes App
|
||||
# Example Heroes App
|
||||
|
||||
You can see the complete application running below.
|
||||
|
||||
@@ -459,12 +459,12 @@ You can see the complete application running below.
|
||||
</example>
|
||||
|
||||
|
||||
### Getting Started
|
||||
# Getting Started
|
||||
|
||||
In the following sections we will step through building this application. The finished application has views
|
||||
to display list and detail views of Heroes and Crises.
|
||||
|
||||
#### Install the libraries
|
||||
## Install the libraries
|
||||
|
||||
It is easier to use [Yarn](https://yarnpkg.com) or [npm](https://www.npmjs.com) to install the
|
||||
**Component Router** module. For this guide we will also install AngularJS itself via Yarn:
|
||||
@@ -475,9 +475,9 @@ yarn add angular@1.5.x @angular/router@0.2.0
|
||||
```
|
||||
|
||||
|
||||
#### Load the scripts
|
||||
## Load the scripts
|
||||
|
||||
Just like any AngularJS application, we load the JavaScript files into our `index.html`:
|
||||
Just like any Angular application, we load the JavaScript files into our `index.html`:
|
||||
|
||||
```html
|
||||
<script src="/node_modules/angular/angular.js"></script>
|
||||
@@ -494,7 +494,7 @@ You also need to include ES6 shims for browsers that do not support ES6 code (In
|
||||
<script src="https://unpkg.com/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
|
||||
```
|
||||
|
||||
#### Create the `app` module
|
||||
## Create the `app` module
|
||||
|
||||
In the app.js file, create the main application module `app` which depends on the `ngComponentRouter`
|
||||
module, which is provided by the **Component Router** script.
|
||||
@@ -528,7 +528,7 @@ Configure the top level routed `App` Component.
|
||||
|
||||
Create a very simple App Component to test that the application is working.
|
||||
|
||||
We are using the AngularJS {@link $compileProvider#component `.component()`} helper method to create
|
||||
We are using the Angular 1.5 {@link $compileProvider#component `.component()`} helper method to create
|
||||
all the **Components** in our application. It is perfectly suited to this task.
|
||||
|
||||
```js
|
||||
@@ -547,9 +547,9 @@ must have a base URL.
|
||||
...
|
||||
```
|
||||
|
||||
#### Bootstrap AngularJS
|
||||
## Bootstrap AngularJS
|
||||
|
||||
Bootstrap the AngularJS application and add the top level App Component.
|
||||
Bootstrap the Angular application and add the top level App Component.
|
||||
|
||||
```html
|
||||
<body ng-app="app">
|
||||
@@ -559,7 +559,7 @@ Bootstrap the AngularJS application and add the top level App Component.
|
||||
```
|
||||
|
||||
|
||||
### Implementing the AppComponent
|
||||
# Implementing the AppComponent
|
||||
|
||||
In the previous section we have created a single top level **App Component**. Let's now create some more
|
||||
**Routing Components** and wire up **Route Config** for those. We start with a Heroes Feature, which
|
||||
@@ -577,7 +577,7 @@ We are going to have a `Heroes` Component for the Heroes feature of our applicat
|
||||
and `HeroDetail` **Components** that will actually display the two different views.
|
||||
|
||||
|
||||
#### App Component
|
||||
## App Component
|
||||
|
||||
Configure the **App Component** with a template and **Route Config**:
|
||||
|
||||
@@ -598,7 +598,7 @@ Configure the **App Component** with a template and **Route Config**:
|
||||
The **App Component** has an `<ng-outlet>` directive in its template. This is where the child **Components**
|
||||
of this view will be rendered.
|
||||
|
||||
#### ngLink
|
||||
### ngLink
|
||||
|
||||
We have used the `ng-link` directive to create a link to navigate to the Heroes Component. By using this
|
||||
directive we don't need to know what the actual URL will be. We can let the Router generate that for us.
|
||||
@@ -607,7 +607,7 @@ We have included a link to the Crisis Center but have not included the `ng-link`
|
||||
implemented the CrisisCenter component.
|
||||
|
||||
|
||||
#### Non-terminal Routes
|
||||
### Non-terminal Routes
|
||||
|
||||
We need to tell the **Router** that the `Heroes` **Route Definition** is **non-terminal**, that it should
|
||||
continue to match **Routes** in its child **Components**. We do this by adding a **continuation ellipsis
|
||||
@@ -616,16 +616,16 @@ Without the **continuation ellipsis** the `HeroList` **Route** will never be mat
|
||||
stop at the `Heroes` **Routing Component** and not try to match the rest of the URL.
|
||||
|
||||
|
||||
### Heroes Feature
|
||||
## Heroes Feature
|
||||
|
||||
Now we can implement our Heroes Feature which consists of three **Components**: `Heroes`, `HeroList` and
|
||||
`HeroDetail`. The `Heroes` **Routing Component** simply provides a template containing the {@link ngOutlet}
|
||||
directive and a **Route Config** that defines a set of child **Routes** which delegate through to the
|
||||
`HeroList` and `HeroDetail` **Components**.
|
||||
|
||||
### HeroesComponent
|
||||
## HeroesComponent
|
||||
|
||||
Create a new file `heroes.js`, which defines a new AngularJS module for the **Components** of this feature
|
||||
Create a new file `heroes.js`, which defines a new Angular module for the **Components** of this feature
|
||||
and registers the Heroes **Component**.
|
||||
|
||||
```js
|
||||
@@ -651,20 +651,20 @@ and also to add the module as a dependency of the `app` module:
|
||||
angular.module('app', ['ngComponentRouter', 'heroes'])
|
||||
```
|
||||
|
||||
#### Use As Default
|
||||
### Use As Default
|
||||
The `useAsDefault` property on the `HeroList` **Route Definition**, indicates that if no other **Route
|
||||
Definition** matches the URL, then this **Route Definition** should be used by default.
|
||||
|
||||
#### Route Parameters
|
||||
### Route Parameters
|
||||
The `HeroDetail` Route has a named parameter (`id`), indicated by prefixing the URL segment with a colon,
|
||||
as part of its `path` property. The **Router** will match anything in this segment and make that value
|
||||
available to the HeroDetail **Component**.
|
||||
|
||||
#### Terminal Routes
|
||||
### Terminal Routes
|
||||
Both the Routes in the `HeroesComponent` are terminal, i.e. their routes do not end with `...`. This is
|
||||
because the `HeroList` and `HeroDetail` will not contain any child routes.
|
||||
|
||||
#### Route Names
|
||||
### Route Names
|
||||
**What is the difference between the `name` and `component` properties on a Route Definition?**
|
||||
|
||||
The `component` property in a **Route Definition** defines the **Component** directive that will be rendered
|
||||
@@ -676,7 +676,7 @@ The `name` property is used to reference the **Route Definition** when generatin
|
||||
that has the `name` property of `"Heroes"`.
|
||||
|
||||
|
||||
### HeroList Component
|
||||
## HeroList Component
|
||||
|
||||
The HeroList **Component** is the first component in the application that actually contains significant
|
||||
functionality. It loads up a list of heroes from a `heroService` and displays them using `ng-repeat`.
|
||||
@@ -705,7 +705,7 @@ The template iterates through each `hero` object of the array in the `$ctrl.hero
|
||||
the `$ctrl` property on the scope of the template.*
|
||||
|
||||
|
||||
### HeroService
|
||||
## HeroService
|
||||
|
||||
Our HeroService simulates requesting a list of heroes from a server. In a real application this would be
|
||||
making an actual server request, perhaps over HTTP.
|
||||
@@ -735,7 +735,7 @@ Note that both the `getHeroes()` and `getHero(id)` methods return a promise for
|
||||
in real-life we would have to wait for the server to respond with the data.
|
||||
|
||||
|
||||
### Router Lifecycle Hooks
|
||||
## Router Lifecycle Hooks
|
||||
|
||||
**How do I know when my Component is active?**
|
||||
|
||||
@@ -780,7 +780,7 @@ By returning a promise for the list of heroes from `$routerOnActivate()` we can
|
||||
Route until the heroes have arrived successfully. This is similar to how a `resolve` works in {@link ngRoute}.
|
||||
|
||||
|
||||
### Route Parameters
|
||||
## Route Parameters
|
||||
|
||||
**How do I access parameters for the current route?**
|
||||
|
||||
@@ -811,11 +811,11 @@ by the **Router**. In this code it is used to identify a specific Hero to retrie
|
||||
This hero is then attached to the **Component** so that it can be accessed in the template.
|
||||
|
||||
|
||||
### Access to the Current Router
|
||||
## Access to the Current Router
|
||||
|
||||
**How do I get hold of the current router for my component?**
|
||||
|
||||
Each component has its own Router. Unlike in the new Angular, we cannot use the dependency injector to get hold of a component's Router.
|
||||
Each component has its own Router. Unlike in Angular 2, we cannot use the dependency injector to get hold of a component's Router.
|
||||
We can only inject the `$rootRouter`. Instead we use the fact that the `ng-outlet` directive binds the current router to a `$router`
|
||||
attribute on our component.
|
||||
|
||||
@@ -882,7 +882,7 @@ Other options for generating this navigation are:
|
||||
```
|
||||
this form gives you the possibility of caching the instruction, but is more verbose.
|
||||
|
||||
#### Absolute vs Relative Navigation
|
||||
### Absolute vs Relative Navigation
|
||||
|
||||
**Why not use `$rootRouter` to do the navigation?**
|
||||
|
||||
@@ -894,7 +894,7 @@ to the `HeroListComponent` with the `$rootRouter`, we would have to provide a co
|
||||
`['App','Heroes','HeroList']`.
|
||||
|
||||
|
||||
### Extra Parameters
|
||||
## Extra Parameters
|
||||
|
||||
We can also pass additional optional parameters to routes, which get encoded into the URL and are again
|
||||
available to the `$routerOnActivate(next, previous)` hook. If we pass the current `id` from the
|
||||
@@ -936,7 +936,7 @@ Finally, we can use this information to highlight the current hero in the templa
|
||||
</div>
|
||||
```
|
||||
|
||||
### Crisis Center
|
||||
## Crisis Center
|
||||
|
||||
Let's implement the Crisis Center feature, which displays a list if crises that need to be dealt with by a hero.
|
||||
The detailed crisis view has an additional feature where it blocks you from navigating if you have not saved
|
||||
@@ -951,7 +951,7 @@ changes to the crisis being edited.
|
||||

|
||||
|
||||
|
||||
### Crisis Feature
|
||||
## Crisis Feature
|
||||
|
||||
This feature is very similar to the Heroes feature. It contains the following **Components**:
|
||||
|
||||
@@ -962,7 +962,7 @@ This feature is very similar to the Heroes feature. It contains the following **
|
||||
CrisisService and CrisisListComponent are basically the same as HeroService and HeroListComponent
|
||||
respectively.
|
||||
|
||||
### Navigation Control Hooks
|
||||
## Navigation Control Hooks
|
||||
|
||||
**How do I prevent navigation from occurring?**
|
||||
|
||||
@@ -979,7 +979,7 @@ can complete, all the **Components** must agree that they can be deactivated or
|
||||
The **Router** will call the `$routerCanDeactivate` and `$canActivate` hooks, if they are provided. If any
|
||||
of the hooks resolve to `false` then the navigation is cancelled.
|
||||
|
||||
#### Dialog Box Service
|
||||
### Dialog Box Service
|
||||
|
||||
We can implement a very simple dialog box that will prompt the user whether they are happy to lose changes they
|
||||
have made. The result of the prompt is a promise that can be used in a `$routerCanDeactivate` hook.
|
||||
|
||||
@@ -5,17 +5,17 @@
|
||||
|
||||
# Understanding Components
|
||||
|
||||
In AngularJS, a Component is a special kind of {@link guide/directive directive} that uses a simpler
|
||||
In Angular, a Component is a special kind of {@link guide/directive directive} that uses a simpler
|
||||
configuration which is suitable for a component-based application structure.
|
||||
|
||||
This makes it easier to write an app in a way that's similar to using Web Components or using the new Angular's
|
||||
style of application architecture.
|
||||
This makes it easier to write an app in a way that's similar to using Web Components or using Angular
|
||||
2's style of application architecture.
|
||||
|
||||
Advantages of Components:
|
||||
- simpler configuration than plain directives
|
||||
- promote sane defaults and best practices
|
||||
- optimized for component-based architecture
|
||||
- writing component directives will make it easier to upgrade to Angular
|
||||
- writing component directives will make it easier to upgrade to Angular 2
|
||||
|
||||
When not to use Components:
|
||||
|
||||
@@ -25,7 +25,7 @@ When not to use Components:
|
||||
|
||||
## Creating and configuring a Component
|
||||
|
||||
Components can be registered using the {@link ng.$compileProvider#component `.component()`} method of an AngularJS module (returned by {@link module `angular.module()`}). The method takes two arguments:
|
||||
Components can be registered using the `.component()` method of an Angular module (returned by {@link module `angular.module()`}). The method takes two arguments:
|
||||
|
||||
* The name of the Component (as string).
|
||||
* The Component config object. (Note that, unlike the `.directive()` method, this method does **not** take a factory function.)
|
||||
@@ -90,14 +90,14 @@ a component-based architecture. But what makes a component beyond the options th
|
||||
the component helper has?
|
||||
|
||||
- **Components only control their own View and Data:**
|
||||
Components should never modify any data or DOM that is out of their own scope. Normally, in AngularJS
|
||||
Components should never modify any data or DOM that is out of their own scope. Normally, in Angular
|
||||
it is possible to modify data anywhere in the application through scope inheritance and watches. This
|
||||
is practical, but can also lead to problems when it is not clear which part of the application is
|
||||
responsible for modifying the data. That is why component directives use an isolate scope, so a whole
|
||||
class of scope manipulation is not possible.
|
||||
|
||||
- **Components have a well-defined public API - Inputs and Outputs:**
|
||||
However, scope isolation only goes so far, because AngularJS uses two-way binding. So if you pass
|
||||
However, scope isolation only goes so far, because Angular uses two-way binding. So if you pass
|
||||
an object to a component like this - `bindings: {item: '='}`, and modify one of its properties, the
|
||||
change will be reflected in the parent component. For components however, only the component that owns
|
||||
the data should modify it, to make it easy to reason about what data is changed, and when. For that reason,
|
||||
@@ -143,7 +143,7 @@ components should follow a few simple conventions:
|
||||
}
|
||||
```
|
||||
|
||||
- **Components have a well-defined lifecycle:**
|
||||
- **Components have a well-defined lifecycle**
|
||||
Each component can implement "lifecycle hooks". These are methods that will be called at certain points in the life
|
||||
of the component. The following hook methods can be implemented:
|
||||
|
||||
@@ -158,7 +158,7 @@ of the component. The following hook methods can be implemented:
|
||||
changes. Any actions that you wish to take in response to the changes that you detect must be
|
||||
invoked from this hook; implementing this has no effect on when `$onChanges` is called. For example, this hook
|
||||
could be useful if you wish to perform a deep equality check, or to check a Date object, changes to which would not
|
||||
be detected by AngularJS's change detector and thus not trigger `$onChanges`. This hook is invoked with no arguments;
|
||||
be detected by Angular's change detector and thus not trigger `$onChanges`. This hook is invoked with no arguments;
|
||||
if detecting changes, you must store the previous value(s) for comparison to the current values.
|
||||
* `$onDestroy()` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
|
||||
external resources, watches and event handlers.
|
||||
@@ -167,8 +167,8 @@ of the component. The following hook methods can be implemented:
|
||||
Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
|
||||
they are waiting for their template to load asynchronously and their own compilation and linking has been
|
||||
suspended until that occurs.
|
||||
This hook can be considered analogous to the `ngAfterViewInit` and `ngAfterContentInit` hooks in Angular.
|
||||
Since the compilation process is rather different in AngularJS there is no direct mapping and care should
|
||||
This hook can be considered analogous to the `ngAfterViewInit` and `ngAfterContentInit` hooks in Angular 2.
|
||||
Since the compilation process is rather different in Angular 1 there is no direct mapping and care should
|
||||
be taken when upgrading.
|
||||
|
||||
By implementing these methods, your component can hook into its lifecycle.
|
||||
@@ -445,7 +445,7 @@ angular.module('docsTabsExample', [])
|
||||
</example>
|
||||
|
||||
|
||||
## Unit-testing Component Controllers
|
||||
# Unit-testing Component Controllers
|
||||
|
||||
The easiest way to unit-test a component controller is by using the
|
||||
{@link ngMock.$componentController $componentController} that is included in {@link ngMock}. The
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user