Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| dcfcf81893 | |||
| d7cc863105 | |||
| 6e91f9c25d | |||
| 7f1b8bdfe1 | |||
| cc92da0d67 | |||
| c9bb5b9fa4 | |||
| c54921008d | |||
| 69f59f2d01 | |||
| f4fb6e0983 | |||
| a18be15137 | |||
| 05a9d3a73c | |||
| 60035f597c | |||
| 0af21a48e5 | |||
| 991a2b30e0 | |||
| fc4afd0c1b | |||
| d5109e26e4 | |||
| cf3c736b61 | |||
| b343e7a560 | |||
| 5ff5815f51 | |||
| a144c1c022 | |||
| d79f9b3693 | |||
| f56926a77d | |||
| 17e98ace48 | |||
| 752c989152 | |||
| 789790feee | |||
| fd1a93a4b0 | |||
| 7d24af110a | |||
| ac7a2daf2e | |||
| 296cfce40c | |||
| fb0225a36a | |||
| 7dd42d31a7 | |||
| 7d9a791c6a | |||
| 17ddba873b | |||
| ce49edc08b | |||
| 0f45adebea | |||
| 5419201a3c | |||
| fcf182eb13 | |||
| f582f9e57b | |||
| c3a8b5d9f1 | |||
| 6f072c8a41 | |||
| 4aa9534b0f | |||
| 627459b96d | |||
| 148cd26030 | |||
| 5ac7daea72 | |||
| b5a5623fc7 | |||
| 3e87f54922 | |||
| 810a3e429a | |||
| fc3e48980b | |||
| a48f64162d | |||
| b28f1fc3fb | |||
| 53cb1d7d40 | |||
| d80cdeb3af | |||
| 6d3329479f | |||
| d71788455d | |||
| bcd0d4d896 | |||
| 0ff10e1b56 | |||
| a7076dc0bb | |||
| 433c8714f3 | |||
| 01d8638114 | |||
| 856e300046 | |||
| 3b7f29ff63 | |||
| bdf960294a | |||
| 79d2b9a5a6 | |||
| e77f717ebf | |||
| 872bdbd343 | |||
| f1e677895e | |||
| 7ed0340488 | |||
| 5cce6e233e | |||
| 305e201b71 | |||
| 47ba51eaf6 |
+261
-50
@@ -1,3 +1,210 @@
|
||||
|
||||
<a name="1.6.0-rc.2"></a>
|
||||
# 1.6.0-rc.2 safety-insurance (2016-11-24)
|
||||
|
||||
|
||||
## Security Fixes
|
||||
- **bootstrap:** explicitly whitelist URL schemes for bootstrap. (#15427)
|
||||
([7f1b8b](https://github.com/angular/angular.js/commit/7f1b8bdfe1043871c5ead2ec602efc41e0de5e53))
|
||||
|
||||
## Bug Fixes
|
||||
- **$sce:** fix `adjustMatcher` to replace multiple '*' and '**'
|
||||
([991a2b](https://github.com/angular/angular.js/commit/991a2b30e00aed1d312e29555e356a795f9e3d62))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
- ***:** don't trigger digests after enter/leave of structural directives
|
||||
([f4fb6e](https://github.com/angular/angular.js/commit/f4fb6e0983a6a700dc4a246a913504550b55f1e9)
|
||||
[#15322](https://github.com/angular/angular.js/issues/15322))
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="1.5.9"></a>
|
||||
# 1.5.9 timeturning-lockdown (2016-11-24)
|
||||
|
||||
This is an interim release primarily to publish some security fixes, in particular a modification to
|
||||
ensure that Angular 1 can pass the linter checks for Mozilla add-ons.
|
||||
|
||||
## Security Fixes
|
||||
- **bootstrap:**
|
||||
- do not auto-bootstrap when loaded from an extension
|
||||
([6ce291](https://github.com/angular/angular.js/commit/6ce2913d99bb0dade6027ba9733295d0aa13b242))
|
||||
- explicitly whitelist URL schemes for bootstrap (#15427)
|
||||
([4edd2d](https://github.com/angular/angular.js/commit/4edd2d95c11819ece2dda6e65f95f32638fda218))
|
||||
- **$location:** throw if the path starts with double (back)slashes
|
||||
([353e3a](https://github.com/angular/angular.js/commit/353e3a6cd8b3a785b5f73a38236155621048522f))
|
||||
- **$sniffer:** don't use `history.pushState` in sandboxed Chrome Packaged Apps
|
||||
([367da5](https://github.com/angular/angular.js/commit/367da583bc12e6f5f01edf757305409cf63fb1f4))
|
||||
- **$parse:**
|
||||
- block assigning to fields of a constructor prototype
|
||||
([d7e31b](https://github.com/angular/angular.js/commit/d7e31b5dc71253edb22190a5850034934e7b778a)
|
||||
[#14939](https://github.com/angular/angular.js/issues/14939))
|
||||
- correctly escape unsafe identifier characters
|
||||
([b01460](https://github.com/angular/angular.js/commit/b014607030835358ed7887e9fd1724cdada56690))
|
||||
- **$compile:**
|
||||
- ensure that hidden input values are correct after history.back
|
||||
([6a2488](https://github.com/angular/angular.js/commit/6a24885771cf8c140b5d2895e92b321e60d86b55))
|
||||
- lower the $sce context for `src` on video, audio, source, track
|
||||
([68fb70](https://github.com/angular/angular.js/commit/68fb70ed295119d7b00c670d796c1b4186091adb))
|
||||
|
||||
|
||||
## New Features
|
||||
- **input:**
|
||||
- add support for binding to `input[range]`
|
||||
([2e7121](https://github.com/angular/angular.js/commit/2e7121b8e4dcac23f28e2375e775ca56b6baf252))
|
||||
- make support for `input[range]` opt-in
|
||||
([07b876](https://github.com/angular/angular.js/commit/07b8761233aaa3d719d94698296295e51c2a1077))
|
||||
- fix `step` validation for `input[number][ng-range-input]`
|
||||
([64f6a6](https://github.com/angular/angular.js/commit/64f6a616d401febc3f06309ed5a5efa46b131717)
|
||||
[#15257](https://github.com/angular/angular.js/issues/15257))
|
||||
- **ngMock/$httpBackend:** flush requests in any order
|
||||
([098b6f](https://github.com/angular/angular.js/commit/098b6f519a53f6348127cd4ce09bca1423cbeb1a))
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
- **$httpBackend:** complete the request on timeout
|
||||
([549edc](https://github.com/angular/angular.js/commit/549edc9d0123d50657d5a03ba0c547cb0f91727f)
|
||||
[#14969](https://github.com/angular/angular.js/issues/14969))
|
||||
- **ngOptions:** remove selected attribute from unselected options
|
||||
([d31b3a](https://github.com/angular/angular.js/commit/d31b3a65b65b73ab077026fc028ddf5b6232fba2)
|
||||
[#14892](https://github.com/angular/angular.js/issues/14892))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
- **$parse:** improve performance of assignment expressions
|
||||
([f83c3d](https://github.com/angular/angular.js/commit/f83c3dea23f910aed25dcf9b85fadf7f11a2a366))
|
||||
- **$compile:** add provider option to turn off compilation of css class and comment directives
|
||||
([775c24](https://github.com/angular/angular.js/commit/775c247085765e08845ae45ed19dd0120c61acc1))
|
||||
|
||||
|
||||
|
||||
<a name="1.6.0-rc.1"></a>
|
||||
# 1.6.0-rc.1 proximity-warning (2016-11-21)
|
||||
|
||||
## New Features
|
||||
|
||||
- **ngModelOptions:** allow options to be inherited from ancestor `ngModelOptions` ([296cfc](https://github.com/angular/angular.js/commit/296cfce40c25e9438bfa46a0eb27240707a10ffa) [#10922](https://github.com/angular/angular.js/issues/10922))
|
||||
- **$compile:** set `preAssignBindingsEnabled` to false by default ([bcd0d4](https://github.com/angular/angular.js/commit/bcd0d4d896d0dfdd988ff4f849c1d40366125858) [#15352](https://github.com/angular/angular.js/issues/15352))
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **ngModelOptions:** handle debounce of `updateOn` triggers that are not in debounce list ([789790](https://github.com/angular/angular.js/commit/789790feee4d6c5b1f5d5b18ecb0ccf6edd36fb3))
|
||||
- **ngMock/$controller:** respect `$compileProvider.preAssignBindingsEnabled()` ([7d9a79](https://github.com/angular/angular.js/commit/7d9a791c6a8c80d29d6c84afa287c81f2a307439))
|
||||
- **$location:** throw if the path starts with double (back)slashes ([4aa953](https://github.com/angular/angular.js/commit/4aa9534b0fea732d6492a2863c3ee7e077c8d004))
|
||||
- **core:** do not auto-bootstrap when loaded from an extension. ([0ff10e](https://github.com/angular/angular.js/commit/0ff10e1b56c6b7c4ac465e35c96a5886e294bac5))
|
||||
- **input[radio]:** use strict comparison when evaluating checked-ness ([5ac7da](https://github.com/angular/angular.js/commit/5ac7daea72ec31cf337d1d21b13f0d17ff33994f) [#15288](https://github.com/angular/angular.js/issues/15288))
|
||||
|
||||
|
||||
## Reverts
|
||||
|
||||
- **ngModelOptions:** allow options to be inherited from ancestor ngModelOptions ([fb0225](https://github.com/angular/angular.js/commit/fb0225a36afb08ab14a808a2fd2d2f39c13fce32))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
- **ngOptions:** avoid calls to `element.value` ([3b7f29](https://github.com/angular/angular.js/commit/3b7f29ff63e8bf02327a1430dcc2a4c83915a206))
|
||||
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- **feat($compile): set preAssignBindingsEnabled to false by default ([bcd0d4](https://github.com/angular/angular.js/commit/bcd0d4d896d0dfdd988ff4f849c1d40366125858))**:
|
||||
|
||||
Previously, `$compileProvider.preAssignBindingsEnabled` was
|
||||
set to true by default. This means bindings were pre-assigned in component
|
||||
constructors. In Angular 1.5+ the place to put the initialization logic
|
||||
relying on bindings being present is the controller `$onInit` method.
|
||||
|
||||
To migrate follow the example below:
|
||||
|
||||
Before:
|
||||
|
||||
```js
|
||||
angular.module('myApp', [])
|
||||
.component('myComponent', {
|
||||
bindings: {value: '<'},
|
||||
controller: function() {
|
||||
this.doubleValue = this.value * 2;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```js
|
||||
angular.module('myApp', [])
|
||||
.component('myComponent', {
|
||||
bindings: {value: '<'},
|
||||
controller: function() {
|
||||
this.$onInit = function() {
|
||||
this.doubleValue = this.value * 2;
|
||||
};
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
If you don't have time to migrate the code at the moment, you can flip the
|
||||
setting back to true:
|
||||
```js
|
||||
angular.module('myApp', [])
|
||||
.config(function($compileProvider) {
|
||||
$compileProvider.preAssignBindingsEnabled(true);
|
||||
})
|
||||
.component('myComponent', {
|
||||
bindings: {value: '<'},
|
||||
controller: function() {
|
||||
this.doubleValue = this.value * 2;
|
||||
}
|
||||
});
|
||||
```
|
||||
Don't do this if you're writing a library, though, as you shouldn't change
|
||||
global configuration then.
|
||||
|
||||
|
||||
- **fix(input[radio]): use strict comparison when evaluating checked-ness ([5ac7da](https://github.com/angular/angular.js/commit/5ac7daea72ec31cf337d1d21b13f0d17ff33994f))**:
|
||||
|
||||
When using input[radio], the checked status is now determined by doing
|
||||
a strict comparison between the value of the input and the ngModel.$viewValue.
|
||||
Previously, this was a non-strict comparison (==).
|
||||
|
||||
This means in the following examples the radio is no longer checked:
|
||||
|
||||
```
|
||||
<!-- this.selected = 0 -->
|
||||
<input type="radio" ng-model="$ctrl.selected" value="0" >
|
||||
|
||||
<!-- this.selected = 0; this.value = false; -->
|
||||
<input type="radio" ng-model="$ctrl.selected" ng-value="$ctrl.value" >
|
||||
```
|
||||
|
||||
The migration strategy is to convert values that matched with non-strict
|
||||
conversion so that they will match with strict conversion.
|
||||
|
||||
|
||||
- **feat(ngModelOptions): allow options to be inherited from ancestor `ngModelOptions` ([296cfc](https://github.com/angular/angular.js/commit/296cfce40c25e9438bfa46a0eb27240707a10ffa))**:
|
||||
|
||||
The programmatic API for `ngModelOptions` has changed. You must now read options
|
||||
via the `ngModelController.$options.getOption(name)` method, rather than accessing the
|
||||
option directly as a property of the `ngModelContoller.$options` object. This does not
|
||||
affect the usage in templates and only affects custom directives that might have been
|
||||
reading options for their own purposes.
|
||||
|
||||
One benefit of these changes, though, is that the `ngModelControler.$options` property
|
||||
is now guaranteed to be defined so there is no need to check before accessing.
|
||||
|
||||
So, previously:
|
||||
|
||||
```
|
||||
var myOption = ngModelController.$options && ngModelController.$options['my-option'];
|
||||
```
|
||||
|
||||
and now:
|
||||
|
||||
```
|
||||
var myOption = ngModelController.$options.getOption('my-option');
|
||||
```
|
||||
|
||||
|
||||
<a name="1.6.0-rc.0"></a>
|
||||
# 1.6.0-rc.0 bracing-vortex (2016-10-26)
|
||||
|
||||
@@ -86,7 +293,7 @@ Please read the [Sandbox Removal Blog Post](http://angularjs.blogspot.com/2016/0
|
||||
## Breaking Changes
|
||||
|
||||
### **jqLite** due to:
|
||||
- **[fc0c11](https://github.com/angular/angular.js/commit/fc0c11db845d53061430b7f05e773dcb3fb5b860))**: camelCase keys in `jqLite#data`
|
||||
- **[fc0c11](https://github.com/angular/angular.js/commit/fc0c11db845d53061430b7f05e773dcb3fb5b860)**: camelCase keys in `jqLite#data`
|
||||
|
||||
Previously, keys passed to the data method were left untouched.
|
||||
Now they are internally camelCased similarly to how jQuery handles it, i.e.
|
||||
@@ -101,7 +308,7 @@ To migrate the code follow the examples below:
|
||||
|
||||
BEFORE:
|
||||
|
||||
```
|
||||
```js
|
||||
/* 1 */
|
||||
elem.data('my-key', 2);
|
||||
elem.data('myKey', 3);
|
||||
@@ -119,7 +326,7 @@ elem.data('foo-bar'); // 1
|
||||
|
||||
AFTER:
|
||||
|
||||
```
|
||||
```js
|
||||
/* 1 */
|
||||
// Rename one of the keys as they would now map to the same data slot.
|
||||
elem.data('my-key', 2);
|
||||
@@ -152,7 +359,7 @@ Before:
|
||||
|
||||
HTML:
|
||||
|
||||
```
|
||||
```html
|
||||
// All five versions used to be equivalent.
|
||||
<div ng-style={background_color: 'blue'}></div>
|
||||
<div ng-style={'background:color': 'blue'}></div>
|
||||
@@ -163,7 +370,7 @@ HTML:
|
||||
|
||||
JS:
|
||||
|
||||
```
|
||||
```js
|
||||
// All five versions used to be equivalent.
|
||||
elem.css('background_color', 'blue');
|
||||
elem.css('background:color', 'blue');
|
||||
@@ -183,7 +390,7 @@ After:
|
||||
|
||||
HTML:
|
||||
|
||||
```
|
||||
```html
|
||||
// Previous five versions are no longer equivalent but these two still are.
|
||||
<div ng-style={'background-color': 'blue'}></div>
|
||||
<div ng-style={backgroundColor: 'blue'}></div>
|
||||
@@ -191,7 +398,7 @@ HTML:
|
||||
|
||||
JS:
|
||||
|
||||
```
|
||||
```js
|
||||
// Previous five versions are no longer equivalent but these two still are.
|
||||
elem.css('background-color', 'blue');
|
||||
elem.css('backgroundColor', 'blue');
|
||||
@@ -212,39 +419,39 @@ To migrate the code follow the example below:
|
||||
|
||||
Before:
|
||||
|
||||
```
|
||||
```js
|
||||
elem.attr(booleanAttrName, '');
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```
|
||||
```js
|
||||
elem.attr(booleanAttrName, false);
|
||||
```
|
||||
|
||||
or:
|
||||
|
||||
```
|
||||
```js
|
||||
elem.attr(booleanAttrName, null);
|
||||
```
|
||||
|
||||
- **[4e3624](https://github.com/angular/angular.js/commit/4e3624552284d0e725bf6262b2e468cd2c7682fa)**: remove the attribute for `.attr(attribute, null)`
|
||||
|
||||
Invoking `elem.attr(attributeName, null)` would set the
|
||||
`attributeName` atribute value to a string `"null"`, now it removes the
|
||||
`attributeName` attribute value to a string `"null"`, now it removes the
|
||||
attribute instead.
|
||||
|
||||
To migrate the code follow the example below:
|
||||
|
||||
Before:
|
||||
|
||||
```
|
||||
```js
|
||||
elem.attr(attributeName, null);
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```
|
||||
```js
|
||||
elem.attr(attributeName, "null");
|
||||
```
|
||||
|
||||
@@ -260,7 +467,7 @@ Before:
|
||||
|
||||
HTML:
|
||||
|
||||
```
|
||||
```html
|
||||
<select multiple>
|
||||
<option>value 1</option>
|
||||
<option>value 2</option>
|
||||
@@ -269,7 +476,7 @@ HTML:
|
||||
|
||||
JavaScript:
|
||||
|
||||
```
|
||||
```js
|
||||
var value = $element.val();
|
||||
if (value) {
|
||||
/* do something */
|
||||
@@ -280,7 +487,7 @@ After:
|
||||
|
||||
HTML:
|
||||
|
||||
```
|
||||
```html
|
||||
<select multiple>
|
||||
<option>value 1</option>
|
||||
<option>value 2</option>
|
||||
@@ -289,7 +496,7 @@ HTML:
|
||||
|
||||
JavaScript:
|
||||
|
||||
```
|
||||
```js
|
||||
var value = $element.val();
|
||||
if (value.length > 0) {
|
||||
/* do something */
|
||||
@@ -302,7 +509,7 @@ JavaScript:
|
||||
- **[7bc71a](https://github.com/angular/angular.js/commit/7bc71adc63bb6bb609b44dd2d3ea8fb0cd3f300b)**: treat synchronous validators as boolean always
|
||||
|
||||
Previously, only a literal `false` return would resolve as the
|
||||
synchronous validator failing. Now, all traditionally false JavaScript values
|
||||
synchronous validator failing. Now, all falsy JavaScript values
|
||||
are treated as failing the validator, as one would naturally expect.
|
||||
|
||||
Specifically, the values `0` (the number zero), `null`, `NaN` and `''` (the
|
||||
@@ -326,12 +533,14 @@ NgModelController and FormController methods without context.
|
||||
|
||||
For example
|
||||
|
||||
`$scope.$watch('something', myNgModelCtrl.$render)`
|
||||
```js
|
||||
$scope.$watch('something', myNgModelCtrl.$render)
|
||||
```
|
||||
|
||||
will no longer work because the `$render` method is passed without any context.
|
||||
This must now be replaced with
|
||||
|
||||
```
|
||||
```js
|
||||
$scope.$watch('something', function() {
|
||||
myNgModelCtrl.$render();
|
||||
})
|
||||
@@ -340,6 +549,8 @@ $scope.$watch('something', function() {
|
||||
or possibly by using `Function.prototype.bind` or `angular.bind`.
|
||||
|
||||
|
||||
### `aria/ngModel` due to:
|
||||
|
||||
- **[975a61](https://github.com/angular/angular.js/commit/975a6170efceb2a5e6377c57329731c0636eb8c8)**: do not overwrite the default `$isEmpty()` method for checkboxes
|
||||
|
||||
Custom `checkbox`-shaped controls (e.g. checkboxes, menuitemcheckboxes), no longer have a custom
|
||||
@@ -490,14 +701,14 @@ the `$http.defaults.jsonpCallbackParam` property, which is `"callback"` by defau
|
||||
|
||||
Before this change:
|
||||
|
||||
```
|
||||
```js
|
||||
$http.json('trusted/url?callback=JSON_CALLBACK');
|
||||
$http.json('other/trusted/url', {params: {cb:'JSON_CALLBACK'}});
|
||||
```
|
||||
|
||||
After this change:
|
||||
|
||||
```
|
||||
```js
|
||||
$http.json('trusted/url');
|
||||
$http.json('other/trusted/url', {jsonpCallbackParam:'cb'});
|
||||
```
|
||||
@@ -512,24 +723,24 @@ method.**
|
||||
|
||||
You configure this list in a module configuration block:
|
||||
|
||||
```
|
||||
```js
|
||||
appModule.config(['$sceDelegateProvider', function($sceDelegateProvider) {
|
||||
$sceDelegateProvider.resourceUrlWhiteList([
|
||||
// Allow same origin resource loads.
|
||||
'self',
|
||||
// Allow JSONP calls that match this pattern
|
||||
'https://some.dataserver.com/**.jsonp?**`
|
||||
'https://some.dataserver.com/**.jsonp?**'
|
||||
]);
|
||||
}]);
|
||||
```
|
||||
|
||||
**Explicitly trusting the URL via the `$sce.trustAsResourceUrl(url)`
|
||||
method**
|
||||
method.**
|
||||
|
||||
You can pass a trusted object instead of a string as a URL to the `$http`
|
||||
service:
|
||||
|
||||
```
|
||||
```js
|
||||
var promise = $http.jsonp($sce.trustAsResourceUrl(url));
|
||||
```
|
||||
|
||||
@@ -595,14 +806,14 @@ ancestor.
|
||||
It is possible that an `ngModelOptions` directive that does not set a property,
|
||||
has an ancestor ngModelOptions that does set this property to a value other than
|
||||
`undefined`. This would cause the `ngModel` and input controls below this `ngModelOptions`
|
||||
directive to display different behaviour. This is fixed by explictly setting the
|
||||
directive to display different behaviour. This is fixed by explicitly setting the
|
||||
property in the `ngModelOptions` to prevent it from inheriting from the ancestor.
|
||||
|
||||
For example if you had the following HTML:
|
||||
|
||||
```
|
||||
```html
|
||||
<form ng-model-options="{updateOn: 'blur'}">
|
||||
<input ng-model="...">
|
||||
<input ng-model="..." ng-model-options="{allowInvalid: true}">
|
||||
</form>
|
||||
```
|
||||
|
||||
@@ -611,9 +822,9 @@ After this change the input will inherit the option to update on blur.
|
||||
If you want the original behaviour then you will need to specify the option
|
||||
on the input as well:
|
||||
|
||||
```
|
||||
```html
|
||||
<form ng-model-options="{updateOn: 'blur'}">
|
||||
<input ng-model="..." ng-model-options="{updateOn: 'default'}">
|
||||
<input ng-model="..." ng-model-options="{updateOn: 'default', allowInvalid: true}">
|
||||
</form>
|
||||
```
|
||||
|
||||
@@ -667,7 +878,7 @@ might have unexpectd side effects in the following cases:
|
||||
|
||||
```js
|
||||
// Assuming the following component:
|
||||
.compoent('someThing', {
|
||||
.component('someThing', {
|
||||
template: '<ng-transclude><!-- Default content goes here --></ng-transclude>'
|
||||
transclude: {
|
||||
ignored: 'veryImportantContent'
|
||||
@@ -725,7 +936,7 @@ The breaking change should be rare, as it relates to incorrect API use that shou
|
||||
production apps in the first place.
|
||||
|
||||
|
||||
- **fix($compile): secure `link[href]` as a `RESOURCE_URL`s in `$sce`. ([04cad4](https://github.com/angular/angular.js/commit/04cad41d26ebaf44b5ee0c29a152d61f235f3efa))**:
|
||||
- **[04cad4](https://github.com/angular/angular.js/commit/04cad41d26ebaf44b5ee0c29a152d61f235f3efa)**: secure `link[href]` as a `RESOURCE_URL` in `$sce`
|
||||
|
||||
`link[href]` attributes are now protected via `$sce`, which prevents interpolated
|
||||
values that fail the `RESOURCE_URL` context tests from being used in interpolation.
|
||||
@@ -754,14 +965,14 @@ A common cases where stray white-space can cause problems is when
|
||||
attribute values are compared, for example in an $observer:
|
||||
|
||||
Before:
|
||||
```
|
||||
```js
|
||||
$attrs.$observe('myAttr', function(newVal) {
|
||||
if (newVal === 'false') ...
|
||||
});
|
||||
```
|
||||
|
||||
To migrate, the attribute value should be trimmed manually:
|
||||
```
|
||||
```js
|
||||
$attrs.$observe('myAttr', function(newVal) {
|
||||
if (newVal.trim() === 'false') ...
|
||||
});
|
||||
@@ -884,7 +1095,7 @@ directive attributes).
|
||||
|
||||
All owned properties of the `params` object that are not used to replace URL params, will be passed
|
||||
to `$http` as `config.params` (to be used as query parameters in the URL), even if
|
||||
`Object.prototype` has a property with same name. E.g.:
|
||||
`Object.prototype` has a property with the same name. E.g.:
|
||||
|
||||
Before:
|
||||
|
||||
@@ -901,7 +1112,7 @@ After:
|
||||
```js
|
||||
var Foo = $resource('/foo/:id');
|
||||
Foo.get({id: 42, bar: 'baz', toString: 'hmm'});
|
||||
// URL: /foo/42?bar=baz&toString=hmm
|
||||
// URL: /foo/42?bar=baz&toString=hmm
|
||||
// Note that `toString` _is_ included in the query, as expected :)
|
||||
```
|
||||
|
||||
@@ -1049,7 +1260,7 @@ a "!" prefix. For example, rather than `mydomain.com/#/a/b/c` will become
|
||||
If you actually wanted to have no hash-prefix then you should configure
|
||||
this by adding a configuration block to you application:
|
||||
|
||||
```
|
||||
```js
|
||||
appModule.config(['$locationProvider', function($locationProvider) {
|
||||
$locationProvider.hashPrefix('');
|
||||
}]);
|
||||
@@ -2919,7 +3130,7 @@ the built-in pattern validator:
|
||||
/**
|
||||
* The built-in directive will call our overwritten validator
|
||||
* (see below). We just need to update the regex.
|
||||
* The preLink fn guaranetees our observer is called first.
|
||||
* The preLink fn guarantees our observer is called first.
|
||||
*/
|
||||
if (isString(regex) && regex.length > 0) {
|
||||
regex = new RegExp('^' + regex + '$');
|
||||
@@ -3035,7 +3246,7 @@ the built-in pattern validator:
|
||||
/**
|
||||
* The built-in directive will call our overwritten validator
|
||||
* (see below). We just need to update the regex.
|
||||
* The preLink fn guaranetees our observer is called first.
|
||||
* The preLink fn guarantees our observer is called first.
|
||||
*/
|
||||
if (isString(regex) && regex.length > 0) {
|
||||
regex = new RegExp('^' + regex + '$');
|
||||
@@ -4909,7 +5120,7 @@ behavior is undefined.
|
||||
([96c61fe7](https://github.com/angular/angular.js/commit/96c61fe756d7d3db011818bf0925e3d86ffff8ce),
|
||||
[#10278](https://github.com/angular/angular.js/issues/10278))
|
||||
- **orderBy:**
|
||||
- make object-to-primtiive behavior work for objects with null prototype
|
||||
- make object-to-primitive behavior work for objects with null prototype
|
||||
([3aa57528](https://github.com/angular/angular.js/commit/3aa5752894419b4638d5c934879258fa6a1c0d07))
|
||||
- maintain order in array of objects when predicate is not provided
|
||||
([8bfeddb5](https://github.com/angular/angular.js/commit/8bfeddb5d671017f4a21b8b46334ac816710b143),
|
||||
@@ -7066,7 +7277,7 @@ Closes #7336
|
||||
|
||||
|
||||
Previously, it was possible for an action passed to $watch
|
||||
to be a string, interpreted as an angular expresison. This is no longer supported.
|
||||
to be a string, interpreted as an angular expression. This is no longer supported.
|
||||
The action now has to be a function.
|
||||
Passing an action to $watch is still optional.
|
||||
|
||||
@@ -8967,7 +9178,7 @@ The animation mock module has been renamed from `mock.animate` to `ngAnimateMock
|
||||
After:
|
||||
|
||||
```
|
||||
// POST, PUT and PATCH default headers must be specified seperately,
|
||||
// POST, PUT and PATCH default headers must be specified separately,
|
||||
// as they do not share data.
|
||||
$httpProvider.defaults.headers.post =
|
||||
$httpProvider.defaults.headers.put =
|
||||
@@ -9753,7 +9964,7 @@ There are no breaking changes in this release (promise!)
|
||||
([31c56f54](https://github.com/angular/angular.js/commit/31c56f540045b5270f5b8e235873da855caf3486),
|
||||
[#4145](https://github.com/angular/angular.js/issues/4145),
|
||||
[#3964](https://github.com/angular/angular.js/issues/3964))
|
||||
- **ngTransclude:** detect ngTranslude usage without a transclusion directive
|
||||
- **ngTransclude:** detect ngTransclude usage without a transclusion directive
|
||||
([5a1a6b86](https://github.com/angular/angular.js/commit/5a1a6b86a8dbcd8aa4fe9c59fad8d005eead686c),
|
||||
[#3759](https://github.com/angular/angular.js/issues/3759))
|
||||
|
||||
@@ -9821,7 +10032,7 @@ There are no breaking changes in this release (promise!)
|
||||
- ensure transition-property is not changed when only keyframe animations are in use
|
||||
([2df3c9f5](https://github.com/angular/angular.js/commit/2df3c9f58def9584455f7c4bfdabbd12aab58bf9),
|
||||
[#3933](https://github.com/angular/angular.js/issues/3933))
|
||||
- avoid completing the animation asynchronously unless CSS transtiions/animations are present
|
||||
- avoid completing the animation asynchronously unless CSS transitions/animations are present
|
||||
([2a63dfa6](https://github.com/angular/angular.js/commit/2a63dfa6cc7889888f4296fff2944e74ff30b3af),
|
||||
[#4023](https://github.com/angular/angular.js/issues/4023),
|
||||
[#3940](https://github.com/angular/angular.js/issues/3940))
|
||||
@@ -11463,7 +11674,7 @@ This release also contains all bug fixes available in [1.0.2](#1.0.2).
|
||||
|
||||
## Features
|
||||
|
||||
- **$http:** support custom reponseType
|
||||
- **$http:** support custom responseType
|
||||
([e0a54f6b](https://github.com/angular/angular.js/commit/e0a54f6b206dc2b6595f2bc3a17c5932e7477545),
|
||||
[#1013](https://github.com/angular/angular.js/issues/1013))
|
||||
- **$interpolate:**
|
||||
@@ -11610,14 +11821,14 @@ This release also contains all bug fixes available in [1.0.2](#1.0.2).
|
||||
- allow defining route async dependencies as promises and defer route change until all promises
|
||||
are resolved
|
||||
([885fb0dd](https://github.com/angular/angular.js/commit/885fb0dd0743859a8985c23e4d0c1855a2be711e))
|
||||
- rename template -> tempalteUrl and add support for inline templates
|
||||
- rename template -> templateUrl and add support for inline templates
|
||||
([0a6e464a](https://github.com/angular/angular.js/commit/0a6e464a93d9a1e76a624b356054ce9ca4015f55))
|
||||
- **$compile:** simplify isolate scope bindings and introduce true two-way data-binding between
|
||||
parent scope and isolate scope
|
||||
([c3a41ff9](https://github.com/angular/angular.js/commit/c3a41ff9fefe894663c4d4f40a83794521deb14f))
|
||||
- **$injector:** provide API for retrieving function annotations
|
||||
([4361efb0](https://github.com/angular/angular.js/commit/4361efb03b79e71bf0cea92b94ff377ed718bad4))
|
||||
- **$location:** add $locatonChange[start|success] event - since events are cancelable, it's now
|
||||
- **$location:** add $locationChange[start|success] event - since events are cancelable, it's now
|
||||
possible to cancel route and location changes.
|
||||
([92a2e180](https://github.com/angular/angular.js/commit/92a2e1807657c69e1372106b0727675a30f4cbd7))
|
||||
- **$rootElement:** expose application root element as $rootElement service
|
||||
@@ -11940,7 +12151,7 @@ This release also contains all bug fixes available in [1.0.2](#1.0.2).
|
||||
([06d09550](https://github.com/angular/angular.js/commit/06d0955074f79de553cc34fbf945045dc458e064))
|
||||
- **booleanAttrs:** always convert the model to boolean before setting the element property
|
||||
([dcb8e076](https://github.com/angular/angular.js/commit/dcb8e0767fbf0a7a55f3b0045fd01b2532ea5441))
|
||||
- **form:** preperly clean up when invalid widget is removed
|
||||
- **form:** properly clean up when invalid widget is removed
|
||||
([21b77ad5](https://github.com/angular/angular.js/commit/21b77ad5c231ab0e05eb89f22005f7ed8d40a6c1))
|
||||
- **ngHref:** copy even if no binding
|
||||
([2f5dba48](https://github.com/angular/angular.js/commit/2f5dba488e855bcdbb9304aa809efcb9de7b43e9))
|
||||
@@ -12082,7 +12293,7 @@ We removed two useless features:
|
||||
([ee5a5352](https://github.com/angular/angular.js/commit/ee5a5352fd4b94cedee6ef20d4bf2d43ce77e00b),
|
||||
[#806](https://github.com/angular/angular.js/issues/806))
|
||||
- **directives:**
|
||||
- **select:** multiselect failes to update view on selection insert
|
||||
- **select:** multiselect fails to update view on selection insert
|
||||
([6ecac8e7](https://github.com/angular/angular.js/commit/6ecac8e71a84792a434d21db2c245b3648c55f18))
|
||||
- **ngForm:** alias name||ngForm
|
||||
([823adb23](https://github.com/angular/angular.js/commit/823adb231995e917bc060bfa49453e2a96bac2b6))
|
||||
|
||||
+5
-2
@@ -241,7 +241,7 @@ Must be one of the following:
|
||||
semi-colons, etc)
|
||||
* **refactor**: A code change that neither fixes a bug nor adds a feature
|
||||
* **perf**: A code change that improves performance
|
||||
* **test**: Adding missing tests
|
||||
* **test**: Adding missing or correcting existing tests
|
||||
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
|
||||
generation
|
||||
|
||||
@@ -249,6 +249,8 @@ Must be one of the following:
|
||||
The scope could be anything specifying place of the commit change. For example `$location`,
|
||||
`$browser`, `$compile`, `$rootScope`, `ngHref`, `ngClick`, `ngView`, etc...
|
||||
|
||||
You can use `*` when the change affects more than a single scope.
|
||||
|
||||
### Subject
|
||||
The subject contains succinct description of the change:
|
||||
|
||||
@@ -262,7 +264,7 @@ The body should include the motivation for the change and contrast this with pre
|
||||
|
||||
### Footer
|
||||
The footer should contain any information about **Breaking Changes** and is also the place to
|
||||
reference GitHub issues that this commit **Closes**.
|
||||
[reference GitHub issues that this commit closes][closing-issues].
|
||||
|
||||
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.
|
||||
|
||||
@@ -285,6 +287,7 @@ You can find out more detailed information about contributing in the
|
||||
|
||||
[Google Closure I18N library]: https://github.com/google/closure-library/tree/master/closure/goog/i18n
|
||||
[angular-dev]: https://groups.google.com/forum/?fromgroups#!forum/angular-dev
|
||||
[closing-issues]: https://help.github.com/articles/closing-issues-via-commit-messages/
|
||||
[coc]: https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md
|
||||
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
|
||||
[contribute]: http://docs.angularjs.org/misc/contribute
|
||||
|
||||
+2
-2
@@ -302,7 +302,7 @@ module.exports = function(grunt) {
|
||||
stderr: true,
|
||||
failOnError: true
|
||||
},
|
||||
command: path.normalize('./node_modules/.bin/promises-aplus-tests tmp/promises-aplus-adapter++.js')
|
||||
command: path.normalize('./node_modules/.bin/promises-aplus-tests tmp/promises-aplus-adapter++.js --timeout 2000')
|
||||
}
|
||||
},
|
||||
|
||||
@@ -346,7 +346,7 @@ module.exports = function(grunt) {
|
||||
|
||||
grunt.registerTask('minify', ['bower', 'clean', 'build', 'minall']);
|
||||
grunt.registerTask('webserver', ['connect:devserver']);
|
||||
grunt.registerTask('package', ['bower', 'validate-angular-files', 'clean', 'buildall', 'minall', 'collect-errors', 'docs', 'copy', 'write', 'compress']);
|
||||
grunt.registerTask('package', ['bower', 'validate-angular-files', 'clean', 'buildall', 'minall', 'collect-errors', 'write', 'docs', 'copy', 'compress']);
|
||||
grunt.registerTask('ci-checks', ['ddescribe-iit', 'merge-conflict', 'eslint']);
|
||||
grunt.registerTask('default', ['package']);
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ AngularJS [ as your template language and lets you extend HTML’s
|
||||
use good old HTML (or HAML, Jade/Pug and friends!) as your template language and lets you extend HTML’s
|
||||
syntax to express your application’s components clearly and succinctly. It automatically
|
||||
synchronizes data from your UI (view) with your JavaScript objects (model) through 2-way data
|
||||
binding. To help you structure your application better and make it easy to test, AngularJS teaches
|
||||
|
||||
+1
@@ -70,6 +70,7 @@ var angularFiles = {
|
||||
'src/ng/directive/ngInit.js',
|
||||
'src/ng/directive/ngList.js',
|
||||
'src/ng/directive/ngModel.js',
|
||||
'src/ng/directive/ngModelOptions.js',
|
||||
'src/ng/directive/ngNonBindable.js',
|
||||
'src/ng/directive/ngOptions.js',
|
||||
'src/ng/directive/ngPluralize.js',
|
||||
|
||||
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
@@ -22,7 +22,7 @@ ul.doc-example > li.doc-example-heading {
|
||||
span.nojsfiddle {
|
||||
float: right;
|
||||
font-size: 14px;
|
||||
margin-right:10px;
|
||||
margin-right: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ form.jsfiddle button {
|
||||
color: #7989D6;
|
||||
border-color: #7989D6;
|
||||
-moz-border-radius: 8px;
|
||||
-webkit-border-radius:8px;
|
||||
-webkit-border-radius: 8px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
|
||||
+229
-215
@@ -1,21 +1,21 @@
|
||||
html, body {
|
||||
position:relative;
|
||||
height:100%;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#wrapper {
|
||||
min-height:100%;
|
||||
position:relative;
|
||||
padding-bottom:120px;
|
||||
min-height: 100%;
|
||||
position: relative;
|
||||
padding-bottom: 120px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
border-top:20px solid white;
|
||||
position:absolute;
|
||||
bottom:0;
|
||||
left:0;
|
||||
right:0;
|
||||
z-index:100;
|
||||
border-top: 20px solid white;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
padding-top: 2em;
|
||||
background-color: #333;
|
||||
color: white;
|
||||
@@ -23,20 +23,20 @@ html, body {
|
||||
}
|
||||
|
||||
.header-fixed {
|
||||
position:fixed;
|
||||
z-index:1000;
|
||||
top:0;
|
||||
left:0;
|
||||
right:0;
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.header-branding {
|
||||
min-height:41px!important;
|
||||
min-height: 41px !important;
|
||||
}
|
||||
|
||||
.docs-navbar-primary {
|
||||
border-radius:0!important;
|
||||
margin-bottom:0!important;
|
||||
border-radius: 0 !important;
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
/* Logo */
|
||||
@@ -49,7 +49,7 @@ h1,h2,h3,h4,h5,h6 {
|
||||
}
|
||||
|
||||
.subnav-body {
|
||||
margin:70px 0 20px;
|
||||
margin: 70px 0 20px;
|
||||
}
|
||||
|
||||
.header .brand {
|
||||
@@ -58,32 +58,32 @@ h1,h2,h3,h4,h5,h6 {
|
||||
}
|
||||
|
||||
.header .brand img {
|
||||
margin-top:5px;
|
||||
margin-top: 5px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.docs-search {
|
||||
margin:10px 0;
|
||||
padding:4px 0 4px 20px;
|
||||
background:white;
|
||||
border-radius:20px;
|
||||
vertical-align:middle;
|
||||
margin: 10px 0;
|
||||
padding: 4px 0 4px 20px;
|
||||
background: white;
|
||||
border-radius: 20px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.docs-search > .search-query {
|
||||
font-size:14px;
|
||||
border:0;
|
||||
width:80%;
|
||||
color:#555;
|
||||
font-size: 14px;
|
||||
border: 0;
|
||||
width: 80%;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.docs-search > .search-icon {
|
||||
font-size:15px;
|
||||
margin-right:10px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.docs-search > .search-query:focus {
|
||||
outline:0;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
/* end: Logo */
|
||||
@@ -101,31 +101,31 @@ h1,h2,h3,h4,h5,h6 {
|
||||
.naked-list,
|
||||
.naked-list ul,
|
||||
.naked-list li {
|
||||
list-style:none;
|
||||
margin:0;
|
||||
padding:0;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.nav-index-section a {
|
||||
font-weight:bold;
|
||||
font-weight: bold;
|
||||
font-family: "Open Sans";
|
||||
color:black!important;
|
||||
margin-top:10px;
|
||||
display:block;
|
||||
color: black !important;
|
||||
margin-top: 10px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.nav-index-group {
|
||||
margin-bottom:20px!important;
|
||||
margin-bottom: 20px !important;
|
||||
}
|
||||
|
||||
.nav-index-group-heading {
|
||||
color:#6F0101;
|
||||
font-weight:bold;
|
||||
font-size:1.2em;
|
||||
padding:0;
|
||||
margin:0;
|
||||
border-bottom:1px solid #aaa;
|
||||
margin-bottom:5px;
|
||||
color: #6F0101;
|
||||
font-weight: bold;
|
||||
font-size: 1.2em;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border-bottom: 1px soild #aaa;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.nav-index-group .nav-index-listing.current a {
|
||||
@@ -133,58 +133,58 @@ h1,h2,h3,h4,h5,h6 {
|
||||
}
|
||||
|
||||
.nav-breadcrumb {
|
||||
margin:4px 0;
|
||||
padding:0;
|
||||
margin: 4px 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.nav-breadcrumb-entry {
|
||||
font-family: "Open Sans";
|
||||
padding:0;
|
||||
margin:0;
|
||||
font-size:18px;
|
||||
display:inline-block;
|
||||
vertical-align:middle;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.nav-breadcrumb-entry > .divider {
|
||||
color:#555;
|
||||
display:inline-block;
|
||||
padding-left:8px;
|
||||
color: #555;
|
||||
display: inline-block;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.nav-breadcrumb-entry > span,
|
||||
.nav-breadcrumb-entry > a {
|
||||
color:#6F0101;
|
||||
color: #6F0101;
|
||||
}
|
||||
|
||||
.step-list > li:nth-child(1) {
|
||||
padding-left:20px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.step-list > li:nth-child(2) {
|
||||
padding-left:40px;
|
||||
padding-left: 40px;
|
||||
}
|
||||
|
||||
.step-list > li:nth-child(3) {
|
||||
padding-left:60px;
|
||||
padding-left: 60px;
|
||||
}
|
||||
|
||||
.api-profile-header-heading {
|
||||
margin:0;
|
||||
padding:0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.api-profile-header-structure,
|
||||
.api-profile-header-structure a {
|
||||
font-family: "Open Sans";
|
||||
font-weight:bold;
|
||||
color:#999;
|
||||
font-weight: bold;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.api-profile-section {
|
||||
margin-top:30px;
|
||||
padding-top:30px;
|
||||
border-top:1px solid #aaa;
|
||||
margin-top: 30px;
|
||||
padding-top: 30px;
|
||||
border-top: 1px solid #aaa;
|
||||
}
|
||||
|
||||
pre {
|
||||
@@ -196,23 +196,23 @@ pre {
|
||||
.aside-nav a:link,
|
||||
.aside-nav a:visited,
|
||||
.aside-nav a:active {
|
||||
color:#999;
|
||||
color: #999;
|
||||
}
|
||||
.aside-nav a:hover {
|
||||
color:black;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.api-profile-description > p:first-child {
|
||||
margin:15px 0;
|
||||
font-size:18px;
|
||||
margin: 15px 0;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
p > code,
|
||||
code.highlighted {
|
||||
background:#f4f4f4;
|
||||
border-radius:5px;
|
||||
padding:2px 5px;
|
||||
color:maroon;
|
||||
background: #f4f4f4;
|
||||
border-radius: 5px;
|
||||
padding: 2px 5px;
|
||||
color: maroon;
|
||||
}
|
||||
|
||||
ul + p {
|
||||
@@ -220,8 +220,8 @@ ul + p {
|
||||
}
|
||||
|
||||
.docs-version-jump {
|
||||
min-width:100%;
|
||||
max-width:100%;
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.picker {
|
||||
@@ -267,14 +267,14 @@ ul + p {
|
||||
}
|
||||
|
||||
.picker:after {
|
||||
content:"";
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 8%;
|
||||
top: 50%;
|
||||
z-index: 0;
|
||||
color: #999;
|
||||
width: 0;
|
||||
margin-top:-2px;
|
||||
margin-top: -2px;
|
||||
height: 0;
|
||||
border-top: 6px solid;
|
||||
border-right: 6px solid transparent;
|
||||
@@ -287,32 +287,32 @@ iframe.example {
|
||||
}
|
||||
|
||||
.search-results-frame {
|
||||
clear:both;
|
||||
display:table;
|
||||
width:100%;
|
||||
clear: both;
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.search-results.ng-hide {
|
||||
display:none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.search-results-container {
|
||||
padding-bottom:1em;
|
||||
border-top:1px solid #111;
|
||||
background:#181818;
|
||||
box-shadow:inset 0 0 10px #111;
|
||||
padding-bottom: 1em;
|
||||
border-top: 1px solid #111;
|
||||
background: #181818;
|
||||
box-shadow: inset 0 0 10px #111;
|
||||
}
|
||||
|
||||
.search-results-container .search-results-group {
|
||||
vertical-align:top;
|
||||
padding:10px 10px;
|
||||
display:inline-block;
|
||||
vertical-align: top;
|
||||
padding: 10px 10px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.search-results-group-heading {
|
||||
font-family: "Open Sans";
|
||||
padding-left:10px;
|
||||
color:white;
|
||||
padding-left: 10px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.search-results-group .search-results {
|
||||
@@ -321,14 +321,23 @@ iframe.example {
|
||||
}
|
||||
|
||||
.search-results-frame > .search-results-group:first-child > .search-results {
|
||||
border-right:1px solid #222;
|
||||
border-right: 1px solid #222;
|
||||
}
|
||||
|
||||
.search-results-group.col-group-api {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.search-results-group.col-group-api { width:30%; }
|
||||
.search-results-group.col-group-guide,
|
||||
.search-results-group.col-group-tutorial { width:20%; }
|
||||
.search-results-group.col-group-tutorial {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.search-results-group.col-group-misc,
|
||||
.search-results-group.col-group-error { width:15%; float: right; }
|
||||
.search-results-group.col-group-error {
|
||||
width: 15%;
|
||||
float: right;
|
||||
}
|
||||
|
||||
@supports ((column-count: 2) or (-moz-column-count: 2) or (-ms-column-count: 2) or (-webkit-column-count: 2)) {
|
||||
.search-results-group.col-group-api .search-results {
|
||||
@@ -371,14 +380,14 @@ iframe.example {
|
||||
}
|
||||
|
||||
.search-results-group.col-group-api .search-result {
|
||||
width:48%;
|
||||
display:inline-block;
|
||||
width: 48%;
|
||||
display: inline-block;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
@supports ((column-count: 2) or (-moz-column-count: 2) or (-ms-column-count: 2) or (-webkit-column-count: 2)) {
|
||||
.search-results-group.col-group-api .search-result {
|
||||
width:auto;
|
||||
width: auto;
|
||||
display: list-item;
|
||||
}
|
||||
}
|
||||
@@ -395,135 +404,135 @@ iframe.example {
|
||||
border-top-right-radius: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
width: 200px;
|
||||
box-shadow:0 0 10px #111;
|
||||
box-shadow: 0 0 10px #111;
|
||||
}
|
||||
|
||||
.variables-matrix {
|
||||
border:1px solid #ddd;
|
||||
width:100%;
|
||||
margin:10px 0;
|
||||
border: 1px solid #ddd;
|
||||
width: 100%;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.variables-matrix td,
|
||||
.variables-matrix th {
|
||||
padding:10px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.variables-matrix td {
|
||||
border-top:1px solid #eee;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
|
||||
.variables-matrix td + td,
|
||||
.variables-matrix th + th {
|
||||
border-left:1px solid #eee;
|
||||
border-left: 1px solid #eee;
|
||||
}
|
||||
|
||||
.variables-matrix tr:nth-child(even) td {
|
||||
background:#f5f5f5;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.variables-matrix th {
|
||||
background:#f1f1f1;
|
||||
background: #f1f1f1;
|
||||
}
|
||||
|
||||
.sup-header {
|
||||
padding-top:10px;
|
||||
padding-bottom:5px;
|
||||
background:rgba(245,245,245,0.88);
|
||||
box-shadow:0 0 2px #999;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 5px;
|
||||
background: rgba(245,245,245,0.88);
|
||||
box-shadow: 0 0 2px #999;
|
||||
}
|
||||
|
||||
.main-body-grid {
|
||||
margin-top:120px;
|
||||
position:relative;
|
||||
margin-top: 120px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.main-body-grid > .grid-left,
|
||||
.main-body-grid > .grid-right {
|
||||
padding:20px 0;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.main-body-grid > .grid-left {
|
||||
position:fixed;
|
||||
top:120px;
|
||||
bottom:0;
|
||||
overflow:auto;
|
||||
position: fixed;
|
||||
top: 120px;
|
||||
bottom: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.main-header-grid > .grid-left,
|
||||
.main-body-grid > .grid-left {
|
||||
width:260px;
|
||||
width: 260px;
|
||||
}
|
||||
|
||||
.main-header-grid > .grid-right,
|
||||
.main-body-grid > .grid-right {
|
||||
margin-left:270px;
|
||||
position:relative;
|
||||
margin-left: 270px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.main-header-grid > .grid-left {
|
||||
float:left;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.main-body-grid .side-navigation {
|
||||
position:relative;
|
||||
padding-bottom:120px;
|
||||
position: relative;
|
||||
padding-bottom: 120px;
|
||||
}
|
||||
|
||||
.main-body-grid .side-navigation.ng-hide {
|
||||
display:block!important;
|
||||
display: block!important;
|
||||
}
|
||||
|
||||
.variables-matrix td {
|
||||
vertical-align:top;
|
||||
padding:5px;
|
||||
vertical-align: top;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.type-hint {
|
||||
display:inline-block;
|
||||
display: inline-block;
|
||||
background: gray;
|
||||
}
|
||||
|
||||
.variables-matrix .type-hint {
|
||||
text-align:center;
|
||||
min-width:60px;
|
||||
margin:1px 5px;
|
||||
text-align: center;
|
||||
min-width: 60px;
|
||||
margin: 1px 5px;
|
||||
}
|
||||
|
||||
.type-hint + .type-hint {
|
||||
margin-top:5px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.type-hint-expression {
|
||||
background:purple;
|
||||
background: purple;
|
||||
}
|
||||
|
||||
.type-hint-date {
|
||||
background:pink;
|
||||
background: pink;
|
||||
}
|
||||
|
||||
.type-hint-string {
|
||||
background:#3a87ad;
|
||||
background: #3a87ad;
|
||||
}
|
||||
|
||||
.type-hint-function {
|
||||
background:green;
|
||||
background: green;
|
||||
}
|
||||
|
||||
.type-hint-object {
|
||||
background:#999;
|
||||
background: #999;
|
||||
}
|
||||
|
||||
.type-hint-array {
|
||||
background:#F90;;
|
||||
background: #F90;;
|
||||
}
|
||||
|
||||
.type-hint-boolean {
|
||||
background:rgb(18, 131, 39);
|
||||
background: rgb(18, 131, 39);
|
||||
}
|
||||
|
||||
.type-hint-number {
|
||||
background:rgb(189, 63, 66);
|
||||
background: rgb(189, 63, 66);
|
||||
}
|
||||
|
||||
.type-hint-regexp {
|
||||
@@ -535,19 +544,19 @@ iframe.example {
|
||||
}
|
||||
|
||||
.runnable-example-frame {
|
||||
width:100%;
|
||||
height:300px;
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius:5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.runnable-example-tabs {
|
||||
margin-top:10px;
|
||||
margin-bottom:20px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.tutorial-nav {
|
||||
display:block;
|
||||
display: block;
|
||||
}
|
||||
|
||||
h1 + ul, h1 + ul > li,
|
||||
@@ -556,23 +565,23 @@ ul.tutorial-nav, ul.tutorial-nav > li,
|
||||
.usage > ul, .usage > ul > li,
|
||||
ul.methods, ul.methods > li,
|
||||
ul.events, ul.events > li {
|
||||
list-style:none;
|
||||
padding:0;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
border-top:1px solid #eee;
|
||||
margin-top:30px;
|
||||
padding-top:30px;
|
||||
border-top: 1px solid #eee;
|
||||
margin-top: 30px;
|
||||
padding-top: 30px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin-top:20px;
|
||||
padding-top:20px;
|
||||
margin-top: 20px;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
color:#428bca;
|
||||
color: #428bca;
|
||||
position: relative;
|
||||
width: auto;
|
||||
display: inline-block;
|
||||
@@ -595,26 +604,26 @@ h4 {
|
||||
}
|
||||
|
||||
.btn + .btn {
|
||||
margin-left:10px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.btn:hover, .btn:focus {
|
||||
color: black!important;
|
||||
border: 1px solid #ddd!important;
|
||||
background: white!important;
|
||||
color: black !important;
|
||||
border: 1px solid #ddd !important;
|
||||
background: white !important;
|
||||
}
|
||||
|
||||
.view-source, .improve-docs {
|
||||
position:relative;
|
||||
z-index:100;
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.view-source {
|
||||
margin-right:10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.improve-docs {
|
||||
float:right;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.return-arguments,
|
||||
@@ -622,17 +631,17 @@ h4 {
|
||||
.return-arguments th + th,
|
||||
.return-arguments td,
|
||||
.return-arguments td + td {
|
||||
border-radius:0;
|
||||
border:0;
|
||||
border-radius: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.return-arguments td:first-child {
|
||||
width:100px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
ul.methods > li,
|
||||
ul.events > li {
|
||||
margin-bottom:40px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.definition-table td {
|
||||
@@ -653,6 +662,11 @@ ul.events > li {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.deprecation .title {
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 769px) {
|
||||
[ng-include="partialPath"].ng-hide {
|
||||
display: block !important;
|
||||
@@ -671,66 +685,66 @@ ul.events > li {
|
||||
|
||||
@media only screen and (max-width : 768px) {
|
||||
.picker, .picker select {
|
||||
width:auto;
|
||||
display:block;
|
||||
margin-bottom:10px;
|
||||
width: auto;
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.docs-navbar-primary {
|
||||
text-align:center;
|
||||
text-align: center;
|
||||
}
|
||||
.main-body-grid {
|
||||
margin-top:0;
|
||||
margin-top: 0;
|
||||
}
|
||||
.main-header-grid > .grid-left,
|
||||
.main-body-grid > .grid-left,
|
||||
.main-header-grid > .grid-right,
|
||||
.main-body-grid > .grid-right {
|
||||
display:block;
|
||||
float:none;
|
||||
width:auto!important;
|
||||
margin-left:0;
|
||||
display: block;
|
||||
float: none;
|
||||
width: auto !important;
|
||||
margin-left: 0;
|
||||
}
|
||||
.main-body-grid > .grid-left,
|
||||
.header-fixed, .footer {
|
||||
position:static!important;
|
||||
position: static !important;
|
||||
}
|
||||
.main-body-grid > .grid-left {
|
||||
background:#efefef;
|
||||
margin-left:-1em;
|
||||
margin-right:-1em;
|
||||
padding:1em;
|
||||
width:auto!important;
|
||||
overflow:visible;
|
||||
background: #efefef;
|
||||
margin-left: -1em;
|
||||
margin-right: -1em;
|
||||
padding: 1em;
|
||||
width: auto !important;
|
||||
overflow: visible;
|
||||
}
|
||||
.main-header-grid > .grid-right,
|
||||
.main-body-grid > .grid-right {
|
||||
margin-left:0;
|
||||
margin-left: 0;
|
||||
}
|
||||
.main-body-grid .side-navigation {
|
||||
display:block!important;
|
||||
padding-bottom:50px;
|
||||
display: block !important;
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
.main-body-grid .side-navigation.ng-hide {
|
||||
display:none!important;
|
||||
display: none !important;
|
||||
}
|
||||
.nav-index-group .nav-index-listing {
|
||||
display:inline-block;
|
||||
padding:3px 0;
|
||||
display: inline-block;
|
||||
padding: 3px 0;
|
||||
}
|
||||
.nav-index-group .nav-index-listing:not(.nav-index-section):after {
|
||||
padding-right:5px;
|
||||
margin-left:-3px;
|
||||
content:", ";
|
||||
padding-right: 5px;
|
||||
margin-left: -3px;
|
||||
content: ", ";
|
||||
}
|
||||
.nav-index-group .nav-index-listing:last-child:after {
|
||||
content:"";
|
||||
display:inline-block;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
}
|
||||
.nav-index-group .nav-index-section {
|
||||
display:block;
|
||||
display: block;
|
||||
}
|
||||
.toc-toggle {
|
||||
margin-bottom:20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.toc-close {
|
||||
position: absolute;
|
||||
@@ -742,16 +756,16 @@ ul.events > li {
|
||||
background: #eee;
|
||||
border-radius: 5px;
|
||||
width: 100%;
|
||||
border:1px solid #ddd;
|
||||
box-shadow:0 0 10px #bbb;
|
||||
border: 1px solid #ddd;
|
||||
box-shadow: 0 0 10px #bbb;
|
||||
}
|
||||
.navbar-brand {
|
||||
float:none;
|
||||
text-align:center;
|
||||
float: none;
|
||||
text-align: center;
|
||||
}
|
||||
.search-results-container {
|
||||
padding-bottom:60px;
|
||||
text-align:left;
|
||||
padding-bottom: 60px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.search-results-frame > .search-results-group:first-child > .search-results {
|
||||
@@ -759,11 +773,11 @@ ul.events > li {
|
||||
}
|
||||
|
||||
.search-results-group {
|
||||
float:none!important;
|
||||
display:block!important;
|
||||
width:auto!important;
|
||||
border:0!important;
|
||||
padding:0!important;
|
||||
float: none !important;
|
||||
display: block !important;
|
||||
width: auto !important;
|
||||
border: 0! important;
|
||||
padding: 0! important;
|
||||
}
|
||||
|
||||
@supports ((column-count: 2) or (-moz-column-count: 2) or (-ms-column-count: 2) or (-webkit-column-count: 2)) {
|
||||
@@ -776,15 +790,15 @@ ul.events > li {
|
||||
}
|
||||
|
||||
.search-results-group .search-result {
|
||||
display:inline-block!important;
|
||||
padding:0 5px;
|
||||
width:auto!important;
|
||||
display: inline-block !important;
|
||||
padding: 0 5px;
|
||||
width: auto !important;
|
||||
text-indent: initial;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.search-results-group .search-result:after {
|
||||
content:", ";
|
||||
content: ", ";
|
||||
}
|
||||
|
||||
.search-results-group .search-result:before {
|
||||
@@ -802,10 +816,10 @@ ul.events > li {
|
||||
}
|
||||
|
||||
#wrapper {
|
||||
padding-bottom:0px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
iframe[name="example-anchoringExample"] {
|
||||
height:400px;
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
Executable → Regular
|
Before Width: | Height: | Size: 212 B After Width: | Height: | Size: 212 B |
@@ -6,7 +6,6 @@ angular.module('docsApp', [
|
||||
'ngSanitize',
|
||||
'ngAnimate',
|
||||
'DocsController',
|
||||
'versionsData',
|
||||
'pagesData',
|
||||
'navData',
|
||||
'directives',
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('DocsController', [])
|
||||
angular.module('DocsController', ['currentVersionData'])
|
||||
|
||||
.controller('DocsController', [
|
||||
'$scope', '$rootScope', '$location', '$window', '$cookies',
|
||||
'NG_PAGES', 'NG_NAVIGATION', 'NG_VERSION',
|
||||
'NG_PAGES', 'NG_NAVIGATION', 'CURRENT_NG_VERSION',
|
||||
function($scope, $rootScope, $location, $window, $cookies,
|
||||
NG_PAGES, NG_NAVIGATION, NG_VERSION) {
|
||||
|
||||
$scope.docsVersion = NG_VERSION.isSnapshot ? 'snapshot' : NG_VERSION.version;
|
||||
NG_PAGES, NG_NAVIGATION, CURRENT_NG_VERSION) {
|
||||
|
||||
$scope.navClass = function(navItem) {
|
||||
return {
|
||||
@@ -60,8 +58,8 @@ angular.module('DocsController', [])
|
||||
Initialize
|
||||
***********************************/
|
||||
|
||||
$scope.versionNumber = angular.version.full;
|
||||
$scope.version = angular.version.full + ' ' + angular.version.codeName;
|
||||
$scope.versionNumber = CURRENT_NG_VERSION.full;
|
||||
$scope.version = CURRENT_NG_VERSION.full + ' ' + CURRENT_NG_VERSION.codeName;
|
||||
$scope.loading = 0;
|
||||
|
||||
|
||||
|
||||
@@ -202,13 +202,13 @@ angular.module('search', [])
|
||||
};
|
||||
})
|
||||
|
||||
.directive('docsSearchInput', ['$document',function($document) {
|
||||
.directive('docsSearchInput', ['$document', function($document) {
|
||||
return function(scope, element, attrs) {
|
||||
var ESCAPE_KEY_KEYCODE = 27,
|
||||
FORWARD_SLASH_KEYCODE = 191;
|
||||
angular.element($document[0].body).on('keydown', function(event) {
|
||||
var input = element[0];
|
||||
if (event.keyCode === FORWARD_SLASH_KEYCODE && window.document.activeElement !== input) {
|
||||
if (event.keyCode === FORWARD_SLASH_KEYCODE && $document[0].activeElement !== input) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
input.focus();
|
||||
|
||||
+36
-31
@@ -1,37 +1,42 @@
|
||||
'use strict';
|
||||
/* global console */
|
||||
|
||||
angular.module('versions', [])
|
||||
angular.module('versions', ['currentVersionData', 'allVersionsData'])
|
||||
|
||||
.controller('DocsVersionsCtrl', ['$scope', '$location', '$window', 'NG_VERSIONS', function($scope, $location, $window, NG_VERSIONS) {
|
||||
$scope.docs_version = NG_VERSIONS[0];
|
||||
$scope.docs_versions = NG_VERSIONS;
|
||||
.directive('versionPicker', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: true,
|
||||
controllerAs: '$ctrl',
|
||||
controller: ['$location', '$window', 'CURRENT_NG_VERSION', 'ALL_NG_VERSIONS',
|
||||
/** @this VersionPickerController */
|
||||
function VersionPickerController($location, $window, CURRENT_NG_VERSION, ALL_NG_VERSIONS) {
|
||||
|
||||
for (var i = 0, minor = NaN; i < NG_VERSIONS.length; i++) {
|
||||
var version = NG_VERSIONS[i];
|
||||
if (version.isSnapshot) {
|
||||
version.isLatest = true;
|
||||
continue;
|
||||
var versionStr = CURRENT_NG_VERSION.isSnapshot ? 'snapshot' : CURRENT_NG_VERSION.version;
|
||||
|
||||
this.versions = ALL_NG_VERSIONS;
|
||||
this.selectedVersion = find(ALL_NG_VERSIONS, function(value) { return value.version.version === versionStr; });
|
||||
|
||||
this.jumpToDocsVersion = function(value) {
|
||||
var currentPagePath = $location.path().replace(/\/$/, '');
|
||||
$window.location = value.docsUrl + currentPagePath;
|
||||
};
|
||||
}],
|
||||
template:
|
||||
'<div class="picker version-picker">' +
|
||||
' <select ng-options="v as v.label group by v.group for v in $ctrl.versions"' +
|
||||
' ng-model="$ctrl.selectedVersion"' +
|
||||
' ng-change="$ctrl.jumpToDocsVersion($ctrl.selectedVersion)"' +
|
||||
' class="docs-version-jump">' +
|
||||
' </select>' +
|
||||
'</div>'
|
||||
};
|
||||
|
||||
function find(collection, matcherFn) {
|
||||
for (var i = 0, ii = collection.length; i < ii; ++i) {
|
||||
if (matcherFn(collection[i])) {
|
||||
return collection[i];
|
||||
}
|
||||
}
|
||||
// NaN will give false here
|
||||
if (minor <= version.minor) {
|
||||
continue;
|
||||
}
|
||||
version.isLatest = true;
|
||||
minor = version.minor;
|
||||
}
|
||||
|
||||
$scope.getGroupName = function(v) {
|
||||
return v.isLatest ? 'Latest' : ('v' + v.major + '.' + v.minor + '.x');
|
||||
};
|
||||
|
||||
$scope.jumpToDocsVersion = function(version) {
|
||||
var currentPagePath = $location.path().replace(/\/$/, ''),
|
||||
url = '';
|
||||
if (version.isOldDocsUrl) {
|
||||
url = version.docsUrl;
|
||||
} else {
|
||||
url = version.docsUrl + currentPagePath;
|
||||
}
|
||||
$window.location = url;
|
||||
};
|
||||
}]);
|
||||
});
|
||||
|
||||
@@ -6,8 +6,13 @@ describe('DocsController', function() {
|
||||
angular.module('fake', [])
|
||||
.value('$cookies', {})
|
||||
.value('NG_PAGES', {})
|
||||
.value('NG_NAVIGATION', {})
|
||||
.value('NG_VERSION', {});
|
||||
.value('NG_NAVIGATION', {});
|
||||
|
||||
angular.module('currentVersionData', [])
|
||||
.value('CURRENT_NG_VERSION', {});
|
||||
|
||||
angular.module('allVersionsData', [])
|
||||
.value('ALL_NG_VERSIONS', {});
|
||||
|
||||
beforeEach(module('fake', 'DocsController'));
|
||||
beforeEach(inject(function($rootScope, $controller) {
|
||||
|
||||
@@ -52,10 +52,12 @@ module.exports = new Package('angularjs', [
|
||||
|
||||
|
||||
.config(function(parseTagsProcessor) {
|
||||
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/deprecated')); // this will override the jsdoc version
|
||||
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/tutorial-step'));
|
||||
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/sortOrder'));
|
||||
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/installation'));
|
||||
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/this'));
|
||||
|
||||
})
|
||||
|
||||
|
||||
@@ -65,7 +67,11 @@ module.exports = new Package('angularjs', [
|
||||
|
||||
|
||||
.config(function(templateFinder, renderDocsProcessor, gitData) {
|
||||
templateFinder.templateFolders.unshift(path.resolve(packagePath, 'templates'));
|
||||
// We are completely overwriting the folders
|
||||
templateFinder.templateFolders.length = 0;
|
||||
templateFinder.templateFolders.unshift(path.resolve(packagePath, 'templates/examples'));
|
||||
templateFinder.templateFolders.unshift(path.resolve(packagePath, 'templates/ngdoc'));
|
||||
templateFinder.templateFolders.unshift(path.resolve(packagePath, 'templates/app'));
|
||||
renderDocsProcessor.extraData.git = gitData;
|
||||
})
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
var _ = require('lodash');
|
||||
var exec = require('shelljs').exec;
|
||||
var semver = require('semver');
|
||||
|
||||
/**
|
||||
* @dgProcessor generateVersionDocProcessor
|
||||
@@ -12,23 +13,96 @@ module.exports = function generateVersionDocProcessor(gitData) {
|
||||
return {
|
||||
$runAfter: ['generatePagesDataProcessor'],
|
||||
$runBefore: ['rendering-docs'],
|
||||
// the blacklist is to remove rogue builds that are in npm but not on code.angularjs.org
|
||||
blacklist: ['1.3.4-build.3588'],
|
||||
$process: function(docs) {
|
||||
|
||||
var versionDoc = {
|
||||
docType: 'versions-data',
|
||||
id: 'versions-data',
|
||||
template: 'versions-data.template.js',
|
||||
outputPath: 'js/versions-data.js',
|
||||
currentVersion: gitData.version
|
||||
};
|
||||
var blacklist = this.blacklist;
|
||||
var currentVersion = require('../../../build/version.json');
|
||||
var output = exec('npm info angular versions --json', { silent: true }).stdout;
|
||||
var allVersions = processAllVersionsResponse(JSON.parse(output));
|
||||
|
||||
versionDoc.versions = _(gitData.versions)
|
||||
.filter(function(version) { return version.major > 0; })
|
||||
.push(gitData.version)
|
||||
.reverse()
|
||||
.value();
|
||||
docs.push({
|
||||
docType: 'current-version-data',
|
||||
id: 'current-version-data',
|
||||
template: 'angular-service.template.js',
|
||||
outputPath: 'js/current-version-data.js',
|
||||
ngModuleName: 'currentVersionData',
|
||||
serviceName: 'CURRENT_NG_VERSION',
|
||||
serviceValue: currentVersion
|
||||
});
|
||||
|
||||
docs.push(versionDoc);
|
||||
docs.push({
|
||||
docType: 'allversions-data',
|
||||
id: 'allversions-data',
|
||||
template: 'angular-service.template.js',
|
||||
outputPath: 'js/all-versions-data.js',
|
||||
ngModuleName: 'allVersionsData',
|
||||
serviceName: 'ALL_NG_VERSIONS',
|
||||
serviceValue: allVersions
|
||||
});
|
||||
|
||||
|
||||
function processAllVersionsResponse(versions) {
|
||||
|
||||
var latestMap = {};
|
||||
|
||||
versions = versions
|
||||
.filter(function(versionStr) {
|
||||
return blacklist.indexOf(versionStr) === -1;
|
||||
})
|
||||
.map(function(versionStr) {
|
||||
return semver.parse(versionStr);
|
||||
})
|
||||
.filter(function(version) {
|
||||
return version && version.major > 0;
|
||||
})
|
||||
.map(function(version) {
|
||||
var key = version.major + '.' + version.minor;
|
||||
var latest = latestMap[key];
|
||||
if (!latest || version.compare(latest) > 0) {
|
||||
latestMap[key] = version;
|
||||
}
|
||||
return version;
|
||||
})
|
||||
.map(function(version) {
|
||||
return makeOption(version);
|
||||
})
|
||||
.reverse();
|
||||
|
||||
var latest = sortObject(latestMap, reverse(semver.compare))
|
||||
.map(function(version) { return makeOption(version, 'Latest'); });
|
||||
|
||||
return [makeOption({version: 'snapshot'}, 'Latest', 'master')]
|
||||
.concat(latest)
|
||||
.concat(versions);
|
||||
}
|
||||
|
||||
function makeOption(version, group, label) {
|
||||
return {
|
||||
version: version,
|
||||
label: label || 'v' + version.raw,
|
||||
group: group || 'v' + version.major + '.' + version.minor,
|
||||
docsUrl: createDocsUrl(version)
|
||||
};
|
||||
}
|
||||
|
||||
function createDocsUrl(version) {
|
||||
var url = 'https://code.angularjs.org/' + version.version + '/docs';
|
||||
// Versions before 1.0.2 had a different docs folder name
|
||||
if (version.major === 1 && version.minor === 0 && version.patch < 2) {
|
||||
url += '-' + version.version;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
function reverse(fn) {
|
||||
return function(left, right) { return -fn(left, right); };
|
||||
}
|
||||
|
||||
function sortObject(obj, cmp) {
|
||||
return Object.keys(obj).map(function(key) { return obj[key]; }).sort(cmp);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -22,7 +22,8 @@ module.exports = function debugDeployment(getVersion) {
|
||||
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js',
|
||||
'js/versions-data.js',
|
||||
'js/current-version-data.js',
|
||||
'js/all-versions-data.js',
|
||||
'js/pages-data.js',
|
||||
'js/nav-data.js',
|
||||
'js/docs.js'
|
||||
|
||||
@@ -22,7 +22,8 @@ module.exports = function defaultDeployment(getVersion) {
|
||||
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.min.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js',
|
||||
'js/versions-data.js',
|
||||
'js/current-version-data.js',
|
||||
'js/all-versions-data.js',
|
||||
'js/pages-data.js',
|
||||
'js/nav-data.js',
|
||||
'js/docs.min.js'
|
||||
|
||||
+2
-1
@@ -26,7 +26,8 @@ module.exports = function jqueryDeployment(getVersion) {
|
||||
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.min.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js',
|
||||
'js/versions-data.js',
|
||||
'js/current-version-data.js',
|
||||
'js/all-versions-data.js',
|
||||
'js/pages-data.js',
|
||||
'js/nav-data.js',
|
||||
'js/docs.min.js'
|
||||
|
||||
@@ -1,16 +1,30 @@
|
||||
'use strict';
|
||||
|
||||
var versionInfo = require('../../../../lib/versions/version-info');
|
||||
var cdnUrl = '//ajax.googleapis.com/ajax/libs/angularjs/' + versionInfo.cdnVersion;
|
||||
|
||||
var googleCdnUrl = '//ajax.googleapis.com/ajax/libs/angularjs/';
|
||||
var angularCodeUrl = '//code.angularjs.org/';
|
||||
|
||||
var cdnUrl = googleCdnUrl + versionInfo.cdnVersion;
|
||||
|
||||
// The plnkr examples must use the code.angularjs.org repo for the snapshot,
|
||||
// and the cdn for the tagged version and, if the build is not tagged, the currentVersion.
|
||||
//
|
||||
// The currentVersion may not be available on the cdn (e.g. if built locally, or hasn't been pushed
|
||||
// yet). This will lead to a 404, but this is preferable to loading a version with which the example
|
||||
// might not work (possibly in subtle ways).
|
||||
var examplesCdnUrl = versionInfo.isSnapshot ?
|
||||
(angularCodeUrl + 'snapshot') :
|
||||
(googleCdnUrl + (versionInfo.version || versionInfo.currentVersion));
|
||||
|
||||
module.exports = function productionDeployment(getVersion) {
|
||||
return {
|
||||
name: 'production',
|
||||
examples: {
|
||||
commonFiles: {
|
||||
scripts: [cdnUrl + '/angular.min.js']
|
||||
scripts: [examplesCdnUrl + '/angular.min.js']
|
||||
},
|
||||
dependencyPath: cdnUrl + '/'
|
||||
dependencyPath: examplesCdnUrl + '/'
|
||||
},
|
||||
scripts: [
|
||||
cdnUrl + '/angular.min.js',
|
||||
@@ -25,7 +39,8 @@ module.exports = function productionDeployment(getVersion) {
|
||||
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.min.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js',
|
||||
'js/versions-data.js',
|
||||
'js/current-version-data.js',
|
||||
'https://code.angularjs.org/snapshot/docs/js/all-versions-data.js',
|
||||
'js/pages-data.js',
|
||||
'js/nav-data.js',
|
||||
'js/docs.min.js'
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
'use strict';
|
||||
|
||||
var OPTION_MATCHER = /^\s*([\w-]+)="([^"]+)"\s+([\s\S]*)/;
|
||||
var VALID_OPTIONS = ['sinceVersion', 'removeVersion'];
|
||||
|
||||
module.exports = {
|
||||
name: 'deprecated',
|
||||
transforms: function(doc, tag, value) {
|
||||
var result = {};
|
||||
var invalidOptions = [];
|
||||
value = value.trim();
|
||||
while (OPTION_MATCHER.test(value)) {
|
||||
value = value.replace(OPTION_MATCHER, function(_, key, value, rest) {
|
||||
if (VALID_OPTIONS.indexOf(key) !== -1) {
|
||||
result[key] = value;
|
||||
} else {
|
||||
invalidOptions.push(key);
|
||||
}
|
||||
return rest;
|
||||
});
|
||||
}
|
||||
if (invalidOptions.length > 0) {
|
||||
throw new Error('Invalid options: ' + humanList(invalidOptions) + '. Value options are: ' + humanList(VALID_OPTIONS));
|
||||
}
|
||||
result.description = value;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
function humanList(values, sep, lastSep) {
|
||||
if (sep === undefined) sep = ', ';
|
||||
if (lastSep === undefined) lastSep = ' and ';
|
||||
|
||||
return values.reduce(function(output, value, index, list) {
|
||||
output += '"' + value + '"';
|
||||
switch (list.length - index) {
|
||||
case 1: return output;
|
||||
case 2: return output + lastSep;
|
||||
default: return output + sep;
|
||||
}
|
||||
}, '');
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
/* globals describe, it, expect */
|
||||
var tagDef = require('./deprecated');
|
||||
|
||||
describe('deprecated tag', function() {
|
||||
describe('transforms', function() {
|
||||
it('should return the trimmed value if no options', function() {
|
||||
var tag = tagDef.transforms({}, {}, 'This is the description');
|
||||
expect(tag.description).toEqual('This is the description');
|
||||
});
|
||||
|
||||
it('should read options', function() {
|
||||
var tag = tagDef.transforms({}, {}, ' sinceVersion="v1.3.4" removeVersion="v1.4.5" what is left is description');
|
||||
expect(tag.description).toEqual('what is left is description');
|
||||
expect(tag.sinceVersion).toEqual('v1.3.4');
|
||||
expect(tag.removeVersion).toEqual('v1.4.5');
|
||||
});
|
||||
|
||||
it('should cope with carriage returns', function() {
|
||||
var tag = tagDef.transforms({}, {}, '\nsinceVersion="v1.3.4"\nremoveVersion="v1.4.5"\nwhat is left is description');
|
||||
expect(tag.description).toEqual('what is left is description');
|
||||
expect(tag.sinceVersion).toEqual('v1.3.4');
|
||||
expect(tag.removeVersion).toEqual('v1.4.5');
|
||||
});
|
||||
|
||||
it('should error if there is an invalid option', function() {
|
||||
expect(function() {
|
||||
tagDef.transforms({}, {}, ' fromVersion="v1.3.4" toVersion="v1.4.5" what is left is description');
|
||||
}).toThrowError('Invalid options: "fromVersion" and "toVersion". Value options are: "sinceVersion" and "removeVersion"');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('{$ doc.ngModuleName $}', [])
|
||||
.value('{$ doc.serviceName $}', {$ doc.serviceValue | json $});
|
||||
+1
-7
@@ -165,13 +165,7 @@
|
||||
<section class="sup-header">
|
||||
<div class="container main-grid main-header-grid">
|
||||
<div class="grid-left">
|
||||
<div ng-controller="DocsVersionsCtrl" class="picker version-picker">
|
||||
<select ng-options="v as (v.isSnapshot ? v.branch : ('v' + v.version)) group by getGroupName(v) for v in docs_versions"
|
||||
ng-model="docs_version"
|
||||
ng-change="jumpToDocsVersion(docs_version)"
|
||||
class="docs-version-jump">
|
||||
</select>
|
||||
</div>
|
||||
<version-picker></version-picker>
|
||||
</div>
|
||||
<div class="grid-right">
|
||||
<ul class="nav-breadcrumb">
|
||||
@@ -0,0 +1,21 @@
|
||||
<!doctype html>
|
||||
<html lang="en"{% if doc.example['ng-csp'] %} ng-csp{% endif %}>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Example - {$ doc.id $}</title>
|
||||
{% for stylesheet in doc.stylesheets %}<link href="{$ stylesheet.path $}" rel="stylesheet" type="text/css">
|
||||
{% endfor %}
|
||||
|
||||
{% for script in doc.scripts %}<script src="{$ script.path $}"></script>
|
||||
{% endfor %}
|
||||
|
||||
{% if doc.example.fixBase -%}
|
||||
<script type="text/javascript">
|
||||
angular.element(document.getElementsByTagName('head')).append(angular.element('<base href="' + window.location.pathname + '" />'));
|
||||
</script>
|
||||
{%- endif %}
|
||||
</head>
|
||||
<body {% if not doc.example['ng-app-included'] %}ng-app="{$ doc.example.module $}"{% endif %}>
|
||||
{$ doc.fileContents $}
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "{$ doc.example.id $}",
|
||||
"files": [
|
||||
"index-production.html"
|
||||
{%- for file in doc.files %},
|
||||
"{$ file $}"{% endfor %}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
describe("{$ doc.description $}", function() {
|
||||
var rootEl;
|
||||
beforeEach(function() {
|
||||
rootEl = browser.rootEl;{% if doc['ng-app-included'] %}
|
||||
browser.rootEl = '[ng-app]';{% endif %}
|
||||
browser.get("{$ doc.basePath $}{$ doc.example.deployments[doc.deployment.name].outputPath $}");
|
||||
});
|
||||
{% if doc['ng-app-included'] %}afterEach(function() { browser.rootEl = rootEl; });{% endif %}
|
||||
{$ doc.innerTest $}
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
{$ doc.fileContents $}
|
||||
@@ -0,0 +1 @@
|
||||
{$ doc.fileContents $}
|
||||
@@ -0,0 +1,4 @@
|
||||
(function(angular) {
|
||||
'use strict';
|
||||
{$ doc.fileContents $}
|
||||
})(window.angular);
|
||||
@@ -0,0 +1 @@
|
||||
{$ doc.fileContents $}
|
||||
@@ -0,0 +1 @@
|
||||
{$ doc.fileContents $}
|
||||
@@ -0,0 +1 @@
|
||||
{$ doc.fileContents $}
|
||||
@@ -0,0 +1 @@
|
||||
{$ doc.fileContents $}
|
||||
+4
-8
@@ -1,4 +1,5 @@
|
||||
{% extends "base.template.html" %}
|
||||
{% import "lib/deprecated.html" as x -%}
|
||||
|
||||
{% block content %}
|
||||
|
||||
@@ -18,6 +19,8 @@
|
||||
</header>
|
||||
{% endblock %}
|
||||
|
||||
{$ x.deprecatedBlock(doc) $}
|
||||
|
||||
{% block description %}
|
||||
<div class="api-profile-description">
|
||||
{$ doc.description | marked $}
|
||||
@@ -28,18 +31,11 @@
|
||||
<h2 id="known-issues">Known Issues</h2>
|
||||
{% for issue in doc.knownIssues -%}
|
||||
<div class="known-issue">
|
||||
{$ issue | marked $} {% if not loop.last %}<hr>{% endif %}
|
||||
{$ issue | marked $}
|
||||
</div>
|
||||
{% endfor -%}
|
||||
{% endif %}
|
||||
|
||||
{% if doc.deprecated %}
|
||||
<fieldset class="deprecated">
|
||||
<legend>Deprecated API</legend>
|
||||
{$ doc.deprecated| marked $}
|
||||
</fieldset>
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
{% block dependencies %}
|
||||
{%- if doc.requires %}
|
||||
@@ -0,0 +1,31 @@
|
||||
{% block content %}
|
||||
<h1>
|
||||
{%- if doc.title -%}
|
||||
{$ doc.title $}
|
||||
{%- elif doc.moduleName -%}
|
||||
{$ doc.groupType | title $} components in {$ doc.moduleName | code $}
|
||||
{%- else -%}
|
||||
Pages
|
||||
{%- endif -%}
|
||||
</h1>
|
||||
|
||||
{$ doc.description | marked $}
|
||||
|
||||
<div class="component-breakdown">
|
||||
<div>
|
||||
<table class="definition-table">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
{% for page in doc.components %}
|
||||
<tr>
|
||||
<td>{$ page.id | link(page.name, page) $}</td>
|
||||
<td>{$ page.description | firstParagraph | marked $}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,72 @@
|
||||
{% import "lib/macros.html" as lib -%}
|
||||
{% extends "api/api.template.html" %}
|
||||
|
||||
{% block additional %}
|
||||
<h2>Directive Info</h2>
|
||||
<ul>
|
||||
{% if doc.scope %}<li>This directive creates new scope.</li>{% endif %}
|
||||
<li>This directive executes at priority level {$ doc.priority $}.</li>
|
||||
{% if doc.multiElement %}<li>This directive can be used as {@link $compile#-multielement- multiElement}</li>{% endif %}
|
||||
</ul>
|
||||
|
||||
{% block usage %}
|
||||
<h2 id="usage">Usage</h2>
|
||||
<div class="usage">
|
||||
{% if doc.usage %}
|
||||
{$ doc.usage | marked $}
|
||||
{% else %}
|
||||
<ul>
|
||||
{% if doc.restrict.element %}
|
||||
<li>as element:
|
||||
{% if doc.name.indexOf('ng') == 0 -%}
|
||||
(This directive can be used as custom element, but be aware of <a href="guide/ie">IE restrictions</a>).
|
||||
{%- endif %}
|
||||
{% code %}
|
||||
<{$ doc.name | dashCase $}
|
||||
{%- for param in doc.params %}
|
||||
{$ lib.directiveParam(param.alias or param.name, param.type, '="', '"') $}
|
||||
{%- endfor %}>
|
||||
...
|
||||
</{$ doc.name | dashCase $}>
|
||||
{% endcode %}
|
||||
</li>
|
||||
{% endif -%}
|
||||
|
||||
{%- if doc.restrict.attribute -%}
|
||||
<li>as attribute:
|
||||
{% code %}
|
||||
<{$ doc.element $}
|
||||
{%- for param in doc.params %}
|
||||
{$ lib.directiveParam(param.name, param.type, '="', '"') $}
|
||||
{%- endfor %}>
|
||||
...
|
||||
</{$ doc.element $}>
|
||||
{% endcode %}
|
||||
</li>
|
||||
{% endif -%}
|
||||
|
||||
{%- if doc.restrict.cssClass -%}
|
||||
<li>as CSS class:
|
||||
{% code %}
|
||||
{% set sep = joiner(' ') %}
|
||||
<{$ doc.element $} class="
|
||||
{%- for param in doc.params -%}
|
||||
{$ sep() $}{$ lib.directiveParam(param.name, param.type, ': ', ';') $}
|
||||
{%- endfor %}"> ... </{$ doc.element $}>
|
||||
{% endcode %}
|
||||
</li>
|
||||
{% endif -%}
|
||||
|
||||
{%- endif %}
|
||||
</div>
|
||||
{% endblock -%}
|
||||
|
||||
{%- if doc.animations %}
|
||||
<h2 id="animations">Animations</h2>
|
||||
{$ doc.animations | marked $}
|
||||
{$ 'module:ngAnimate.$animate' | link('Click here', doc) $} to learn more about the steps involved in the animation.
|
||||
{%- endif -%}
|
||||
|
||||
{% include "lib/params.template.html" %}
|
||||
{% include "lib/events.template.html" %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,26 @@
|
||||
{% import "lib/macros.html" as lib -%}
|
||||
{% extends "api/api.template.html" %}
|
||||
|
||||
{% block additional %}
|
||||
<h2>Usage</h2>
|
||||
<h3>In HTML Template Binding</h3>
|
||||
{% if doc.usage %}
|
||||
{$ doc.usage | code $}
|
||||
{% else %}
|
||||
{% code -%}
|
||||
{{ {$ doc.name $}_expression | {$ doc.name $}
|
||||
{%- for param in doc.params %}{% if not loop.first %} : {$ param.name $}{% endif %}{% endfor -%}
|
||||
}}
|
||||
{%- endcode %}
|
||||
{% endif %}
|
||||
|
||||
<h3>In JavaScript</h3>
|
||||
{% code -%}
|
||||
{%- set sep = joiner(', ') -%}
|
||||
$filter('{$ doc.name $}')({% for param in doc.params %}{$ sep() $}{$ param.name $}{% endfor -%})
|
||||
{%- endcode %}
|
||||
|
||||
{% include "lib/params.template.html" %}
|
||||
{% include "lib/this.template.html" %}
|
||||
{% include "lib/returns.template.html" %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1 @@
|
||||
{% extends "api/object.template.html" %}
|
||||
@@ -0,0 +1,12 @@
|
||||
{% import "lib/macros.html" as lib -%}
|
||||
{% extends "api/directive.template.html" %}
|
||||
|
||||
{% block usage %}
|
||||
<h2>Usage</h2>
|
||||
{% code %}
|
||||
<input type="{$ doc.inputType $}"
|
||||
{%- for param in doc.params %}
|
||||
{$ lib.directiveParam(param.alias or param.name, param.type, '="', '"') $}
|
||||
{%- endfor %}>
|
||||
{% endcode %}
|
||||
{% endblock %}
|
||||
+3
@@ -1,10 +1,13 @@
|
||||
{% extends "base.template.html" %}
|
||||
{% import "lib/deprecated.html" as x %}
|
||||
|
||||
{% block content %}
|
||||
<h1>
|
||||
{% if doc.title %}{$ doc.title | marked $}{% else %}{$ doc.name | code $}{% endif %}
|
||||
</h1>
|
||||
|
||||
{$ x.deprecatedBlock(doc) $}
|
||||
|
||||
<h2>Installation</h2>
|
||||
{% if doc.installation or doc.installation == '' %}
|
||||
{$ doc.installation | marked $}
|
||||
@@ -0,0 +1,23 @@
|
||||
{% import "lib/macros.html" as lib %}
|
||||
{% extends "api/api.template.html" %}
|
||||
|
||||
{% block additional %}
|
||||
|
||||
{% if doc.params or doc.returns or doc.this or doc.kind == 'function' -%}
|
||||
<h2 id="usage">Usage</h2>
|
||||
{% if doc.usage %}
|
||||
{$ doc.usage | code $}
|
||||
{% else %}
|
||||
{$ lib.functionSyntax(doc) $}
|
||||
{% endif %}
|
||||
|
||||
{% include "lib/params.template.html" %}
|
||||
{% include "lib/this.template.html" %}
|
||||
{% include "lib/returns.template.html" %}
|
||||
{%- endif %}
|
||||
|
||||
{% include "lib/methods.template.html" %}
|
||||
{% include "lib/events.template.html" %}
|
||||
{% include "lib/properties.template.html" %}
|
||||
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,9 @@
|
||||
{% extends "api/object.template.html" %}
|
||||
|
||||
{% block related_components %}
|
||||
{% if doc.serviceDoc -%}
|
||||
<li>
|
||||
<a href="{$ doc.serviceDoc.path $}">- {$ doc.serviceDoc.name $}</a>
|
||||
</li>
|
||||
{%- endif %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,9 @@
|
||||
{% extends "api/object.template.html" %}
|
||||
|
||||
{% block related_components %}
|
||||
{% if doc.providerDoc -%}
|
||||
<li>
|
||||
<a href="{$ doc.providerDoc.path $}">- {$ doc.providerDoc.name $}</a>
|
||||
</li>
|
||||
{%- endif %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1 @@
|
||||
{% extends "api/object.template.html" %}
|
||||
@@ -0,0 +1,4 @@
|
||||
<a href='https://github.com/angular/angular.js/edit/{$ git.version.branch $}/{$ doc.fileInfo.projectRelativePath $}?message=docs({$ (doc.area != "api") and (doc.area + "%2F") or "" $}{$ doc.name $})%3A%20describe%20your%20change...{$ (doc.area == "api") and ("#L" + doc.startingLine) or "" $}' class='improve-docs btn btn-primary'><i class="glyphicon glyphicon-edit"> </i>Improve this Doc</a>
|
||||
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,9 @@
|
||||
{% macro deprecatedBlock(doc) %}{% if doc.deprecated %}
|
||||
<div class="alert alert-danger deprecation">
|
||||
<div class="title"><strong>Deprecated:</strong>
|
||||
{% if doc.deprecated.sinceVersion %}<span class="since">(since {$ doc.deprecated.sinceVersion $}) </span>{% endif %}
|
||||
{% if doc.deprecated.removeVersion %}<span class="remove">(to be removed in {$ doc.deprecated.removeVersion $}) </span>{% endif %}
|
||||
</div>
|
||||
{$ doc.deprecated.description | marked $}
|
||||
</div>
|
||||
{% endif %}{% endmacro %}
|
||||
@@ -0,0 +1,37 @@
|
||||
{% import "lib/macros.html" as lib -%}
|
||||
{% import "lib/deprecated.html" as x -%}
|
||||
|
||||
{%- if doc.events %}
|
||||
<h2>Events</h2>
|
||||
<ul class="events">
|
||||
{%- for event in doc.events %}
|
||||
<li id="{$ event.name $}">
|
||||
<h3>{$ event.name $}</h3>
|
||||
<div>{$ event.description | marked $}</div>
|
||||
|
||||
{$ x.deprecatedBlock(event) $}
|
||||
|
||||
{%- if event.eventType == 'listen' %}
|
||||
<div class="inline">
|
||||
<h4>Listen on: {$ event.eventTarget $}</h4>
|
||||
</div>
|
||||
{%- else %}
|
||||
<div class="inline">
|
||||
<h4>Type:</h4>
|
||||
<div class="type">{$ event.eventType $}</div>
|
||||
</div>
|
||||
<div class="inline">
|
||||
<h4>Target:</h4>
|
||||
<div class="target">{$ event.eventTarget $}</div>
|
||||
</div>
|
||||
{% endif -%}
|
||||
{%- if event.params %}
|
||||
<section class="api-section">
|
||||
<h3>Parameters</h3>
|
||||
{$ lib.paramTable(event.params) $}
|
||||
</section>
|
||||
{%- endif -%}
|
||||
</li>
|
||||
{% endfor -%}
|
||||
</ul>
|
||||
{% endif -%}
|
||||
@@ -0,0 +1,32 @@
|
||||
{% import "lib/macros.html" as lib -%}
|
||||
{% import "lib/deprecated.html" as x -%}
|
||||
|
||||
{%- if doc.methods %}
|
||||
<h2>Methods</h2>
|
||||
<ul class="methods">
|
||||
{%- for method in doc.methods %}
|
||||
<li id="{$ method.name $}">
|
||||
<h3>{$ lib.functionSyntax(method) $}</h3>
|
||||
<div>{$ method.description | marked $}</div>
|
||||
|
||||
{$ x.deprecatedBlock(method) $}
|
||||
|
||||
{% if method.params %}
|
||||
<h4>Parameters</h4>
|
||||
{$ lib.paramTable(method.params) $}
|
||||
{% endif %}
|
||||
|
||||
{% if method.this %}
|
||||
<h4>Method's {% code %}this{% endcode %}</h4>
|
||||
{$ method.this | marked $}
|
||||
{% endif %}
|
||||
|
||||
{% if method.returns %}
|
||||
<h4>Returns</h4>
|
||||
{$ lib.typeInfo(method.returns) $}
|
||||
{% endif %}
|
||||
|
||||
</li>
|
||||
{% endfor -%}
|
||||
</ul>
|
||||
{%- endif -%}
|
||||
@@ -0,0 +1,7 @@
|
||||
{% import "lib/macros.html" as lib -%}
|
||||
{%- if doc.params %}
|
||||
<section class="api-section">
|
||||
<h3>Arguments</h3>
|
||||
{$ lib.paramTable(doc.params) $}
|
||||
</section>
|
||||
{%- endif -%}
|
||||
@@ -0,0 +1,15 @@
|
||||
{% import "lib/macros.html" as lib -%}
|
||||
{% import "lib/deprecated.html" as x -%}
|
||||
|
||||
{%- if doc.properties %}
|
||||
<h2>Properties</h2>
|
||||
<ul class="properties">
|
||||
{%- for property in doc.properties %}
|
||||
<li id="{$ property.name $}">
|
||||
<h3>{$ property.name | code $}</h3>
|
||||
{$ lib.typeInfo(property) $}
|
||||
{$ x.deprecatedBlock(property) $}
|
||||
</li>
|
||||
{% endfor -%}
|
||||
</ul>
|
||||
{%- endif -%}
|
||||
@@ -0,0 +1,5 @@
|
||||
{% import "lib/macros.html" as lib -%}
|
||||
{% if doc.returns -%}
|
||||
<h3>Returns</h3>
|
||||
{$ lib.typeInfo(doc.returns) $}
|
||||
{%- endif %}
|
||||
@@ -0,0 +1,4 @@
|
||||
{% if doc.this %}
|
||||
<h3>Method's {% code %}this{% endcode %}</h3>
|
||||
{$ doc.this | marked $}
|
||||
{% endif %}
|
||||
@@ -0,0 +1,5 @@
|
||||
{% extends "base.template.html" %}
|
||||
|
||||
{% block content %}
|
||||
{$ doc.description | marked $}
|
||||
{% endblock %}
|
||||
@@ -1,6 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
// Meta data used by the AngularJS docs app
|
||||
angular.module('versionsData', [])
|
||||
.value('NG_VERSION', {$ doc.currentVersion | json $})
|
||||
.value('NG_VERSIONS', {$ doc.versions | json $});
|
||||
@@ -0,0 +1,9 @@
|
||||
@ngdoc error
|
||||
@name $location:badpath
|
||||
@fullName Invalid Path
|
||||
@description
|
||||
|
||||
This error occurs when the path of a location contains invalid characters.
|
||||
The most common fault is when the path starts with double slashes (`//`) or backslashes ('\\').
|
||||
For example if the base path of an application is `https://a.b.c/` then the following path is
|
||||
invalid `https://a.b.c///d/e/f`.
|
||||
@@ -3,7 +3,9 @@
|
||||
@fullName Bad Argument
|
||||
@description
|
||||
|
||||
AngularJS often asserts that certain values will be present and truthy using a
|
||||
helper function. If the assertion fails, this error is thrown. To fix this problem,
|
||||
make sure that the value the assertion expects is defined and matches the type mentioned in the
|
||||
error.
|
||||
AngularJS often asserts that certain values will be present and truthy using a helper function. If
|
||||
the assertion fails, this error is thrown. To fix this problem, make sure that the value the
|
||||
assertion expects is defined and matches the type mentioned in the error.
|
||||
|
||||
If the type is `undefined`, make sure any newly added controllers/directives/services are properly
|
||||
defined and included in the script(s) loaded by your page.
|
||||
|
||||
@@ -384,7 +384,7 @@ By default, any `ngAnimate` enabled directives will assume any transition / anim
|
||||
element are part of an `ngAnimate` animation. This can lead to problems when the styles are actually
|
||||
for animations that are independent of `ngAnimate`.
|
||||
|
||||
For example, an element acts as a loading spinner. It has an inifinite css animation on it, and also an
|
||||
For example, an element acts as a loading spinner. It has an infinite css animation on it, and also an
|
||||
{@link ngIf `ngIf`} directive, for which no animations are defined:
|
||||
|
||||
```css
|
||||
|
||||
@@ -380,3 +380,106 @@ restrict: 'E',
|
||||
replace: true
|
||||
```
|
||||
|
||||
### Double Compilation, and how to avoid it
|
||||
|
||||
Double compilation occurs when an already compiled part of the DOM gets compiled again. This is an
|
||||
undesired effect and can lead to misbehaving directives, performance issues, and memory
|
||||
leaks.
|
||||
A common scenario where this happens is a directive that calls `$compile` in a directive link
|
||||
function on the directive element. In the following **faulty example**, a directive adds a mouseover behavior
|
||||
to a button with `ngClick` on it:
|
||||
|
||||
```
|
||||
angular.module('app').directive('addMouseover', function($compile) {
|
||||
return {
|
||||
link: function(scope, element, attrs) {
|
||||
var newEl = angular.element('<span ng-show="showHint"> My Hint</span>');
|
||||
element.on('mouseenter mouseleave', function() {
|
||||
scope.$apply('showHint = !showHint');
|
||||
});
|
||||
|
||||
attrs.$set('addMouseover', null); // To stop infinite compile loop
|
||||
element.append(newEl);
|
||||
$compile(element)(scope); // Double compilation
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
At first glance, it looks like removing the original `addMouseover` attribute is all there is needed
|
||||
to make this example work.
|
||||
However, if the directive element or its children have other directives attached, they will be compiled and
|
||||
linked again, because the compiler doesn't keep track of which directives have been assigned to which
|
||||
elements.
|
||||
|
||||
This can cause unpredictable behavior, e.g. `ngClick` or other event handlers will be attached
|
||||
again. It can also degrade performance, as watchers for text interpolation are added twice to the scope.
|
||||
|
||||
Double compilation should therefore be avoided. In the above example, only the new element should
|
||||
be compiled:
|
||||
|
||||
```
|
||||
angular.module('app').directive('addMouseover', function($compile) {
|
||||
return {
|
||||
link: function(scope, element, attrs) {
|
||||
var newEl = angular.element('<span ng-show="showHint"> My Hint</span>');
|
||||
element.on('mouseenter mouseleave', function() {
|
||||
scope.$apply('showHint = !showHint');
|
||||
});
|
||||
|
||||
element.append(newEl);
|
||||
$compile(newEl)(scope); // Only compile the new element
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Another scenario is adding a directive programmatically to a compiled element and then executing
|
||||
compile again. See the following **faulty example**:
|
||||
|
||||
```html
|
||||
<input ng-model="$ctrl.value" add-options>
|
||||
```
|
||||
|
||||
```
|
||||
angular.module('app').directive('addOptions', function($compile) {
|
||||
return {
|
||||
link: function(scope, element, attrs) {
|
||||
attrs.$set('addOptions', null) // To stop infinite compile loop
|
||||
attrs.$set('ngModelOptions', '{debounce: 1000}');
|
||||
$compile(element)(scope); // Double compilation
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
In that case, it is necessary to intercept the *initial* compilation of the element:
|
||||
|
||||
1. Give your directive the `terminal` property and a higher priority than directives
|
||||
that should not be compiled twice. In the example, the compiler will only compile directives
|
||||
which have a priority of 100 or higher.
|
||||
2. Inside this directive's compile function, add any other directive attributes to the template.
|
||||
3. Compile the element, but restrict the maximum priority, so that any already compiled directives
|
||||
(including the `addOptions` directive) are not compiled again.
|
||||
4. In the link function, link the compiled element with the element's scope.
|
||||
|
||||
```
|
||||
angular.module('app').directive('addOptions', function($compile) {
|
||||
return {
|
||||
priority: 100, // ngModel has priority 1
|
||||
terminal: true,
|
||||
compile: function(templateElement, templateAttributes) {
|
||||
templateAttributes.$set('ngModelOptions', '{debounce: 1000}');
|
||||
|
||||
// The third argument is the max priority. Only directives with priority < 100 will be compiled,
|
||||
// therefore we don't need to remove the attribute
|
||||
var compiled = $compile(templateElement, null, 100);
|
||||
|
||||
return function linkFn(scope) {
|
||||
compiled(scope) // Link compiled element to scope
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@ Here is a table of the main concepts used in the Component Router.
|
||||
| Routing Component | An Angular component with a RouteConfig and an associated Router. |
|
||||
| RouteDefinition | Defines how the router should navigate to a component based on a URL pattern. |
|
||||
| ngOutlet | The directive (`<ng-outlet>`) that marks where the router should display a view. |
|
||||
| ngLink | The directive (`ng-link="..."`) for binding a clickable HTML element to a route, via a Link Paramaters Array. |
|
||||
| Link Parameters Array | An array that the router inteprets into a routing instruction. We can bind a RouterLink to that array or pass the array as an argument to the Router.navigate method. |
|
||||
| ngLink | The directive (`ng-link="..."`) for binding a clickable HTML element to a route, via a Link Parameters Array. |
|
||||
| Link Parameters Array | An array that the router interprets into a routing instruction. We can bind a RouterLink to that array or pass the array as an argument to the Router.navigate method. |
|
||||
|
||||
|
||||
## Component-based Applications
|
||||
@@ -150,7 +150,7 @@ You can see the complete application running below.
|
||||
<app></app>
|
||||
|
||||
<!-- Load up the router library - normally you might use npm and host it locally -->
|
||||
<script src="https://npmcdn.com/@angular/router@0.2.0/angular1/angular_1_router.js"></script>
|
||||
<script src="https://unpkg.com/@angular/router@0.2.0/angular1/angular_1_router.js"></script>
|
||||
</file>
|
||||
|
||||
<file name="app.js">
|
||||
@@ -493,7 +493,7 @@ You also need to include ES6 shims for browsers that do not support ES6 code (In
|
||||
<!-- IE required polyfills, in this exact order -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.33.3/es6-shim.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.20/system-polyfills.js"></script>
|
||||
<script src="https://npmcdn.com/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
|
||||
<script src="https://unpkg.com/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
|
||||
```
|
||||
|
||||
## Create the `app` module
|
||||
@@ -929,7 +929,7 @@ function HeroListComponent(heroService) {
|
||||
}
|
||||
```
|
||||
|
||||
Finally, we can use this information to higlight the current hero in the template.
|
||||
Finally, we can use this information to highlight the current hero in the template.
|
||||
|
||||
```html
|
||||
<div ng-repeat="hero in $ctrl.heroes"
|
||||
|
||||
@@ -141,7 +141,7 @@ different currencies and also pay the invoice.
|
||||
<b>Total:</b>
|
||||
<span ng-repeat="c in invoice.currencies">
|
||||
{{invoice.total(c) | currency:c}}
|
||||
</span>
|
||||
</span><br>
|
||||
<button class="btn" ng-click="invoice.pay()">Pay</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -242,7 +242,7 @@ Let's refactor our example and move the currency conversion into a service in an
|
||||
<b>Total:</b>
|
||||
<span ng-repeat="c in invoice.currencies">
|
||||
{{invoice.total(c) | currency:c}}
|
||||
</span>
|
||||
</span><br>
|
||||
<button class="btn" ng-click="invoice.pay()">Pay</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -337,7 +337,7 @@ The following example shows how this is done with Angular:
|
||||
var refresh = function() {
|
||||
var url = YAHOO_FINANCE_URL_PATTERN.
|
||||
replace('PAIRS', 'USD' + currencies.join('","USD'));
|
||||
return $http.jsonp(url).then(function(response) {
|
||||
return $http.get(url).then(function(response) {
|
||||
var newUsdToForeignRates = {};
|
||||
angular.forEach(response.data.query.results.rate, function(rate) {
|
||||
var currency = rate.id.substring(3,6);
|
||||
@@ -371,7 +371,7 @@ The following example shows how this is done with Angular:
|
||||
<b>Total:</b>
|
||||
<span ng-repeat="c in invoice.currencies">
|
||||
{{invoice.total(c) | currency:c}}
|
||||
</span>
|
||||
</span><br>
|
||||
<button class="btn" ng-click="invoice.pay()">Pay</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -253,10 +253,10 @@ scopes being created for our view:
|
||||
|
||||
- The root scope
|
||||
- The `MainController` scope, which contains `timeOfDay` and `name` properties
|
||||
- The `ChildController` scope, which inherits the `timeOfDay` property but overrides (hides) the `name`
|
||||
property from the previous
|
||||
- The `GrandChildController` scope, which overrides (hides) both the `timeOfDay` property defined in `MainController`
|
||||
and the `name` property defined in `ChildController`
|
||||
- The `ChildController` scope, which inherits the `timeOfDay` property but overrides (shadows) the
|
||||
`name` property from the previous scope
|
||||
- The `GrandChildController` scope, which overrides (shadows) both the `timeOfDay` property defined
|
||||
in `MainController` and the `name` property defined in `ChildController`
|
||||
|
||||
Inheritance works with methods in the same way as it does with properties. So in our previous
|
||||
examples, all of the properties could be replaced with methods that return string values.
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
<div class="alert alert-warning">
|
||||
**Note:** this guide is targeted towards developers who are already familiar with AngularJS basics.
|
||||
If you're just getting started, we recommend the {@link tutorial/ tutorial} first.
|
||||
If you're looking for the **directives API**, we recently moved it to {@link ng.$compile `$compile`}.
|
||||
If you're looking for the **directives API**, you can find it in the
|
||||
{@link ng.$compile `$compile` API docs}.
|
||||
</div>
|
||||
|
||||
|
||||
@@ -58,7 +59,7 @@ The following `<input>` element also **matches** `ngModel`:
|
||||
<input data-ng-model="foo">
|
||||
```
|
||||
|
||||
And the following <person> element **matches** the `person` directive:
|
||||
And the following `<person>` element **matches** the `person` directive:
|
||||
|
||||
```html
|
||||
<person>{{name}}</person>
|
||||
@@ -335,9 +336,7 @@ Let's change our directive to use `restrict: 'E'`:
|
||||
</file>
|
||||
</example>
|
||||
|
||||
For more on the
|
||||
{@link ng.$compile#directive-definition-object `restrict`}
|
||||
property, see the
|
||||
For more on the `restrict` property, see the
|
||||
{@link ng.$compile#directive-definition-object API docs}.
|
||||
|
||||
<div class="alert alert-info">
|
||||
@@ -450,8 +449,8 @@ scope: {
|
||||
The **scope option** is an object that contains a property for each isolate scope binding. In this
|
||||
case it has just one property:
|
||||
|
||||
- Its name (`customerInfo`) corresponds to the
|
||||
directive's **isolate scope** property `customerInfo`.
|
||||
- Its name (`customerInfo`) corresponds to the directive's **isolate scope** property,
|
||||
`customerInfo`.
|
||||
- Its value (`=info`) tells `$compile` to bind to the `info` attribute.
|
||||
|
||||
<div class="alert alert-warning">
|
||||
@@ -517,8 +516,8 @@ that you explicitly pass in.
|
||||
|
||||
<div class="alert alert-warning">
|
||||
**Note:** Normally, a scope prototypically inherits from its parent. An isolated scope does not.
|
||||
See the {@link $compile#directive-definition-object
|
||||
"Directive Definition Object - scope"} section for more information about isolate scopes.
|
||||
See the {@link $compile#directive-definition-object "Directive Definition Object - scope"} section
|
||||
for more information about isolate scopes.
|
||||
</div>
|
||||
|
||||
<div class="alert alert-success">
|
||||
|
||||
@@ -41,7 +41,7 @@ This is a collection of external, 3rd party resources for learning and developin
|
||||
##### General
|
||||
|
||||
* **Javascript minification: **[Background](http://thegreenpizza.github.io/2013/05/25/building-minification-safe-angular.js-applications/), [ng-annotate automation tool](https://github.com/olov/ng-annotate)
|
||||
* **Analytics and Logging:** [Angularyitcs (Google Analytics)](http://ngmodules.org/modules/angularytics), [Angulartics (Analytics)](https://github.com/luisfarzati/angulartics), [Logging Client-Side Errors](http://www.bennadel.com/blog/2542-Logging-Client-Side-Errors-With-AngularJS-And-Stacktrace-js.htm)
|
||||
* **Analytics and Logging:** [Angularytics (Google Analytics)](http://ngmodules.org/modules/angularytics), [Angulartics (Analytics)](https://github.com/luisfarzati/angulartics), [Logging Client-Side Errors](http://www.bennadel.com/blog/2542-Logging-Client-Side-Errors-With-AngularJS-And-Stacktrace-js.htm)
|
||||
* **SEO:** [By hand](http://www.yearofmoo.com/2012/11/angularjs-and-seo.html), [prerender.io](http://prerender.io/), [Brombone](http://www.brombone.com/), [SEO.js](http://getseojs.com/), [SEO4Ajax](http://www.seo4ajax.com/)
|
||||
|
||||
##### Server-Specific
|
||||
@@ -117,16 +117,17 @@ You can find a larger list of Angular external libraries at [ngmodules.org](http
|
||||
## General Learning Resources
|
||||
|
||||
### Books
|
||||
* [AngularJS: Up and Running](http://www.amazon.com/AngularJS-Running-Enhanced-Productivity-Structured/dp/1491901942) by Brad Green and Shyam Seshadri
|
||||
* [Mastering Web App Development](http://www.amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821) by Pawel Kozlowski and Pete Bacon Darwin
|
||||
* [AngularJS Directives](http://www.amazon.com/AngularJS-Directives-Alex-Vanston/dp/1783280336) by Alex Vanston
|
||||
* [Recipes With AngularJS](http://www.amazon.co.uk/Recipes-Angular-js-Frederik-Dietz-ebook/dp/B00DK95V48) by Frederik Dietz
|
||||
* [Developing an AngularJS Edge](http://www.amazon.com/Developing-AngularJS-Edge-Christopher-Hiller-ebook/dp/B00CJLFF8K) by Christopher Hiller
|
||||
* [ng-book: The Complete Book on AngularJS](http://ng-book.com/) by Ari Lerner
|
||||
* [AngularJS Essentials (Free eBook)](https://www.packtpub.com/packt/free-ebook/angularjs-essentials) by Rodrigo Branas
|
||||
* [AngularJS : Novice to Ninja](http://www.amazon.in/AngularJS-Novice-Ninja-Sandeep-Panda/dp/0992279453) by Sandeep Panda
|
||||
* [AngularJS UI Development](http://www.amazon.com/AngularJS-UI-Development-Amit-Ghart-ebook/dp/B00OXVAK7A) by Amit Gharat and Matthias Nehlsen
|
||||
* [Responsive Web Design with AngularJS](http://www.amazon.com/Responsive-Design-AngularJS-Sandeep-Kumar/dp/178439842X) by Sandeep Kumar Patel
|
||||
* [AngularJS: Up and Running](http://www.amazon.com/AngularJS-Running-Enhanced-Productivity-Structured/dp/1491901942) by Brad Green and Shyam Seshadri
|
||||
* [Developing an AngularJS Edge](http://www.amazon.com/Developing-AngularJS-Edge-Christopher-Hiller-ebook/dp/B00CJLFF8K) by Christopher Hiller
|
||||
* [Mastering Web App Development](http://www.amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821) by Pawel Kozlowski and Pete Bacon Darwin
|
||||
* [ng-book: The Complete Book on AngularJS](http://ng-book.com/) by Ari Lerner
|
||||
* [Professional AngularJS](http://www.amazon.com/Professional-AngularJS-Valeri-Karpov/dp/1118832078/)
|
||||
* [Recipes With AngularJS](http://www.amazon.co.uk/Recipes-Angular-js-Frederik-Dietz-ebook/dp/B00DK95V48) by Frederik Dietz
|
||||
* [Responsive Web Design with AngularJS](http://www.amazon.com/Responsive-Design-AngularJS-Sandeep-Kumar/dp/178439842X) by Sandeep Kumar Patel
|
||||
|
||||
### Videos:
|
||||
* [egghead.io](http://egghead.io/)
|
||||
@@ -137,7 +138,7 @@ You can find a larger list of Angular external libraries at [ngmodules.org](http
|
||||
[CodeAcademy](http://www.codecademy.com/courses/javascript-advanced-en-2hJ3J/0/1),
|
||||
[CodeSchool](https://www.codeschool.com/courses/shaping-up-with-angular-js)
|
||||
* **Paid online:**
|
||||
[Pluralsite (3 courses)](http://www.pluralsight.com/training/Courses/Find?highlight=true&searchTerm=angularjs),
|
||||
[Pluralsight (3 courses)](http://www.pluralsight.com/training/Courses/Find?highlight=true&searchTerm=angularjs),
|
||||
[Tuts+](https://tutsplus.com/course/easier-js-apps-with-angular/),
|
||||
[lynda.com](http://www.lynda.com/AngularJS-tutorials/Up-Running-AngularJS/133318-2.html),
|
||||
[WintellectNOW (4 lessons)](http://www.wintellectnow.com/Course/Detail/mastering-angularjs),
|
||||
|
||||
@@ -26,10 +26,10 @@ for other directives to augment its behavior.
|
||||
<file name="index.html">
|
||||
<div ng-controller="ExampleController">
|
||||
<form novalidate class="simple-form">
|
||||
Name: <input type="text" ng-model="user.name" /><br />
|
||||
E-mail: <input type="email" ng-model="user.email" /><br />
|
||||
Gender: <input type="radio" ng-model="user.gender" value="male" />male
|
||||
<input type="radio" ng-model="user.gender" value="female" />female<br />
|
||||
<label>Name: <input type="text" ng-model="user.name" /></label><br />
|
||||
<label>E-mail: <input type="email" ng-model="user.email" /></label><br />
|
||||
Gender: <label><input type="radio" ng-model="user.gender" value="male" />male</label>
|
||||
<label><input type="radio" ng-model="user.gender" value="female" />female</label><br />
|
||||
<input type="button" ng-click="reset()" value="Reset" />
|
||||
<input type="submit" ng-click="update(user)" value="Save" />
|
||||
</form>
|
||||
@@ -88,10 +88,10 @@ and failing to satisfy its validity.
|
||||
<file name="index.html">
|
||||
<div ng-controller="ExampleController">
|
||||
<form novalidate class="css-form">
|
||||
Name: <input type="text" ng-model="user.name" required /><br />
|
||||
E-mail: <input type="email" ng-model="user.email" required /><br />
|
||||
Gender: <input type="radio" ng-model="user.gender" value="male" />male
|
||||
<input type="radio" ng-model="user.gender" value="female" />female<br />
|
||||
<label>Name: <input type="text" ng-model="user.name" required /></label><br />
|
||||
<label>E-mail: <input type="email" ng-model="user.email" required /></label><br />
|
||||
Gender: <label><input type="radio" ng-model="user.gender" value="male" />male</label>
|
||||
<label><input type="radio" ng-model="user.gender" value="female" />female</label><br />
|
||||
<input type="button" ng-click="reset()" value="Reset" />
|
||||
<input type="submit" ng-click="update(user)" value="Save" />
|
||||
</form>
|
||||
@@ -154,15 +154,17 @@ didn't interact with a control
|
||||
<file name="index.html">
|
||||
<div ng-controller="ExampleController">
|
||||
<form name="form" class="css-form" novalidate>
|
||||
Name:
|
||||
<input type="text" ng-model="user.name" name="uName" required="" />
|
||||
<label>Name:
|
||||
<input type="text" ng-model="user.name" name="uName" required="" />
|
||||
</label>
|
||||
<br />
|
||||
<div ng-show="form.$submitted || form.uName.$touched">
|
||||
<div ng-show="form.uName.$error.required">Tell us your name.</div>
|
||||
</div>
|
||||
|
||||
E-mail:
|
||||
<input type="email" ng-model="user.email" name="uEmail" required="" />
|
||||
<label>E-mail:
|
||||
<input type="email" ng-model="user.email" name="uEmail" required="" />
|
||||
</label>
|
||||
<br />
|
||||
<div ng-show="form.$submitted || form.uEmail.$touched">
|
||||
<span ng-show="form.uEmail.$error.required">Tell us your email.</span>
|
||||
@@ -170,12 +172,14 @@ didn't interact with a control
|
||||
</div>
|
||||
|
||||
Gender:
|
||||
<input type="radio" ng-model="user.gender" value="male" />male
|
||||
<input type="radio" ng-model="user.gender" value="female" />female
|
||||
<label><input type="radio" ng-model="user.gender" value="male" />male</label>
|
||||
<label><input type="radio" ng-model="user.gender" value="female" />female</label>
|
||||
<br />
|
||||
<label>
|
||||
<input type="checkbox" ng-model="user.agree" name="userAgree" required="" />
|
||||
|
||||
I agree:
|
||||
</label>
|
||||
<input ng-show="user.agree" type="text" ng-model="user.agreeSign" required="" />
|
||||
<br />
|
||||
<div ng-show="form.$submitted || form.userAgree.$touched">
|
||||
@@ -236,10 +240,11 @@ will update the model only when the control loses focus (blur event).
|
||||
<file name="index.html">
|
||||
<div ng-controller="ExampleController">
|
||||
<form>
|
||||
Name:
|
||||
<input type="text" ng-model="user.name" ng-model-options="{ updateOn: 'blur' }" /><br />
|
||||
<label>Name:
|
||||
<input type="text" ng-model="user.name" ng-model-options="{ updateOn: 'blur' }" /></label><br />
|
||||
<label>
|
||||
Other data:
|
||||
<input type="text" ng-model="user.data" /><br />
|
||||
<input type="text" ng-model="user.data" /></label><br />
|
||||
</form>
|
||||
<pre>username = "{{user.name}}"</pre>
|
||||
<pre>userdata = "{{user.data}}"</pre>
|
||||
@@ -282,8 +287,8 @@ after last change.
|
||||
<file name="index.html">
|
||||
<div ng-controller="ExampleController">
|
||||
<form>
|
||||
Name:
|
||||
<input type="text" ng-model="user.name" ng-model-options="{ debounce: 250 }" /><br />
|
||||
<label>Name:
|
||||
<input type="text" ng-model="user.name" ng-model-options="{ debounce: 250 }" /></label><br />
|
||||
</form>
|
||||
<pre>username = "{{user.name}}"</pre>
|
||||
</div>
|
||||
@@ -335,17 +340,19 @@ In the following example we create two directives:
|
||||
<file name="index.html">
|
||||
<form name="form" class="css-form" novalidate>
|
||||
<div>
|
||||
<label>
|
||||
Size (integer 0 - 10):
|
||||
<input type="number" ng-model="size" name="size"
|
||||
min="0" max="10" integer />{{size}}<br />
|
||||
min="0" max="10" integer />{{size}}</label><br />
|
||||
<span ng-show="form.size.$error.integer">The value is not a valid integer!</span>
|
||||
<span ng-show="form.size.$error.min || form.size.$error.max">
|
||||
The value must be in range 0 to 10!</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>
|
||||
Username:
|
||||
<input type="text" ng-model="name" name="name" username />{{name}}<br />
|
||||
<input type="text" ng-model="name" name="name" username />{{name}}</label><br />
|
||||
<span ng-show="form.name.$pending.username">Checking if this name is available...</span>
|
||||
<span ng-show="form.name.$error.username">This username is already taken!</span>
|
||||
</div>
|
||||
@@ -425,8 +432,10 @@ Note that you can alternatively use `ng-pattern` to further restrict the validat
|
||||
<file name="index.html">
|
||||
<form name="form" class="css-form" novalidate>
|
||||
<div>
|
||||
Overwritten Email:
|
||||
<input type="email" ng-model="myEmail" overwrite-email name="overwrittenEmail" />
|
||||
<label>
|
||||
Overwritten Email:
|
||||
<input type="email" ng-model="myEmail" overwrite-email name="overwrittenEmail" />
|
||||
</label>
|
||||
<span ng-show="form.overwrittenEmail.$error.email">This email format is invalid!</span><br>
|
||||
Model: {{myEmail}}
|
||||
</div>
|
||||
|
||||
@@ -120,13 +120,13 @@ can be used with `ngAttr` instead. The following is a list of known problematic
|
||||
### Dynamically changing an interpolated value
|
||||
|
||||
You should avoid dynamically changing the content of an interpolated string (e.g. attribute value
|
||||
or text node). Your changes are likely to be overwriten, when the original string gets evaluated.
|
||||
or text node). Your changes are likely to be overwritten, when the original string gets evaluated.
|
||||
This restriction applies to both directly changing the content via JavaScript or indirectly using a
|
||||
directive.
|
||||
|
||||
For example, you should not use interpolation in the value of the `style` attribute (e.g.
|
||||
`style="color: {{ 'orange' }}; font-weight: {{ 'bold' }};"`) **and** at the same time use a
|
||||
directive that changes the content of that attributte, such as `ngStyle`.
|
||||
directive that changes the content of that attribute, such as `ngStyle`.
|
||||
|
||||
### Embedding interpolation markup inside expressions
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -88,7 +88,7 @@ Nowadays most of the Angular projects are using only element and attribute direc
|
||||
and in such projects there is no need to compile comments and classes.
|
||||
|
||||
If you are sure that your project only uses element and attribute directives,
|
||||
and you are not using any 3rd part library that uses
|
||||
and you are not using any 3rd party library that uses
|
||||
directives inside element classes or html comments,
|
||||
you can disable the compilation of directives on element classes and comments
|
||||
for the whole application.
|
||||
|
||||
@@ -247,7 +247,7 @@ If you want to apply a directive to each inner piece of the repeat, put it on a
|
||||
|
||||
### `$rootScope` exists, but it can be used for evil
|
||||
|
||||
Scopes in Angular form a hierarchy, prototypally inheriting from a root scope at the top of the tree.
|
||||
Scopes in Angular form a hierarchy, prototypically inheriting from a root scope at the top of the tree.
|
||||
Usually this can be ignored, since most views have a controller, and therefore a scope, of their own.
|
||||
|
||||
Occasionally there are pieces of data that you want to make global to the whole app.
|
||||
|
||||
@@ -135,7 +135,7 @@ To learn more about Angular scopes, see the {@link ng.$rootScope.Scope angular s
|
||||
|
||||
<div class="alert alert-warning">
|
||||
<p>
|
||||
Angular scopes prototypally inherit from their parent scope, all the way up to the *root scope*
|
||||
Angular scopes prototypically inherit from their parent scope, all the way up to the *root scope*
|
||||
of the application. As a result, assigning values directly on the scope makes it easy to share
|
||||
data across different parts of the page and create interactive applications.
|
||||
While this approach works for prototypes and smaller applications, it quickly leads to tight
|
||||
|
||||
@@ -324,7 +324,7 @@ modularity.
|
||||
|
||||
The takeaway here is:
|
||||
|
||||
* Always be explicit about the dependecies of a sub-module. Do not rely on dependencies inherited
|
||||
* Always be explicit about the dependencies of a sub-module. Do not rely on dependencies inherited
|
||||
from a parent module (because that parent module might not be there some day).
|
||||
|
||||
<div class="alert alert-success">
|
||||
|
||||
@@ -1,258 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
var http = require('http');
|
||||
var https = require('https');
|
||||
var fs = require('fs');
|
||||
|
||||
var collections = {
|
||||
'guide': 'https://docs.google.com/feeds/default/private/full/folder%3A0B9PsajIPqzmANGUwMGVhZmYtMTk1ZC00NTdmLWIxMDAtZGI5YWNlZjQ2YjZl/contents',
|
||||
'api': 'https://docs.google.com/feeds/default/private/full/folder%3A0B7Ovm8bUYiUDYjMwYTc2YWUtZTgzYy00YjIxLThlZDYtYWJlOTFlNzE2NzEw/contents',
|
||||
'tutorial': 'https://docs.google.com/feeds/default/private/full/folder%3A0B9PsajIPqzmAYWMxYWE3MzYtYzdjYS00OGQxLWJhZjItYzZkMzJiZTRhZjFl/contents',
|
||||
'cookbook': 'https://docs.google.com/feeds/default/private/full/folder%3A0B7Ovm8bUYiUDNzkxZWM5ZTItN2M5NC00NWIxLTg2ZDMtMmYwNDY1NWM1MGU4/contents',
|
||||
'misc': 'https://docs.google.com/feeds/default/private/full/folder%3A0B7Ovm8bUYiUDZjVlNmZkYzQtMjZlOC00NmZhLWI5MjAtMGRjZjlkOGJkMDBi/contents'
|
||||
};
|
||||
|
||||
console.log('Google Docs...');
|
||||
|
||||
var flag = process && process.argv[2];
|
||||
if (flag === '--login') {
|
||||
var username = process.argv[3];
|
||||
if (username) {
|
||||
askPassword(function(password) {
|
||||
login(username, password);
|
||||
});
|
||||
} else {
|
||||
console.log('Missing username!');
|
||||
}
|
||||
} else if (flag === '--fetch') {
|
||||
var collection = process.argv[3];
|
||||
if (collection) {
|
||||
fetch(collection, collections[collection]);
|
||||
} else {
|
||||
for (collection in collections)
|
||||
fetch(collection, collections[collection]);
|
||||
}
|
||||
} else {
|
||||
help();
|
||||
}
|
||||
|
||||
function help() {
|
||||
console.log('Synopsys');
|
||||
console.log('gdocs.js --login <username>');
|
||||
console.log('gdocs.js --fetch [<docs collection>]');
|
||||
process.exit(-1);
|
||||
}
|
||||
|
||||
|
||||
function fetch(collection, url) {
|
||||
console.log('fetching a list of docs in collection ' + collection + '...');
|
||||
request('GET', url, {
|
||||
headers: {
|
||||
'Gdata-Version': '3.0',
|
||||
'Authorization': 'GoogleLogin auth=' + getAuthToken()
|
||||
}
|
||||
},
|
||||
function(chunk) {
|
||||
var entries = chunk.split('<entry');
|
||||
entries.shift();
|
||||
entries.forEach(function(entry) {
|
||||
var title = entry.match(/<title>(.*?)<\/title>/)[1];
|
||||
if (title.match(/\.ngdoc$/)) {
|
||||
var exportUrl = entry.match(/<content type='text\/html' src='(.*?)'\/>/)[1];
|
||||
download(collection, title, exportUrl);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function download(collection, name, url) {
|
||||
console.log('Downloading:', name, '...');
|
||||
request('GET', url + '&exportFormat=txt',
|
||||
{
|
||||
headers: {
|
||||
'Gdata-Version': '3.0',
|
||||
'Authorization': 'GoogleLogin auth=' + getAuthToken()
|
||||
}
|
||||
},
|
||||
function(data) {
|
||||
data = data.replace('\ufeff', '');
|
||||
data = data.replace(/\r\n/mg, '\n');
|
||||
|
||||
// strip out all text annotations
|
||||
data = data.replace(/\[[a-zA-Z]{1,2}\]/mg, '');
|
||||
|
||||
// strip out all docos comments
|
||||
data = data.replace(/^[^\s_]+:\n\S+[\S\s]*$/m, '');
|
||||
|
||||
// fix smart-quotes
|
||||
data = data.replace(/[“”]/g, '"');
|
||||
data = data.replace(/[‘’]/g, '\'');
|
||||
|
||||
|
||||
data = data + '\n';
|
||||
|
||||
//this should be a bug in Google Doc API, hence need to remove this once the bug is fixed
|
||||
data = data.replace(/\n\n/g, '\n');
|
||||
|
||||
fs.writeFileSync('docs/content/' + collection + '/' + name, reflow(data, 100));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* token=$(curl
|
||||
* -s https://www.google.com/accounts/ClientLogin
|
||||
* -d Email=...username...
|
||||
* -d Passwd=...password...
|
||||
* -d accountType=GOOGLE
|
||||
* -d service=writely
|
||||
* -d Gdata-version=3.0 | cut -d "=" -f 2)
|
||||
*/
|
||||
function login(username, password) {
|
||||
request('POST', 'https://www.google.com/accounts/ClientLogin',
|
||||
{
|
||||
data: {
|
||||
Email: username,
|
||||
Passwd: password,
|
||||
accountType: 'GOOGLE',
|
||||
service: 'writely',
|
||||
'Gdata-version': '3.0'
|
||||
},
|
||||
headers: {
|
||||
'Content-type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
},
|
||||
function(chunk) {
|
||||
var token;
|
||||
chunk.split('\n').forEach(function(line) {
|
||||
var parts = line.split('=');
|
||||
if (parts[0] === 'Auth') {
|
||||
token = parts[1];
|
||||
}
|
||||
});
|
||||
if (token) {
|
||||
fs.writeFileSync('tmp/gdocs.auth', token);
|
||||
console.log('logged in, token saved in \'tmp/gdocs.auth\'');
|
||||
} else {
|
||||
console.log('failed to log in');
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function getAuthToken() {
|
||||
var pwdFile = 'tmp/gdocs.auth';
|
||||
try {
|
||||
fs.statSync(pwdFile);
|
||||
return fs.readFileSync(pwdFile);
|
||||
} catch (e) {
|
||||
console.log('Please log in first...');
|
||||
}
|
||||
}
|
||||
|
||||
function request(method, url, options, response) {
|
||||
url = url.match(/http(s?):\/\/(.+?)(\/.*)/);
|
||||
var isHttps = url[1];
|
||||
var req = (isHttps ? https : http).request({
|
||||
host: url[2],
|
||||
port: (url[1] ? 443 : 80),
|
||||
path: url[3],
|
||||
method: method
|
||||
}, function(res) {
|
||||
var data;
|
||||
switch (res.statusCode) {
|
||||
case 200:
|
||||
data = [];
|
||||
res.setEncoding('utf8');
|
||||
res.on('end', function() { response(data.join('')); });
|
||||
res.on('close', function() { response(data.join('')); }); // https
|
||||
res.on('data', function(chunk) { data.push(chunk); });
|
||||
res.on('error', function(e) { console.log(e); });
|
||||
break;
|
||||
case 401:
|
||||
console.log('Error: Login credentials expired! Please login.');
|
||||
break;
|
||||
default:
|
||||
data = [];
|
||||
console.log('ERROR: ', res.statusCode);
|
||||
console.log('REQUEST URL: ', url[0]);
|
||||
console.log('REQUEST POST: ', options.data);
|
||||
console.log('REQUEST HEADERS: ', options.headers);
|
||||
console.log('RESPONSE HEADERS: ', res.headers);
|
||||
res.on('end', function() { console.log('BODY: ', data.join('')); });
|
||||
res.on('close', function() { console.log('BODY: ', data.join('')); }); // https
|
||||
res.on('data', function(chunk) { data.push(chunk); });
|
||||
res.on('error', function(e) { console.log(e); });
|
||||
}
|
||||
});
|
||||
for (var header in options.headers) {
|
||||
req.setHeader(header, options.headers[header]);
|
||||
}
|
||||
if (options.data)
|
||||
req.write(encodeData(options.data));
|
||||
req.on('end', function() {
|
||||
console.log('end');
|
||||
});
|
||||
req.end();
|
||||
}
|
||||
|
||||
function encodeData(obj) {
|
||||
var pairs = [];
|
||||
for (var key in obj) {
|
||||
pairs.push(key + '=' + obj[key]);
|
||||
}
|
||||
return pairs.join('&') + '\n';
|
||||
}
|
||||
|
||||
function askPassword(callback) {
|
||||
var stdin = process.openStdin(),
|
||||
stdio = process.binding('stdio');
|
||||
|
||||
stdio.setRawMode();
|
||||
|
||||
console.log('Enter your password:');
|
||||
var password = '';
|
||||
stdin.on('data', function(c) {
|
||||
c = c + '';
|
||||
switch (c) {
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '\u0004':
|
||||
stdio.setRawMode(false);
|
||||
stdin.pause();
|
||||
callback(password);
|
||||
break;
|
||||
case '\u0003':
|
||||
process.exit();
|
||||
break;
|
||||
default:
|
||||
password += c;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function reflow(text, margin) {
|
||||
var lines = [];
|
||||
text.split(/\n/).forEach(function(line) {
|
||||
var col = 0;
|
||||
var reflowLine = '';
|
||||
function flush() {
|
||||
reflowLine = reflowLine.replace(/\s*$/, '');
|
||||
lines.push(reflowLine);
|
||||
reflowLine = '';
|
||||
col = 0;
|
||||
}
|
||||
line.replace(/\s*\S*\s*/g, function(chunk) {
|
||||
if (col + chunk.length > margin) flush();
|
||||
reflowLine += chunk;
|
||||
col += chunk.length;
|
||||
});
|
||||
flush();
|
||||
});
|
||||
return lines.join('\n');
|
||||
}
|
||||
@@ -53,7 +53,7 @@ var getGitRepoInfo = function() {
|
||||
* @return {String} The codename if found, otherwise null/undefined
|
||||
*/
|
||||
var getCodeName = function(tagName) {
|
||||
var gitCatOutput = shell.exec('git cat-file -p ' + tagName, {silent:true}).output;
|
||||
var gitCatOutput = shell.exec('git cat-file -p ' + tagName, {silent:true}).stdout;
|
||||
var tagMessage = gitCatOutput.match(/^.*codename.*$/mg)[0];
|
||||
var codeName = tagMessage && tagMessage.match(/codename\((.*)\)/)[1];
|
||||
if (!codeName) {
|
||||
@@ -69,7 +69,7 @@ var getCodeName = function(tagName) {
|
||||
* @return {String} The build segment of the version
|
||||
*/
|
||||
function getBuild() {
|
||||
var hash = shell.exec('git rev-parse --short HEAD', {silent: true}).output.replace('\n', '');
|
||||
var hash = shell.exec('git rev-parse --short HEAD', {silent: true}).stdout.replace('\n', '');
|
||||
return 'sha.' + hash;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ var getTaggedVersion = function() {
|
||||
var gitTagResult = shell.exec('git describe --exact-match', {silent:true});
|
||||
|
||||
if (gitTagResult.code === 0) {
|
||||
var tag = gitTagResult.output.trim();
|
||||
var tag = gitTagResult.stdout.trim();
|
||||
var version = semver.parse(tag);
|
||||
|
||||
if (version && checkBranchPattern(version.version, currentPackage.branchPattern)) {
|
||||
@@ -113,7 +113,7 @@ var getPreviousVersions = function() {
|
||||
var query = NO_REMOTE_REQUESTS ? 'git tag' : 'git ls-remote --tags ' + repo_url;
|
||||
var tagResults = shell.exec(query, {silent: true});
|
||||
if (tagResults.code === 0) {
|
||||
return _(tagResults.output.match(/v[0-9].*[0-9]$/mg))
|
||||
return _(tagResults.stdout.match(/v[0-9].*[0-9]$/mg))
|
||||
.map(function(tag) {
|
||||
var version = semver.parse(tag);
|
||||
return version;
|
||||
@@ -159,7 +159,7 @@ var getCdnVersion = function() {
|
||||
{silent: true});
|
||||
if (cdnResult.code === 0) {
|
||||
// --write-out appends its content to the general request response, so extract it
|
||||
var statusCode = cdnResult.output.split('\n').pop().trim();
|
||||
var statusCode = cdnResult.stdout.split('\n').pop().trim();
|
||||
if (statusCode === '200') {
|
||||
cdnVersion = version;
|
||||
}
|
||||
|
||||
+852
-250
File diff suppressed because it is too large
Load Diff
Generated
+1603
-637
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -33,7 +33,7 @@
|
||||
"cross-spawn": "^4.0.0",
|
||||
"cz-conventional-changelog": "1.1.4",
|
||||
"dgeni": "^0.4.0",
|
||||
"dgeni-packages": "^0.14.0",
|
||||
"dgeni-packages": "^0.16.0",
|
||||
"event-stream": "~3.1.0",
|
||||
"glob": "^6.0.1",
|
||||
"grunt": "^1.0.1",
|
||||
@@ -73,7 +73,7 @@
|
||||
"marked": "~0.3.0",
|
||||
"node-html-encoder": "0.0.2",
|
||||
"promises-aplus-tests": "~2.1.0",
|
||||
"protractor": "^4.0.2",
|
||||
"protractor": "^4.0.10",
|
||||
"q": "~1.0.0",
|
||||
"q-io": "^1.10.9",
|
||||
"qq": "^0.3.5",
|
||||
@@ -84,7 +84,7 @@
|
||||
"serve-favicon": "^2.3.0",
|
||||
"serve-index": "^1.8.0",
|
||||
"serve-static": "^1.11.1",
|
||||
"shelljs": "~0.3.0",
|
||||
"shelljs": "^0.7.5",
|
||||
"sorted-object": "^1.0.0",
|
||||
"stringmap": "^0.2.2"
|
||||
},
|
||||
|
||||
+36
-1
@@ -169,6 +169,7 @@ var
|
||||
angularModule,
|
||||
uid = 0;
|
||||
|
||||
// Support: IE 9-11 only
|
||||
/**
|
||||
* documentMode is an IE-only property
|
||||
* http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx
|
||||
@@ -601,7 +602,7 @@ function isDate(value) {
|
||||
* @kind function
|
||||
*
|
||||
* @description
|
||||
* Determines if a reference is an `Array`.
|
||||
* Determines if a reference is an `Array`. Alias of Array.isArray.
|
||||
*
|
||||
* @param {*} value Reference to check.
|
||||
* @returns {boolean} True if `value` is an `Array`.
|
||||
@@ -1279,6 +1280,7 @@ function fromJson(json) {
|
||||
|
||||
var ALL_COLONS = /:/g;
|
||||
function timezoneToOffset(timezone, fallback) {
|
||||
// Support: IE 9-11 only, Edge 13-14+
|
||||
// IE/Edge do not "understand" colon (`:`) in timezone
|
||||
timezone = timezone.replace(ALL_COLONS, '');
|
||||
var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;
|
||||
@@ -1444,6 +1446,34 @@ function getNgAttribute(element, ngAttr) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function allowAutoBootstrap(document) {
|
||||
if (!document.currentScript) {
|
||||
return true;
|
||||
}
|
||||
var src = document.currentScript.getAttribute('src');
|
||||
var link = document.createElement('a');
|
||||
link.href = src;
|
||||
var scriptProtocol = link.protocol;
|
||||
var docLoadProtocol = document.location.protocol;
|
||||
if (docLoadProtocol === scriptProtocol) {
|
||||
return true;
|
||||
}
|
||||
switch (scriptProtocol) {
|
||||
case 'http:':
|
||||
case 'https:':
|
||||
case 'ftp:':
|
||||
case 'blob:':
|
||||
case 'file:':
|
||||
case 'data:':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Cached as it has to run during loading so that document.currentScript is available.
|
||||
var isAutoBootstrapAllowed = allowAutoBootstrap(window.document);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name ngApp
|
||||
@@ -1602,6 +1632,11 @@ function angularInit(element, bootstrap) {
|
||||
}
|
||||
});
|
||||
if (appElement) {
|
||||
if (!isAutoBootstrapAllowed) {
|
||||
window.console.error('Angular: disabling automatic bootstrap. <script> protocol indicates ' +
|
||||
'an extension, document.location.href does not match.');
|
||||
return;
|
||||
}
|
||||
config.strictDi = getNgAttribute(appElement, 'strict-di') !== null;
|
||||
bootstrap(appElement, module ? [module] : [], config);
|
||||
}
|
||||
|
||||
@@ -79,7 +79,6 @@
|
||||
$jsonpCallbacksProvider,
|
||||
$LocationProvider,
|
||||
$LogProvider,
|
||||
$ModelOptionsProvider,
|
||||
$ParseProvider,
|
||||
$RootScopeProvider,
|
||||
$QProvider,
|
||||
@@ -247,7 +246,6 @@ function publishExternalAPI(angular) {
|
||||
$jsonpCallbacks: $jsonpCallbacksProvider,
|
||||
$location: $LocationProvider,
|
||||
$log: $LogProvider,
|
||||
$modelOptions: $ModelOptionsProvider,
|
||||
$parse: $ParseProvider,
|
||||
$rootScope: $RootScopeProvider,
|
||||
$q: $QProvider,
|
||||
|
||||
@@ -849,8 +849,9 @@ function createInjector(modulesToLoad, strictDi) {
|
||||
}
|
||||
|
||||
function isClass(func) {
|
||||
// Support: IE 9-11 only
|
||||
// IE 9-11 do not support classes and IE9 leaks with the code below.
|
||||
if (msie <= 11 || typeof func !== 'function') {
|
||||
if (msie || typeof func !== 'function') {
|
||||
return false;
|
||||
}
|
||||
var result = func.$$ngIsClass;
|
||||
|
||||
@@ -252,7 +252,6 @@ var $AnimateProvider = ['$provide', /** @this */ function($provide) {
|
||||
var reservedRegex = new RegExp('(\\s+|\\/)' + NG_ANIMATE_CLASSNAME + '(\\s+|\\/)');
|
||||
if (reservedRegex.test(this.$$classNameFilter.toString())) {
|
||||
throw $animateMinErr('nongcls','$animateProvider.classNameFilter(regex) prohibits accepting a regex value which matches/contains the "{0}" CSS class.', NG_ANIMATE_CLASSNAME);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-4
@@ -402,7 +402,7 @@
|
||||
* * defines the parent to which the `cloneLinkingFn` will add the cloned elements.
|
||||
* * default: `$element.parent()` resp. `$element` for `transclude:'element'` resp. `transclude:true`.
|
||||
* * only needed for transcludes that are allowed to contain non html elements (e.g. SVG elements)
|
||||
* and when the `cloneLinkinFn` is passed,
|
||||
* and when the `cloneLinkingFn` is passed,
|
||||
* as those elements need to created and cloned in a special way when they are defined outside their
|
||||
* usual containers (e.g. like `<svg>`).
|
||||
* * See also the `directive.templateNamespace` property.
|
||||
@@ -943,6 +943,16 @@
|
||||
*
|
||||
* For information on how the compiler works, see the
|
||||
* {@link guide/compiler Angular HTML Compiler} section of the Developer Guide.
|
||||
*
|
||||
* @knownIssue
|
||||
*
|
||||
* ### Double Compilation
|
||||
*
|
||||
Double compilation occurs when an already compiled part of the DOM gets
|
||||
compiled again. This is an undesired effect and can lead to misbehaving directives, performance issues,
|
||||
and memory leaks. Refer to the Compiler Guide {@link guide/compiler#double-compilation-and-how-to-avoid-it
|
||||
section on double compilation} for an in-depth explanation and ways to avoid it.
|
||||
*
|
||||
*/
|
||||
|
||||
var $compileMinErr = minErr('$compile');
|
||||
@@ -1379,7 +1389,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
*
|
||||
* The default value is true in Angular 1.5.x but will switch to false in Angular 1.6.x.
|
||||
*/
|
||||
var preAssignBindingsEnabled = true;
|
||||
var preAssignBindingsEnabled = false;
|
||||
this.preAssignBindingsEnabled = function(enabled) {
|
||||
if (isDefined(enabled)) {
|
||||
preAssignBindingsEnabled = enabled;
|
||||
@@ -1949,6 +1959,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
for (var i = 0; i < nodeList.length; i++) {
|
||||
attrs = new Attributes();
|
||||
|
||||
// Support: IE 11 only
|
||||
// Workaround for #11781 and #14924
|
||||
if (msie === 11) {
|
||||
mergeConsecutiveTextNodes(nodeList, i, notLiveList);
|
||||
@@ -2222,7 +2233,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a node with an directive-start it collects all of the siblings until it finds
|
||||
* Given a node with a directive-start it collects all of the siblings until it finds
|
||||
* directive-end.
|
||||
* @param node
|
||||
* @param attrStart
|
||||
@@ -2409,7 +2420,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
}
|
||||
|
||||
if (!directive.templateUrl && directive.controller) {
|
||||
directiveValue = directive.controller;
|
||||
controllerDirectives = controllerDirectives || createMap();
|
||||
assertNoDuplicate('\'' + directiveName + '\' controller',
|
||||
controllerDirectives[directiveName], directive, $compileNode);
|
||||
|
||||
@@ -61,7 +61,9 @@ function $ControllerProvider() {
|
||||
* @description If called, allows `$controller` to find controller constructors on `window`
|
||||
*
|
||||
* @deprecated
|
||||
* This method of finding controllers has been deprecated. This will be removed in 1.7.
|
||||
* sinceVersion="v1.3.0"
|
||||
* removeVersion="v1.7.0"
|
||||
* This method of finding controllers has been deprecated.
|
||||
*/
|
||||
this.allowGlobals = function() {
|
||||
globals = true;
|
||||
|
||||
@@ -426,10 +426,11 @@ forEach(['src', 'srcset', 'href'], function(attrName) {
|
||||
|
||||
attr.$set(name, value);
|
||||
|
||||
// on IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist
|
||||
// Support: IE 9-11 only
|
||||
// On IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist
|
||||
// then calling element.setAttribute('src', 'foo') doesn't do anything, so we need
|
||||
// to set the property as well to achieve the desired effect.
|
||||
// we use attr[attrName] value since $set can sanitize the url.
|
||||
// We use attr[attrName] value since $set can sanitize the url.
|
||||
if (msie && propName) element.prop(propName, attr[name]);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1234,7 +1234,7 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
||||
function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
||||
var type = lowercase(element[0].type);
|
||||
|
||||
// In composition mode, users are still inputing intermediate text buffer,
|
||||
// In composition mode, users are still inputting intermediate text buffer,
|
||||
// hold the listener until composition is done.
|
||||
// More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent
|
||||
if (!$sniffer.android) {
|
||||
@@ -1811,9 +1811,7 @@ function radioInputType(scope, element, attr, ctrl) {
|
||||
if (doTrim) {
|
||||
value = trim(value);
|
||||
}
|
||||
// Strict comparison would cause a BC
|
||||
// eslint-disable-next-line eqeqeq
|
||||
element[0].checked = (value == ctrl.$viewValue);
|
||||
element[0].checked = (value === ctrl.$viewValue);
|
||||
};
|
||||
|
||||
attr.$observe('value', ctrl.$render);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user