Compare commits
145 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 874392464b | |||
| 7e7244402d | |||
| 4b94b9e34f | |||
| a2e7f54320 | |||
| 9b2e11b6fa | |||
| 2114a50c9a | |||
| 38f92c3a27 | |||
| 7dbf1ef2d1 | |||
| e13aae1ed0 | |||
| 36eacb172a | |||
| f2683f956f | |||
| 1a670aa466 | |||
| 578425303f | |||
| 528cf09e3f | |||
| c849098fbf | |||
| 145d397988 | |||
| 26d4d0dc22 | |||
| 64a9faaf8e | |||
| b7aba16839 | |||
| a72e1c4767 | |||
| 6545212d24 | |||
| 3fabbdb804 | |||
| ce8be9c47f | |||
| b3878a36d9 | |||
| ebd84e8008 | |||
| e721169738 | |||
| cdfbe25c00 | |||
| 0d4b15a4c9 | |||
| 0dd061c239 | |||
| 7288be25a7 | |||
| 2b279dd8a1 | |||
| 63b9956faf | |||
| 92767c098f | |||
| 2fe9b1dd9e | |||
| b9ad91cf1e | |||
| 40752a520a | |||
| 21369943fa | |||
| 190ea883c5 | |||
| 3a093123ef | |||
| b8e8f9af78 | |||
| 01161a0e9f | |||
| 75abbd525f | |||
| 01a725a769 | |||
| f5781dbb60 | |||
| 59205d7809 | |||
| 0cf170df16 | |||
| 05a3b088fd | |||
| 65df5da07a | |||
| 0689c3697f | |||
| 0f53c29954 | |||
| 11bfe85598 | |||
| 93c503fa16 | |||
| 9d4e948e82 | |||
| 26f19d0399 | |||
| 5cd2e2291b | |||
| 69bbbe675e | |||
| 825de1cdf2 | |||
| e5318c61ee | |||
| 67b40a19fb | |||
| 5fbac749c9 | |||
| 0daadeb3d3 | |||
| 6b7625a095 | |||
| ab7e0cd100 | |||
| dee5f7fea5 | |||
| 140d149cee | |||
| 4d65ddddf8 | |||
| abfce5327c | |||
| 944c150e6c | |||
| d8dc53d215 | |||
| 0ec206f5a6 | |||
| ce49d4d61b | |||
| 69ee593fd2 | |||
| 39ddef6829 | |||
| 11aedbd741 | |||
| e4d1e12f7f | |||
| 9c2b32d6f3 | |||
| 4b3a590b00 | |||
| 7f50e97628 | |||
| e5ee6123fc | |||
| 923b6aba0d | |||
| 955e20eb61 | |||
| 286a40751c | |||
| eca0535457 | |||
| 7ace77a5d7 | |||
| 7f362af153 | |||
| 35dee2abac | |||
| 29c926201d | |||
| 9b6852a8c9 | |||
| 53efc8d5d0 | |||
| 0b8461c9cb | |||
| abd8e2a9eb | |||
| bc4dadc894 | |||
| ec53089bb1 | |||
| 7bb50e2823 | |||
| 632b2ddd34 | |||
| 7caad2205a | |||
| 9bf5f89659 | |||
| f41ca4a53e | |||
| 0bcd0872d8 | |||
| 6ec5946094 | |||
| 784ea8e160 | |||
| 6ec53bdfd3 | |||
| d1b6480dcf | |||
| ef6fed3ef8 | |||
| 473dee5786 | |||
| 779e3f6b5f | |||
| 71bca00651 | |||
| 9a9fce0abc | |||
| 939ca37cfe | |||
| 4ae8a2a4b6 | |||
| 113d3954b9 | |||
| 7cb5983750 | |||
| 2b149ca6d4 | |||
| e77866c18c | |||
| 0dc6418d20 | |||
| 837a077578 | |||
| adf91fe6ee | |||
| dea1c0d34c | |||
| f533acc9aa | |||
| d01cae2a0d | |||
| d015c8a80b | |||
| 8d2717146b | |||
| 3d598dae64 | |||
| 0a58986f52 | |||
| 6e69b85f9a | |||
| 7a9e336028 | |||
| 9b8df52aa9 | |||
| 7fab29fbe1 | |||
| 1a47fcbb8b | |||
| ffd4dab611 | |||
| 13edaa95c7 | |||
| 47b1f54bba | |||
| cdc7280dd3 | |||
| 0bb282bc6d | |||
| fdb09ef858 | |||
| 5e69cb2f9f | |||
| 5c2da38e3f | |||
| 3a799df0f1 | |||
| 511c765a44 | |||
| bf55d76d27 | |||
| c9efc80cd0 | |||
| fa15f2a6df | |||
| c023a0bfbb | |||
| b470e005e8 | |||
| c959191882 |
+9
-2
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"excludeFiles": ["src/ngLocale/**"],
|
||||
"disallowKeywords": ["with"],
|
||||
"disallowKeywordsOnNewLine": ["else"],
|
||||
"disallowMixedSpacesAndTabs": true,
|
||||
"disallowMultipleLineStrings": true,
|
||||
"disallowNewlineBeforeBlockStatements": true,
|
||||
@@ -11,6 +12,7 @@
|
||||
"disallowSpacesInAnonymousFunctionExpression": {
|
||||
"beforeOpeningRoundBrace": true
|
||||
},
|
||||
"disallowSpacesInCallExpression": true,
|
||||
"disallowSpacesInFunctionDeclaration": {
|
||||
"beforeOpeningRoundBrace": true
|
||||
},
|
||||
@@ -18,6 +20,11 @@
|
||||
"beforeOpeningRoundBrace": true
|
||||
},
|
||||
"disallowSpacesInsideArrayBrackets": true,
|
||||
"requireSpaceBeforeKeywords": [
|
||||
"else",
|
||||
"while",
|
||||
"catch"
|
||||
],
|
||||
"disallowSpacesInsideParentheses": true,
|
||||
"disallowTrailingComma": true,
|
||||
"disallowTrailingWhitespace": true,
|
||||
@@ -33,9 +40,9 @@
|
||||
"afterConsequent": true,
|
||||
"beforeAlternate": true
|
||||
},
|
||||
"requireSpacesInForStatement": true,
|
||||
"requireSpacesInFunction": {
|
||||
"beforeOpeningCurlyBrace": true
|
||||
},
|
||||
"validateLineBreaks": "LF",
|
||||
"validateParameterSeparator": ", "
|
||||
"validateLineBreaks": "LF"
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,10 +4,10 @@
|
||||
// that correct the existing code base issues and make the new check pass.
|
||||
|
||||
{
|
||||
"validateParameterSeparator": ", ", // Re-assert this rule when JSCS allows multiple spaces
|
||||
"requireCurlyBraces": ["if", "else", "for", "while", "do", "try", "catch"],
|
||||
"disallowImplicitTypeConversion": ["string"],
|
||||
"disallowMultipleLineBreaks": true,
|
||||
"disallowKeywordsOnNewLine": ["else"],
|
||||
"validateJSDoc": {
|
||||
"checkParamNames": true,
|
||||
"requireParamTypes": true
|
||||
|
||||
+14
-2
@@ -2,6 +2,12 @@ language: node_js
|
||||
node_js:
|
||||
- '0.10'
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
- bower_components
|
||||
- docs/bower_components
|
||||
|
||||
branches:
|
||||
except:
|
||||
- /^g3_.*$/
|
||||
@@ -27,15 +33,21 @@ env:
|
||||
matrix:
|
||||
allow_failures:
|
||||
- env: "JOB=unit BROWSER_PROVIDER=browserstack"
|
||||
- env: "JOB=docs-e2e BROWSER_PROVIDER=browserstack"
|
||||
- env: "JOB=e2e TEST_TARGET=jqlite BROWSER_PROVIDER=browserstack"
|
||||
- env: "JOB=e2e TEST_TARGET=jquery BROWSER_PROVIDER=browserstack"
|
||||
|
||||
install:
|
||||
# Check the size of caches
|
||||
- du -sh ./node_modules ./bower_components/ ./docs/bower_components/ || true
|
||||
# - npm config set registry http://23.251.144.68
|
||||
# Disable the spinner, it looks bad on Travis
|
||||
- npm config set spin false
|
||||
# Log HTTP requests
|
||||
- npm config set loglevel http
|
||||
- time ./scripts/travis/npm-bundle-deps.sh
|
||||
- time npm install
|
||||
- npm install -g npm@2.5
|
||||
# Instal npm dependecies and ensure that npm cache is not stale
|
||||
- scripts/npm/install-dependencies.sh
|
||||
|
||||
before_script:
|
||||
- mkdir -p $LOGS_DIR
|
||||
|
||||
+390
@@ -1,3 +1,393 @@
|
||||
<a name="1.4.0-beta.5"></a>
|
||||
# 1.4.0-beta.5 karmic-stabilization (2015-02-24)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$http:** properly access request headers with mixed case
|
||||
([5da1256f](https://github.com/angular/angular.js/commit/5da1256fc2812d5b28fb0af0de81256054856369),
|
||||
[#10881](https://github.com/angular/angular.js/issues/10881), [#10883](https://github.com/angular/angular.js/issues/10883))
|
||||
- **input:** create max and/or min validator regardless of initial value
|
||||
([c211e7a5](https://github.com/angular/angular.js/commit/c211e7a5ad5f1fb8748125f14912aa8715081925),
|
||||
[#10307](https://github.com/angular/angular.js/issues/10307), [#10327](https://github.com/angular/angular.js/issues/10327))
|
||||
- **ngAria:** correctly set "checked" attr for checkboxes and radios
|
||||
([d6eba217](https://github.com/angular/angular.js/commit/d6eba21733c6e67e90e3a4763d8d41ad89a73a0c),
|
||||
[#10389](https://github.com/angular/angular.js/issues/10389), [#10212](https://github.com/angular/angular.js/issues/10212))
|
||||
- **ngModel:** fix issues when parserName is same as validator key
|
||||
([056a3170](https://github.com/angular/angular.js/commit/056a31700803c0a6014b43cfcc36c5c500cc596e),
|
||||
[#10698](https://github.com/angular/angular.js/issues/10698), [#10850](https://github.com/angular/angular.js/issues/10850), [#11046](https://github.com/angular/angular.js/issues/11046))
|
||||
- **ngOptions:** ngModel is optional
|
||||
([ef894c87](https://github.com/angular/angular.js/commit/ef894c87eaead76d90169113ab6acc9287654ea3))
|
||||
- **ngSanitize:** Do not ignore white-listed svg camelCased attributes
|
||||
([46b80654](https://github.com/angular/angular.js/commit/46b80654cae9105642909cd55f73f7c26d2fbd80),
|
||||
[#10779](https://github.com/angular/angular.js/issues/10779), [#10990](https://github.com/angular/angular.js/issues/10990), [#11124](https://github.com/angular/angular.js/issues/11124))
|
||||
- **select:** remove unknown option when model is undefined and empty option is available
|
||||
([30b48132](https://github.com/angular/angular.js/commit/30b48132e0fb92ea8dd25a9794b4c41a3a81a951),
|
||||
[#11078](https://github.com/angular/angular.js/issues/11078), [#11092](https://github.com/angular/angular.js/issues/11092))
|
||||
- **templateRequest:** avoid throwing syntax error in Android 2.3
|
||||
([f6272333](https://github.com/angular/angular.js/commit/f6272333127d908b19da23f9cd8a74052711795b),
|
||||
[#11089](https://github.com/angular/angular.js/issues/11089), [#11051](https://github.com/angular/angular.js/issues/11051), [#11088](https://github.com/angular/angular.js/issues/11088))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **CommonJS:** - angular modules are now packaged for npm with helpful exports
|
||||
|
||||
- **limitTo:** extend the filter to take a beginning index argument
|
||||
([aaae3cc4](https://github.com/angular/angular.js/commit/aaae3cc4160417e6dad802ed9d9f6d5471821a87),
|
||||
[#5355](https://github.com/angular/angular.js/issues/5355), [#10899](https://github.com/angular/angular.js/issues/10899))
|
||||
- **ngMessages:** provide support for dynamic message resolution
|
||||
([c9a4421f](https://github.com/angular/angular.js/commit/c9a4421fc3c97448527eadef1f42eb2f487ec2e0),
|
||||
[#10036](https://github.com/angular/angular.js/issues/10036), [#9338](https://github.com/angular/angular.js/issues/9338))
|
||||
- **ngOptions:** add support for disabling an option
|
||||
([da9eac86](https://github.com/angular/angular.js/commit/da9eac8660343b1cd9fdcf9d2d1bda06067142d7),
|
||||
[#638](https://github.com/angular/angular.js/issues/638), [#11017](https://github.com/angular/angular.js/issues/11017))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
|
||||
- **$compile:**
|
||||
- replace forEach(controller) with plain loops
|
||||
([5b522867](https://github.com/angular/angular.js/commit/5b5228675f67c8f5e04c7183c3ef5e71cb2bf08b),
|
||||
[#11084](https://github.com/angular/angular.js/issues/11084))
|
||||
- avoid .data when fetching required controllers
|
||||
([fa0aa839](https://github.com/angular/angular.js/commit/fa0aa83937378cf8fc720c38bcc5c78fc923624e))
|
||||
- **ngOptions:** only watch labels if a display expression is specified
|
||||
([51faaffd](https://github.com/angular/angular.js/commit/51faaffdbcc734c55d52ff6c42b386d5c90207ea))
|
||||
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- **ngMessages:** due to [c9a4421f](https://github.com/angular/angular.js/commit/c9a4421fc3c97448527eadef1f42eb2f487ec2e0),
|
||||
|
||||
|
||||
The `ngMessagesInclude` attribute is now its own directive and that must
|
||||
be placed as a **child** element within the element with the ngMessages
|
||||
directive. (Keep in mind that the former behaviour of the
|
||||
ngMessageInclude attribute was that all **included** ngMessage template
|
||||
code was placed at the **bottom** of the element containing the
|
||||
ngMessages directive; therefore to make this behave in the same way,
|
||||
place the element containing the ngMessagesInclude directive at the
|
||||
end of the container containing the ngMessages directive).
|
||||
|
||||
```html
|
||||
<!-- AngularJS 1.3.x -->
|
||||
<div ng-messages="model.$error" ng-messages-include="remote.html">
|
||||
<div ng-message="required">Your message is required</div>
|
||||
</div>
|
||||
|
||||
<!-- AngularJS 1.4.x -->
|
||||
<div ng-messages="model.$error">
|
||||
<div ng-message="required">Your message is required</div>
|
||||
<div ng-messages-include="remote.html"></div>
|
||||
</div>
|
||||
```
|
||||
|
||||
<a name="1.3.14"></a>
|
||||
# 1.3.14 instantaneous-browserification (2015-02-24)
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **CommonJS:** - angular modules are now packaged for npm with helpful exports
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **input:** create max and/or min validator regardless of initial value
|
||||
([abfce532](https://github.com/angular/angular.js/commit/abfce5327ce6fd29c33c62d2edf3600674a6b4c0),
|
||||
[#10307](https://github.com/angular/angular.js/issues/10307), [#10327](https://github.com/angular/angular.js/issues/10327))
|
||||
- **ngAria:** correctly set "checked" attr for checkboxes and radios
|
||||
([944c150e](https://github.com/angular/angular.js/commit/944c150e6c3001e51d4bf5e2d8149ae4c565d1e3),
|
||||
[#10389](https://github.com/angular/angular.js/issues/10389), [#10212](https://github.com/angular/angular.js/issues/10212))
|
||||
- **ngModel:** fix issues when parserName is same as validator key
|
||||
([6b7625a0](https://github.com/angular/angular.js/commit/6b7625a09508c4b5355121a9d4206a734b07b2e1),
|
||||
[#10698](https://github.com/angular/angular.js/issues/10698), [#10850](https://github.com/angular/angular.js/issues/10850), [#11046](https://github.com/angular/angular.js/issues/11046))
|
||||
|
||||
|
||||
|
||||
<a name="1.4.0-beta.4"></a>
|
||||
# 1.4.0-beta.4 overlyexplosive-poprocks (2015-02-09)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$location:** prevent page reload if initial url has empty hash at the end
|
||||
([a509e9aa](https://github.com/angular/angular.js/commit/a509e9aa149d0f88cc39f703d539f7ffd4cd6103),
|
||||
[#10397](https://github.com/angular/angular.js/issues/10397), [#10960](https://github.com/angular/angular.js/issues/10960))
|
||||
- **$parse:** Initialize elements in an array from left to right
|
||||
([966f6d83](https://github.com/angular/angular.js/commit/966f6d831f9469a917601f9a10604612cd7bd792))
|
||||
- **ngAria:** ensure native controls fire a single click
|
||||
([9d53e5a3](https://github.com/angular/angular.js/commit/9d53e5a38dd369dec82d82e13e078df3d6054c8a),
|
||||
[#10388](https://github.com/angular/angular.js/issues/10388), [#10766](https://github.com/angular/angular.js/issues/10766))
|
||||
- **ngMock:** handle cases where injector is created before tests
|
||||
([898714df](https://github.com/angular/angular.js/commit/898714df9ea38f9ef700015ced5ddea52f096b77),
|
||||
[#10967](https://github.com/angular/angular.js/issues/10967))
|
||||
- **sanitize:** handle newline characters inside special tags
|
||||
([cc8755cd](https://github.com/angular/angular.js/commit/cc8755cda6efda0b52954388e8a8d5306e4bfbca),
|
||||
[030a42e7](https://github.com/angular/angular.js/commit/030a42e79dec8a4bb73053762f7a54d797a058f6)
|
||||
[#10943](https://github.com/angular/angular.js/issues/10943))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **ng-jq:** adds the ability to force jqLite or a specific jQuery version
|
||||
([09ee82d8](https://github.com/angular/angular.js/commit/09ee82d84dcbea4a6e8d85903af82dcd087a78a7))
|
||||
|
||||
|
||||
|
||||
<a name="1.3.13"></a>
|
||||
# 1.3.13 meticulous-riffleshuffle (2015-02-09)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$location:** prevent page reload if initial url has empty hash at the end
|
||||
([4b3a590b](https://github.com/angular/angular.js/commit/4b3a590b009d7fdceda7f52e7ba0352a271b3256),
|
||||
[#10397](https://github.com/angular/angular.js/issues/10397), [#10960](https://github.com/angular/angular.js/issues/10960))
|
||||
- **ngAria:** ensure native controls fire a single click
|
||||
([69ee593f](https://github.com/angular/angular.js/commit/69ee593fd2cb5f1d7757efbe6b256e4458752fd7),
|
||||
[#10388](https://github.com/angular/angular.js/issues/10388), [#10766](https://github.com/angular/angular.js/issues/10766))
|
||||
- **ngMock:** handle cases where injector is created before tests
|
||||
([39ddef68](https://github.com/angular/angular.js/commit/39ddef682971d3b7282bf9d08f6eaf97b7f4bca4),
|
||||
[#10967](https://github.com/angular/angular.js/issues/10967))
|
||||
- **sanitize:** handle newline characters inside special tags
|
||||
([11aedbd7](https://github.com/angular/angular.js/commit/11aedbd741ccddba060a9805adba1779391731da),
|
||||
[ce49d4d6](https://github.com/angular/angular.js/commit/ce49d4d61bd02464b6c6376af8048f6eb09330a8)
|
||||
[#10943](https://github.com/angular/angular.js/issues/10943))
|
||||
|
||||
|
||||
|
||||
<a name="1.4.0-beta.3"></a>
|
||||
# 1.4.0-beta.3 substance-mimicry (2015-02-02)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$compile:**
|
||||
- do not initialize optional '&' binding if attribute not specified
|
||||
([6a38dbfd](https://github.com/angular/angular.js/commit/6a38dbfd3c34c8f9efff503d17eb3cbeb666d422),
|
||||
[#6404](https://github.com/angular/angular.js/issues/6404), [#9216](https://github.com/angular/angular.js/issues/9216))
|
||||
- respect return value from controller constructor
|
||||
([62d514b0](https://github.com/angular/angular.js/commit/62d514b06937cc7dd86e973ea11165c88343b42d))
|
||||
- **$controller:** throw better error when controller expression is bad
|
||||
([dda65e99](https://github.com/angular/angular.js/commit/dda65e992b72044c0fa0c8f5f33184028c0e3ad7),
|
||||
[#10875](https://github.com/angular/angular.js/issues/10875), [#10910](https://github.com/angular/angular.js/issues/10910))
|
||||
- **$parse:**
|
||||
- handle null targets at assign
|
||||
([2e5a7e52](https://github.com/angular/angular.js/commit/2e5a7e52a0385575bbb55a801471b009afafeca3))
|
||||
- remove references to last arguments to a fn call
|
||||
([e61eae1b](https://github.com/angular/angular.js/commit/e61eae1b1f2351c51bcfe4142749a4e68a2806ff),
|
||||
[#10894](https://github.com/angular/angular.js/issues/10894))
|
||||
- **a:** don't reload if there is only a name attribute
|
||||
([d729fcf0](https://github.com/angular/angular.js/commit/d729fcf030be1d3ef37196d36ea3bf3249ee3318),
|
||||
[#6273](https://github.com/angular/angular.js/issues/6273), [#10880](https://github.com/angular/angular.js/issues/10880))
|
||||
- **angular.copy:** support copying `TypedArray`s
|
||||
([aa0f6449](https://github.com/angular/angular.js/commit/aa0f64496a66d2a5d1a4d033f2eb075a8b084a78),
|
||||
[#10745](https://github.com/angular/angular.js/issues/10745))
|
||||
- **filter:** format timezone correctly in the case that UTC timezone is used
|
||||
([8c469191](https://github.com/angular/angular.js/commit/8c46919199090a05634789774124b38983430c76),
|
||||
[#9359](https://github.com/angular/angular.js/issues/9359))
|
||||
- **ngRoute:** dont duplicate optional params into query
|
||||
([27bf2ce4](https://github.com/angular/angular.js/commit/27bf2ce40c5adfb1494d69c9d0ac9cf433834a12),
|
||||
[#10689](https://github.com/angular/angular.js/issues/10689))
|
||||
- **ngScenario:** allow ngScenario to handle lazy-loaded and manually bootstrapped applications
|
||||
([c69caa7b](https://github.com/angular/angular.js/commit/c69caa7beee4e920f8f587eb3e943be99864a14f),
|
||||
[#10723](https://github.com/angular/angular.js/issues/10723))
|
||||
- **validators:** maxlength should use viewValue for $isEmpty
|
||||
([bfcf9946](https://github.com/angular/angular.js/commit/bfcf9946e16d21b55dde50d4d21c71c898b10215),
|
||||
[#10898](https://github.com/angular/angular.js/issues/10898))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **$compile:** allow using bindToController as object, support both new/isolate scopes
|
||||
([35498d70](https://github.com/angular/angular.js/commit/35498d7045ba9138016464a344e2c145ce5264c1),
|
||||
[#10420](https://github.com/angular/angular.js/issues/10420), [#10467](https://github.com/angular/angular.js/issues/10467))
|
||||
- **filter:** support conversion to timezone other than UTC
|
||||
([c6d8512a](https://github.com/angular/angular.js/commit/c6d8512a1d7345516d1bd9a039d81821b9518bff),
|
||||
[#10858](https://github.com/angular/angular.js/issues/10858))
|
||||
- **ngMocks:** cleanup $inject annotations after each test
|
||||
([0baa17a3](https://github.com/angular/angular.js/commit/0baa17a3b7ad2b242df2b277b81cebdf75b04287))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
|
||||
- **$scope:** Add a property $$watchersCount to scope
|
||||
([c1500ea7](https://github.com/angular/angular.js/commit/c1500ea775c4cb130088b7d5bb5fb872bda50bae))
|
||||
- **$parse** new and more performant parser
|
||||
([0d42426](https://github.com/angular/angular.js/commit/0d424263ead16635afb582affab2b147f8e71626))
|
||||
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- **$compile:** due to [6a38dbfd](https://github.com/angular/angular.js/commit/6a38dbfd3c34c8f9efff503d17eb3cbeb666d422),
|
||||
Previously, '&' expressions would always set up a function in the isolate scope. Now, if the binding
|
||||
is marked as optional and the attribute is not specified, no function will be added to the isolate scope.
|
||||
|
||||
|
||||
<a name="1.3.12"></a>
|
||||
# 1.3.12 outlandish-knitting (2015-02-02)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$controller:** throw better error when controller expression is bad
|
||||
([632b2ddd](https://github.com/angular/angular.js/commit/632b2ddd34c07b3b5a207bd83ca3a5e6e613e63b),
|
||||
[#10875](https://github.com/angular/angular.js/issues/10875), [#10910](https://github.com/angular/angular.js/issues/10910))
|
||||
- **$parse:** remove references to last arguments to a fn call
|
||||
([7caad220](https://github.com/angular/angular.js/commit/7caad2205a6e9927890192a3638f55532bdaaf75),
|
||||
[#10894](https://github.com/angular/angular.js/issues/10894))
|
||||
- **ngRoute:** dont duplicate optional params into query
|
||||
([f41ca4a5](https://github.com/angular/angular.js/commit/f41ca4a53ed53f172fb334911be56e42aad58794),
|
||||
[#10689](https://github.com/angular/angular.js/issues/10689))
|
||||
- **ngScenario:** Allow ngScenario to handle lazy-loaded and manually bootstrapped applications
|
||||
([0bcd0872](https://github.com/angular/angular.js/commit/0bcd0872d8d2e37e6cb7aa5bc5cb0c742b4294f9),
|
||||
[#10723](https://github.com/angular/angular.js/issues/10723))
|
||||
- **validators:** maxlength should use viewValue for $isEmpty
|
||||
([abd8e2a9](https://github.com/angular/angular.js/commit/abd8e2a9eb2d21ac67989c2f7b64c4c6547a1585),
|
||||
[#10898](https://github.com/angular/angular.js/issues/10898))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **ngMocks:** cleanup $inject annotations after each test
|
||||
([6ec59460](https://github.com/angular/angular.js/commit/6ec5946094ee92b820bbacc886fa2367715e60b4))
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="1.4.0-beta.2"></a>
|
||||
# 1.4.0-beta.2 holographic-rooster (2015-01-26)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$location:** don't rewrite when link is shift-clicked
|
||||
([8b33de6f](https://github.com/angular/angular.js/commit/8b33de6fd0ec0eb785fed697f062763b5c1d8d23),
|
||||
[#9904](https://github.com/angular/angular.js/issues/9904), [#9906](https://github.com/angular/angular.js/issues/9906))
|
||||
- **$templateRequest:** cache downloaded templates as strings
|
||||
([b3a9bd3a](https://github.com/angular/angular.js/commit/b3a9bd3ae043e3042ea7ccfe08e3b36a84feb35e),
|
||||
[#10630](https://github.com/angular/angular.js/issues/10630), [#10646](https://github.com/angular/angular.js/issues/10646))
|
||||
- **filterFilter:** throw error if input is not an array
|
||||
([cea8e751](https://github.com/angular/angular.js/commit/cea8e75144e6910b806b63a6ec2a6d118316fddd),
|
||||
[#9992](https://github.com/angular/angular.js/issues/9992), [#10352](https://github.com/angular/angular.js/issues/10352))
|
||||
- **htmlAnchorDirective:**
|
||||
- remove "element !== target element" check
|
||||
([2958cd30](https://github.com/angular/angular.js/commit/2958cd308b5ebaf223a3e5df3fb5bf0f23408447),
|
||||
[#10866](https://github.com/angular/angular.js/issues/10866))
|
||||
- don't add event listener if replaced, ignore event if target is different element
|
||||
([b146af11](https://github.com/angular/angular.js/commit/b146af11271de8fa4c51c6db87df104269f41a33),
|
||||
[#4262](https://github.com/angular/angular.js/issues/4262), [#10849](https://github.com/angular/angular.js/issues/10849))
|
||||
- **ngPluralize:** fix wrong text content when count is null/undefined
|
||||
([3228d3b4](https://github.com/angular/angular.js/commit/3228d3b4991af681e57de5ab079c1e1c11cf35cb),
|
||||
[#10836](https://github.com/angular/angular.js/issues/10836), [#10841](https://github.com/angular/angular.js/issues/10841))
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- **filterFilter:** due to [cea8e751](https://github.com/angular/angular.js/commit/cea8e75144e6910b806b63a6ec2a6d118316fddd),
|
||||
Previously, the filter was not applied if used with a non array.
|
||||
Now, it throws an error. This can be worked around by converting an object to an array, using
|
||||
a filter such as https://github.com/petebacondarwin/angular-toArrayFilter
|
||||
|
||||
Closes #9992
|
||||
Closes #10352
|
||||
|
||||
|
||||
<a name="1.3.11"></a>
|
||||
# 1.3.11 spiffy-manatee (2015-01-26)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$location:** don't rewrite when link is shift-clicked
|
||||
([939ca37c](https://github.com/angular/angular.js/commit/939ca37cfe5f6fc35b09b6705caabd1fcc3cf9d3),
|
||||
[#9904](https://github.com/angular/angular.js/issues/9904), [#9906](https://github.com/angular/angular.js/issues/9906))
|
||||
- **htmlAnchorDirective:**
|
||||
- remove "element !== target element" check
|
||||
([779e3f6b](https://github.com/angular/angular.js/commit/779e3f6b5f8d2550e758cb0c5f64187ba8e00e29),
|
||||
[#10866](https://github.com/angular/angular.js/issues/10866))
|
||||
- don't add event listener if replaced, ignore event if target is different element
|
||||
([837a0775](https://github.com/angular/angular.js/commit/837a077578081bbd07863bef85241537d19fa652),
|
||||
[#4262](https://github.com/angular/angular.js/issues/4262), [#10849](https://github.com/angular/angular.js/issues/10849))
|
||||
|
||||
|
||||
<a name="1.4.0-beta.1"></a>
|
||||
# 1.4.0-beta.1 trepidatious-salamander (2015-01-20)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$animate:** ensure no transitions are applied when an empty inline style object is provided
|
||||
([0db5b21b](https://github.com/angular/angular.js/commit/0db5b21b1d09431535e0c0bf8ac63d4b5b24d349),
|
||||
[#10613](https://github.com/angular/angular.js/issues/10613), [#10770](https://github.com/angular/angular.js/issues/10770))
|
||||
- **$compile:** support class directives on SVG elements
|
||||
([23c8a90d](https://github.com/angular/angular.js/commit/23c8a90d22f7c7b41b5a756b89498ffac828980a),
|
||||
[#10736](https://github.com/angular/angular.js/issues/10736), [#10756](https://github.com/angular/angular.js/issues/10756))
|
||||
- **form:** clean up success state of controls when they are removed
|
||||
([2408f2de](https://github.com/angular/angular.js/commit/2408f2ded5ead6e678c241e38ef474c1fadff92b),
|
||||
[#10509](https://github.com/angular/angular.js/issues/10509))
|
||||
- **ngController:** allow bound constructor fns as controllers
|
||||
([d17fbc38](https://github.com/angular/angular.js/commit/d17fbc3862e0a2e646db1222f184dbe663da4a1f),
|
||||
[#10784](https://github.com/angular/angular.js/issues/10784), [#10790](https://github.com/angular/angular.js/issues/10790))
|
||||
- **ngRepeat:** do not sort object keys alphabetically
|
||||
([c260e738](https://github.com/angular/angular.js/commit/c260e7386391877625eda086480de73e8a0ba921),
|
||||
[#6210](https://github.com/angular/angular.js/issues/6210), [#10538](https://github.com/angular/angular.js/issues/10538))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **$http:** provide a config object as an argument to header functions
|
||||
([d435464c](https://github.com/angular/angular.js/commit/d435464c51d3912f56cfc830d86bfc64a1578327),
|
||||
[#7235](https://github.com/angular/angular.js/issues/7235), [#10622](https://github.com/angular/angular.js/issues/10622))
|
||||
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- **ngRepeat:** due to [c260e738](https://github.com/angular/angular.js/commit/c260e7386391877625eda086480de73e8a0ba921),
|
||||
|
||||
|
||||
Previously, the order of items when using ngRepeat to iterate
|
||||
over object properties was guaranteed to be consistent by sorting the
|
||||
keys into alphabetic order.
|
||||
|
||||
Now, the order of the items is browser dependent based on the order returned
|
||||
from iterating over the object using the `for key in obj` syntax.
|
||||
|
||||
It seems that browsers generally follow the strategy of providing
|
||||
keys in the order in which they were defined, although there are exceptions
|
||||
when keys are deleted and reinstated. See
|
||||
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete#Cross-browser_issues
|
||||
|
||||
The best approach is to convert Objects into Arrays by a filter such as
|
||||
https://github.com/petebacondarwin/angular-toArrayFilter
|
||||
or some other mechanism, and then sort them manually in the order you need.
|
||||
|
||||
Closes #6210
|
||||
Closes #10538
|
||||
|
||||
|
||||
|
||||
<a name="1.3.10"></a>
|
||||
# 1.3.10 heliotropic-sundial (2015-01-20)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$animate:** ensure no transitions are applied when an empty inline style object is provided
|
||||
([9b8df52a](https://github.com/angular/angular.js/commit/9b8df52aa960b9b6288fc150d55ea2e35f56555e),
|
||||
[#10613](https://github.com/angular/angular.js/issues/10613), [#10770](https://github.com/angular/angular.js/issues/10770))
|
||||
- **$compile:** support class directives on SVG elements
|
||||
([7a9e3360](https://github.com/angular/angular.js/commit/7a9e3360284d58197a1fe34de57f5e0f6d1f4a76),
|
||||
[#10736](https://github.com/angular/angular.js/issues/10736), [#10756](https://github.com/angular/angular.js/issues/10756))
|
||||
- **form:** clean up success state of controls when they are removed
|
||||
([cdc7280d](https://github.com/angular/angular.js/commit/cdc7280dd3d5a2ded784c06dd55fe36c2053fb6f),
|
||||
[#10509](https://github.com/angular/angular.js/issues/10509))
|
||||
- **ngController:** allow bound constructor fns as controllers
|
||||
([d015c8a8](https://github.com/angular/angular.js/commit/d015c8a80b28754633c846fc50d11c9437519486),
|
||||
[#10784](https://github.com/angular/angular.js/issues/10784), [#10790](https://github.com/angular/angular.js/issues/10790))
|
||||
|
||||
|
||||
|
||||
<a name="1.4.0-beta.0"></a>
|
||||
# 1.4.0-beta.0 photonic-umbrakinesis (2015-01-13)
|
||||
|
||||
|
||||
+7
-7
@@ -1,4 +1,4 @@
|
||||
#Contributing to AngularJS
|
||||
# Contributing to AngularJS
|
||||
|
||||
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:
|
||||
@@ -54,7 +54,7 @@ For large fixes, please build and test the documentation before submitting the P
|
||||
accidentally introduced any layout or formatting issues. You should also make sure that your commit message
|
||||
is labeled "docs:" and follows the **Git Commit Guidelines** outlined below.
|
||||
|
||||
If you're just making a small change, don't worry about filing an issue first. Use the friendly blue "Improve this doc" button at the top right of the doc page to fork the repository in-place and make a quick change on the fly. When naming the commit, it is advised to still label it according to the commit guidelines below, by starting the commit message with **docs** and referencing the filename. Since this is not obvious and some changes are made on the fly, this is not strictly necessary and we will understand if this isn't done the first few times.
|
||||
If you're just making a small change, don't worry about filing an issue first. Use the friendly blue "Improve this doc" button at the top right of the doc page to fork the repository in-place and make a quick change on the fly. When naming the commit, it is advised to still label it according to the commit guidelines below, by starting the commit message with **docs** and referencing the filename. Since this is not obvious and some changes are made on the fly, this is not strictly necessary and we will understand if this isn't done the first few times.
|
||||
|
||||
## <a name="submit"></a> Submission Guidelines
|
||||
|
||||
@@ -87,7 +87,7 @@ Before you submit your pull request consider the following guidelines:
|
||||
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.
|
||||
* Make your changes in a new git branch
|
||||
* Make your changes in a new git branch:
|
||||
|
||||
```shell
|
||||
git checkout -b my-fix-branch master
|
||||
@@ -107,7 +107,7 @@ Before you submit your pull request consider the following guidelines:
|
||||
```
|
||||
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
|
||||
* Build your changes locally to ensure all the tests pass:
|
||||
|
||||
```shell
|
||||
grunt test
|
||||
@@ -120,7 +120,7 @@ Before you submit your pull request consider the following guidelines:
|
||||
```
|
||||
|
||||
* In GitHub, send a pull request to `angular:master`.
|
||||
* If we suggest changes then
|
||||
* If we suggest changes then:
|
||||
* Make the required updates.
|
||||
* Re-run the Angular test suite to ensure tests are still passing.
|
||||
* Rebase your branch and force push to your GitHub repository (this will update your Pull Request):
|
||||
@@ -227,11 +227,11 @@ The subject contains succinct description of the change:
|
||||
* don't capitalize first letter
|
||||
* no dot (.) at the end
|
||||
|
||||
###Body
|
||||
### 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
|
||||
### Footer
|
||||
The footer should contain any information about **Breaking Changes** and is also the place to
|
||||
reference GitHub issues that this commit **Closes**.
|
||||
|
||||
|
||||
+23
-8
@@ -17,10 +17,6 @@ module.exports = function(grunt) {
|
||||
NG_VERSION.cdn = versionInfo.cdnVersion;
|
||||
var dist = 'angular-'+ NG_VERSION.full;
|
||||
|
||||
//global beforeEach
|
||||
util.init();
|
||||
|
||||
|
||||
//config
|
||||
grunt.initConfig({
|
||||
NG_VERSION: NG_VERSION,
|
||||
@@ -251,8 +247,19 @@ module.exports = function(grunt) {
|
||||
'test/**/*.js',
|
||||
'!test/ngScenario/DescribeSpec.js',
|
||||
'!src/ng/directive/attrs.js', // legitimate xit here
|
||||
'!src/ngScenario/**/*.js'
|
||||
]
|
||||
'!src/ngScenario/**/*.js',
|
||||
'!test/helpers/privateMocks*.js'
|
||||
],
|
||||
options: {
|
||||
disallowed: [
|
||||
'iit',
|
||||
'xit',
|
||||
'tthey',
|
||||
'xthey',
|
||||
'ddescribe',
|
||||
'xdescribe'
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
"merge-conflict": {
|
||||
@@ -285,6 +292,10 @@ module.exports = function(grunt) {
|
||||
},
|
||||
|
||||
shell: {
|
||||
"npm-install": {
|
||||
command: path.normalize('scripts/npm/install-dependencies.sh')
|
||||
},
|
||||
|
||||
"promises-aplus-tests": {
|
||||
options: {
|
||||
stdout: false,
|
||||
@@ -311,14 +322,18 @@ module.exports = function(grunt) {
|
||||
}
|
||||
});
|
||||
|
||||
// global beforeEach task
|
||||
if (!process.env.TRAVIS) {
|
||||
grunt.task.run('shell:npm-install');
|
||||
}
|
||||
|
||||
//alias tasks
|
||||
grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', ['jshint', 'jscs', '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 unit tests with Karma', ['tests:jquery']);
|
||||
grunt.registerTask('test:modules', 'Run the Karma module tests with Karma', ['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', ['tests:jqlite', 'tests:jquery', 'tests:modules']);
|
||||
grunt.registerTask('test:unit', 'Run unit, jQuery and Karma module tests with Karma', ['test:jqlite', 'test:jquery', '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']);
|
||||
|
||||
+5
-1
@@ -55,7 +55,11 @@ This process based on the idea of minimizing user pain
|
||||
* inconvenience - causes ugly/boilerplate code in apps
|
||||
1. Label `component: *`
|
||||
* In rare cases, it's ok to have multiple components.
|
||||
1. Label `PRs plz!` - These issues are good targets for PRs from the open source community. Apply to issues where the problem and solution are well defined in the comments, and it's not too complex.
|
||||
1. Label `PRs plz!` - These issues are good targets for PRs from the open source community. In addition to applying this label, you must:
|
||||
* Leave a comment explaining the problem and solution so someone can easily finish it.
|
||||
* Assign the issue to yourself.
|
||||
* Give feedback on PRs addressing this issue.
|
||||
* You are responsible for mentoring contributors helping with this issue.
|
||||
1. Label `origin: google` for issues from Google
|
||||
1. Assign a milestone:
|
||||
* Backlog - triaged fixes and features, should be the default choice
|
||||
|
||||
@@ -546,10 +546,10 @@ h4 {
|
||||
margin-left:10px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
color:black!important;
|
||||
.btn:hover, .btn:focus {
|
||||
color: black!important;
|
||||
border: 1px solid #ddd!important;
|
||||
background:white!important;
|
||||
background: white!important;
|
||||
}
|
||||
|
||||
.view-source, .improve-docs {
|
||||
@@ -631,6 +631,7 @@ ul.events > li {
|
||||
}
|
||||
.main-body-grid .side-navigation {
|
||||
display:block!important;
|
||||
padding-bottom:50px;
|
||||
}
|
||||
.main-body-grid .side-navigation.ng-hide {
|
||||
display:none!important;
|
||||
@@ -656,14 +657,14 @@ ul.events > li {
|
||||
}
|
||||
.toc-close {
|
||||
position: absolute;
|
||||
bottom: -50px;
|
||||
bottom: 5px;
|
||||
left: 50%;
|
||||
margin-left: -50%;
|
||||
text-align: center;
|
||||
padding: 5px;
|
||||
background: #eee;
|
||||
border-radius: 5px;
|
||||
width: 90%;
|
||||
width: 100%;
|
||||
border:1px solid #ddd;
|
||||
box-shadow:0 0 10px #bbb;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
angular.module('examples', [])
|
||||
|
||||
.factory('formPostData', ['$document', function($document) {
|
||||
return function(url, fields) {
|
||||
return function(url, newWindow, fields) {
|
||||
/**
|
||||
* Form previously posted to target="_blank", but pop-up blockers were causing this to not work.
|
||||
* If a user chose to bypass pop-up blocker one time and click the link, they would arrive at
|
||||
* a new default plnkr, not a plnkr with the desired template.
|
||||
* If the form posts to target="_blank", pop-up blockers can cause it not to work.
|
||||
* If a user choses to bypass pop-up blocker one time and click the link, they will arrive at
|
||||
* a new default plnkr, not a plnkr with the desired template. Given this undesired behavior,
|
||||
* some may still want to open the plnk in a new window by opting-in via ctrl+click. The
|
||||
* newWindow param allows for this possibility.
|
||||
*/
|
||||
var form = angular.element('<form style="display: none;" method="post" action="' + url + '"></form>');
|
||||
var target = newWindow ? '_blank' : '_self';
|
||||
var form = angular.element('<form style="display: none;" method="post" action="' + url + '" target="' + target + '"></form>');
|
||||
angular.forEach(fields, function(value, name) {
|
||||
var input = angular.element('<input type="hidden" name="' + name + '">');
|
||||
input.attr('value', value);
|
||||
@@ -21,9 +24,10 @@ angular.module('examples', [])
|
||||
|
||||
|
||||
.factory('openPlunkr', ['formPostData', '$http', '$q', function(formPostData, $http, $q) {
|
||||
return function(exampleFolder) {
|
||||
return function(exampleFolder, clickEvent) {
|
||||
|
||||
var exampleName = 'AngularJS Example';
|
||||
var newWindow = clickEvent.ctrlKey || clickEvent.metaKey;
|
||||
|
||||
// Load the manifest for the example
|
||||
$http.get(exampleFolder + '/manifest.json')
|
||||
@@ -71,7 +75,7 @@ angular.module('examples', [])
|
||||
postData.private = true;
|
||||
postData.description = exampleName;
|
||||
|
||||
formPostData('http://plnkr.co/edit/?p=preview', postData);
|
||||
formPostData('http://plnkr.co/edit/?p=preview', newWindow, postData);
|
||||
});
|
||||
};
|
||||
}]);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
is HTML and wrap each line in a <p> - thus breaking the HTML #}
|
||||
|
||||
<div>
|
||||
<a ng-click="openPlunkr('{$ doc.path $}')" class="btn pull-right">
|
||||
<a ng-click="openPlunkr('{$ doc.path $}', $event)" class="btn pull-right">
|
||||
<i class="glyphicon glyphicon-edit"> </i>
|
||||
Edit in Plunker</a>
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
@ngdoc error
|
||||
@name $controller:ctrlfmt
|
||||
@fullName Badly formed controller string
|
||||
@description
|
||||
|
||||
This error occurs when {@link ng.$controller $controller} service is called
|
||||
with a string that does not match the supported controller string formats.
|
||||
|
||||
Supported formats:
|
||||
|
||||
1. `__name__`
|
||||
2. `__name__ as __identifier__`
|
||||
|
||||
N'either `__name__` or `__identifier__` may contain spaces.
|
||||
|
||||
Example of incorrect usage that leads to this error:
|
||||
```html
|
||||
<!-- unclosed ng-controller attribute messes up the format -->
|
||||
<div ng-controller="myController>
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```js
|
||||
// does not match `__name__` or `__name__ as __identifier__`
|
||||
var myCtrl = $controller("mY contRoller", { $scope: newScope });
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```js
|
||||
directive("myDirective", function() {
|
||||
return {
|
||||
// does not match `__name__` or `__name__ as __identifier__`
|
||||
controller: "mY contRoller",
|
||||
link: function() {}
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
To fix the examples above, ensure that the controller string matches the supported
|
||||
formats, and that any html attributes which are used as controller expressions are
|
||||
closed.
|
||||
|
||||
|
||||
Please consult the {@link ng.$controller $controller} service api docs to learn more.
|
||||
@@ -16,6 +16,8 @@ Reserved names include:
|
||||
- `this`
|
||||
- `undefined`
|
||||
- `$parent`
|
||||
- `$id`
|
||||
- `$root`
|
||||
- `$even`
|
||||
- `$odd`
|
||||
- `$first`
|
||||
|
||||
@@ -37,6 +37,7 @@ Currently, ngAria interfaces with the following directives:
|
||||
* {@link guide/accessibility#nghide ngHide}
|
||||
* {@link guide/accessibility#ngclick ngClick}
|
||||
* {@link guide/accessibility#ngdblclick ngDblClick}
|
||||
* {@link guide/accessibility#ngmessages ngMessages}
|
||||
|
||||
<h2 id="ngmodel">ngModel</h2>
|
||||
|
||||
@@ -209,10 +210,16 @@ The default CSS for `ngHide`, the inverse method to `ngShow`, makes ngAria redun
|
||||
`display: none`. See explanation for {@link guide/accessibility#ngshow ngShow} when overriding the default CSS.
|
||||
|
||||
<h2><span id="ngclick">ngClick</span> and <span id="ngdblclick">ngDblclick</span></h2>
|
||||
If `ng-click` or `ng-dblclick` is encountered, ngAria will add `tabindex` if it isn't there already.
|
||||
Even with this, you must currently still add `ng-keypress` to non-interactive elements such as `div`
|
||||
or `taco-button` to enable keyboard access. Conversation is currently ongoing about whether ngAria
|
||||
should also bind `ng-keypress`.
|
||||
If `ng-click` or `ng-dblclick` is encountered, ngAria will add `tabindex="0"` if it isn't there
|
||||
already.
|
||||
|
||||
To fix widespread accessibility problems with `ng-click` on div elements, ngAria will dynamically
|
||||
bind keypress by default as long as the element isn't an anchor, button, input or textarea.
|
||||
You can turn this functionality on or off with the `bindKeypress` configuration option. ngAria
|
||||
will also add the `button` role to communicate to users of assistive technologies.
|
||||
|
||||
For `ng-dblclick`, you must still manually add `ng-keypress` and role to non-interactive elements such
|
||||
as `div` or `taco-button` to enable keyboard access.
|
||||
|
||||
<h3>Example</h3>
|
||||
```html
|
||||
@@ -223,7 +230,6 @@ Becomes:
|
||||
```html
|
||||
<div ng-click="toggleMenu()" tabindex="0"></div>
|
||||
```
|
||||
*Note: ngAria still requires `ng-keypress` to be added manually to non-native controls like divs.*
|
||||
|
||||
<h2 id="ngmessages">ngMessages</h2>
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ The example below shows how to perform animations during class changes:
|
||||
</file>
|
||||
</example>
|
||||
|
||||
Although the CSS is a little different then what we saw before, the idea is the same.
|
||||
Although the CSS is a little different than what we saw before, the idea is the same.
|
||||
|
||||
## Which directives support animations?
|
||||
|
||||
|
||||
@@ -179,11 +179,11 @@ The following graphic shows how everything works together after we introduced th
|
||||
|
||||
<img style="padding-left: 3em; padding-bottom: 1em;" src="img/guide/concepts-databinding2.png">
|
||||
|
||||
## View independent business logic: Services
|
||||
## View-independent business logic: Services
|
||||
|
||||
Right now, the `InvoiceController` contains all logic of our example. When the application grows it
|
||||
is a good practice to move view independent logic from the controller into a so called
|
||||
<a name="service">"{@link services service}"</a>, so it can be reused by other parts
|
||||
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.
|
||||
|
||||
|
||||
@@ -54,6 +54,8 @@ The following also **matches** `ngModel`:
|
||||
<input data-ng:model="foo">
|
||||
```
|
||||
|
||||
### Normalization
|
||||
|
||||
Angular **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`).
|
||||
@@ -100,6 +102,8 @@ If you want to use an HTML validating tool, you can instead use the `data`-prefi
|
||||
The other forms shown above are accepted for legacy reasons but we advise you to avoid them.
|
||||
</div>
|
||||
|
||||
### Directive types
|
||||
|
||||
`$compile` can match directives based on element names, attributes, class names, as well as comments.
|
||||
|
||||
All of the Angular-provided directives match attribute name, tag name, comments, or class name.
|
||||
@@ -751,9 +755,12 @@ own behavior to it.
|
||||
angular.module('docsIsoFnBindExample', [])
|
||||
.controller('Controller', ['$scope', '$timeout', function($scope, $timeout) {
|
||||
$scope.name = 'Tobias';
|
||||
$scope.hideDialog = function () {
|
||||
$scope.message = '';
|
||||
$scope.hideDialog = function (message) {
|
||||
$scope.message = message;
|
||||
$scope.dialogIsHidden = true;
|
||||
$timeout(function () {
|
||||
$scope.message = '';
|
||||
$scope.dialogIsHidden = false;
|
||||
}, 2000);
|
||||
};
|
||||
@@ -771,14 +778,15 @@ own behavior to it.
|
||||
</file>
|
||||
<file name="index.html">
|
||||
<div ng-controller="Controller">
|
||||
<my-dialog ng-hide="dialogIsHidden" on-close="hideDialog()">
|
||||
{{message}}
|
||||
<my-dialog ng-hide="dialogIsHidden" on-close="hideDialog(message)">
|
||||
Check out the contents, {{name}}!
|
||||
</my-dialog>
|
||||
</div>
|
||||
</file>
|
||||
<file name="my-dialog-close.html">
|
||||
<div class="alert">
|
||||
<a href class="close" ng-click="close()">×</a>
|
||||
<a href class="close" ng-click="close({message: 'closing for now'})">×</a>
|
||||
<div ng-transclude></div>
|
||||
</div>
|
||||
</file>
|
||||
@@ -795,9 +803,15 @@ callback functions to directive behaviors.
|
||||
|
||||
When the user clicks the `x` in the dialog, the directive's `close` function is called, thanks to
|
||||
`ng-click.` This call to `close` on the isolated scope actually evaluates the expression
|
||||
`hideDialog()` in the context of the original scope, thus running `Controller`'s `hideDialog`
|
||||
`hideDialog(message)` in the context of the original scope, thus running `Controller`'s `hideDialog`
|
||||
function.
|
||||
|
||||
Often it's desirable to pass data from the isolate scope via an expression to the
|
||||
parent scope, this can be done by passing a map of local variable names and values into the expression
|
||||
wrapper fn. For example, the hideDialog function takes a message to display when the dialog is hidden.
|
||||
This is specified in the directive by calling `close({message: 'closing for now'})`. Then the local
|
||||
variable `message` will be available within the `on-close` expression.
|
||||
|
||||
<div class="alert alert-success">
|
||||
**Best Practice:** use `&attr` in the `scope` option when you want your directive
|
||||
to expose an API for binding to behaviors.
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
Controls (`input`, `select`, `textarea`) are ways for a user to enter data.
|
||||
A Form is a collection of controls for the purpose of grouping related controls together.
|
||||
|
||||
Form and controls provide validation services, so that the user can be notified of invalid input.
|
||||
This provides a better user experience, because the user gets instant feedback on how to
|
||||
correct the error. Keep in mind that while client-side validation plays an important role
|
||||
in providing good user experience, it can easily be circumvented and thus can not be trusted.
|
||||
Server-side validation is still necessary for a secure application.
|
||||
Form and controls provide validation services, so that the user can be notified of invalid input
|
||||
before submitting a form. This provides a better user experience than server-side validation alone
|
||||
because the user gets instant feedback on how to correct the error. Keep in mind that while
|
||||
client-side validation plays an important role in providing good user experience, it can easily
|
||||
be circumvented and thus can not be trusted. Server-side validation is still necessary for a
|
||||
secure application.
|
||||
|
||||
|
||||
# Simple form
|
||||
|
||||
@@ -102,7 +102,7 @@ This is a short list of libraries with specific support and documentation for wo
|
||||
## Learning Resources
|
||||
|
||||
###Books
|
||||
* [AngularJS](http://www.amazon.com/AngularJS-Brad-Green/dp/1449344852) by Brad Green and Shyam Seshadri
|
||||
* [AngularJS: Up and Running](http://www.amazon.com/AngularJS-Running-Enhanced-Productivity-Structured/dp/1491901942) by Brad Green and Shyam Seshadri
|
||||
* [Mastering Web App Development](http://www.amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821) by Pawel Kozlowski and Pete Bacon Darwin
|
||||
* [AngularJS Directives](http://www.amazon.com/AngularJS-Directives-Alex-Vanston/dp/1783280336) by Alex Vanston
|
||||
* [Recipes With AngularJS](http://www.amazon.co.uk/Recipes-Angular-js-Frederik-Dietz-ebook/dp/B00DK95V48) by Frederik Dietz
|
||||
|
||||
@@ -12,7 +12,7 @@ succinctly. Angular's data binding and dependency injection eliminate much of th
|
||||
would otherwise have to write. And it all happens within the browser, making it
|
||||
an ideal partner with any server technology.
|
||||
|
||||
Angular is what HTML would have been had it been designed for applications. HTML is a great
|
||||
Angular is what HTML would have been, had it been designed for applications. HTML is a great
|
||||
declarative language for static documents. It does not contain much in the way of creating
|
||||
applications, and as a result building web applications is an exercise in *what do I have to do
|
||||
to trick the browser into doing what I want?*
|
||||
@@ -28,10 +28,10 @@ The impedance mismatch between dynamic applications and static documents is ofte
|
||||
|
||||
Angular takes another approach. It attempts to minimize the impedance mismatch between document
|
||||
centric HTML and what an application needs by creating new HTML constructs. Angular teaches the
|
||||
browser new syntax through a construct we call directives. Examples include:
|
||||
browser new syntax through a construct we call *directives*. Examples include:
|
||||
|
||||
* Data binding, as in `{{}}`.
|
||||
* DOM control structures for repeating/hiding DOM fragments.
|
||||
* DOM control structures for repeating, showing and hiding DOM fragments.
|
||||
* Support for forms and form validation.
|
||||
* Attaching new behavior to DOM elements, such as DOM event handling.
|
||||
* Grouping of HTML into reusable components.
|
||||
@@ -42,20 +42,20 @@ browser new syntax through a construct we call directives. Examples include:
|
||||
|
||||
Angular is not a single piece in the overall puzzle of building the client-side of a web
|
||||
application. It handles all of the DOM and AJAX glue code you once wrote by hand and puts it in a
|
||||
well-defined structure. This makes Angular opinionated about how a CRUD application should be
|
||||
built. But while it is opinionated, it also tries to make sure that its opinion is just a
|
||||
starting point you can easily change. Angular comes with the following out-of-the-box:
|
||||
well-defined structure. This makes Angular opinionated about how a CRUD (Create, Read, Update, Delete)
|
||||
application should be built. But while it is opinionated, it also tries to make sure that its opinion
|
||||
is just a starting point you can easily change. Angular comes with the following out-of-the-box:
|
||||
|
||||
* Everything you need to build a CRUD app in a cohesive set: data-binding, basic templating
|
||||
directives, form validation, routing, deep-linking, reusable components, dependency injection.
|
||||
* Testability story: unit-testing, end-to-end testing, mocks, test harnesses.
|
||||
* Everything you need to build a CRUD app in a cohesive set: Data-binding, basic templating
|
||||
directives, form validation, routing, deep-linking, reusable components and dependency injection.
|
||||
* Testability story: Unit-testing, end-to-end testing, mocks and test harnesses.
|
||||
* Seed application with directory layout and test scripts as a starting point.
|
||||
|
||||
|
||||
## Angular Sweet Spot
|
||||
## Angular's sweet spot
|
||||
|
||||
Angular simplifies application development by presenting a higher level of abstraction to the
|
||||
developer. Like any abstraction, it comes at a cost of flexibility. In other words not every app
|
||||
developer. Like any abstraction, it comes at a cost of flexibility. In other words, not every app
|
||||
is a good fit for Angular. Angular was built with the CRUD application in mind. Luckily CRUD
|
||||
applications represent the majority of web applications. To understand what Angular is
|
||||
good at, though, it helps to understand when an app is not a good fit for Angular.
|
||||
@@ -78,7 +78,7 @@ expressing business logic.
|
||||
* It is an excellent idea to decouple the client side of an app from the server side. This
|
||||
allows development work to progress in parallel, and allows for reuse of both sides.
|
||||
* It is very helpful indeed if the framework guides developers through the entire journey of
|
||||
building an app: from designing the UI, through writing the business logic, to testing.
|
||||
building an app: From designing the UI, through writing the business logic, to testing.
|
||||
* It is always good to make common tasks trivial and difficult tasks possible.
|
||||
|
||||
|
||||
|
||||
@@ -15,6 +15,44 @@ which drives many of these changes.
|
||||
|
||||
# Migrating from 1.2 to 1.3
|
||||
|
||||
## Controllers
|
||||
|
||||
Due to [3f2232b5](https://github.com/angular/angular.js/commit/3f2232b5a181512fac23775b1df4a6ebda67d018),
|
||||
`$controller` will no longer look for controllers on `window`.
|
||||
The old behavior of looking on `window` for controllers was originally intended
|
||||
for use in examples, demos, and toy apps. We found that allowing global controller
|
||||
functions encouraged poor practices, so we resolved to disable this behavior by
|
||||
default.
|
||||
|
||||
To migrate, register your controllers with modules rather than exposing them
|
||||
as globals:
|
||||
|
||||
Before:
|
||||
|
||||
```javascript
|
||||
function MyController() {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```javascript
|
||||
angular.module('myApp', []).controller('MyController', [function() {
|
||||
// ...
|
||||
}]);
|
||||
```
|
||||
|
||||
Although it's not recommended, you can re-enable the old behavior like this:
|
||||
|
||||
```javascript
|
||||
angular.module('myModule').config(['$controllerProvider', function($controllerProvider) {
|
||||
// this option might be handy for migrating old apps, but please don't use it
|
||||
// in new ones!
|
||||
$controllerProvider.allowGlobals();
|
||||
}]);
|
||||
```
|
||||
|
||||
## Angular Expression Parsing (`$parse` + `$interpolate`)
|
||||
|
||||
- due to [77ada4c8](https://github.com/angular/angular.js/commit/77ada4c82d6b8fc6d977c26f3cdb48c2f5fbe5a5),
|
||||
|
||||
@@ -10,13 +10,13 @@ There are a few things you might consider when running your AngularJS applicatio
|
||||
|
||||
## Disabling Debug Data
|
||||
|
||||
By default AngularJS attaches information about scopes to DOM nodes, and adds CSS classes
|
||||
to data-bound elements. The information that is not included is:
|
||||
By default AngularJS attaches information about binding and scopes to DOM nodes,
|
||||
and adds CSS classes to data-bound elements:
|
||||
|
||||
As a result of `ngBind`, `ngBindHtml` or `{{...}}` interpolations, binding data and CSS class
|
||||
`ng-class` is attached to the corresponding element.
|
||||
- As a result of `ngBind`, `ngBindHtml` or `{{...}}` interpolations, binding data and CSS class
|
||||
`ng-binding` are attached to the corresponding element.
|
||||
|
||||
Where the compiler has created a new scope, the scope and either `ng-scope` or `ng-isolated-scope`
|
||||
- Where the compiler has created a new scope, the scope and either `ng-scope` or `ng-isolated-scope`
|
||||
CSS class are attached to the corresponding element. These scope references can then be accessed via
|
||||
`element.scope()` and `element.isolateScope()`.
|
||||
|
||||
|
||||
@@ -15,14 +15,14 @@ development.
|
||||
production.
|
||||
|
||||
To point your code to an angular script on the Google CDN server, use the following template. This
|
||||
example points to the minified version 1.2.0:
|
||||
example points to the minified version 1.3.14:
|
||||
|
||||
```
|
||||
<!doctype html>
|
||||
<html ng-app>
|
||||
<head>
|
||||
<title>My Angular App</title>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
|
||||
@@ -67,7 +67,7 @@ illustration we typically build snappy apps with hundreds or thousands of active
|
||||
|
||||
### How big is the angular.js file that I need to include?
|
||||
|
||||
The size of the file is < 36KB compressed and minified.
|
||||
The size of the file is ~50KB compressed and minified.
|
||||
|
||||
|
||||
### Can I use the open-source Closure Library with Angular?
|
||||
|
||||
@@ -33,6 +33,9 @@ To see the app running in a browser, open a *separate* terminal/command line tab
|
||||
run `npm start` to start the web server. Now, open a browser window for the app and navigate to
|
||||
<a href="http://localhost:8000/app/" target="_blank">`http://localhost:8000/app/`</a>
|
||||
|
||||
Note that if you already ran the master branch app prior to checking out step-0, you may see the cached
|
||||
master version of the app in your browser window at this point. Just hit refresh to re-load the page.
|
||||
|
||||
You can now see the page in your browser. It's not very exciting, but that's OK.
|
||||
|
||||
The HTML page that displays "Nothing here yet!" was constructed with the HTML code shown below.
|
||||
@@ -62,7 +65,7 @@ __`app/index.html`:__
|
||||
|
||||
## What is the code doing?
|
||||
|
||||
* `ng-app` directive:
|
||||
**`ng-app` directive:**
|
||||
|
||||
<html ng-app>
|
||||
|
||||
@@ -74,17 +77,17 @@ __`app/index.html`:__
|
||||
This gives application developers the freedom to tell Angular if the entire html page or only a
|
||||
portion of it should be treated as the Angular application.
|
||||
|
||||
* AngularJS script tag:
|
||||
**AngularJS script tag:**
|
||||
|
||||
<script src="bower_components/angular/angular.js">
|
||||
|
||||
This code downloads the `angular.js` script and registers a callback that will be executed by the
|
||||
This code downloads the `angular.js` script which registers a callback that will be executed by the
|
||||
browser when the containing HTML page is fully downloaded. When the callback is executed, Angular
|
||||
looks for the {@link ng.directive:ngApp ngApp} directive. If
|
||||
Angular finds the directive, it will bootstrap the application with the root of the application DOM
|
||||
being the element on which the `ngApp` directive was defined.
|
||||
|
||||
* Double-curly binding with an expression:
|
||||
**Double-curly binding with an expression:**
|
||||
|
||||
Nothing here {{'yet' + '!'}}
|
||||
|
||||
@@ -108,7 +111,7 @@ being the element on which the `ngApp` directive was defined.
|
||||
## Bootstrapping AngularJS apps
|
||||
|
||||
Bootstrapping AngularJS apps automatically using the `ngApp` directive is very easy and suitable
|
||||
for most cases. In advanced cases, such as when using script loaders, you can use
|
||||
for most cases. In advanced cases, such as when using script loaders, you can use the
|
||||
{@link guide/bootstrap imperative / manual way} to bootstrap the app.
|
||||
|
||||
There are 3 important things that happen during the app bootstrap:
|
||||
|
||||
@@ -21,7 +21,7 @@ multiple views by adding routing, using an Angular module called 'ngRoute'.
|
||||
The routing functionality added by this step is provided by angular in the `ngRoute` module, which
|
||||
is distributed separately from the core Angular framework.
|
||||
|
||||
We are using [Bower][bower] to install client side dependencies. This step updates the
|
||||
We are using [Bower][bower] to install client-side dependencies. This step updates the
|
||||
`bower.json` configuration file to include the new dependency:
|
||||
|
||||
```json
|
||||
@@ -46,7 +46,7 @@ The new dependency `"angular-route": "~1.3.0"` tells bower to install a version
|
||||
angular-route component that is compatible with version 1.3.x. We must tell bower to download
|
||||
and install this dependency.
|
||||
|
||||
If you have bower installed globally then you can run `bower install` but for this project we have
|
||||
If you have bower installed globally, then you can run `bower install` but for this project, we have
|
||||
preconfigured npm to run bower install for us:
|
||||
|
||||
```
|
||||
@@ -70,7 +70,7 @@ the current "route" — the view that is currently displayed to the user.
|
||||
Application routes in Angular are declared via the {@link ngRoute.$routeProvider $routeProvider},
|
||||
which is the provider of the {@link ngRoute.$route $route service}. This service makes it easy to
|
||||
wire together controllers, view templates, and the current URL location in the browser. Using this
|
||||
feature we can implement [deep linking](http://en.wikipedia.org/wiki/Deep_linking), which lets us
|
||||
feature, we can implement [deep linking](http://en.wikipedia.org/wiki/Deep_linking), which lets us
|
||||
utilize the browser's history (back and forward navigation) and bookmarks.
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ AngularJS, so it's important for you to understand a thing or two about how it w
|
||||
|
||||
When the application bootstraps, Angular creates an injector that will be used to find and inject all
|
||||
of the services that are required by your app. The injector itself doesn't know anything about what
|
||||
`$http` or `$route` services do, in fact it doesn't even know about the existence of these services
|
||||
`$http` or `$route` services do. In fact, the injector doesn't even know about the existence of these services
|
||||
unless it is configured with proper module definitions.
|
||||
|
||||
The injector only carries out the following steps :
|
||||
@@ -295,7 +295,7 @@ phonecatControllers.controller('PhoneDetailCtrl', ['$scope', '$routeParams',
|
||||
|
||||
Again, note that we created a new module called `phonecatControllers`. For small AngularJS
|
||||
applications, it's common to create just one module for all of your controllers if there are just a
|
||||
few. As your application grows it is quite common to refactor your code into additional modules.
|
||||
few. As your application grows, it is quite common to refactor your code into additional modules.
|
||||
For larger apps, you will probably want to create separate modules for each major feature of
|
||||
your app.
|
||||
|
||||
@@ -349,7 +349,7 @@ the same binding into the `phone-list.html` template, the binding will work as e
|
||||
|
||||
<div style="display: none">
|
||||
* In `PhoneCatCtrl`, create a new model called "`hero`" with `this.hero = 'Zoro'`. In
|
||||
`PhoneListCtrl` let's shadow it with `this.hero = 'Batman'`, and in `PhoneDetailCtrl` we'll use
|
||||
`PhoneListCtrl`, let's shadow it with `this.hero = 'Batman'`. In `PhoneDetailCtrl`, we'll use
|
||||
`this.hero = "Captain Proton"`. Then add the `<p>hero = {{hero}}</p>` to all three of our templates
|
||||
(`index.html`, `phone-list.html`, and `phone-detail.html`). Open the app and you'll see scope
|
||||
inheritance and model property shadowing do some wonders.
|
||||
|
||||
@@ -31,7 +31,7 @@ phonecatControllers.controller('PhoneDetailCtrl', ['$scope', '$routeParams', '$h
|
||||
|
||||
$scope.setImage = function(imageUrl) {
|
||||
$scope.mainImageUrl = imageUrl;
|
||||
}
|
||||
};
|
||||
}]);
|
||||
```
|
||||
|
||||
|
||||
@@ -288,5 +288,5 @@ learn how to improve this application with animations.
|
||||
<ul doc-tutorial-nav="11"></ul>
|
||||
|
||||
[restful]: http://en.wikipedia.org/wiki/Representational_State_Transfer
|
||||
[jasmine-matchers]: https://github.com/pivotal/jasmine/wiki/Matchers
|
||||
[jasmine-matchers]: http://jasmine.github.io/1.3/introduction.html#section-Matchers
|
||||
[bower]: http://bower.io/
|
||||
|
||||
@@ -2912,16 +2912,12 @@ goog.i18n.DateTimeSymbols_my = {
|
||||
'ဇွန်', 'ဇူလိုင်', 'ဩဂုတ်',
|
||||
'စက်တင်ဘာ', 'အောက်တိုဘာ',
|
||||
'နိုဝင်ဘာ', 'ဒီဇင်ဘာ'],
|
||||
SHORTMONTHS: ['ဇန်နဝါရီ', 'ဖေဖော်ဝါရီ',
|
||||
'မတ်', 'ဧပြီ', 'မေ', 'ဇွန်',
|
||||
'ဇူလိုင်', 'ဩဂုတ်', 'စက်တင်ဘာ',
|
||||
'အောက်တိုဘာ', 'နိုဝင်ဘာ',
|
||||
'ဒီဇင်ဘာ'],
|
||||
STANDALONESHORTMONTHS: ['ဇန်နဝါရီ',
|
||||
'ဖေဖော်ဝါရီ', 'မတ်', 'ဧပြီ', 'မေ',
|
||||
'ဇွန်', 'ဇူလိုင်', 'ဩဂုတ်',
|
||||
'စက်တင်ဘာ', 'အောက်တိုဘာ',
|
||||
'နိုဝင်ဘာ', 'ဒီဇင်ဘာ'],
|
||||
SHORTMONTHS: ['ဇန်', 'ဖေ', 'မတ်', 'ဧပြီ', 'မေ',
|
||||
'ဇွန်', 'ဇူ', 'ဩ', 'စက်', 'အောက်',
|
||||
'နို', 'ဒီ'],
|
||||
STANDALONESHORTMONTHS: ['ဇန်', 'ဖေ', 'မတ်', 'ဧပြီ',
|
||||
'မေ', 'ဇွန်', 'ဇူ', 'ဩ', 'စက်', 'အောက်',
|
||||
'နို', 'ဒီ'],
|
||||
WEEKDAYS: ['တနင်္ဂနွေ', 'တနင်္လာ',
|
||||
'အင်္ဂါ', 'ဗုဒ္ဓဟူး',
|
||||
'ကြာသပတေး', 'သောကြာ', 'စနေ'],
|
||||
@@ -2945,7 +2941,7 @@ goog.i18n.DateTimeSymbols_my = {
|
||||
'တတိယ သုံးလပတ်',
|
||||
'စတုတ္ထ သုံးလပတ်'],
|
||||
AMPMS: ['နံနက်', 'ညနေ'],
|
||||
DATEFORMATS: ['EEEE, y MMMM dd', 'y MMMM d', 'y MMM d', 'yy/MM/dd'],
|
||||
DATEFORMATS: ['EEEE, dd MMMM y', 'd MMMM y', 'd MMM y', 'dd-MM-yy'],
|
||||
TIMEFORMATS: ['HH:mm:ss zzzz', 'HH:mm:ss z', 'HH:mm:ss', 'HH:mm'],
|
||||
DATETIMEFORMATS: ['{1}မှာ {0}', '{1} {0}', '{1} {0}', '{1} {0}'],
|
||||
FIRSTDAYOFWEEK: 6,
|
||||
|
||||
@@ -14493,16 +14493,12 @@ goog.i18n.DateTimeSymbols_my_MM = {
|
||||
'ဇွန်', 'ဇူလိုင်', 'ဩဂုတ်',
|
||||
'စက်တင်ဘာ', 'အောက်တိုဘာ',
|
||||
'နိုဝင်ဘာ', 'ဒီဇင်ဘာ'],
|
||||
SHORTMONTHS: ['ဇန်နဝါရီ', 'ဖေဖော်ဝါရီ',
|
||||
'မတ်', 'ဧပြီ', 'မေ', 'ဇွန်',
|
||||
'ဇူလိုင်', 'ဩဂုတ်', 'စက်တင်ဘာ',
|
||||
'အောက်တိုဘာ', 'နိုဝင်ဘာ',
|
||||
'ဒီဇင်ဘာ'],
|
||||
STANDALONESHORTMONTHS: ['ဇန်နဝါရီ',
|
||||
'ဖေဖော်ဝါရီ', 'မတ်', 'ဧပြီ', 'မေ',
|
||||
'ဇွန်', 'ဇူလိုင်', 'ဩဂုတ်',
|
||||
'စက်တင်ဘာ', 'အောက်တိုဘာ',
|
||||
'နိုဝင်ဘာ', 'ဒီဇင်ဘာ'],
|
||||
SHORTMONTHS: ['ဇန်', 'ဖေ', 'မတ်', 'ဧပြီ', 'မေ',
|
||||
'ဇွန်', 'ဇူ', 'ဩ', 'စက်', 'အောက်',
|
||||
'နို', 'ဒီ'],
|
||||
STANDALONESHORTMONTHS: ['ဇန်', 'ဖေ', 'မတ်', 'ဧပြီ',
|
||||
'မေ', 'ဇွန်', 'ဇူ', 'ဩ', 'စက်', 'အောက်',
|
||||
'နို', 'ဒီ'],
|
||||
WEEKDAYS: ['တနင်္ဂနွေ', 'တနင်္လာ',
|
||||
'အင်္ဂါ', 'ဗုဒ္ဓဟူး',
|
||||
'ကြာသပတေး', 'သောကြာ', 'စနေ'],
|
||||
@@ -14526,7 +14522,7 @@ goog.i18n.DateTimeSymbols_my_MM = {
|
||||
'တတိယ သုံးလပတ်',
|
||||
'စတုတ္ထ သုံးလပတ်'],
|
||||
AMPMS: ['နံနက်', 'ညနေ'],
|
||||
DATEFORMATS: ['EEEE, y MMMM dd', 'y MMMM d', 'y MMM d', 'yy/MM/dd'],
|
||||
DATEFORMATS: ['EEEE, dd MMMM y', 'd MMMM y', 'd MMM y', 'dd-MM-yy'],
|
||||
TIMEFORMATS: ['HH:mm:ss zzzz', 'HH:mm:ss z', 'HH:mm:ss', 'HH:mm'],
|
||||
DATETIMEFORMATS: ['{1}မှာ {0}', '{1} {0}', '{1} {0}', '{1} {0}'],
|
||||
FIRSTDAYOFWEEK: 6,
|
||||
|
||||
@@ -2112,7 +2112,7 @@ goog.i18n.NumberFormatSymbols_lt = {
|
||||
SCIENTIFIC_PATTERN: '#E0',
|
||||
PERCENT_PATTERN: '#,##0\u00A0%',
|
||||
CURRENCY_PATTERN: '#,##0.00\u00A0\u00A4',
|
||||
DEF_CURRENCY_CODE: 'LTL'
|
||||
DEF_CURRENCY_CODE: 'EUR'
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -185,6 +185,8 @@ describe("extractDateTimeSymbols", function() {
|
||||
DAY: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
|
||||
SHORTDAY: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],
|
||||
AMPMS: ['AM', 'PM'],
|
||||
ERAS: ['av. J.-C.', 'ap. J.-C.'],
|
||||
ERANAMES: ['avant Jésus-Christ', 'après Jésus-Christ'],
|
||||
medium: 'yyyy-MM-dd HH:mm:ss',
|
||||
short: 'yy-MM-dd HH:mm',
|
||||
fullDate: 'EEEE d MMMM y',
|
||||
|
||||
@@ -42,6 +42,8 @@ function convertDatetimeData(dataObj) {
|
||||
datetimeFormats.DAY = dataObj.WEEKDAYS;
|
||||
datetimeFormats.SHORTDAY = dataObj.SHORTWEEKDAYS;
|
||||
datetimeFormats.AMPMS = dataObj.AMPMS;
|
||||
datetimeFormats.ERAS = dataObj.ERAS;
|
||||
datetimeFormats.ERANAMES = dataObj.ERANAMES;
|
||||
|
||||
|
||||
datetimeFormats.medium = dataObj.DATEFORMATS[2] + ' ' + dataObj.TIMEFORMATS[2];
|
||||
|
||||
@@ -35,18 +35,18 @@ module.exports = function(config, specificOptions) {
|
||||
'SL_Chrome': {
|
||||
base: 'SauceLabs',
|
||||
browserName: 'chrome',
|
||||
version: '34'
|
||||
version: '39'
|
||||
},
|
||||
'SL_Firefox': {
|
||||
base: 'SauceLabs',
|
||||
browserName: 'firefox',
|
||||
version: '26'
|
||||
version: '31'
|
||||
},
|
||||
'SL_Safari': {
|
||||
base: 'SauceLabs',
|
||||
browserName: 'safari',
|
||||
platform: 'OS X 10.9',
|
||||
version: '7'
|
||||
platform: 'OS X 10.10',
|
||||
version: '8'
|
||||
},
|
||||
'SL_IE_9': {
|
||||
base: 'SauceLabs',
|
||||
@@ -71,13 +71,13 @@ module.exports = function(config, specificOptions) {
|
||||
base: 'BrowserStack',
|
||||
browser: 'chrome',
|
||||
os: 'OS X',
|
||||
os_version: 'Mountain Lion'
|
||||
os_version: 'Yosemite'
|
||||
},
|
||||
'BS_Safari': {
|
||||
base: 'BrowserStack',
|
||||
browser: 'safari',
|
||||
os: 'OS X',
|
||||
os_version: 'Mountain Lion'
|
||||
os_version: 'Yosemite'
|
||||
},
|
||||
'BS_Firefox': {
|
||||
base: 'BrowserStack',
|
||||
|
||||
@@ -14,13 +14,6 @@ var CSP_CSS_HEADER = '/* Include this file in your html if you are using the CSP
|
||||
|
||||
module.exports = {
|
||||
|
||||
init: function() {
|
||||
if (!process.env.TRAVIS) {
|
||||
shell.exec('npm install');
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
startKarma: function(config, singleRun, done){
|
||||
var browsers = grunt.option('browsers');
|
||||
var reporters = grunt.option('reporters');
|
||||
|
||||
@@ -12,9 +12,9 @@ set -e
|
||||
# before_script:
|
||||
# - curl https://gist.github.com/santiycr/5139565/raw/sauce_connect_setup.sh | bash
|
||||
|
||||
CONNECT_URL="https://saucelabs.com/downloads/sc-4.3-linux.tar.gz"
|
||||
CONNECT_URL="https://saucelabs.com/downloads/sc-4.3.7-linux.tar.gz"
|
||||
CONNECT_DIR="/tmp/sauce-connect-$RANDOM"
|
||||
CONNECT_DOWNLOAD="sc-4.3-linux.tar.gz"
|
||||
CONNECT_DOWNLOAD="sc-4.3.7-linux.tar.gz"
|
||||
|
||||
CONNECT_LOG="$LOGS_DIR/sauce-connect"
|
||||
CONNECT_STDOUT="$LOGS_DIR/sauce-connect.stdout"
|
||||
@@ -46,5 +46,5 @@ echo "Starting Sauce Connect in the background, logging into:"
|
||||
echo " $CONNECT_LOG"
|
||||
echo " $CONNECT_STDOUT"
|
||||
echo " $CONNECT_STDERR"
|
||||
sauce-connect/bin/sc -u $SAUCE_USERNAME -k $SAUCE_ACCESS_KEY $ARGS -v \
|
||||
sauce-connect/bin/sc -u $SAUCE_USERNAME -k $SAUCE_ACCESS_KEY $ARGS \
|
||||
--logfile $CONNECT_LOG 2> $CONNECT_STDERR 1> $CONNECT_STDOUT &
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Generated
+6631
-1505
File diff suppressed because it is too large
Load Diff
+7
-2
@@ -5,6 +5,11 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/angular/angular.js.git"
|
||||
},
|
||||
"engines": {
|
||||
"node": "~0.10",
|
||||
"npm": "~2.5"
|
||||
},
|
||||
"engineStrict": true,
|
||||
"devDependencies": {
|
||||
"angular-benchpress": "0.x.x",
|
||||
"benchmark": "1.x.x",
|
||||
@@ -24,7 +29,7 @@
|
||||
"grunt-contrib-jshint": "~0.10.0",
|
||||
"grunt-ddescribe-iit": "~0.0.1",
|
||||
"grunt-jasmine-node": "git://github.com/vojtajina/grunt-jasmine-node.git#fix-grunt-exit-code",
|
||||
"grunt-jscs": "~0.7.1",
|
||||
"grunt-jscs": "~1.2.0",
|
||||
"grunt-merge-conflict": "~0.0.1",
|
||||
"grunt-shell": "~1.1.1",
|
||||
"gulp": "~3.8.0",
|
||||
@@ -38,7 +43,7 @@
|
||||
"jasmine-node": "~1.14.5",
|
||||
"jasmine-reporters": "~1.0.1",
|
||||
"jshint-stylish": "~1.0.0",
|
||||
"karma": "vojtajina/karma#socketio_10",
|
||||
"karma": "0.12.32",
|
||||
"karma-browserstack-launcher": "0.1.2",
|
||||
"karma-chrome-launcher": "0.1.5",
|
||||
"karma-firefox-launcher": "0.1.3",
|
||||
|
||||
@@ -63,6 +63,21 @@ function prepare {
|
||||
cp $BUILD_DIR/angular-csp.css $TMP_DIR/bower-angular
|
||||
|
||||
|
||||
#
|
||||
# Run local precommit script if there is one
|
||||
#
|
||||
for repo in "${REPOS[@]}"
|
||||
do
|
||||
if [ -f $TMP_DIR/bower-$repo/precommit.sh ]
|
||||
then
|
||||
echo "-- Running precommit.sh script for bower-$repo"
|
||||
cd $TMP_DIR/bower-$repo
|
||||
$TMP_DIR/bower-$repo/precommit.sh
|
||||
cd $SCRIPT_DIR
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
#
|
||||
# update bower.json
|
||||
# tag each repo
|
||||
|
||||
@@ -10,22 +10,17 @@
|
||||
var _ = require('lodash');
|
||||
var sorted = require('sorted-object');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
|
||||
function cleanModule(module, name) {
|
||||
|
||||
// keep `from` and `resolve` properties for git dependencies, delete otherwise
|
||||
if (!(module.resolved && module.resolved.match(/^git:\/\//))) {
|
||||
delete module.from;
|
||||
// keep `resolve` properties for git dependencies, delete otherwise
|
||||
delete module.from;
|
||||
if (!(module.resolved && module.resolved.match(/^git(\+[a-z]+)?:\/\//))) {
|
||||
delete module.resolved;
|
||||
}
|
||||
|
||||
if (name === 'chokidar') {
|
||||
if (module.version === '0.8.1') {
|
||||
delete module.dependencies;
|
||||
}
|
||||
}
|
||||
|
||||
_.forEach(module.dependencies, function(mod, name) {
|
||||
cleanModule(mod, name);
|
||||
});
|
||||
@@ -33,10 +28,11 @@ function cleanModule(module, name) {
|
||||
|
||||
|
||||
console.log('Reading npm-shrinkwrap.json');
|
||||
var shrinkwrap = require('./../npm-shrinkwrap.json');
|
||||
var shrinkwrap = require('../../npm-shrinkwrap.json');
|
||||
|
||||
console.log('Cleaning shrinkwrap object');
|
||||
cleanModule(shrinkwrap, shrinkwrap.name);
|
||||
|
||||
console.log('Writing cleaned npm-shrinkwrap.json');
|
||||
fs.writeFileSync('./npm-shrinkwrap.json', JSON.stringify(sorted(shrinkwrap), null, 2) + "\n");
|
||||
var cleanShrinkwrapPath = path.join(__dirname, '..', '..', 'npm-shrinkwrap.clean.json');
|
||||
console.log('Writing cleaned to', cleanShrinkwrapPath);
|
||||
fs.writeFileSync(cleanShrinkwrapPath, JSON.stringify(sorted(shrinkwrap), null, 2) + "\n");
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
SHRINKWRAP_FILE=npm-shrinkwrap.json
|
||||
SHRINKWRAP_CACHED_FILE=node_modules/npm-shrinkwrap.cached.json
|
||||
|
||||
if diff -q $SHRINKWRAP_FILE $SHRINKWRAP_CACHED_FILE; then
|
||||
echo 'No shrinkwrap changes detected. npm install will be skipped...';
|
||||
else
|
||||
echo 'Blowing away node_modules and reinstalling npm dependencies...'
|
||||
rm -rf node_modules
|
||||
npm install
|
||||
cp $SHRINKWRAP_FILE $SHRINKWRAP_CACHED_FILE
|
||||
echo 'npm install successful!'
|
||||
fi
|
||||
+18
-8
@@ -317,8 +317,7 @@ function nextUid() {
|
||||
function setHashKey(obj, h) {
|
||||
if (h) {
|
||||
obj.$$hashKey = h;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
delete obj.$$hashKey;
|
||||
}
|
||||
}
|
||||
@@ -483,6 +482,12 @@ function isString(value) {return typeof value === 'string';}
|
||||
* @description
|
||||
* Determines if a reference is a `Number`.
|
||||
*
|
||||
* This includes the "special" numbers `NaN`, `+Infinity` and `-Infinity`.
|
||||
*
|
||||
* If you wish to exclude these then you can use the native
|
||||
* [`isFinite'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite)
|
||||
* method.
|
||||
*
|
||||
* @param {*} value Reference to check.
|
||||
* @returns {boolean} True if `value` is a `Number`.
|
||||
*/
|
||||
@@ -627,7 +632,7 @@ function isElement(node) {
|
||||
function makeMap(str) {
|
||||
var obj = {}, items = str.split(","), i;
|
||||
for (i = 0; i < items.length; i++)
|
||||
obj[ items[i] ] = true;
|
||||
obj[items[i]] = true;
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -851,10 +856,11 @@ function equals(o1, o2) {
|
||||
} else if (isDate(o1)) {
|
||||
if (!isDate(o2)) return false;
|
||||
return equals(o1.getTime(), o2.getTime());
|
||||
} else if (isRegExp(o1) && isRegExp(o2)) {
|
||||
return o1.toString() == o2.toString();
|
||||
} else if (isRegExp(o1)) {
|
||||
return isRegExp(o2) ? o1.toString() == o2.toString() : false;
|
||||
} else {
|
||||
if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) || isArray(o2)) return false;
|
||||
if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) ||
|
||||
isArray(o2) || isDate(o2) || isRegExp(o2)) return false;
|
||||
keySet = {};
|
||||
for (key in o1) {
|
||||
if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
|
||||
@@ -1338,7 +1344,7 @@ function angularInit(element, bootstrap) {
|
||||
* @param {DOMElement} element DOM element which is the root of angular application.
|
||||
* @param {Array<String|Function|Array>=} modules an array of modules to load into the application.
|
||||
* Each item in the array should be the name of a predefined module or a (DI annotated)
|
||||
* function that will be invoked by the injector as a run block.
|
||||
* function that will be invoked by the injector as a `config` block.
|
||||
* See: {@link angular.module modules}
|
||||
* @param {Object=} config an object for defining configuration options for the application. The
|
||||
* following keys are supported:
|
||||
@@ -1408,8 +1414,12 @@ function bootstrap(element, modules, config) {
|
||||
forEach(extraModules, function(module) {
|
||||
modules.push(module);
|
||||
});
|
||||
doBootstrap();
|
||||
return doBootstrap();
|
||||
};
|
||||
|
||||
if (isFunction(angular.resumeDeferredBootstrap)) {
|
||||
angular.resumeDeferredBootstrap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -800,7 +800,7 @@ function createInjector(modulesToLoad, strictDi) {
|
||||
}
|
||||
|
||||
var args = [],
|
||||
$inject = annotate(fn, strictDi, serviceName),
|
||||
$inject = createInjector.$$annotate(fn, strictDi, serviceName),
|
||||
length, i,
|
||||
key;
|
||||
|
||||
@@ -829,7 +829,7 @@ function createInjector(modulesToLoad, strictDi) {
|
||||
// Check if Type is annotated and use just the given function at n-1 as parameter
|
||||
// e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);
|
||||
// Object creation: http://jsperf.com/create-constructor/2
|
||||
var instance = Object.create((isArray(Type) ? Type[Type.length - 1] : Type).prototype);
|
||||
var instance = Object.create((isArray(Type) ? Type[Type.length - 1] : Type).prototype || null);
|
||||
var returnedValue = invoke(Type, instance, locals, serviceName);
|
||||
|
||||
return isObject(returnedValue) || isFunction(returnedValue) ? returnedValue : instance;
|
||||
@@ -839,7 +839,7 @@ function createInjector(modulesToLoad, strictDi) {
|
||||
invoke: invoke,
|
||||
instantiate: instantiate,
|
||||
get: getService,
|
||||
annotate: annotate,
|
||||
annotate: createInjector.$$annotate,
|
||||
has: function(name) {
|
||||
return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Any commits to this file should be reviewed with security in mind. *
|
||||
* Changes to this file can potentially create security vulnerabilities. *
|
||||
* An approval from 2 Core members with history of modifying *
|
||||
* this file is required. *
|
||||
* *
|
||||
* Does the change somehow allow for arbitrary javascript to be executed? *
|
||||
* Or allows for someone to change the prototype of built-in objects? *
|
||||
* Or gives undesired access to variables likes document or window? *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/* global JQLitePrototype: true,
|
||||
addEventListenerFn: true,
|
||||
removeEventListenerFn: true,
|
||||
|
||||
@@ -210,6 +210,7 @@ var $AnimateProvider = ['$provide', function($provide) {
|
||||
* @return {Promise} the animation callback promise
|
||||
*/
|
||||
leave: function(element, options) {
|
||||
applyStyles(element, options);
|
||||
element.remove();
|
||||
return asyncPromise();
|
||||
},
|
||||
|
||||
+9
-1
@@ -233,11 +233,19 @@ function Browser(window, document, $log, $sniffer) {
|
||||
fireUrlChange();
|
||||
}
|
||||
|
||||
function getCurrentState() {
|
||||
try {
|
||||
return history.state;
|
||||
} catch (e) {
|
||||
// MSIE can reportedly throw when there is no state (UNCONFIRMED).
|
||||
}
|
||||
}
|
||||
|
||||
// This variable should be used *only* inside the cacheState function.
|
||||
var lastCachedState = null;
|
||||
function cacheState() {
|
||||
// This should be the only place in $browser where `history.state` is read.
|
||||
cachedState = window.history.state;
|
||||
cachedState = getCurrentState();
|
||||
cachedState = isUndefined(cachedState) ? null : cachedState;
|
||||
|
||||
// Prevent callbacks fo fire twice if both hashchange & popstate were fired.
|
||||
|
||||
@@ -372,7 +372,7 @@ function $CacheFactoryProvider() {
|
||||
* the document, but it must be a descendent of the {@link ng.$rootElement $rootElement} (IE,
|
||||
* element with ng-app attribute), otherwise the template will be ignored.
|
||||
*
|
||||
* Adding via the $templateCache service:
|
||||
* Adding via the `$templateCache` service:
|
||||
*
|
||||
* ```js
|
||||
* var myApp = angular.module('myApp', []);
|
||||
|
||||
+18
-3
@@ -1,5 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Any commits to this file should be reviewed with security in mind. *
|
||||
* Changes to this file can potentially create security vulnerabilities. *
|
||||
* An approval from 2 Core members with history of modifying *
|
||||
* this file is required. *
|
||||
* *
|
||||
* Does the change somehow allow for arbitrary javascript to be executed? *
|
||||
* Or allows for someone to change the prototype of built-in objects? *
|
||||
* Or gives undesired access to variables likes document or window? *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/* ! VARIABLE/FUNCTION NAMING CONVENTIONS THAT APPLY TO THIS FILE!
|
||||
*
|
||||
* DOM-related variables:
|
||||
@@ -211,7 +222,8 @@
|
||||
* Require another directive and inject its controller as the fourth argument to the linking function. The
|
||||
* `require` takes a string name (or array of strings) of the directive(s) to pass in. If an array is used, the
|
||||
* injected argument will be an array in corresponding order. If no such directive can be
|
||||
* found, or if the directive does not have a controller, then an error is raised. The name can be prefixed with:
|
||||
* found, or if the directive does not have a controller, then an error is raised (unless no link function
|
||||
* is specified, in which case error checking is skipped). The name can be prefixed with:
|
||||
*
|
||||
* * (no prefix) - Locate the required controller on the current element. Throw an error if not found.
|
||||
* * `?` - Attempt to locate the required controller or pass `null` to the `link` fn if not found.
|
||||
@@ -1450,6 +1462,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
|
||||
// use class as directive
|
||||
className = node.className;
|
||||
if (isObject(className)) {
|
||||
// Maybe SVGAnimatedString
|
||||
className = className.animVal;
|
||||
}
|
||||
if (isString(className) && className !== '') {
|
||||
while (match = CLASS_DIRECTIVE_REGEXP.exec(className)) {
|
||||
nName = directiveNormalize(match[2]);
|
||||
@@ -2151,8 +2167,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
afterTemplateChildLinkFn,
|
||||
beforeTemplateCompileNode = $compileNode[0],
|
||||
origAsyncDirective = directives.shift(),
|
||||
// The fact that we have to copy and patch the directive seems wrong!
|
||||
derivedSyncDirective = extend({}, origAsyncDirective, {
|
||||
derivedSyncDirective = inherit(origAsyncDirective, {
|
||||
templateUrl: null, transclude: null, replace: null, $$originalDirective: origAsyncDirective
|
||||
}),
|
||||
templateUrl = (isFunction(origAsyncDirective.templateUrl))
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
var $controllerMinErr = minErr('$controller');
|
||||
|
||||
/**
|
||||
* @ngdoc provider
|
||||
* @name $controllerProvider
|
||||
@@ -87,7 +89,12 @@ function $ControllerProvider() {
|
||||
}
|
||||
|
||||
if (isString(expression)) {
|
||||
match = expression.match(CNTRL_REG),
|
||||
match = expression.match(CNTRL_REG);
|
||||
if (!match) {
|
||||
throw $controllerMinErr('ctrlfmt',
|
||||
"Badly formed controller string '{0}'. " +
|
||||
"Must match `__name__ as __id__` or `__name__`.", expression);
|
||||
}
|
||||
constructor = match[1],
|
||||
identifier = identifier || match[3];
|
||||
expression = controllers.hasOwnProperty(constructor)
|
||||
@@ -111,7 +118,7 @@ function $ControllerProvider() {
|
||||
// Object creation: http://jsperf.com/create-constructor/2
|
||||
var controllerPrototype = (isArray(expression) ?
|
||||
expression[expression.length - 1] : expression).prototype;
|
||||
instance = Object.create(controllerPrototype);
|
||||
instance = Object.create(controllerPrototype || null);
|
||||
|
||||
if (identifier) {
|
||||
addIdentifier(locals, identifier, instance, constructor || expression.name);
|
||||
|
||||
@@ -18,6 +18,9 @@ var htmlAnchorDirective = valueFn({
|
||||
compile: function(element, attr) {
|
||||
if (!attr.href && !attr.xlinkHref && !attr.name) {
|
||||
return function(scope, element) {
|
||||
// If the linked element is not an anchor tag anymore, do nothing
|
||||
if (element[0].nodeName.toLowerCase() !== 'a') return;
|
||||
|
||||
// SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.
|
||||
var href = toString.call(element.prop('href')) === '[object SVGAnimatedString]' ?
|
||||
'xlink:href' : 'href';
|
||||
|
||||
@@ -159,20 +159,24 @@
|
||||
*
|
||||
* @description
|
||||
*
|
||||
* We shouldn't do this, because it will make the button enabled on Chrome/Firefox but not on IE8 and older IEs:
|
||||
* This directive sets the `disabled` attribute on the element if the
|
||||
* {@link guide/expression expression} inside `ngDisabled` evaluates to truthy.
|
||||
*
|
||||
* A special directive is necessary because we cannot use interpolation inside the `disabled`
|
||||
* attribute. The following example would make the button enabled on Chrome/Firefox
|
||||
* but not on older IEs:
|
||||
*
|
||||
* ```html
|
||||
* <div ng-init="scope = { isDisabled: false }">
|
||||
* <button disabled="{{scope.isDisabled}}">Disabled</button>
|
||||
* <!-- See below for an example of ng-disabled being used correctly -->
|
||||
* <div ng-init="isDisabled = false">
|
||||
* <button disabled="{{isDisabled}}">Disabled</button>
|
||||
* </div>
|
||||
* ```
|
||||
*
|
||||
* The HTML specification does not require browsers to preserve the values of boolean attributes
|
||||
* such as disabled. (Their presence means true and their absence means false.)
|
||||
* This is because the HTML specification does not require browsers to preserve the values of
|
||||
* boolean attributes such as `disabled` (Their presence means true and their absence means false.)
|
||||
* If we put an Angular interpolation expression into such an attribute then the
|
||||
* binding information would be lost when the browser removes the attribute.
|
||||
* The `ngDisabled` directive solves this problem for the `disabled` attribute.
|
||||
* This complementary directive is not removed by the browser and so provides
|
||||
* a permanent reliable place to store the binding information.
|
||||
*
|
||||
* @example
|
||||
<example>
|
||||
@@ -191,7 +195,7 @@
|
||||
*
|
||||
* @element INPUT
|
||||
* @param {expression} ngDisabled If the {@link guide/expression expression} is truthy,
|
||||
* then special attribute "disabled" will be set on the element
|
||||
* then the `disabled` attribute will be set on the element
|
||||
*/
|
||||
|
||||
|
||||
|
||||
+23
-20
@@ -163,6 +163,9 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
|
||||
forEach(form.$error, function(value, name) {
|
||||
form.$setValidity(name, null, control);
|
||||
});
|
||||
forEach(form.$$success, function(value, name) {
|
||||
form.$setValidity(name, null, control);
|
||||
});
|
||||
|
||||
arrayRemove(controls, control);
|
||||
};
|
||||
@@ -180,23 +183,23 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
|
||||
addSetValidityMethod({
|
||||
ctrl: this,
|
||||
$element: element,
|
||||
set: function(object, property, control) {
|
||||
set: function(object, property, controller) {
|
||||
var list = object[property];
|
||||
if (!list) {
|
||||
object[property] = [control];
|
||||
object[property] = [controller];
|
||||
} else {
|
||||
var index = list.indexOf(control);
|
||||
var index = list.indexOf(controller);
|
||||
if (index === -1) {
|
||||
list.push(control);
|
||||
list.push(controller);
|
||||
}
|
||||
}
|
||||
},
|
||||
unset: function(object, property, control) {
|
||||
unset: function(object, property, controller) {
|
||||
var list = object[property];
|
||||
if (!list) {
|
||||
return;
|
||||
}
|
||||
arrayRemove(list, control);
|
||||
arrayRemove(list, controller);
|
||||
if (list.length === 0) {
|
||||
delete object[property];
|
||||
}
|
||||
@@ -313,7 +316,7 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
|
||||
*
|
||||
* # Alias: {@link ng.directive:ngForm `ngForm`}
|
||||
*
|
||||
* In Angular forms can be nested. This means that the outer form is valid when all of the child
|
||||
* In Angular, forms can be nested. This means that the outer form is valid when all of the child
|
||||
* forms are valid as well. However, browsers do not allow nesting of `<form>` elements, so
|
||||
* Angular provides the {@link ng.directive:ngForm `ngForm`} directive which behaves identically to
|
||||
* `<form>` but can be nested. This allows you to have nested forms, which is very useful when
|
||||
@@ -451,10 +454,12 @@ var formDirectiveFactory = function(isNgForm) {
|
||||
name: 'form',
|
||||
restrict: isNgForm ? 'EAC' : 'E',
|
||||
controller: FormController,
|
||||
compile: function ngFormCompile(formElement) {
|
||||
compile: function ngFormCompile(formElement, attr) {
|
||||
// Setup initial state of the control
|
||||
formElement.addClass(PRISTINE_CLASS).addClass(VALID_CLASS);
|
||||
|
||||
var nameAttr = attr.name ? 'name' : (isNgForm && attr.ngForm ? 'ngForm' : false);
|
||||
|
||||
return {
|
||||
pre: function ngFormPreLink(scope, formElement, attr, controller) {
|
||||
// if `action` attr is not present on the form, prevent the default action (submission)
|
||||
@@ -485,23 +490,21 @@ var formDirectiveFactory = function(isNgForm) {
|
||||
});
|
||||
}
|
||||
|
||||
var parentFormCtrl = controller.$$parentForm,
|
||||
alias = controller.$name;
|
||||
var parentFormCtrl = controller.$$parentForm;
|
||||
|
||||
if (alias) {
|
||||
setter(scope, null, alias, controller, alias);
|
||||
attr.$observe(attr.name ? 'name' : 'ngForm', function(newValue) {
|
||||
if (alias === newValue) return;
|
||||
setter(scope, null, alias, undefined, alias);
|
||||
alias = newValue;
|
||||
setter(scope, null, alias, controller, alias);
|
||||
parentFormCtrl.$$renameControl(controller, alias);
|
||||
if (nameAttr) {
|
||||
setter(scope, null, controller.$name, controller, controller.$name);
|
||||
attr.$observe(nameAttr, function(newValue) {
|
||||
if (controller.$name === newValue) return;
|
||||
setter(scope, null, controller.$name, undefined, controller.$name);
|
||||
parentFormCtrl.$$renameControl(controller, newValue);
|
||||
setter(scope, null, controller.$name, controller, controller.$name);
|
||||
});
|
||||
}
|
||||
formElement.on('$destroy', function() {
|
||||
parentFormCtrl.$removeControl(controller);
|
||||
if (alias) {
|
||||
setter(scope, null, alias, undefined, alias);
|
||||
if (nameAttr) {
|
||||
setter(scope, null, attr[nameAttr], undefined, controller.$name);
|
||||
}
|
||||
extend(controller, nullFormCtrl); //stop propagating child destruction handlers upwards
|
||||
});
|
||||
|
||||
+89
-67
@@ -61,19 +61,21 @@ var inputType = {
|
||||
<script>
|
||||
angular.module('textInputExample', [])
|
||||
.controller('ExampleController', ['$scope', function($scope) {
|
||||
$scope.text = 'guest';
|
||||
$scope.word = /^\s*\w*\s*$/;
|
||||
$scope.example = {
|
||||
text: 'guest',
|
||||
word: /^\s*\w*\s*$/
|
||||
};
|
||||
}]);
|
||||
</script>
|
||||
<form name="myForm" ng-controller="ExampleController">
|
||||
Single word: <input type="text" name="input" ng-model="text"
|
||||
ng-pattern="word" required ng-trim="false">
|
||||
Single word: <input type="text" name="input" ng-model="example.text"
|
||||
ng-pattern="example.word" required ng-trim="false">
|
||||
<span class="error" ng-show="myForm.input.$error.required">
|
||||
Required!</span>
|
||||
<span class="error" ng-show="myForm.input.$error.pattern">
|
||||
Single word only!</span>
|
||||
|
||||
<tt>text = {{text}}</tt><br/>
|
||||
<tt>text = {{example.text}}</tt><br/>
|
||||
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
|
||||
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
|
||||
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
|
||||
@@ -81,9 +83,9 @@ var inputType = {
|
||||
</form>
|
||||
</file>
|
||||
<file name="protractor.js" type="protractor">
|
||||
var text = element(by.binding('text'));
|
||||
var text = element(by.binding('example.text'));
|
||||
var valid = element(by.binding('myForm.input.$valid'));
|
||||
var input = element(by.model('text'));
|
||||
var input = element(by.model('example.text'));
|
||||
|
||||
it('should initialize to model', function() {
|
||||
expect(text.getText()).toContain('guest');
|
||||
@@ -145,18 +147,20 @@ var inputType = {
|
||||
<script>
|
||||
angular.module('dateInputExample', [])
|
||||
.controller('DateController', ['$scope', function($scope) {
|
||||
$scope.value = new Date(2013, 9, 22);
|
||||
$scope.example = {
|
||||
value: new Date(2013, 9, 22)
|
||||
};
|
||||
}]);
|
||||
</script>
|
||||
<form name="myForm" ng-controller="DateController as dateCtrl">
|
||||
Pick a date in 2013:
|
||||
<input type="date" id="exampleInput" name="input" ng-model="value"
|
||||
<input type="date" id="exampleInput" name="input" ng-model="example.value"
|
||||
placeholder="yyyy-MM-dd" min="2013-01-01" max="2013-12-31" required />
|
||||
<span class="error" ng-show="myForm.input.$error.required">
|
||||
Required!</span>
|
||||
<span class="error" ng-show="myForm.input.$error.date">
|
||||
Not a valid date!</span>
|
||||
<tt>value = {{value | date: "yyyy-MM-dd"}}</tt><br/>
|
||||
<tt>value = {{example.value | date: "yyyy-MM-dd"}}</tt><br/>
|
||||
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
|
||||
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
|
||||
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
|
||||
@@ -164,9 +168,9 @@ var inputType = {
|
||||
</form>
|
||||
</file>
|
||||
<file name="protractor.js" type="protractor">
|
||||
var value = element(by.binding('value | date: "yyyy-MM-dd"'));
|
||||
var value = element(by.binding('example.value | date: "yyyy-MM-dd"'));
|
||||
var valid = element(by.binding('myForm.input.$valid'));
|
||||
var input = element(by.model('value'));
|
||||
var input = element(by.model('example.value'));
|
||||
|
||||
// currently protractor/webdriver does not support
|
||||
// sending keys to all known HTML5 input controls
|
||||
@@ -236,18 +240,20 @@ var inputType = {
|
||||
<script>
|
||||
angular.module('dateExample', [])
|
||||
.controller('DateController', ['$scope', function($scope) {
|
||||
$scope.value = new Date(2010, 11, 28, 14, 57);
|
||||
$scope.example = {
|
||||
value: new Date(2010, 11, 28, 14, 57)
|
||||
};
|
||||
}]);
|
||||
</script>
|
||||
<form name="myForm" ng-controller="DateController as dateCtrl">
|
||||
Pick a date between in 2013:
|
||||
<input type="datetime-local" id="exampleInput" name="input" ng-model="value"
|
||||
<input type="datetime-local" id="exampleInput" name="input" ng-model="example.value"
|
||||
placeholder="yyyy-MM-ddTHH:mm:ss" min="2001-01-01T00:00:00" max="2013-12-31T00:00:00" required />
|
||||
<span class="error" ng-show="myForm.input.$error.required">
|
||||
Required!</span>
|
||||
<span class="error" ng-show="myForm.input.$error.datetimelocal">
|
||||
Not a valid date!</span>
|
||||
<tt>value = {{value | date: "yyyy-MM-ddTHH:mm:ss"}}</tt><br/>
|
||||
<tt>value = {{example.value | date: "yyyy-MM-ddTHH:mm:ss"}}</tt><br/>
|
||||
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
|
||||
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
|
||||
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
|
||||
@@ -255,9 +261,9 @@ var inputType = {
|
||||
</form>
|
||||
</file>
|
||||
<file name="protractor.js" type="protractor">
|
||||
var value = element(by.binding('value | date: "yyyy-MM-ddTHH:mm:ss"'));
|
||||
var value = element(by.binding('example.value | date: "yyyy-MM-ddTHH:mm:ss"'));
|
||||
var valid = element(by.binding('myForm.input.$valid'));
|
||||
var input = element(by.model('value'));
|
||||
var input = element(by.model('example.value'));
|
||||
|
||||
// currently protractor/webdriver does not support
|
||||
// sending keys to all known HTML5 input controls
|
||||
@@ -328,18 +334,20 @@ var inputType = {
|
||||
<script>
|
||||
angular.module('timeExample', [])
|
||||
.controller('DateController', ['$scope', function($scope) {
|
||||
$scope.value = new Date(1970, 0, 1, 14, 57, 0);
|
||||
$scope.example = {
|
||||
value: new Date(1970, 0, 1, 14, 57, 0)
|
||||
};
|
||||
}]);
|
||||
</script>
|
||||
<form name="myForm" ng-controller="DateController as dateCtrl">
|
||||
Pick a between 8am and 5pm:
|
||||
<input type="time" id="exampleInput" name="input" ng-model="value"
|
||||
<input type="time" id="exampleInput" name="input" ng-model="example.value"
|
||||
placeholder="HH:mm:ss" min="08:00:00" max="17:00:00" required />
|
||||
<span class="error" ng-show="myForm.input.$error.required">
|
||||
Required!</span>
|
||||
<span class="error" ng-show="myForm.input.$error.time">
|
||||
Not a valid date!</span>
|
||||
<tt>value = {{value | date: "HH:mm:ss"}}</tt><br/>
|
||||
<tt>value = {{example.value | date: "HH:mm:ss"}}</tt><br/>
|
||||
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
|
||||
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
|
||||
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
|
||||
@@ -347,9 +355,9 @@ var inputType = {
|
||||
</form>
|
||||
</file>
|
||||
<file name="protractor.js" type="protractor">
|
||||
var value = element(by.binding('value | date: "HH:mm:ss"'));
|
||||
var value = element(by.binding('example.value | date: "HH:mm:ss"'));
|
||||
var valid = element(by.binding('myForm.input.$valid'));
|
||||
var input = element(by.model('value'));
|
||||
var input = element(by.model('example.value'));
|
||||
|
||||
// currently protractor/webdriver does not support
|
||||
// sending keys to all known HTML5 input controls
|
||||
@@ -419,18 +427,20 @@ var inputType = {
|
||||
<script>
|
||||
angular.module('weekExample', [])
|
||||
.controller('DateController', ['$scope', function($scope) {
|
||||
$scope.value = new Date(2013, 0, 3);
|
||||
$scope.example = {
|
||||
value: new Date(2013, 0, 3)
|
||||
};
|
||||
}]);
|
||||
</script>
|
||||
<form name="myForm" ng-controller="DateController as dateCtrl">
|
||||
Pick a date between in 2013:
|
||||
<input id="exampleInput" type="week" name="input" ng-model="value"
|
||||
<input id="exampleInput" type="week" name="input" ng-model="example.value"
|
||||
placeholder="YYYY-W##" min="2012-W32" max="2013-W52" required />
|
||||
<span class="error" ng-show="myForm.input.$error.required">
|
||||
Required!</span>
|
||||
<span class="error" ng-show="myForm.input.$error.week">
|
||||
Not a valid date!</span>
|
||||
<tt>value = {{value | date: "yyyy-Www"}}</tt><br/>
|
||||
<tt>value = {{example.value | date: "yyyy-Www"}}</tt><br/>
|
||||
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
|
||||
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
|
||||
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
|
||||
@@ -438,9 +448,9 @@ var inputType = {
|
||||
</form>
|
||||
</file>
|
||||
<file name="protractor.js" type="protractor">
|
||||
var value = element(by.binding('value | date: "yyyy-Www"'));
|
||||
var value = element(by.binding('example.value | date: "yyyy-Www"'));
|
||||
var valid = element(by.binding('myForm.input.$valid'));
|
||||
var input = element(by.model('value'));
|
||||
var input = element(by.model('example.value'));
|
||||
|
||||
// currently protractor/webdriver does not support
|
||||
// sending keys to all known HTML5 input controls
|
||||
@@ -510,18 +520,20 @@ var inputType = {
|
||||
<script>
|
||||
angular.module('monthExample', [])
|
||||
.controller('DateController', ['$scope', function($scope) {
|
||||
$scope.value = new Date(2013, 9, 1);
|
||||
$scope.example = {
|
||||
value: new Date(2013, 9, 1)
|
||||
};
|
||||
}]);
|
||||
</script>
|
||||
<form name="myForm" ng-controller="DateController as dateCtrl">
|
||||
Pick a month int 2013:
|
||||
<input id="exampleInput" type="month" name="input" ng-model="value"
|
||||
Pick a month in 2013:
|
||||
<input id="exampleInput" type="month" name="input" ng-model="example.value"
|
||||
placeholder="yyyy-MM" min="2013-01" max="2013-12" required />
|
||||
<span class="error" ng-show="myForm.input.$error.required">
|
||||
Required!</span>
|
||||
<span class="error" ng-show="myForm.input.$error.month">
|
||||
Not a valid month!</span>
|
||||
<tt>value = {{value | date: "yyyy-MM"}}</tt><br/>
|
||||
<tt>value = {{example.value | date: "yyyy-MM"}}</tt><br/>
|
||||
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
|
||||
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
|
||||
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
|
||||
@@ -529,9 +541,9 @@ var inputType = {
|
||||
</form>
|
||||
</file>
|
||||
<file name="protractor.js" type="protractor">
|
||||
var value = element(by.binding('value | date: "yyyy-MM"'));
|
||||
var value = element(by.binding('example.value | date: "yyyy-MM"'));
|
||||
var valid = element(by.binding('myForm.input.$valid'));
|
||||
var input = element(by.model('value'));
|
||||
var input = element(by.model('example.value'));
|
||||
|
||||
// currently protractor/webdriver does not support
|
||||
// sending keys to all known HTML5 input controls
|
||||
@@ -607,17 +619,19 @@ var inputType = {
|
||||
<script>
|
||||
angular.module('numberExample', [])
|
||||
.controller('ExampleController', ['$scope', function($scope) {
|
||||
$scope.value = 12;
|
||||
$scope.example = {
|
||||
value: 12
|
||||
};
|
||||
}]);
|
||||
</script>
|
||||
<form name="myForm" ng-controller="ExampleController">
|
||||
Number: <input type="number" name="input" ng-model="value"
|
||||
Number: <input type="number" name="input" ng-model="example.value"
|
||||
min="0" max="99" required>
|
||||
<span class="error" ng-show="myForm.input.$error.required">
|
||||
Required!</span>
|
||||
<span class="error" ng-show="myForm.input.$error.number">
|
||||
Not valid number!</span>
|
||||
<tt>value = {{value}}</tt><br/>
|
||||
<tt>value = {{example.value}}</tt><br/>
|
||||
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
|
||||
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
|
||||
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
|
||||
@@ -625,9 +639,9 @@ var inputType = {
|
||||
</form>
|
||||
</file>
|
||||
<file name="protractor.js" type="protractor">
|
||||
var value = element(by.binding('value'));
|
||||
var value = element(by.binding('example.value'));
|
||||
var valid = element(by.binding('myForm.input.$valid'));
|
||||
var input = element(by.model('value'));
|
||||
var input = element(by.model('example.value'));
|
||||
|
||||
it('should initialize to model', function() {
|
||||
expect(value.getText()).toContain('12');
|
||||
@@ -695,16 +709,18 @@ var inputType = {
|
||||
<script>
|
||||
angular.module('urlExample', [])
|
||||
.controller('ExampleController', ['$scope', function($scope) {
|
||||
$scope.text = 'http://google.com';
|
||||
$scope.url = {
|
||||
text: 'http://google.com'
|
||||
};
|
||||
}]);
|
||||
</script>
|
||||
<form name="myForm" ng-controller="ExampleController">
|
||||
URL: <input type="url" name="input" ng-model="text" required>
|
||||
URL: <input type="url" name="input" ng-model="url.text" required>
|
||||
<span class="error" ng-show="myForm.input.$error.required">
|
||||
Required!</span>
|
||||
<span class="error" ng-show="myForm.input.$error.url">
|
||||
Not valid url!</span>
|
||||
<tt>text = {{text}}</tt><br/>
|
||||
<tt>text = {{url.text}}</tt><br/>
|
||||
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
|
||||
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
|
||||
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
|
||||
@@ -713,9 +729,9 @@ var inputType = {
|
||||
</form>
|
||||
</file>
|
||||
<file name="protractor.js" type="protractor">
|
||||
var text = element(by.binding('text'));
|
||||
var text = element(by.binding('url.text'));
|
||||
var valid = element(by.binding('myForm.input.$valid'));
|
||||
var input = element(by.model('text'));
|
||||
var input = element(by.model('url.text'));
|
||||
|
||||
it('should initialize to model', function() {
|
||||
expect(text.getText()).toContain('http://google.com');
|
||||
@@ -784,16 +800,18 @@ var inputType = {
|
||||
<script>
|
||||
angular.module('emailExample', [])
|
||||
.controller('ExampleController', ['$scope', function($scope) {
|
||||
$scope.text = 'me@example.com';
|
||||
$scope.email = {
|
||||
text: 'me@example.com'
|
||||
};
|
||||
}]);
|
||||
</script>
|
||||
<form name="myForm" ng-controller="ExampleController">
|
||||
Email: <input type="email" name="input" ng-model="text" required>
|
||||
Email: <input type="email" name="input" ng-model="email.text" required>
|
||||
<span class="error" ng-show="myForm.input.$error.required">
|
||||
Required!</span>
|
||||
<span class="error" ng-show="myForm.input.$error.email">
|
||||
Not valid email!</span>
|
||||
<tt>text = {{text}}</tt><br/>
|
||||
<tt>text = {{email.text}}</tt><br/>
|
||||
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
|
||||
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
|
||||
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
|
||||
@@ -802,9 +820,9 @@ var inputType = {
|
||||
</form>
|
||||
</file>
|
||||
<file name="protractor.js" type="protractor">
|
||||
var text = element(by.binding('text'));
|
||||
var text = element(by.binding('email.text'));
|
||||
var valid = element(by.binding('myForm.input.$valid'));
|
||||
var input = element(by.model('text'));
|
||||
var input = element(by.model('email.text'));
|
||||
|
||||
it('should initialize to model', function() {
|
||||
expect(text.getText()).toContain('me@example.com');
|
||||
@@ -851,7 +869,9 @@ var inputType = {
|
||||
<script>
|
||||
angular.module('radioExample', [])
|
||||
.controller('ExampleController', ['$scope', function($scope) {
|
||||
$scope.color = 'blue';
|
||||
$scope.color = {
|
||||
name: 'blue'
|
||||
};
|
||||
$scope.specialValue = {
|
||||
"id": "12345",
|
||||
"value": "green"
|
||||
@@ -859,20 +879,20 @@ var inputType = {
|
||||
}]);
|
||||
</script>
|
||||
<form name="myForm" ng-controller="ExampleController">
|
||||
<input type="radio" ng-model="color" value="red"> Red <br/>
|
||||
<input type="radio" ng-model="color" ng-value="specialValue"> Green <br/>
|
||||
<input type="radio" ng-model="color" value="blue"> Blue <br/>
|
||||
<tt>color = {{color | json}}</tt><br/>
|
||||
<input type="radio" ng-model="color.name" value="red"> Red <br/>
|
||||
<input type="radio" ng-model="color.name" ng-value="specialValue"> Green <br/>
|
||||
<input type="radio" ng-model="color.name" value="blue"> Blue <br/>
|
||||
<tt>color = {{color.name | json}}</tt><br/>
|
||||
</form>
|
||||
Note that `ng-value="specialValue"` sets radio item's value to be the value of `$scope.specialValue`.
|
||||
</file>
|
||||
<file name="protractor.js" type="protractor">
|
||||
it('should change state', function() {
|
||||
var color = element(by.binding('color'));
|
||||
var color = element(by.binding('color.name'));
|
||||
|
||||
expect(color.getText()).toContain('blue');
|
||||
|
||||
element.all(by.model('color')).get(0).click();
|
||||
element.all(by.model('color.name')).get(0).click();
|
||||
|
||||
expect(color.getText()).toContain('red');
|
||||
});
|
||||
@@ -902,28 +922,30 @@ var inputType = {
|
||||
<script>
|
||||
angular.module('checkboxExample', [])
|
||||
.controller('ExampleController', ['$scope', function($scope) {
|
||||
$scope.value1 = true;
|
||||
$scope.value2 = 'YES'
|
||||
$scope.checkboxModel = {
|
||||
value1 : true,
|
||||
value2 : 'YES'
|
||||
};
|
||||
}]);
|
||||
</script>
|
||||
<form name="myForm" ng-controller="ExampleController">
|
||||
Value1: <input type="checkbox" ng-model="value1"> <br/>
|
||||
Value2: <input type="checkbox" ng-model="value2"
|
||||
Value1: <input type="checkbox" ng-model="checkboxModel.value1"> <br/>
|
||||
Value2: <input type="checkbox" ng-model="checkboxModel.value2"
|
||||
ng-true-value="'YES'" ng-false-value="'NO'"> <br/>
|
||||
<tt>value1 = {{value1}}</tt><br/>
|
||||
<tt>value2 = {{value2}}</tt><br/>
|
||||
<tt>value1 = {{checkboxModel.value1}}</tt><br/>
|
||||
<tt>value2 = {{checkboxModel.value2}}</tt><br/>
|
||||
</form>
|
||||
</file>
|
||||
<file name="protractor.js" type="protractor">
|
||||
it('should change state', function() {
|
||||
var value1 = element(by.binding('value1'));
|
||||
var value2 = element(by.binding('value2'));
|
||||
var value1 = element(by.binding('checkboxModel.value1'));
|
||||
var value2 = element(by.binding('checkboxModel.value2'));
|
||||
|
||||
expect(value1.getText()).toContain('true');
|
||||
expect(value2.getText()).toContain('YES');
|
||||
|
||||
element(by.model('value1')).click();
|
||||
element(by.model('value2')).click();
|
||||
element(by.model('checkboxModel.value1')).click();
|
||||
element(by.model('checkboxModel.value2')).click();
|
||||
|
||||
expect(value1.getText()).toContain('false');
|
||||
expect(value2.getText()).toContain('NO');
|
||||
@@ -1228,7 +1250,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
||||
return value;
|
||||
});
|
||||
|
||||
if (attr.min || attr.ngMin) {
|
||||
if (isDefined(attr.min) || attr.ngMin) {
|
||||
var minVal;
|
||||
ctrl.$validators.min = function(value) {
|
||||
return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal;
|
||||
@@ -1244,7 +1266,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
||||
});
|
||||
}
|
||||
|
||||
if (attr.max || attr.ngMax) {
|
||||
if (isDefined(attr.max) || attr.ngMax) {
|
||||
var maxVal;
|
||||
ctrl.$validators.max = function(value) {
|
||||
return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal;
|
||||
|
||||
@@ -141,8 +141,9 @@ function classDirective(name, selector) {
|
||||
* new classes are added.
|
||||
*
|
||||
* @animations
|
||||
* add - happens just before the class is applied to the element
|
||||
* remove - happens just before the class is removed from the element
|
||||
* **add** - happens just before the class is applied to the elements
|
||||
*
|
||||
* **remove** - happens just before the class is removed from the element
|
||||
*
|
||||
* @element ANY
|
||||
* @param {expression} ngClass {@link guide/expression Expression} to eval. The result
|
||||
|
||||
@@ -173,7 +173,7 @@
|
||||
* @name ngInclude#$includeContentError
|
||||
* @eventType emit on the scope ngInclude was declared in
|
||||
* @description
|
||||
* Emitted when a template HTTP request yields an erronous response (status < 200 || status > 299)
|
||||
* Emitted when a template HTTP request yields an erroneous response (status < 200 || status > 299)
|
||||
*
|
||||
* @param {Object} angularEvent Synthetic event object.
|
||||
* @param {String} src URL of content to load.
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* **Note**: If you have assignment in `ngInit` along with {@link ng.$filter `$filter`}, make
|
||||
* sure you have parenthesis for correct precedence:
|
||||
* <pre class="prettyprint">
|
||||
* <div ng-init="test1 = (data | orderBy:'name')"></div>
|
||||
* `<div ng-init="test1 = (data | orderBy:'name')"></div>`
|
||||
* </pre>
|
||||
* </div>
|
||||
*
|
||||
|
||||
+30
-30
@@ -129,8 +129,8 @@ is set to `true`. The parse error is stored in `ngModel.$error.parse`.
|
||||
* data-binding. Notice how different directives (`contenteditable`, `ng-model`, and `required`)
|
||||
* collaborate together to achieve the desired result.
|
||||
*
|
||||
* Note that `contenteditable` is an HTML5 attribute, which tells the browser to let the element
|
||||
* contents be edited in place by the user. This will not work on older browsers.
|
||||
* `contenteditable` is an HTML5 attribute, which tells the browser to let the element
|
||||
* contents be edited in place by the user.
|
||||
*
|
||||
* We are using the {@link ng.service:$sce $sce} service here and include the {@link ngSanitize $sanitize}
|
||||
* module to automatically remove "bad" content like inline event listener (e.g. `<span onclick="...">`).
|
||||
@@ -244,6 +244,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
||||
ngModelGet = parsedNgModel,
|
||||
ngModelSet = parsedNgModelAssign,
|
||||
pendingDebounce = null,
|
||||
parserValid,
|
||||
ctrl = this;
|
||||
|
||||
this.$$setOptions = function(options) {
|
||||
@@ -516,16 +517,12 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
||||
// the model although neither viewValue nor the model on the scope changed
|
||||
var modelValue = ctrl.$$rawModelValue;
|
||||
|
||||
// Check if the there's a parse error, so we don't unset it accidentially
|
||||
var parserName = ctrl.$$parserName || 'parse';
|
||||
var parserValid = ctrl.$error[parserName] ? false : undefined;
|
||||
|
||||
var prevValid = ctrl.$valid;
|
||||
var prevModelValue = ctrl.$modelValue;
|
||||
|
||||
var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid;
|
||||
|
||||
ctrl.$$runValidators(parserValid, modelValue, viewValue, function(allValid) {
|
||||
ctrl.$$runValidators(modelValue, viewValue, function(allValid) {
|
||||
// If there was no change in validity, don't update the model
|
||||
// This prevents changing an invalid modelValue to undefined
|
||||
if (!allowInvalid && prevValid !== allValid) {
|
||||
@@ -543,12 +540,12 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
||||
|
||||
};
|
||||
|
||||
this.$$runValidators = function(parseValid, modelValue, viewValue, doneCallback) {
|
||||
this.$$runValidators = function(modelValue, viewValue, doneCallback) {
|
||||
currentValidationRunId++;
|
||||
var localValidationRunId = currentValidationRunId;
|
||||
|
||||
// check parser error
|
||||
if (!processParseErrors(parseValid)) {
|
||||
if (!processParseErrors()) {
|
||||
validationDone(false);
|
||||
return;
|
||||
}
|
||||
@@ -558,21 +555,22 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
||||
}
|
||||
processAsyncValidators();
|
||||
|
||||
function processParseErrors(parseValid) {
|
||||
function processParseErrors() {
|
||||
var errorKey = ctrl.$$parserName || 'parse';
|
||||
if (parseValid === undefined) {
|
||||
if (parserValid === undefined) {
|
||||
setValidity(errorKey, null);
|
||||
} else {
|
||||
setValidity(errorKey, parseValid);
|
||||
if (!parseValid) {
|
||||
if (!parserValid) {
|
||||
forEach(ctrl.$validators, function(v, name) {
|
||||
setValidity(name, null);
|
||||
});
|
||||
forEach(ctrl.$asyncValidators, function(v, name) {
|
||||
setValidity(name, null);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
// Set the parse error last, to prevent unsetting it, should a $validators key == parserName
|
||||
setValidity(errorKey, parserValid);
|
||||
return parserValid;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -667,7 +665,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
||||
this.$$parseAndValidate = function() {
|
||||
var viewValue = ctrl.$$lastCommittedViewValue;
|
||||
var modelValue = viewValue;
|
||||
var parserValid = isUndefined(modelValue) ? undefined : true;
|
||||
parserValid = isUndefined(modelValue) ? undefined : true;
|
||||
|
||||
if (parserValid) {
|
||||
for (var i = 0; i < ctrl.$parsers.length; i++) {
|
||||
@@ -693,7 +691,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
||||
|
||||
// Pass the $$lastCommittedViewValue here, because the cached viewValue might be out of date.
|
||||
// This can happen if e.g. $setViewValue is called from inside a parser
|
||||
ctrl.$$runValidators(parserValid, modelValue, ctrl.$$lastCommittedViewValue, function(allValid) {
|
||||
ctrl.$$runValidators(modelValue, ctrl.$$lastCommittedViewValue, function(allValid) {
|
||||
if (!allowInvalid) {
|
||||
// Note: Don't check ctrl.$valid here, as we could have
|
||||
// external validators (e.g. calculated on the server),
|
||||
@@ -814,6 +812,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
||||
// TODO(perf): why not move this to the action fn?
|
||||
if (modelValue !== ctrl.$modelValue) {
|
||||
ctrl.$modelValue = ctrl.$$rawModelValue = modelValue;
|
||||
parserValid = undefined;
|
||||
|
||||
var formatters = ctrl.$formatters,
|
||||
idx = formatters.length;
|
||||
@@ -826,7 +825,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
||||
ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;
|
||||
ctrl.$render();
|
||||
|
||||
ctrl.$$runValidators(undefined, modelValue, viewValue, noop);
|
||||
ctrl.$$runValidators(modelValue, viewValue, noop);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1247,22 +1246,22 @@ function addSetValidityMethod(context) {
|
||||
|
||||
ctrl.$setValidity = setValidity;
|
||||
|
||||
function setValidity(validationErrorKey, state, options) {
|
||||
function setValidity(validationErrorKey, state, controller) {
|
||||
if (state === undefined) {
|
||||
createAndSet('$pending', validationErrorKey, options);
|
||||
createAndSet('$pending', validationErrorKey, controller);
|
||||
} else {
|
||||
unsetAndCleanup('$pending', validationErrorKey, options);
|
||||
unsetAndCleanup('$pending', validationErrorKey, controller);
|
||||
}
|
||||
if (!isBoolean(state)) {
|
||||
unset(ctrl.$error, validationErrorKey, options);
|
||||
unset(ctrl.$$success, validationErrorKey, options);
|
||||
unset(ctrl.$error, validationErrorKey, controller);
|
||||
unset(ctrl.$$success, validationErrorKey, controller);
|
||||
} else {
|
||||
if (state) {
|
||||
unset(ctrl.$error, validationErrorKey, options);
|
||||
set(ctrl.$$success, validationErrorKey, options);
|
||||
unset(ctrl.$error, validationErrorKey, controller);
|
||||
set(ctrl.$$success, validationErrorKey, controller);
|
||||
} else {
|
||||
set(ctrl.$error, validationErrorKey, options);
|
||||
unset(ctrl.$$success, validationErrorKey, options);
|
||||
set(ctrl.$error, validationErrorKey, controller);
|
||||
unset(ctrl.$$success, validationErrorKey, controller);
|
||||
}
|
||||
}
|
||||
if (ctrl.$pending) {
|
||||
@@ -1290,20 +1289,21 @@ function addSetValidityMethod(context) {
|
||||
} else {
|
||||
combinedState = null;
|
||||
}
|
||||
|
||||
toggleValidationCss(validationErrorKey, combinedState);
|
||||
parentForm.$setValidity(validationErrorKey, combinedState, ctrl);
|
||||
}
|
||||
|
||||
function createAndSet(name, value, options) {
|
||||
function createAndSet(name, value, controller) {
|
||||
if (!ctrl[name]) {
|
||||
ctrl[name] = {};
|
||||
}
|
||||
set(ctrl[name], value, options);
|
||||
set(ctrl[name], value, controller);
|
||||
}
|
||||
|
||||
function unsetAndCleanup(name, value, options) {
|
||||
function unsetAndCleanup(name, value, controller) {
|
||||
if (ctrl[name]) {
|
||||
unset(ctrl[name], value, options);
|
||||
unset(ctrl[name], value, controller);
|
||||
}
|
||||
if (isObjectEmpty(ctrl[name])) {
|
||||
ctrl[name] = undefined;
|
||||
|
||||
@@ -23,6 +23,78 @@
|
||||
* Creating aliases for these properties is possible with {@link ng.directive:ngInit `ngInit`}.
|
||||
* This may be useful when, for instance, nesting ngRepeats.
|
||||
*
|
||||
* # Iterating over object properties
|
||||
*
|
||||
* It is possible to get `ngRepeat` to iterate over the properties of an object using the following
|
||||
* syntax:
|
||||
*
|
||||
* ```js
|
||||
* <div ng-repeat="(key, value) in myObj"> ... </div>
|
||||
* ```
|
||||
*
|
||||
* You need to be aware that the JavaScript specification does not define what order
|
||||
* it will return the keys for an object. In order to have a guaranteed deterministic order
|
||||
* for the keys, Angular versions up to and including 1.3 **sort the keys alphabetically**.
|
||||
*
|
||||
* If this is not desired, the recommended workaround is to convert your object into an array
|
||||
* that is sorted into the order that you prefer before providing it to `ngRepeat`. You could
|
||||
* do this with a filter such as [toArrayFilter](http://ngmodules.org/modules/angular-toArrayFilter)
|
||||
* or implement a `$watch` on the object yourself.
|
||||
*
|
||||
* In version 1.4 we will remove the sorting, since it seems that browsers generally follow the
|
||||
* strategy of providing keys in the order in which they were defined, although there are exceptions
|
||||
* when keys are deleted and reinstated.
|
||||
*
|
||||
*
|
||||
* # Tracking and Duplicates
|
||||
*
|
||||
* When the contents of the collection change, `ngRepeat` makes the corresponding changes to the DOM:
|
||||
*
|
||||
* * When an item is added, a new instance of the template is added to the DOM.
|
||||
* * When an item is removed, its template instance is removed from the DOM.
|
||||
* * When items are reordered, their respective templates are reordered in the DOM.
|
||||
*
|
||||
* By default, `ngRepeat` does not allow duplicate items in arrays. This is because when
|
||||
* there are duplicates, it is not possible to maintain a one-to-one mapping between collection
|
||||
* items and DOM elements.
|
||||
*
|
||||
* If you do need to repeat duplicate items, you can substitute the default tracking behavior
|
||||
* with your own using the `track by` expression.
|
||||
*
|
||||
* For example, you may track items by the index of each item in the collection, using the
|
||||
* special scope property `$index`:
|
||||
* ```html
|
||||
* <div ng-repeat="n in [42, 42, 43, 43] track by $index">
|
||||
* {{n}}
|
||||
* </div>
|
||||
* ```
|
||||
*
|
||||
* You may use arbitrary expressions in `track by`, including references to custom functions
|
||||
* on the scope:
|
||||
* ```html
|
||||
* <div ng-repeat="n in [42, 42, 43, 43] track by myTrackingFunction(n)">
|
||||
* {{n}}
|
||||
* </div>
|
||||
* ```
|
||||
*
|
||||
* If you are working with objects that have an identifier property, you can track
|
||||
* by the identifier instead of the whole object. Should you reload your data later, `ngRepeat`
|
||||
* will not have to rebuild the DOM elements for items it has already rendered, even if the
|
||||
* JavaScript objects in the collection have been substituted for new ones:
|
||||
* ```html
|
||||
* <div ng-repeat="model in collection track by model.id">
|
||||
* {{model.name}}
|
||||
* </div>
|
||||
* ```
|
||||
*
|
||||
* When no `track by` expression is provided, it is equivalent to tracking by the built-in
|
||||
* `$id` function, which tracks items by their identity:
|
||||
* ```html
|
||||
* <div ng-repeat="obj in collection track by $id(obj)">
|
||||
* {{obj.prop}}
|
||||
* </div>
|
||||
* ```
|
||||
*
|
||||
* # Special repeat start and end points
|
||||
* To repeat a series of elements instead of just one parent element, ngRepeat (as well as other ng directives) supports extending
|
||||
* the range of the repeater by defining explicit start and end points by using **ng-repeat-start** and **ng-repeat-end** respectively.
|
||||
@@ -90,12 +162,12 @@
|
||||
*
|
||||
* For example: `(name, age) in {'adam':10, 'amalie':12}`.
|
||||
*
|
||||
* * `variable in expression track by tracking_expression` – You can also provide an optional tracking function
|
||||
* which can be used to associate the objects in the collection with the DOM elements. If no tracking function
|
||||
* is specified the ng-repeat associates elements by identity in the collection. It is an error to have
|
||||
* more than one tracking function to resolve to the same key. (This would mean that two distinct objects are
|
||||
* mapped to the same DOM element, which is not possible.) Filters should be applied to the expression,
|
||||
* before specifying a tracking expression.
|
||||
* * `variable in expression track by tracking_expression` – You can also provide an optional tracking expression
|
||||
* which can be used to associate the objects in the collection with the DOM elements. If no tracking expression
|
||||
* is specified, ng-repeat associates elements by identity. It is an error to have
|
||||
* more than one tracking expression value resolve to the same key. (This would mean that two distinct objects are
|
||||
* mapped to the same DOM element, which is not possible.) If filters are used in the expression, they should be
|
||||
* applied before the tracking expression.
|
||||
*
|
||||
* For example: `item in items` is equivalent to `item in items track by $id(item)`. This implies that the DOM elements
|
||||
* will be associated by item identity in the array.
|
||||
@@ -267,7 +339,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
||||
var keyIdentifier = match[2];
|
||||
|
||||
if (aliasAs && (!/^[$a-zA-Z_][$a-zA-Z0-9_]*$/.test(aliasAs) ||
|
||||
/^(null|undefined|this|\$index|\$first|\$middle|\$last|\$even|\$odd|\$parent)$/.test(aliasAs))) {
|
||||
/^(null|undefined|this|\$index|\$first|\$middle|\$last|\$even|\$odd|\$parent|\$root|\$id)$/.test(aliasAs))) {
|
||||
throw ngRepeatMinErr('badident', "alias '{0}' is invalid --- must be a valid JS identifier which is not a reserved name.",
|
||||
aliasAs);
|
||||
}
|
||||
|
||||
@@ -40,10 +40,11 @@ var NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';
|
||||
*
|
||||
* By default, the `.ng-hide` class will style the element with `display: none!important`. If you wish to change
|
||||
* the hide behavior with ngShow/ngHide then this can be achieved by restating the styles for the `.ng-hide`
|
||||
* class in CSS:
|
||||
* class CSS. Note that the selector that needs to be used is actually `.ng-hide:not(.ng-hide-animate)` to cope
|
||||
* with extra animation classes that can be added.
|
||||
*
|
||||
* ```css
|
||||
* .ng-hide {
|
||||
* .ng-hide:not(.ng-hide-animate) {
|
||||
* /* this is just another form of hiding an element */
|
||||
* display: block!important;
|
||||
* position: absolute;
|
||||
|
||||
@@ -65,7 +65,7 @@ var maxlengthDirective = function() {
|
||||
ctrl.$validate();
|
||||
});
|
||||
ctrl.$validators.maxlength = function(modelValue, viewValue) {
|
||||
return (maxlength < 0) || ctrl.$isEmpty(modelValue) || (viewValue.length <= maxlength);
|
||||
return (maxlength < 0) || ctrl.$isEmpty(viewValue) || (viewValue.length <= maxlength);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -181,8 +181,8 @@ function createPredicateFn(expression, comparator, matchAgainstAnyProp) {
|
||||
}
|
||||
|
||||
function deepCompare(actual, expected, comparator, matchAgainstAnyProp, dontMatchWholeObject) {
|
||||
var actualType = typeof actual;
|
||||
var expectedType = typeof expected;
|
||||
var actualType = (actual !== null) ? typeof actual : 'null';
|
||||
var expectedType = (expected !== null) ? typeof expected : 'null';
|
||||
|
||||
if ((expectedType === 'string') && (expected.charAt(0) === '!')) {
|
||||
return !deepCompare(actual, expected.substring(1), comparator, matchAgainstAnyProp);
|
||||
@@ -207,7 +207,7 @@ function deepCompare(actual, expected, comparator, matchAgainstAnyProp, dontMatc
|
||||
} else if (expectedType === 'object') {
|
||||
for (key in expected) {
|
||||
var expectedVal = expected[key];
|
||||
if (isFunction(expectedVal)) {
|
||||
if (isFunction(expectedVal) || isUndefined(expectedVal)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -292,6 +292,14 @@ function ampmGetter(date, formats) {
|
||||
return date.getHours() < 12 ? formats.AMPMS[0] : formats.AMPMS[1];
|
||||
}
|
||||
|
||||
function eraGetter(date, formats) {
|
||||
return date.getFullYear() <= 0 ? formats.ERAS[0] : formats.ERAS[1];
|
||||
}
|
||||
|
||||
function longEraGetter(date, formats) {
|
||||
return date.getFullYear() <= 0 ? formats.ERANAMES[0] : formats.ERANAMES[1];
|
||||
}
|
||||
|
||||
var DATE_FORMATS = {
|
||||
yyyy: dateGetter('FullYear', 4),
|
||||
yy: dateGetter('FullYear', 2, 0, true),
|
||||
@@ -318,10 +326,14 @@ var DATE_FORMATS = {
|
||||
a: ampmGetter,
|
||||
Z: timeZoneGetter,
|
||||
ww: weekGetter(2),
|
||||
w: weekGetter(1)
|
||||
w: weekGetter(1),
|
||||
G: eraGetter,
|
||||
GG: eraGetter,
|
||||
GGG: eraGetter,
|
||||
GGGG: longEraGetter
|
||||
};
|
||||
|
||||
var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZEw']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z|w+))(.*)/,
|
||||
var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,
|
||||
NUMBER_STRING = /^\-?\d+$/;
|
||||
|
||||
/**
|
||||
@@ -353,11 +365,13 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZEw']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d
|
||||
* * `'m'`: Minute in hour (0-59)
|
||||
* * `'ss'`: Second in minute, padded (00-59)
|
||||
* * `'s'`: Second in minute (0-59)
|
||||
* * `'.sss' or ',sss'`: Millisecond in second, padded (000-999)
|
||||
* * `'sss'`: Millisecond in second, padded (000-999)
|
||||
* * `'a'`: AM/PM marker
|
||||
* * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-+1200)
|
||||
* * `'ww'`: Week of year, padded (00-53). Week 01 is the week with the first Thursday of the year
|
||||
* * `'w'`: Week of year (0-53). Week 1 is the week with the first Thursday of the year
|
||||
* * `'G'`, `'GG'`, `'GGG'`: The abbreviated form of the era string (e.g. 'AD')
|
||||
* * `'GGGG'`: The long form of the era string (e.g. 'Anno Domini')
|
||||
*
|
||||
* `format` string can also be one of the following predefined
|
||||
* {@link guide/i18n localizable formats}:
|
||||
|
||||
@@ -34,6 +34,43 @@
|
||||
* @param {boolean=} reverse Reverse the order of the array.
|
||||
* @returns {Array} Sorted copy of the source array.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* The example below demonstrates a simple ngRepeat, where the data is sorted
|
||||
* by age in descending order (predicate is set to `'-age'`).
|
||||
* `reverse` is not set, which means it defaults to `false`.
|
||||
<example module="orderByExample">
|
||||
<file name="index.html">
|
||||
<script>
|
||||
angular.module('orderByExample', [])
|
||||
.controller('ExampleController', ['$scope', function($scope) {
|
||||
$scope.friends =
|
||||
[{name:'John', phone:'555-1212', age:10},
|
||||
{name:'Mary', phone:'555-9876', age:19},
|
||||
{name:'Mike', phone:'555-4321', age:21},
|
||||
{name:'Adam', phone:'555-5678', age:35},
|
||||
{name:'Julie', phone:'555-8765', age:29}];
|
||||
}]);
|
||||
</script>
|
||||
<div ng-controller="ExampleController">
|
||||
<table class="friend">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Phone Number</th>
|
||||
<th>Age</th>
|
||||
</tr>
|
||||
<tr ng-repeat="friend in friends | orderBy:'-age'">
|
||||
<td>{{friend.name}}</td>
|
||||
<td>{{friend.phone}}</td>
|
||||
<td>{{friend.age}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</file>
|
||||
</example>
|
||||
*
|
||||
* The predicate and reverse parameters can be controlled dynamically through scope properties,
|
||||
* as shown in the next example.
|
||||
* @example
|
||||
<example module="orderByExample">
|
||||
<file name="index.html">
|
||||
|
||||
+9
-1
@@ -59,7 +59,15 @@ function $LocaleProvider() {
|
||||
mediumDate: 'MMM d, y',
|
||||
shortDate: 'M/d/yy',
|
||||
mediumTime: 'h:mm:ss a',
|
||||
shortTime: 'h:mm a'
|
||||
shortTime: 'h:mm a',
|
||||
ERANAMES: [
|
||||
"Before Christ",
|
||||
"Anno Domini"
|
||||
],
|
||||
ERAS: [
|
||||
"BC",
|
||||
"AD"
|
||||
]
|
||||
},
|
||||
|
||||
pluralCat: function(num) {
|
||||
|
||||
+2
-2
@@ -837,7 +837,7 @@ function $LocationProvider() {
|
||||
// TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)
|
||||
// currently we open nice url link and redirect then
|
||||
|
||||
if (!html5Mode.rewriteLinks || event.ctrlKey || event.metaKey || event.which == 2) return;
|
||||
if (!html5Mode.rewriteLinks || event.ctrlKey || event.metaKey || event.shiftKey || event.which == 2 || event.button == 2) return;
|
||||
|
||||
var elm = jqLite(event.target);
|
||||
|
||||
@@ -879,7 +879,7 @@ function $LocationProvider() {
|
||||
|
||||
|
||||
// rewrite hashbang url <> html5 url
|
||||
if ($location.absUrl() != initialUrl) {
|
||||
if (trimEmptyHash($location.absUrl()) != trimEmptyHash(initialUrl)) {
|
||||
$browser.url($location.absUrl(), true);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<button ng-click="$log.warn(message)">warn</button>
|
||||
<button ng-click="$log.info(message)">info</button>
|
||||
<button ng-click="$log.error(message)">error</button>
|
||||
<button ng-click="$log.debug(message)">debug</button>
|
||||
</div>
|
||||
</file>
|
||||
</example>
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Any commits to this file should be reviewed with security in mind. *
|
||||
* Changes to this file can potentially create security vulnerabilities. *
|
||||
* An approval from 2 Core members with history of modifying *
|
||||
* this file is required. *
|
||||
* *
|
||||
* Does the change somehow allow for arbitrary javascript to be executed? *
|
||||
* Or allows for someone to change the prototype of built-in objects? *
|
||||
* Or gives undesired access to variables likes document or window? *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
var $parseMinErr = minErr('$parse');
|
||||
|
||||
// Sandboxing Angular Expressions
|
||||
@@ -728,6 +739,11 @@ Parser.prototype = {
|
||||
? fn.apply(context, args)
|
||||
: fn(args[0], args[1], args[2], args[3], args[4]);
|
||||
|
||||
if (args) {
|
||||
// Free-up the memory (arguments of the last function call).
|
||||
args.length = 0;
|
||||
}
|
||||
|
||||
return ensureSafeObject(v, expressionText);
|
||||
};
|
||||
},
|
||||
|
||||
+1
-2
@@ -347,8 +347,7 @@ function qFactory(nextTick, exceptionHandler) {
|
||||
'qcycle',
|
||||
"Expected promise to be resolved with value other than itself '{0}'",
|
||||
val));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.$$resolve(val);
|
||||
}
|
||||
|
||||
|
||||
+21
-15
@@ -80,9 +80,27 @@ function $RootScopeProvider() {
|
||||
return TTL;
|
||||
};
|
||||
|
||||
function createChildScopeClass(parent) {
|
||||
function ChildScope() {
|
||||
this.$$watchers = this.$$nextSibling =
|
||||
this.$$childHead = this.$$childTail = null;
|
||||
this.$$listeners = {};
|
||||
this.$$listenerCount = {};
|
||||
this.$$watchersCount = 0;
|
||||
this.$id = nextUid();
|
||||
this.$$ChildScope = null;
|
||||
}
|
||||
ChildScope.prototype = parent;
|
||||
return ChildScope;
|
||||
}
|
||||
|
||||
this.$get = ['$injector', '$exceptionHandler', '$parse', '$browser',
|
||||
function($injector, $exceptionHandler, $parse, $browser) {
|
||||
|
||||
function destroyChildScope($event) {
|
||||
$event.currentScope.$$destroyed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc type
|
||||
* @name $rootScope.Scope
|
||||
@@ -205,15 +223,7 @@ function $RootScopeProvider() {
|
||||
// Only create a child scope class if somebody asks for one,
|
||||
// but cache it to allow the VM to optimize lookups.
|
||||
if (!this.$$ChildScope) {
|
||||
this.$$ChildScope = function ChildScope() {
|
||||
this.$$watchers = this.$$nextSibling =
|
||||
this.$$childHead = this.$$childTail = null;
|
||||
this.$$listeners = {};
|
||||
this.$$listenerCount = {};
|
||||
this.$id = nextUid();
|
||||
this.$$ChildScope = null;
|
||||
};
|
||||
this.$$ChildScope.prototype = this;
|
||||
this.$$ChildScope = createChildScopeClass(this);
|
||||
}
|
||||
child = new this.$$ChildScope();
|
||||
}
|
||||
@@ -231,13 +241,9 @@ function $RootScopeProvider() {
|
||||
// prototypically. In all other cases, this property needs to be set
|
||||
// when the parent scope is destroyed.
|
||||
// The listener needs to be added after the parent is set
|
||||
if (isolate || parent != this) child.$on('$destroy', destroyChild);
|
||||
if (isolate || parent != this) child.$on('$destroy', destroyChildScope);
|
||||
|
||||
return child;
|
||||
|
||||
function destroyChild() {
|
||||
child.$$destroyed = true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1045,7 +1051,7 @@ function $RootScopeProvider() {
|
||||
* @kind function
|
||||
*
|
||||
* @description
|
||||
* Schedule the invokation of $apply to occur at a later time. The actual time difference
|
||||
* Schedule the invocation of $apply to occur at a later time. The actual time difference
|
||||
* varies across browsers, but is typically around ~10 milliseconds.
|
||||
*
|
||||
* This can be used to queue up multiple expressions which need to be evaluated in the same
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Any commits to this file should be reviewed with security in mind. *
|
||||
* Changes to this file can potentially create security vulnerabilities. *
|
||||
* An approval from 2 Core members with history of modifying *
|
||||
* this file is required. *
|
||||
* *
|
||||
* Does the change somehow allow for arbitrary javascript to be executed? *
|
||||
* Or allows for someone to change the prototype of built-in objects? *
|
||||
* Or gives undesired access to variables likes document or window? *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
var $sceMinErr = minErr('$sce');
|
||||
|
||||
var SCE_CONTEXTS = {
|
||||
|
||||
@@ -22,8 +22,7 @@ var $compileMinErr = minErr('$compile');
|
||||
function $TemplateRequestProvider() {
|
||||
this.$get = ['$templateCache', '$http', '$q', function($templateCache, $http, $q) {
|
||||
function handleRequestFn(tpl, ignoreRequestError) {
|
||||
var self = handleRequestFn;
|
||||
self.totalPendingRequests++;
|
||||
handleRequestFn.totalPendingRequests++;
|
||||
|
||||
var transformResponse = $http.defaults && $http.defaults.transformResponse;
|
||||
|
||||
@@ -41,13 +40,14 @@ function $TemplateRequestProvider() {
|
||||
};
|
||||
|
||||
return $http.get(tpl, httpOptions)
|
||||
['finally'](function() {
|
||||
handleRequestFn.totalPendingRequests--;
|
||||
})
|
||||
.then(function(response) {
|
||||
self.totalPendingRequests--;
|
||||
return response.data;
|
||||
}, handleError);
|
||||
|
||||
function handleError(resp) {
|
||||
self.totalPendingRequests--;
|
||||
if (!ignoreRequestError) {
|
||||
throw $compileMinErr('tpload', 'Failed to load template: {0}', tpl);
|
||||
}
|
||||
|
||||
@@ -1327,8 +1327,7 @@ angular.module('ngAnimate', ['ng'])
|
||||
} else if (lastAnimation.event == 'setClass') {
|
||||
animationsToCancel.push(lastAnimation);
|
||||
cleanup(element, className);
|
||||
}
|
||||
else if (runningAnimations[className]) {
|
||||
} else if (runningAnimations[className]) {
|
||||
var current = runningAnimations[className];
|
||||
if (current.event == animationEvent) {
|
||||
skipAnimation = true;
|
||||
@@ -1869,7 +1868,7 @@ angular.module('ngAnimate', ['ng'])
|
||||
return;
|
||||
}
|
||||
|
||||
if (!staggerTime && styles) {
|
||||
if (!staggerTime && styles && Object.keys(styles).length > 0) {
|
||||
if (!timings.transitionDuration) {
|
||||
element.css('transition', timings.animationDuration + 's linear all');
|
||||
appliedStyles.push('transition');
|
||||
|
||||
+32
-7
@@ -22,13 +22,13 @@
|
||||
*
|
||||
* | Directive | Supported Attributes |
|
||||
* |---------------------------------------------|----------------------------------------------------------------------------------------|
|
||||
* | {@link ng.directive:ngModel ngModel} | aria-checked, aria-valuemin, aria-valuemax, aria-valuenow, aria-invalid, aria-required |
|
||||
* | {@link ng.directive:ngDisabled ngDisabled} | aria-disabled |
|
||||
* | {@link ng.directive:ngShow ngShow} | aria-hidden |
|
||||
* | {@link ng.directive:ngHide ngHide} | aria-hidden |
|
||||
* | {@link ng.directive:ngClick ngClick} | tabindex, keypress event |
|
||||
* | {@link ng.directive:ngDblclick ngDblclick} | tabindex |
|
||||
* | {@link module:ngMessages ngMessages} | aria-live |
|
||||
* | {@link ng.directive:ngModel ngModel} | aria-checked, aria-valuemin, aria-valuemax, aria-valuenow, aria-invalid, aria-required, input roles |
|
||||
* | {@link ng.directive:ngClick ngClick} | tabindex, keypress event, button role |
|
||||
*
|
||||
* Find out more information about each directive by reading the
|
||||
* {@link guide/accessibility ngAria Developer Guide}.
|
||||
@@ -100,7 +100,8 @@ function $AriaProvider() {
|
||||
* - **ariaMultiline** – `{boolean}` – Enables/disables aria-multiline tags
|
||||
* - **ariaValue** – `{boolean}` – Enables/disables aria-valuemin, aria-valuemax and aria-valuenow tags
|
||||
* - **tabindex** – `{boolean}` – Enables/disables tabindex tags
|
||||
* - **bindKeypress** – `{boolean}` – Enables/disables keypress event binding on ng-click
|
||||
* - **bindKeypress** – `{boolean}` – Enables/disables keypress event binding on `<div>` and
|
||||
* `<li>` elements with ng-click
|
||||
*
|
||||
* @description
|
||||
* Enables/disables various ARIA attributes
|
||||
@@ -128,6 +129,7 @@ function $AriaProvider() {
|
||||
* @name $aria
|
||||
*
|
||||
* @description
|
||||
* @priority 200
|
||||
*
|
||||
* The $aria service contains helper methods for applying common
|
||||
* [ARIA](http://www.w3.org/TR/wai-aria/) attributes to HTML directives.
|
||||
@@ -191,6 +193,10 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
|
||||
return $aria.config(normalizedAttr) && !elem.attr(attr);
|
||||
}
|
||||
|
||||
function shouldAttachRole(role, elem) {
|
||||
return !elem.attr('role') && (elem.attr('type') === role) && (elem[0].nodeName !== 'INPUT');
|
||||
}
|
||||
|
||||
function getShape(attr, elem) {
|
||||
var type = attr.type,
|
||||
role = attr.role;
|
||||
@@ -204,6 +210,7 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: '?ngModel',
|
||||
priority: 200, //Make sure watches are fired after any other directives that affect the ngModel value
|
||||
link: function(scope, elem, attr, ngModel) {
|
||||
var shape = getShape(attr, elem);
|
||||
var needsTabIndex = shouldAttachAttr('tabindex', 'tabindex', elem);
|
||||
@@ -216,30 +223,36 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
|
||||
if (needsTabIndex) {
|
||||
needsTabIndex = false;
|
||||
return function ngAriaRadioReaction(newVal) {
|
||||
var boolVal = newVal === attr.value;
|
||||
var boolVal = (attr.value == ngModel.$viewValue);
|
||||
elem.attr('aria-checked', boolVal);
|
||||
elem.attr('tabindex', 0 - !boolVal);
|
||||
};
|
||||
} else {
|
||||
return function ngAriaRadioReaction(newVal) {
|
||||
elem.attr('aria-checked', newVal === attr.value);
|
||||
elem.attr('aria-checked', (attr.value == ngModel.$viewValue));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function ngAriaCheckboxReaction(newVal) {
|
||||
elem.attr('aria-checked', !!newVal);
|
||||
elem.attr('aria-checked', !ngModel.$isEmpty(ngModel.$viewValue));
|
||||
}
|
||||
|
||||
switch (shape) {
|
||||
case 'radio':
|
||||
case 'checkbox':
|
||||
if (shouldAttachRole(shape, elem)) {
|
||||
elem.attr('role', shape);
|
||||
}
|
||||
if (shouldAttachAttr('aria-checked', 'ariaChecked', elem)) {
|
||||
scope.$watch(ngAriaWatchModelValue, shape === 'radio' ?
|
||||
getRadioReaction() : ngAriaCheckboxReaction);
|
||||
}
|
||||
break;
|
||||
case 'range':
|
||||
if (shouldAttachRole(shape, elem)) {
|
||||
elem.attr('role', 'slider');
|
||||
}
|
||||
if ($aria.config('ariaValue')) {
|
||||
if (attr.min && !elem.attr('aria-valuemin')) {
|
||||
elem.attr('aria-valuemin', attr.min);
|
||||
@@ -303,11 +316,23 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
|
||||
compile: function(elem, attr) {
|
||||
var fn = $parse(attr.ngClick, /* interceptorFn */ null, /* expensiveChecks */ true);
|
||||
return function(scope, elem, attr) {
|
||||
|
||||
var nodeBlackList = ['BUTTON', 'A', 'INPUT', 'TEXTAREA'];
|
||||
|
||||
function isNodeOneOf(elem, nodeTypeArray) {
|
||||
if (nodeTypeArray.indexOf(elem[0].nodeName) !== -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!elem.attr('role') && !isNodeOneOf(elem, nodeBlackList)) {
|
||||
elem.attr('role', 'button');
|
||||
}
|
||||
|
||||
if ($aria.config('tabindex') && !elem.attr('tabindex')) {
|
||||
elem.attr('tabindex', 0);
|
||||
}
|
||||
|
||||
if ($aria.config('bindKeypress') && !attr.ngKeypress) {
|
||||
if ($aria.config('bindKeypress') && !attr.ngKeypress && !isNodeOneOf(elem, nodeBlackList)) {
|
||||
elem.on('keypress', function(event) {
|
||||
if (event.keyCode === 32 || event.keyCode === 13) {
|
||||
scope.$apply(callback);
|
||||
|
||||
Vendored
+8
@@ -34,6 +34,14 @@ $provide.value("$locale", {
|
||||
"Gumqata",
|
||||
"Sabti"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"Yaasuusuk Duma",
|
||||
"Yaasuusuk Wadir"
|
||||
],
|
||||
"ERAS": [
|
||||
"Yaasuusuk Duma",
|
||||
"Yaasuusuk Wadir"
|
||||
],
|
||||
"MONTH": [
|
||||
"Qunxa Garablu",
|
||||
"Kudo",
|
||||
|
||||
Vendored
+8
@@ -34,6 +34,14 @@ $provide.value("$locale", {
|
||||
"Gumqata",
|
||||
"Sabti"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"Yaasuusuk Duma",
|
||||
"Yaasuusuk Wadir"
|
||||
],
|
||||
"ERAS": [
|
||||
"Yaasuusuk Duma",
|
||||
"Yaasuusuk Wadir"
|
||||
],
|
||||
"MONTH": [
|
||||
"Qunxa Garablu",
|
||||
"Kudo",
|
||||
|
||||
Vendored
+8
@@ -34,6 +34,14 @@ $provide.value("$locale", {
|
||||
"Gumqata",
|
||||
"Sabti"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"Yaasuusuk Duma",
|
||||
"Yaasuusuk Wadir"
|
||||
],
|
||||
"ERAS": [
|
||||
"Yaasuusuk Duma",
|
||||
"Yaasuusuk Wadir"
|
||||
],
|
||||
"MONTH": [
|
||||
"Qunxa Garablu",
|
||||
"Kudo",
|
||||
|
||||
Vendored
+8
@@ -34,6 +34,14 @@ $provide.value("$locale", {
|
||||
"Gumqata",
|
||||
"Sabti"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"Yaasuusuk Duma",
|
||||
"Yaasuusuk Wadir"
|
||||
],
|
||||
"ERAS": [
|
||||
"Yaasuusuk Duma",
|
||||
"Yaasuusuk Wadir"
|
||||
],
|
||||
"MONTH": [
|
||||
"Qunxa Garablu",
|
||||
"Kudo",
|
||||
|
||||
Vendored
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"Vrydag",
|
||||
"Saterdag"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"voor Christus",
|
||||
"na Christus"
|
||||
],
|
||||
"ERAS": [
|
||||
"v.C.",
|
||||
"n.C."
|
||||
],
|
||||
"MONTH": [
|
||||
"Januarie",
|
||||
"Februarie",
|
||||
|
||||
Vendored
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"Vrydag",
|
||||
"Saterdag"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"voor Christus",
|
||||
"na Christus"
|
||||
],
|
||||
"ERAS": [
|
||||
"v.C.",
|
||||
"n.C."
|
||||
],
|
||||
"MONTH": [
|
||||
"Januarie",
|
||||
"Februarie",
|
||||
|
||||
Vendored
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"Vrydag",
|
||||
"Saterdag"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"voor Christus",
|
||||
"na Christus"
|
||||
],
|
||||
"ERAS": [
|
||||
"v.C.",
|
||||
"n.C."
|
||||
],
|
||||
"MONTH": [
|
||||
"Januarie",
|
||||
"Februarie",
|
||||
|
||||
+8
@@ -34,6 +34,14 @@ $provide.value("$locale", {
|
||||
"tsu\u0294ugh\u0268\u0302m",
|
||||
"tsu\u0294ndz\u0268k\u0254\u0294\u0254"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"S\u011be K\u0268\u0300lesto",
|
||||
"B\u01cea K\u0268\u0300lesto"
|
||||
],
|
||||
"ERAS": [
|
||||
"SK",
|
||||
"BK"
|
||||
],
|
||||
"MONTH": [
|
||||
"ndz\u0254\u0300\u014b\u0254\u0300n\u00f9m",
|
||||
"ndz\u0254\u0300\u014b\u0254\u0300k\u0197\u0300z\u00f9\u0294",
|
||||
|
||||
Vendored
+8
@@ -34,6 +34,14 @@ $provide.value("$locale", {
|
||||
"tsu\u0294ugh\u0268\u0302m",
|
||||
"tsu\u0294ndz\u0268k\u0254\u0294\u0254"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"S\u011be K\u0268\u0300lesto",
|
||||
"B\u01cea K\u0268\u0300lesto"
|
||||
],
|
||||
"ERAS": [
|
||||
"SK",
|
||||
"BK"
|
||||
],
|
||||
"MONTH": [
|
||||
"ndz\u0254\u0300\u014b\u0254\u0300n\u00f9m",
|
||||
"ndz\u0254\u0300\u014b\u0254\u0300k\u0197\u0300z\u00f9\u0294",
|
||||
|
||||
Vendored
+8
@@ -34,6 +34,14 @@ $provide.value("$locale", {
|
||||
"Fida",
|
||||
"Memeneda"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"Ansa Kristo",
|
||||
"Kristo Ekyiri"
|
||||
],
|
||||
"ERAS": [
|
||||
"AK",
|
||||
"KE"
|
||||
],
|
||||
"MONTH": [
|
||||
"Sanda-\u0186p\u025bp\u0254n",
|
||||
"Kwakwar-\u0186gyefuo",
|
||||
|
||||
Vendored
+8
@@ -34,6 +34,14 @@ $provide.value("$locale", {
|
||||
"Fida",
|
||||
"Memeneda"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"Ansa Kristo",
|
||||
"Kristo Ekyiri"
|
||||
],
|
||||
"ERAS": [
|
||||
"AK",
|
||||
"KE"
|
||||
],
|
||||
"MONTH": [
|
||||
"Sanda-\u0186p\u025bp\u0254n",
|
||||
"Kwakwar-\u0186gyefuo",
|
||||
|
||||
Vendored
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"\u12d3\u122d\u1265",
|
||||
"\u1245\u12f3\u121c"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"\u12d3\u1218\u1270 \u12d3\u1208\u121d",
|
||||
"\u12d3\u1218\u1270 \u121d\u1215\u1228\u1275"
|
||||
],
|
||||
"ERAS": [
|
||||
"\u12d3/\u12d3",
|
||||
"\u12d3/\u121d"
|
||||
],
|
||||
"MONTH": [
|
||||
"\u1303\u1295\u12e9\u12c8\u122a",
|
||||
"\u134c\u1265\u1229\u12c8\u122a",
|
||||
|
||||
Vendored
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"\u12d3\u122d\u1265",
|
||||
"\u1245\u12f3\u121c"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"\u12d3\u1218\u1270 \u12d3\u1208\u121d",
|
||||
"\u12d3\u1218\u1270 \u121d\u1215\u1228\u1275"
|
||||
],
|
||||
"ERAS": [
|
||||
"\u12d3/\u12d3",
|
||||
"\u12d3/\u121d"
|
||||
],
|
||||
"MONTH": [
|
||||
"\u1303\u1295\u12e9\u12c8\u122a",
|
||||
"\u134c\u1265\u1229\u12c8\u122a",
|
||||
|
||||
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"\u0627\u0644\u062c\u0645\u0639\u0629",
|
||||
"\u0627\u0644\u0633\u0628\u062a"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"\u0642\u0628\u0644 \u0627\u0644\u0645\u064a\u0644\u0627\u062f",
|
||||
"\u0645\u064a\u0644\u0627\u062f\u064a"
|
||||
],
|
||||
"ERAS": [
|
||||
"\u0642.\u0645",
|
||||
"\u0645"
|
||||
],
|
||||
"MONTH": [
|
||||
"\u064a\u0646\u0627\u064a\u0631",
|
||||
"\u0641\u0628\u0631\u0627\u064a\u0631",
|
||||
|
||||
Vendored
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"\u0627\u0644\u062c\u0645\u0639\u0629",
|
||||
"\u0627\u0644\u0633\u0628\u062a"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"\u0642\u0628\u0644 \u0627\u0644\u0645\u064a\u0644\u0627\u062f",
|
||||
"\u0645\u064a\u0644\u0627\u062f\u064a"
|
||||
],
|
||||
"ERAS": [
|
||||
"\u0642.\u0645",
|
||||
"\u0645"
|
||||
],
|
||||
"MONTH": [
|
||||
"\u064a\u0646\u0627\u064a\u0631",
|
||||
"\u0641\u0628\u0631\u0627\u064a\u0631",
|
||||
|
||||
Vendored
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"\u0627\u0644\u062c\u0645\u0639\u0629",
|
||||
"\u0627\u0644\u0633\u0628\u062a"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"\u0642\u0628\u0644 \u0627\u0644\u0645\u064a\u0644\u0627\u062f",
|
||||
"\u0645\u064a\u0644\u0627\u062f\u064a"
|
||||
],
|
||||
"ERAS": [
|
||||
"\u0642.\u0645",
|
||||
"\u0645"
|
||||
],
|
||||
"MONTH": [
|
||||
"\u064a\u0646\u0627\u064a\u0631",
|
||||
"\u0641\u0628\u0631\u0627\u064a\u0631",
|
||||
|
||||
Vendored
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"\u0627\u0644\u062c\u0645\u0639\u0629",
|
||||
"\u0627\u0644\u0633\u0628\u062a"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"\u0642\u0628\u0644 \u0627\u0644\u0645\u064a\u0644\u0627\u062f",
|
||||
"\u0645\u064a\u0644\u0627\u062f\u064a"
|
||||
],
|
||||
"ERAS": [
|
||||
"\u0642.\u0645",
|
||||
"\u0645"
|
||||
],
|
||||
"MONTH": [
|
||||
"\u064a\u0646\u0627\u064a\u0631",
|
||||
"\u0641\u0628\u0631\u0627\u064a\u0631",
|
||||
|
||||
Vendored
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"\u0627\u0644\u062c\u0645\u0639\u0629",
|
||||
"\u0627\u0644\u0633\u0628\u062a"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"\u0642\u0628\u0644 \u0627\u0644\u0645\u064a\u0644\u0627\u062f",
|
||||
"\u0645\u064a\u0644\u0627\u062f\u064a"
|
||||
],
|
||||
"ERAS": [
|
||||
"\u0642.\u0645",
|
||||
"\u0645"
|
||||
],
|
||||
"MONTH": [
|
||||
"\u062c\u0627\u0646\u0641\u064a",
|
||||
"\u0641\u064a\u0641\u0631\u064a",
|
||||
|
||||
Vendored
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"\u0627\u0644\u062c\u0645\u0639\u0629",
|
||||
"\u0627\u0644\u0633\u0628\u062a"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"\u0642\u0628\u0644 \u0627\u0644\u0645\u064a\u0644\u0627\u062f",
|
||||
"\u0645\u064a\u0644\u0627\u062f\u064a"
|
||||
],
|
||||
"ERAS": [
|
||||
"\u0642.\u0645",
|
||||
"\u0645"
|
||||
],
|
||||
"MONTH": [
|
||||
"\u064a\u0646\u0627\u064a\u0631",
|
||||
"\u0641\u0628\u0631\u0627\u064a\u0631",
|
||||
|
||||
Vendored
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"\u0627\u0644\u062c\u0645\u0639\u0629",
|
||||
"\u0627\u0644\u0633\u0628\u062a"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"\u0642\u0628\u0644 \u0627\u0644\u0645\u064a\u0644\u0627\u062f",
|
||||
"\u0645\u064a\u0644\u0627\u062f\u064a"
|
||||
],
|
||||
"ERAS": [
|
||||
"\u0642.\u0645",
|
||||
"\u0645"
|
||||
],
|
||||
"MONTH": [
|
||||
"\u064a\u0646\u0627\u064a\u0631",
|
||||
"\u0641\u0628\u0631\u0627\u064a\u0631",
|
||||
|
||||
Vendored
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"\u0627\u0644\u062c\u0645\u0639\u0629",
|
||||
"\u0627\u0644\u0633\u0628\u062a"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"\u0642\u0628\u0644 \u0627\u0644\u0645\u064a\u0644\u0627\u062f",
|
||||
"\u0645\u064a\u0644\u0627\u062f\u064a"
|
||||
],
|
||||
"ERAS": [
|
||||
"\u0642.\u0645",
|
||||
"\u0645"
|
||||
],
|
||||
"MONTH": [
|
||||
"\u064a\u0646\u0627\u064a\u0631",
|
||||
"\u0641\u0628\u0631\u0627\u064a\u0631",
|
||||
|
||||
Vendored
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"\u0627\u0644\u062c\u0645\u0639\u0629",
|
||||
"\u0627\u0644\u0633\u0628\u062a"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"\u0642\u0628\u0644 \u0627\u0644\u0645\u064a\u0644\u0627\u062f",
|
||||
"\u0645\u064a\u0644\u0627\u062f\u064a"
|
||||
],
|
||||
"ERAS": [
|
||||
"\u0642.\u0645",
|
||||
"\u0645"
|
||||
],
|
||||
"MONTH": [
|
||||
"\u064a\u0646\u0627\u064a\u0631",
|
||||
"\u0641\u0628\u0631\u0627\u064a\u0631",
|
||||
|
||||
Vendored
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"\u0627\u0644\u062c\u0645\u0639\u0629",
|
||||
"\u0627\u0644\u0633\u0628\u062a"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"\u0642\u0628\u0644 \u0627\u0644\u0645\u064a\u0644\u0627\u062f",
|
||||
"\u0645\u064a\u0644\u0627\u062f\u064a"
|
||||
],
|
||||
"ERAS": [
|
||||
"\u0642.\u0645",
|
||||
"\u0645"
|
||||
],
|
||||
"MONTH": [
|
||||
"\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
|
||||
"\u0634\u0628\u0627\u0637",
|
||||
|
||||
Vendored
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"\u0627\u0644\u062c\u0645\u0639\u0629",
|
||||
"\u0627\u0644\u0633\u0628\u062a"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"\u0642\u0628\u0644 \u0627\u0644\u0645\u064a\u0644\u0627\u062f",
|
||||
"\u0645\u064a\u0644\u0627\u062f\u064a"
|
||||
],
|
||||
"ERAS": [
|
||||
"\u0642.\u0645",
|
||||
"\u0645"
|
||||
],
|
||||
"MONTH": [
|
||||
"\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
|
||||
"\u0634\u0628\u0627\u0637",
|
||||
|
||||
Vendored
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"\u0627\u0644\u062c\u0645\u0639\u0629",
|
||||
"\u0627\u0644\u0633\u0628\u062a"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"\u0642\u0628\u0644 \u0627\u0644\u0645\u064a\u0644\u0627\u062f",
|
||||
"\u0645\u064a\u0644\u0627\u062f\u064a"
|
||||
],
|
||||
"ERAS": [
|
||||
"\u0642.\u0645",
|
||||
"\u0645"
|
||||
],
|
||||
"MONTH": [
|
||||
"\u064a\u0646\u0627\u064a\u0631",
|
||||
"\u0641\u0628\u0631\u0627\u064a\u0631",
|
||||
|
||||
Vendored
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"\u0627\u0644\u062c\u0645\u0639\u0629",
|
||||
"\u0627\u0644\u0633\u0628\u062a"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"\u0642\u0628\u0644 \u0627\u0644\u0645\u064a\u0644\u0627\u062f",
|
||||
"\u0645\u064a\u0644\u0627\u062f\u064a"
|
||||
],
|
||||
"ERAS": [
|
||||
"\u0642.\u0645",
|
||||
"\u0645"
|
||||
],
|
||||
"MONTH": [
|
||||
"\u064a\u0646\u0627\u064a\u0631",
|
||||
"\u0641\u0628\u0631\u0627\u064a\u0631",
|
||||
|
||||
Vendored
+8
@@ -16,6 +16,14 @@ $provide.value("$locale", {
|
||||
"\u0627\u0644\u062c\u0645\u0639\u0629",
|
||||
"\u0627\u0644\u0633\u0628\u062a"
|
||||
],
|
||||
"ERANAMES": [
|
||||
"\u0642\u0628\u0644 \u0627\u0644\u0645\u064a\u0644\u0627\u062f",
|
||||
"\u0645\u064a\u0644\u0627\u062f\u064a"
|
||||
],
|
||||
"ERAS": [
|
||||
"\u0642.\u0645",
|
||||
"\u0645"
|
||||
],
|
||||
"MONTH": [
|
||||
"\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
|
||||
"\u0634\u0628\u0627\u0637",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user