Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5a3504abdc | |||
| 0dfc1dfebf | |||
| e9c406b246 | |||
| 79b6d55792 | |||
| 8f94b5b277 | |||
| b11120be0a | |||
| bfba95ce46 | |||
| 310f80e78e | |||
| acfda1022d | |||
| 04d4d93e5b | |||
| 8348365df9 | |||
| 16bcdcb61d | |||
| adcfa74327 | |||
| d641901be6 | |||
| eae0a1121f | |||
| 173c9063e7 | |||
| b461551b81 | |||
| 63492a0261 | |||
| adb0e1746b | |||
| 3be79cd6a1 | |||
| e4c6e01791 | |||
| fb76d96009 | |||
| f322c4f3c3 | |||
| 081f6ec7f2 | |||
| 9bb6a30417 | |||
| 97e97d1eb7 | |||
| 1ab4e44443 | |||
| 99eeec358c | |||
| ce8a7525cc | |||
| 5df2e5ce29 | |||
| ef03dfc4a4 | |||
| 4ff9c027b0 | |||
| 20b8ece444 | |||
| 6406e3b01d | |||
| 234053fc9a | |||
| a277bcf0f7 | |||
| 7985416d39 | |||
| dc3013e848 | |||
| 0f2926db38 | |||
| bd59335eba | |||
| 6aa111b333 | |||
| 42b5ce99fb | |||
| 2cb1989d12 | |||
| 1137d91abd | |||
| 288e4e33c3 | |||
| d98c5f03a4 | |||
| 8d20b04f1c | |||
| 56c3666fe5 | |||
| cd21216ff7 | |||
| 3ffdf380c5 | |||
| db5e0ffe12 | |||
| 92e4801d88 | |||
| 6a92e9111f | |||
| ba6d37756e | |||
| 683bd92f56 | |||
| 7700e2df09 | |||
| 3fb809e412 | |||
| 52ea4110d3 | |||
| a3a7afd3aa | |||
| 20bc37fbc8 | |||
| 7761b6c3b0 |
+3
-2
@@ -62,6 +62,7 @@ notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/d2120f3f2bb39a4531b2
|
||||
on_success: change # options: [always|never|change] default: always
|
||||
- http://104.197.9.155:8484/hubot/travis/activity #hubot-server
|
||||
on_success: always # options: [always|never|change] default: always
|
||||
on_failure: always # options: [always|never|change] default: always
|
||||
on_start: false # default: false
|
||||
on_start: always # default: false
|
||||
|
||||
+288
-138
@@ -1,7 +1,264 @@
|
||||
<a name="1.5.0-rc.2"></a>
|
||||
# 1.5.0-rc.2 controller-requisition (2016-01-28)
|
||||
|
||||
## Deprecation Warning
|
||||
|
||||
- The `ngTouch` module's `ngClick` directive has been deprecated and disabled by default. See the breaking
|
||||
changes section for more information
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$compile:**
|
||||
- properly denormalize templates when only one of the start/end symbols is different
|
||||
([8348365d](https://github.com/angular/angular.js/commit/8348365df9b9e2d4c9c8d5211e3424d4b9a29767),
|
||||
[#13848](https://github.com/angular/angular.js/issues/13848))
|
||||
- handle boolean attributes in `@` bindings
|
||||
([db5e0ffe](https://github.com/angular/angular.js/commit/db5e0ffe124ac588f01ef0fe79efebfa72f5eec7),
|
||||
[#13767](https://github.com/angular/angular.js/issues/13767), [#13769](https://github.com/angular/angular.js/issues/13769))
|
||||
- **$parse:** Preserve expensive checks when runnning $eval inside an expression
|
||||
([acfda102](https://github.com/angular/angular.js/commit/acfda1022d23ecaea34bbc8931588a0715b3ab03))
|
||||
- **dateFilter:** follow the CLDR on pattern escape sequences
|
||||
([1ab4e444](https://github.com/angular/angular.js/commit/1ab4e44443716c33cd857dcb1098d20580dbb0cc),
|
||||
[#12839](https://github.com/angular/angular.js/issues/12839))
|
||||
- **ngAnimate:**
|
||||
- cancel fallback timeout when animation ends normally
|
||||
([e9c406b2](https://github.com/angular/angular.js/commit/e9c406b2464614c9784f7324d8910180c81c38a7),
|
||||
[#13787](https://github.com/angular/angular.js/issues/13787))
|
||||
- correctly handle `$animate.pin()` host elements
|
||||
([7700e2df](https://github.com/angular/angular.js/commit/7700e2df096cf50dfdf84841cab7e2d24d2eb96d),
|
||||
[#13783](https://github.com/angular/angular.js/issues/13783))
|
||||
- properly cancel-out previously running class-based animations
|
||||
([20b8ece4](https://github.com/angular/angular.js/commit/20b8ece444408a64ac69f7b5d45ddb3af0c418a0),
|
||||
[#10156](https://github.com/angular/angular.js/issues/10156), [#13822](https://github.com/angular/angular.js/issues/13822))
|
||||
- ensure that animate promises resolve when the document is hidden
|
||||
([52ea4110](https://github.com/angular/angular.js/commit/52ea4110d33b7de2845a698913682a03365aa074))
|
||||
- do not trigger animations if the document is hidden
|
||||
([a3a7afd3](https://github.com/angular/angular.js/commit/a3a7afd3aa70d981b0210088df53fa2cf68d3a3d),
|
||||
[#12842](https://github.com/angular/angular.js/issues/12842), [#13776](https://github.com/angular/angular.js/issues/13776))
|
||||
- **ngSanitize:** Blacklist the attribute `usemap`
|
||||
([234053fc](https://github.com/angular/angular.js/commit/234053fc9ad90e0d05be7e8359c6af66be94c094))
|
||||
- **ngTouch:** deprecate ngClick and disable it by default
|
||||
([0dfc1dfe](https://github.com/angular/angular.js/commit/0dfc1dfebf26af7f951f301c4e3848ac46f05d7f),
|
||||
[#4030](https://github.com/angular/angular.js/issues/4030), [#5307](https://github.com/angular/angular.js/issues/5307), [#6001](https://github.com/angular/angular.js/issues/6001), [#6432](https://github.com/angular/angular.js/issues/6432), [#7231](https://github.com/angular/angular.js/issues/7231), [#11358](https://github.com/angular/angular.js/issues/11358), [#12082](https://github.com/angular/angular.js/issues/12082), [#12153](https://github.com/angular/angular.js/issues/12153), [#12392](https://github.com/angular/angular.js/issues/12392), [#12545](https://github.com/angular/angular.js/issues/12545), [#12867](https://github.com/angular/angular.js/issues/12867), [#13213](https://github.com/angular/angular.js/issues/13213), [#13558](https://github.com/angular/angular.js/issues/13558), [#3296](https://github.com/angular/angular.js/issues/3296), [#3347](https://github.com/angular/angular.js/issues/3347), [#3447](https://github.com/angular/angular.js/issues/3447), [#3999](https://github.com/angular/angular.js/issues/3999), [#4428](https://github.com/angular/angular.js/issues/4428), [#6251](https://github.com/angular/angular.js/issues/6251), [#6330](https://github.com/angular/angular.js/issues/6330), [#7134](https://github.com/angular/angular.js/issues/7134), [#7935](https://github.com/angular/angular.js/issues/7935), [#9724](https://github.com/angular/angular.js/issues/9724), [#9744](https://github.com/angular/angular.js/issues/9744), [#9872](https://github.com/angular/angular.js/issues/9872), [#10211](https://github.com/angular/angular.js/issues/10211), [#10366](https://github.com/angular/angular.js/issues/10366), [#10918](https://github.com/angular/angular.js/issues/10918), [#11197](https://github.com/angular/angular.js/issues/11197), [#11261](https://github.com/angular/angular.js/issues/11261), [#11342](https://github.com/angular/angular.js/issues/11342), [#11577](https://github.com/angular/angular.js/issues/11577), [#12150](https://github.com/angular/angular.js/issues/12150), [#12317](https://github.com/angular/angular.js/issues/12317), [#12455](https://github.com/angular/angular.js/issues/12455), [#12734](https://github.com/angular/angular.js/issues/12734), [#13122](https://github.com/angular/angular.js/issues/13122), [#13272](https://github.com/angular/angular.js/issues/13272), [#13447](https://github.com/angular/angular.js/issues/13447))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **$compile:**
|
||||
- allow required controllers to be bound to the directive controller
|
||||
([56c3666f](https://github.com/angular/angular.js/commit/56c3666fe50955aa7d1c1b6159626f1c1cb34637),
|
||||
[#6040](https://github.com/angular/angular.js/issues/6040), [#5893](https://github.com/angular/angular.js/issues/5893), [#13763](https://github.com/angular/angular.js/issues/13763))
|
||||
- allow directive definition property `require` to be an object
|
||||
([cd21216f](https://github.com/angular/angular.js/commit/cd21216ff7eb6d81fc9aa1d1ef994c3d8e046394),
|
||||
[#8401](https://github.com/angular/angular.js/issues/8401), [#13763](https://github.com/angular/angular.js/issues/13763))
|
||||
- call `$ngOnInit` on directive controllers after all sibling controllers have been constructed
|
||||
([3ffdf380](https://github.com/angular/angular.js/commit/3ffdf380c522cbf15a4ce5a8b08d21d40d5f8859),
|
||||
[#13763](https://github.com/angular/angular.js/issues/13763))
|
||||
- **$locale:** include original locale ID in `$locale`
|
||||
([63492a02](https://github.com/angular/angular.js/commit/63492a02614a33a50cc28f9fdd73bae731352dd5),
|
||||
[#13390](https://github.com/angular/angular.js/issues/13390))
|
||||
- **$resource:** add support for timeout in cancellable actions
|
||||
([d641901b](https://github.com/angular/angular.js/commit/d641901be6887cdd93dc678eb514366eb759d21e),
|
||||
[#13824](https://github.com/angular/angular.js/issues/13824))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
|
||||
- **$compile:** avoid needless overhead when wrapping text nodes
|
||||
([92e4801d](https://github.com/angular/angular.js/commit/92e4801d88fbe9b7ef719fd3d0175d85420e1cc4))
|
||||
- **ngAnimate:** speed up `areAnimationsAllowed` check
|
||||
([683bd92f](https://github.com/angular/angular.js/commit/683bd92f56990bf1bfeabf619d997716909ebf6b))
|
||||
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- **ngTouch:** due to [0dfc1dfe](https://github.com/angular/angular.js/commit/0dfc1dfebf26af7f951f301c4e3848ac46f05d7f),
|
||||
|
||||
|
||||
The `ngClick` override directive from the `ngTouch` module is **deprecated and disabled by default**.
|
||||
This means that on touch-based devices, users might now experience a 300ms delay before a click event is fired.
|
||||
|
||||
If you rely on this directive, you can still enable it with the `$touchProvider.ngClickOverrideEnabled()`method:
|
||||
|
||||
```js
|
||||
angular.module('myApp').config(function($touchProvider) {
|
||||
$touchProvider.ngClickOverrideEnabled(true);
|
||||
});
|
||||
```
|
||||
|
||||
Going forward, we recommend using [FastClick](https://github.com/ftlabs/fastclick) or perhaps one of the [Angular
|
||||
3rd party touch-related modules](http://ngmodules.org/tags/touch) that provide similar functionality.
|
||||
|
||||
Also note that modern browsers already remove the 300ms delay under some circumstances:
|
||||
- Chrome and Firefox for Android remove the 300ms delay when the well-known `<meta name="viewport" content="width=device-width">` is set
|
||||
- Internet Explorer removes the delay when `touch-action` css property is set to `none` or `manipulation`
|
||||
- Since iOs 8, Safari removes the delay on so-called "slow taps"
|
||||
|
||||
See this [article by Telerik](http://developer.telerik.com/featured/300-ms-click-delay-ios-8/) for more info on the topic.
|
||||
|
||||
**Note that this change does not affect the `ngSwipe` directive.**
|
||||
|
||||
|
||||
<a name="1.4.9"></a>
|
||||
# 1.4.9 implicit-superannuation (2016-01-21)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **Animation**
|
||||
- ensure that animate promises resolve when the document is hidden
|
||||
([9a60408c](https://github.com/angular/angular.js/commit/9a60408c804a62a9517857bdb9a42182ab6769e3))
|
||||
- do not trigger animations if the document is hidden
|
||||
([09f6061a](https://github.com/angular/angular.js/commit/09f6061a8ee41cae4268e8d44d727d3bf52e22a9),
|
||||
[#12842](https://github.com/angular/angular.js/issues/12842), [#13776](https://github.com/angular/angular.js/issues/13776))
|
||||
- only copy over the animation options once
|
||||
([2fc954d3](https://github.com/angular/angular.js/commit/2fc954d33a3a4c5d4f355be1e15a381664e02f1b),
|
||||
[#13722](https://github.com/angular/angular.js/issues/13722), [#13578](https://github.com/angular/angular.js/issues/13578))
|
||||
- allow event listeners on document in IE
|
||||
([5ba4419e](https://github.com/angular/angular.js/commit/5ba4419e265ff34c6c23bf3533a3332c99c5f014),
|
||||
[#13548](https://github.com/angular/angular.js/issues/13548), [#13696](https://github.com/angular/angular.js/issues/13696))
|
||||
- allow removing classes that are added by a running animation
|
||||
([6c4581fc](https://github.com/angular/angular.js/commit/6c4581fcb692b17295a41b8918c6038333e7bc3d),
|
||||
[#13339](https://github.com/angular/angular.js/issues/13339), [#13380](https://github.com/angular/angular.js/issues/13380), [#13414](https://github.com/angular/angular.js/issues/13414), [#13472](https://github.com/angular/angular.js/issues/13472), [#13678](https://github.com/angular/angular.js/issues/13678))
|
||||
- do not use `event.timeStamp` anymore for time tracking
|
||||
([620a20d1](https://github.com/angular/angular.js/commit/620a20d1b3376d95f85004ffa494e36bb19a2e4d),
|
||||
[#13494](https://github.com/angular/angular.js/issues/13494), [#13495](https://github.com/angular/angular.js/issues/13495))
|
||||
- ignore children without animation data when closing them
|
||||
([be01cebf](https://github.com/angular/angular.js/commit/be01cebfae9ca2383105e535820442b39a96b240),
|
||||
[#11992](https://github.com/angular/angular.js/issues/11992), [#13424](https://github.com/angular/angular.js/issues/13424))
|
||||
- do not alter the provided options data
|
||||
([7a81e6fe](https://github.com/angular/angular.js/commit/7a81e6fe2db084172e34d509f0baad2b33a8722c),
|
||||
[#13040](https://github.com/angular/angular.js/issues/13040), [#13175](https://github.com/angular/angular.js/issues/13175))
|
||||
- correctly handle `$animate.pin()` host elements
|
||||
([a985adfd](https://github.com/angular/angular.js/commit/a985adfdabd871f3f3f3ee59f371da50cd9611d9),
|
||||
[#13783](https://github.com/angular/angular.js/issues/13783))
|
||||
- allow animations when pinned element is parent element
|
||||
([4cb8ac61](https://github.com/angular/angular.js/commit/4cb8ac61c7574ab4039852c358dd5946268b69fb),
|
||||
[#13466](https://github.com/angular/angular.js/issues/13466))
|
||||
- allow enabled children to animate on disabled parents
|
||||
([6d85f24e](https://github.com/angular/angular.js/commit/6d85f24e2081d2a69c80697d90ebd45f228d9682),
|
||||
[#13179](https://github.com/angular/angular.js/issues/13179), [#13695](https://github.com/angular/angular.js/issues/13695))
|
||||
- correctly access `minErr`
|
||||
([0c1b54f0](https://github.com/angular/angular.js/commit/0c1b54f04cf5bd7c1fe42ac49b4fbfdf35c60979))
|
||||
- ensure animate runner is the same with and without animations
|
||||
([937942f5](https://github.com/angular/angular.js/commit/937942f5ada6de1bdacdf0ba465f6f118c270119),
|
||||
[#13205](https://github.com/angular/angular.js/issues/13205), [#13347](https://github.com/angular/angular.js/issues/13347))
|
||||
- remove animation end event listeners on close
|
||||
([d9157849](https://github.com/angular/angular.js/commit/d9157849df224a3a8d2e0bf03099d137f51499f6),
|
||||
[#13672](https://github.com/angular/angular.js/issues/13672))
|
||||
- consider options.delay value for closing timeout
|
||||
([592bf516](https://github.com/angular/angular.js/commit/592bf516e50b9729e446d9aa01f4d9ebdd72d187),
|
||||
[#13355](https://github.com/angular/angular.js/issues/13355), [#13363](https://github.com/angular/angular.js/issues/13363))
|
||||
- **$controller:** allow identifiers containing `$`
|
||||
([2563ff7b](https://github.com/angular/angular.js/commit/2563ff7ba92d84af978e7e4131253190d4d00c20),
|
||||
[#13736](https://github.com/angular/angular.js/issues/13736))
|
||||
- **$http:** throw if url passed is not a string
|
||||
([c5bf9dae](https://github.com/angular/angular.js/commit/c5bf9daef6dfdb3e4a2942c21155a9f67d92e237),
|
||||
[#12925](https://github.com/angular/angular.js/issues/12925), [#13444](https://github.com/angular/angular.js/issues/13444))
|
||||
- **$parse:** handle interceptors with `undefined` expressions
|
||||
([7bb2414b](https://github.com/angular/angular.js/commit/7bb2414bf6461aa45a983fd322ae875f81814cc4))
|
||||
- **$resource:** don't allow using promises as `timeout` and log a warning
|
||||
([47486524](https://github.com/angular/angular.js/commit/474865242c89ba3e8143f0cd52f8c292979ea730))
|
||||
- **formatNumber:** cope with large and small number corner cases
|
||||
([9c49eb13](https://github.com/angular/angular.js/commit/9c49eb131a6100d58c965d01fb08bcd319032229),
|
||||
[#13394](https://github.com/angular/angular.js/issues/13394), [#8674](https://github.com/angular/angular.js/issues/8674), [#12709](https://github.com/angular/angular.js/issues/12709), [#8705](https://github.com/angular/angular.js/issues/8705), [#12707](https://github.com/angular/angular.js/issues/12707), [#10246](https://github.com/angular/angular.js/issues/10246), [#10252](https://github.com/angular/angular.js/issues/10252))
|
||||
- **input:**
|
||||
- fix URL validation being too strict
|
||||
([6610ae81](https://github.com/angular/angular.js/commit/6610ae816f78ee8fc1080b93a55bf19e4ce48d3e),
|
||||
[#13528](https://github.com/angular/angular.js/issues/13528), [#13544](https://github.com/angular/angular.js/issues/13544))
|
||||
- add missing chars to URL validation regex
|
||||
([2995b54a](https://github.com/angular/angular.js/commit/2995b54afdb9a3a2a81b0076a6ac0a9001041163),
|
||||
[#13379](https://github.com/angular/angular.js/issues/13379), [#13460](https://github.com/angular/angular.js/issues/13460))
|
||||
- **isArrayLike:** recognize empty instances of an Array subclass
|
||||
([323f9ab7](https://github.com/angular/angular.js/commit/323f9ab73696f223c245ddefd62a769fe102615e),
|
||||
[#13560](https://github.com/angular/angular.js/issues/13560), [#13708](https://github.com/angular/angular.js/issues/13708))
|
||||
- **ngInclude:** do not compile template if original scope is destroyed
|
||||
([9590bcf0](https://github.com/angular/angular.js/commit/9590bcf0620cd507a7795c55f9a6f4a48bfedbc1))
|
||||
- **ngOptions:**
|
||||
- don't skip `optgroup` elements with `value === ''`
|
||||
([85e392f3](https://github.com/angular/angular.js/commit/85e392f3543ef5285c7e90e843af0ab522cb0531),
|
||||
[#13487](https://github.com/angular/angular.js/issues/13487), [#13489](https://github.com/angular/angular.js/issues/13489))
|
||||
- don't `$dirty` multiple select after compilation
|
||||
([f163c905](https://github.com/angular/angular.js/commit/f163c90555774426ccb14752d089fc707cb4029c),
|
||||
[#13211](https://github.com/angular/angular.js/issues/13211), [#13326](https://github.com/angular/angular.js/issues/13326))
|
||||
- **select:** re-define `ngModelCtrl.$render` in the `select` directive's postLink function
|
||||
([529b2507](https://github.com/angular/angular.js/commit/529b2507bdb4fcc22dfa0f7ab462c79fc78d1413),
|
||||
[#13583](https://github.com/angular/angular.js/issues/13583), [#13583](https://github.com/angular/angular.js/issues/13583), [#13663](https://github.com/angular/angular.js/issues/13663))
|
||||
|
||||
## Minor Features
|
||||
|
||||
- **ngLocale:** add support for standalone months
|
||||
([54c4041e](https://github.com/angular/angular.js/commit/54c4041ebc0cc4df70cf6996f43a6aaaf56d46bd),
|
||||
[#3744](https://github.com/angular/angular.js/issues/3744), [#10247](https://github.com/angular/angular.js/issues/10247), [#12642](https://github.com/angular/angular.js/issues/12642), [#12844](https://github.com/angular/angular.js/issues/12844))
|
||||
- **ngMock:** add support for `$animate.closeAndFlush()`
|
||||
([512c0811](https://github.com/angular/angular.js/commit/512c08118786a419fabbd063fa17d224aba125cf))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
|
||||
- **ngAnimate:** speed up `areAnimationsAllowed` check
|
||||
([2d3303dd](https://github.com/angular/angular.js/commit/2d3303ddda6330c4f45b381b6b17346f6cfe2d97))
|
||||
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
While we do not deem the following to be a real breaking change we are highlighting it here in the
|
||||
changelog to ensure that it does not surprise anyone.
|
||||
|
||||
- **$resource:** due to [47486524](https://github.com/angular/angular.js/commit/474865242c89ba3e8143f0cd52f8c292979ea730),
|
||||
|
||||
**Possible breaking change** for users who updated their code to provide a `timeout`
|
||||
promise for a `$resource` request in version v1.4.8.
|
||||
|
||||
Up to v1.4.7 (included), using a promise as a timeout in `$resource`, would silently
|
||||
fail (i.e. have no effect).
|
||||
|
||||
In v1.4.8, using a promise as timeout would have the (buggy) behaviour described
|
||||
in https://github.com/angular/angular.js/pull/12657#issuecomment-152108887.
|
||||
(I.e. it will work as expected for the first time you resolve the promise and will
|
||||
cancel all subsequent requests after that - one has to re-create the resource
|
||||
class. This was not documented.)
|
||||
|
||||
With this change, using a promise as timeout in v1.4.9 onwards is not allowed.
|
||||
It will log a warning and ignore the timeout value.
|
||||
|
||||
If you need support for cancellable `$resource` actions, you should upgrade to
|
||||
version 1.5 or higher.
|
||||
|
||||
|
||||
<a name="1.5.0-rc.1"></a>
|
||||
# 1.5.0-rc.1 quantum-fermentation (2016-01-15)
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **$compile:**
|
||||
- Allow ES6 classes as controllers with `bindToController: true`
|
||||
([8955cfb6](https://github.com/angular/angular.js/commit/8955cfb6462f79a32caa641ffc002f1522f08220))
|
||||
- Allow ES6 classes as controllers with `bindToController: true`
|
||||
([b0248b78](https://github.com/angular/angular.js/commit/b0248b7894649aa1e083698c66d01679fa66d1c1))
|
||||
- **$compileProvider:** - allow registering components with the component() method
|
||||
([feeb19787ca6e23e15578a4d1319f1c33853290c](https://github.com/angular/angular.js/commit/feeb19787ca6e23e15578a4d1319f1c33853290c))
|
||||
- **component:**
|
||||
- default controllerAs to `$ctrl`
|
||||
([d91cf167](https://github.com/angular/angular.js/commit/d91cf167960d47ce38fec0d33cab6119268623f0),
|
||||
[#13664](https://github.com/angular/angular.js/issues/13664), [#13710](https://github.com/angular/angular.js/issues/13710))
|
||||
- disallow non-isolate scopes
|
||||
([f31c5a39](https://github.com/angular/angular.js/commit/f31c5a3924629795cd9169e69b9e20efd4a9d927),
|
||||
[#13710](https://github.com/angular/angular.js/issues/13710))
|
||||
- allow `component()` helper to copy over custom annotations
|
||||
([90975db5](https://github.com/angular/angular.js/commit/90975db5f91dfe44fa5dc4542e92c68e0d425929),
|
||||
[#13741](https://github.com/angular/angular.js/issues/13741))
|
||||
- **$injector:** support instantiating classes.
|
||||
([8b6b4282](https://github.com/angular/angular.js/commit/8b6b42827186e5e4eb7a56f6b824c560a5058bd2))
|
||||
- **ngMock:** add support for `$animate.closeAndFlush()`
|
||||
([e1def1b8](https://github.com/angular/angular.js/commit/e1def1b8fe543fde09abda076d66606027f7dbeb),
|
||||
[#13005](https://github.com/angular/angular.js/issues/13005), [#13576](https://github.com/angular/angular.js/issues/13576), [#13707](https://github.com/angular/angular.js/issues/13707))
|
||||
- **ngMock.$componentController:** add helper to instantiate controllers for components
|
||||
([dd14e0c4](https://github.com/angular/angular.js/commit/dd14e0c44d2963d217cd4eb28f1ad6e6a643d63f),
|
||||
[#13683](https://github.com/angular/angular.js/issues/13683), [#13711](https://github.com/angular/angular.js/issues/13711))
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$animate:**
|
||||
@@ -24,13 +281,19 @@
|
||||
([de9777d8](https://github.com/angular/angular.js/commit/de9777d8193531472df4b57fdeb6650d7f7c1846),
|
||||
[#12656](https://github.com/angular/angular.js/issues/12656), [#13333](https://github.com/angular/angular.js/issues/13333))
|
||||
- **$compile:**
|
||||
- Add missing variable declaration
|
||||
- add missing variable declaration
|
||||
([6cdbda7c](https://github.com/angular/angular.js/commit/6cdbda7cf1cfc1d49eb98d42d8e823e65bebb90d))
|
||||
- Fix namespace detection for achor elements
|
||||
- fix namespace detection for anchor elements
|
||||
([c9e6cf9b](https://github.com/angular/angular.js/commit/c9e6cf9be0d549fba234956f7e263f40d1bb1e76))
|
||||
- **$compileProvider:** remove the ability to set the `restrict` option on `component()` helper
|
||||
- **component:**
|
||||
- remove the ability to set the `restrict` option on `component()` helper
|
||||
([25bc5318](https://github.com/angular/angular.js/commit/25bc53180248bf5e8a6467c55d913cfa38fc7a3b),
|
||||
[#13741](https://github.com/angular/angular.js/issues/13741))
|
||||
- use `false` as default value for `transclude` in `component()` helper
|
||||
([6a47c0d7](https://github.com/angular/angular.js/commit/6a47c0d75d0c6f0bfb3b5492d1f05ec900387744),
|
||||
[#13566](https://github.com/angular/angular.js/issues/13566), [#13581](https://github.com/angular/angular.js/issues/13581))
|
||||
- allow passing template/templateUrl in array notation
|
||||
([99d601a0](https://github.com/angular/angular.js/commit/99d601a048ac2b82e2f74ae88c96773e5d1a7258))
|
||||
- **$controller:** allow identifiers containing `$`
|
||||
([4e1b36c2](https://github.com/angular/angular.js/commit/4e1b36c21686ad0ca4930d1d81f77a7d9cc35851),
|
||||
[#13736](https://github.com/angular/angular.js/issues/13736))
|
||||
@@ -38,8 +301,6 @@
|
||||
([fabc6ab5](https://github.com/angular/angular.js/commit/fabc6ab5b01dc687aa8385da067752ba34da6524))
|
||||
- **$q:** make instanceof work for $q promises
|
||||
([b3ef5e08](https://github.com/angular/angular.js/commit/b3ef5e08528f5f1916876032700a016448fb196a))
|
||||
- **Module:** allow passing template/templateUrl in array notation
|
||||
([99d601a0](https://github.com/angular/angular.js/commit/99d601a048ac2b82e2f74ae88c96773e5d1a7258))
|
||||
- **copy:**
|
||||
- add support for ArrayBuffer, handle multiple references to ArrayBuffer
|
||||
([986647a9](https://github.com/angular/angular.js/commit/986647a968858121c1de472fc4913221dc8d339a))
|
||||
@@ -54,9 +315,6 @@
|
||||
- **linky:** throw error if input is not a string
|
||||
([98c2db7f](https://github.com/angular/angular.js/commit/98c2db7f9c2d078a408576e722407d518c7ee10a),
|
||||
[#13547](https://github.com/angular/angular.js/issues/13547), [#13693](https://github.com/angular/angular.js/issues/13693))
|
||||
- **loader:** use `false` as default value for `transclude` in component helper
|
||||
([6a47c0d7](https://github.com/angular/angular.js/commit/6a47c0d75d0c6f0bfb3b5492d1f05ec900387744),
|
||||
[#13566](https://github.com/angular/angular.js/issues/13566), [#13581](https://github.com/angular/angular.js/issues/13581))
|
||||
- **ngAnimate:**
|
||||
- only copy over the animation options once
|
||||
([d4fa3313](https://github.com/angular/angular.js/commit/d4fa3313088a03d15ccbf266583d6ecaa0d22241),
|
||||
@@ -82,41 +340,30 @@
|
||||
[#13583](https://github.com/angular/angular.js/issues/13583), [#13583](https://github.com/angular/angular.js/issues/13583), [#13663](https://github.com/angular/angular.js/issues/13663))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **$compile:**
|
||||
- Allow ES6 classes as controllers with `bindToController: true`
|
||||
([8955cfb6](https://github.com/angular/angular.js/commit/8955cfb6462f79a32caa641ffc002f1522f08220))
|
||||
- Allow ES6 classes as controllers with `bindToController: true`
|
||||
([b0248b78](https://github.com/angular/angular.js/commit/b0248b7894649aa1e083698c66d01679fa66d1c1))
|
||||
- **$compileProvider:** allow `component()` helper to copy over custom annotations
|
||||
([90975db5](https://github.com/angular/angular.js/commit/90975db5f91dfe44fa5dc4542e92c68e0d425929),
|
||||
[#13741](https://github.com/angular/angular.js/issues/13741))
|
||||
- **$injector:** support instantiating classes.
|
||||
([8b6b4282](https://github.com/angular/angular.js/commit/8b6b42827186e5e4eb7a56f6b824c560a5058bd2))
|
||||
- **component:**
|
||||
- default controllerAs to be $ctrl
|
||||
([d91cf167](https://github.com/angular/angular.js/commit/d91cf167960d47ce38fec0d33cab6119268623f0),
|
||||
[#13664](https://github.com/angular/angular.js/issues/13664), [#13710](https://github.com/angular/angular.js/issues/13710))
|
||||
- disallow non-isolate scopes
|
||||
([f31c5a39](https://github.com/angular/angular.js/commit/f31c5a3924629795cd9169e69b9e20efd4a9d927),
|
||||
[#13710](https://github.com/angular/angular.js/issues/13710))
|
||||
- **ngMock:** add support for `$animate.closeAndFlush()`
|
||||
([e1def1b8](https://github.com/angular/angular.js/commit/e1def1b8fe543fde09abda076d66606027f7dbeb),
|
||||
[#13005](https://github.com/angular/angular.js/issues/13005), [#13576](https://github.com/angular/angular.js/issues/13576), [#13707](https://github.com/angular/angular.js/issues/13707))
|
||||
- **ngMock.$componentController:** add helper to instantiate controllers for components
|
||||
([dd14e0c4](https://github.com/angular/angular.js/commit/dd14e0c44d2963d217cd4eb28f1ad6e6a643d63f),
|
||||
[#13683](https://github.com/angular/angular.js/issues/13683), [#13711](https://github.com/angular/angular.js/issues/13711))
|
||||
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- **$compileProvider**: due to [25bc5318](https://github.com/angular/angular.js/commit/25bc5318),
|
||||
- **$component**:
|
||||
*These breaking changes affect only applications updating from previous 1.5 beta / rc versions*
|
||||
|
||||
This release removes the ability to set the `restrict` option on directives created via the `module.component()` helper.
|
||||
All components are now element directives. If you need a directive that is not an element then you must use the
|
||||
- Due to [d91cf167](https://github.com/angular/angular.js/commit/d91cf167960d47ce38fec0d33cab6119268623f0),
|
||||
the default `controllerAs` value for components is now `$ctrl` (previously the name of the component was used).
|
||||
To migrate, either set `controllerAs` to the component name, or change the property name in your templates
|
||||
to `$ctrl`
|
||||
|
||||
- Due to [25bc5318](https://github.com/angular/angular.js/commit/25bc5318), it is no longer possible to
|
||||
set the `restrict` option on directives created via the `module.component()` helper.
|
||||
All components are now element directives (`restrict: 'E'`). If you need a directive that is not an element then you must use the
|
||||
`module.directive()` helper instead.
|
||||
|
||||
- Due to [f31c5a39](https://github.com/angular/angular.js/commit/f31c5a3924629795cd9169e69b9e20efd4a9d927),
|
||||
components are now always created with `scope: {}` (isolate scope). Previously, it was also possible to create components
|
||||
with `scope: true` or `scope: false`. If your components rely on this scope configuration, you will have to
|
||||
create a regular directive instead.
|
||||
|
||||
- Due to [6a47c0d7](https://github.com/angular/angular.js/commit/6a47c0d75d0c6f0bfb3b5492d1f05ec900387744),
|
||||
the `transclude` property is now `false` by default (previously `true`). If you created components that expected
|
||||
transclusion then you must change your code to specify `transclude: true`.
|
||||
|
||||
- **linky:** due to [98c2db7f](https://github.com/angular/angular.js/commit/98c2db7f9c2d078a408576e722407d518c7ee10a),
|
||||
|
||||
Before this change, the filter assumed that the input (if not undefined/null) was of type 'string'
|
||||
@@ -129,12 +376,6 @@ values through `linky`, you need to explicitly convert them to strings first.
|
||||
Since input values could be initialized asynchronously, `undefined` or `null` will still be
|
||||
returned unchanged (without throwing an error).
|
||||
|
||||
- **loader:** due to [6a47c0d7](https://github.com/angular/angular.js/commit/6a47c0d75d0c6f0bfb3b5492d1f05ec900387744),
|
||||
|
||||
Angular 1.5.0.beta.2 introduced the `module.component` helper where `transclude` was true by default.
|
||||
This changes the default for `transclude` to `false`. If you created components that expected
|
||||
transclusion then you must change your code to specify `transclude: true`.
|
||||
|
||||
|
||||
<a name="1.5.0-rc.0"></a>
|
||||
# 1.5.0-rc.0 oblong-panoptikum (2015-12-09)
|
||||
@@ -428,57 +669,24 @@ is `$locals`.
|
||||
- fix scoping of transclusion directives inside a replace directive
|
||||
([1a98c0ee](https://github.com/angular/angular.js/commit/1a98c0ee346b718b9462da1abf4352a4605cbc7f),
|
||||
[#12975](https://github.com/angular/angular.js/issues/12975), [#12936](https://github.com/angular/angular.js/issues/12936), [#13244](https://github.com/angular/angular.js/issues/13244))
|
||||
- use createMap() for $$observe listeners when initialized from attr interpolation
|
||||
([76c2491a](https://github.com/angular/angular.js/commit/76c2491a316d6b296c721227529fcb09087d369a),
|
||||
[#10446](https://github.com/angular/angular.js/issues/10446))
|
||||
- properly sanitize xlink:href attribute interpolation
|
||||
([f33ce173](https://github.com/angular/angular.js/commit/f33ce173c90736e349cf594df717ae3ee41e0f7a),
|
||||
[#12524](https://github.com/angular/angular.js/issues/12524))
|
||||
- **$http:** apply `transformResponse` even when `data` is empty
|
||||
([7c0731ed](https://github.com/angular/angular.js/commit/7c0731edb2f72bdf0efa186f641dab3b6aecc5d5),
|
||||
[#12976](https://github.com/angular/angular.js/issues/12976), [#12979](https://github.com/angular/angular.js/issues/12979))
|
||||
- **$location:** ensure `$locationChangeSuccess` fires even if URL ends with `#`
|
||||
([4412fe23](https://github.com/angular/angular.js/commit/4412fe238f37f79a2017ee7b20ba089c0acd73e9),
|
||||
[#12175](https://github.com/angular/angular.js/issues/12175), [#13251](https://github.com/angular/angular.js/issues/13251))
|
||||
- **$parse:**
|
||||
- evaluate simple expressions in interpolations only once
|
||||
- **$parse:** evaluate simple expressions in interpolations only once
|
||||
([1caf0b6b](https://github.com/angular/angular.js/commit/1caf0b6bee5781589e20f7a27a8c60e8b1b784f5),
|
||||
[#12983](https://github.com/angular/angular.js/issues/12983), [#13002](https://github.com/angular/angular.js/issues/13002))
|
||||
- fix typo in error message ("assing" -> "assign")
|
||||
([70dac5ae](https://github.com/angular/angular.js/commit/70dac5ae82ffe9c6250681274905583747523b5d),
|
||||
[#12940](https://github.com/angular/angular.js/issues/12940))
|
||||
- block assigning to fields of a constructor
|
||||
([e1f4f23f](https://github.com/angular/angular.js/commit/e1f4f23f781a79ae8a4046b21130283cec3f2917),
|
||||
[#12860](https://github.com/angular/angular.js/issues/12860))
|
||||
- safer conversion of computed properties to strings
|
||||
([20cf7d5e](https://github.com/angular/angular.js/commit/20cf7d5e3a0af766b1929e24794859c79439351c))
|
||||
- **$resource:** allow XHR request to be cancelled via a timeout promise
|
||||
([4fc73466](https://github.com/angular/angular.js/commit/4fc734665e5dddef26ed30a9d4f75632cd269481),
|
||||
[#12657](https://github.com/angular/angular.js/issues/12657), [#12675](https://github.com/angular/angular.js/issues/12675), [#10890](https://github.com/angular/angular.js/issues/10890), [#9332](https://github.com/angular/angular.js/issues/9332))
|
||||
- **$rootScope:** prevent IE9 memory leak when destroying scopes
|
||||
([8fe781fb](https://github.com/angular/angular.js/commit/8fe781fbe7c42c64eb895c28d9fd5479b037d020),
|
||||
[#10706](https://github.com/angular/angular.js/issues/10706), [#11786](https://github.com/angular/angular.js/issues/11786))
|
||||
- **$sanitize:**
|
||||
- strip urls starting with 'unsafe:' as opposed to 'unsafe'
|
||||
([a4dfa4d0](https://github.com/angular/angular.js/commit/a4dfa4d061fd2f6baf9821f0863dcce7888232ab),
|
||||
[#12524](https://github.com/angular/angular.js/issues/12524))
|
||||
- add mXSS protection
|
||||
([bc0d8c4e](https://github.com/angular/angular.js/commit/bc0d8c4eea9a34bff5e29dd492dcdd668251be40),
|
||||
[#12524](https://github.com/angular/angular.js/issues/12524))
|
||||
- support void elements, fixups, remove dead code, typos
|
||||
([94207f8f](https://github.com/angular/angular.js/commit/94207f8fb6ee8fe26fe18657f6b5aca6def99605),
|
||||
[#12524](https://github.com/angular/angular.js/issues/12524))
|
||||
- **Angular.js:** fix `isArrayLike` for unusual cases
|
||||
([2c8d87e0](https://github.com/angular/angular.js/commit/2c8d87e064dca99a49ed35d1db885b1f2e40dcf4),
|
||||
[#10186](https://github.com/angular/angular.js/issues/10186), [#8000](https://github.com/angular/angular.js/issues/8000), [#4855](https://github.com/angular/angular.js/issues/4855), [#4751](https://github.com/angular/angular.js/issues/4751), [#10272](https://github.com/angular/angular.js/issues/10272))
|
||||
- **filters:** ensure `formatNumber` observes i18n decimal separators
|
||||
([658a865c](https://github.com/angular/angular.js/commit/658a865c5b2580eed53b340e7394945cd76e2260),
|
||||
[#10342](https://github.com/angular/angular.js/issues/10342), [#12850](https://github.com/angular/angular.js/issues/12850))
|
||||
- **injector:** support arrow functions with no parentheses
|
||||
([03726f7f](https://github.com/angular/angular.js/commit/03726f7fbd5d71c0604b8dd40e97cb2fb0fb777f),
|
||||
[#12890](https://github.com/angular/angular.js/issues/12890))
|
||||
- **input:** remove workaround for Firefox bug
|
||||
([b366f035](https://github.com/angular/angular.js/commit/b366f0352abccfe4c4868b5a9e8c0b88659bd1ee))
|
||||
- **isArrayLike:** handle jQuery objects of length 0
|
||||
([773efd08](https://github.com/angular/angular.js/commit/773efd0812097a89944c889c595485a5744326f6))
|
||||
- **jqLite:**
|
||||
@@ -497,12 +705,6 @@ is `$locals`.
|
||||
- clone elements instead of treating them like simple objects
|
||||
([17715fa3](https://github.com/angular/angular.js/commit/17715fa3668b1fcabaedcd82e2e57b2a80e0a0c2),
|
||||
[#12286](https://github.com/angular/angular.js/issues/12286))
|
||||
- **ngAnimate:**
|
||||
- ensure anchoring uses body as a container when needed
|
||||
([240d5896](https://github.com/angular/angular.js/commit/240d5896ecdfac2351f9bd6147b52de52c0b7608),
|
||||
[#12872](https://github.com/angular/angular.js/issues/12872))
|
||||
- callback detection should only use RAF when necessary
|
||||
([8b27c3f0](https://github.com/angular/angular.js/commit/8b27c3f064b34532ba99d709cadf09fc4c0cbeab))
|
||||
- **ngAria:** don't add tabindex to radio and checkbox inputs
|
||||
([662fb282](https://github.com/angular/angular.js/commit/662fb282c176ca00a85b6dec7af90446ea90f662),
|
||||
[#12492](https://github.com/angular/angular.js/issues/12492), [#13095](https://github.com/angular/angular.js/issues/13095))
|
||||
@@ -512,9 +714,6 @@ is `$locals`.
|
||||
- **ngMessage:** make ngMessage compatible with ngBind
|
||||
([4971ef12](https://github.com/angular/angular.js/commit/4971ef12d4c2c268cb8d26f90385dc96eba19db8),
|
||||
[#8089](https://github.com/angular/angular.js/issues/8089), [#13074](https://github.com/angular/angular.js/issues/13074))
|
||||
- **ngMessages:** prevent race condition with ngAnimate
|
||||
([8366622b](https://github.com/angular/angular.js/commit/8366622bed009d2cad7d0cff28b9c1e48bfbd4e1),
|
||||
[#12856](https://github.com/angular/angular.js/issues/12856), [#12903](https://github.com/angular/angular.js/issues/12903))
|
||||
- **ngMock:** reset cache before every test
|
||||
([fd83d372](https://github.com/angular/angular.js/commit/fd83d3724ad30a93254f08cb82f981eaddb5dbff),
|
||||
[#13013](https://github.com/angular/angular.js/issues/13013))
|
||||
@@ -525,18 +724,6 @@ is `$locals`.
|
||||
- override select option registration to allow compilation of empty option
|
||||
([2fcfd75a](https://github.com/angular/angular.js/commit/2fcfd75a142200e1a4b1b7ed4fb588e3befcbd57),
|
||||
[#11685](https://github.com/angular/angular.js/issues/11685), [#12972](https://github.com/angular/angular.js/issues/12972), [#12968](https://github.com/angular/angular.js/issues/12968), [#13012](https://github.com/angular/angular.js/issues/13012))
|
||||
- prevent frozen select ui in IE
|
||||
([42c97c5d](https://github.com/angular/angular.js/commit/42c97c5db5921e9e5447fb32bdae1f48da42844f),
|
||||
[#11314](https://github.com/angular/angular.js/issues/11314), [#11795](https://github.com/angular/angular.js/issues/11795))
|
||||
- allow falsy values as option group identifiers
|
||||
([b71d7c3f](https://github.com/angular/angular.js/commit/b71d7c3f3c04e65b02d88b33c22dd90ae3cdfc27),
|
||||
[#7015](https://github.com/angular/angular.js/issues/7015), [#7024](https://github.com/angular/angular.js/issues/7024), [#12888](https://github.com/angular/angular.js/issues/12888))
|
||||
- throw if ngModel is not present
|
||||
([ded25187](https://github.com/angular/angular.js/commit/ded2518756d4409fdfda0d4af243f2125bea01b5),
|
||||
[#7047](https://github.com/angular/angular.js/issues/7047), [#12840](https://github.com/angular/angular.js/issues/12840))
|
||||
- **ngResource:** encode `&` in URL query param values
|
||||
([1c97a605](https://github.com/angular/angular.js/commit/1c97a6057bc013262be761bca5e5c22224c4bbf8),
|
||||
[#12201](https://github.com/angular/angular.js/issues/12201))
|
||||
- **orderByFilter:** throw error if input is not array-like
|
||||
([2a85a634](https://github.com/angular/angular.js/commit/2a85a634f86c84f15b411ce009a3515fca7ba580),
|
||||
[#11255](https://github.com/angular/angular.js/issues/11255), [#11719](https://github.com/angular/angular.js/issues/11719))
|
||||
@@ -544,24 +731,11 @@ is `$locals`.
|
||||
|
||||
## Features
|
||||
|
||||
- **$animateCss:** add support for temporary styles via `cleanupStyles`
|
||||
([9f67da62](https://github.com/angular/angular.js/commit/9f67da625293441e27559ebde7503cc63408a95c),
|
||||
[#12930](https://github.com/angular/angular.js/issues/12930))
|
||||
- **$compile:** multiple transclusion via named slots
|
||||
([a4ada8ba](https://github.com/angular/angular.js/commit/a4ada8ba9c4358273575e16778e76446ad080054),
|
||||
[#4357](https://github.com/angular/angular.js/issues/4357), [#12742](https://github.com/angular/angular.js/issues/12742), [#11736](https://github.com/angular/angular.js/issues/11736), [#12934](https://github.com/angular/angular.js/issues/12934))
|
||||
- **$http:** add `$xhrFactory` service to enable creation of custom xhr objects
|
||||
([106f90aa](https://github.com/angular/angular.js/commit/106f90aafa0fa5a81ad7af7ffc9d1e00ab97ffef),
|
||||
[#2318](https://github.com/angular/angular.js/issues/2318), [#9319](https://github.com/angular/angular.js/issues/9319), [#12159](https://github.com/angular/angular.js/issues/12159))
|
||||
- **$injector:**
|
||||
- Allow specifying a decorator on $injector
|
||||
- **$injector:** allow specifying a decorator on $injector
|
||||
([29a05984](https://github.com/angular/angular.js/commit/29a05984fe46c2c18ca51404f07c866dd92d1eec))
|
||||
- add strictDi property to $injector instance
|
||||
([79577c5d](https://github.com/angular/angular.js/commit/79577c5d316c7bf0204d7d1747ddc5b15bfe2955),
|
||||
[#11728](https://github.com/angular/angular.js/issues/11728), [#11734](https://github.com/angular/angular.js/issues/11734))
|
||||
- **$sanitize:** make svg support an opt-in
|
||||
([181fc567](https://github.com/angular/angular.js/commit/181fc567d873df065f1e84af7225deb70a8d2eb9),
|
||||
[#12524](https://github.com/angular/angular.js/issues/12524))
|
||||
- **$templateRequest:** support configuration of $http options
|
||||
([b2fc39d2](https://github.com/angular/angular.js/commit/b2fc39d2ddac64249b4f2961ee18b878a1e98251),
|
||||
[#13188](https://github.com/angular/angular.js/issues/13188), [#11868](https://github.com/angular/angular.js/issues/11868), [#6860](https://github.com/angular/angular.js/issues/6860))
|
||||
@@ -580,18 +754,12 @@ is `$locals`.
|
||||
- invoke nested calls to `module()` immediately
|
||||
([51a27c0f](https://github.com/angular/angular.js/commit/51a27c0f1ad6cd8d3e33ab0d71de22c1627c7ec3),
|
||||
[#12887](https://github.com/angular/angular.js/issues/12887))
|
||||
- **ngModel:** provide ng-empty and ng-not-empty CSS classes
|
||||
([630280c7](https://github.com/angular/angular.js/commit/630280c7fb04a83208d09c97c2efb81be3a3db74),
|
||||
[#10050](https://github.com/angular/angular.js/issues/10050), [#12848](https://github.com/angular/angular.js/issues/12848))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
|
||||
- **$compile:**
|
||||
- use static jquery data method to avoid creating new instances
|
||||
- **$compile:** use static jquery data method to avoid creating new instances
|
||||
([9b90c32f](https://github.com/angular/angular.js/commit/9b90c32f31fd56e348539674128acec6536cd846))
|
||||
- lazily compile the `transclude` function
|
||||
([652b83eb](https://github.com/angular/angular.js/commit/652b83eb226131d131a44453520a569202aa4aac))
|
||||
- **$interpolate:** provide a simplified result for constant expressions
|
||||
([cf83b4f4](https://github.com/angular/angular.js/commit/cf83b4f445d3a1fc18fc140e65e670754401d50b))
|
||||
- **copy:**
|
||||
@@ -607,13 +775,6 @@ is `$locals`.
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- **$sanitize:** due to [181fc567](https://github.com/angular/angular.js/commit/181fc567d873df065f1e84af7225deb70a8d2eb9),
|
||||
The svg support in is now an opt-in option
|
||||
|
||||
Applications that depend on this option can use to turn the option back on,
|
||||
but while doing so, please read the warning provided in the documentation for
|
||||
information on preventing click-hijacking attacks when this option is turned on.
|
||||
|
||||
- **ngMessage:** due to [4971ef12](https://github.com/angular/angular.js/commit/4971ef12d4c2c268cb8d26f90385dc96eba19db8),
|
||||
|
||||
ngMessage is now compiled with a priority of 1, which means directives
|
||||
@@ -624,14 +785,6 @@ passed the comment element created by the transclusion of ngMessage.
|
||||
To restore this behavior, custom directives need to have
|
||||
their priority increased to at least "1".
|
||||
|
||||
- **ngOptions:** due to [ded25187](https://github.com/angular/angular.js/commit/ded2518756d4409fdfda0d4af243f2125bea01b5),
|
||||
|
||||
`ngOptions` will now throw if `ngModel` is not present on the `select`
|
||||
element. Previously, having no `ngModel` let `ngOptions` silently
|
||||
fail, which could lead to hard to debug errors. The change should
|
||||
therefore not affect any applications, as it simply makes the
|
||||
requirement more strict and alerts the developer explicitly.
|
||||
|
||||
- **orderByFilter:** due to [2a85a634](https://github.com/angular/angular.js/commit/2a85a634f86c84f15b411ce009a3515fca7ba580),
|
||||
|
||||
Previously, an non array-like input would pass through the orderBy filter unchanged.
|
||||
@@ -641,9 +794,6 @@ https://github.com/petebacondarwin/angular-toArrayFilter.
|
||||
(`null` and `undefined` still pass through without an error, in order to
|
||||
support asynchronous loading of resources.)
|
||||
|
||||
Closes #11255
|
||||
Closes #11719
|
||||
|
||||
|
||||
|
||||
<a name="1.5.0-beta.1"></a>
|
||||
|
||||
@@ -8,20 +8,20 @@
|
||||
Large table rendered with AngularJS
|
||||
</p>
|
||||
|
||||
<div>none: <input type="radio" ng-model="benchmarkType" value="none"></div>
|
||||
<div>baseline binding: <input type="radio" ng-model="benchmarkType" value="baselineBinding"></div>
|
||||
<div>baseline interpolation: <input type="radio" ng-model="benchmarkType" value="baselineInterpolation"></div>
|
||||
<div>ngBind: <input type="radio" ng-model="benchmarkType" value="ngBind"></div>
|
||||
<div>ngBindOnce: <input type="radio" ng-model="benchmarkType" value="ngBindOnce"></div>
|
||||
<div>interpolation: <input type="radio" ng-model="benchmarkType" value="interpolation"></div>
|
||||
<div>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>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="none">none: </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="baselineBinding">baseline binding: </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="baselineInterpolation">baseline interpolation: </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="ngBind">ngBind: </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="ngBindOnce">ngBindOnce: </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="interpolation">interpolation: </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="bindOnceInterpolation">interpolation + bind-once: </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="interpolationAttr">attribute interpolation: </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="ngBindFn">ngBind + fnInvocation: </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="interpolationFn">interpolation + fnInvocation: </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="ngBindFilter">ngBind + filter: </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="interpolationFilter">interpolation + filter: </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="ngModelConstName">ngModel (const name): </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="ngModelInterpName">ngModel (interp name): </label></div>
|
||||
|
||||
<ng-switch on="benchmarkType">
|
||||
<baseline-binding-table ng-switch-when="baselineBinding">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"name": "AngularJS",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"jquery": "2.1.1",
|
||||
"closure-compiler": "https://dl.google.com/closure-compiler/compiler-20140814.zip",
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
This error occurs when a module fails to load due to some exception. The error
|
||||
message above should provide additional context.
|
||||
|
||||
A common reason why the module fails to load is that you've forgotten to
|
||||
include the file with the defined module or that the file couldn't be loaded.
|
||||
|
||||
### Using `ngRoute`
|
||||
|
||||
In AngularJS `1.2.0` and later, `ngRoute` has been moved to its own module.
|
||||
@@ -24,4 +27,4 @@ angular.module('ng').filter('tel', function (){});
|
||||
|
||||
Instead create your own module and add it as a dependency to your application's top-level module.
|
||||
See [#9692](https://github.com/angular/angular.js/issues/9692) and
|
||||
[#7709](https://github.com/angular/angular.js/issues/7709) for more information
|
||||
[#7709](https://github.com/angular/angular.js/issues/7709) for more information
|
||||
|
||||
@@ -81,3 +81,6 @@ angular.module('myModule', [])
|
||||
// a scope object cannot be injected into a service.
|
||||
}]);
|
||||
```
|
||||
|
||||
If you encounter this error only with minified code, consider using `ngStrictDi` (see
|
||||
{@link ng.directive:ngApp ngApp}) to provoke the error with the non-minified source.
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
@ngdoc error
|
||||
@name ngModel:nopromise
|
||||
@fullName No promise
|
||||
@description
|
||||
|
||||
The return value of an async validator, must always be a promise. If you want to return a
|
||||
non-promise value, you can convert it to a promise using {@link ng.$q#resolve `$q.resolve()`} or
|
||||
{@link ng.$q#reject `$q.reject()`}.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
.directive('asyncValidator', function($q) {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
link: function(scope, elem, attrs, ngModel) {
|
||||
ngModel.$asyncValidators.myAsyncValidation = function(modelValue, viewValue) {
|
||||
if (/* I don't need to hit the backend API */) {
|
||||
return $q.resolve(); // to mark as valid or
|
||||
// return $q.reject(); // to mark as invalid
|
||||
} else {
|
||||
// ...send a request to the backend and return a promise
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
})
|
||||
```
|
||||
@@ -99,8 +99,13 @@ For example, the following forms are all equivalent and match the {@link ngBind}
|
||||
</file>
|
||||
<file name="protractor.js" type="protractor">
|
||||
it('should show off bindings', function() {
|
||||
expect(element(by.css('div[ng-controller="Controller"] span[ng-bind]')).getText())
|
||||
.toBe('Max Karl Ernst Ludwig Planck (April 23, 1858 – October 4, 1947)');
|
||||
var containerElm = element(by.css('div[ng-controller="Controller"]'));
|
||||
var nameBindings = containerElm.all(by.binding('name'));
|
||||
|
||||
expect(nameBindings.count()).toBe(5);
|
||||
nameBindings.each(function(elem) {
|
||||
expect(elem.getText()).toEqual('Max Karl Ernst Ludwig Planck (April 23, 1858 – October 4, 1947)');
|
||||
});
|
||||
});
|
||||
</file>
|
||||
</example>
|
||||
@@ -401,7 +406,7 @@ This is clearly not a great solution.
|
||||
|
||||
What we want to be able to do is separate the scope inside a directive from the scope
|
||||
outside, and then map the outer scope to a directive's inner scope. We can do this by creating what
|
||||
we call an **isolate scope**. To do this, we can use a directive's `scope` option:
|
||||
we call an **isolate scope**. To do this, we can use a {@link $compile#-scope- directive's `scope`} option:
|
||||
|
||||
<example module="docsIsolateScopeDirective">
|
||||
<file name="script.js">
|
||||
|
||||
@@ -32,10 +32,13 @@ E.g. the markup `{{ 1234 | number:2 }}` formats the number 1234 with 2 decimal p
|
||||
|
||||
## Using filters in controllers, services, and directives
|
||||
|
||||
You can also use filters in controllers, services, and directives. For this, inject a dependency
|
||||
with the name `<filterName>Filter` to your controller/service/directive. E.g. using the dependency
|
||||
`numberFilter` will inject the number filter. The injected argument is a function that takes the
|
||||
value to format as first argument and filter parameters starting with the second argument.
|
||||
You can also use filters in controllers, services, and directives.
|
||||
|
||||
<div class="alert alert-info">
|
||||
For this, inject a dependency with the name `<filterName>Filter` into your controller/service/directive.
|
||||
E.g. a filter called `number` is injected by using the dependency `numberFilter`. The injected argument
|
||||
is a function that takes the value to format as first argument, and filter parameters starting with the second argument.
|
||||
</div>
|
||||
|
||||
The example below uses the filter called {@link ng.filter:filter `filter`}.
|
||||
This filter reduces arrays into sub arrays based on
|
||||
@@ -108,6 +111,7 @@ text upper-case.
|
||||
No filter: {{greeting}}<br>
|
||||
Reverse: {{greeting|reverse}}<br>
|
||||
Reverse + uppercase: {{greeting|reverse:true}}<br>
|
||||
Reverse, filtered in controller: {{filteredGreeting}}<br>
|
||||
</div>
|
||||
</file>
|
||||
|
||||
@@ -127,8 +131,9 @@ text upper-case.
|
||||
return out;
|
||||
};
|
||||
})
|
||||
.controller('MyController', ['$scope', function($scope) {
|
||||
.controller('MyController', ['$scope', 'reverseFilter', function($scope, reverseFilter) {
|
||||
$scope.greeting = 'hello';
|
||||
$scope.filteredGreeting = reverseFilter($scope.greeting);
|
||||
}]);
|
||||
</file>
|
||||
</example>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
# Interpolation and data-binding
|
||||
|
||||
Interpolation markup with embedded @link {guide/expressions expressions} is used by Angular to
|
||||
Interpolation markup with embedded {@link guide/expression expressions} is used by Angular to
|
||||
provide data-binding to text nodes and attribute values.
|
||||
|
||||
An example of interpolation is shown below:
|
||||
@@ -43,8 +43,8 @@ interpret the attribute as present, meaning that the button would always be disa
|
||||
```
|
||||
|
||||
For this reason, Angular provides special `ng`-prefixed directives for the following boolean attributes:
|
||||
{@link ngDisabled `disabled`}, [@link ngRequired `required`}, [@link ngSelected `selected`},
|
||||
{@link ngChecked `checked`}, {@link ngReadonly `readOnly`} , and [@link ngOpen `open`}.
|
||||
{@link ngDisabled `disabled`}, {@link ngRequired `required`}, {@link ngSelected `selected`},
|
||||
{@link ngChecked `checked`}, {@link ngReadonly `readOnly`} , and {@link ngOpen `open`}.
|
||||
|
||||
These directives take an expression inside the attribute, and set the corresponding boolean attribute
|
||||
to true when the expression evaluates to truthy.
|
||||
|
||||
@@ -13,6 +13,156 @@ 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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Migrate from 1.4 to 1.5
|
||||
|
||||
Angular 1.5 takes a big step towards preparing developers for a smoother transition to Angular 2 in
|
||||
the future. Architecturing your applications using components, making use of lifecycle hooks in
|
||||
directive controllers and relying on native ES6 features (such as classes and arrow functions) are
|
||||
now all possible with Angular 1.5.
|
||||
|
||||
|
||||
This release includes numerous bug and security fixes, as well as performance improvements to core
|
||||
services, directives, filters and helper functions. Existing applications can start enjoying the
|
||||
benefits of such changes in `$compile`, `$parse`, `$animate`, `$animateCss`, `$sanitize`, `ngOptions`,
|
||||
`currencyFilter`, `numberFilter`, `copy()` (to name but a few) without any change in code.
|
||||
|
||||
New features have been added to more than a dozen services, directives and filters across 7 modules.
|
||||
Among them, a few stand out:
|
||||
|
||||
* `angular.component()`: Introducing "components", a special sort of directive that are easy to
|
||||
configure and promote best practices (plus can bring Angular 1 applications closer to Angular 2's
|
||||
style of architecture).
|
||||
* Multi-slot transclusion: Enabling the design of more powerful and complex UI elements with a much
|
||||
simpler configuration and reduced boilerplate.
|
||||
* `ngAnimateSwap`: A new directive in `ngAnimate`, making it super easy to create rotating
|
||||
banner-like components
|
||||
* Testing helpers: New helper functions in `ngMock`, simplifying testing for animations, component
|
||||
controllers and routing.
|
||||
|
||||
Also, notable is the improved support for ES6 features, such as classes and arrow functions. These
|
||||
features are now more reliably detected and correctly handled within the core.
|
||||
|
||||
|
||||
All this goodness doesn't come without a price, though. Below is a list of breaking changes (grouped
|
||||
by module) that need to be taken into account while migrating from 1.4. Fortunately, the majority of
|
||||
them should have a pretty low impact on most applications.
|
||||
|
||||
|
||||
## Core
|
||||
|
||||
We tried to keep the breaking changes inside the core components to a bare minimum. Still, a few of
|
||||
them were unavoidable.
|
||||
|
||||
### Services (`$parse`)
|
||||
|
||||
Due to [0ea53503](https://github.com/angular/angular.js/commit/0ea535035a3a1a992948490c3533bffb83235052),
|
||||
a new special property, `$locals`, will be available for accessing the locals from an expression.
|
||||
This is a breaking change, only if a `$locals` property does already exist (and needs to be
|
||||
referenced) either on the `scope` or on the `locals` object. Your expressions should be changed to
|
||||
access such existing properties as `this.$locals` and `$locals.$locals` respectively.
|
||||
|
||||
|
||||
### Directives (`ngOptions`)
|
||||
|
||||
A fair amount of work has been put into the `ngOptions` directive, fixing bugs and corner-cases and
|
||||
neutralizing browser quirks. A couple of breaking changes were made in the process:
|
||||
|
||||
Due to [b71d7c3f](https://github.com/angular/angular.js/commit/b71d7c3f3c04e65b02d88b33c22dd90ae3cdfc27),
|
||||
falsy values (`''`, `0`, `false` and `null`) are properly recognized as option group identifiers for
|
||||
options passed to `ngOptions`. Previously, all of these values were ignored and the option was not
|
||||
assigned to any group. `undefined` is still interpreted as "no group".
|
||||
If you have options with falsy group indentifiers that should still not be assigned to any group,
|
||||
then you must filter the values before passing them to `ngOptions`, converting falsy values to
|
||||
`undefined`.
|
||||
|
||||
Due to [ded25187](https://github.com/angular/angular.js/commit/ded2518756d4409fdfda0d4af243f2125bea01b5),
|
||||
`ngOptions` now explicitly requires `ngModel` on the same element, thus an error will be thrown if
|
||||
`ngModel` is not found. Previously, `ngOptions` would silently fail, which could lead to
|
||||
hard-to-debug errors.
|
||||
This is not expected to have any significant impact on applications, since `ngOptions` didn't work
|
||||
without `ngModel` before either. The main difference is that now it will fail with a more
|
||||
informative error message.
|
||||
|
||||
|
||||
### Filters (`orderBy`)
|
||||
|
||||
Due to [2a85a634](https://github.com/angular/angular.js/commit/2a85a634f86c84f15b411ce009a3515fca7ba580),
|
||||
passing a non-array-like value (other than `undefined` or `null`) through the `orderBy` filter will
|
||||
throw an error. Previously, the input was returned unchanged, which could lead to hard-to-spot bugs
|
||||
and was not consistent with other filters (e.g. `filter`).
|
||||
Objects considered array-like include: arrays, array subclasses, strings, NodeLists,
|
||||
jqLite/jQuery collections
|
||||
|
||||
|
||||
## ngMessages (`ngMessage`)
|
||||
|
||||
Due to [4971ef12](https://github.com/angular/angular.js/commit/4971ef12d4c2c268cb8d26f90385dc96eba19db8),
|
||||
the `ngMessage` directive is now compiled with a priority of 1, which means directives on the same
|
||||
element as `ngMessage` with a priority lower than 1 will be applied when `ngMessage` calls its
|
||||
`$transclude` function. Previously, they were applied during the initial compile phase and were
|
||||
passed the comment element created by the transclusion of `ngMessage`.
|
||||
If you have custom directives that relied on the previous behavior, you need to give them a priority
|
||||
of 1 or greater.
|
||||
|
||||
|
||||
## ngResource (`$resource`)
|
||||
|
||||
The `$resource` service underwent a minor internal refactoring to finally solve a long-standing bug
|
||||
preventing requests from being cancelled using promises. Due to the nature of `$resource`'s
|
||||
configuration, it was not possible to follow the `$http` convention. A new `$cancelRequest()` method
|
||||
was introduced instead.
|
||||
|
||||
Due to [98528be3](https://github.com/angular/angular.js/commit/98528be311b48269ba0e15ba4e3e2ad9b89693a9),
|
||||
using a promise as `timeout` in `$resource` is no longer supported and will log a warning. This is
|
||||
hardly expected to affect the behavior of your application, since a promise as `timeout` didn't work
|
||||
before either, but it will now warn you explicitly when trying to pass one.
|
||||
If you need to be able to cancel pending requests, you can now use the new `$cancelRequest()` that
|
||||
will be available on `$resource` instances.
|
||||
|
||||
|
||||
## ngRoute (`ngView`)
|
||||
|
||||
Due to [983b0598](https://github.com/angular/angular.js/commit/983b0598121a8c5a3a51a30120e114d7e3085d4d),
|
||||
a new property will be available on the scope of the route, allowing easy access to the route's
|
||||
resolved values from the view's template. The default name for this property is `$resolve`. This is
|
||||
a breaking change, only if a `$resolve` property is already available on the scope, in which case
|
||||
the existing property will be hidden or overwritten.
|
||||
To fix this, you should choose a custom name for this property, that does not collide with other
|
||||
properties on the scope, by specifying the `resolveAs` property on the route.
|
||||
|
||||
|
||||
## ngSanitize (`$sanitize`, `linky`)
|
||||
|
||||
The HTML sanitizer has been re-implemented using inert documents, increasing security, fixing some
|
||||
corner-cases that were difficult to handle and reducing its size by about 20% (in terms of loc). In
|
||||
order to make it more secure by default, a couple of breaking changes have been introduced:
|
||||
|
||||
Due to [181fc567](https://github.com/angular/angular.js/commit/181fc567d873df065f1e84af7225deb70a8d2eb9),
|
||||
SVG support in `$sanitize` is now an opt-in feature (i.e. disabled by default), as it could make
|
||||
an application vulnerable to click-hijacking attacks. If your application relies on it, you can
|
||||
still turn it on with `$sanitizeProvider.enableSvg(true)`, but you extra precautions need to be
|
||||
taken in order to keep your application secure. Read the documentation for more information about
|
||||
the dangers and ways to mitigate them.
|
||||
|
||||
Due to [7a668cdd](https://github.com/angular/angular.js/commit/7a668cdd7d08a7016883eb3c671cbcd586223ae8),
|
||||
the `$sanitize` service will now remove instances of the `<use>` tag from the content passed to it.
|
||||
This element is used to import external SVG resources, which is a security risk as the `$sanitize`
|
||||
service does not have access to the resource in order to sanitize it.
|
||||
|
||||
Due to [98c2db7f](https://github.com/angular/angular.js/commit/98c2db7f9c2d078a408576e722407d518c7ee10a),
|
||||
passing a non-string value (other than `undefined` or `null`) through the `linky` filter will throw
|
||||
an error. This is not expected to have any significant impact on applications, since the input was
|
||||
always assumed to be of type 'string', so passing non-string values never worked correctly anyway.
|
||||
The main difference is that now it will fail faster and with a more informative error message.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Migrating from 1.3 to 1.4
|
||||
|
||||
Angular 1.4 fixes major animation issues and introduces a new API for `ngCookies`. Further, there
|
||||
|
||||
@@ -75,9 +75,8 @@ that you break your application to multiple modules like this:
|
||||
* And an application level module which depends on the above modules and contains any
|
||||
initialization code.
|
||||
|
||||
We've also
|
||||
[written a document](http://angularjs.blogspot.com/2014/02/an-angularjs-style-guide-and-best.html)
|
||||
on how we organize large apps at Google.
|
||||
You can find a community
|
||||
[style guide](https://github.com/johnpapa/angular-styleguide) to help yourself when application grows.
|
||||
|
||||
The above is a suggestion. Tailor it to your needs.
|
||||
|
||||
|
||||
@@ -246,6 +246,15 @@ npm run update-webdriver
|
||||
|
||||
*(You should only need to do this once.)*
|
||||
|
||||
You will need to have Java present on your dev machine to allow the Selenium standalone to be started.
|
||||
Check if you already have java installed by opening a terminal/command line window and typing
|
||||
'''
|
||||
java -version
|
||||
'''
|
||||
If java is already installed and exists in the PATH then you will be shown the version installed,
|
||||
if, however you receive a message that "java is not recognized as an internal command or external
|
||||
command" you will need to install [java].
|
||||
|
||||
Since Protractor works by interacting with a running application, we need to start our web server:
|
||||
|
||||
```
|
||||
@@ -280,3 +289,4 @@ Now that you have set up your local machine, let's get started with the tutorial
|
||||
[bower]: http://bower.io/
|
||||
[http-server]: https://github.com/nodeapps/http-server
|
||||
[karma]: https://github.com/karma-runner/karma
|
||||
[java]: https://www.java.com/en/download/help/download_options.xml
|
||||
|
||||
@@ -43,7 +43,7 @@ __`app/index.html`:__
|
||||
...
|
||||
<ul class="phones">
|
||||
<li ng-repeat="phone in phones | filter:query | orderBy:orderProp" class="thumbnail">
|
||||
<a href="#/phones/{{phone.id}}" class="thumb"><img ng-src="{{phone.imageUrl}}"></a>
|
||||
<a href="#/phones/{{phone.id}}" class="thumb"><img ng-src="{{phone.imageUrl}}" alt="{{phone.name}}"></a>
|
||||
<a href="#/phones/{{phone.id}}">{{phone.name}}</a>
|
||||
<p>{{phone.snippet}}</p>
|
||||
</li>
|
||||
|
||||
@@ -53,6 +53,18 @@ preconfigured npm to run bower install for us:
|
||||
npm install
|
||||
```
|
||||
|
||||
<div class="alert alert-warning">
|
||||
**Warning:** If a new version of Angular has been released since you last ran `npm install`, then you may have a
|
||||
problem with the `bower install` due to a conflict between the versions of angular.js that need to
|
||||
be installed. If you get this then simply delete your `app/bower_components` folder before running
|
||||
`npm install`.
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info">
|
||||
**Note:** If you have bower installed globally then you can run `bower install` but for this project we have
|
||||
preconfigured `npm install` to run bower for us.
|
||||
</div>
|
||||
|
||||
|
||||
## Multiple Views, Routing and Layout Template
|
||||
|
||||
|
||||
@@ -239,7 +239,7 @@ The name of the starting class is the name of the event that is fired (like `ent
|
||||
The active class name is the same as the starting class's but with an `-active` suffix.
|
||||
This two-class CSS naming convention allows the developer to craft an animation, beginning to end.
|
||||
|
||||
In our example above, elements are expanded from a height of **0** to **120 pixels** when they're added to the
|
||||
In our example above, elements are expanded from a height of **0** to **120 pixels** when they're added to the
|
||||
list and are collapsed back down to **0 pixels** before being removed from the list.
|
||||
There's also a nice fade-in and fade-out effect that occurs at the same time. All of this is handled
|
||||
by the CSS transition declarations at the top of the example code above.
|
||||
@@ -357,10 +357,10 @@ For more on CSS animations, see the
|
||||
## Animating `ngClass` with JavaScript
|
||||
|
||||
Let's add another animation to our application. Switching to our `phone-detail.html` page,
|
||||
we see that we have a nice thumbnail swapper. By clicking on the thumbnails listed on the page,
|
||||
we see that we have a nice thumbnail swapper. By hovering over the thumbnails listed on the page,
|
||||
the profile phone image changes. But how can we change this around to add animations?
|
||||
|
||||
Let's think about it first. Basically, when you click on a thumbnail image, you're changing the
|
||||
Let's think about it first. Basically, when you hover over a thumbnail image, you're changing the
|
||||
state of the profile image to reflect the newly selected thumbnail image.
|
||||
The best way to specify state changes within HTML is to use classes.
|
||||
Much like before, how we used a CSS class to specify an animation, this time the animation will
|
||||
@@ -369,7 +369,7 @@ occur whenever the CSS class itself changes.
|
||||
Whenever a new phone thumbnail is selected, the state changes and the `.active` CSS class is added
|
||||
to the matching profile image and the animation plays.
|
||||
|
||||
Let's get started and tweak our HTML code on the `phone-detail.html` page first. Notice that we
|
||||
Let's get started and tweak our HTML code on the `phone-detail.html` page first. Notice that we
|
||||
have changed the way we display our large image:
|
||||
|
||||
__`app/partials/phone-detail.html`.__
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ set -e
|
||||
BASE_DIR=`dirname $0`
|
||||
cd $BASE_DIR
|
||||
|
||||
./run-tests.sh
|
||||
npm run test-i18n
|
||||
|
||||
node src/closureSlurper.js
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
PARENT_DIR="$(dirname "$0")"
|
||||
|
||||
../node_modules/.bin/jasmine-node "$PARENT_DIR"/spec/
|
||||
@@ -4,6 +4,7 @@ findLocaleId = closureI18nExtractor.findLocaleId;
|
||||
extractNumberSymbols = closureI18nExtractor.extractNumberSymbols;
|
||||
extractCurrencySymbols = closureI18nExtractor.extractCurrencySymbols;
|
||||
extractDateTimeSymbols = closureI18nExtractor.extractDateTimeSymbols;
|
||||
outputLocale = closureI18nExtractor.outputLocale;
|
||||
|
||||
|
||||
function newTestLocaleInfo() {
|
||||
@@ -72,7 +73,7 @@ describe("findLocaleId", function() {
|
||||
it("should throw an error otherwise", function() {
|
||||
expect(function() {
|
||||
findLocaleId("str", "otherwise")
|
||||
}).toThrow("unknown type in findLocaleId: otherwise");
|
||||
}).toThrowError("unknown type in findLocaleId: otherwise");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -131,7 +132,10 @@ describe("extractCurrencySymbols", function() {
|
||||
].join('\n');
|
||||
|
||||
var localeInfo = {};
|
||||
expect(extractCurrencySymbols(CONTENT)).toEqual({
|
||||
var currencySymbols = extractCurrencySymbols(CONTENT);
|
||||
expect(currencySymbols.GBP).toEqual([2, '£', 'GB£']);
|
||||
expect(currencySymbols.AOA).toEqual([2, 'Kz', 'Kz']);
|
||||
expect(currencySymbols).toEqual({
|
||||
'GBP':[2, '£', 'GB£'],
|
||||
'AOA':[2, 'Kz', 'Kz']
|
||||
});
|
||||
@@ -142,71 +146,71 @@ describe("extractCurrencySymbols", function() {
|
||||
describe("extractDateTimeSymbols", function() {
|
||||
it("should extract date time data", function() {
|
||||
var CONTENT = [
|
||||
"goog.i18n.DateTimeSymbols_fr_CA = {",
|
||||
" ERAS: ['av. J.-C.', 'ap. J.-C.'],",
|
||||
" ERANAMES: ['avant Jésus-Christ', 'après Jésus-Christ'],",
|
||||
" NARROWMONTHS: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],",
|
||||
" STANDALONENARROWMONTHS: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O',",
|
||||
" 'N', 'D'],",
|
||||
" MONTHS: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet',",
|
||||
" 'août', 'septembre', 'octobre', 'novembre', 'décembre'],",
|
||||
" STANDALONEMONTHS: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin',",
|
||||
" 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'],",
|
||||
" SHORTMONTHS: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.',",
|
||||
" 'août', 'sept.', 'oct.', 'nov.', 'déc.'],",
|
||||
" STANDALONESHORTMONTHS: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin',",
|
||||
" 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'],",
|
||||
" WEEKDAYS: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi',",
|
||||
" 'samedi'],",
|
||||
" STANDALONEWEEKDAYS: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi',",
|
||||
" 'vendredi', 'samedi'],",
|
||||
" SHORTWEEKDAYS: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],",
|
||||
" STANDALONESHORTWEEKDAYS: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.',",
|
||||
" 'sam.'],",
|
||||
" NARROWWEEKDAYS: ['D', 'L', 'M', 'M', 'J', 'V', 'S'],",
|
||||
" STANDALONENARROWWEEKDAYS: ['D', 'L', 'M', 'M', 'J', 'V', 'S'],",
|
||||
" SHORTQUARTERS: ['T1', 'T2', 'T3', 'T4'],",
|
||||
" QUARTERS: ['1er trimestre', '2e trimestre', '3e trimestre', '4e trimestre'],",
|
||||
" AMPMS: ['AM', 'PM'],",
|
||||
" DATEFORMATS: ['EEEE d MMMM y', 'd MMMM y', 'yyyy-MM-dd', 'yy-MM-dd'],",
|
||||
" TIMEFORMATS: ['HH \\'h\\' mm \\'min\\' ss \\'s\\' zzzz', 'HH:mm:ss z',",
|
||||
" 'HH:mm:ss', 'HH:mm'],",
|
||||
" FIRSTDAYOFWEEK: 6,",
|
||||
" WEEKENDRANGE: [5, 6],",
|
||||
" FIRSTWEEKCUTOFFDAY: 2",
|
||||
"};"
|
||||
"goog.i18n.DateTimeSymbols_fr_CA = {",
|
||||
" ERAS: ['av. J.-C.', 'ap. J.-C.'],",
|
||||
" ERANAMES: ['avant Jésus-Christ', 'après Jésus-Christ'],",
|
||||
" NARROWMONTHS: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],",
|
||||
" STANDALONENARROWMONTHS: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O',",
|
||||
" 'N', 'D'],",
|
||||
" MONTHS: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet',",
|
||||
" 'août', 'septembre', 'octobre', 'novembre', 'décembre'],",
|
||||
" STANDALONEMONTHS: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin',",
|
||||
" 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'],",
|
||||
" SHORTMONTHS: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.',",
|
||||
" 'août', 'sept.', 'oct.', 'nov.', 'déc.'],",
|
||||
" STANDALONESHORTMONTHS: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin',",
|
||||
" 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'],",
|
||||
" WEEKDAYS: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi',",
|
||||
" 'samedi'],",
|
||||
" STANDALONEWEEKDAYS: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi',",
|
||||
" 'vendredi', 'samedi'],",
|
||||
" SHORTWEEKDAYS: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],",
|
||||
" STANDALONESHORTWEEKDAYS: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.',",
|
||||
" 'sam.'],",
|
||||
" NARROWWEEKDAYS: ['D', 'L', 'M', 'M', 'J', 'V', 'S'],",
|
||||
" STANDALONENARROWWEEKDAYS: ['D', 'L', 'M', 'M', 'J', 'V', 'S'],",
|
||||
" SHORTQUARTERS: ['T1', 'T2', 'T3', 'T4'],",
|
||||
" QUARTERS: ['1er trimestre', '2e trimestre', '3e trimestre', '4e trimestre'],",
|
||||
" AMPMS: ['AM', 'PM'],",
|
||||
" DATEFORMATS: ['EEEE d MMMM y', 'd MMMM y', 'yyyy-MM-dd', 'yy-MM-dd'],",
|
||||
" TIMEFORMATS: ['HH \\'h\\' mm \\'min\\' ss \\'s\\' zzzz', 'HH:mm:ss z',",
|
||||
" 'HH:mm:ss', 'HH:mm'],",
|
||||
" FIRSTDAYOFWEEK: 6,",
|
||||
" WEEKENDRANGE: [5, 6],",
|
||||
" FIRSTWEEKCUTOFFDAY: 2",
|
||||
"};"
|
||||
].join('\n');
|
||||
var localeInfo = {};
|
||||
var expectedLocaleInfo = {
|
||||
fr_CA: {
|
||||
DATETIME_FORMATS: {
|
||||
MONTH: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre',
|
||||
'octobre', 'novembre', 'décembre'],
|
||||
STANDALONEMONTH: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet',
|
||||
'août', 'septembre', 'octobre', 'novembre', 'décembre'],
|
||||
SHORTMONTH: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.',
|
||||
'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',
|
||||
longDate: 'd MMMM y',
|
||||
mediumDate: 'yyyy-MM-dd',
|
||||
shortDate: 'yy-MM-dd',
|
||||
mediumTime: 'HH:mm:ss',
|
||||
shortTime: 'HH:mm'
|
||||
}
|
||||
var localeInfo = {};
|
||||
var expectedLocaleInfo = {
|
||||
fr_CA: {
|
||||
DATETIME_FORMATS: {
|
||||
MONTH: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre',
|
||||
'octobre', 'novembre', 'décembre'],
|
||||
STANDALONEMONTH: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet',
|
||||
'août', 'septembre', 'octobre', 'novembre', 'décembre'],
|
||||
SHORTMONTH: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.',
|
||||
'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',
|
||||
longDate: 'd MMMM y',
|
||||
mediumDate: 'yyyy-MM-dd',
|
||||
shortDate: 'yy-MM-dd',
|
||||
mediumTime: 'HH:mm:ss',
|
||||
shortTime: 'HH:mm'
|
||||
}
|
||||
};
|
||||
extractDateTimeSymbols(CONTENT, localeInfo);
|
||||
expect(localeInfo).toEqual(expectedLocaleInfo);
|
||||
})
|
||||
}
|
||||
};
|
||||
extractDateTimeSymbols(CONTENT, localeInfo);
|
||||
expect(localeInfo).toEqual(expectedLocaleInfo);
|
||||
});
|
||||
});
|
||||
|
||||
describe("pluralExtractor", function() {
|
||||
@@ -272,3 +276,10 @@ describe("serializeContent", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("outputLocale", function() {
|
||||
it("should render the correct locale ids", function() {
|
||||
var output = outputLocale(newTestLocaleInfo(), 'fr_CA');
|
||||
expect(output).toContain('"id": "fr-ca"');
|
||||
expect(output).toContain('"localeID": "fr_CA"');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -50,10 +50,10 @@ function extractNumberSymbols(content, localeInfo, currencySymbols) {
|
||||
function extractCurrencySymbols(content) {
|
||||
//eval script in the current context so that we get access to all the symbols
|
||||
eval(content.toString());
|
||||
var currencySymbols = goog.i18n.currency.CurrencyInfo;
|
||||
currencySymbols.__proto__ = goog.i18n.currency.CurrencyInfoTier2;
|
||||
// var currencySymbols = goog.i18n.currency.CurrencyInfo;
|
||||
// currencySymbols.__proto__ = goog.i18n.currency.CurrencyInfoTier2;
|
||||
|
||||
return currencySymbols;
|
||||
return Object.assign({}, goog.i18n.currency.CurrencyInfoTier2, goog.i18n.currency.CurrencyInfo);
|
||||
}
|
||||
|
||||
function extractDateTimeSymbols(content, localeInfo) {
|
||||
@@ -79,7 +79,7 @@ function pluralExtractor(content, localeInfo) {
|
||||
goog.LOCALE = localeIds[i].match(/[^_]+/)[0];
|
||||
try {
|
||||
eval(contentText);
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
console.log("Error in eval(contentText): " + e.stack);
|
||||
}
|
||||
if (!goog.i18n.pluralRules.select) {
|
||||
@@ -133,7 +133,7 @@ function canonicalizeForJsonStringify(unused_key, object) {
|
||||
|
||||
function serializeContent(localeObj) {
|
||||
return JSON.stringify(localeObj, canonicalizeForJsonStringify, ' ')
|
||||
.replace(new RegExp('[\\u007f-\\uffff]', 'g'), function(c) { return '\\u'+('0000'+c.charCodeAt(0).toString(16)).slice(-4); })
|
||||
.replace(new RegExp('[\\u007f-\\uffff]', 'g'), function(c) { return '\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4); })
|
||||
.replace(/"@@|@@"/g, '');
|
||||
}
|
||||
|
||||
@@ -161,6 +161,7 @@ function outputLocale(localeInfo, localeID) {
|
||||
if (!localeObj.DATETIME_FORMATS) {
|
||||
localeObj.DATETIME_FORMATS = fallBackObj.DATETIME_FORMATS;
|
||||
}
|
||||
localeObj.localeID = localeID;
|
||||
localeObj.id = correctedLocaleId(localeID);
|
||||
|
||||
var getDecimals = [
|
||||
@@ -201,10 +202,11 @@ function outputLocale(localeInfo, localeID) {
|
||||
DATETIME_FORMATS: localeObj.DATETIME_FORMATS,
|
||||
NUMBER_FORMATS: localeObj.NUMBER_FORMATS,
|
||||
pluralCat: localeObj.pluralCat,
|
||||
id: localeObj.id
|
||||
id: localeObj.id,
|
||||
localeID: localeID
|
||||
};
|
||||
|
||||
var content = serializeContent(localeInfo[localeID]);
|
||||
var content = serializeContent(localeObj);
|
||||
if (content.indexOf('getVF(') < 0) {
|
||||
getVF = '';
|
||||
}
|
||||
|
||||
@@ -2142,7 +2142,7 @@ queue}</string>
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qr
|
||||
|
||||
\f0\fs22 \cf2 $scope\
|
||||
name='Wold'}</string>
|
||||
name='World'}</string>
|
||||
<key>VerticalPad</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
|
||||
+90
-95
@@ -8810,61 +8810,45 @@
|
||||
}
|
||||
},
|
||||
"jasmine-node": {
|
||||
"version": "1.14.5",
|
||||
"version": "2.0.0",
|
||||
"dependencies": {
|
||||
"coffee-script": {
|
||||
"version": "1.9.1"
|
||||
},
|
||||
"jasmine-growl-reporter": {
|
||||
"version": "0.0.3",
|
||||
"dependencies": {
|
||||
"growl": {
|
||||
"version": "1.7.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirejs": {
|
||||
"version": "2.1.17"
|
||||
"version": "1.7.1"
|
||||
},
|
||||
"walkdir": {
|
||||
"version": "0.0.7"
|
||||
"version": "0.0.11"
|
||||
},
|
||||
"underscore": {
|
||||
"version": "1.8.3"
|
||||
"version": "1.6.0"
|
||||
},
|
||||
"gaze": {
|
||||
"version": "0.3.4",
|
||||
"version": "0.5.2",
|
||||
"dependencies": {
|
||||
"minimatch": {
|
||||
"version": "0.2.14",
|
||||
"globule": {
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"lru-cache": {
|
||||
"version": "2.5.0"
|
||||
"lodash": {
|
||||
"version": "1.0.2"
|
||||
},
|
||||
"sigmund": {
|
||||
"version": "1.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"fileset": {
|
||||
"version": "0.1.5",
|
||||
"dependencies": {
|
||||
"glob": {
|
||||
"version": "3.2.11",
|
||||
"version": "3.1.21",
|
||||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "2.0.1"
|
||||
"graceful-fs": {
|
||||
"version": "1.2.3"
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "0.3.0",
|
||||
"dependencies": {
|
||||
"lru-cache": {
|
||||
"version": "2.5.0"
|
||||
},
|
||||
"sigmund": {
|
||||
"version": "1.0.0"
|
||||
}
|
||||
}
|
||||
"inherits": {
|
||||
"version": "1.0.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "0.2.14",
|
||||
"dependencies": {
|
||||
"lru-cache": {
|
||||
"version": "2.7.3"
|
||||
},
|
||||
"sigmund": {
|
||||
"version": "1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8874,6 +8858,17 @@
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.3.5"
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8"
|
||||
},
|
||||
"jasmine-growl-reporter": {
|
||||
"version": "0.2.1",
|
||||
"dependencies": {
|
||||
"growl": {
|
||||
"version": "1.7.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -9249,21 +9244,21 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ansi": {
|
||||
"version": "0.3.0"
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"ansi": {
|
||||
"version": "0.3.0"
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "2.1.0"
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
"version": "1.0.4"
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.3"
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
"version": "1.0.4"
|
||||
},
|
||||
"assert-plus": {
|
||||
"version": "0.1.5"
|
||||
},
|
||||
@@ -9291,12 +9286,12 @@
|
||||
"commander": {
|
||||
"version": "2.9.0"
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2"
|
||||
},
|
||||
"cryptiles": {
|
||||
"version": "2.0.5"
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2"
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.10.1"
|
||||
},
|
||||
@@ -9309,42 +9304,42 @@
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"delegates": {
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.1"
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.3"
|
||||
},
|
||||
"delegates": {
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.0"
|
||||
},
|
||||
"form-data": {
|
||||
"version": "1.0.0-rc3"
|
||||
},
|
||||
"extsprintf": {
|
||||
"version": "1.0.2"
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1"
|
||||
},
|
||||
"form-data": {
|
||||
"version": "1.0.0-rc3"
|
||||
},
|
||||
"fstream": {
|
||||
"version": "1.0.8"
|
||||
},
|
||||
"gauge": {
|
||||
"version": "1.2.2"
|
||||
},
|
||||
"generate-function": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"generate-object-property": {
|
||||
"version": "1.2.0"
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.1.2"
|
||||
},
|
||||
"generate-function": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"graceful-readlink": {
|
||||
"version": "1.0.1"
|
||||
},
|
||||
@@ -9354,11 +9349,14 @@
|
||||
"has-ansi": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"hawk": {
|
||||
"version": "3.1.2"
|
||||
},
|
||||
"has-unicode": {
|
||||
"version": "1.0.1"
|
||||
},
|
||||
"hawk": {
|
||||
"version": "3.1.2"
|
||||
"inherits": {
|
||||
"version": "2.0.1"
|
||||
},
|
||||
"hoek": {
|
||||
"version": "2.16.3"
|
||||
@@ -9366,44 +9364,47 @@
|
||||
"http-signature": {
|
||||
"version": "1.1.0"
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1"
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.4"
|
||||
},
|
||||
"is-my-json-valid": {
|
||||
"version": "2.12.3"
|
||||
},
|
||||
"is-property": {
|
||||
"version": "1.0.2"
|
||||
},
|
||||
"is-my-json-valid": {
|
||||
"version": "2.12.3"
|
||||
},
|
||||
"is-typedarray": {
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"isarray": {
|
||||
"version": "0.0.1"
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2"
|
||||
},
|
||||
"jodid25519": {
|
||||
"version": "1.0.2"
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.2.2"
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1"
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.2.2"
|
||||
},
|
||||
"jsonpointer": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.2.2"
|
||||
"lodash.pad": {
|
||||
"version": "3.1.1"
|
||||
},
|
||||
"lodash.padright": {
|
||||
"version": "3.1.1"
|
||||
},
|
||||
"lodash._basetostring": {
|
||||
"version": "3.0.1"
|
||||
@@ -9411,24 +9412,18 @@
|
||||
"lodash._createpadding": {
|
||||
"version": "3.6.1"
|
||||
},
|
||||
"lodash.pad": {
|
||||
"version": "3.1.1"
|
||||
},
|
||||
"lodash.padleft": {
|
||||
"version": "3.1.1"
|
||||
},
|
||||
"lodash.padright": {
|
||||
"version": "3.1.1"
|
||||
"mime-db": {
|
||||
"version": "1.19.0"
|
||||
},
|
||||
"lodash.repeat": {
|
||||
"version": "3.0.1"
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.19.0"
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.7"
|
||||
},
|
||||
"lodash.padleft": {
|
||||
"version": "3.1.1"
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8"
|
||||
},
|
||||
@@ -9438,15 +9433,15 @@
|
||||
"node-uuid": {
|
||||
"version": "1.4.7"
|
||||
},
|
||||
"npmlog": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.8.0"
|
||||
},
|
||||
"once": {
|
||||
"version": "1.1.1"
|
||||
},
|
||||
"npmlog": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"pinkie": {
|
||||
"version": "2.0.1"
|
||||
},
|
||||
@@ -9462,24 +9457,24 @@
|
||||
"request": {
|
||||
"version": "2.67.0"
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.1.0"
|
||||
},
|
||||
"sntp": {
|
||||
"version": "1.0.9"
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.1.0"
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31"
|
||||
},
|
||||
"stringstream": {
|
||||
"version": "0.0.5"
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.0"
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "1.0.4"
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.0"
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
@@ -9495,12 +9490,12 @@
|
||||
"tweetnacl": {
|
||||
"version": "0.13.2"
|
||||
},
|
||||
"uid-number": {
|
||||
"version": "0.0.3"
|
||||
},
|
||||
"verror": {
|
||||
"version": "1.3.6"
|
||||
},
|
||||
"uid-number": {
|
||||
"version": "0.0.3"
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.1"
|
||||
},
|
||||
|
||||
Generated
+524
-531
File diff suppressed because it is too large
Load Diff
+3
-2
@@ -16,7 +16,8 @@
|
||||
"scripts": {
|
||||
"preinstall": "node scripts/npm/check-node-modules.js --purge",
|
||||
"postinstall": "node scripts/npm/copy-npm-shrinkwrap.js",
|
||||
"commit": "git-cz"
|
||||
"commit": "git-cz",
|
||||
"test-i18n": "jasmine-node i18n/spec"
|
||||
},
|
||||
"devDependencies": {
|
||||
"angular-benchpress": "0.x.x",
|
||||
@@ -51,7 +52,7 @@
|
||||
"gulp-sourcemaps": "^1.2.2",
|
||||
"gulp-uglify": "^1.0.1",
|
||||
"gulp-util": "^3.0.1",
|
||||
"jasmine-node": "~1.14.5",
|
||||
"jasmine-node": "^2.0.0",
|
||||
"jasmine-reporters": "~1.0.1",
|
||||
"jshint-stylish": "~1.0.0",
|
||||
"karma": "^0.13.19",
|
||||
|
||||
@@ -138,6 +138,7 @@
|
||||
"jqLiteInheritedData": false,
|
||||
"jqLiteBuildFragment": false,
|
||||
"jqLiteParseHTML": false,
|
||||
"jqLiteWrapNode": false,
|
||||
"getBooleanAttrName": false,
|
||||
"getAliasedAttrName": false,
|
||||
"createEventHandler": false,
|
||||
|
||||
+32
-53
@@ -119,29 +119,9 @@ var REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/;
|
||||
// This is used so that it's possible for internal tests to create mock ValidityStates.
|
||||
var VALIDITY_STATE_PROPERTY = 'validity';
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name angular.lowercase
|
||||
* @module ng
|
||||
* @kind function
|
||||
*
|
||||
* @description Converts the specified string to lowercase.
|
||||
* @param {string} string String to be converted to lowercase.
|
||||
* @returns {string} Lowercased string.
|
||||
*/
|
||||
var lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;};
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name angular.uppercase
|
||||
* @module ng
|
||||
* @kind function
|
||||
*
|
||||
* @description Converts the specified string to uppercase.
|
||||
* @param {string} string String to be converted to uppercase.
|
||||
* @returns {string} Uppercased string.
|
||||
*/
|
||||
var lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;};
|
||||
var uppercase = function(string) {return isString(string) ? string.toUpperCase() : string;};
|
||||
|
||||
|
||||
@@ -161,7 +141,7 @@ var manualUppercase = function(s) {
|
||||
|
||||
// String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish
|
||||
// locale, for this reason we need to detect this case and redefine lowercase/uppercase methods
|
||||
// with correct but slower alternatives.
|
||||
// with correct but slower alternatives. See https://github.com/angular/angular.js/issues/11387
|
||||
if ('i' !== 'I'.toLowerCase()) {
|
||||
lowercase = manualLowercase;
|
||||
uppercase = manualUppercase;
|
||||
@@ -313,7 +293,7 @@ function forEachSorted(obj, iterator, context) {
|
||||
* @returns {function(*, string)}
|
||||
*/
|
||||
function reverseParams(iteratorFn) {
|
||||
return function(value, key) { iteratorFn(key, value); };
|
||||
return function(value, key) {iteratorFn(key, value);};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -725,7 +705,7 @@ function isElement(node) {
|
||||
* @returns {object} in the form of {key1:true, key2:true, ...}
|
||||
*/
|
||||
function makeMap(str) {
|
||||
var obj = {}, items = str.split(","), i;
|
||||
var obj = {}, items = str.split(','), i;
|
||||
for (i = 0; i < items.length; i++) {
|
||||
obj[items[i]] = true;
|
||||
}
|
||||
@@ -1001,38 +981,37 @@ function equals(o1, o2) {
|
||||
if (o1 === null || o2 === null) return false;
|
||||
if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN
|
||||
var t1 = typeof o1, t2 = typeof o2, length, key, keySet;
|
||||
if (t1 == t2) {
|
||||
if (t1 == 'object') {
|
||||
if (isArray(o1)) {
|
||||
if (!isArray(o2)) return false;
|
||||
if ((length = o1.length) == o2.length) {
|
||||
for (key = 0; key < length; key++) {
|
||||
if (!equals(o1[key], o2[key])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} 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 (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) ||
|
||||
isArray(o2) || isDate(o2) || isRegExp(o2)) return false;
|
||||
keySet = createMap();
|
||||
for (key in o1) {
|
||||
if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
|
||||
if (t1 == t2 && t1 == 'object') {
|
||||
if (isArray(o1)) {
|
||||
if (!isArray(o2)) return false;
|
||||
if ((length = o1.length) == o2.length) {
|
||||
for (key = 0; key < length; key++) {
|
||||
if (!equals(o1[key], o2[key])) return false;
|
||||
keySet[key] = true;
|
||||
}
|
||||
for (key in o2) {
|
||||
if (!(key in keySet) &&
|
||||
key.charAt(0) !== '$' &&
|
||||
isDefined(o2[key]) &&
|
||||
!isFunction(o2[key])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else if (isDate(o1)) {
|
||||
if (!isDate(o2)) return false;
|
||||
return equals(o1.getTime(), o2.getTime());
|
||||
} else if (isRegExp(o1)) {
|
||||
if (!isRegExp(o2)) return false;
|
||||
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();
|
||||
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) &&
|
||||
key.charAt(0) !== '$' &&
|
||||
isDefined(o2[key]) &&
|
||||
!isFunction(o2[key])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -1271,7 +1250,7 @@ function startingTag(element) {
|
||||
return element[0].nodeType === NODE_TYPE_TEXT ? lowercase(elemHtml) :
|
||||
elemHtml.
|
||||
match(/^(<[^>]+>)/)[1].
|
||||
replace(/^<([\w\-]+)/, function(match, nodeName) { return '<' + lowercase(nodeName); });
|
||||
replace(/^<([\w\-]+)/, function(match, nodeName) {return '<' + lowercase(nodeName);});
|
||||
} catch (e) {
|
||||
return lowercase(elemHtml);
|
||||
}
|
||||
|
||||
+14
-2
@@ -491,8 +491,20 @@ function annotate(fn, strictDi, name) {
|
||||
*
|
||||
* Register a **service constructor**, which will be invoked with `new` to create the service
|
||||
* instance.
|
||||
* This is short for registering a service where its provider's `$get` property is the service
|
||||
* constructor function that will be used to instantiate the service instance.
|
||||
* This is short for registering a service where its provider's `$get` property is a factory
|
||||
* function that returns an instance instantiated by the injector from the service constructor
|
||||
* function.
|
||||
*
|
||||
* Internally it looks a bit like this:
|
||||
*
|
||||
* ```
|
||||
* {
|
||||
* $get: function() {
|
||||
* return $injector.instantiate(constructor);
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* You should use {@link auto.$provide#service $provide.service(class)} if you define your service
|
||||
* as a type/class.
|
||||
|
||||
+11
-6
@@ -254,6 +254,16 @@ function jqLiteParseHTML(html, context) {
|
||||
return [];
|
||||
}
|
||||
|
||||
function jqLiteWrapNode(node, wrapper) {
|
||||
var parent = node.parentNode;
|
||||
|
||||
if (parent) {
|
||||
parent.replaceChild(wrapper, node);
|
||||
}
|
||||
|
||||
wrapper.appendChild(node);
|
||||
}
|
||||
|
||||
|
||||
// IE9-11 has no method "contains" in SVG element and in Node.prototype. Bug #10259.
|
||||
var jqLiteContains = Node.prototype.contains || function(arg) {
|
||||
@@ -946,12 +956,7 @@ forEach({
|
||||
},
|
||||
|
||||
wrap: function(element, wrapNode) {
|
||||
wrapNode = jqLite(wrapNode).eq(0).clone()[0];
|
||||
var parent = element.parentNode;
|
||||
if (parent) {
|
||||
parent.replaceChild(wrapNode, element);
|
||||
}
|
||||
wrapNode.appendChild(element);
|
||||
jqLiteWrapNode(element, jqLite(wrapNode).eq(0).clone()[0]);
|
||||
},
|
||||
|
||||
remove: jqLiteRemove,
|
||||
|
||||
+2
-2
@@ -329,8 +329,8 @@ var $AnimateProvider = ['$provide', function($provide) {
|
||||
* // remove all the animation event listeners listening for `enter` on the given element and its children
|
||||
* $animate.off('enter', container);
|
||||
*
|
||||
* // remove the event listener function provided by `listenerFn` that is set
|
||||
* // to listen for `enter` on the given `element` as well as its children
|
||||
* // remove the event listener function provided by `callback` that is set
|
||||
* // to listen for `enter` on the given `container` as well as its children
|
||||
* $animate.off('enter', container, callback);
|
||||
* ```
|
||||
*
|
||||
|
||||
+19
-4
@@ -28,8 +28,8 @@ var $$AnimateAsyncRunFactoryProvider = function() {
|
||||
};
|
||||
|
||||
var $$AnimateRunnerFactoryProvider = function() {
|
||||
this.$get = ['$q', '$sniffer', '$$animateAsyncRun',
|
||||
function($q, $sniffer, $$animateAsyncRun) {
|
||||
this.$get = ['$q', '$sniffer', '$$animateAsyncRun', '$document', '$timeout',
|
||||
function($q, $sniffer, $$animateAsyncRun, $document, $timeout) {
|
||||
|
||||
var INITIAL_STATE = 0;
|
||||
var DONE_PENDING_STATE = 1;
|
||||
@@ -74,8 +74,23 @@ var $$AnimateRunnerFactoryProvider = function() {
|
||||
function AnimateRunner(host) {
|
||||
this.setHost(host);
|
||||
|
||||
var rafTick = $$animateAsyncRun();
|
||||
var timeoutTick = function(fn) {
|
||||
$timeout(fn, 0, false);
|
||||
};
|
||||
|
||||
this._doneCallbacks = [];
|
||||
this._runInAnimationFrame = $$animateAsyncRun();
|
||||
this._tick = function(fn) {
|
||||
var doc = $document[0];
|
||||
|
||||
// the document may not be ready or attached
|
||||
// to the module for some internal tests
|
||||
if (doc && doc.hidden) {
|
||||
timeoutTick(fn);
|
||||
} else {
|
||||
rafTick(fn);
|
||||
}
|
||||
};
|
||||
this._state = 0;
|
||||
}
|
||||
|
||||
@@ -148,7 +163,7 @@ var $$AnimateRunnerFactoryProvider = function() {
|
||||
var self = this;
|
||||
if (self._state === INITIAL_STATE) {
|
||||
self._state = DONE_PENDING_STATE;
|
||||
self._runInAnimationFrame(function() {
|
||||
self._tick(function() {
|
||||
self._resolve(response);
|
||||
});
|
||||
}
|
||||
|
||||
+160
-20
@@ -218,8 +218,18 @@
|
||||
* definition: `controller: 'myCtrl as myAlias'`.
|
||||
*
|
||||
* When an isolate scope is used for a directive (see above), `bindToController: true` will
|
||||
* allow a component to have its properties bound to the controller, rather than to scope. When the controller
|
||||
* is instantiated, the initial values of the isolate scope bindings will be available if the controller is not an ES6 class.
|
||||
* allow a component to have its properties bound to the controller, rather than to scope.
|
||||
*
|
||||
* After the controller is instantiated, the initial values of the isolate scope bindings will be bound to the controller
|
||||
* properties. You can access these bindings once they have been initialized by providing a controller method called
|
||||
* `$onInit`, which is called after all the controllers on an element have been constructed and had their bindings
|
||||
* initialized.
|
||||
*
|
||||
* <div class="alert alert-warning">
|
||||
* **Deprecation warning:** although bindings for non-ES6 class controllers are currently
|
||||
* bound to `this` before the controller constructor is called, this use is now deprecated. Please place initialization
|
||||
* code that relies upon bindings inside a `$onInit` method on the controller, instead.
|
||||
* </div>
|
||||
*
|
||||
* It is also possible to set `bindToController` to an object hash with the same format as the `scope` property.
|
||||
* This will set up the scope bindings to the controller directly. Note that `scope` can still be used
|
||||
@@ -255,12 +265,29 @@
|
||||
* The `$transclude` function also has a method on it, `$transclude.isSlotFilled(slotName)`, which returns
|
||||
* `true` if the specified slot contains content (i.e. one or more DOM nodes).
|
||||
*
|
||||
* The controller can provide the following methods that act as life-cycle hooks:
|
||||
* * `$onInit` - Called on each controller after all the controllers on an element have been constructed and
|
||||
* had their bindings initialized (and before the pre & post linking functions for the directives on
|
||||
* this element). This is a good place to put initialization code for your controller.
|
||||
*
|
||||
* #### `require`
|
||||
* Require another directive and inject its controller as the fourth argument to the linking function. The
|
||||
* `require` takes a string name (or array of strings) of the directive(s) to pass in. If an array is used, the
|
||||
* injected argument will be an array in corresponding order. If no such directive can be
|
||||
* found, or if the directive does not have a controller, then an error is raised (unless no link function
|
||||
* is specified, in which case error checking is skipped). The name can be prefixed with:
|
||||
* `require` property can be a string, an array or an object:
|
||||
* * a **string** containing the name of the directive to pass to the linking function
|
||||
* * an **array** containing the names of directives to pass to the linking function. The argument passed to the
|
||||
* linking function will be an array of controllers in the same order as the names in the `require` property
|
||||
* * an **object** whose property values are the names of the directives to pass to the linking function. The argument
|
||||
* passed to the linking function will also be an object with matching keys, whose values will hold the corresponding
|
||||
* controllers.
|
||||
*
|
||||
* If the `require` property is an object and `bindToController` is truthy, then the required controllers are
|
||||
* bound to the controller using the keys of the `require` property. This binding occurs after all the controllers
|
||||
* have been constructed but before `$onInit` is called.
|
||||
* See the {@link $compileProvider#component} helper for an example of how this can be used.
|
||||
*
|
||||
* If no such required directive(s) can be found, or if the directive does not have a controller, then an error is
|
||||
* raised (unless no link function is specified and the required controllers are not being bound to the directive
|
||||
* controller, in which case error checking is skipped). The name can be prefixed with:
|
||||
*
|
||||
* * (no prefix) - Locate the required controller on the current element. Throw an error if not found.
|
||||
* * `?` - Attempt to locate the required controller or pass `null` to the `link` fn if not found.
|
||||
@@ -731,8 +758,15 @@
|
||||
* directives; if given, it will be passed through to the link functions of
|
||||
* directives found in `element` during compilation.
|
||||
* * `transcludeControllers` - an object hash with keys that map controller names
|
||||
* to controller instances; if given, it will make the controllers
|
||||
* available to directives.
|
||||
* to a hash with the key `instance`, which maps to the controller instance;
|
||||
* if given, it will make the controllers available to directives on the compileNode:
|
||||
* ```
|
||||
* {
|
||||
* parent: {
|
||||
* instance: parentControllerInstance
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
* * `futureParentElement` - defines the parent to which the `cloneAttachFn` will add
|
||||
* the cloned elements; only needed for transcludes that are allowed to contain non html
|
||||
* elements (e.g. SVG elements). See also the directive.controller property.
|
||||
@@ -1005,6 +1039,80 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
*
|
||||
* ```
|
||||
*
|
||||
* ### Intercomponent Communication
|
||||
* Directives can require the controllers of other directives to enable communication
|
||||
* between the directives. This can be achieved in a component by providing an
|
||||
* object mapping for the `require` property. Here is the tab pane example built
|
||||
* from components...
|
||||
*
|
||||
* <example module="docsTabsExample">
|
||||
* <file name="script.js">
|
||||
* angular.module('docsTabsExample', [])
|
||||
* .component('myTabs', {
|
||||
* transclude: true,
|
||||
* controller: function() {
|
||||
* var panes = this.panes = [];
|
||||
*
|
||||
* this.select = function(pane) {
|
||||
* angular.forEach(panes, function(pane) {
|
||||
* pane.selected = false;
|
||||
* });
|
||||
* pane.selected = true;
|
||||
* };
|
||||
*
|
||||
* this.addPane = function(pane) {
|
||||
* if (panes.length === 0) {
|
||||
* this.select(pane);
|
||||
* }
|
||||
* panes.push(pane);
|
||||
* };
|
||||
* },
|
||||
* templateUrl: 'my-tabs.html'
|
||||
* })
|
||||
* .component('myPane', {
|
||||
* transclude: true,
|
||||
* require: {tabsCtrl: '^myTabs'},
|
||||
* bindings: {
|
||||
* title: '@'
|
||||
* },
|
||||
* controller: function() {
|
||||
* this.$onInit = function() {
|
||||
* this.tabsCtrl.addPane(this);
|
||||
* console.log(this);
|
||||
* };
|
||||
* },
|
||||
* templateUrl: 'my-pane.html'
|
||||
* });
|
||||
* </file>
|
||||
* <file name="index.html">
|
||||
* <my-tabs>
|
||||
* <my-pane title="Hello">
|
||||
* <h4>Hello</h4>
|
||||
* <p>Lorem ipsum dolor sit amet</p>
|
||||
* </my-pane>
|
||||
* <my-pane title="World">
|
||||
* <h4>World</h4>
|
||||
* <em>Mauris elementum elementum enim at suscipit.</em>
|
||||
* <p><a href ng-click="i = i + 1">counter: {{i || 0}}</a></p>
|
||||
* </my-pane>
|
||||
* </my-tabs>
|
||||
* </file>
|
||||
* <file name="my-tabs.html">
|
||||
* <div class="tabbable">
|
||||
* <ul class="nav nav-tabs">
|
||||
* <li ng-repeat="pane in $ctrl.panes" ng-class="{active:pane.selected}">
|
||||
* <a href="" ng-click="$ctrl.select(pane)">{{pane.title}}</a>
|
||||
* </li>
|
||||
* </ul>
|
||||
* <div class="tab-content" ng-transclude></div>
|
||||
* </div>
|
||||
* </file>
|
||||
* <file name="my-pane.html">
|
||||
* <div class="tab-pane" ng-show="$ctrl.selected" ng-transclude></div>
|
||||
* </file>
|
||||
* </example>
|
||||
*
|
||||
*
|
||||
* <br />
|
||||
* Components are also useful as route templates (e.g. when using
|
||||
* {@link ngRoute ngRoute}):
|
||||
@@ -1072,7 +1180,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
transclude: options.transclude,
|
||||
scope: {},
|
||||
bindToController: options.bindings || {},
|
||||
restrict: 'E'
|
||||
restrict: 'E',
|
||||
require: options.require
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1182,9 +1291,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
|
||||
this.$get = [
|
||||
'$injector', '$interpolate', '$exceptionHandler', '$templateRequest', '$parse',
|
||||
'$controller', '$rootScope', '$document', '$sce', '$animate', '$$sanitizeUri',
|
||||
'$controller', '$rootScope', '$sce', '$animate', '$$sanitizeUri',
|
||||
function($injector, $interpolate, $exceptionHandler, $templateRequest, $parse,
|
||||
$controller, $rootScope, $document, $sce, $animate, $$sanitizeUri) {
|
||||
$controller, $rootScope, $sce, $animate, $$sanitizeUri) {
|
||||
|
||||
var SIMPLE_ATTR_NAME = /^\w/;
|
||||
var specialAttrHolder = document.createElement('div');
|
||||
@@ -1450,7 +1559,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
|
||||
var startSymbol = $interpolate.startSymbol(),
|
||||
endSymbol = $interpolate.endSymbol(),
|
||||
denormalizeTemplate = (startSymbol == '{{' || endSymbol == '}}')
|
||||
denormalizeTemplate = (startSymbol == '{{' && endSymbol == '}}')
|
||||
? identity
|
||||
: function denormalizeTemplate(template) {
|
||||
return template.replace(/\{\{/g, startSymbol).replace(/}}/g, endSymbol);
|
||||
@@ -1494,13 +1603,19 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
// modify it.
|
||||
$compileNodes = jqLite($compileNodes);
|
||||
}
|
||||
|
||||
var NOT_EMPTY = /\S+/;
|
||||
|
||||
// We can not compile top level text elements since text nodes can be merged and we will
|
||||
// not be able to attach scope data to them, so we will wrap them in <span>
|
||||
forEach($compileNodes, function(node, index) {
|
||||
if (node.nodeType == NODE_TYPE_TEXT && node.nodeValue.match(/\S+/) /* non-empty */) {
|
||||
$compileNodes[index] = jqLite(node).wrap('<span></span>').parent()[0];
|
||||
for (var i = 0, len = $compileNodes.length; i < len; i++) {
|
||||
var domNode = $compileNodes[i];
|
||||
|
||||
if (domNode.nodeType === NODE_TYPE_TEXT && domNode.nodeValue.match(NOT_EMPTY) /* non-empty */) {
|
||||
jqLiteWrapNode(domNode, $compileNodes[i] = document.createElement('span'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var compositeLinkFn =
|
||||
compileNodes($compileNodes, transcludeFn, $compileNodes,
|
||||
maxPriority, ignoreDirective, previousCompileContext);
|
||||
@@ -2280,6 +2395,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
for (var i = 0, ii = require.length; i < ii; i++) {
|
||||
value[i] = getControllers(directiveName, require[i], $element, elementControllers);
|
||||
}
|
||||
} else if (isObject(require)) {
|
||||
value = {};
|
||||
forEach(require, function(controller, property) {
|
||||
value[property] = getControllers(directiveName, controller, $element, elementControllers);
|
||||
});
|
||||
}
|
||||
|
||||
return value || null;
|
||||
@@ -2388,6 +2508,21 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
}
|
||||
}
|
||||
|
||||
// Bind the required controllers to the controller, if `require` is an object and `bindToController` is truthy
|
||||
forEach(controllerDirectives, function(controllerDirective, name) {
|
||||
var require = controllerDirective.require;
|
||||
if (controllerDirective.bindToController && !isArray(require) && isObject(require)) {
|
||||
extend(elementControllers[name].instance, getControllers(name, require, $element, elementControllers));
|
||||
}
|
||||
});
|
||||
|
||||
// Trigger the `$onInit` method on all controllers that have one
|
||||
forEach(elementControllers, function(controller) {
|
||||
if (isFunction(controller.instance.$onInit)) {
|
||||
controller.instance.$onInit();
|
||||
}
|
||||
});
|
||||
|
||||
// PRELINKING
|
||||
for (i = 0, ii = preLinkFns.length; i < ii; i++) {
|
||||
linkFn = preLinkFns[i];
|
||||
@@ -2956,10 +3091,15 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
}
|
||||
});
|
||||
attrs.$$observers[attrName].$$scope = scope;
|
||||
if (isString(attrs[attrName])) {
|
||||
lastValue = attrs[attrName];
|
||||
if (isString(lastValue)) {
|
||||
// If the attribute has been provided then we trigger an interpolation to ensure
|
||||
// the value is there for use in the link fn
|
||||
destination[scopeName] = $interpolate(attrs[attrName])(scope);
|
||||
destination[scopeName] = $interpolate(lastValue)(scope);
|
||||
} else if (isBoolean(lastValue)) {
|
||||
// If the attributes is one of the BOOLEAN_ATTR then Angular will have converted
|
||||
// the value to boolean rather than a string, so we special case this situation
|
||||
destination[scopeName] = lastValue;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2980,8 +3120,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
// reset the change, or we will throw this exception on every $digest
|
||||
lastValue = destination[scopeName] = parentGet(scope);
|
||||
throw $compileMinErr('nonassign',
|
||||
"Expression '{0}' used with directive '{1}' is non-assignable!",
|
||||
attrs[attrName], directive.name);
|
||||
"Expression '{0}' in attribute '{1}' used with directive '{2}' is non-assignable!",
|
||||
attrs[attrName], attrName, directive.name);
|
||||
};
|
||||
lastValue = destination[scopeName] = parentGet(scope);
|
||||
var parentValueWatch = function parentValueWatch(parentValue) {
|
||||
|
||||
@@ -638,7 +638,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
||||
forEach(ctrl.$asyncValidators, function(validator, name) {
|
||||
var promise = validator(modelValue, viewValue);
|
||||
if (!isPromiseLike(promise)) {
|
||||
throw ngModelMinErr("$asyncValidators",
|
||||
throw ngModelMinErr('nopromise',
|
||||
"Expected asynchronous validator to return a promise but got '{0}' instead.", promise);
|
||||
}
|
||||
setValidity(name, undefined);
|
||||
@@ -937,6 +937,22 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
||||
* - {@link ng.directive:select select}
|
||||
* - {@link ng.directive:textarea textarea}
|
||||
*
|
||||
* # Complex Models (objects or collections)
|
||||
*
|
||||
* By default, `ngModel` watches the model by reference, not value. This is important to know when
|
||||
* binding inputs to models that are objects (e.g. `Date`) or collections (e.g. arrays). If only properties of the
|
||||
* object or collection change, `ngModel` will not be notified and so the input will not be re-rendered.
|
||||
*
|
||||
* The model must be assigned an entirely new object or collection before a re-rendering will occur.
|
||||
*
|
||||
* Some directives have options that will cause them to use a custom `$watchCollection` on the model expression
|
||||
* - for example, `ngOptions` will do so when a `track by` clause is included in the comprehension expression or
|
||||
* if the select is given the `multiple` attribute.
|
||||
*
|
||||
* The `$watchCollection()` method only does a shallow comparison, meaning that changing properties deeper than the
|
||||
* first level of the object (or only changing the properties of an item in the collection if it's an array) will still
|
||||
* not trigger a re-rendering of the model.
|
||||
*
|
||||
* # CSS classes
|
||||
* The following CSS classes are added and removed on the associated input/select/textarea element
|
||||
* depending on the validity of the model.
|
||||
|
||||
@@ -170,6 +170,8 @@
|
||||
*
|
||||
* **.move** - when an adjacent item is filtered out causing a reorder or when the item contents are reordered
|
||||
*
|
||||
* See the example below for defining CSS animations with ngRepeat.
|
||||
*
|
||||
* @element ANY
|
||||
* @scope
|
||||
* @priority 1000
|
||||
@@ -222,22 +224,11 @@
|
||||
* For example: `item in items | filter : x | orderBy : order | limitTo : limit as results` .
|
||||
*
|
||||
* @example
|
||||
* This example initializes the scope to a list of names and
|
||||
* then uses `ngRepeat` to display every person:
|
||||
<example module="ngAnimate" deps="angular-animate.js" animations="true">
|
||||
* This example uses `ngRepeat` to display a list of people. A filter is used to restrict the displayed
|
||||
* results by name. New (entering) and removed (leaving) items are animated.
|
||||
<example module="ngRepeat" name="ngRepeat" deps="angular-animate.js" animations="true">
|
||||
<file name="index.html">
|
||||
<div ng-init="friends = [
|
||||
{name:'John', age:25, gender:'boy'},
|
||||
{name:'Jessie', age:30, gender:'girl'},
|
||||
{name:'Johanna', age:28, gender:'girl'},
|
||||
{name:'Joy', age:15, gender:'girl'},
|
||||
{name:'Mary', age:28, gender:'girl'},
|
||||
{name:'Peter', age:95, gender:'boy'},
|
||||
{name:'Sebastian', age:50, gender:'boy'},
|
||||
{name:'Erika', age:27, gender:'girl'},
|
||||
{name:'Patrick', age:40, gender:'boy'},
|
||||
{name:'Samantha', age:60, gender:'girl'}
|
||||
]">
|
||||
<div ng-controller="repeatController">
|
||||
I have {{friends.length}} friends. They are:
|
||||
<input type="search" ng-model="q" placeholder="filter friends..." aria-label="filter friends" />
|
||||
<ul class="example-animate-container">
|
||||
@@ -250,6 +241,22 @@
|
||||
</ul>
|
||||
</div>
|
||||
</file>
|
||||
<file name="script.js">
|
||||
angular.module('ngRepeat', ['ngAnimate']).controller('repeatController', function($scope) {
|
||||
$scope.friends = [
|
||||
{name:'John', age:25, gender:'boy'},
|
||||
{name:'Jessie', age:30, gender:'girl'},
|
||||
{name:'Johanna', age:28, gender:'girl'},
|
||||
{name:'Joy', age:15, gender:'girl'},
|
||||
{name:'Mary', age:28, gender:'girl'},
|
||||
{name:'Peter', age:95, gender:'boy'},
|
||||
{name:'Sebastian', age:50, gender:'boy'},
|
||||
{name:'Erika', age:27, gender:'girl'},
|
||||
{name:'Patrick', age:40, gender:'boy'},
|
||||
{name:'Samantha', age:60, gender:'girl'}
|
||||
];
|
||||
});
|
||||
</file>
|
||||
<file name="animations.css">
|
||||
.example-animate-container {
|
||||
background:white;
|
||||
@@ -260,7 +267,7 @@
|
||||
}
|
||||
|
||||
.animate-repeat {
|
||||
line-height:40px;
|
||||
line-height:30px;
|
||||
list-style:none;
|
||||
box-sizing:border-box;
|
||||
}
|
||||
@@ -282,7 +289,7 @@
|
||||
.animate-repeat.ng-move.ng-move-active,
|
||||
.animate-repeat.ng-enter.ng-enter-active {
|
||||
opacity:1;
|
||||
max-height:40px;
|
||||
max-height:30px;
|
||||
}
|
||||
</file>
|
||||
<file name="protractor.js" type="protractor">
|
||||
|
||||
@@ -613,7 +613,7 @@ function dateFilter($locale) {
|
||||
forEach(parts, function(value) {
|
||||
fn = DATE_FORMATS[value];
|
||||
text += fn ? fn(date, $locale.DATETIME_FORMATS, dateTimezoneOffset)
|
||||
: value.replace(/(^'|'$)/g, '').replace(/''/g, "'");
|
||||
: value === "''" ? "'" : value.replace(/(^'|'$)/g, '').replace(/''/g, "'");
|
||||
});
|
||||
|
||||
return text;
|
||||
|
||||
+37
-2
@@ -1757,10 +1757,19 @@ function $ParseProvider() {
|
||||
csp: noUnsafeEval,
|
||||
expensiveChecks: true
|
||||
};
|
||||
var runningChecksEnabled = false;
|
||||
|
||||
return function $parse(exp, interceptorFn, expensiveChecks) {
|
||||
$parse.$$runningExpensiveChecks = function() {
|
||||
return runningChecksEnabled;
|
||||
};
|
||||
|
||||
return $parse;
|
||||
|
||||
function $parse(exp, interceptorFn, expensiveChecks) {
|
||||
var parsedExpression, oneTime, cacheKey;
|
||||
|
||||
expensiveChecks = expensiveChecks || runningChecksEnabled;
|
||||
|
||||
switch (typeof exp) {
|
||||
case 'string':
|
||||
exp = exp.trim();
|
||||
@@ -1786,6 +1795,9 @@ function $ParseProvider() {
|
||||
} else if (parsedExpression.inputs) {
|
||||
parsedExpression.$$watchDelegate = inputsWatchDelegate;
|
||||
}
|
||||
if (expensiveChecks) {
|
||||
parsedExpression = expensiveChecksInterceptor(parsedExpression);
|
||||
}
|
||||
cache[cacheKey] = parsedExpression;
|
||||
}
|
||||
return addInterceptor(parsedExpression, interceptorFn);
|
||||
@@ -1796,7 +1808,30 @@ function $ParseProvider() {
|
||||
default:
|
||||
return addInterceptor(noop, interceptorFn);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function expensiveChecksInterceptor(fn) {
|
||||
if (!fn) return fn;
|
||||
expensiveCheckFn.$$watchDelegate = fn.$$watchDelegate;
|
||||
expensiveCheckFn.assign = expensiveChecksInterceptor(fn.assign);
|
||||
expensiveCheckFn.constant = fn.constant;
|
||||
expensiveCheckFn.literal = fn.literal;
|
||||
for (var i = 0; fn.inputs && i < fn.inputs.length; ++i) {
|
||||
fn.inputs[i] = expensiveChecksInterceptor(fn.inputs[i]);
|
||||
}
|
||||
|
||||
return expensiveCheckFn;
|
||||
|
||||
function expensiveCheckFn(scope, locals, assign, inputs) {
|
||||
var expensiveCheckOldValue = runningChecksEnabled;
|
||||
runningChecksEnabled = true;
|
||||
try {
|
||||
return fn(scope, locals, assign, inputs);
|
||||
} finally {
|
||||
runningChecksEnabled = expensiveCheckOldValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function expressionInputDirtyCheck(newValue, oldValueOfValue) {
|
||||
|
||||
|
||||
+2
-1
@@ -998,7 +998,7 @@ function $RootScopeProvider() {
|
||||
});
|
||||
}
|
||||
|
||||
asyncQueue.push({scope: this, expression: expr, locals: locals});
|
||||
asyncQueue.push({scope: this, expression: $parse(expr), locals: locals});
|
||||
},
|
||||
|
||||
$$postDigest: function(fn) {
|
||||
@@ -1090,6 +1090,7 @@ function $RootScopeProvider() {
|
||||
$applyAsync: function(expr) {
|
||||
var scope = this;
|
||||
expr && applyAsyncQueue.push($applyAsyncExpression);
|
||||
expr = $parse(expr);
|
||||
scheduleApplyAsync();
|
||||
|
||||
function $applyAsyncExpression() {
|
||||
|
||||
+15
-13
@@ -144,13 +144,15 @@ function $SceDelegateProvider() {
|
||||
* @kind function
|
||||
*
|
||||
* @param {Array=} whitelist When provided, replaces the resourceUrlWhitelist with the value
|
||||
* provided. This must be an array or null. A snapshot of this array is used so further
|
||||
* changes to the array are ignored.
|
||||
* provided. This must be an array or null. A snapshot of this array is used so further
|
||||
* changes to the array are ignored.
|
||||
*
|
||||
* Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
|
||||
* allowed in this array.
|
||||
* Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
|
||||
* allowed in this array.
|
||||
*
|
||||
* Note: **an empty whitelist array will block all URLs**!
|
||||
* <div class="alert alert-warning">
|
||||
* **Note:** an empty whitelist array will block all URLs!
|
||||
* </div>
|
||||
*
|
||||
* @return {Array} the currently set whitelist array.
|
||||
*
|
||||
@@ -173,17 +175,17 @@ function $SceDelegateProvider() {
|
||||
* @kind function
|
||||
*
|
||||
* @param {Array=} blacklist When provided, replaces the resourceUrlBlacklist with the value
|
||||
* provided. This must be an array or null. A snapshot of this array is used so further
|
||||
* changes to the array are ignored.
|
||||
* provided. This must be an array or null. A snapshot of this array is used so further
|
||||
* changes to the array are ignored.
|
||||
*
|
||||
* Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
|
||||
* allowed in this array.
|
||||
* Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
|
||||
* allowed in this array.
|
||||
*
|
||||
* The typical usage for the blacklist is to **block
|
||||
* [open redirects](http://cwe.mitre.org/data/definitions/601.html)** served by your domain as
|
||||
* these would otherwise be trusted but actually return content from the redirected domain.
|
||||
* The typical usage for the blacklist is to **block
|
||||
* [open redirects](http://cwe.mitre.org/data/definitions/601.html)** served by your domain as
|
||||
* these would otherwise be trusted but actually return content from the redirected domain.
|
||||
*
|
||||
* Finally, **the blacklist overrides the whitelist** and has the final say.
|
||||
* Finally, **the blacklist overrides the whitelist** and has the final say.
|
||||
*
|
||||
* @return {Array} the currently set blacklist array.
|
||||
*
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
"assertArg": false,
|
||||
"isPromiseLike": false,
|
||||
"mergeClasses": false,
|
||||
"mergeAnimationOptions": false,
|
||||
"mergeAnimationDetails": false,
|
||||
"prepareAnimationOptions": false,
|
||||
"applyAnimationStyles": false,
|
||||
"applyAnimationFromStyles": false,
|
||||
|
||||
@@ -756,6 +756,13 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
|
||||
element.off(events.join(' '), onAnimationProgress);
|
||||
}
|
||||
|
||||
//Cancel the fallback closing timeout and remove the timer data
|
||||
var animationTimerData = element.data(ANIMATE_TIMER_KEY);
|
||||
if (animationTimerData) {
|
||||
$timeout.cancel(animationTimerData[0].timer);
|
||||
element.removeData(ANIMATE_TIMER_KEY);
|
||||
}
|
||||
|
||||
// if the preparation function fails then the promise is not setup
|
||||
if (runner) {
|
||||
runner.complete(!rejected);
|
||||
|
||||
@@ -42,22 +42,21 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
});
|
||||
}
|
||||
|
||||
function hasAnimationClasses(options, and) {
|
||||
options = options || {};
|
||||
var a = (options.addClass || '').length > 0;
|
||||
var b = (options.removeClass || '').length > 0;
|
||||
function hasAnimationClasses(animation, and) {
|
||||
var a = (animation.addClass || '').length > 0;
|
||||
var b = (animation.removeClass || '').length > 0;
|
||||
return and ? a && b : a || b;
|
||||
}
|
||||
|
||||
rules.join.push(function(element, newAnimation, currentAnimation) {
|
||||
// if the new animation is class-based then we can just tack that on
|
||||
return !newAnimation.structural && hasAnimationClasses(newAnimation.options);
|
||||
return !newAnimation.structural && hasAnimationClasses(newAnimation);
|
||||
});
|
||||
|
||||
rules.skip.push(function(element, newAnimation, currentAnimation) {
|
||||
// there is no need to animate anything if no classes are being added and
|
||||
// there is no structural animation that will be triggered
|
||||
return !newAnimation.structural && !hasAnimationClasses(newAnimation.options);
|
||||
return !newAnimation.structural && !hasAnimationClasses(newAnimation);
|
||||
});
|
||||
|
||||
rules.skip.push(function(element, newAnimation, currentAnimation) {
|
||||
@@ -83,19 +82,17 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
});
|
||||
|
||||
rules.cancel.push(function(element, newAnimation, currentAnimation) {
|
||||
|
||||
|
||||
var nA = newAnimation.options.addClass;
|
||||
var nR = newAnimation.options.removeClass;
|
||||
var cA = currentAnimation.options.addClass;
|
||||
var cR = currentAnimation.options.removeClass;
|
||||
var nA = newAnimation.addClass;
|
||||
var nR = newAnimation.removeClass;
|
||||
var cA = currentAnimation.addClass;
|
||||
var cR = currentAnimation.removeClass;
|
||||
|
||||
// early detection to save the global CPU shortage :)
|
||||
if ((isUndefined(nA) && isUndefined(nR)) || (isUndefined(cA) && isUndefined(cR))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (hasMatchingClasses(nA, cR)) || (hasMatchingClasses(nR, cA));
|
||||
return hasMatchingClasses(nA, cR) || hasMatchingClasses(nR, cA);
|
||||
});
|
||||
|
||||
this.$get = ['$$rAF', '$rootScope', '$rootElement', '$document', '$$HashMap',
|
||||
@@ -167,8 +164,8 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
|
||||
var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
|
||||
|
||||
function normalizeAnimationOptions(element, options) {
|
||||
return mergeAnimationOptions(element, options, {});
|
||||
function normalizeAnimationDetails(element, animation) {
|
||||
return mergeAnimationDetails(element, animation, {});
|
||||
}
|
||||
|
||||
// IE9-11 has no method "contains" in SVG element and in Node.prototype. Bug #10259.
|
||||
@@ -337,7 +334,9 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
// this is a hard disable of all animations for the application or on
|
||||
// the element itself, therefore there is no need to continue further
|
||||
// past this point if not enabled
|
||||
var skipAnimations = !animationsEnabled || disabledElementsLookup.get(node);
|
||||
// Animations are also disabled if the document is currently hidden (page is not visible
|
||||
// to the user), because browsers slow down or do not flush calls to requestAnimationFrame
|
||||
var skipAnimations = !animationsEnabled || $document[0].hidden || disabledElementsLookup.get(node);
|
||||
var existingAnimation = (!skipAnimations && activeAnimationsLookup.get(node)) || {};
|
||||
var hasExistingAnimation = !!existingAnimation.state;
|
||||
|
||||
@@ -360,6 +359,8 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
structural: isStructural,
|
||||
element: element,
|
||||
event: event,
|
||||
addClass: options.addClass,
|
||||
removeClass: options.removeClass,
|
||||
close: close,
|
||||
options: options,
|
||||
runner: runner
|
||||
@@ -372,11 +373,10 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
close();
|
||||
return runner;
|
||||
} else {
|
||||
mergeAnimationOptions(element, existingAnimation.options, options);
|
||||
mergeAnimationDetails(element, existingAnimation, newAnimation);
|
||||
return existingAnimation.runner;
|
||||
}
|
||||
}
|
||||
|
||||
var cancelAnimationFlag = isAllowed('cancel', element, newAnimation, existingAnimation);
|
||||
if (cancelAnimationFlag) {
|
||||
if (existingAnimation.state === RUNNING_STATE) {
|
||||
@@ -391,7 +391,8 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
existingAnimation.close();
|
||||
} else {
|
||||
// this will merge the new animation options into existing animation options
|
||||
mergeAnimationOptions(element, existingAnimation.options, newAnimation.options);
|
||||
mergeAnimationDetails(element, existingAnimation, newAnimation);
|
||||
|
||||
return existingAnimation.runner;
|
||||
}
|
||||
} else {
|
||||
@@ -401,12 +402,12 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
var joinAnimationFlag = isAllowed('join', element, newAnimation, existingAnimation);
|
||||
if (joinAnimationFlag) {
|
||||
if (existingAnimation.state === RUNNING_STATE) {
|
||||
normalizeAnimationOptions(element, options);
|
||||
normalizeAnimationDetails(element, newAnimation);
|
||||
} else {
|
||||
applyGeneratedPreparationClasses(element, isStructural ? event : null, options);
|
||||
|
||||
event = newAnimation.event = existingAnimation.event;
|
||||
options = mergeAnimationOptions(element, existingAnimation.options, newAnimation.options);
|
||||
options = mergeAnimationDetails(element, existingAnimation, newAnimation);
|
||||
|
||||
//we return the same runner since only the option values of this animation will
|
||||
//be fed into the `existingAnimation`.
|
||||
@@ -417,7 +418,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
} else {
|
||||
// normalization in this case means that it removes redundant CSS classes that
|
||||
// already exist (addClass) or do not exist (removeClass) on the element
|
||||
normalizeAnimationOptions(element, options);
|
||||
normalizeAnimationDetails(element, newAnimation);
|
||||
}
|
||||
|
||||
// when the options are merged and cleaned up we may end up not having to do
|
||||
@@ -427,7 +428,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
if (!isValidAnimation) {
|
||||
// animate (from/to) can be quickly checked first, otherwise we check if any classes are present
|
||||
isValidAnimation = (newAnimation.event === 'animate' && Object.keys(newAnimation.options.to || {}).length > 0)
|
||||
|| hasAnimationClasses(newAnimation.options);
|
||||
|| hasAnimationClasses(newAnimation);
|
||||
}
|
||||
|
||||
if (!isValidAnimation) {
|
||||
@@ -457,7 +458,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
var isValidAnimation = parentElement.length > 0
|
||||
&& (animationDetails.event === 'animate'
|
||||
|| animationDetails.structural
|
||||
|| hasAnimationClasses(animationDetails.options));
|
||||
|| hasAnimationClasses(animationDetails));
|
||||
|
||||
// this means that the previous animation was cancelled
|
||||
// even if the follow-up animation is the same event
|
||||
@@ -489,7 +490,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
|
||||
// this combined multiple class to addClass / removeClass into a setClass event
|
||||
// so long as a structural event did not take over the animation
|
||||
event = !animationDetails.structural && hasAnimationClasses(animationDetails.options, true)
|
||||
event = !animationDetails.structural && hasAnimationClasses(animationDetails, true)
|
||||
? 'setClass'
|
||||
: animationDetails.event;
|
||||
|
||||
@@ -569,6 +570,13 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
return getDomNode(nodeOrElmA) === getDomNode(nodeOrElmB);
|
||||
}
|
||||
|
||||
/**
|
||||
* This fn returns false if any of the following is true:
|
||||
* a) animations on any parent element are disabled, and animations on the element aren't explicitly allowed
|
||||
* b) a parent element has an ongoing structural animation, and animateChildren is false
|
||||
* c) the element is not a child of the body
|
||||
* d) the element is not a child of the $rootElement
|
||||
*/
|
||||
function areAnimationsAllowed(element, parentElement, event) {
|
||||
var bodyElement = jqLite($document[0].body);
|
||||
var bodyElementDetected = isMatchingElement(element, bodyElement) || element[0].nodeName === 'HTML';
|
||||
@@ -602,10 +610,12 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
if (!parentAnimationDetected) {
|
||||
var parentElementDisabled = disabledElementsLookup.get(parentNode);
|
||||
|
||||
// disable animations if the user hasn't explicitly enabled animations on the
|
||||
// current element
|
||||
if (parentElementDisabled === true && elementDisabled !== false) {
|
||||
// disable animations if the user hasn't explicitly enabled animations on the
|
||||
// current element
|
||||
elementDisabled = true;
|
||||
// element is disabled via parent element, no need to check anything else
|
||||
break;
|
||||
} else if (parentElementDisabled === false) {
|
||||
elementDisabled = false;
|
||||
}
|
||||
@@ -622,25 +632,28 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
// there is no need to continue traversing at this point
|
||||
if (parentAnimationDetected && animateChildren === false) break;
|
||||
|
||||
if (!rootElementDetected) {
|
||||
// angular doesn't want to attempt to animate elements outside of the application
|
||||
// therefore we need to ensure that the rootElement is an ancestor of the current element
|
||||
rootElementDetected = isMatchingElement(parentElement, $rootElement);
|
||||
if (!rootElementDetected) {
|
||||
parentHost = parentElement.data(NG_ANIMATE_PIN_DATA);
|
||||
if (parentHost) {
|
||||
parentElement = parentHost;
|
||||
rootElementDetected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bodyElementDetected) {
|
||||
// we also need to ensure that the element is or will be apart of the body element
|
||||
// we also need to ensure that the element is or will be a part of the body element
|
||||
// otherwise it is pointless to even issue an animation to be rendered
|
||||
bodyElementDetected = isMatchingElement(parentElement, bodyElement);
|
||||
}
|
||||
|
||||
if (bodyElementDetected && rootElementDetected) {
|
||||
// If both body and root have been found, any other checks are pointless,
|
||||
// as no animation data should live outside the application
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rootElementDetected) {
|
||||
// If no rootElement is detected, check if the parentElement is pinned to another element
|
||||
parentHost = parentElement.data(NG_ANIMATE_PIN_DATA);
|
||||
if (parentHost) {
|
||||
// The pin target element becomes the next parent element
|
||||
parentElement = parentHost;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
parentElement = parentElement.parent();
|
||||
}
|
||||
|
||||
|
||||
@@ -218,7 +218,10 @@ function applyAnimationToStyles(element, options) {
|
||||
}
|
||||
}
|
||||
|
||||
function mergeAnimationOptions(element, target, newOptions) {
|
||||
function mergeAnimationDetails(element, oldAnimation, newAnimation) {
|
||||
var target = oldAnimation.options || {};
|
||||
var newOptions = newAnimation.options || {};
|
||||
|
||||
var toAdd = (target.addClass || '') + ' ' + (newOptions.addClass || '');
|
||||
var toRemove = (target.removeClass || '') + ' ' + (newOptions.removeClass || '');
|
||||
var classes = resolveElementClasses(element.attr('class'), toAdd, toRemove);
|
||||
@@ -250,6 +253,9 @@ function mergeAnimationOptions(element, target, newOptions) {
|
||||
target.removeClass = null;
|
||||
}
|
||||
|
||||
oldAnimation.addClass = target.addClass;
|
||||
oldAnimation.removeClass = target.removeClass;
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,16 +34,17 @@ angular.module('ngCookies', ['ng']).
|
||||
* The object may have following properties:
|
||||
*
|
||||
* - **path** - `{string}` - The cookie will be available only for this path and its
|
||||
* sub-paths. By default, this would be the URL that appears in your base tag.
|
||||
* sub-paths. By default, this is the URL that appears in your `<base>` tag.
|
||||
* - **domain** - `{string}` - The cookie will be available only for this domain and
|
||||
* its sub-domains. For obvious security reasons the user agent will not accept the
|
||||
* cookie if the current domain is not a sub domain or equals to the requested domain.
|
||||
* its sub-domains. For security reasons the user agent will not accept the cookie
|
||||
* if the current domain is not a sub-domain of this domain or equal to it.
|
||||
* - **expires** - `{string|Date}` - String of the form "Wdy, DD Mon YYYY HH:MM:SS GMT"
|
||||
* or a Date object indicating the exact date/time this cookie will expire.
|
||||
* - **secure** - `{boolean}` - The cookie will be available only in secured connection.
|
||||
* - **secure** - `{boolean}` - If `true`, then the cookie will only be available through a
|
||||
* secured connection.
|
||||
*
|
||||
* Note: by default the address that appears in your `<base>` tag will be used as path.
|
||||
* This is important so that cookies will be visible for all routes in case html5mode is enabled
|
||||
* Note: By default, the address that appears in your `<base>` tag will be used as the path.
|
||||
* This is important so that cookies will be visible for all routes when html5mode is enabled.
|
||||
*
|
||||
**/
|
||||
var defaults = this.defaults = {};
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "af-na",
|
||||
"localeID": "af_NA",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "af-za",
|
||||
"localeID": "af_ZA",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "af",
|
||||
"localeID": "af",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
+1
@@ -137,6 +137,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "agq-cm",
|
||||
"localeID": "agq_CM",
|
||||
"pluralCat": function(n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -137,6 +137,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "agq",
|
||||
"localeID": "agq",
|
||||
"pluralCat": function(n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -137,6 +137,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ak-gh",
|
||||
"localeID": "ak_GH",
|
||||
"pluralCat": function(n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -137,6 +137,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ak",
|
||||
"localeID": "ak",
|
||||
"pluralCat": function(n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "am-et",
|
||||
"localeID": "am_ET",
|
||||
"pluralCat": function(n, opt_precision) { var i = n | 0; if (i == 0 || n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "am",
|
||||
"localeID": "am",
|
||||
"pluralCat": function(n, opt_precision) { var i = n | 0; if (i == 0 || n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-001",
|
||||
"localeID": "ar_001",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-ae",
|
||||
"localeID": "ar_AE",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-bh",
|
||||
"localeID": "ar_BH",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-dj",
|
||||
"localeID": "ar_DJ",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-dz",
|
||||
"localeID": "ar_DZ",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-eg",
|
||||
"localeID": "ar_EG",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-eh",
|
||||
"localeID": "ar_EH",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-er",
|
||||
"localeID": "ar_ER",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-il",
|
||||
"localeID": "ar_IL",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-iq",
|
||||
"localeID": "ar_IQ",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-jo",
|
||||
"localeID": "ar_JO",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-km",
|
||||
"localeID": "ar_KM",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-kw",
|
||||
"localeID": "ar_KW",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-lb",
|
||||
"localeID": "ar_LB",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-ly",
|
||||
"localeID": "ar_LY",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-ma",
|
||||
"localeID": "ar_MA",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-mr",
|
||||
"localeID": "ar_MR",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-om",
|
||||
"localeID": "ar_OM",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-ps",
|
||||
"localeID": "ar_PS",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-qa",
|
||||
"localeID": "ar_QA",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-sa",
|
||||
"localeID": "ar_SA",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-sd",
|
||||
"localeID": "ar_SD",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-so",
|
||||
"localeID": "ar_SO",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-ss",
|
||||
"localeID": "ar_SS",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-sy",
|
||||
"localeID": "ar_SY",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-td",
|
||||
"localeID": "ar_TD",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-tn",
|
||||
"localeID": "ar_TN",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar-ye",
|
||||
"localeID": "ar_YE",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ar",
|
||||
"localeID": "ar",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -137,6 +137,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "as-in",
|
||||
"localeID": "as_IN",
|
||||
"pluralCat": function(n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -137,6 +137,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "as",
|
||||
"localeID": "as",
|
||||
"pluralCat": function(n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
+1
@@ -137,6 +137,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "asa-tz",
|
||||
"localeID": "asa_TZ",
|
||||
"pluralCat": function(n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -137,6 +137,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "asa",
|
||||
"localeID": "asa",
|
||||
"pluralCat": function(n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
+1
@@ -137,6 +137,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ast-es",
|
||||
"localeID": "ast_ES",
|
||||
"pluralCat": function(n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -137,6 +137,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "ast",
|
||||
"localeID": "ast",
|
||||
"pluralCat": function(n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "az-cyrl-az",
|
||||
"localeID": "az_Cyrl_AZ",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "az-cyrl",
|
||||
"localeID": "az_Cyrl",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "az-latn-az",
|
||||
"localeID": "az_Latn_AZ",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "az-latn",
|
||||
"localeID": "az_Latn",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "az",
|
||||
"localeID": "az",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
+1
@@ -137,6 +137,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "bas-cm",
|
||||
"localeID": "bas_CM",
|
||||
"pluralCat": function(n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -137,6 +137,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "bas",
|
||||
"localeID": "bas",
|
||||
"pluralCat": function(n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "be-by",
|
||||
"localeID": "be_BY",
|
||||
"pluralCat": function(n, opt_precision) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n % 10 >= 5 && n % 10 <= 9 || n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "be",
|
||||
"localeID": "be",
|
||||
"pluralCat": function(n, opt_precision) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n % 10 >= 5 && n % 10 <= 9 || n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
+1
@@ -137,6 +137,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "bem-zm",
|
||||
"localeID": "bem_ZM",
|
||||
"pluralCat": function(n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -137,6 +137,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "bem",
|
||||
"localeID": "bem",
|
||||
"pluralCat": function(n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
+1
@@ -137,6 +137,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "bez-tz",
|
||||
"localeID": "bez_TZ",
|
||||
"pluralCat": function(n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -137,6 +137,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "bez",
|
||||
"localeID": "bez",
|
||||
"pluralCat": function(n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Vendored
+1
@@ -119,6 +119,7 @@ $provide.value("$locale", {
|
||||
]
|
||||
},
|
||||
"id": "bg-bg",
|
||||
"localeID": "bg_BG",
|
||||
"pluralCat": function(n, opt_precision) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
|
||||
});
|
||||
}]);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user