angularjs-rails 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/lib/angularjs-rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/angular-animate.js +78 -54
  4. data/vendor/assets/javascripts/angular-aria.js +5 -5
  5. data/vendor/assets/javascripts/angular-cookies.js +4 -4
  6. data/vendor/assets/javascripts/angular-loader.js +6 -6
  7. data/vendor/assets/javascripts/angular-messages.js +15 -15
  8. data/vendor/assets/javascripts/angular-mocks.js +34 -32
  9. data/vendor/assets/javascripts/angular-resource.js +22 -22
  10. data/vendor/assets/javascripts/angular-route.js +8 -8
  11. data/vendor/assets/javascripts/angular-sanitize.js +94 -63
  12. data/vendor/assets/javascripts/angular-scenario.js +532 -497
  13. data/vendor/assets/javascripts/angular-touch.js +3 -3
  14. data/vendor/assets/javascripts/angular.js +516 -475
  15. data/vendor/assets/javascripts/unstable/angular-animate.js +78 -54
  16. data/vendor/assets/javascripts/unstable/angular-aria.js +5 -5
  17. data/vendor/assets/javascripts/unstable/angular-cookies.js +4 -4
  18. data/vendor/assets/javascripts/unstable/angular-loader.js +6 -6
  19. data/vendor/assets/javascripts/unstable/angular-messages.js +15 -15
  20. data/vendor/assets/javascripts/unstable/angular-mocks.js +34 -32
  21. data/vendor/assets/javascripts/unstable/angular-resource.js +22 -22
  22. data/vendor/assets/javascripts/unstable/angular-route.js +8 -8
  23. data/vendor/assets/javascripts/unstable/angular-sanitize.js +94 -63
  24. data/vendor/assets/javascripts/unstable/angular-scenario.js +532 -497
  25. data/vendor/assets/javascripts/unstable/angular-touch.js +3 -3
  26. data/vendor/assets/javascripts/unstable/angular.js +516 -475
  27. metadata +14 -14
@@ -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) ||