Compare commits
96 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 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 | |||
| e4adebd07a | |||
| ac94f6125f | |||
| c5686c5271 | |||
| 7fdb54d12b | |||
| 869008140a | |||
| 26ee32ec79 | |||
| a06193f97b | |||
| ba9dee170c | |||
| d4b60ada1e | |||
| b839f73ad0 | |||
| aee32931fd | |||
| 7ee5f46bbc | |||
| 2b97854bf4 | |||
| 316ee8f7ca | |||
| 2e18f44fcd | |||
| c85d064ecf | |||
| 7b9b82281a | |||
| aab632b330 | |||
| 4c8d8ad508 | |||
| 3a8f3dc9ea | |||
| c139e68d99 |
@@ -1,5 +0,0 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# JS files must always use LF for tools to work
|
||||
*.js eol=lf
|
||||
@@ -0,0 +1,15 @@
|
||||
// This is an incomplete TODO list of checks we want to start enforcing
|
||||
//
|
||||
// The goal is to enable these checks one by one by moving them to .jscs.json along with commits
|
||||
// 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,
|
||||
"validateJSDoc": {
|
||||
"checkParamNames": true,
|
||||
"requireParamTypes": true
|
||||
}
|
||||
}
|
||||
+2
-15
@@ -1,14 +1,7 @@
|
||||
language: node_js
|
||||
sudo: false
|
||||
node_js:
|
||||
- '0.10'
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
- bower_components
|
||||
- docs/bower_components
|
||||
|
||||
branches:
|
||||
except:
|
||||
- /^g3_.*$/
|
||||
@@ -34,21 +27,15 @@ 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
|
||||
- npm install -g npm@2.5
|
||||
# Instal npm dependecies and ensure that npm cache is not stale
|
||||
- scripts/npm/install-dependencies.sh
|
||||
- time ./scripts/travis/npm-bundle-deps.sh
|
||||
- time npm install
|
||||
|
||||
before_script:
|
||||
- mkdir -p $LOGS_DIR
|
||||
|
||||
+2
-960
@@ -1,935 +1,3 @@
|
||||
<a name="1.4.1"></a>
|
||||
# 1.4.1 hyperionic-illumination (2015-06-16)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$compile:**
|
||||
- workaround for IE11 MutationObserver
|
||||
([f3b1d0b7](https://github.com/angular/angular.js/commit/f3b1d0b723298a5f8ea21d0704405649cce1b5fc),
|
||||
[#11781](https://github.com/angular/angular.js/issues/11781))
|
||||
- prevent exception when using `watch` as isolated scope binding property in Firefox
|
||||
([a6339d30](https://github.com/angular/angular.js/commit/a6339d30d1379689da5eec9647a953f64821f8b0),
|
||||
[#11627](https://github.com/angular/angular.js/issues/11627))
|
||||
- assign controller return values correctly for multiple directives
|
||||
([8caf1802](https://github.com/angular/angular.js/commit/8caf1802e0e93389dec626ef35e04a302aa6c39d),
|
||||
[#12029](https://github.com/angular/angular.js/issues/12029), [#12036](https://github.com/angular/angular.js/issues/12036))
|
||||
- **$location:** do not get caught in infinite digest in IE9 when redirecting in `$locationChangeSuccess`
|
||||
([91b60226](https://github.com/angular/angular.js/commit/91b602263b96b6fce1331208462e18eb647f4d60),
|
||||
[#11439](https://github.com/angular/angular.js/issues/11439), [#11675](https://github.com/angular/angular.js/issues/11675), [#11935](https://github.com/angular/angular.js/issues/11935), [#12083](https://github.com/angular/angular.js/issues/12083))
|
||||
- **$parse:** set null reference properties to `undefined`
|
||||
([71fc3f4f](https://github.com/angular/angular.js/commit/71fc3f4fa0cd12eff335d57efed7c033554749f4),
|
||||
[#12099](https://github.com/angular/angular.js/issues/12099))
|
||||
([d19504a1](https://github.com/angular/angular.js/commit/d19504a179355d7801d59a8db0285a1322e04601),
|
||||
[#11959](https://github.com/angular/angular.js/issues/11959))
|
||||
- **$sanitize:** do not remove `tabindex` attribute
|
||||
([799353c7](https://github.com/angular/angular.js/commit/799353c75de28e6fbf52dac6e0721e85b578575a),
|
||||
[#8371](https://github.com/angular/angular.js/issues/8371), [#5853](https://github.com/angular/angular.js/issues/5853))
|
||||
- **copy:** do not copy the same object twice
|
||||
([0e622f7b](https://github.com/angular/angular.js/commit/0e622f7b5bc3d5d0ab0fbc1a1bc69404bd7216d5))
|
||||
- **forms:** parse exponential notation in `numberInputType` directive
|
||||
([ebd0fbba](https://github.com/angular/angular.js/commit/ebd0fbba8ff90bee0cd016d574643d56a7f81ed0),
|
||||
[#12121](https://github.com/angular/angular.js/issues/12121), [#12122](https://github.com/angular/angular.js/issues/12122))
|
||||
- **linky:** allow case insensitive scheme detection
|
||||
([8dc09e6d](https://github.com/angular/angular.js/commit/8dc09e6dabb84c2c611cdc9e40adfac989648200),
|
||||
[#12073](https://github.com/angular/angular.js/issues/12073), [#12073](https://github.com/angular/angular.js/issues/12073))
|
||||
- **ngAria:**
|
||||
- update `aria-valuemin/max` when `min/max` change
|
||||
([ebaa0f59](https://github.com/angular/angular.js/commit/ebaa0f598501702ae64d59ada0ae492eaf0e2db6),
|
||||
[#11770](https://github.com/angular/angular.js/issues/11770), [#11774](https://github.com/angular/angular.js/issues/11774))
|
||||
- ensure boolean values for aria-hidden and aria-disabled
|
||||
([59273354](https://github.com/angular/angular.js/commit/59273354b57dd8d1ad2cd2f4740ffa8923e480f9),
|
||||
[#11365](https://github.com/angular/angular.js/issues/11365))
|
||||
- **ngModel:** ignore Object.prototype properties on the form validation object
|
||||
([0934b76b](https://github.com/angular/angular.js/commit/0934b76b72cec86093414834ac4cb7f0946b651d),
|
||||
[#12066](https://github.com/angular/angular.js/issues/12066))
|
||||
- **ngOptions:**
|
||||
- do not watch properties starting with $
|
||||
([34a6da24](https://github.com/angular/angular.js/commit/34a6da24c17356d4ffc70aec3f621a140a9a61ab),
|
||||
[#11930](https://github.com/angular/angular.js/issues/11930), [#12010](https://github.com/angular/angular.js/issues/12010))
|
||||
- use reference check only when not using trackBy
|
||||
([d7dc14dc](https://github.com/angular/angular.js/commit/d7dc14dc0cdeb9c187d227e19acc8aca7df9d740),
|
||||
[#11936](https://github.com/angular/angular.js/issues/11936), [#11996](https://github.com/angular/angular.js/issues/11996))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **$compile:** show module name during `multidir` error
|
||||
([351fe4b7](https://github.com/angular/angular.js/commit/351fe4b79c50a45a11af2fcd2aa7b6fd3b70058d),
|
||||
[#11775](https://github.com/angular/angular.js/issues/11775))
|
||||
- **$q:** $q.resolve as an alias for $q.when
|
||||
([3ef52980](https://github.com/angular/angular.js/commit/3ef529806fef28b41ca4af86a330f39a95699cf6),
|
||||
[#11944](https://github.com/angular/angular.js/issues/11944), [#11987](https://github.com/angular/angular.js/issues/11987))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
|
||||
- **$compile:** avoid jquery data calls when there is no data
|
||||
([9efb0d5e](https://github.com/angular/angular.js/commit/9efb0d5ee961b57c8fc144a3138a15955e4010e2))
|
||||
|
||||
|
||||
|
||||
<a name="1.3.16"></a>
|
||||
# 1.3.16 cookie-oatmealification (2015-06-05)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$compile:** throw error on invalid directive name
|
||||
([634e4671](https://github.com/angular/angular.js/commit/634e467172efa696eb32ef8942ffbedeecbd030e),
|
||||
[#11281](https://github.com/angular/angular.js/issues/11281), [#11109](https://github.com/angular/angular.js/issues/11109))
|
||||
- **$cookies:** update $cookies to prevent duplicate cookie writes and play nice with external code
|
||||
([706a93ab](https://github.com/angular/angular.js/commit/706a93ab6960e3474698ccf9a8048b3c32e567c6),
|
||||
[#11490](https://github.com/angular/angular.js/issues/11490), [#11515](https://github.com/angular/angular.js/issues/11515))
|
||||
- **$http:** throw error if `success` and `error` methods do not receive a function
|
||||
([731e1f65](https://github.com/angular/angular.js/commit/731e1f6534ab7fd1e053b8d7a25c902fcd934fea),
|
||||
[#11330](https://github.com/angular/angular.js/issues/11330), [#11333](https://github.com/angular/angular.js/issues/11333))
|
||||
- **core:** ensure that multiple requests to requestAnimationFrame are buffered
|
||||
([0adc0364](https://github.com/angular/angular.js/commit/0adc0364265b06c567ccc8e90a7f09cc46f235b2),
|
||||
[#11791](https://github.com/angular/angular.js/issues/11791))
|
||||
- **filterFilter:** fix matching against `null`/`undefined`
|
||||
([9dd0fe35](https://github.com/angular/angular.js/commit/9dd0fe35d1027e59b84b2396abee00d8683f3b50),
|
||||
[#11573](https://github.com/angular/angular.js/issues/11573), [#11617](https://github.com/angular/angular.js/issues/11617))
|
||||
- **jqLite:**
|
||||
- check for "length" in obj in isArrayLike to prevent iOS8 JIT bug from surfacing
|
||||
([647f3f55](https://github.com/angular/angular.js/commit/647f3f55eb7100a255272f7277f0f962de234a32),
|
||||
[#11508](https://github.com/angular/angular.js/issues/11508))
|
||||
- attr should ignore comment, text and attribute nodes
|
||||
([181e5ebc](https://github.com/angular/angular.js/commit/181e5ebc3fce5312feacaeace4fcad0d32f4d73c))
|
||||
- **ngAnimate:**
|
||||
- ensure that minified repaint code isn't removed
|
||||
([d5c99ea4](https://github.com/angular/angular.js/commit/d5c99ea42b834343fd0362cfc572f47e7536ccfb),
|
||||
[#9936](https://github.com/angular/angular.js/issues/9936))
|
||||
- **ngAria:** handle elements with role="checkbox/menuitemcheckbox"
|
||||
([1c282af5](https://github.com/angular/angular.js/commit/1c282af5abc205d4aac37c05c5cb725d71747134),
|
||||
[#11317](https://github.com/angular/angular.js/issues/11317), [#11321](https://github.com/angular/angular.js/issues/11321))
|
||||
- **ngModel:** allow setting model to NaN when asyncValidator is present
|
||||
([b64519fe](https://github.com/angular/angular.js/commit/b64519fea7f1a5ec75e32c4b71b012b827314153),
|
||||
[#11315](https://github.com/angular/angular.js/issues/11315), [#11411](https://github.com/angular/angular.js/issues/11411))
|
||||
- **ngTouch:**
|
||||
- check undefined tagName for SVG event target
|
||||
([7560a8d2](https://github.com/angular/angular.js/commit/7560a8d2d65955ddb60ede9d586502f4e3cbd062))
|
||||
- register touches properly when jQuery is used
|
||||
([40441f6d](https://github.com/angular/angular.js/commit/40441f6dfc5ebd5cdc679c269c4639238f5351eb),
|
||||
[#4001](https://github.com/angular/angular.js/issues/4001), [#8584](https://github.com/angular/angular.js/issues/8584), [#10797](https://github.com/angular/angular.js/issues/10797), [#11488](https://github.com/angular/angular.js/issues/11488))
|
||||
- **select:** prevent unknown option being added to select when bound to null property
|
||||
([9e3f82bb](https://github.com/angular/angular.js/commit/9e3f82bbaf83cad7bb3121db756099b0880562e6),
|
||||
[#11872](https://github.com/angular/angular.js/issues/11872), [#11875](https://github.com/angular/angular.js/issues/11875))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **travis:** run unit tests on iOS 8
|
||||
([1f650871](https://github.com/angular/angular.js/commit/1f650871266b88b3dab4a894a839a82ac9a06b69),
|
||||
[#11479](https://github.com/angular/angular.js/issues/11479))
|
||||
|
||||
|
||||
|
||||
<a name="1.4.0"></a>
|
||||
# 1.4.0 jaracimrman-existence (2015-05-26)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$animate:**
|
||||
- ignore invalid option parameter values
|
||||
([72edd4df](https://github.com/angular/angular.js/commit/72edd4dff931c644eecb8f0d1c878dc839c76947),
|
||||
[#11826](https://github.com/angular/angular.js/issues/11826))
|
||||
- accept unwrapped DOM elements as inputs for enter + move
|
||||
([f26fc26f](https://github.com/angular/angular.js/commit/f26fc26f6ea283b2fc5ddb18627b13850de2663e),
|
||||
[#11848](https://github.com/angular/angular.js/issues/11848))
|
||||
- **$animateCss:** ensure that custom durations do not confuse the gcs cache
|
||||
([e0e1b520](https://github.com/angular/angular.js/commit/e0e1b5208767dd62f5586fdc607cb2e31dac9516),
|
||||
[#11723](https://github.com/angular/angular.js/issues/11723), [#11852](https://github.com/angular/angular.js/issues/11852))
|
||||
- **$http:** do not modify the config object passed into $http short methods
|
||||
([f7a4b481](https://github.com/angular/angular.js/commit/f7a4b48121ed2b04af89bd2b754f500d1872360d))
|
||||
- **ngAnimate:**
|
||||
- close follow-up class-based animations when the same class is added/removed when removed/added
|
||||
([db246eb7](https://github.com/angular/angular.js/commit/db246eb701529b41049fc118908e528920f13b24),
|
||||
[#11717](https://github.com/angular/angular.js/issues/11717))
|
||||
- ensure nested class-based animations are spaced out with a RAF
|
||||
([213c2a70](https://github.com/angular/angular.js/commit/213c2a703293ee0af8229dde2b608687cd77ccfa),
|
||||
[#11812](https://github.com/angular/angular.js/issues/11812))
|
||||
- class-based animations must not set addClass/removeClass CSS classes on the element
|
||||
([3a3db690](https://github.com/angular/angular.js/commit/3a3db690a16e888aa7371e3b02e2954b9ec2d558),
|
||||
[#11810](https://github.com/angular/angular.js/issues/11810))
|
||||
- ensure that repeated structural calls during pre-digest function
|
||||
([2327f5a0](https://github.com/angular/angular.js/commit/2327f5a0a7e018a9b03aefabe1fbd0c9330e2eeb),
|
||||
[#11867](https://github.com/angular/angular.js/issues/11867))
|
||||
- ensure that cancelled class-based animations are properly cleaned up
|
||||
([718ff844](https://github.com/angular/angular.js/commit/718ff84405558ac64402e1fca5caefd7d307ea1e),
|
||||
[#11652](https://github.com/angular/angular.js/issues/11652))
|
||||
- throw an error if a callback is passed to animate methods
|
||||
([9bb4d6cc](https://github.com/angular/angular.js/commit/9bb4d6ccbe80b7704c6b7f53317ca8146bc103ca),
|
||||
[#11826](https://github.com/angular/angular.js/issues/11826), [#11713](https://github.com/angular/angular.js/issues/11713))
|
||||
- ensure anchored animations remove the leave element at correct time
|
||||
([64c66d0e](https://github.com/angular/angular.js/commit/64c66d0eea11b575d2a71d00c70cfc5be12cd450),
|
||||
[#11850](https://github.com/angular/angular.js/issues/11850))
|
||||
- **select:** prevent unknown option being added to select when bound to null property
|
||||
([4090491c](https://github.com/angular/angular.js/commit/4090491c73910c169d4fba0494a4e26b45dca7ec),
|
||||
[#11872](https://github.com/angular/angular.js/issues/11872), [#11875](https://github.com/angular/angular.js/issues/11875))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **filterFilter:** allow array like objects to be filtered
|
||||
([1b0d0fd8](https://github.com/angular/angular.js/commit/1b0d0fd8d00b42dffd798845fe0947d594372613),
|
||||
[#11782](https://github.com/angular/angular.js/issues/11782), [#11787](https://github.com/angular/angular.js/issues/11787))
|
||||
|
||||
|
||||
|
||||
<a name="1.4.0-rc.2"></a>
|
||||
# 1.4.0-rc.2 rocket-zambonimation (2015-05-12)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$compile:** ensure directive names have no leading or trailing whitespace
|
||||
([bab474aa](https://github.com/angular/angular.js/commit/bab474aa8b146f6732857c3af1a8b3b010fda8b0),
|
||||
[#11397](https://github.com/angular/angular.js/issues/11397), [#11772](https://github.com/angular/angular.js/issues/11772))
|
||||
- **$httpParamSerializerJQLike:** follow jQuery logic for nested params
|
||||
([2420a0a7](https://github.com/angular/angular.js/commit/2420a0a77e27b530dbb8c41319b2995eccf76791),
|
||||
[#11551](https://github.com/angular/angular.js/issues/11551), [#11635](https://github.com/angular/angular.js/issues/11635))
|
||||
- **jqLite:** check for "length" in obj in isArrayLike to prevent iOS8 JIT bug from surfacing
|
||||
([426a5ac0](https://github.com/angular/angular.js/commit/426a5ac0547109648e5c5e358f668c274a111ab2),
|
||||
[#11508](https://github.com/angular/angular.js/issues/11508))
|
||||
- **ngAnimate:**
|
||||
- ensure that multiple requests to requestAnimationFrame are buffered
|
||||
([db20b830](https://github.com/angular/angular.js/commit/db20b830fc6074a00dc11d3f47d665c55e8bb515),
|
||||
[#11791](https://github.com/angular/angular.js/issues/11791))
|
||||
- ensure that an object is always returned even when no animation is set to run
|
||||
([d5683d21](https://github.com/angular/angular.js/commit/d5683d21165e725bc5a850e795f681b0a8a008f5))
|
||||
- force use of `ng-anchor` instead of a suffixed `-anchor` CSS class when triggering anchor animations
|
||||
([df24410c](https://github.com/angular/angular.js/commit/df24410c17d51a8d44929b9cffee2c91cedfed72))
|
||||
- rename `ng-animate-anchor` to `ng-anchor`
|
||||
([e6d053de](https://github.com/angular/angular.js/commit/e6d053de0993c0d38de46ad8a9c6760537316430))
|
||||
- ensure that shared CSS classes between anchor nodes are retained
|
||||
([e0014002](https://github.com/angular/angular.js/commit/e0014002370278778077d0612f9fab6beb80d07a),
|
||||
[#11681](https://github.com/angular/angular.js/issues/11681))
|
||||
- prohibit usage of the `ng-animate` class with classNameFilter
|
||||
([1002b80a](https://github.com/angular/angular.js/commit/1002b80a6fb5d98c424a01330234276d65d93c0b),
|
||||
[#11431](https://github.com/angular/angular.js/issues/11431), [#11807](https://github.com/angular/angular.js/issues/11807))
|
||||
- ensure that the temporary CSS classes are applied before detection
|
||||
([f7e9ff1a](https://github.com/angular/angular.js/commit/f7e9ff1aba9ed70835c084e6e154f6b0bf9c3a19),
|
||||
[#11769](https://github.com/angular/angular.js/issues/11769), [#11804](https://github.com/angular/angular.js/issues/11804))
|
||||
- ensure that all jqLite elements are deconstructed properly
|
||||
([64d05180](https://github.com/angular/angular.js/commit/64d05180a667e586328fbdbd328889d3b003571d),
|
||||
[#11658](https://github.com/angular/angular.js/issues/11658))
|
||||
- ensure animations are not attempted on text nodes
|
||||
([2aacc2d6](https://github.com/angular/angular.js/commit/2aacc2d622893e05eb94b3974d562e681cc3a17f),
|
||||
[#11703](https://github.com/angular/angular.js/issues/11703))
|
||||
- ensure JS animations recognize $animateCss directly
|
||||
([0681a540](https://github.com/angular/angular.js/commit/0681a5400e4150a961f9c8651e55623ca23b0cc2))
|
||||
- **ngClass:** add/remove classes which are properties of Object.prototype
|
||||
([f7b99970](https://github.com/angular/angular.js/commit/f7b999703f4f3bdaea035ce692f1a656b0c1a933),
|
||||
[#11813](https://github.com/angular/angular.js/issues/11813), [#11814](https://github.com/angular/angular.js/issues/11814))
|
||||
- **ngOptions:**
|
||||
- ensure that tracked properties are always watched
|
||||
([b5a9053b](https://github.com/angular/angular.js/commit/b5a9053ba33d48db2482ca6736d1fcae8b33d0f8),
|
||||
[#11784](https://github.com/angular/angular.js/issues/11784))
|
||||
- ensure label is watched in all cases
|
||||
([ae98dadf](https://github.com/angular/angular.js/commit/ae98dadf6dca3313746f42a441c7659654dd9d50),
|
||||
[#11765](https://github.com/angular/angular.js/issues/11765))
|
||||
- iterate over the options collection in the same way as `ngRepeat`
|
||||
([dfa722a8](https://github.com/angular/angular.js/commit/dfa722a8a6864793fd9580d8ae704a06d10b5509),
|
||||
[#11733](https://github.com/angular/angular.js/issues/11733))
|
||||
- use watchCollection not deep watch of ngModel
|
||||
([47f9fc3e](https://github.com/angular/angular.js/commit/47f9fc3e70bc361e8c11fe68dc3ec4489238efb3),
|
||||
[#11372](https://github.com/angular/angular.js/issues/11372), [#11653](https://github.com/angular/angular.js/issues/11653), [#11743](https://github.com/angular/angular.js/issues/11743))
|
||||
- **ngTouch:**
|
||||
- check undefined tagName for SVG event target
|
||||
([74eb17d7](https://github.com/angular/angular.js/commit/74eb17d7c8232f72f134bf2546f10fed7234d276))
|
||||
- don't prevent click event after a touchmove
|
||||
([95521876](https://github.com/angular/angular.js/commit/95521876eb9eb330548b0549f0cfe22a26d88f6e),
|
||||
[#10985](https://github.com/angular/angular.js/issues/10985))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **$resource:** include request context in error message
|
||||
([266bc652](https://github.com/angular/angular.js/commit/266bc6520ba4d188dbc949643def102604f98905),
|
||||
[#11363](https://github.com/angular/angular.js/issues/11363))
|
||||
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
### ngAnimate
|
||||
|
||||
- **$animateCss:** due to [d5683d21](https://github.com/angular/angular.js/commit/d5683d21165e725bc5a850e795f681b0a8a008f5),
|
||||
The $animateCss service will now always return an
|
||||
object even if the animation is not set to run. If your code is using
|
||||
$animateCss then please consider the following code change:
|
||||
|
||||
```
|
||||
// before
|
||||
var animator = $animateCss(element, { ... });
|
||||
if (!animator) {
|
||||
continueApp();
|
||||
return;
|
||||
}
|
||||
var runner = animator.start();
|
||||
runner.done(continueApp);
|
||||
runner.then(continueApp);
|
||||
|
||||
// now
|
||||
var animator = $animateCss(element, { ... });
|
||||
var runner = animator.start();
|
||||
runner.done(continueApp);
|
||||
runner.then(continueApp);
|
||||
```
|
||||
|
||||
- due to [df24410c](https://github.com/angular/angular.js/commit/df24410c17d51a8d44929b9cffee2c91cedfed72),
|
||||
Prior to this fix there were to ways to apply CSS
|
||||
animation code to an anchor animation. With this fix, the suffixed
|
||||
CSS -anchor classes are now not used anymore for CSS anchor animations.
|
||||
|
||||
Instead just use the `ng-anchor` CSS class like so:
|
||||
|
||||
```html
|
||||
<div class="container-animation" ng-if="on">
|
||||
<div ng-animate-ref="1" class="my-anchor-element"></div>
|
||||
</div>
|
||||
|
||||
<div class="container-animation" ng-if="!on">
|
||||
<div ng-animate-ref="1" class="my-anchor-element"></div>
|
||||
</div>
|
||||
```
|
||||
|
||||
**before**:
|
||||
```css
|
||||
/* before (notice the container-animation CSS class) */
|
||||
.container-animation-anchor {
|
||||
transition:0.5s linear all;
|
||||
}
|
||||
```
|
||||
|
||||
**now**:
|
||||
```css
|
||||
/* now (just use `ng-anchor` on a class that both the
|
||||
elements that contain `ng-animate-ref` share) */
|
||||
.my-anchor-element.ng-anchor {
|
||||
transition:0.5s linear all;
|
||||
}
|
||||
```
|
||||
|
||||
- due to [e6d053de](https://github.com/angular/angular.js/commit/e6d053de0993c0d38de46ad8a9c6760537316430),
|
||||
if your CSS code made use of the `ng-animate-anchor`
|
||||
CSS class for referencing the anchored animation element then your
|
||||
code must now use `ng-anchor` instead.
|
||||
|
||||
- due to [1002b80a](https://github.com/angular/angular.js/commit/1002b80a6fb5d98c424a01330234276d65d93c0b),
|
||||
partially or fully using a regex value containing
|
||||
`ng-animate` as a token is not allowed anymore. Doing so will trigger a
|
||||
minErr exception to be thrown.
|
||||
|
||||
So don't do this:
|
||||
|
||||
```js
|
||||
// only animate elements that contain the `ng-animate` CSS class
|
||||
$animateProvider.classNameFilter(/ng-animate/);
|
||||
|
||||
// or partially contain it
|
||||
$animateProvider.classNameFilter(/some-class ng-animate another-class/);
|
||||
```
|
||||
|
||||
but this is OK:
|
||||
|
||||
```js
|
||||
$animateProvider.classNameFilter(/ng-animate-special/);
|
||||
```
|
||||
|
||||
|
||||
### ngOptions
|
||||
|
||||
- ** due to [dfa722a8](https://github.com/angular/angular.js/commit/dfa722a8a6864793fd9580d8ae704a06d10b5509),
|
||||
|
||||
|
||||
Although it is unlikely that anyone is using it in this way, this change does change the
|
||||
behaviour of `ngOptions` in the following case:
|
||||
|
||||
* you are iterating over an array-like object, using the array form of the `ngOptions` syntax
|
||||
(`item.label for item in items`) and that object contains non-numeric property keys.
|
||||
|
||||
In this case these properties with non-numeric keys will be ignored.
|
||||
|
||||
** Here array-like is defined by the result of a call to this internal function:
|
||||
https://github.com/angular/angular.js/blob/v1.4.0-rc.1/src/Angular.js#L198-L211 **
|
||||
|
||||
To get the desired behaviour you need to iterate using the object form of the `ngOptions` syntax
|
||||
(`value.label` for (key, value) in items)`).
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="v1.4.0-rc.1"></a>
|
||||
# v1.4.0-rc.1 sartorial-chronography (2015-04-24)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$animate:**
|
||||
- ensure that from styles are applied for class-based animations
|
||||
([8f819d2c](https://github.com/angular/angular.js/commit/8f819d2cb5c8025b25534529a6e897dc8805885b))
|
||||
- make sure the JS animation lookup is an object lookup
|
||||
([103a39ca](https://github.com/angular/angular.js/commit/103a39ca8dad0300bead15c358aad846510b2229),
|
||||
[#11619](https://github.com/angular/angular.js/issues/11619))
|
||||
- **$animateCss:** ensure that rAF waiting loop doesn't ignore pending items during a flush
|
||||
([90e424b2](https://github.com/angular/angular.js/commit/90e424b206239e261024e8ef7fcac762236cd8b7))
|
||||
- **$http:** stop coercing falsy HTTP request bodies to null / empty body
|
||||
([e04a887c](https://github.com/angular/angular.js/commit/e04a887c9b506de18516600310fe6e529d9d2ca3),
|
||||
[#11552](https://github.com/angular/angular.js/issues/11552), [#11593](https://github.com/angular/angular.js/issues/11593))
|
||||
- **ngAnimate:**
|
||||
- close parent animations only when there are classes to resolve
|
||||
([1459be17](https://github.com/angular/angular.js/commit/1459be170dabfca40501dcf219dfced5ba513169))
|
||||
- ensure ngClass-based classes are always resolved for CSS-enabled animations
|
||||
([89f081e4](https://github.com/angular/angular.js/commit/89f081e452e9a75c2d3bf86bfef8b7f9bd1f2b0e))
|
||||
- do not abort animation if only `ng-anchor-in` is used
|
||||
([3333a5c3](https://github.com/angular/angular.js/commit/3333a5c380f830cba8efec5825cb6648f930f206))
|
||||
- ensure that a filtered-out leave animation always runs its DOM operation
|
||||
([6dd64ab5](https://github.com/angular/angular.js/commit/6dd64ab5f34fa19db8f90e6eabc810843089ba14),
|
||||
[#11555](https://github.com/angular/angular.js/issues/11555))
|
||||
- ensure that animations work when the app is bootstrapped on the document node
|
||||
([bee14ed1](https://github.com/angular/angular.js/commit/bee14ed1e7b77ea7dc62326611380da36dec297e),
|
||||
[#11574](https://github.com/angular/angular.js/issues/11574))
|
||||
- ensure SVG classes are properly removed
|
||||
([fa0bbded](https://github.com/angular/angular.js/commit/fa0bbded1ea040fbfdb1a4339e4a374fe9717a82))
|
||||
- **ngAria:** change accessibility keypress event to use event.which if it is provided
|
||||
([249f9b81](https://github.com/angular/angular.js/commit/249f9b81cbad5c57cf978a47842744aadd85cdb4),
|
||||
[#11340](https://github.com/angular/angular.js/issues/11340))
|
||||
- **ngMessageFormat:**
|
||||
- ensure bindings are valid for Protractor
|
||||
([992114f7](https://github.com/angular/angular.js/commit/992114f7a7f5f39778753e0c49458f14b6290ffc),
|
||||
[#11644](https://github.com/angular/angular.js/issues/11644), [#11649](https://github.com/angular/angular.js/issues/11649))
|
||||
- minified symbol and nested required expression
|
||||
([8a45064f](https://github.com/angular/angular.js/commit/8a45064f2bdec13ba3de5b0a0785df76188ab172),
|
||||
[#11414](https://github.com/angular/angular.js/issues/11414), [#11592](https://github.com/angular/angular.js/issues/11592))
|
||||
- **select:** allow empty option to be added dynamically by ng-repeat
|
||||
([abf59c28](https://github.com/angular/angular.js/commit/abf59c285c3ff6af20dbf4236eba5204ae735abb),
|
||||
[#11470](https://github.com/angular/angular.js/issues/11470), [#11512](https://github.com/angular/angular.js/issues/11512))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **$animate:** provide support for animations on elements outside of $rootElement
|
||||
([e41faaa2](https://github.com/angular/angular.js/commit/e41faaa2a155a42bcc66952497a6f33866878508))
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="v1.4.0-rc.0"></a>
|
||||
# v1.4.0-rc.0 smooth-unwinding (2015-04-10)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$compile:**
|
||||
- throw error on invalid directive name
|
||||
([170ff9a3](https://github.com/angular/angular.js/commit/170ff9a37dea8772dda7c89e84176ac1a8992878),
|
||||
[#11281](https://github.com/angular/angular.js/issues/11281), [#11109](https://github.com/angular/angular.js/issues/11109))
|
||||
- update data() when controller returns custom value
|
||||
([9900610e](https://github.com/angular/angular.js/commit/9900610eea4ece87b063f2aa9d82c75c369927df),
|
||||
[#11147](https://github.com/angular/angular.js/issues/11147), [#11326](https://github.com/angular/angular.js/issues/11326))
|
||||
- **$http:** throw error if `success` and `error` methods do not receive a function
|
||||
([1af563d4](https://github.com/angular/angular.js/commit/1af563d43e74cb7be53e815b66fd91dd93986ed6),
|
||||
[#11330](https://github.com/angular/angular.js/issues/11330), [#11333](https://github.com/angular/angular.js/issues/11333))
|
||||
- **$parse:** fix parse errors on older Android WebViews which choke with reserved keywords
|
||||
([10ae33b2](https://github.com/angular/angular.js/commit/10ae33b2d88b04df76f519edc50a47fa30f83e96),
|
||||
[#11455](https://github.com/angular/angular.js/issues/11455))
|
||||
- **$rootScope:** allow destroying a root scope
|
||||
([f8c8cf69](https://github.com/angular/angular.js/commit/f8c8cf698aa23640249d79fd405605694478e4f7),
|
||||
[#11241](https://github.com/angular/angular.js/issues/11241), [#10895](https://github.com/angular/angular.js/issues/10895))
|
||||
- **cookieReader:** safely access $document so it can be mocked
|
||||
([a057e089](https://github.com/angular/angular.js/commit/a057e0896a7fe2fdaba50b2515555b86e4f4be27),
|
||||
[#11373](https://github.com/angular/angular.js/issues/11373), [#11388](https://github.com/angular/angular.js/issues/11388))
|
||||
- **filterFilter:** fix matching against `null`/`undefined`
|
||||
([b5002ab6](https://github.com/angular/angular.js/commit/b5002ab62ad6e13f4339e20106e1fdece14912a2),
|
||||
[#11432](https://github.com/angular/angular.js/issues/11432), [#11445](https://github.com/angular/angular.js/issues/11445))
|
||||
- **ngAnimate:** ensure that minified repaint code isn't removed
|
||||
([c55a4944](https://github.com/angular/angular.js/commit/c55a494433e619aad0c7ef9fddadc0b3fdf53915),
|
||||
[#9936](https://github.com/angular/angular.js/issues/9936))
|
||||
- **ngAria:** handle elements with role="checkbox/menuitemcheckbox"
|
||||
([44337f63](https://github.com/angular/angular.js/commit/44337f63fa94116795e83e3a764a6ba6782809c7),
|
||||
[#11317](https://github.com/angular/angular.js/issues/11317), [#11321](https://github.com/angular/angular.js/issues/11321))
|
||||
- **ngModel:** allow setting model to NaN when asyncValidator is present
|
||||
([948120ec](https://github.com/angular/angular.js/commit/948120ecdbc4dd07880c0107564c50c7675b8a93),
|
||||
[#11315](https://github.com/angular/angular.js/issues/11315), [#11411](https://github.com/angular/angular.js/issues/11411))
|
||||
- **ngTouch:** register touches properly when jQuery is used
|
||||
([06a9f0a9](https://github.com/angular/angular.js/commit/06a9f0a95f0e72fa2e9879fe8a49e9bf69986a5f),
|
||||
[#4001](https://github.com/angular/angular.js/issues/4001), [#8584](https://github.com/angular/angular.js/issues/8584), [#10797](https://github.com/angular/angular.js/issues/10797), [#11488](https://github.com/angular/angular.js/issues/11488))
|
||||
- **select:** don't call $render twice if $viewValue ref changes
|
||||
([7e5c447f](https://github.com/angular/angular.js/commit/7e5c447fa9ad7d81cc818d6e79392c3e4a6b23a0),
|
||||
[#11329](https://github.com/angular/angular.js/issues/11329), [#11412](https://github.com/angular/angular.js/issues/11412))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **$anchorScroll:** allow scrolling to a specified element
|
||||
([731c8b5e](https://github.com/angular/angular.js/commit/731c8b5e2d01a44aa91f967f1a6acbadb8005a8b),
|
||||
[#4568](https://github.com/angular/angular.js/issues/4568), [#9596](https://github.com/angular/angular.js/issues/9596))
|
||||
- **$animate:** complete refactor of internal animation code
|
||||
([c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef))
|
||||
- **$http:** support custom params serializers
|
||||
([6c8464ad](https://github.com/angular/angular.js/commit/6c8464ad14dd308349f632245c1a064c9aae242a),
|
||||
[#3740](https://github.com/angular/angular.js/issues/3740), [#7429](https://github.com/angular/angular.js/issues/7429), [#9224](https://github.com/angular/angular.js/issues/9224), [#11461](https://github.com/angular/angular.js/issues/11461))
|
||||
- **$interpolate:** extend interpolation with MessageFormat like syntax
|
||||
([1e58488a](https://github.com/angular/angular.js/commit/1e58488ad65abf7031bab5813523bb9d86dbd28c),
|
||||
[#11152](https://github.com/angular/angular.js/issues/11152))
|
||||
- **angular.Module:** add `decorator` method
|
||||
([e57138d7](https://github.com/angular/angular.js/commit/e57138d7eff1210f99238c475fff57530bf0ab19),
|
||||
[#11305](https://github.com/angular/angular.js/issues/11305), [#11300](https://github.com/angular/angular.js/issues/11300))
|
||||
- **ngClass:** add support for conditional map within an array.
|
||||
([4588e627](https://github.com/angular/angular.js/commit/4588e627bb7238b2113241919b948d0e5166c76d),
|
||||
[#4807](https://github.com/angular/angular.js/issues/4807))
|
||||
- **travis:** run unit tests on iOS 8
|
||||
([2cdb2016](https://github.com/angular/angular.js/commit/2cdb2016b9d89abfb5ab988b67d5f26f3bf21908),
|
||||
[#11479](https://github.com/angular/angular.js/issues/11479))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
|
||||
- **$rootScope:** remove history event handler when app is torn down
|
||||
([d996305b](https://github.com/angular/angular.js/commit/d996305b4470f80fbb1cbddf54b7d10ffbb6ab47),
|
||||
[#9897](https://github.com/angular/angular.js/issues/9897), [#9905](https://github.com/angular/angular.js/issues/9905))
|
||||
- **benchmark:** add ngmodel benchmarks to largetable-bp
|
||||
([b8dbdb0c](https://github.com/angular/angular.js/commit/b8dbdb0c5e2cd176c6d94d60f781cfc02e646592),
|
||||
[#11082](https://github.com/angular/angular.js/issues/11082))
|
||||
- **ngOptions:** only perform deep equality check on ngModel if using track by
|
||||
([171b9f7f](https://github.com/angular/angular.js/commit/171b9f7f2339ef9047b8526b2c3f36bb58d14feb),
|
||||
[#11448](https://github.com/angular/angular.js/issues/11448), [#11447](https://github.com/angular/angular.js/issues/11447))
|
||||
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- **$animate:** due to [c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef),
|
||||
JavaScript and CSS animations can no longer be run in
|
||||
parallel. With earlier versions of ngAnimate, both CSS and JS animations
|
||||
would be run together when multiple animations were detected. This
|
||||
feature has now been removed, however, the same effect, with even more
|
||||
possibilities, can be achieved by injecting `$animateCss` into a
|
||||
JavaScript-defined animation and creating custom CSS-based animations
|
||||
from there. Read the ngAnimate docs for more info.
|
||||
|
||||
- **$animate:** due to [c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef),
|
||||
The function params for `$animate.enabled()` when an
|
||||
element is used are now flipped. This fix allows the function to act as
|
||||
a getter when a single element param is provided.
|
||||
|
||||
```js
|
||||
// < 1.4
|
||||
$animate.enabled(false, element);
|
||||
|
||||
// 1.4+
|
||||
$animate.enabled(element, false);
|
||||
```
|
||||
|
||||
- **$animate:** due to [c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef),
|
||||
In addition to disabling the children of the element,
|
||||
`$animate.enabled(element, false)` will now also disable animations on
|
||||
the element itself.
|
||||
|
||||
- **$animate:** due to [c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef),
|
||||
Animation-related callbacks are now fired on
|
||||
`$animate.on` instead of directly being on the element.
|
||||
|
||||
```js
|
||||
// < 1.4
|
||||
element.on('$animate:before', function(e, data) {
|
||||
if (data.event === 'enter') { ... }
|
||||
});
|
||||
element.off('$animate:before', fn);
|
||||
|
||||
// 1.4+
|
||||
$animate.on(element, 'enter', function(data) {
|
||||
//...
|
||||
});
|
||||
$animate.off(element, 'enter', fn);
|
||||
```
|
||||
|
||||
- **$animate:** due to [c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef),
|
||||
There is no need to call `$scope.$apply` or
|
||||
`$scope.$digest` inside of an animation promise callback anymore
|
||||
since the promise is resolved within a digest automatically (but a
|
||||
digest is not run unless the promise is chained).
|
||||
|
||||
```js
|
||||
// < 1.4
|
||||
$animate.enter(element).then(function() {
|
||||
$scope.$apply(function() {
|
||||
$scope.explode = true;
|
||||
});
|
||||
});
|
||||
|
||||
// 1.4+
|
||||
$animate.enter(element).then(function() {
|
||||
$scope.explode = true;
|
||||
});
|
||||
```
|
||||
|
||||
- **$animate:** due to [c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef),
|
||||
When an enter, leave or move animation is triggered then it
|
||||
will always end any pending or active parent class based animations
|
||||
(animations triggered via ngClass) in order to ensure that any CSS
|
||||
styles are resolved in time.
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="1.4.0-beta.6"></a>
|
||||
# 1.4.0-beta.6 cookie-liberation (2015-03-17)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$animate:** call `applyStyles` from options on `leave`
|
||||
([4374f892](https://github.com/angular/angular.js/commit/4374f892c6fa4af6ba1f2ed47c5f888fdb5fadc5),
|
||||
[#10068](https://github.com/angular/angular.js/issues/10068))
|
||||
- **$browser:** don't crash if `history.state` access causes error in IE
|
||||
([3b8163b7](https://github.com/angular/angular.js/commit/3b8163b7b664f24499e75460ab50c066eaec0f78),
|
||||
[#10367](https://github.com/angular/angular.js/issues/10367), [#10369](https://github.com/angular/angular.js/issues/10369))
|
||||
- **$sanitize:** disallow unsafe svg animation tags
|
||||
([67688d5c](https://github.com/angular/angular.js/commit/67688d5ca00f6de4c7fe6084e2fa762a00d25610),
|
||||
[#11290](https://github.com/angular/angular.js/issues/11290))
|
||||
- **Angular:** properly compare RegExp with other objects for equality
|
||||
([f22e1fc9](https://github.com/angular/angular.js/commit/f22e1fc9610ae111a3ea8746a3a57169c99ce142),
|
||||
[#11204](https://github.com/angular/angular.js/issues/11204), [#11205](https://github.com/angular/angular.js/issues/11205))
|
||||
- **date filter:** display localised era for `G` format codes
|
||||
([2b4dfa9e](https://github.com/angular/angular.js/commit/2b4dfa9e2b63d7ebb78f3b0fd3439d18f932e1cd),
|
||||
[#10503](https://github.com/angular/angular.js/issues/10503), [#11266](https://github.com/angular/angular.js/issues/11266))
|
||||
- **filterFilter:**
|
||||
- fix filtering using an object expression when the filter value is undefined
|
||||
([c62fa6bd](https://github.com/angular/angular.js/commit/c62fa6bd898e1048d4690d41034489dc60ba6ac2),
|
||||
[#10419](https://github.com/angular/angular.js/issues/10419), [#10424](https://github.com/angular/angular.js/issues/10424))
|
||||
- do not throw an error if property is null when comparing objects
|
||||
([2c4ffd6a](https://github.com/angular/angular.js/commit/2c4ffd6af4eb012c4054fe7c096267bbc5510af0),
|
||||
[#10991](https://github.com/angular/angular.js/issues/10991), [#10992](https://github.com/angular/angular.js/issues/10992), [#11116](https://github.com/angular/angular.js/issues/11116))
|
||||
- **form:** allow dynamic form names which initially evaluate to blank
|
||||
([410f7c68](https://github.com/angular/angular.js/commit/410f7c682633c681be641cd2a321f9e51671d474))
|
||||
- **jqLite:** attr should ignore comment, text and attribute nodes
|
||||
([bb5bf7f8](https://github.com/angular/angular.js/commit/bb5bf7f8162d11610a53428e630b47030bdc38e5))
|
||||
- **ng/$locale:** add ERA info in generic locale
|
||||
([4acb0af2](https://github.com/angular/angular.js/commit/4acb0af24c7fb3705a197ca96adc532de4766a7a))
|
||||
- **ngJq:** don't rely on existence of jqlite
|
||||
([342e5f3c](https://github.com/angular/angular.js/commit/342e5f3ce38d2fd10c5d5a98ca66f864286a7922),
|
||||
[#11044](https://github.com/angular/angular.js/issues/11044))
|
||||
- **ngMessages:** ensure that multi-level transclusion works with `ngMessagesInclude`
|
||||
([d7ec5f39](https://github.com/angular/angular.js/commit/d7ec5f392e1550658ddf271a30627b1749eccb69),
|
||||
[#11196](https://github.com/angular/angular.js/issues/11196))
|
||||
- **ngOptions:** fix model<->option interaction when using `track by`
|
||||
([6a03ca27](https://github.com/angular/angular.js/commit/6a03ca274314352052c3082163367a146bb11c2d),
|
||||
[#10869](https://github.com/angular/angular.js/issues/10869), [#10893](https://github.com/angular/angular.js/issues/10893))
|
||||
- **rootScope:** prevent memory leak when destroying scopes
|
||||
([fb7db4a0](https://github.com/angular/angular.js/commit/fb7db4a07bd1b0b67824d3808fe315419b272689),
|
||||
[#11173](https://github.com/angular/angular.js/issues/11173), [#11169](https://github.com/angular/angular.js/issues/11169))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **$cookies:**
|
||||
- allow passing cookie options
|
||||
([92c366d2](https://github.com/angular/angular.js/commit/92c366d205da36ec26502aded23db71a6473dad7),
|
||||
[#8324](https://github.com/angular/angular.js/issues/8324), [#3988](https://github.com/angular/angular.js/issues/3988), [#1786](https://github.com/angular/angular.js/issues/1786), [#950](https://github.com/angular/angular.js/issues/950))
|
||||
- move logic into $cookies and deprecate $cookieStore
|
||||
([38fbe3ee](https://github.com/angular/angular.js/commit/38fbe3ee8370fc449b82d80df07b5c2ed2cd5fbe),
|
||||
[#6411](https://github.com/angular/angular.js/issues/6411), [#7631](https://github.com/angular/angular.js/issues/7631))
|
||||
- **$cookiesProvider:** provide path, domain, expires and secure options
|
||||
([53c66369](https://github.com/angular/angular.js/commit/53c663699126815eabc2a3bc1e3bafc8b3874268))
|
||||
- **$interval:** pass additional arguments to the callback
|
||||
([4f1f9cfd](https://github.com/angular/angular.js/commit/4f1f9cfdb721cf308ca1162b2227836dc1d28388),
|
||||
[#10632](https://github.com/angular/angular.js/issues/10632))
|
||||
- **$timeout:** pass additional arguments to the callback
|
||||
([3a4b6b83](https://github.com/angular/angular.js/commit/3a4b6b83efdb8051e5c4803c0892c19ceb2cba50),
|
||||
[#10631](https://github.com/angular/angular.js/issues/10631))
|
||||
- **angular.merge:** provide an alternative to `angular.extend` that merges 'deeply'
|
||||
([c0498d45](https://github.com/angular/angular.js/commit/c0498d45feb913c318224ea70b5adf7112df6bac),
|
||||
[#10507](https://github.com/angular/angular.js/issues/10507), [#10519](https://github.com/angular/angular.js/issues/10519))
|
||||
- **filterFilter:** compare object with custom `toString()` to primitive
|
||||
([f8c42161](https://github.com/angular/angular.js/commit/f8c421617096a8d613f4eb6d0f5b098ee149c029),
|
||||
[#10464](https://github.com/angular/angular.js/issues/10464), [#10548](https://github.com/angular/angular.js/issues/10548))
|
||||
- **ngAria:**
|
||||
- add `button` role to `ngClick`
|
||||
([bb365070](https://github.com/angular/angular.js/commit/bb365070a3ed7c2d26056d378ab6a8ef493b23cc),
|
||||
[#9254](https://github.com/angular/angular.js/issues/9254), [#10318](https://github.com/angular/angular.js/issues/10318))
|
||||
- add roles to custom inputs
|
||||
([29cdaee2](https://github.com/angular/angular.js/commit/29cdaee2b6e853bc3f8882a00661698d146ecd18),
|
||||
[#10012](https://github.com/angular/angular.js/issues/10012), [#10318](https://github.com/angular/angular.js/issues/10318))
|
||||
- **ngLocale:** Add FIRSTDAYOFWEEK and WEEKENDRANGE from google data
|
||||
([3d149c7f](https://github.com/angular/angular.js/commit/3d149c7f20ffabab5a635af9ddcfc7105112ab4a))
|
||||
- **ngMock:**
|
||||
- allow mock $controller service to set up controller bindings
|
||||
([d02d0585](https://github.com/angular/angular.js/commit/d02d0585a086ecd2e1de628218b5a6d85c8fc7bd),
|
||||
[#9425](https://github.com/angular/angular.js/issues/9425), [#11239](https://github.com/angular/angular.js/issues/11239))
|
||||
- add `they` helpers for testing multiple specs
|
||||
([e650c458](https://github.com/angular/angular.js/commit/e650c45894abe6314a806e6b3e32c908df5c00fd),
|
||||
[#10864](https://github.com/angular/angular.js/issues/10864))
|
||||
- **ngModel:** support conversion to timezone other than UTC
|
||||
([0413bee8](https://github.com/angular/angular.js/commit/0413bee8cc563a6555f8d42d5f183f6fbefc7350),
|
||||
[#11005](https://github.com/angular/angular.js/issues/11005))
|
||||
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- **$cookies:** due to [38fbe3ee](https://github.com/angular/angular.js/commit/38fbe3ee8370fc449b82d80df07b5c2ed2cd5fbe),
|
||||
|
||||
|
||||
`$cookies` no longer exposes properties that represent the current browser cookie
|
||||
values. Now you must explicitly the methods described above to access the cookie
|
||||
values. This also means that you can no longer watch the `$cookies` properties for
|
||||
changes to the browser's cookies.
|
||||
|
||||
This feature is generally only needed if a 3rd party library was programmatically
|
||||
changing the cookies at runtime. If you rely on this then you must either write code that
|
||||
can react to the 3rd party library making the changes to cookies or implement your own polling
|
||||
mechanism.
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="1.3.15"></a>
|
||||
# 1.3.15 locality-filtration (2015-03-17)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$animate:** call `applyStyles` with options on `leave`
|
||||
([ebd84e80](https://github.com/angular/angular.js/commit/ebd84e8008f45ccaa84290f6da8c2a114fcfa8cd),
|
||||
[#10068](https://github.com/angular/angular.js/issues/10068))
|
||||
- **$browser:** don't crash if history.state access causes error in IE
|
||||
([92767c09](https://github.com/angular/angular.js/commit/92767c098feaf8c58faf2d67f882305019d8160e),
|
||||
[#10367](https://github.com/angular/angular.js/issues/10367), [#10369](https://github.com/angular/angular.js/issues/10369))
|
||||
- **Angular:** properly compare RegExp with other objects for equality
|
||||
([b8e8f9af](https://github.com/angular/angular.js/commit/b8e8f9af78f4ef3e556dd3cef6bfee35ad4cb82a),
|
||||
[#11204](https://github.com/angular/angular.js/issues/11204), [#11205](https://github.com/angular/angular.js/issues/11205))
|
||||
- **date filter:** display localised era for `G` format codes
|
||||
([f2683f95](https://github.com/angular/angular.js/commit/f2683f956fcd3216eaa263db20b31e0d46338800),
|
||||
[#10503](https://github.com/angular/angular.js/issues/10503), [#11266](https://github.com/angular/angular.js/issues/11266))
|
||||
- **filterFilter:**
|
||||
- fix filtering using an object expression when the filter value is `undefined`
|
||||
([63b9956f](https://github.com/angular/angular.js/commit/63b9956faf4c3679c88a9401b8ccbb111c0294ee),
|
||||
[#10419](https://github.com/angular/angular.js/issues/10419), [#10424](https://github.com/angular/angular.js/issues/10424))
|
||||
- do not throw an error if property is null when comparing objects
|
||||
([01161a0e](https://github.com/angular/angular.js/commit/01161a0e9fb1af93e9f06535aed8392ed7f116a4),
|
||||
[#10991](https://github.com/angular/angular.js/issues/10991), [#10992](https://github.com/angular/angular.js/issues/10992), [#11116](https://github.com/angular/angular.js/issues/11116))
|
||||
- **form:** allow dynamic form names which initially evaluate to blank
|
||||
([190ea883](https://github.com/angular/angular.js/commit/190ea883c588d63f8b900a8de1d45c6c9ebb01ec),
|
||||
[#11096](https://github.com/angular/angular.js/issues/11096))
|
||||
- **ng/$locale:** add ERA info in generic locale
|
||||
([57842530](https://github.com/angular/angular.js/commit/578425303f2480959da80f31920d08f277d42010))
|
||||
- **rootScope:** prevent memory leak when destroying scopes
|
||||
([528cf09e](https://github.com/angular/angular.js/commit/528cf09e3f78ad4e3bb6a329ebe315c4f29b4cdb),
|
||||
[#11173](https://github.com/angular/angular.js/issues/11173), [#11169](https://github.com/angular/angular.js/issues/11169))
|
||||
- **templateRequest:** avoid throwing syntax error in Android 2.3
|
||||
([75abbd52](https://github.com/angular/angular.js/commit/75abbd525f07866fdcc6fb311802b8fe700af174),
|
||||
[#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
|
||||
|
||||
- **ngAria:**
|
||||
- add `button` role to `ngClick`
|
||||
([b9ad91cf](https://github.com/angular/angular.js/commit/b9ad91cf1e86310a2d2bf13b29fa13a9b835e1ce),
|
||||
[#9254](https://github.com/angular/angular.js/issues/9254), [#10318](https://github.com/angular/angular.js/issues/10318))
|
||||
- add roles to custom inputs
|
||||
([21369943](https://github.com/angular/angular.js/commit/21369943fafd577b36827a641b021b1c14cefb57),
|
||||
[#10012](https://github.com/angular/angular.js/issues/10012), [#10318](https://github.com/angular/angular.js/issues/10318))
|
||||
- **ngMock:**
|
||||
- allow mock $controller service to set up controller bindings
|
||||
([b3878a36](https://github.com/angular/angular.js/commit/b3878a36d9f8e56ad7be1eedb9691c9bd12568cb),
|
||||
[#9425](https://github.com/angular/angular.js/issues/9425), [#11239](https://github.com/angular/angular.js/issues/11239))
|
||||
- add `they` helpers for testing multiple specs
|
||||
([7288be25](https://github.com/angular/angular.js/commit/7288be25a75d6ca6ac7eca05a7d6b12ccb3a22f8),
|
||||
[#10864](https://github.com/angular/angular.js/issues/10864))
|
||||
|
||||
|
||||
|
||||
<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>
|
||||
```
|
||||
|
||||
- **$http:** due to [5da1256](https://github.com/angular/angular.js/commit/5da1256fc2812d5b28fb0af0de81256054856369),
|
||||
|
||||
`transformRequest` functions can no longer modify request headers.
|
||||
|
||||
Before this commit `transformRequest` could modify request headers, ex.:
|
||||
|
||||
```javascript
|
||||
function requestTransform(data, headers) {
|
||||
headers = angular.extend(headers(), {
|
||||
'X-MY_HEADER': 'abcd'
|
||||
});
|
||||
}
|
||||
return angular.toJson(data);
|
||||
}
|
||||
```
|
||||
|
||||
This behavior was unintended and undocumented, so the change should affect very few applications. If one
|
||||
needs to dynamically add / remove headers it should be done in a header function, for example:
|
||||
|
||||
```javascript
|
||||
$http.get(url, {
|
||||
headers: {
|
||||
'X-MY_HEADER': function(config) {
|
||||
return 'abcd'; //you've got access to a request config object to specify header value dynamically
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
<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)
|
||||
|
||||
@@ -1280,33 +348,7 @@ But in practice this is not what people want and so this change iterates over pr
|
||||
in the order they are returned by Object.keys(obj), which is almost always the order
|
||||
in which the properties were defined.
|
||||
|
||||
- **select:** due to [7fda214c](https://github.com/angular/angular.js/commit/7fda214c4f65a6a06b25cf5d5aff013a364e9cef),
|
||||
|
||||
the `select` directive will now use strict comparison of the `ngModel` scope value against `option`
|
||||
values to determine which option is selected. This means `Number` scope values will not be matched
|
||||
against numeric option strings.
|
||||
In Angular 1.3.x, setting `scope.x = 200` would select the `option` with the value 200 in the following `select`:
|
||||
|
||||
```
|
||||
<select ng-model="x">
|
||||
<option value="100">100</option>
|
||||
<option value="200">200</option>
|
||||
</select>
|
||||
```
|
||||
|
||||
In Angular 1.4.x, the 'unknown option' will be selected.
|
||||
To remedy this, you can simply initialize the model as a string: `scope.x = '200'`, or if you want to
|
||||
keep the model as a `Number`, you can do the conversion via `$formatters` and `$parsers` on `ngModel`:
|
||||
|
||||
```js
|
||||
ngModelCtrl.$parsers.push(function(value) {
|
||||
return parseInt(value, 10); // Convert option value to number
|
||||
});
|
||||
|
||||
ngModelCtrl.$formatters.push(function(value) {
|
||||
return value.toString(); // Convert scope value to string
|
||||
});
|
||||
```
|
||||
|
||||
<a name="1.3.9"></a>
|
||||
# 1.3.9 multidimensional-awareness (2015-01-13)
|
||||
@@ -5266,7 +4308,7 @@ For more info: http://blog.angularjs.org/2013/12/angularjs-13-new-release-approa
|
||||
- properly toggle multiple classes
|
||||
([4e73c80b](https://github.com/angular/angular.js/commit/4e73c80b17bd237a8491782bcf9e19f1889e12ed),
|
||||
[#4467](https://github.com/angular/angular.js/issues/4467), [#6448](https://github.com/angular/angular.js/issues/6448))
|
||||
- make `jqLite(<iframe src="someurl">').contents()` return iframe document, as in jQuery
|
||||
- make jqLite('<iframe src="someurl">').contents() return iframe document, as in jQuery
|
||||
([05fbed57](https://github.com/angular/angular.js/commit/05fbed5710b702c111c1425a9e241c40d13b0a54),
|
||||
[#6320](https://github.com/angular/angular.js/issues/6320), [#6323](https://github.com/angular/angular.js/issues/6323))
|
||||
- **numberFilter:** convert all non-finite/non-numbers/non-numeric strings to the empty string
|
||||
@@ -9642,7 +8684,7 @@ with the `$route` service
|
||||
mocks now part of `angular-mocks.js` (commit f5d08963)
|
||||
|
||||
### Bug Fixes
|
||||
- `<select>` (one/multiple) could not chose from a list of objects (commit 347be5ae)
|
||||
- <select> (one/multiple) could not chose from a list of objects (commit 347be5ae)
|
||||
- null and other falsy values should not be rendered in the view (issue #242)
|
||||
|
||||
### Docs
|
||||
|
||||
+4
-4
@@ -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
|
||||
|
||||
@@ -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**.
|
||||
|
||||
|
||||
+7
-30
@@ -17,6 +17,10 @@ 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,
|
||||
@@ -126,9 +130,6 @@ module.exports = function(grunt) {
|
||||
ngLocale: {
|
||||
files: { src: 'src/ngLocale/**/*.js' },
|
||||
},
|
||||
ngMessageFormat: {
|
||||
files: { src: 'src/ngMessageFormat/**/*.js' },
|
||||
},
|
||||
ngMessages: {
|
||||
files: { src: 'src/ngMessages/**/*.js' },
|
||||
},
|
||||
@@ -158,7 +159,7 @@ module.exports = function(grunt) {
|
||||
jscs: {
|
||||
src: ['src/**/*.js', 'test/**/*.js'],
|
||||
options: {
|
||||
config: ".jscsrc"
|
||||
config: ".jscs.json"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -203,10 +204,6 @@ module.exports = function(grunt) {
|
||||
dest: 'build/angular-resource.js',
|
||||
src: util.wrap(files['angularModules']['ngResource'], 'module')
|
||||
},
|
||||
messageformat: {
|
||||
dest: 'build/angular-message-format.js',
|
||||
src: util.wrap(files['angularModules']['ngMessageFormat'], 'module')
|
||||
},
|
||||
messages: {
|
||||
dest: 'build/angular-messages.js',
|
||||
src: util.wrap(files['angularModules']['ngMessages'], 'module')
|
||||
@@ -239,7 +236,6 @@ module.exports = function(grunt) {
|
||||
animate: 'build/angular-animate.js',
|
||||
cookies: 'build/angular-cookies.js',
|
||||
loader: 'build/angular-loader.js',
|
||||
messageformat: 'build/angular-message-format.js',
|
||||
messages: 'build/angular-messages.js',
|
||||
touch: 'build/angular-touch.js',
|
||||
resource: 'build/angular-resource.js',
|
||||
@@ -255,19 +251,8 @@ module.exports = function(grunt) {
|
||||
'test/**/*.js',
|
||||
'!test/ngScenario/DescribeSpec.js',
|
||||
'!src/ng/directive/attrs.js', // legitimate xit here
|
||||
'!src/ngScenario/**/*.js',
|
||||
'!test/helpers/privateMocks*.js'
|
||||
],
|
||||
options: {
|
||||
disallowed: [
|
||||
'iit',
|
||||
'xit',
|
||||
'tthey',
|
||||
'xthey',
|
||||
'ddescribe',
|
||||
'xdescribe'
|
||||
]
|
||||
}
|
||||
'!src/ngScenario/**/*.js'
|
||||
]
|
||||
},
|
||||
|
||||
"merge-conflict": {
|
||||
@@ -300,10 +285,6 @@ module.exports = function(grunt) {
|
||||
},
|
||||
|
||||
shell: {
|
||||
"npm-install": {
|
||||
command: path.normalize('scripts/npm/install-dependencies.sh')
|
||||
},
|
||||
|
||||
"promises-aplus-tests": {
|
||||
options: {
|
||||
stdout: false,
|
||||
@@ -330,10 +311,6 @@ 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']);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2010-2015 Google, Inc. http://angularjs.org
|
||||
Copyright (c) 2010-2014 Google, Inc. http://angularjs.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
Using AngularJS with the Closure Compiler
|
||||
=========================================
|
||||
|
||||
The Closure Compiler project contains definitions for the AngularJS JavaScript
|
||||
in its `contrib/externs` directory.
|
||||
The Closure Compiler project contains externs definitions for AngularJS
|
||||
JavaScript in its `contrib/externs` directory.
|
||||
|
||||
The definitions contain externs for use with the Closure compiler (aka
|
||||
JSCompiler). Passing these files to the --externs parameter of a compiler
|
||||
|
||||
@@ -10,7 +10,7 @@ the browser how to do dependency injection and inversion of control.
|
||||
|
||||
Oh yeah and it helps with server-side communication, taming async callbacks with promises and
|
||||
deferreds. It also makes client-side navigation and deeplinking with hashbang urls or HTML5 pushState a
|
||||
piece of cake. Best of all?? It makes development fun!
|
||||
piece of cake. The best of all: it makes development fun!
|
||||
|
||||
* Web site: http://angularjs.org
|
||||
* Tutorial: http://docs.angularjs.org/tutorial
|
||||
|
||||
+1
-5
@@ -55,11 +55,7 @@ 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. 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 `PRs plz!` - These issues are good targets for PRs from the open source community. Apply to issues where the problem and solution are well defined in the comments, and it's not too complex.
|
||||
1. Label `origin: google` for issues from Google
|
||||
1. Assign a milestone:
|
||||
* Backlog - triaged fixes and features, should be the default choice
|
||||
|
||||
Vendored
+4
-27
@@ -40,7 +40,6 @@ var angularFiles = {
|
||||
'src/ng/timeout.js',
|
||||
'src/ng/urlUtils.js',
|
||||
'src/ng/window.js',
|
||||
'src/ng/cookieReader.js',
|
||||
|
||||
'src/ng/filter.js',
|
||||
'src/ng/filter/filter.js',
|
||||
@@ -66,7 +65,6 @@ var angularFiles = {
|
||||
'src/ng/directive/ngList.js',
|
||||
'src/ng/directive/ngModel.js',
|
||||
'src/ng/directive/ngNonBindable.js',
|
||||
'src/ng/directive/ngOptions.js',
|
||||
'src/ng/directive/ngPluralize.js',
|
||||
'src/ng/directive/ngRepeat.js',
|
||||
'src/ng/directive/ngShowHide.js',
|
||||
@@ -87,29 +85,10 @@ var angularFiles = {
|
||||
|
||||
'angularModules': {
|
||||
'ngAnimate': [
|
||||
'src/ngAnimate/shared.js',
|
||||
'src/ngAnimate/rafScheduler.js',
|
||||
'src/ngAnimate/animateChildrenDirective.js',
|
||||
'src/ngAnimate/animateCss.js',
|
||||
'src/ngAnimate/animateCssDriver.js',
|
||||
'src/ngAnimate/animateJs.js',
|
||||
'src/ngAnimate/animateJsDriver.js',
|
||||
'src/ngAnimate/animateQueue.js',
|
||||
'src/ngAnimate/animateRunner.js',
|
||||
'src/ngAnimate/animation.js',
|
||||
'src/ngAnimate/module.js'
|
||||
'src/ngAnimate/animate.js'
|
||||
],
|
||||
'ngCookies': [
|
||||
'src/ngCookies/cookies.js',
|
||||
'src/ngCookies/cookieStore.js',
|
||||
'src/ngCookies/cookieWriter.js'
|
||||
],
|
||||
'ngMessageFormat': [
|
||||
'src/ngMessageFormat/messageFormatCommon.js',
|
||||
'src/ngMessageFormat/messageFormatSelector.js',
|
||||
'src/ngMessageFormat/messageFormatInterpolationParts.js',
|
||||
'src/ngMessageFormat/messageFormatParser.js',
|
||||
'src/ngMessageFormat/messageFormatService.js'
|
||||
'src/ngCookies/cookies.js'
|
||||
],
|
||||
'ngMessages': [
|
||||
'src/ngMessages/messages.js'
|
||||
@@ -182,7 +161,7 @@ var angularFiles = {
|
||||
'src/publishExternalApis.js',
|
||||
'@angularSrcModules',
|
||||
'@angularScenario',
|
||||
'@angularTest'
|
||||
'@angularTest',
|
||||
],
|
||||
|
||||
'karmaExclude': [
|
||||
@@ -201,7 +180,6 @@ var angularFiles = {
|
||||
'@angularSrcModules',
|
||||
'src/ngScenario/browserTrigger.js',
|
||||
'test/helpers/*.js',
|
||||
'test/ngMessageFormat/*.js',
|
||||
'test/ngMock/*.js',
|
||||
'test/ngCookies/*.js',
|
||||
'test/ngRoute/**/*.js',
|
||||
@@ -218,7 +196,7 @@ var angularFiles = {
|
||||
'src/publishExternalApis.js',
|
||||
'@angularSrcModules',
|
||||
'@angularScenario',
|
||||
'@angularTest'
|
||||
'@angularTest',
|
||||
],
|
||||
|
||||
'karmaJqueryExclude': [
|
||||
@@ -230,7 +208,6 @@ var angularFiles = {
|
||||
|
||||
angularFiles['angularSrcModules'] = [].concat(
|
||||
angularFiles['angularModules']['ngAnimate'],
|
||||
angularFiles['angularModules']['ngMessageFormat'],
|
||||
angularFiles['angularModules']['ngMessages'],
|
||||
angularFiles['angularModules']['ngCookies'],
|
||||
angularFiles['angularModules']['ngResource'],
|
||||
|
||||
@@ -14,14 +14,11 @@
|
||||
<div>ngBind: <input type="radio" ng-model="benchmarkType" value="ngBind"></div>
|
||||
<div>ngBindOnce: <input type="radio" ng-model="benchmarkType" value="ngBindOnce"></div>
|
||||
<div>interpolation: <input type="radio" ng-model="benchmarkType" value="interpolation"></div>
|
||||
<div>interpolation + bind-once: <input type="radio" ng-model="benchmarkType" value="bindOnceInterpolation"></div>
|
||||
<div>attribute interpolation: <input type="radio" ng-model="benchmarkType" value="interpolationAttr"></div>
|
||||
<div>ngBind + fnInvocation: <input type="radio" ng-model="benchmarkType" value="ngBindFn"></div>
|
||||
<div>interpolation + fnInvocation: <input type="radio" ng-model="benchmarkType" value="interpolationFn"></div>
|
||||
<div>ngBind + filter: <input type="radio" ng-model="benchmarkType" value="ngBindFilter"></div>
|
||||
<div>interpolation + filter: <input type="radio" ng-model="benchmarkType" value="interpolationFilter"></div>
|
||||
<div>ngModel (const name): <input type="radio" ng-model="benchmarkType" value="ngModelConstName"></div>
|
||||
<div>ngModel (interp name): <input type="radio" ng-model="benchmarkType" value="ngModelInterpName"></div>
|
||||
|
||||
<ng-switch on="benchmarkType">
|
||||
<baseline-binding-table ng-switch-when="baselineBinding">
|
||||
@@ -38,7 +35,7 @@
|
||||
</div>
|
||||
<div ng-switch-when="ngBindOnce">
|
||||
<h2>baseline binding once</h2>
|
||||
<div ng-repeat="row in ::data">
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in ::row">
|
||||
<span ng-bind="::column.i"></span>:<span ng-bind="::column.j"></span>|
|
||||
</span>
|
||||
@@ -50,12 +47,6 @@
|
||||
<span ng-repeat="column in row">{{column.i}}:{{column.j}}|</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="bindOnceInterpolation">
|
||||
<h2>baseline one-time interpolation</h2>
|
||||
<div ng-repeat="row in ::data">
|
||||
<span ng-repeat="column in ::row">{{::column.i}}:{{::column.j}}|</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="interpolationAttr">
|
||||
<h2>attribute interpolation</h2>
|
||||
<div ng-repeat="row in data">
|
||||
@@ -86,20 +77,6 @@
|
||||
<span ng-repeat="column in row">{{column.i | noop}}:{{column.j | noop}}|</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="ngModelConstName">
|
||||
<h2>ngModel (const name)</h2>
|
||||
<div ng-repeat="row in data">
|
||||
<input type="text" ng-model="row.i" name="constName" />
|
||||
<input type="text" ng-model="row.j" />
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="ngModelInterpName">
|
||||
<h2>ngModel (interp name)</h2>
|
||||
<div ng-repeat="(rowIdx, row) in data">
|
||||
<input type="text" ng-model="row.i" name="input-{{rowIdx}}" />
|
||||
<input type="text" ng-model="row.j" name="input2-{{rowIdx}}" />
|
||||
</div>
|
||||
</div>
|
||||
</ng-switch>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
/* globals angular, benchmarkSteps */
|
||||
|
||||
var app = angular.module('ngOptionsBenchmark', []);
|
||||
|
||||
app.config(function($compileProvider) {
|
||||
if ($compileProvider.debugInfoEnabled) {
|
||||
$compileProvider.debugInfoEnabled(false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
app.controller('DataController', function($scope, $element) {
|
||||
$scope.items = [];
|
||||
$scope.count = 10000;
|
||||
|
||||
function changeOptions() {
|
||||
$scope.items = [];
|
||||
for (var i = 0; i < $scope.count; ++i) {
|
||||
$scope.items.push({
|
||||
id: i,
|
||||
label: 'item-' + i,
|
||||
group: 'group-' + i % 100
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var selectElement = $element.find('select');
|
||||
console.log(selectElement);
|
||||
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: 'add-options',
|
||||
fn: function() {
|
||||
$scope.$apply(function() {
|
||||
$scope.count = 10000;
|
||||
changeOptions();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: 'set-model-1',
|
||||
fn: function() {
|
||||
$scope.$apply(function() {
|
||||
$scope.x = $scope.items[1000];
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: 'set-model-2',
|
||||
fn: function() {
|
||||
$scope.$apply(function() {
|
||||
$scope.x = $scope.items[10];
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: 'remove-options',
|
||||
fn: function() {
|
||||
$scope.count = 100;
|
||||
changeOptions();
|
||||
}
|
||||
});
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: 'add-options',
|
||||
fn: function() {
|
||||
$scope.$apply(function() {
|
||||
$scope.count = 10000;
|
||||
changeOptions();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: 'set-view-1',
|
||||
fn: function() {
|
||||
selectElement.val('2000');
|
||||
selectElement.triggerHandler('change');
|
||||
}
|
||||
});
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: 'set-view-2',
|
||||
fn: function() {
|
||||
selectElement.val('1000');
|
||||
selectElement.triggerHandler('change');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
scripts: [ {
|
||||
id: 'angular',
|
||||
src: '/build/angular.js'
|
||||
},
|
||||
{
|
||||
src: 'app.js',
|
||||
}]
|
||||
});
|
||||
};
|
||||
@@ -1,10 +0,0 @@
|
||||
<div ng-app="ngOptionsBenchmark" ng-cloak>
|
||||
<div ng-controller="DataController">
|
||||
<div class="container-fluid">
|
||||
<p>
|
||||
Tests the execution of ng-options for rendering during model and option updates.
|
||||
</p>
|
||||
<select ng-model="x" ng-options="a as a.label group by a.group for a in items track by a.id"></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -103,10 +103,10 @@ then(function (tags) {
|
||||
sort(semver.rcompare);
|
||||
}).
|
||||
then(function (tags) {
|
||||
var major = tags[0].split('.')[0];
|
||||
var major = tags[0].split('.')[0] + '.x';
|
||||
return tags.
|
||||
filter(function (ver) {
|
||||
return semver(ver).major == major;
|
||||
return semver.satisfies(ver, major);
|
||||
});
|
||||
}).
|
||||
then(function (tags) {
|
||||
|
||||
@@ -9,11 +9,3 @@
|
||||
ng\:form {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ng-animate-shim {
|
||||
visibility:hidden;
|
||||
}
|
||||
|
||||
.ng-anchor {
|
||||
position:absolute;
|
||||
}
|
||||
|
||||
@@ -583,12 +583,6 @@ ul.events > li {
|
||||
margin-bottom:40px;
|
||||
}
|
||||
|
||||
.definition-table td {
|
||||
padding: 8px;
|
||||
border: 1px solid #eee;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 769px) and (max-width: 991px) {
|
||||
.main-body-grid {
|
||||
margin-top: 160px;
|
||||
@@ -701,7 +695,3 @@ ul.events > li {
|
||||
padding-bottom:0px;
|
||||
}
|
||||
}
|
||||
|
||||
iframe[name="example-anchoringExample"] {
|
||||
height:400px;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ angular.module('tutorials', [])
|
||||
'step': '@docTutorialReset'
|
||||
},
|
||||
template:
|
||||
'<p><button class="btn" ng-click="show=!show">Workspace Reset Instructions ➤</button></p>\n' +
|
||||
'<p><a href="" ng-click="show=!show;$event.stopPropagation()">Workspace Reset Instructions ➤</a></p>\n' +
|
||||
'<div class="alert alert-info" ng-show="show">\n' +
|
||||
' <p>Reset the workspace to step {{step}}.</p>' +
|
||||
' <p><pre>git checkout -f step-{{step}}</pre></p>\n' +
|
||||
@@ -43,7 +43,7 @@ angular.module('tutorials', [])
|
||||
'<a href="http://angular.github.io/angular-phonecat/step-{{step}}/app">Step {{step}} Live Demo</a>.</p>\n' +
|
||||
'</div>\n' +
|
||||
'<p>The most important changes are listed below. You can see the full diff on ' +
|
||||
'<a ng-href="https://github.com/angular/angular-phonecat/compare/step-{{step ? (step - 1): \'0~1\'}}...step-{{step}}" title="See diff on Github">GitHub</a>\n' +
|
||||
'<a ng-href="https://github.com/angular/angular-phonecat/compare/step-{{step ? (step - 1): \'0~1\'}}...step-{{step}}">GitHub</a>\n' +
|
||||
'</p>'
|
||||
};
|
||||
});
|
||||
@@ -21,13 +21,11 @@ angular.module('versions', [])
|
||||
};
|
||||
|
||||
$scope.jumpToDocsVersion = function(version) {
|
||||
var currentPagePath = $location.path().replace(/\/$/, ''),
|
||||
url = '';
|
||||
if (version.isOldDocsUrl) {
|
||||
url = version.docsUrl;
|
||||
}else{
|
||||
url = version.docsUrl + currentPagePath;
|
||||
}
|
||||
$window.location = url;
|
||||
var currentPagePath = $location.path().replace(/\/$/, '');
|
||||
|
||||
// TODO: We need to do some munging of the path for different versions of the API...
|
||||
|
||||
|
||||
$window.location = version.docsUrl + currentPagePath;
|
||||
};
|
||||
}]);
|
||||
|
||||
+6
-11
@@ -6,18 +6,18 @@ var packagePath = __dirname;
|
||||
var Package = require('dgeni').Package;
|
||||
|
||||
// Create and export a new Dgeni package called angularjs. This package depends upon
|
||||
// the ngdoc, nunjucks, and examples packages defined in the dgeni-packages npm module.
|
||||
// the ngdoc,nunjucks and examples packages defined in the dgeni-packages npm module.
|
||||
module.exports = new Package('angularjs', [
|
||||
require('dgeni-packages/ngdoc'),
|
||||
require('dgeni-packages/nunjucks'),
|
||||
require('dgeni-packages/examples'),
|
||||
require('dgeni-packages/git')
|
||||
require('dgeni-packages/examples')
|
||||
])
|
||||
|
||||
|
||||
.factory(require('./services/errorNamespaceMap'))
|
||||
.factory(require('./services/getMinerrInfo'))
|
||||
.factory(require('./services/getVersion'))
|
||||
.factory(require('./services/gitData'))
|
||||
|
||||
.factory(require('./services/deployments/debug'))
|
||||
.factory(require('./services/deployments/default'))
|
||||
@@ -26,6 +26,7 @@ module.exports = new Package('angularjs', [
|
||||
|
||||
.factory(require('./inline-tag-defs/type'))
|
||||
|
||||
|
||||
.processor(require('./processors/error-docs'))
|
||||
.processor(require('./processors/index-page'))
|
||||
.processor(require('./processors/keywords'))
|
||||
@@ -124,16 +125,10 @@ module.exports = new Package('angularjs', [
|
||||
});
|
||||
|
||||
computeIdsProcessor.idTemplates.push({
|
||||
docTypes: ['error'],
|
||||
getId: function(doc) { return 'error:' + doc.namespace + ':' + doc.name; },
|
||||
getAliases: function(doc) { return [doc.name, doc.namespace + ':' + doc.name, doc.id]; }
|
||||
},
|
||||
{
|
||||
docTypes: ['errorNamespace'],
|
||||
docTypes: ['error', 'errorNamespace'],
|
||||
getId: function(doc) { return 'error:' + doc.name; },
|
||||
getAliases: function(doc) { return [doc.id]; }
|
||||
}
|
||||
);
|
||||
});
|
||||
})
|
||||
|
||||
.config(function(checkAnchorLinksProcessor) {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
"use strict";
|
||||
|
||||
var versionInfo = require('../../../lib/versions/version-info');
|
||||
|
||||
/**
|
||||
* @dgService gitData
|
||||
* @description
|
||||
* Information from the local git repository
|
||||
*/
|
||||
module.exports = function gitData() {
|
||||
return {
|
||||
version: versionInfo.currentVersion,
|
||||
versions: versionInfo.previousVersions,
|
||||
info: versionInfo.gitRepoInfo
|
||||
};
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
{% extends "base.template.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Error: {$ doc.namespace $}:{$ doc.name $}
|
||||
<h1>Error: {$ doc.id $}
|
||||
<div><span class='hint'>{$ doc.fullName $}</span></div>
|
||||
</h1>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="Description"
|
||||
content="AngularJS is what HTML would have been, had it been designed for building web-apps.
|
||||
Declarative templates with data-binding, MVC, dependency injection and great
|
||||
@@ -76,7 +76,7 @@
|
||||
<div class="row">
|
||||
<div class="col-md-9 header-branding">
|
||||
<a class="brand navbar-brand" href="http://angularjs.org">
|
||||
<img width="117" height="30" class="logo" alt="Link to Angular JS Homepage" ng-src="img/angularjs-for-header-only.svg">
|
||||
<img width="117" height="30" class="logo" ng-src="img/angularjs-for-header-only.svg">
|
||||
</a>
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="divider-vertical"></li>
|
||||
@@ -220,10 +220,10 @@
|
||||
<p class="pull-right"><a back-to-top>Back to top</a></p>
|
||||
|
||||
<p>
|
||||
Super-powered by Google ©2010-2015
|
||||
Super-powered by Google ©2010-2014
|
||||
( <a id="version"
|
||||
ng-href="https://github.com/angular/angular.js/blob/master/CHANGELOG.md#{{versionNumber}}"
|
||||
ng-bind-template="v{{version}}" title="Changelog of this version of Angular JS">
|
||||
ng-bind-template="v{{version}}">
|
||||
</a>
|
||||
)
|
||||
</p>
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
{% macro typeList(types) -%}
|
||||
{% for typeName in types %}<a href="" class="{$ typeName | typeClass $}">{$ typeName | escape $}</a>{% endfor %}
|
||||
{%- endmacro -%}
|
||||
|
||||
{%- macro paramTable(params) %}
|
||||
<table class="variables-matrix input-arguments">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Param</th>
|
||||
<th>Type</th>
|
||||
<th>Details</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for param in params %}
|
||||
<tr>
|
||||
<td>
|
||||
{$ param.name $}
|
||||
{% if param.alias %}| {$ param.alias $}{% endif %}
|
||||
{% if param.optional %}<div><em>(optional)</em></div>{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{$ typeList(param.typeList) $}
|
||||
</td>
|
||||
<td>
|
||||
{$ param.description | marked $}
|
||||
{% if param.defaultValue %}<p><em>(default: {$ param.defaultValue $})</em></p>{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endmacro -%}
|
||||
|
||||
|
||||
{%- macro directiveParam(name, type, join, sep) %}
|
||||
{%- if type.optional %}[{% endif -%}
|
||||
{$ name | dashCase $}{$ join $}{$ type.name $}{$ sep $}
|
||||
{%- if type.optional %}]{% endif -%}
|
||||
{% endmacro -%}
|
||||
|
||||
{%- macro functionSyntax(fn) %}
|
||||
{%- set sep = joiner(', ') -%}
|
||||
{% marked -%}
|
||||
`{$ fn.name $}({%- for param in fn.params %}{$ sep() $}
|
||||
{%- if param.type.optional %}[{% endif -%}
|
||||
{$ param.name $}
|
||||
{%- if param.type.optional %}]{% endif -%}
|
||||
{% endfor %});`
|
||||
{%- endmarked %}
|
||||
{% endmacro -%}
|
||||
|
||||
{%- macro typeInfo(fn) -%}
|
||||
<table class="variables-matrix return-arguments">
|
||||
<tr>
|
||||
<td>{$ typeList(fn.typeList) $}</td>
|
||||
<td>{$ fn.description | marked $}</td>
|
||||
</tr>
|
||||
</table>
|
||||
{%- endmacro -%}
|
||||
@@ -140,7 +140,7 @@ or JavaScript callbacks.
|
||||
{@link ngAnimate#service Services / Factories}
|
||||
</td>
|
||||
<td>
|
||||
Use {@link ng.$animate $animate} to trigger animation operations within your directive code.
|
||||
Use {@link ngAnimate.$animate $animate} to trigger animation operations within your directive code.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $animate:nocb
|
||||
@fullName Do not pass a callback to animate methods
|
||||
@description
|
||||
|
||||
Since Angular 1.3, the methods of {@link ng.$animate} do not accept a callback as the last parameter.
|
||||
Instead, they return a promise to which you can attach `then` handlers to be run when the animation completes.
|
||||
|
||||
If you are getting this error then you need to update your code to use the promise-based API.
|
||||
|
||||
See https://github.com/angular/angular.js/commit/bf0f5502b1bbfddc5cdd2f138efd9188b8c652a9 for information about
|
||||
the change to the animation API and the changes you need to make.
|
||||
@@ -1,8 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:baddir
|
||||
@fullName Invalid Directive Name
|
||||
@description
|
||||
|
||||
This error occurs when the name of a directive is not valid.
|
||||
|
||||
Directives must start with a lowercase character and must not contain leading or trailing whitespaces.
|
||||
@@ -1,12 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:noctrl
|
||||
@fullName Controller is required.
|
||||
@description
|
||||
|
||||
When using the `bindToController` feature of AngularJS, a directive is required
|
||||
to have a Controller. A controller may be specified by adding a "controller"
|
||||
property to the directive definition object. Its value should be either a
|
||||
string, or an invokable object (a function, or an array whose last element is a
|
||||
function).
|
||||
|
||||
For more information, see the {@link guide/directive directives guide}.
|
||||
@@ -1,71 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:noident
|
||||
@fullName Controller identifier is required.
|
||||
@description
|
||||
|
||||
When using the `bindToController` feature of AngularJS, a directive is required
|
||||
to have a Controller identifier, which is initialized in scope with the value of
|
||||
the controller instance. This can be supplied using the "controllerAs" property
|
||||
of the directive object, or alternatively by adding " as IDENTIFIER" to the controller
|
||||
name.
|
||||
|
||||
For example, the following directives are valid:
|
||||
|
||||
```js
|
||||
// OKAY, because controller is a string with an identifier component.
|
||||
directive("okay", function() {
|
||||
return {
|
||||
bindToController: true,
|
||||
controller: "myCtrl as $ctrl"
|
||||
scope: {
|
||||
text: "@text"
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
// OKAY, because the directive uses the controllerAs property to override
|
||||
// the controller identifier.
|
||||
directive("okay2", function() {
|
||||
return {
|
||||
bindToController: true,
|
||||
controllerAs: "$ctrl",
|
||||
controller: function() {
|
||||
|
||||
},
|
||||
scope: {
|
||||
text: "@text"
|
||||
}
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
While the following are invalid:
|
||||
|
||||
```js
|
||||
// BAD, because the controller property is a string with no identifier.
|
||||
directive("bad", function() {
|
||||
return {
|
||||
bindToController: true,
|
||||
controller: "noIdentCtrl",
|
||||
scope: {
|
||||
text: "@text"
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
// BAD because the controller is not a string (therefore has no identifier),
|
||||
// and there is no controllerAs property.
|
||||
directive("bad2", function() {
|
||||
return {
|
||||
bindToController: true,
|
||||
controller: function noControllerAs() {
|
||||
|
||||
},
|
||||
scope: {
|
||||
text: "@text"
|
||||
}
|
||||
};
|
||||
});
|
||||
```
|
||||
@@ -36,25 +36,9 @@ Following are invalid uses of this directive:
|
||||
```
|
||||
|
||||
|
||||
To resolve this error, do one of the following options:
|
||||
|
||||
- use path expressions with scope properties that are two-way data-bound like so:
|
||||
|
||||
To resolve this error, always use path expressions with scope properties that are two-way data-bound:
|
||||
```
|
||||
<my-directive bind="some.property">
|
||||
<my-directive bind="some[3]['property']">
|
||||
```
|
||||
|
||||
- Make the binding optional
|
||||
|
||||
```
|
||||
myModule.directive('myDirective', function factory() {
|
||||
return {
|
||||
...
|
||||
scope: {
|
||||
localValue: '=?bind' // <-- the '?' makes it optional
|
||||
}
|
||||
...
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
@@ -69,15 +69,3 @@ angular.module('myModule', [])
|
||||
```
|
||||
|
||||
Use the `$controller` service if you want to instantiate controllers yourself.
|
||||
|
||||
Attempting to inject a scope object into anything that's not a controller or a directive,
|
||||
for example a service, will also throw an `Unknown provider: $scopeProvider <- $scope` error.
|
||||
This might happen if one mistakenly registers a controller as a service, ex.:
|
||||
|
||||
```
|
||||
angular.module('myModule', [])
|
||||
.service('MyController', ['$scope', function($scope) {
|
||||
// This controller throws an unknown provider error because
|
||||
// a scope object cannot be injected into a service.
|
||||
}]);
|
||||
```
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $interpolate:badexpr
|
||||
@fullName Expecting end operator
|
||||
@description
|
||||
|
||||
The Angular expression is missing the corresponding closing operator.
|
||||
@@ -1,11 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $interpolate:dupvalue
|
||||
@fullName Duplicate choice in plural/select
|
||||
@description
|
||||
|
||||
You have repeated a match selection for your plural or select MessageFormat
|
||||
extension in your interpolation expression. The different choices have to be unique.
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
@@ -1,12 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $interpolate:logicbug
|
||||
@fullName Bug in ngMessageFormat module
|
||||
@description
|
||||
|
||||
You've just hit a bug in the ngMessageFormat module provided by angular-message-format.min.js.
|
||||
Please file a github issue for this and provide the interpolation text that caused you to hit this
|
||||
bug mentioning the exact version of AngularJS used and we will fix it!
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
@@ -1,17 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $interpolate:nochgmustache
|
||||
@fullName Redefinition of start/endSymbol incompatible with MessageFormat extensions
|
||||
@description
|
||||
|
||||
You have redefined `$interpolate.startSymbol`/`$interpolate.endSymbol` and also
|
||||
loaded the `ngMessageFormat` module (provided by angular-message-format.min.js)
|
||||
while creating your injector.
|
||||
|
||||
`ngMessageFormat` currently does not support redefinition of the
|
||||
startSymbol/endSymbol used by `$interpolate`. If this is affecting you, please
|
||||
file an issue and mention @chirayuk on it. This is intended to be fixed in a
|
||||
future commit and the github issue will help gauge urgency.
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
@@ -1,12 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $interpolate:reqarg
|
||||
@fullName Missing required argument for MessageFormat
|
||||
@description
|
||||
|
||||
You must specify the MessageFormat function that you're using right after the
|
||||
comma following the Angular expression. Currently, the supported functions are
|
||||
"plural" and "select" (for gender selections.)
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
@@ -1,11 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $interpolate:reqcomma
|
||||
@fullName Missing comma following MessageFormat plural/select keyword
|
||||
@description
|
||||
|
||||
The MessageFormat syntax requires a comma following the "plural" or "select"
|
||||
extension keyword in the extended interpolation syntax.
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
@@ -1,11 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $interpolate:reqendbrace
|
||||
@fullName Unterminated message for plural/select value
|
||||
@description
|
||||
|
||||
The plural or select message for a value or keyword choice has no matching end
|
||||
brace to mark the end of the message.
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
@@ -1,6 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $interpolate:reqendinterp
|
||||
@fullName Unterminated interpolation
|
||||
@description
|
||||
|
||||
The interpolation text does not have an ending `endSymbol` ("}}" by default) and is unterminated.
|
||||
@@ -1,12 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $interpolate:reqopenbrace
|
||||
@fullName An opening brace was expected but not found
|
||||
@description
|
||||
|
||||
The plural or select extension keyword or values (such as "other", "male",
|
||||
"female", "=0", "one", "many", etc.) MUST be followed by a message enclosed in
|
||||
braces.
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
@@ -1,13 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $interpolate:reqother
|
||||
@fullName Required choice "other" for select/plural in MessageFormat
|
||||
@description
|
||||
|
||||
Your interpolation expression with a MessageFormat extension for either
|
||||
"plural" or "select" (typically used for gender selection) does not contain a
|
||||
message for the choice "other". Using either select or plural MessageFormat
|
||||
extensions require that you provide a message for the selection "other".
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
@@ -1,12 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $interpolate:unknarg
|
||||
@fullName Unrecognized MessageFormat extension
|
||||
@description
|
||||
|
||||
The MessageFormat extensions provided by `ngMessageFormat` are currently
|
||||
limited to "plural" and "select". The extension that you have used is either
|
||||
unsupported or invalid.
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
@@ -1,10 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $interpolate:unsafe
|
||||
@fullName MessageFormat extensions not allowed in secure context
|
||||
@description
|
||||
|
||||
You have attempted to use a MessageFormat extension in your interpolation expression that is marked as a secure context. For security purposes, this is not supported.
|
||||
|
||||
Read more about secure contexts at {@link ng.$sce Strict Contextual Escaping
|
||||
(SCE)} and about the MessageFormat extensions at {@link
|
||||
guide/i18n#MessageFormat Angular i18n MessageFormat}.
|
||||
@@ -1,6 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $interpolate:untermstr
|
||||
@fullName Unterminated string literal
|
||||
@description
|
||||
|
||||
The string literal was not terminated in your Angular expression.
|
||||
@@ -1,8 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $interpolate:wantstring
|
||||
@fullName Expected the beginning of a string
|
||||
@description
|
||||
|
||||
We expected to see the beginning of a string (either a single quote or a double
|
||||
quote character) in the expression but it was not found. The expression is
|
||||
invalid. If this is incorrect, please file an issue on github.
|
||||
@@ -35,7 +35,7 @@ URL of the subcontext:
|
||||
|
||||
```html
|
||||
<head>
|
||||
<base href="/subapp/">
|
||||
<base href="/subapp">
|
||||
...
|
||||
</head>
|
||||
```
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
@ngdoc error
|
||||
@name filter:notarray
|
||||
@fullName Not an array
|
||||
@description
|
||||
|
||||
This error occurs when {@link ng.filter filter} is not used with an array:
|
||||
```html
|
||||
<input ng-model="search">
|
||||
<div ng-repeat="(key, value) in myObj | filter:search">
|
||||
{{ key }} : {{ value }}
|
||||
</div>
|
||||
```
|
||||
|
||||
Filter must be used with an array so a subset of items can be returned.
|
||||
The array can be initialized asynchronously and therefore null or undefined won't throw this error.
|
||||
|
||||
To filter an object by the value of its properties you can create your own custom filter:
|
||||
```js
|
||||
angular.module('customFilter',[])
|
||||
.filter('custom', function() {
|
||||
return function(input, search) {
|
||||
if (!input) return input;
|
||||
if (!search) return input;
|
||||
var expected = ('' + search).toLowerCase();
|
||||
var result = {};
|
||||
angular.forEach(input, function(value, key) {
|
||||
var actual = ('' + value).toLowerCase();
|
||||
if (actual.indexOf(expected) !== -1) {
|
||||
result[key] = value;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
});
|
||||
```
|
||||
That can be used as:
|
||||
```html
|
||||
<input ng-model="search">
|
||||
<div ng-repeat="(key, value) in myObj | custom:search">
|
||||
{{ key }} : {{ value }}
|
||||
</div>
|
||||
```
|
||||
|
||||
You could as well convert the object to an array using a filter such as
|
||||
[toArrayFilter](https://github.com/petebacondarwin/angular-toArrayFilter):
|
||||
```html
|
||||
<input ng-model="search">
|
||||
<div ng-repeat="item in myObj | toArray:false | filter:search">
|
||||
{{ item }}
|
||||
</div>
|
||||
```
|
||||
@@ -1,7 +0,0 @@
|
||||
@ngdoc error
|
||||
@name ng:cpta
|
||||
@fullName Copying TypedArray
|
||||
@description
|
||||
|
||||
Copying TypedArray's with a destination is not supported because TypedArray
|
||||
objects can not be mutated, they are fixed length.
|
||||
@@ -1,56 +0,0 @@
|
||||
@ngdoc error
|
||||
@name ngModel:numfmt
|
||||
@fullName Model is not of type `number`
|
||||
@description
|
||||
|
||||
The number input directive `<input type="number">` requires the model to be a `number`.
|
||||
|
||||
If the model is something else, this error will be thrown.
|
||||
|
||||
Angular does not set validation errors on the `<input>` in this case
|
||||
as this error is caused by incorrect application logic and not by bad input from the user.
|
||||
|
||||
If your model does not contain actual numbers then it is up to the application developer
|
||||
to use a directive that will do the conversion in the `ngModel` `$formatters` and `$parsers`
|
||||
pipeline.
|
||||
|
||||
## Example
|
||||
|
||||
In this example, our model stores the number as a string, so we provide the `stringToNumber`
|
||||
directive to convert it into the format the `input[number]` directive expects.
|
||||
|
||||
|
||||
<example module="numfmt-error-module">
|
||||
<file name="index.html">
|
||||
<table>
|
||||
<tr ng-repeat="x in ['0', '1']">
|
||||
<td>
|
||||
<input type="number" string-to-number ng-model="x" /> {{ x }} : {{ typeOf(x) }}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</file>
|
||||
<file name="app.js">
|
||||
angular.module('numfmt-error-module', [])
|
||||
|
||||
.run(function($rootScope) {
|
||||
$rootScope.typeOf = function(value) {
|
||||
return typeof value;
|
||||
};
|
||||
})
|
||||
|
||||
.directive('stringToNumber', function() {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
link: function(scope, element, attrs, ngModel) {
|
||||
ngModel.$parsers.push(function(value) {
|
||||
return '' + value;
|
||||
});
|
||||
ngModel.$formatters.push(function(value) {
|
||||
return parseFloat(value, 10);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
</file>
|
||||
</example>
|
||||
@@ -165,7 +165,7 @@ encoded.
|
||||
|
||||
`$location` service has two configuration modes which control the format of the URL in the browser
|
||||
address bar: **Hashbang mode** (the default) and the **HTML5 mode** which is based on using the
|
||||
[HTML5 History API](https://html.spec.whatwg.org/multipage/browsers.html#the-history-interface). Applications use the same API in
|
||||
HTML5 [History API](http://www.w3.org/TR/html5/introduction.html#history-0). Applications use the same API in
|
||||
both modes and the `$location` service will work with appropriate URL segments and browser APIs to
|
||||
facilitate the browser URL change and history management.
|
||||
|
||||
@@ -693,7 +693,7 @@ A path should always begin with forward slash (`/`); the `$location.path()` sett
|
||||
forward slash if it is missing.
|
||||
|
||||
Note that the `!` prefix in the hashbang mode is not part of `$location.path()`; it is actually
|
||||
`hashPrefix`.
|
||||
hashPrefix.
|
||||
|
||||
## Crawling your app
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ Currently, ngAria interfaces with the following directives:
|
||||
|
||||
Most of ngAria's heavy lifting happens in the {@link ngModel ngModel}
|
||||
directive. For elements using ngModel, special attention is paid by ngAria if that element also
|
||||
has a role or type of `checkbox`, `radio`, `range` or `textbox`.
|
||||
has a a role or type of `checkbox`, `radio`, `range` or `textbox`.
|
||||
|
||||
For those elements using ngModel, ngAria will dynamically bind and update the following ARIA
|
||||
attributes (if they have not been explicitly specified by the developer):
|
||||
@@ -213,13 +213,11 @@ The default CSS for `ngHide`, the inverse method to `ngShow`, makes ngAria redun
|
||||
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-click`, keypress will also be bound to `div` and `li` elements. You can turn this
|
||||
functionality on or off with the `bindKeypress` configuration option.
|
||||
|
||||
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.
|
||||
For `ng-dblclick`, you must manually add `ng-keypress` to non-interactive elements such as `div`
|
||||
or `taco-button` to enable keyboard access.
|
||||
|
||||
<h3>Example</h3>
|
||||
```html
|
||||
@@ -235,7 +233,7 @@ Becomes:
|
||||
|
||||
The new ngMessages module makes it easy to display form validation or other messages with priority
|
||||
sequencing and animation. To expose these visual messages to screen readers,
|
||||
ngAria injects `aria-live="assertive"`, causing them to be read aloud any time a message is shown,
|
||||
ngAria injects `aria-live="polite"`, causing them to be read aloud any time a message is shown,
|
||||
regardless of the user's focus location.
|
||||
###Example
|
||||
|
||||
@@ -249,7 +247,7 @@ regardless of the user's focus location.
|
||||
Becomes:
|
||||
|
||||
```html
|
||||
<div ng-messages="myForm.myName.$error" aria-live="assertive">
|
||||
<div ng-messages="myForm.myName.$error" aria-live="polite">
|
||||
<div ng-message="required">You did not enter a field</div>
|
||||
<div ng-message="maxlength">Your field is too long</div>
|
||||
</div>
|
||||
|
||||
@@ -236,7 +236,7 @@ The example below shows how to perform animations during class changes:
|
||||
</file>
|
||||
</example>
|
||||
|
||||
Although the CSS is a little different than what we saw before, the idea is the same.
|
||||
Although the CSS is a little different then what we saw before, the idea is the same.
|
||||
|
||||
## Which directives support animations?
|
||||
|
||||
@@ -253,7 +253,7 @@ The table below explains in detail which animation events are triggered
|
||||
| {@link ng.directive:ngClass#animations ngClass or {{class}}} | add and remove |
|
||||
| {@link ng.directive:ngShow#animations ngShow & ngHide} | add and remove (the ng-hide class value) |
|
||||
|
||||
For a full breakdown of the steps involved during each animation event, refer to the {@link ng.$animate API docs}.
|
||||
For a full breakdown of the steps involved during each animation event, refer to the {@link ngAnimate.$animate API docs}.
|
||||
|
||||
## How do I use animations in my own directives?
|
||||
|
||||
@@ -276,6 +276,6 @@ myModule.directive('my-directive', ['$animate', function($animate) {
|
||||
|
||||
## More about animations
|
||||
|
||||
For a full breakdown of each method available on `$animate`, see the {@link ng.$animate API documentation}.
|
||||
For a full breakdown of each method available on `$animate`, see the {@link ngAnimate.$animate API documentation}.
|
||||
|
||||
To see a complete demo, see the {@link tutorial/step_12 animation step within the AngularJS phonecat tutorial}.
|
||||
|
||||
@@ -55,11 +55,11 @@ Try out the Live Preview above, and then let's walk through the example and desc
|
||||
<img class="pull-right" style="padding-left: 3em; padding-bottom: 1em;" src="img/guide/concepts-databinding1.png">
|
||||
|
||||
This looks like normal HTML, with some new markup. In Angular, a file like this is called a
|
||||
<a name="template">{@link templates template}</a>. When Angular starts your application, it parses and
|
||||
processes this new markup from the template using the <a name="compiler">{@link compiler compiler}</a>.
|
||||
The loaded, transformed and rendered DOM is then called the <a name="view"></a>*view*.
|
||||
<a name="template">"{@link templates template}"</a>. When Angular starts your application, it parses and
|
||||
processes this new markup from the template using the so-called <a name="compiler">"{@link compiler compiler}"</a>.
|
||||
The loaded, transformed and rendered DOM is then called the <a name="view">"view"</a>.
|
||||
|
||||
The first kind of new markup are the <a name="directive">{@link directive directives}</a>.
|
||||
The first kind of new markup are the so-called <a name="directive">"{@link directive directives}"</a>.
|
||||
They apply special behavior to attributes or elements in the HTML. In the example above we use the
|
||||
{@link ng.directive:ngApp `ng-app`} attribute, which is linked to a directive that automatically
|
||||
initializes our application. Angular also defines a directive for the {@link ng.directive:input `input`}
|
||||
@@ -75,16 +75,16 @@ stores/updates the value of the input field into/from a variable.
|
||||
|
||||
The second kind of new markup are the double curly braces `{{ expression | filter }}`:
|
||||
When the compiler encounters this markup, it will replace it with the evaluated value of the markup.
|
||||
An <a name="expression">{@link expression expression}</a> in a template is a JavaScript-like code snippet that allows
|
||||
An <a name="expression">"{@link expression expression}"</a> in a template is a JavaScript-like code snippet that allows
|
||||
to read and write variables. Note that those variables are not global variables.
|
||||
Just like variables in a JavaScript function live in a scope,
|
||||
Angular provides a <a name="scope">{@link scope scope}</a> for the variables accessible to expressions.
|
||||
The values that are stored in variables on the scope are referred to as the <a name="model"></a>*model*
|
||||
Angular provides a <a name="scope">"{@link scope scope}"</a> for the variables accessible to expressions.
|
||||
The values that are stored in variables on the scope are referred to as the <a name="model">"model"</a>
|
||||
in the rest of the documentation.
|
||||
Applied to the example above, the markup directs Angular to "take the data we got from the input widgets
|
||||
and multiply them together".
|
||||
|
||||
The example above also contains a <a name="filter">{@link guide/filter filter}</a>.
|
||||
The example above also contains a <a name="filter">"{@link guide/filter filter}"</a>.
|
||||
A filter formats the value of an expression for display to the user.
|
||||
In the example above, the filter {@link ng.filter:currency `currency`} formats a number
|
||||
into an output that looks like money.
|
||||
@@ -92,7 +92,7 @@ into an output that looks like money.
|
||||
The important thing in the example is that Angular provides _live_ bindings:
|
||||
Whenever the input values change, the value of the expressions are automatically
|
||||
recalculated and the DOM is updated with their values.
|
||||
The concept behind this is <a name="databinding">{@link databinding two-way data binding}</a>.
|
||||
The concept behind this is <a name="databinding">"{@link databinding two-way data binding}"</a>.
|
||||
|
||||
|
||||
## Adding UI logic: Controllers
|
||||
@@ -150,7 +150,7 @@ different currencies and also pay the invoice.
|
||||
|
||||
What changed?
|
||||
|
||||
First, there is a new JavaScript file that contains a <a name="controller">{@link controller controller}</a>.
|
||||
First, there is a new JavaScript file that contains a so-called <a name="controller">"{@link controller controller}"</a>.
|
||||
More exactly, the file contains a constructor function that creates the actual controller instance.
|
||||
The purpose of controllers is to expose variables and functionality to expressions and directives.
|
||||
|
||||
@@ -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
|
||||
<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 so called
|
||||
<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.
|
||||
|
||||
@@ -255,15 +255,15 @@ We moved the `convertCurrency` function and the definition of the existing curre
|
||||
into the new file `finance2.js`. But how does the controller
|
||||
get a hold of the now separated function?
|
||||
|
||||
This is where <a name="di">{@link di Dependency Injection}</a> comes into play.
|
||||
This is where <a name="di">"{@link di Dependency Injection}"</a> comes into play.
|
||||
Dependency Injection (DI) is a software design pattern that
|
||||
deals with how objects and functions get created and how they get a hold of their dependencies.
|
||||
Everything within Angular (directives, filters, controllers,
|
||||
services, ...) is created and wired using dependency injection. Within Angular,
|
||||
the DI container is called the <a name="injector">{@link di injector}</a>.
|
||||
the DI container is called the <a name="injector">"{@link di injector}"</a>.
|
||||
|
||||
To use DI, there needs to be a place where all the things that should work together are registered.
|
||||
In Angular, this is the purpose of the <a name="module">{@link module modules}</a>.
|
||||
In Angular, this is the purpose of the so-called <a name="module">"{@link module modules}"</a>.
|
||||
When Angular starts, it will use the configuration of the module with the name defined by the `ng-app` directive,
|
||||
including the configuration of all modules that this module depends on.
|
||||
|
||||
|
||||
@@ -30,12 +30,12 @@ Do not use controllers to:
|
||||
services} instead.
|
||||
- Manage the life-cycle of other components (for example, to create service instances).
|
||||
|
||||
## Setting up the initial state of a `$scope` object
|
||||
# Setting up the initial state of a `$scope` object
|
||||
|
||||
Typically, when you create an application you need to set up the initial state for the Angular
|
||||
`$scope`. You set up the initial state of a scope by attaching properties to the `$scope` object.
|
||||
The properties contain the **view model** (the model that will be presented by the view). All the
|
||||
`$scope` properties will be available to the {@link templates template} at the point in the DOM where the Controller
|
||||
`$scope` properties will be available to the template at the point in the DOM where the Controller
|
||||
is registered.
|
||||
|
||||
The following example demonstrates creating a `GreetingController`, which attaches a `greeting`
|
||||
@@ -69,13 +69,13 @@ now be data-bound to the template:
|
||||
```
|
||||
|
||||
|
||||
## Adding Behavior to a Scope Object
|
||||
# Adding Behavior to a Scope Object
|
||||
|
||||
In order to react to events or execute computation in the view we must provide behavior to the
|
||||
scope. We add behavior to the scope by attaching methods to the `$scope` object. These methods are
|
||||
then available to be called from the template/view.
|
||||
|
||||
The following example uses a Controller to add a method, which doubles a number, to the scope:
|
||||
The following example uses a Controller to add a method to the scope, which doubles a number:
|
||||
|
||||
```js
|
||||
var myApp = angular.module('myApp',[]);
|
||||
@@ -99,7 +99,7 @@ objects (or primitives) assigned to the scope become model properties. Any metho
|
||||
the scope are available in the template/view, and can be invoked via angular expressions
|
||||
and `ng` event handler directives (e.g. {@link ng.directive:ngClick ngClick}).
|
||||
|
||||
## Using Controllers Correctly
|
||||
# Using Controllers Correctly
|
||||
|
||||
In general, a Controller shouldn't try to do too much. It should contain only the business logic
|
||||
needed for a single view.
|
||||
@@ -125,7 +125,7 @@ following components:
|
||||
- A model consisting of a string named `spice`
|
||||
- A Controller with two functions that set the value of `spice`
|
||||
|
||||
The message in our template contains a binding to the `spice` model which, by default, is set to the
|
||||
The message in our template contains a binding to the `spice` model, which by default is set to the
|
||||
string "very". Depending on which button is clicked, the `spice` model is set to `chili` or
|
||||
`jalapeño`, and the message is automatically updated by data-binding.
|
||||
|
||||
@@ -259,7 +259,7 @@ Inheritance works with methods in the same way as it does with properties. So in
|
||||
examples, all of the properties could be replaced with methods that return string values.
|
||||
|
||||
|
||||
# Testing Controllers
|
||||
## Testing Controllers
|
||||
|
||||
Although there are many ways to test a Controller, one of the best conventions, shown below,
|
||||
involves injecting the {@link ng.$rootScope $rootScope} and {@link ng.$controller $controller}:
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
@sortOrder 210
|
||||
@description
|
||||
|
||||
# Data Binding
|
||||
|
||||
Data-binding in Angular apps is the automatic synchronization of data between the model and view
|
||||
components. The way that Angular implements data-binding lets you treat the model as the
|
||||
single-source-of-truth in your application. The view is a projection of the model at all times.
|
||||
|
||||
@@ -51,11 +51,9 @@ In the following example, we say that the `<input>` element **matches** the `ngM
|
||||
The following also **matches** `ngModel`:
|
||||
|
||||
```html
|
||||
<input data-ng-model="foo">
|
||||
<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`).
|
||||
@@ -102,8 +100,6 @@ 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.
|
||||
@@ -831,39 +827,37 @@ element?
|
||||
<file name="script.js">
|
||||
angular.module('dragModule', [])
|
||||
.directive('myDraggable', ['$document', function($document) {
|
||||
return {
|
||||
link: function(scope, element, attr) {
|
||||
var startX = 0, startY = 0, x = 0, y = 0;
|
||||
return function(scope, element, attr) {
|
||||
var startX = 0, startY = 0, x = 0, y = 0;
|
||||
|
||||
element.css({
|
||||
position: 'relative',
|
||||
border: '1px solid red',
|
||||
backgroundColor: 'lightgrey',
|
||||
cursor: 'pointer'
|
||||
});
|
||||
|
||||
element.on('mousedown', function(event) {
|
||||
// Prevent default dragging of selected content
|
||||
event.preventDefault();
|
||||
startX = event.pageX - x;
|
||||
startY = event.pageY - y;
|
||||
$document.on('mousemove', mousemove);
|
||||
$document.on('mouseup', mouseup);
|
||||
});
|
||||
|
||||
function mousemove(event) {
|
||||
y = event.pageY - startY;
|
||||
x = event.pageX - startX;
|
||||
element.css({
|
||||
position: 'relative',
|
||||
border: '1px solid red',
|
||||
backgroundColor: 'lightgrey',
|
||||
cursor: 'pointer'
|
||||
top: y + 'px',
|
||||
left: x + 'px'
|
||||
});
|
||||
}
|
||||
|
||||
element.on('mousedown', function(event) {
|
||||
// Prevent default dragging of selected content
|
||||
event.preventDefault();
|
||||
startX = event.pageX - x;
|
||||
startY = event.pageY - y;
|
||||
$document.on('mousemove', mousemove);
|
||||
$document.on('mouseup', mouseup);
|
||||
});
|
||||
|
||||
function mousemove(event) {
|
||||
y = event.pageY - startY;
|
||||
x = event.pageX - startX;
|
||||
element.css({
|
||||
top: y + 'px',
|
||||
left: x + 'px'
|
||||
});
|
||||
}
|
||||
|
||||
function mouseup() {
|
||||
$document.off('mousemove', mousemove);
|
||||
$document.off('mouseup', mouseup);
|
||||
}
|
||||
function mouseup() {
|
||||
$document.off('mousemove', mousemove);
|
||||
$document.off('mouseup', mouseup);
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
@@ -28,13 +28,13 @@ Angular expressions are like JavaScript expressions with the following differenc
|
||||
|
||||
* **No Control Flow Statements:** You cannot use the following in an Angular expression:
|
||||
conditionals, loops, or exceptions.
|
||||
|
||||
|
||||
* **No Function Declarations:** You cannot declare functions in an Angular expression,
|
||||
even inside `ng-init` directive.
|
||||
|
||||
* **No RegExp Creation With Literal Notation:** You cannot create regular expressions
|
||||
|
||||
* **No RegExp Creation With Literal Notation:** You cannot create regular expressions
|
||||
in an Angular expression.
|
||||
|
||||
|
||||
* **No Comma And Void Operators:** You cannot use `,` or `void` in an Angular expression.
|
||||
|
||||
* **Filters:** You can use {@link guide/filter filters} within expressions to format data before
|
||||
@@ -175,7 +175,7 @@ expression, delegate to a JavaScript method instead.
|
||||
## No function declarations or RegExp creation with literal notation
|
||||
|
||||
You can't declare functions or create regular expressions from within AngularJS expressions. This is
|
||||
to avoid complex model transformation logic inside templates. Such logic is better placed in a
|
||||
to avoid complex model transformation logic inside templates. Such logic is better placed in a
|
||||
controller or in a dedicated filter where it can be tested properly.
|
||||
|
||||
## `$event`
|
||||
@@ -297,29 +297,25 @@ then the expression is not fulfilled and will remain watched.
|
||||
2. If V is not undefined, mark the result of the expression as stable and schedule a task
|
||||
to deregister the watch for this expression when we exit the digest loop
|
||||
3. Process the digest loop as normal
|
||||
4. When digest loop is done and all the values have settled, process the queue of watch
|
||||
deregistration tasks. For each watch to be deregistered, check if it still evaluates
|
||||
to a value that is not `undefined`. If that's the case, deregister the watch. Otherwise,
|
||||
4. When digest loop is done and all the values have settled process the queue of watch
|
||||
deregistration tasks. For each watch to be deregistered check if it still evaluates
|
||||
to value that is not `undefined`. If that's the case, deregister the watch. Otherwise
|
||||
keep dirty-checking the watch in the future digest loops by following the same
|
||||
algorithm starting from step 1
|
||||
|
||||
#### Special case for object literals
|
||||
|
||||
Unlike simple values, object-literals are watched until every key is defined.
|
||||
See http://www.bennadel.com/blog/2760-one-time-data-bindings-for-object-literal-expressions-in-angularjs-1-3.htm
|
||||
|
||||
### How to benefit from one-time binding
|
||||
|
||||
If the expression will not change once set, it is a candidate for one-time binding.
|
||||
If the expression will not change once set, it is a candidate for one-time binding.
|
||||
Here are three example cases.
|
||||
|
||||
When interpolating text or attributes:
|
||||
|
||||
```html
|
||||
<div name="attr: {{::color}}">text: {{::name | uppercase}}</div>
|
||||
<div name="attr: {{::color}}">text: {{::name}}</div>
|
||||
```
|
||||
|
||||
When using a directive with bidirectional binding and parameters that will not change:
|
||||
When using a directive with bidirectional binding and the parameters will not change:
|
||||
|
||||
```js
|
||||
someModule.directive('someDirective', function() {
|
||||
@@ -342,6 +338,7 @@ When using a directive that takes an expression:
|
||||
|
||||
```html
|
||||
<ul>
|
||||
<li ng-repeat="item in ::items | orderBy:'name'">{{item.name}};</li>
|
||||
<li ng-repeat="item in ::items">{{item.name}};</li>
|
||||
</ul>
|
||||
```
|
||||
```
|
||||
|
||||
|
||||
@@ -92,10 +92,8 @@ means that it should be stateless and idempotent. Angular relies on these proper
|
||||
the filter only when the inputs to the function change.
|
||||
|
||||
<div class="alert alert-warning">
|
||||
**Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.
|
||||
Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace
|
||||
your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores
|
||||
(`myapp_subsection_filterx`).
|
||||
**Note:** filter names must be valid angular expression identifiers, such as `uppercase` or `orderBy`.
|
||||
Names with special characters, such as hyphens and dots, are not allowed.
|
||||
</div>
|
||||
|
||||
The following sample filter reverses a text string. In addition, it conditionally makes the
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
@sortOrder 290
|
||||
@description
|
||||
|
||||
# Forms
|
||||
|
||||
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.
|
||||
|
||||
@@ -16,7 +14,7 @@ be circumvented and thus can not be trusted. Server-side validation is still nec
|
||||
secure application.
|
||||
|
||||
|
||||
## Simple form
|
||||
# Simple form
|
||||
The key directive in understanding two-way data-binding is {@link ng.directive:ngModel ngModel}.
|
||||
The `ngModel` directive provides the two-way data-binding by synchronizing the model to the view,
|
||||
as well as view to the model. In addition it provides an {@link ngModel.NgModelController API}
|
||||
@@ -64,7 +62,7 @@ For example: inputs of type `email` must have a value in the form of `user@domai
|
||||
|
||||
|
||||
|
||||
## Using CSS classes
|
||||
# Using CSS classes
|
||||
|
||||
To allow styling of form as well as controls, `ngModel` adds these CSS classes:
|
||||
|
||||
@@ -128,7 +126,7 @@ and failing to satisfy its validity.
|
||||
|
||||
|
||||
|
||||
## Binding to form and control state
|
||||
# Binding to form and control state
|
||||
|
||||
A form is an instance of {@link form.FormController FormController}.
|
||||
The form instance can optionally be published into the scope using the `name` attribute.
|
||||
@@ -210,7 +208,7 @@ didn't interact with a control
|
||||
|
||||
|
||||
|
||||
## Custom model update triggers
|
||||
# Custom model update triggers
|
||||
|
||||
By default, any change to the content will trigger a model update and form validation. You can
|
||||
override this behavior using the {@link ng.directive:ngModelOptions ngModelOptions} directive to
|
||||
@@ -251,7 +249,7 @@ will update the model only when the control loses focus (blur event).
|
||||
|
||||
|
||||
|
||||
## Non-immediate (debounced) model updates
|
||||
# Non-immediate (debounced) model updates
|
||||
|
||||
You can delay the model update/validation by using the `debounce` key with the
|
||||
{@link ng.directive:ngModelOptions ngModelOptions} directive. This delay will also apply to
|
||||
@@ -292,7 +290,7 @@ after last change.
|
||||
</file>
|
||||
</example>
|
||||
|
||||
## Custom Validation
|
||||
# Custom Validation
|
||||
|
||||
Angular provides basic implementation for most common HTML5 {@link ng.directive:input input}
|
||||
types: ({@link input[text] text}, {@link input[number] number}, {@link input[url] url},
|
||||
@@ -409,7 +407,7 @@ In the following example we create two directives:
|
||||
</file>
|
||||
</example>
|
||||
|
||||
## Modifying built-in validators
|
||||
# Modifying built-in validators
|
||||
|
||||
Since Angular itself uses `$validators`, you can easily replace or remove built-in validators,
|
||||
should you find it necessary. The following example shows you how to overwrite the email validator
|
||||
@@ -454,7 +452,7 @@ Note that you can alternatively use `ng-pattern` to further restrict the validat
|
||||
</example>
|
||||
|
||||
|
||||
## Implementing custom form controls (using `ngModel`)
|
||||
# Implementing custom form controls (using `ngModel`)
|
||||
Angular implements all of the basic HTML form controls ({@link ng.directive:input input},
|
||||
{@link ng.directive:select select}, {@link ng.directive:textarea textarea}),
|
||||
which should be sufficient for most cases. However, if you need more flexibility,
|
||||
@@ -491,7 +489,9 @@ The following example shows how to add two-way data-binding to contentEditable e
|
||||
link: function(scope, elm, attrs, ctrl) {
|
||||
// view -> model
|
||||
elm.on('blur', function() {
|
||||
ctrl.$setViewValue(elm.html());
|
||||
scope.$apply(function() {
|
||||
ctrl.$setViewValue(elm.html());
|
||||
});
|
||||
});
|
||||
|
||||
// model -> view
|
||||
|
||||
@@ -18,10 +18,8 @@ application means providing translations and localized formats for the abstracte
|
||||
Angular supports i18n/l10n for {@link ng.filter:date date}, {@link ng.filter:number number} and
|
||||
{@link ng.filter:currency currency} filters.
|
||||
|
||||
Localizable pluralization is supported via the {@link ng.directive:ngPluralize `ngPluralize`
|
||||
directive}. Additionally, you can use {@link guide/i18n#messageformat-extensions MessageFormat extensions} to
|
||||
`$interpolate` for localizable pluralization and gender support in all interpolations via the
|
||||
`ngMessageFormat` module.
|
||||
Additionally, Angular supports localizable pluralization support through the {@link
|
||||
ng.directive:ngPluralize `ngPluralize` directive}.
|
||||
|
||||
All localizable Angular components depend on locale-specific rule sets managed by the {@link
|
||||
ng.$locale `$locale` service}.
|
||||
@@ -139,242 +137,3 @@ The Angular datetime filter uses the time zone settings of the browser. The same
|
||||
application will show different time information depending on the time zone settings of the
|
||||
computer that the application is running on. Neither JavaScript nor Angular currently supports
|
||||
displaying the date with a timezone specified by the developer.
|
||||
|
||||
|
||||
<a name="MessageFormat"></a>
|
||||
## MessageFormat extensions
|
||||
|
||||
You can write localizable plural and gender based messages in Angular interpolation expressions and
|
||||
`$interpolate` calls.
|
||||
|
||||
This syntax extension is provided by way of the `ngMessageFormat` module that your application can
|
||||
depend upon (shipped separately as `angular-message-format.min.js` and `angular-message-format.js`.)
|
||||
A current limitation of the `ngMessageFormat` module, is that it does not support redefining the
|
||||
`$interpolate` start and end symbols. Only the default `{{` and `}}` are allowed.
|
||||
|
||||
The syntax extension is based on a subset of the ICU MessageFormat syntax that covers plurals and
|
||||
gender selections. Please refer to the links in the “Further Reading” section at the bottom of this
|
||||
section.
|
||||
|
||||
You may find it helpful to play with our [Plnkr Example](http://plnkr.co/edit/QBVRQ70dvKZDWmHW9RyR?p=preview)
|
||||
as you read the examples below.
|
||||
|
||||
### Plural Syntax
|
||||
|
||||
The syntax for plural based message selection looks like the following:
|
||||
|
||||
```text
|
||||
{{NUMERIC_EXPRESSION, plural,
|
||||
=0 {MESSAGE_WHEN_VALUE_IS_0}
|
||||
=1 {MESSAGE_WHEN_VALUE_IS_1}
|
||||
=2 {MESSAGE_WHEN_VALUE_IS_2}
|
||||
=3 {MESSAGE_WHEN_VALUE_IS_3}
|
||||
...
|
||||
zero {MESSAGE_WHEN_PLURAL_CATEGORY_IS_ZERO}
|
||||
one {MESSAGE_WHEN_PLURAL_CATEGORY_IS_ONE}
|
||||
two {MESSAGE_WHEN_PLURAL_CATEGORY_IS_TWO}
|
||||
few {MESSAGE_WHEN_PLURAL_CATEGORY_IS_FEW}
|
||||
many {MESSAGE_WHEN_PLURAL_CATEGORY_IS_MANY}
|
||||
other {MESSAGE_WHEN_THERE_IS_NO_MATCH}
|
||||
}}
|
||||
```
|
||||
|
||||
Please note that whitespace (including newline) is generally insignificant except as part of the
|
||||
actual message text that occurs in curly braces. Whitespace is generally used to aid readability.
|
||||
|
||||
Here, `NUMERIC_EXPRESSION` is an expression that evaluates to a numeric value based on which the
|
||||
displayed message should change based on pluralization rules.
|
||||
|
||||
Following the Angular expression, you would denote the plural extension syntax by the `, plural,`
|
||||
syntax element. The spaces there are optional.
|
||||
|
||||
This is followed by a list of selection keyword and corresponding message pairs. The "other"
|
||||
keyword and corresponding message are **required** but you may have as few or as many of the other
|
||||
categories as you need.
|
||||
|
||||
#### Selection Keywords
|
||||
|
||||
The selection keywords can be either exact matches or language dependent [plural
|
||||
categories](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html).
|
||||
|
||||
Exact matches are written as the equal sign followed by the exact value. `=0`, `=1`, `=2` and
|
||||
`=123` are all examples of exact matches. Note that there should be no space between the equal sign
|
||||
and the numeric value.
|
||||
|
||||
Plural category matches are single words corresponding to the [plural
|
||||
categories](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html) of
|
||||
the CLDR plural category spec. These categories vary by locale. The "en" (English) locale, for
|
||||
example, defines just "one" and "other" while the "ga" (Irish) locale defines "one", "two", "few",
|
||||
"many" and "other". Typically, you would just write the categories for your language. During
|
||||
translation, the translators will add or remove more categories depending on the target locale.
|
||||
|
||||
Exact matches always win over keyword matches. Therefore, if you define both `=0` and `zero`, when
|
||||
the value of the expression is zero, the `=0` message is the one that will be selected. (The
|
||||
duplicate keyword categories are helpful when used with the optional `offset` syntax described
|
||||
later.)
|
||||
|
||||
|
||||
#### Messages
|
||||
|
||||
Messages immediately follow a selection keyword and are optionally preceded by whitespace. They are
|
||||
written in single curly braces (`{}`). They may contain Angular interpolation syntax inside them.
|
||||
In addition, the `#` symbol is a placeholder for the actual numeric value of the expression.
|
||||
|
||||
### Simple plural example
|
||||
|
||||
```text
|
||||
{{numMessages, plural,
|
||||
=0 {You have no new messages}
|
||||
=1 {You have one new message}
|
||||
other {You have # new messages}
|
||||
}}
|
||||
```
|
||||
|
||||
Because these messages can themselves contain Angular expressions, you could also write this as
|
||||
follows:
|
||||
|
||||
```text
|
||||
{{numMessages, plural,
|
||||
=0 {You have no new messages}
|
||||
=1 {You have one new message}
|
||||
other {You have {{numMessages}} new messages}
|
||||
}}
|
||||
```
|
||||
|
||||
|
||||
### Plural syntax with optional `offset`
|
||||
|
||||
The plural syntax supports an optional `offset` syntax that is used in matching. It's simpler to
|
||||
explain this with an example.
|
||||
|
||||
```text
|
||||
{{recipients.length, plural, offset:1
|
||||
=0 {You gave no gifts}
|
||||
=1 {You gave {{recipients[0].name}} a gift}
|
||||
one {You gave {{recipients[0].name}} and one other person a gift}
|
||||
other {You gave {{recipients[0].name}} and # other people a gift}
|
||||
}}
|
||||
```
|
||||
|
||||
When an `offset` is specified, the matching works as follows. First, the exact value of the Angular
|
||||
expression is matched against the exact matches (i.e. `=N` selectors) to find a match. If there is
|
||||
one, that message is used. If there was no match, then the offset value is subtracted from the
|
||||
value of the expression and locale specific pluralization rules are applied to this new value to
|
||||
obtain its plural category (such as “one”, “few”, “many”, etc.) and a match is attempted against the
|
||||
keyword selectors and the matching message is used. If there was no match, then the “other”
|
||||
category (required) is used. The value of the `#` character inside a message is the value of
|
||||
original expression reduced by the offset value that was specified.
|
||||
|
||||
### Escaping / Quoting
|
||||
|
||||
You will need to escape curly braces or the `#` character inside message texts if you want them to
|
||||
be treated literally with no special meaning. You may quote/escape any character in your message
|
||||
text by preceding it with a `\` (backslash) character. The backslash character removes any special
|
||||
meaning to the character that immediately follows it. Therefore, you can escape or quote the
|
||||
backslash itself by preceding it with another backslash character.
|
||||
|
||||
|
||||
### Gender (aka select) Syntax
|
||||
|
||||
The gender support is provided by the more generic "select" syntax that is more akin to a switch
|
||||
statement. It is general enough to support use for gender based messages.
|
||||
|
||||
The syntax for gender based message selection looks like the following:
|
||||
|
||||
```text
|
||||
{{EXPRESSION, select,
|
||||
male {MESSAGE_WHEN_EXPRESSION_IS_MALE}
|
||||
female {MESSAGE_WHEN_EXPRESSION_IS_FEMALE}
|
||||
...
|
||||
other {MESSAGE_WHEN_THERE_IS_NO_GENDER_MATCH}
|
||||
}}
|
||||
```
|
||||
|
||||
Please note that whitespace (including newline) is generally insignificant except as part of the
|
||||
actual message text that occurs in curly braces. Whitespace is generally used to aid readability.
|
||||
|
||||
Here, `EXPRESSION` is an Angular expression that evaluates to the gender of the person that
|
||||
is used to select the message that should be displayed.
|
||||
|
||||
The Angular expression is followed by `, select,` where the spaces are optional.
|
||||
|
||||
This is followed by a list of selection keyword and corresponding message pairs. The "other"
|
||||
keyword and corresponding message are **required** but you may have as few or as many of the other
|
||||
gender values as you need (i.e. it isn't restricted to male/female.) Note however, that the
|
||||
matching is **case-sensitive**.
|
||||
|
||||
#### Selection Keywords
|
||||
|
||||
Selection keywords are simple words like "male" and "female". The keyword, "other", and its
|
||||
corresponding message are required while others are optional. It is used when the Angular
|
||||
expression does not match (case-insensitively) any of the other keywords specified.
|
||||
|
||||
#### Messages
|
||||
|
||||
Messages immediately follow a selection keyword and are optionally preceded by whitespace. They are
|
||||
written in single curly braces (`{}`). They may contain Angular interpolation syntax inside them.
|
||||
|
||||
### Simple gender example
|
||||
|
||||
```text
|
||||
{{friendGender, select,
|
||||
male {Invite him}
|
||||
female {Invite her}
|
||||
other {Invite them}
|
||||
}}
|
||||
```
|
||||
|
||||
### Nesting
|
||||
|
||||
As mentioned in the syntax for plural and select, the embedded messages can contain Angular
|
||||
interpolation syntax. Since you can use MessageFormat extensions in Angular interpolation, this
|
||||
allows you to nest plural and gender expressions in any order.
|
||||
|
||||
Please note that if these are intended to reach a translator and be translated, it is recommended
|
||||
that the messages appear as a whole and not be split up.
|
||||
|
||||
### More complex example that demonstrates nesting
|
||||
|
||||
This is taken from the [plunker example](http://plnkr.co/edit/QBVRQ70dvKZDWmHW9RyR?p=preview) linked to earlier.
|
||||
|
||||
```text
|
||||
{{recipients.length, plural, offset:1
|
||||
=0 {You ({{sender.name}}) gave no gifts}
|
||||
=1 { {{ recipients[0].gender, select,
|
||||
male {You ({{sender.name}}) gave him ({{recipients[0].name}}) a gift.}
|
||||
female {You ({{sender.name}}) gave her ({{recipients[0].name}}) a gift.}
|
||||
other {You ({{sender.name}}) gave them ({{recipients[0].name}}) a gift.}
|
||||
}}
|
||||
}
|
||||
one { {{ recipients[0].gender, select,
|
||||
male {You ({{sender.name}}) gave him ({{recipients[0].name}}) and one other person a gift.}
|
||||
female {You ({{sender.name}}) gave her ({{recipients[0].name}}) and one other person a gift.}
|
||||
other {You ({{sender.name}}) gave them ({{recipients[0].name}}) and one other person a gift.}
|
||||
}}
|
||||
}
|
||||
other {You ({{sender.name}}) gave {{recipients.length}} people gifts. }
|
||||
}}
|
||||
```
|
||||
|
||||
### Differences from the ICU MessageFormat syntax
|
||||
|
||||
This section is useful to you if you're already familiar with the ICU MessageFormat syntax.
|
||||
|
||||
This syntax extension, while based on MessageFormat, has been designed to be backwards compatible
|
||||
with existing AngularJS interpolation expressions. The key rule is simply this: **All
|
||||
interpolations are done inside double curlies.** The top level comma operator after an expression
|
||||
inside the double curlies causes MessageFormat extensions to be recognized. Such a top level comma
|
||||
is otherwise illegal in an Angular expression and is used by MessageFormat to specify the function
|
||||
(such as plural/select) and it's related syntax.
|
||||
|
||||
To understand the extension, take a look at the ICU MessageFormat syntax as specified by the ICU
|
||||
documentation. Anywhere in that MessageFormat that you have regular message text and you want to
|
||||
substitute an expression, just put it in double curlies instead of single curlies that MessageFormat
|
||||
dictates. This has a huge advantage. **You are no longer limited to simple identifiers for
|
||||
substitutions**. Because you are using double curlies, you can stick in any arbitrary interpolation
|
||||
syntax there, including nesting more MessageFormat expressions!
|
||||
|
||||
### Further Reading
|
||||
For more details, please refer to our [design doc](https://docs.google.com/a/google.com/document/d/1pbtW2yvtmFBikfRrJd8VAsabiFkKezmYZ_PbgdjQOVU/edit).
|
||||
You can read more about the ICU MessageFormat syntax at
|
||||
[Formatting Messages | ICU User Guide](http://userguide.icu-project.org/formatparse/messages#TOC-MessageFormat).
|
||||
|
||||
@@ -13,335 +13,6 @@ which drives many of these changes.
|
||||
* Several new features, especially animations, would not be possible without a few changes.
|
||||
* Finally, some outstanding bugs were best fixed by changing an existing API.
|
||||
|
||||
# Migrating from 1.3 to 1.4
|
||||
|
||||
Angular 1.4 fixes major animation issues and introduces a new API for `ngCookies`. Further, there
|
||||
are changes to `ngMessages`, `$compile`, `ngRepeat`, `ngOptions `and some fixes to core filters:
|
||||
`limitTo` and `filter`.
|
||||
|
||||
The reason for the ngAnimate refactor was to fix timing issues and to expose new APIs to allow
|
||||
for developers to construct more versatile animations. We now have access to `$animateCss`
|
||||
and the many timing-oriented bugs were fixed which results in smoother animations.
|
||||
If animation is something of interest, then please read over the breaking changes below for animations when
|
||||
`ngAnimate` is used.
|
||||
|
||||
`ngMessages` has been upgraded to allow for dynamic message resolution. This handy feature allows for developers
|
||||
to render error messages with ngMessages that are listed with a directive such as ngRepeat. A great usecase for this
|
||||
involves pulling error message data from a server and then displaying that data via the mechanics of ngMessages. Be
|
||||
sure to read the breaking change involved with `ngMessagesInclude` to upgrade your template code.
|
||||
|
||||
Other changes, such as the ordering of elements with ngRepeat and ngOptions, may also affect the behavior of your
|
||||
application. And be sure to also read up on the changes to `$cookies`. The migration jump from 1.3 to 1.4 should be
|
||||
relatively straightforward otherwise.
|
||||
|
||||
|
||||
|
||||
|
||||
## Animation (`ngAnimate`)
|
||||
|
||||
Animations in 1.4 have been refactored internally, but the API has stayed much the same. There are, however,
|
||||
some breaking changes that need to be addressed when upgrading to 1.4.
|
||||
|
||||
Due to [c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef),
|
||||
JavaScript and CSS animations can no longer be run in
|
||||
parallel. With earlier versions of ngAnimate, both CSS and JS animations
|
||||
would be run together when multiple animations were detected. This
|
||||
feature has been removed, however, the same effect, with even more
|
||||
possibilities, can be achieved by injecting `$animateCss` into a
|
||||
JavaScript-defined animation and creating custom CSS-based animations
|
||||
from there.
|
||||
|
||||
By using `$animateCss` inside of a JavaScript animation in Angular 1.4, we can trigger custom CSS-based animations
|
||||
directly from our JavaScript code.
|
||||
|
||||
```js
|
||||
ngModule.animation('.slide-animation', ['$animateCss', function($animateCss) {
|
||||
return {
|
||||
enter: function(element, doneFn) {
|
||||
// this will trigger a `.ng-enter` and `.ng-enter-active` CSS animation
|
||||
var animation = $animateCss(element, {
|
||||
event: 'enter'
|
||||
// any other CSS-related properties
|
||||
// addClass: 'some-class',
|
||||
// removeClass: 'some-other-class',
|
||||
// from: {},
|
||||
// to: {}
|
||||
});
|
||||
|
||||
// make sure to read the ngAnimate docs to understand how this works
|
||||
animation.start().done(doneFn);
|
||||
}
|
||||
}
|
||||
}]);
|
||||
```
|
||||
|
||||
{@link ngAnimate.$animateCss Click here to learn how to use $animateCss in your animation code}
|
||||
|
||||
Due to [c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef),
|
||||
animation-related callbacks are now fired on `$animate.on` instead of directly being on the element.
|
||||
|
||||
```js
|
||||
// < 1.4
|
||||
element.on('$animate:before', function(e, data) {
|
||||
if (data.event === 'enter') { ... }
|
||||
});
|
||||
element.off('$animate:before', fn);
|
||||
|
||||
// 1.4+
|
||||
$animate.on('enter', element, function(data) {
|
||||
//...
|
||||
});
|
||||
$animate.off('enter', element, fn);
|
||||
```
|
||||
|
||||
Due to [c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef),
|
||||
the function params for `$animate.enabled()` when an element is used are now flipped. This fix allows
|
||||
the function to act as a getter when a single element param is provided.
|
||||
|
||||
```js
|
||||
// < 1.4
|
||||
$animate.enabled(false, element);
|
||||
|
||||
// 1.4+
|
||||
$animate.enabled(element, false);
|
||||
```
|
||||
|
||||
Due to [c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef),
|
||||
in addition to disabling the children of the element, `$animate.enabled(element, false)` will now also
|
||||
disable animations on the element itself.
|
||||
|
||||
Due to [c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef),
|
||||
there is no need to call `$scope.$apply` or `$scope.$digest` inside of a animation promise callback anymore
|
||||
since the promise is resolved within a digest automatically. (Not to worry, any extra digests will not be
|
||||
run unless the promise is used.)
|
||||
|
||||
```js
|
||||
// < 1.4
|
||||
$animate.enter(element).then(function() {
|
||||
$scope.$apply(function() {
|
||||
$scope.explode = true;
|
||||
});
|
||||
});
|
||||
|
||||
// 1.4+
|
||||
$animate.enter(element).then(function() {
|
||||
$scope.explode = true;
|
||||
});
|
||||
```
|
||||
|
||||
Due to [c8700f04](https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef),
|
||||
when an enter, leave or move animation is triggered then it will always end any pending or active parent
|
||||
class based animations (animations triggered via ngClass) in order to ensure that any CSS styles are resolved in time.
|
||||
|
||||
|
||||
|
||||
|
||||
## Forms (`ngMessages`, `ngOptions`, `select`)
|
||||
|
||||
### ngMessages
|
||||
The ngMessages module has also been subject to an internal refactor to allow it to be more flexible
|
||||
and compatible with dynamic message data. The `ngMessage` directive now supports a new attribute
|
||||
called `ng-message-exp` which will evaluate an expression and will keep track of that expression
|
||||
as it changes in order to re-evaluate the listed messages.
|
||||
|
||||
[Click here to learn more about dynamic ng-messages](https://docs.angularjs.org/api/ngMessages#dynamic-messaging)
|
||||
|
||||
There is only one breaking change. Please consider the following when including remote
|
||||
message templates via `ng-messages-include`:
|
||||
|
||||
Due to [c9a4421f](https://github.com/angular/angular.js/commit/c9a4421fc3c97448527eadef1f42eb2f487ec2e0),
|
||||
the `ngMessagesInclude` attribute has now been removed and cannot be used in the same element containing
|
||||
the `ngMessages` directive. Instead, `ngMessagesInclude` is to be used on its own element inline with
|
||||
other inline messages situated as children within the `ngMessages` container 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>
|
||||
```
|
||||
|
||||
Depending on where the `ngMessagesInclude` directive is placed it will be prioritized inline with the other messages
|
||||
before and after it.
|
||||
|
||||
### ngOptions
|
||||
|
||||
The `ngOptions` directive has also been refactored and as a result some long-standing bugs
|
||||
have been fixed. The breaking changes are comparatively minor and should not affect most applications.
|
||||
|
||||
Due to [7fda214c](https://github.com/angular/angular.js/commit/7fda214c4f65a6a06b25cf5d5aff013a364e9cef),
|
||||
when `ngOptions` renders the option values within the DOM, the resulting HTML code is different.
|
||||
Normally this should not affect your application at all, however, if your code relies on inspecting
|
||||
the value property of `<option>` elements (that `ngOptions` generates) then be sure
|
||||
to [read the details](https://github.com/angular/angular.js/commit/7fda214c4f65a6a06b25cf5d5aff013a364e9cef).
|
||||
|
||||
Due to [7fda214c](https://github.com/angular/angular.js/commit/7fda214c4f65a6a06b25cf5d5aff013a364e9cef),
|
||||
when iterating over an object's properties using the `(key, value) in obj` syntax
|
||||
the order of the elements used to be sorted alphabetically. This was an artificial
|
||||
attempt to create a deterministic ordering since browsers don't guarantee the order.
|
||||
But in practice this is not what people want and so this change iterates over properties
|
||||
in the order they are returned by Object.keys(obj), which is almost always the order
|
||||
in which the properties were defined.
|
||||
|
||||
|
||||
### select
|
||||
|
||||
Due to [7fda214c](https://github.com/angular/angular.js/commit/7fda214c4f65a6a06b25cf5d5aff013a364e9cef),
|
||||
the `select` directive will now use strict comparison of the `ngModel` scope value against `option`
|
||||
values to determine which option is selected. This means `Number` scope values will not be matched
|
||||
against numeric option strings.
|
||||
In Angular 1.3.x, setting `scope.x = 200` would select the option with the value 200 in the following `select`:
|
||||
|
||||
```
|
||||
<select ng-model="x">
|
||||
<option value="100">100</option>
|
||||
<option value="200">200</option>
|
||||
</select>
|
||||
```
|
||||
|
||||
In Angular 1.4.x, the 'unknown option' will be selected.
|
||||
To remedy this, you can simply initialize the model as a string: `scope.x = '200'`, or if you want to
|
||||
keep the model as a `Number`, you can do the conversion via `$formatters` and `$parsers` on `ngModel`:
|
||||
|
||||
```js
|
||||
ngModelCtrl.$parsers.push(function(value) {
|
||||
return parseInt(value, 10); // Convert option value to number
|
||||
});
|
||||
|
||||
ngModelCtrl.$formatters.push(function(value) {
|
||||
return value.toString(); // Convert scope value to string
|
||||
});
|
||||
```
|
||||
|
||||
## Templating (`ngRepeat`, `$compile`)
|
||||
|
||||
### 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.
|
||||
|
||||
|
||||
### $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.
|
||||
|
||||
Due to [62d514b](https://github.com/angular/angular.js/commit/62d514b06937cc7dd86e973ea11165c88343b42d),
|
||||
returning an object from a controller constructor function will now override the scope. Views that use the
|
||||
controllerAs method will no longer get the this reference, but the returned object.
|
||||
|
||||
|
||||
## Cookies (`ngCookies`)
|
||||
|
||||
Due to [38fbe3ee](https://github.com/angular/angular.js/commit/38fbe3ee8370fc449b82d80df07b5c2ed2cd5fbe),
|
||||
`$cookies` will no longer expose properties that represent the current browser cookie
|
||||
values. `$cookies` no longer polls the browser for changes to the cookies and ***no longer copies
|
||||
cookie values onto the `$cookies` object***.
|
||||
|
||||
This was changed because the polling is expensive and caused issues with the `$cookies` properties
|
||||
not synchronizing correctly with the actual browser cookie values (The reason the polling
|
||||
was originally added was to allow communication between different tabs,
|
||||
but there are better ways to do this today, for example `localStorage`.)
|
||||
|
||||
The new API on `$cookies` is as follows:
|
||||
|
||||
* `get`
|
||||
* `put`
|
||||
* `getObject`
|
||||
* `putObject`
|
||||
* `getAll`
|
||||
* `remove`
|
||||
|
||||
You must explictly use the methods above in order to access cookie data. This also means that
|
||||
you can no longer watch the properties on `$cookies` to detect changes
|
||||
that occur on the browsers cookies.
|
||||
|
||||
This feature is generally only needed if a 3rd party library was programmatically
|
||||
changing the cookies at runtime. If you rely on this then you must either write code that
|
||||
can react to the 3rd party library making the changes to cookies or implement your own polling
|
||||
mechanism.
|
||||
|
||||
**DEPRECATION NOTICE**
|
||||
|
||||
`$cookieStore` is now deprecated as all the useful logic
|
||||
has been moved to `$cookies`, to which `$cookieStore` now simply
|
||||
delegates calls.
|
||||
|
||||
|
||||
|
||||
|
||||
## Server Requests (`$http`)
|
||||
|
||||
Due to [5da1256](https://github.com/angular/angular.js/commit/5da1256fc2812d5b28fb0af0de81256054856369),
|
||||
`transformRequest` functions can no longer modify request headers.
|
||||
|
||||
Before this commit `transformRequest` could modify request headers, ex.:
|
||||
|
||||
```javascript
|
||||
function requestTransform(data, headers) {
|
||||
headers = angular.extend(headers(), {
|
||||
'X-MY_HEADER': 'abcd'
|
||||
});
|
||||
}
|
||||
return angular.toJson(data);
|
||||
}
|
||||
```
|
||||
|
||||
This behavior was unintended and undocumented, so the change should affect very few applications. If one
|
||||
needs to dynamically add / remove headers it should be done in a header function, for example:
|
||||
|
||||
```javascript
|
||||
$http.get(url, {
|
||||
headers: {
|
||||
'X-MY_HEADER': function(config) {
|
||||
return 'abcd'; //you've got access to a request config object to specify header value dynamically
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## Filters (`filter`, `limitTo`)
|
||||
|
||||
### `filter` filter
|
||||
Due to [cea8e751](https://github.com/angular/angular.js/commit/cea8e75144e6910b806b63a6ec2a6d118316fddd),
|
||||
the `filter` filter will throw an error when used with a non-array. Beforehand it would silently
|
||||
return an empty array.
|
||||
|
||||
If necessary, this can be worked around by converting an object to an array,
|
||||
using a filter such as https://github.com/petebacondarwin/angular-toArrayFilter.
|
||||
|
||||
### `limitTo` filter
|
||||
Due to [a3c3bf33](https://github.com/angular/angular.js/commit/a3c3bf3332e5685dc319c46faef882cb6ac246e1),
|
||||
the limitTo filter has changed behavior when the provided limit value is invalid.
|
||||
Now, instead of returning empty object/array, it returns unchanged input.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Migrating from 1.2 to 1.3
|
||||
|
||||
## Controllers
|
||||
|
||||
@@ -140,7 +140,7 @@ The above is a suggestion. Tailor it to your needs.
|
||||
# Module Loading & Dependencies
|
||||
|
||||
A module is a collection of configuration and run blocks which get applied to the application
|
||||
during the bootstrap process. In its simplest form the module consists of a collection of two kinds
|
||||
during the bootstrap process. In its simplest form the module consist of a collection of two kinds
|
||||
of blocks:
|
||||
|
||||
1. **Configuration blocks** - get executed during the provider registrations and configuration
|
||||
@@ -197,14 +197,14 @@ Then Angular applies configuration blocks in the same order they were registered
|
||||
## Run Blocks
|
||||
|
||||
Run blocks are the closest thing in Angular to the main method. A run block is the code which
|
||||
needs to run to kickstart the application. It is executed after all of the services have been
|
||||
needs to run to kickstart the application. It is executed after all of the service have been
|
||||
configured and the injector has been created. Run blocks typically contain code which is hard
|
||||
to unit-test, and for this reason should be declared in isolated modules, so that they can be
|
||||
ignored in the unit-tests.
|
||||
|
||||
## Dependencies
|
||||
|
||||
Modules can list other modules as their dependencies. Depending on a module implies that the required
|
||||
Modules can list other modules as their dependencies. Depending on a module implies that required
|
||||
module needs to be loaded before the requiring module is loaded. In other words the configuration
|
||||
blocks of the required modules execute before the configuration blocks of the requiring module.
|
||||
The same is true for the run blocks. Each module can only be loaded once, even if multiple other
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
# What are Scopes?
|
||||
|
||||
{@link ng.$rootScope.Scope Scope} is an object that refers to the application
|
||||
{@link ng.$rootScope.Scope scope} is an object that refers to the application
|
||||
model. It is an execution context for {@link expression expressions}. Scopes are
|
||||
arranged in hierarchical structure which mimic the DOM structure of the application. Scopes can
|
||||
watch {@link guide/expression expressions} and propagate events.
|
||||
@@ -245,7 +245,7 @@ of the `$watch` expressions and compares them with the previous value. This dirt
|
||||
asynchronously. This means that assignment such as `$scope.username="angular"` will not
|
||||
immediately cause a `$watch` to be notified, instead the `$watch` notification is delayed until
|
||||
the `$digest` phase. This delay is desirable, since it coalesces multiple model updates into one
|
||||
`$watch` notification as well as guarantees that during the `$watch` notification no other
|
||||
`$watch` notification as well as it guarantees that during the `$watch` notification no other
|
||||
`$watch`es are running. If a `$watch` changes the value of the model, it will force additional
|
||||
`$digest` cycle.
|
||||
|
||||
@@ -264,7 +264,7 @@ the `$digest` phase. This delay is desirable, since it coalesces multiple model
|
||||
3. **Model mutation**
|
||||
|
||||
For mutations to be properly observed, you should make them only within the {@link
|
||||
ng.$rootScope.Scope#$apply scope.$apply()}. Angular APIs do this
|
||||
ng.$rootScope.Scope#$apply scope.$apply()}. (Angular APIs do this
|
||||
implicitly, so no extra `$apply` call is needed when doing synchronous work in controllers,
|
||||
or asynchronous work with {@link ng.$http $http}, {@link ng.$timeout $timeout}
|
||||
or {@link ng.$interval $interval} services.
|
||||
|
||||
@@ -39,7 +39,7 @@ In general, we recommend against this because it can create unintended XSS vecto
|
||||
|
||||
However, it's ok to mix server-side templating in the bootstrap template (`index.html`) as long
|
||||
as user input cannot be used on the server to output html that would then be processed by Angular
|
||||
in a way that would allow for arbitrary code execution.
|
||||
in a way that would cause allow for arbitrary code execution.
|
||||
|
||||
For instance, you can use server-side templating to dynamically generate CSS, URLs, etc, but not
|
||||
for generating templates that are bootstrapped/compiled by Angular.
|
||||
|
||||
@@ -82,7 +82,7 @@ on the service.
|
||||
### Registering Services
|
||||
|
||||
Services are registered to modules via the {@link angular.Module Module API}.
|
||||
Typically you use the {@link angular.Module#factory Module factory} API to register a service:
|
||||
Typically you use the {@link angular.module Module#factory} API to register a service:
|
||||
|
||||
```js
|
||||
var myModule = angular.module('myModule', []);
|
||||
@@ -181,7 +181,7 @@ of a real browser alert.
|
||||
|
||||
```js
|
||||
var mock, notify;
|
||||
beforeEach(module('myServiceModule'));
|
||||
|
||||
beforeEach(function() {
|
||||
mock = {alert: jasmine.createSpy()};
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ are available on [the Karma website](http://karma-runner.github.io/0.12/intro/in
|
||||
|
||||
### Jasmine
|
||||
|
||||
[Jasmine](http://jasmine.github.io/1.3/introduction.html) is a behavior driven development framework for
|
||||
[Jasmine](http://jasmine.github.io/1.3/introduction.html) is a test driven development framework for
|
||||
JavaScript that has become the most popular choice for testing Angular applications. Jasmine
|
||||
provides functions to help with structuring your tests and also making assertions. As your tests
|
||||
grow, keeping them well structured and documented is vital, and Jasmine helps achieve this.
|
||||
@@ -260,13 +260,6 @@ myModule.filter('length', function() {
|
||||
});
|
||||
|
||||
describe('length filter', function() {
|
||||
|
||||
var $filter;
|
||||
|
||||
beforeEach(inject(function(_$filter_){
|
||||
$filter = _$filter_;
|
||||
}));
|
||||
|
||||
it('returns 0 when given null', function() {
|
||||
var length = $filter('length');
|
||||
expect(length(null)).toEqual(0);
|
||||
|
||||
@@ -153,7 +153,7 @@ grunt test:unit --browsers Opera,Firefox
|
||||
|
||||
Note there should be _no spaces between browsers_. `Opera, Firefox` is INVALID.
|
||||
|
||||
During development, however, it's more productive to continuously run unit tests every time the source or test files
|
||||
During development it's however more productive to continuously run unit tests every time the source or test files
|
||||
change. To execute tests in this mode run:
|
||||
|
||||
1. To start the Karma server, capture Chrome browser and run unit tests, run:
|
||||
|
||||
@@ -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.3.14:
|
||||
example points to the minified version 1.2.0:
|
||||
|
||||
```
|
||||
<!doctype html>
|
||||
<html ng-app>
|
||||
<head>
|
||||
<title>My Angular App</title>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
|
||||
@@ -20,42 +20,6 @@ AngularJS is 100% JavaScript, 100% client-side and compatible with both desktop
|
||||
So it's definitely not a plugin or some other native browser extension.
|
||||
|
||||
|
||||
### What is the AngularJS versioning strategy?
|
||||
|
||||
In Angular 1 we do not allow intentional breaking changes to appear in versions where only the "patch"
|
||||
number changes. For example between 1.3.12 and 1.3.13 there can be no breaking changes. We do allow
|
||||
breaking changes happen between "minor" number changes. For example between 1.3.15 and 1.4.0 there
|
||||
will be a number of breaking changes. We also allow breaking changes between beta releases of Angular.
|
||||
For example between 1.4.0-beta.4 and 1.4.0-beta.5 there may be breaking changes. We try hard to minimize
|
||||
these kinds of change only to those where there is a strong use case such as a strongly requested feature
|
||||
improvement, a considerable simplification of the code or a measurable performance improvement.
|
||||
|
||||
When adding new code to branches of Angular, have a very stringent commit policy:
|
||||
|
||||
- Every commit must contain tests and documentation updates alongside the code changes and that all the
|
||||
tests must pass;
|
||||
- Commit messages must be written in a specific manner that allows us to parse them and extract the changes
|
||||
for release notes.
|
||||
|
||||
The Angular code base has a very large set of unit tests (over 4000) and end to end tests, which are pretty
|
||||
comprehensive. This means that a breaking change will require one or more tests to be changed to allow the
|
||||
tests to pass. So when a commit includes tests that are being removed or modified, this is a flag that the
|
||||
code might include a breaking change. When reviewing the commit we can then decide whether there really is
|
||||
a breaking change and if it is appropriate for the branch to which it is being merged. If so, then we
|
||||
require that the commit message contains an appropriate breaking change message.
|
||||
|
||||
Additionally, when a commit lands in our master repository it is synced to Google where we test it against
|
||||
over 2000 applications using the test suites of these applications. This allows us to catch regressions
|
||||
quickly before a release. We've had a pretty good experience with this setup. Only bugs that affect features
|
||||
not used at Google or without sufficient test coverage, have a chance of making it through.
|
||||
|
||||
Lastly, when we are making a release we generate updates to the changelog directly from the commits. This
|
||||
generated update contains a highlighted section that contains all the breaking changes that have been
|
||||
extracted from the commits. We can quickly see in the new changelog exactly what commits contain breaking
|
||||
changes and so can application developers when they are deciding whether to update to a new version of
|
||||
Angular.
|
||||
|
||||
|
||||
### Is AngularJS a templating system?
|
||||
|
||||
At the highest level, Angular does look like just another templating system. But there is one
|
||||
@@ -69,7 +33,7 @@ templating systems.
|
||||
### Do I need to worry about security holes in AngularJS?
|
||||
|
||||
Like any other technology, AngularJS is not impervious to attack. Angular does, however, provide
|
||||
built-in protection from basic security holes, including cross-site scripting and HTML injection
|
||||
built-in protection from basic security holes including cross-site scripting and HTML injection
|
||||
attacks. AngularJS does round-trip escaping on all strings for you and even offers XSRF protection
|
||||
for server-side communication.
|
||||
|
||||
@@ -88,7 +52,7 @@ Yes. See instructions in {@link downloading}.
|
||||
|
||||
We run our extensive test suite against the following browsers: Safari, Chrome, Firefox, Opera 15,
|
||||
IE9 and mobile browsers (Android, Chrome Mobile, iOS Safari). See {@link guide/ie Internet
|
||||
Explorer Compatibility} for more details on supporting legacy IE browsers.
|
||||
Explorer Compatibility} for more details in supporting legacy IE browsers.
|
||||
|
||||
|
||||
### What's Angular's performance like?
|
||||
@@ -97,13 +61,13 @@ The startup time heavily depends on your network connection, state of the cache,
|
||||
available hardware, but typically we measure bootstrap time in tens or hundreds of milliseconds.
|
||||
|
||||
The runtime performance will vary depending on the number and complexity of bindings on the page
|
||||
as well as the speed of your backend (for apps that fetch data from the backend). For an
|
||||
illustration, we typically build snappy apps with hundreds or thousands of active bindings.
|
||||
as well as the speed of your backend (for apps that fetch data from the backend). Just for an
|
||||
illustration we typically build snappy apps with hundreds or thousands of active bindings.
|
||||
|
||||
|
||||
### How big is the angular.js file that I need to include?
|
||||
|
||||
The size of the file is ~50KB compressed and minified.
|
||||
The size of the file is < 36KB compressed and minified.
|
||||
|
||||
|
||||
### Can I use the open-source Closure Library with Angular?
|
||||
@@ -124,7 +88,7 @@ but we don't guarantee that.
|
||||
|
||||
### What is testability like in Angular?
|
||||
|
||||
Very testable and designed this way from the ground up. It has an integrated dependency injection
|
||||
Very testable and designed this way from ground up. It has an integrated dependency injection
|
||||
framework, provides mocks for many heavy dependencies (server-side communication). See
|
||||
{@link ngMock} for details.
|
||||
|
||||
@@ -194,7 +158,7 @@ Conditionally showing and hiding things using jQuery is a common pattern in othe
|
||||
`ng-show` (and `ng-hide`) conditionally show and hide elements based on boolean expressions.
|
||||
Describe the conditions for showing and hiding an element in terms of `$scope` variables:
|
||||
|
||||
<div ng-show="!loggedIn"><a href="#/login">Click here to log in</a></div>
|
||||
<div ng-show="!loggedIn">Click <a href="#/login">here</a> to log in</div>
|
||||
|
||||
Note also the counterpart `ng-hide` and similar `ng-disabled`.
|
||||
Note especially the powerful `ng-switch` that should be used instead of several mutually exclusive `ng-show`s.
|
||||
@@ -225,7 +189,7 @@ Then whenever a value on a scope changes, all `$watch`es observing that element
|
||||
|
||||
Sometimes, usually when you're writing a custom directive, you will have to define your own `$watch` on a scope value to make the directive react to changes.
|
||||
|
||||
On the flip side, sometimes you change a scope value in some code, but the app doesn't react to it.
|
||||
On the flip side, sometimes you change a scope value in some code but the app doesn't react to it.
|
||||
Angular checks for scope variable changes after pieces of your code have finished running; for example, when `ng-click` calls a function on your scope, Angular will check for changes and react.
|
||||
However, some code is outside of Angular and you'll have to call `scope.$apply()` yourself to trigger the update.
|
||||
This is most commonly seen in event handlers in custom directives.
|
||||
|
||||
@@ -129,8 +129,7 @@ Once you have Node.js installed on your machine you can download the tool depend
|
||||
npm install
|
||||
```
|
||||
|
||||
This command reads angular-phonecat's `package.json` file and downloads the following tools
|
||||
into the `node_modules` directory:
|
||||
This command will download the following tools, into the `node_modules` directory:
|
||||
|
||||
- [Bower][bower] - client-side code package manager
|
||||
- [Http-Server][http-server] - simple local static web server
|
||||
@@ -199,7 +198,7 @@ http://localhost:8000/app/index.html
|
||||
|
||||
<div class="alert alert-info">
|
||||
To serve the web app on a different ip address or port, edit the "start" script within package.json.
|
||||
You can use `-a` to set the address and `-p` to set the port.
|
||||
You can `-a` to set the address and `-p` to set the port.
|
||||
</div>
|
||||
|
||||
### Running Unit Tests
|
||||
@@ -271,7 +270,6 @@ It is good to run the end to end tests whenever you make changes to the HTML vie
|
||||
that the application as a whole is executing correctly. It is very common to run End to End tests
|
||||
before pushing a new commit of changes to a remote repository.
|
||||
|
||||
Now that you have set up your local machine, let's get started with the tutorial: {@link step_00 Step 0 - Bootstrapping}
|
||||
|
||||
[git]: http://git-scm.com/
|
||||
[node]: http://nodejs.org/
|
||||
|
||||
@@ -31,7 +31,7 @@ npm install
|
||||
|
||||
To see the app running in a browser, open a *separate* terminal/command line tab or window, then
|
||||
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" title="Open app on localhost">`http://localhost:8000/app/`</a>
|
||||
<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.
|
||||
@@ -65,7 +65,7 @@ __`app/index.html`:__
|
||||
|
||||
## What is the code doing?
|
||||
|
||||
**`ng-app` directive:**
|
||||
* `ng-app` directive:
|
||||
|
||||
<html ng-app>
|
||||
|
||||
@@ -77,41 +77,41 @@ __`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 which registers a callback that will be executed by the
|
||||
This code downloads the `angular.js` script and 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' + '!'}}
|
||||
|
||||
This line demonstrates two core features of Angular's templating capabilities:
|
||||
This line demonstrates two core features of Angular's templating capabilities:
|
||||
|
||||
* a binding, denoted by double-curlies `{{ }}`
|
||||
* a simple expression `'yet' + '!'` used in this binding.
|
||||
* a binding, denoted by double-curlies `{{ }}`
|
||||
* a simple expression `'yet' + '!'` used in this binding.
|
||||
|
||||
The binding tells Angular that it should evaluate an expression and insert the result into the
|
||||
DOM in place of the binding. Rather than a one-time insert, as we'll see in the next steps, a
|
||||
binding will result in efficient continuous updates whenever the result of the expression
|
||||
evaluation changes.
|
||||
The binding tells Angular that it should evaluate an expression and insert the result into the
|
||||
DOM in place of the binding. Rather than a one-time insert, as we'll see in the next steps, a
|
||||
binding will result in efficient continuous updates whenever the result of the expression
|
||||
evaluation changes.
|
||||
|
||||
{@link guide/expression Angular expression} is a JavaScript-like code snippet that is
|
||||
evaluated by Angular in the context of the current model scope, rather than within the scope of
|
||||
the global context (`window`).
|
||||
{@link guide/expression Angular expression} is a JavaScript-like code snippet that is
|
||||
evaluated by Angular in the context of the current model scope, rather than within the scope of
|
||||
the global context (`window`).
|
||||
|
||||
As expected, once this template is processed by Angular, the html page contains the text:
|
||||
"Nothing here yet!".
|
||||
As expected, once this template is processed by Angular, the html page contains the text:
|
||||
"Nothing here yet!".
|
||||
|
||||
## 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 the
|
||||
for most cases. In advanced cases, such as when using script loaders, you can use
|
||||
{@link guide/bootstrap imperative / manual way} to bootstrap the app.
|
||||
|
||||
There are 3 important things that happen during the app bootstrap:
|
||||
|
||||
@@ -11,7 +11,7 @@ multiple views by adding routing, using an Angular module called 'ngRoute'.
|
||||
|
||||
* When you now navigate to `app/index.html`, you are redirected to `app/index.html/#/phones`
|
||||
and the phone list appears in the browser.
|
||||
* When you click on a phone link, the url changes to that specific phone and the stub of a
|
||||
* When you click on a phone link the url changes to one specific to that phone and the stub of a
|
||||
phone detail page is displayed.
|
||||
|
||||
<div doc-tutorial-reset="7"></div>
|
||||
|
||||
@@ -225,7 +225,7 @@ inserted into and removed from the list:
|
||||
* The `ng-leave` class is applied when they're removed from the list.
|
||||
|
||||
The phone listing items are added and removed depending on the data passed to the `ng-repeat` attribute.
|
||||
For example, if the filter data changes, the items will be animated in and out of the repeat list.
|
||||
For example, if the filter data changes the items will be animated in and out of the repeat list.
|
||||
|
||||
Something important to note is that when an animation occurs, two sets of CSS classes
|
||||
are added to the element:
|
||||
@@ -233,7 +233,7 @@ are added to the element:
|
||||
1. a "starting" class that represents the style at the beginning of the animation
|
||||
2. an "active" class that represents the style at the end of the animation
|
||||
|
||||
The name of the starting class is the name of the event that is fired (like `enter`, `move` or `leave`) prefixed with
|
||||
The name of the starting class is the name of event that is fired (like `enter`, `move` or `leave`) prefixed with
|
||||
`ng-`. So an `enter` event will result in a class called `ng-enter`.
|
||||
|
||||
The active class name is the same as the starting class's but with an `-active` suffix.
|
||||
|
||||
@@ -184,11 +184,7 @@ describe("extractDateTimeSymbols", function() {
|
||||
'nov.', 'déc.'],
|
||||
DAY: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
|
||||
SHORTDAY: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],
|
||||
FIRSTDAYOFWEEK: 6,
|
||||
WEEKENDRANGE: [5, 6],
|
||||
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,10 +42,6 @@ function convertDatetimeData(dataObj) {
|
||||
datetimeFormats.DAY = dataObj.WEEKDAYS;
|
||||
datetimeFormats.SHORTDAY = dataObj.SHORTWEEKDAYS;
|
||||
datetimeFormats.AMPMS = dataObj.AMPMS;
|
||||
datetimeFormats.FIRSTDAYOFWEEK = dataObj.FIRSTDAYOFWEEK;
|
||||
datetimeFormats.WEEKENDRANGE = dataObj.WEEKENDRANGE;
|
||||
datetimeFormats.ERAS = dataObj.ERAS;
|
||||
datetimeFormats.ERANAMES = dataObj.ERANAMES;
|
||||
|
||||
|
||||
datetimeFormats.medium = dataObj.DATEFORMATS[2] + ' ' + dataObj.TIMEFORMATS[2];
|
||||
|
||||
@@ -66,12 +66,6 @@ module.exports = function(config, specificOptions) {
|
||||
platform: 'Windows 8.1',
|
||||
version: '11'
|
||||
},
|
||||
'SL_iOS': {
|
||||
base: "SauceLabs",
|
||||
browserName: "iphone",
|
||||
platform: "OS X 10.10",
|
||||
version: "8.1"
|
||||
},
|
||||
|
||||
'BS_Chrome': {
|
||||
base: 'BrowserStack',
|
||||
@@ -111,12 +105,6 @@ module.exports = function(config, specificOptions) {
|
||||
browser_version: '11.0',
|
||||
os: 'Windows',
|
||||
os_version: '8.1'
|
||||
},
|
||||
'BS_iOS': {
|
||||
base: 'BrowserStack',
|
||||
device: 'iPhone 6',
|
||||
os: 'ios',
|
||||
os_version: '8.0'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
+9
-8
@@ -14,6 +14,13 @@ 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');
|
||||
@@ -185,16 +192,14 @@ module.exports = {
|
||||
var mapFileName = mapFile.match(/[^\/]+$/)[0];
|
||||
var errorFileName = file.replace(/\.js$/, '-errors.json');
|
||||
var versionNumber = grunt.config('NG_VERSION').full;
|
||||
var compilationLevel = (file === 'build/angular-message-format.js') ?
|
||||
'ADVANCED_OPTIMIZATIONS' : 'SIMPLE_OPTIMIZATIONS';
|
||||
shell.exec(
|
||||
'java ' +
|
||||
this.java32flags() + ' ' +
|
||||
this.memoryRequirement() + ' ' +
|
||||
'-Xmx2g ' +
|
||||
'-cp bower_components/closure-compiler/compiler.jar' + classPathSep +
|
||||
'bower_components/ng-closure-runner/ngcompiler.jar ' +
|
||||
'org.angularjs.closurerunner.NgClosureRunner ' +
|
||||
'--compilation_level ' + compilationLevel + ' ' +
|
||||
'--compilation_level SIMPLE_OPTIMIZATIONS ' +
|
||||
'--language_in ECMASCRIPT5_STRICT ' +
|
||||
'--minerr_pass ' +
|
||||
'--minerr_errors ' + errorFileName + ' ' +
|
||||
@@ -217,10 +222,6 @@ module.exports = {
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
memoryRequirement: function() {
|
||||
return (process.platform === 'win32') ? '' : '-Xmx2g';
|
||||
},
|
||||
|
||||
|
||||
//returns the 32-bit mode force flags for java compiler if supported, this makes the build much faster
|
||||
java32flags: function(){
|
||||
|
||||
@@ -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.7-linux.tar.gz"
|
||||
CONNECT_URL="https://saucelabs.com/downloads/sc-4.3-linux.tar.gz"
|
||||
CONNECT_DIR="/tmp/sauce-connect-$RANDOM"
|
||||
CONNECT_DOWNLOAD="sc-4.3.7-linux.tar.gz"
|
||||
CONNECT_DOWNLOAD="sc-4.3-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 \
|
||||
sauce-connect/bin/sc -u $SAUCE_USERNAME -k $SAUCE_ACCESS_KEY $ARGS -v \
|
||||
--logfile $CONNECT_LOG 2> $CONNECT_STDERR 1> $CONNECT_STDOUT &
|
||||
|
||||
@@ -16,9 +16,9 @@ var currentPackage, previousVersions, cdnVersion, gitRepoInfo;
|
||||
var getPackage = function() {
|
||||
// Search up the folder hierarchy for the first package.json
|
||||
var packageFolder = path.resolve('.');
|
||||
while (!fs.existsSync(path.join(packageFolder, 'package.json'))) {
|
||||
while ( !fs.existsSync(path.join(packageFolder, 'package.json')) ) {
|
||||
var parent = path.dirname(packageFolder);
|
||||
if (parent === packageFolder) { break; }
|
||||
if ( parent === packageFolder) { break; }
|
||||
packageFolder = parent;
|
||||
}
|
||||
return JSON.parse(fs.readFileSync(path.join(packageFolder,'package.json'), 'UTF-8'));
|
||||
@@ -48,11 +48,11 @@ var getGitRepoInfo = function() {
|
||||
* @return {String} The codename if found, otherwise null/undefined
|
||||
*/
|
||||
var getCodeName = function(tagName) {
|
||||
var gitCatOutput = shell.exec('git cat-file -p ' + tagName, {silent:true}).output;
|
||||
var gitCatOutput = shell.exec('git cat-file -p '+ tagName, {silent:true}).output;
|
||||
var tagMessage = gitCatOutput.match(/^.*codename.*$/mg)[0];
|
||||
var codeName = tagMessage && tagMessage.match(/codename\((.*)\)/)[1];
|
||||
if (!codeName) {
|
||||
throw new Error("Could not extract release code name. The message of tag " + tagName +
|
||||
throw new Error("Could not extract release code name. The message of tag "+tagName+
|
||||
" must match '*codename(some release name)*'");
|
||||
}
|
||||
return codeName;
|
||||
@@ -65,7 +65,7 @@ var getCodeName = function(tagName) {
|
||||
*/
|
||||
function getBuild() {
|
||||
var hash = shell.exec('git rev-parse --short HEAD', {silent: true}).output.replace('\n', '');
|
||||
return 'sha.' + hash;
|
||||
return 'sha.'+hash;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,14 +76,14 @@ function getBuild() {
|
||||
var getTaggedVersion = function() {
|
||||
var gitTagResult = shell.exec('git describe --exact-match', {silent:true});
|
||||
|
||||
if (gitTagResult.code === 0) {
|
||||
if ( gitTagResult.code === 0 ) {
|
||||
var tag = gitTagResult.output.trim();
|
||||
var version = semver.parse(tag);
|
||||
|
||||
if (version && semver.satisfies(version, currentPackage.branchVersion)) {
|
||||
if ( version && semver.satisfies(version, currentPackage.branchVersion)) {
|
||||
version.codeName = getCodeName(tag);
|
||||
version.full = version.version;
|
||||
version.branch = 'v' + currentPackage.branchPattern.replace('*', 'x');
|
||||
version.branch = 'v' + currentPackage.branchVersion.replace('*', 'x');
|
||||
return version;
|
||||
}
|
||||
}
|
||||
@@ -102,7 +102,7 @@ var getPreviousVersions = function() {
|
||||
var repo_url = currentPackage.repository.url;
|
||||
var tagResults = shell.exec('git ls-remote --tags ' + repo_url,
|
||||
{silent: true});
|
||||
if (tagResults.code === 0) {
|
||||
if ( tagResults.code === 0 ) {
|
||||
return _(tagResults.output.match(/v[0-9].*[0-9]$/mg))
|
||||
.map(function(tag) {
|
||||
var version = semver.parse(tag);
|
||||
@@ -110,16 +110,10 @@ var getPreviousVersions = function() {
|
||||
})
|
||||
.filter()
|
||||
.map(function(version) {
|
||||
// angular.js didn't follow semantic version until 1.20rc1
|
||||
if ((version.major === 1 && version.minor === 0 && version.prerelease.length > 0) || (version.major === 1 && version.minor === 2 && version.prerelease[0] === 'rc1')) {
|
||||
version.version = [version.major, version.minor, version.patch].join('.') + version.prerelease.join('');
|
||||
version.raw = 'v' + version.version;
|
||||
}
|
||||
version.docsUrl = 'http://code.angularjs.org/' + version.version + '/docs';
|
||||
// Versions before 1.0.2 had a different docs folder name
|
||||
if (version.major < 1 || (version.major === 1 && version.minor === 0 && version.patch < 2)) {
|
||||
if ( version.major < 1 || (version.major === 1 && version.minor === 0 && version.dot < 2 ) ) {
|
||||
version.docsUrl += '-' + version.version;
|
||||
version.isOldDocsUrl = true;
|
||||
}
|
||||
return version;
|
||||
})
|
||||
@@ -140,10 +134,10 @@ var getCdnVersion = function() {
|
||||
if (!cdnVersion) {
|
||||
// Note: need to use shell.exec and curl here
|
||||
// as version-infos returns its result synchronously...
|
||||
var cdnResult = shell.exec('curl http://ajax.googleapis.com/ajax/libs/angularjs/' + version + '/angular.min.js ' +
|
||||
var cdnResult = shell.exec('curl http://ajax.googleapis.com/ajax/libs/angularjs/'+version+'/angular.min.js '+
|
||||
'--head --write-out "%{http_code}" -o /dev/null -silent',
|
||||
{silent: true});
|
||||
if (cdnResult.code === 0) {
|
||||
if ( cdnResult.code === 0 ) {
|
||||
var statusCode = cdnResult.output.trim();
|
||||
if (statusCode === '200') {
|
||||
cdnVersion = version;
|
||||
@@ -165,9 +159,9 @@ var getSnapshotVersion = function() {
|
||||
})
|
||||
.last();
|
||||
|
||||
if (!version) {
|
||||
if ( !version ) {
|
||||
// a snapshot version before the first tag on the branch
|
||||
version = semver(currentPackage.branchPattern.replace('*','0-beta.1'));
|
||||
version = semver(currentPackage.branchVersion.replace('*','0-beta.1'));
|
||||
}
|
||||
|
||||
// We need to clone to ensure that we are not modifying another version
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Generated
+1527
-6966
File diff suppressed because it is too large
Load Diff
+3
-10
@@ -1,17 +1,10 @@
|
||||
{
|
||||
"name": "angularjs",
|
||||
"license": "MIT",
|
||||
"branchVersion": "^1.4.0-beta.0",
|
||||
"branchPattern": "1.4.*",
|
||||
"branchVersion": "1.3.*",
|
||||
"repository": {
|
||||
"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",
|
||||
@@ -45,7 +38,7 @@
|
||||
"jasmine-node": "~1.14.5",
|
||||
"jasmine-reporters": "~1.0.1",
|
||||
"jshint-stylish": "~1.0.0",
|
||||
"karma": "0.12.32",
|
||||
"karma": "vojtajina/karma#socketio_10",
|
||||
"karma-browserstack-launcher": "0.1.2",
|
||||
"karma-chrome-launcher": "0.1.5",
|
||||
"karma-firefox-launcher": "0.1.3",
|
||||
@@ -59,7 +52,7 @@
|
||||
"marked": "~0.3.0",
|
||||
"node-html-encoder": "0.0.2",
|
||||
"promises-aplus-tests": "~2.1.0",
|
||||
"protractor": "^2.1.0",
|
||||
"protractor": "^1.6.0",
|
||||
"q": "~1.0.0",
|
||||
"q-io": "^1.10.9",
|
||||
"qq": "^0.3.5",
|
||||
|
||||
@@ -17,7 +17,7 @@ ARG_DEFS=(
|
||||
)
|
||||
|
||||
function checkVersionNumber() {
|
||||
BRANCH_PATTERN=$(readJsonProp "package.json" "branchPattern")
|
||||
BRANCH_PATTERN=$(readJsonProp "package.json" "branchVersion")
|
||||
if [[ $VERSION_NUMBER != $BRANCH_PATTERN ]]; then
|
||||
echo "version-number needs to match $BRANCH_PATTERN on this branch"
|
||||
usage
|
||||
|
||||
+15
-16
@@ -14,6 +14,21 @@ function init {
|
||||
TMP_DIR=$(resolveDir ../../tmp)
|
||||
BUILD_DIR=$(resolveDir ../../build)
|
||||
NEW_VERSION=$(cat $BUILD_DIR/version.txt)
|
||||
REPOS=(
|
||||
angular
|
||||
angular-animate
|
||||
angular-aria
|
||||
angular-cookies
|
||||
angular-i18n
|
||||
angular-loader
|
||||
angular-mocks
|
||||
angular-route
|
||||
angular-resource
|
||||
angular-sanitize
|
||||
angular-scenario
|
||||
angular-touch
|
||||
angular-messages
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -48,21 +63,6 @@ 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
|
||||
@@ -114,5 +114,4 @@ function publish {
|
||||
done
|
||||
}
|
||||
|
||||
source $(dirname $0)/repos.inc
|
||||
source $(dirname $0)/../utils.inc
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/bin/false
|
||||
# -*- mode: sh; -*- vim: set filetype=sh:
|
||||
|
||||
REPOS=(
|
||||
angular
|
||||
angular-animate
|
||||
angular-aria
|
||||
angular-cookies
|
||||
angular-i18n
|
||||
angular-loader
|
||||
angular-message-format
|
||||
angular-messages
|
||||
angular-mocks
|
||||
angular-resource
|
||||
angular-route
|
||||
angular-sanitize
|
||||
angular-scenario
|
||||
angular-touch
|
||||
)
|
||||
@@ -13,6 +13,21 @@ ARG_DEFS=(
|
||||
|
||||
function init {
|
||||
TMP_DIR=$(resolveDir ../../tmp)
|
||||
REPOS=(
|
||||
angular
|
||||
angular-animate
|
||||
angular-aria
|
||||
angular-cookies
|
||||
angular-i18n
|
||||
angular-loader
|
||||
angular-messages
|
||||
angular-mocks
|
||||
angular-route
|
||||
angular-resource
|
||||
angular-sanitize
|
||||
angular-scenario
|
||||
angular-touch
|
||||
)
|
||||
}
|
||||
|
||||
function prepare {
|
||||
@@ -38,5 +53,4 @@ function publish {
|
||||
done
|
||||
}
|
||||
|
||||
source $(dirname $0)/repos.inc
|
||||
source $(dirname $0)/../utils.inc
|
||||
|
||||
@@ -10,17 +10,22 @@
|
||||
var _ = require('lodash');
|
||||
var sorted = require('sorted-object');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
|
||||
function cleanModule(module, name) {
|
||||
|
||||
// keep `resolve` properties for git dependencies, delete otherwise
|
||||
delete module.from;
|
||||
if (!(module.resolved && module.resolved.match(/^git(\+[a-z]+)?:\/\//))) {
|
||||
// keep `from` and `resolve` properties for git dependencies, delete otherwise
|
||||
if (!(module.resolved && module.resolved.match(/^git:\/\//))) {
|
||||
delete module.from;
|
||||
delete module.resolved;
|
||||
}
|
||||
|
||||
if (name === 'chokidar') {
|
||||
if (module.version === '0.8.1') {
|
||||
delete module.dependencies;
|
||||
}
|
||||
}
|
||||
|
||||
_.forEach(module.dependencies, function(mod, name) {
|
||||
cleanModule(mod, name);
|
||||
});
|
||||
@@ -28,11 +33,10 @@ 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);
|
||||
|
||||
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");
|
||||
console.log('Writing cleaned npm-shrinkwrap.json');
|
||||
fs.writeFileSync('./npm-shrinkwrap.json', JSON.stringify(sorted(shrinkwrap), null, 2) + "\n");
|
||||
@@ -23,26 +23,22 @@ function init {
|
||||
}
|
||||
|
||||
function prepare {
|
||||
if [[ $IS_SNAPSHOT_BUILD ]]; then
|
||||
# nothing to prepare for snapshot builds as
|
||||
# code.angularjs.org will fetch the current snapshot from
|
||||
# the build server during publish
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "-- Cloning code.angularjs.org"
|
||||
git clone git@github.com:angular/code.angularjs.org.git $REPO_DIR --depth=1
|
||||
git clone git@github.com:angular/code.angularjs.org.git $REPO_DIR
|
||||
|
||||
#
|
||||
# copy the files from the build
|
||||
#
|
||||
echo "-- Updating code.angularjs.org"
|
||||
|
||||
if [[ $IS_SNAPSHOT_BUILD ]]; then
|
||||
#
|
||||
# update the snapshot folder
|
||||
#
|
||||
rm -rf $REPO_DIR/snapshot
|
||||
mkdir $REPO_DIR/snapshot
|
||||
cp -r $BUILD_DIR/* $REPO_DIR/snapshot/
|
||||
else
|
||||
#
|
||||
# copy the files from the build
|
||||
#
|
||||
mkdir $REPO_DIR/$NEW_VERSION
|
||||
cp -r $BUILD_DIR/* $REPO_DIR/$NEW_VERSION/
|
||||
fi
|
||||
mkdir $REPO_DIR/$NEW_VERSION
|
||||
cp -r $BUILD_DIR/* $REPO_DIR/$NEW_VERSION/
|
||||
|
||||
#
|
||||
# commit
|
||||
@@ -54,6 +50,13 @@ function prepare {
|
||||
}
|
||||
|
||||
|
||||
function _update_snapshot() {
|
||||
for backend in "$@" ; do
|
||||
echo "-- Updating snapshot version: backend=$backend"
|
||||
curl -G --data-urlencode "ver=$NEW_VERSION" http://$backend:8003/fetchLatestSnapshot.php
|
||||
done
|
||||
}
|
||||
|
||||
function _update_code() {
|
||||
cd $REPO_DIR
|
||||
|
||||
@@ -71,7 +74,12 @@ function publish {
|
||||
# the currently serving Compute Engine backends.
|
||||
# code.angularjs.org is served out of port 8003 on these backends.
|
||||
backends=("$(dig backends.angularjs.org +short TXT | python -c 'print raw_input()[1:-1].replace(",", "\n")')")
|
||||
_update_code ${backends[@]}
|
||||
|
||||
if [[ $IS_SNAPSHOT_BUILD ]]; then
|
||||
_update_snapshot ${backends[@]}
|
||||
else
|
||||
_update_code ${backends[@]}
|
||||
fi
|
||||
}
|
||||
|
||||
source $(dirname $0)/../utils.inc
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/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
|
||||
@@ -7,9 +7,9 @@ export SAUCE_ACCESS_KEY=`echo $SAUCE_ACCESS_KEY | rev`
|
||||
|
||||
if [ $JOB = "unit" ]; then
|
||||
if [ "$BROWSER_PROVIDER" == "browserstack" ]; then
|
||||
BROWSERS="BS_Chrome,BS_Safari,BS_Firefox,BS_IE_9,BS_IE_10,BS_IE_11,BS_iOS"
|
||||
BROWSERS="BS_Chrome,BS_Safari,BS_Firefox,BS_IE_9,BS_IE_10,BS_IE_11"
|
||||
else
|
||||
BROWSERS="SL_Chrome,SL_Safari,SL_Firefox,SL_IE_9,SL_IE_10,SL_IE_11,SL_iOS"
|
||||
BROWSERS="SL_Chrome,SL_Safari,SL_Firefox,SL_IE_9,SL_IE_10,SL_IE_11"
|
||||
fi
|
||||
|
||||
grunt test:promises-aplus
|
||||
|
||||
@@ -2,18 +2,6 @@
|
||||
|
||||
|
||||
# Wait for Connect to be ready before exiting
|
||||
# Time out if we wait for more than 2 minutes, so that we can print logs.
|
||||
let "counter=0"
|
||||
|
||||
while [ ! -f $BROWSER_PROVIDER_READY_FILE ]; do
|
||||
let "counter++"
|
||||
if [ $counter -gt 240 ]; then
|
||||
echo "Timed out after 2 minutes waiting for browser provider ready file"
|
||||
# We must manually print logs here because travis will not run
|
||||
# after_script commands if the failure occurs before the script
|
||||
# phase.
|
||||
./scripts/travis/print_logs.sh
|
||||
exit 5
|
||||
fi
|
||||
sleep .5
|
||||
done
|
||||
|
||||
+2
-9
@@ -28,14 +28,14 @@
|
||||
"manualUppercase": false,
|
||||
"isArrayLike": false,
|
||||
"forEach": false,
|
||||
"sortedKeys": false,
|
||||
"forEachSorted": false,
|
||||
"reverseParams": false,
|
||||
"nextUid": false,
|
||||
"setHashKey": false,
|
||||
"extend": false,
|
||||
"toInt": false,
|
||||
"int": false,
|
||||
"inherit": false,
|
||||
"merge": false,
|
||||
"noop": false,
|
||||
"identity": false,
|
||||
"valueFn": false,
|
||||
@@ -55,7 +55,6 @@
|
||||
"isBlob": false,
|
||||
"isBoolean": false,
|
||||
"isPromiseLike": false,
|
||||
"hasCustomToString": false,
|
||||
"trim": false,
|
||||
"escapeForRegexp": false,
|
||||
"isElement": false,
|
||||
@@ -72,8 +71,6 @@
|
||||
"toJsonReplacer": false,
|
||||
"toJson": false,
|
||||
"fromJson": false,
|
||||
"convertTimezoneToLocal": false,
|
||||
"timezoneToOffset": false,
|
||||
"startingTag": false,
|
||||
"tryDecodeURIComponent": false,
|
||||
"parseKeyValue": false,
|
||||
@@ -97,7 +94,6 @@
|
||||
"skipDestroyOnNextJQueryCleanData": true,
|
||||
|
||||
"NODE_TYPE_ELEMENT": false,
|
||||
"NODE_TYPE_ATTRIBUTE": false,
|
||||
"NODE_TYPE_TEXT": false,
|
||||
"NODE_TYPE_COMMENT": false,
|
||||
"NODE_TYPE_COMMENT": false,
|
||||
@@ -157,9 +153,6 @@
|
||||
"urlResolve": false,
|
||||
"urlIsSameOrigin": false,
|
||||
|
||||
/* ng/controller.js */
|
||||
"identifierForController": false,
|
||||
|
||||
/* ng/compile.js */
|
||||
"directiveNormalize": false,
|
||||
|
||||
|
||||
+62
-248
@@ -22,21 +22,20 @@
|
||||
nodeName_: true,
|
||||
isArrayLike: true,
|
||||
forEach: true,
|
||||
sortedKeys: true,
|
||||
forEachSorted: true,
|
||||
reverseParams: true,
|
||||
nextUid: true,
|
||||
setHashKey: true,
|
||||
extend: true,
|
||||
toInt: true,
|
||||
int: true,
|
||||
inherit: true,
|
||||
merge: true,
|
||||
noop: true,
|
||||
identity: true,
|
||||
valueFn: true,
|
||||
isUndefined: true,
|
||||
isDefined: true,
|
||||
isObject: true,
|
||||
isBlankObject: true,
|
||||
isString: true,
|
||||
isNumber: true,
|
||||
isDate: true,
|
||||
@@ -60,15 +59,12 @@
|
||||
shallowCopy: true,
|
||||
equals: true,
|
||||
csp: true,
|
||||
jq: true,
|
||||
concat: true,
|
||||
sliceArgs: true,
|
||||
bind: true,
|
||||
toJsonReplacer: true,
|
||||
toJson: true,
|
||||
fromJson: true,
|
||||
convertTimezoneToLocal: true,
|
||||
timezoneToOffset: true,
|
||||
startingTag: true,
|
||||
tryDecodeURIComponent: true,
|
||||
parseKeyValue: true,
|
||||
@@ -89,7 +85,6 @@
|
||||
createMap: true,
|
||||
|
||||
NODE_TYPE_ELEMENT: true,
|
||||
NODE_TYPE_ATTRIBUTE: true,
|
||||
NODE_TYPE_TEXT: true,
|
||||
NODE_TYPE_COMMENT: true,
|
||||
NODE_TYPE_DOCUMENT: true,
|
||||
@@ -176,7 +171,6 @@ var
|
||||
splice = [].splice,
|
||||
push = [].push,
|
||||
toString = Object.prototype.toString,
|
||||
getPrototypeOf = Object.getPrototypeOf,
|
||||
ngMinErr = minErr('ng'),
|
||||
|
||||
/** @name angular */
|
||||
@@ -202,9 +196,7 @@ function isArrayLike(obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Support: iOS 8.2 (not reproducible in simulator)
|
||||
// "length" in obj used to prevent JIT error (gh-11508)
|
||||
var length = "length" in Object(obj) && obj.length;
|
||||
var length = obj.length;
|
||||
|
||||
if (obj.nodeType === NODE_TYPE_ELEMENT && length) {
|
||||
return true;
|
||||
@@ -269,32 +261,23 @@ function forEach(obj, iterator, context) {
|
||||
}
|
||||
} else if (obj.forEach && obj.forEach !== forEach) {
|
||||
obj.forEach(iterator, context, obj);
|
||||
} else if (isBlankObject(obj)) {
|
||||
// createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
|
||||
for (key in obj) {
|
||||
iterator.call(context, obj[key], key, obj);
|
||||
}
|
||||
} else if (typeof obj.hasOwnProperty === 'function') {
|
||||
// Slow path for objects inheriting Object.prototype, hasOwnProperty check needed
|
||||
} else {
|
||||
for (key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
iterator.call(context, obj[key], key, obj);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Slow path for objects which do not have a method `hasOwnProperty`
|
||||
for (key in obj) {
|
||||
if (hasOwnProperty.call(obj, key)) {
|
||||
iterator.call(context, obj[key], key, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
function sortedKeys(obj) {
|
||||
return Object.keys(obj).sort();
|
||||
}
|
||||
|
||||
function forEachSorted(obj, iterator, context) {
|
||||
var keys = Object.keys(obj).sort();
|
||||
var keys = sortedKeys(obj);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
iterator.call(context, obj[keys[i]], keys[i]);
|
||||
}
|
||||
@@ -339,35 +322,6 @@ function setHashKey(obj, h) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function baseExtend(dst, objs, deep) {
|
||||
var h = dst.$$hashKey;
|
||||
|
||||
for (var i = 0, ii = objs.length; i < ii; ++i) {
|
||||
var obj = objs[i];
|
||||
if (!isObject(obj) && !isFunction(obj)) continue;
|
||||
var keys = Object.keys(obj);
|
||||
for (var j = 0, jj = keys.length; j < jj; j++) {
|
||||
var key = keys[j];
|
||||
var src = obj[key];
|
||||
|
||||
if (deep && isObject(src)) {
|
||||
if (isDate(src)) {
|
||||
dst[key] = new Date(src.valueOf());
|
||||
} else {
|
||||
if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};
|
||||
baseExtend(dst[key], [src], true);
|
||||
}
|
||||
} else {
|
||||
dst[key] = src;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setHashKey(dst, h);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name angular.extend
|
||||
@@ -378,44 +332,31 @@ function baseExtend(dst, objs, deep) {
|
||||
* Extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
|
||||
* to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
|
||||
* by passing an empty object as the target: `var object = angular.extend({}, object1, object2)`.
|
||||
*
|
||||
* **Note:** Keep in mind that `angular.extend` does not support recursive merge (deep copy). Use
|
||||
* {@link angular.merge} for this.
|
||||
* Note: Keep in mind that `angular.extend` does not support recursive merge (deep copy).
|
||||
*
|
||||
* @param {Object} dst Destination object.
|
||||
* @param {...Object} src Source object(s).
|
||||
* @returns {Object} Reference to `dst`.
|
||||
*/
|
||||
function extend(dst) {
|
||||
return baseExtend(dst, slice.call(arguments, 1), false);
|
||||
var h = dst.$$hashKey;
|
||||
|
||||
for (var i = 1, ii = arguments.length; i < ii; i++) {
|
||||
var obj = arguments[i];
|
||||
if (obj) {
|
||||
var keys = Object.keys(obj);
|
||||
for (var j = 0, jj = keys.length; j < jj; j++) {
|
||||
var key = keys[j];
|
||||
dst[key] = obj[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setHashKey(dst, h);
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name angular.merge
|
||||
* @module ng
|
||||
* @kind function
|
||||
*
|
||||
* @description
|
||||
* Deeply extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
|
||||
* to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
|
||||
* by passing an empty object as the target: `var object = angular.merge({}, object1, object2)`.
|
||||
*
|
||||
* Unlike {@link angular.extend extend()}, `merge()` recursively descends into object properties of source
|
||||
* objects, performing a deep copy.
|
||||
*
|
||||
* @param {Object} dst Destination object.
|
||||
* @param {...Object} src Source object(s).
|
||||
* @returns {Object} Reference to `dst`.
|
||||
*/
|
||||
function merge(dst) {
|
||||
return baseExtend(dst, slice.call(arguments, 1), true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function toInt(str) {
|
||||
function int(str) {
|
||||
return parseInt(str, 10);
|
||||
}
|
||||
|
||||
@@ -468,11 +409,6 @@ identity.$inject = [];
|
||||
|
||||
function valueFn(value) {return function() {return value;};}
|
||||
|
||||
function hasCustomToString(obj) {
|
||||
return isFunction(obj.toString) && obj.toString !== Object.prototype.toString;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name angular.isUndefined
|
||||
@@ -522,16 +458,6 @@ function isObject(value) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine if a value is an object with a null prototype
|
||||
*
|
||||
* @returns {boolean} True if `value` is an `Object` with a null prototype
|
||||
*/
|
||||
function isBlankObject(value) {
|
||||
return value !== null && typeof value === 'object' && !getPrototypeOf(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name angular.isString
|
||||
@@ -556,12 +482,6 @@ 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`.
|
||||
*/
|
||||
@@ -668,12 +588,6 @@ function isPromiseLike(obj) {
|
||||
}
|
||||
|
||||
|
||||
var TYPED_ARRAY_REGEXP = /^\[object (Uint8(Clamped)?)|(Uint16)|(Uint32)|(Int8)|(Int16)|(Int32)|(Float(32)|(64))Array\]$/;
|
||||
function isTypedArray(value) {
|
||||
return TYPED_ARRAY_REGEXP.test(toString.call(value));
|
||||
}
|
||||
|
||||
|
||||
var trim = function(value) {
|
||||
return isString(value) ? value.trim() : value;
|
||||
};
|
||||
@@ -711,9 +625,8 @@ function isElement(node) {
|
||||
*/
|
||||
function makeMap(str) {
|
||||
var obj = {}, items = str.split(","), i;
|
||||
for (i = 0; i < items.length; i++) {
|
||||
for (i = 0; i < items.length; i++)
|
||||
obj[items[i]] = true;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -728,10 +641,9 @@ function includes(array, obj) {
|
||||
|
||||
function arrayRemove(array, value) {
|
||||
var index = array.indexOf(value);
|
||||
if (index >= 0) {
|
||||
if (index >= 0)
|
||||
array.splice(index, 1);
|
||||
}
|
||||
return index;
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -797,40 +709,20 @@ function copy(source, destination, stackSource, stackDest) {
|
||||
throw ngMinErr('cpws',
|
||||
"Can't copy! Making copies of Window or Scope instances is not supported.");
|
||||
}
|
||||
if (isTypedArray(destination)) {
|
||||
throw ngMinErr('cpta',
|
||||
"Can't copy! TypedArray destination cannot be mutated.");
|
||||
}
|
||||
|
||||
if (!destination) {
|
||||
destination = source;
|
||||
if (isObject(source)) {
|
||||
var index;
|
||||
if (stackSource && (index = stackSource.indexOf(source)) !== -1) {
|
||||
return stackDest[index];
|
||||
}
|
||||
|
||||
// TypedArray, Date and RegExp have specific copy functionality and must be
|
||||
// pushed onto the stack before returning.
|
||||
// Array and other objects create the base object and recurse to copy child
|
||||
// objects. The array/object will be pushed onto the stack when recursed.
|
||||
if (source) {
|
||||
if (isArray(source)) {
|
||||
return copy(source, [], stackSource, stackDest);
|
||||
} else if (isTypedArray(source)) {
|
||||
destination = new source.constructor(source);
|
||||
destination = copy(source, [], stackSource, stackDest);
|
||||
} else if (isDate(source)) {
|
||||
destination = new Date(source.getTime());
|
||||
} else if (isRegExp(source)) {
|
||||
destination = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]);
|
||||
destination.lastIndex = source.lastIndex;
|
||||
} else {
|
||||
var emptyObject = Object.create(getPrototypeOf(source));
|
||||
return copy(source, emptyObject, stackSource, stackDest);
|
||||
}
|
||||
|
||||
if (stackDest) {
|
||||
stackSource.push(source);
|
||||
stackDest.push(destination);
|
||||
} else if (isObject(source)) {
|
||||
var emptyObject = Object.create(Object.getPrototypeOf(source));
|
||||
destination = copy(source, emptyObject, stackSource, stackDest);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -841,15 +733,23 @@ function copy(source, destination, stackSource, stackDest) {
|
||||
stackDest = stackDest || [];
|
||||
|
||||
if (isObject(source)) {
|
||||
var index = stackSource.indexOf(source);
|
||||
if (index !== -1) return stackDest[index];
|
||||
|
||||
stackSource.push(source);
|
||||
stackDest.push(destination);
|
||||
}
|
||||
|
||||
var result, key;
|
||||
var result;
|
||||
if (isArray(source)) {
|
||||
destination.length = 0;
|
||||
for (var i = 0; i < source.length; i++) {
|
||||
destination.push(copy(source[i], null, stackSource, stackDest));
|
||||
result = copy(source[i], null, stackSource, stackDest);
|
||||
if (isObject(source[i])) {
|
||||
stackSource.push(source[i]);
|
||||
stackDest.push(result);
|
||||
}
|
||||
destination.push(result);
|
||||
}
|
||||
} else {
|
||||
var h = destination.$$hashKey;
|
||||
@@ -860,28 +760,19 @@ function copy(source, destination, stackSource, stackDest) {
|
||||
delete destination[key];
|
||||
});
|
||||
}
|
||||
if (isBlankObject(source)) {
|
||||
// createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
|
||||
for (key in source) {
|
||||
destination[key] = copy(source[key], null, stackSource, stackDest);
|
||||
}
|
||||
} else if (source && typeof source.hasOwnProperty === 'function') {
|
||||
// Slow path, which must rely on hasOwnProperty
|
||||
for (key in source) {
|
||||
if (source.hasOwnProperty(key)) {
|
||||
destination[key] = copy(source[key], null, stackSource, stackDest);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Slowest path --- hasOwnProperty can't be called as a method
|
||||
for (key in source) {
|
||||
if (hasOwnProperty.call(source, key)) {
|
||||
destination[key] = copy(source[key], null, stackSource, stackDest);
|
||||
for (var key in source) {
|
||||
if (source.hasOwnProperty(key)) {
|
||||
result = copy(source[key], null, stackSource, stackDest);
|
||||
if (isObject(source[key])) {
|
||||
stackSource.push(source[key]);
|
||||
stackDest.push(result);
|
||||
}
|
||||
destination[key] = result;
|
||||
}
|
||||
}
|
||||
setHashKey(destination,h);
|
||||
}
|
||||
|
||||
}
|
||||
return destination;
|
||||
}
|
||||
@@ -959,19 +850,18 @@ function equals(o1, o2) {
|
||||
} else if (isDate(o1)) {
|
||||
if (!isDate(o2)) return false;
|
||||
return equals(o1.getTime(), o2.getTime());
|
||||
} else if (isRegExp(o1)) {
|
||||
return isRegExp(o2) ? o1.toString() == o2.toString() : false;
|
||||
} else if (isRegExp(o1) && isRegExp(o2)) {
|
||||
return o1.toString() == o2.toString();
|
||||
} else {
|
||||
if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) ||
|
||||
isArray(o2) || isDate(o2) || isRegExp(o2)) return false;
|
||||
keySet = createMap();
|
||||
if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) || isArray(o2)) return false;
|
||||
keySet = {};
|
||||
for (key in o1) {
|
||||
if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
|
||||
if (!equals(o1[key], o2[key])) return false;
|
||||
keySet[key] = true;
|
||||
}
|
||||
for (key in o2) {
|
||||
if (!(key in keySet) &&
|
||||
if (!keySet.hasOwnProperty(key) &&
|
||||
key.charAt(0) !== '$' &&
|
||||
o2[key] !== undefined &&
|
||||
!isFunction(o2[key])) return false;
|
||||
@@ -1002,58 +892,7 @@ var csp = function() {
|
||||
return (csp.isActive_ = active);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @module ng
|
||||
* @name ngJq
|
||||
*
|
||||
* @element ANY
|
||||
* @param {string=} ngJq the name of the library available under `window`
|
||||
* to be used for angular.element
|
||||
* @description
|
||||
* Use this directive to force the angular.element library. This should be
|
||||
* used to force either jqLite by leaving ng-jq blank or setting the name of
|
||||
* the jquery variable under window (eg. jQuery).
|
||||
*
|
||||
* Since angular looks for this directive when it is loaded (doesn't wait for the
|
||||
* DOMContentLoaded event), it must be placed on an element that comes before the script
|
||||
* which loads angular. Also, only the first instance of `ng-jq` will be used and all
|
||||
* others ignored.
|
||||
*
|
||||
* @example
|
||||
* This example shows how to force jqLite using the `ngJq` directive to the `html` tag.
|
||||
```html
|
||||
<!doctype html>
|
||||
<html ng-app ng-jq>
|
||||
...
|
||||
...
|
||||
</html>
|
||||
```
|
||||
* @example
|
||||
* This example shows how to use a jQuery based library of a different name.
|
||||
* The library name must be available at the top most 'window'.
|
||||
```html
|
||||
<!doctype html>
|
||||
<html ng-app ng-jq="jQueryLib">
|
||||
...
|
||||
...
|
||||
</html>
|
||||
```
|
||||
*/
|
||||
var jq = function() {
|
||||
if (isDefined(jq.name_)) return jq.name_;
|
||||
var el;
|
||||
var i, ii = ngAttrPrefixes.length, prefix, name;
|
||||
for (i = 0; i < ii; ++i) {
|
||||
prefix = ngAttrPrefixes[i];
|
||||
if (el = document.querySelector('[' + prefix.replace(':', '\\:') + 'jq]')) {
|
||||
name = el.getAttribute(prefix + 'jq');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (jq.name_ = name);
|
||||
};
|
||||
|
||||
function concat(array1, array2, index) {
|
||||
return array1.concat(slice.call(array2, index));
|
||||
@@ -1132,8 +971,8 @@ function toJsonReplacer(key, value) {
|
||||
* stripped since angular uses this notation internally.
|
||||
*
|
||||
* @param {Object|Array|Date|string|number} obj Input to be serialized into JSON.
|
||||
* @param {boolean|number} [pretty=2] If set to true, the JSON output will contain newlines and whitespace.
|
||||
* If set to an integer, the JSON output will contain that many spaces per indentation.
|
||||
* @param {boolean|number=} pretty If set to true, the JSON output will contain newlines and whitespace.
|
||||
* If set to an integer, the JSON output will contain that many spaces per indentation (the default is 2).
|
||||
* @returns {string|undefined} JSON-ified string representing `obj`.
|
||||
*/
|
||||
function toJson(obj, pretty) {
|
||||
@@ -1164,26 +1003,6 @@ function fromJson(json) {
|
||||
}
|
||||
|
||||
|
||||
function timezoneToOffset(timezone, fallback) {
|
||||
var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;
|
||||
return isNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset;
|
||||
}
|
||||
|
||||
|
||||
function addDateMinutes(date, minutes) {
|
||||
date = new Date(date.getTime());
|
||||
date.setMinutes(date.getMinutes() + minutes);
|
||||
return date;
|
||||
}
|
||||
|
||||
|
||||
function convertTimezoneToLocal(date, timezone, reverse) {
|
||||
reverse = reverse ? -1 : 1;
|
||||
var timezoneOffset = timezoneToOffset(timezone, date.getTimezoneOffset());
|
||||
return addDateMinutes(date, reverse * (timezoneOffset - date.getTimezoneOffset()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @returns {string} Returns the string representation of the element.
|
||||
*/
|
||||
@@ -1312,9 +1131,10 @@ var ngAttrPrefixes = ['ng-', 'data-ng-', 'ng:', 'x-ng-'];
|
||||
|
||||
function getNgAttribute(element, ngAttr) {
|
||||
var attr, i, ii = ngAttrPrefixes.length;
|
||||
element = jqLite(element);
|
||||
for (i = 0; i < ii; ++i) {
|
||||
attr = ngAttrPrefixes[i] + ngAttr;
|
||||
if (isString(attr = element.getAttribute(attr))) {
|
||||
if (isString(attr = element.attr(attr))) {
|
||||
return attr;
|
||||
}
|
||||
}
|
||||
@@ -1645,12 +1465,7 @@ function bindJQuery() {
|
||||
}
|
||||
|
||||
// bind to jQuery if present;
|
||||
var jqName = jq();
|
||||
jQuery = window.jQuery; // use default jQuery.
|
||||
if (isDefined(jqName)) { // `ngJq` present
|
||||
jQuery = jqName === null ? undefined : window[jqName]; // if empty; use jqLite. if not empty, use jQuery specified by `ngJq`.
|
||||
}
|
||||
|
||||
jQuery = window.jQuery;
|
||||
// Use jQuery if it exists with proper functionality, otherwise default to us.
|
||||
// Angular 1.2+ requires jQuery 1.7+ for on()/off() support.
|
||||
// Angular 1.3+ technically requires at least jQuery 2.1+ but it may work with older
|
||||
@@ -1789,7 +1604,6 @@ function createMap() {
|
||||
}
|
||||
|
||||
var NODE_TYPE_ELEMENT = 1;
|
||||
var NODE_TYPE_ATTRIBUTE = 2;
|
||||
var NODE_TYPE_TEXT = 3;
|
||||
var NODE_TYPE_COMMENT = 8;
|
||||
var NODE_TYPE_DOCUMENT = 9;
|
||||
|
||||
+2
-15
@@ -57,8 +57,6 @@
|
||||
|
||||
$AnchorScrollProvider,
|
||||
$AnimateProvider,
|
||||
$$CoreAnimateQueueProvider,
|
||||
$$CoreAnimateRunnerProvider,
|
||||
$BrowserProvider,
|
||||
$CacheFactoryProvider,
|
||||
$ControllerProvider,
|
||||
@@ -67,10 +65,7 @@
|
||||
$FilterProvider,
|
||||
$InterpolateProvider,
|
||||
$IntervalProvider,
|
||||
$$HashMapProvider,
|
||||
$HttpProvider,
|
||||
$HttpParamSerializerProvider,
|
||||
$HttpParamSerializerJQLikeProvider,
|
||||
$HttpBackendProvider,
|
||||
$LocationProvider,
|
||||
$LogProvider,
|
||||
@@ -89,8 +84,7 @@
|
||||
$$RAFProvider,
|
||||
$$AsyncCallbackProvider,
|
||||
$WindowProvider,
|
||||
$$jqLiteProvider,
|
||||
$$CookieReaderProvider
|
||||
$$jqLiteProvider
|
||||
*/
|
||||
|
||||
|
||||
@@ -122,7 +116,6 @@ function publishExternalAPI(angular) {
|
||||
'bootstrap': bootstrap,
|
||||
'copy': copy,
|
||||
'extend': extend,
|
||||
'merge': merge,
|
||||
'equals': equals,
|
||||
'element': jqLite,
|
||||
'forEach': forEach,
|
||||
@@ -219,8 +212,6 @@ function publishExternalAPI(angular) {
|
||||
$provide.provider({
|
||||
$anchorScroll: $AnchorScrollProvider,
|
||||
$animate: $AnimateProvider,
|
||||
$$animateQueue: $$CoreAnimateQueueProvider,
|
||||
$$AnimateRunner: $$CoreAnimateRunnerProvider,
|
||||
$browser: $BrowserProvider,
|
||||
$cacheFactory: $CacheFactoryProvider,
|
||||
$controller: $ControllerProvider,
|
||||
@@ -230,8 +221,6 @@ function publishExternalAPI(angular) {
|
||||
$interpolate: $InterpolateProvider,
|
||||
$interval: $IntervalProvider,
|
||||
$http: $HttpProvider,
|
||||
$httpParamSerializer: $HttpParamSerializerProvider,
|
||||
$httpParamSerializerJQLike: $HttpParamSerializerJQLikeProvider,
|
||||
$httpBackend: $HttpBackendProvider,
|
||||
$location: $LocationProvider,
|
||||
$log: $LogProvider,
|
||||
@@ -249,9 +238,7 @@ function publishExternalAPI(angular) {
|
||||
$window: $WindowProvider,
|
||||
$$rAF: $$RAFProvider,
|
||||
$$asyncCallback: $$AsyncCallbackProvider,
|
||||
$$jqLite: $$jqLiteProvider,
|
||||
$$HashMap: $$HashMapProvider,
|
||||
$$cookieReader: $$CookieReaderProvider
|
||||
$$jqLite: $$jqLiteProvider
|
||||
});
|
||||
}
|
||||
]);
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @license AngularJS v"NG_VERSION_FULL"
|
||||
* (c) 2010-2015 Google, Inc. http://angularjs.org
|
||||
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
||||
* License: MIT
|
||||
*/
|
||||
(function(window, document, undefined) {
|
||||
|
||||
@@ -73,9 +73,3 @@ HashMap.prototype = {
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
var $$HashMapProvider = [function() {
|
||||
this.$get = [function() {
|
||||
return HashMap;
|
||||
}];
|
||||
}];
|
||||
|
||||
@@ -179,7 +179,7 @@ function annotate(fn, strictDi, name) {
|
||||
* Return an instance of the service.
|
||||
*
|
||||
* @param {string} name The name of the instance to retrieve.
|
||||
* @param {string=} caller An optional string to provide the origin of the function call for error messages.
|
||||
* @param {string} caller An optional string to provide the origin of the function call for error messages.
|
||||
* @return {*} The instance.
|
||||
*/
|
||||
|
||||
@@ -190,8 +190,8 @@ function annotate(fn, strictDi, name) {
|
||||
* @description
|
||||
* Invoke the method and supply the method arguments from the `$injector`.
|
||||
*
|
||||
* @param {Function|Array.<string|Function>} fn The injectable function to invoke. Function parameters are
|
||||
* injected according to the {@link guide/di $inject Annotation} rules.
|
||||
* @param {!Function} fn The function to invoke. Function parameters are injected according to the
|
||||
* {@link guide/di $inject Annotation} rules.
|
||||
* @param {Object=} self The `this` for the invoked method.
|
||||
* @param {Object=} locals Optional object. If preset then any argument names are read from this
|
||||
* object first, before the `$injector` is consulted.
|
||||
@@ -458,8 +458,8 @@ function annotate(fn, strictDi, name) {
|
||||
* configure your service in a provider.
|
||||
*
|
||||
* @param {string} name The name of the instance.
|
||||
* @param {Function|Array.<string|Function>} $getFn The injectable $getFn for the instance creation.
|
||||
* Internally this is a short hand for `$provide.provider(name, {$get: $getFn})`.
|
||||
* @param {function()} $getFn The $getFn for the instance creation. Internally this is a short hand
|
||||
* for `$provide.provider(name, {$get: $getFn})`.
|
||||
* @returns {Object} registered provider instance
|
||||
*
|
||||
* @example
|
||||
@@ -494,8 +494,7 @@ function annotate(fn, strictDi, name) {
|
||||
* as a type/class.
|
||||
*
|
||||
* @param {string} name The name of the instance.
|
||||
* @param {Function|Array.<string|Function>} constructor An injectable class (constructor function)
|
||||
* that will be instantiated.
|
||||
* @param {Function} constructor A class (constructor function) that will be instantiated.
|
||||
* @returns {Object} registered provider instance
|
||||
*
|
||||
* @example
|
||||
@@ -594,7 +593,7 @@ function annotate(fn, strictDi, name) {
|
||||
* object which replaces or wraps and delegates to the original service.
|
||||
*
|
||||
* @param {string} name The name of the service to decorate.
|
||||
* @param {Function|Array.<string|Function>} decorator This function will be invoked when the service needs to be
|
||||
* @param {function()} decorator This function will be invoked when the service needs to be
|
||||
* instantiated and should return the decorated service instance. The function is called using
|
||||
* the {@link auto.$injector#invoke injector.invoke} method and is therefore fully injectable.
|
||||
* Local injection arguments:
|
||||
@@ -645,7 +644,7 @@ function createInjector(modulesToLoad, strictDi) {
|
||||
}));
|
||||
|
||||
|
||||
forEach(loadModules(modulesToLoad), function(fn) { if (fn) instanceInjector.invoke(fn); });
|
||||
forEach(loadModules(modulesToLoad), function(fn) { instanceInjector.invoke(fn || noop); });
|
||||
|
||||
return instanceInjector;
|
||||
|
||||
|
||||
+4
-28
@@ -1,16 +1,5 @@
|
||||
'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,
|
||||
@@ -39,7 +28,7 @@
|
||||
* Angular to manipulate the DOM in a cross-browser compatible way. **jqLite** implements only the most
|
||||
* commonly needed functionality with the goal of having a very small footprint.</div>
|
||||
*
|
||||
* To use `jQuery`, simply ensure it is loaded before the `angular.js` file.
|
||||
* To use jQuery, simply load it before `DOMContentLoaded` event fired.
|
||||
*
|
||||
* <div class="alert">**Note:** all element references in Angular are always wrapped with jQuery or
|
||||
* jqLite; they are never raw DOM references.</div>
|
||||
@@ -55,7 +44,7 @@
|
||||
* - [`children()`](http://api.jquery.com/children/) - Does not support selectors
|
||||
* - [`clone()`](http://api.jquery.com/clone/)
|
||||
* - [`contents()`](http://api.jquery.com/contents/)
|
||||
* - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyle()`. As a setter, does not convert numbers to strings or append 'px'.
|
||||
* - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyle()`
|
||||
* - [`data()`](http://api.jquery.com/data/)
|
||||
* - [`detach()`](http://api.jquery.com/detach/)
|
||||
* - [`empty()`](http://api.jquery.com/empty/)
|
||||
@@ -182,13 +171,6 @@ function jqLiteAcceptsData(node) {
|
||||
return nodeType === NODE_TYPE_ELEMENT || !nodeType || nodeType === NODE_TYPE_DOCUMENT;
|
||||
}
|
||||
|
||||
function jqLiteHasData(node) {
|
||||
for (var key in jqCache[node.ng339]) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function jqLiteBuildFragment(html, context) {
|
||||
var tmp, tag, wrap,
|
||||
fragment = context.createDocumentFragment(),
|
||||
@@ -563,8 +545,7 @@ function getAliasedAttrName(element, name) {
|
||||
|
||||
forEach({
|
||||
data: jqLiteData,
|
||||
removeData: jqLiteRemoveData,
|
||||
hasData: jqLiteHasData
|
||||
removeData: jqLiteRemoveData
|
||||
}, function(fn, name) {
|
||||
JQLite[name] = fn;
|
||||
});
|
||||
@@ -606,10 +587,6 @@ forEach({
|
||||
},
|
||||
|
||||
attr: function(element, name, value) {
|
||||
var nodeType = element.nodeType;
|
||||
if (nodeType === NODE_TYPE_TEXT || nodeType === NODE_TYPE_ATTRIBUTE || nodeType === NODE_TYPE_COMMENT) {
|
||||
return;
|
||||
}
|
||||
var lowercasedName = lowercase(name);
|
||||
if (BOOLEAN_ATTR[lowercasedName]) {
|
||||
if (isDefined(value)) {
|
||||
@@ -874,9 +851,8 @@ forEach({
|
||||
children: function(element) {
|
||||
var children = [];
|
||||
forEach(element.childNodes, function(element) {
|
||||
if (element.nodeType === NODE_TYPE_ELEMENT) {
|
||||
if (element.nodeType === NODE_TYPE_ELEMENT)
|
||||
children.push(element);
|
||||
}
|
||||
});
|
||||
return children;
|
||||
},
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user