angularjs-rails 1.2.16 → 1.2.18
Sign up to get free protection for your applications and to get access to all the features.
- 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>');
|