angularjs-rails 1.2.16 → 1.2.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/angularjs-rails/version.rb +2 -2
- data/vendor/assets/javascripts/angular-animate.js +25 -8
- data/vendor/assets/javascripts/angular-cookies.js +21 -13
- data/vendor/assets/javascripts/angular-loader.js +8 -6
- data/vendor/assets/javascripts/angular-mocks.js +8 -6
- data/vendor/assets/javascripts/angular-resource.js +19 -10
- data/vendor/assets/javascripts/angular-route.js +3 -3
- data/vendor/assets/javascripts/angular-sanitize.js +9 -3
- data/vendor/assets/javascripts/angular-scenario.js +874 -620
- data/vendor/assets/javascripts/angular-touch.js +17 -8
- data/vendor/assets/javascripts/angular.js +870 -616
- data/vendor/assets/javascripts/unstable/angular-animate.js +28 -9
- data/vendor/assets/javascripts/unstable/angular-cookies.js +21 -13
- data/vendor/assets/javascripts/unstable/angular-loader.js +13 -6
- data/vendor/assets/javascripts/unstable/angular-messages.js +400 -0
- data/vendor/assets/javascripts/unstable/angular-mocks.js +51 -18
- data/vendor/assets/javascripts/unstable/angular-resource.js +286 -236
- data/vendor/assets/javascripts/unstable/angular-route.js +4 -5
- data/vendor/assets/javascripts/unstable/angular-sanitize.js +9 -3
- data/vendor/assets/javascripts/unstable/angular-scenario.js +2159 -1346
- data/vendor/assets/javascripts/unstable/angular-touch.js +65 -18
- data/vendor/assets/javascripts/unstable/angular.js +2138 -1322
- metadata +3 -2
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.2.
|
2
|
+
* @license AngularJS v1.2.18
|
3
3
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -187,13 +187,16 @@ ngTouch.factory('$swipe', [function() {
|
|
187
187
|
* upon tap. (Event object is available as `$event`)
|
188
188
|
*
|
189
189
|
* @example
|
190
|
-
<example>
|
190
|
+
<example module="ngClickExample" deps="angular-touch.js">
|
191
191
|
<file name="index.html">
|
192
192
|
<button ng-click="count = count + 1" ng-init="count=0">
|
193
193
|
Increment
|
194
194
|
</button>
|
195
195
|
count: {{ count }}
|
196
196
|
</file>
|
197
|
+
<file name="script.js">
|
198
|
+
angular.module('ngClickExample', ['ngTouch']);
|
199
|
+
</file>
|
197
200
|
</example>
|
198
201
|
*/
|
199
202
|
|
@@ -230,7 +233,7 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
|
|
230
233
|
//
|
231
234
|
// What happens when the browser then generates a click event?
|
232
235
|
// The browser, of course, also detects the tap and fires a click after a delay. This results in
|
233
|
-
// tapping/clicking twice.
|
236
|
+
// tapping/clicking twice. We do "clickbusting" to prevent it.
|
234
237
|
//
|
235
238
|
// How does it work?
|
236
239
|
// We attach global touchstart and click handlers, that run during the capture (early) phase.
|
@@ -253,9 +256,9 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
|
|
253
256
|
// encapsulates this ugly logic away from the user.
|
254
257
|
//
|
255
258
|
// Why not just put click handlers on the element?
|
256
|
-
// We do that too, just to be sure.
|
257
|
-
//
|
258
|
-
// the handlers are global and care only about coordinates
|
259
|
+
// We do that too, just to be sure. If the tap event caused the DOM to change,
|
260
|
+
// it is possible another element is now in that position. To take account for these possibly
|
261
|
+
// distinct elements, the handlers are global and care only about coordinates.
|
259
262
|
|
260
263
|
// Checks if the coordinates are close enough to be within the region.
|
261
264
|
function hit(x1, y1, x2, y2) {
|
@@ -469,7 +472,7 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
|
|
469
472
|
* upon left swipe. (Event object is available as `$event`)
|
470
473
|
*
|
471
474
|
* @example
|
472
|
-
<example>
|
475
|
+
<example module="ngSwipeLeftExample" deps="angular-touch.js">
|
473
476
|
<file name="index.html">
|
474
477
|
<div ng-show="!showActions" ng-swipe-left="showActions = true">
|
475
478
|
Some list content, like an email in the inbox
|
@@ -479,6 +482,9 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
|
|
479
482
|
<button ng-click="delete()">Delete</button>
|
480
483
|
</div>
|
481
484
|
</file>
|
485
|
+
<file name="script.js">
|
486
|
+
angular.module('ngSwipeLeftExample', ['ngTouch']);
|
487
|
+
</file>
|
482
488
|
</example>
|
483
489
|
*/
|
484
490
|
|
@@ -499,7 +505,7 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
|
|
499
505
|
* upon right swipe. (Event object is available as `$event`)
|
500
506
|
*
|
501
507
|
* @example
|
502
|
-
<example>
|
508
|
+
<example module="ngSwipeRightExample" deps="angular-touch.js">
|
503
509
|
<file name="index.html">
|
504
510
|
<div ng-show="!showActions" ng-swipe-left="showActions = true">
|
505
511
|
Some list content, like an email in the inbox
|
@@ -509,6 +515,9 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
|
|
509
515
|
<button ng-click="delete()">Delete</button>
|
510
516
|
</div>
|
511
517
|
</file>
|
518
|
+
<file name="script.js">
|
519
|
+
angular.module('ngSwipeRightExample', ['ngTouch']);
|
520
|
+
</file>
|
512
521
|
</example>
|
513
522
|
*/
|
514
523
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.2.
|
2
|
+
* @license AngularJS v1.2.18
|
3
3
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -68,7 +68,7 @@ function minErr(module) {
|
|
68
68
|
return match;
|
69
69
|
});
|
70
70
|
|
71
|
-
message = message + '\nhttp://errors.angularjs.org/1.2.
|
71
|
+
message = message + '\nhttp://errors.angularjs.org/1.2.18/' +
|
72
72
|
(module ? module + '/' : '') + code;
|
73
73
|
for (i = 2; i < arguments.length; i++) {
|
74
74
|
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
|
@@ -89,7 +89,6 @@ function minErr(module) {
|
|
89
89
|
-push,
|
90
90
|
-toString,
|
91
91
|
-ngMinErr,
|
92
|
-
-_angular,
|
93
92
|
-angularModule,
|
94
93
|
-nodeName_,
|
95
94
|
-uid,
|
@@ -186,7 +185,7 @@ function minErr(module) {
|
|
186
185
|
* @ngdoc function
|
187
186
|
* @name angular.lowercase
|
188
187
|
* @module ng
|
189
|
-
* @function
|
188
|
+
* @kind function
|
190
189
|
*
|
191
190
|
* @description Converts the specified string to lowercase.
|
192
191
|
* @param {string} string String to be converted to lowercase.
|
@@ -199,7 +198,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
199
198
|
* @ngdoc function
|
200
199
|
* @name angular.uppercase
|
201
200
|
* @module ng
|
202
|
-
* @function
|
201
|
+
* @kind function
|
203
202
|
*
|
204
203
|
* @description Converts the specified string to uppercase.
|
205
204
|
* @param {string} string String to be converted to uppercase.
|
@@ -240,8 +239,6 @@ var /** holds major version number for IE or NaN for real browsers */
|
|
240
239
|
toString = Object.prototype.toString,
|
241
240
|
ngMinErr = minErr('ng'),
|
242
241
|
|
243
|
-
|
244
|
-
_angular = window.angular,
|
245
242
|
/** @name angular */
|
246
243
|
angular = window.angular || (window.angular = {}),
|
247
244
|
angularModule,
|
@@ -283,7 +280,7 @@ function isArrayLike(obj) {
|
|
283
280
|
* @ngdoc function
|
284
281
|
* @name angular.forEach
|
285
282
|
* @module ng
|
286
|
-
* @function
|
283
|
+
* @kind function
|
287
284
|
*
|
288
285
|
* @description
|
289
286
|
* Invokes the `iterator` function once for each item in `obj` collection, which can be either an
|
@@ -297,7 +294,7 @@ function isArrayLike(obj) {
|
|
297
294
|
```js
|
298
295
|
var values = {name: 'misko', gender: 'male'};
|
299
296
|
var log = [];
|
300
|
-
angular.forEach(values, function(value, key){
|
297
|
+
angular.forEach(values, function(value, key) {
|
301
298
|
this.push(key + ': ' + value);
|
302
299
|
}, log);
|
303
300
|
expect(log).toEqual(['name: misko', 'gender: male']);
|
@@ -311,7 +308,7 @@ function isArrayLike(obj) {
|
|
311
308
|
function forEach(obj, iterator, context) {
|
312
309
|
var key;
|
313
310
|
if (obj) {
|
314
|
-
if (isFunction(obj)){
|
311
|
+
if (isFunction(obj)) {
|
315
312
|
for (key in obj) {
|
316
313
|
// Need to check if hasOwnProperty exists,
|
317
314
|
// as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
|
@@ -412,7 +409,7 @@ function setHashKey(obj, h) {
|
|
412
409
|
* @ngdoc function
|
413
410
|
* @name angular.extend
|
414
411
|
* @module ng
|
415
|
-
* @function
|
412
|
+
* @kind function
|
416
413
|
*
|
417
414
|
* @description
|
418
415
|
* Extends the destination object `dst` by copying all of the properties from the `src` object(s)
|
@@ -424,9 +421,9 @@ function setHashKey(obj, h) {
|
|
424
421
|
*/
|
425
422
|
function extend(dst) {
|
426
423
|
var h = dst.$$hashKey;
|
427
|
-
forEach(arguments, function(obj){
|
424
|
+
forEach(arguments, function(obj) {
|
428
425
|
if (obj !== dst) {
|
429
|
-
forEach(obj, function(value, key){
|
426
|
+
forEach(obj, function(value, key) {
|
430
427
|
dst[key] = value;
|
431
428
|
});
|
432
429
|
}
|
@@ -449,7 +446,7 @@ function inherit(parent, extra) {
|
|
449
446
|
* @ngdoc function
|
450
447
|
* @name angular.noop
|
451
448
|
* @module ng
|
452
|
-
* @function
|
449
|
+
* @kind function
|
453
450
|
*
|
454
451
|
* @description
|
455
452
|
* A function that performs no operations. This function can be useful when writing code in the
|
@@ -469,7 +466,7 @@ noop.$inject = [];
|
|
469
466
|
* @ngdoc function
|
470
467
|
* @name angular.identity
|
471
468
|
* @module ng
|
472
|
-
* @function
|
469
|
+
* @kind function
|
473
470
|
*
|
474
471
|
* @description
|
475
472
|
* A function that returns its first argument. This function is useful when writing code in the
|
@@ -491,7 +488,7 @@ function valueFn(value) {return function() {return value;};}
|
|
491
488
|
* @ngdoc function
|
492
489
|
* @name angular.isUndefined
|
493
490
|
* @module ng
|
494
|
-
* @function
|
491
|
+
* @kind function
|
495
492
|
*
|
496
493
|
* @description
|
497
494
|
* Determines if a reference is undefined.
|
@@ -506,7 +503,7 @@ function isUndefined(value){return typeof value === 'undefined';}
|
|
506
503
|
* @ngdoc function
|
507
504
|
* @name angular.isDefined
|
508
505
|
* @module ng
|
509
|
-
* @function
|
506
|
+
* @kind function
|
510
507
|
*
|
511
508
|
* @description
|
512
509
|
* Determines if a reference is defined.
|
@@ -521,7 +518,7 @@ function isDefined(value){return typeof value !== 'undefined';}
|
|
521
518
|
* @ngdoc function
|
522
519
|
* @name angular.isObject
|
523
520
|
* @module ng
|
524
|
-
* @function
|
521
|
+
* @kind function
|
525
522
|
*
|
526
523
|
* @description
|
527
524
|
* Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not
|
@@ -537,7 +534,7 @@ function isObject(value){return value != null && typeof value === 'object';}
|
|
537
534
|
* @ngdoc function
|
538
535
|
* @name angular.isString
|
539
536
|
* @module ng
|
540
|
-
* @function
|
537
|
+
* @kind function
|
541
538
|
*
|
542
539
|
* @description
|
543
540
|
* Determines if a reference is a `String`.
|
@@ -552,7 +549,7 @@ function isString(value){return typeof value === 'string';}
|
|
552
549
|
* @ngdoc function
|
553
550
|
* @name angular.isNumber
|
554
551
|
* @module ng
|
555
|
-
* @function
|
552
|
+
* @kind function
|
556
553
|
*
|
557
554
|
* @description
|
558
555
|
* Determines if a reference is a `Number`.
|
@@ -567,7 +564,7 @@ function isNumber(value){return typeof value === 'number';}
|
|
567
564
|
* @ngdoc function
|
568
565
|
* @name angular.isDate
|
569
566
|
* @module ng
|
570
|
-
* @function
|
567
|
+
* @kind function
|
571
568
|
*
|
572
569
|
* @description
|
573
570
|
* Determines if a value is a date.
|
@@ -575,7 +572,7 @@ function isNumber(value){return typeof value === 'number';}
|
|
575
572
|
* @param {*} value Reference to check.
|
576
573
|
* @returns {boolean} True if `value` is a `Date`.
|
577
574
|
*/
|
578
|
-
function isDate(value){
|
575
|
+
function isDate(value) {
|
579
576
|
return toString.call(value) === '[object Date]';
|
580
577
|
}
|
581
578
|
|
@@ -584,7 +581,7 @@ function isDate(value){
|
|
584
581
|
* @ngdoc function
|
585
582
|
* @name angular.isArray
|
586
583
|
* @module ng
|
587
|
-
* @function
|
584
|
+
* @kind function
|
588
585
|
*
|
589
586
|
* @description
|
590
587
|
* Determines if a reference is an `Array`.
|
@@ -592,16 +589,20 @@ function isDate(value){
|
|
592
589
|
* @param {*} value Reference to check.
|
593
590
|
* @returns {boolean} True if `value` is an `Array`.
|
594
591
|
*/
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
592
|
+
var isArray = (function() {
|
593
|
+
if (!isFunction(Array.isArray)) {
|
594
|
+
return function(value) {
|
595
|
+
return toString.call(value) === '[object Array]';
|
596
|
+
};
|
597
|
+
}
|
598
|
+
return Array.isArray;
|
599
|
+
})();
|
599
600
|
|
600
601
|
/**
|
601
602
|
* @ngdoc function
|
602
603
|
* @name angular.isFunction
|
603
604
|
* @module ng
|
604
|
-
* @function
|
605
|
+
* @kind function
|
605
606
|
*
|
606
607
|
* @description
|
607
608
|
* Determines if a reference is a `Function`.
|
@@ -675,7 +676,7 @@ var trim = (function() {
|
|
675
676
|
* @ngdoc function
|
676
677
|
* @name angular.isElement
|
677
678
|
* @module ng
|
678
|
-
* @function
|
679
|
+
* @kind function
|
679
680
|
*
|
680
681
|
* @description
|
681
682
|
* Determines if a reference is a DOM element (or wrapped jQuery element).
|
@@ -693,7 +694,7 @@ function isElement(node) {
|
|
693
694
|
* @param str 'key1,key2,...'
|
694
695
|
* @returns {object} in the form of {key1:true, key2:true, ...}
|
695
696
|
*/
|
696
|
-
function makeMap(str){
|
697
|
+
function makeMap(str) {
|
697
698
|
var obj = {}, items = str.split(","), i;
|
698
699
|
for ( i = 0; i < items.length; i++ )
|
699
700
|
obj[ items[i] ] = true;
|
@@ -740,7 +741,7 @@ function size(obj, ownPropsOnly) {
|
|
740
741
|
|
741
742
|
if (isArray(obj) || isString(obj)) {
|
742
743
|
return obj.length;
|
743
|
-
} else if (isObject(obj)){
|
744
|
+
} else if (isObject(obj)) {
|
744
745
|
for (key in obj)
|
745
746
|
if (!ownPropsOnly || obj.hasOwnProperty(key))
|
746
747
|
count++;
|
@@ -786,7 +787,7 @@ function isLeafNode (node) {
|
|
786
787
|
* @ngdoc function
|
787
788
|
* @name angular.copy
|
788
789
|
* @module ng
|
789
|
-
* @function
|
790
|
+
* @kind function
|
790
791
|
*
|
791
792
|
* @description
|
792
793
|
* Creates a deep copy of `source`, which should be an object or an array.
|
@@ -839,7 +840,7 @@ function isLeafNode (node) {
|
|
839
840
|
</file>
|
840
841
|
</example>
|
841
842
|
*/
|
842
|
-
function copy(source, destination){
|
843
|
+
function copy(source, destination, stackSource, stackDest) {
|
843
844
|
if (isWindow(source) || isScope(source)) {
|
844
845
|
throw ngMinErr('cpws',
|
845
846
|
"Can't copy! Making copies of Window or Scope instances is not supported.");
|
@@ -849,52 +850,82 @@ function copy(source, destination){
|
|
849
850
|
destination = source;
|
850
851
|
if (source) {
|
851
852
|
if (isArray(source)) {
|
852
|
-
destination = copy(source, []);
|
853
|
+
destination = copy(source, [], stackSource, stackDest);
|
853
854
|
} else if (isDate(source)) {
|
854
855
|
destination = new Date(source.getTime());
|
855
856
|
} else if (isRegExp(source)) {
|
856
857
|
destination = new RegExp(source.source);
|
857
858
|
} else if (isObject(source)) {
|
858
|
-
destination = copy(source, {});
|
859
|
+
destination = copy(source, {}, stackSource, stackDest);
|
859
860
|
}
|
860
861
|
}
|
861
862
|
} else {
|
862
863
|
if (source === destination) throw ngMinErr('cpi',
|
863
864
|
"Can't copy! Source and destination are identical.");
|
865
|
+
|
866
|
+
stackSource = stackSource || [];
|
867
|
+
stackDest = stackDest || [];
|
868
|
+
|
869
|
+
if (isObject(source)) {
|
870
|
+
var index = indexOf(stackSource, source);
|
871
|
+
if (index !== -1) return stackDest[index];
|
872
|
+
|
873
|
+
stackSource.push(source);
|
874
|
+
stackDest.push(destination);
|
875
|
+
}
|
876
|
+
|
877
|
+
var result;
|
864
878
|
if (isArray(source)) {
|
865
879
|
destination.length = 0;
|
866
880
|
for ( var i = 0; i < source.length; i++) {
|
867
|
-
|
881
|
+
result = copy(source[i], null, stackSource, stackDest);
|
882
|
+
if (isObject(source[i])) {
|
883
|
+
stackSource.push(source[i]);
|
884
|
+
stackDest.push(result);
|
885
|
+
}
|
886
|
+
destination.push(result);
|
868
887
|
}
|
869
888
|
} else {
|
870
889
|
var h = destination.$$hashKey;
|
871
|
-
forEach(destination, function(value, key){
|
890
|
+
forEach(destination, function(value, key) {
|
872
891
|
delete destination[key];
|
873
892
|
});
|
874
893
|
for ( var key in source) {
|
875
|
-
|
894
|
+
result = copy(source[key], null, stackSource, stackDest);
|
895
|
+
if (isObject(source[key])) {
|
896
|
+
stackSource.push(source[key]);
|
897
|
+
stackDest.push(result);
|
898
|
+
}
|
899
|
+
destination[key] = result;
|
876
900
|
}
|
877
901
|
setHashKey(destination,h);
|
878
902
|
}
|
903
|
+
|
879
904
|
}
|
880
905
|
return destination;
|
881
906
|
}
|
882
907
|
|
883
908
|
/**
|
884
|
-
*
|
909
|
+
* Creates a shallow copy of an object, an array or a primitive
|
885
910
|
*/
|
886
911
|
function shallowCopy(src, dst) {
|
887
|
-
|
912
|
+
if (isArray(src)) {
|
913
|
+
dst = dst || [];
|
914
|
+
|
915
|
+
for ( var i = 0; i < src.length; i++) {
|
916
|
+
dst[i] = src[i];
|
917
|
+
}
|
918
|
+
} else if (isObject(src)) {
|
919
|
+
dst = dst || {};
|
888
920
|
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
dst[key] = src[key];
|
921
|
+
for (var key in src) {
|
922
|
+
if (hasOwnProperty.call(src, key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
|
923
|
+
dst[key] = src[key];
|
924
|
+
}
|
894
925
|
}
|
895
926
|
}
|
896
927
|
|
897
|
-
return dst;
|
928
|
+
return dst || src;
|
898
929
|
}
|
899
930
|
|
900
931
|
|
@@ -902,7 +933,7 @@ function shallowCopy(src, dst) {
|
|
902
933
|
* @ngdoc function
|
903
934
|
* @name angular.equals
|
904
935
|
* @module ng
|
905
|
-
* @function
|
936
|
+
* @kind function
|
906
937
|
*
|
907
938
|
* @description
|
908
939
|
* Determines if two objects or two values are equivalent. Supports value types, regular
|
@@ -914,7 +945,7 @@ function shallowCopy(src, dst) {
|
|
914
945
|
* * Both objects or values are of the same type and all of their properties are equal by
|
915
946
|
* comparing them with `angular.equals`.
|
916
947
|
* * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal)
|
917
|
-
* * Both values represent the same regular expression (In
|
948
|
+
* * Both values represent the same regular expression (In JavaScript,
|
918
949
|
* /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual
|
919
950
|
* representation matches).
|
920
951
|
*
|
@@ -989,7 +1020,7 @@ function sliceArgs(args, startIndex) {
|
|
989
1020
|
* @ngdoc function
|
990
1021
|
* @name angular.bind
|
991
1022
|
* @module ng
|
992
|
-
* @function
|
1023
|
+
* @kind function
|
993
1024
|
*
|
994
1025
|
* @description
|
995
1026
|
* Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for
|
@@ -1045,7 +1076,7 @@ function toJsonReplacer(key, value) {
|
|
1045
1076
|
* @ngdoc function
|
1046
1077
|
* @name angular.toJson
|
1047
1078
|
* @module ng
|
1048
|
-
* @function
|
1079
|
+
* @kind function
|
1049
1080
|
*
|
1050
1081
|
* @description
|
1051
1082
|
* Serializes input into a JSON-formatted string. Properties with leading $ characters will be
|
@@ -1065,7 +1096,7 @@ function toJson(obj, pretty) {
|
|
1065
1096
|
* @ngdoc function
|
1066
1097
|
* @name angular.fromJson
|
1067
1098
|
* @module ng
|
1068
|
-
* @function
|
1099
|
+
* @kind function
|
1069
1100
|
*
|
1070
1101
|
* @description
|
1071
1102
|
* Deserializes a JSON string.
|
@@ -1142,7 +1173,7 @@ function tryDecodeURIComponent(value) {
|
|
1142
1173
|
*/
|
1143
1174
|
function parseKeyValue(/**string*/keyValue) {
|
1144
1175
|
var obj = {}, key_value, key;
|
1145
|
-
forEach((keyValue || "").split('&'), function(keyValue){
|
1176
|
+
forEach((keyValue || "").split('&'), function(keyValue) {
|
1146
1177
|
if ( keyValue ) {
|
1147
1178
|
key_value = keyValue.split('=');
|
1148
1179
|
key = tryDecodeURIComponent(key_value[0]);
|
@@ -1404,7 +1435,7 @@ function bootstrap(element, modules) {
|
|
1404
1435
|
}
|
1405
1436
|
|
1406
1437
|
var SNAKE_CASE_REGEXP = /[A-Z]/g;
|
1407
|
-
function snake_case(name, separator){
|
1438
|
+
function snake_case(name, separator) {
|
1408
1439
|
separator = separator || '_';
|
1409
1440
|
return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {
|
1410
1441
|
return (pos ? separator : '') + letter.toLowerCase();
|
@@ -1414,8 +1445,9 @@ function snake_case(name, separator){
|
|
1414
1445
|
function bindJQuery() {
|
1415
1446
|
// bind to jQuery if present;
|
1416
1447
|
jQuery = window.jQuery;
|
1417
|
-
//
|
1418
|
-
|
1448
|
+
// Use jQuery if it exists with proper functionality, otherwise default to us.
|
1449
|
+
// Angular 1.2+ requires jQuery 1.7.1+ for on()/off() support.
|
1450
|
+
if (jQuery && jQuery.fn.on) {
|
1419
1451
|
jqLite = jQuery;
|
1420
1452
|
extend(jQuery.fn, {
|
1421
1453
|
scope: JQLitePrototype.scope,
|
@@ -1561,7 +1593,7 @@ function setupModuleLoader(window) {
|
|
1561
1593
|
*
|
1562
1594
|
* # Module
|
1563
1595
|
*
|
1564
|
-
* A module is a collection of services, directives, filters, and configuration information.
|
1596
|
+
* A module is a collection of services, directives, controllers, filters, and configuration information.
|
1565
1597
|
* `angular.module` is used to configure the {@link auto.$injector $injector}.
|
1566
1598
|
*
|
1567
1599
|
* ```js
|
@@ -1589,9 +1621,9 @@ function setupModuleLoader(window) {
|
|
1589
1621
|
* {@link angular.bootstrap} to simplify this process for you.
|
1590
1622
|
*
|
1591
1623
|
* @param {!string} name The name of the module to create or retrieve.
|
1592
|
-
|
1593
|
-
|
1594
|
-
* @param {Function} configFn Optional configuration function for the module. Same as
|
1624
|
+
* @param {!Array.<string>=} requires If specified then new module is being created. If
|
1625
|
+
* unspecified then the module is being retrieved for further configuration.
|
1626
|
+
* @param {Function=} configFn Optional configuration function for the module. Same as
|
1595
1627
|
* {@link angular.Module#config Module#config()}.
|
1596
1628
|
* @returns {module} new module with the {@link angular.Module} api.
|
1597
1629
|
*/
|
@@ -1783,6 +1815,8 @@ function setupModuleLoader(window) {
|
|
1783
1815
|
* configuration.
|
1784
1816
|
* @description
|
1785
1817
|
* Use this method to register work which needs to be performed on module loading.
|
1818
|
+
* For more about how to configure services, see
|
1819
|
+
* {@link providers#providers_provider-recipe Provider Recipe}.
|
1786
1820
|
*/
|
1787
1821
|
config: config,
|
1788
1822
|
|
@@ -1919,11 +1953,11 @@ function setupModuleLoader(window) {
|
|
1919
1953
|
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
|
1920
1954
|
*/
|
1921
1955
|
var version = {
|
1922
|
-
full: '1.2.
|
1956
|
+
full: '1.2.18', // all of these placeholder strings will be replaced by grunt's
|
1923
1957
|
major: 1, // package task
|
1924
1958
|
minor: 2,
|
1925
|
-
dot:
|
1926
|
-
codeName: '
|
1959
|
+
dot: 18,
|
1960
|
+
codeName: 'ear-extendability'
|
1927
1961
|
};
|
1928
1962
|
|
1929
1963
|
|
@@ -2063,7 +2097,7 @@ function publishExternalAPI(angular){
|
|
2063
2097
|
* @ngdoc function
|
2064
2098
|
* @name angular.element
|
2065
2099
|
* @module ng
|
2066
|
-
* @function
|
2100
|
+
* @kind function
|
2067
2101
|
*
|
2068
2102
|
* @description
|
2069
2103
|
* Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element.
|
@@ -2146,7 +2180,7 @@ function publishExternalAPI(angular){
|
|
2146
2180
|
*/
|
2147
2181
|
|
2148
2182
|
var jqCache = JQLite.cache = {},
|
2149
|
-
jqName = JQLite.expando = 'ng
|
2183
|
+
jqName = JQLite.expando = 'ng' + new Date().getTime(),
|
2150
2184
|
jqId = 1,
|
2151
2185
|
addEventListenerFn = (window.document.addEventListener
|
2152
2186
|
? function(element, type, fn) {element.addEventListener(type, fn, false);}
|
@@ -2699,6 +2733,7 @@ forEach({
|
|
2699
2733
|
*/
|
2700
2734
|
JQLite.prototype[name] = function(arg1, arg2) {
|
2701
2735
|
var i, key;
|
2736
|
+
var nodeCount = this.length;
|
2702
2737
|
|
2703
2738
|
// jqLiteHasClass has only two arguments, but is a getter-only fn, so we need to special-case it
|
2704
2739
|
// in a way that survives minification.
|
@@ -2708,7 +2743,7 @@ forEach({
|
|
2708
2743
|
if (isObject(arg1)) {
|
2709
2744
|
|
2710
2745
|
// we are a write, but the object properties are the key/values
|
2711
|
-
for (i = 0; i <
|
2746
|
+
for (i = 0; i < nodeCount; i++) {
|
2712
2747
|
if (fn === jqLiteData) {
|
2713
2748
|
// data() takes the whole object in jQuery
|
2714
2749
|
fn(this[i], arg1);
|
@@ -2722,9 +2757,10 @@ forEach({
|
|
2722
2757
|
return this;
|
2723
2758
|
} else {
|
2724
2759
|
// we are a read, so read the first child.
|
2760
|
+
// TODO: do we still need this?
|
2725
2761
|
var value = fn.$dv;
|
2726
2762
|
// Only if we have $dv do we iterate over all, otherwise it is just the first element.
|
2727
|
-
var jj = (value === undefined) ? Math.min(
|
2763
|
+
var jj = (value === undefined) ? Math.min(nodeCount, 1) : nodeCount;
|
2728
2764
|
for (var j = 0; j < jj; j++) {
|
2729
2765
|
var nodeValue = fn(this[j], arg1, arg2);
|
2730
2766
|
value = value ? value + nodeValue : nodeValue;
|
@@ -2733,7 +2769,7 @@ forEach({
|
|
2733
2769
|
}
|
2734
2770
|
} else {
|
2735
2771
|
// we are a write, so apply to all children
|
2736
|
-
for (i = 0; i <
|
2772
|
+
for (i = 0; i < nodeCount; i++) {
|
2737
2773
|
fn(this[i], arg1, arg2);
|
2738
2774
|
}
|
2739
2775
|
// return self for chaining
|
@@ -3102,7 +3138,7 @@ HashMap.prototype = {
|
|
3102
3138
|
* @ngdoc function
|
3103
3139
|
* @module ng
|
3104
3140
|
* @name angular.injector
|
3105
|
-
* @function
|
3141
|
+
* @kind function
|
3106
3142
|
*
|
3107
3143
|
* @description
|
3108
3144
|
* Creates an injector function that can be used for retrieving services as well as for
|
@@ -3129,7 +3165,7 @@ HashMap.prototype = {
|
|
3129
3165
|
*
|
3130
3166
|
* Sometimes you want to get access to the injector of a currently running Angular app
|
3131
3167
|
* from outside Angular. Perhaps, you want to inject and compile some markup after the
|
3132
|
-
* application has been bootstrapped. You can do this using extra `injector()` added
|
3168
|
+
* application has been bootstrapped. You can do this using the extra `injector()` added
|
3133
3169
|
* to JQuery/jqLite elements. See {@link angular.element}.
|
3134
3170
|
*
|
3135
3171
|
* *This is fairly rare but could be the case if a third party library is injecting the
|
@@ -3199,7 +3235,7 @@ function annotate(fn) {
|
|
3199
3235
|
/**
|
3200
3236
|
* @ngdoc service
|
3201
3237
|
* @name $injector
|
3202
|
-
* @function
|
3238
|
+
* @kind function
|
3203
3239
|
*
|
3204
3240
|
* @description
|
3205
3241
|
*
|
@@ -3242,7 +3278,7 @@ function annotate(fn) {
|
|
3242
3278
|
* minification, and obfuscation tools since these tools change the argument names.
|
3243
3279
|
*
|
3244
3280
|
* ## `$inject` Annotation
|
3245
|
-
* By adding
|
3281
|
+
* By adding an `$inject` property onto a function the injection parameters can be specified.
|
3246
3282
|
*
|
3247
3283
|
* ## Inline
|
3248
3284
|
* As an array of injection names, where the last item in the array is the function to call.
|
@@ -3279,7 +3315,7 @@ function annotate(fn) {
|
|
3279
3315
|
* @name $injector#has
|
3280
3316
|
*
|
3281
3317
|
* @description
|
3282
|
-
* Allows the user to query if the particular service
|
3318
|
+
* Allows the user to query if the particular service exists.
|
3283
3319
|
*
|
3284
3320
|
* @param {string} Name of the service to query.
|
3285
3321
|
* @returns {boolean} returns true if injector has given service.
|
@@ -3289,8 +3325,8 @@ function annotate(fn) {
|
|
3289
3325
|
* @ngdoc method
|
3290
3326
|
* @name $injector#instantiate
|
3291
3327
|
* @description
|
3292
|
-
* Create a new instance of JS type. The method takes a constructor function invokes the new
|
3293
|
-
* operator and supplies all of the arguments to the constructor function as specified by the
|
3328
|
+
* Create a new instance of JS type. The method takes a constructor function, invokes the new
|
3329
|
+
* operator, and supplies all of the arguments to the constructor function as specified by the
|
3294
3330
|
* constructor annotation.
|
3295
3331
|
*
|
3296
3332
|
* @param {Function} Type Annotated constructor function.
|
@@ -3822,7 +3858,8 @@ function createInjector(modulesToLoad) {
|
|
3822
3858
|
function getService(serviceName) {
|
3823
3859
|
if (cache.hasOwnProperty(serviceName)) {
|
3824
3860
|
if (cache[serviceName] === INSTANTIATING) {
|
3825
|
-
throw $injectorMinErr('cdep', 'Circular dependency found: {0}',
|
3861
|
+
throw $injectorMinErr('cdep', 'Circular dependency found: {0}',
|
3862
|
+
serviceName + ' <- ' + path.join(' <- '));
|
3826
3863
|
}
|
3827
3864
|
return cache[serviceName];
|
3828
3865
|
} else {
|
@@ -3903,7 +3940,7 @@ function createInjector(modulesToLoad) {
|
|
3903
3940
|
* @requires $rootScope
|
3904
3941
|
*
|
3905
3942
|
* @description
|
3906
|
-
* When called, it checks current value of `$location.hash()` and
|
3943
|
+
* When called, it checks current value of `$location.hash()` and scrolls to the related element,
|
3907
3944
|
* according to rules specified in
|
3908
3945
|
* [Html5 spec](http://dev.w3.org/html5/spec/Overview.html#the-indicated-part-of-the-document).
|
3909
3946
|
*
|
@@ -4105,7 +4142,7 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4105
4142
|
*
|
4106
4143
|
* @ngdoc method
|
4107
4144
|
* @name $animate#enter
|
4108
|
-
* @function
|
4145
|
+
* @kind function
|
4109
4146
|
* @description Inserts the element into the DOM either after the `after` element or within
|
4110
4147
|
* the `parent` element. Once complete, the done() callback will be fired (if provided).
|
4111
4148
|
* @param {DOMElement} element the element which will be inserted into the DOM
|
@@ -4132,7 +4169,7 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4132
4169
|
*
|
4133
4170
|
* @ngdoc method
|
4134
4171
|
* @name $animate#leave
|
4135
|
-
* @function
|
4172
|
+
* @kind function
|
4136
4173
|
* @description Removes the element from the DOM. Once complete, the done() callback will be
|
4137
4174
|
* fired (if provided).
|
4138
4175
|
* @param {DOMElement} element the element which will be removed from the DOM
|
@@ -4148,7 +4185,7 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4148
4185
|
*
|
4149
4186
|
* @ngdoc method
|
4150
4187
|
* @name $animate#move
|
4151
|
-
* @function
|
4188
|
+
* @kind function
|
4152
4189
|
* @description Moves the position of the provided element within the DOM to be placed
|
4153
4190
|
* either after the `after` element or inside of the `parent` element. Once complete, the
|
4154
4191
|
* done() callback will be fired (if provided).
|
@@ -4172,7 +4209,7 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4172
4209
|
*
|
4173
4210
|
* @ngdoc method
|
4174
4211
|
* @name $animate#addClass
|
4175
|
-
* @function
|
4212
|
+
* @kind function
|
4176
4213
|
* @description Adds the provided className CSS class value to the provided element. Once
|
4177
4214
|
* complete, the done() callback will be fired (if provided).
|
4178
4215
|
* @param {DOMElement} element the element which will have the className value
|
@@ -4195,7 +4232,7 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4195
4232
|
*
|
4196
4233
|
* @ngdoc method
|
4197
4234
|
* @name $animate#removeClass
|
4198
|
-
* @function
|
4235
|
+
* @kind function
|
4199
4236
|
* @description Removes the provided className CSS class value from the provided element.
|
4200
4237
|
* Once complete, the done() callback will be fired (if provided).
|
4201
4238
|
* @param {DOMElement} element the element which will have the className value
|
@@ -4218,10 +4255,10 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
4218
4255
|
*
|
4219
4256
|
* @ngdoc method
|
4220
4257
|
* @name $animate#setClass
|
4221
|
-
* @function
|
4258
|
+
* @kind function
|
4222
4259
|
* @description Adds and/or removes the given CSS classes to and from the element.
|
4223
4260
|
* Once complete, the done() callback will be fired (if provided).
|
4224
|
-
* @param {DOMElement} element the element which will
|
4261
|
+
* @param {DOMElement} element the element which will have its CSS classes changed
|
4225
4262
|
* removed from it
|
4226
4263
|
* @param {string} add the CSS classes which will be added to the element
|
4227
4264
|
* @param {string} remove the CSS class which will be removed from the element
|
@@ -4775,7 +4812,7 @@ function $CacheFactoryProvider() {
|
|
4775
4812
|
/**
|
4776
4813
|
* @ngdoc method
|
4777
4814
|
* @name $cacheFactory.Cache#put
|
4778
|
-
* @function
|
4815
|
+
* @kind function
|
4779
4816
|
*
|
4780
4817
|
* @description
|
4781
4818
|
* Inserts a named entry into the {@link $cacheFactory.Cache Cache} object to be
|
@@ -4811,7 +4848,7 @@ function $CacheFactoryProvider() {
|
|
4811
4848
|
/**
|
4812
4849
|
* @ngdoc method
|
4813
4850
|
* @name $cacheFactory.Cache#get
|
4814
|
-
* @function
|
4851
|
+
* @kind function
|
4815
4852
|
*
|
4816
4853
|
* @description
|
4817
4854
|
* Retrieves named data stored in the {@link $cacheFactory.Cache Cache} object.
|
@@ -4835,7 +4872,7 @@ function $CacheFactoryProvider() {
|
|
4835
4872
|
/**
|
4836
4873
|
* @ngdoc method
|
4837
4874
|
* @name $cacheFactory.Cache#remove
|
4838
|
-
* @function
|
4875
|
+
* @kind function
|
4839
4876
|
*
|
4840
4877
|
* @description
|
4841
4878
|
* Removes an entry from the {@link $cacheFactory.Cache Cache} object.
|
@@ -4863,7 +4900,7 @@ function $CacheFactoryProvider() {
|
|
4863
4900
|
/**
|
4864
4901
|
* @ngdoc method
|
4865
4902
|
* @name $cacheFactory.Cache#removeAll
|
4866
|
-
* @function
|
4903
|
+
* @kind function
|
4867
4904
|
*
|
4868
4905
|
* @description
|
4869
4906
|
* Clears the cache object of any entries.
|
@@ -4879,7 +4916,7 @@ function $CacheFactoryProvider() {
|
|
4879
4916
|
/**
|
4880
4917
|
* @ngdoc method
|
4881
4918
|
* @name $cacheFactory.Cache#destroy
|
4882
|
-
* @function
|
4919
|
+
* @kind function
|
4883
4920
|
*
|
4884
4921
|
* @description
|
4885
4922
|
* Destroys the {@link $cacheFactory.Cache Cache} object entirely,
|
@@ -4896,7 +4933,7 @@ function $CacheFactoryProvider() {
|
|
4896
4933
|
/**
|
4897
4934
|
* @ngdoc method
|
4898
4935
|
* @name $cacheFactory.Cache#info
|
4899
|
-
* @function
|
4936
|
+
* @kind function
|
4900
4937
|
*
|
4901
4938
|
* @description
|
4902
4939
|
* Retrieve information regarding a particular {@link $cacheFactory.Cache Cache}.
|
@@ -4951,7 +4988,7 @@ function $CacheFactoryProvider() {
|
|
4951
4988
|
* @name $cacheFactory#info
|
4952
4989
|
*
|
4953
4990
|
* @description
|
4954
|
-
* Get information about all the
|
4991
|
+
* Get information about all the caches that have been created
|
4955
4992
|
*
|
4956
4993
|
* @returns {Object} - key-value map of `cacheId` to the result of calling `cache#info`
|
4957
4994
|
*/
|
@@ -5052,7 +5089,7 @@ function $TemplateCacheProvider() {
|
|
5052
5089
|
/**
|
5053
5090
|
* @ngdoc service
|
5054
5091
|
* @name $compile
|
5055
|
-
* @function
|
5092
|
+
* @kind function
|
5056
5093
|
*
|
5057
5094
|
* @description
|
5058
5095
|
* Compiles an HTML string or DOM into a template and produces a template function, which
|
@@ -5090,7 +5127,6 @@ function $TemplateCacheProvider() {
|
|
5090
5127
|
* template: '<div></div>', // or // function(tElement, tAttrs) { ... },
|
5091
5128
|
* // or
|
5092
5129
|
* // templateUrl: 'directive.html', // or // function(tElement, tAttrs) { ... },
|
5093
|
-
* replace: false,
|
5094
5130
|
* transclude: false,
|
5095
5131
|
* restrict: 'A',
|
5096
5132
|
* scope: false,
|
@@ -5266,7 +5302,7 @@ function $TemplateCacheProvider() {
|
|
5266
5302
|
* api/ng.$sce#getTrustedResourceUrl $sce.getTrustedResourceUrl}.
|
5267
5303
|
*
|
5268
5304
|
*
|
5269
|
-
* #### `replace`
|
5305
|
+
* #### `replace` ([*DEPRECATED*!], will be removed in next major release)
|
5270
5306
|
* specify where the template should be inserted. Defaults to `false`.
|
5271
5307
|
*
|
5272
5308
|
* * `true` - the template will replace the current element.
|
@@ -5293,11 +5329,7 @@ function $TemplateCacheProvider() {
|
|
5293
5329
|
* ```
|
5294
5330
|
*
|
5295
5331
|
* The compile function deals with transforming the template DOM. Since most directives do not do
|
5296
|
-
* template transformation, it is not used often.
|
5297
|
-
* directives that transform template DOM, such as {@link
|
5298
|
-
* api/ng.directive:ngRepeat ngRepeat}, or load the contents
|
5299
|
-
* asynchronously, such as {@link ngRoute.directive:ngView ngView}. The
|
5300
|
-
* compile function takes the following arguments.
|
5332
|
+
* template transformation, it is not used often. The compile function takes the following arguments:
|
5301
5333
|
*
|
5302
5334
|
* * `tElement` - template element - The element where the directive has been declared. It is
|
5303
5335
|
* safe to do template transformation on the element and child elements only.
|
@@ -5535,7 +5567,7 @@ var $compileMinErr = minErr('$compile');
|
|
5535
5567
|
/**
|
5536
5568
|
* @ngdoc provider
|
5537
5569
|
* @name $compileProvider
|
5538
|
-
* @function
|
5570
|
+
* @kind function
|
5539
5571
|
*
|
5540
5572
|
* @description
|
5541
5573
|
*/
|
@@ -5543,8 +5575,8 @@ $CompileProvider.$inject = ['$provide', '$$sanitizeUriProvider'];
|
|
5543
5575
|
function $CompileProvider($provide, $$sanitizeUriProvider) {
|
5544
5576
|
var hasDirectives = {},
|
5545
5577
|
Suffix = 'Directive',
|
5546
|
-
COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\
|
5547
|
-
CLASS_DIRECTIVE_REGEXP = /(([\d\
|
5578
|
+
COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w_\-]+)\s+(.*)$/,
|
5579
|
+
CLASS_DIRECTIVE_REGEXP = /(([\d\w_\-]+)(?:\:([^;]+))?;?)/;
|
5548
5580
|
|
5549
5581
|
// Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes
|
5550
5582
|
// The assumption is that future DOM event attribute names will begin with
|
@@ -5554,7 +5586,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
5554
5586
|
/**
|
5555
5587
|
* @ngdoc method
|
5556
5588
|
* @name $compileProvider#directive
|
5557
|
-
* @function
|
5589
|
+
* @kind function
|
5558
5590
|
*
|
5559
5591
|
* @description
|
5560
5592
|
* Register a new directive with the compiler.
|
@@ -5607,7 +5639,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
5607
5639
|
/**
|
5608
5640
|
* @ngdoc method
|
5609
5641
|
* @name $compileProvider#aHrefSanitizationWhitelist
|
5610
|
-
* @function
|
5642
|
+
* @kind function
|
5611
5643
|
*
|
5612
5644
|
* @description
|
5613
5645
|
* Retrieves or overrides the default regular expression that is used for whitelisting of safe
|
@@ -5637,7 +5669,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
5637
5669
|
/**
|
5638
5670
|
* @ngdoc method
|
5639
5671
|
* @name $compileProvider#imgSrcSanitizationWhitelist
|
5640
|
-
* @function
|
5672
|
+
* @kind function
|
5641
5673
|
*
|
5642
5674
|
* @description
|
5643
5675
|
* Retrieves or overrides the default regular expression that is used for whitelisting of safe
|
@@ -5681,7 +5713,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
5681
5713
|
/**
|
5682
5714
|
* @ngdoc method
|
5683
5715
|
* @name $compile.directive.Attributes#$addClass
|
5684
|
-
* @function
|
5716
|
+
* @kind function
|
5685
5717
|
*
|
5686
5718
|
* @description
|
5687
5719
|
* Adds the CSS class value specified by the classVal parameter to the element. If animations
|
@@ -5698,7 +5730,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
5698
5730
|
/**
|
5699
5731
|
* @ngdoc method
|
5700
5732
|
* @name $compile.directive.Attributes#$removeClass
|
5701
|
-
* @function
|
5733
|
+
* @kind function
|
5702
5734
|
*
|
5703
5735
|
* @description
|
5704
5736
|
* Removes the CSS class value specified by the classVal parameter from the element. If
|
@@ -5715,7 +5747,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
5715
5747
|
/**
|
5716
5748
|
* @ngdoc method
|
5717
5749
|
* @name $compile.directive.Attributes#$updateClass
|
5718
|
-
* @function
|
5750
|
+
* @kind function
|
5719
5751
|
*
|
5720
5752
|
* @description
|
5721
5753
|
* Adds and removes the appropriate CSS class values to the element based on the difference
|
@@ -5803,7 +5835,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
5803
5835
|
/**
|
5804
5836
|
* @ngdoc method
|
5805
5837
|
* @name $compile.directive.Attributes#$observe
|
5806
|
-
* @function
|
5838
|
+
* @kind function
|
5807
5839
|
*
|
5808
5840
|
* @description
|
5809
5841
|
* Observes an interpolated attribute.
|
@@ -5866,7 +5898,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
5866
5898
|
compileNodes($compileNodes, transcludeFn, $compileNodes,
|
5867
5899
|
maxPriority, ignoreDirective, previousCompileContext);
|
5868
5900
|
safeAddClass($compileNodes, 'ng-scope');
|
5869
|
-
return function publicLinkFn(scope, cloneConnectFn, transcludeControllers){
|
5901
|
+
return function publicLinkFn(scope, cloneConnectFn, transcludeControllers, parentBoundTranscludeFn){
|
5870
5902
|
assertArg(scope, 'scope');
|
5871
5903
|
// important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart
|
5872
5904
|
// and sometimes changes the structure of the DOM.
|
@@ -5888,7 +5920,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
5888
5920
|
}
|
5889
5921
|
|
5890
5922
|
if (cloneConnectFn) cloneConnectFn($linkNode, scope);
|
5891
|
-
if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode);
|
5923
|
+
if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode, parentBoundTranscludeFn);
|
5892
5924
|
return $linkNode;
|
5893
5925
|
};
|
5894
5926
|
}
|
@@ -5943,7 +5975,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
5943
5975
|
!childNodes.length)
|
5944
5976
|
? null
|
5945
5977
|
: compileNodes(childNodes,
|
5946
|
-
nodeLinkFn ?
|
5978
|
+
nodeLinkFn ? (
|
5979
|
+
(nodeLinkFn.transcludeOnThisElement || !nodeLinkFn.templateOnThisElement)
|
5980
|
+
&& nodeLinkFn.transclude) : transcludeFn);
|
5947
5981
|
|
5948
5982
|
linkFns.push(nodeLinkFn, childLinkFn);
|
5949
5983
|
linkFnFound = linkFnFound || nodeLinkFn || childLinkFn;
|
@@ -5954,8 +5988,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
5954
5988
|
// return a linking function if we have found anything, null otherwise
|
5955
5989
|
return linkFnFound ? compositeLinkFn : null;
|
5956
5990
|
|
5957
|
-
function compositeLinkFn(scope, nodeList, $rootElement,
|
5958
|
-
var nodeLinkFn, childLinkFn, node, $node, childScope,
|
5991
|
+
function compositeLinkFn(scope, nodeList, $rootElement, parentBoundTranscludeFn) {
|
5992
|
+
var nodeLinkFn, childLinkFn, node, $node, childScope, i, ii, n, childBoundTranscludeFn;
|
5959
5993
|
|
5960
5994
|
// copy nodeList so that linking doesn't break due to live list updates.
|
5961
5995
|
var nodeListLength = nodeList.length,
|
@@ -5977,23 +6011,32 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
5977
6011
|
} else {
|
5978
6012
|
childScope = scope;
|
5979
6013
|
}
|
5980
|
-
|
5981
|
-
if (
|
5982
|
-
|
5983
|
-
|
5984
|
-
|
6014
|
+
|
6015
|
+
if ( nodeLinkFn.transcludeOnThisElement ) {
|
6016
|
+
childBoundTranscludeFn = createBoundTranscludeFn(scope, nodeLinkFn.transclude, parentBoundTranscludeFn);
|
6017
|
+
|
6018
|
+
} else if (!nodeLinkFn.templateOnThisElement && parentBoundTranscludeFn) {
|
6019
|
+
childBoundTranscludeFn = parentBoundTranscludeFn;
|
6020
|
+
|
6021
|
+
} else if (!parentBoundTranscludeFn && transcludeFn) {
|
6022
|
+
childBoundTranscludeFn = createBoundTranscludeFn(scope, transcludeFn);
|
6023
|
+
|
5985
6024
|
} else {
|
5986
|
-
|
6025
|
+
childBoundTranscludeFn = null;
|
5987
6026
|
}
|
6027
|
+
|
6028
|
+
nodeLinkFn(childLinkFn, childScope, node, $rootElement, childBoundTranscludeFn);
|
6029
|
+
|
5988
6030
|
} else if (childLinkFn) {
|
5989
|
-
childLinkFn(scope, node.childNodes, undefined,
|
6031
|
+
childLinkFn(scope, node.childNodes, undefined, parentBoundTranscludeFn);
|
5990
6032
|
}
|
5991
6033
|
}
|
5992
6034
|
}
|
5993
6035
|
}
|
5994
6036
|
|
5995
|
-
function createBoundTranscludeFn(scope, transcludeFn) {
|
5996
|
-
|
6037
|
+
function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) {
|
6038
|
+
|
6039
|
+
var boundTranscludeFn = function(transcludedScope, cloneFn, controllers) {
|
5997
6040
|
var scopeCreated = false;
|
5998
6041
|
|
5999
6042
|
if (!transcludedScope) {
|
@@ -6002,12 +6045,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6002
6045
|
scopeCreated = true;
|
6003
6046
|
}
|
6004
6047
|
|
6005
|
-
var clone = transcludeFn(transcludedScope, cloneFn, controllers);
|
6048
|
+
var clone = transcludeFn(transcludedScope, cloneFn, controllers, previousBoundTranscludeFn);
|
6006
6049
|
if (scopeCreated) {
|
6007
|
-
clone.on('$destroy',
|
6050
|
+
clone.on('$destroy', function() { transcludedScope.$destroy(); });
|
6008
6051
|
}
|
6009
6052
|
return clone;
|
6010
6053
|
};
|
6054
|
+
|
6055
|
+
return boundTranscludeFn;
|
6011
6056
|
}
|
6012
6057
|
|
6013
6058
|
/**
|
@@ -6185,6 +6230,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6185
6230
|
templateDirective = previousCompileContext.templateDirective,
|
6186
6231
|
nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective,
|
6187
6232
|
hasTranscludeDirective = false,
|
6233
|
+
hasTemplate = false,
|
6188
6234
|
hasElementTranscludeDirective = previousCompileContext.hasElementTranscludeDirective,
|
6189
6235
|
$compileNode = templateAttrs.$$element = jqLite(compileNode),
|
6190
6236
|
directive,
|
@@ -6275,6 +6321,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6275
6321
|
}
|
6276
6322
|
|
6277
6323
|
if (directive.template) {
|
6324
|
+
hasTemplate = true;
|
6278
6325
|
assertNoDuplicate('template', templateDirective, directive, $compileNode);
|
6279
6326
|
templateDirective = directive;
|
6280
6327
|
|
@@ -6289,7 +6336,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6289
6336
|
if (jqLiteIsTextNode(directiveValue)) {
|
6290
6337
|
$template = [];
|
6291
6338
|
} else {
|
6292
|
-
$template = jqLite(directiveValue);
|
6339
|
+
$template = jqLite(trim(directiveValue));
|
6293
6340
|
}
|
6294
6341
|
compileNode = $template[0];
|
6295
6342
|
|
@@ -6324,6 +6371,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6324
6371
|
}
|
6325
6372
|
|
6326
6373
|
if (directive.templateUrl) {
|
6374
|
+
hasTemplate = true;
|
6327
6375
|
assertNoDuplicate('template', templateDirective, directive, $compileNode);
|
6328
6376
|
templateDirective = directive;
|
6329
6377
|
|
@@ -6332,7 +6380,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6332
6380
|
}
|
6333
6381
|
|
6334
6382
|
nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode,
|
6335
|
-
templateAttrs, jqCollection, childTranscludeFn, preLinkFns, postLinkFns, {
|
6383
|
+
templateAttrs, jqCollection, hasTranscludeDirective && childTranscludeFn, preLinkFns, postLinkFns, {
|
6336
6384
|
controllerDirectives: controllerDirectives,
|
6337
6385
|
newIsolateScopeDirective: newIsolateScopeDirective,
|
6338
6386
|
templateDirective: templateDirective,
|
@@ -6360,7 +6408,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6360
6408
|
}
|
6361
6409
|
|
6362
6410
|
nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true;
|
6363
|
-
nodeLinkFn.
|
6411
|
+
nodeLinkFn.transcludeOnThisElement = hasTranscludeDirective;
|
6412
|
+
nodeLinkFn.templateOnThisElement = hasTemplate;
|
6413
|
+
nodeLinkFn.transclude = childTranscludeFn;
|
6414
|
+
|
6364
6415
|
previousCompileContext.hasElementTranscludeDirective = hasElementTranscludeDirective;
|
6365
6416
|
|
6366
6417
|
// might be normal or delayed nodeLinkFn depending on if templateUrl is present
|
@@ -6372,6 +6423,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6372
6423
|
if (pre) {
|
6373
6424
|
if (attrStart) pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd);
|
6374
6425
|
pre.require = directive.require;
|
6426
|
+
pre.directiveName = directiveName;
|
6375
6427
|
if (newIsolateScopeDirective === directive || directive.$$isolateScope) {
|
6376
6428
|
pre = cloneAndAnnotateFn(pre, {isolateScope: true});
|
6377
6429
|
}
|
@@ -6380,6 +6432,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6380
6432
|
if (post) {
|
6381
6433
|
if (attrStart) post = groupElementsLinkFnWrapper(post, attrStart, attrEnd);
|
6382
6434
|
post.require = directive.require;
|
6435
|
+
post.directiveName = directiveName;
|
6383
6436
|
if (newIsolateScopeDirective === directive || directive.$$isolateScope) {
|
6384
6437
|
post = cloneAndAnnotateFn(post, {isolateScope: true});
|
6385
6438
|
}
|
@@ -6388,7 +6441,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6388
6441
|
}
|
6389
6442
|
|
6390
6443
|
|
6391
|
-
function getControllers(require, $element, elementControllers) {
|
6444
|
+
function getControllers(directiveName, require, $element, elementControllers) {
|
6392
6445
|
var value, retrievalMethod = 'data', optional = false;
|
6393
6446
|
if (isString(require)) {
|
6394
6447
|
while((value = require.charAt(0)) == '^' || value == '?') {
|
@@ -6414,7 +6467,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6414
6467
|
} else if (isArray(require)) {
|
6415
6468
|
value = [];
|
6416
6469
|
forEach(require, function(require) {
|
6417
|
-
value.push(getControllers(require, $element, elementControllers));
|
6470
|
+
value.push(getControllers(directiveName, require, $element, elementControllers));
|
6418
6471
|
});
|
6419
6472
|
}
|
6420
6473
|
return value;
|
@@ -6437,7 +6490,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6437
6490
|
|
6438
6491
|
isolateScope = scope.$new(true);
|
6439
6492
|
|
6440
|
-
if (templateDirective && (templateDirective === newIsolateScopeDirective
|
6493
|
+
if (templateDirective && (templateDirective === newIsolateScopeDirective ||
|
6494
|
+
templateDirective === newIsolateScopeDirective.$$originalDirective)) {
|
6441
6495
|
$linkNode.data('$isolateScope', isolateScope) ;
|
6442
6496
|
} else {
|
6443
6497
|
$linkNode.data('$isolateScopeNoTemplate', isolateScope);
|
@@ -6557,7 +6611,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6557
6611
|
try {
|
6558
6612
|
linkFn = preLinkFns[i];
|
6559
6613
|
linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs,
|
6560
|
-
linkFn.require && getControllers(linkFn.require, $element, elementControllers), transcludeFn);
|
6614
|
+
linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers), transcludeFn);
|
6561
6615
|
} catch (e) {
|
6562
6616
|
$exceptionHandler(e, startingTag($element));
|
6563
6617
|
}
|
@@ -6577,7 +6631,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6577
6631
|
try {
|
6578
6632
|
linkFn = postLinkFns[i];
|
6579
6633
|
linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs,
|
6580
|
-
linkFn.require && getControllers(linkFn.require, $element, elementControllers), transcludeFn);
|
6634
|
+
linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers), transcludeFn);
|
6581
6635
|
} catch (e) {
|
6582
6636
|
$exceptionHandler(e, startingTag($element));
|
6583
6637
|
}
|
@@ -6663,7 +6717,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6663
6717
|
// reapply the old attributes to the new element
|
6664
6718
|
forEach(dst, function(value, key) {
|
6665
6719
|
if (key.charAt(0) != '$') {
|
6666
|
-
if (src[key]) {
|
6720
|
+
if (src[key] && src[key] !== value) {
|
6667
6721
|
value += (key === 'style' ? ';' : ' ') + src[key];
|
6668
6722
|
}
|
6669
6723
|
dst.$set(key, value, true, srcAttr[key]);
|
@@ -6716,7 +6770,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6716
6770
|
if (jqLiteIsTextNode(content)) {
|
6717
6771
|
$template = [];
|
6718
6772
|
} else {
|
6719
|
-
$template = jqLite(content);
|
6773
|
+
$template = jqLite(trim(content));
|
6720
6774
|
}
|
6721
6775
|
compileNode = $template[0];
|
6722
6776
|
|
@@ -6752,7 +6806,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6752
6806
|
});
|
6753
6807
|
afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn);
|
6754
6808
|
|
6755
|
-
|
6756
6809
|
while(linkQueue.length) {
|
6757
6810
|
var scope = linkQueue.shift(),
|
6758
6811
|
beforeTemplateLinkNode = linkQueue.shift(),
|
@@ -6774,8 +6827,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6774
6827
|
// Copy in CSS classes from original node
|
6775
6828
|
safeAddClass(jqLite(linkNode), oldClasses);
|
6776
6829
|
}
|
6777
|
-
if (afterTemplateNodeLinkFn.
|
6778
|
-
childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude);
|
6830
|
+
if (afterTemplateNodeLinkFn.transcludeOnThisElement) {
|
6831
|
+
childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);
|
6779
6832
|
} else {
|
6780
6833
|
childBoundTranscludeFn = boundTranscludeFn;
|
6781
6834
|
}
|
@@ -6789,13 +6842,17 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6789
6842
|
});
|
6790
6843
|
|
6791
6844
|
return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, boundTranscludeFn) {
|
6845
|
+
var childBoundTranscludeFn = boundTranscludeFn;
|
6792
6846
|
if (linkQueue) {
|
6793
6847
|
linkQueue.push(scope);
|
6794
6848
|
linkQueue.push(node);
|
6795
6849
|
linkQueue.push(rootElement);
|
6796
|
-
linkQueue.push(
|
6850
|
+
linkQueue.push(childBoundTranscludeFn);
|
6797
6851
|
} else {
|
6798
|
-
afterTemplateNodeLinkFn
|
6852
|
+
if (afterTemplateNodeLinkFn.transcludeOnThisElement) {
|
6853
|
+
childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);
|
6854
|
+
}
|
6855
|
+
afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, childBoundTranscludeFn);
|
6799
6856
|
}
|
6800
6857
|
};
|
6801
6858
|
}
|
@@ -6820,23 +6877,31 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6820
6877
|
}
|
6821
6878
|
|
6822
6879
|
|
6823
|
-
|
6824
|
-
|
6825
|
-
|
6826
|
-
|
6827
|
-
|
6828
|
-
|
6829
|
-
|
6830
|
-
|
6831
|
-
|
6832
|
-
|
6833
|
-
|
6834
|
-
node
|
6835
|
-
|
6836
|
-
|
6837
|
-
|
6880
|
+
function addTextInterpolateDirective(directives, text) {
|
6881
|
+
var interpolateFn = $interpolate(text, true);
|
6882
|
+
if (interpolateFn) {
|
6883
|
+
directives.push({
|
6884
|
+
priority: 0,
|
6885
|
+
compile: function textInterpolateCompileFn(templateNode) {
|
6886
|
+
// when transcluding a template that has bindings in the root
|
6887
|
+
// then we don't have a parent and should do this in the linkFn
|
6888
|
+
var parent = templateNode.parent(), hasCompileParent = parent.length;
|
6889
|
+
if (hasCompileParent) safeAddClass(templateNode.parent(), 'ng-binding');
|
6890
|
+
|
6891
|
+
return function textInterpolateLinkFn(scope, node) {
|
6892
|
+
var parent = node.parent(),
|
6893
|
+
bindings = parent.data('$binding') || [];
|
6894
|
+
bindings.push(interpolateFn);
|
6895
|
+
parent.data('$binding', bindings);
|
6896
|
+
if (!hasCompileParent) safeAddClass(parent, 'ng-binding');
|
6897
|
+
scope.$watch(interpolateFn, function interpolateFnWatchAction(value) {
|
6898
|
+
node[0].nodeValue = value;
|
6899
|
+
});
|
6900
|
+
};
|
6901
|
+
}
|
6902
|
+
});
|
6903
|
+
}
|
6838
6904
|
}
|
6839
|
-
}
|
6840
6905
|
|
6841
6906
|
|
6842
6907
|
function getTrustedContext(node, attrNormalizedName) {
|
@@ -6997,7 +7062,9 @@ function directiveNormalize(name) {
|
|
6997
7062
|
* element attributes. The values reflect current binding state `{{ }}`. The normalization is
|
6998
7063
|
* needed since all of these are treated as equivalent in Angular:
|
6999
7064
|
*
|
7065
|
+
* ```
|
7000
7066
|
* <span ng:bind="a" ng-bind="a" data-ng-bind="a" x-ng-bind="a">
|
7067
|
+
* ```
|
7001
7068
|
*/
|
7002
7069
|
|
7003
7070
|
/**
|
@@ -7011,7 +7078,7 @@ function directiveNormalize(name) {
|
|
7011
7078
|
/**
|
7012
7079
|
* @ngdoc method
|
7013
7080
|
* @name $compile.directive.Attributes#$set
|
7014
|
-
* @function
|
7081
|
+
* @kind function
|
7015
7082
|
*
|
7016
7083
|
* @description
|
7017
7084
|
* Set DOM element attribute value.
|
@@ -7329,9 +7396,9 @@ function $HttpProvider() {
|
|
7329
7396
|
common: {
|
7330
7397
|
'Accept': 'application/json, text/plain, */*'
|
7331
7398
|
},
|
7332
|
-
post:
|
7333
|
-
put:
|
7334
|
-
patch:
|
7399
|
+
post: shallowCopy(CONTENT_TYPE_APPLICATION_JSON),
|
7400
|
+
put: shallowCopy(CONTENT_TYPE_APPLICATION_JSON),
|
7401
|
+
patch: shallowCopy(CONTENT_TYPE_APPLICATION_JSON)
|
7335
7402
|
},
|
7336
7403
|
|
7337
7404
|
xsrfCookieName: 'XSRF-TOKEN',
|
@@ -7573,14 +7640,14 @@ function $HttpProvider() {
|
|
7573
7640
|
*
|
7574
7641
|
* There are two kinds of interceptors (and two kinds of rejection interceptors):
|
7575
7642
|
*
|
7576
|
-
* * `request`: interceptors get called with http `config` object. The function is free to
|
7577
|
-
* modify the `config` or create a new one. The function needs to return the `config`
|
7578
|
-
* directly or
|
7643
|
+
* * `request`: interceptors get called with a http `config` object. The function is free to
|
7644
|
+
* modify the `config` object or create a new one. The function needs to return the `config`
|
7645
|
+
* object directly, or a promise containing the `config` or a new `config` object.
|
7579
7646
|
* * `requestError`: interceptor gets called when a previous interceptor threw an error or
|
7580
7647
|
* resolved with a rejection.
|
7581
7648
|
* * `response`: interceptors get called with http `response` object. The function is free to
|
7582
|
-
* modify the `response` or create a new one. The function needs to return the `response`
|
7583
|
-
* directly or as a promise.
|
7649
|
+
* modify the `response` object or create a new one. The function needs to return the `response`
|
7650
|
+
* object directly, or as a promise containing the `response` or a new `response` object.
|
7584
7651
|
* * `responseError`: interceptor gets called when a previous interceptor threw an error or
|
7585
7652
|
* resolved with a rejection.
|
7586
7653
|
*
|
@@ -7592,7 +7659,7 @@ function $HttpProvider() {
|
|
7592
7659
|
* // optional method
|
7593
7660
|
* 'request': function(config) {
|
7594
7661
|
* // do something on success
|
7595
|
-
* return config
|
7662
|
+
* return config;
|
7596
7663
|
* },
|
7597
7664
|
*
|
7598
7665
|
* // optional method
|
@@ -7609,7 +7676,7 @@ function $HttpProvider() {
|
|
7609
7676
|
* // optional method
|
7610
7677
|
* 'response': function(response) {
|
7611
7678
|
* // do something on success
|
7612
|
-
* return response
|
7679
|
+
* return response;
|
7613
7680
|
* },
|
7614
7681
|
*
|
7615
7682
|
* // optional method
|
@@ -7770,7 +7837,7 @@ function $HttpProvider() {
|
|
7770
7837
|
* caching.
|
7771
7838
|
* - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise}
|
7772
7839
|
* that should abort the request when resolved.
|
7773
|
-
* - **withCredentials** - `{boolean}` - whether to
|
7840
|
+
* - **withCredentials** - `{boolean}` - whether to set the `withCredentials` flag on the
|
7774
7841
|
* XHR object. See [requests with credentials]https://developer.mozilla.org/en/http_access_control#section_5
|
7775
7842
|
* for more information.
|
7776
7843
|
* - **responseType** - `{string}` - see
|
@@ -7808,11 +7875,11 @@ function $HttpProvider() {
|
|
7808
7875
|
<button id="samplegetbtn" ng-click="updateModel('GET', 'http-hello.html')">Sample GET</button>
|
7809
7876
|
<button id="samplejsonpbtn"
|
7810
7877
|
ng-click="updateModel('JSONP',
|
7811
|
-
'
|
7878
|
+
'https://angularjs.org/greet.php?callback=JSON_CALLBACK&name=Super%20Hero')">
|
7812
7879
|
Sample JSONP
|
7813
7880
|
</button>
|
7814
7881
|
<button id="invalidjsonpbtn"
|
7815
|
-
ng-click="updateModel('JSONP', '
|
7882
|
+
ng-click="updateModel('JSONP', 'https://angularjs.org/doesntexist&callback=JSON_CALLBACK')">
|
7816
7883
|
Invalid JSONP
|
7817
7884
|
</button>
|
7818
7885
|
<pre>http status code: {{status}}</pre>
|
@@ -7892,14 +7959,6 @@ function $HttpProvider() {
|
|
7892
7959
|
config.headers = headers;
|
7893
7960
|
config.method = uppercase(config.method);
|
7894
7961
|
|
7895
|
-
var xsrfValue = urlIsSameOrigin(config.url)
|
7896
|
-
? $browser.cookies()[config.xsrfCookieName || defaults.xsrfCookieName]
|
7897
|
-
: undefined;
|
7898
|
-
if (xsrfValue) {
|
7899
|
-
headers[(config.xsrfHeaderName || defaults.xsrfHeaderName)] = xsrfValue;
|
7900
|
-
}
|
7901
|
-
|
7902
|
-
|
7903
7962
|
var serverRequest = function(config) {
|
7904
7963
|
headers = config.headers;
|
7905
7964
|
var reqData = transformData(config.data, headersGetter(headers), config.transformRequest);
|
@@ -8164,7 +8223,7 @@ function $HttpProvider() {
|
|
8164
8223
|
} else {
|
8165
8224
|
// serving from cache
|
8166
8225
|
if (isArray(cachedResp)) {
|
8167
|
-
resolvePromise(cachedResp[1], cachedResp[0],
|
8226
|
+
resolvePromise(cachedResp[1], cachedResp[0], shallowCopy(cachedResp[2]), cachedResp[3]);
|
8168
8227
|
} else {
|
8169
8228
|
resolvePromise(cachedResp, 200, {}, 'OK');
|
8170
8229
|
}
|
@@ -8175,8 +8234,17 @@ function $HttpProvider() {
|
|
8175
8234
|
}
|
8176
8235
|
}
|
8177
8236
|
|
8178
|
-
|
8237
|
+
|
8238
|
+
// if we won't have the response in cache, set the xsrf headers and
|
8239
|
+
// send the request to the backend
|
8179
8240
|
if (isUndefined(cachedResp)) {
|
8241
|
+
var xsrfValue = urlIsSameOrigin(config.url)
|
8242
|
+
? $browser.cookies()[config.xsrfCookieName || defaults.xsrfCookieName]
|
8243
|
+
: undefined;
|
8244
|
+
if (xsrfValue) {
|
8245
|
+
reqHeaders[(config.xsrfHeaderName || defaults.xsrfHeaderName)] = xsrfValue;
|
8246
|
+
}
|
8247
|
+
|
8180
8248
|
$httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout,
|
8181
8249
|
config.withCredentials, config.responseType);
|
8182
8250
|
}
|
@@ -8303,16 +8371,13 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
|
|
8303
8371
|
var callbackId = '_' + (callbacks.counter++).toString(36);
|
8304
8372
|
callbacks[callbackId] = function(data) {
|
8305
8373
|
callbacks[callbackId].data = data;
|
8374
|
+
callbacks[callbackId].called = true;
|
8306
8375
|
};
|
8307
8376
|
|
8308
8377
|
var jsonpDone = jsonpReq(url.replace('JSON_CALLBACK', 'angular.callbacks.' + callbackId),
|
8309
|
-
function() {
|
8310
|
-
|
8311
|
-
|
8312
|
-
} else {
|
8313
|
-
completeRequest(callback, status || -2);
|
8314
|
-
}
|
8315
|
-
callbacks[callbackId] = angular.noop;
|
8378
|
+
callbackId, function(status, text) {
|
8379
|
+
completeRequest(callback, status, callbacks[callbackId].data, "", text);
|
8380
|
+
callbacks[callbackId] = noop;
|
8316
8381
|
});
|
8317
8382
|
} else {
|
8318
8383
|
|
@@ -8414,34 +8479,52 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
|
|
8414
8479
|
}
|
8415
8480
|
};
|
8416
8481
|
|
8417
|
-
function jsonpReq(url, done) {
|
8482
|
+
function jsonpReq(url, callbackId, done) {
|
8418
8483
|
// we can't use jQuery/jqLite here because jQuery does crazy shit with script elements, e.g.:
|
8419
8484
|
// - fetches local scripts via XHR and evals them
|
8420
8485
|
// - adds and immediately removes script elements from the document
|
8421
|
-
var script = rawDocument.createElement('script'),
|
8422
|
-
|
8423
|
-
script.onreadystatechange = script.onload = script.onerror = null;
|
8424
|
-
rawDocument.body.removeChild(script);
|
8425
|
-
if (done) done();
|
8426
|
-
};
|
8427
|
-
|
8428
|
-
script.type = 'text/javascript';
|
8486
|
+
var script = rawDocument.createElement('script'), callback = null;
|
8487
|
+
script.type = "text/javascript";
|
8429
8488
|
script.src = url;
|
8489
|
+
script.async = true;
|
8490
|
+
|
8491
|
+
callback = function(event) {
|
8492
|
+
removeEventListenerFn(script, "load", callback);
|
8493
|
+
removeEventListenerFn(script, "error", callback);
|
8494
|
+
rawDocument.body.removeChild(script);
|
8495
|
+
script = null;
|
8496
|
+
var status = -1;
|
8497
|
+
var text = "unknown";
|
8498
|
+
|
8499
|
+
if (event) {
|
8500
|
+
if (event.type === "load" && !callbacks[callbackId].called) {
|
8501
|
+
event = { type: "error" };
|
8502
|
+
}
|
8503
|
+
text = event.type;
|
8504
|
+
status = event.type === "error" ? 404 : 200;
|
8505
|
+
}
|
8506
|
+
|
8507
|
+
if (done) {
|
8508
|
+
done(status, text);
|
8509
|
+
}
|
8510
|
+
};
|
8511
|
+
|
8512
|
+
addEventListenerFn(script, "load", callback);
|
8513
|
+
addEventListenerFn(script, "error", callback);
|
8430
8514
|
|
8431
|
-
if (msie
|
8515
|
+
if (msie <= 8) {
|
8432
8516
|
script.onreadystatechange = function() {
|
8433
|
-
if (/loaded|complete/.test(script.readyState)) {
|
8434
|
-
|
8517
|
+
if (isString(script.readyState) && /loaded|complete/.test(script.readyState)) {
|
8518
|
+
script.onreadystatechange = null;
|
8519
|
+
callback({
|
8520
|
+
type: 'load'
|
8521
|
+
});
|
8435
8522
|
}
|
8436
8523
|
};
|
8437
|
-
} else {
|
8438
|
-
script.onload = script.onerror = function() {
|
8439
|
-
doneWrapper();
|
8440
|
-
};
|
8441
8524
|
}
|
8442
8525
|
|
8443
8526
|
rawDocument.body.appendChild(script);
|
8444
|
-
return
|
8527
|
+
return callback;
|
8445
8528
|
}
|
8446
8529
|
}
|
8447
8530
|
|
@@ -8450,7 +8533,7 @@ var $interpolateMinErr = minErr('$interpolate');
|
|
8450
8533
|
/**
|
8451
8534
|
* @ngdoc provider
|
8452
8535
|
* @name $interpolateProvider
|
8453
|
-
* @function
|
8536
|
+
* @kind function
|
8454
8537
|
*
|
8455
8538
|
* @description
|
8456
8539
|
*
|
@@ -8468,7 +8551,7 @@ var $interpolateMinErr = minErr('$interpolate');
|
|
8468
8551
|
});
|
8469
8552
|
|
8470
8553
|
|
8471
|
-
customInterpolationApp.controller('DemoController', function
|
8554
|
+
customInterpolationApp.controller('DemoController', function() {
|
8472
8555
|
this.label = "This binding is brought you by // interpolation symbols.";
|
8473
8556
|
});
|
8474
8557
|
</script>
|
@@ -8531,7 +8614,7 @@ function $InterpolateProvider() {
|
|
8531
8614
|
/**
|
8532
8615
|
* @ngdoc service
|
8533
8616
|
* @name $interpolate
|
8534
|
-
* @function
|
8617
|
+
* @kind function
|
8535
8618
|
*
|
8536
8619
|
* @requires $parse
|
8537
8620
|
* @requires $sce
|
@@ -8623,10 +8706,24 @@ function $InterpolateProvider() {
|
|
8623
8706
|
} else {
|
8624
8707
|
part = $sce.valueOf(part);
|
8625
8708
|
}
|
8626
|
-
if (part
|
8709
|
+
if (part == null) { // null || undefined
|
8627
8710
|
part = '';
|
8628
|
-
} else
|
8629
|
-
|
8711
|
+
} else {
|
8712
|
+
switch (typeof part) {
|
8713
|
+
case 'string':
|
8714
|
+
{
|
8715
|
+
break;
|
8716
|
+
}
|
8717
|
+
case 'number':
|
8718
|
+
{
|
8719
|
+
part = '' + part;
|
8720
|
+
break;
|
8721
|
+
}
|
8722
|
+
default:
|
8723
|
+
{
|
8724
|
+
part = toJson(part);
|
8725
|
+
}
|
8726
|
+
}
|
8630
8727
|
}
|
8631
8728
|
}
|
8632
8729
|
concat[i] = part;
|
@@ -9137,7 +9234,7 @@ function LocationHashbangUrl(appBase, hashPrefix) {
|
|
9137
9234
|
Matches paths for file protocol on windows,
|
9138
9235
|
such as /C:/foo/bar, and captures only /foo/bar.
|
9139
9236
|
*/
|
9140
|
-
var windowsFilePathExp =
|
9237
|
+
var windowsFilePathExp = /^\/[A-Z]:(\/.*)/;
|
9141
9238
|
|
9142
9239
|
var firstPathSegmentMatch;
|
9143
9240
|
|
@@ -9146,10 +9243,7 @@ function LocationHashbangUrl(appBase, hashPrefix) {
|
|
9146
9243
|
url = url.replace(base, '');
|
9147
9244
|
}
|
9148
9245
|
|
9149
|
-
|
9150
|
-
* The input URL intentionally contains a
|
9151
|
-
* first path segment that ends with a colon.
|
9152
|
-
*/
|
9246
|
+
// The input URL intentionally contains a first path segment that ends with a colon.
|
9153
9247
|
if (windowsFilePathExp.exec(url)) {
|
9154
9248
|
return path;
|
9155
9249
|
}
|
@@ -9205,6 +9299,16 @@ function LocationHashbangInHtml5Url(appBase, hashPrefix) {
|
|
9205
9299
|
return appBaseNoFile;
|
9206
9300
|
}
|
9207
9301
|
};
|
9302
|
+
|
9303
|
+
this.$$compose = function() {
|
9304
|
+
var search = toKeyValue(this.$$search),
|
9305
|
+
hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';
|
9306
|
+
|
9307
|
+
this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;
|
9308
|
+
// include hashPrefix in $$absUrl when $$url is empty so IE8 & 9 do not reload page because of removal of '#'
|
9309
|
+
this.$$absUrl = appBase + hashPrefix + this.$$url;
|
9310
|
+
};
|
9311
|
+
|
9208
9312
|
}
|
9209
9313
|
|
9210
9314
|
|
@@ -9336,15 +9440,37 @@ LocationHashbangInHtml5Url.prototype =
|
|
9336
9440
|
*
|
9337
9441
|
* Change search part when called with parameter and return `$location`.
|
9338
9442
|
*
|
9443
|
+
*
|
9444
|
+
* ```js
|
9445
|
+
* // given url http://example.com/#/some/path?foo=bar&baz=xoxo
|
9446
|
+
* var searchObject = $location.search();
|
9447
|
+
* // => {foo: 'bar', baz: 'xoxo'}
|
9448
|
+
*
|
9449
|
+
*
|
9450
|
+
* // set foo to 'yipee'
|
9451
|
+
* $location.search('foo', 'yipee');
|
9452
|
+
* // => $location
|
9453
|
+
* ```
|
9454
|
+
*
|
9339
9455
|
* @param {string|Object.<string>|Object.<Array.<string>>} search New search params - string or
|
9340
|
-
* hash object.
|
9341
|
-
*
|
9456
|
+
* hash object.
|
9457
|
+
*
|
9458
|
+
* When called with a single argument the method acts as a setter, setting the `search` component
|
9459
|
+
* of `$location` to the specified value.
|
9460
|
+
*
|
9461
|
+
* If the argument is a hash object containing an array of values, these values will be encoded
|
9462
|
+
* as duplicate search parameters in the url.
|
9342
9463
|
*
|
9343
|
-
* @param {(string|Array<string>)=} paramValue If `search` is a string, then `paramValue` will
|
9344
|
-
* single search
|
9345
|
-
* comma-separated value. If `paramValue` is `null`, the parameter will be deleted.
|
9464
|
+
* @param {(string|Array<string>)=} paramValue If `search` is a string, then `paramValue` will
|
9465
|
+
* override only a single search property.
|
9346
9466
|
*
|
9347
|
-
*
|
9467
|
+
* If `paramValue` is an array, it will override the property of the `search` component of
|
9468
|
+
* `$location` specified via the first argument.
|
9469
|
+
*
|
9470
|
+
* If `paramValue` is `null`, the property specified via the first argument will be deleted.
|
9471
|
+
*
|
9472
|
+
* @return {Object} If called with no arguments returns the parsed `search` object. If called with
|
9473
|
+
* one or more arguments returns `$location` object itself.
|
9348
9474
|
*/
|
9349
9475
|
search: function(search, paramValue) {
|
9350
9476
|
switch (arguments.length) {
|
@@ -9557,6 +9683,39 @@ function $LocationProvider(){
|
|
9557
9683
|
absHref = urlResolve(absHref.animVal).href;
|
9558
9684
|
}
|
9559
9685
|
|
9686
|
+
// Make relative links work in HTML5 mode for legacy browsers (or at least IE8 & 9)
|
9687
|
+
// The href should be a regular url e.g. /link/somewhere or link/somewhere or ../somewhere or
|
9688
|
+
// somewhere#anchor or http://example.com/somewhere
|
9689
|
+
if (LocationMode === LocationHashbangInHtml5Url) {
|
9690
|
+
// get the actual href attribute - see
|
9691
|
+
// http://msdn.microsoft.com/en-us/library/ie/dd347148(v=vs.85).aspx
|
9692
|
+
var href = elm.attr('href') || elm.attr('xlink:href');
|
9693
|
+
|
9694
|
+
if (href.indexOf('://') < 0) { // Ignore absolute URLs
|
9695
|
+
var prefix = '#' + hashPrefix;
|
9696
|
+
if (href[0] == '/') {
|
9697
|
+
// absolute path - replace old path
|
9698
|
+
absHref = appBase + prefix + href;
|
9699
|
+
} else if (href[0] == '#') {
|
9700
|
+
// local anchor
|
9701
|
+
absHref = appBase + prefix + ($location.path() || '/') + href;
|
9702
|
+
} else {
|
9703
|
+
// relative path - join with current path
|
9704
|
+
var stack = $location.path().split("/"),
|
9705
|
+
parts = href.split("/");
|
9706
|
+
for (var i=0; i<parts.length; i++) {
|
9707
|
+
if (parts[i] == ".")
|
9708
|
+
continue;
|
9709
|
+
else if (parts[i] == "..")
|
9710
|
+
stack.pop();
|
9711
|
+
else if (parts[i].length)
|
9712
|
+
stack.push(parts[i]);
|
9713
|
+
}
|
9714
|
+
absHref = appBase + prefix + stack.join('/');
|
9715
|
+
}
|
9716
|
+
}
|
9717
|
+
}
|
9718
|
+
|
9560
9719
|
var rewrittenUrl = $location.$$rewrite(absHref);
|
9561
9720
|
|
9562
9721
|
if (absHref && !elm.attr('target') && rewrittenUrl && !event.isDefaultPrevented()) {
|
@@ -9917,9 +10076,6 @@ Lexer.prototype = {
|
|
9917
10076
|
|
9918
10077
|
this.tokens = [];
|
9919
10078
|
|
9920
|
-
var token;
|
9921
|
-
var json = [];
|
9922
|
-
|
9923
10079
|
while (this.index < this.text.length) {
|
9924
10080
|
this.ch = this.text.charAt(this.index);
|
9925
10081
|
if (this.is('"\'')) {
|
@@ -9928,19 +10084,11 @@ Lexer.prototype = {
|
|
9928
10084
|
this.readNumber();
|
9929
10085
|
} else if (this.isIdent(this.ch)) {
|
9930
10086
|
this.readIdent();
|
9931
|
-
// identifiers can only be if the preceding char was a { or ,
|
9932
|
-
if (this.was('{,') && json[0] === '{' &&
|
9933
|
-
(token = this.tokens[this.tokens.length - 1])) {
|
9934
|
-
token.json = token.text.indexOf('.') === -1;
|
9935
|
-
}
|
9936
10087
|
} else if (this.is('(){}[].,;:?')) {
|
9937
10088
|
this.tokens.push({
|
9938
10089
|
index: this.index,
|
9939
|
-
text: this.ch
|
9940
|
-
json: (this.was(':[,') && this.is('{[')) || this.is('}]:,')
|
10090
|
+
text: this.ch
|
9941
10091
|
});
|
9942
|
-
if (this.is('{[')) json.unshift(this.ch);
|
9943
|
-
if (this.is('}]')) json.shift();
|
9944
10092
|
this.index++;
|
9945
10093
|
} else if (this.isWhitespace(this.ch)) {
|
9946
10094
|
this.index++;
|
@@ -9961,8 +10109,7 @@ Lexer.prototype = {
|
|
9961
10109
|
this.tokens.push({
|
9962
10110
|
index: this.index,
|
9963
10111
|
text: this.ch,
|
9964
|
-
fn: fn
|
9965
|
-
json: (this.was('[,:') && this.is('+-'))
|
10112
|
+
fn: fn
|
9966
10113
|
});
|
9967
10114
|
this.index += 1;
|
9968
10115
|
} else {
|
@@ -10045,7 +10192,8 @@ Lexer.prototype = {
|
|
10045
10192
|
this.tokens.push({
|
10046
10193
|
index: start,
|
10047
10194
|
text: number,
|
10048
|
-
|
10195
|
+
literal: true,
|
10196
|
+
constant: true,
|
10049
10197
|
fn: function() { return number; }
|
10050
10198
|
});
|
10051
10199
|
},
|
@@ -10097,7 +10245,8 @@ Lexer.prototype = {
|
|
10097
10245
|
// OPERATORS is our own object so we don't need to use special hasOwnPropertyFn
|
10098
10246
|
if (OPERATORS.hasOwnProperty(ident)) {
|
10099
10247
|
token.fn = OPERATORS[ident];
|
10100
|
-
token.
|
10248
|
+
token.literal = true;
|
10249
|
+
token.constant = true;
|
10101
10250
|
} else {
|
10102
10251
|
var getter = getterFn(ident, this.options, this.text);
|
10103
10252
|
token.fn = extend(function(self, locals) {
|
@@ -10114,13 +10263,11 @@ Lexer.prototype = {
|
|
10114
10263
|
if (methodName) {
|
10115
10264
|
this.tokens.push({
|
10116
10265
|
index:lastDot,
|
10117
|
-
text: '.'
|
10118
|
-
json: false
|
10266
|
+
text: '.'
|
10119
10267
|
});
|
10120
10268
|
this.tokens.push({
|
10121
10269
|
index: lastDot + 1,
|
10122
|
-
text: methodName
|
10123
|
-
json: false
|
10270
|
+
text: methodName
|
10124
10271
|
});
|
10125
10272
|
}
|
10126
10273
|
},
|
@@ -10158,7 +10305,8 @@ Lexer.prototype = {
|
|
10158
10305
|
index: start,
|
10159
10306
|
text: rawString,
|
10160
10307
|
string: string,
|
10161
|
-
|
10308
|
+
literal: true,
|
10309
|
+
constant: true,
|
10162
10310
|
fn: function() { return string; }
|
10163
10311
|
});
|
10164
10312
|
return;
|
@@ -10190,28 +10338,12 @@ Parser.ZERO = extend(function () {
|
|
10190
10338
|
Parser.prototype = {
|
10191
10339
|
constructor: Parser,
|
10192
10340
|
|
10193
|
-
parse: function (text
|
10341
|
+
parse: function (text) {
|
10194
10342
|
this.text = text;
|
10195
10343
|
|
10196
|
-
//TODO(i): strip all the obsolte json stuff from this file
|
10197
|
-
this.json = json;
|
10198
|
-
|
10199
10344
|
this.tokens = this.lexer.lex(text);
|
10200
10345
|
|
10201
|
-
|
10202
|
-
// The extra level of aliasing is here, just in case the lexer misses something, so that
|
10203
|
-
// we prevent any accidental execution in JSON.
|
10204
|
-
this.assignment = this.logicalOR;
|
10205
|
-
|
10206
|
-
this.functionCall =
|
10207
|
-
this.fieldAccess =
|
10208
|
-
this.objectIndex =
|
10209
|
-
this.filterChain = function() {
|
10210
|
-
this.throwError('is not valid json', {text: text, index: 0});
|
10211
|
-
};
|
10212
|
-
}
|
10213
|
-
|
10214
|
-
var value = json ? this.primary() : this.statements();
|
10346
|
+
var value = this.statements();
|
10215
10347
|
|
10216
10348
|
if (this.tokens.length !== 0) {
|
10217
10349
|
this.throwError('is an unexpected token', this.tokens[0]);
|
@@ -10238,10 +10370,8 @@ Parser.prototype = {
|
|
10238
10370
|
if (!primary) {
|
10239
10371
|
this.throwError('not a primary expression', token);
|
10240
10372
|
}
|
10241
|
-
|
10242
|
-
|
10243
|
-
primary.literal = true;
|
10244
|
-
}
|
10373
|
+
primary.literal = !!token.literal;
|
10374
|
+
primary.constant = !!token.constant;
|
10245
10375
|
}
|
10246
10376
|
|
10247
10377
|
var next, context;
|
@@ -10289,9 +10419,6 @@ Parser.prototype = {
|
|
10289
10419
|
expect: function(e1, e2, e3, e4){
|
10290
10420
|
var token = this.peek(e1, e2, e3, e4);
|
10291
10421
|
if (token) {
|
10292
|
-
if (this.json && !token.json) {
|
10293
|
-
this.throwError('is not valid json', token);
|
10294
|
-
}
|
10295
10422
|
this.tokens.shift();
|
10296
10423
|
return token;
|
10297
10424
|
}
|
@@ -10926,7 +11053,7 @@ function getterFn(path, options, fullExp) {
|
|
10926
11053
|
/**
|
10927
11054
|
* @ngdoc provider
|
10928
11055
|
* @name $parseProvider
|
10929
|
-
* @function
|
11056
|
+
* @kind function
|
10930
11057
|
*
|
10931
11058
|
* @description
|
10932
11059
|
* `$parseProvider` can be used for configuring the default behavior of the {@link ng.$parse $parse}
|
@@ -11045,7 +11172,7 @@ function $ParseProvider() {
|
|
11045
11172
|
|
11046
11173
|
var lexer = new Lexer($parseOptions);
|
11047
11174
|
var parser = new Parser(lexer, $filter, $parseOptions);
|
11048
|
-
parsedExpression = parser.parse(exp
|
11175
|
+
parsedExpression = parser.parse(exp);
|
11049
11176
|
|
11050
11177
|
if (exp !== 'hasOwnProperty') {
|
11051
11178
|
// Only cache the value if it's not going to mess up the cache object
|
@@ -11256,7 +11383,7 @@ function qFactory(nextTick, exceptionHandler) {
|
|
11256
11383
|
/**
|
11257
11384
|
* @ngdoc method
|
11258
11385
|
* @name $q#defer
|
11259
|
-
* @function
|
11386
|
+
* @kind function
|
11260
11387
|
*
|
11261
11388
|
* @description
|
11262
11389
|
* Creates a `Deferred` object which represents a task which will finish in the future.
|
@@ -11413,7 +11540,7 @@ function qFactory(nextTick, exceptionHandler) {
|
|
11413
11540
|
/**
|
11414
11541
|
* @ngdoc method
|
11415
11542
|
* @name $q#reject
|
11416
|
-
* @function
|
11543
|
+
* @kind function
|
11417
11544
|
*
|
11418
11545
|
* @description
|
11419
11546
|
* Creates a promise that is resolved as rejected with the specified `reason`. This api should be
|
@@ -11473,7 +11600,7 @@ function qFactory(nextTick, exceptionHandler) {
|
|
11473
11600
|
/**
|
11474
11601
|
* @ngdoc method
|
11475
11602
|
* @name $q#when
|
11476
|
-
* @function
|
11603
|
+
* @kind function
|
11477
11604
|
*
|
11478
11605
|
* @description
|
11479
11606
|
* Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise.
|
@@ -11545,7 +11672,7 @@ function qFactory(nextTick, exceptionHandler) {
|
|
11545
11672
|
/**
|
11546
11673
|
* @ngdoc method
|
11547
11674
|
* @name $q#all
|
11548
|
-
* @function
|
11675
|
+
* @kind function
|
11549
11676
|
*
|
11550
11677
|
* @description
|
11551
11678
|
* Combines multiple promises into a single promise that is resolved when all of the input
|
@@ -11636,7 +11763,7 @@ function $$RAFProvider(){ //rAF
|
|
11636
11763
|
*
|
11637
11764
|
* Loop operations are optimized by using while(count--) { ... }
|
11638
11765
|
* - this means that in order to keep the same order of execution as addition we have to add
|
11639
|
-
* items to the array at the beginning (
|
11766
|
+
* items to the array at the beginning (unshift) instead of at the end (push)
|
11640
11767
|
*
|
11641
11768
|
* Child scopes are created and removed often
|
11642
11769
|
* - Using an array would be slow since inserts in middle are expensive so we use linked list
|
@@ -11770,7 +11897,7 @@ function $RootScopeProvider(){
|
|
11770
11897
|
/**
|
11771
11898
|
* @ngdoc method
|
11772
11899
|
* @name $rootScope.Scope#$new
|
11773
|
-
* @function
|
11900
|
+
* @kind function
|
11774
11901
|
*
|
11775
11902
|
* @description
|
11776
11903
|
* Creates a new child {@link ng.$rootScope.Scope scope}.
|
@@ -11802,18 +11929,23 @@ function $RootScopeProvider(){
|
|
11802
11929
|
child.$$asyncQueue = this.$$asyncQueue;
|
11803
11930
|
child.$$postDigestQueue = this.$$postDigestQueue;
|
11804
11931
|
} else {
|
11805
|
-
|
11806
|
-
|
11807
|
-
|
11808
|
-
|
11809
|
-
|
11810
|
-
|
11932
|
+
// Only create a child scope class if somebody asks for one,
|
11933
|
+
// but cache it to allow the VM to optimize lookups.
|
11934
|
+
if (!this.$$childScopeClass) {
|
11935
|
+
this.$$childScopeClass = function() {
|
11936
|
+
this.$$watchers = this.$$nextSibling =
|
11937
|
+
this.$$childHead = this.$$childTail = null;
|
11938
|
+
this.$$listeners = {};
|
11939
|
+
this.$$listenerCount = {};
|
11940
|
+
this.$id = nextUid();
|
11941
|
+
this.$$childScopeClass = null;
|
11942
|
+
};
|
11943
|
+
this.$$childScopeClass.prototype = this;
|
11944
|
+
}
|
11945
|
+
child = new this.$$childScopeClass();
|
11811
11946
|
}
|
11812
11947
|
child['this'] = child;
|
11813
|
-
child.$$listeners = {};
|
11814
|
-
child.$$listenerCount = {};
|
11815
11948
|
child.$parent = this;
|
11816
|
-
child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null;
|
11817
11949
|
child.$$prevSibling = this.$$childTail;
|
11818
11950
|
if (this.$$childHead) {
|
11819
11951
|
this.$$childTail.$$nextSibling = child;
|
@@ -11827,7 +11959,7 @@ function $RootScopeProvider(){
|
|
11827
11959
|
/**
|
11828
11960
|
* @ngdoc method
|
11829
11961
|
* @name $rootScope.Scope#$watch
|
11830
|
-
* @function
|
11962
|
+
* @kind function
|
11831
11963
|
*
|
11832
11964
|
* @description
|
11833
11965
|
* Registers a `listener` callback to be executed whenever the `watchExpression` changes.
|
@@ -11839,10 +11971,14 @@ function $RootScopeProvider(){
|
|
11839
11971
|
* {@link ng.$rootScope.Scope#$digest $digest()} and should be idempotent.)
|
11840
11972
|
* - The `listener` is called only when the value from the current `watchExpression` and the
|
11841
11973
|
* previous call to `watchExpression` are not equal (with the exception of the initial run,
|
11842
|
-
* see below).
|
11843
|
-
*
|
11844
|
-
*
|
11845
|
-
*
|
11974
|
+
* see below). Inequality is determined according to reference inequality,
|
11975
|
+
* [strict comparison](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators)
|
11976
|
+
* via the `!==` Javascript operator, unless `objectEquality == true`
|
11977
|
+
* (see next point)
|
11978
|
+
* - When `objectEquality == true`, inequality of the `watchExpression` is determined
|
11979
|
+
* according to the {@link angular.equals} function. To save the value of the object for
|
11980
|
+
* later comparison, the {@link angular.copy} function is used. This therefore means that
|
11981
|
+
* watching complex objects will have adverse memory and performance implications.
|
11846
11982
|
* - The watch `listener` may change the model, which may trigger other `listener`s to fire.
|
11847
11983
|
* This is achieved by rerunning the watchers until no changes are detected. The rerun
|
11848
11984
|
* iteration limit is 10 to prevent an infinite loop deadlock.
|
@@ -11877,13 +12013,17 @@ function $RootScopeProvider(){
|
|
11877
12013
|
expect(scope.counter).toEqual(0);
|
11878
12014
|
|
11879
12015
|
scope.$digest();
|
11880
|
-
//
|
11881
|
-
expect(scope.counter).toEqual(
|
12016
|
+
// the listener is always called during the first $digest loop after it was registered
|
12017
|
+
expect(scope.counter).toEqual(1);
|
11882
12018
|
|
11883
|
-
scope.name = 'adam';
|
11884
12019
|
scope.$digest();
|
12020
|
+
// but now it will not be called unless the value changes
|
11885
12021
|
expect(scope.counter).toEqual(1);
|
11886
12022
|
|
12023
|
+
scope.name = 'adam';
|
12024
|
+
scope.$digest();
|
12025
|
+
expect(scope.counter).toEqual(2);
|
12026
|
+
|
11887
12027
|
|
11888
12028
|
|
11889
12029
|
// Using a listener function
|
@@ -11969,7 +12109,7 @@ function $RootScopeProvider(){
|
|
11969
12109
|
// the while loop reads in reverse order.
|
11970
12110
|
array.unshift(watcher);
|
11971
12111
|
|
11972
|
-
return function() {
|
12112
|
+
return function deregisterWatch() {
|
11973
12113
|
arrayRemove(array, watcher);
|
11974
12114
|
lastDirtyWatch = null;
|
11975
12115
|
};
|
@@ -11979,7 +12119,7 @@ function $RootScopeProvider(){
|
|
11979
12119
|
/**
|
11980
12120
|
* @ngdoc method
|
11981
12121
|
* @name $rootScope.Scope#$watchCollection
|
11982
|
-
* @function
|
12122
|
+
* @kind function
|
11983
12123
|
*
|
11984
12124
|
* @description
|
11985
12125
|
* Shallow watches the properties of an object and fires whenever any of the properties change
|
@@ -12155,7 +12295,7 @@ function $RootScopeProvider(){
|
|
12155
12295
|
/**
|
12156
12296
|
* @ngdoc method
|
12157
12297
|
* @name $rootScope.Scope#$digest
|
12158
|
-
* @function
|
12298
|
+
* @kind function
|
12159
12299
|
*
|
12160
12300
|
* @description
|
12161
12301
|
* Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and
|
@@ -12190,12 +12330,16 @@ function $RootScopeProvider(){
|
|
12190
12330
|
expect(scope.counter).toEqual(0);
|
12191
12331
|
|
12192
12332
|
scope.$digest();
|
12193
|
-
//
|
12194
|
-
expect(scope.counter).toEqual(
|
12333
|
+
// the listener is always called during the first $digest loop after it was registered
|
12334
|
+
expect(scope.counter).toEqual(1);
|
12195
12335
|
|
12196
|
-
scope.name = 'adam';
|
12197
12336
|
scope.$digest();
|
12337
|
+
// but now it will not be called unless the value changes
|
12198
12338
|
expect(scope.counter).toEqual(1);
|
12339
|
+
|
12340
|
+
scope.name = 'adam';
|
12341
|
+
scope.$digest();
|
12342
|
+
expect(scope.counter).toEqual(2);
|
12199
12343
|
* ```
|
12200
12344
|
*
|
12201
12345
|
*/
|
@@ -12247,7 +12391,7 @@ function $RootScopeProvider(){
|
|
12247
12391
|
&& isNaN(value) && isNaN(last)))) {
|
12248
12392
|
dirty = true;
|
12249
12393
|
lastDirtyWatch = watch;
|
12250
|
-
watch.last = watch.eq ? copy(value) : value;
|
12394
|
+
watch.last = watch.eq ? copy(value, null) : value;
|
12251
12395
|
watch.fn(value, ((last === initWatchVal) ? value : last), current);
|
12252
12396
|
if (ttl < 5) {
|
12253
12397
|
logIdx = 4 - ttl;
|
@@ -12322,7 +12466,7 @@ function $RootScopeProvider(){
|
|
12322
12466
|
/**
|
12323
12467
|
* @ngdoc method
|
12324
12468
|
* @name $rootScope.Scope#$destroy
|
12325
|
-
* @function
|
12469
|
+
* @kind function
|
12326
12470
|
*
|
12327
12471
|
* @description
|
12328
12472
|
* Removes the current scope (and all of its children) from the parent scope. Removal implies
|
@@ -12383,7 +12527,7 @@ function $RootScopeProvider(){
|
|
12383
12527
|
/**
|
12384
12528
|
* @ngdoc method
|
12385
12529
|
* @name $rootScope.Scope#$eval
|
12386
|
-
* @function
|
12530
|
+
* @kind function
|
12387
12531
|
*
|
12388
12532
|
* @description
|
12389
12533
|
* Executes the `expression` on the current scope and returns the result. Any exceptions in
|
@@ -12415,7 +12559,7 @@ function $RootScopeProvider(){
|
|
12415
12559
|
/**
|
12416
12560
|
* @ngdoc method
|
12417
12561
|
* @name $rootScope.Scope#$evalAsync
|
12418
|
-
* @function
|
12562
|
+
* @kind function
|
12419
12563
|
*
|
12420
12564
|
* @description
|
12421
12565
|
* Executes the expression on the current scope at a later point in time.
|
@@ -12462,7 +12606,7 @@ function $RootScopeProvider(){
|
|
12462
12606
|
/**
|
12463
12607
|
* @ngdoc method
|
12464
12608
|
* @name $rootScope.Scope#$apply
|
12465
|
-
* @function
|
12609
|
+
* @kind function
|
12466
12610
|
*
|
12467
12611
|
* @description
|
12468
12612
|
* `$apply()` is used to execute an expression in angular from outside of the angular
|
@@ -12524,7 +12668,7 @@ function $RootScopeProvider(){
|
|
12524
12668
|
/**
|
12525
12669
|
* @ngdoc method
|
12526
12670
|
* @name $rootScope.Scope#$on
|
12527
|
-
* @function
|
12671
|
+
* @kind function
|
12528
12672
|
*
|
12529
12673
|
* @description
|
12530
12674
|
* Listens on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for
|
@@ -12573,7 +12717,7 @@ function $RootScopeProvider(){
|
|
12573
12717
|
/**
|
12574
12718
|
* @ngdoc method
|
12575
12719
|
* @name $rootScope.Scope#$emit
|
12576
|
-
* @function
|
12720
|
+
* @kind function
|
12577
12721
|
*
|
12578
12722
|
* @description
|
12579
12723
|
* Dispatches an event `name` upwards through the scope hierarchy notifying the
|
@@ -12641,7 +12785,7 @@ function $RootScopeProvider(){
|
|
12641
12785
|
/**
|
12642
12786
|
* @ngdoc method
|
12643
12787
|
* @name $rootScope.Scope#$broadcast
|
12644
|
-
* @function
|
12788
|
+
* @kind function
|
12645
12789
|
*
|
12646
12790
|
* @description
|
12647
12791
|
* Dispatches an event `name` downwards to all child scopes (and their children) notifying the
|
@@ -12889,7 +13033,7 @@ function adjustMatchers(matchers) {
|
|
12889
13033
|
/**
|
12890
13034
|
* @ngdoc service
|
12891
13035
|
* @name $sceDelegate
|
12892
|
-
* @function
|
13036
|
+
* @kind function
|
12893
13037
|
*
|
12894
13038
|
* @description
|
12895
13039
|
*
|
@@ -12961,7 +13105,7 @@ function $SceDelegateProvider() {
|
|
12961
13105
|
/**
|
12962
13106
|
* @ngdoc method
|
12963
13107
|
* @name $sceDelegateProvider#resourceUrlWhitelist
|
12964
|
-
* @function
|
13108
|
+
* @kind function
|
12965
13109
|
*
|
12966
13110
|
* @param {Array=} whitelist When provided, replaces the resourceUrlWhitelist with the value
|
12967
13111
|
* provided. This must be an array or null. A snapshot of this array is used so further
|
@@ -12990,7 +13134,7 @@ function $SceDelegateProvider() {
|
|
12990
13134
|
/**
|
12991
13135
|
* @ngdoc method
|
12992
13136
|
* @name $sceDelegateProvider#resourceUrlBlacklist
|
12993
|
-
* @function
|
13137
|
+
* @kind function
|
12994
13138
|
*
|
12995
13139
|
* @param {Array=} blacklist When provided, replaces the resourceUrlBlacklist with the value
|
12996
13140
|
* provided. This must be an array or null. A snapshot of this array is used so further
|
@@ -13217,7 +13361,7 @@ function $SceDelegateProvider() {
|
|
13217
13361
|
/**
|
13218
13362
|
* @ngdoc service
|
13219
13363
|
* @name $sce
|
13220
|
-
* @function
|
13364
|
+
* @kind function
|
13221
13365
|
*
|
13222
13366
|
* @description
|
13223
13367
|
*
|
@@ -13343,7 +13487,7 @@ function $SceDelegateProvider() {
|
|
13343
13487
|
*
|
13344
13488
|
* | Context | Notes |
|
13345
13489
|
* |---------------------|----------------|
|
13346
|
-
* | `$sce.HTML` | For HTML that's safe to source into the application. The {@link ng.directive:ngBindHtml ngBindHtml} directive uses this context for bindings. |
|
13490
|
+
* | `$sce.HTML` | For HTML that's safe to source into the application. The {@link ng.directive:ngBindHtml ngBindHtml} directive uses this context for bindings. If an unsafe value is encountered and the {@link ngSanitize $sanitize} module is present this will sanitize the value instead of throwing an error. |
|
13347
13491
|
* | `$sce.CSS` | For CSS that's safe to source into the application. Currently unused. Feel free to use it in your own directives. |
|
13348
13492
|
* | `$sce.URL` | For URLs that are safe to follow as links. Currently unused (`<a href=` and `<img src=` sanitize their urls and don't constitute an SCE context. |
|
13349
13493
|
* | `$sce.RESOURCE_URL` | For URLs that are not only safe to follow as links, but whose contents are also safe to include in your application. Examples include `ng-include`, `src` / `ngSrc` bindings for tags other than `IMG` (e.g. `IFRAME`, `OBJECT`, etc.) <br><br>Note that `$sce.RESOURCE_URL` makes a stronger statement about the URL than `$sce.URL` does and therefore contexts requiring values trusted for `$sce.RESOURCE_URL` can be used anywhere that values trusted for `$sce.URL` are required. |
|
@@ -13367,7 +13511,7 @@ function $SceDelegateProvider() {
|
|
13367
13511
|
* - `**`: matches zero or more occurrences of *any* character. As such, it's not
|
13368
13512
|
* not appropriate to use in for a scheme, domain, etc. as it would match too much. (e.g.
|
13369
13513
|
* http://**.example.com/ would match http://evil.com/?ignore=.example.com/ and that might
|
13370
|
-
* not have been the intention.)
|
13514
|
+
* not have been the intention.) Its usage at the very end of the path is ok. (e.g.
|
13371
13515
|
* http://foo.example.com/templates/**).
|
13372
13516
|
* - **RegExp** (*see caveat below*)
|
13373
13517
|
* - *Caveat*: While regular expressions are powerful and offer great flexibility, their syntax
|
@@ -13488,7 +13632,7 @@ function $SceProvider() {
|
|
13488
13632
|
/**
|
13489
13633
|
* @ngdoc method
|
13490
13634
|
* @name $sceProvider#enabled
|
13491
|
-
* @function
|
13635
|
+
* @kind function
|
13492
13636
|
*
|
13493
13637
|
* @param {boolean=} value If provided, then enables/disables SCE.
|
13494
13638
|
* @return {boolean} true if SCE is enabled, false otherwise.
|
@@ -13561,12 +13705,12 @@ function $SceProvider() {
|
|
13561
13705
|
'document. See http://docs.angularjs.org/api/ng.$sce for more information.');
|
13562
13706
|
}
|
13563
13707
|
|
13564
|
-
var sce =
|
13708
|
+
var sce = shallowCopy(SCE_CONTEXTS);
|
13565
13709
|
|
13566
13710
|
/**
|
13567
13711
|
* @ngdoc method
|
13568
13712
|
* @name $sce#isEnabled
|
13569
|
-
* @function
|
13713
|
+
* @kind function
|
13570
13714
|
*
|
13571
13715
|
* @return {Boolean} true if SCE is enabled, false otherwise. If you want to set the value, you
|
13572
13716
|
* have to do it at module config time on {@link ng.$sceProvider $sceProvider}.
|
@@ -14101,7 +14245,7 @@ var originUrl = urlResolve(window.location.href, true);
|
|
14101
14245
|
* https://github.com/angular/angular.js/pull/2902
|
14102
14246
|
* http://james.padolsey.com/javascript/parsing-urls-with-the-dom/
|
14103
14247
|
*
|
14104
|
-
* @function
|
14248
|
+
* @kind function
|
14105
14249
|
* @param {string} url The URL to be parsed.
|
14106
14250
|
* @description Normalizes and parses a URL.
|
14107
14251
|
* @returns {object} Returns the normalized URL as a dictionary.
|
@@ -14265,7 +14409,7 @@ function $WindowProvider(){
|
|
14265
14409
|
/**
|
14266
14410
|
* @ngdoc service
|
14267
14411
|
* @name $filter
|
14268
|
-
* @function
|
14412
|
+
* @kind function
|
14269
14413
|
* @description
|
14270
14414
|
* Filters are used for formatting data displayed to the user.
|
14271
14415
|
*
|
@@ -14275,7 +14419,24 @@ function $WindowProvider(){
|
|
14275
14419
|
*
|
14276
14420
|
* @param {String} name Name of the filter function to retrieve
|
14277
14421
|
* @return {Function} the filter function
|
14278
|
-
|
14422
|
+
* @example
|
14423
|
+
<example name="$filter" module="filterExample">
|
14424
|
+
<file name="index.html">
|
14425
|
+
<div ng-controller="MainCtrl">
|
14426
|
+
<h3>{{ originalText }}</h3>
|
14427
|
+
<h3>{{ filteredText }}</h3>
|
14428
|
+
</div>
|
14429
|
+
</file>
|
14430
|
+
|
14431
|
+
<file name="script.js">
|
14432
|
+
angular.module('filterExample', [])
|
14433
|
+
.controller('MainCtrl', function($scope, $filter) {
|
14434
|
+
$scope.originalText = 'hello';
|
14435
|
+
$scope.filteredText = $filter('uppercase')($scope.originalText);
|
14436
|
+
});
|
14437
|
+
</file>
|
14438
|
+
</example>
|
14439
|
+
*/
|
14279
14440
|
$FilterProvider.$inject = ['$provide'];
|
14280
14441
|
function $FilterProvider($provide) {
|
14281
14442
|
var suffix = 'Filter';
|
@@ -14335,7 +14496,7 @@ function $FilterProvider($provide) {
|
|
14335
14496
|
/**
|
14336
14497
|
* @ngdoc filter
|
14337
14498
|
* @name filter
|
14338
|
-
* @function
|
14499
|
+
* @kind function
|
14339
14500
|
*
|
14340
14501
|
* @description
|
14341
14502
|
* Selects a subset of items from `array` and returns it as a new array.
|
@@ -14367,15 +14528,15 @@ function $FilterProvider($provide) {
|
|
14367
14528
|
*
|
14368
14529
|
* Can be one of:
|
14369
14530
|
*
|
14370
|
-
*
|
14371
|
-
*
|
14372
|
-
*
|
14531
|
+
* - `function(actual, expected)`:
|
14532
|
+
* The function will be given the object value and the predicate value to compare and
|
14533
|
+
* should return true if the item should be included in filtered result.
|
14373
14534
|
*
|
14374
|
-
*
|
14375
|
-
*
|
14535
|
+
* - `true`: A shorthand for `function(actual, expected) { return angular.equals(expected, actual)}`.
|
14536
|
+
* this is essentially strict comparison of expected and actual.
|
14376
14537
|
*
|
14377
|
-
*
|
14378
|
-
*
|
14538
|
+
* - `false|undefined`: A short hand for a function which will look for a substring match in case
|
14539
|
+
* insensitive way.
|
14379
14540
|
*
|
14380
14541
|
* @example
|
14381
14542
|
<example>
|
@@ -14554,7 +14715,7 @@ function filterFilter() {
|
|
14554
14715
|
/**
|
14555
14716
|
* @ngdoc filter
|
14556
14717
|
* @name currency
|
14557
|
-
* @function
|
14718
|
+
* @kind function
|
14558
14719
|
*
|
14559
14720
|
* @description
|
14560
14721
|
* Formats a number as a currency (ie $1,234.56). When no currency symbol is provided, default
|
@@ -14611,7 +14772,7 @@ function currencyFilter($locale) {
|
|
14611
14772
|
/**
|
14612
14773
|
* @ngdoc filter
|
14613
14774
|
* @name number
|
14614
|
-
* @function
|
14775
|
+
* @kind function
|
14615
14776
|
*
|
14616
14777
|
* @description
|
14617
14778
|
* Formats a number as text.
|
@@ -14696,8 +14857,8 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
|
|
14696
14857
|
fractionSize = Math.min(Math.max(pattern.minFrac, fractionLen), pattern.maxFrac);
|
14697
14858
|
}
|
14698
14859
|
|
14699
|
-
var pow = Math.pow(10, fractionSize);
|
14700
|
-
number = Math.
|
14860
|
+
var pow = Math.pow(10, fractionSize + 1);
|
14861
|
+
number = Math.floor(number * pow + 5) / pow;
|
14701
14862
|
var fraction = ('' + number).split(DECIMAL_SEP);
|
14702
14863
|
var whole = fraction[0];
|
14703
14864
|
fraction = fraction[1] || '';
|
@@ -14823,7 +14984,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
|
|
14823
14984
|
/**
|
14824
14985
|
* @ngdoc filter
|
14825
14986
|
* @name date
|
14826
|
-
* @function
|
14987
|
+
* @kind function
|
14827
14988
|
*
|
14828
14989
|
* @description
|
14829
14990
|
* Formats `date` to a string based on the requested `format`.
|
@@ -14980,7 +15141,7 @@ function dateFilter($locale) {
|
|
14980
15141
|
/**
|
14981
15142
|
* @ngdoc filter
|
14982
15143
|
* @name json
|
14983
|
-
* @function
|
15144
|
+
* @kind function
|
14984
15145
|
*
|
14985
15146
|
* @description
|
14986
15147
|
* Allows you to convert a JavaScript object into JSON string.
|
@@ -15015,7 +15176,7 @@ function jsonFilter() {
|
|
15015
15176
|
/**
|
15016
15177
|
* @ngdoc filter
|
15017
15178
|
* @name lowercase
|
15018
|
-
* @function
|
15179
|
+
* @kind function
|
15019
15180
|
* @description
|
15020
15181
|
* Converts string to lowercase.
|
15021
15182
|
* @see angular.lowercase
|
@@ -15026,7 +15187,7 @@ var lowercaseFilter = valueFn(lowercase);
|
|
15026
15187
|
/**
|
15027
15188
|
* @ngdoc filter
|
15028
15189
|
* @name uppercase
|
15029
|
-
* @function
|
15190
|
+
* @kind function
|
15030
15191
|
* @description
|
15031
15192
|
* Converts string to uppercase.
|
15032
15193
|
* @see angular.uppercase
|
@@ -15036,7 +15197,7 @@ var uppercaseFilter = valueFn(uppercase);
|
|
15036
15197
|
/**
|
15037
15198
|
* @ngdoc filter
|
15038
15199
|
* @name limitTo
|
15039
|
-
* @function
|
15200
|
+
* @kind function
|
15040
15201
|
*
|
15041
15202
|
* @description
|
15042
15203
|
* Creates a new array or string containing only a specified number of elements. The elements
|
@@ -15106,7 +15267,11 @@ function limitToFilter(){
|
|
15106
15267
|
return function(input, limit) {
|
15107
15268
|
if (!isArray(input) && !isString(input)) return input;
|
15108
15269
|
|
15109
|
-
|
15270
|
+
if (Math.abs(Number(limit)) === Infinity) {
|
15271
|
+
limit = Number(limit);
|
15272
|
+
} else {
|
15273
|
+
limit = int(limit);
|
15274
|
+
}
|
15110
15275
|
|
15111
15276
|
if (isString(input)) {
|
15112
15277
|
//NaN check on limit
|
@@ -15145,10 +15310,12 @@ function limitToFilter(){
|
|
15145
15310
|
/**
|
15146
15311
|
* @ngdoc filter
|
15147
15312
|
* @name orderBy
|
15148
|
-
* @function
|
15313
|
+
* @kind function
|
15149
15314
|
*
|
15150
15315
|
* @description
|
15151
|
-
* Orders a specified `array` by the `expression` predicate.
|
15316
|
+
* Orders a specified `array` by the `expression` predicate. It is ordered alphabetically
|
15317
|
+
* for strings and numerically for numbers. Note: if you notice numbers are not being sorted
|
15318
|
+
* correctly, make sure they are actually being saved as numbers and not strings.
|
15152
15319
|
*
|
15153
15320
|
* @param {Array} array The array to sort.
|
15154
15321
|
* @param {function(*)|string|Array.<(function(*)|string)>} expression A predicate to be
|
@@ -15201,6 +15368,51 @@ function limitToFilter(){
|
|
15201
15368
|
</div>
|
15202
15369
|
</file>
|
15203
15370
|
</example>
|
15371
|
+
*
|
15372
|
+
* It's also possible to call the orderBy filter manually, by injecting `$filter`, retrieving the
|
15373
|
+
* filter routine with `$filter('orderBy')`, and calling the returned filter routine with the
|
15374
|
+
* desired parameters.
|
15375
|
+
*
|
15376
|
+
* Example:
|
15377
|
+
*
|
15378
|
+
* @example
|
15379
|
+
<example>
|
15380
|
+
<file name="index.html">
|
15381
|
+
<div ng-controller="Ctrl">
|
15382
|
+
<table class="friend">
|
15383
|
+
<tr>
|
15384
|
+
<th><a href="" ng-click="reverse=false;order('name', false)">Name</a>
|
15385
|
+
(<a href="" ng-click="order('-name',false)">^</a>)</th>
|
15386
|
+
<th><a href="" ng-click="reverse=!reverse;order('phone', reverse)">Phone Number</a></th>
|
15387
|
+
<th><a href="" ng-click="reverse=!reverse;order('age',reverse)">Age</a></th>
|
15388
|
+
</tr>
|
15389
|
+
<tr ng-repeat="friend in friends">
|
15390
|
+
<td>{{friend.name}}</td>
|
15391
|
+
<td>{{friend.phone}}</td>
|
15392
|
+
<td>{{friend.age}}</td>
|
15393
|
+
</tr>
|
15394
|
+
</table>
|
15395
|
+
</div>
|
15396
|
+
</file>
|
15397
|
+
|
15398
|
+
<file name="script.js">
|
15399
|
+
function Ctrl($scope, $filter) {
|
15400
|
+
var orderBy = $filter('orderBy');
|
15401
|
+
$scope.friends = [
|
15402
|
+
{ name: 'John', phone: '555-1212', age: 10 },
|
15403
|
+
{ name: 'Mary', phone: '555-9876', age: 19 },
|
15404
|
+
{ name: 'Mike', phone: '555-4321', age: 21 },
|
15405
|
+
{ name: 'Adam', phone: '555-5678', age: 35 },
|
15406
|
+
{ name: 'Julie', phone: '555-8765', age: 29 }
|
15407
|
+
];
|
15408
|
+
|
15409
|
+
$scope.order = function(predicate, reverse) {
|
15410
|
+
$scope.friends = orderBy($scope.friends, predicate, reverse);
|
15411
|
+
};
|
15412
|
+
$scope.order('-age',false);
|
15413
|
+
}
|
15414
|
+
</file>
|
15415
|
+
</example>
|
15204
15416
|
*/
|
15205
15417
|
orderByFilter.$inject = ['$parse'];
|
15206
15418
|
function orderByFilter($parse){
|
@@ -15752,7 +15964,7 @@ var nullFormCtrl = {
|
|
15752
15964
|
* - `url`
|
15753
15965
|
*
|
15754
15966
|
* @description
|
15755
|
-
* `FormController` keeps track of all its controls and nested forms as well as state of them,
|
15967
|
+
* `FormController` keeps track of all its controls and nested forms as well as the state of them,
|
15756
15968
|
* such as being valid/invalid or dirty/pristine.
|
15757
15969
|
*
|
15758
15970
|
* Each {@link ng.directive:form form} directive creates an instance
|
@@ -16594,6 +16806,8 @@ function addNativeHtml5Validators(ctrl, validatorName, element) {
|
|
16594
16806
|
|
16595
16807
|
function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
16596
16808
|
var validity = element.prop('validity');
|
16809
|
+
var placeholder = element[0].placeholder, noevent = {};
|
16810
|
+
|
16597
16811
|
// In composition mode, users are still inputing intermediate text buffer,
|
16598
16812
|
// hold the listener until composition is done.
|
16599
16813
|
// More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent
|
@@ -16610,10 +16824,19 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
|
16610
16824
|
});
|
16611
16825
|
}
|
16612
16826
|
|
16613
|
-
var listener = function() {
|
16827
|
+
var listener = function(ev) {
|
16614
16828
|
if (composing) return;
|
16615
16829
|
var value = element.val();
|
16616
16830
|
|
16831
|
+
// IE (11 and under) seem to emit an 'input' event if the placeholder value changes.
|
16832
|
+
// We don't want to dirty the value when this happens, so we abort here. Unfortunately,
|
16833
|
+
// IE also sends input events for other non-input-related things, (such as focusing on a
|
16834
|
+
// form control), so this change is not entirely enough to solve this.
|
16835
|
+
if (msie && (ev || noevent).type === 'input' && element[0].placeholder !== placeholder) {
|
16836
|
+
placeholder = element[0].placeholder;
|
16837
|
+
return;
|
16838
|
+
}
|
16839
|
+
|
16617
16840
|
// By default we will trim the value
|
16618
16841
|
// If the attribute ng-trim exists we will avoid trimming
|
16619
16842
|
// e.g. <input ng-model="foo" ng-trim="false">
|
@@ -16877,6 +17100,7 @@ function checkboxInputType(scope, element, attr, ctrl) {
|
|
16877
17100
|
* patterns defined as scope expressions.
|
16878
17101
|
* @param {string=} ngChange Angular expression to be executed when input changes due to user
|
16879
17102
|
* interaction with the input element.
|
17103
|
+
* @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.
|
16880
17104
|
*/
|
16881
17105
|
|
16882
17106
|
|
@@ -17026,14 +17250,14 @@ var VALID_CLASS = 'ng-valid',
|
|
17026
17250
|
* @property {Array.<Function>} $formatters Array of functions to execute, as a pipeline, whenever
|
17027
17251
|
the model value changes. Each function is called, in turn, passing the value through to the
|
17028
17252
|
next. Used to format / convert values for display in the control and validation.
|
17029
|
-
*
|
17030
|
-
*
|
17031
|
-
*
|
17032
|
-
*
|
17033
|
-
*
|
17034
|
-
*
|
17035
|
-
*
|
17036
|
-
*
|
17253
|
+
* ```js
|
17254
|
+
* function formatter(value) {
|
17255
|
+
* if (value) {
|
17256
|
+
* return value.toUpperCase();
|
17257
|
+
* }
|
17258
|
+
* }
|
17259
|
+
* ngModel.$formatters.push(formatter);
|
17260
|
+
* ```
|
17037
17261
|
*
|
17038
17262
|
* @property {Array.<Function>} $viewChangeListeners Array of functions to execute whenever the
|
17039
17263
|
* view value has changed. It is called with no arguments, and its return value is ignored.
|
@@ -17062,7 +17286,12 @@ var VALID_CLASS = 'ng-valid',
|
|
17062
17286
|
* Note that `contenteditable` is an HTML5 attribute, which tells the browser to let the element
|
17063
17287
|
* contents be edited in place by the user. This will not work on older browsers.
|
17064
17288
|
*
|
17065
|
-
*
|
17289
|
+
* We are using the {@link ng.service:$sce $sce} service here and include the {@link ngSanitize $sanitize}
|
17290
|
+
* module to automatically remove "bad" content like inline event listener (e.g. `<span onclick="...">`).
|
17291
|
+
* However, as we are using `$sce` the model can still decide to to provide unsafe content if it marks
|
17292
|
+
* that content using the `$sce` service.
|
17293
|
+
*
|
17294
|
+
* <example name="NgModelController" module="customControl" deps="angular-sanitize.js">
|
17066
17295
|
<file name="style.css">
|
17067
17296
|
[contenteditable] {
|
17068
17297
|
border: 1px solid black;
|
@@ -17076,8 +17305,8 @@ var VALID_CLASS = 'ng-valid',
|
|
17076
17305
|
|
17077
17306
|
</file>
|
17078
17307
|
<file name="script.js">
|
17079
|
-
angular.module('customControl', []).
|
17080
|
-
directive('contenteditable', function() {
|
17308
|
+
angular.module('customControl', ['ngSanitize']).
|
17309
|
+
directive('contenteditable', ['$sce', function($sce) {
|
17081
17310
|
return {
|
17082
17311
|
restrict: 'A', // only activate on element attribute
|
17083
17312
|
require: '?ngModel', // get a hold of NgModelController
|
@@ -17086,7 +17315,7 @@ var VALID_CLASS = 'ng-valid',
|
|
17086
17315
|
|
17087
17316
|
// Specify how UI should be updated
|
17088
17317
|
ngModel.$render = function() {
|
17089
|
-
element.html(ngModel.$viewValue || '');
|
17318
|
+
element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));
|
17090
17319
|
};
|
17091
17320
|
|
17092
17321
|
// Listen for change events to enable binding
|
@@ -17107,7 +17336,7 @@ var VALID_CLASS = 'ng-valid',
|
|
17107
17336
|
}
|
17108
17337
|
}
|
17109
17338
|
};
|
17110
|
-
});
|
17339
|
+
}]);
|
17111
17340
|
</file>
|
17112
17341
|
<file name="index.html">
|
17113
17342
|
<form name="myForm">
|
@@ -17781,14 +18010,19 @@ var ngValueDirective = function() {
|
|
17781
18010
|
</file>
|
17782
18011
|
</example>
|
17783
18012
|
*/
|
17784
|
-
var ngBindDirective = ngDirective(
|
17785
|
-
|
17786
|
-
|
17787
|
-
|
17788
|
-
|
17789
|
-
|
17790
|
-
|
17791
|
-
|
18013
|
+
var ngBindDirective = ngDirective({
|
18014
|
+
compile: function(templateElement) {
|
18015
|
+
templateElement.addClass('ng-binding');
|
18016
|
+
return function (scope, element, attr) {
|
18017
|
+
element.data('$binding', attr.ngBind);
|
18018
|
+
scope.$watch(attr.ngBind, function ngBindWatchAction(value) {
|
18019
|
+
// We are purposefully using == here rather than === because we want to
|
18020
|
+
// catch when value is "null or undefined"
|
18021
|
+
// jshint -W041
|
18022
|
+
element.text(value == undefined ? '' : value);
|
18023
|
+
});
|
18024
|
+
};
|
18025
|
+
}
|
17792
18026
|
});
|
17793
18027
|
|
17794
18028
|
|
@@ -17932,7 +18166,7 @@ function classDirective(name, selector) {
|
|
17932
18166
|
scope.$watch('$index', function($index, old$index) {
|
17933
18167
|
// jshint bitwise: false
|
17934
18168
|
var mod = $index & 1;
|
17935
|
-
if (mod !== old$index & 1) {
|
18169
|
+
if (mod !== (old$index & 1)) {
|
17936
18170
|
var classes = arrayClasses(scope.$eval(attr[name]));
|
17937
18171
|
mod === selector ?
|
17938
18172
|
addClasses(classes) :
|
@@ -17991,7 +18225,7 @@ function classDirective(name, selector) {
|
|
17991
18225
|
updateClasses(oldClasses, newClasses);
|
17992
18226
|
}
|
17993
18227
|
}
|
17994
|
-
oldVal =
|
18228
|
+
oldVal = shallowCopy(newVal);
|
17995
18229
|
}
|
17996
18230
|
}
|
17997
18231
|
};
|
@@ -18019,7 +18253,7 @@ function classDirective(name, selector) {
|
|
18019
18253
|
var classes = [], i = 0;
|
18020
18254
|
forEach(classVal, function(v, k) {
|
18021
18255
|
if (v) {
|
18022
|
-
classes.
|
18256
|
+
classes = classes.concat(k.split(' '));
|
18023
18257
|
}
|
18024
18258
|
});
|
18025
18259
|
return classes;
|
@@ -18344,7 +18578,7 @@ var ngCloakDirective = ngDirective({
|
|
18344
18578
|
*
|
18345
18579
|
* MVC components in angular:
|
18346
18580
|
*
|
18347
|
-
* * Model —
|
18581
|
+
* * Model — Models are the properties of a scope; scopes are attached to the DOM where scope properties
|
18348
18582
|
* are accessed through bindings.
|
18349
18583
|
* * View — The template (HTML with data bindings) that is rendered into the View.
|
18350
18584
|
* * Controller — The `ngController` directive specifies a Controller class; the class contains business
|
@@ -18365,165 +18599,186 @@ var ngCloakDirective = ngDirective({
|
|
18365
18599
|
* @example
|
18366
18600
|
* Here is a simple form for editing user contact information. Adding, removing, clearing, and
|
18367
18601
|
* greeting are methods declared on the controller (see source tab). These methods can
|
18368
|
-
* easily be called from the angular markup.
|
18369
|
-
*
|
18370
|
-
*
|
18371
|
-
*
|
18372
|
-
*
|
18373
|
-
|
18374
|
-
|
18375
|
-
|
18376
|
-
|
18377
|
-
|
18378
|
-
|
18379
|
-
|
18380
|
-
|
18381
|
-
|
18382
|
-
|
18383
|
-
|
18384
|
-
|
18385
|
-
|
18386
|
-
|
18387
|
-
|
18388
|
-
|
18389
|
-
|
18390
|
-
|
18391
|
-
|
18392
|
-
|
18393
|
-
|
18394
|
-
|
18395
|
-
|
18396
|
-
|
18397
|
-
|
18398
|
-
|
18399
|
-
|
18400
|
-
|
18401
|
-
|
18402
|
-
|
18403
|
-
|
18404
|
-
|
18405
|
-
|
18406
|
-
|
18407
|
-
|
18408
|
-
|
18409
|
-
|
18410
|
-
|
18411
|
-
|
18412
|
-
|
18413
|
-
|
18414
|
-
|
18415
|
-
|
18416
|
-
|
18417
|
-
|
18418
|
-
|
18419
|
-
|
18420
|
-
|
18421
|
-
|
18422
|
-
|
18423
|
-
|
18424
|
-
|
18425
|
-
|
18426
|
-
|
18427
|
-
|
18428
|
-
|
18429
|
-
|
18430
|
-
|
18431
|
-
|
18432
|
-
|
18433
|
-
|
18434
|
-
|
18435
|
-
|
18436
|
-
|
18437
|
-
|
18438
|
-
|
18439
|
-
|
18440
|
-
|
18441
|
-
|
18442
|
-
|
18443
|
-
|
18444
|
-
|
18445
|
-
|
18446
|
-
|
18447
|
-
|
18448
|
-
|
18449
|
-
|
18450
|
-
|
18451
|
-
|
18452
|
-
|
18453
|
-
|
18454
|
-
|
18455
|
-
|
18456
|
-
|
18457
|
-
|
18458
|
-
|
18459
|
-
|
18460
|
-
|
18461
|
-
|
18462
|
-
|
18463
|
-
|
18464
|
-
|
18465
|
-
|
18466
|
-
|
18467
|
-
|
18468
|
-
|
18469
|
-
|
18470
|
-
|
18471
|
-
|
18472
|
-
|
18473
|
-
|
18474
|
-
|
18475
|
-
|
18476
|
-
|
18477
|
-
|
18478
|
-
|
18479
|
-
|
18480
|
-
|
18481
|
-
|
18482
|
-
|
18483
|
-
|
18484
|
-
|
18485
|
-
|
18486
|
-
|
18487
|
-
|
18488
|
-
|
18489
|
-
|
18490
|
-
|
18491
|
-
|
18492
|
-
|
18493
|
-
|
18494
|
-
|
18495
|
-
|
18496
|
-
|
18497
|
-
|
18498
|
-
|
18499
|
-
|
18500
|
-
|
18501
|
-
|
18502
|
-
|
18503
|
-
|
18504
|
-
|
18505
|
-
|
18506
|
-
|
18507
|
-
|
18508
|
-
|
18509
|
-
|
18510
|
-
|
18511
|
-
|
18512
|
-
|
18513
|
-
|
18514
|
-
|
18515
|
-
|
18516
|
-
|
18517
|
-
|
18518
|
-
|
18519
|
-
|
18520
|
-
|
18521
|
-
|
18522
|
-
|
18523
|
-
|
18524
|
-
|
18525
|
-
|
18526
|
-
|
18602
|
+
* easily be called from the angular markup. Any changes to the data are automatically reflected
|
18603
|
+
* in the View without the need for a manual update.
|
18604
|
+
*
|
18605
|
+
* Two different declaration styles are included below:
|
18606
|
+
*
|
18607
|
+
* * one binds methods and properties directly onto the controller using `this`:
|
18608
|
+
* `ng-controller="SettingsController1 as settings"`
|
18609
|
+
* * one injects `$scope` into the controller:
|
18610
|
+
* `ng-controller="SettingsController2"`
|
18611
|
+
*
|
18612
|
+
* The second option is more common in the Angular community, and is generally used in boilerplates
|
18613
|
+
* and in this guide. However, there are advantages to binding properties directly to the controller
|
18614
|
+
* and avoiding scope.
|
18615
|
+
*
|
18616
|
+
* * Using `controller as` makes it obvious which controller you are accessing in the template when
|
18617
|
+
* multiple controllers apply to an element.
|
18618
|
+
* * If you are writing your controllers as classes you have easier access to the properties and
|
18619
|
+
* methods, which will appear on the scope, from inside the controller code.
|
18620
|
+
* * Since there is always a `.` in the bindings, you don't have to worry about prototypal
|
18621
|
+
* inheritance masking primitives.
|
18622
|
+
*
|
18623
|
+
* This example demonstrates the `controller as` syntax.
|
18624
|
+
*
|
18625
|
+
* <example name="ngControllerAs">
|
18626
|
+
* <file name="index.html">
|
18627
|
+
* <div id="ctrl-as-exmpl" ng-controller="SettingsController1 as settings">
|
18628
|
+
* Name: <input type="text" ng-model="settings.name"/>
|
18629
|
+
* [ <a href="" ng-click="settings.greet()">greet</a> ]<br/>
|
18630
|
+
* Contact:
|
18631
|
+
* <ul>
|
18632
|
+
* <li ng-repeat="contact in settings.contacts">
|
18633
|
+
* <select ng-model="contact.type">
|
18634
|
+
* <option>phone</option>
|
18635
|
+
* <option>email</option>
|
18636
|
+
* </select>
|
18637
|
+
* <input type="text" ng-model="contact.value"/>
|
18638
|
+
* [ <a href="" ng-click="settings.clearContact(contact)">clear</a>
|
18639
|
+
* | <a href="" ng-click="settings.removeContact(contact)">X</a> ]
|
18640
|
+
* </li>
|
18641
|
+
* <li>[ <a href="" ng-click="settings.addContact()">add</a> ]</li>
|
18642
|
+
* </ul>
|
18643
|
+
* </div>
|
18644
|
+
* </file>
|
18645
|
+
* <file name="app.js">
|
18646
|
+
* function SettingsController1() {
|
18647
|
+
* this.name = "John Smith";
|
18648
|
+
* this.contacts = [
|
18649
|
+
* {type: 'phone', value: '408 555 1212'},
|
18650
|
+
* {type: 'email', value: 'john.smith@example.org'} ];
|
18651
|
+
* }
|
18652
|
+
*
|
18653
|
+
* SettingsController1.prototype.greet = function() {
|
18654
|
+
* alert(this.name);
|
18655
|
+
* };
|
18656
|
+
*
|
18657
|
+
* SettingsController1.prototype.addContact = function() {
|
18658
|
+
* this.contacts.push({type: 'email', value: 'yourname@example.org'});
|
18659
|
+
* };
|
18660
|
+
*
|
18661
|
+
* SettingsController1.prototype.removeContact = function(contactToRemove) {
|
18662
|
+
* var index = this.contacts.indexOf(contactToRemove);
|
18663
|
+
* this.contacts.splice(index, 1);
|
18664
|
+
* };
|
18665
|
+
*
|
18666
|
+
* SettingsController1.prototype.clearContact = function(contact) {
|
18667
|
+
* contact.type = 'phone';
|
18668
|
+
* contact.value = '';
|
18669
|
+
* };
|
18670
|
+
* </file>
|
18671
|
+
* <file name="protractor.js" type="protractor">
|
18672
|
+
* it('should check controller as', function() {
|
18673
|
+
* var container = element(by.id('ctrl-as-exmpl'));
|
18674
|
+
* expect(container.findElement(by.model('settings.name'))
|
18675
|
+
* .getAttribute('value')).toBe('John Smith');
|
18676
|
+
*
|
18677
|
+
* var firstRepeat =
|
18678
|
+
* container.findElement(by.repeater('contact in settings.contacts').row(0));
|
18679
|
+
* var secondRepeat =
|
18680
|
+
* container.findElement(by.repeater('contact in settings.contacts').row(1));
|
18681
|
+
*
|
18682
|
+
* expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
|
18683
|
+
* .toBe('408 555 1212');
|
18684
|
+
*
|
18685
|
+
* expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value'))
|
18686
|
+
* .toBe('john.smith@example.org');
|
18687
|
+
*
|
18688
|
+
* firstRepeat.findElement(by.linkText('clear')).click();
|
18689
|
+
*
|
18690
|
+
* expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
|
18691
|
+
* .toBe('');
|
18692
|
+
*
|
18693
|
+
* container.findElement(by.linkText('add')).click();
|
18694
|
+
*
|
18695
|
+
* expect(container.findElement(by.repeater('contact in settings.contacts').row(2))
|
18696
|
+
* .findElement(by.model('contact.value'))
|
18697
|
+
* .getAttribute('value'))
|
18698
|
+
* .toBe('yourname@example.org');
|
18699
|
+
* });
|
18700
|
+
* </file>
|
18701
|
+
* </example>
|
18702
|
+
*
|
18703
|
+
* This example demonstrates the "attach to `$scope`" style of controller.
|
18704
|
+
*
|
18705
|
+
* <example name="ngController">
|
18706
|
+
* <file name="index.html">
|
18707
|
+
* <div id="ctrl-exmpl" ng-controller="SettingsController2">
|
18708
|
+
* Name: <input type="text" ng-model="name"/>
|
18709
|
+
* [ <a href="" ng-click="greet()">greet</a> ]<br/>
|
18710
|
+
* Contact:
|
18711
|
+
* <ul>
|
18712
|
+
* <li ng-repeat="contact in contacts">
|
18713
|
+
* <select ng-model="contact.type">
|
18714
|
+
* <option>phone</option>
|
18715
|
+
* <option>email</option>
|
18716
|
+
* </select>
|
18717
|
+
* <input type="text" ng-model="contact.value"/>
|
18718
|
+
* [ <a href="" ng-click="clearContact(contact)">clear</a>
|
18719
|
+
* | <a href="" ng-click="removeContact(contact)">X</a> ]
|
18720
|
+
* </li>
|
18721
|
+
* <li>[ <a href="" ng-click="addContact()">add</a> ]</li>
|
18722
|
+
* </ul>
|
18723
|
+
* </div>
|
18724
|
+
* </file>
|
18725
|
+
* <file name="app.js">
|
18726
|
+
* function SettingsController2($scope) {
|
18727
|
+
* $scope.name = "John Smith";
|
18728
|
+
* $scope.contacts = [
|
18729
|
+
* {type:'phone', value:'408 555 1212'},
|
18730
|
+
* {type:'email', value:'john.smith@example.org'} ];
|
18731
|
+
*
|
18732
|
+
* $scope.greet = function() {
|
18733
|
+
* alert($scope.name);
|
18734
|
+
* };
|
18735
|
+
*
|
18736
|
+
* $scope.addContact = function() {
|
18737
|
+
* $scope.contacts.push({type:'email', value:'yourname@example.org'});
|
18738
|
+
* };
|
18739
|
+
*
|
18740
|
+
* $scope.removeContact = function(contactToRemove) {
|
18741
|
+
* var index = $scope.contacts.indexOf(contactToRemove);
|
18742
|
+
* $scope.contacts.splice(index, 1);
|
18743
|
+
* };
|
18744
|
+
*
|
18745
|
+
* $scope.clearContact = function(contact) {
|
18746
|
+
* contact.type = 'phone';
|
18747
|
+
* contact.value = '';
|
18748
|
+
* };
|
18749
|
+
* }
|
18750
|
+
* </file>
|
18751
|
+
* <file name="protractor.js" type="protractor">
|
18752
|
+
* it('should check controller', function() {
|
18753
|
+
* var container = element(by.id('ctrl-exmpl'));
|
18754
|
+
*
|
18755
|
+
* expect(container.findElement(by.model('name'))
|
18756
|
+
* .getAttribute('value')).toBe('John Smith');
|
18757
|
+
*
|
18758
|
+
* var firstRepeat =
|
18759
|
+
* container.findElement(by.repeater('contact in contacts').row(0));
|
18760
|
+
* var secondRepeat =
|
18761
|
+
* container.findElement(by.repeater('contact in contacts').row(1));
|
18762
|
+
*
|
18763
|
+
* expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
|
18764
|
+
* .toBe('408 555 1212');
|
18765
|
+
* expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value'))
|
18766
|
+
* .toBe('john.smith@example.org');
|
18767
|
+
*
|
18768
|
+
* firstRepeat.findElement(by.linkText('clear')).click();
|
18769
|
+
*
|
18770
|
+
* expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
|
18771
|
+
* .toBe('');
|
18772
|
+
*
|
18773
|
+
* container.findElement(by.linkText('add')).click();
|
18774
|
+
*
|
18775
|
+
* expect(container.findElement(by.repeater('contact in contacts').row(2))
|
18776
|
+
* .findElement(by.model('contact.value'))
|
18777
|
+
* .getAttribute('value'))
|
18778
|
+
* .toBe('yourname@example.org');
|
18779
|
+
* });
|
18780
|
+
* </file>
|
18781
|
+
*</example>
|
18527
18782
|
|
18528
18783
|
*/
|
18529
18784
|
var ngControllerDirective = [function() {
|
@@ -18621,7 +18876,7 @@ forEach(
|
|
18621
18876
|
return {
|
18622
18877
|
compile: function($element, attr) {
|
18623
18878
|
var fn = $parse(attr[directiveName]);
|
18624
|
-
return function(scope, element
|
18879
|
+
return function ngEventHandler(scope, element) {
|
18625
18880
|
element.on(lowercase(name), function(event) {
|
18626
18881
|
scope.$apply(function() {
|
18627
18882
|
fn(scope, {$event:event});
|
@@ -18838,8 +19093,13 @@ forEach(
|
|
18838
19093
|
* @example
|
18839
19094
|
<example>
|
18840
19095
|
<file name="index.html">
|
18841
|
-
|
18842
|
-
|
19096
|
+
<p>Typing in the input box below updates the key count</p>
|
19097
|
+
<input ng-keyup="count = count + 1" ng-init="count=0"> key up count: {{count}}
|
19098
|
+
|
19099
|
+
<p>Typing in the input box below updates the keycode</p>
|
19100
|
+
<input ng-keyup="event=$event">
|
19101
|
+
<p>event keyCode: {{ event.keyCode }}</p>
|
19102
|
+
<p>event altKey: {{ event.altKey }}</p>
|
18843
19103
|
</file>
|
18844
19104
|
</example>
|
18845
19105
|
*/
|
@@ -19111,7 +19371,7 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
19111
19371
|
clone[clone.length++] = document.createComment(' end ngIf: ' + $attr.ngIf + ' ');
|
19112
19372
|
// Note: We only need the first/last node of the cloned nodes.
|
19113
19373
|
// However, we need to keep the reference to the jqlite wrapper as it might be changed later
|
19114
|
-
// by a directive with templateUrl when
|
19374
|
+
// by a directive with templateUrl when its template arrives.
|
19115
19375
|
block = {
|
19116
19376
|
clone: clone
|
19117
19377
|
};
|
@@ -19810,7 +20070,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
|
|
19810
20070
|
* mapped to the same DOM element, which is not possible.) Filters should be applied to the expression,
|
19811
20071
|
* before specifying a tracking expression.
|
19812
20072
|
*
|
19813
|
-
* For example: `item in items` is equivalent to `item in items track by $id(item)
|
20073
|
+
* For example: `item in items` is equivalent to `item in items track by $id(item)`. This implies that the DOM elements
|
19814
20074
|
* will be associated by item identity in the array.
|
19815
20075
|
*
|
19816
20076
|
* For example: `item in items track by $id(item)`. A built in `$id()` function can be used to assign a unique
|
@@ -20088,7 +20348,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
20088
20348
|
block.scope = childScope;
|
20089
20349
|
// Note: We only need the first/last node of the cloned nodes.
|
20090
20350
|
// However, we need to keep the reference to the jqlite wrapper as it might be changed later
|
20091
|
-
// by a directive with templateUrl when
|
20351
|
+
// by a directive with templateUrl when its template arrives.
|
20092
20352
|
block.clone = clone;
|
20093
20353
|
nextBlockMap[block.id] = block;
|
20094
20354
|
});
|
@@ -20131,6 +20391,11 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
20131
20391
|
* on the element causing it to become hidden. When true, the ng-hide CSS class is removed
|
20132
20392
|
* from the element causing the element not to appear hidden.
|
20133
20393
|
*
|
20394
|
+
* <div class="alert alert-warning">
|
20395
|
+
* **Note:** Here is a list of values that ngShow will consider as a falsy value (case insensitive):<br />
|
20396
|
+
* "f" / "0" / "false" / "no" / "n" / "[]"
|
20397
|
+
* </div>
|
20398
|
+
*
|
20134
20399
|
* ## Why is !important used?
|
20135
20400
|
*
|
20136
20401
|
* You may be wondering why !important is used for the .ng-hide CSS class. This is because the `.ng-hide` selector
|
@@ -20144,26 +20409,21 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
20144
20409
|
*
|
20145
20410
|
* ### Overriding .ng-hide
|
20146
20411
|
*
|
20147
|
-
*
|
20148
|
-
* restating the styles for the
|
20412
|
+
* By default, the `.ng-hide` class will style the element with `display:none!important`. If you wish to change
|
20413
|
+
* the hide behavior with ngShow/ngHide then this can be achieved by restating the styles for the `.ng-hide`
|
20414
|
+
* class in CSS:
|
20415
|
+
*
|
20149
20416
|
* ```css
|
20150
20417
|
* .ng-hide {
|
20151
|
-
* //!annotate CSS Specificity|Not to worry, this will override the AngularJS default...
|
20152
|
-
* display:block!important;
|
20153
|
-
*
|
20154
20418
|
* //this is just another form of hiding an element
|
20419
|
+
* display:block!important;
|
20155
20420
|
* position:absolute;
|
20156
20421
|
* top:-9999px;
|
20157
20422
|
* left:-9999px;
|
20158
20423
|
* }
|
20159
20424
|
* ```
|
20160
20425
|
*
|
20161
|
-
*
|
20162
|
-
*
|
20163
|
-
* <div class="alert alert-warning">
|
20164
|
-
* **Note:** Here is a list of values that ngShow will consider as a falsy value (case insensitive):<br />
|
20165
|
-
* "f" / "0" / "false" / "no" / "n" / "[]"
|
20166
|
-
* </div>
|
20426
|
+
* By default you don't need to override in CSS anything and the animations will work around the display style.
|
20167
20427
|
*
|
20168
20428
|
* ## A note about animations with ngShow
|
20169
20429
|
*
|
@@ -20178,7 +20438,6 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
20178
20438
|
* //
|
20179
20439
|
* .my-element.ng-hide-add, .my-element.ng-hide-remove {
|
20180
20440
|
* transition:0.5s linear all;
|
20181
|
-
* display:block!important;
|
20182
20441
|
* }
|
20183
20442
|
*
|
20184
20443
|
* .my-element.ng-hide-add { ... }
|
@@ -20187,6 +20446,9 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
20187
20446
|
* .my-element.ng-hide-remove.ng-hide-remove-active { ... }
|
20188
20447
|
* ```
|
20189
20448
|
*
|
20449
|
+
* Keep in mind that, as of AngularJS version 1.2.17 (and 1.3.0-beta.11), there is no need to change the display
|
20450
|
+
* property to block during animation states--ngAnimate will handle the style toggling automatically for you.
|
20451
|
+
*
|
20190
20452
|
* @animations
|
20191
20453
|
* addClass: .ng-hide - happens after the ngShow expression evaluates to a truthy value and the just before contents are set to visible
|
20192
20454
|
* removeClass: .ng-hide - happens after the ngShow expression evaluates to a non truthy value and just before the contents are set to hidden
|
@@ -20226,11 +20488,6 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
20226
20488
|
background:white;
|
20227
20489
|
}
|
20228
20490
|
|
20229
|
-
.animate-show.ng-hide-add,
|
20230
|
-
.animate-show.ng-hide-remove {
|
20231
|
-
display:block!important;
|
20232
|
-
}
|
20233
|
-
|
20234
20491
|
.animate-show.ng-hide {
|
20235
20492
|
line-height:0;
|
20236
20493
|
opacity:0;
|
@@ -20281,16 +20538,21 @@ var ngShowDirective = ['$animate', function($animate) {
|
|
20281
20538
|
*
|
20282
20539
|
* ```html
|
20283
20540
|
* <!-- when $scope.myValue is truthy (element is hidden) -->
|
20284
|
-
* <div ng-hide="myValue"></div>
|
20541
|
+
* <div ng-hide="myValue" class="ng-hide"></div>
|
20285
20542
|
*
|
20286
20543
|
* <!-- when $scope.myValue is falsy (element is visible) -->
|
20287
|
-
* <div ng-hide="myValue"
|
20544
|
+
* <div ng-hide="myValue"></div>
|
20288
20545
|
* ```
|
20289
20546
|
*
|
20290
20547
|
* When the ngHide expression evaluates to true then the .ng-hide CSS class is added to the class attribute
|
20291
20548
|
* on the element causing it to become hidden. When false, the ng-hide CSS class is removed
|
20292
20549
|
* from the element causing the element not to appear hidden.
|
20293
20550
|
*
|
20551
|
+
* <div class="alert alert-warning">
|
20552
|
+
* **Note:** Here is a list of values that ngHide will consider as a falsy value (case insensitive):<br />
|
20553
|
+
* "f" / "0" / "false" / "no" / "n" / "[]"
|
20554
|
+
* </div>
|
20555
|
+
*
|
20294
20556
|
* ## Why is !important used?
|
20295
20557
|
*
|
20296
20558
|
* You may be wondering why !important is used for the .ng-hide CSS class. This is because the `.ng-hide` selector
|
@@ -20304,33 +20566,27 @@ var ngShowDirective = ['$animate', function($animate) {
|
|
20304
20566
|
*
|
20305
20567
|
* ### Overriding .ng-hide
|
20306
20568
|
*
|
20307
|
-
*
|
20308
|
-
* restating the styles for the
|
20569
|
+
* By default, the `.ng-hide` class will style the element with `display:none!important`. If you wish to change
|
20570
|
+
* the hide behavior with ngShow/ngHide then this can be achieved by restating the styles for the `.ng-hide`
|
20571
|
+
* class in CSS:
|
20572
|
+
*
|
20309
20573
|
* ```css
|
20310
20574
|
* .ng-hide {
|
20311
|
-
* //!annotate CSS Specificity|Not to worry, this will override the AngularJS default...
|
20312
|
-
* display:block!important;
|
20313
|
-
*
|
20314
20575
|
* //this is just another form of hiding an element
|
20576
|
+
* display:block!important;
|
20315
20577
|
* position:absolute;
|
20316
20578
|
* top:-9999px;
|
20317
20579
|
* left:-9999px;
|
20318
20580
|
* }
|
20319
20581
|
* ```
|
20320
20582
|
*
|
20321
|
-
*
|
20322
|
-
*
|
20323
|
-
* <div class="alert alert-warning">
|
20324
|
-
* **Note:** Here is a list of values that ngHide will consider as a falsy value (case insensitive):<br />
|
20325
|
-
* "f" / "0" / "false" / "no" / "n" / "[]"
|
20326
|
-
* </div>
|
20583
|
+
* By default you don't need to override in CSS anything and the animations will work around the display style.
|
20327
20584
|
*
|
20328
20585
|
* ## A note about animations with ngHide
|
20329
20586
|
*
|
20330
20587
|
* Animations in ngShow/ngHide work with the show and hide events that are triggered when the directive expression
|
20331
|
-
* is true and false. This system works like the animation system present with ngClass, except that
|
20332
|
-
*
|
20333
|
-
* that you can perform an animation when the element is hidden during the time of the animation.
|
20588
|
+
* is true and false. This system works like the animation system present with ngClass, except that the `.ng-hide`
|
20589
|
+
* CSS class is added and removed for you instead of your own CSS class.
|
20334
20590
|
*
|
20335
20591
|
* ```css
|
20336
20592
|
* //
|
@@ -20338,7 +20594,6 @@ var ngShowDirective = ['$animate', function($animate) {
|
|
20338
20594
|
* //
|
20339
20595
|
* .my-element.ng-hide-add, .my-element.ng-hide-remove {
|
20340
20596
|
* transition:0.5s linear all;
|
20341
|
-
* display:block!important;
|
20342
20597
|
* }
|
20343
20598
|
*
|
20344
20599
|
* .my-element.ng-hide-add { ... }
|
@@ -20347,6 +20602,9 @@ var ngShowDirective = ['$animate', function($animate) {
|
|
20347
20602
|
* .my-element.ng-hide-remove.ng-hide-remove-active { ... }
|
20348
20603
|
* ```
|
20349
20604
|
*
|
20605
|
+
* Keep in mind that, as of AngularJS version 1.2.17 (and 1.3.0-beta.11), there is no need to change the display
|
20606
|
+
* property to block during animation states--ngAnimate will handle the style toggling automatically for you.
|
20607
|
+
*
|
20350
20608
|
* @animations
|
20351
20609
|
* removeClass: .ng-hide - happens after the ngHide expression evaluates to a truthy value and just before the contents are set to hidden
|
20352
20610
|
* addClass: .ng-hide - happens after the ngHide expression evaluates to a non truthy value and just before the contents are set to visible
|
@@ -20386,11 +20644,6 @@ var ngShowDirective = ['$animate', function($animate) {
|
|
20386
20644
|
background:white;
|
20387
20645
|
}
|
20388
20646
|
|
20389
|
-
.animate-hide.ng-hide-add,
|
20390
|
-
.animate-hide.ng-hide-remove {
|
20391
|
-
display:block!important;
|
20392
|
-
}
|
20393
|
-
|
20394
20647
|
.animate-hide.ng-hide {
|
20395
20648
|
line-height:0;
|
20396
20649
|
opacity:0;
|
@@ -20436,14 +20689,20 @@ var ngHideDirective = ['$animate', function($animate) {
|
|
20436
20689
|
* The `ngStyle` directive allows you to set CSS style on an HTML element conditionally.
|
20437
20690
|
*
|
20438
20691
|
* @element ANY
|
20439
|
-
* @param {expression} ngStyle
|
20440
|
-
*
|
20441
|
-
*
|
20692
|
+
* @param {expression} ngStyle
|
20693
|
+
*
|
20694
|
+
* {@link guide/expression Expression} which evals to an
|
20695
|
+
* object whose keys are CSS style names and values are corresponding values for those CSS
|
20696
|
+
* keys.
|
20697
|
+
*
|
20698
|
+
* Since some CSS style names are not valid keys for an object, they must be quoted.
|
20699
|
+
* See the 'background-color' style in the example below.
|
20442
20700
|
*
|
20443
20701
|
* @example
|
20444
20702
|
<example>
|
20445
20703
|
<file name="index.html">
|
20446
|
-
<input type="button" value="set" ng-click="myStyle={color:'red'}">
|
20704
|
+
<input type="button" value="set color" ng-click="myStyle={color:'red'}">
|
20705
|
+
<input type="button" value="set background" ng-click="myStyle={'background-color':'blue'}">
|
20447
20706
|
<input type="button" value="clear" ng-click="myStyle={}">
|
20448
20707
|
<br/>
|
20449
20708
|
<span ng-style="myStyle">Sample Text</span>
|
@@ -20457,9 +20716,9 @@ var ngHideDirective = ['$animate', function($animate) {
|
|
20457
20716
|
<file name="protractor.js" type="protractor">
|
20458
20717
|
var colorSpan = element(by.css('span'));
|
20459
20718
|
|
20460
|
-
|
20719
|
+
iit('should check ng-style', function() {
|
20461
20720
|
expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
|
20462
|
-
element(by.css('input[value
|
20721
|
+
element(by.css('input[value=\'set color\']')).click();
|
20463
20722
|
expect(colorSpan.getCssValue('color')).toBe('rgba(255, 0, 0, 1)');
|
20464
20723
|
element(by.css('input[value=clear]')).click();
|
20465
20724
|
expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
|
@@ -20507,11 +20766,14 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
|
|
20507
20766
|
* leave - happens just after the ngSwitch contents change and just before the former contents are removed from the DOM
|
20508
20767
|
*
|
20509
20768
|
* @usage
|
20769
|
+
*
|
20770
|
+
* ```
|
20510
20771
|
* <ANY ng-switch="expression">
|
20511
20772
|
* <ANY ng-switch-when="matchValue1">...</ANY>
|
20512
20773
|
* <ANY ng-switch-when="matchValue2">...</ANY>
|
20513
20774
|
* <ANY ng-switch-default>...</ANY>
|
20514
20775
|
* </ANY>
|
20776
|
+
* ```
|
20515
20777
|
*
|
20516
20778
|
*
|
20517
20779
|
* @scope
|
@@ -20611,37 +20873,29 @@ var ngSwitchDirective = ['$animate', function($animate) {
|
|
20611
20873
|
}],
|
20612
20874
|
link: function(scope, element, attr, ngSwitchController) {
|
20613
20875
|
var watchExpr = attr.ngSwitch || attr.on,
|
20614
|
-
selectedTranscludes,
|
20615
|
-
selectedElements,
|
20616
|
-
previousElements,
|
20876
|
+
selectedTranscludes = [],
|
20877
|
+
selectedElements = [],
|
20878
|
+
previousElements = [],
|
20617
20879
|
selectedScopes = [];
|
20618
20880
|
|
20619
20881
|
scope.$watch(watchExpr, function ngSwitchWatchAction(value) {
|
20620
|
-
var i, ii
|
20621
|
-
|
20622
|
-
|
20623
|
-
|
20624
|
-
|
20625
|
-
|
20626
|
-
|
20627
|
-
|
20628
|
-
|
20629
|
-
previousElements =
|
20630
|
-
|
20631
|
-
|
20632
|
-
|
20633
|
-
previousElements[i] = selected;
|
20634
|
-
$animate.leave(selected, function() {
|
20635
|
-
previousElements.splice(i, 1);
|
20636
|
-
if(previousElements.length === 0) {
|
20637
|
-
previousElements = null;
|
20638
|
-
}
|
20639
|
-
});
|
20640
|
-
}
|
20882
|
+
var i, ii;
|
20883
|
+
for (i = 0, ii = previousElements.length; i < ii; ++i) {
|
20884
|
+
previousElements[i].remove();
|
20885
|
+
}
|
20886
|
+
previousElements.length = 0;
|
20887
|
+
|
20888
|
+
for (i = 0, ii = selectedScopes.length; i < ii; ++i) {
|
20889
|
+
var selected = selectedElements[i];
|
20890
|
+
selectedScopes[i].$destroy();
|
20891
|
+
previousElements[i] = selected;
|
20892
|
+
$animate.leave(selected, function() {
|
20893
|
+
previousElements.splice(i, 1);
|
20894
|
+
});
|
20641
20895
|
}
|
20642
20896
|
|
20643
|
-
selectedElements =
|
20644
|
-
selectedScopes =
|
20897
|
+
selectedElements.length = 0;
|
20898
|
+
selectedScopes.length = 0;
|
20645
20899
|
|
20646
20900
|
if ((selectedTranscludes = ngSwitchController.cases['!' + value] || ngSwitchController.cases['?'])) {
|
20647
20901
|
scope.$eval(attr.change);
|
@@ -20885,7 +21139,7 @@ var ngOptionsMinErr = minErr('ngOptions');
|
|
20885
21139
|
{name:'blue', shade:'dark'},
|
20886
21140
|
{name:'yellow', shade:'light'}
|
20887
21141
|
];
|
20888
|
-
$scope.
|
21142
|
+
$scope.myColor = $scope.colors[2]; // red
|
20889
21143
|
}
|
20890
21144
|
</script>
|
20891
21145
|
<div ng-controller="MyCntrl">
|
@@ -20900,37 +21154,37 @@ var ngOptionsMinErr = minErr('ngOptions');
|
|
20900
21154
|
</ul>
|
20901
21155
|
<hr/>
|
20902
21156
|
Color (null not allowed):
|
20903
|
-
<select ng-model="
|
21157
|
+
<select ng-model="myColor" ng-options="color.name for color in colors"></select><br>
|
20904
21158
|
|
20905
21159
|
Color (null allowed):
|
20906
21160
|
<span class="nullable">
|
20907
|
-
<select ng-model="
|
21161
|
+
<select ng-model="myColor" ng-options="color.name for color in colors">
|
20908
21162
|
<option value="">-- choose color --</option>
|
20909
21163
|
</select>
|
20910
21164
|
</span><br/>
|
20911
21165
|
|
20912
21166
|
Color grouped by shade:
|
20913
|
-
<select ng-model="
|
21167
|
+
<select ng-model="myColor" ng-options="color.name group by color.shade for color in colors">
|
20914
21168
|
</select><br/>
|
20915
21169
|
|
20916
21170
|
|
20917
|
-
Select <a href ng-click="
|
21171
|
+
Select <a href ng-click="myColor = { name:'not in list', shade: 'other' }">bogus</a>.<br>
|
20918
21172
|
<hr/>
|
20919
|
-
Currently selected: {{ {selected_color:
|
21173
|
+
Currently selected: {{ {selected_color:myColor} }}
|
20920
21174
|
<div style="border:solid 1px black; height:20px"
|
20921
|
-
ng-style="{'background-color':
|
21175
|
+
ng-style="{'background-color':myColor.name}">
|
20922
21176
|
</div>
|
20923
21177
|
</div>
|
20924
21178
|
</file>
|
20925
21179
|
<file name="protractor.js" type="protractor">
|
20926
21180
|
it('should check ng-options', function() {
|
20927
|
-
expect(element(by.binding('{selected_color:
|
20928
|
-
element.all(by.select('
|
20929
|
-
element.all(by.css('select[ng-model="
|
20930
|
-
expect(element(by.binding('{selected_color:
|
20931
|
-
element(by.css('.nullable select[ng-model="
|
20932
|
-
element.all(by.css('.nullable select[ng-model="
|
20933
|
-
expect(element(by.binding('{selected_color:
|
21181
|
+
expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('red');
|
21182
|
+
element.all(by.select('myColor')).first().click();
|
21183
|
+
element.all(by.css('select[ng-model="myColor"] option')).first().click();
|
21184
|
+
expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('black');
|
21185
|
+
element(by.css('.nullable select[ng-model="myColor"]')).click();
|
21186
|
+
element.all(by.css('.nullable select[ng-model="myColor"] option')).first().click();
|
21187
|
+
expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('null');
|
20934
21188
|
});
|
20935
21189
|
</file>
|
20936
21190
|
</example>
|
@@ -21085,7 +21339,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
21085
21339
|
// we need to work of an array, so we need to see if anything was inserted/removed
|
21086
21340
|
scope.$watch(function selectMultipleWatch() {
|
21087
21341
|
if (!equals(lastView, ctrl.$viewValue)) {
|
21088
|
-
lastView =
|
21342
|
+
lastView = shallowCopy(ctrl.$viewValue);
|
21089
21343
|
ctrl.$render();
|
21090
21344
|
}
|
21091
21345
|
});
|
@@ -21461,4 +21715,4 @@ var styleDirective = valueFn({
|
|
21461
21715
|
|
21462
21716
|
})(window, document);
|
21463
21717
|
|
21464
|
-
!angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-block-transitions{transition:0s all!important;-webkit-transition:0s all!important;}</style>');
|
21718
|
+
!window.angular.$$csp() && window.angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-block-transitions{transition:0s all!important;-webkit-transition:0s all!important;}.ng-hide-add-active,.ng-hide-remove{display:block!important;}</style>');
|