Compare commits
273 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c3c5c5eea2 | |||
| 4cc7701700 | |||
| 5dc07667de | |||
| 212e5132ab | |||
| 00162655e7 | |||
| 09f1325065 | |||
| c01dad694d | |||
| c4586513d1 | |||
| 7a1270cf4b | |||
| 559e93c7ce | |||
| 9d058de04b | |||
| 1d826e2f1e | |||
| 5789094546 | |||
| cf92c33a32 | |||
| 5d8f5a8be7 | |||
| 74a2808487 | |||
| 9ba181b80f | |||
| 44c16b5b51 | |||
| 70a42fcaee | |||
| 3bd62d2d59 | |||
| b9ef6585e1 | |||
| e06b4fb62c | |||
| 9204a1a153 | |||
| f4d49f3769 | |||
| d5c35b44d7 | |||
| 551375c736 | |||
| 17691790e9 | |||
| e47dead052 | |||
| 1a2532601b | |||
| cb862aaaa0 | |||
| fa2034c167 | |||
| 750b43b6f6 | |||
| 048f5e3ab8 | |||
| 13c566cc03 | |||
| 45834eac09 | |||
| 3673909896 | |||
| 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 |
+1
-1
@@ -1,4 +1,3 @@
|
||||
bower_components/**
|
||||
build/**
|
||||
docs/bower_components/**
|
||||
docs/app/assets/js/angular-bootstrap/**
|
||||
@@ -9,3 +8,4 @@ src/angular.bind.js
|
||||
src/ngParseExt/ucd.js
|
||||
i18n/closure/**
|
||||
tmp/**
|
||||
vendor/**
|
||||
|
||||
+29
-19
@@ -1,27 +1,37 @@
|
||||
***Note*: for support questions, please use one of these channels: https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#question. This repository's issues are reserved for feature requests and bug reports.**
|
||||
<!--
|
||||
IF YOU DON'T FILL OUT THE FOLLOWING INFORMATION WE MIGHT CLOSE YOUR ISSUE WITHOUT INVESTIGATION
|
||||
-->
|
||||
|
||||
**Do you want to request a *feature* or report a *bug*?**
|
||||
<!--
|
||||
- For *SUPPORT QUESTIONS*, use one of the
|
||||
[support channels](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#question).
|
||||
- Before submitting, please **SEARCH GITHUB** for a similar issue or PR. -->
|
||||
|
||||
**I'm submitting a ...**
|
||||
<!-- (check one with "x") -->
|
||||
- [ ] bug report
|
||||
- [ ] feature request
|
||||
- [ ] other <!--(Please do not submit support requests here - see above)-->
|
||||
|
||||
**Current behavior:**
|
||||
<!-- Describe how the bug manifests / how the current features are insufficient. -->
|
||||
|
||||
**What is the current behavior?**
|
||||
**Expected / new behavior:**
|
||||
<!-- Describe what the behavior would be without the bug / how the feature would improve AngularJS -->
|
||||
|
||||
**Minimal reproduction of the problem with instructions:**
|
||||
<!--
|
||||
If the current behavior is a bug or you can illustrate your feature request better with an example,
|
||||
please provide the *STEPS TO REPRODUCE* and if possible a *MINIMAL DEMO* of the problem via
|
||||
https://plnkr.co or similar (you can use this template as a starting point: http://plnkr.co/edit/tpl:yBpEi4).
|
||||
-->
|
||||
|
||||
**AngularJS version:** 1.x.y
|
||||
<!-- Check whether this is still an issue in the most recent stable or in the snapshot AngularJS
|
||||
version (https://code.angularjs.org/snapshot/) -->
|
||||
|
||||
**If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar (template: http://plnkr.co/edit/tpl:yBpEi4).**
|
||||
**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) -->
|
||||
|
||||
|
||||
|
||||
**What is the expected behavior?**
|
||||
|
||||
|
||||
|
||||
**What is the motivation / use case for changing the behavior?**
|
||||
|
||||
|
||||
|
||||
**Which versions of Angular, and which browser / OS are affected by this issue? Did this work in previous versions of Angular? Please also test with the latest stable and snapshot (https://code.angularjs.org/snapshot/) versions.**
|
||||
|
||||
|
||||
|
||||
**Other information (e.g. stacktraces, related issues, suggestions how to fix)**
|
||||
**Anything else:**
|
||||
<!-- e.g. stacktraces, related issues, suggestions how to fix -->
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<!-- 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, ...)**
|
||||
|
||||
|
||||
@@ -15,9 +16,9 @@
|
||||
|
||||
|
||||
**Please check if the PR fulfills these requirements**
|
||||
- [ ] The commit message follows our guidelines: https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit-message-format
|
||||
- [ ] Tests for the changes have been added (for bug fixes / features)
|
||||
- [ ] Docs have been added / updated (for bug fixes / features)
|
||||
- [ ] 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**:
|
||||
|
||||
|
||||
+2
-4
@@ -9,8 +9,7 @@ performance/temp*.html
|
||||
*~
|
||||
*.swp
|
||||
angular.js.tmproj
|
||||
/node_modules/
|
||||
bower_components/
|
||||
node_modules/
|
||||
angular.xcodeproj
|
||||
.idea
|
||||
*.iml
|
||||
@@ -19,7 +18,6 @@ angular.xcodeproj
|
||||
libpeerconnection.log
|
||||
npm-debug.log
|
||||
/tmp/
|
||||
/scripts/bower/bower-*
|
||||
.vscode
|
||||
*.log
|
||||
*.stackdump
|
||||
*.stackdump
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
Andres Ornelas <aornelas@google.com>
|
||||
Caitlin Potter <caitpotter88@gmail.com>
|
||||
Caitlin Potter <caitpotter88@gmail.com> <snowball@defpixel.com>
|
||||
Di Peng <pengdi@google.com>
|
||||
Di Peng <pengdi@google.com> <pengdi@go.wustl.edu>
|
||||
Georgios Kalpakas <kalpakas.g@gmail.com>
|
||||
Georgios Kalpakas <kalpakas.g@gmail.com> <g.kalpakas@hotmail.com>
|
||||
Julie Ralph <ju.ralph@gmail.com>
|
||||
Lucas Galfaso <lgalfaso@gmail.com>
|
||||
Martin Staffa <mjstaffa@gmail.com>
|
||||
Martin Staffa <mjstaffa@gmail.com> <mjstaffa@googlemail.com>
|
||||
Matias Niemelä <matias@yearofmoo.com>
|
||||
Michał Gołębiowski-Owczarek <m.goleb@gmail.com>
|
||||
Misko Hevery <misko@hevery.com>
|
||||
Misko Hevery <misko@hevery.com> <misko@google.com>
|
||||
Igor Minar <igor@angularjs.org>
|
||||
Igor Minar <igor@angularjs.org> <iiminar@gmail.com>
|
||||
Igor Minar <igor@angularjs.org> <iminar@google.com>
|
||||
Igor Minar <igor@angularjs.org> <iminar@dhcp-172-19-37-154.mtv.corp.google.com>
|
||||
Pawel Kozlowski <pkozlowski.opensource@gmail.com>
|
||||
Peter Bacon Darwin <pete@bacondarwin.com>
|
||||
Rodric Haddad <rody@rodyhaddad.com>
|
||||
Shahar Talmi <shahar.talmi@gmail.com>
|
||||
Shahar Talmi <shahar.talmi@gmail.com> <shahart@wix.com>
|
||||
Shyam Seshadri <shyamseshadri@google.com>
|
||||
Shyam Seshadri <shyamseshadri@google.com> <shyamseshadri@gmail.com>
|
||||
Vojta Jina <vojta.jina@gmail.com>
|
||||
Vojta Jina <vojta.jina@gmail.com> <vojta@gemin-i.org>
|
||||
Vojta Jina <vojta.jina@gmail.com> <vojta@google.com>
|
||||
+71
-28
@@ -1,61 +1,104 @@
|
||||
language: node_js
|
||||
sudo: false
|
||||
node_js:
|
||||
- '6'
|
||||
- '8'
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
- bower_components
|
||||
- docs/bower_components
|
||||
yarn: true
|
||||
|
||||
branches:
|
||||
except:
|
||||
- /^g3_.*$/
|
||||
- "/^g3_.*$/"
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- JOB=ci-checks
|
||||
- JOB=unit BROWSER_PROVIDER=saucelabs
|
||||
- JOB=docs-e2e BROWSER_PROVIDER=saucelabs
|
||||
- JOB=unit-core BROWSER_PROVIDER=saucelabs
|
||||
- JOB=unit-jquery 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
|
||||
global:
|
||||
- CXX=g++-4.8 # node 4 likes the G++ v4.8 compiler
|
||||
- SAUCE_USERNAME=angular-ci
|
||||
- SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987
|
||||
- LOGS_DIR=/tmp/angular-build/logs
|
||||
- BROWSER_PROVIDER_READY_FILE=/tmp/browsersprovider-tunnel-ready
|
||||
|
||||
# node 4 likes the G++ v4.8 compiler
|
||||
# see https://docs.travis-ci.com/user/languages/javascript-with-nodejs#Node.js-v4-(or-io.js-v3)-compiler-requirements
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-4.8
|
||||
- secure: oTBjhnOKhs0qDSKTf7fE4f6DYiNDPycvB7qfSF5QRIbJK/LK/J4UtFwetXuXj79HhUZG9qnoT+5e7lPaiaMlpsIKn9ann7ffqFWN1E8TMtpJF+AGigx3djYElwfgf5nEnFUFhwjFzvbfpZNnxVGgX5YbIZpe/WUbHkP4ffU0Wks=
|
||||
|
||||
before_install:
|
||||
- curl -o- -L https://raw.githubusercontent.com/yarnpkg/yarn/2a0afc73210c7a82082585283e518eeb88ca19ae/scripts/install-latest.sh | bash -s -- --version 0.17.9
|
||||
- export PATH=$HOME/.yarn/bin:$PATH
|
||||
- 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 ./bower_components/ ./docs/bower_components/ || true
|
||||
- ./scripts/travis/before_build.sh
|
||||
- du -sh ./node_modules || true
|
||||
- "./scripts/travis/before_build.sh"
|
||||
|
||||
script:
|
||||
- ./scripts/travis/build.sh
|
||||
- "./scripts/travis/build.sh"
|
||||
|
||||
after_script:
|
||||
- ./scripts/travis/tear_down_browser_provider.sh
|
||||
- ./scripts/travis/print_logs.sh
|
||||
- "./scripts/travis/tear_down_browser_provider.sh"
|
||||
- "./scripts/travis/print_logs.sh"
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/d2120f3f2bb39a4531b2
|
||||
- http://104.197.9.155:8484/hubot/travis/activity #hubot-server
|
||||
on_success: always # options: [always|never|change] default: always
|
||||
on_failure: always # options: [always|never|change] default: always
|
||||
on_start: always # default: false
|
||||
on_success: always # options: [always|never|change] default: always
|
||||
on_failure: always # options: [always|never|change] default: always
|
||||
on_start: always # default: false
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: deploy
|
||||
# Don't deploy from PRs. Only deploy from our default branches, or if commit is tagged.
|
||||
# This is a Travis-specific boolean language: https://docs.travis-ci.com/user/conditional-builds-stages-jobs#Specifying-conditions
|
||||
# The deployment logic for pushed branches is further defined in scripts\travis\build.sh
|
||||
if: type != pull_request and (branch =~ ^(v1\.\d+\.x|master)$ or tag IS present)
|
||||
env:
|
||||
- JOB=deploy
|
||||
before_script: skip
|
||||
script:
|
||||
# Export the variables into the current process
|
||||
- . ./scripts/travis/build.sh
|
||||
- "echo DEPLOY_DOCS: $DEPLOY_DOCS, DEPLOY_CODE: $DEPLOY_CODE"
|
||||
after_script: skip
|
||||
# Work around the 10min Travis timeout so the code.angularjs firebase+gcs code deploy can complete
|
||||
# Only run the keep_alive once (before_deploy is run for each provider)
|
||||
before_deploy: |
|
||||
if ! [ "$BEFORE_DEPLOY_RUN" ]; then
|
||||
export BEFORE_DEPLOY_RUN=1;
|
||||
|
||||
function keep_alive() {
|
||||
while true; do
|
||||
echo -en "\a"
|
||||
sleep 10
|
||||
done
|
||||
}
|
||||
keep_alive &
|
||||
fi
|
||||
deploy:
|
||||
- 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:
|
||||
repo: angular/angular.js
|
||||
all_branches: true
|
||||
condition: "$DEPLOY_DOCS == true"
|
||||
- provider: gcs
|
||||
skip_cleanup: true
|
||||
access_key_id: GOOGLDB7W2J3LFHICF3R
|
||||
secret_access_key:
|
||||
secure: tHIFdSq55qkyZf9zT/3+VkhUrTvOTMuswxXU3KyWaBrSieZqG0UnUDyNm+n3lSfX95zEl/+rJAWbfvhVSxZi13ndOtvRF+MdI1cvow2JynP0aDSiPffEvVrZOmihD6mt2SlMfhskr5FTduQ69kZG6DfLcve1PPDaIwnbOv3phb8=
|
||||
bucket: code-angularjs-org-338b8.appspot.com
|
||||
local-dir: uploadCode
|
||||
detect_encoding: true # detects gzip compression
|
||||
on:
|
||||
repo: angular/angular.js
|
||||
all_branches: true
|
||||
condition: "$DEPLOY_CODE == true"
|
||||
|
||||
|
||||
+418
-16
@@ -1,3 +1,405 @@
|
||||
<a name="1.6.9"></a>
|
||||
# 1.6.9 fiery-basilisk (2018-02-02)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
- **input:** add `drop` event support for IE
|
||||
([5dc076](https://github.com/angular/angular.js/commit/5dc07667de00c5e85fd69c5b7b7fe4fb5fd65a77))
|
||||
- **ngMessages:** prevent memory leak from messages that are never attached
|
||||
([9d058d](https://github.com/angular/angular.js/commit/9d058de04bb78694b83179e9b97bc40214eca01a),
|
||||
[#16389](https://github.com/angular/angular.js/issues/16389),
|
||||
[#16404](https://github.com/angular/angular.js/issues/16404),
|
||||
[#16406](https://github.com/angular/angular.js/issues/16406))
|
||||
- **ngTransclude:** remove terminal: true
|
||||
([1d826e](https://github.com/angular/angular.js/commit/1d826e2f1e941d14c3c56d7a0249f5796ba11f85),
|
||||
[#16411](https://github.com/angular/angular.js/issues/16411),
|
||||
[#16412](https://github.com/angular/angular.js/issues/16412))
|
||||
- **$sanitize:** sanitize `xml:base` attributes
|
||||
([b9ef65](https://github.com/angular/angular.js/commit/b9ef6585e10477fbbf912a971fe0b390bca692a6))
|
||||
|
||||
|
||||
## New Features
|
||||
- **currencyFilter:** trim whitespace around an empty currency symbol
|
||||
([367390](https://github.com/angular/angular.js/commit/3673909896efb6ff47546caf7fc61549f193e043),
|
||||
[#15018](https://github.com/angular/angular.js/issues/15018),
|
||||
[#15085](https://github.com/angular/angular.js/issues/15085),
|
||||
[#15105](https://github.com/angular/angular.js/issues/15105))
|
||||
|
||||
|
||||
<a name="1.6.8"></a>
|
||||
# 1.6.8 beneficial-tincture (2017-12-18)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
- **$location:**
|
||||
- always decode special chars in `$location.url(value)`
|
||||
([2bdf71](https://github.com/angular/angular.js/commit/2bdf7126878c87474bb7588ce093d0a3c57b0026))
|
||||
- decode non-component special chars in Hashbang URLS
|
||||
([57b626](https://github.com/angular/angular.js/commit/57b626a673b7530399d3377dfe770165bec35f8a))
|
||||
- **ngModelController:** allow $overrideModelOptions to set updateOn
|
||||
([55516d](https://github.com/angular/angular.js/commit/55516da2dfc7c5798dce24e9fa930c5ac90c900c),
|
||||
[#16351](https://github.com/angular/angular.js/issues/16351),
|
||||
[#16364](https://github.com/angular/angular.js/issues/16364))
|
||||
|
||||
|
||||
## New Features
|
||||
- **$parse:** add a hidden interface to retrieve an expression's AST
|
||||
([f33d95](https://github.com/angular/angular.js/commit/f33d95cfcff6fd0270f92a142df8794cca2013ad),
|
||||
[#16253](https://github.com/angular/angular.js/issues/16253),
|
||||
[#16260](https://github.com/angular/angular.js/issues/16260))
|
||||
|
||||
<a name="1.6.7"></a>
|
||||
# 1.6.7 imperial-backstroke (2017-11-24)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
- **$compile:** sanitize special chars in directive name
|
||||
([c4003f](https://github.com/angular/angular.js/commit/c4003fd03489f876b646f06838f4edb576bacf6f),
|
||||
[#16314](https://github.com/angular/angular.js/issues/16314),
|
||||
[#16278](https://github.com/angular/angular.js/issues/16278))
|
||||
- **$location:** do not decode forward slashes in the path in HTML5 mode
|
||||
([e06ebf](https://github.com/angular/angular.js/commit/e06ebfdbb558544602fe9da4d7d98045a965f468),
|
||||
[#16312](https://github.com/angular/angular.js/issues/16312))
|
||||
- **sanitizeUri:** sanitize URIs that contain IDEOGRAPHIC SPACE chars
|
||||
([ddeb1d](https://github.com/angular/angular.js/commit/ddeb1df15a23de93eb95dbe202e83e93673e1c4e),
|
||||
[#16288](https://github.com/angular/angular.js/issues/16288))
|
||||
- **$rootScope:** fix potential memory leak when removing scope listeners
|
||||
([358a69](https://github.com/angular/angular.js/commit/358a69fa8b89b251ee44e523458d6c7f40b92b2d),
|
||||
[#16135](https://github.com/angular/angular.js/issues/16135),
|
||||
[#16161](https://github.com/angular/angular.js/issues/16161))
|
||||
- **http:** do not allow encoded callback params in jsonp requests
|
||||
([569e90](https://github.com/angular/angular.js/commit/569e906a5818271416ad0b749be2f58dc34938bd))
|
||||
- **ngMock:** pass unexpected request failures in `$httpBackend` to the error handler
|
||||
([1555a4](https://github.com/angular/angular.js/commit/1555a4911ad5360c145c0ddc8ec6c4bf9a381c13),
|
||||
[#16150](https://github.com/angular/angular.js/issues/16150),
|
||||
[#15855](https://github.com/angular/angular.js/issues/15855))
|
||||
- **ngAnimate:** don't close transitions when child transitions close
|
||||
([1391e9](https://github.com/angular/angular.js/commit/1391e99c7f73795180b792af21ad4402f96e225d),
|
||||
[#16210](https://github.com/angular/angular.js/issues/16210))
|
||||
- **ngMock.browserTrigger:** add 'bubbles' to Transition/Animation Event
|
||||
([7a5f06](https://github.com/angular/angular.js/commit/7a5f06d55d123a39bb7b030667fb1ab672939598))
|
||||
|
||||
|
||||
## New Features
|
||||
- **$sanitize, $compileProvider, linky:** add support for the "sftp" protocol in links
|
||||
([a675ea](https://github.com/angular/angular.js/commit/a675ea034366fbb0fcf0d73fed65216aa99bce11),
|
||||
[#16102](https://github.com/angular/angular.js/issues/16102))
|
||||
- **ngModel.NgModelController:** expose $processModelValue to run model -> view pipeline
|
||||
([145194](https://github.com/angular/angular.js/commit/14519488ce9218aa891d34e89fc3271fd4ed0f04),
|
||||
[#3407](https://github.com/angular/angular.js/issues/3407),
|
||||
[#10764](https://github.com/angular/angular.js/issues/10764),
|
||||
[#16237](https://github.com/angular/angular.js/issues/16237))
|
||||
- **$injector:** ability to load new modules after bootstrapping
|
||||
([6e78fe](https://github.com/angular/angular.js/commit/6e78fee73258bb0ae36414f9db2e8734273e481b))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
- **jqLite:**
|
||||
- avoid setting class attribute when not changed
|
||||
([9c95f6](https://github.com/angular/angular.js/commit/9c95f6d5e00ee7e054aabb3e363f5bfb3b7b4103))
|
||||
- avoid repeated add/removeAttribute in jqLiteRemoveClass
|
||||
([cab9eb](https://github.com/angular/angular.js/commit/cab9ebfd5a02e897f802bf6321b8471e4843c5d3),
|
||||
[#16078](https://github.com/angular/angular.js/issues/16078),
|
||||
[#16131](https://github.com/angular/angular.js/issues/16131))
|
||||
|
||||
|
||||
<a name="1.6.6"></a>
|
||||
# 1.6.6 interdimensional-cable (2017-08-18)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
- **$httpParamSerializer:** ignore functions
|
||||
([b51ded](https://github.com/angular/angular.js/commit/b51ded67366865f36c5781dd5d9b801488ec95ea),
|
||||
[#16133](https://github.com/angular/angular.js/issues/16133))
|
||||
- **$resource:** do not throw when calling old `$cancelRequest()`
|
||||
([009ebe](https://github.com/angular/angular.js/commit/009ebec64c81d11b280c635167050e8906e191c6),
|
||||
[#16037](https://github.com/angular/angular.js/issues/16037))
|
||||
- **$parse:**
|
||||
- do not shallow-watch computed property keys
|
||||
([750465](https://github.com/angular/angular.js/commit/7504656a26202de591e4ac9674333254304edf8a))
|
||||
- support constants in computed keys
|
||||
([9d6c3f](https://github.com/angular/angular.js/commit/9d6c3f3ec233279885e37a250d25860d5c15f716))
|
||||
- **$http:** do not throw error if `Content-Type` is not `application/json` but response is JSON-like
|
||||
([2e1163](https://github.com/angular/angular.js/commit/2e1163ef5cb56d1933e8ecd7b74020b9df9c6693),
|
||||
[#16027](https://github.com/angular/angular.js/issues/16027),
|
||||
[#16075](https://github.com/angular/angular.js/issues/16075))
|
||||
|
||||
|
||||
## New Features
|
||||
- **$compile:** add `strictComponentBindingsEnabled()` method
|
||||
([3ec181](https://github.com/angular/angular.js/commit/3ec1819b913c8edf0649e06217dbd5920f29f126),
|
||||
[#16129](https://github.com/angular/angular.js/issues/16129))
|
||||
- **$resource:** add resource to response for error interceptors
|
||||
([9256db](https://github.com/angular/angular.js/commit/9256dbc4201343ce5cd63a9eadf98da4793f45af),
|
||||
[#16109](https://github.com/angular/angular.js/issues/16109))
|
||||
- **$http:** allow differentiation between XHR completion, error, abort, timeout
|
||||
([5e2bc5](https://github.com/angular/angular.js/commit/5e2bc5bbf347a9dfadc08b1514b8be06fd550913),
|
||||
[#15924](https://github.com/angular/angular.js/issues/15924),
|
||||
[#15847](https://github.com/angular/angular.js/issues/15847))
|
||||
|
||||
|
||||
<a name="1.6.5"></a>
|
||||
# 1.6.5 toffee-salinization (2017-07-03)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
- **core:**
|
||||
- correctly detect Error instances from different contexts
|
||||
([6daca0](https://github.com/angular/angular.js/commit/6daca023e42098f7098b9bf153c8e53a17af84f1),
|
||||
[#15868](https://github.com/angular/angular.js/issues/15868),
|
||||
[#15872](https://github.com/angular/angular.js/issues/15872))
|
||||
- deprecate `angular.merge`
|
||||
([dc41f4](https://github.com/angular/angular.js/commit/dc41f465baae9bc91418a61f446596157c530b6e),
|
||||
[#12653](https://github.com/angular/angular.js/issues/12653),
|
||||
[#14941](https://github.com/angular/angular.js/issues/14941),
|
||||
[#15180](https://github.com/angular/angular.js/issues/15180),
|
||||
[#15992](https://github.com/angular/angular.js/issues/15992),
|
||||
[#16036](https://github.com/angular/angular.js/issues/16036))
|
||||
- **ngOptions:**
|
||||
- re-render after empty option has been removed
|
||||
([510d0f](https://github.com/angular/angular.js/commit/510d0f946fa1a443ad43fa31bc9337676ef31332))
|
||||
- allow empty option to be removed and re-added
|
||||
([71b4da](https://github.com/angular/angular.js/commit/71b4daa4e10b6912891927ee2a7930c604b538f8))
|
||||
- select unknown option if unmatched model does not match empty option
|
||||
([17d34b](https://github.com/angular/angular.js/commit/17d34b7a983a0ef63f6cf404490385c696fb0da1))
|
||||
- **orderBy:** guarantee stable sort
|
||||
([e50ed4](https://github.com/angular/angular.js/commit/e50ed4da9e8177168f67da68bdf02f07da4e7bcf),
|
||||
[#14881](https://github.com/angular/angular.js/issues/14881),
|
||||
[#15914](https://github.com/angular/angular.js/issues/15914))
|
||||
- **$parse:**
|
||||
- do not shallow-watch inputs to one-time intercepted expressions
|
||||
([6e3b5a](https://github.com/angular/angular.js/commit/6e3b5a57cd921823f3eca7200a79ac5c2ef0567a))
|
||||
- standardize one-time literal vs non-literal and interceptors
|
||||
([f003d9](https://github.com/angular/angular.js/commit/f003d93a3dd052dccddef41125d9c51034ac3605))
|
||||
- do not shallow-watch inputs when wrapped in an interceptor fn
|
||||
([aac562](https://github.com/angular/angular.js/commit/aac5623247a86681cbe0e1c8179617b816394c1d),
|
||||
[#15905](https://github.com/angular/angular.js/issues/15905))
|
||||
- always re-evaluate filters within literals when an input is an object
|
||||
([ec9768](https://github.com/angular/angular.js/commit/ec97686f2f4a5481cc806462313a664fc7a1c893),
|
||||
[#15964](https://github.com/angular/angular.js/issues/15964),
|
||||
[#15990](https://github.com/angular/angular.js/issues/15990))
|
||||
- **$sanitize:** use appropriate inert document strategy for Firefox and Safari
|
||||
([8f31f1](https://github.com/angular/angular.js/commit/8f31f1ff43b673a24f84422d5c13d6312b2c4d94))
|
||||
- **$timeout/$interval:** do not trigger a digest on cancel
|
||||
([a222d0](https://github.com/angular/angular.js/commit/a222d0b452622624dc498ef0b9d3c43647fd4fbc),
|
||||
[#16057](https://github.com/angular/angular.js/issues/16057),
|
||||
[#16064](https://github.com/angular/angular.js/issues/16064))<br>
|
||||
This change might affect the use of `$timeout.flush()` in unit tests. See the commit message for
|
||||
more info.
|
||||
- **ngMock/$interval:** add support for zero-delay intervals in tests
|
||||
([a1e3f8](https://github.com/angular/angular.js/commit/a1e3f8728e0a80396f980e48f8dc68dde6721b2b),
|
||||
[#15952](https://github.com/angular/angular.js/issues/15952),
|
||||
[#15953](https://github.com/angular/angular.js/issues/15953))
|
||||
- **angular-loader:** do not depend on "closure" globals that may not be available
|
||||
([a3226d](https://github.com/angular/angular.js/commit/a3226d01fadaf145713518dc5b8022b581c34e81),
|
||||
[#15880](https://github.com/angular/angular.js/issues/15880),
|
||||
[#15881](https://github.com/angular/angular.js/issues/15881))
|
||||
|
||||
|
||||
## New Features
|
||||
- **select:** expose info about selection state in controller
|
||||
([0b962d](https://github.com/angular/angular.js/commit/0b962d4881e98327a91c37f7317da557aa991663),
|
||||
[#13172](https://github.com/angular/angular.js/issues/13172),
|
||||
[#10127](https://github.com/angular/angular.js/issues/10127))
|
||||
- **$animate:** add support for `customFilter`
|
||||
([ab114a](https://github.com/angular/angular.js/commit/ab114af8508bdbdb1fa5fd1e070d08818d882e28),
|
||||
[#14891](https://github.com/angular/angular.js/issues/14891))
|
||||
- **$compile:** overload `.component()` to accept object map of components
|
||||
([210112](https://github.com/angular/angular.js/commit/2101126ce72308d8fc468ca2411bb9972e614f79),
|
||||
[#14579](https://github.com/angular/angular.js/issues/14579),
|
||||
[#16062](https://github.com/angular/angular.js/issues/16062))
|
||||
- **$log:** log all parameters in IE 9, not just the first two.
|
||||
([3671a4](https://github.com/angular/angular.js/commit/3671a43be43d05b00c90dfb3a3f746c013139581))
|
||||
- **ngMock:** describe unflushed http requests
|
||||
([d9128e](https://github.com/angular/angular.js/commit/d9128e7b2371ab2bb5169ba854b21c78baa784d2),
|
||||
[#10596](https://github.com/angular/angular.js/issues/10596),
|
||||
[#15928](https://github.com/angular/angular.js/issues/15928))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
- **ngOptions:** prevent initial options repainting
|
||||
([ff52b1](https://github.com/angular/angular.js/commit/ff52b188a759f2cc7ee6ee78a8c646c2354a47eb),
|
||||
[#15801](https://github.com/angular/angular.js/issues/15801),
|
||||
[#15812](https://github.com/angular/angular.js/issues/15812),
|
||||
[#16071](https://github.com/angular/angular.js/issues/16071))
|
||||
- **$animate:**
|
||||
- avoid unnecessary computations if animations are globally disabled
|
||||
([ce5ffb](https://github.com/angular/angular.js/commit/ce5ffbf667464bd58eae4c4af0917eb2685f1f6a),
|
||||
[#14914](https://github.com/angular/angular.js/issues/14914))
|
||||
- do not retrieve `className` unless `classNameFilter` is used
|
||||
([275978](https://github.com/angular/angular.js/commit/27597887379a1904cd86832602e286894b449a75))
|
||||
|
||||
|
||||
|
||||
<a name="1.6.4"></a>
|
||||
# 1.6.4 phenomenal-footnote (2017-03-31)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
- **$parse:**
|
||||
- standardize one-time literal vs non-literal and interceptors
|
||||
([60394a](https://github.com/angular/angular.js/commit/60394a9d91dad8932fa900af7c8529837f1d4557),
|
||||
[#15858](https://github.com/angular/angular.js/issues/15858))
|
||||
- fix infinite digest errors when watching objects with .valueOf in literals
|
||||
([f5ddb1](https://github.com/angular/angular.js/commit/f5ddb10b56676c2ad912ce453acb87f0a7a94e01),
|
||||
[#15867](https://github.com/angular/angular.js/issues/15867))
|
||||
- **ngModel:** prevent internal scope reference from being copied
|
||||
([e1f8a6](https://github.com/angular/angular.js/commit/e1f8a6e82bb8a70079ef3db9a891b1c08b5bae31),
|
||||
[#15833](https://github.com/angular/angular.js/issues/15833))
|
||||
- **jqLite:** make jqLite invoke jqLite.cleanData as a method
|
||||
([9cde98](https://github.com/angular/angular.js/commit/9cde98cbc770f8d33fc074ba563b7ab6e2baaf8b),
|
||||
[#15846](https://github.com/angular/angular.js/issues/15846))
|
||||
- **$http:** throw more informative error on invalid JSON response
|
||||
([df8887](https://github.com/angular/angular.js/commit/df88873bb79213057057adb47151b626a7ec0e5d),
|
||||
[#15695](https://github.com/angular/angular.js/issues/15695),
|
||||
[#15724](https://github.com/angular/angular.js/issues/15724))
|
||||
- **dateFilter:** correctly handle newlines in `format` string
|
||||
([982271](https://github.com/angular/angular.js/commit/9822711ad2a401c2449239edc13d18b301714757),
|
||||
[#15794](https://github.com/angular/angular.js/issues/15794),
|
||||
[#15792](https://github.com/angular/angular.js/issues/15792))
|
||||
|
||||
|
||||
## New Features
|
||||
- **$resource:** add `hasBody` action configuration option
|
||||
([a9f987](https://github.com/angular/angular.js/commit/a9f987a0c9653246ea471a89197907d94c0cea2a),
|
||||
[#10128](https://github.com/angular/angular.js/issues/10128),
|
||||
[#12181](https://github.com/angular/angular.js/issues/12181))
|
||||
|
||||
|
||||
<a name="1.6.3"></a>
|
||||
# 1.6.3 scriptalicious-bootstrapping (2017-03-08)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
- **AngularJS:**
|
||||
- do not auto-bootstrap if the `src` exists but is empty
|
||||
([3536e8](https://github.com/angular/angular.js/commit/3536e83d8a085b02bd6dcec8324800b7e6c734e4))
|
||||
- do not auto bootstrap if the currentScript has been clobbered
|
||||
([95f964](https://github.com/angular/angular.js/commit/95f964b827b6f5b5aab10af54f7831316c7a9935))
|
||||
- do not auto-bootstrap if the script source is bad and inside SVG
|
||||
([c8f78a](https://github.com/angular/angular.js/commit/c8f78a8ca9debc33a6deaf951f344b8d372bf210))
|
||||
- **$log:** don't parse error stacks manually outside of IE/Edge
|
||||
([64e5af](https://github.com/angular/angular.js/commit/64e5afc4786fdfd850c6bdb488a5aa2b8b077f74),
|
||||
[#15590](https://github.com/angular/angular.js/issues/15590),
|
||||
[#15767](https://github.com/angular/angular.js/issues/15767))
|
||||
- **$sanitize:** prevent clobbered elements from freezing the browser
|
||||
([3bb1dd](https://github.com/angular/angular.js/commit/3bb1dd5d7f7dcde6fea5a3148f8f10e92f451e9d),
|
||||
[#15699](https://github.com/angular/angular.js/issues/15699))
|
||||
- **$animate:**
|
||||
- reset `classNameFilter` to `null` when a disallowed RegExp is used
|
||||
([a584fb](https://github.com/angular/angular.js/commit/a584fb6e1569fc1dd85e23b251a7c126edc2dd5b),
|
||||
[#14913](https://github.com/angular/angular.js/issues/14913))
|
||||
- improve detection on `ng-animate` in `classNameFilter` RegExp
|
||||
([1f1331](https://github.com/angular/angular.js/commit/1f13313f403381581e1c31c57ebfe7a96546c6e4),
|
||||
[#14806](https://github.com/angular/angular.js/issues/14806))
|
||||
- **filterFilter:** don't throw if `key.charAt` is not a function
|
||||
([f27d19](https://github.com/angular/angular.js/commit/f27d19ed606bf05ba41698159ebbc5fbc195033e),
|
||||
[#15644](https://github.com/angular/angular.js/issues/15644),
|
||||
[#15660](https://github.com/angular/angular.js/issues/15660))
|
||||
- **select:**
|
||||
- add attribute "selected" for `select[multiple]`
|
||||
([851367](https://github.com/angular/angular.js/commit/8513674911300b27d518383a905fde9b3f25f7ae))
|
||||
- keep original selection when using shift to add options in IE/Edge
|
||||
([97b74a](https://github.com/angular/angular.js/commit/97b74ad6fbcbc4b63e37e9eb44962d6f8de83e8b),
|
||||
[#15675](https://github.com/angular/angular.js/issues/15675),
|
||||
[#15676](https://github.com/angular/angular.js/issues/15676))
|
||||
- **$jsonpCallbacks:** allow `$window` to be mocked in unit tests
|
||||
([5ca0de](https://github.com/angular/angular.js/commit/5ca0de64873c32ab2f540a3226e73c4175a15c50),
|
||||
[#15685](https://github.com/angular/angular.js/issues/15685),
|
||||
[#15686](https://github.com/angular/angular.js/issues/15686))
|
||||
|
||||
|
||||
## New Features
|
||||
- **info:** add `angularVersion` info to each module
|
||||
([1e582e](https://github.com/angular/angular.js/commit/1e582e4fa486f340150bba95927f1b26d9142de2))
|
||||
- **$injector:** add new `modules` property
|
||||
([742123](https://github.com/angular/angular.js/commit/7421235f247e5b7113345401bc5727cfbf81ddc2))
|
||||
- **Module:** add `info()` method
|
||||
([09ba69](https://github.com/angular/angular.js/commit/09ba69078de6ba52c70571b82b6205929f6facc5),
|
||||
[#15225](https://github.com/angular/angular.js/issues/15225))
|
||||
- **errorHandlingConfig:** make the depth for object stringification in errors configurable
|
||||
([4a5eaf](https://github.com/angular/angular.js/commit/4a5eaf7bec85ceca8b934ebaff4d1834a1a09f57),
|
||||
[#15402](https://github.com/angular/angular.js/issues/15402),
|
||||
[#15433](https://github.com/angular/angular.js/issues/15433))
|
||||
|
||||
|
||||
<a name="1.6.2"></a>
|
||||
# 1.6.2 llamacorn-lovehug (2017-02-07)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
- **$compile:**
|
||||
- do not swallow thrown errors in testsg
|
||||
([0377c6](https://github.com/angular/angular.js/commit/0377c6f0e890cb4ed3eb020b96720b4b34f75df3),
|
||||
[#15629](https://github.com/angular/angular.js/issues/15629),
|
||||
[#15631](https://github.com/angular/angular.js/issues/15631))
|
||||
- allow the usage of "$" in isolate scope property alias
|
||||
([7f2af3](https://github.com/angular/angular.js/commit/7f2af3f923e7a3f85c8862d0ed57d21c72eae904),
|
||||
[#15594](https://github.com/angular/angular.js/issues/15594))
|
||||
- **$location:** correctly handle external URL change during `$digest`
|
||||
([b60761](https://github.com/angular/angular.js/commit/b607618342d6c4fab364966fe05f152be6bd4d5f),
|
||||
[#11075](https://github.com/angular/angular.js/issues/11075),
|
||||
[#12571](https://github.com/angular/angular.js/issues/12571),
|
||||
[#15556](https://github.com/angular/angular.js/issues/15556),
|
||||
[#15561](https://github.com/angular/angular.js/issues/15561))
|
||||
- **$browser:** detect external changes in `history.state`
|
||||
([fa50fb](https://github.com/angular/angular.js/commit/fa50fbaf57b3437be7a410ecaba7008dbe0ef239))
|
||||
- **$resource:**
|
||||
- do not swallow errors in `success` callback
|
||||
([27146e](https://github.com/angular/angular.js/commit/27146e8a7fad54c1342179b6d291b1b5c2ebe816),
|
||||
[#15624](https://github.com/angular/angular.js/issues/15624),
|
||||
[#15628](https://github.com/angular/angular.js/issues/15628))
|
||||
- correctly unescape `/\.` even if `\.` comes from a param value
|
||||
([419a48](https://github.com/angular/angular.js/commit/419a4813e354496bdf0df44e3f8afaa198df1ab1),
|
||||
[#15627](https://github.com/angular/angular.js/issues/15627))
|
||||
- delete `$cancelRequest()` in `toJSON()`
|
||||
([086c5d](https://github.com/angular/angular.js/commit/086c5d0354db8cb3d106b9ff966fb48d6fb46ef8),
|
||||
[#15244](https://github.com/angular/angular.js/issues/15244))
|
||||
- **$animate:** correctly animate transcluded clones with `templateUrl`
|
||||
([f01212](https://github.com/angular/angular.js/commit/f01212ab5287ac7a154da7d75037ed444e81eb34),
|
||||
[#15510](https://github.com/angular/angular.js/issues/15510),
|
||||
[#15514](https://github.com/angular/angular.js/issues/15514))
|
||||
- **$route:** make asynchronous tasks count as pending requests
|
||||
([eb968c](https://github.com/angular/angular.js/commit/eb968c4a6884838db05369a04459066424c5bba8),
|
||||
[#14159](https://github.com/angular/angular.js/issues/14159))
|
||||
- **$parse:** make sure ES6 object computed properties are watched
|
||||
([5e418b](https://github.com/angular/angular.js/commit/5e418b1145a1045da598c7863e785d647ea83850),
|
||||
[#15678](https://github.com/angular/angular.js/issues/15678))
|
||||
- **$sniffer:** allow `history` for NW.js apps
|
||||
([4a593d](https://github.com/angular/angular.js/commit/4a593db79ba1e21a6aa600a82cf6d757cad94d01),
|
||||
[#15474](https://github.com/angular/angular.js/issues/15474),
|
||||
[#15633](https://github.com/angular/angular.js/issues/15633))
|
||||
- **input:** fix `step` validation for `input[type=number/range]`
|
||||
([c95a67](https://github.com/angular/angular.js/commit/c95a6737fbd277e40c064bd9f68f383bf119505c),
|
||||
[#15504](https://github.com/angular/angular.js/issues/15504),
|
||||
[#15506](https://github.com/angular/angular.js/issues/15506))
|
||||
- **select:** keep `ngModel` when selected option is recreated by `ngRepeat`
|
||||
([131af8](https://github.com/angular/angular.js/commit/131af8272d269a541d04cb522c264a91e0ec8b6a),
|
||||
[#15630](https://github.com/angular/angular.js/issues/15630),
|
||||
[#15632](https://github.com/angular/angular.js/issues/15632))
|
||||
- **ngValue:** correctly update the `value` property when `value` is undefined
|
||||
([05aab6](https://github.com/angular/angular.js/commit/05aab660ce74f526f2110d3b5faf9a5b4f4e664b)
|
||||
[#15603](https://github.com/angular/angular.js/issues/15603),
|
||||
[#15605](https://github.com/angular/angular.js/issues/15605))
|
||||
- **angularInit:** allow auto-bootstrapping from inline script
|
||||
([bb464d](https://github.com/angular/angular.js/commit/bb464d16b434b9e2de2fecf80c192d4741cba879),
|
||||
[#15567](https://github.com/angular/angular.js/issues/15567),
|
||||
[#15571](https://github.com/angular/angular.js/issues/15571))
|
||||
- **ngMockE2E:** ensure that mocked `$httpBackend` uses correct `$browser`
|
||||
([bd63b2](https://github.com/angular/angular.js/commit/bd63b2235cd410251cb83eebd9a47d3102830b6b),
|
||||
[#15593](https://github.com/angular/angular.js/issues/15593))
|
||||
|
||||
|
||||
## New Features
|
||||
- **ngModel:** add `$overrideModelOptions` support
|
||||
([2546c2](https://github.com/angular/angular.js/commit/2546c29f811b68eea4d68be7fa1c8f7bb562dc11),
|
||||
[#15415](https://github.com/angular/angular.js/issues/15415))
|
||||
- **$parse:** allow watching array/object literals with non-primitive values
|
||||
([25f008](https://github.com/angular/angular.js/commit/25f008f541d68b09efd7b428b648c6d4899e6972),
|
||||
[#15301](https://github.com/angular/angular.js/issues/15301))
|
||||
|
||||
|
||||
|
||||
<a name="1.5.11"></a>
|
||||
# 1.5.11 princely-quest (2017-01-13)
|
||||
|
||||
@@ -438,10 +840,10 @@ consolidating all the changes shown in the previous 1.6.0 release candidates.**
|
||||
- **feat($compile): set preAssignBindingsEnabled to false by default
|
||||
([bcd0d4](https://github.com/angular/angular.js/commit/bcd0d4d896d0dfdd988ff4f849c1d40366125858))**:
|
||||
|
||||
Previously, `$compileProvider.preAssignBindingsEnabled` was
|
||||
set to true by default. This means bindings were pre-assigned in component
|
||||
constructors. In Angular 1.5+ the place to put the initialization logic
|
||||
relying on bindings being present is the controller `$onInit` method.
|
||||
Previously, `$compileProvider.preAssignBindingsEnabled` was set to true by default. This means
|
||||
bindings were pre-assigned on component/directive controller instances (which made them available
|
||||
inside the constructors). In AngularJS 1.5+ the place to put the initialization logic relying on
|
||||
bindings being present is the controller's `$onInit` method.
|
||||
|
||||
To migrate follow the example below:
|
||||
|
||||
@@ -1022,7 +1424,7 @@ You configure this list in a module configuration block:
|
||||
|
||||
```js
|
||||
appModule.config(['$sceDelegateProvider', function($sceDelegateProvider) {
|
||||
$sceDelegateProvider.resourceUrlWhiteList([
|
||||
$sceDelegateProvider.resourceUrlWhitelist([
|
||||
// Allow same origin resource loads.
|
||||
'self',
|
||||
// Allow JSONP calls that match this pattern
|
||||
@@ -1640,7 +2042,7 @@ validation), you can overwrite the built-in `step` validator with a custom direc
|
||||
# 1.5.9 timeturning-lockdown (2016-11-24)
|
||||
|
||||
This is an interim release primarily to publish some security fixes, in particular a modification to
|
||||
ensure that Angular 1 can pass the linter checks for Mozilla add-ons.
|
||||
ensure that AngularJS can pass the linter checks for Mozilla add-ons.
|
||||
|
||||
## Security Fixes
|
||||
- **bootstrap:**
|
||||
@@ -1728,7 +2130,7 @@ ensure that Angular 1 can pass the linter checks for Mozilla add-ons.
|
||||
|
||||
Previously, `$compileProvider.preAssignBindingsEnabled` was
|
||||
set to true by default. This means bindings were pre-assigned in component
|
||||
constructors. In Angular 1.5+ the place to put the initialization logic
|
||||
constructors. In AngularJS 1.5+ the place to put the initialization logic
|
||||
relying on bindings being present is the controller `$onInit` method.
|
||||
|
||||
To migrate follow the example below:
|
||||
@@ -2433,7 +2835,7 @@ You configure this list in a module configuration block:
|
||||
|
||||
```js
|
||||
appModule.config(['$sceDelegateProvider', function($sceDelegateProvider) {
|
||||
$sceDelegateProvider.resourceUrlWhiteList([
|
||||
$sceDelegateProvider.resourceUrlWhitelist([
|
||||
// Allow same origin resource loads.
|
||||
'self',
|
||||
// Allow JSONP calls that match this pattern
|
||||
@@ -4842,12 +5244,12 @@ before the $parsers are applied. Previously, the modelValue
|
||||
|
||||
This fixes issues where `input[date]` and `input[number]` cannot
|
||||
be validated because the viewValue string is parsed into
|
||||
`Date` and `Number` respectively (starting with Angular 1.3).
|
||||
`Date` and `Number` respectively (starting with AngularJS 1.3).
|
||||
It also brings the directives in line with HTML5 constraint
|
||||
validation, which validates against the input value.
|
||||
|
||||
This change is unlikely to cause applications to fail, because even
|
||||
in Angular 1.2, the value that was validated by pattern could have
|
||||
in AngularJS 1.2, the value that was validated by pattern could have
|
||||
been manipulated by the $parsers, as all validation was done
|
||||
inside this pipeline.
|
||||
|
||||
@@ -4958,12 +5360,12 @@ before the $parsers are applied. Previously, the modelValue
|
||||
|
||||
This fixes issues where `input[date]` and `input[number]` cannot
|
||||
be validated because the viewValue string is parsed into
|
||||
`Date` and `Number` respectively (starting with Angular 1.3).
|
||||
`Date` and `Number` respectively (starting with AngularJS 1.3).
|
||||
It also brings the directives in line with HTML5 constraint
|
||||
validation, which validates against the input value.
|
||||
|
||||
This change is unlikely to cause applications to fail, because even
|
||||
in Angular 1.2, the value that was validated by pattern could have
|
||||
in AngularJS 1.2, the value that was validated by pattern could have
|
||||
been manipulated by the $parsers, as all validation was done
|
||||
inside this pipeline.
|
||||
|
||||
@@ -5177,7 +5579,7 @@ describe('$q.when', function() {
|
||||
it('should not need a call to $timeout.flush() to resolve already resolved promises',
|
||||
inject(function($q, $timeout) {
|
||||
$q.when('foo');
|
||||
// In Angular 1.4.3 a call to `$timeout.flush();` was needed
|
||||
// In AngularJS 1.4.3 a call to `$timeout.flush();` was needed
|
||||
$timeout.verifyNoPendingTasks();
|
||||
}));
|
||||
|
||||
@@ -6653,7 +7055,7 @@ it is now implemented in the ngOptions directive itself.
|
||||
the `select` directive will now use strict comparison of the `ngModel` scope value against `option`
|
||||
values to determine which option is selected. This means `Number` scope values will not be matched
|
||||
against numeric option strings.
|
||||
In Angular 1.3.x, setting `scope.x = 200` would select the `option` with the value 200 in the following `select`:
|
||||
In AngularJS 1.3.x, setting `scope.x = 200` would select the `option` with the value 200 in the following `select`:
|
||||
|
||||
```
|
||||
<select ng-model="x">
|
||||
@@ -6662,7 +7064,7 @@ In Angular 1.3.x, setting `scope.x = 200` would select the `option` with the val
|
||||
</select>
|
||||
```
|
||||
|
||||
In Angular 1.4.x, the 'unknown option' will be selected.
|
||||
In AngularJS 1.4.x, the 'unknown option' will be selected.
|
||||
To remedy this, you can simply initialize the model as a string: `scope.x = '200'`, or if you want to
|
||||
keep the model as a `Number`, you can do the conversion via `$formatters` and `$parsers` on `ngModel`:
|
||||
|
||||
@@ -15236,7 +15638,7 @@ with the `$route` service
|
||||
|
||||
### Breaking changes
|
||||
- we now support ISO 8601 extended format datetime strings (YYYY-MM-DDTHH:mm:ss.SSSZ) as defined
|
||||
in EcmaScript 5 throughout angular. This means that the following apis switched from
|
||||
in EcmaScript 5 throughout AngularJS. This means that the following apis switched from
|
||||
YYYY-MM-DDTHH:mm:ssZ to YYYY-MM-DDTHH:mm:ss.SSSZ (note the added millis) when representing dates:
|
||||
- angular.Date.toString
|
||||
- angular.String.fromDate
|
||||
|
||||
+116
-186
@@ -3,85 +3,102 @@
|
||||
We'd love for you to contribute to our source code and to make AngularJS even better than it is
|
||||
today! Here are the guidelines we'd like you to follow:
|
||||
|
||||
- [Code of Conduct](#coc)
|
||||
- [Question or Problem?](#question)
|
||||
- [Issues and Bugs](#issue)
|
||||
- [Feature Requests](#feature)
|
||||
- [Submission Guidelines](#submit)
|
||||
- [Coding Rules](#rules)
|
||||
- [Commit Message Guidelines](#commit)
|
||||
- [Signing the CLA](#cla)
|
||||
- [Further Info](#info)
|
||||
* [Code of Conduct](#coc)
|
||||
* [Questions and Problems](#question)
|
||||
* [Issues and Bugs](#issue)
|
||||
* [Feature Requests](#feature)
|
||||
* [Improving Documentation](#docs)
|
||||
* [Issue Submission Guidelines](#submit)
|
||||
* [Pull Request Submission Guidelines](#submit-pr)
|
||||
* [Signing the CLA](#cla)
|
||||
|
||||
## <a name="coc"></a> Code of Conduct
|
||||
|
||||
Help us keep Angular open and inclusive. Please read and follow our [Code of Conduct][coc].
|
||||
Help us keep AngularJS open and inclusive. Please read and follow our [Code of Conduct][coc].
|
||||
|
||||
## <a name="question"></a> Got a Question or Problem?
|
||||
## <a name="requests"></a> Questions, Bugs, Features
|
||||
|
||||
If you have questions about how to use AngularJS, please direct these to the [Google Group][groups]
|
||||
discussion list or [StackOverflow][stackoverflow]. We are also available on [IRC][irc] and
|
||||
[Gitter][gitter].
|
||||
### <a name="question"></a> Got a Question or Problem?
|
||||
|
||||
## <a name="issue"></a> Found an Issue?
|
||||
Do not open issues for general support questions as we want to keep GitHub issues for bug reports
|
||||
and feature requests. You've got much better chances of getting your question answered on dedicated
|
||||
support platforms, the best being [Stack Overflow][stackoverflow].
|
||||
|
||||
If you find a bug in the source code or a mistake in the documentation, you can help us by
|
||||
submitting an issue to our [GitHub Repository][github]. Even better you can submit a Pull Request
|
||||
with a fix.
|
||||
Stack Overflow is a much better place to ask questions since:
|
||||
|
||||
- there are thousands of people willing to help on Stack Overflow
|
||||
- questions and answers stay available for public viewing so your question / answer might help
|
||||
someone else
|
||||
- Stack Overflow's voting system assures that the best answers are prominently visible.
|
||||
|
||||
To save your and our time, we will systematically close all issues that are requests for general
|
||||
support and redirect people to the section you are reading right now.
|
||||
|
||||
Other channels for support are:
|
||||
- the [Google Group][groups] discussion list
|
||||
- the [AngularJS IRC][irc]
|
||||
- the [AngularJS Gitter][gitter]
|
||||
|
||||
### <a name="issue"></a> Found an Issue or Bug?
|
||||
|
||||
If you find a bug in the source code, you can help us by submitting an issue to our
|
||||
[GitHub Repository][github]. Even better, you can submit a Pull Request with a fix.
|
||||
|
||||
**Please see the [Submission Guidelines](#submit) below.**
|
||||
|
||||
**Special Note for Localization Issues:** AngularJS uses the [Google Closure I18N library] to
|
||||
generate its own I18N files (the ngLocale module). This means that any changes to these files
|
||||
would be lost the next time that we import the library.
|
||||
|
||||
**Localization Issues:** Angular.js uses the [Google Closure I18N library] to generate
|
||||
its own I18N files (the ngLocale module). This means that any changes to these files would be lost
|
||||
the next time that we import the library.
|
||||
Since the Closure library i18n data is itself auto-generated from the data of the
|
||||
[Common Locale Data Repository (CLDR)] project, errors in the data should
|
||||
be reported there. See also the [Closure guide to i18n changes].
|
||||
|
||||
**Please see the [Submission Guidelines](#submit) below.**
|
||||
### <a name="feature"></a> Missing a Feature?
|
||||
|
||||
## <a name="feature"></a> Want a Feature?
|
||||
You can request a new feature by submitting an issue to our [GitHub Repository][github-issues].
|
||||
|
||||
You can request a new feature by submitting an issue to our [GitHub Repository][github]. If you
|
||||
would like to implement a new feature then consider what kind of change it is:
|
||||
If you would like to implement a new feature then consider what kind of change it is:
|
||||
|
||||
* **Major Changes** that you wish to contribute to the project should be discussed first on our
|
||||
[dev mailing list][angular-dev] or [IRC][irc] so that we can better coordinate our efforts,
|
||||
prevent duplication of work, and help you to craft the change so that it is successfully accepted
|
||||
into the project.
|
||||
* **Small Changes** can be crafted and submitted to the [GitHub Repository][github] as a Pull
|
||||
Request.
|
||||
* **Major Changes** that you wish to contribute to the project should be discussed first in an
|
||||
[GitHub issue][github-issues] that clearly outlines the changes and benefits of the feature.
|
||||
* **Small Changes** can directly be crafted and submitted to the [GitHub Repository][github]
|
||||
as a Pull Request. See the section about [Pull Request Submission Guidelines](#submit-pr), and
|
||||
for detailed information the [core development documentation][developers].
|
||||
|
||||
### <a name="docs"></a> Want a Doc Fix?
|
||||
|
||||
## <a name="docs"></a> Want a Doc Fix?
|
||||
Should you have a suggestion for the documentation, you can open an issue and outline the problem
|
||||
or improvement you have - however, creating the doc fix yourself is much better!
|
||||
|
||||
If you want to help improve the docs, it's a good idea to let others know what you're working on to
|
||||
minimize duplication of effort. Create a new issue (or comment on a related existing one) to let
|
||||
others know what you're working on.
|
||||
|
||||
If you're making a small change (typo, phrasing) don't worry about filing an issue first. Use the
|
||||
friendly blue "Improve this doc" button at the top right of the doc page to fork the repository
|
||||
in-place and make a quick change on the fly. The commit message is preformatted to the right type
|
||||
and scope, so you only have to add the description.
|
||||
|
||||
For large fixes, please build and test the documentation before submitting the PR to be sure you
|
||||
haven't accidentally introduced any layout or formatting issues. You should also make sure that your
|
||||
commit message starts with "docs" and follows the **[Commit Message Guidelines](#commit)** outlined
|
||||
below.
|
||||
commit message follows the **[Commit Message Guidelines][developers.commits]**.
|
||||
|
||||
If you're just making a small change, don't worry about filing an issue first. Use the friendly blue
|
||||
"Improve this doc" button at the top right of the doc page to fork the repository in-place and make
|
||||
a quick change on the fly. When naming the commit, it is advised to follow the commit message
|
||||
guidelines below, by starting the commit message with **docs** and referencing the filename. Since
|
||||
this is not obvious and some changes are made on the fly, this is not strictly necessary and we will
|
||||
understand if this isn't done the first few times.
|
||||
|
||||
## <a name="submit"></a> Submission Guidelines
|
||||
|
||||
### Submitting an Issue
|
||||
## <a name="submit"></a> Issue Submission Guidelines
|
||||
Before you submit your issue search the archive, maybe your question was already answered.
|
||||
|
||||
If your issue appears to be a bug, and hasn't been reported, open a new issue. Help us to maximize
|
||||
the effort we can spend fixing issues and adding new features, by not reporting duplicate issues.
|
||||
Providing the following information will increase the chances of your issue being dealt with
|
||||
quickly:
|
||||
|
||||
The "[new issue][github-new-issue]" form contains a number of prompts that you should fill out to
|
||||
make it easier to understand and categorize the issue.
|
||||
|
||||
In general, providing the following information will increase the chances of your issue being dealt
|
||||
with quickly:
|
||||
|
||||
* **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps
|
||||
* **Motivation for or Use Case** - explain why this is a bug for you
|
||||
* **Angular Version(s)** - is it a regression?
|
||||
* **AngularJS Version(s)** - is it a regression?
|
||||
* **Browsers and Operating System** - is this a problem with all browsers or only specific ones?
|
||||
* **Reproduce the Error** - provide a live example (using [Plunker][plunker] or
|
||||
[JSFiddle][jsfiddle]) or an unambiguous set of steps.
|
||||
@@ -89,41 +106,43 @@ quickly:
|
||||
* **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be
|
||||
causing the problem (line of code or commit)
|
||||
|
||||
Here is a great example of a well defined issue: https://github.com/angular/angular.js/issues/5069
|
||||
Here is a great example of a well defined issue: https://github.com/angular/angular.js/issues/5069.
|
||||
|
||||
**If you get help, help others. Good karma rulez!**
|
||||
|
||||
### Submitting a Pull Request
|
||||
## <a name="submit-pr"></a> Pull Request Submission Guidelines
|
||||
Before you submit your pull request consider the following guidelines:
|
||||
|
||||
* Search [GitHub](https://github.com/angular/angular.js/pulls) for an open or closed Pull Request
|
||||
that relates to your submission. You don't want to duplicate effort.
|
||||
* Please sign our [Contributor License Agreement (CLA)](#cla) before sending pull
|
||||
requests. We cannot accept code without this.
|
||||
* Create the [development environment][developers.setup]
|
||||
* Make your changes in a new git branch:
|
||||
|
||||
```shell
|
||||
git checkout -b my-fix-branch master
|
||||
```
|
||||
|
||||
* Create your patch, **including appropriate test cases**.
|
||||
* Follow our [Coding Rules](#rules).
|
||||
* Run the full Angular test suite, as described in the [developer documentation][dev-doc],
|
||||
and ensure that all tests pass.
|
||||
* Create your patch commit, **including appropriate test cases**.
|
||||
* Follow our [Coding Rules][developers.rules].
|
||||
* If the changes affect public APIs, change or add relevant [documentation][developers.documentation].
|
||||
* Run the AngularJS [unit][developers.tests-unit] and [E2E test][developers.tests-e2e] suites, and ensure that all tests
|
||||
pass. It is generally sufficient to run the tests only on Chrome, as our Travis integration will
|
||||
run the tests on all supported browsers.
|
||||
* Run `yarn grunt eslint` to check that you have followed the automatically enforced coding rules
|
||||
* Commit your changes using a descriptive commit message that follows our
|
||||
[commit message conventions](#commit) and passes our commit message presubmit hook
|
||||
(`validate-commit-msg.js`). Adherence to the [commit message conventions](#commit) is required,
|
||||
because release notes are automatically generated from these messages.
|
||||
[commit message conventions][developers.commits]. Adherence to the
|
||||
[commit message conventions][developers.commits] is required, because release notes are
|
||||
automatically generated from these messages.
|
||||
|
||||
```shell
|
||||
git commit -a
|
||||
```
|
||||
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
|
||||
|
||||
* Build your changes locally to ensure all the tests pass:
|
||||
* Before creating the Pull Request, package and run all tests a last time:
|
||||
|
||||
```shell
|
||||
grunt test
|
||||
yarn grunt test
|
||||
```
|
||||
|
||||
* Push your branch to GitHub:
|
||||
@@ -132,24 +151,29 @@ Before you submit your pull request consider the following guidelines:
|
||||
git push origin my-fix-branch
|
||||
```
|
||||
|
||||
In GitHub, send a pull request to `angular:master`.
|
||||
If we suggest changes, then:
|
||||
* In GitHub, send a pull request to `angular.js:master`. This will trigger the check of the
|
||||
[Contributor License Agreement](#cla) and the Travis integration.
|
||||
|
||||
* Make the required updates.
|
||||
* Re-run the Angular test suite to ensure tests are still passing.
|
||||
* Commit your changes to your branch (e.g. `my-fix-branch`).
|
||||
* Push the changes to your GitHub repository (this will update your Pull Request).
|
||||
* If you find that the Travis integration has failed, look into the logs on Travis to find out
|
||||
if your changes caused test failures, the commit message was malformed etc. If you find that the
|
||||
tests failed or times out for unrelated reasons, you can ping a team member so that the build can be
|
||||
restarted.
|
||||
|
||||
If the PR gets too outdated we may ask you to rebase and force push to update the PR:
|
||||
* If we suggest changes, then:
|
||||
|
||||
```shell
|
||||
git rebase master -i
|
||||
git push origin my-fix-branch -f
|
||||
```
|
||||
* Make the required updates.
|
||||
* Re-run the AngularJS test suite to ensure tests are still passing.
|
||||
* Commit your changes to your branch (e.g. `my-fix-branch`).
|
||||
* Push the changes to your GitHub repository (this will update your Pull Request).
|
||||
You can also amend the initial commits and force push them to the branch.
|
||||
|
||||
_WARNING: Squashing or reverting commits and force-pushing thereafter may remove GitHub comments
|
||||
on code that were previously made by you or others in your commits. Avoid any form of rebasing
|
||||
unless necessary._
|
||||
```shell
|
||||
git rebase master -i
|
||||
git push origin my-fix-branch -f
|
||||
```
|
||||
|
||||
This is generally easier to follow, but seperate commits are useful if the Pull Request contains
|
||||
iterations that might be interesting to see side-by-side.
|
||||
|
||||
That's it! Thank you for your contribution!
|
||||
|
||||
@@ -182,135 +206,41 @@ from the main (upstream) repository:
|
||||
git pull --ff upstream master
|
||||
```
|
||||
|
||||
## <a name="rules"></a> Coding Rules
|
||||
## <a name="cla"></a> Signing the Contributor License Agreement (CLA)
|
||||
|
||||
To ensure consistency throughout the source code, keep these rules in mind as you are working:
|
||||
|
||||
* All features or bug fixes **must be tested** by one or more [specs][unit-testing].
|
||||
* All public API methods **must be documented** with ngdoc, an extended version of jsdoc (we added
|
||||
support for markdown and templating via @ngdoc tag). To see how we document our APIs, please check
|
||||
out the existing ngdocs and see [this wiki page][ngDocs].
|
||||
* With the exceptions listed below, we follow the rules contained in
|
||||
[Google's JavaScript Style Guide][js-style-guide]:
|
||||
* **Do not use namespaces**: Instead, wrap the entire angular code base in an anonymous closure and
|
||||
export our API explicitly rather than implicitly.
|
||||
* Wrap all code at **100 characters**.
|
||||
* Instead of complex inheritance hierarchies, we **prefer simple objects**. We use prototypal
|
||||
inheritance only when absolutely necessary.
|
||||
* We **love functions and closures** and, whenever possible, prefer them over objects.
|
||||
* To write concise code that can be better minified, we **use aliases internally** that map to the
|
||||
external API. See our existing code to see what we mean.
|
||||
* We **don't go crazy with type annotations** for private internal APIs unless it's an internal API
|
||||
that is used throughout AngularJS. The best guidance is to do what makes the most sense.
|
||||
|
||||
## <a name="commit"></a> Git Commit Guidelines
|
||||
|
||||
We have very precise rules over how our git commit messages can be formatted. This leads to **more
|
||||
readable messages** that are easy to follow when looking through the **project history**. But also,
|
||||
we use the git commit messages to **generate the AngularJS change log**.
|
||||
|
||||
The commit message formatting can be added using a typical git workflow or through the use of a CLI
|
||||
wizard ([Commitizen](https://github.com/commitizen/cz-cli)). To use the wizard, run `yarn run commit`
|
||||
in your terminal after staging your changes in git.
|
||||
|
||||
### Commit Message Format
|
||||
Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
|
||||
format that includes a **type**, a **scope** and a **subject**:
|
||||
|
||||
```
|
||||
<type>(<scope>): <subject>
|
||||
<BLANK LINE>
|
||||
<body>
|
||||
<BLANK LINE>
|
||||
<footer>
|
||||
```
|
||||
|
||||
The **header** is mandatory and the **scope** of the header is optional.
|
||||
|
||||
Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
|
||||
to read on GitHub as well as in various git tools.
|
||||
|
||||
### Revert
|
||||
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit.
|
||||
In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
|
||||
|
||||
### Type
|
||||
Must be one of the following:
|
||||
|
||||
* **feat**: A new feature
|
||||
* **fix**: A bug fix
|
||||
* **docs**: Documentation only changes
|
||||
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing
|
||||
semi-colons, etc)
|
||||
* **refactor**: A code change that neither fixes a bug nor adds a feature
|
||||
* **perf**: A code change that improves performance
|
||||
* **test**: Adding missing or correcting existing tests
|
||||
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
|
||||
generation
|
||||
|
||||
### Scope
|
||||
The scope could be anything specifying place of the commit change. For example `$location`,
|
||||
`$browser`, `$compile`, `$rootScope`, `ngHref`, `ngClick`, `ngView`, etc...
|
||||
|
||||
You can use `*` when the change affects more than a single scope.
|
||||
|
||||
### Subject
|
||||
The subject contains succinct description of the change:
|
||||
|
||||
* use the imperative, present tense: "change" not "changed" nor "changes"
|
||||
* don't capitalize first letter
|
||||
* no dot (.) at the end
|
||||
|
||||
### Body
|
||||
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
|
||||
The body should include the motivation for the change and contrast this with previous behavior.
|
||||
|
||||
### Footer
|
||||
The footer should contain any information about **Breaking Changes** and is also the place to
|
||||
[reference GitHub issues that this commit closes][closing-issues].
|
||||
|
||||
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines.
|
||||
The rest of the commit message is then used for this.
|
||||
|
||||
A detailed explanation can be found in this [document][commit-message-format].
|
||||
|
||||
## <a name="cla"></a> Signing the CLA
|
||||
|
||||
Please sign our Contributor License Agreement (CLA) before sending pull requests. For any code
|
||||
changes to be accepted, the CLA must be signed. It's a quick process, we promise!
|
||||
Upon submmitting a Pull Request, a friendly bot will ask you to sign our CLA if you haven't done
|
||||
so before. Unfortunately, this is necessary for documentation changes, too.
|
||||
It's a quick process, we promise!
|
||||
|
||||
* For individuals we have a [simple click-through form][individual-cla].
|
||||
* For corporations we'll need you to
|
||||
[print, sign and one of scan+email, fax or mail the form][corporate-cla].
|
||||
|
||||
## <a name="info"></a> Further Information
|
||||
You can find out more detailed information about contributing in the
|
||||
[AngularJS documentation][contributing].
|
||||
|
||||
|
||||
|
||||
[Google Closure I18N library]: https://github.com/google/closure-library/tree/master/closure/goog/i18n
|
||||
[angular-dev]: https://groups.google.com/forum/?fromgroups#!forum/angular-dev
|
||||
[closing-issues]: https://help.github.com/articles/closing-issues-via-commit-messages/
|
||||
[Closure guide to i18n changes]: https://github.com/google/closure-library/wiki/Internationalization-%28i18n%29-changes-in-Closure-Library
|
||||
[coc]: https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md
|
||||
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
|
||||
[contribute]: http://docs.angularjs.org/misc/contribute
|
||||
[contributing]: http://docs.angularjs.org/misc/contribute
|
||||
[Common Locale Data Repository (CLDR)]: http://cldr.unicode.org
|
||||
[corporate-cla]: http://code.google.com/legal/corporate-cla-v1.0.html
|
||||
[dev-doc]: https://docs.angularjs.org/guide
|
||||
[developers]: DEVELOPERS.md
|
||||
[developers.commits]: DEVELOPERS.md#commits
|
||||
[developers.documentation]: DEVELOPERS.md#documentation
|
||||
[developers.rules]: DEVELOPERS.md#rules
|
||||
[developers.setup]: DEVELOPERS.md#setup
|
||||
[developers.tests-e2e]: DEVELOPERS.md#e2e-tests
|
||||
[developers.tests-unit]: DEVELOPERS.md#unit-tests
|
||||
[github-issues]: https://github.com/angular/angular.js/issues
|
||||
[github-new-issue]: https://github.com/angular/angular.js/issues/new
|
||||
[github]: https://github.com/angular/angular.js
|
||||
[gitter]: https://gitter.im/angular/angular.js
|
||||
[Google Closure I18N library]: https://github.com/google/closure-library/tree/master/closure/goog/i18n
|
||||
[groups]: https://groups.google.com/forum/?fromgroups#!forum/angular
|
||||
[individual-cla]: http://code.google.com/legal/individual-cla-v1.0.html
|
||||
[irc]: http://webchat.freenode.net/?channels=angularjs&uio=d4
|
||||
[js-style-guide]: https://google.github.io/styleguide/javascriptguide.xml
|
||||
[jsfiddle]: http://jsfiddle.net/
|
||||
[list]: https://groups.google.com/forum/?fromgroups#!forum/angular
|
||||
[ngDocs]: https://github.com/angular/angular.js/wiki/Writing-AngularJS-Documentation
|
||||
[karma-browserstack]: https://github.com/karma-runner/karma-browserstack-launcher
|
||||
[karma-saucelabs]: https://github.com/karma-runner/karma-sauce-launcher
|
||||
[plunker]: http://plnkr.co/edit
|
||||
[stackoverflow]: http://stackoverflow.com/questions/tagged/angularjs
|
||||
[unit-testing]: https://docs.angularjs.org/guide/unit-testing
|
||||
[Common Locale Data Repository (CLDR)]: http://cldr.unicode.org
|
||||
[Closure guide to i18n changes]: https://github.com/google/closure-library/wiki/Internationalization-%28i18n%29-changes-in-Closure-Library
|
||||
|
||||
[](https://github.com/igrigorik/ga-beacon)
|
||||
|
||||
+489
@@ -0,0 +1,489 @@
|
||||
# Developing AngularJS
|
||||
|
||||
* [Development Setup](#setup)
|
||||
* [Running Tests](#tests)
|
||||
* [Coding Rules](#rules)
|
||||
* [Commit Message Guidelines](#commits)
|
||||
* [Writing Documentation](#documentation)
|
||||
|
||||
## <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`.
|
||||
|
||||
### Installing Dependencies
|
||||
|
||||
Before you can build AngularJS, you must install and configure the following dependencies on your
|
||||
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
|
||||
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.
|
||||
|
||||
We recommend using [nvm](https://github.com/creationix/nvm) (or
|
||||
[nvm-windows](https://github.com/coreybutler/nvm-windows))
|
||||
to manage and install Node.js, which makes it easy to change the version of Node.js per project.
|
||||
|
||||
* [Yarn](https://yarnpkg.com): We use Yarn to install our Node.js module dependencies
|
||||
(rather than using npm). See the detailed [installation instructions][yarn-install].
|
||||
|
||||
* [Java](http://www.java.com): We minify JavaScript using
|
||||
[Closure Tools](https://developers.google.com/closure/), which require Java (version 7 or higher)
|
||||
to be installed and included in your
|
||||
[PATH](http://docs.oracle.com/javase/tutorial/essential/environment/paths.html) variable.
|
||||
|
||||
* [Grunt](http://gruntjs.com): We use Grunt as our build system. We're using it as a local dependency,
|
||||
but you can also add the grunt command-line tool globally (with `yarn global add grunt-cli`), which allows
|
||||
you to leave out the `yarn` prefix for all our grunt commands.
|
||||
|
||||
### Forking AngularJS on Github
|
||||
|
||||
To contribute code to AngularJS, you must have a GitHub account so you can push code to your own
|
||||
fork of AngularJS and open Pull Requests in the [GitHub Repository][github].
|
||||
|
||||
To create a Github account, follow the instructions [here](https://github.com/signup/free).
|
||||
Afterwards, go ahead and [fork](http://help.github.com/forking) the
|
||||
[main AngularJS repository][github].
|
||||
|
||||
|
||||
### Building AngularJS
|
||||
|
||||
To build AngularJS, you clone the source code repository and use Grunt to generate the non-minified
|
||||
and minified AngularJS files:
|
||||
|
||||
```shell
|
||||
# Clone your Github repository:
|
||||
git clone https://github.com/<github username>/angular.js.git
|
||||
|
||||
# Go to the AngularJS directory:
|
||||
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:
|
||||
yarn install
|
||||
|
||||
# Build AngularJS:
|
||||
yarn grunt package
|
||||
```
|
||||
|
||||
**Note:** If you're using Windows, you must use an elevated command prompt (right click, run as
|
||||
Administrator). This is because `yarn grunt package` creates some symbolic links.
|
||||
|
||||
The build output is in the `build` directory. It consists of the following files and
|
||||
directories:
|
||||
|
||||
* `angular-<version>.zip` — The complete zip file, containing all of the release build
|
||||
artifacts.
|
||||
|
||||
* `angular.js` / `angular.min.js` — The regular and minified core AngularJS script file.
|
||||
|
||||
* `angular-*.js` / `angular-*.min.js` — All other AngularJS module script files.
|
||||
|
||||
* `docs/` — A directory that contains a standalone version of the docs
|
||||
(same as served in `docs.angularjs.org`).
|
||||
|
||||
### <a name="local-server"></a> Running a Local Development Web Server
|
||||
|
||||
To debug code, run end-to-end tests, and serve the docs, it is often useful to have a local
|
||||
HTTP server. For this purpose, we have made available a local web server based on Node.js.
|
||||
|
||||
1. To start the web server, run:
|
||||
```shell
|
||||
yarn grunt webserver
|
||||
```
|
||||
|
||||
2. To access the local server, enter the following URL into your web browser:
|
||||
```text
|
||||
http://localhost:8000/
|
||||
```
|
||||
By default, it serves the contents of the AngularJS project directory.
|
||||
|
||||
3. To access the locally served docs, visit this URL:
|
||||
```text
|
||||
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
|
||||
tests once on Chrome run:
|
||||
|
||||
```shell
|
||||
yarn grunt test:unit
|
||||
```
|
||||
|
||||
To run the tests on other browsers use the command line flag:
|
||||
|
||||
```shell
|
||||
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.
|
||||
|
||||
For example, to run the whole unit test suite on selected browsers:
|
||||
|
||||
```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
|
||||
# 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
|
||||
```
|
||||
|
||||
Running these commands requires you to set up [Karma Browserstack][karma-browserstack] or
|
||||
[Karma-Saucelabs][karma-saucelabs], respectively.
|
||||
|
||||
During development, however, it's more productive to continuously run unit tests every time the
|
||||
source or test files change. To execute tests in this mode run:
|
||||
|
||||
1. To start the Karma server, capture Chrome browser and run unit tests, run:
|
||||
|
||||
```shell
|
||||
yarn grunt autotest
|
||||
```
|
||||
|
||||
2. To capture more browsers, open this URL in the desired browser (URL might be different if you
|
||||
have multiple instance of Karma running, read Karma's console output for the correct URL):
|
||||
|
||||
```text
|
||||
http://localhost:9876/
|
||||
```
|
||||
|
||||
3. To re-run tests just change any source or test file.
|
||||
|
||||
|
||||
To learn more about all of the preconfigured Grunt tasks run:
|
||||
|
||||
```shell
|
||||
yarn grunt --help
|
||||
```
|
||||
|
||||
|
||||
### <a name="e2e-tests"></a> Running the End-to-end Test Suite
|
||||
|
||||
AngularJS's end to end tests are run with Protractor. Simply run:
|
||||
|
||||
```shell
|
||||
yarn grunt test:e2e
|
||||
```
|
||||
|
||||
This will start the webserver and run the tests on Chrome.
|
||||
|
||||
## <a name="rules"></a> Coding Rules
|
||||
|
||||
To ensure consistency throughout the source code, keep these rules in mind as you are working:
|
||||
|
||||
* All features or bug fixes **must be tested** by one or more [specs][unit-testing].
|
||||
* All public API methods **must be documented** with ngdoc, an extended version of jsdoc (we added
|
||||
support for markdown and templating via @ngdoc tag). To see how we document our APIs, please check
|
||||
out the existing source code and see the section about [writing documentation](#documentation)
|
||||
* With the exceptions listed below, we follow the rules contained in
|
||||
[Google's JavaScript Style Guide][js-style-guide]:
|
||||
* **Do not use namespaces**: Instead, wrap the entire AngularJS code base in an anonymous
|
||||
closure and export our API explicitly rather than implicitly.
|
||||
* Wrap all code at **100 characters**.
|
||||
* Instead of complex inheritance hierarchies, we **prefer simple objects**. We use prototypal
|
||||
inheritance only when absolutely necessary.
|
||||
* We **love functions and closures** and, whenever possible, prefer them over objects.
|
||||
* To write concise code that can be better minified, we **use aliases internally** that map to
|
||||
the external API. See our existing code to see what we mean.
|
||||
* We **don't go crazy with type annotations** for private internal APIs unless it's an internal
|
||||
API that is used throughout AngularJS. The best guidance is to do what makes the most sense.
|
||||
|
||||
### Specific topics
|
||||
|
||||
#### Provider configuration
|
||||
|
||||
When adding configuration (options) to [providers][docs.provider], we follow a special pattern.
|
||||
|
||||
- for each option, add a `method` that ...
|
||||
- works as a getter and returns the current value when called without argument
|
||||
- works as a setter and returns itself for chaining when called with argument
|
||||
- for boolean options, uses the naming scheme `<option>Enabled([enabled])`
|
||||
- non-primitive options (e.g. objects) should be copied or the properties assigned explicitly to a
|
||||
new object so that the configuration cannot be changed during runtime.
|
||||
|
||||
For a boolean config example, see [`$compileProvider#debugInfoEnabled`][code.debugInfoEnabled]
|
||||
|
||||
For an object config example, see [`$location.html5Mode`][code.html5Mode]
|
||||
|
||||
#### Throwing errors
|
||||
|
||||
User-facing errors should be thrown with [`minErr`][code.minErr], a special error function that provides
|
||||
errors ids, templated error messages, and adds a link to a detailed error description.
|
||||
|
||||
The `$compile:badrestrict` error is a good example for a well-defined `minErr`:
|
||||
[code][code.badrestrict] and [description][docs.badrestrict].
|
||||
|
||||
|
||||
## <a name="commits"></a> Git Commit Guidelines
|
||||
|
||||
We have very precise rules over how our git commit messages can be formatted. This leads to **more
|
||||
readable messages** that are easy to follow when looking through the **project history**. But also,
|
||||
we use the git commit messages to **generate the AngularJS change log**.
|
||||
|
||||
The commit message formatting can be added using a typical git workflow or through the use of a CLI
|
||||
wizard ([Commitizen](https://github.com/commitizen/cz-cli)). To use the wizard, run `yarn run commit`
|
||||
in your terminal after staging your changes in git.
|
||||
|
||||
### Commit Message Format
|
||||
Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
|
||||
format that includes a **type**, a **scope** and a **subject**:
|
||||
|
||||
```
|
||||
<type>(<scope>): <subject>
|
||||
<BLANK LINE>
|
||||
<body>
|
||||
<BLANK LINE>
|
||||
<footer>
|
||||
```
|
||||
|
||||
The **header** is mandatory and the **scope** of the header is optional.
|
||||
|
||||
Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
|
||||
to read on GitHub as well as in various git tools.
|
||||
|
||||
### Revert
|
||||
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header
|
||||
of the reverted commit.
|
||||
In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit
|
||||
being reverted.
|
||||
A commit with this format is automatically created by the [`git revert`][git-revert] command.
|
||||
|
||||
### Type
|
||||
Must be one of the following:
|
||||
|
||||
* **feat**: A new feature
|
||||
* **fix**: A bug fix
|
||||
* **docs**: Documentation only changes
|
||||
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing
|
||||
semi-colons, etc)
|
||||
* **refactor**: A code change that neither fixes a bug nor adds a feature
|
||||
* **perf**: A code change that improves performance
|
||||
* **test**: Adding missing or correcting existing tests
|
||||
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
|
||||
generation
|
||||
|
||||
### Scope
|
||||
The scope could be anything specifying place of the commit change. For example `$location`,
|
||||
`$browser`, `$compile`, `$rootScope`, `ngHref`, `ngClick`, `ngView`, etc...
|
||||
|
||||
You can use `*` when the change affects more than a single scope.
|
||||
|
||||
### Subject
|
||||
The subject contains succinct description of the change:
|
||||
|
||||
* use the imperative, present tense: "change" not "changed" nor "changes"
|
||||
* don't capitalize first letter
|
||||
* no dot (.) at the end
|
||||
|
||||
### Body
|
||||
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
|
||||
The body should include the motivation for the change and contrast this with previous behavior.
|
||||
|
||||
### Footer
|
||||
The footer should contain any information about **Breaking Changes** and is also the place to
|
||||
[reference GitHub issues that this commit closes][closing-issues].
|
||||
|
||||
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines.
|
||||
The rest of the commit message is then used for this.
|
||||
|
||||
A detailed explanation can be found in this [document][commit-message-format].
|
||||
|
||||
## <a name="documentation"></a> Writing Documentation
|
||||
|
||||
The AngularJS project uses a form of [jsdoc](http://usejsdoc.org/) called ngdoc for all of its code
|
||||
documentation.
|
||||
|
||||
This means that all the docs are stored inline in the source code and so are kept in sync as it
|
||||
changes.
|
||||
|
||||
There is also extra content (the developer guide, error pages, the tutorial,
|
||||
and misceallenous pages) that live inside the AngularJS repository as markdown files.
|
||||
|
||||
This means that since we generate the documentation from the source code, we can easily provide
|
||||
version-specific documentation by simply checking out a version of AngularJS and running the build.
|
||||
|
||||
Extracting the source code documentation, processing and building the docs is handled by the
|
||||
documentation generation tool [Dgeni][dgeni].
|
||||
|
||||
### Building and viewing the docs locally
|
||||
The docs can be built from scratch using grunt:
|
||||
|
||||
```shell
|
||||
yarn grunt docs
|
||||
```
|
||||
|
||||
This defers the doc-building task to `gulp`.
|
||||
|
||||
Note that the docs app is using the local build files to run. This means you might first have to run
|
||||
the build:
|
||||
|
||||
```shell
|
||||
yarn grunt build
|
||||
```
|
||||
|
||||
(This is also necessary if you are making changes to minErrors).
|
||||
|
||||
To view the docs, see [Running a Local Development Web Server](#local-server).
|
||||
|
||||
### Writing jsdoc
|
||||
The ngdoc utility has basic support for many of the standard jsdoc directives. But in particular it
|
||||
is interested in the following block tags:
|
||||
|
||||
* `@name name` - the name of the ngdoc document
|
||||
* `@param {type} name description` - describes a parameter of a function
|
||||
* `@returns {type} description` - describes what a function returns
|
||||
* `@requires` - normally indicates that a JavaScript module is required; in an Angular service it is
|
||||
used to describe what other services this service relies on
|
||||
* `@property` - describes a property of an object
|
||||
* `@description` - used to provide a description of a component in markdown
|
||||
* `@link` - specifies a link to a URL or a type in the API reference.
|
||||
Links to the API have the following structure:
|
||||
|
||||
* the module namespace, followed by `.` (optional, default `ng`)
|
||||
* the `@ngdoc` type (see below), followed by `:` (optional, automatically inferred)
|
||||
* the name
|
||||
* the method, property, or anchor (optional)
|
||||
* the display name
|
||||
|
||||
For example: `{@link ng.type:$rootScope.Scope#$new Scope.$new()}`.
|
||||
|
||||
* `@example` - specifies an example. This can be a simple code block, or a
|
||||
[runnable example](#the-example-tag).
|
||||
* `@deprecated` - specifies that the following code is deprecated and should not be used.
|
||||
In The AngularJS docs, there are two specific patterns which can be used to further describe
|
||||
the deprecation: `sinceVersion="<version>"` and `removeVersion="<version>"`
|
||||
|
||||
The `type` in `@param` and `@returns` must be wrapped in `{}` curly braces, e.g. `{Object|Array}`.
|
||||
Parameters can be made optional by *either* appending a `=` to the type, e.g. `{Object=}`, *or* by
|
||||
putting the `[name]` in square brackets.
|
||||
Default values are only possible with the second syntax by appending `=<value>` to the parameter
|
||||
name, e.g. `@param {boolean} [ownPropsOnly=false]`.
|
||||
|
||||
Descriptions can contain markdown formatting.
|
||||
|
||||
#### AngularJS-specific jsdoc directives
|
||||
|
||||
In addition to the standard jsdoc tags, there are a number that are specific to the Angular
|
||||
code-base:
|
||||
|
||||
* `@ngdoc` - specifies the type of thing being documented. See below for more detail.
|
||||
* `@eventType emit|broadcast` - specifies whether the event is emitted or broadcast
|
||||
* `@usage` - shows how to use a `function` or `directive`. Is usually automatically generated.
|
||||
* `@knownIssue` - adds info about known quirks, problems, or limitations with the API, and possibly,
|
||||
workarounds. This section is not for bugs.
|
||||
|
||||
The following are specific to directives:
|
||||
|
||||
* `@animations` - specifies the animations a directive supports
|
||||
* `@multiElement` - specifies if a directive can span over multiple elements
|
||||
* `@priority` - specifies a directive's priority
|
||||
* `@restrict` - is extracted to show the usage of a directive. For example, for [E]lement,
|
||||
[A]ttribute, and [C]lass, use `@restrict ECA`
|
||||
* `@scope` - specifies that a directive will create a new scope
|
||||
|
||||
### The `@ngdoc` Directive
|
||||
This directive helps to specify the template used to render the item being documented. For instance,
|
||||
a directive would have different properties to a filter and so would be documented differently. The
|
||||
commonly used types are:
|
||||
|
||||
* `overview` - a general page (guide, api index)
|
||||
* `provider` - AngularJS provider, such as `$compileProvider` or `$httpProvider`.
|
||||
* `service` - injectable AngularJS service, such as `$compile` or `$http`.
|
||||
* `object` - well defined object (often exposed as a service)
|
||||
* `function` - function that will be available to other methods (such as a helper function within
|
||||
the ng module)
|
||||
* `method` - method on an object/service/controller
|
||||
* `property` - property on an object/service/controller
|
||||
* `event` - AngularJS event that will propagate through the `$scope` tree.
|
||||
* `directive` - AngularJS directive
|
||||
* `filter` - AngularJS filter
|
||||
* `error` - minErr error description
|
||||
|
||||
### General documentation with Markdown
|
||||
|
||||
Any text in tags can contain markdown syntax for formatting. Generally, you can use any markdown
|
||||
feature.
|
||||
|
||||
#### Headings
|
||||
|
||||
Only use *h2* headings and lower, as the page title is set in *h1*. Also make sure you follow the
|
||||
heading hierarchy. This ensures correct table of contents are created.
|
||||
|
||||
#### Code blocks
|
||||
In line code can be specified by enclosing the code in back-ticks (\`).
|
||||
A block of multi-line code can be enclosed in triple back-ticks (\`\`\`) but it is formatted better
|
||||
if it is enclosed in <pre>...</pre> tags and the code lines themselves are indented.
|
||||
|
||||
### Writing runnable (live) examples and e2e tests
|
||||
It is possible to embed examples in the documentation along with appropriate e2e tests. These
|
||||
examples and scenarios will be converted to runnable code within the documentation. So it is
|
||||
important that they work correctly. To ensure this, all these e2e scenarios are run as part of the
|
||||
automated Travis tests.
|
||||
|
||||
If you are adding an example with an e2e test, you should [run the test locally](#e2e-tests) first
|
||||
to ensure it passes. You can change `it(...)` to `fit(...)` to run only your test,
|
||||
but make sure you change it back to `it(...)` before committing.
|
||||
|
||||
#### The `<example>` tag
|
||||
This tag identifies a block of HTML that will define a runnable example. It can take the following
|
||||
attributes:
|
||||
|
||||
* `animations` - if set to `true` then this example uses ngAnimate.
|
||||
* `deps` - Semicolon-separated list of additional angular module files to be loaded,
|
||||
e.g. `angular-animate.js`
|
||||
* `name` - every example should have a name. It should start with the component, e.g directive name,
|
||||
and not contain whitespace
|
||||
* `module` - the name of the app module as defined in the example's JavaScript
|
||||
|
||||
Within this tag we provide `<file>` tags that specify what files contain the example code.
|
||||
|
||||
```
|
||||
<example
|
||||
module="angularAppModule"
|
||||
name="exampleName"
|
||||
deps="angular-animate.js;angular-route.js"
|
||||
animations="true">
|
||||
...
|
||||
<file name="index.html">...</file>
|
||||
<file name="script.js">...</file>
|
||||
<file name="animations.css">...</file>
|
||||
<file name="protractor.js">...</file>
|
||||
...
|
||||
</example>
|
||||
```
|
||||
|
||||
You can see an example of a well-defined example [in the `ngRepeat` documentation][code.ngRepeat-example].
|
||||
|
||||
[closing-issues]: https://help.github.com/articles/closing-issues-via-commit-messages/
|
||||
[Closure guide to i18n changes]: https://github.com/google/closure-library/wiki/Internationalization-%28i18n%29-changes-in-Closure-Library
|
||||
[code.badrestrict]: https://github.com/angular/angular.js/blob/202f1809ad14827a6ac6a125157c605d65e0b551/src/ng/compile.js#L1107-L1110
|
||||
[code.debugInfoEnabled]: https://github.com/angular/angular.js/blob/32fbb2e78f53d765fbb170f7cf99e42e072d363b/src/ng/compile.js#L1378-L1413
|
||||
[code.html5Mode]: https://github.com/angular/angular.js/blob/202f1809ad14827a6ac6a125157c605d65e0b551/src/ng/location.js#L752-L797
|
||||
[code.minErr]: https://github.com/angular/angular.js/blob/202f1809ad14827a6ac6a125157c605d65e0b551/src/minErr.js#L53-L113
|
||||
[code.ngRepeat-example]: https://github.com/angular/angular.js/blob/0822d34b10ea0371c260c80a1486a4d508ea5a91/src/ng/directive/ngRepeat.js#L249-L340
|
||||
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
|
||||
[Common Locale Data Repository (CLDR)]: http://cldr.unicode.org
|
||||
[corporate-cla]: http://code.google.com/legal/corporate-cla-v1.0.html
|
||||
[dgeni]: https://github.com/angular/dgeni
|
||||
[docs.badrestrict]: docs/content/error/$compile/badrestrict.ngdoc
|
||||
[docs.provider]: https://code.angularjs.org/snapshot/docs/api/auto/service/$provide#provider
|
||||
[git-revert]: https://git-scm.com/docs/git-revert
|
||||
[git-setup]: https://help.github.com/articles/set-up-git
|
||||
[github-issues]: https://github.com/angular/angular.js/issues
|
||||
[github]: https://github.com/angular/angular.js
|
||||
[js-style-guide]: https://google.github.io/styleguide/javascriptguide.xml
|
||||
[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
|
||||
+118
-13
@@ -49,7 +49,6 @@ if (!process.env.TRAVIS && !process.env.JENKINS_HOME) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = function(grunt) {
|
||||
|
||||
// this loads all the node_modules that start with `grunt-` as plugins
|
||||
@@ -64,6 +63,12 @@ module.exports = function(grunt) {
|
||||
NG_VERSION.cdn = versionInfo.cdnVersion;
|
||||
var dist = 'angular-' + NG_VERSION.full;
|
||||
|
||||
var deployVersion = NG_VERSION.full;
|
||||
|
||||
if (NG_VERSION.isSnapshot) {
|
||||
deployVersion = NG_VERSION.distTag === 'latest' ? 'snapshot-stable' : 'snapshot';
|
||||
}
|
||||
|
||||
if (versionInfo.cdnVersion == null) {
|
||||
throw new Error('Unable to read CDN version, are you offline or has the CDN not been properly pushed?\n' +
|
||||
'Perhaps you want to set the NG1_BUILD_NO_REMOTE_VERSION_REQUESTS environment variable?');
|
||||
@@ -311,7 +316,40 @@ module.exports = function(grunt) {
|
||||
copy: {
|
||||
i18n: {
|
||||
files: [
|
||||
{ src: 'src/ngLocale/**', dest: 'build/i18n/', expand: true, flatten: true }
|
||||
{
|
||||
src: 'src/ngLocale/**',
|
||||
dest: 'build/i18n/',
|
||||
expand: true,
|
||||
flatten: true
|
||||
}
|
||||
]
|
||||
},
|
||||
deployFirebaseCode: {
|
||||
files: [
|
||||
// the zip file should not be compressed again.
|
||||
{
|
||||
src: 'build/*.zip',
|
||||
dest: 'uploadCode/' + deployVersion + '/',
|
||||
expand: true,
|
||||
flatten: true
|
||||
}
|
||||
]
|
||||
},
|
||||
deployFirebaseDocs: {
|
||||
files: [
|
||||
// The source files are needed by the embedded examples in the docs app.
|
||||
{
|
||||
src: 'build/angular*.{js,js.map,min.js}',
|
||||
dest: 'uploadDocs/',
|
||||
expand: true,
|
||||
flatten: true
|
||||
},
|
||||
{
|
||||
cwd: 'build/docs',
|
||||
src: '**',
|
||||
dest: 'uploadDocs/',
|
||||
expand: true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -325,10 +363,23 @@ module.exports = function(grunt) {
|
||||
expand: true,
|
||||
dot: true,
|
||||
dest: dist + '/'
|
||||
},
|
||||
deployFirebaseCode: {
|
||||
options: {
|
||||
mode: 'gzip'
|
||||
},
|
||||
src: ['**', '!*.zip'],
|
||||
cwd: 'build',
|
||||
expand: true,
|
||||
dest: 'uploadCode/' + deployVersion + '/'
|
||||
}
|
||||
},
|
||||
|
||||
shell: {
|
||||
// Travis expects the firebase.json in the repository root, but we have it in a sub-folder
|
||||
'symlink-firebase-docs': {
|
||||
command: 'ln -s ./scripts/docs.angularjs.org-firebase/firebase.json ./firebase.json'
|
||||
},
|
||||
'install-node-dependencies': {
|
||||
command: 'yarn'
|
||||
},
|
||||
@@ -359,24 +410,78 @@ module.exports = function(grunt) {
|
||||
});
|
||||
|
||||
//alias tasks
|
||||
grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', ['eslint', 'package', 'test:unit', 'test:promises-aplus', 'tests:docs', 'test:protractor']);
|
||||
grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', [
|
||||
'eslint',
|
||||
'package',
|
||||
'test:unit',
|
||||
'test:promises-aplus',
|
||||
'tests:docs',
|
||||
'test:protractor'
|
||||
]);
|
||||
grunt.registerTask('test:jqlite', 'Run the unit tests with Karma' , ['tests:jqlite']);
|
||||
grunt.registerTask('test:jquery', 'Run the jQuery (latest) unit tests with Karma', ['tests:jquery']);
|
||||
grunt.registerTask('test:jquery-2.2', 'Run the jQuery 2.2 unit tests with Karma', ['tests:jquery-2.2']);
|
||||
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']);
|
||||
grunt.registerTask('test:modules', 'Run the Karma module tests with Karma', [
|
||||
'build',
|
||||
'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', ['test:jqlite', 'test:jquery', 'test:jquery-2.2', 'test:jquery-2.1', 'test:modules']);
|
||||
grunt.registerTask('test:protractor', 'Run the end to end tests with Protractor and keep a test server running in the background', ['webdriver', 'connect:testserver', 'protractor:normal']);
|
||||
grunt.registerTask('test:travis-protractor', 'Run the end to end tests with Protractor for Travis CI builds', ['connect:testserver', 'protractor:travis']);
|
||||
grunt.registerTask('test:ci-protractor', 'Run the end to end tests with Protractor for Jenkins CI builds', ['webdriver', 'connect:testserver', 'protractor:jenkins']);
|
||||
grunt.registerTask('test:unit', 'Run unit, jQuery and Karma module tests with Karma', [
|
||||
'test:jqlite',
|
||||
'test:jquery',
|
||||
'test:jquery-2.2',
|
||||
'test:jquery-2.1',
|
||||
'test:modules'
|
||||
]);
|
||||
grunt.registerTask('test:protractor', 'Run the end to end tests with Protractor and keep a test server running in the background', [
|
||||
'webdriver',
|
||||
'connect:testserver',
|
||||
'protractor:normal'
|
||||
]);
|
||||
grunt.registerTask('test:travis-protractor', 'Run the end to end tests with Protractor for Travis CI builds', [
|
||||
'connect:testserver',
|
||||
'protractor:travis'
|
||||
]);
|
||||
grunt.registerTask('test:ci-protractor', 'Run the end to end tests with Protractor for Jenkins CI builds', [
|
||||
'webdriver',
|
||||
'connect:testserver',
|
||||
'protractor:jenkins'
|
||||
]);
|
||||
grunt.registerTask('test:e2e', 'Alias for test:protractor', ['test:protractor']);
|
||||
grunt.registerTask('test:promises-aplus',['build:promises-aplus-adapter', 'shell:promises-aplus-tests']);
|
||||
|
||||
grunt.registerTask('minify', ['bower', 'clean', 'build', 'minall']);
|
||||
grunt.registerTask('test:promises-aplus',[
|
||||
'build:promises-aplus-adapter',
|
||||
'shell:promises-aplus-tests'
|
||||
]);
|
||||
grunt.registerTask('minify', [
|
||||
'clean',
|
||||
'build',
|
||||
'minall'
|
||||
]);
|
||||
grunt.registerTask('webserver', ['connect:devserver']);
|
||||
grunt.registerTask('package', ['bower', 'validate-angular-files', 'clean', 'buildall', 'minall', 'collect-errors', 'write', 'docs', 'copy', 'compress']);
|
||||
grunt.registerTask('ci-checks', ['ddescribe-iit', 'merge-conflict', 'eslint']);
|
||||
grunt.registerTask('package', [
|
||||
'validate-angular-files',
|
||||
'clean',
|
||||
'buildall',
|
||||
'minall',
|
||||
'collect-errors',
|
||||
'write',
|
||||
'docs',
|
||||
'copy:i18n',
|
||||
'compress:build'
|
||||
]);
|
||||
grunt.registerTask('ci-checks', [
|
||||
'ddescribe-iit',
|
||||
'merge-conflict',
|
||||
'eslint'
|
||||
]);
|
||||
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-2017 Google, Inc. http://angularjs.org
|
||||
Copyright (c) 2010-2018 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,
|
||||
Angular's $scope objects can be annotated as:
|
||||
AngularJS's $scope objects can be annotated as:
|
||||
```js
|
||||
/** @type {angular.Scope} */
|
||||
var scope = $scope;
|
||||
|
||||
@@ -8,43 +8,35 @@ synchronizes data from your UI (view) with your JavaScript objects (model) throu
|
||||
binding. To help you structure your application better and make it easy to test, AngularJS teaches
|
||||
the browser how to do dependency injection and inversion of control.
|
||||
|
||||
It also helps with server-side communication, taming async callbacks with promises and deferreds,
|
||||
and it makes client-side navigation and deeplinking with hashbang urls or HTML5 pushState a
|
||||
It also helps with server-side communication, taming async callbacks with promises and deferred objects,
|
||||
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!
|
||||
|
||||
* Web site: https://angularjs.org
|
||||
* Tutorial: https://docs.angularjs.org/tutorial
|
||||
* API Docs: https://docs.angularjs.org/api
|
||||
* Developer Guide: https://docs.angularjs.org/guide
|
||||
* Contribution guidelines: [CONTRIBUTING.md](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md)
|
||||
* Contribution guidelines: [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
* Core Development: [DEVELOPERS.md](DEVELOPERS.md)
|
||||
* Dashboard: https://dashboard.angularjs.org
|
||||
|
||||
##### Looking for Angular 2? Go here: https://github.com/angular/angular
|
||||
##### Looking for the new Angular? Go here: https://github.com/angular/angular
|
||||
|
||||
Building AngularJS
|
||||
---------
|
||||
[Once you have set up your environment](https://docs.angularjs.org/misc/contribute), just run:
|
||||
Documentation
|
||||
--------------------
|
||||
Go to https://docs.angularjs.org
|
||||
|
||||
grunt package
|
||||
|
||||
|
||||
Running tests
|
||||
-------------
|
||||
To execute all unit tests, use:
|
||||
|
||||
grunt test:unit
|
||||
|
||||
To execute end-to-end (e2e) tests, use:
|
||||
|
||||
grunt package
|
||||
grunt test:e2e
|
||||
|
||||
To learn more about the grunt tasks, run `grunt --help`
|
||||
|
||||
Contribute & Develop
|
||||
Contribute
|
||||
--------------------
|
||||
|
||||
We've set up a separate document for our [contribution guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md).
|
||||
We've set up a separate document for our
|
||||
[contribution guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md).
|
||||
|
||||
Develop
|
||||
--------------------
|
||||
|
||||
We've set up a separate document for
|
||||
[developers](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md).
|
||||
|
||||
|
||||
[](https://github.com/igrigorik/ga-beacon)
|
||||
@@ -80,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 Angular will take care of the dependencies.
|
||||
moving parts, we simply define what we want and AngularJS 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
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
# Triage new issues/PRs on github
|
||||
|
||||
This document shows the steps the Angular team is using to triage issues.
|
||||
This document shows the steps the AngularJS 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 Angular apps
|
||||
* high - impacts most or all AngularJS 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 Angular to accomplish something that Angular should be able to do
|
||||
* broken expected use - it's hard or impossible for a developer using AngularJS to accomplish something that AngularJS 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 on Bower and/or to the npm repository.
|
||||
> The good news is that you could easily implement this as a third-party module and publish it to the npm registry.
|
||||
|
||||
|
||||
## Assigning Work
|
||||
|
||||
Vendored
+4
-4
@@ -190,7 +190,7 @@ var angularFiles = {
|
||||
],
|
||||
|
||||
'karma': [
|
||||
'bower_components/jquery/dist/jquery.js',
|
||||
'node_modules/jquery/dist/jquery.js',
|
||||
'test/jquery_remove.js',
|
||||
'@angularSrc',
|
||||
'@angularSrcModules',
|
||||
@@ -228,7 +228,7 @@ var angularFiles = {
|
||||
],
|
||||
|
||||
'karmaJquery': [
|
||||
'bower_components/jquery/dist/jquery.js',
|
||||
'node_modules/jquery/dist/jquery.js',
|
||||
'test/jquery_alias.js',
|
||||
'@angularSrc',
|
||||
'@angularSrcModules',
|
||||
@@ -248,8 +248,8 @@ var angularFiles = {
|
||||
angularFiles['karmaJquery' + jQueryVersion] = []
|
||||
.concat(angularFiles.karmaJquery)
|
||||
.map(function(path) {
|
||||
if (path.startsWith('bower_components/jquery')) {
|
||||
return path.replace(/^bower_components\/jquery/, 'bower_components/jquery-' + jQueryVersion);
|
||||
if (path.startsWith('node_modules/jquery')) {
|
||||
return path.replace(/^node_modules\/jquery/, 'node_modules/jquery-' + jQueryVersion);
|
||||
}
|
||||
return path;
|
||||
});
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
|
||||
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
|
||||
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
|
||||
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
|
||||
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"name": "angularjs",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"jquery": "3.1.0",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
.visible-phone{display:none}.visible-desktop{display:block}.navbar{display:block}.navbar .container{padding:0 16px;width:auto}.navbar .brand{float:left;margin:8px 80px 0 8px;padding:0}.navbar .brand a{display:block;height:30px;margin:6px 0 5px 0;overflow:hidden;padding:0;width:117px}.navbar .nav{float:right}.navbar .nav .dropdown-toggle{color:rgba(255,255,255,0.87);font-size:16px;font-weight:300;line-height:56px;padding:0 24px;text-transform:uppercase;transition:all .3s}.navbar .nav .dropdown-toggle:hover,.navbar .nav .dropdown-toggle:active,.navbar .nav .dropdown-toggle:focus{background:#37474F;color:#fff}.navbar .nav .dropdown-menu{background:#37474F;border:none;border-radius:0;box-shadow:0 0 16px rgba(0,0,0,0.12),0 16px 16px rgba(0,0,0,0.24);color:#fff;left:auto;margin:0;padding:0;right:0}.navbar .nav .dropdown-menu:after,.navbar .nav .dropdown-menu:before{display:none}.navbar .nav .dropdown-menu li{border-bottom:1px solid rgba(38,50,56,0.56);box-sizing:border-box;line-height:48px}.navbar .nav .dropdown-menu li:last-child{border:none}.navbar .nav .dropdown-menu a{background:#37474F;color:#fff;font-weight:300;line-height:48px;padding:0 16px;transition:all .2s}.navbar .nav .dropdown-menu a:hover,.navbar .nav .dropdown-menu a:focus{background:#455A64}.navbar .navbar-search{left:200px;margin:0;position:absolute;right:440px;top:8px;width:auto}.navbar .navbar-search i{color:#546E7A;font-size:16px;left:12px;position:absolute;top:11px}.navbar .navbar-search .search-query{background:#37474F;border:none;border-radius:2px;box-shadow:none;box-sizing:border-box;color:#546E7A;font-size:14px;height:40px;width:100%;padding:0 16px 0 32px;text-shadow:none;transition:all .3s}.navbar .navbar-search .search-query:-webkit-autofill,.navbar .navbar-search .search-query:-webkit-autofill:hover,.navbar .navbar-search .search-query:-webkit-autofill:focus{background-color:#fff;transition:background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#455A64}.navbar .navbar-search .search-query:hover,.navbar .navbar-search .search-query:active,.navbar .navbar-search .search-query:focus{background:#fff;box-shadow:inset 0 2px 4px rgba(0,0,0,0.24);color:#2196F3}.navbar .navbar-search .search-query::-webkit-input-placeholder{color:#546E7A}.navbar .navbar-search .search-query::-moz-placeholder{color:#546E7A}.navbar .navbar-search .search-query:-ms-input-placeholder{color:#546E7A}.navbar .navbar-search .search-query:-moz-placeholder{color:#546E7A}#navbar-main .navbar-inner{background:#263238;height:56px}#navbar-notice{z-index:1029;top:56px}#navbar-notice .navbar-inner{background:#ECEFF1;box-shadow:0 0 3px rgba(0,0,0,0.12),0 3px 3px rgba(0,0,0,0.24);height:auto}.site-notice{padding:4px 0;text-align:center;font-size:13px;margin:0}@media handheld and (max-width: 800px), screen and (max-device-width: 800px), screen and (max-width: 800px){.visible-phone{display:block}.visible-desktop{display:none}}@media handheld and (max-width: 800px), screen and (max-device-width: 800px), screen and (max-width: 800px){.homepage .container{padding:16px;width:auto}.homepage .span1{width:auto}.homepage .span2{width:auto}.homepage .span3{width:auto}.homepage .span4{width:auto}.homepage .span5{width:auto}.homepage .span6{width:auto}.homepage .span7{width:auto}.homepage .span8{width:auto}.homepage .span9{width:auto}.homepage .span10{width:auto}.homepage .navbar .container{padding:0 8px}.homepage #navbar-main .navbar-inner{height:40px}.homepage #navbar-main .brand{margin:6px 0 0 0}.homepage #navbar-main .brand a{margin:0}.homepage #navbar-main .nav{margin:0}.homepage #navbar-main .nav .dropdown-toggle{font-size:12px;line-height:40px;padding:0 8px}.homepage #navbar-main .dropdown-menu a{padding:0 8px}.homepage #navbar-main .navbar-search{background:#263238;border-bottom:1px solid #263238;left:0;right:0;top:100%}.homepage #navbar-main .navbar-search i{left:12px;top:7px}.homepage #navbar-main .navbar-search .search-query{border-radius:0;height:32px}.homepage #navbar-notice{top:40px}.homepage #navbar-notice .site-notice{font-size:11px}.homepage .hero{padding:80px 32px 32px 32px}.homepage .hero h2{background-size:230px 60px;height:60px;width:230px}}
|
||||
@@ -1,3 +1,37 @@
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url("../components/open-sans-fontface-1.4.0/fonts/Regular/OpenSans-Regular.eot?v=1.1.0");
|
||||
src: url("../components/open-sans-fontface-1.4.0/fonts/Regular/OpenSans-Regular.eot?#iefix&v=1.1.0") format("embedded-opentype"),
|
||||
url("../components/open-sans-fontface-1.4.0/fonts/Regular/OpenSans-Regular.woff?v=1.1.0") format("woff"),
|
||||
url("../components/open-sans-fontface-1.4.0/fonts/Regular/OpenSans-Regular.ttf?v=1.1.0") format("truetype"),
|
||||
url("../components/open-sans-fontface-1.4.0/fonts/Regular/OpenSans-Regular.svg?v=1.1.0#OpenSansBold") format("svg");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url("../components/open-sans-fontface-1.4.0/fonts/Semibold/OpenSans-Semibold.eot?v=1.1.0");
|
||||
src: url("../components/open-sans-fontface-1.4.0/fonts/Semibold/OpenSans-Semibold.eot?#iefix&v=1.1.0") format("embedded-opentype"),
|
||||
url("../components/open-sans-fontface-1.4.0/fonts/Semibold/OpenSans-Semibold.woff?v=1.1.0") format("woff"),
|
||||
url("../components/open-sans-fontface-1.4.0/fonts/Semibold/OpenSans-Semibold.ttf?v=1.1.0") format("truetype"),
|
||||
url("../components/open-sans-fontface-1.4.0/fonts/Semibold/OpenSans-Semibold.svg?v=1.1.0#OpenSansBold") format("svg");
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url("../components/open-sans-fontface-1.4.0/fonts/Bold/OpenSans-Bold.eot?v=1.1.0");
|
||||
src: url("../components/open-sans-fontface-1.4.0/fonts/Bold/OpenSans-Bold.eot?#iefix&v=1.1.0") format("embedded-opentype"),
|
||||
url("../components/open-sans-fontface-1.4.0/fonts/Bold/OpenSans-Bold.woff?v=1.1.0") format("woff"),
|
||||
url("../components/open-sans-fontface-1.4.0/fonts/Bold/OpenSans-Bold.ttf?v=1.1.0") format("truetype"),
|
||||
url("../components/open-sans-fontface-1.4.0/fonts/Bold/OpenSans-Bold.svg?v=1.1.0#OpenSansBold") format("svg");
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
html, body {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
@@ -53,13 +87,13 @@ h1,h2,h3,h4,h5,h6 {
|
||||
}
|
||||
|
||||
.header .brand {
|
||||
padding-top: 6px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.header .brand img {
|
||||
margin-top: 5px;
|
||||
height: 30px;
|
||||
margin-top: 0;
|
||||
height: auto;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.docs-search {
|
||||
@@ -82,6 +116,11 @@ h1,h2,h3,h4,h5,h6 {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.navbar .navbar-search i {
|
||||
top: 13px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.docs-search > .search-query:focus {
|
||||
outline: 0;
|
||||
}
|
||||
@@ -297,6 +336,7 @@ iframe.example {
|
||||
}
|
||||
|
||||
.search-results-container {
|
||||
position: relative;
|
||||
padding-bottom: 1em;
|
||||
border-top: 1px solid #111;
|
||||
background: #181818;
|
||||
@@ -435,15 +475,17 @@ iframe.example {
|
||||
background: #f1f1f1;
|
||||
}
|
||||
|
||||
.sup-header {
|
||||
#navbar-sub {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 5px;
|
||||
background: rgba(245,245,245,0.88);
|
||||
box-shadow: 0 0 2px #999;
|
||||
z-index: 1028;
|
||||
top: 83px;
|
||||
}
|
||||
|
||||
.main-body-grid {
|
||||
margin-top: 120px;
|
||||
margin-top: 144px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -454,7 +496,7 @@ iframe.example {
|
||||
|
||||
.main-body-grid > .grid-left {
|
||||
position: fixed;
|
||||
top: 120px;
|
||||
top: 144px;
|
||||
bottom: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
@@ -827,3 +869,115 @@ ul.events > li {
|
||||
iframe[name="example-anchoringExample"] {
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
/*
|
||||
angular-topnav.css and bootstrap overrides
|
||||
*/
|
||||
|
||||
.navbar .navbar-inner .container {
|
||||
padding: 0 16px;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.navbar .nav > li {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.navbar-nav .open .dropdown-menu {
|
||||
position: absolute;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.navbar-nav .open .dropdown-menu > li > a {
|
||||
line-height: 48px;
|
||||
}
|
||||
|
||||
#navbar-main .navbar-inner, #navbar-notice .navbar-inner {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
#navbar-sub .container {
|
||||
max-width: 970px;
|
||||
}
|
||||
|
||||
.nav .open > a, .nav .open > a:hover, .nav .open > a:focus {
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
toc-container {
|
||||
display: block;
|
||||
margin: 15px 10px;
|
||||
}
|
||||
|
||||
toc-container b {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
toc-container .btn {
|
||||
padding: 3px 6px;
|
||||
font-size: 13px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
toc-container > div > toc-tree ul {
|
||||
list-style: none;
|
||||
padding-left: 15px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
toc-container > div > toc-tree > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
toc-container > div > toc-tree > ul > li > toc-tree > ul > li toc-tree > ul li {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
@media handheld and (max-width:800px), screen and (max-device-width:800px), screen and (max-width:800px) {
|
||||
.navbar {
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
.search-results-container {
|
||||
top: 32px;
|
||||
overflow: auto;
|
||||
max-height: 85vh;
|
||||
padding-bottom: 0;
|
||||
position: static;
|
||||
}
|
||||
|
||||
.search-close {
|
||||
right: 1px;
|
||||
margin-left: 0;
|
||||
top: 41px;
|
||||
padding: 5px 10px;
|
||||
border-top-right-radius: 0;
|
||||
border-top-left-radius: 0;
|
||||
box-shadow: none;
|
||||
width: auto;
|
||||
bottom: auto;
|
||||
left: auto;
|
||||
}
|
||||
|
||||
.navbar-nav .open .dropdown-menu > li > a, .navbar-nav .open .dropdown-menu .dropdown-header {
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.homepage #navbar-notice {
|
||||
top: 72px;
|
||||
}
|
||||
|
||||
#navbar-notice .navbar-inner {
|
||||
box-shadow: 0 0 3px rgba(0, 0, 0, .12), 0 3px 3px rgba(0, 0, 0, .24)
|
||||
}
|
||||
|
||||
#navbar-sub {
|
||||
position: relative;
|
||||
top: 17px;
|
||||
margin-top: 80px;
|
||||
padding-bottom: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.0 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 212 B After Width: | Height: | Size: 183 B |
@@ -1,51 +1,48 @@
|
||||
'use strict';
|
||||
|
||||
describe('doc.angularjs.org', function() {
|
||||
describe('API pages', function() {
|
||||
|
||||
describe('API pages', function() {
|
||||
it('should display links to code on GitHub', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/service/$http');
|
||||
expect(element(by.css('.improve-docs')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/edit\/.+\/src\/ng\/http\.js/);
|
||||
|
||||
it('should display links to code on GitHub', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/service/$http');
|
||||
expect(element(by.css('.improve-docs')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/edit\/.+\/src\/ng\/http\.js/);
|
||||
browser.get('build/docs/index.html#!/api/ng/service/$http');
|
||||
expect(element(by.css('.view-source')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/tree\/.+\/src\/ng\/http\.js#L\d+/);
|
||||
});
|
||||
|
||||
browser.get('build/docs/index.html#!/api/ng/service/$http');
|
||||
expect(element(by.css('.view-source')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/tree\/.+\/src\/ng\/http\.js#L\d+/);
|
||||
});
|
||||
it('should change the page content when clicking a link to a service', function() {
|
||||
browser.get('build/docs/index.html');
|
||||
|
||||
it('should change the page content when clicking a link to a service', function() {
|
||||
browser.get('build/docs/index.html');
|
||||
var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]'));
|
||||
ngBindLink.click();
|
||||
|
||||
var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]'));
|
||||
ngBindLink.click();
|
||||
|
||||
var pageBody = element(by.css('h1'));
|
||||
expect(pageBody.getText()).toEqual('ngClick');
|
||||
});
|
||||
var mainHeader = element(by.css('.main-body h1 '));
|
||||
expect(mainHeader.getText()).toEqual('ngClick');
|
||||
});
|
||||
|
||||
|
||||
it('should show the functioning input directive example', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/directive/input');
|
||||
it('should show the functioning input directive example', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/directive/input');
|
||||
|
||||
// Ensure that the page is loaded before trying to switch frames.
|
||||
browser.waitForAngular();
|
||||
// Ensure that the page is loaded before trying to switch frames.
|
||||
browser.waitForAngular();
|
||||
|
||||
browser.switchTo().frame('example-input-directive');
|
||||
browser.switchTo().frame('example-input-directive');
|
||||
|
||||
var nameInput = element(by.model('user.name'));
|
||||
nameInput.sendKeys('!!!');
|
||||
var nameInput = element(by.model('user.name'));
|
||||
nameInput.sendKeys('!!!');
|
||||
|
||||
var code = element.all(by.css('tt')).first();
|
||||
expect(code.getText()).toContain('guest!!!');
|
||||
});
|
||||
var code = element.all(by.css('tt')).first();
|
||||
expect(code.getText()).toContain('guest!!!');
|
||||
});
|
||||
|
||||
it('should trim indentation from code blocks', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/type/$rootScope.Scope');
|
||||
it('should trim indentation from code blocks', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/type/$rootScope.Scope');
|
||||
|
||||
var codeBlocks = element.all(by.css('pre > code.lang-js'));
|
||||
codeBlocks.each(function(codeBlock) {
|
||||
var firstSpan = codeBlock.all(by.css('span')).first();
|
||||
expect(firstSpan.getText()).not.toMatch(/^\W+$/);
|
||||
});
|
||||
var codeBlocks = element.all(by.css('pre > code.lang-js'));
|
||||
codeBlocks.each(function(codeBlock) {
|
||||
var firstSpan = codeBlock.all(by.css('span')).first();
|
||||
expect(firstSpan.getText()).not.toMatch(/^\W+$/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
'use strict';
|
||||
|
||||
describe('directives', function() {
|
||||
|
||||
describe('parameter section', function() {
|
||||
|
||||
it('should show the directive name only if it is a param (attribute) with a value', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/directive/ngInclude');
|
||||
expect(getParamNames().getText()).toContain('ngInclude | src');
|
||||
|
||||
browser.get('build/docs/index.html#!/api/ngRoute/directive/ngView');
|
||||
expect(getParamNames().getText()).not.toContain('ngView');
|
||||
});
|
||||
});
|
||||
|
||||
describe('usage section', function() {
|
||||
|
||||
it('should show the directive name if it is a param (attribute) with a value', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/directive/ngInclude');
|
||||
|
||||
expect(getUsageAs('element', 'ng-include').isPresent()).toBe(true);
|
||||
expect(getUsageAs('attribute', 'ng-include').isPresent()).toBe(true);
|
||||
expect(getUsageAs('CSS class', 'ng-include').isPresent()).toBe(true);
|
||||
});
|
||||
|
||||
it('should show the directive name if it is a void param (attribute)', function() {
|
||||
browser.get('build/docs/index.html#!/api/ngRoute/directive/ngView');
|
||||
|
||||
expect(getUsageAs('element', 'ng-view').isPresent()).toBe(true);
|
||||
expect(getUsageAs('attribute', 'ng-view').isPresent()).toBe(true);
|
||||
expect(getUsageAs('CSS class', 'ng-view').isPresent()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function getParamNames() {
|
||||
var argsSection = element(by.className('input-arguments'));
|
||||
|
||||
var paramNames = argsSection.all(by.css('tr td:nth-child(1)'));
|
||||
|
||||
return paramNames;
|
||||
}
|
||||
|
||||
// Based on the type of directive usage, the directive name will show up in the code block
|
||||
// with a specific class
|
||||
var typeClassMap = {
|
||||
element: 'tag',
|
||||
attribute: 'atn',
|
||||
'CSS class': 'atv'
|
||||
};
|
||||
|
||||
function getUsageAs(type, directiveName) {
|
||||
var usage = element(by.className('usage'));
|
||||
|
||||
var as = usage.element(by.cssContainingText('li', 'as ' + type));
|
||||
|
||||
return as.element(by.cssContainingText('span.' + typeClassMap[type], directiveName));
|
||||
}
|
||||
@@ -44,30 +44,50 @@ describe('docs.angularjs.org', function() {
|
||||
var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]'));
|
||||
ngBindLink.click();
|
||||
|
||||
var pageBody = element(by.css('h1'));
|
||||
expect(pageBody.getText()).toEqual('ngClick');
|
||||
var mainHeader = element(by.css('.main-body h1 '));
|
||||
expect(mainHeader.getText()).toEqual('ngClick');
|
||||
});
|
||||
|
||||
|
||||
it('should include the files for the embedded examples from the same domain', function() {
|
||||
browser.get('build/docs/index-production.html#!api/ng/directive/ngClick');
|
||||
|
||||
var origin = browser.executeScript('return document.location.origin;');
|
||||
|
||||
var exampleIFrame = element(by.name('example-ng-click'));
|
||||
|
||||
// This is technically an implementation detail, but if this changes, then there's a good
|
||||
// chance the deployment process changed
|
||||
expect(exampleIFrame.getAttribute('src')).toContain('examples/example-ng-click/index.html');
|
||||
|
||||
browser.switchTo().frame('example-ng-click');
|
||||
|
||||
var scriptEl = element(by.tagName('script'));
|
||||
|
||||
// Ensure the included file is from the same domain
|
||||
expect(scriptEl.getAttribute('src')).toContain(origin);
|
||||
});
|
||||
|
||||
|
||||
it('should be resilient to trailing slashes', function() {
|
||||
browser.get('build/docs/index-production.html#!/api/ng/function/angular.noop/');
|
||||
var pageBody = element(by.css('h1'));
|
||||
expect(pageBody.getText()).toEqual('angular.noop');
|
||||
|
||||
var mainHeader = element(by.css('.main-body h1 '));
|
||||
expect(mainHeader.getText()).toEqual('angular.noop');
|
||||
});
|
||||
|
||||
|
||||
it('should be resilient to trailing "index"', function() {
|
||||
browser.get('build/docs/index-production.html#!/api/ng/function/angular.noop/index');
|
||||
var pageBody = element(by.css('h1'));
|
||||
expect(pageBody.getText()).toEqual('angular.noop');
|
||||
var mainHeader = element(by.css('.main-body h1 '));
|
||||
expect(mainHeader.getText()).toEqual('angular.noop');
|
||||
});
|
||||
|
||||
|
||||
it('should be resilient to trailing "index/"', function() {
|
||||
browser.get('build/docs/index-production.html#!/api/ng/function/angular.noop/index/');
|
||||
var pageBody = element(by.css('h1'));
|
||||
expect(pageBody.getText()).toEqual('angular.noop');
|
||||
var mainHeader = element(by.css('.main-body h1 '));
|
||||
expect(mainHeader.getText()).toEqual('angular.noop');
|
||||
});
|
||||
|
||||
|
||||
@@ -78,7 +98,8 @@ describe('docs.angularjs.org', function() {
|
||||
|
||||
it('should display an error if the page does not exist', function() {
|
||||
browser.get('build/docs/index-production.html#!/api/does/not/exist');
|
||||
expect(element(by.css('h1')).getText()).toBe('Oops!');
|
||||
var mainHeader = element(by.css('.main-body h1 '));
|
||||
expect(mainHeader.getText()).toEqual('Oops!');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* This scenario checks the presence of the table of contents for a sample of pages - API and guide.
|
||||
* The expectations are kept vague so that they can be easily adjusted when the docs change.
|
||||
*/
|
||||
|
||||
describe('table of contents', function() {
|
||||
|
||||
it('on provider pages', function() {
|
||||
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) {
|
||||
expect(text.join('')).toContain('Overview');
|
||||
expect(text.join('')).toContain('Methods');
|
||||
});
|
||||
|
||||
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
|
||||
|
||||
tocFirstLevel.then(function(match) {
|
||||
expect(match.length).toBe(3);
|
||||
|
||||
expect(match[1].all(by.css('li')).count()).toBe(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('on service pages', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/service/$controller');
|
||||
|
||||
var toc = element.all(by.css('toc-container > div > toc-tree'));
|
||||
toc.getText().then(function(text) {
|
||||
expect(text.join('')).toContain('Overview');
|
||||
expect(text.join('')).toContain('Usage');
|
||||
});
|
||||
|
||||
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
|
||||
|
||||
tocFirstLevel.then(function(match) {
|
||||
expect(match.length).toBe(3);
|
||||
|
||||
expect(match[2].all(by.css('li')).count()).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
it('on directive pages', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/directive/input');
|
||||
|
||||
var toc = element.all(by.css('toc-container > div > toc-tree'));
|
||||
toc.getText().then(function(text) {
|
||||
expect(text.join('')).toContain('Overview');
|
||||
expect(text.join('')).toContain('Usage');
|
||||
expect(text.join('')).toContain('Directive Info');
|
||||
});
|
||||
|
||||
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
|
||||
|
||||
tocFirstLevel.then(function(match) {
|
||||
expect(match.length).toBe(4);
|
||||
|
||||
expect(match[2].all(by.css('li')).count()).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('on function pages', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/function/angular.bind');
|
||||
|
||||
var toc = element.all(by.css('toc-container > div > toc-tree'));
|
||||
toc.getText().then(function(text) {
|
||||
expect(text.join('')).toContain('Overview');
|
||||
expect(text.join('')).toContain('Usage');
|
||||
});
|
||||
|
||||
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
|
||||
|
||||
tocFirstLevel.then(function(match) {
|
||||
expect(match.length).toBe(2);
|
||||
|
||||
expect(match[1].all(by.css('li')).count()).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
it('on type pages', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/type/ModelOptions');
|
||||
|
||||
var toc = element.all(by.css('toc-container > div > toc-tree'));
|
||||
toc.getText().then(function(text) {
|
||||
expect(text.join('')).toContain('Overview');
|
||||
expect(text.join('')).toContain('Methods');
|
||||
});
|
||||
|
||||
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
|
||||
|
||||
tocFirstLevel.then(function(match) {
|
||||
expect(match.length).toBe(2);
|
||||
|
||||
expect(match[1].all(by.css('li')).count()).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
it('on filter pages', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/filter/date');
|
||||
|
||||
var toc = element.all(by.css('toc-container > div > toc-tree'));
|
||||
toc.getText().then(function(text) {
|
||||
expect(text.join('')).toContain('Overview');
|
||||
expect(text.join('')).toContain('Usage');
|
||||
});
|
||||
|
||||
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
|
||||
|
||||
tocFirstLevel.then(function(match) {
|
||||
expect(match.length).toBe(3);
|
||||
|
||||
expect(match[1].all(by.css('li')).count()).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
it('on guide pages', function() {
|
||||
browser.get('build/docs/index.html#!/guide/services');
|
||||
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
|
||||
|
||||
tocFirstLevel.then(function(match) {
|
||||
expect(match.length).toBe(5);
|
||||
|
||||
expect(match[1].all(by.css('li')).count()).toBe(3);
|
||||
});
|
||||
});
|
||||
});
|
||||
+132
-2
@@ -1,7 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('directives', [])
|
||||
var directivesModule = angular.module('directives', []);
|
||||
|
||||
directivesModule
|
||||
/**
|
||||
* backToTop Directive
|
||||
* @param {Function} $anchorScroll
|
||||
@@ -47,4 +48,133 @@ angular.module('directives', [])
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
})
|
||||
|
||||
.directive('tocCollector', ['$rootScope', function($rootScope) {
|
||||
return {
|
||||
controller: ['$element', function($element) {
|
||||
/* eslint-disable no-invalid-this */
|
||||
var ctrl = this;
|
||||
|
||||
$rootScope.$on('$includeContentRequested', function() {
|
||||
ctrl.hs = [];
|
||||
ctrl.root = [];
|
||||
});
|
||||
|
||||
this.hs = [];
|
||||
this.root = [];
|
||||
this.element = $element;
|
||||
|
||||
this.register = function(h) {
|
||||
var previousLevel;
|
||||
|
||||
for (var i = ctrl.hs.length - 1; i >= 0; i--) {
|
||||
if (ctrl.hs[i].level === (h.level - 1)) {
|
||||
previousLevel = ctrl.hs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (previousLevel) {
|
||||
previousLevel.children.push(h);
|
||||
} else {
|
||||
this.root.push(h);
|
||||
}
|
||||
|
||||
ctrl.hs.push(h);
|
||||
/* eslint-enable no-invalid-this */
|
||||
};
|
||||
}]
|
||||
};
|
||||
}])
|
||||
|
||||
.component('tocTree', {
|
||||
template: '<ul>' +
|
||||
'<li ng-repeat="item in $ctrl.items">' +
|
||||
'<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: '<'
|
||||
}
|
||||
})
|
||||
.directive('tocContainer', function() {
|
||||
return {
|
||||
scope: true,
|
||||
restrict: 'E',
|
||||
require: {
|
||||
tocContainer: '',
|
||||
tocCollector: '^^'
|
||||
},
|
||||
controller: function() {
|
||||
this.showToc = true;
|
||||
this.items = [];
|
||||
},
|
||||
controllerAs: '$ctrl',
|
||||
link: function(scope, element, attrs, ctrls) {
|
||||
ctrls.tocContainer.items = ctrls.tocCollector.root;
|
||||
},
|
||||
template: '<div ng-if="::$ctrl.items.length > 1">' +
|
||||
'<b>Contents</b>' +
|
||||
'<button class="btn" ng-click="$ctrl.showToc = !$ctrl.showToc">{{$ctrl.showToc ? \'Hide\' : \'Show\'}}</button><br>' +
|
||||
'<toc-tree items="$ctrl.items" ng-show="$ctrl.showToc"></toc-tree>' +
|
||||
'</div>'
|
||||
};
|
||||
})
|
||||
.directive('header', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
controller: ['$element', function($element) {
|
||||
// eslint-disable-next-line no-invalid-this
|
||||
this.element = $element;
|
||||
}]
|
||||
};
|
||||
})
|
||||
.directive('h1', ['$compile', function($compile) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
require: {
|
||||
tocCollector: '^^?',
|
||||
header: '^^?'
|
||||
},
|
||||
link: function(scope, element, attrs, ctrls) {
|
||||
if (!ctrls.tocCollector) return;
|
||||
|
||||
var tocContainer = angular.element('<toc-container></toc-container>');
|
||||
var containerElement = ctrls.header ? ctrls.header.element : element;
|
||||
|
||||
containerElement.after(tocContainer);
|
||||
$compile(tocContainer)(scope);
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
for (var i = 2; i <= 5; i++) {
|
||||
registerHDirective(i);
|
||||
}
|
||||
|
||||
function registerHDirective(i) {
|
||||
directivesModule.directive('h' + i, function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
require: {
|
||||
'tocCollector': '^^?'
|
||||
},
|
||||
link: function(scope, element, attrs, ctrls) {
|
||||
var toc = ctrls.tocCollector;
|
||||
|
||||
if (!toc || !attrs.id) return;
|
||||
|
||||
toc.register({
|
||||
level: i,
|
||||
fragment: attrs.id,
|
||||
title: element.text(),
|
||||
children: []
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,12 @@ angular.module('search', [])
|
||||
clearResults();
|
||||
$scope.q = '';
|
||||
};
|
||||
|
||||
$scope.handleResultClicked = function($event) {
|
||||
if ($event.which === 1 && !$event.ctrlKey && !$event.metaKey) {
|
||||
$scope.hideResults();
|
||||
}
|
||||
};
|
||||
}])
|
||||
|
||||
|
||||
|
||||
@@ -12,10 +12,16 @@ angular.module('versions', ['currentVersionData', 'allVersionsData'])
|
||||
/** @this VersionPickerController */
|
||||
function VersionPickerController($location, $window, CURRENT_NG_VERSION, ALL_NG_VERSIONS) {
|
||||
|
||||
var versionStr = CURRENT_NG_VERSION.isSnapshot ? 'snapshot' : CURRENT_NG_VERSION.version;
|
||||
var versionStr = CURRENT_NG_VERSION.version;
|
||||
|
||||
if (CURRENT_NG_VERSION.isSnapshot) {
|
||||
versionStr = CURRENT_NG_VERSION.distTag === 'latest' ? 'snapshot-stable' : 'snapshot';
|
||||
}
|
||||
|
||||
this.versions = ALL_NG_VERSIONS;
|
||||
this.selectedVersion = find(ALL_NG_VERSIONS, function(value) { return value.version.version === versionStr; });
|
||||
this.selectedVersion = find(ALL_NG_VERSIONS, function(value) {
|
||||
return value.version.version === versionStr;
|
||||
});
|
||||
|
||||
this.jumpToDocsVersion = function(value) {
|
||||
var currentPagePath = $location.path().replace(/\/$/, '');
|
||||
|
||||
@@ -1,40 +1,50 @@
|
||||
'use strict';
|
||||
|
||||
describe('code', function() {
|
||||
var prettyPrintOne, oldPP;
|
||||
describe('directives', function() {
|
||||
var compile, scope;
|
||||
|
||||
var any = jasmine.any;
|
||||
|
||||
beforeEach(module('directives'));
|
||||
|
||||
beforeEach(inject(function($rootScope, $compile) {
|
||||
// Provide stub for pretty print function
|
||||
oldPP = window.prettyPrintOne;
|
||||
prettyPrintOne = window.prettyPrintOne = jasmine.createSpy();
|
||||
beforeEach(module(function($compileProvider) {
|
||||
$compileProvider.debugInfoEnabled(false);
|
||||
}));
|
||||
|
||||
beforeEach(inject(function($rootScope, $compile) {
|
||||
scope = $rootScope.$new();
|
||||
compile = $compile;
|
||||
}));
|
||||
|
||||
afterEach(function() {
|
||||
window.prettyPrintOne = oldPP;
|
||||
});
|
||||
describe('code', function() {
|
||||
var prettyPrintOne, oldPP;
|
||||
var any = jasmine.any;
|
||||
|
||||
beforeEach(function() {
|
||||
// Provide stub for pretty print function
|
||||
oldPP = window.prettyPrintOne;
|
||||
prettyPrintOne = window.prettyPrintOne = jasmine.createSpy();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
window.prettyPrintOne = oldPP;
|
||||
});
|
||||
|
||||
|
||||
it('should pretty print innerHTML', function() {
|
||||
compile('<code>var x;</code>')(scope);
|
||||
expect(prettyPrintOne).toHaveBeenCalledWith('var x;', null, false);
|
||||
it('should pretty print innerHTML', function() {
|
||||
compile('<code>var x;</code>')(scope);
|
||||
expect(prettyPrintOne).toHaveBeenCalledWith('var x;', null, false);
|
||||
});
|
||||
|
||||
it('should allow language declaration', function() {
|
||||
compile('<code class="lang-javascript"></code>')(scope);
|
||||
expect(prettyPrintOne).toHaveBeenCalledWith(any(String), 'javascript', false);
|
||||
});
|
||||
|
||||
it('supports allow line numbers', function() {
|
||||
compile('<code class="linenum"></code>')(scope);
|
||||
expect(prettyPrintOne).toHaveBeenCalledWith(any(String), null, true);
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow language declaration', function() {
|
||||
compile('<code class="lang-javascript"></code>')(scope);
|
||||
expect(prettyPrintOne).toHaveBeenCalledWith(any(String), 'javascript', false);
|
||||
});
|
||||
|
||||
it('supports allow line numbers', function() {
|
||||
compile('<code class="linenum"></code>')(scope);
|
||||
expect(prettyPrintOne).toHaveBeenCalledWith(any(String), null, true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -47,6 +47,17 @@ module.exports = function generateVersionDocProcessor(gitData) {
|
||||
|
||||
var latestMap = {};
|
||||
|
||||
// When the docs are built on a tagged commit, yarn info won't include the latest release,
|
||||
// so we add it manually based on the local version.json file.
|
||||
var missesCurrentVersion = !currentVersion.isSnapshot && !versions.find(function(version) {
|
||||
return version === currentVersion.version;
|
||||
});
|
||||
|
||||
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;
|
||||
@@ -70,10 +81,25 @@ module.exports = function generateVersionDocProcessor(gitData) {
|
||||
})
|
||||
.reverse();
|
||||
|
||||
// List the latest version for each branch
|
||||
var latest = sortObject(latestMap, reverse(semver.compare))
|
||||
.map(function(version) { return makeOption(version, 'Latest'); });
|
||||
|
||||
return [makeOption({version: 'snapshot'}, 'Latest', 'master')]
|
||||
// Generate master and stable snapshots
|
||||
var snapshots = [
|
||||
makeOption(
|
||||
{version: 'snapshot'},
|
||||
'Latest',
|
||||
'master-snapshot'
|
||||
),
|
||||
makeOption(
|
||||
{version: 'snapshot-stable'},
|
||||
'Latest',
|
||||
createSnapshotStableLabel(highestStableRelease)
|
||||
)
|
||||
];
|
||||
|
||||
return snapshots
|
||||
.concat(latest)
|
||||
.concat(versions);
|
||||
}
|
||||
@@ -103,6 +129,18 @@ module.exports = function generateVersionDocProcessor(gitData) {
|
||||
function sortObject(obj, cmp) {
|
||||
return Object.keys(obj).map(function(key) { return obj[key]; }).sort(cmp);
|
||||
}
|
||||
|
||||
// https://github.com/kaelzhang/node-semver-stable/blob/34dd29842409295d49889d45871bec55a992b7f6/index.js#L25
|
||||
function semverIsStable(version) {
|
||||
var semverObj = semver.parse(version);
|
||||
return semverObj === null ? false : !semverObj.prerelease.length;
|
||||
}
|
||||
|
||||
function createSnapshotStableLabel(version) {
|
||||
var label = 'v' + version.replace(/.$/, 'x') + '-snapshot';
|
||||
|
||||
return label;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -30,8 +30,8 @@ module.exports = function debugDeployment(getVersion) {
|
||||
],
|
||||
stylesheets: [
|
||||
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.css',
|
||||
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
|
||||
'css/prettify-theme.css',
|
||||
'css/angular-topnav.css',
|
||||
'css/docs.css',
|
||||
'css/animations.css'
|
||||
]
|
||||
|
||||
@@ -17,7 +17,7 @@ module.exports = function defaultDeployment(getVersion) {
|
||||
'../angular-sanitize.min.js',
|
||||
'../angular-touch.min.js',
|
||||
'../angular-animate.min.js',
|
||||
'components/marked-' + getVersion('marked') + '/lib/marked.js',
|
||||
'components/marked-' + getVersion('marked') + '/marked.min.js',
|
||||
'js/angular-bootstrap/dropdown-toggle.min.js',
|
||||
'components/lunr-' + getVersion('lunr') + '/lunr.min.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
|
||||
@@ -30,8 +30,8 @@ module.exports = function defaultDeployment(getVersion) {
|
||||
],
|
||||
stylesheets: [
|
||||
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.min.css',
|
||||
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
|
||||
'css/prettify-theme.css',
|
||||
'css/angular-topnav.css',
|
||||
'css/docs.css',
|
||||
'css/animations.css'
|
||||
]
|
||||
|
||||
+1
-1
@@ -34,8 +34,8 @@ module.exports = function jqueryDeployment(getVersion) {
|
||||
],
|
||||
stylesheets: [
|
||||
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.min.css',
|
||||
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
|
||||
'css/prettify-theme.css',
|
||||
'css/angular-topnav.css',
|
||||
'css/docs.css',
|
||||
'css/animations.css'
|
||||
]
|
||||
|
||||
@@ -7,24 +7,25 @@ var angularCodeUrl = '//code.angularjs.org/';
|
||||
|
||||
var cdnUrl = googleCdnUrl + versionInfo.cdnVersion;
|
||||
|
||||
// The plnkr examples must use the code.angularjs.org repo for the snapshot,
|
||||
// and the cdn for the tagged version and, if the build is not tagged, the currentVersion.
|
||||
//
|
||||
// The currentVersion may not be available on the cdn (e.g. if built locally, or hasn't been pushed
|
||||
// yet). This will lead to a 404, but this is preferable to loading a version with which the example
|
||||
// might not work (possibly in subtle ways).
|
||||
var examplesCdnUrl = versionInfo.currentVersion.isSnapshot ?
|
||||
(angularCodeUrl + 'snapshot') :
|
||||
(googleCdnUrl + (versionInfo.currentVersion.version || versionInfo.currentVersion));
|
||||
// The "examplesDependencyPath" here applies to the examples when they are opened in plnkr.co.
|
||||
// The embedded examples instead always include the files from the *default* deployment,
|
||||
// to ensure that the source files are always available.
|
||||
// The plnkr examples must always use the code.angularjs.org source files.
|
||||
// We cannot rely on the CDN files here, because they are not deployed by the time
|
||||
// docs.angularjs.org and code.angularjs.org need them.
|
||||
var versionPath = versionInfo.currentVersion.isSnapshot ?
|
||||
'snapshot' :
|
||||
(versionInfo.currentVersion.version || versionInfo.currentVersion.version);
|
||||
var examplesDependencyPath = angularCodeUrl + versionPath + '/';
|
||||
|
||||
module.exports = function productionDeployment(getVersion) {
|
||||
return {
|
||||
name: 'production',
|
||||
examples: {
|
||||
commonFiles: {
|
||||
scripts: [examplesCdnUrl + '/angular.min.js']
|
||||
scripts: [examplesDependencyPath + 'angular.min.js']
|
||||
},
|
||||
dependencyPath: examplesCdnUrl + '/'
|
||||
dependencyPath: examplesDependencyPath
|
||||
},
|
||||
scripts: [
|
||||
cdnUrl + '/angular.min.js',
|
||||
@@ -34,7 +35,7 @@ module.exports = function productionDeployment(getVersion) {
|
||||
cdnUrl + '/angular-sanitize.min.js',
|
||||
cdnUrl + '/angular-touch.min.js',
|
||||
cdnUrl + '/angular-animate.min.js',
|
||||
'components/marked-' + getVersion('marked') + '/lib/marked.js',
|
||||
'components/marked-' + getVersion('marked') + '/marked.min.js',
|
||||
'js/angular-bootstrap/dropdown-toggle.min.js',
|
||||
'components/lunr-' + getVersion('lunr') + '/lunr.min.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
|
||||
@@ -47,8 +48,8 @@ module.exports = function productionDeployment(getVersion) {
|
||||
],
|
||||
stylesheets: [
|
||||
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.min.css',
|
||||
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
|
||||
'css/prettify-theme.css',
|
||||
'css/angular-topnav.css',
|
||||
'css/docs.css',
|
||||
'css/animations.css'
|
||||
]
|
||||
|
||||
@@ -4,14 +4,13 @@ var path = require('canonical-path');
|
||||
/**
|
||||
* dgService getVersion
|
||||
* @description
|
||||
* Find the current version of the bower component (or node module)
|
||||
* Find the current version of the node module
|
||||
*/
|
||||
module.exports = function getVersion(readFilesProcessor) {
|
||||
var basePath = readFilesProcessor.basePath;
|
||||
var sourceFolder = path.resolve(readFilesProcessor.basePath, 'node_modules');
|
||||
var packageFile = 'package.json';
|
||||
|
||||
return function(component, sourceFolder, packageFile) {
|
||||
sourceFolder = path.resolve(basePath, sourceFolder || 'node_modules');
|
||||
packageFile = packageFile || 'package.json';
|
||||
return require(path.join(sourceFolder,component,packageFile)).version;
|
||||
return function(component) {
|
||||
return require(path.join(sourceFolder, component, packageFile)).version;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<pre class="minerr-errmsg" error-display="{$ doc.formattedErrorMessage $}">{$ doc.formattedErrorMessage $}</pre>
|
||||
</div>
|
||||
|
||||
<h2>Description</h2>
|
||||
<h2 id="description">Description</h2>
|
||||
<div class="description">
|
||||
{$ doc.description | marked $}
|
||||
</div>
|
||||
|
||||
@@ -68,101 +68,96 @@
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<body class="homepage">
|
||||
<div id="wrapper">
|
||||
<header scroll-y-offset-element class="header header-fixed">
|
||||
<section class="navbar navbar-inverse docs-navbar-primary" ng-controller="DocsSearchCtrl">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-9 header-branding">
|
||||
<a class="brand navbar-brand" href="http://angularjs.org">
|
||||
<img width="117" height="30" class="logo" alt="Link to Angular JS Homepage" ng-src="img/angularjs-for-header-only.svg">
|
||||
</a>
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="divider-vertical"></li>
|
||||
<li><a href="http://angularjs.org"><i class="icon-home icon-white"></i> Home</a></li>
|
||||
<li class="divider-vertical"></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="icon-eye-open icon-white"></i> Learn <b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li class="disabled"><a href="http://angularjs.org/">Why AngularJS?</a></li>
|
||||
<li><a href="http://www.youtube.com/user/angularjs">Watch</a></li>
|
||||
<li><a href="tutorial">Tutorial</a></li>
|
||||
<li><a href="https://www.madewithangular.com/">Case Studies</a></li>
|
||||
<li><a href="https://github.com/angular/angular-seed">Seed App project template</a></li>
|
||||
<li><a href="misc/faq">FAQ</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="divider-vertical"></li>
|
||||
<li class="dropdown active">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="icon-book icon-white"></i> Develop <b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="tutorial">Tutorial</a></li>
|
||||
<li><a href="guide">Developer Guide</a></li>
|
||||
<li><a href="api">API Reference</a></li>
|
||||
<li><a href="error">Error Reference</a></li>
|
||||
<li><a href="misc/contribute">Contribute</a></li>
|
||||
<li><a href="http://code.angularjs.org/">Download</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="divider-vertical"></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="icon-comment icon-white"></i> Discuss <b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://blog.angularjs.org">Blog</a></li>
|
||||
<li><a href="http://groups.google.com/group/angular">Mailing List</a></li>
|
||||
<li><a href="http://webchat.freenode.net/?channels=angularjs&uio=d4">Chat Room</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="https://twitter.com/#!/angularjs">Twitter</a></li>
|
||||
<li><a href="https://plus.google.com/110323587230527980117">Google+</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="https://github.com/angular/angular.js">GitHub</a></li>
|
||||
<li><a href="https://github.com/angular/angular.js/issues">Issue Tracker</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="divider-vertical"></li>
|
||||
</ul>
|
||||
</div>
|
||||
<form ng-class="{focus:focus}" class="navbar-search col-md-3 docs-search" ng-submit="submit()">
|
||||
<span class="glyphicon glyphicon-search search-icon"></span>
|
||||
<input type="text"
|
||||
name="as_q"
|
||||
class="search-query"
|
||||
placeholder="Click or press / to search"
|
||||
ng-focus="focus=true"
|
||||
ng-blur="focus=false"
|
||||
ng-change="search(q)"
|
||||
ng-model="q"
|
||||
docs-search-input
|
||||
autocomplete="off" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-results-container" ng-show="hasResults">
|
||||
<header class="header">
|
||||
<nav id="navbar-main" class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner" ng-controller="DocsSearchCtrl">
|
||||
<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">
|
||||
<h4 class="search-results-group-heading">{{ key }}</h4>
|
||||
<ul class="search-results">
|
||||
<!-- Do not insert a line break between li and a. Chrome will insert an actual line-break, which breaks the list item view.
|
||||
TODO: use a html minifier instead -->
|
||||
<li ng-repeat="item in value" class="search-result"><a ng-click="hideResults()" ng-href="{{ item.path }}">{{ item.name }}</a></li>
|
||||
<h1 class="brand"><a href="http://angularjs.org"><img width="117" height="30" src="img/angularjs-for-header-only.svg" alt="AngularJS"></a></h1>
|
||||
|
||||
<form class="navbar-search" ng-submit="submit()">
|
||||
<i class="glyphicon glyphicon-search search-icon"></i>
|
||||
<input type="text" name="as_q" class="search-query" placeholder="SEARCH"
|
||||
ng-focus="focus=true"
|
||||
ng-blur="focus=false"
|
||||
ng-change="search(q)"
|
||||
ng-model="q"
|
||||
ng-model-options="{debounce: 150}"
|
||||
docs-search-input
|
||||
autocomplete="off">
|
||||
</form>
|
||||
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="dropdown" uib-dropdown>
|
||||
<a href="#" class="dropdown-toggle" uib-dropdown-toggle>Learn</a>
|
||||
<ul class="dropdown-menu" uib-dropdown-menu>
|
||||
<li><a href="tutorial">Tutorial</a></li>
|
||||
<li><a href="misc/faq">FAQ</a></li>
|
||||
<li><a href="https://www.youtube.com/user/angularjs">Videos</a></li>
|
||||
<li><a href="http://angular.codeschool.com/">Free Course</a></li>
|
||||
<li><a href="https://www.madewithangular.com/">Case Studies</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown" uib-dropdown>
|
||||
<a href="#" class="dropdown-toggle" uib-dropdown-toggle>Develop</a>
|
||||
<ul class="dropdown-menu" uib-dropdown-menu>
|
||||
<li><a href="guide">Developer Guide</a></li>
|
||||
<li><a href="api">API Reference</a></li>
|
||||
<li><a href="error">Error Reference</a></li>
|
||||
<li><a href="misc/contribute">Contribute</a></li>
|
||||
<li><a href="https://github.com/angular/angular-seed">Seed App project template</a></li>
|
||||
<li><a href="https://github.com/angular/angular.js">GitHub</a></li>
|
||||
<li><a href="https://github.com/angular/angular.js/blob/master/CHANGELOG.md">Changelog</a></li>
|
||||
<li><a href="http://code.angularjs.org/">Download</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown" uib-dropdown>
|
||||
<a href="#" class="dropdown-toggle" uib-dropdown-toggle>Discuss</a>
|
||||
<ul class="dropdown-menu" uib-dropdown-menu>
|
||||
<li><a href="http://blog.angularjs.org">Blog</a></li>
|
||||
<li><a href="https://twitter.com/angular">Twitter</a></li>
|
||||
<li><a href="https://plus.google.com/110323587230527980117">Google+</a></li>
|
||||
<li><a href="https://github.com/angular/angular.js/issues">Feature & Bug Tracker</a></li>
|
||||
<li><a href="http://groups.google.com/group/angular">Mailing List</a></li>
|
||||
<li><a href="http://webchat.freenode.net/?channels=angularjs&uio=d4">IRC</a></li>
|
||||
<li><a href="https://gitter.im/angular/angular.js">Gitter</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<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">
|
||||
<h4 class="search-results-group-heading">{{ key }}</h4>
|
||||
<ul class="search-results">
|
||||
<li ng-repeat="item in value" class="search-result"><a ng-click="handleResultClicked($event)" ng-href="{{ item.path }}">{{ item.name }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<a href="" ng-click="hideResults()" class="search-close">
|
||||
<span class="glyphicon glyphicon-remove search-close-icon"></span> Close
|
||||
</a>
|
||||
</div>
|
||||
<a href="" ng-click="hideResults()" class="search-close">
|
||||
<span class="glyphicon glyphicon-remove search-close-icon"></span> Close
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="sup-header">
|
||||
</nav>
|
||||
<nav id="navbar-notice" class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<p class="site-notice visible-phone">
|
||||
This site refers to AngularJS (v1.x). <a href="https://angular.io/">Go to the latest Angular</a>.
|
||||
</p>
|
||||
<p class="site-notice visible-desktop">
|
||||
This site and all of its contents are referring to AngularJS (version 1.x),
|
||||
if you are looking for the latest Angular, please visit <a href="https://angular.io/">angular.io</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<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>
|
||||
@@ -176,7 +171,7 @@
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<section role="main" class="container main-body">
|
||||
@@ -204,7 +199,7 @@
|
||||
</div>
|
||||
<div class="grid-right">
|
||||
<div id="loading" ng-show="loading">Loading...</div>
|
||||
<div ng-hide="loading" ng-include="partialPath" autoscroll></div>
|
||||
<div ng-hide="loading" ng-include="partialPath" toc-collector autoscroll></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -214,10 +209,10 @@
|
||||
<p class="pull-right"><a back-to-top>Back to top</a></p>
|
||||
|
||||
<p>
|
||||
Super-powered by Google ©2010-2017
|
||||
Super-powered by Google ©2010-2018
|
||||
(<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 Angular JS">
|
||||
ng-bind-template="v{{version}}" title="Changelog of this version of AngularJS">
|
||||
</a>)
|
||||
</p>
|
||||
<p>
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
{% block description %}
|
||||
<div class="api-profile-description">
|
||||
<h2 id="overview">Overview</h2>
|
||||
{$ doc.description | marked $}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -51,7 +52,7 @@
|
||||
|
||||
{% block examples %}
|
||||
{%- if doc.examples %}
|
||||
<h2 id="example">Examples</h2>
|
||||
<h2 id="examples">{$ "Examples" if doc.examples | length > 1 else "Example" $}</h2>
|
||||
{%- for example in doc.examples -%}
|
||||
{$ example | marked $}
|
||||
{%- endfor -%}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{% extends "api/api.template.html" %}
|
||||
|
||||
{% block additional %}
|
||||
<h2>Directive Info</h2>
|
||||
<h2 id="{$ doc.name $}-info">Directive Info</h2>
|
||||
<ul>
|
||||
{% if doc.scope %}<li>This directive creates new scope.</li>{% endif %}
|
||||
<li>This directive executes at priority level {$ doc.priority $}.</li>
|
||||
@@ -18,9 +18,6 @@
|
||||
<ul>
|
||||
{% if doc.restrict.element %}
|
||||
<li>as element:
|
||||
{% if doc.name.indexOf('ng') == 0 -%}
|
||||
(This directive can be used as custom element, but be aware of <a href="guide/ie">IE restrictions</a>).
|
||||
{%- endif %}
|
||||
{% code %}
|
||||
<{$ doc.name | dashCase $}
|
||||
{%- for param in doc.params %}
|
||||
@@ -32,10 +29,23 @@
|
||||
</li>
|
||||
{% endif -%}
|
||||
|
||||
|
||||
{% set hasNameAsParam = false %}
|
||||
|
||||
{# when a directive's name is not a parameter (i.e. doesn't take a value),
|
||||
add the directive name to the list of attributes and/or css classes #}
|
||||
|
||||
{%- for param in doc.params %}
|
||||
{% set hasNameAsParam = true if param.name === doc.name else hasNameAsParam %}
|
||||
{%- endfor %}
|
||||
|
||||
{%- if doc.restrict.attribute -%}
|
||||
<li>as attribute:
|
||||
{% code %}
|
||||
<{$ doc.element $}
|
||||
{%- if not hasNameAsParam %}
|
||||
{$ lib.directiveParam(doc.name, {}, '', '') $}
|
||||
{%- endif -%}
|
||||
{%- for param in doc.params %}
|
||||
{$ lib.directiveParam(param.name, param.type, '="', '"') $}
|
||||
{%- endfor %}>
|
||||
@@ -46,10 +56,14 @@
|
||||
{% endif -%}
|
||||
|
||||
{%- if doc.restrict.cssClass -%}
|
||||
|
||||
<li>as CSS class:
|
||||
{% code %}
|
||||
{% set sep = joiner(' ') %}
|
||||
<{$ doc.element $} class="
|
||||
{%- if not hasNameAsParam -%}
|
||||
{$ sep() $}{$ lib.directiveParam(doc.name, {}, '', '') $}
|
||||
{%- endif -%}
|
||||
{%- for param in doc.params -%}
|
||||
{$ sep() $}{$ lib.directiveParam(param.name, param.type, ': ', ';') $}
|
||||
{%- endfor %}"> ... </{$ doc.element $}>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{% extends "api/api.template.html" %}
|
||||
|
||||
{% block additional %}
|
||||
<h2>Usage</h2>
|
||||
<h2 id="usage">Usage</h2>
|
||||
<h3>In HTML Template Binding</h3>
|
||||
{% if doc.usage %}
|
||||
{$ doc.usage | code $}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
{$ x.deprecatedBlock(doc) $}
|
||||
|
||||
<h2>Installation</h2>
|
||||
<h2 id="module-installation">Installation</h2>
|
||||
{% if doc.installation or doc.installation == '' %}
|
||||
{$ doc.installation | marked $}
|
||||
{% else %}
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
{% if doc.componentGroups.length %}
|
||||
<div class="component-breakdown">
|
||||
<h2>Module Components</h2>
|
||||
<h2 id="module-components">Module Components</h2>
|
||||
{% for componentGroup in doc.componentGroups %}
|
||||
<div>
|
||||
<h3 class="component-heading" id="{$ componentGroup.groupType | dashCase $}">{$ componentGroup.groupType | title $}</h3>
|
||||
@@ -98,7 +98,7 @@
|
||||
{% endif %}
|
||||
|
||||
{% if doc.usage %}
|
||||
<h2>Usage</h2>
|
||||
<h2 id="module-usage">Usage</h2>
|
||||
{$ doc.usage | marked $}
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
{% import "lib/deprecated.html" as x -%}
|
||||
|
||||
{%- if doc.events %}
|
||||
<h2>Events</h2>
|
||||
<h2 id="events">Events</h2>
|
||||
<ul class="events">
|
||||
{%- for event in doc.events %}
|
||||
<li id="{$ event.name $}">
|
||||
<h3>{$ event.name $}</h3>
|
||||
<h3 id="event-{$ event.name $}">{$ event.name $}</h3>
|
||||
<div>{$ event.description | marked $}</div>
|
||||
|
||||
{$ x.deprecatedBlock(event) $}
|
||||
@@ -27,7 +27,7 @@
|
||||
{% endif -%}
|
||||
{%- if event.params %}
|
||||
<section class="api-section">
|
||||
<h3>Parameters</h3>
|
||||
<h4>Parameters</h4>
|
||||
{$ lib.paramTable(event.params) $}
|
||||
</section>
|
||||
{%- endif -%}
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
{% import "lib/deprecated.html" as x -%}
|
||||
|
||||
{%- if doc.methods %}
|
||||
<h2>Methods</h2>
|
||||
<h2 id="{$ doc.name $}-methods">Methods</h2>
|
||||
<ul class="methods">
|
||||
{%- for method in doc.methods %}
|
||||
<li id="{$ method.name $}">
|
||||
<h3>{$ lib.functionSyntax(method) $}</h3>
|
||||
<li>
|
||||
<h3 id="{$ method.name $}">{$ lib.functionSyntax(method) $}</h3>
|
||||
<div>{$ method.description | marked $}</div>
|
||||
|
||||
{$ x.deprecatedBlock(method) $}
|
||||
@@ -27,7 +27,7 @@
|
||||
{% endif %}
|
||||
|
||||
{%- if method.examples %}
|
||||
<h4 id="{$ doc.name $}.{$ method.name $}-examples">Examples</h4>
|
||||
<h4 id="{$ doc.name $}.{$ method.name $}-examples">{$ "Examples" if method.examples | length > 1 else "Example" $}</h4>
|
||||
{%- for example in method.examples -%}
|
||||
{$ example | marked $}
|
||||
{%- endfor -%}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% import "lib/macros.html" as lib -%}
|
||||
{%- if doc.params %}
|
||||
<section class="api-section">
|
||||
<h3>Arguments</h3>
|
||||
<h3 id="{$ doc.name $}-arguments">Arguments</h3>
|
||||
{$ lib.paramTable(doc.params) $}
|
||||
</section>
|
||||
{%- endif -%}
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
{% import "lib/deprecated.html" as x -%}
|
||||
|
||||
{%- if doc.properties %}
|
||||
<h2>Properties</h2>
|
||||
<h2 id="{$ doc.name $}-properties">Properties</h2>
|
||||
<ul class="properties">
|
||||
{%- for property in doc.properties %}
|
||||
<li id="{$ property.name $}">
|
||||
<h3>{$ property.name | code $}</h3>
|
||||
<li>
|
||||
<h3 id="{$ property.name $}">{$ property.name | code $}</h3>
|
||||
{$ lib.typeInfo(property) $}
|
||||
{$ x.deprecatedBlock(property) $}
|
||||
</li>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% import "lib/macros.html" as lib -%}
|
||||
{% if doc.returns -%}
|
||||
<h3>Returns</h3>
|
||||
<h3 id="{$ doc.name $}-returns">Returns</h3>
|
||||
{$ lib.typeInfo(doc.returns) $}
|
||||
{%- endif %}
|
||||
@@ -11,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">
|
||||
**Angular Prefixes `$` and `$$`**:
|
||||
**AngularJS Prefixes `$` and `$$`**:
|
||||
|
||||
To prevent accidental name collisions with your code,
|
||||
Angular prefixes names of public objects with `$` and names of private objects with `$$`.
|
||||
AngularJS prefixes names of public objects with `$` and names of private objects with `$$`.
|
||||
Please do not use the `$` or `$$` prefix in your code.
|
||||
</div>
|
||||
|
||||
## Angular Modules
|
||||
## AngularJS Modules
|
||||
|
||||
|
||||
## {@link ng ng (core module)}
|
||||
@@ -83,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:
|
||||
@@ -130,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 ng directives will provide
|
||||
Use ngAnimate to enable animation features within your application. Various core AngularJS directives will provide
|
||||
animation hooks into your application when ngAnimate is included. Animations are defined by using CSS transitions/animations
|
||||
or JavaScript callbacks.
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $animate:nocb
|
||||
@fullName Do not pass a callback to animate methods
|
||||
@description
|
||||
|
||||
Since Angular 1.3, the methods of {@link ng.$animate} do not accept a callback as the last parameter.
|
||||
Instead, they return a promise to which you can attach `then` handlers to be run when the animation completes.
|
||||
|
||||
If you are getting this error then you need to update your code to use the promise-based API.
|
||||
|
||||
See https://github.com/angular/angular.js/commit/bf0f5502b1bbfddc5cdd2f138efd9188b8c652a9 for information about
|
||||
the change to the animation API and the changes you need to make.
|
||||
@@ -0,0 +1,8 @@
|
||||
@ngdoc error
|
||||
@name $animate:nongcls
|
||||
@fullName `ng-animate` class not allowed
|
||||
@description
|
||||
|
||||
This error occurs, when trying to set `$animateProvider.classNameFilter()` to a RegExp containing
|
||||
the reserved `ng-animate` class. Since `.ng-animate` will be added/removed by `$animate` itself,
|
||||
using it as part of the `classNameFilter` RegExp is not allowed.
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
This error occurs when the restrict property of a directive is not valid.
|
||||
|
||||
The directive restrict property must be a string including one of more of the following characters:
|
||||
The directive restrict property must be a string including one or more of the following characters:
|
||||
* E (element)
|
||||
* A (attribute)
|
||||
* C (class)
|
||||
@@ -15,4 +15,4 @@ For example:
|
||||
```javascript
|
||||
restrict: 'E'
|
||||
restrict: 'EAC'
|
||||
```
|
||||
```
|
||||
|
||||
@@ -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.
|
||||
Angular detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
|
||||
AngularJS 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:
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
@ngdoc error
|
||||
@name $compile:missingattr
|
||||
@fullName Missing required attribute
|
||||
@description
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,38 @@
|
||||
@ngdoc error
|
||||
@name $compile:noslot
|
||||
@fullName No matching slot in parent directive
|
||||
@description
|
||||
|
||||
This error occurs when declaring a specific slot in a {@link ng.ngTransclude `ngTransclude`}
|
||||
which does not map to a specific slot defined in the transclude property of the directive.
|
||||
|
||||
In this example the template has declared a slot missing from the transclude definition.
|
||||
This example will generate a noslot error.
|
||||
```js
|
||||
var componentConfig = {
|
||||
template: '<div>' +
|
||||
'<div ng-transclude="slotProvided"></div>' +
|
||||
'<div ng-transclude="noSlotProvided"></div>' +
|
||||
'</div>',
|
||||
transclude: {
|
||||
// The key value pairs here are considered "slots" that are provided for components to slot into.
|
||||
slotProvided: 'slottedComponent', // mandatory transclusion
|
||||
// There is no slot provided here for the transclude 'noSlotProvided' declared in the above template.
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
If we make the following change we will no longer get the noslot error.
|
||||
```js
|
||||
var componentConfig = {
|
||||
template: '<div>' +
|
||||
'<div ng-transclude="slotProvided"></div>' +
|
||||
'<div ng-transclude="noSlotProvided"></div>' +
|
||||
'</div>',
|
||||
transclude: {
|
||||
slotProvided: 'slottedComponent',
|
||||
noSlotProvided: 'otherComponent' // now it is declared and the error should cease
|
||||
}
|
||||
};
|
||||
|
||||
```
|
||||
@@ -0,0 +1,14 @@
|
||||
@ngdoc error
|
||||
@name $http:baddata
|
||||
@fullName Bad JSON Data
|
||||
@description
|
||||
|
||||
The default {@link ng.$http#default-transformations `transformResponse`} will try to parse the
|
||||
response as JSON if the `Content-Type` header is `application/json`, or the response looks like a
|
||||
valid JSON-stringified object or array.
|
||||
This error occurs when that data is not a valid JSON object.
|
||||
|
||||
To resolve this error, make sure you pass valid JSON data to `transformResponse`. If the response
|
||||
data looks like JSON, but has a different `Content-Type` header, you must
|
||||
{@link ng.$http#overriding-the-default-transformations-per-request implement your own response
|
||||
transformer on a per request basis}, or {@link ng.$http#default-transformations modify the default `$http` responseTransform}.
|
||||
@@ -11,7 +11,7 @@ value is `JSON_CALLBACK`.
|
||||
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 configuratio of the request.
|
||||
|
||||
In previous versions of Angular, you specified where to add the callback parameter value via the
|
||||
In previous versions of AngularJS, 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 Angular's `ng` module
|
||||
### Monkey-patching AngularJS'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 Angular expression is missing the corresponding closing operator.
|
||||
The AngularJS 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 Angular i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat AngularJS 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 Angular i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat AngularJS 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 Angular i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
@description
|
||||
|
||||
You must specify the MessageFormat function that you're using right after the
|
||||
comma following the Angular expression. Currently, the supported functions are
|
||||
comma following the AngularJS 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 Angular i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat AngularJS 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 Angular i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat AngularJS 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 Angular i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat AngularJS 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 Angular i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat AngularJS 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 Angular i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat AngularJS 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 Angular i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat AngularJS 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 Angular i18n MessageFormat}.
|
||||
guide/i18n#MessageFormat AngularJS i18n MessageFormat}.
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
@fullName Unterminated string literal
|
||||
@description
|
||||
|
||||
The string literal was not terminated in your Angular expression.
|
||||
The string literal was not terminated in your AngularJS expression.
|
||||
|
||||
@@ -40,7 +40,7 @@ URL of the subcontext:
|
||||
</head>
|
||||
```
|
||||
|
||||
Before Angular 1.3 we didn't have this hard requirement and it was easy to write apps that worked
|
||||
Before AngularJS 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:
|
||||
|
||||
@@ -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 Angular expressions}, identify the error and fix the expression's syntax.
|
||||
To resolve, learn more about {@link guide/expression AngularJS expressions}, identify the error and fix the expression's syntax.
|
||||
|
||||
@@ -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 Angular expressions}, identify the error and fix the expression's syntax.
|
||||
To resolve, learn more about {@link guide/expression AngularJS 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 Angular expressions}, identify the error and
|
||||
To resolve, learn more about {@link guide/expression AngularJS 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.
|
||||
Angular detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
|
||||
AngularJS 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, Angular determines that the model is different on each `$digest`
|
||||
Since `getUsers()` returns a new array, AngularJS 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
|
||||
|
||||
Angular uses a dirty-checking digest mechanism to monitor and update values of the scope during
|
||||
AngularJS 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 Angular application code
|
||||
application, such as mouse events, timeouts or server responses, wrap the AngularJS application code
|
||||
in a block of code that will run `$digest` when the code completes.
|
||||
|
||||
You wrap Angular code in a block that will be followed by a `$digest` by calling `$apply` on a scope
|
||||
You wrap AngularJS 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
|
||||
|
||||
Angular keeps track of what phase of processing we are in, the relevant ones being `$apply` and
|
||||
AngularJS 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 Angular will throw this error when
|
||||
typically a sign of programming error that needs to be fixed. So AngularJS 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 Angular scope or services, in a call to
|
||||
case you should wrap any code that will be interacting with AngularJS scope or services, in a call to
|
||||
`$apply`.
|
||||
|
||||
As an example, all Controller code should expect to be run within Angular, so it should have no need
|
||||
As an example, all Controller code should expect to be run within AngularJS, 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 Angular, and so any Angular application code that it calls should first be wrapped in a call
|
||||
within AngularJS, and so any AngularJS 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 Angular. Therefore, we
|
||||
correctly wrap our application code that interacts with Angular in a call to `$apply`.
|
||||
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`.
|
||||
|
||||
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 Angular), which is normally called by an external trigger.
|
||||
programmatically (from within AngularJS), 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 Angular not to wrap this `fn` in an
|
||||
by using `$timeout(fn, 0, false)`, where the `false` value tells AngularJS 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 Angular directive then it is likely that it matches the second
|
||||
* If the second call was made inside an AngularJS 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 Angular code is minified) that there were two calls to `$apply`, first
|
||||
We can see (even though the AngularJS 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 Angular directive.
|
||||
this call is made by an AngularJS 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 Angular processing model please check out the
|
||||
To learn more about AngularJS processing model please check out the
|
||||
{@link guide/concepts concepts doc} as well as the {@link ng.$rootScope.Scope api} doc.
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
@ngdoc error
|
||||
@name $sanitize:elclob
|
||||
@fullName Failed to sanitize html because the element is clobbered
|
||||
@description
|
||||
|
||||
This error occurs when `$sanitize` sanitizer is unable to traverse the HTML because one or more of the elements in the
|
||||
HTML have been "clobbered". This could be a sign that the payload contains code attempting to cause a DoS attack on the
|
||||
browser.
|
||||
|
||||
Typically clobbering breaks the `nextSibling` property on an element so that it points to one of its child nodes. This
|
||||
makes it impossible to walk the HTML tree without getting stuck in an infinite loop, which causes the browser to freeze.
|
||||
@@ -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 Angular'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 AngularJS'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 Angular template from an untrusted source.
|
||||
Typically, this would occur if you're attempting to load an AngularJS template from an untrusted source.
|
||||
It's also possible that a custom directive threw this error for a similar reason.
|
||||
|
||||
Angular only loads templates from trusted URLs (by calling {@link ng.$sce#getTrustedResourceUrl $sce.getTrustedResourceUrl} on the template URL).
|
||||
AngularJS 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.
|
||||
|
||||
Angular's {@link ng.$sce Strict Contextual Escaping (SCE)} mode
|
||||
AngularJS'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
|
||||
Angular template from a URL requires that the URL is one considered safe for loading resources.)
|
||||
AngularJS 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)}
|
||||
|
||||
@@ -3,9 +3,12 @@
|
||||
@fullName Unsupported Selector Lookup
|
||||
@description
|
||||
|
||||
In order to keep Angular small, Angular implements only a subset of the selectors in {@link angular.element#angular-s-jqlite jqLite}.
|
||||
In order to keep AngularJS small, AngularJS implements only a subset of the selectors in
|
||||
{@link angular.element#angularjs-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.
|
||||
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 Angular will automatically use and that will make all selectors available.
|
||||
Alternatively, you can include a full version of jQuery, which AngularJS will automatically use
|
||||
and that will make all selectors available.
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
@ngdoc error
|
||||
@name ng:aobj
|
||||
@fullName Invalid Argument
|
||||
@description
|
||||
|
||||
The argument passed should be an object. Check the value that was passed to the function where
|
||||
this error was thrown.
|
||||
@@ -3,7 +3,7 @@
|
||||
@fullName Testability Not Found
|
||||
@description
|
||||
|
||||
Angular's testability helper, getTestability, requires a root element to be
|
||||
passed in. This helps differentiate between different Angular apps on the same
|
||||
AngularJS's testability helper, getTestability, requires a root element to be
|
||||
passed in. This helps differentiate between different AngularJS 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.
|
||||
Angular does not set validation errors on the `<input>` in this case
|
||||
AngularJS 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.
|
||||
|
||||
Angular does not set validation errors on the `<input>` in this case
|
||||
AngularJS 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
|
||||
|
||||
@@ -48,7 +48,7 @@ changes to `$location` are reflected into the browser address bar.
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="head">integration with angular application life-cycle</td>
|
||||
<td class="head">integration with AngularJS 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>
|
||||
@@ -224,7 +224,7 @@ facilitate the browser URL change and history management.
|
||||
## Hashbang mode (default mode)
|
||||
|
||||
In this mode, `$location` uses Hashbang URLs in all browsers.
|
||||
Angular also does not intercept and rewrite links in this mode. I.e. links work
|
||||
AngularJS 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.
|
||||
|
||||
@@ -267,7 +267,7 @@ 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, Angular intercepts all links (subject to the "Html link rewriting" rules below)
|
||||
Note that in this mode, AngularJS 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.
|
||||
|
||||
|
||||
@@ -363,7 +363,7 @@ Note that [attribute name normalization](guide/directive#normalization) does not
|
||||
|
||||
### Relative links
|
||||
|
||||
Be sure to check all relative links, images, scripts etc. Angular requires you to specify the url
|
||||
Be sure to check all relative links, images, scripts etc. AngularJS 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
|
||||
@@ -378,7 +378,7 @@ to anchors on the same page without needing to know on which page the user curre
|
||||
|
||||
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 Angular to differentiate between the part of the url that is the application
|
||||
this case, as it allows AngularJS 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
|
||||
@@ -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
|
||||
you server is setup to redirect such requests to `/base/`.
|
||||
your server is setup to redirect such requests to `/base/`.
|
||||
|
||||
See https://github.com/angular/angular.js/issues/14018 for more information.
|
||||
|
||||
@@ -728,14 +728,14 @@ use a lower level API, {@link ng.$window $window.location.href}.
|
||||
|
||||
## Using $location outside of the scope life-cycle
|
||||
|
||||
`$location` knows about Angular's {@link ng.$rootScope.Scope scope} life-cycle. When a URL changes in
|
||||
`$location` knows about AngularJS'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 Angular (for example, through a DOM Event or
|
||||
When you want to change the `$location` from outside AngularJS (for example, through a DOM Event or
|
||||
during testing) - you must call `$apply` to propagate the changes.
|
||||
|
||||
## $location.path() and ! or / prefixes
|
||||
@@ -787,7 +787,7 @@ describe('serviceUnderTest', function() {
|
||||
|
||||
# Migrating from earlier AngularJS releases
|
||||
|
||||
In earlier releases of Angular, `$location` used `hashPath` or `hashSearch` to process path and
|
||||
In earlier releases of AngularJS, `$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.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
# Accessibility with ngAria
|
||||
|
||||
The goal of ngAria is to improve Angular's default accessibility by enabling common
|
||||
The goal of ngAria is to improve AngularJS'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 Angular.
|
||||
Accessibility best practices that apply to web apps in general also apply to AngularJS.
|
||||
|
||||
* **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
|
||||
|
||||
+244
-197
@@ -6,20 +6,26 @@
|
||||
|
||||
# Animations
|
||||
|
||||
AngularJS provides animation hooks for common directives such as `ngRepeat`, `ngSwitch`, and `ngView`, as well as custom directives
|
||||
via the `$animate` service. These animation hooks are set in place to trigger animations during the life cycle of various directives and when
|
||||
triggered, will attempt to perform a CSS Transition, CSS Keyframe Animation or a JavaScript callback Animation (depending on if an animation is
|
||||
placed on the given directive). Animations can be placed using vanilla CSS by following the naming conventions set in place by AngularJS
|
||||
or with JavaScript code when it's defined as a factory.
|
||||
AngularJS provides animation hooks for common directives such as
|
||||
{@link ng.directive:ngRepeat ngRepeat}, {@link ng.directive:ngSwitch ngSwitch}, and
|
||||
{@link ngRoute.directive:ngView ngView}, as well as custom directives via the `$animate` service.
|
||||
These animation hooks are set in place to trigger animations during the life cycle of various
|
||||
directives and when triggered, will attempt to perform a CSS Transition, CSS Keyframe Animation or a
|
||||
JavaScript callback Animation (depending on whether an animation is placed on the given directive).
|
||||
Animations can be placed using vanilla CSS by following the naming conventions set in place by
|
||||
AngularJS or with JavaScript code, defined as a factory.
|
||||
|
||||
<div class="alert alert-info">
|
||||
Note that we have used non-prefixed CSS transition properties in our examples as the major browsers now support non-prefixed
|
||||
properties. If you intend to support older browsers or certain mobile browsers then you will need to include prefixed
|
||||
versions of the transition properties. Take a look at http://caniuse.com/#feat=css-transitions for what browsers require prefixes,
|
||||
and https://github.com/postcss/autoprefixer for a tool that can automatically generate the prefixes for you.
|
||||
Note that we have used non-prefixed CSS transition properties in our examples as the major
|
||||
browsers now support non-prefixed properties. If you intend to support older browsers or certain
|
||||
mobile browsers then you will need to include prefixed versions of the transition properties. Take
|
||||
a look at http://caniuse.com/#feat=css-transitions for what browsers require prefixes, and
|
||||
https://github.com/postcss/autoprefixer for a tool that can automatically generate the prefixes
|
||||
for you.
|
||||
</div>
|
||||
|
||||
Animations are not available unless you include the {@link ngAnimate `ngAnimate` module} as a dependency within your application.
|
||||
Animations are not available unless you include the {@link ngAnimate `ngAnimate` module} as a
|
||||
dependency of your application.
|
||||
|
||||
Below is a quick example of animations being enabled for `ngShow` and `ngHide`:
|
||||
|
||||
@@ -59,8 +65,9 @@ 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 a HTML element within
|
||||
your website, you can apply animations to it. Lets say for example that we have an HTML template with a repeater in it like so:
|
||||
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
|
||||
example that we have an HTML template with a repeater like so:
|
||||
|
||||
```html
|
||||
<div ng-repeat="item in items" class="repeated-item">
|
||||
@@ -68,22 +75,21 @@ your website, you can apply animations to it. Lets say for example that we have
|
||||
</div>
|
||||
```
|
||||
|
||||
As you can see, the `.repeated-item` class is present on the element that will be repeated and this class will be
|
||||
used as a reference within our application's CSS and/or JavaScript animation code to tell AngularJS to perform an animation.
|
||||
As you can see, the `repeated-item` class is present on the element that will be repeated and this
|
||||
class will be used as a reference within our application's CSS and/or JavaScript animation code to
|
||||
tell AngularJS to perform an animation.
|
||||
|
||||
As ngRepeat does its thing, each time a new item is added into the list, ngRepeat will add
|
||||
a `ng-enter` class name to the element that is being added. When removed it will apply a `ng-leave` class name and when moved around
|
||||
it will apply a `ng-move` class name.
|
||||
As `ngRepeat` does its thing, each time a new item is added into the list, `ngRepeat` will add an
|
||||
`ng-enter` class to the element that is being added. When removed it will apply an `ng-leave` class
|
||||
and when moved around it will apply an `ng-move` class.
|
||||
|
||||
Taking a look at the following CSS code, we can see some transition and keyframe animation code set for each of those events that
|
||||
occur when ngRepeat triggers them:
|
||||
Taking a look at the following CSS code, we can see some transition and keyframe animation code set
|
||||
up for each of those events that occur when `ngRepeat` triggers them:
|
||||
|
||||
```css
|
||||
/*
|
||||
We're using CSS transitions for when
|
||||
the enter and move events are triggered
|
||||
for the element that has the .repeated-item
|
||||
class
|
||||
We are using CSS transitions for when the enter and move events
|
||||
are triggered for the element that has the `repeated-item` class
|
||||
*/
|
||||
.repeated-item.ng-enter, .repeated-item.ng-move {
|
||||
transition: all 0.5s linear;
|
||||
@@ -91,10 +97,8 @@ occur when ngRepeat triggers them:
|
||||
}
|
||||
|
||||
/*
|
||||
The ng-enter-active and ng-move-active
|
||||
are where the transition destination properties
|
||||
are set so that the animation knows what to
|
||||
animate.
|
||||
`.ng-enter-active` and `.ng-move-active` are where the transition destination
|
||||
properties are set so that the animation knows what to animate
|
||||
*/
|
||||
.repeated-item.ng-enter.ng-enter-active,
|
||||
.repeated-item.ng-move.ng-move-active {
|
||||
@@ -102,73 +106,64 @@ occur when ngRepeat triggers them:
|
||||
}
|
||||
|
||||
/*
|
||||
We're using CSS keyframe animations for when
|
||||
the leave event is triggered for the element
|
||||
that has the .repeated-item class
|
||||
We are using CSS keyframe animations for when the `leave` event
|
||||
is triggered for the element that has the `repeated-item` class
|
||||
*/
|
||||
.repeated-item.ng-leave {
|
||||
animation: 0.5s my_animation;
|
||||
}
|
||||
|
||||
@keyframes my_animation {
|
||||
from { opacity:1; }
|
||||
to { opacity:0; }
|
||||
from { opacity: 1; }
|
||||
to { opacity: 0; }
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The same approach to animation can be used using JavaScript code (**jQuery is used within to perform animations**):
|
||||
The same approach to animation can be used using JavaScript code
|
||||
(**for simplicity, we rely on jQuery to perform animations here**):
|
||||
|
||||
```js
|
||||
myModule.animation('.repeated-item', function() {
|
||||
return {
|
||||
enter: function(element, done) {
|
||||
element.css('opacity',0);
|
||||
jQuery(element).animate({
|
||||
opacity: 1
|
||||
}, done);
|
||||
// Initialize the element's opacity
|
||||
element.css('opacity', 0);
|
||||
|
||||
// optional onDone or onCancel callback
|
||||
// function to handle any post-animation
|
||||
// cleanup operations
|
||||
// Animate the element's opacity
|
||||
// (`element.animate()` is provided by jQuery)
|
||||
element.animate({opacity: 1}, done);
|
||||
|
||||
// Optional `onDone`/`onCancel` callback function
|
||||
// to handle any post-animation cleanup operations
|
||||
return function(isCancelled) {
|
||||
if(isCancelled) {
|
||||
jQuery(element).stop();
|
||||
if (isCancelled) {
|
||||
// Abort the animation if cancelled
|
||||
// (`element.stop()` is provided by jQuery)
|
||||
element.stop();
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
leave: function(element, done) {
|
||||
// Initialize the element's opacity
|
||||
element.css('opacity', 1);
|
||||
jQuery(element).animate({
|
||||
opacity: 0
|
||||
}, done);
|
||||
|
||||
// optional onDone or onCancel callback
|
||||
// function to handle any post-animation
|
||||
// cleanup operations
|
||||
return function(isCancelled) {
|
||||
if(isCancelled) {
|
||||
jQuery(element).stop();
|
||||
}
|
||||
}
|
||||
},
|
||||
move: function(element, done) {
|
||||
element.css('opacity', 0);
|
||||
jQuery(element).animate({
|
||||
opacity: 1
|
||||
}, done);
|
||||
// Animate the element's opacity
|
||||
// (`element.animate()` is provided by jQuery)
|
||||
element.animate({opacity: 0}, done);
|
||||
|
||||
// optional onDone or onCancel callback
|
||||
// function to handle any post-animation
|
||||
// cleanup operations
|
||||
// Optional `onDone`/`onCancel` callback function
|
||||
// to handle any post-animation cleanup operations
|
||||
return function(isCancelled) {
|
||||
if(isCancelled) {
|
||||
jQuery(element).stop();
|
||||
if (isCancelled) {
|
||||
// Abort the animation if cancelled
|
||||
// (`element.stop()` is provided by jQuery)
|
||||
element.stop();
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
// you can also capture these animation events
|
||||
// We can also capture the following animation events:
|
||||
move: function(element, done) {},
|
||||
addClass: function(element, className, done) {},
|
||||
removeClass: function(element, className, done) {}
|
||||
}
|
||||
@@ -176,74 +171,84 @@ myModule.animation('.repeated-item', function() {
|
||||
```
|
||||
|
||||
With these generated CSS class names present on the element at the time, AngularJS automatically
|
||||
figures out whether to perform a CSS and/or JavaScript animation. If both CSS and JavaScript animation
|
||||
code is present, and match the CSS class name on the element, then AngularJS will run both animations at the same time.
|
||||
figures out whether to perform a CSS and/or JavaScript animation. Note that you can't have both CSS
|
||||
and JavaScript animations based on the same CSS class. See
|
||||
{@link ngAnimate#css-js-animations-together here} for more details.
|
||||
|
||||
## Class and ngClass animation hooks
|
||||
## Class and `ngClass` animation hooks
|
||||
|
||||
AngularJS also pays attention to CSS class changes on elements by triggering the **add** and **remove** hooks.
|
||||
This means that if a CSS class is added to or removed from an element then an animation can be executed in between,
|
||||
before the CSS class addition or removal is finalized. (Keep in mind that AngularJS will only be
|
||||
able to capture class changes if an **expression** or the **ng-class** directive is used on the element.)
|
||||
AngularJS also pays attention to CSS class changes on elements by triggering the **add** and
|
||||
**remove** hooks. This means that if a CSS class is added to or removed from an element then an
|
||||
animation can be executed in between, before the CSS class addition or removal is finalized.
|
||||
(Keep in mind that AngularJS will only be able to capture class changes if an
|
||||
**interpolated expression** or the **ng-class** directive is used on the element.)
|
||||
|
||||
The example below shows how to perform animations during class changes:
|
||||
|
||||
<example module="ngAnimate" deps="angular-animate.js" animations="true" name="animate-css-class">
|
||||
<file name="index.html">
|
||||
<p>
|
||||
<input type="button" value="set" ng-click="myCssVar='css-class'">
|
||||
<input type="button" value="clear" ng-click="myCssVar=''">
|
||||
<br>
|
||||
<span ng-class="myCssVar">CSS-Animated Text</span>
|
||||
</p>
|
||||
</file>
|
||||
<file name="style.css">
|
||||
.css-class-add, .css-class-remove {
|
||||
transition: all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
||||
}
|
||||
<file name="index.html">
|
||||
<p>
|
||||
<button ng-click="myCssVar='css-class'">Set</button>
|
||||
<button ng-click="myCssVar=''">Clear</button>
|
||||
<br>
|
||||
<span ng-class="myCssVar">CSS-Animated Text</span>
|
||||
</p>
|
||||
</file>
|
||||
<file name="style.css">
|
||||
.css-class-add, .css-class-remove {
|
||||
transition: all 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940);
|
||||
}
|
||||
|
||||
.css-class,
|
||||
.css-class-add.css-class-add-active {
|
||||
color: red;
|
||||
font-size:3em;
|
||||
}
|
||||
.css-class,
|
||||
.css-class-add.css-class-add-active {
|
||||
color: red;
|
||||
font-size: 3em;
|
||||
}
|
||||
|
||||
.css-class-remove.css-class-remove-active {
|
||||
font-size:1.0em;
|
||||
color: black;
|
||||
}
|
||||
</file>
|
||||
.css-class-remove.css-class-remove-active {
|
||||
font-size: 1em;
|
||||
color: black;
|
||||
}
|
||||
</file>
|
||||
</example>
|
||||
|
||||
Although the CSS is a little different than what we saw before, the idea is the same.
|
||||
|
||||
## Which directives support animations?
|
||||
|
||||
A handful of common AngularJS directives support and trigger animation hooks whenever any major event occurs during its life cycle.
|
||||
The table below explains in detail which animation events are triggered
|
||||
A handful of common AngularJS directives support and trigger animation hooks whenever any major
|
||||
event occurs during their life cycle. The table below explains in detail which animation events are
|
||||
triggered:
|
||||
|
||||
| Directive | Supported Animations |
|
||||
|-------------------------------------------------------------------------------------|------------------------------------------|
|
||||
| {@link ng.directive:ngRepeat#animations ngRepeat} | enter, leave, and move |
|
||||
| {@link ngRoute.directive:ngView#animations ngView} | enter and leave |
|
||||
| {@link ng.directive:ngInclude#animations ngInclude} | enter and leave |
|
||||
| {@link ng.directive:ngSwitch#animations ngSwitch} | enter and leave |
|
||||
| {@link ng.directive:ngIf#animations ngIf} | enter and leave |
|
||||
| {@link ng.directive:ngClass#animations ngClass or {{class}}} | add and remove |
|
||||
| {@link ng.directive:ngShow#animations ngShow & ngHide} | add and remove (the ng-hide class value) |
|
||||
| Directive | Supported Animations |
|
||||
|-------------------------------------------------------------------------------|---------------------------------------------------------------------------|
|
||||
| {@link ng.directive:ngRepeat#animations ngRepeat} | enter, leave, and move |
|
||||
| {@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 |
|
||||
| {@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 API docs}.
|
||||
For a full breakdown of the steps involved during each animation event, refer to the
|
||||
{@link ng.$animate API docs}.
|
||||
|
||||
## How do I use animations in my own directives?
|
||||
|
||||
Animations within custom directives can also be established by injecting `$animate` directly into your directive and
|
||||
making calls to it when needed.
|
||||
Animations within custom directives can also be established by injecting `$animate` directly into
|
||||
your directive and making calls to it when needed.
|
||||
|
||||
```js
|
||||
myModule.directive('my-directive', ['$animate', function($animate) {
|
||||
return function(scope, element, attrs) {
|
||||
return function(scope, element) {
|
||||
element.on('click', function() {
|
||||
if(element.hasClass('clicked')) {
|
||||
if (element.hasClass('clicked')) {
|
||||
$animate.removeClass(element, 'clicked');
|
||||
} else {
|
||||
$animate.addClass(element, 'clicked');
|
||||
@@ -255,17 +260,19 @@ myModule.directive('my-directive', ['$animate', function($animate) {
|
||||
|
||||
## Animations on app bootstrap / page load
|
||||
|
||||
By default, animations are disabled when the Angular app {@link guide/bootstrap bootstraps}. If you are using the {@link ngApp} directive,
|
||||
this happens in the `DOMContentLoaded` event, so immediately after the page has been loaded.
|
||||
Animations are disabled, so that UI and content are instantly visible. Otherwise, with many animations on
|
||||
the page, the loading process may become too visually overwhelming, and the performance may suffer.
|
||||
By default, animations are disabled when the AngularJS app {@link guide/bootstrap bootstraps}. If you
|
||||
are using the {@link ngApp} directive, this happens in the `DOMContentLoaded` event, so immediately
|
||||
after the page has been loaded. Animations are disabled, so that UI and content are instantly
|
||||
visible. Otherwise, with many animations on the page, the loading process may become too visually
|
||||
overwhelming, and the performance may suffer.
|
||||
|
||||
Internally, `ngAnimate` waits until all template downloads that are started right after bootstrap have finished.
|
||||
Then, it waits for the currently running {@link ng.$rootScope.Scope#$digest} and the one after that to finish.
|
||||
This ensures that the whole app has been compiled fully before animations are attempted.
|
||||
Internally, `ngAnimate` waits until all template downloads that are started right after bootstrap
|
||||
have finished. Then, it waits for the currently running {@link ng.$rootScope.Scope#$digest $digest}
|
||||
and one more after that, to finish. This ensures that the whole app has been compiled fully before
|
||||
animations are attempted.
|
||||
|
||||
If you do want your animations to play when the app bootstraps, you can enable animations globally in
|
||||
your main module's {@link angular.Module#run run} function:
|
||||
If you do want your animations to play when the app bootstraps, you can enable animations globally
|
||||
in your main module's {@link angular.Module#run run} function:
|
||||
|
||||
```js
|
||||
myModule.run(function($animate) {
|
||||
@@ -275,17 +282,50 @@ myModule.run(function($animate) {
|
||||
|
||||
## How to (selectively) enable, disable and skip animations
|
||||
|
||||
There are three different ways to disable animations, both globally and for specific animations.
|
||||
Disabling specific animations can help to speed up the render performance, for example for large `ngRepeat`
|
||||
lists that don't actually have animations. Because ngAnimate checks at runtime if animations are present,
|
||||
performance will take a hit even if an element has no animation.
|
||||
There are several different ways to disable animations, both globally and for specific animations.
|
||||
Disabling specific animations can help to speed up the render performance, for example for large
|
||||
`ngRepeat` lists that don't actually have animations. Because `ngAnimate` checks at runtime if
|
||||
animations are present, performance will take a hit even if an element has no animation.
|
||||
|
||||
### In the config: {@link $animateProvider#classNameFilter $animateProvider.classNameFilter()}
|
||||
### During the config: {@link $animateProvider#customFilter $animateProvider.customFilter()}
|
||||
|
||||
This function can be called in the {@link angular.Module#config config} phase of an app. It takes a regex as the only argument,
|
||||
which will then be matched against the classes of any element that is about to be animated. The regex
|
||||
allows a lot of flexibility - you can either allow animations only for specific classes (useful when
|
||||
you are working with 3rd party animations), or exclude specific classes from getting animated.
|
||||
This function can be called during the {@link angular.Module#config config} phase of an app. It
|
||||
takes a filter function as the only argument, which will then be used to "filter" animations (based
|
||||
on the animated element, the event type, and the animation options). Only when the filter function
|
||||
returns `true`, will the animation be performed. This allows great flexibility - you can easily
|
||||
create complex rules, such as allowing specific events only or enabling animations on specific
|
||||
subtrees of the DOM, and dynamically modify them, for example disabling animations at certain points
|
||||
in time or under certain circumstances.
|
||||
|
||||
```js
|
||||
app.config(function($animateProvider) {
|
||||
$animateProvider.customFilter(function(node, event, options) {
|
||||
// Example: Only animate `enter` and `leave` operations.
|
||||
return event === 'enter' || event === 'leave';
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
The `customFilter` approach generally gives a big speed boost compared to other strategies, because
|
||||
the matching is done before other animation disabling strategies are checked.
|
||||
|
||||
<div class="alert alert-success">
|
||||
**Best Practice:**
|
||||
Keep the filtering function as lean as possible, because it will be called for each DOM
|
||||
action (e.g. insertion, removal, class change) performed by "animation-aware" directives.
|
||||
See {@link guide/animations#which-directives-support-animations- here} for a list of built-in
|
||||
directives that support animations.
|
||||
Performing computationally expensive or time-consuming operations on each call of the
|
||||
filtering function can make your animations sluggish.
|
||||
</div>
|
||||
|
||||
### During the config: {@link $animateProvider#classNameFilter $animateProvider.classNameFilter()}
|
||||
|
||||
This function too can be called during the {@link angular.Module#config config} phase of an app. It
|
||||
takes a regex as the only argument, which will then be matched against the classes of any element
|
||||
that is about to be animated. The regex allows a lot of flexibility - you can either allow
|
||||
animations for specific classes only (useful when you are working with 3rd party animations), or
|
||||
exclude specific classes from getting animated.
|
||||
|
||||
```js
|
||||
app.config(function($animateProvider) {
|
||||
@@ -294,42 +334,43 @@ app.config(function($animateProvider) {
|
||||
```
|
||||
|
||||
```css
|
||||
/* prefixed with animate- */
|
||||
/* prefixed with `animate-` */
|
||||
.animate-fade-add.animate-fade-add-active {
|
||||
transition: all 1s linear;
|
||||
opacity: 0;
|
||||
}
|
||||
```
|
||||
|
||||
The classNameFilter approach generally applies the biggest speed boost, because the matching is
|
||||
done before any other animation disabling strategies are checked. However, that also means it is not
|
||||
possible to override class name matching with the two following strategies. It's of course still possible
|
||||
to enable / disable animations by changing an element's class name at runtime.
|
||||
The `classNameFilter` approach generally gives a big speed boost compared to other strategies,
|
||||
because the matching is done before other animation disabling strategies are checked. However, that
|
||||
also means it is not possible to override class name matching with the two following strategies.
|
||||
It's of course still possible to enable / disable animations by changing an element's class name at
|
||||
runtime.
|
||||
|
||||
### At runtime: {@link ng.$animate#enabled $animate.enabled()}
|
||||
|
||||
This function can be used to enable / disable animations in two different ways:
|
||||
|
||||
With a single `boolean` argument, it enables / disables animations globally: `$animate.enabled(false)`
|
||||
disables all animations in your app.
|
||||
With a single `boolean` argument, it enables / disables animations globally:
|
||||
`$animate.enabled(false)` disables all animations in your app.
|
||||
|
||||
When the first argument is a native DOM or jqLite/jQuery element, the function enables / disables
|
||||
animations on this element *and all its children*: `$animate.enabled(myElement, false)`. This is the
|
||||
most flexible way to change the animation state. For example, even if you have used it to disable
|
||||
animations on a parent element, you can still re-enable it for a child element. And compared to the
|
||||
`classNameFilter`, you can change the animation status at runtime instead of during the config phase.
|
||||
animations on this element *and all its children*: `$animate.enabled(myElement, false)`. You can
|
||||
still use it to re-enable animations for a child element, even if you have disabled them on a parent
|
||||
element. And compared to the `classNameFilter`, you can change the animation status at runtime
|
||||
instead of during the config phase.
|
||||
|
||||
Note however that the `$animate.enabled()` state for individual elements does not overwrite disabling
|
||||
rules that have been set in the {@link $animateProvider#classNameFilter classNameFilter}.
|
||||
Note however that the `$animate.enabled()` state for individual elements does not overwrite
|
||||
disabling rules that have been set in the {@link $animateProvider#classNameFilter classNameFilter}.
|
||||
|
||||
### Via CSS styles: overwriting styles in the `ng-animate` CSS class
|
||||
Whenever an animation is started, ngAnimate applies the `ng-animate` class to the element for the
|
||||
whole duration of the animation. By applying CSS transition / animation styling to the class,
|
||||
you can skip an animation:
|
||||
|
||||
Whenever an animation is started, `ngAnimate` applies the `ng-animate` class to the element for the
|
||||
whole duration of the animation. By applying CSS transition / animation styling to that class, you
|
||||
can skip an animation:
|
||||
|
||||
```css
|
||||
|
||||
.my-class{
|
||||
.my-class {
|
||||
transition: transform 2s;
|
||||
}
|
||||
|
||||
@@ -340,23 +381,23 @@ you can skip an animation:
|
||||
my-class.ng-animate {
|
||||
transition: 0s;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
By setting `transition: 0s`, ngAnimate will ignore the existing transition styles, and not try to animate them (Javascript
|
||||
animations will still execute, though). This can be used to prevent {@link guide/animations#preventing-collisions-with-existing-animations-and-third-party-libraries
|
||||
issues with existing animations interfering with ngAnimate}.
|
||||
By setting `transition: 0s`, `ngAnimate` will ignore the existing transition styles, and not try to
|
||||
animate them (Javascript animations will still execute, though). This can be used to prevent
|
||||
{@link guide/animations#preventing-collisions-with-existing-animations-and-third-party-libraries
|
||||
issues with existing animations interfering with `ngAnimate`}.
|
||||
|
||||
|
||||
## Preventing flicker before an animation starts
|
||||
|
||||
When nesting elements with structural animations such as `ngIf` into elements that have class-based
|
||||
animations such as `ngClass`, it sometimes happens that before the actual animation starts, there is a brief flicker or flash of content
|
||||
where the animated element is briefly visible.
|
||||
When nesting elements with structural animations, such as `ngIf`, into elements that have
|
||||
class-based animations such as `ngClass`, it sometimes happens that before the actual animation
|
||||
starts, there is a brief flicker or flash of content where the animated element is briefly visible.
|
||||
|
||||
To prevent this, you can apply styles to the `ng-[event]-prepare` class, which is added as soon as an animation is initialized,
|
||||
but removed before the actual animation starts (after waiting for a $digest). This class is only added for *structural*
|
||||
animations (`enter`, `move`, and `leave`).
|
||||
To prevent this, you can apply styles to the `ng-[event]-prepare` class, which is added as soon as
|
||||
an animation is initialized, but removed before the actual animation starts (after waiting for a
|
||||
`$digest`). This class is only added for *structural* animations (`enter`, `move`, and `leave`).
|
||||
|
||||
Here's an example where you might see flickering:
|
||||
|
||||
@@ -368,8 +409,9 @@ Here's an example where you might see flickering:
|
||||
</div>
|
||||
```
|
||||
|
||||
It is possible that during the `enter` event, the `.message` div will be briefly visible before it starts animating.
|
||||
In that case, you can add styles to the CSS that make sure the element stays hidden before the animation starts:
|
||||
It is possible that during the `enter` event, the `.message` div will be briefly visible before it
|
||||
starts animating. In that case, you can add styles to the CSS that make sure the element stays
|
||||
hidden before the animation starts:
|
||||
|
||||
```css
|
||||
.message.ng-enter-prepare {
|
||||
@@ -379,66 +421,71 @@ In that case, you can add styles to the CSS that make sure the element stays hid
|
||||
/* Other animation styles ... */
|
||||
```
|
||||
|
||||
## Preventing Collisions with Existing Animations and Third Party Libraries
|
||||
By default, any `ngAnimate` enabled directives will assume any transition / animation styles on the
|
||||
element are part of an `ngAnimate` animation. This can lead to problems when the styles are actually
|
||||
for animations that are independent of `ngAnimate`.
|
||||
## Preventing collisions with existing animations and third-party libraries
|
||||
|
||||
For example, an element acts as a loading spinner. It has an infinite css animation on it, and also an
|
||||
{@link ngIf `ngIf`} directive, for which no animations are defined:
|
||||
By default, any `ngAnimate`-enabled directives will assume that `transition` / `animation` styles on
|
||||
the element are part of an `ngAnimate` animation. This can lead to problems when the styles are
|
||||
actually for animations that are independent of `ngAnimate`.
|
||||
|
||||
For example, an element acts as a loading spinner. It has an infinite css animation on it, and also
|
||||
an {@link ngIf `ngIf`} directive, for which no animations are defined:
|
||||
|
||||
```css
|
||||
@keyframes rotating {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
.spinner {
|
||||
animation: rotating 2s linear infinite;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
animation: rotating 2s linear infinite;
|
||||
@keyframes rotating {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
```
|
||||
|
||||
Now, when the `ngIf` changes, `ngAnimate` will see the spinner animation and use
|
||||
it to animate the `enter`/`leave` event, which doesn't work because
|
||||
the animation is infinite. The element will still be added / removed after a timeout, but there will be a
|
||||
noticable delay.
|
||||
Now, when the `ngIf` expression changes, `ngAnimate` will see the spinner animation and use it to
|
||||
animate the `enter`/`leave` event, which doesn't work because the animation is infinite. The element
|
||||
will still be added / removed after a timeout, but there will be a noticeable delay.
|
||||
|
||||
This might also happen because some third-party frameworks place animation duration defaults
|
||||
across many element or className selectors in order to make their code small and reuseable.
|
||||
This might also happen because some third-party frameworks place animation duration defaults across
|
||||
many element or className selectors in order to make their code small and reusable.
|
||||
|
||||
You can prevent this unwanted behavior by adding CSS to the `.ng-animate` class that is added
|
||||
for the whole duration of an animation. Simply overwrite the transition / animation duration. In the
|
||||
You can prevent this unwanted behavior by adding CSS to the `.ng-animate` class, that is added for
|
||||
the whole duration of each animation. Simply overwrite the transition / animation duration. In the
|
||||
case of the spinner, this would be:
|
||||
|
||||
```css
|
||||
.spinner.ng-animate {
|
||||
transition: 0s none;
|
||||
animation: 0s none;
|
||||
animation: 0s none;
|
||||
transition: 0s none;
|
||||
}
|
||||
```
|
||||
|
||||
If you do have CSS transitions / animations defined for the animation events, make sure they have higher priority
|
||||
than any styles that are independent from ngAnimate.
|
||||
If you do have CSS transitions / animations defined for the animation events, make sure they have a
|
||||
higher priority than any styles that are not related to `ngAnimate`.
|
||||
|
||||
You can also use one of the two other {@link guide/animations#how-to-selectively-enable-disable-and-skip-animations strategies to disable animations}.
|
||||
You can also use one of the other
|
||||
{@link guide/animations#how-to-selectively-enable-disable-and-skip-animations
|
||||
strategies to disable animations}.
|
||||
|
||||
|
||||
### Enable animations for elements outside of the Angular application DOM tree: {@link ng.$animate#pin $animate.pin()}
|
||||
### Enable animations for elements outside of the AngularJS application DOM tree: {@link ng.$animate#pin $animate.pin()}
|
||||
|
||||
Before animating, `ngAnimate` checks to see if the element being animated is inside the application DOM tree,
|
||||
and if it is not, no animation is run. Usually, this is not a problem as most apps use the `ngApp`
|
||||
attribute / bootstrap the app on the `html` or `body` element.
|
||||
Before animating, `ngAnimate` checks if the animated element is inside the application DOM tree. If
|
||||
not, no animation is run. Usually, this is not a problem since most apps use the `html` or `body`
|
||||
elements as their root.
|
||||
|
||||
Problems arise when the application is bootstrapped on a different element, and animations are
|
||||
attempted on elements that are outside the application tree, e.g. when libraries append popup and modal
|
||||
elements as the last child in the body tag.
|
||||
attempted on elements that are outside the application tree, e.g. when libraries append popup or
|
||||
modal elements to the body tag.
|
||||
|
||||
You can use {@link ng.$animate#pin `$animate.pin(elementToAnimate, parentHost)`} to specify that an
|
||||
element belongs to your application. Simply call it before the element is added to the DOM / before
|
||||
the animation starts, with the element you want to animate, and the element which should be its
|
||||
assumed parent.
|
||||
You can use {@link ng.$animate#pin `$animate.pin(element, parentHost)`} to associate an element with
|
||||
another element that belongs to your application. Simply call it before the element is added to the
|
||||
DOM / before the animation starts, with the element you want to animate, and the element which
|
||||
should be its assumed parent.
|
||||
|
||||
|
||||
## More about animations
|
||||
|
||||
For a full breakdown of each method available on `$animate`, see the {@link ng.$animate API documentation}.
|
||||
For a full breakdown of each method available on `$animate`, see the
|
||||
{@link ng.$animate API documentation}.
|
||||
|
||||
To see a complete demo, see the {@link tutorial/step_14 animation step within the AngularJS phonecat tutorial}.
|
||||
To see a complete demo, see the {@link tutorial/step_14 animation step in the phonecat tutorial}.
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
# Bootstrap
|
||||
|
||||
This page explains the Angular initialization process and how you can manually initialize Angular
|
||||
This page explains the AngularJS initialization process and how you can manually initialize AngularJS
|
||||
if necessary.
|
||||
|
||||
|
||||
## Angular `<script>` Tag
|
||||
## AngularJS `<script>` Tag
|
||||
|
||||
This example shows the recommended path for integrating Angular with what we call automatic
|
||||
This example shows the recommended path for integrating AngularJS with what we call automatic
|
||||
initialization.
|
||||
|
||||
|
||||
@@ -35,13 +35,13 @@ 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
|
||||
angular to auto-bootstrap your application.
|
||||
AngularJS to auto-bootstrap your application.
|
||||
|
||||
<html ng-app>
|
||||
|
||||
3. If you choose to use the old style directive syntax `ng:` then include xml-namespace in `html`
|
||||
to make IE happy. (This is here for historical reasons, and we no longer recommend use of
|
||||
`ng:`.)
|
||||
when running the page in the XHTML mode. (This is here for historical reasons, and we no longer
|
||||
recommend use of `ng:`.)
|
||||
|
||||
<html xmlns:ng="http://angularjs.org">
|
||||
|
||||
@@ -51,16 +51,16 @@ initialization.
|
||||
|
||||
<img class="pull-right" style="padding-left: 3em;" src="img/guide/concepts-startup.png">
|
||||
|
||||
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
|
||||
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
|
||||
for the {@link ng.directive:ngApp `ngApp`} directive which designates your application root.
|
||||
If the {@link ng.directive:ngApp `ngApp`} directive is found then Angular will:
|
||||
If the {@link ng.directive:ngApp `ngApp`} directive is found then AngularJS 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 Angular application.
|
||||
portion of the DOM as an AngularJS 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 Angular compiles a page.
|
||||
or the need to perform an operation before AngularJS compiles a page.
|
||||
|
||||
Here is an example of manually initializing Angular:
|
||||
Here is an example of manually initializing AngularJS:
|
||||
|
||||
```html
|
||||
<!doctype html>
|
||||
@@ -144,7 +144,7 @@ This is the sequence that your code should follow:
|
||||
|
||||
## Things to keep in mind
|
||||
|
||||
There a few things to keep in mind regardless of automatic or manual bootstrapping:
|
||||
There are a few things to keep in mind regardless of automatic or manual bootstrapping:
|
||||
|
||||
- While it's possible to bootstrap more than one AngularJS application per page, we don't actively
|
||||
test against this scenario. It's possible that you'll run into problems, especially with complex apps, so
|
||||
|
||||
@@ -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 Angular's compilation process, you're in the right place.
|
||||
If you want a deeper look into AngularJS's compilation process, you're in the right place.
|
||||
</div>
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
Angular's {@link ng.$compile HTML compiler} allows the developer to teach the
|
||||
AngularJS'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. Angular calls these behavior
|
||||
and even create new HTML elements or attributes with custom behavior. AngularJS 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.
|
||||
|
||||
Angular comes pre-bundled with common directives which are useful for building any app. We also
|
||||
AngularJS 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 Angular service which traverses the DOM looking for attributes. The compilation
|
||||
Compiler is an AngularJS 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
|
||||
|
||||
Angular is different. The Angular compiler consumes the DOM, not string templates.
|
||||
AngularJS is different. The AngularJS 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, Angular directives can contain not just text bindings, but behavioral constructs as
|
||||
Furthermore, AngularJS directives can contain not just text bindings, but behavioral constructs as
|
||||
well.
|
||||
|
||||
<img src="img/Two_Way_Data_Binding.png">
|
||||
|
||||
The Angular approach produces a stable DOM. The DOM element instance bound to a model
|
||||
The AngularJS 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 Angular operates on DOM nodes rather than strings. Usually, you don't
|
||||
It's important to note that AngularJS 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 Angular does internally.
|
||||
This should help give you an idea of what AngularJS does internally.
|
||||
|
||||
```js
|
||||
var $compile = ...; // injected into your code
|
||||
|
||||
@@ -5,19 +5,17 @@
|
||||
|
||||
# Component Router
|
||||
|
||||
<div class="alert alert-info">
|
||||
**Deprecation Notice:** In an effort to keep synchronized with router changes in Angular 2, this implementation of the Component Router (ngComponentRouter module) has been deprecated and will not receive further updates.
|
||||
We are investigating backporting the Angular 2 Router to Angular 1, but alternatively, use the {@link ngRoute} module or community developed projects (e.g. [ui-router](https://github.com/angular-ui/ui-router)).
|
||||
<div class="alert alert-danger">
|
||||
**Deprecation Notice:** In an effort to keep synchronized with router changes in the new Angular, this implementation of the Component Router (ngComponentRouter module) has been deprecated and will not receive further updates.
|
||||
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 new Component Router for AngularJS 1.5.
|
||||
This guide describes the Component Router for AngularJS.
|
||||
|
||||
<div class="alert alert-info">
|
||||
If you are looking for information about the old router for AngularJS 1.4 and
|
||||
earlier have a look at the {@link ngRoute} module.
|
||||
|
||||
If you are looking for information about the Component Router for Angular 2 then
|
||||
check out the [Angular 2 Router Guide](https://angular.io/docs/ts/latest/guide/router.html).
|
||||
If you are looking for information about the default router for AngularJS have a look at the {@link ngRoute} module.
|
||||
If you are looking for information about the Component Router for the new Angular then
|
||||
check out the [Angular Router Guide](https://angular.io/docs/ts/latest/guide/router.html).
|
||||
</div>
|
||||
|
||||
## Overview
|
||||
@@ -29,7 +27,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 Angular component with a RouteConfig and an associated Router. |
|
||||
| Routing Component | An AngularJS 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. |
|
||||
@@ -139,7 +137,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.
|
||||
|
||||
@@ -460,12 +458,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:
|
||||
@@ -476,9 +474,9 @@ yarn add angular@1.5.x @angular/router@0.2.0
|
||||
```
|
||||
|
||||
|
||||
## Load the scripts
|
||||
#### Load the scripts
|
||||
|
||||
Just like any Angular application, we load the JavaScript files into our `index.html`:
|
||||
Just like any AngularJS application, we load the JavaScript files into our `index.html`:
|
||||
|
||||
```html
|
||||
<script src="/node_modules/angular/angular.js"></script>
|
||||
@@ -495,7 +493,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.
|
||||
@@ -529,7 +527,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 Angular 1.5 {@link $compileProvider#component `.component()`} helper method to create
|
||||
We are using the AngularJS {@link $compileProvider#component `.component()`} helper method to create
|
||||
all the **Components** in our application. It is perfectly suited to this task.
|
||||
|
||||
```js
|
||||
@@ -548,9 +546,9 @@ must have a base URL.
|
||||
...
|
||||
```
|
||||
|
||||
## Bootstrap AngularJS
|
||||
#### Bootstrap AngularJS
|
||||
|
||||
Bootstrap the Angular application and add the top level App Component.
|
||||
Bootstrap the AngularJS application and add the top level App Component.
|
||||
|
||||
```html
|
||||
<body ng-app="app">
|
||||
@@ -560,7 +558,7 @@ Bootstrap the Angular 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
|
||||
@@ -578,7 +576,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**:
|
||||
|
||||
@@ -599,7 +597,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.
|
||||
@@ -608,7 +606,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
|
||||
@@ -617,16 +615,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 Angular module for the **Components** of this feature
|
||||
Create a new file `heroes.js`, which defines a new AngularJS module for the **Components** of this feature
|
||||
and registers the Heroes **Component**.
|
||||
|
||||
```js
|
||||
@@ -652,20 +650,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
|
||||
@@ -677,7 +675,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`.
|
||||
@@ -706,7 +704,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.
|
||||
@@ -736,7 +734,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?**
|
||||
|
||||
@@ -781,7 +779,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?**
|
||||
|
||||
@@ -812,11 +810,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 Angular 2, we cannot use the dependency injector to get hold of a component's Router.
|
||||
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.
|
||||
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.
|
||||
|
||||
@@ -883,7 +881,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?**
|
||||
|
||||
@@ -895,7 +893,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
|
||||
@@ -937,7 +935,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
|
||||
@@ -952,7 +950,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**:
|
||||
|
||||
@@ -963,7 +961,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?**
|
||||
|
||||
@@ -980,7 +978,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 Angular, a Component is a special kind of {@link guide/directive directive} that uses a simpler
|
||||
In AngularJS, 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 Angular
|
||||
2'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 the new Angular'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 2
|
||||
- writing component directives will make it easier to upgrade to Angular
|
||||
|
||||
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 `.component()` method of an Angular module (returned by {@link module `angular.module()`}). The method takes two arguments:
|
||||
Components can be registered using the `.component()` method of an AngularJS 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.)
|
||||
@@ -39,14 +39,8 @@ Components can be registered using the `.component()` method of an Angular modul
|
||||
});
|
||||
</file>
|
||||
<file name="heroDetail.js">
|
||||
|
||||
function HeroDetailController() {
|
||||
|
||||
}
|
||||
|
||||
angular.module('heroApp').component('heroDetail', {
|
||||
templateUrl: 'heroDetail.html',
|
||||
controller: HeroDetailController,
|
||||
bindings: {
|
||||
hero: '='
|
||||
}
|
||||
@@ -96,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 Angular
|
||||
Components should never modify any data or DOM that is out of their own scope. Normally, in AngularJS
|
||||
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 Angular uses two-way binding. So if you pass
|
||||
However, scope isolation only goes so far, because AngularJS 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,
|
||||
@@ -164,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 Angular's change detector and thus not trigger `$onChanges`. This hook is invoked with no arguments;
|
||||
be detected by AngularJS'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.
|
||||
@@ -173,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 2.
|
||||
Since the compilation process is rather different in Angular 1 there is no direct mapping and care should
|
||||
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
|
||||
be taken when upgrading.
|
||||
|
||||
By implementing these methods, your component can hook into its lifecycle.
|
||||
@@ -451,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
|
||||
@@ -462,7 +456,7 @@ The examples use the [Jasmine](http://jasmine.github.io/) testing framework.
|
||||
|
||||
**Controller Test:**
|
||||
```js
|
||||
describe('component: heroDetail', function() {
|
||||
describe('HeroDetailController', function() {
|
||||
var $componentController;
|
||||
|
||||
beforeEach(module('heroApp'));
|
||||
@@ -470,15 +464,6 @@ describe('component: heroDetail', function() {
|
||||
$componentController = _$componentController_;
|
||||
}));
|
||||
|
||||
it('should expose a `hero` object', function() {
|
||||
// Here we are passing actual bindings to the component
|
||||
var bindings = {hero: {name: 'Wolverine'}};
|
||||
var ctrl = $componentController('heroDetail', null, bindings);
|
||||
|
||||
expect(ctrl.hero).toBeDefined();
|
||||
expect(ctrl.hero.name).toBe('Wolverine');
|
||||
});
|
||||
|
||||
it('should call the `onDelete` binding, when deleting the hero', function() {
|
||||
var onDeleteSpy = jasmine.createSpy('onDelete');
|
||||
var bindings = {hero: {}, onDelete: onDeleteSpy};
|
||||
|
||||
@@ -54,20 +54,20 @@ Try out the Live Preview above, and then let's walk through the example and desc
|
||||
|
||||
<img class="pull-right" style="padding-left: 3em; padding-bottom: 1em;" src="img/guide/concepts-databinding1.png">
|
||||
|
||||
This looks like normal HTML, with some new markup. In Angular, a file like this is called a
|
||||
<a name="template">{@link templates template}</a>. When Angular starts your application, it parses and
|
||||
This looks like normal HTML, with some new markup. In AngularJS, a file like this is called a
|
||||
<a name="template">{@link templates template}</a>. When AngularJS starts your application, it parses and
|
||||
processes this new markup from the template using the <a name="compiler">{@link compiler compiler}</a>.
|
||||
The loaded, transformed and rendered DOM is then called the <a name="view"></a>*view*.
|
||||
|
||||
The first kind of new markup are the <a name="directive">{@link directive directives}</a>.
|
||||
They apply special behavior to attributes or elements in the HTML. In the example above we use the
|
||||
{@link ng.directive:ngApp `ng-app`} attribute, which is linked to a directive that automatically
|
||||
initializes our application. Angular also defines a directive for the {@link ng.directive:input `input`}
|
||||
initializes our application. AngularJS also defines a directive for the {@link ng.directive:input `input`}
|
||||
element that adds extra behavior to the element. The {@link ng.directive:ngModel `ng-model`} directive
|
||||
stores/updates the value of the input field into/from a variable.
|
||||
|
||||
<div class="alert alert-info">
|
||||
**Custom directives to access the DOM**: In Angular, the only place where an application should access the DOM is
|
||||
**Custom directives to access the DOM**: In AngularJS, the only place where an application should access the DOM is
|
||||
within directives. This is important because artifacts that access the DOM are hard to test.
|
||||
If you need to access the DOM directly you should write a custom directive for this. The
|
||||
{@link directive directives guide} explains how to do this.
|
||||
@@ -76,12 +76,12 @@ stores/updates the value of the input field into/from a variable.
|
||||
The second kind of new markup are the double curly braces `{{ expression | filter }}`:
|
||||
When the compiler encounters this markup, it will replace it with the evaluated value of the markup.
|
||||
An <a name="expression">{@link expression expression}</a> in a template is a JavaScript-like code snippet that allows
|
||||
Angular to read and write variables. Note that those variables are not global variables.
|
||||
AngularJS to read and write variables. Note that those variables are not global variables.
|
||||
Just like variables in a JavaScript function live in a scope,
|
||||
Angular provides a <a name="scope">{@link scope scope}</a> for the variables accessible to expressions.
|
||||
AngularJS provides a <a name="scope">{@link scope scope}</a> for the variables accessible to expressions.
|
||||
The values that are stored in variables on the scope are referred to as the <a name="model"></a>*model*
|
||||
in the rest of the documentation.
|
||||
Applied to the example above, the markup directs Angular to "take the data we got from the input widgets
|
||||
Applied to the example above, the markup directs AngularJS to "take the data we got from the input widgets
|
||||
and multiply them together".
|
||||
|
||||
The example above also contains a <a name="filter">{@link guide/filter filter}</a>.
|
||||
@@ -89,7 +89,7 @@ A filter formats the value of an expression for display to the user.
|
||||
In the example above, the filter {@link ng.filter:currency `currency`} formats a number
|
||||
into an output that looks like money.
|
||||
|
||||
The important thing in the example is that Angular provides _live_ bindings:
|
||||
The important thing in the example is that AngularJS provides _live_ bindings:
|
||||
Whenever the input values change, the value of the expressions are automatically
|
||||
recalculated and the DOM is updated with their values.
|
||||
The concept behind this is <a name="databinding">{@link databinding two-way data binding}</a>.
|
||||
@@ -157,9 +157,9 @@ expressions and directives.
|
||||
|
||||
Besides the new file that contains the controller code, we also added an
|
||||
{@link ng.directive:ngController `ng-controller`} directive to the HTML.
|
||||
This directive tells Angular that the new `InvoiceController` is responsible for the element with the directive
|
||||
This directive tells AngularJS that the new `InvoiceController` is responsible for the element with the directive
|
||||
and all of the element's children.
|
||||
The syntax `InvoiceController as invoice` tells Angular to instantiate the controller
|
||||
The syntax `InvoiceController as invoice` tells AngularJS to instantiate the controller
|
||||
and save it in the variable `invoice` in the current scope.
|
||||
|
||||
We also changed all expressions in the page to read and write variables within that
|
||||
@@ -186,7 +186,7 @@ Right now, the `InvoiceController` contains all logic of our example. When the a
|
||||
is a good practice to move view-independent logic from the controller into a
|
||||
<a name="service">{@link services service}</a>, so it can be reused by other parts
|
||||
of the application as well. Later on, we could also change that service to load the exchange rates
|
||||
from the web, e.g. by calling the Yahoo Finance API, without changing the controller.
|
||||
from the web, e.g. by calling the [Fixer.io](http://fixer.io) exchange rate API, without changing the controller.
|
||||
|
||||
Let's refactor our example and move the currency conversion into a service in another file:
|
||||
|
||||
@@ -260,22 +260,22 @@ get a hold of the now separated function?
|
||||
This is where <a name="di">{@link di Dependency Injection}</a> comes into play.
|
||||
Dependency Injection (DI) is a software design pattern that
|
||||
deals with how objects and functions get created and how they get a hold of their dependencies.
|
||||
Everything within Angular (directives, filters, controllers,
|
||||
services, ...) is created and wired using dependency injection. Within Angular,
|
||||
Everything within AngularJS (directives, filters, controllers,
|
||||
services, ...) is created and wired using dependency injection. Within AngularJS,
|
||||
the DI container is called the <a name="injector">{@link di injector}</a>.
|
||||
|
||||
To use DI, there needs to be a place where all the things that should work together are registered.
|
||||
In Angular, this is the purpose of the <a name="module">{@link module modules}</a>.
|
||||
When Angular starts, it will use the configuration of the module with the name defined by the `ng-app` directive,
|
||||
In AngularJS, this is the purpose of the <a name="module">{@link module modules}</a>.
|
||||
When AngularJS starts, it will use the configuration of the module with the name defined by the `ng-app` directive,
|
||||
including the configuration of all modules that this module depends on.
|
||||
|
||||
In the example above:
|
||||
The template contains the directive `ng-app="invoice2"`. This tells Angular
|
||||
The template contains the directive `ng-app="invoice2"`. This tells AngularJS
|
||||
to use the `invoice2` module as the main module for the application.
|
||||
The code snippet `angular.module('invoice2', ['finance2'])` specifies that the `invoice2` module depends on the
|
||||
`finance2` module. By this, Angular uses the `InvoiceController` as well as the `currencyConverter` service.
|
||||
`finance2` module. By this, AngularJS uses the `InvoiceController` as well as the `currencyConverter` service.
|
||||
|
||||
Now that Angular knows of all the parts of the application, it needs to create them.
|
||||
Now that AngularJS knows of all the parts of the application, it needs to create them.
|
||||
In the previous section we saw that controllers are created using a constructor function.
|
||||
For services, there are multiple ways to specify how they are created
|
||||
(see the {@link services service guide}).
|
||||
@@ -284,24 +284,24 @@ In the example above, we are using an anonymous function as the factory function
|
||||
This function should return the `currencyConverter` service instance.
|
||||
|
||||
Back to the initial question: How does the `InvoiceController` get a reference to the `currencyConverter` function?
|
||||
In Angular, this is done by simply defining arguments on the constructor function. With this, the injector
|
||||
In AngularJS, this is done by simply defining arguments on the constructor function. With this, the injector
|
||||
is able to create the objects in the right order and pass the previously created objects into the
|
||||
factories of the objects that depend on them.
|
||||
In our example, the `InvoiceController` has an argument named `currencyConverter`. By this, Angular knows about the
|
||||
In our example, the `InvoiceController` has an argument named `currencyConverter`. By this, AngularJS knows about the
|
||||
dependency between the controller and the service and calls the controller with the service instance as argument.
|
||||
|
||||
The last thing that changed in the example between the previous section and this section is that we
|
||||
now pass an array to the `module.controller` function, instead of a plain function. The array first
|
||||
contains the names of the service dependencies that the controller needs. The last entry
|
||||
in the array is the controller constructor function.
|
||||
Angular uses this array syntax to define the dependencies so that the DI also works after minifying
|
||||
AngularJS uses this array syntax to define the dependencies so that the DI also works after minifying
|
||||
the code, which will most probably rename the argument name of the controller constructor function
|
||||
to something shorter like `a`.
|
||||
|
||||
## Accessing the backend
|
||||
|
||||
Let's finish our example by fetching the exchange rates from the Yahoo Finance API.
|
||||
The following example shows how this is done with Angular:
|
||||
Let's finish our example by fetching the exchange rates from the [Fixer.io](http://fixer.io) exchange rate API.
|
||||
The following example shows how this is done with AngularJS:
|
||||
|
||||
<example name="guide-concepts-3" ng-app-included="true">
|
||||
<file name="invoice3.js">
|
||||
@@ -323,10 +323,6 @@ The following example shows how this is done with Angular:
|
||||
<file name="finance3.js">
|
||||
angular.module('finance3', [])
|
||||
.factory('currencyConverter', ['$http', function($http) {
|
||||
var YAHOO_FINANCE_URL_PATTERN =
|
||||
'//query.yahooapis.com/v1/public/yql?q=select * from ' +
|
||||
'yahoo.finance.xchange where pair in ("PAIRS")&format=json&' +
|
||||
'env=store://datatables.org/alltableswithkeys';
|
||||
var currencies = ['USD', 'EUR', 'CNY'];
|
||||
var usdToForeignRates = {};
|
||||
|
||||
@@ -335,15 +331,10 @@ The following example shows how this is done with Angular:
|
||||
};
|
||||
|
||||
var refresh = function() {
|
||||
var url = YAHOO_FINANCE_URL_PATTERN.
|
||||
replace('PAIRS', 'USD' + currencies.join('","USD'));
|
||||
var url = 'https://api.fixer.io/latest?base=USD&symbols=' + currencies.join(",");
|
||||
return $http.get(url).then(function(response) {
|
||||
var newUsdToForeignRates = {};
|
||||
angular.forEach(response.data.query.results.rate, function(rate) {
|
||||
var currency = rate.id.substring(3,6);
|
||||
newUsdToForeignRates[currency] = window.parseFloat(rate.Rate);
|
||||
});
|
||||
usdToForeignRates = newUsdToForeignRates;
|
||||
usdToForeignRates = response.data.rates;
|
||||
usdToForeignRates['USD'] = 1;
|
||||
});
|
||||
};
|
||||
|
||||
@@ -380,7 +371,7 @@ The following example shows how this is done with Angular:
|
||||
|
||||
What changed?
|
||||
Our `currencyConverter` service of the `finance` module now uses the {@link ng.$http `$http`}, a
|
||||
built-in service provided by Angular for accessing a server backend. `$http` is a wrapper around
|
||||
built-in service provided by AngularJS for accessing a server backend. `$http` is a wrapper around
|
||||
[`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)
|
||||
and [JSONP](http://en.wikipedia.org/wiki/JSONP) transports.
|
||||
|
||||
|
||||
@@ -5,16 +5,21 @@
|
||||
|
||||
# Understanding Controllers
|
||||
|
||||
In Angular, a Controller is defined by a JavaScript **constructor function** that is used to augment the
|
||||
{@link scope Angular Scope}.
|
||||
In AngularJS, a Controller is defined by a JavaScript **constructor function** that is used to augment the
|
||||
{@link scope AngularJS Scope}.
|
||||
|
||||
When a Controller is attached to the DOM via the {@link ng.directive:ngController ng-controller}
|
||||
directive, Angular will instantiate a new Controller object, using the specified Controller's
|
||||
**constructor function**. A new **child scope** will be created and made available as an injectable
|
||||
parameter to the Controller's constructor function as `$scope`.
|
||||
Controllers can be attached to the DOM in different ways. For each of them, AngularJS will
|
||||
instantiate a new Controller object, using the specified Controller's **constructor function**:
|
||||
|
||||
- the {@link ng.directive:ngController ngController} directive. A new **child scope** will be
|
||||
created and made available as an injectable parameter to the Controller's constructor function
|
||||
as `$scope`.
|
||||
- a route controller in a {@link ngRoute.$routeProvider $route definition}.
|
||||
- the controller of a {@link guide/directive regular directive}, or a
|
||||
{@link guide/component component directive}.
|
||||
|
||||
If the controller has been attached using the `controller as` syntax then the controller instance will
|
||||
be assigned to a property on the new scope.
|
||||
be assigned to a property on the scope.
|
||||
|
||||
Use controllers to:
|
||||
|
||||
@@ -24,18 +29,27 @@ Use controllers to:
|
||||
Do not use controllers to:
|
||||
|
||||
- Manipulate DOM — Controllers should contain only business logic.
|
||||
Putting any presentation logic into Controllers significantly affects its testability. Angular
|
||||
Putting any presentation logic into Controllers significantly affects its testability. AngularJS
|
||||
has {@link databinding databinding} for most cases and {@link guide/directive directives} to
|
||||
encapsulate manual DOM manipulation.
|
||||
- Format input — Use {@link forms angular form controls} instead.
|
||||
- Filter output — Use {@link guide/filter angular filters} instead.
|
||||
- Share code or state across controllers — Use {@link services angular
|
||||
- Format input — Use {@link forms AngularJS form controls} instead.
|
||||
- Filter output — Use {@link guide/filter AngularJS filters} instead.
|
||||
- Share code or state across controllers — Use {@link services AngularJS
|
||||
services} instead.
|
||||
- Manage the life-cycle of other components (for example, to create service instances).
|
||||
|
||||
In general, a Controller shouldn't try to do too much. It should contain only the business logic
|
||||
needed for a single view.
|
||||
|
||||
The most common way to keep Controllers slim is by encapsulating work that doesn't belong to
|
||||
controllers into services and then using these services in Controllers via dependency injection.
|
||||
This is discussed in the {@link di Dependency Injection} and {@link services
|
||||
Services} sections of this guide.
|
||||
|
||||
|
||||
## Setting up the initial state of a `$scope` object
|
||||
|
||||
Typically, when you create an application you need to set up the initial state for the Angular
|
||||
Typically, when you create an application you need to set up the initial state for the AngularJS
|
||||
`$scope`. You set up the initial state of a scope by attaching properties to the `$scope` object.
|
||||
The properties contain the **view model** (the model that will be presented by the view). All the
|
||||
`$scope` properties will be available to the {@link templates template} at the point in the DOM where the Controller
|
||||
@@ -52,13 +66,13 @@ myApp.controller('GreetingController', ['$scope', function($scope) {
|
||||
}]);
|
||||
```
|
||||
|
||||
We create an {@link module Angular Module}, `myApp`, for our application. Then we add the controller's
|
||||
We create an {@link module AngularJS Module}, `myApp`, for our application. Then we add the controller's
|
||||
constructor function to the module using the `.controller()` method. This keeps the controller's
|
||||
constructor function out of the global scope.
|
||||
|
||||
<div class="alert alert-info">
|
||||
We have used an **inline injection annotation** to explicitly specify the dependency
|
||||
of the Controller on the `$scope` service provided by Angular. See the guide on
|
||||
of the Controller on the `$scope` service provided by AngularJS. See the guide on
|
||||
{@link guide/di Dependency Injection} for more information.
|
||||
</div>
|
||||
|
||||
@@ -88,7 +102,7 @@ myApp.controller('DoubleController', ['$scope', function($scope) {
|
||||
}]);
|
||||
```
|
||||
|
||||
Once the Controller has been attached to the DOM, the `double` method can be invoked in an Angular
|
||||
Once the Controller has been attached to the DOM, the `double` method can be invoked in an AngularJS
|
||||
expression in the template:
|
||||
|
||||
```js
|
||||
@@ -99,29 +113,13 @@ expression in the template:
|
||||
|
||||
As discussed in the {@link concepts Concepts} section of this guide, any
|
||||
objects (or primitives) assigned to the scope become model properties. Any methods assigned to
|
||||
the scope are available in the template/view, and can be invoked via angular expressions
|
||||
the scope are available in the template/view, and can be invoked via AngularJS expressions
|
||||
and `ng` event handler directives (e.g. {@link ng.directive:ngClick ngClick}).
|
||||
|
||||
## Using Controllers Correctly
|
||||
|
||||
In general, a Controller shouldn't try to do too much. It should contain only the business logic
|
||||
needed for a single view.
|
||||
|
||||
The most common way to keep Controllers slim is by encapsulating work that doesn't belong to
|
||||
controllers into services and then using these services in Controllers via dependency injection.
|
||||
This is discussed in the {@link di Dependency Injection} and {@link services
|
||||
Services} sections of this guide.
|
||||
|
||||
|
||||
# Associating Controllers with Angular Scope Objects
|
||||
|
||||
You can associate Controllers with scope objects implicitly via the {@link ng.directive:ngController ngController
|
||||
directive} or {@link ngRoute.$route $route service}.
|
||||
|
||||
|
||||
## Simple Spicy Controller Example
|
||||
|
||||
To illustrate further how Controller components work in Angular, let's create a little app with the
|
||||
To illustrate further how Controller components work in AngularJS, let's create a little app with the
|
||||
following components:
|
||||
|
||||
- A {@link templates template} with two buttons and a simple message
|
||||
@@ -159,7 +157,7 @@ string "very". Depending on which button is clicked, the `spice` model is set to
|
||||
|
||||
Things to notice in the example above:
|
||||
|
||||
- The `ng-controller` directive is used to (implicitly) create a scope for our template, and the
|
||||
- The `ngController` directive is used to (implicitly) create a scope for our template, and the
|
||||
scope is augmented (managed) by the `SpicyController` Controller.
|
||||
- `SpicyController` is just a plain JavaScript function. As an (optional) naming convention the name
|
||||
starts with capital letter and ends with "Controller".
|
||||
@@ -262,7 +260,7 @@ Inheritance works with methods in the same way as it does with properties. So in
|
||||
examples, all of the properties could be replaced with methods that return string values.
|
||||
|
||||
|
||||
# Testing Controllers
|
||||
## Testing Controllers
|
||||
|
||||
Although there are many ways to test a Controller, one of the best conventions, shown below,
|
||||
involves injecting the {@link ng.$rootScope $rootScope} and {@link ng.$controller $controller}:
|
||||
|
||||
@@ -4,38 +4,38 @@
|
||||
@description
|
||||
|
||||
|
||||
Angular sets these CSS classes. It is up to your application to provide useful styling.
|
||||
AngularJS sets these CSS classes. It is up to your application to provide useful styling.
|
||||
|
||||
# CSS classes used by angular
|
||||
# CSS classes used by AngularJS
|
||||
|
||||
* `ng-scope`
|
||||
- **Usage:** angular applies this class to any element for which a new {@link $rootScope scope}
|
||||
- **Usage:** AngularJS applies this class to any element for which a new {@link $rootScope scope}
|
||||
is defined. (see {@link guide/scope scope} guide for more information about scopes)
|
||||
|
||||
* `ng-isolate-scope`
|
||||
- **Usage:** angular applies this class to any element for which a new
|
||||
- **Usage:** AngularJS applies this class to any element for which a new
|
||||
{@link guide/directive#isolating-the-scope-of-a-directive isolate scope} is defined.
|
||||
|
||||
* `ng-binding`
|
||||
- **Usage:** angular applies this class to any element that is attached to a data binding, via `ng-bind` or
|
||||
- **Usage:** AngularJS applies this class to any element that is attached to a data binding, via `ng-bind` or
|
||||
`{{}}` curly braces, for example. (see {@link guide/databinding databinding} guide)
|
||||
|
||||
* `ng-invalid`, `ng-valid`
|
||||
- **Usage:** angular applies this class to a form control widget element if that element's input does
|
||||
- **Usage:** AngularJS applies this class to a form control widget element if that element's input does
|
||||
not pass validation. (see {@link ng.directive:input input} directive)
|
||||
|
||||
* `ng-pristine`, `ng-dirty`
|
||||
- **Usage:** angular {@link ng.directive:ngModel ngModel} directive applies `ng-pristine` class
|
||||
- **Usage:** AngularJS {@link ng.directive:ngModel ngModel} directive applies `ng-pristine` class
|
||||
to a new form control widget which did not have user interaction. Once the user interacts with
|
||||
the form control, the class is changed to `ng-dirty`.
|
||||
|
||||
* `ng-touched`, `ng-untouched`
|
||||
- **Usage:** angular {@link ng.directive:ngModel ngModel} directive applies `ng-untouched` class
|
||||
- **Usage:** AngularJS {@link ng.directive:ngModel ngModel} directive applies `ng-untouched` class
|
||||
to a new form control widget which has not been blurred. Once the user blurs the form control,
|
||||
the class is changed to `ng-touched`.
|
||||
|
||||
|
||||
## Related Topics
|
||||
|
||||
* {@link guide/templates Angular Templates}
|
||||
* {@link guide/forms Angular Forms}
|
||||
* {@link guide/templates AngularJS Templates}
|
||||
* {@link guide/forms AngularJS Forms}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
# Data Binding
|
||||
|
||||
Data-binding in Angular apps is the automatic synchronization of data between the model and view
|
||||
components. The way that Angular implements data-binding lets you treat the model as the
|
||||
Data-binding in AngularJS apps is the automatic synchronization of data between the model and view
|
||||
components. The way that AngularJS implements data-binding lets you treat the model as the
|
||||
single-source-of-truth in your application. The view is a projection of the model at all times.
|
||||
When the model changes, the view reflects the change, and vice versa.
|
||||
|
||||
@@ -19,10 +19,10 @@ or related sections of the view are NOT automatically reflected in the view. Wor
|
||||
that the user makes to the view are not reflected in the model. This means that the developer has
|
||||
to write code that constantly syncs the view with the model and the model with the view.
|
||||
|
||||
## Data Binding in Angular Templates
|
||||
## Data Binding in AngularJS Templates
|
||||
|
||||
<img class="right" src="img/Two_Way_Data_Binding.png"/><br />
|
||||
Angular templates work differently. First the template (which is the uncompiled HTML along with
|
||||
AngularJS templates work differently. First the template (which is the uncompiled HTML along with
|
||||
any additional markup or directives) is compiled on the browser. The compilation step produces a
|
||||
live view. Any changes to the view are immediately reflected in the model, and any changes in
|
||||
the model are propagated to the view. The model is the single-source-of-truth for the application
|
||||
@@ -36,5 +36,5 @@ isolation without the view and the related DOM/browser dependency.
|
||||
|
||||
## Related Topics
|
||||
|
||||
* {@link scope Angular Scopes}
|
||||
* {@link templates Angular Templates}
|
||||
* {@link scope AngularJS Scopes}
|
||||
* {@link templates AngularJS Templates}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
## What are decorators?
|
||||
|
||||
Decorators are a design pattern that is used to separate modification or *decoration* of a class without modifying the
|
||||
original source code. In Angular, decorators are functions that allow a service, directive or filter to be modified
|
||||
original source code. In AngularJS, decorators are functions that allow a service, directive or filter to be modified
|
||||
prior to its usage.
|
||||
|
||||
## How to use decorators
|
||||
|
||||
+32
-24
@@ -8,32 +8,40 @@
|
||||
Dependency Injection (DI) is a software design pattern that deals with how components get hold of
|
||||
their dependencies.
|
||||
|
||||
The Angular injector subsystem is in charge of creating components, resolving their dependencies,
|
||||
The AngularJS injector subsystem is in charge of creating components, resolving their dependencies,
|
||||
and providing them to other components as requested.
|
||||
|
||||
|
||||
## Using Dependency Injection
|
||||
|
||||
DI is pervasive throughout Angular. You can use it when defining components or when providing `run`
|
||||
and `config` blocks for a module.
|
||||
Dependency Injection is pervasive throughout AngularJS. You can use it when defining components
|
||||
or when providing `run` and `config` blocks for a module.
|
||||
|
||||
- Components such as services, directives, filters, and animations are defined by an injectable
|
||||
factory method or constructor function. These components can be injected with "service" and "value"
|
||||
components as dependencies.
|
||||
- {@link angular.Module#service Services}, {@link angular.Module#directive directives},
|
||||
{@link angular.Module#filter filters}, and {@link angular.Module#animation animations} are
|
||||
defined by an injectable factory method or constructor function, and can be injected with
|
||||
"services", "values", and "constants" as dependencies.
|
||||
|
||||
- Controllers are defined by a constructor function, which can be injected with any of the "service"
|
||||
and "value" components as dependencies, but they can also be provided with special dependencies. See
|
||||
{@link di#controllers Controllers} below for a list of these special dependencies.
|
||||
- {@link ng.$controller Controllers} are defined by a constructor function, which can be injected
|
||||
with any of the "service" and "value" as dependencies, but they can also be provided with
|
||||
"special dependencies". See {@link di#controllers Controllers} below for a list of these
|
||||
special dependencies.
|
||||
|
||||
- The `run` method accepts a function, which can be injected with "service", "value" and "constant"
|
||||
components as dependencies. Note that you cannot inject "providers" into `run` blocks.
|
||||
- The {@link angular.Module#run `run`} method accepts a function, which can be injected with
|
||||
"services", "values" and, "constants" as dependencies. Note that you cannot inject "providers"
|
||||
into `run` blocks.
|
||||
|
||||
- The `config` method accepts a function, which can be injected with "provider" and "constant"
|
||||
components as dependencies. Note that you cannot inject "service" or "value" components into
|
||||
configuration.
|
||||
- The {@link angular.Module#config `config`} method accepts a function, which can be injected with
|
||||
"providers" and "constants" as dependencies. Note that you cannot inject "services" or
|
||||
"values" into configuration.
|
||||
|
||||
See {@link module#module-loading-dependencies Modules} for more details about `run` and `config`
|
||||
blocks.
|
||||
- The {@link angular.Module#provider `provider`} method can only be injected with other "providers".
|
||||
However, only those that have been **registered beforehand** can be injected. This is different
|
||||
from services, where the order of registration does not matter.
|
||||
|
||||
See {@link module#module-loading Modules} for more details about `run` and `config`
|
||||
blocks and {@link guide/providers Providers} for more information about the different provider
|
||||
types.
|
||||
|
||||
|
||||
### Factory Methods
|
||||
@@ -100,7 +108,7 @@ Moreover, additional dependencies are made available to Controllers:
|
||||
|
||||
## Dependency Annotation
|
||||
|
||||
Angular invokes certain functions (like service factories and controllers) via the injector.
|
||||
AngularJS invokes certain functions (like service factories and controllers) via the injector.
|
||||
You need to annotate these functions so that the injector knows what services to inject into
|
||||
the function. There are three ways of annotating your code with service name information:
|
||||
|
||||
@@ -204,11 +212,11 @@ angular.module('myApp', [])
|
||||
// $rootScope is implicitly injected
|
||||
})
|
||||
.run(['willBreak', function(willBreak) {
|
||||
// Angular will throw when this runs
|
||||
// AngularJS will throw when this runs
|
||||
}]);
|
||||
```
|
||||
|
||||
When the `willBreak` service is instantiated, Angular will throw an error because of strict mode.
|
||||
When the `willBreak` service is instantiated, AngularJS will throw an error because of strict mode.
|
||||
This is useful when using a tool like [ng-annotate](https://github.com/olov/ng-annotate) to
|
||||
ensure that all of your application components have annotations.
|
||||
|
||||
@@ -225,7 +233,7 @@ angular.bootstrap(document, ['myApp'], {
|
||||
|
||||
## Why Dependency Injection?
|
||||
|
||||
This section motivates and explains Angular's use of DI. For how to use DI, see above.
|
||||
This section motivates and explains AngularJS's use of DI. For how to use DI, see above.
|
||||
|
||||
For in-depth discussion about DI, see
|
||||
[Dependency Injection](http://en.wikipedia.org/wiki/Dependency_injection) at Wikipedia,
|
||||
@@ -264,7 +272,7 @@ code that constructs `SomeClass`.
|
||||
|
||||
<img class="pull-right" style="padding-left: 3em; padding-bottom: 1em;" src="img/guide/concepts-module-injector.png">
|
||||
|
||||
To manage the responsibility of dependency creation, each Angular application has an {@link
|
||||
To manage the responsibility of dependency creation, each AngularJS application has an {@link
|
||||
angular.injector injector}. The injector is a
|
||||
[service locator](http://en.wikipedia.org/wiki/Service_locator_pattern) that is responsible for
|
||||
construction and lookup of dependencies.
|
||||
@@ -290,7 +298,7 @@ myModule.factory('greeter', function($window) {
|
||||
```
|
||||
|
||||
Create a new injector that can provide components defined in our `myModule` module and request our
|
||||
`greeter` service from the injector. (This is usually done automatically by angular bootstrap).
|
||||
`greeter` service from the injector. (This is usually done automatically by AngularJS bootstrap).
|
||||
|
||||
```js
|
||||
var injector = angular.injector(['ng', 'myModule']);
|
||||
@@ -317,7 +325,7 @@ function MyController($scope, greeter) {
|
||||
}
|
||||
```
|
||||
|
||||
When Angular compiles the HTML, it processes the `ng-controller` directive, which in turn
|
||||
When AngularJS compiles the HTML, it processes the `ng-controller` directive, which in turn
|
||||
asks the injector to create an instance of the controller and its dependencies.
|
||||
|
||||
```js
|
||||
@@ -332,6 +340,6 @@ This is the best outcome. The application code simply declares the dependencies
|
||||
having to deal with the injector. This setup does not break the Law of Demeter.
|
||||
|
||||
<div class="alert alert-info">
|
||||
**Note:** Angular uses
|
||||
**Note:** AngularJS uses
|
||||
[**constructor injection**](http://misko.hevery.com/2009/02/19/constructor-injection-vs-setter-injection/).
|
||||
</div>
|
||||
|
||||
@@ -24,9 +24,9 @@ name, comment or CSS class) that tell AngularJS's **HTML compiler** ({@link ng.$
|
||||
to attach a specified behavior to that DOM element (e.g. via event listeners), or even to transform
|
||||
the DOM element and its children.
|
||||
|
||||
Angular comes with a set of these directives built-in, like `ngBind`, `ngModel`, and `ngClass`.
|
||||
Much like you create controllers and services, you can create your own directives for Angular to use.
|
||||
When Angular {@link guide/bootstrap bootstraps} your application, the
|
||||
AngularJS comes with a set of these directives built-in, like `ngBind`, `ngModel`, and `ngClass`.
|
||||
Much like you create controllers and services, you can create your own directives for AngularJS to use.
|
||||
When AngularJS {@link guide/bootstrap bootstraps} your application, the
|
||||
{@link guide/compiler HTML compiler} traverses the DOM matching directives against the DOM elements.
|
||||
|
||||
<div class="alert alert-info">
|
||||
@@ -41,7 +41,7 @@ mirrors the process of compiling source code in
|
||||
|
||||
## Matching Directives
|
||||
|
||||
Before we can write a directive, we need to know how Angular's {@link guide/compiler HTML compiler}
|
||||
Before we can write a directive, we need to know how AngularJS's {@link guide/compiler HTML compiler}
|
||||
determines when to use a given directive.
|
||||
|
||||
Similar to the terminology used when an [element **matches** a selector](https://developer.mozilla.org/en-US/docs/Web/API/Element.matches), we say an element **matches** a
|
||||
@@ -67,7 +67,7 @@ And the following `<person>` element **matches** the `person` directive:
|
||||
|
||||
### Normalization
|
||||
|
||||
Angular **normalizes** an element's tag and attribute name to determine which elements match which
|
||||
AngularJS **normalizes** an element's tag and attribute name to determine which elements match which
|
||||
directives. We typically refer to directives by their case-sensitive
|
||||
[camelCase](http://en.wikipedia.org/wiki/CamelCase) **normalized** name (e.g. `ngModel`).
|
||||
However, since HTML is case-insensitive, we refer to directives in the DOM by lower-case
|
||||
@@ -120,11 +120,13 @@ The other forms shown above are accepted for legacy reasons but we advise you to
|
||||
|
||||
### Directive types
|
||||
|
||||
`$compile` can match directives based on element names, attributes, class names, as well as comments.
|
||||
`$compile` can match directives based on element names (E), attributes (A), class names (C),
|
||||
and comments (M).
|
||||
|
||||
All of the Angular-provided directives match attribute name, tag name, comments, or class name.
|
||||
The following demonstrates the various ways a directive (`myDir` in this case) can be referenced
|
||||
from within a template:
|
||||
The built-in AngularJS directives show in their documentation page which type of matching they support.
|
||||
|
||||
The following demonstrates the various ways a directive that matches all 4 types
|
||||
(`myDir` in this case) can be referenced from within a template.
|
||||
|
||||
```html
|
||||
<my-dir></my-dir>
|
||||
@@ -133,6 +135,10 @@ from within a template:
|
||||
<span class="my-dir: exp;"></span>
|
||||
```
|
||||
|
||||
A directive can specify which of the 4 matching types it supports in the
|
||||
{@link ng.$compile#-restrict- `restrict`} property of the directive definition object.
|
||||
The default is `EA`.
|
||||
|
||||
<div class="alert alert-success">
|
||||
**Best Practice:** Prefer using directives via tag name and attributes over comment and class names.
|
||||
Doing so generally makes it easier to determine what directives a given element matches.
|
||||
@@ -172,7 +178,7 @@ and compilation process.
|
||||
directive names. For instance, if you created a `<carousel>` directive, it would be problematic if HTML7
|
||||
introduced the same element. A two or three letter prefix (e.g. `btfCarousel`) works well. Similarly, do
|
||||
not prefix your own directives with `ng` or they might conflict with directives included in a future
|
||||
version of Angular.
|
||||
version of AngularJS.
|
||||
</div>
|
||||
|
||||
For the following examples, we'll use the prefix `my` (e.g. `myCustomer`).
|
||||
@@ -251,7 +257,7 @@ using `templateUrl` instead:
|
||||
</example>
|
||||
|
||||
`templateUrl` can also be a function which returns the URL of an HTML template to be loaded and
|
||||
used for the directive. Angular will call the `templateUrl` function with two parameters: the
|
||||
used for the directive. AngularJS will call the `templateUrl` function with two parameters: the
|
||||
element that the directive was called on, and an `attr` object associated with that element.
|
||||
|
||||
<div class="alert alert-warning">
|
||||
@@ -538,7 +544,7 @@ directive logic will be put.
|
||||
`link` takes a function with the following signature,
|
||||
`function link(scope, element, attrs, controller, transcludeFn) { ... }`, where:
|
||||
|
||||
* `scope` is an Angular scope object.
|
||||
* `scope` is an AngularJS scope object.
|
||||
* `element` is the jqLite-wrapped element that this directive matches.
|
||||
* `attrs` is a hash object with key-value pairs of normalized attribute names and their
|
||||
corresponding attribute values.
|
||||
@@ -608,7 +614,7 @@ function.
|
||||
We register an event `element.on('$destroy', ...)`. What fires this `$destroy` event?
|
||||
|
||||
There are a few special events that AngularJS emits. When a DOM node that has been compiled
|
||||
with Angular's compiler is destroyed, it emits a `$destroy` event. Similarly, when an AngularJS
|
||||
with AngularJS's compiler is destroyed, it emits a `$destroy` event. Similarly, when an AngularJS
|
||||
scope is destroyed, it broadcasts a `$destroy` event to listening scopes.
|
||||
|
||||
By listening to this event, you can remove event listeners that might cause memory leaks.
|
||||
@@ -971,7 +977,7 @@ controllers using `require`.
|
||||
Otherwise use `link`.
|
||||
</div>
|
||||
|
||||
### Summary
|
||||
## Summary
|
||||
|
||||
Here we've seen the main use cases for directives. Each of these samples acts as a good starting
|
||||
point for creating your own directives.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user