angular-gem 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. checksums.yaml +8 -8
  2. data/lib/angular-gem/version.rb +1 -1
  3. data/vendor/assets/javascripts/1.3.1/angular-animate.js +2136 -0
  4. data/vendor/assets/javascripts/1.3.1/angular-aria.js +250 -0
  5. data/vendor/assets/javascripts/1.3.1/angular-cookies.js +206 -0
  6. data/vendor/assets/javascripts/1.3.1/angular-loader.js +422 -0
  7. data/vendor/assets/javascripts/1.3.1/angular-messages.js +400 -0
  8. data/vendor/assets/javascripts/1.3.1/angular-mocks.js +2289 -0
  9. data/vendor/assets/javascripts/1.3.1/angular-resource.js +667 -0
  10. data/vendor/assets/javascripts/1.3.1/angular-route.js +978 -0
  11. data/vendor/assets/javascripts/1.3.1/angular-sanitize.js +678 -0
  12. data/vendor/assets/javascripts/1.3.1/angular-scenario.js +36979 -0
  13. data/vendor/assets/javascripts/1.3.1/angular-touch.js +622 -0
  14. data/vendor/assets/javascripts/1.3.1/angular.js +25625 -0
  15. data/vendor/assets/javascripts/angular-animate.js +78 -54
  16. data/vendor/assets/javascripts/angular-aria.js +5 -5
  17. data/vendor/assets/javascripts/angular-cookies.js +4 -4
  18. data/vendor/assets/javascripts/angular-loader.js +6 -6
  19. data/vendor/assets/javascripts/angular-messages.js +15 -15
  20. data/vendor/assets/javascripts/angular-mocks.js +34 -32
  21. data/vendor/assets/javascripts/angular-resource.js +22 -22
  22. data/vendor/assets/javascripts/angular-route.js +8 -8
  23. data/vendor/assets/javascripts/angular-sanitize.js +94 -63
  24. data/vendor/assets/javascripts/angular-scenario.js +532 -497
  25. data/vendor/assets/javascripts/angular-touch.js +3 -3
  26. data/vendor/assets/javascripts/angular.js +516 -475
  27. metadata +14 -2
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.0
2
+ * @license AngularJS v1.3.1
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -406,7 +406,7 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
406
406
  tapping = true;
407
407
  tapElement = event.target ? event.target : event.srcElement; // IE uses srcElement.
408
408
  // Hack for Safari, which can target text nodes instead of containers.
409
- if(tapElement.nodeType == 3) {
409
+ if (tapElement.nodeType == 3) {
410
410
  tapElement = tapElement.parentNode;
411
411
  }
412
412
 
@@ -436,7 +436,7 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
436
436
  var e = touches[0].originalEvent || touches[0];
437
437
  var x = e.clientX;
438
438
  var y = e.clientY;
439
- var dist = Math.sqrt( Math.pow(x - touchStartX, 2) + Math.pow(y - touchStartY, 2) );
439
+ var dist = Math.sqrt(Math.pow(x - touchStartX, 2) + Math.pow(y - touchStartY, 2));
440
440
 
441
441
  if (tapping && diff < TAP_DURATION && dist < MOVE_TOLERANCE) {
442
442
  // Call preventGhostClick so the clickbuster will catch the corresponding click.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.0
2
+ * @license AngularJS v1.3.1
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -37,12 +37,12 @@
37
37
 
38
38
  function minErr(module, ErrorConstructor) {
39
39
  ErrorConstructor = ErrorConstructor || Error;
40
- return function () {
40
+ return function() {
41
41
  var code = arguments[0],
42
42
  prefix = '[' + (module ? module + ':' : '') + code + '] ',
43
43
  template = arguments[1],
44
44
  templateArgs = arguments,
45
- stringify = function (obj) {
45
+ stringify = function(obj) {
46
46
  if (typeof obj === 'function') {
47
47
  return obj.toString().replace(/ \{[\s\S]*$/, '');
48
48
  } else if (typeof obj === 'undefined') {
@@ -54,7 +54,7 @@ function minErr(module, ErrorConstructor) {
54
54
  },
55
55
  message, i;
56
56
 
57
- message = prefix + template.replace(/\{\d+\}/g, function (match) {
57
+ message = prefix + template.replace(/\{\d+\}/g, function(match) {
58
58
  var index = +match.slice(1, -1), arg;
59
59
 
60
60
  if (index + 2 < templateArgs.length) {
@@ -71,7 +71,7 @@ function minErr(module, ErrorConstructor) {
71
71
  return match;
72
72
  });
73
73
 
74
- message = message + '\nhttp://errors.angularjs.org/1.3.0/' +
74
+ message = message + '\nhttp://errors.angularjs.org/1.3.1/' +
75
75
  (module ? module + '/' : '') + code;
76
76
  for (i = 2; i < arguments.length; i++) {
77
77
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -130,12 +130,11 @@ function minErr(module, ErrorConstructor) {
130
130
  isBoolean: true,
131
131
  isPromiseLike: true,
132
132
  trim: true,
133
+ escapeForRegexp: true,
133
134
  isElement: true,
134
135
  makeMap: true,
135
- size: true,
136
136
  includes: true,
137
137
  arrayRemove: true,
138
- isLeafNode: true,
139
138
  copy: true,
140
139
  shallowCopy: true,
141
140
  equals: true,
@@ -205,7 +204,7 @@ var VALIDITY_STATE_PROPERTY = 'validity';
205
204
  * @param {string} string String to be converted to lowercase.
206
205
  * @returns {string} Lowercased string.
207
206
  */
208
- var lowercase = function(string){return isString(string) ? string.toLowerCase() : string;};
207
+ var lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;};
209
208
  var hasOwnProperty = Object.prototype.hasOwnProperty;
210
209
 
211
210
  /**
@@ -218,7 +217,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty;
218
217
  * @param {string} string String to be converted to uppercase.
219
218
  * @returns {string} Uppercased string.
220
219
  */
221
- var uppercase = function(string){return isString(string) ? string.toUpperCase() : string;};
220
+ var uppercase = function(string) {return isString(string) ? string.toUpperCase() : string;};
222
221
 
223
222
 
224
223
  var manualLowercase = function(s) {
@@ -301,6 +300,11 @@ function isArrayLike(obj) {
301
300
  *
302
301
  * It is worth noting that `.forEach` does not iterate over inherited properties because it filters
303
302
  * using the `hasOwnProperty` method.
303
+ *
304
+ * Unlike ES262's
305
+ * [Array.prototype.forEach](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18),
306
+ * Providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just
307
+ * return the value provided.
304
308
  *
305
309
  ```js
306
310
  var values = {name: 'misko', gender: 'male'};
@@ -349,18 +353,12 @@ function forEach(obj, iterator, context) {
349
353
  }
350
354
 
351
355
  function sortedKeys(obj) {
352
- var keys = [];
353
- for (var key in obj) {
354
- if (obj.hasOwnProperty(key)) {
355
- keys.push(key);
356
- }
357
- }
358
- return keys.sort();
356
+ return Object.keys(obj).sort();
359
357
  }
360
358
 
361
359
  function forEachSorted(obj, iterator, context) {
362
360
  var keys = sortedKeys(obj);
363
- for ( var i = 0; i < keys.length; i++) {
361
+ for (var i = 0; i < keys.length; i++) {
364
362
  iterator.call(context, obj[keys[i]], keys[i]);
365
363
  }
366
364
  return keys;
@@ -415,6 +413,7 @@ function setHashKey(obj, h) {
415
413
  * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
416
414
  * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
417
415
  * by passing an empty object as the target: `var object = angular.extend({}, object1, object2)`.
416
+ * Note: Keep in mind that `angular.extend` does not support recursive merge (deep copy).
418
417
  *
419
418
  * @param {Object} dst Destination object.
420
419
  * @param {...Object} src Source object(s).
@@ -501,7 +500,7 @@ function valueFn(value) {return function() {return value;};}
501
500
  * @param {*} value Reference to check.
502
501
  * @returns {boolean} True if `value` is undefined.
503
502
  */
504
- function isUndefined(value){return typeof value === 'undefined';}
503
+ function isUndefined(value) {return typeof value === 'undefined';}
505
504
 
506
505
 
507
506
  /**
@@ -516,7 +515,7 @@ function isUndefined(value){return typeof value === 'undefined';}
516
515
  * @param {*} value Reference to check.
517
516
  * @returns {boolean} True if `value` is defined.
518
517
  */
519
- function isDefined(value){return typeof value !== 'undefined';}
518
+ function isDefined(value) {return typeof value !== 'undefined';}
520
519
 
521
520
 
522
521
  /**
@@ -532,7 +531,7 @@ function isDefined(value){return typeof value !== 'undefined';}
532
531
  * @param {*} value Reference to check.
533
532
  * @returns {boolean} True if `value` is an `Object` but not `null`.
534
533
  */
535
- function isObject(value){
534
+ function isObject(value) {
536
535
  // http://jsperf.com/isobject4
537
536
  return value !== null && typeof value === 'object';
538
537
  }
@@ -550,7 +549,7 @@ function isObject(value){
550
549
  * @param {*} value Reference to check.
551
550
  * @returns {boolean} True if `value` is a `String`.
552
551
  */
553
- function isString(value){return typeof value === 'string';}
552
+ function isString(value) {return typeof value === 'string';}
554
553
 
555
554
 
556
555
  /**
@@ -565,7 +564,7 @@ function isString(value){return typeof value === 'string';}
565
564
  * @param {*} value Reference to check.
566
565
  * @returns {boolean} True if `value` is a `Number`.
567
566
  */
568
- function isNumber(value){return typeof value === 'number';}
567
+ function isNumber(value) {return typeof value === 'number';}
569
568
 
570
569
 
571
570
  /**
@@ -611,7 +610,7 @@ var isArray = Array.isArray;
611
610
  * @param {*} value Reference to check.
612
611
  * @returns {boolean} True if `value` is a `Function`.
613
612
  */
614
- function isFunction(value){return typeof value === 'function';}
613
+ function isFunction(value) {return typeof value === 'function';}
615
614
 
616
615
 
617
616
  /**
@@ -667,6 +666,14 @@ var trim = function(value) {
667
666
  return isString(value) ? value.trim() : value;
668
667
  };
669
668
 
669
+ // Copied from:
670
+ // http://docs.closure-library.googlecode.com/git/local_closure_goog_string_string.js.source.html#line1021
671
+ // Prereq: s is a string.
672
+ var escapeForRegexp = function(s) {
673
+ return s.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1').
674
+ replace(/\x08/g, '\\x08');
675
+ };
676
+
670
677
 
671
678
  /**
672
679
  * @ngdoc function
@@ -692,7 +699,7 @@ function isElement(node) {
692
699
  */
693
700
  function makeMap(str) {
694
701
  var obj = {}, items = str.split(","), i;
695
- for ( i = 0; i < items.length; i++ )
702
+ for (i = 0; i < items.length; i++)
696
703
  obj[ items[i] ] = true;
697
704
  return obj;
698
705
  }
@@ -702,34 +709,6 @@ function nodeName_(element) {
702
709
  return lowercase(element.nodeName || element[0].nodeName);
703
710
  }
704
711
 
705
-
706
- /**
707
- * @description
708
- * Determines the number of elements in an array, the number of properties an object has, or
709
- * the length of a string.
710
- *
711
- * Note: This function is used to augment the Object type in Angular expressions. See
712
- * {@link angular.Object} for more information about Angular arrays.
713
- *
714
- * @param {Object|Array|string} obj Object, array, or string to inspect.
715
- * @param {boolean} [ownPropsOnly=false] Count only "own" properties in an object
716
- * @returns {number} The size of `obj` or `0` if `obj` is neither an object nor an array.
717
- */
718
- function size(obj, ownPropsOnly) {
719
- var count = 0, key;
720
-
721
- if (isArray(obj) || isString(obj)) {
722
- return obj.length;
723
- } else if (isObject(obj)) {
724
- for (key in obj)
725
- if (!ownPropsOnly || obj.hasOwnProperty(key))
726
- count++;
727
- }
728
-
729
- return count;
730
- }
731
-
732
-
733
712
  function includes(array, obj) {
734
713
  return Array.prototype.indexOf.call(array, obj) != -1;
735
714
  }
@@ -741,18 +720,6 @@ function arrayRemove(array, value) {
741
720
  return value;
742
721
  }
743
722
 
744
- function isLeafNode (node) {
745
- if (node) {
746
- switch (nodeName_(node)) {
747
- case "option":
748
- case "pre":
749
- case "title":
750
- return true;
751
- }
752
- }
753
- return false;
754
- }
755
-
756
723
  /**
757
724
  * @ngdoc function
758
725
  * @name angular.copy
@@ -850,7 +817,7 @@ function copy(source, destination, stackSource, stackDest) {
850
817
  var result;
851
818
  if (isArray(source)) {
852
819
  destination.length = 0;
853
- for ( var i = 0; i < source.length; i++) {
820
+ for (var i = 0; i < source.length; i++) {
854
821
  result = copy(source[i], null, stackSource, stackDest);
855
822
  if (isObject(source[i])) {
856
823
  stackSource.push(source[i]);
@@ -867,8 +834,8 @@ function copy(source, destination, stackSource, stackDest) {
867
834
  delete destination[key];
868
835
  });
869
836
  }
870
- for ( var key in source) {
871
- if(source.hasOwnProperty(key)) {
837
+ for (var key in source) {
838
+ if (source.hasOwnProperty(key)) {
872
839
  result = copy(source[key], null, stackSource, stackDest);
873
840
  if (isObject(source[key])) {
874
841
  stackSource.push(source[key]);
@@ -949,7 +916,7 @@ function equals(o1, o2) {
949
916
  if (isArray(o1)) {
950
917
  if (!isArray(o2)) return false;
951
918
  if ((length = o1.length) == o2.length) {
952
- for(key=0; key<length; key++) {
919
+ for (key=0; key<length; key++) {
953
920
  if (!equals(o1[key], o2[key])) return false;
954
921
  }
955
922
  return true;
@@ -962,12 +929,12 @@ function equals(o1, o2) {
962
929
  } else {
963
930
  if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) || isArray(o2)) return false;
964
931
  keySet = {};
965
- for(key in o1) {
932
+ for (key in o1) {
966
933
  if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
967
934
  if (!equals(o1[key], o2[key])) return false;
968
935
  keySet[key] = true;
969
936
  }
970
- for(key in o2) {
937
+ for (key in o2) {
971
938
  if (!keySet.hasOwnProperty(key) &&
972
939
  key.charAt(0) !== '$' &&
973
940
  o2[key] !== undefined &&
@@ -1115,14 +1082,14 @@ function startingTag(element) {
1115
1082
  // turns out IE does not let you set .html() on elements which
1116
1083
  // are not allowed to have children. So we just ignore it.
1117
1084
  element.empty();
1118
- } catch(e) {}
1085
+ } catch (e) {}
1119
1086
  var elemHtml = jqLite('<div>').append(element).html();
1120
1087
  try {
1121
1088
  return element[0].nodeType === NODE_TYPE_TEXT ? lowercase(elemHtml) :
1122
1089
  elemHtml.
1123
1090
  match(/^(<[^>]+>)/)[1].
1124
1091
  replace(/^<([\w\-]+)/, function(match, nodeName) { return '<' + lowercase(nodeName); });
1125
- } catch(e) {
1092
+ } catch (e) {
1126
1093
  return lowercase(elemHtml);
1127
1094
  }
1128
1095
 
@@ -1142,7 +1109,7 @@ function startingTag(element) {
1142
1109
  function tryDecodeURIComponent(value) {
1143
1110
  try {
1144
1111
  return decodeURIComponent(value);
1145
- } catch(e) {
1112
+ } catch (e) {
1146
1113
  // Ignore any invalid uri component
1147
1114
  }
1148
1115
  }
@@ -1155,14 +1122,14 @@ function tryDecodeURIComponent(value) {
1155
1122
  function parseKeyValue(/**string*/keyValue) {
1156
1123
  var obj = {}, key_value, key;
1157
1124
  forEach((keyValue || "").split('&'), function(keyValue) {
1158
- if ( keyValue ) {
1125
+ if (keyValue) {
1159
1126
  key_value = keyValue.replace(/\+/g,'%20').split('=');
1160
1127
  key = tryDecodeURIComponent(key_value[0]);
1161
- if ( isDefined(key) ) {
1128
+ if (isDefined(key)) {
1162
1129
  var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
1163
1130
  if (!hasOwnProperty.call(obj, key)) {
1164
1131
  obj[key] = val;
1165
- } else if(isArray(obj[key])) {
1132
+ } else if (isArray(obj[key])) {
1166
1133
  obj[key].push(val);
1167
1134
  } else {
1168
1135
  obj[key] = [obj[key],val];
@@ -1999,7 +1966,7 @@ function setupModuleLoader(window) {
1999
1966
  config(configFn);
2000
1967
  }
2001
1968
 
2002
- return moduleInstance;
1969
+ return moduleInstance;
2003
1970
 
2004
1971
  /**
2005
1972
  * @param {string} provider
@@ -2122,15 +2089,15 @@ function setupModuleLoader(window) {
2122
2089
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
2123
2090
  */
2124
2091
  var version = {
2125
- full: '1.3.0', // all of these placeholder strings will be replaced by grunt's
2092
+ full: '1.3.1', // all of these placeholder strings will be replaced by grunt's
2126
2093
  major: 1, // package task
2127
2094
  minor: 3,
2128
- dot: 0,
2129
- codeName: 'superluminal-nudge'
2095
+ dot: 1,
2096
+ codeName: 'spectral-lobster'
2130
2097
  };
2131
2098
 
2132
2099
 
2133
- function publishExternalAPI(angular){
2100
+ function publishExternalAPI(angular) {
2134
2101
  extend(angular, {
2135
2102
  'bootstrap': bootstrap,
2136
2103
  'copy': copy,
@@ -2256,7 +2223,7 @@ function publishExternalAPI(angular){
2256
2223
  $timeout: $TimeoutProvider,
2257
2224
  $window: $WindowProvider,
2258
2225
  $$rAF: $$RAFProvider,
2259
- $$asyncCallback : $$AsyncCallbackProvider
2226
+ $$asyncCallback: $$AsyncCallbackProvider
2260
2227
  });
2261
2228
  }
2262
2229
  ]);
@@ -2306,7 +2273,7 @@ function publishExternalAPI(angular){
2306
2273
  * - [`children()`](http://api.jquery.com/children/) - Does not support selectors
2307
2274
  * - [`clone()`](http://api.jquery.com/clone/)
2308
2275
  * - [`contents()`](http://api.jquery.com/contents/)
2309
- * - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyles()`
2276
+ * - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyle()`
2310
2277
  * - [`data()`](http://api.jquery.com/data/)
2311
2278
  * - [`detach()`](http://api.jquery.com/detach/)
2312
2279
  * - [`empty()`](http://api.jquery.com/empty/)
@@ -2384,7 +2351,7 @@ function jqNextId() { return ++jqId; }
2384
2351
 
2385
2352
  var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
2386
2353
  var MOZ_HACK_REGEXP = /^moz([A-Z])/;
2387
- var MOUSE_EVENT_MAP= { mouseleave : "mouseout", mouseenter : "mouseover"};
2354
+ var MOUSE_EVENT_MAP= { mouseleave: "mouseout", mouseenter: "mouseover"};
2388
2355
  var jqLiteMinErr = minErr('jqLite');
2389
2356
 
2390
2357
  /**
@@ -2513,7 +2480,7 @@ function jqLiteClone(element) {
2513
2480
  return element.cloneNode(true);
2514
2481
  }
2515
2482
 
2516
- function jqLiteDealoc(element, onlyDescendants){
2483
+ function jqLiteDealoc(element, onlyDescendants) {
2517
2484
  if (!onlyDescendants) jqLiteRemoveData(element);
2518
2485
 
2519
2486
  if (element.querySelectorAll) {
@@ -2620,7 +2587,7 @@ function jqLiteData(element, key, value) {
2620
2587
  function jqLiteHasClass(element, selector) {
2621
2588
  if (!element.getAttribute) return false;
2622
2589
  return ((" " + (element.getAttribute('class') || '') + " ").replace(/[\n\t]/g, " ").
2623
- indexOf( " " + selector + " " ) > -1);
2590
+ indexOf(" " + selector + " ") > -1);
2624
2591
  }
2625
2592
 
2626
2593
  function jqLiteRemoveClass(element, cssClasses) {
@@ -2679,13 +2646,13 @@ function jqLiteAddNodes(root, elements) {
2679
2646
 
2680
2647
 
2681
2648
  function jqLiteController(element, name) {
2682
- return jqLiteInheritedData(element, '$' + (name || 'ngController' ) + 'Controller');
2649
+ return jqLiteInheritedData(element, '$' + (name || 'ngController') + 'Controller');
2683
2650
  }
2684
2651
 
2685
2652
  function jqLiteInheritedData(element, name, value) {
2686
2653
  // if element is the document object work with the html element instead
2687
2654
  // this makes $(document).scope() possible
2688
- if(element.nodeType == NODE_TYPE_DOCUMENT) {
2655
+ if (element.nodeType == NODE_TYPE_DOCUMENT) {
2689
2656
  element = element.documentElement;
2690
2657
  }
2691
2658
  var names = isArray(name) ? name : [name];
@@ -2743,7 +2710,7 @@ var JQLitePrototype = JQLite.prototype = {
2743
2710
  }
2744
2711
 
2745
2712
  // check if document is already loaded
2746
- if (document.readyState === 'complete'){
2713
+ if (document.readyState === 'complete') {
2747
2714
  setTimeout(trigger);
2748
2715
  } else {
2749
2716
  this.on('DOMContentLoaded', trigger); // works for modern browsers and IE9
@@ -2751,12 +2718,11 @@ var JQLitePrototype = JQLite.prototype = {
2751
2718
  // jshint -W064
2752
2719
  JQLite(window).on('load', trigger); // fallback to window.onload for others
2753
2720
  // jshint +W064
2754
- this.on('DOMContentLoaded', trigger);
2755
2721
  }
2756
2722
  },
2757
2723
  toString: function() {
2758
2724
  var value = [];
2759
- forEach(this, function(e){ value.push('' + e);});
2725
+ forEach(this, function(e) { value.push('' + e);});
2760
2726
  return '[' + value.join(', ') + ']';
2761
2727
  },
2762
2728
 
@@ -2784,11 +2750,11 @@ forEach('input,select,option,textarea,button,form,details'.split(','), function(
2784
2750
  BOOLEAN_ELEMENTS[value] = true;
2785
2751
  });
2786
2752
  var ALIASED_ATTR = {
2787
- 'ngMinlength' : 'minlength',
2788
- 'ngMaxlength' : 'maxlength',
2789
- 'ngMin' : 'min',
2790
- 'ngMax' : 'max',
2791
- 'ngPattern' : 'pattern'
2753
+ 'ngMinlength': 'minlength',
2754
+ 'ngMaxlength': 'maxlength',
2755
+ 'ngMin': 'min',
2756
+ 'ngMax': 'max',
2757
+ 'ngPattern': 'pattern'
2792
2758
  };
2793
2759
 
2794
2760
  function getBooleanAttrName(element, name) {
@@ -2847,7 +2813,7 @@ forEach({
2847
2813
  }
2848
2814
  },
2849
2815
 
2850
- attr: function(element, name, value){
2816
+ attr: function(element, name, value) {
2851
2817
  var lowercasedName = lowercase(name);
2852
2818
  if (BOOLEAN_ATTR[lowercasedName]) {
2853
2819
  if (isDefined(value)) {
@@ -2900,7 +2866,7 @@ forEach({
2900
2866
  if (isUndefined(value)) {
2901
2867
  if (element.multiple && nodeName_(element) === 'select') {
2902
2868
  var result = [];
2903
- forEach(element.options, function (option) {
2869
+ forEach(element.options, function(option) {
2904
2870
  if (option.selected) {
2905
2871
  result.push(option.value || option.text);
2906
2872
  }
@@ -2921,7 +2887,7 @@ forEach({
2921
2887
  },
2922
2888
 
2923
2889
  empty: jqLiteEmpty
2924
- }, function(fn, name){
2890
+ }, function(fn, name) {
2925
2891
  /**
2926
2892
  * Properties: writes return selection, reads return first value
2927
2893
  */
@@ -2973,7 +2939,7 @@ forEach({
2973
2939
  });
2974
2940
 
2975
2941
  function createEventHandler(element, events) {
2976
- var eventHandler = function (event, type) {
2942
+ var eventHandler = function(event, type) {
2977
2943
  // jQuery specific api
2978
2944
  event.isDefaultPrevented = function() {
2979
2945
  return event.defaultPrevented;
@@ -3029,7 +2995,7 @@ function createEventHandler(element, events) {
3029
2995
  forEach({
3030
2996
  removeData: jqLiteRemoveData,
3031
2997
 
3032
- on: function jqLiteOn(element, type, fn, unsupported){
2998
+ on: function jqLiteOn(element, type, fn, unsupported) {
3033
2999
  if (isDefined(unsupported)) throw jqLiteMinErr('onargs', 'jqLite#on() does not support the `selector` or `eventData` parameters');
3034
3000
 
3035
3001
  // Do not add event handlers to non-elements because they will not be cleaned up.
@@ -3065,7 +3031,7 @@ forEach({
3065
3031
  var target = this, related = event.relatedTarget;
3066
3032
  // For mousenter/leave call the handler if related is outside the target.
3067
3033
  // NB: No relatedTarget if the mouse left/entered the browser window
3068
- if ( !related || (related !== target && !target.contains(related)) ){
3034
+ if (!related || (related !== target && !target.contains(related))) {
3069
3035
  handle(event, type);
3070
3036
  }
3071
3037
  });
@@ -3099,7 +3065,7 @@ forEach({
3099
3065
  replaceWith: function(element, replaceNode) {
3100
3066
  var index, parent = element.parentNode;
3101
3067
  jqLiteDealoc(element);
3102
- forEach(new JQLite(replaceNode), function(node){
3068
+ forEach(new JQLite(replaceNode), function(node) {
3103
3069
  if (index) {
3104
3070
  parent.insertBefore(node, index.nextSibling);
3105
3071
  } else {
@@ -3111,7 +3077,7 @@ forEach({
3111
3077
 
3112
3078
  children: function(element) {
3113
3079
  var children = [];
3114
- forEach(element.childNodes, function(element){
3080
+ forEach(element.childNodes, function(element) {
3115
3081
  if (element.nodeType === NODE_TYPE_ELEMENT)
3116
3082
  children.push(element);
3117
3083
  });
@@ -3137,7 +3103,7 @@ forEach({
3137
3103
  prepend: function(element, node) {
3138
3104
  if (element.nodeType === NODE_TYPE_ELEMENT) {
3139
3105
  var index = element.firstChild;
3140
- forEach(new JQLite(node), function(child){
3106
+ forEach(new JQLite(node), function(child) {
3141
3107
  element.insertBefore(child, index);
3142
3108
  });
3143
3109
  }
@@ -3174,7 +3140,7 @@ forEach({
3174
3140
 
3175
3141
  toggleClass: function(element, selector, condition) {
3176
3142
  if (selector) {
3177
- forEach(selector.split(' '), function(className){
3143
+ forEach(selector.split(' '), function(className) {
3178
3144
  var classCondition = condition;
3179
3145
  if (isUndefined(classCondition)) {
3180
3146
  classCondition = !jqLiteHasClass(element, className);
@@ -3239,14 +3205,14 @@ forEach({
3239
3205
  });
3240
3206
  }
3241
3207
  }
3242
- }, function(fn, name){
3208
+ }, function(fn, name) {
3243
3209
  /**
3244
3210
  * chaining functions
3245
3211
  */
3246
3212
  JQLite.prototype[name] = function(arg1, arg2, arg3) {
3247
3213
  var value;
3248
3214
 
3249
- for(var i = 0, ii = this.length; i < ii; i++) {
3215
+ for (var i = 0, ii = this.length; i < ii; i++) {
3250
3216
  if (isUndefined(value)) {
3251
3217
  value = fn(this[i], arg1, arg2, arg3);
3252
3218
  if (isDefined(value)) {
@@ -4043,7 +4009,7 @@ function createInjector(modulesToLoad, strictDi) {
4043
4009
  ////////////////////////////////////
4044
4010
  // Module Loading
4045
4011
  ////////////////////////////////////
4046
- function loadModules(modulesToLoad){
4012
+ function loadModules(modulesToLoad) {
4047
4013
  var runBlocks = [], moduleFn;
4048
4014
  forEach(modulesToLoad, function(module) {
4049
4015
  if (loadedModules.get(module)) return;
@@ -4051,7 +4017,7 @@ function createInjector(modulesToLoad, strictDi) {
4051
4017
 
4052
4018
  function runInvokeQueue(queue) {
4053
4019
  var i, ii;
4054
- for(i = 0, ii = queue.length; i < ii; i++) {
4020
+ for (i = 0, ii = queue.length; i < ii; i++) {
4055
4021
  var invokeArgs = queue[i],
4056
4022
  provider = providerInjector.get(invokeArgs[0]);
4057
4023
 
@@ -4131,7 +4097,7 @@ function createInjector(modulesToLoad, strictDi) {
4131
4097
  length, i,
4132
4098
  key;
4133
4099
 
4134
- for(i = 0, length = $inject.length; i < length; i++) {
4100
+ for (i = 0, length = $inject.length; i < length; i++) {
4135
4101
  key = $inject[i];
4136
4102
  if (typeof key !== 'string') {
4137
4103
  throw $injectorMinErr('itkn',
@@ -4347,7 +4313,6 @@ function $AnchorScrollProvider() {
4347
4313
  */
4348
4314
  this.$get = ['$window', '$location', '$rootScope', function($window, $location, $rootScope) {
4349
4315
  var document = $window.document;
4350
- var scrollScheduled = false;
4351
4316
 
4352
4317
  // Helper function to get first anchor from a NodeList
4353
4318
  // (using `Array#some()` instead of `angular#forEach()` since it's more performant
@@ -4521,7 +4486,7 @@ var $AnimateProvider = ['$provide', function($provide) {
4521
4486
  * @return {RegExp} The current CSS className expression value. If null then there is no expression value
4522
4487
  */
4523
4488
  this.classNameFilter = function(expression) {
4524
- if(arguments.length === 1) {
4489
+ if (arguments.length === 1) {
4525
4490
  this.$$classNameFilter = (expression instanceof RegExp) ? expression : null;
4526
4491
  }
4527
4492
  return this.$$classNameFilter;
@@ -4616,7 +4581,7 @@ var $AnimateProvider = ['$provide', function($provide) {
4616
4581
  * page}.
4617
4582
  */
4618
4583
  return {
4619
- animate : function(element, from, to) {
4584
+ animate: function(element, from, to) {
4620
4585
  applyStyles(element, { from: from, to: to });
4621
4586
  return asyncPromise();
4622
4587
  },
@@ -4637,7 +4602,7 @@ var $AnimateProvider = ['$provide', function($provide) {
4637
4602
  * @param {object=} options an optional collection of styles that will be applied to the element.
4638
4603
  * @return {Promise} the animation callback promise
4639
4604
  */
4640
- enter : function(element, parent, after, options) {
4605
+ enter: function(element, parent, after, options) {
4641
4606
  applyStyles(element, options);
4642
4607
  after ? after.after(element)
4643
4608
  : parent.prepend(element);
@@ -4655,7 +4620,7 @@ var $AnimateProvider = ['$provide', function($provide) {
4655
4620
  * @param {object=} options an optional collection of options that will be applied to the element.
4656
4621
  * @return {Promise} the animation callback promise
4657
4622
  */
4658
- leave : function(element, options) {
4623
+ leave: function(element, options) {
4659
4624
  element.remove();
4660
4625
  return asyncPromise();
4661
4626
  },
@@ -4678,7 +4643,7 @@ var $AnimateProvider = ['$provide', function($provide) {
4678
4643
  * @param {object=} options an optional collection of options that will be applied to the element.
4679
4644
  * @return {Promise} the animation callback promise
4680
4645
  */
4681
- move : function(element, parent, after, options) {
4646
+ move: function(element, parent, after, options) {
4682
4647
  // Do not remove element before insert. Removing will cause data associated with the
4683
4648
  // element to be dropped. Insert will implicitly do the remove.
4684
4649
  return this.enter(element, parent, after, options);
@@ -4697,16 +4662,16 @@ var $AnimateProvider = ['$provide', function($provide) {
4697
4662
  * @param {object=} options an optional collection of options that will be applied to the element.
4698
4663
  * @return {Promise} the animation callback promise
4699
4664
  */
4700
- addClass : function(element, className, options) {
4665
+ addClass: function(element, className, options) {
4701
4666
  return this.setClass(element, className, [], options);
4702
4667
  },
4703
4668
 
4704
- $$addClassImmediately : function(element, className, options) {
4669
+ $$addClassImmediately: function(element, className, options) {
4705
4670
  element = jqLite(element);
4706
4671
  className = !isString(className)
4707
4672
  ? (isArray(className) ? className.join(' ') : '')
4708
4673
  : className;
4709
- forEach(element, function (element) {
4674
+ forEach(element, function(element) {
4710
4675
  jqLiteAddClass(element, className);
4711
4676
  });
4712
4677
  applyStyles(element, options);
@@ -4726,16 +4691,16 @@ var $AnimateProvider = ['$provide', function($provide) {
4726
4691
  * @param {object=} options an optional collection of options that will be applied to the element.
4727
4692
  * @return {Promise} the animation callback promise
4728
4693
  */
4729
- removeClass : function(element, className, options) {
4694
+ removeClass: function(element, className, options) {
4730
4695
  return this.setClass(element, [], className, options);
4731
4696
  },
4732
4697
 
4733
- $$removeClassImmediately : function(element, className, options) {
4698
+ $$removeClassImmediately: function(element, className, options) {
4734
4699
  element = jqLite(element);
4735
4700
  className = !isString(className)
4736
4701
  ? (isArray(className) ? className.join(' ') : '')
4737
4702
  : className;
4738
- forEach(element, function (element) {
4703
+ forEach(element, function(element) {
4739
4704
  jqLiteRemoveClass(element, className);
4740
4705
  });
4741
4706
  applyStyles(element, options);
@@ -4756,7 +4721,7 @@ var $AnimateProvider = ['$provide', function($provide) {
4756
4721
  * @param {object=} options an optional collection of options that will be applied to the element.
4757
4722
  * @return {Promise} the animation callback promise
4758
4723
  */
4759
- setClass : function(element, add, remove, options) {
4724
+ setClass: function(element, add, remove, options) {
4760
4725
  var self = this;
4761
4726
  var STORAGE_KEY = '$$animateClasses';
4762
4727
  var createdCache = false;
@@ -4766,7 +4731,7 @@ var $AnimateProvider = ['$provide', function($provide) {
4766
4731
  if (!cache) {
4767
4732
  cache = {
4768
4733
  classes: {},
4769
- options : options
4734
+ options: options
4770
4735
  };
4771
4736
  createdCache = true;
4772
4737
  } else if (options && cache.options) {
@@ -4803,20 +4768,20 @@ var $AnimateProvider = ['$provide', function($provide) {
4803
4768
  return cache.promise;
4804
4769
  },
4805
4770
 
4806
- $$setClassImmediately : function(element, add, remove, options) {
4771
+ $$setClassImmediately: function(element, add, remove, options) {
4807
4772
  add && this.$$addClassImmediately(element, add);
4808
4773
  remove && this.$$removeClassImmediately(element, remove);
4809
4774
  applyStyles(element, options);
4810
4775
  return asyncPromise();
4811
4776
  },
4812
4777
 
4813
- enabled : noop,
4814
- cancel : noop
4778
+ enabled: noop,
4779
+ cancel: noop
4815
4780
  };
4816
4781
  }];
4817
4782
  }];
4818
4783
 
4819
- function $$AsyncCallbackProvider(){
4784
+ function $$AsyncCallbackProvider() {
4820
4785
  this.$get = ['$$rAF', '$timeout', function($$rAF, $timeout) {
4821
4786
  return $$rAF.supported
4822
4787
  ? function(fn) { return $$rAF(fn); }
@@ -4878,7 +4843,7 @@ function Browser(window, document, $log, $sniffer) {
4878
4843
  } finally {
4879
4844
  outstandingRequestCount--;
4880
4845
  if (outstandingRequestCount === 0) {
4881
- while(outstandingRequestCallbacks.length) {
4846
+ while (outstandingRequestCallbacks.length) {
4882
4847
  try {
4883
4848
  outstandingRequestCallbacks.pop()();
4884
4849
  } catch (e) {
@@ -4899,7 +4864,7 @@ function Browser(window, document, $log, $sniffer) {
4899
4864
  // force browser to execute all pollFns - this is needed so that cookies and other pollers fire
4900
4865
  // at some deterministic time in respect to the test runner's actions. Leaving things up to the
4901
4866
  // regular poller would result in flaky tests.
4902
- forEach(pollFns, function(pollFn){ pollFn(); });
4867
+ forEach(pollFns, function(pollFn) { pollFn(); });
4903
4868
 
4904
4869
  if (outstandingRequestCount === 0) {
4905
4870
  callback();
@@ -4941,7 +4906,7 @@ function Browser(window, document, $log, $sniffer) {
4941
4906
  */
4942
4907
  function startPoller(interval, setTimeout) {
4943
4908
  (function check() {
4944
- forEach(pollFns, function(pollFn){ pollFn(); });
4909
+ forEach(pollFns, function(pollFn) { pollFn(); });
4945
4910
  pollTimeout = setTimeout(check, interval);
4946
4911
  })();
4947
4912
  }
@@ -5276,9 +5241,9 @@ function Browser(window, document, $log, $sniffer) {
5276
5241
 
5277
5242
  }
5278
5243
 
5279
- function $BrowserProvider(){
5244
+ function $BrowserProvider() {
5280
5245
  this.$get = ['$window', '$log', '$sniffer', '$document',
5281
- function( $window, $log, $sniffer, $document){
5246
+ function($window, $log, $sniffer, $document) {
5282
5247
  return new Browser($window, $document, $log, $sniffer);
5283
5248
  }];
5284
5249
  }
@@ -5652,7 +5617,8 @@ function $CacheFactoryProvider() {
5652
5617
  * ```
5653
5618
  *
5654
5619
  * **Note:** the `script` tag containing the template does not need to be included in the `head` of
5655
- * the document, but it must be below the `ng-app` definition.
5620
+ * the document, but it must be a descendent of the {@link ng.$rootElement $rootElement} (IE,
5621
+ * element with ng-app attribute), otherwise the template will be ignored.
5656
5622
  *
5657
5623
  * Adding via the $templateCache service:
5658
5624
  *
@@ -5846,7 +5812,9 @@ function $TemplateCacheProvider() {
5846
5812
  * value of `parentModel` on the parent scope. Any changes to `parentModel` will be reflected
5847
5813
  * in `localModel` and any changes in `localModel` will reflect in `parentModel`. If the parent
5848
5814
  * scope property doesn't exist, it will throw a NON_ASSIGNABLE_MODEL_EXPRESSION exception. You
5849
- * can avoid this behavior using `=?` or `=?attr` in order to flag the property as optional.
5815
+ * can avoid this behavior using `=?` or `=?attr` in order to flag the property as optional. If
5816
+ * you want to shallow watch for changes (i.e. $watchCollection instead of $watch) you can use
5817
+ * `=*` or `=*attr` (`=*?` or `=*?attr` if the property is optional).
5850
5818
  *
5851
5819
  * * `&` or `&attr` - provides a way to execute an expression in the context of the parent scope.
5852
5820
  * If no `attr` name is specified then the attribute name is assumed to be the same as the
@@ -6362,8 +6330,8 @@ $CompileProvider.$inject = ['$provide', '$$sanitizeUriProvider'];
6362
6330
  function $CompileProvider($provide, $$sanitizeUriProvider) {
6363
6331
  var hasDirectives = {},
6364
6332
  Suffix = 'Directive',
6365
- COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w_\-]+)\s+(.*)$/,
6366
- CLASS_DIRECTIVE_REGEXP = /(([\d\w_\-]+)(?:\:([^;]+))?;?)/,
6333
+ COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\w\-]+)\s+(.*)$/,
6334
+ CLASS_DIRECTIVE_REGEXP = /(([\w\-]+)(?:\:([^;]+))?;?)/,
6367
6335
  ALL_OR_NOTHING_ATTRS = makeMap('ngSrc,ngSrcset,src,srcset'),
6368
6336
  REQUIRE_PREFIX_REGEXP = /^(?:(\^\^?)?(\?)?(\^\^?)?)?/;
6369
6337
 
@@ -6373,7 +6341,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6373
6341
  var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
6374
6342
 
6375
6343
  function parseIsolateBindings(scope, directiveName) {
6376
- var LOCAL_REGEXP = /^\s*([@=&])(\??)\s*(\w*)\s*$/;
6344
+ var LOCAL_REGEXP = /^\s*([@&]|=(\*?))(\??)\s*(\w*)\s*$/;
6377
6345
 
6378
6346
  var bindings = {};
6379
6347
 
@@ -6388,9 +6356,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6388
6356
  }
6389
6357
 
6390
6358
  bindings[scopeName] = {
6391
- attrName: match[3] || scopeName,
6392
- mode: match[1],
6393
- optional: match[2] === '?'
6359
+ mode: match[1][0],
6360
+ collection: match[2] === '*',
6361
+ optional: match[3] === '?',
6362
+ attrName: match[4] || scopeName
6394
6363
  };
6395
6364
  });
6396
6365
 
@@ -6536,7 +6505,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6536
6505
  */
6537
6506
  var debugInfoEnabled = true;
6538
6507
  this.debugInfoEnabled = function(enabled) {
6539
- if(isDefined(enabled)) {
6508
+ if (isDefined(enabled)) {
6540
6509
  debugInfoEnabled = enabled;
6541
6510
  return this;
6542
6511
  }
@@ -6580,8 +6549,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6580
6549
  *
6581
6550
  * @param {string} classVal The className value that will be added to the element
6582
6551
  */
6583
- $addClass : function(classVal) {
6584
- if(classVal && classVal.length > 0) {
6552
+ $addClass: function(classVal) {
6553
+ if (classVal && classVal.length > 0) {
6585
6554
  $animate.addClass(this.$$element, classVal);
6586
6555
  }
6587
6556
  },
@@ -6597,8 +6566,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6597
6566
  *
6598
6567
  * @param {string} classVal The className value that will be removed from the element
6599
6568
  */
6600
- $removeClass : function(classVal) {
6601
- if(classVal && classVal.length > 0) {
6569
+ $removeClass: function(classVal) {
6570
+ if (classVal && classVal.length > 0) {
6602
6571
  $animate.removeClass(this.$$element, classVal);
6603
6572
  }
6604
6573
  },
@@ -6615,7 +6584,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6615
6584
  * @param {string} newClasses The current CSS className value
6616
6585
  * @param {string} oldClasses The former CSS className value
6617
6586
  */
6618
- $updateClass : function(newClasses, oldClasses) {
6587
+ $updateClass: function(newClasses, oldClasses) {
6619
6588
  var toAdd = tokenDifference(newClasses, oldClasses);
6620
6589
  if (toAdd && toAdd.length) {
6621
6590
  $animate.addClass(this.$$element, toAdd);
@@ -6645,13 +6614,12 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6645
6614
  booleanKey = getBooleanAttrName(node, key),
6646
6615
  aliasedKey = getAliasedAttrName(node, key),
6647
6616
  observer = key,
6648
- normalizedVal,
6649
6617
  nodeName;
6650
6618
 
6651
6619
  if (booleanKey) {
6652
6620
  this.$$element.prop(key, value);
6653
6621
  attrName = booleanKey;
6654
- } else if(aliasedKey) {
6622
+ } else if (aliasedKey) {
6655
6623
  this[aliasedKey] = value;
6656
6624
  observer = aliasedKey;
6657
6625
  }
@@ -6692,9 +6660,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6692
6660
  for (var i=0; i<nbrUrisWith2parts; i++) {
6693
6661
  var innerIdx = i*2;
6694
6662
  // sanitize the uri
6695
- result += $$sanitizeUri(trim( rawUris[innerIdx]), true);
6663
+ result += $$sanitizeUri(trim(rawUris[innerIdx]), true);
6696
6664
  // add the descriptor
6697
- result += ( " " + trim(rawUris[innerIdx+1]));
6665
+ result += (" " + trim(rawUris[innerIdx+1]));
6698
6666
  }
6699
6667
 
6700
6668
  // split the last item into uri and descriptor
@@ -6704,7 +6672,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6704
6672
  result += $$sanitizeUri(trim(lastTuple[0]), true);
6705
6673
 
6706
6674
  // and add the last descriptor if any
6707
- if( lastTuple.length === 2) {
6675
+ if (lastTuple.length === 2) {
6708
6676
  result += (" " + trim(lastTuple[1]));
6709
6677
  }
6710
6678
  this[key] = value = result;
@@ -6755,7 +6723,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6755
6723
 
6756
6724
  listeners.push(fn);
6757
6725
  $rootScope.$evalAsync(function() {
6758
- if (!listeners.$$inter) {
6726
+ if (!listeners.$$inter && attrs.hasOwnProperty(key)) {
6759
6727
  // no one registered attribute interpolation function, so lets call it manually
6760
6728
  fn(attrs[key]);
6761
6729
  }
@@ -6771,7 +6739,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6771
6739
  function safeAddClass($element, className) {
6772
6740
  try {
6773
6741
  $element.addClass(className);
6774
- } catch(e) {
6742
+ } catch (e) {
6775
6743
  // ignore, since it means that we are trying to set class on
6776
6744
  // SVG element, where class name is read-only.
6777
6745
  }
@@ -6825,7 +6793,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6825
6793
  }
6826
6794
  // We can not compile top level text elements since text nodes can be merged and we will
6827
6795
  // not be able to attach scope data to them, so we will wrap them in <span>
6828
- forEach($compileNodes, function(node, index){
6796
+ forEach($compileNodes, function(node, index) {
6829
6797
  if (node.nodeType == NODE_TYPE_TEXT && node.nodeValue.match(/\S+/) /* non-empty */ ) {
6830
6798
  $compileNodes[index] = jqLite(node).wrap('<span></span>').parent()[0];
6831
6799
  }
@@ -6835,7 +6803,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6835
6803
  maxPriority, ignoreDirective, previousCompileContext);
6836
6804
  compile.$$addScopeClass($compileNodes);
6837
6805
  var namespace = null;
6838
- return function publicLinkFn(scope, cloneConnectFn, transcludeControllers, parentBoundTranscludeFn, futureParentElement){
6806
+ return function publicLinkFn(scope, cloneConnectFn, transcludeControllers, parentBoundTranscludeFn, futureParentElement) {
6839
6807
  assertArg(scope, 'scope');
6840
6808
  if (!namespace) {
6841
6809
  namespace = detectNamespaceForChildElements(futureParentElement);
@@ -6960,7 +6928,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6960
6928
  stableNodeList = nodeList;
6961
6929
  }
6962
6930
 
6963
- for(i = 0, ii = linkFns.length; i < ii;) {
6931
+ for (i = 0, ii = linkFns.length; i < ii;) {
6964
6932
  node = stableNodeList[linkFns[i++]];
6965
6933
  nodeLinkFn = linkFns[i++];
6966
6934
  childLinkFn = linkFns[i++];
@@ -6973,7 +6941,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6973
6941
  childScope = scope;
6974
6942
  }
6975
6943
 
6976
- if ( nodeLinkFn.transcludeOnThisElement ) {
6944
+ if (nodeLinkFn.transcludeOnThisElement) {
6977
6945
  childBoundTranscludeFn = createBoundTranscludeFn(
6978
6946
  scope, nodeLinkFn.transclude, parentBoundTranscludeFn,
6979
6947
  nodeLinkFn.elementTranscludeOnThisElement);
@@ -7028,7 +6996,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7028
6996
  match,
7029
6997
  className;
7030
6998
 
7031
- switch(nodeType) {
6999
+ switch (nodeType) {
7032
7000
  case NODE_TYPE_ELEMENT: /* Element */
7033
7001
  // use the node name: <directive>
7034
7002
  addDirective(directives,
@@ -7120,7 +7088,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7120
7088
  var nodes = [];
7121
7089
  var depth = 0;
7122
7090
  if (attrStart && node.hasAttribute && node.hasAttribute(attrStart)) {
7123
- var startNode = node;
7124
7091
  do {
7125
7092
  if (!node) {
7126
7093
  throw $compileMinErr('uterdir',
@@ -7204,7 +7171,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7204
7171
  directiveValue;
7205
7172
 
7206
7173
  // executes all directives on the current element
7207
- for(var i = 0, ii = directives.length; i < ii; i++) {
7174
+ for (var i = 0, ii = directives.length; i < ii; i++) {
7208
7175
  directive = directives[i];
7209
7176
  var attrStart = directive.$$start;
7210
7177
  var attrEnd = directive.$$end;
@@ -7448,7 +7415,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7448
7415
  "Controller '{0}', required by directive '{1}', can't be found!",
7449
7416
  require, directiveName);
7450
7417
  }
7451
- return value;
7418
+ return value || null;
7452
7419
  } else if (isArray(require)) {
7453
7420
  value = [];
7454
7421
  forEach(require, function(require) {
@@ -7510,8 +7477,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7510
7477
  }
7511
7478
 
7512
7479
  if (newIsolateScopeDirective) {
7513
- var LOCAL_REGEXP = /^\s*([@=&])(\??)\s*(\w*)\s*$/;
7514
-
7515
7480
  compile.$$addScopeInfo($element, isolateScope, true, !(templateDirective && (templateDirective === newIsolateScopeDirective ||
7516
7481
  templateDirective === newIsolateScopeDirective.$$originalDirective)));
7517
7482
  compile.$$addScopeClass($element, true);
@@ -7537,7 +7502,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7537
7502
  isolateBindingContext[scopeName] = value;
7538
7503
  });
7539
7504
  attrs.$$observers[attrName].$$scope = scope;
7540
- if( attrs[attrName] ) {
7505
+ if (attrs[attrName]) {
7541
7506
  // If the attribute has been provided then we trigger an interpolation to ensure
7542
7507
  // the value is there for use in the link fn
7543
7508
  isolateBindingContext[scopeName] = $interpolate(attrs[attrName])(scope);
@@ -7552,7 +7517,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7552
7517
  if (parentGet.literal) {
7553
7518
  compare = equals;
7554
7519
  } else {
7555
- compare = function(a,b) { return a === b || (a !== a && b !== b); };
7520
+ compare = function(a, b) { return a === b || (a !== a && b !== b); };
7556
7521
  }
7557
7522
  parentSet = parentGet.assign || function() {
7558
7523
  // reset the change, or we will throw this exception on every $digest
@@ -7576,7 +7541,12 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7576
7541
  return lastValue = parentValue;
7577
7542
  };
7578
7543
  parentValueWatch.$stateful = true;
7579
- var unwatch = scope.$watch($parse(attrs[attrName], parentValueWatch), null, parentGet.literal);
7544
+ var unwatch;
7545
+ if (definition.collection) {
7546
+ unwatch = scope.$watchCollection(attrs[attrName], parentValueWatch);
7547
+ } else {
7548
+ unwatch = scope.$watch($parse(attrs[attrName], parentValueWatch), null, parentGet.literal);
7549
+ }
7580
7550
  isolateScope.$on('$destroy', unwatch);
7581
7551
  break;
7582
7552
 
@@ -7597,7 +7567,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7597
7567
  }
7598
7568
 
7599
7569
  // PRELINKING
7600
- for(i = 0, ii = preLinkFns.length; i < ii; i++) {
7570
+ for (i = 0, ii = preLinkFns.length; i < ii; i++) {
7601
7571
  linkFn = preLinkFns[i];
7602
7572
  invokeLinkFn(linkFn,
7603
7573
  linkFn.isolateScope ? isolateScope : scope,
@@ -7618,7 +7588,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7618
7588
  childLinkFn && childLinkFn(scopeToChild, linkNode.childNodes, undefined, boundTranscludeFn);
7619
7589
 
7620
7590
  // POSTLINKING
7621
- for(i = postLinkFns.length - 1; i >= 0; i--) {
7591
+ for (i = postLinkFns.length - 1; i >= 0; i--) {
7622
7592
  linkFn = postLinkFns[i];
7623
7593
  invokeLinkFn(linkFn,
7624
7594
  linkFn.isolateScope ? isolateScope : scope,
@@ -7678,11 +7648,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7678
7648
  if (name === ignoreDirective) return null;
7679
7649
  var match = null;
7680
7650
  if (hasDirectives.hasOwnProperty(name)) {
7681
- for(var directive, directives = $injector.get(name + Suffix),
7651
+ for (var directive, directives = $injector.get(name + Suffix),
7682
7652
  i = 0, ii = directives.length; i<ii; i++) {
7683
7653
  try {
7684
7654
  directive = directives[i];
7685
- if ( (maxPriority === undefined || maxPriority > directive.priority) &&
7655
+ if ((maxPriority === undefined || maxPriority > directive.priority) &&
7686
7656
  directive.restrict.indexOf(location) != -1) {
7687
7657
  if (startAttrName) {
7688
7658
  directive = inherit(directive, {$$start: startAttrName, $$end: endAttrName});
@@ -7690,7 +7660,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7690
7660
  tDirectives.push(directive);
7691
7661
  match = directive;
7692
7662
  }
7693
- } catch(e) { $exceptionHandler(e); }
7663
+ } catch (e) { $exceptionHandler(e); }
7694
7664
  }
7695
7665
  }
7696
7666
  return match;
@@ -7707,7 +7677,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7707
7677
  */
7708
7678
  function directiveIsMultiElement(name) {
7709
7679
  if (hasDirectives.hasOwnProperty(name)) {
7710
- for(var directive, directives = $injector.get(name + Suffix),
7680
+ for (var directive, directives = $injector.get(name + Suffix),
7711
7681
  i = 0, ii = directives.length; i<ii; i++) {
7712
7682
  directive = directives[i];
7713
7683
  if (directive.multiElement) {
@@ -7824,7 +7794,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7824
7794
  });
7825
7795
  afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn);
7826
7796
 
7827
- while(linkQueue.length) {
7797
+ while (linkQueue.length) {
7828
7798
  var scope = linkQueue.shift(),
7829
7799
  beforeTemplateLinkNode = linkQueue.shift(),
7830
7800
  linkRootElement = linkQueue.shift(),
@@ -7923,7 +7893,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7923
7893
 
7924
7894
  function wrapTemplate(type, template) {
7925
7895
  type = lowercase(type || 'html');
7926
- switch(type) {
7896
+ switch (type) {
7927
7897
  case 'svg':
7928
7898
  case 'math':
7929
7899
  var wrapper = document.createElement('div');
@@ -8004,7 +7974,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
8004
7974
  //skip animations when the first digest occurs (when
8005
7975
  //both the new and the old values are the same) since
8006
7976
  //the CSS classes are the non-interpolated values
8007
- if(name === 'class' && newValue != oldValue) {
7977
+ if (name === 'class' && newValue != oldValue) {
8008
7978
  attr.$updateClass(newValue, oldValue);
8009
7979
  } else {
8010
7980
  attr.$set(name, newValue);
@@ -8034,7 +8004,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
8034
8004
  i, ii;
8035
8005
 
8036
8006
  if ($rootElement) {
8037
- for(i = 0, ii = $rootElement.length; i < ii; i++) {
8007
+ for (i = 0, ii = $rootElement.length; i < ii; i++) {
8038
8008
  if ($rootElement[i] == firstElementToRemove) {
8039
8009
  $rootElement[i++] = newNode;
8040
8010
  for (var j = i, j2 = j + removeCount - 1,
@@ -8109,14 +8079,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
8109
8079
  function invokeLinkFn(linkFn, scope, $element, attrs, controllers, transcludeFn) {
8110
8080
  try {
8111
8081
  linkFn(scope, $element, attrs, controllers, transcludeFn);
8112
- } catch(e) {
8082
+ } catch (e) {
8113
8083
  $exceptionHandler(e, startingTag($element));
8114
8084
  }
8115
8085
  }
8116
8086
  }];
8117
8087
  }
8118
8088
 
8119
- var PREFIX_REGEXP = /^(x[\:\-_]|data[\:\-_])/i;
8089
+ var PREFIX_REGEXP = /^((?:x|data)[\:\-_])/i;
8120
8090
  /**
8121
8091
  * Converts all accepted directives format into proper directive name.
8122
8092
  * All of these will become 'myDirective':
@@ -8182,7 +8152,7 @@ function nodesetLinkingFn(
8182
8152
  /* NodeList */ nodeList,
8183
8153
  /* Element */ rootElement,
8184
8154
  /* function(Function) */ boundTranscludeFn
8185
- ){}
8155
+ ) {}
8186
8156
 
8187
8157
  function directiveLinkingFn(
8188
8158
  /* nodesetLinkingFn */ nodesetLinkingFn,
@@ -8190,7 +8160,7 @@ function directiveLinkingFn(
8190
8160
  /* Node */ node,
8191
8161
  /* Element */ rootElement,
8192
8162
  /* function(Function) */ boundTranscludeFn
8193
- ){}
8163
+ ) {}
8194
8164
 
8195
8165
  function tokenDifference(str1, str2) {
8196
8166
  var values = '',
@@ -8198,10 +8168,10 @@ function tokenDifference(str1, str2) {
8198
8168
  tokens2 = str2.split(/\s+/);
8199
8169
 
8200
8170
  outer:
8201
- for(var i = 0; i < tokens1.length; i++) {
8171
+ for (var i = 0; i < tokens1.length; i++) {
8202
8172
  var token = tokens1[i];
8203
- for(var j = 0; j < tokens2.length; j++) {
8204
- if(token == tokens2[j]) continue outer;
8173
+ for (var j = 0; j < tokens2.length; j++) {
8174
+ if (token == tokens2[j]) continue outer;
8205
8175
  }
8206
8176
  values += (values.length > 0 ? ' ' : '') + token;
8207
8177
  }
@@ -8307,7 +8277,7 @@ function $ControllerProvider() {
8307
8277
  identifier = ident;
8308
8278
  }
8309
8279
 
8310
- if(isString(expression)) {
8280
+ if (isString(expression)) {
8311
8281
  match = expression.match(CNTRL_REG),
8312
8282
  constructor = match[1],
8313
8283
  identifier = identifier || match[3];
@@ -8393,8 +8363,8 @@ function $ControllerProvider() {
8393
8363
  </file>
8394
8364
  </example>
8395
8365
  */
8396
- function $DocumentProvider(){
8397
- this.$get = ['$window', function(window){
8366
+ function $DocumentProvider() {
8367
+ this.$get = ['$window', function(window) {
8398
8368
  return jqLite(window.document);
8399
8369
  }];
8400
8370
  }
@@ -8415,8 +8385,8 @@ function $DocumentProvider(){
8415
8385
  * ## Example:
8416
8386
  *
8417
8387
  * ```js
8418
- * angular.module('exceptionOverride', []).factory('$exceptionHandler', function () {
8419
- * return function (exception, cause) {
8388
+ * angular.module('exceptionOverride', []).factory('$exceptionHandler', function() {
8389
+ * return function(exception, cause) {
8420
8390
  * exception.message += ' (caused by "' + cause + '")';
8421
8391
  * throw exception;
8422
8392
  * };
@@ -8447,6 +8417,25 @@ function $ExceptionHandlerProvider() {
8447
8417
  }];
8448
8418
  }
8449
8419
 
8420
+ var APPLICATION_JSON = 'application/json';
8421
+ var CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': APPLICATION_JSON + ';charset=utf-8'};
8422
+ var JSON_START = /^\s*(\[|\{[^\{])/;
8423
+ var JSON_END = /[\}\]]\s*$/;
8424
+ var JSON_PROTECTION_PREFIX = /^\)\]\}',?\n/;
8425
+
8426
+ function defaultHttpResponseTransform(data, headers) {
8427
+ if (isString(data)) {
8428
+ // strip json vulnerability protection prefix
8429
+ data = data.replace(JSON_PROTECTION_PREFIX, '');
8430
+ var contentType = headers('Content-Type');
8431
+ if ((contentType && contentType.indexOf(APPLICATION_JSON) === 0) ||
8432
+ (JSON_START.test(data) && JSON_END.test(data))) {
8433
+ data = fromJson(data);
8434
+ }
8435
+ }
8436
+ return data;
8437
+ }
8438
+
8450
8439
  /**
8451
8440
  * Parse headers into key value object
8452
8441
  *
@@ -8533,12 +8522,6 @@ function isSuccess(status) {
8533
8522
  * Use `$httpProvider` to change the default behavior of the {@link ng.$http $http} service.
8534
8523
  * */
8535
8524
  function $HttpProvider() {
8536
- var JSON_START = /^\s*(\[|\{[^\{])/,
8537
- JSON_END = /[\}\]]\s*$/,
8538
- PROTECTION_PREFIX = /^\)\]\}',?\n/,
8539
- APPLICATION_JSON = 'application/json',
8540
- CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': APPLICATION_JSON + ';charset=utf-8'};
8541
-
8542
8525
  /**
8543
8526
  * @ngdoc property
8544
8527
  * @name $httpProvider#defaults
@@ -8562,18 +8545,7 @@ function $HttpProvider() {
8562
8545
  **/
8563
8546
  var defaults = this.defaults = {
8564
8547
  // transform incoming response data
8565
- transformResponse: [function defaultHttpResponseTransform(data, headers) {
8566
- if (isString(data)) {
8567
- // strip json vulnerability protection prefix
8568
- data = data.replace(PROTECTION_PREFIX, '');
8569
- var contentType = headers('Content-Type');
8570
- if ((contentType && contentType.indexOf(APPLICATION_JSON) === 0) ||
8571
- (JSON_START.test(data) && JSON_END.test(data))) {
8572
- data = fromJson(data);
8573
- }
8574
- }
8575
- return data;
8576
- }],
8548
+ transformResponse: [defaultHttpResponseTransform],
8577
8549
 
8578
8550
  // transform outgoing request data
8579
8551
  transformRequest: [function(d) {
@@ -8623,9 +8595,18 @@ function $HttpProvider() {
8623
8595
  };
8624
8596
 
8625
8597
  /**
8626
- * Are ordered by request, i.e. they are applied in the same order as the
8598
+ * @ngdoc property
8599
+ * @name $httpProvider#interceptors
8600
+ * @description
8601
+ *
8602
+ * Array containing service factories for all synchronous or asynchronous {@link ng.$http $http}
8603
+ * pre-processing of request or postprocessing of responses.
8604
+ *
8605
+ * These service factories are ordered by request, i.e. they are applied in the same order as the
8627
8606
  * array, on request, but reverse order, on response.
8628
- */
8607
+ *
8608
+ * {@link ng.$http#interceptors Interceptors detailed info}
8609
+ **/
8629
8610
  var interceptorFactories = this.interceptors = [];
8630
8611
 
8631
8612
  this.$get = ['$httpBackend', '$browser', '$cacheFactory', '$rootScope', '$q', '$injector',
@@ -9192,7 +9173,7 @@ function $HttpProvider() {
9192
9173
  }
9193
9174
  });
9194
9175
 
9195
- while(chain.length) {
9176
+ while (chain.length) {
9196
9177
  var thenFn = chain.shift();
9197
9178
  var rejectFn = chain.shift();
9198
9179
 
@@ -9507,7 +9488,7 @@ function $HttpProvider() {
9507
9488
  status: status,
9508
9489
  headers: headersGetter(headers),
9509
9490
  config: config,
9510
- statusText : statusText
9491
+ statusText: statusText
9511
9492
  });
9512
9493
  }
9513
9494
 
@@ -9528,7 +9509,7 @@ function $HttpProvider() {
9528
9509
 
9529
9510
  forEach(value, function(v) {
9530
9511
  if (isObject(v)) {
9531
- if (isDate(v)){
9512
+ if (isDate(v)) {
9532
9513
  v = v.toISOString();
9533
9514
  } else {
9534
9515
  v = toJson(v);
@@ -9538,7 +9519,7 @@ function $HttpProvider() {
9538
9519
  encodeUriQuery(v));
9539
9520
  });
9540
9521
  });
9541
- if(parts.length > 0) {
9522
+ if (parts.length > 0) {
9542
9523
  url += ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&');
9543
9524
  }
9544
9525
  return url;
@@ -9625,7 +9606,7 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
9625
9606
  statusText);
9626
9607
  };
9627
9608
 
9628
- var requestError = function () {
9609
+ var requestError = function() {
9629
9610
  // The response is always empty
9630
9611
  // See https://xhr.spec.whatwg.org/#request-error-steps and https://fetch.spec.whatwg.org/#concept-network-error
9631
9612
  completeRequest(callback, -1, null, null, '');
@@ -9767,7 +9748,7 @@ function $InterpolateProvider() {
9767
9748
  * @param {string=} value new value to set the starting symbol to.
9768
9749
  * @returns {string|self} Returns the symbol when used as getter and self if used as setter.
9769
9750
  */
9770
- this.startSymbol = function(value){
9751
+ this.startSymbol = function(value) {
9771
9752
  if (value) {
9772
9753
  startSymbol = value;
9773
9754
  return this;
@@ -9785,7 +9766,7 @@ function $InterpolateProvider() {
9785
9766
  * @param {string=} value new value to set the ending symbol to.
9786
9767
  * @returns {string|self} Returns the symbol when used as getter and self if used as setter.
9787
9768
  */
9788
- this.endSymbol = function(value){
9769
+ this.endSymbol = function(value) {
9789
9770
  if (value) {
9790
9771
  endSymbol = value;
9791
9772
  return this;
@@ -9911,9 +9892,9 @@ function $InterpolateProvider() {
9911
9892
  concat = [],
9912
9893
  expressionPositions = [];
9913
9894
 
9914
- while(index < textLength) {
9915
- if ( ((startIndex = text.indexOf(startSymbol, index)) != -1) &&
9916
- ((endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) != -1) ) {
9895
+ while (index < textLength) {
9896
+ if (((startIndex = text.indexOf(startSymbol, index)) != -1) &&
9897
+ ((endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) != -1)) {
9917
9898
  if (index !== startIndex) {
9918
9899
  concat.push(unescapeText(text.substring(index, startIndex)));
9919
9900
  }
@@ -9947,20 +9928,20 @@ function $InterpolateProvider() {
9947
9928
 
9948
9929
  if (!mustHaveExpression || expressions.length) {
9949
9930
  var compute = function(values) {
9950
- for(var i = 0, ii = expressions.length; i < ii; i++) {
9931
+ for (var i = 0, ii = expressions.length; i < ii; i++) {
9951
9932
  if (allOrNothing && isUndefined(values[i])) return;
9952
9933
  concat[expressionPositions[i]] = values[i];
9953
9934
  }
9954
9935
  return concat.join('');
9955
9936
  };
9956
9937
 
9957
- var getValue = function (value) {
9938
+ var getValue = function(value) {
9958
9939
  return trustedContext ?
9959
9940
  $sce.getTrusted(trustedContext, value) :
9960
9941
  $sce.valueOf(value);
9961
9942
  };
9962
9943
 
9963
- var stringify = function (value) {
9944
+ var stringify = function(value) {
9964
9945
  if (value == null) { // null || undefined
9965
9946
  return '';
9966
9947
  }
@@ -9988,7 +9969,7 @@ function $InterpolateProvider() {
9988
9969
  }
9989
9970
 
9990
9971
  return compute(values);
9991
- } catch(err) {
9972
+ } catch (err) {
9992
9973
  var newErr = $interpolateMinErr('interr', "Can't interpolate: {0}\n{1}", text,
9993
9974
  err.toString());
9994
9975
  $exceptionHandler(newErr);
@@ -9998,7 +9979,7 @@ function $InterpolateProvider() {
9998
9979
  // all of these properties are undocumented for now
9999
9980
  exp: text, //just for compatibility with regular watchers created via $watch
10000
9981
  expressions: expressions,
10001
- $$watchDelegate: function (scope, listener, objectEquality) {
9982
+ $$watchDelegate: function(scope, listener, objectEquality) {
10002
9983
  var lastValue;
10003
9984
  return scope.$watchGroup(parseFns, function interpolateFnWatcher(values, oldValues) {
10004
9985
  var currValue = compute(values);
@@ -10019,7 +10000,7 @@ function $InterpolateProvider() {
10019
10000
  function parseStringifyInterceptor(value) {
10020
10001
  try {
10021
10002
  return stringify(getValue(value));
10022
- } catch(err) {
10003
+ } catch (err) {
10023
10004
  var newErr = $interpolateMinErr('interr', "Can't interpolate: {0}\n{1}", text,
10024
10005
  err.toString());
10025
10006
  $exceptionHandler(newErr);
@@ -10258,7 +10239,7 @@ function $IntervalProvider() {
10258
10239
  *
10259
10240
  * * `id` – `{string}` – locale id formatted as `languageId-countryId` (e.g. `en-us`)
10260
10241
  */
10261
- function $LocaleProvider(){
10242
+ function $LocaleProvider() {
10262
10243
  this.$get = function() {
10263
10244
  return {
10264
10245
  id: 'en-us',
@@ -10301,7 +10282,7 @@ function $LocaleProvider(){
10301
10282
  SHORTDAY: 'Sun,Mon,Tue,Wed,Thu,Fri,Sat'.split(','),
10302
10283
  AMPMS: ['AM','PM'],
10303
10284
  medium: 'MMM d, y h:mm:ss a',
10304
- short: 'M/d/yy h:mm a',
10285
+ 'short': 'M/d/yy h:mm a',
10305
10286
  fullDate: 'EEEE, MMMM d, y',
10306
10287
  longDate: 'MMMM d, y',
10307
10288
  mediumDate: 'MMM d, y',
@@ -10416,7 +10397,7 @@ function LocationHtml5Url(appBase, basePrefix) {
10416
10397
 
10417
10398
  /**
10418
10399
  * Parse given html5 (regular) url string into properties
10419
- * @param {string} newAbsoluteUrl HTML5 url
10400
+ * @param {string} url HTML5 url
10420
10401
  * @private
10421
10402
  */
10422
10403
  this.$$parse = function(url) {
@@ -10457,14 +10438,14 @@ function LocationHtml5Url(appBase, basePrefix) {
10457
10438
  var appUrl, prevAppUrl;
10458
10439
  var rewrittenUrl;
10459
10440
 
10460
- if ( (appUrl = beginsWith(appBase, url)) !== undefined ) {
10441
+ if ((appUrl = beginsWith(appBase, url)) !== undefined) {
10461
10442
  prevAppUrl = appUrl;
10462
- if ( (appUrl = beginsWith(basePrefix, appUrl)) !== undefined ) {
10443
+ if ((appUrl = beginsWith(basePrefix, appUrl)) !== undefined) {
10463
10444
  rewrittenUrl = appBaseNoFile + (beginsWith('/', appUrl) || appUrl);
10464
10445
  } else {
10465
10446
  rewrittenUrl = appBase + prevAppUrl;
10466
10447
  }
10467
- } else if ( (appUrl = beginsWith(appBaseNoFile, url)) !== undefined ) {
10448
+ } else if ((appUrl = beginsWith(appBaseNoFile, url)) !== undefined) {
10468
10449
  rewrittenUrl = appBaseNoFile + appUrl;
10469
10450
  } else if (appBaseNoFile == url + '/') {
10470
10451
  rewrittenUrl = appBaseNoFile;
@@ -10526,7 +10507,7 @@ function LocationHashbangUrl(appBase, hashPrefix) {
10526
10507
  * Inside of Angular, we're always using pathnames that
10527
10508
  * do not include drive names for routing.
10528
10509
  */
10529
- function removeWindowsDriveName (path, url, base) {
10510
+ function removeWindowsDriveName(path, url, base) {
10530
10511
  /*
10531
10512
  Matches paths for file protocol on windows,
10532
10513
  such as /C:/foo/bar, and captures only /foo/bar.
@@ -10563,7 +10544,7 @@ function LocationHashbangUrl(appBase, hashPrefix) {
10563
10544
  };
10564
10545
 
10565
10546
  this.$$parseLinkUrl = function(url, relHref) {
10566
- if(stripHash(appBase) == stripHash(url)) {
10547
+ if (stripHash(appBase) == stripHash(url)) {
10567
10548
  this.$$parse(url);
10568
10549
  return true;
10569
10550
  }
@@ -10598,11 +10579,11 @@ function LocationHashbangInHtml5Url(appBase, hashPrefix) {
10598
10579
  var rewrittenUrl;
10599
10580
  var appUrl;
10600
10581
 
10601
- if ( appBase == stripHash(url) ) {
10582
+ if (appBase == stripHash(url)) {
10602
10583
  rewrittenUrl = url;
10603
- } else if ( (appUrl = beginsWith(appBaseNoFile, url)) ) {
10584
+ } else if ((appUrl = beginsWith(appBaseNoFile, url))) {
10604
10585
  rewrittenUrl = appBase + hashPrefix + appUrl;
10605
- } else if ( appBaseNoFile === url + '/') {
10586
+ } else if (appBaseNoFile === url + '/') {
10606
10587
  rewrittenUrl = appBaseNoFile;
10607
10588
  }
10608
10589
  if (rewrittenUrl) {
@@ -10849,7 +10830,7 @@ var locationPrototype = {
10849
10830
  }
10850
10831
  };
10851
10832
 
10852
- forEach([LocationHashbangInHtml5Url, LocationHashbangUrl, LocationHtml5Url], function (Location) {
10833
+ forEach([LocationHashbangInHtml5Url, LocationHashbangUrl, LocationHtml5Url], function(Location) {
10853
10834
  Location.prototype = Object.create(locationPrototype);
10854
10835
 
10855
10836
  /**
@@ -10941,7 +10922,7 @@ function locationGetterSetter(property, preprocess) {
10941
10922
  * @description
10942
10923
  * Use the `$locationProvider` to configure how the application deep linking paths are stored.
10943
10924
  */
10944
- function $LocationProvider(){
10925
+ function $LocationProvider() {
10945
10926
  var hashPrefix = '',
10946
10927
  html5Mode = {
10947
10928
  enabled: false,
@@ -11048,7 +11029,7 @@ function $LocationProvider(){
11048
11029
  */
11049
11030
 
11050
11031
  this.$get = ['$rootScope', '$browser', '$sniffer', '$rootElement',
11051
- function( $rootScope, $browser, $sniffer, $rootElement) {
11032
+ function($rootScope, $browser, $sniffer, $rootElement) {
11052
11033
  var $location,
11053
11034
  LocationMode,
11054
11035
  baseHref = $browser.baseHref(), // if base[href] is undefined, it defaults to ''
@@ -11249,7 +11230,7 @@ function $LocationProvider(){
11249
11230
  * @description
11250
11231
  * Use the `$logProvider` to configure how the application logs messages
11251
11232
  */
11252
- function $LogProvider(){
11233
+ function $LogProvider() {
11253
11234
  var debug = true,
11254
11235
  self = this;
11255
11236
 
@@ -11269,7 +11250,7 @@ function $LogProvider(){
11269
11250
  }
11270
11251
  };
11271
11252
 
11272
- this.$get = ['$window', function($window){
11253
+ this.$get = ['$window', function($window) {
11273
11254
  return {
11274
11255
  /**
11275
11256
  * @ngdoc method
@@ -11314,7 +11295,7 @@ function $LogProvider(){
11314
11295
  * @description
11315
11296
  * Write a debug message
11316
11297
  */
11317
- debug: (function () {
11298
+ debug: (function() {
11318
11299
  var fn = consoleLog('debug');
11319
11300
 
11320
11301
  return function() {
@@ -11467,7 +11448,7 @@ CONSTANTS['this'].sharedGetter = true;
11467
11448
 
11468
11449
  //Operators - will be wrapped by binaryFn/unaryFn/assignment/filter
11469
11450
  var OPERATORS = extend(createMap(), {
11470
- '+':function(self, locals, a,b){
11451
+ '+':function(self, locals, a, b) {
11471
11452
  a=a(self, locals); b=b(self, locals);
11472
11453
  if (isDefined(a)) {
11473
11454
  if (isDefined(b)) {
@@ -11476,24 +11457,24 @@ var OPERATORS = extend(createMap(), {
11476
11457
  return a;
11477
11458
  }
11478
11459
  return isDefined(b)?b:undefined;},
11479
- '-':function(self, locals, a,b){
11460
+ '-':function(self, locals, a, b) {
11480
11461
  a=a(self, locals); b=b(self, locals);
11481
11462
  return (isDefined(a)?a:0)-(isDefined(b)?b:0);
11482
11463
  },
11483
- '*':function(self, locals, a,b){return a(self, locals)*b(self, locals);},
11484
- '/':function(self, locals, a,b){return a(self, locals)/b(self, locals);},
11485
- '%':function(self, locals, a,b){return a(self, locals)%b(self, locals);},
11486
- '===':function(self, locals, a, b){return a(self, locals)===b(self, locals);},
11487
- '!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);},
11488
- '==':function(self, locals, a,b){return a(self, locals)==b(self, locals);},
11489
- '!=':function(self, locals, a,b){return a(self, locals)!=b(self, locals);},
11490
- '<':function(self, locals, a,b){return a(self, locals)<b(self, locals);},
11491
- '>':function(self, locals, a,b){return a(self, locals)>b(self, locals);},
11492
- '<=':function(self, locals, a,b){return a(self, locals)<=b(self, locals);},
11493
- '>=':function(self, locals, a,b){return a(self, locals)>=b(self, locals);},
11494
- '&&':function(self, locals, a,b){return a(self, locals)&&b(self, locals);},
11495
- '||':function(self, locals, a,b){return a(self, locals)||b(self, locals);},
11496
- '!':function(self, locals, a){return !a(self, locals);},
11464
+ '*':function(self, locals, a, b) {return a(self, locals)*b(self, locals);},
11465
+ '/':function(self, locals, a, b) {return a(self, locals)/b(self, locals);},
11466
+ '%':function(self, locals, a, b) {return a(self, locals)%b(self, locals);},
11467
+ '===':function(self, locals, a, b) {return a(self, locals)===b(self, locals);},
11468
+ '!==':function(self, locals, a, b) {return a(self, locals)!==b(self, locals);},
11469
+ '==':function(self, locals, a, b) {return a(self, locals)==b(self, locals);},
11470
+ '!=':function(self, locals, a, b) {return a(self, locals)!=b(self, locals);},
11471
+ '<':function(self, locals, a, b) {return a(self, locals)<b(self, locals);},
11472
+ '>':function(self, locals, a, b) {return a(self, locals)>b(self, locals);},
11473
+ '<=':function(self, locals, a, b) {return a(self, locals)<=b(self, locals);},
11474
+ '>=':function(self, locals, a, b) {return a(self, locals)>=b(self, locals);},
11475
+ '&&':function(self, locals, a, b) {return a(self, locals)&&b(self, locals);},
11476
+ '||':function(self, locals, a, b) {return a(self, locals)||b(self, locals);},
11477
+ '!':function(self, locals, a) {return !a(self, locals);},
11497
11478
 
11498
11479
  //Tokenized as operators but parsed as assignment/filters
11499
11480
  '=':true,
@@ -11508,14 +11489,14 @@ var ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'
11508
11489
  /**
11509
11490
  * @constructor
11510
11491
  */
11511
- var Lexer = function (options) {
11492
+ var Lexer = function(options) {
11512
11493
  this.options = options;
11513
11494
  };
11514
11495
 
11515
11496
  Lexer.prototype = {
11516
11497
  constructor: Lexer,
11517
11498
 
11518
- lex: function (text) {
11499
+ lex: function(text) {
11519
11500
  this.text = text;
11520
11501
  this.index = 0;
11521
11502
  this.ch = undefined;
@@ -11752,13 +11733,13 @@ function isConstant(exp) {
11752
11733
  /**
11753
11734
  * @constructor
11754
11735
  */
11755
- var Parser = function (lexer, $filter, options) {
11736
+ var Parser = function(lexer, $filter, options) {
11756
11737
  this.lexer = lexer;
11757
11738
  this.$filter = $filter;
11758
11739
  this.options = options;
11759
11740
  };
11760
11741
 
11761
- Parser.ZERO = extend(function () {
11742
+ Parser.ZERO = extend(function() {
11762
11743
  return 0;
11763
11744
  }, {
11764
11745
  sharedGetter: true,
@@ -11768,7 +11749,7 @@ Parser.ZERO = extend(function () {
11768
11749
  Parser.prototype = {
11769
11750
  constructor: Parser,
11770
11751
 
11771
- parse: function (text) {
11752
+ parse: function(text) {
11772
11753
  this.text = text;
11773
11754
  this.tokens = this.lexer.lex(text);
11774
11755
 
@@ -11784,7 +11765,7 @@ Parser.prototype = {
11784
11765
  return value;
11785
11766
  },
11786
11767
 
11787
- primary: function () {
11768
+ primary: function() {
11788
11769
  var primary;
11789
11770
  if (this.expect('(')) {
11790
11771
  primary = this.filterChain();
@@ -11847,7 +11828,7 @@ Parser.prototype = {
11847
11828
  return false;
11848
11829
  },
11849
11830
 
11850
- expect: function(e1, e2, e3, e4){
11831
+ expect: function(e1, e2, e3, e4) {
11851
11832
  var token = this.peek(e1, e2, e3, e4);
11852
11833
  if (token) {
11853
11834
  this.tokens.shift();
@@ -11856,7 +11837,7 @@ Parser.prototype = {
11856
11837
  return false;
11857
11838
  },
11858
11839
 
11859
- consume: function(e1){
11840
+ consume: function(e1) {
11860
11841
  if (!this.expect(e1)) {
11861
11842
  this.throwError('is unexpected, expecting [' + e1 + ']', this.peek());
11862
11843
  }
@@ -11978,7 +11959,7 @@ Parser.prototype = {
11978
11959
  if ((token = this.expect(':'))) {
11979
11960
  var right = this.assignment();
11980
11961
 
11981
- return extend(function $parseTernary(self, locals){
11962
+ return extend(function $parseTernary(self, locals) {
11982
11963
  return left(self, locals) ? middle(self, locals) : right(self, locals);
11983
11964
  }, {
11984
11965
  constant: left.constant && middle.constant && right.constant
@@ -12138,7 +12119,7 @@ Parser.prototype = {
12138
12119
  },
12139
12120
 
12140
12121
  // This is used with json array declaration
12141
- arrayDeclaration: function () {
12122
+ arrayDeclaration: function() {
12142
12123
  var elementFns = [];
12143
12124
  if (this.peekToken().text !== ']') {
12144
12125
  do {
@@ -12165,7 +12146,7 @@ Parser.prototype = {
12165
12146
  });
12166
12147
  },
12167
12148
 
12168
- object: function () {
12149
+ object: function() {
12169
12150
  var keys = [], valueFns = [];
12170
12151
  if (this.peekToken().text !== '}') {
12171
12152
  do {
@@ -12314,6 +12295,12 @@ function getterFn(path, options, fullExp) {
12314
12295
  return fn;
12315
12296
  }
12316
12297
 
12298
+ var objectValueOf = Object.prototype.valueOf;
12299
+
12300
+ function getValueOf(value) {
12301
+ return isFunction(value.valueOf) ? value.valueOf() : objectValueOf.call(value);
12302
+ }
12303
+
12317
12304
  ///////////////////////////////////
12318
12305
 
12319
12306
  /**
@@ -12460,7 +12447,7 @@ function $ParseProvider() {
12460
12447
  // attempt to convert the value to a primitive type
12461
12448
  // TODO(docs): add a note to docs that by implementing valueOf even objects and arrays can
12462
12449
  // be cheaply dirty-checked
12463
- newValue = newValue.valueOf();
12450
+ newValue = getValueOf(newValue);
12464
12451
 
12465
12452
  if (typeof newValue === 'object') {
12466
12453
  // objects/arrays are not supported - deep-watching them would be too expensive
@@ -12487,7 +12474,7 @@ function $ParseProvider() {
12487
12474
  var newInputValue = inputExpressions(scope);
12488
12475
  if (!expressionInputDirtyCheck(newInputValue, oldInputValue)) {
12489
12476
  lastResult = parsedExpression(scope);
12490
- oldInputValue = newInputValue && newInputValue.valueOf();
12477
+ oldInputValue = newInputValue && getValueOf(newInputValue);
12491
12478
  }
12492
12479
  return lastResult;
12493
12480
  }, listener, objectEquality);
@@ -12504,7 +12491,7 @@ function $ParseProvider() {
12504
12491
  for (var i = 0, ii = inputExpressions.length; i < ii; i++) {
12505
12492
  var newInputValue = inputExpressions[i](scope);
12506
12493
  if (changed || (changed = !expressionInputDirtyCheck(newInputValue, oldInputValueOfValues[i]))) {
12507
- oldInputValueOfValues[i] = newInputValue && newInputValue.valueOf();
12494
+ oldInputValueOfValues[i] = newInputValue && getValueOf(newInputValue);
12508
12495
  }
12509
12496
  }
12510
12497
 
@@ -12526,7 +12513,7 @@ function $ParseProvider() {
12526
12513
  listener.apply(this, arguments);
12527
12514
  }
12528
12515
  if (isDefined(value)) {
12529
- scope.$$postDigest(function () {
12516
+ scope.$$postDigest(function() {
12530
12517
  if (isDefined(lastValue)) {
12531
12518
  unwatch();
12532
12519
  }
@@ -12545,15 +12532,15 @@ function $ParseProvider() {
12545
12532
  listener.call(this, value, old, scope);
12546
12533
  }
12547
12534
  if (isAllDefined(value)) {
12548
- scope.$$postDigest(function () {
12549
- if(isAllDefined(lastValue)) unwatch();
12535
+ scope.$$postDigest(function() {
12536
+ if (isAllDefined(lastValue)) unwatch();
12550
12537
  });
12551
12538
  }
12552
12539
  }, objectEquality);
12553
12540
 
12554
12541
  function isAllDefined(value) {
12555
12542
  var allDefined = true;
12556
- forEach(value, function (val) {
12543
+ forEach(value, function(val) {
12557
12544
  if (!isDefined(val)) allDefined = false;
12558
12545
  });
12559
12546
  return allDefined;
@@ -12917,7 +12904,7 @@ function qFactory(nextTick, exceptionHandler) {
12917
12904
  } else {
12918
12905
  promise.reject(state.value);
12919
12906
  }
12920
- } catch(e) {
12907
+ } catch (e) {
12921
12908
  promise.reject(e);
12922
12909
  exceptionHandler(e);
12923
12910
  }
@@ -12967,7 +12954,7 @@ function qFactory(nextTick, exceptionHandler) {
12967
12954
  this.promise.$$state.status = 1;
12968
12955
  scheduleProcessQueue(this.promise.$$state);
12969
12956
  }
12970
- } catch(e) {
12957
+ } catch (e) {
12971
12958
  fns[1](e);
12972
12959
  exceptionHandler(e);
12973
12960
  }
@@ -12995,7 +12982,7 @@ function qFactory(nextTick, exceptionHandler) {
12995
12982
  callback = callbacks[i][3];
12996
12983
  try {
12997
12984
  result.notify(isFunction(callback) ? callback(progress) : progress);
12998
- } catch(e) {
12985
+ } catch (e) {
12999
12986
  exceptionHandler(e);
13000
12987
  }
13001
12988
  }
@@ -13060,7 +13047,7 @@ function qFactory(nextTick, exceptionHandler) {
13060
13047
  var callbackOutput = null;
13061
13048
  try {
13062
13049
  if (isFunction(callback)) callbackOutput = callback();
13063
- } catch(e) {
13050
+ } catch (e) {
13064
13051
  return makePromise(e, false);
13065
13052
  }
13066
13053
  if (isPromiseLike(callbackOutput)) {
@@ -13168,7 +13155,7 @@ function qFactory(nextTick, exceptionHandler) {
13168
13155
  return $Q;
13169
13156
  }
13170
13157
 
13171
- function $$RAFProvider(){ //rAF
13158
+ function $$RAFProvider() { //rAF
13172
13159
  this.$get = ['$window', '$timeout', function($window, $timeout) {
13173
13160
  var requestAnimationFrame = $window.requestAnimationFrame ||
13174
13161
  $window.webkitRequestAnimationFrame ||
@@ -13267,7 +13254,7 @@ function $$RAFProvider(){ //rAF
13267
13254
  * They also provide an event emission/broadcast and subscription facility. See the
13268
13255
  * {@link guide/scope developer guide on scopes}.
13269
13256
  */
13270
- function $RootScopeProvider(){
13257
+ function $RootScopeProvider() {
13271
13258
  var TTL = 10;
13272
13259
  var $rootScopeMinErr = minErr('$rootScope');
13273
13260
  var lastDirtyWatch = null;
@@ -13281,7 +13268,7 @@ function $RootScopeProvider(){
13281
13268
  };
13282
13269
 
13283
13270
  this.$get = ['$injector', '$exceptionHandler', '$parse', '$browser',
13284
- function( $injector, $exceptionHandler, $parse, $browser) {
13271
+ function($injector, $exceptionHandler, $parse, $browser) {
13285
13272
 
13286
13273
  /**
13287
13274
  * @ngdoc type
@@ -13624,7 +13611,7 @@ function $RootScopeProvider(){
13624
13611
  if (!watchExpressions.length) {
13625
13612
  // No expressions means we call the listener ASAP
13626
13613
  var shouldCall = true;
13627
- self.$evalAsync(function () {
13614
+ self.$evalAsync(function() {
13628
13615
  if (shouldCall) listener(newValues, newValues, self);
13629
13616
  });
13630
13617
  return function deregisterWatchGroup() {
@@ -13641,7 +13628,7 @@ function $RootScopeProvider(){
13641
13628
  });
13642
13629
  }
13643
13630
 
13644
- forEach(watchExpressions, function (expr, i) {
13631
+ forEach(watchExpressions, function(expr, i) {
13645
13632
  var unwatchFn = self.$watch(expr, function watchGroupSubAction(value, oldValue) {
13646
13633
  newValues[i] = value;
13647
13634
  oldValues[i] = oldValue;
@@ -13813,7 +13800,7 @@ function $RootScopeProvider(){
13813
13800
  if (oldLength > newLength) {
13814
13801
  // we used to have more keys, need to find them and destroy them.
13815
13802
  changeDetected++;
13816
- for(key in oldValue) {
13803
+ for (key in oldValue) {
13817
13804
  if (!newValue.hasOwnProperty(key)) {
13818
13805
  oldLength--;
13819
13806
  delete oldValue[key];
@@ -13933,7 +13920,7 @@ function $RootScopeProvider(){
13933
13920
  dirty = false;
13934
13921
  current = target;
13935
13922
 
13936
- while(asyncQueue.length) {
13923
+ while (asyncQueue.length) {
13937
13924
  try {
13938
13925
  asyncTask = asyncQueue.shift();
13939
13926
  asyncTask.scope.$eval(asyncTask.expression);
@@ -13990,7 +13977,7 @@ function $RootScopeProvider(){
13990
13977
  // this piece should be kept in sync with the traversal in $broadcast
13991
13978
  if (!(next = (current.$$childHead ||
13992
13979
  (current !== target && current.$$nextSibling)))) {
13993
- while(current !== target && !(next = current.$$nextSibling)) {
13980
+ while (current !== target && !(next = current.$$nextSibling)) {
13994
13981
  current = current.$parent;
13995
13982
  }
13996
13983
  }
@@ -13998,7 +13985,7 @@ function $RootScopeProvider(){
13998
13985
 
13999
13986
  // `break traverseScopesLoop;` takes us to here
14000
13987
 
14001
- if((dirty || asyncQueue.length) && !(ttl--)) {
13988
+ if ((dirty || asyncQueue.length) && !(ttl--)) {
14002
13989
  clearPhase();
14003
13990
  throw $rootScopeMinErr('infdig',
14004
13991
  '{0} $digest() iterations reached. Aborting!\n' +
@@ -14010,7 +13997,7 @@ function $RootScopeProvider(){
14010
13997
 
14011
13998
  clearPhase();
14012
13999
 
14013
- while(postDigestQueue.length) {
14000
+ while (postDigestQueue.length) {
14014
14001
  try {
14015
14002
  postDigestQueue.shift()();
14016
14003
  } catch (e) {
@@ -14166,7 +14153,7 @@ function $RootScopeProvider(){
14166
14153
  asyncQueue.push({scope: this, expression: expr});
14167
14154
  },
14168
14155
 
14169
- $$postDigest : function(fn) {
14156
+ $$postDigest: function(fn) {
14170
14157
  postDigestQueue.push(fn);
14171
14158
  },
14172
14159
 
@@ -14303,8 +14290,11 @@ function $RootScopeProvider(){
14303
14290
 
14304
14291
  var self = this;
14305
14292
  return function() {
14306
- namedListeners[namedListeners.indexOf(listener)] = null;
14307
- decrementListenerCount(self, 1, name);
14293
+ var indexOfListener = namedListeners.indexOf(listener);
14294
+ if (indexOfListener !== -1) {
14295
+ namedListeners[indexOfListener] = null;
14296
+ decrementListenerCount(self, 1, name);
14297
+ }
14308
14298
  };
14309
14299
  },
14310
14300
 
@@ -14436,7 +14426,7 @@ function $RootScopeProvider(){
14436
14426
 
14437
14427
  try {
14438
14428
  listeners[i].apply(null, listenerArgs);
14439
- } catch(e) {
14429
+ } catch (e) {
14440
14430
  $exceptionHandler(e);
14441
14431
  }
14442
14432
  }
@@ -14447,7 +14437,7 @@ function $RootScopeProvider(){
14447
14437
  // (though it differs due to having the extra check for $$listenerCount)
14448
14438
  if (!(next = ((current.$$listenerCount[name] && current.$$childHead) ||
14449
14439
  (current !== target && current.$$nextSibling)))) {
14450
- while(current !== target && !(next = current.$$nextSibling)) {
14440
+ while (current !== target && !(next = current.$$nextSibling)) {
14451
14441
  current = current.$parent;
14452
14442
  }
14453
14443
  }
@@ -14501,7 +14491,7 @@ function $RootScopeProvider(){
14501
14491
  while (applyAsyncQueue.length) {
14502
14492
  try {
14503
14493
  applyAsyncQueue.shift()();
14504
- } catch(e) {
14494
+ } catch (e) {
14505
14495
  $exceptionHandler(e);
14506
14496
  }
14507
14497
  }
@@ -14602,15 +14592,6 @@ var SCE_CONTEXTS = {
14602
14592
 
14603
14593
  // Helper functions follow.
14604
14594
 
14605
- // Copied from:
14606
- // http://docs.closure-library.googlecode.com/git/closure_goog_string_string.js.source.html#line962
14607
- // Prereq: s is a string.
14608
- function escapeForRegexp(s) {
14609
- return s.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1').
14610
- replace(/\x08/g, '\\x08');
14611
- }
14612
-
14613
-
14614
14595
  function adjustMatcher(matcher) {
14615
14596
  if (matcher === 'self') {
14616
14597
  return matcher;
@@ -14746,7 +14727,7 @@ function $SceDelegateProvider() {
14746
14727
  * @description
14747
14728
  * Sets/Gets the whitelist of trusted resource URLs.
14748
14729
  */
14749
- this.resourceUrlWhitelist = function (value) {
14730
+ this.resourceUrlWhitelist = function(value) {
14750
14731
  if (arguments.length) {
14751
14732
  resourceUrlWhitelist = adjustMatchers(value);
14752
14733
  }
@@ -14780,7 +14761,7 @@ function $SceDelegateProvider() {
14780
14761
  * Sets/Gets the blacklist of trusted resource URLs.
14781
14762
  */
14782
14763
 
14783
- this.resourceUrlBlacklist = function (value) {
14764
+ this.resourceUrlBlacklist = function(value) {
14784
14765
  if (arguments.length) {
14785
14766
  resourceUrlBlacklist = adjustMatchers(value);
14786
14767
  }
@@ -15261,7 +15242,7 @@ function $SceProvider() {
15261
15242
  * @description
15262
15243
  * Enables/disables SCE and returns the current value.
15263
15244
  */
15264
- this.enabled = function (value) {
15245
+ this.enabled = function(value) {
15265
15246
  if (arguments.length) {
15266
15247
  enabled = !!value;
15267
15248
  }
@@ -15315,11 +15296,11 @@ function $SceProvider() {
15315
15296
  * sce.js and sceSpecs.js would need to be aware of this detail.
15316
15297
  */
15317
15298
 
15318
- this.$get = ['$document', '$parse', '$sceDelegate', function(
15319
- $document, $parse, $sceDelegate) {
15299
+ this.$get = ['$parse', '$sceDelegate', function(
15300
+ $parse, $sceDelegate) {
15320
15301
  // Prereq: Ensure that we're not running in IE<11 quirks mode. In that mode, IE < 11 allow
15321
15302
  // the "expression(javascript expression)" syntax which is insecure.
15322
- if (enabled && $document[0].documentMode < 8) {
15303
+ if (enabled && msie < 8) {
15323
15304
  throw $sceMinErr('iequirks',
15324
15305
  'Strict Contextual Escaping does not support Internet Explorer version < 11 in quirks ' +
15325
15306
  'mode. You can fix this by adding the text <!doctype html> to the top of your HTML ' +
@@ -15339,7 +15320,7 @@ function $SceProvider() {
15339
15320
  * @description
15340
15321
  * Returns a boolean indicating if SCE is enabled.
15341
15322
  */
15342
- sce.isEnabled = function () {
15323
+ sce.isEnabled = function() {
15343
15324
  return enabled;
15344
15325
  };
15345
15326
  sce.trustAs = $sceDelegate.trustAs;
@@ -15375,7 +15356,7 @@ function $SceProvider() {
15375
15356
  if (parsed.literal && parsed.constant) {
15376
15357
  return parsed;
15377
15358
  } else {
15378
- return $parse(expr, function (value) {
15359
+ return $parse(expr, function(value) {
15379
15360
  return sce.getTrusted(type, value);
15380
15361
  });
15381
15362
  }
@@ -15628,15 +15609,15 @@ function $SceProvider() {
15628
15609
  getTrusted = sce.getTrusted,
15629
15610
  trustAs = sce.trustAs;
15630
15611
 
15631
- forEach(SCE_CONTEXTS, function (enumValue, name) {
15612
+ forEach(SCE_CONTEXTS, function(enumValue, name) {
15632
15613
  var lName = lowercase(name);
15633
- sce[camelCase("parse_as_" + lName)] = function (expr) {
15614
+ sce[camelCase("parse_as_" + lName)] = function(expr) {
15634
15615
  return parse(enumValue, expr);
15635
15616
  };
15636
- sce[camelCase("get_trusted_" + lName)] = function (value) {
15617
+ sce[camelCase("get_trusted_" + lName)] = function(value) {
15637
15618
  return getTrusted(enumValue, value);
15638
15619
  };
15639
- sce[camelCase("trust_as_" + lName)] = function (value) {
15620
+ sce[camelCase("trust_as_" + lName)] = function(value) {
15640
15621
  return trustAs(enumValue, value);
15641
15622
  };
15642
15623
  });
@@ -15667,22 +15648,22 @@ function $SnifferProvider() {
15667
15648
  boxee = /Boxee/i.test(($window.navigator || {}).userAgent),
15668
15649
  document = $document[0] || {},
15669
15650
  vendorPrefix,
15670
- vendorRegex = /^(Moz|webkit|O|ms)(?=[A-Z])/,
15651
+ vendorRegex = /^(Moz|webkit|ms)(?=[A-Z])/,
15671
15652
  bodyStyle = document.body && document.body.style,
15672
15653
  transitions = false,
15673
15654
  animations = false,
15674
15655
  match;
15675
15656
 
15676
15657
  if (bodyStyle) {
15677
- for(var prop in bodyStyle) {
15678
- if(match = vendorRegex.exec(prop)) {
15658
+ for (var prop in bodyStyle) {
15659
+ if (match = vendorRegex.exec(prop)) {
15679
15660
  vendorPrefix = match[0];
15680
15661
  vendorPrefix = vendorPrefix.substr(0, 1).toUpperCase() + vendorPrefix.substr(1);
15681
15662
  break;
15682
15663
  }
15683
15664
  }
15684
15665
 
15685
- if(!vendorPrefix) {
15666
+ if (!vendorPrefix) {
15686
15667
  vendorPrefix = ('WebkitOpacity' in bodyStyle) && 'webkit';
15687
15668
  }
15688
15669
 
@@ -15723,8 +15704,8 @@ function $SnifferProvider() {
15723
15704
  },
15724
15705
  csp: csp(),
15725
15706
  vendorPrefix: vendorPrefix,
15726
- transitions : transitions,
15727
- animations : animations,
15707
+ transitions: transitions,
15708
+ animations: animations,
15728
15709
  android: android
15729
15710
  };
15730
15711
  }];
@@ -15755,13 +15736,29 @@ function $TemplateRequestProvider() {
15755
15736
  var self = handleRequestFn;
15756
15737
  self.totalPendingRequests++;
15757
15738
 
15758
- return $http.get(tpl, { cache : $templateCache })
15759
- .then(function(response) {
15760
- var html = response.data;
15761
- if(!html || html.length === 0) {
15762
- return handleError();
15739
+ var transformResponse = $http.defaults && $http.defaults.transformResponse;
15740
+
15741
+ if (isArray(transformResponse)) {
15742
+ var original = transformResponse;
15743
+ transformResponse = [];
15744
+ for (var i=0; i<original.length; ++i) {
15745
+ var transformer = original[i];
15746
+ if (transformer !== defaultHttpResponseTransform) {
15747
+ transformResponse.push(transformer);
15763
15748
  }
15749
+ }
15750
+ } else if (transformResponse === defaultHttpResponseTransform) {
15751
+ transformResponse = null;
15752
+ }
15753
+
15754
+ var httpOptions = {
15755
+ cache: $templateCache,
15756
+ transformResponse: transformResponse
15757
+ };
15764
15758
 
15759
+ return $http.get(tpl, httpOptions)
15760
+ .then(function(response) {
15761
+ var html = response.data;
15765
15762
  self.totalPendingRequests--;
15766
15763
  $templateCache.put(tpl, html);
15767
15764
  return html;
@@ -15815,7 +15812,7 @@ function $$TestabilityProvider() {
15815
15812
  if (dataBinding) {
15816
15813
  forEach(dataBinding, function(bindingName) {
15817
15814
  if (opt_exactMatch) {
15818
- var matcher = new RegExp('(^|\\s)' + expression + '(\\s|\\||$)');
15815
+ var matcher = new RegExp('(^|\\s)' + escapeForRegexp(expression) + '(\\s|\\||$)');
15819
15816
  if (matcher.test(bindingName)) {
15820
15817
  matches.push(binding);
15821
15818
  }
@@ -15937,7 +15934,7 @@ function $TimeoutProvider() {
15937
15934
  timeoutId = $browser.defer(function() {
15938
15935
  try {
15939
15936
  deferred.resolve(fn());
15940
- } catch(e) {
15937
+ } catch (e) {
15941
15938
  deferred.reject(e);
15942
15939
  $exceptionHandler(e);
15943
15940
  }
@@ -16103,7 +16100,7 @@ function urlIsSameOrigin(requestUrl) {
16103
16100
  <file name="index.html">
16104
16101
  <script>
16105
16102
  angular.module('windowExample', [])
16106
- .controller('ExampleController', ['$scope', '$window', function ($scope, $window) {
16103
+ .controller('ExampleController', ['$scope', '$window', function($scope, $window) {
16107
16104
  $scope.greeting = 'Hello, World!';
16108
16105
  $scope.doGreeting = function(greeting) {
16109
16106
  $window.alert(greeting);
@@ -16124,7 +16121,7 @@ function urlIsSameOrigin(requestUrl) {
16124
16121
  </file>
16125
16122
  </example>
16126
16123
  */
16127
- function $WindowProvider(){
16124
+ function $WindowProvider() {
16128
16125
  this.$get = valueFn(window);
16129
16126
  }
16130
16127
 
@@ -16233,7 +16230,7 @@ function $FilterProvider($provide) {
16233
16230
  * of the registered filter instances.
16234
16231
  */
16235
16232
  function register(name, factory) {
16236
- if(isObject(name)) {
16233
+ if (isObject(name)) {
16237
16234
  var filters = {};
16238
16235
  forEach(name, function(filter, key) {
16239
16236
  filters[key] = register(key, filter);
@@ -16400,7 +16397,7 @@ function filterFilter() {
16400
16397
 
16401
16398
  predicates.check = function(value, index) {
16402
16399
  for (var j = 0; j < predicates.length; j++) {
16403
- if(!predicates[j](value, index)) {
16400
+ if (!predicates[j](value, index)) {
16404
16401
  return false;
16405
16402
  }
16406
16403
  }
@@ -16429,7 +16426,7 @@ function filterFilter() {
16429
16426
  }
16430
16427
  }
16431
16428
 
16432
- var search = function(obj, text){
16429
+ var search = function(obj, text) {
16433
16430
  if (typeof text === 'string' && text.charAt(0) === '!') {
16434
16431
  return !search(obj, text.substr(1));
16435
16432
  }
@@ -16443,7 +16440,7 @@ function filterFilter() {
16443
16440
  case 'object':
16444
16441
  return comparator(obj, text);
16445
16442
  default:
16446
- for ( var objKey in obj) {
16443
+ for (var objKey in obj) {
16447
16444
  if (objKey.charAt(0) !== '$' && search(obj[objKey], text)) {
16448
16445
  return true;
16449
16446
  }
@@ -16452,7 +16449,7 @@ function filterFilter() {
16452
16449
  }
16453
16450
  return false;
16454
16451
  case 'array':
16455
- for ( var i = 0; i < obj.length; i++) {
16452
+ for (var i = 0; i < obj.length; i++) {
16456
16453
  if (search(obj[i], text)) {
16457
16454
  return true;
16458
16455
  }
@@ -16487,7 +16484,7 @@ function filterFilter() {
16487
16484
  return array;
16488
16485
  }
16489
16486
  var filtered = [];
16490
- for ( var j = 0; j < array.length; j++) {
16487
+ for (var j = 0; j < array.length; j++) {
16491
16488
  var value = array[j];
16492
16489
  if (predicates.check(value, j)) {
16493
16490
  filtered.push(value);
@@ -16552,7 +16549,7 @@ function filterFilter() {
16552
16549
  currencyFilter.$inject = ['$locale'];
16553
16550
  function currencyFilter($locale) {
16554
16551
  var formats = $locale.NUMBER_FORMATS;
16555
- return function(amount, currencySymbol, fractionSize){
16552
+ return function(amount, currencySymbol, fractionSize) {
16556
16553
  if (isUndefined(currencySymbol)) {
16557
16554
  currencySymbol = formats.CURRENCY_SYM;
16558
16555
  }
@@ -16699,7 +16696,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
16699
16696
  }
16700
16697
 
16701
16698
  // format fraction part.
16702
- while(fraction.length < fractionSize) {
16699
+ while (fraction.length < fractionSize) {
16703
16700
  fraction += '0';
16704
16701
  }
16705
16702
 
@@ -16724,7 +16721,7 @@ function padNumber(num, digits, trim) {
16724
16721
  num = -num;
16725
16722
  }
16726
16723
  num = '' + num;
16727
- while(num.length < digits) num = '0' + num;
16724
+ while (num.length < digits) num = '0' + num;
16728
16725
  if (trim)
16729
16726
  num = num.substr(num.length - digits);
16730
16727
  return neg + num;
@@ -16737,7 +16734,7 @@ function dateGetter(name, size, offset, trim) {
16737
16734
  var value = date['get' + name]();
16738
16735
  if (offset > 0 || value > -offset)
16739
16736
  value += offset;
16740
- if (value === 0 && offset == -12 ) value = 12;
16737
+ if (value === 0 && offset == -12) value = 12;
16741
16738
  return padNumber(value, size, trim);
16742
16739
  };
16743
16740
  }
@@ -16962,7 +16959,7 @@ function dateFilter($locale) {
16962
16959
  return date;
16963
16960
  }
16964
16961
 
16965
- while(format) {
16962
+ while (format) {
16966
16963
  match = DATE_FORMATS_SPLIT.exec(format);
16967
16964
  if (match) {
16968
16965
  parts = concat(parts, match, 1);
@@ -16977,7 +16974,7 @@ function dateFilter($locale) {
16977
16974
  date = new Date(date.getTime());
16978
16975
  date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
16979
16976
  }
16980
- forEach(parts, function(value){
16977
+ forEach(parts, function(value) {
16981
16978
  fn = DATE_FORMATS[value];
16982
16979
  text += fn ? fn(date, $locale.DATETIME_FORMATS)
16983
16980
  : value.replace(/(^'|'$)/g, '').replace(/''/g, "'");
@@ -17130,7 +17127,7 @@ var uppercaseFilter = valueFn(uppercase);
17130
17127
  </file>
17131
17128
  </example>
17132
17129
  */
17133
- function limitToFilter(){
17130
+ function limitToFilter() {
17134
17131
  return function(input, limit) {
17135
17132
  if (isNumber(input)) input = input.toString();
17136
17133
  if (!isArray(input) && !isString(input)) return input;
@@ -17291,42 +17288,42 @@ function limitToFilter(){
17291
17288
  </example>
17292
17289
  */
17293
17290
  orderByFilter.$inject = ['$parse'];
17294
- function orderByFilter($parse){
17291
+ function orderByFilter($parse) {
17295
17292
  return function(array, sortPredicate, reverseOrder) {
17296
17293
  if (!(isArrayLike(array))) return array;
17297
17294
  sortPredicate = isArray(sortPredicate) ? sortPredicate: [sortPredicate];
17298
17295
  if (sortPredicate.length === 0) { sortPredicate = ['+']; }
17299
- sortPredicate = sortPredicate.map(function(predicate){
17296
+ sortPredicate = sortPredicate.map(function(predicate) {
17300
17297
  var descending = false, get = predicate || identity;
17301
17298
  if (isString(predicate)) {
17302
17299
  if ((predicate.charAt(0) == '+' || predicate.charAt(0) == '-')) {
17303
17300
  descending = predicate.charAt(0) == '-';
17304
17301
  predicate = predicate.substring(1);
17305
17302
  }
17306
- if ( predicate === '' ) {
17303
+ if (predicate === '') {
17307
17304
  // Effectively no predicate was passed so we compare identity
17308
- return reverseComparator(function(a,b) {
17305
+ return reverseComparator(function(a, b) {
17309
17306
  return compare(a, b);
17310
17307
  }, descending);
17311
17308
  }
17312
17309
  get = $parse(predicate);
17313
17310
  if (get.constant) {
17314
17311
  var key = get();
17315
- return reverseComparator(function(a,b) {
17312
+ return reverseComparator(function(a, b) {
17316
17313
  return compare(a[key], b[key]);
17317
17314
  }, descending);
17318
17315
  }
17319
17316
  }
17320
- return reverseComparator(function(a,b){
17317
+ return reverseComparator(function(a, b) {
17321
17318
  return compare(get(a),get(b));
17322
17319
  }, descending);
17323
17320
  });
17324
17321
  var arrayCopy = [];
17325
- for ( var i = 0; i < array.length; i++) { arrayCopy.push(array[i]); }
17322
+ for (var i = 0; i < array.length; i++) { arrayCopy.push(array[i]); }
17326
17323
  return arrayCopy.sort(reverseComparator(comparator, reverseOrder));
17327
17324
 
17328
- function comparator(o1, o2){
17329
- for ( var i = 0; i < sortPredicate.length; i++) {
17325
+ function comparator(o1, o2) {
17326
+ for (var i = 0; i < sortPredicate.length; i++) {
17330
17327
  var comp = sortPredicate[i](o1, o2);
17331
17328
  if (comp !== 0) return comp;
17332
17329
  }
@@ -17334,10 +17331,10 @@ function orderByFilter($parse){
17334
17331
  }
17335
17332
  function reverseComparator(comp, descending) {
17336
17333
  return descending
17337
- ? function(a,b){return comp(b,a);}
17334
+ ? function(a, b) {return comp(b,a);}
17338
17335
  : comp;
17339
17336
  }
17340
- function compare(v1, v2){
17337
+ function compare(v1, v2) {
17341
17338
  var t1 = typeof v1;
17342
17339
  var t2 = typeof v2;
17343
17340
  if (t1 == t2) {
@@ -17389,7 +17386,7 @@ var htmlAnchorDirective = valueFn({
17389
17386
  // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.
17390
17387
  var href = toString.call(element.prop('href')) === '[object SVGAnimatedString]' ?
17391
17388
  'xlink:href' : 'href';
17392
- element.on('click', function(event){
17389
+ element.on('click', function(event) {
17393
17390
  // if we have no href url, then don't navigate anywhere.
17394
17391
  if (!element.attr(href)) {
17395
17392
  event.preventDefault();
@@ -17868,6 +17865,11 @@ function nullFormRenameControl(control, name) {
17868
17865
  * - `pattern`
17869
17866
  * - `required`
17870
17867
  * - `url`
17868
+ * - `date`
17869
+ * - `datetimelocal`
17870
+ * - `time`
17871
+ * - `week`
17872
+ * - `month`
17871
17873
  *
17872
17874
  * @description
17873
17875
  * `FormController` keeps track of all its controls and nested forms as well as the state of them,
@@ -18056,7 +18058,7 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
18056
18058
  * Setting a form back to a pristine state is often useful when we want to 'reuse' a form after
18057
18059
  * saving or resetting it.
18058
18060
  */
18059
- form.$setPristine = function () {
18061
+ form.$setPristine = function() {
18060
18062
  $animate.setClass(element, PRISTINE_CLASS, DIRTY_CLASS + ' ' + SUBMITTED_CLASS);
18061
18063
  form.$dirty = false;
18062
18064
  form.$pristine = true;
@@ -18079,7 +18081,7 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
18079
18081
  * Setting a form controls back to their untouched state is often useful when setting the form
18080
18082
  * back to its pristine state.
18081
18083
  */
18082
- form.$setUntouched = function () {
18084
+ form.$setUntouched = function() {
18083
18085
  forEach(controls, function(control) {
18084
18086
  control.$setUntouched();
18085
18087
  });
@@ -18092,7 +18094,7 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
18092
18094
  * @description
18093
18095
  * Sets the form to its submitted state.
18094
18096
  */
18095
- form.$setSubmitted = function () {
18097
+ form.$setSubmitted = function() {
18096
18098
  $animate.addClass(element, SUBMITTED_CLASS);
18097
18099
  form.$submitted = true;
18098
18100
  parentForm.$setSubmitted();
@@ -18369,7 +18371,6 @@ var inputType = {
18369
18371
  * @description
18370
18372
  * Standard HTML text input with angular data binding, inherited by most of the `input` elements.
18371
18373
  *
18372
- * *NOTE* Not every feature offered is available for all input types.
18373
18374
  *
18374
18375
  * @param {string} ngModel Assignable angular expression to data-bind to.
18375
18376
  * @param {string=} name Property name of the form under which the control is published.
@@ -18453,7 +18454,10 @@ var inputType = {
18453
18454
  * the HTML5 date input, a text element will be used. In that case, text must be entered in a valid ISO-8601
18454
18455
  * date format (yyyy-MM-dd), for example: `2009-01-06`. Since many
18455
18456
  * modern browsers do not yet support this input type, it is important to provide cues to users on the
18456
- * expected input format via a placeholder or label. The model must always be a Date object.
18457
+ * expected input format via a placeholder or label.
18458
+ *
18459
+ * The model must always be a Date object, otherwise Angular will throw an error.
18460
+ * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
18457
18461
  *
18458
18462
  * The timezone to be used to read/write the `Date` instance in the model can be defined using
18459
18463
  * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
@@ -18541,7 +18545,10 @@ var inputType = {
18541
18545
  * @description
18542
18546
  * Input with datetime validation and transformation. In browsers that do not yet support
18543
18547
  * the HTML5 date input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
18544
- * local datetime format (yyyy-MM-ddTHH:mm:ss), for example: `2010-12-28T14:57:00`. The model must be a Date object.
18548
+ * local datetime format (yyyy-MM-ddTHH:mm:ss), for example: `2010-12-28T14:57:00`.
18549
+ *
18550
+ * The model must always be a Date object, otherwise Angular will throw an error.
18551
+ * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
18545
18552
  *
18546
18553
  * The timezone to be used to read/write the `Date` instance in the model can be defined using
18547
18554
  * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
@@ -18632,6 +18639,9 @@ var inputType = {
18632
18639
  * local time format (HH:mm:ss), for example: `14:57:00`. Model must be a Date object. This binding will always output a
18633
18640
  * Date object to the model of January 1, 1970, or local date `new Date(1970, 0, 1, HH, mm, ss)`.
18634
18641
  *
18642
+ * The model must always be a Date object, otherwise Angular will throw an error.
18643
+ * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
18644
+ *
18635
18645
  * The timezone to be used to read/write the `Date` instance in the model can be defined using
18636
18646
  * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
18637
18647
  *
@@ -18718,7 +18728,10 @@ var inputType = {
18718
18728
  * @description
18719
18729
  * Input with week-of-the-year validation and transformation to Date. In browsers that do not yet support
18720
18730
  * the HTML5 week input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
18721
- * week format (yyyy-W##), for example: `2013-W02`. The model must always be a Date object.
18731
+ * week format (yyyy-W##), for example: `2013-W02`.
18732
+ *
18733
+ * The model must always be a Date object, otherwise Angular will throw an error.
18734
+ * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
18722
18735
  *
18723
18736
  * The timezone to be used to read/write the `Date` instance in the model can be defined using
18724
18737
  * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
@@ -18804,8 +18817,12 @@ var inputType = {
18804
18817
  * @description
18805
18818
  * Input with month validation and transformation. In browsers that do not yet support
18806
18819
  * the HTML5 month input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
18807
- * month format (yyyy-MM), for example: `2009-01`. The model must always be a Date object. In the event the model is
18808
- * not set to the first of the month, the first of that model's month is assumed.
18820
+ * month format (yyyy-MM), for example: `2009-01`.
18821
+ *
18822
+ * The model must always be a Date object, otherwise Angular will throw an error.
18823
+ * Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
18824
+ * If the model is not set to the first of the month, the next view to model update will set it
18825
+ * to the first of the month.
18809
18826
  *
18810
18827
  * The timezone to be used to read/write the `Date` instance in the model can be defined using
18811
18828
  * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
@@ -18894,6 +18911,8 @@ var inputType = {
18894
18911
  * Text input with number validation and transformation. Sets the `number` validation
18895
18912
  * error if not a valid number.
18896
18913
  *
18914
+ * The model must always be a number, otherwise Angular will throw an error.
18915
+ *
18897
18916
  * @param {string} ngModel Assignable angular expression to data-bind to.
18898
18917
  * @param {string=} name Property name of the form under which the control is published.
18899
18918
  * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
@@ -18972,6 +18991,12 @@ var inputType = {
18972
18991
  * Text input with URL validation. Sets the `url` validation error key if the content is not a
18973
18992
  * valid URL.
18974
18993
  *
18994
+ * <div class="alert alert-warning">
18995
+ * **Note:** `input[url]` uses a regex to validate urls that is derived from the regex
18996
+ * used in Chromium. If you need stricter validation, you can use `ng-pattern` or modify
18997
+ * the built-in validators (see the {@link guide/forms Forms guide})
18998
+ * </div>
18999
+ *
18975
19000
  * @param {string} ngModel Assignable angular expression to data-bind to.
18976
19001
  * @param {string=} name Property name of the form under which the control is published.
18977
19002
  * @param {string=} required Sets `required` validation error key if the value is not entered.
@@ -19049,6 +19074,12 @@ var inputType = {
19049
19074
  * Text input with email validation. Sets the `email` validation error key if not a valid email
19050
19075
  * address.
19051
19076
  *
19077
+ * <div class="alert alert-warning">
19078
+ * **Note:** `input[email]` uses a regex to validate email addresses that is derived from the regex
19079
+ * used in Chromium. If you need stricter validation (e.g. requiring a top-level domain), you can
19080
+ * use `ng-pattern` or modify the built-in validators (see the {@link guide/forms Forms guide})
19081
+ * </div>
19082
+ *
19052
19083
  * @param {string} ngModel Assignable angular expression to data-bind to.
19053
19084
  * @param {string=} name Property name of the form under which the control is published.
19054
19085
  * @param {string=} required Sets `required` validation error key if the value is not entered.
@@ -19227,19 +19258,6 @@ var inputType = {
19227
19258
  'file': noop
19228
19259
  };
19229
19260
 
19230
- function testFlags(validity, flags) {
19231
- var i, flag;
19232
- if (flags) {
19233
- for (i=0; i<flags.length; ++i) {
19234
- flag = flags[i];
19235
- if (validity[flag]) {
19236
- return true;
19237
- }
19238
- }
19239
- }
19240
- return false;
19241
- }
19242
-
19243
19261
  function stringBasedInputType(ctrl) {
19244
19262
  ctrl.$formatters.push(function(value) {
19245
19263
  return ctrl.$isEmpty(value) ? value : value.toString();
@@ -19252,7 +19270,6 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
19252
19270
  }
19253
19271
 
19254
19272
  function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
19255
- var validity = element.prop(VALIDITY_STATE_PROPERTY);
19256
19273
  var placeholder = element[0].placeholder, noevent = {};
19257
19274
  var type = lowercase(element[0].type);
19258
19275
 
@@ -19689,10 +19706,14 @@ function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filt
19689
19706
  * @restrict E
19690
19707
  *
19691
19708
  * @description
19692
- * HTML input element control with angular data-binding. Input control follows HTML5 input types
19693
- * and polyfills the HTML5 validation behavior for older browsers.
19709
+ * HTML input element control. When used together with {@link ngModel `ngModel`}, it provides data-binding,
19710
+ * input state control, and validation.
19711
+ * Input control follows HTML5 input types and polyfills the HTML5 validation behavior for older browsers.
19694
19712
  *
19695
- * *NOTE* Not every feature offered is available for all input types.
19713
+ * <div class="alert alert-warning">
19714
+ * **Note:** Not every feature offered is available for all input types.
19715
+ * Specifically, data binding and event handling via `ng-model` is unsupported for `input[file]`.
19716
+ * </div>
19696
19717
  *
19697
19718
  * @param {string} ngModel Assignable angular expression to data-bind to.
19698
19719
  * @param {string=} name Property name of the form under which the control is published.
@@ -19828,19 +19849,20 @@ var VALID_CLASS = 'ng-valid',
19828
19849
  * @name ngModel.NgModelController
19829
19850
  *
19830
19851
  * @property {string} $viewValue Actual string value in the view.
19831
- * @property {*} $modelValue The value in the model, that the control is bound to.
19852
+ * @property {*} $modelValue The value in the model that the control is bound to.
19832
19853
  * @property {Array.<Function>} $parsers Array of functions to execute, as a pipeline, whenever
19833
- the control reads value from the DOM. Each function is called, in turn, passing the value
19834
- through to the next. The last return value is used to populate the model.
19835
- Used to sanitize / convert the value as well as validation. For validation,
19836
- the parsers should update the validity state using
19837
- {@link ngModel.NgModelController#$setValidity $setValidity()},
19838
- and return `undefined` for invalid values.
19854
+ the control reads value from the DOM. The functions are called in array order, each passing the value
19855
+ through to the next. The last return value is forwarded to the $validators collection.
19856
+ Used to sanitize / convert the value.
19857
+ Returning undefined from a parser means a parse error occurred. No $validators will
19858
+ run and the 'ngModel' will not be updated until the parse error is resolved. The parse error is stored
19859
+ in 'ngModel.$error.parse'.
19839
19860
 
19840
19861
  *
19841
19862
  * @property {Array.<Function>} $formatters Array of functions to execute, as a pipeline, whenever
19842
- the model value changes. Each function is called, in turn, passing the value through to the
19843
- next. Used to format / convert values for display in the control and validation.
19863
+ the model value changes. The functions are called in reverse array order, each passing the value through to the
19864
+ next. The last return value is used as the actual DOM value.
19865
+ Used to format / convert values for display in the control.
19844
19866
  * ```js
19845
19867
  * function formatter(value) {
19846
19868
  * if (value) {
@@ -19871,8 +19893,9 @@ var VALID_CLASS = 'ng-valid',
19871
19893
  * is expected to return a promise when it is run during the model validation process. Once the promise
19872
19894
  * is delivered then the validation status will be set to true when fulfilled and false when rejected.
19873
19895
  * When the asynchronous validators are triggered, each of the validators will run in parallel and the model
19874
- * value will only be updated once all validators have been fulfilled. Also, keep in mind that all
19875
- * asynchronous validators will only run once all synchronous validators have passed.
19896
+ * value will only be updated once all validators have been fulfilled. As long as an asynchronous validator
19897
+ * is unfulfilled, its key will be added to the controllers `$pending` property. Also, all asynchronous validators
19898
+ * will only run once all synchronous validators have passed.
19876
19899
  *
19877
19900
  * Please note that if $http is used then it is important that the server returns a success HTTP response code
19878
19901
  * in order to fulfill the validation and a status level of `4xx` in order to reject the validation.
@@ -19928,7 +19951,7 @@ var VALID_CLASS = 'ng-valid',
19928
19951
  *
19929
19952
  * We are using the {@link ng.service:$sce $sce} service here and include the {@link ngSanitize $sanitize}
19930
19953
  * module to automatically remove "bad" content like inline event listener (e.g. `<span onclick="...">`).
19931
- * However, as we are using `$sce` the model can still decide to to provide unsafe content if it marks
19954
+ * However, as we are using `$sce` the model can still decide to provide unsafe content if it marks
19932
19955
  * that content using the `$sce` service.
19933
19956
  *
19934
19957
  * <example name="NgModelController" module="customControl" deps="angular-sanitize.js">
@@ -20115,19 +20138,22 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
20115
20138
  * @name ngModel.NgModelController#$setValidity
20116
20139
  *
20117
20140
  * @description
20118
- * Change the validity state, and notifies the form.
20141
+ * Change the validity state, and notify the form.
20119
20142
  *
20120
- * This method can be called within $parsers/$formatters. However, if possible, please use the
20121
- * `ngModel.$validators` pipeline which is designed to call this method automatically.
20143
+ * This method can be called within $parsers/$formatters or a custom validation implementation.
20144
+ * However, in most cases it should be sufficient to use the `ngModel.$validators` and
20145
+ * `ngModel.$asyncValidators` collections which will call `$setValidity` automatically.
20122
20146
  *
20123
- * @param {string} validationErrorKey Name of the validator. the `validationErrorKey` will assign
20124
- * to `$error[validationErrorKey]` and `$pending[validationErrorKey]`
20125
- * so that it is available for data-binding.
20147
+ * @param {string} validationErrorKey Name of the validator. The `validationErrorKey` will be assigned
20148
+ * to either `$error[validationErrorKey]` or `$pending[validationErrorKey]`
20149
+ * (for unfulfilled `$asyncValidators`), so that it is available for data-binding.
20126
20150
  * The `validationErrorKey` should be in camelCase and will get converted into dash-case
20127
20151
  * for class name. Example: `myError` will result in `ng-valid-my-error` and `ng-invalid-my-error`
20128
20152
  * class and can be bound to as `{{someForm.someControl.$error.myError}}` .
20129
20153
  * @param {boolean} isValid Whether the current state is valid (true), invalid (false), pending (undefined),
20130
- * or skipped (null).
20154
+ * or skipped (null). Pending is used for unfulfilled `$asyncValidators`.
20155
+ * Skipped is used by Angular when validators do not run because of parse errors and
20156
+ * when `$asyncValidators` do not run because any of the `$validators` failed.
20131
20157
  */
20132
20158
  addSetValidityMethod({
20133
20159
  ctrl: this,
@@ -20153,7 +20179,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
20153
20179
  * state (ng-pristine class). A model is considered to be pristine when the model has not been changed
20154
20180
  * from when first compiled within then form.
20155
20181
  */
20156
- this.$setPristine = function () {
20182
+ this.$setPristine = function() {
20157
20183
  ctrl.$dirty = false;
20158
20184
  ctrl.$pristine = true;
20159
20185
  $animate.removeClass($element, DIRTY_CLASS);
@@ -20222,13 +20248,13 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
20222
20248
  * angular.module('cancel-update-example', [])
20223
20249
  *
20224
20250
  * .controller('CancelUpdateController', ['$scope', function($scope) {
20225
- * $scope.resetWithCancel = function (e) {
20251
+ * $scope.resetWithCancel = function(e) {
20226
20252
  * if (e.keyCode == 27) {
20227
20253
  * $scope.myForm.myInput1.$rollbackViewValue();
20228
20254
  * $scope.myValue = '';
20229
20255
  * }
20230
20256
  * };
20231
- * $scope.resetWithoutCancel = function (e) {
20257
+ * $scope.resetWithoutCancel = function(e) {
20232
20258
  * if (e.keyCode == 27) {
20233
20259
  * $scope.myValue = '';
20234
20260
  * }
@@ -20407,7 +20433,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
20407
20433
  var parserValid = isUndefined(modelValue) ? undefined : true;
20408
20434
 
20409
20435
  if (parserValid) {
20410
- for(var i = 0; i < ctrl.$parsers.length; i++) {
20436
+ for (var i = 0; i < ctrl.$parsers.length; i++) {
20411
20437
  modelValue = ctrl.$parsers[i](modelValue);
20412
20438
  if (isUndefined(modelValue)) {
20413
20439
  parserValid = false;
@@ -20448,7 +20474,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
20448
20474
  forEach(ctrl.$viewChangeListeners, function(listener) {
20449
20475
  try {
20450
20476
  listener();
20451
- } catch(e) {
20477
+ } catch (e) {
20452
20478
  $exceptionHandler(e);
20453
20479
  }
20454
20480
  });
@@ -20551,7 +20577,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
20551
20577
  idx = formatters.length;
20552
20578
 
20553
20579
  var viewValue = modelValue;
20554
- while(idx--) {
20580
+ while (idx--) {
20555
20581
  viewValue = formatters[idx](viewValue);
20556
20582
  }
20557
20583
  if (ctrl.$viewValue !== viewValue) {
@@ -20572,6 +20598,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
20572
20598
  * @name ngModel
20573
20599
  *
20574
20600
  * @element input
20601
+ * @priority 1
20575
20602
  *
20576
20603
  * @description
20577
20604
  * The `ngModel` directive binds an `input`,`select`, `textarea` (or custom form control) to a
@@ -20593,7 +20620,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
20593
20620
  *
20594
20621
  * For best practices on using `ngModel`, see:
20595
20622
  *
20596
- * - [https://github.com/angular/angular.js/wiki/Understanding-Scopes]
20623
+ * - [Understanding Scopes](https://github.com/angular/angular.js/wiki/Understanding-Scopes)
20597
20624
  *
20598
20625
  * For basic examples, how to use `ngModel`, see:
20599
20626
  *
@@ -20616,10 +20643,15 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
20616
20643
  * The following CSS classes are added and removed on the associated input/select/textarea element
20617
20644
  * depending on the validity of the model.
20618
20645
  *
20619
- * - `ng-valid` is set if the model is valid.
20620
- * - `ng-invalid` is set if the model is invalid.
20621
- * - `ng-pristine` is set if the model is pristine.
20622
- * - `ng-dirty` is set if the model is dirty.
20646
+ * - `ng-valid`: the model is valid
20647
+ * - `ng-invalid`: the model is invalid
20648
+ * - `ng-valid-[key]`: for each valid key added by `$setValidity`
20649
+ * - `ng-invalid-[key]`: for each invalid key added by `$setValidity`
20650
+ * - `ng-pristine`: the control hasn't been interacted with yet
20651
+ * - `ng-dirty`: the control has been interacted with
20652
+ * - `ng-touched`: the control has been blurred
20653
+ * - `ng-untouched`: the control hasn't been blurred
20654
+ * - `ng-pending`: any `$asyncValidators` are unfulfilled
20623
20655
  *
20624
20656
  * Keep in mind that ngAnimate can detect each of these classes when added and removed.
20625
20657
  *
@@ -20713,7 +20745,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
20713
20745
  .controller('ExampleController', ['$scope', function($scope) {
20714
20746
  var _name = 'Brian';
20715
20747
  $scope.user = {
20716
- name: function (newName) {
20748
+ name: function(newName) {
20717
20749
  if (angular.isDefined(newName)) {
20718
20750
  _name = newName;
20719
20751
  }
@@ -21080,9 +21112,9 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
21080
21112
  * @name ngValue
21081
21113
  *
21082
21114
  * @description
21083
- * Binds the given expression to the value of `input[select]` or `input[radio]`, so
21084
- * that when the element is selected, the `ngModel` of that element is set to the
21085
- * bound value.
21115
+ * Binds the given expression to the value of `option` or `input[radio]`, so
21116
+ * that when the element is selected, the `ngModel` of that element is set to
21117
+ * the bound value.
21086
21118
  *
21087
21119
  * `ngValue` is useful when dynamically generating lists of radio buttons using `ng-repeat`, as
21088
21120
  * shown below.
@@ -21215,7 +21247,7 @@ var ngValueDirective = function() {
21215
21247
  .controller('ExampleController', ['$scope', function($scope) {
21216
21248
  $scope.user = { name: 'say', data: '' };
21217
21249
 
21218
- $scope.cancel = function (e) {
21250
+ $scope.cancel = function(e) {
21219
21251
  if (e.keyCode == 27) {
21220
21252
  $scope.userForm.userName.$rollbackViewValue();
21221
21253
  }
@@ -21289,7 +21321,7 @@ var ngValueDirective = function() {
21289
21321
  .controller('ExampleController', ['$scope', function($scope) {
21290
21322
  var _name = 'Brian';
21291
21323
  $scope.user = {
21292
- name: function (newName) {
21324
+ name: function(newName) {
21293
21325
  return angular.isDefined(newName) ? (_name = newName) : _name;
21294
21326
  }
21295
21327
  };
@@ -21512,7 +21544,7 @@ var ngBindDirective = ['$compile', function($compile) {
21512
21544
  <file name="index.html">
21513
21545
  <script>
21514
21546
  angular.module('bindExample', [])
21515
- .controller('ExampleController', ['$scope', function ($scope) {
21547
+ .controller('ExampleController', ['$scope', function($scope) {
21516
21548
  $scope.salutation = 'Hello';
21517
21549
  $scope.name = 'World';
21518
21550
  }]);
@@ -21667,10 +21699,10 @@ function classDirective(name, selector) {
21667
21699
  attr.$removeClass(newClasses);
21668
21700
  }
21669
21701
 
21670
- function digestClassCounts (classes, count) {
21702
+ function digestClassCounts(classes, count) {
21671
21703
  var classCounts = element.data('$classCounts') || {};
21672
21704
  var classesToUpdate = [];
21673
- forEach(classes, function (className) {
21705
+ forEach(classes, function(className) {
21674
21706
  if (count > 0 || classCounts[className]) {
21675
21707
  classCounts[className] = (classCounts[className] || 0) + count;
21676
21708
  if (classCounts[className] === +(count > 0)) {
@@ -21682,7 +21714,7 @@ function classDirective(name, selector) {
21682
21714
  return classesToUpdate.join(' ');
21683
21715
  }
21684
21716
 
21685
- function updateClasses (oldClasses, newClasses) {
21717
+ function updateClasses(oldClasses, newClasses) {
21686
21718
  var toAdd = arrayDifference(newClasses, oldClasses);
21687
21719
  var toRemove = arrayDifference(oldClasses, newClasses);
21688
21720
  toAdd = digestClassCounts(toAdd, 1);
@@ -21714,23 +21746,23 @@ function classDirective(name, selector) {
21714
21746
  var values = [];
21715
21747
 
21716
21748
  outer:
21717
- for(var i = 0; i < tokens1.length; i++) {
21749
+ for (var i = 0; i < tokens1.length; i++) {
21718
21750
  var token = tokens1[i];
21719
- for(var j = 0; j < tokens2.length; j++) {
21720
- if(token == tokens2[j]) continue outer;
21751
+ for (var j = 0; j < tokens2.length; j++) {
21752
+ if (token == tokens2[j]) continue outer;
21721
21753
  }
21722
21754
  values.push(token);
21723
21755
  }
21724
21756
  return values;
21725
21757
  }
21726
21758
 
21727
- function arrayClasses (classVal) {
21759
+ function arrayClasses(classVal) {
21728
21760
  if (isArray(classVal)) {
21729
21761
  return classVal;
21730
21762
  } else if (isString(classVal)) {
21731
21763
  return classVal.split(' ');
21732
21764
  } else if (isObject(classVal)) {
21733
- var classes = [], i = 0;
21765
+ var classes = [];
21734
21766
  forEach(classVal, function(v, k) {
21735
21767
  if (v) {
21736
21768
  classes = classes.concat(k.split(' '));
@@ -22489,10 +22521,8 @@ var ngControllerDirective = [function() {
22489
22521
  </example>
22490
22522
  */
22491
22523
  /*
22492
- * A directive that allows creation of custom onclick handlers that are defined as angular
22493
- * expressions and are compiled and executed within the current scope.
22494
- *
22495
- * Events that are handled via these handler are always configured not to propagate further.
22524
+ * A collection of directives that allows creation of custom event handlers that are defined as
22525
+ * angular expressions and are compiled and executed within the current scope.
22496
22526
  */
22497
22527
  var ngEventDirectives = {};
22498
22528
 
@@ -23022,13 +23052,13 @@ var ngIfDirective = ['$animate', function($animate) {
23022
23052
  terminal: true,
23023
23053
  restrict: 'A',
23024
23054
  $$tlb: true,
23025
- link: function ($scope, $element, $attr, ctrl, $transclude) {
23055
+ link: function($scope, $element, $attr, ctrl, $transclude) {
23026
23056
  var block, childScope, previousElements;
23027
23057
  $scope.$watch($attr.ngIf, function ngIfWatchAction(value) {
23028
23058
 
23029
23059
  if (value) {
23030
23060
  if (!childScope) {
23031
- $transclude(function (clone, newScope) {
23061
+ $transclude(function(clone, newScope) {
23032
23062
  childScope = newScope;
23033
23063
  clone[clone.length++] = document.createComment(' end ngIf: ' + $attr.ngIf + ' ');
23034
23064
  // Note: We only need the first/last node of the cloned nodes.
@@ -23260,15 +23290,15 @@ var ngIncludeDirective = ['$templateRequest', '$anchorScroll', '$animate', '$sce
23260
23290
  currentElement;
23261
23291
 
23262
23292
  var cleanupLastIncludeContent = function() {
23263
- if(previousElement) {
23293
+ if (previousElement) {
23264
23294
  previousElement.remove();
23265
23295
  previousElement = null;
23266
23296
  }
23267
- if(currentScope) {
23297
+ if (currentScope) {
23268
23298
  currentScope.$destroy();
23269
23299
  currentScope = null;
23270
23300
  }
23271
- if(currentElement) {
23301
+ if (currentElement) {
23272
23302
  $animate.leave(currentElement).then(function() {
23273
23303
  previousElement = null;
23274
23304
  });
@@ -23951,10 +23981,10 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
23951
23981
  if (trackByExp) {
23952
23982
  trackByExpGetter = $parse(trackByExp);
23953
23983
  } else {
23954
- trackByIdArrayFn = function (key, value) {
23984
+ trackByIdArrayFn = function(key, value) {
23955
23985
  return hashKey(value);
23956
23986
  };
23957
- trackByIdObjFn = function (key) {
23987
+ trackByIdObjFn = function(key) {
23958
23988
  return key;
23959
23989
  };
23960
23990
  }
@@ -24034,7 +24064,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
24034
24064
  nextBlockOrder[index] = block;
24035
24065
  } else if (nextBlockMap[trackById]) {
24036
24066
  // if collision detected. restore lastBlockMap and throw an error
24037
- forEach(nextBlockOrder, function (block) {
24067
+ forEach(nextBlockOrder, function(block) {
24038
24068
  if (block && block.scope) lastBlockMap[block.id] = block;
24039
24069
  });
24040
24070
  throw ngRepeatMinErr('dupes',
@@ -24224,7 +24254,7 @@ var NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';
24224
24254
  </div>
24225
24255
  </file>
24226
24256
  <file name="glyphicons.css">
24227
- @import url(//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css);
24257
+ @import url(../../components/bootstrap-3.1.1/css/bootstrap.css);
24228
24258
  </file>
24229
24259
  <file name="animations.css">
24230
24260
  .animate-show {
@@ -24274,13 +24304,13 @@ var ngShowDirective = ['$animate', function($animate) {
24274
24304
  restrict: 'A',
24275
24305
  multiElement: true,
24276
24306
  link: function(scope, element, attr) {
24277
- scope.$watch(attr.ngShow, function ngShowWatchAction(value){
24307
+ scope.$watch(attr.ngShow, function ngShowWatchAction(value) {
24278
24308
  // we're adding a temporary, animation-specific class for ng-hide since this way
24279
24309
  // we can control when the element is actually displayed on screen without having
24280
24310
  // to have a global/greedy CSS selector that breaks when other animations are run.
24281
24311
  // Read: https://github.com/angular/angular.js/issues/9103#issuecomment-58335845
24282
24312
  $animate[value ? 'removeClass' : 'addClass'](element, NG_HIDE_CLASS, {
24283
- tempClasses : NG_HIDE_IN_PROGRESS_CLASS
24313
+ tempClasses: NG_HIDE_IN_PROGRESS_CLASS
24284
24314
  });
24285
24315
  });
24286
24316
  }
@@ -24389,7 +24419,7 @@ var ngShowDirective = ['$animate', function($animate) {
24389
24419
  </div>
24390
24420
  </file>
24391
24421
  <file name="glyphicons.css">
24392
- @import url(//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css);
24422
+ @import url(../../components/bootstrap-3.1.1/css/bootstrap.css);
24393
24423
  </file>
24394
24424
  <file name="animations.css">
24395
24425
  .animate-hide {
@@ -24435,11 +24465,11 @@ var ngHideDirective = ['$animate', function($animate) {
24435
24465
  restrict: 'A',
24436
24466
  multiElement: true,
24437
24467
  link: function(scope, element, attr) {
24438
- scope.$watch(attr.ngHide, function ngHideWatchAction(value){
24468
+ scope.$watch(attr.ngHide, function ngHideWatchAction(value) {
24439
24469
  // The comment inside of the ngShowDirective explains why we add and
24440
24470
  // remove a temporary class for the show/hide animation
24441
24471
  $animate[value ? 'addClass' : 'removeClass'](element,NG_HIDE_CLASS, {
24442
- tempClasses : NG_HIDE_IN_PROGRESS_CLASS
24472
+ tempClasses: NG_HIDE_IN_PROGRESS_CLASS
24443
24473
  });
24444
24474
  });
24445
24475
  }
@@ -24842,34 +24872,37 @@ var ngOptionsMinErr = minErr('ngOptions');
24842
24872
  * elements for the `<select>` element using the array or object obtained by evaluating the
24843
24873
  * `ngOptions` comprehension_expression.
24844
24874
  *
24875
+ * In many cases, `ngRepeat` can be used on `<option>` elements instead of `ngOptions` to achieve a
24876
+ * similar result. However, the `ngOptions` provides some benefits such as reducing memory and
24877
+ * increasing speed by not creating a new scope for each repeated instance, as well as providing
24878
+ * more flexibility in how the `select`'s model is assigned via `select as`. `ngOptions should be
24879
+ * used when the `select` model needs to be bound to a non-string value. This is because an option
24880
+ * element can only be bound to string values at present.
24881
+ *
24845
24882
  * When an item in the `<select>` menu is selected, the array element or object property
24846
24883
  * represented by the selected option will be bound to the model identified by the `ngModel`
24847
24884
  * directive.
24848
24885
  *
24849
- * <div class="alert alert-warning">
24850
- * **Note:** `ngModel` compares by reference, not value. This is important when binding to an
24851
- * array of objects. See an example [in this jsfiddle](http://jsfiddle.net/qWzTb/).
24852
- * </div>
24853
- *
24854
24886
  * Optionally, a single hard-coded `<option>` element, with the value set to an empty string, can
24855
24887
  * be nested into the `<select>` element. This element will then represent the `null` or "not selected"
24856
24888
  * option. See example below for demonstration.
24857
24889
  *
24858
24890
  * <div class="alert alert-warning">
24859
- * **Note:** `ngOptions` provides an iterator facility for the `<option>` element which should be used instead
24860
- * of {@link ng.directive:ngRepeat ngRepeat} when you want the
24861
- * `select` model to be bound to a non-string value. This is because an option element can only
24862
- * be bound to string values at present.
24891
+ * **Note:** `ngModel` compares by reference, not value. This is important when binding to an
24892
+ * array of objects. See an example [in this jsfiddle](http://jsfiddle.net/qWzTb/).
24863
24893
  * </div>
24864
24894
  *
24865
- * <div class="alert alert-info">
24866
- * **Note:** Using `select as` will bind the result of the `select as` expression to the model, but
24895
+ * ## `select as`
24896
+ *
24897
+ * Using `select as` will bind the result of the `select as` expression to the model, but
24867
24898
  * the value of the `<select>` and `<option>` html elements will be either the index (for array data sources)
24868
- * or property name (for object data sources) of the value within the collection.
24869
- * </div>
24899
+ * or property name (for object data sources) of the value within the collection. If a `track by` expression
24900
+ * is used, the result of that expression will be set as the value of the `option` and `select` elements.
24901
+ *
24902
+ * ### `select as` with `trackexpr`
24903
+ *
24904
+ * Using `select as` together with `trackexpr` is not recommended. Reasoning:
24870
24905
  *
24871
- * **Note:** Using `select as` together with `trackexpr` is not recommended.
24872
- * Reasoning:
24873
24906
  * - Example: &lt;select ng-options="item.subItem as item.label for item in values track by item.id" ng-model="selected"&gt;
24874
24907
  * values: [{id: 1, label: 'aLabel', subItem: {name: 'aSubItem'}}, {id: 2, label: 'bLabel', subItem: {name: 'bSubItem'}}],
24875
24908
  * $scope.selected = {name: 'aSubItem'};
@@ -25080,7 +25113,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
25080
25113
  unknownOption = optionTemplate.clone();
25081
25114
 
25082
25115
  // find "null" option
25083
- for(var i = 0, children = element.children(), ii = children.length; i < ii; i++) {
25116
+ for (var i = 0, children = element.children(), ii = children.length; i < ii; i++) {
25084
25117
  if (children[i].value === '') {
25085
25118
  emptyOption = nullOption = children.eq(i);
25086
25119
  break;
@@ -25182,6 +25215,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
25182
25215
  valuesFn = $parse(match[7]),
25183
25216
  track = match[8],
25184
25217
  trackFn = track ? $parse(match[8]) : null,
25218
+ trackKeysCache = {},
25185
25219
  // This is an array of array of existing option groups in DOM.
25186
25220
  // We try to reuse these if possible
25187
25221
  // - optionGroupsCache[0] is the options with no option group
@@ -25227,17 +25261,16 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
25227
25261
 
25228
25262
  function selectionChanged() {
25229
25263
  scope.$apply(function() {
25230
- var optionGroup,
25231
- collection = valuesFn(scope) || [],
25232
- key, value, optionElement, index, groupIndex, length, groupLength, trackIndex;
25264
+ var collection = valuesFn(scope) || [];
25233
25265
  var viewValue;
25234
25266
  if (multiple) {
25235
25267
  viewValue = [];
25236
25268
  forEach(selectElement.val(), function(selectedKey) {
25269
+ selectedKey = trackFn ? trackKeysCache[selectedKey] : selectedKey;
25237
25270
  viewValue.push(getViewValue(selectedKey, collection[selectedKey]));
25238
25271
  });
25239
25272
  } else {
25240
- var selectedKey = selectElement.val();
25273
+ var selectedKey = trackFn ? trackKeysCache[selectElement.val()] : selectElement.val();
25241
25274
  viewValue = getViewValue(selectedKey, collection[selectedKey]);
25242
25275
  }
25243
25276
  ctrl.$setViewValue(viewValue);
@@ -25359,14 +25392,17 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
25359
25392
  anySelected = false,
25360
25393
  lastElement,
25361
25394
  element,
25362
- label;
25395
+ label,
25396
+ optionId;
25397
+
25398
+ trackKeysCache = {};
25363
25399
 
25364
25400
  // We now build up the list of options we need (we merge later)
25365
25401
  for (index = 0; length = keys.length, index < length; index++) {
25366
25402
  key = index;
25367
25403
  if (keyName) {
25368
25404
  key = keys[index];
25369
- if ( key.charAt(0) === '$' ) continue;
25405
+ if (key.charAt(0) === '$') continue;
25370
25406
  }
25371
25407
  value = values[key];
25372
25408
 
@@ -25383,9 +25419,14 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
25383
25419
 
25384
25420
  // doing displayFn(scope, locals) || '' overwrites zero values
25385
25421
  label = isDefined(label) ? label : '';
25422
+ optionId = trackFn ? trackFn(scope, locals) : (keyName ? keys[index] : index);
25423
+ if (trackFn) {
25424
+ trackKeysCache[optionId] = key;
25425
+ }
25426
+
25386
25427
  optionGroup.push({
25387
25428
  // either the index into array or key from object
25388
- id: (keyName ? keys[index] : index),
25429
+ id: optionId,
25389
25430
  label: label,
25390
25431
  selected: selected // determine if we should be selected
25391
25432
  });
@@ -25430,7 +25471,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
25430
25471
  }
25431
25472
 
25432
25473
  lastElement = null; // start at the beginning
25433
- for(index = 0, length = optionGroup.length; index < length; index++) {
25474
+ for (index = 0, length = optionGroup.length; index < length; index++) {
25434
25475
  option = optionGroup[index];
25435
25476
  if ((existingOption = existingOptions[index+1])) {
25436
25477
  // reuse elements
@@ -25488,12 +25529,12 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
25488
25529
  }
25489
25530
  // remove any excessive OPTIONs in a group
25490
25531
  index++; // increment since the existingOptions[0] is parent element not OPTION
25491
- while(existingOptions.length > index) {
25532
+ while (existingOptions.length > index) {
25492
25533
  option = existingOptions.pop();
25493
25534
  updateLabelMap(labelMap, option.label, false);
25494
25535
  option.element.remove();
25495
25536
  }
25496
- forEach(labelMap, function (count, label) {
25537
+ forEach(labelMap, function(count, label) {
25497
25538
  if (count > 0) {
25498
25539
  selectCtrl.addOption(label);
25499
25540
  } else if (count < 0) {
@@ -25502,7 +25543,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
25502
25543
  });
25503
25544
  }
25504
25545
  // remove any excessive OPTGROUPs from select
25505
- while(optionGroupsCache.length > groupIndex) {
25546
+ while (optionGroupsCache.length > groupIndex) {
25506
25547
  optionGroupsCache.pop()[0].element.remove();
25507
25548
  }
25508
25549
  }
@@ -25528,7 +25569,7 @@ var optionDirective = ['$interpolate', function($interpolate) {
25528
25569
  }
25529
25570
  }
25530
25571
 
25531
- return function (scope, element, attr) {
25572
+ return function(scope, element, attr) {
25532
25573
  var selectCtrlName = '$selectController',
25533
25574
  parent = element.parent(),
25534
25575
  selectCtrl = parent.data(selectCtrlName) ||