angular_velocity 0.0.6alpha → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.0.6
2
+ * @license AngularJS v1.0.8
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -67,6 +67,29 @@ var /** holds major version number for IE or NaN for real browsers */
67
67
  nodeName_,
68
68
  uid = ['0', '0', '0'];
69
69
 
70
+
71
+ /**
72
+ * @private
73
+ * @param {*} obj
74
+ * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, ...)
75
+ */
76
+ function isArrayLike(obj) {
77
+ if (!obj || (typeof obj.length !== 'number')) return false;
78
+
79
+ // We have on object which has length property. Should we treat it as array?
80
+ if (typeof obj.hasOwnProperty != 'function' &&
81
+ typeof obj.constructor != 'function') {
82
+ // This is here for IE8: it is a bogus object treat it as array;
83
+ return true;
84
+ } else {
85
+ return obj instanceof JQLite || // JQLite
86
+ (jQuery && obj instanceof jQuery) || // jQuery
87
+ toString.call(obj) !== '[object Object]' || // some browser native object
88
+ typeof obj.callee === 'function'; // arguments (on IE8 looks like regular obj)
89
+ }
90
+ }
91
+
92
+
70
93
  /**
71
94
  * @ngdoc function
72
95
  * @name angular.forEach
@@ -94,30 +117,6 @@ var /** holds major version number for IE or NaN for real browsers */
94
117
  * @param {Object=} context Object to become context (`this`) for the iterator function.
95
118
  * @returns {Object|Array} Reference to `obj`.
96
119
  */
97
-
98
-
99
- /**
100
- * @private
101
- * @param {*} obj
102
- * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, ...)
103
- */
104
- function isArrayLike(obj) {
105
- if (!obj || (typeof obj.length !== 'number')) return false;
106
-
107
- // We have on object which has length property. Should we treat it as array?
108
- if (typeof obj.hasOwnProperty != 'function' &&
109
- typeof obj.constructor != 'function') {
110
- // This is here for IE8: it is a bogus object treat it as array;
111
- return true;
112
- } else {
113
- return obj instanceof JQLite || // JQLite
114
- (jQuery && obj instanceof jQuery) || // jQuery
115
- toString.call(obj) !== '[object Object]' || // some browser native object
116
- typeof obj.callee === 'function'; // arguments (on IE8 looks like regular obj)
117
- }
118
- }
119
-
120
-
121
120
  function forEach(obj, iterator, context) {
122
121
  var key;
123
122
  if (obj) {
@@ -201,6 +200,21 @@ function nextUid() {
201
200
  return uid.join('');
202
201
  }
203
202
 
203
+
204
+ /**
205
+ * Set or clear the hashkey for an object.
206
+ * @param obj object
207
+ * @param h the hashkey (!truthy to delete the hashkey)
208
+ */
209
+ function setHashKey(obj, h) {
210
+ if (h) {
211
+ obj.$$hashKey = h;
212
+ }
213
+ else {
214
+ delete obj.$$hashKey;
215
+ }
216
+ }
217
+
204
218
  /**
205
219
  * @ngdoc function
206
220
  * @name angular.extend
@@ -212,8 +226,10 @@ function nextUid() {
212
226
  *
213
227
  * @param {Object} dst Destination object.
214
228
  * @param {...Object} src Source object(s).
229
+ * @returns {Object} Reference to `dst`.
215
230
  */
216
231
  function extend(dst) {
232
+ var h = dst.$$hashKey;
217
233
  forEach(arguments, function(obj){
218
234
  if (obj !== dst) {
219
235
  forEach(obj, function(value, key){
@@ -221,6 +237,8 @@ function extend(dst) {
221
237
  });
222
238
  }
223
239
  });
240
+
241
+ setHashKey(dst,h);
224
242
  return dst;
225
243
  }
226
244
 
@@ -264,7 +282,7 @@ noop.$inject = [];
264
282
  *
265
283
  <pre>
266
284
  function transformer(transformationFn, value) {
267
- return (transformationFn || identity)(value);
285
+ return (transformationFn || angular.identity)(value);
268
286
  };
269
287
  </pre>
270
288
  */
@@ -391,6 +409,18 @@ function isArray(value) {
391
409
  function isFunction(value){return typeof value == 'function';}
392
410
 
393
411
 
412
+ /**
413
+ * Determines if a value is a regular expression object.
414
+ *
415
+ * @private
416
+ * @param {*} value Reference to check.
417
+ * @returns {boolean} True if `value` is a `RegExp`.
418
+ */
419
+ function isRegExp(value) {
420
+ return toString.apply(value) == '[object RegExp]';
421
+ }
422
+
423
+
394
424
  /**
395
425
  * Checks if `obj` is a window object.
396
426
  *
@@ -418,9 +448,20 @@ function isBoolean(value) {
418
448
  }
419
449
 
420
450
 
421
- function trim(value) {
422
- return isString(value) ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
423
- }
451
+ var trim = (function() {
452
+ // native trim is way faster: http://jsperf.com/angular-trim-test
453
+ // but IE doesn't have it... :-(
454
+ // TODO: we should move this into IE/ES5 polyfill
455
+ if (!String.prototype.trim) {
456
+ return function(value) {
457
+ return isString(value) ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
458
+ };
459
+ }
460
+ return function(value) {
461
+ return isString(value) ? value.trim() : value;
462
+ };
463
+ })();
464
+
424
465
 
425
466
  /**
426
467
  * @ngdoc function
@@ -563,6 +604,8 @@ function copy(source, destination){
563
604
  destination = copy(source, []);
564
605
  } else if (isDate(source)) {
565
606
  destination = new Date(source.getTime());
607
+ } else if (isRegExp(source)) {
608
+ destination = new RegExp(source.source);
566
609
  } else if (isObject(source)) {
567
610
  destination = copy(source, {});
568
611
  }
@@ -575,12 +618,14 @@ function copy(source, destination){
575
618
  destination.push(copy(source[i]));
576
619
  }
577
620
  } else {
621
+ var h = destination.$$hashKey;
578
622
  forEach(destination, function(value, key){
579
623
  delete destination[key];
580
624
  });
581
625
  for ( var key in source) {
582
626
  destination[key] = copy(source[key]);
583
627
  }
628
+ setHashKey(destination,h);
584
629
  }
585
630
  }
586
631
  return destination;
@@ -608,7 +653,7 @@ function shallowCopy(src, dst) {
608
653
  * @function
609
654
  *
610
655
  * @description
611
- * Determines if two objects or two values are equivalent. Supports value types, arrays and
656
+ * Determines if two objects or two values are equivalent. Supports value types, regular expressions, arrays and
612
657
  * objects.
613
658
  *
614
659
  * Two objects or values are considered equivalent if at least one of the following is true:
@@ -616,11 +661,14 @@ function shallowCopy(src, dst) {
616
661
  * * Both objects or values pass `===` comparison.
617
662
  * * Both objects or values are of the same type and all of their properties pass `===` comparison.
618
663
  * * Both values are NaN. (In JavasScript, NaN == NaN => false. But we consider two NaN as equal)
664
+ * * Both values represent the same regular expression (In JavasScript,
665
+ * /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual
666
+ * representation matches).
619
667
  *
620
668
  * During a property comparision, properties of `function` type and properties with names
621
669
  * that begin with `$` are ignored.
622
670
  *
623
- * Scope and DOMWindow objects are being compared only be identify (`===`).
671
+ * Scope and DOMWindow objects are being compared only by identify (`===`).
624
672
  *
625
673
  * @param {*} o1 Object or value to compare.
626
674
  * @param {*} o2 Object or value to compare.
@@ -634,6 +682,7 @@ function equals(o1, o2) {
634
682
  if (t1 == t2) {
635
683
  if (t1 == 'object') {
636
684
  if (isArray(o1)) {
685
+ if (!isArray(o2)) return false;
637
686
  if ((length = o1.length) == o2.length) {
638
687
  for(key=0; key<length; key++) {
639
688
  if (!equals(o1[key], o2[key])) return false;
@@ -642,8 +691,10 @@ function equals(o1, o2) {
642
691
  }
643
692
  } else if (isDate(o1)) {
644
693
  return isDate(o2) && o1.getTime() == o2.getTime();
694
+ } else if (isRegExp(o1) && isRegExp(o2)) {
695
+ return o1.toString() == o2.toString();
645
696
  } else {
646
- if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2)) return false;
697
+ if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) || isArray(o2)) return false;
647
698
  keySet = {};
648
699
  for(key in o1) {
649
700
  if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
@@ -680,7 +731,7 @@ function sliceArgs(args, startIndex) {
680
731
  *
681
732
  * @description
682
733
  * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for
683
- * `fn`). You can supply optional `args` that are are prebound to the function. This feature is also
734
+ * `fn`). You can supply optional `args` that are prebound to the function. This feature is also
684
735
  * known as [function currying](http://en.wikipedia.org/wiki/Currying).
685
736
  *
686
737
  * @param {Object} self Context which `fn` should be evaluated in.
@@ -732,13 +783,15 @@ function toJsonReplacer(key, value) {
732
783
  * @function
733
784
  *
734
785
  * @description
735
- * Serializes input into a JSON-formatted string.
786
+ * Serializes input into a JSON-formatted string. Properties with leading $ characters will be
787
+ * stripped since angular uses this notation internally.
736
788
  *
737
789
  * @param {Object|Array|Date|string|number} obj Input to be serialized into JSON.
738
790
  * @param {boolean=} pretty If set to true, the JSON output will contain newlines and whitespace.
739
- * @returns {string} Jsonified string representing `obj`.
791
+ * @returns {string|undefined} Jsonified string representing `obj`.
740
792
  */
741
793
  function toJson(obj, pretty) {
794
+ if (typeof obj === 'undefined') return undefined;
742
795
  return JSON.stringify(obj, toJsonReplacer, pretty ? ' ' : null);
743
796
  }
744
797
 
@@ -798,6 +851,23 @@ function startingTag(element) {
798
851
 
799
852
  /////////////////////////////////////////////////
800
853
 
854
+ /**
855
+ * Tries to decode the URI component without throwing an exception.
856
+ *
857
+ * @private
858
+ * @param str value potential URI component to check.
859
+ * @returns {boolean} True if `value` can be decoded
860
+ * with the decodeURIComponent function.
861
+ */
862
+ function tryDecodeURIComponent(value) {
863
+ try {
864
+ return decodeURIComponent(value);
865
+ } catch(e) {
866
+ // Ignore any invalid uri component
867
+ }
868
+ }
869
+
870
+
801
871
  /**
802
872
  * Parses an escaped url query string into key-value pairs.
803
873
  * @returns Object.<(string|boolean)>
@@ -805,10 +875,12 @@ function startingTag(element) {
805
875
  function parseKeyValue(/**string*/keyValue) {
806
876
  var obj = {}, key_value, key;
807
877
  forEach((keyValue || "").split('&'), function(keyValue){
808
- if (keyValue) {
878
+ if ( keyValue ) {
809
879
  key_value = keyValue.split('=');
810
- key = decodeURIComponent(key_value[0]);
811
- obj[key] = isDefined(key_value[1]) ? decodeURIComponent(key_value[1]) : true;
880
+ key = tryDecodeURIComponent(key_value[0]);
881
+ if ( isDefined(key) ) {
882
+ obj[key] = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
883
+ }
812
884
  }
813
885
  });
814
886
  return obj;
@@ -873,11 +945,15 @@ function encodeUriQuery(val, pctEncodeSpaces) {
873
945
  *
874
946
  * @description
875
947
  *
876
- * Use this directive to auto-bootstrap on application. Only
877
- * one directive can be used per HTML document. The directive
948
+ * Use this directive to auto-bootstrap an application. Only
949
+ * one ngApp directive can be used per HTML document. The directive
878
950
  * designates the root of the application and is typically placed
879
951
  * at the root of the page.
880
952
  *
953
+ * The first ngApp found in the document will be auto-bootstrapped. To use multiple applications in an
954
+ * HTML document you must manually bootstrap them using {@link angular.bootstrap}.
955
+ * Applications cannot be nested.
956
+ *
881
957
  * In the example below if the `ngApp` directive would not be placed
882
958
  * on the `html` element then the document would not be compiled
883
959
  * and the `{{ 1+2 }}` would not be resolved to `3`.
@@ -943,12 +1019,15 @@ function angularInit(element, bootstrap) {
943
1019
  *
944
1020
  * See: {@link guide/bootstrap Bootstrap}
945
1021
  *
1022
+ * Note that ngScenario-based end-to-end tests cannot use this function to bootstrap manually.
1023
+ * They must use {@link api/ng.directive:ngApp ngApp}.
1024
+ *
946
1025
  * @param {Element} element DOM element which is the root of angular application.
947
1026
  * @param {Array<String|Function>=} modules an array of module declarations. See: {@link angular.module modules}
948
1027
  * @returns {AUTO.$injector} Returns the newly created injector for this app.
949
1028
  */
950
1029
  function bootstrap(element, modules) {
951
- var resumeBootstrapInternal = function() {
1030
+ var doBootstrap = function() {
952
1031
  element = jqLite(element);
953
1032
  modules = modules || [];
954
1033
  modules.unshift(['$provide', function($provide) {
@@ -970,7 +1049,7 @@ function bootstrap(element, modules) {
970
1049
  var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;
971
1050
 
972
1051
  if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
973
- return resumeBootstrapInternal();
1052
+ return doBootstrap();
974
1053
  }
975
1054
 
976
1055
  window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
@@ -978,7 +1057,7 @@ function bootstrap(element, modules) {
978
1057
  forEach(extraModules, function(module) {
979
1058
  modules.push(module);
980
1059
  });
981
- resumeBootstrapInternal();
1060
+ doBootstrap();
982
1061
  };
983
1062
  }
984
1063
 
@@ -1002,9 +1081,10 @@ function bindJQuery() {
1002
1081
  injector: JQLitePrototype.injector,
1003
1082
  inheritedData: JQLitePrototype.inheritedData
1004
1083
  });
1005
- JQLitePatchJQueryRemove('remove', true);
1006
- JQLitePatchJQueryRemove('empty');
1007
- JQLitePatchJQueryRemove('html');
1084
+ // Method signature: JQLitePatchJQueryRemove(name, dispatchThis, filterElems, getterIfNoArguments)
1085
+ JQLitePatchJQueryRemove('remove', true, true, false);
1086
+ JQLitePatchJQueryRemove('empty', false, false, false);
1087
+ JQLitePatchJQueryRemove('html', false, false, true);
1008
1088
  } else {
1009
1089
  jqLite = JQLite;
1010
1090
  }
@@ -1012,7 +1092,7 @@ function bindJQuery() {
1012
1092
  }
1013
1093
 
1014
1094
  /**
1015
- * throw error of the argument is falsy.
1095
+ * throw error if the argument is falsy.
1016
1096
  */
1017
1097
  function assertArg(arg, name, reason) {
1018
1098
  if (!arg) {
@@ -1031,6 +1111,33 @@ function assertArgFn(arg, name, acceptArrayAnnotation) {
1031
1111
  return arg;
1032
1112
  }
1033
1113
 
1114
+ /**
1115
+ * Return the value accessible from the object by path. Any undefined traversals are ignored
1116
+ * @param {Object} obj starting object
1117
+ * @param {string} path path to traverse
1118
+ * @param {boolean=true} bindFnToScope
1119
+ * @returns value as accessible by path
1120
+ */
1121
+ //TODO(misko): this function needs to be removed
1122
+ function getter(obj, path, bindFnToScope) {
1123
+ if (!path) return obj;
1124
+ var keys = path.split('.');
1125
+ var key;
1126
+ var lastInstance = obj;
1127
+ var len = keys.length;
1128
+
1129
+ for (var i = 0; i < len; i++) {
1130
+ key = keys[i];
1131
+ if (obj) {
1132
+ obj = (lastInstance = obj)[key];
1133
+ }
1134
+ }
1135
+ if (!bindFnToScope && isFunction(obj)) {
1136
+ return bind(lastInstance, obj);
1137
+ }
1138
+ return obj;
1139
+ }
1140
+
1034
1141
  /**
1035
1142
  * @ngdoc interface
1036
1143
  * @name angular.Module
@@ -1061,8 +1168,8 @@ function setupModuleLoader(window) {
1061
1168
  *
1062
1169
  * # Module
1063
1170
  *
1064
- * A module is a collocation of services, directives, filters, and configuration information. Module
1065
- * is used to configure the {@link AUTO.$injector $injector}.
1171
+ * A module is a collection of services, directives, filters, and configuration information.
1172
+ * `angular.module` is used to configure the {@link AUTO.$injector $injector}.
1066
1173
  *
1067
1174
  * <pre>
1068
1175
  * // Create a new module
@@ -1293,11 +1400,11 @@ function setupModuleLoader(window) {
1293
1400
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
1294
1401
  */
1295
1402
  var version = {
1296
- full: '1.0.6', // all of these placeholder strings will be replaced by grunt's
1403
+ full: '1.0.8', // all of these placeholder strings will be replaced by grunt's
1297
1404
  major: 1, // package task
1298
1405
  minor: 0,
1299
- dot: 6,
1300
- codeName: 'universal-irreversibility'
1406
+ dot: 8,
1407
+ codeName: 'bubble-burst'
1301
1408
  };
1302
1409
 
1303
1410
 
@@ -1366,7 +1473,6 @@ function publishExternalAPI(angular){
1366
1473
  ngPluralize: ngPluralizeDirective,
1367
1474
  ngRepeat: ngRepeatDirective,
1368
1475
  ngShow: ngShowDirective,
1369
- ngSubmit: ngSubmitDirective,
1370
1476
  ngStyle: ngStyleDirective,
1371
1477
  ngSwitch: ngSwitchDirective,
1372
1478
  ngSwitchWhen: ngSwitchWhenDirective,
@@ -1436,24 +1542,25 @@ function publishExternalAPI(angular){
1436
1542
  * Note: All element references in Angular are always wrapped with jQuery or jqLite; they are never
1437
1543
  * raw DOM references.
1438
1544
  *
1439
- * ## Angular's jQuery lite provides the following methods:
1545
+ * ## Angular's jqLite
1546
+ * Angular's lite version of jQuery provides only the following jQuery methods:
1440
1547
  *
1441
1548
  * - [addClass()](http://api.jquery.com/addClass/)
1442
1549
  * - [after()](http://api.jquery.com/after/)
1443
1550
  * - [append()](http://api.jquery.com/append/)
1444
1551
  * - [attr()](http://api.jquery.com/attr/)
1445
- * - [bind()](http://api.jquery.com/bind/)
1446
- * - [children()](http://api.jquery.com/children/)
1552
+ * - [bind()](http://api.jquery.com/bind/) - Does not support namespaces
1553
+ * - [children()](http://api.jquery.com/children/) - Does not support selectors
1447
1554
  * - [clone()](http://api.jquery.com/clone/)
1448
1555
  * - [contents()](http://api.jquery.com/contents/)
1449
1556
  * - [css()](http://api.jquery.com/css/)
1450
1557
  * - [data()](http://api.jquery.com/data/)
1451
1558
  * - [eq()](http://api.jquery.com/eq/)
1452
- * - [find()](http://api.jquery.com/find/) - Limited to lookups by tag name.
1559
+ * - [find()](http://api.jquery.com/find/) - Limited to lookups by tag name
1453
1560
  * - [hasClass()](http://api.jquery.com/hasClass/)
1454
1561
  * - [html()](http://api.jquery.com/html/)
1455
- * - [next()](http://api.jquery.com/next/)
1456
- * - [parent()](http://api.jquery.com/parent/)
1562
+ * - [next()](http://api.jquery.com/next/) - Does not support selectors
1563
+ * - [parent()](http://api.jquery.com/parent/) - Does not support selectors
1457
1564
  * - [prepend()](http://api.jquery.com/prepend/)
1458
1565
  * - [prop()](http://api.jquery.com/prop/)
1459
1566
  * - [ready()](http://api.jquery.com/ready/)
@@ -1465,12 +1572,18 @@ function publishExternalAPI(angular){
1465
1572
  * - [text()](http://api.jquery.com/text/)
1466
1573
  * - [toggleClass()](http://api.jquery.com/toggleClass/)
1467
1574
  * - [triggerHandler()](http://api.jquery.com/triggerHandler/) - Doesn't pass native event objects to handlers.
1468
- * - [unbind()](http://api.jquery.com/unbind/)
1575
+ * - [unbind()](http://api.jquery.com/unbind/) - Does not support namespaces
1469
1576
  * - [val()](http://api.jquery.com/val/)
1470
1577
  * - [wrap()](http://api.jquery.com/wrap/)
1471
1578
  *
1472
- * ## In addtion to the above, Angular provides additional methods to both jQuery and jQuery lite:
1579
+ * ## jQuery/jqLite Extras
1580
+ * Angular also provides the following additional methods and events to both jQuery and jqLite:
1473
1581
  *
1582
+ * ### Events
1583
+ * - `$destroy` - AngularJS intercepts all jqLite/jQuery's DOM destruction apis and fires this event
1584
+ * on all DOM nodes being removed. This can be used to clean up and 3rd party bindings to the DOM
1585
+ * element before it is removed.
1586
+ * ### Methods
1474
1587
  * - `controller(name)` - retrieves the controller of the current element or its parent. By default
1475
1588
  * retrieves controller associated with the `ngController` directive. If `name` is provided as
1476
1589
  * camelCase directive name, then the controller for this directive will be retrieved (e.g.
@@ -1517,37 +1630,38 @@ function camelCase(name) {
1517
1630
  /////////////////////////////////////////////
1518
1631
  // jQuery mutation patch
1519
1632
  //
1520
- // In conjunction with bindJQuery intercepts all jQuery's DOM destruction apis and fires a
1633
+ // In conjunction with bindJQuery intercepts all jQuery's DOM destruction apis and fires a
1521
1634
  // $destroy event on all DOM nodes being removed.
1522
1635
  //
1523
1636
  /////////////////////////////////////////////
1524
1637
 
1525
- function JQLitePatchJQueryRemove(name, dispatchThis) {
1638
+ function JQLitePatchJQueryRemove(name, dispatchThis, filterElems, getterIfNoArguments) {
1526
1639
  var originalJqFn = jQuery.fn[name];
1527
1640
  originalJqFn = originalJqFn.$original || originalJqFn;
1528
1641
  removePatch.$original = originalJqFn;
1529
1642
  jQuery.fn[name] = removePatch;
1530
1643
 
1531
- function removePatch() {
1532
- var list = [this],
1644
+ function removePatch(param) {
1645
+ var list = filterElems && param ? [this.filter(param)] : [this],
1533
1646
  fireEvent = dispatchThis,
1534
1647
  set, setIndex, setLength,
1535
- element, childIndex, childLength, children,
1536
- fns, events;
1537
-
1538
- while(list.length) {
1539
- set = list.shift();
1540
- for(setIndex = 0, setLength = set.length; setIndex < setLength; setIndex++) {
1541
- element = jqLite(set[setIndex]);
1542
- if (fireEvent) {
1543
- element.triggerHandler('$destroy');
1544
- } else {
1545
- fireEvent = !fireEvent;
1546
- }
1547
- for(childIndex = 0, childLength = (children = element.children()).length;
1548
- childIndex < childLength;
1549
- childIndex++) {
1550
- list.push(jQuery(children[childIndex]));
1648
+ element, childIndex, childLength, children;
1649
+
1650
+ if (!getterIfNoArguments || param != null) {
1651
+ while(list.length) {
1652
+ set = list.shift();
1653
+ for(setIndex = 0, setLength = set.length; setIndex < setLength; setIndex++) {
1654
+ element = jqLite(set[setIndex]);
1655
+ if (fireEvent) {
1656
+ element.triggerHandler('$destroy');
1657
+ } else {
1658
+ fireEvent = !fireEvent;
1659
+ }
1660
+ for(childIndex = 0, childLength = (children = element.children()).length;
1661
+ childIndex < childLength;
1662
+ childIndex++) {
1663
+ list.push(jQuery(children[childIndex]));
1664
+ }
1551
1665
  }
1552
1666
  }
1553
1667
  }
@@ -1607,7 +1721,7 @@ function JQLiteUnbind(element, type, fn) {
1607
1721
  removeEventListenerFn(element, type, events[type]);
1608
1722
  delete events[type];
1609
1723
  } else {
1610
- arrayRemove(events[type], fn);
1724
+ arrayRemove(events[type] || [], fn);
1611
1725
  }
1612
1726
  }
1613
1727
  }
@@ -1881,6 +1995,15 @@ forEach({
1881
1995
 
1882
1996
  val: function(element, value) {
1883
1997
  if (isUndefined(value)) {
1998
+ if (nodeName_(element) === 'SELECT' && element.multiple) {
1999
+ var result = [];
2000
+ forEach(element.options, function (option) {
2001
+ if (option.selected) {
2002
+ result.push(option.value || option.text);
2003
+ }
2004
+ });
2005
+ return result.length === 0 ? null : result;
2006
+ }
1884
2007
  return element.value;
1885
2008
  }
1886
2009
  element.value = value;
@@ -2012,23 +2135,43 @@ forEach({
2012
2135
 
2013
2136
  if (!eventFns) {
2014
2137
  if (type == 'mouseenter' || type == 'mouseleave') {
2015
- var counter = 0;
2138
+ var contains = document.body.contains || document.body.compareDocumentPosition ?
2139
+ function( a, b ) {
2140
+ var adown = a.nodeType === 9 ? a.documentElement : a,
2141
+ bup = b && b.parentNode;
2142
+ return a === bup || !!( bup && bup.nodeType === 1 && (
2143
+ adown.contains ?
2144
+ adown.contains( bup ) :
2145
+ a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
2146
+ ));
2147
+ } :
2148
+ function( a, b ) {
2149
+ if ( b ) {
2150
+ while ( (b = b.parentNode) ) {
2151
+ if ( b === a ) {
2152
+ return true;
2153
+ }
2154
+ }
2155
+ }
2156
+ return false;
2157
+ };
2016
2158
 
2017
- events.mouseenter = [];
2018
- events.mouseleave = [];
2159
+ events[type] = [];
2160
+
2161
+ // Refer to jQuery's implementation of mouseenter & mouseleave
2162
+ // Read about mouseenter and mouseleave:
2163
+ // http://www.quirksmode.org/js/events_mouse.html#link8
2164
+ var eventmap = { mouseleave : "mouseout", mouseenter : "mouseover"}
2165
+ bindFn(element, eventmap[type], function(event) {
2166
+ var ret, target = this, related = event.relatedTarget;
2167
+ // For mousenter/leave call the handler if related is outside the target.
2168
+ // NB: No relatedTarget if the mouse left/entered the browser window
2169
+ if ( !related || (related !== target && !contains(target, related)) ){
2170
+ handle(event, type);
2171
+ }
2019
2172
 
2020
- bindFn(element, 'mouseover', function(event) {
2021
- counter++;
2022
- if (counter == 1) {
2023
- handle(event, 'mouseenter');
2024
- }
2025
- });
2026
- bindFn(element, 'mouseout', function(event) {
2027
- counter --;
2028
- if (counter == 0) {
2029
- handle(event, 'mouseleave');
2030
- }
2031
2173
  });
2174
+
2032
2175
  } else {
2033
2176
  addEventListenerFn(element, type, handle);
2034
2177
  events[type] = [];
@@ -2078,12 +2221,7 @@ forEach({
2078
2221
  if (element.nodeType === 1) {
2079
2222
  var index = element.firstChild;
2080
2223
  forEach(new JQLite(node), function(child){
2081
- if (index) {
2082
- element.insertBefore(child, index);
2083
- } else {
2084
- element.appendChild(child);
2085
- index = child;
2086
- }
2224
+ element.insertBefore(child, index);
2087
2225
  });
2088
2226
  }
2089
2227
  },
@@ -2344,7 +2482,7 @@ function annotate(fn) {
2344
2482
  }
2345
2483
  } else if (isArray(fn)) {
2346
2484
  last = fn.length - 1;
2347
- assertArgFn(fn[last], 'fn')
2485
+ assertArgFn(fn[last], 'fn');
2348
2486
  $inject = fn.slice(0, last);
2349
2487
  } else {
2350
2488
  assertArgFn(fn, 'fn', true);
@@ -2378,7 +2516,7 @@ function annotate(fn) {
2378
2516
  * # Injection Function Annotation
2379
2517
  *
2380
2518
  * JavaScript does not have annotations, and annotations are needed for dependency injection. The
2381
- * following ways are all valid way of annotating function with injection arguments and are equivalent.
2519
+ * following are all valid ways of annotating function with injection arguments and are equivalent.
2382
2520
  *
2383
2521
  * <pre>
2384
2522
  * // inferred (only works if code not minified/obfuscated)
@@ -2507,7 +2645,7 @@ function annotate(fn) {
2507
2645
  * // ...
2508
2646
  * };
2509
2647
  * tmpFn.$inject = ['$compile', '$rootScope'];
2510
- * injector.invoke(tempFn);
2648
+ * injector.invoke(tmpFn);
2511
2649
  *
2512
2650
  * // To better support inline function the inline annotation is supported
2513
2651
  * injector.invoke(['$compile', '$rootScope', function(obfCompile, obfRootScope) {
@@ -2560,7 +2698,7 @@ function annotate(fn) {
2560
2698
  *
2561
2699
  * beforeEach(module(function($provide) {
2562
2700
  * $provide.provider('greet', GreetProvider);
2563
- * });
2701
+ * }));
2564
2702
  *
2565
2703
  * it('should greet', inject(function(greet) {
2566
2704
  * expect(greet('angular')).toEqual('Hello angular!');
@@ -2573,9 +2711,7 @@ function annotate(fn) {
2573
2711
  * inject(function(greet) {
2574
2712
  * expect(greet('angular')).toEqual('Ahoj angular!');
2575
2713
  * });
2576
- * )};
2577
- *
2578
- * });
2714
+ * });
2579
2715
  * </pre>
2580
2716
  */
2581
2717
 
@@ -2669,7 +2805,7 @@ function annotate(fn) {
2669
2805
  *
2670
2806
  * @param {string} name The name of the service to decorate.
2671
2807
  * @param {function()} decorator This function will be invoked when the service needs to be
2672
- * instanciated. The function is called using the {@link AUTO.$injector#invoke
2808
+ * instantiated. The function is called using the {@link AUTO.$injector#invoke
2673
2809
  * injector.invoke} method and is therefore fully injectable. Local injection arguments:
2674
2810
  *
2675
2811
  * * `$delegate` - The original service instance, which can be monkey patched, configured,
@@ -2869,6 +3005,8 @@ function createInjector(modulesToLoad) {
2869
3005
  var Constructor = function() {},
2870
3006
  instance, returnedValue;
2871
3007
 
3008
+ // Check if Type is annotated and use just the given function at n-1 as parameter
3009
+ // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);
2872
3010
  Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Type).prototype;
2873
3011
  instance = new Constructor();
2874
3012
  returnedValue = invoke(Type, instance, locals);
@@ -3076,7 +3214,8 @@ function Browser(window, document, $log, $sniffer) {
3076
3214
  //////////////////////////////////////////////////////////////
3077
3215
 
3078
3216
  var lastBrowserUrl = location.href,
3079
- baseElement = document.find('base');
3217
+ baseElement = document.find('base'),
3218
+ replacedUrl = null;
3080
3219
 
3081
3220
  /**
3082
3221
  * @name ng.$browser#url
@@ -3111,14 +3250,21 @@ function Browser(window, document, $log, $sniffer) {
3111
3250
  baseElement.attr('href', baseElement.attr('href'));
3112
3251
  }
3113
3252
  } else {
3114
- if (replace) location.replace(url);
3115
- else location.href = url;
3253
+ if (replace) {
3254
+ location.replace(url);
3255
+ replacedUrl = url;
3256
+ } else {
3257
+ location.href = url;
3258
+ replacedUrl = null;
3259
+ }
3116
3260
  }
3117
3261
  return self;
3118
3262
  // getter
3119
3263
  } else {
3120
- // the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172
3121
- return location.href.replace(/%27/g,"'");
3264
+ // - the replacedUrl is a workaround for an IE8-9 issue with location.replace method that doesn't update
3265
+ // location.href synchronously
3266
+ // - the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172
3267
+ return replacedUrl || location.href.replace(/%27/g,"'");
3122
3268
  }
3123
3269
  };
3124
3270
 
@@ -3249,7 +3395,13 @@ function Browser(window, document, $log, $sniffer) {
3249
3395
  cookie = cookieArray[i];
3250
3396
  index = cookie.indexOf('=');
3251
3397
  if (index > 0) { //ignore nameless cookies
3252
- lastCookies[unescape(cookie.substring(0, index))] = unescape(cookie.substring(index + 1));
3398
+ var name = unescape(cookie.substring(0, index));
3399
+ // the first value that is seen for a cookie is the most
3400
+ // specific one. values for the same cookie name that
3401
+ // follow are for less specific paths.
3402
+ if (lastCookies[name] === undefined) {
3403
+ lastCookies[name] = unescape(cookie.substring(index + 1));
3404
+ }
3253
3405
  }
3254
3406
  }
3255
3407
  }
@@ -3319,7 +3471,20 @@ function $BrowserProvider(){
3319
3471
  * @name ng.$cacheFactory
3320
3472
  *
3321
3473
  * @description
3322
- * Factory that constructs cache objects.
3474
+ * Factory that constructs cache objects and gives access to them.
3475
+ *
3476
+ * <pre>
3477
+ *
3478
+ * var cache = $cacheFactory('cacheId');
3479
+ * expect($cacheFactory.get('cacheId')).toBe(cache);
3480
+ * expect($cacheFactory.get('noSuchCacheId')).not.toBeDefined();
3481
+ *
3482
+ * cache.put("key", "value");
3483
+ * cache.put("another key", "another value");
3484
+ *
3485
+ * expect(cache.info()).toEqual({id: 'cacheId', size: 2}); // Since we've specified no options on creation
3486
+ *
3487
+ * </pre>
3323
3488
  *
3324
3489
  *
3325
3490
  * @param {string} cacheId Name or id of the newly created cache.
@@ -3451,6 +3616,16 @@ function $CacheFactoryProvider() {
3451
3616
  }
3452
3617
 
3453
3618
 
3619
+ /**
3620
+ * @ngdoc method
3621
+ * @name ng.$cacheFactory#info
3622
+ * @methodOf ng.$cacheFactory
3623
+ *
3624
+ * @description
3625
+ * Get information about all the of the caches that have been created
3626
+ *
3627
+ * @returns {Object} - key-value map of `cacheId` to the result of calling `cache#info`
3628
+ */
3454
3629
  cacheFactory.info = function() {
3455
3630
  var info = {};
3456
3631
  forEach(caches, function(cache, cacheId) {
@@ -3460,6 +3635,17 @@ function $CacheFactoryProvider() {
3460
3635
  };
3461
3636
 
3462
3637
 
3638
+ /**
3639
+ * @ngdoc method
3640
+ * @name ng.$cacheFactory#get
3641
+ * @methodOf ng.$cacheFactory
3642
+ *
3643
+ * @description
3644
+ * Get access to a cache object by the `cacheId` used when it was created.
3645
+ *
3646
+ * @param {string} cacheId Name or id of a cache to access.
3647
+ * @returns {object} Cache object identified by the cacheId or undefined if no such cache.
3648
+ */
3463
3649
  cacheFactory.get = function(cacheId) {
3464
3650
  return caches[cacheId];
3465
3651
  };
@@ -3474,8 +3660,44 @@ function $CacheFactoryProvider() {
3474
3660
  * @name ng.$templateCache
3475
3661
  *
3476
3662
  * @description
3477
- * Cache used for storing html templates.
3478
- *
3663
+ * The first time a template is used, it is loaded in the template cache for quick retrieval. You can
3664
+ * load templates directly into the cache in a `script` tag, or by consuming the `$templateCache`
3665
+ * service directly.
3666
+ *
3667
+ * Adding via the `script` tag:
3668
+ * <pre>
3669
+ * <html ng-app>
3670
+ * <head>
3671
+ * <script type="text/ng-template" id="templateId.html">
3672
+ * This is the content of the template
3673
+ * </script>
3674
+ * </head>
3675
+ * ...
3676
+ * </html>
3677
+ * </pre>
3678
+ *
3679
+ * **Note:** the `script` tag containing the template does not need to be included in the `head` of the document, but
3680
+ * it must be below the `ng-app` definition.
3681
+ *
3682
+ * Adding via the $templateCache service:
3683
+ *
3684
+ * <pre>
3685
+ * var myApp = angular.module('myApp', []);
3686
+ * myApp.run(function($templateCache) {
3687
+ * $templateCache.put('templateId.html', 'This is the content of the template');
3688
+ * });
3689
+ * </pre>
3690
+ *
3691
+ * To retrieve the template later, simply use it in your HTML:
3692
+ * <pre>
3693
+ * <div ng-include=" 'templateId.html' "></div>
3694
+ * </pre>
3695
+ *
3696
+ * or get it via Javascript:
3697
+ * <pre>
3698
+ * $templateCache.get('templateId.html')
3699
+ * </pre>
3700
+ *
3479
3701
  * See {@link ng.$cacheFactory $cacheFactory}.
3480
3702
  *
3481
3703
  */
@@ -3651,11 +3873,11 @@ function $CompileProvider($provide) {
3651
3873
  * @function
3652
3874
  *
3653
3875
  * @description
3654
- * Register a new directives with the compiler.
3876
+ * Register a new directive with the compiler.
3655
3877
  *
3656
3878
  * @param {string} name Name of the directive in camel-case. (ie <code>ngBind</code> which will match as
3657
3879
  * <code>ng-bind</code>).
3658
- * @param {function} directiveFactory An injectable directive factroy function. See {@link guide/directive} for more
3880
+ * @param {function|Array} directiveFactory An injectable directive factory function. See {@link guide/directive} for more
3659
3881
  * info.
3660
3882
  * @returns {ng.$compileProvider} Self for chaining.
3661
3883
  */
@@ -3778,7 +4000,7 @@ function $CompileProvider($provide) {
3778
4000
 
3779
4001
  // href property always returns normalized absolute url, so we can match against that
3780
4002
  normalizedVal = urlSanitizationNode.href;
3781
- if (!normalizedVal.match(urlSanitizationWhitelist)) {
4003
+ if (normalizedVal !== '' && !normalizedVal.match(urlSanitizationWhitelist)) {
3782
4004
  this[key] = value = 'unsafe:' + normalizedVal;
3783
4005
  }
3784
4006
  }
@@ -4002,7 +4224,7 @@ function $CompileProvider($provide) {
4002
4224
  for (var attr, name, nName, value, nAttrs = node.attributes,
4003
4225
  j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) {
4004
4226
  attr = nAttrs[j];
4005
- if (attr.specified) {
4227
+ if (!msie || msie >= 8 || attr.specified) {
4006
4228
  name = attr.name;
4007
4229
  nName = directiveNormalize(name.toLowerCase());
4008
4230
  attrsMap[nName] = name;
@@ -4054,9 +4276,9 @@ function $CompileProvider($provide) {
4054
4276
 
4055
4277
 
4056
4278
  /**
4057
- * Once the directives have been collected their compile functions is executed. This method
4279
+ * Once the directives have been collected, their compile functions are executed. This method
4058
4280
  * is responsible for inlining directive templates as well as terminating the application
4059
- * of the directives if the terminal directive has been reached..
4281
+ * of the directives if the terminal directive has been reached.
4060
4282
  *
4061
4283
  * @param {Array} directives Array of collected directives to execute their compile function.
4062
4284
  * this needs to be pre-sorted by priority order.
@@ -4064,11 +4286,11 @@ function $CompileProvider($provide) {
4064
4286
  * @param {Object} templateAttrs The shared attribute function
4065
4287
  * @param {function(angular.Scope[, cloneAttachFn]} transcludeFn A linking function, where the
4066
4288
  * scope argument is auto-generated to the new child of the transcluded parent scope.
4067
- * @param {DOMElement} $rootElement If we are working on the root of the compile tree then this
4068
- * argument has the root jqLite array so that we can replace widgets on it.
4289
+ * @param {JQLite} jqCollection If we are working on the root of the compile tree then this
4290
+ * argument has the root jqLite array so that we can replace nodes on it.
4069
4291
  * @returns linkFn
4070
4292
  */
4071
- function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn, $rootElement) {
4293
+ function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn, jqCollection) {
4072
4294
  var terminalPriority = -Number.MAX_VALUE,
4073
4295
  preLinkFns = [],
4074
4296
  postLinkFns = [],
@@ -4122,7 +4344,7 @@ function $CompileProvider($provide) {
4122
4344
  $compileNode = templateAttrs.$$element =
4123
4345
  jqLite(document.createComment(' ' + directiveName + ': ' + templateAttrs[directiveName] + ' '));
4124
4346
  compileNode = $compileNode[0];
4125
- replaceWith($rootElement, jqLite($template[0]), compileNode);
4347
+ replaceWith(jqCollection, jqLite($template[0]), compileNode);
4126
4348
  childTranscludeFn = compile($template, transcludeFn, terminalPriority);
4127
4349
  } else {
4128
4350
  $template = jqLite(JQLiteClone(compileNode)).contents();
@@ -4146,7 +4368,7 @@ function $CompileProvider($provide) {
4146
4368
  throw new Error(MULTI_ROOT_TEMPLATE_ERROR + directiveValue);
4147
4369
  }
4148
4370
 
4149
- replaceWith($rootElement, $compileNode, compileNode);
4371
+ replaceWith(jqCollection, $compileNode, compileNode);
4150
4372
 
4151
4373
  var newTemplateAttrs = {$attr: {}};
4152
4374
 
@@ -4174,7 +4396,7 @@ function $CompileProvider($provide) {
4174
4396
  assertNoDuplicate('template', templateDirective, directive, $compileNode);
4175
4397
  templateDirective = directive;
4176
4398
  nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i),
4177
- nodeLinkFn, $compileNode, templateAttrs, $rootElement, directive.replace,
4399
+ nodeLinkFn, $compileNode, templateAttrs, jqCollection, directive.replace,
4178
4400
  childTranscludeFn);
4179
4401
  ii = directives.length;
4180
4402
  } else if (directive.compile) {
@@ -4307,7 +4529,7 @@ function $CompileProvider($provide) {
4307
4529
  parentGet = $parse(attrs[attrName]);
4308
4530
  scope[scopeName] = function(locals) {
4309
4531
  return parentGet(parentScope, locals);
4310
- }
4532
+ };
4311
4533
  break;
4312
4534
  }
4313
4535
 
@@ -4795,7 +5017,7 @@ function $DocumentProvider(){
4795
5017
  *
4796
5018
  */
4797
5019
  function $ExceptionHandlerProvider() {
4798
- this.$get = ['$log', function($log){
5020
+ this.$get = ['$log', function($log) {
4799
5021
  return function(exception, cause) {
4800
5022
  $log.error.apply($log, arguments);
4801
5023
  };
@@ -5560,6 +5782,10 @@ function $LocationProvider(){
5560
5782
  // update $location when $browser url changes
5561
5783
  $browser.onUrlChange(function(newUrl) {
5562
5784
  if ($location.absUrl() != newUrl) {
5785
+ if ($rootScope.$broadcast('$locationChangeStart', newUrl, $location.absUrl()).defaultPrevented) {
5786
+ $browser.url($location.absUrl());
5787
+ return;
5788
+ }
5563
5789
  $rootScope.$evalAsync(function() {
5564
5790
  var oldUrl = $location.absUrl();
5565
5791
 
@@ -5868,10 +6094,10 @@ function lex(text, csp){
5868
6094
  function readIdent() {
5869
6095
  var ident = "",
5870
6096
  start = index,
5871
- lastDot, peekIndex, methodName;
6097
+ lastDot, peekIndex, methodName, ch;
5872
6098
 
5873
6099
  while (index < text.length) {
5874
- var ch = text.charAt(index);
6100
+ ch = text.charAt(index);
5875
6101
  if (ch == '.' || isIdent(ch) || isNumber(ch)) {
5876
6102
  if (ch == '.') lastDot = index;
5877
6103
  ident += ch;
@@ -5885,7 +6111,7 @@ function lex(text, csp){
5885
6111
  if (lastDot) {
5886
6112
  peekIndex = index;
5887
6113
  while(peekIndex < text.length) {
5888
- var ch = text.charAt(peekIndex);
6114
+ ch = text.charAt(peekIndex);
5889
6115
  if (ch == '(') {
5890
6116
  methodName = ident.substr(lastDot - start + 1);
5891
6117
  ident = ident.substr(0, lastDot - start);
@@ -6138,8 +6364,8 @@ function parser(text, json, $filter, csp){
6138
6364
  text.substring(0, token.index) + "] can not be assigned to", token);
6139
6365
  }
6140
6366
  right = logicalOR();
6141
- return function(self, locals){
6142
- return left.assign(self, right(self, locals), locals);
6367
+ return function(scope, locals){
6368
+ return left.assign(scope, right(scope, locals), locals);
6143
6369
  };
6144
6370
  } else {
6145
6371
  return left;
@@ -6256,12 +6482,12 @@ function parser(text, json, $filter, csp){
6256
6482
  var field = expect().text;
6257
6483
  var getter = getterFn(field, csp);
6258
6484
  return extend(
6259
- function(self, locals) {
6260
- return getter(object(self, locals), locals);
6485
+ function(scope, locals, self) {
6486
+ return getter(self || object(scope, locals), locals);
6261
6487
  },
6262
6488
  {
6263
- assign:function(self, value, locals) {
6264
- return setter(object(self, locals), field, value);
6489
+ assign:function(scope, value, locals) {
6490
+ return setter(object(scope, locals), field, value);
6265
6491
  }
6266
6492
  }
6267
6493
  );
@@ -6302,14 +6528,14 @@ function parser(text, json, $filter, csp){
6302
6528
  } while (expect(','));
6303
6529
  }
6304
6530
  consume(')');
6305
- return function(self, locals){
6531
+ return function(scope, locals){
6306
6532
  var args = [],
6307
- context = contextGetter ? contextGetter(self, locals) : self;
6533
+ context = contextGetter ? contextGetter(scope, locals) : scope;
6308
6534
 
6309
6535
  for ( var i = 0; i < argsFn.length; i++) {
6310
- args.push(argsFn[i](self, locals));
6536
+ args.push(argsFn[i](scope, locals));
6311
6537
  }
6312
- var fnPtr = fn(self, locals) || noop;
6538
+ var fnPtr = fn(scope, locals, context) || noop;
6313
6539
  // IE stupidity!
6314
6540
  return fnPtr.apply
6315
6541
  ? fnPtr.apply(context, args)
@@ -6351,8 +6577,7 @@ function parser(text, json, $filter, csp){
6351
6577
  var object = {};
6352
6578
  for ( var i = 0; i < keyValues.length; i++) {
6353
6579
  var keyValue = keyValues[i];
6354
- var value = keyValue.value(self, locals);
6355
- object[keyValue.key] = value;
6580
+ object[keyValue.key] = keyValue.value(self, locals);
6356
6581
  }
6357
6582
  return object;
6358
6583
  };
@@ -6378,33 +6603,6 @@ function setter(obj, path, setValue) {
6378
6603
  return setValue;
6379
6604
  }
6380
6605
 
6381
- /**
6382
- * Return the value accesible from the object by path. Any undefined traversals are ignored
6383
- * @param {Object} obj starting object
6384
- * @param {string} path path to traverse
6385
- * @param {boolean=true} bindFnToScope
6386
- * @returns value as accesbile by path
6387
- */
6388
- //TODO(misko): this function needs to be removed
6389
- function getter(obj, path, bindFnToScope) {
6390
- if (!path) return obj;
6391
- var keys = path.split('.');
6392
- var key;
6393
- var lastInstance = obj;
6394
- var len = keys.length;
6395
-
6396
- for (var i = 0; i < len; i++) {
6397
- key = keys[i];
6398
- if (obj) {
6399
- obj = (lastInstance = obj)[key];
6400
- }
6401
- }
6402
- if (!bindFnToScope && isFunction(obj)) {
6403
- return bind(lastInstance, obj);
6404
- }
6405
- return obj;
6406
- }
6407
-
6408
6606
  var getterFnCache = {};
6409
6607
 
6410
6608
  /**
@@ -6474,7 +6672,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4) {
6474
6672
  }
6475
6673
  return pathVal;
6476
6674
  };
6477
- };
6675
+ }
6478
6676
 
6479
6677
  function getterFn(path, csp) {
6480
6678
  if (getterFnCache.hasOwnProperty(path)) {
@@ -6489,7 +6687,7 @@ function getterFn(path, csp) {
6489
6687
  fn = (pathKeysLength < 6)
6490
6688
  ? cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4])
6491
6689
  : function(scope, locals) {
6492
- var i = 0, val
6690
+ var i = 0, val;
6493
6691
  do {
6494
6692
  val = cspSafeGetterFn(
6495
6693
  pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++]
@@ -6666,8 +6864,8 @@ function $ParseProvider() {
6666
6864
  * **Methods**
6667
6865
  *
6668
6866
  * - `then(successCallback, errorCallback)` – regardless of when the promise was or will be resolved
6669
- * or rejected calls one of the success or error callbacks asynchronously as soon as the result
6670
- * is available. The callbacks are called with a single argument the result or rejection reason.
6867
+ * or rejected, `then` calls one of the success or error callbacks asynchronously as soon as the result
6868
+ * is available. The callbacks are called with a single argument: the result or rejection reason.
6671
6869
  *
6672
6870
  * This method *returns a new promise* which is resolved or rejected via the return value of the
6673
6871
  * `successCallback` or `errorCallback`.
@@ -6675,7 +6873,7 @@ function $ParseProvider() {
6675
6873
  *
6676
6874
  * # Chaining promises
6677
6875
  *
6678
- * Because calling `then` api of a promise returns a new derived promise, it is easily possible
6876
+ * Because calling the `then` method of a promise returns a new derived promise, it is easily possible
6679
6877
  * to create a chain of promises:
6680
6878
  *
6681
6879
  * <pre>
@@ -6683,13 +6881,13 @@ function $ParseProvider() {
6683
6881
  * return result + 1;
6684
6882
  * });
6685
6883
  *
6686
- * // promiseB will be resolved immediately after promiseA is resolved and its value will be
6687
- * // the result of promiseA incremented by 1
6884
+ * // promiseB will be resolved immediately after promiseA is resolved and its value
6885
+ * // will be the result of promiseA incremented by 1
6688
6886
  * </pre>
6689
6887
  *
6690
6888
  * It is possible to create chains of any length and since a promise can be resolved with another
6691
6889
  * promise (which will defer its resolution further), it is possible to pause/defer resolution of
6692
- * the promises at any point in the chain. This makes it possible to implement powerful apis like
6890
+ * the promises at any point in the chain. This makes it possible to implement powerful APIs like
6693
6891
  * $http's response interceptors.
6694
6892
  *
6695
6893
  *
@@ -6702,7 +6900,7 @@ function $ParseProvider() {
6702
6900
  * models and avoiding unnecessary browser repaints, which would result in flickering UI.
6703
6901
  * - $q promises are recognized by the templating engine in angular, which means that in templates
6704
6902
  * you can treat promises attached to a scope as if they were the resulting values.
6705
- * - Q has many more features that $q, but that comes at a cost of bytes. $q is tiny, but contains
6903
+ * - Q has many more features than $q, but that comes at a cost of bytes. $q is tiny, but contains
6706
6904
  * all the important functionality needed for common async tasks.
6707
6905
  *
6708
6906
  * # Testing
@@ -6796,8 +6994,8 @@ function qFactory(nextTick, exceptionHandler) {
6796
6994
  try {
6797
6995
  result.resolve((callback || defaultCallback)(value));
6798
6996
  } catch(e) {
6799
- exceptionHandler(e);
6800
6997
  result.reject(e);
6998
+ exceptionHandler(e);
6801
6999
  }
6802
7000
  };
6803
7001
 
@@ -6805,8 +7003,8 @@ function qFactory(nextTick, exceptionHandler) {
6805
7003
  try {
6806
7004
  result.resolve((errback || defaultErrback)(reason));
6807
7005
  } catch(e) {
6808
- exceptionHandler(e);
6809
7006
  result.reject(e);
7007
+ exceptionHandler(e);
6810
7008
  }
6811
7009
  };
6812
7010
 
@@ -6897,10 +7095,7 @@ function qFactory(nextTick, exceptionHandler) {
6897
7095
  * the promise comes from a source that can't be trusted.
6898
7096
  *
6899
7097
  * @param {*} value Value or a promise
6900
- * @returns {Promise} Returns a single promise that will be resolved with an array of values,
6901
- * each value corresponding to the promise at the same index in the `promises` array. If any of
6902
- * the promises is resolved with a rejection, this resulting promise will be resolved with the
6903
- * same rejection.
7098
+ * @returns {Promise} Returns a promise of the passed value or promise
6904
7099
  */
6905
7100
  var when = function(value, callback, errback) {
6906
7101
  var result = defer(),
@@ -7018,8 +7213,8 @@ function $RouteProvider(){
7018
7213
  * route definition.
7019
7214
  *
7020
7215
  * `path` can contain named groups starting with a colon (`:name`). All characters up to the
7021
- * next slash are matched and stored in `$routeParams` under the given `name` when the route
7022
- * matches.
7216
+ * next slash are matched and stored in `$routeParams` under the given `name` after the route
7217
+ * is resolved.
7023
7218
  *
7024
7219
  * @param {Object} route Mapping information to be assigned to `$route.current` on route
7025
7220
  * match.
@@ -7044,7 +7239,9 @@ function $RouteProvider(){
7044
7239
  * - `factory` - `{string|function}`: If `string` then it is an alias for a service.
7045
7240
  * Otherwise if function, then it is {@link api/AUTO.$injector#invoke injected}
7046
7241
  * and the return value is treated as the dependency. If the result is a promise, it is resolved
7047
- * before its value is injected into the controller.
7242
+ * before its value is injected into the controller. Be aware that `ngRoute.$routeParams` will
7243
+ * still refer to the previous route within these resolve functions. Use `$route.current.params`
7244
+ * to access the new route parameters, instead.
7048
7245
  *
7049
7246
  * - `redirectTo` – {(string|function())=} – value to update
7050
7247
  * {@link ng.$location $location} path with and trigger route redirection.
@@ -7479,6 +7676,10 @@ function $RouteProvider(){
7479
7676
  * The service guarantees that the identity of the `$routeParams` object will remain unchanged
7480
7677
  * (but its properties will likely change) even when a route change occurs.
7481
7678
  *
7679
+ * Note that the `$routeParams` are only updated *after* a route change completes successfully.
7680
+ * This means that you cannot rely on `$routeParams` being correct in route resolve functions.
7681
+ * Instead you can use `$route.current.params` to access the new route's parameters.
7682
+ *
7482
7683
  * @example
7483
7684
  * <pre>
7484
7685
  * // Given:
@@ -7496,22 +7697,22 @@ function $RouteParamsProvider() {
7496
7697
  /**
7497
7698
  * DESIGN NOTES
7498
7699
  *
7499
- * The design decisions behind the scope ware heavily favored for speed and memory consumption.
7700
+ * The design decisions behind the scope are heavily favored for speed and memory consumption.
7500
7701
  *
7501
7702
  * The typical use of scope is to watch the expressions, which most of the time return the same
7502
7703
  * value as last time so we optimize the operation.
7503
7704
  *
7504
- * Closures construction is expensive from speed as well as memory:
7505
- * - no closures, instead ups prototypical inheritance for API
7705
+ * Closures construction is expensive in terms of speed as well as memory:
7706
+ * - No closures, instead use prototypical inheritance for API
7506
7707
  * - Internal state needs to be stored on scope directly, which means that private state is
7507
7708
  * exposed as $$____ properties
7508
7709
  *
7509
7710
  * Loop operations are optimized by using while(count--) { ... }
7510
7711
  * - this means that in order to keep the same order of execution as addition we have to add
7511
- * items to the array at the begging (shift) instead of at the end (push)
7712
+ * items to the array at the beginning (shift) instead of at the end (push)
7512
7713
  *
7513
7714
  * Child scopes are created and removed often
7514
- * - Using array would be slow since inserts in meddle are expensive so we use linked list
7715
+ * - Using an array would be slow since inserts in middle are expensive so we use linked list
7515
7716
  *
7516
7717
  * There are few watches then a lot of observers. This is why you don't want the observer to be
7517
7718
  * implemented in the same way as watch. Watch requires return of initialization function which
@@ -7533,7 +7734,7 @@ function $RouteParamsProvider() {
7533
7734
  * @methodOf ng.$rootScopeProvider
7534
7735
  * @description
7535
7736
  *
7536
- * Sets the number of digest iteration the scope should attempt to execute before giving up and
7737
+ * Sets the number of digest iterations the scope should attempt to execute before giving up and
7537
7738
  * assuming that the model is unstable.
7538
7739
  *
7539
7740
  * The current default is 10 iterations.
@@ -7813,7 +8014,7 @@ function $RootScopeProvider(){
7813
8014
  * @function
7814
8015
  *
7815
8016
  * @description
7816
- * Process all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and its children.
8017
+ * Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and its children.
7817
8018
  * Because a {@link ng.$rootScope.Scope#$watch watcher}'s listener can change the model, the
7818
8019
  * `$digest()` keeps calling the {@link ng.$rootScope.Scope#$watch watchers} until no more listeners are
7819
8020
  * firing. This means that it is possible to get into an infinite loop. This function will throw
@@ -7886,7 +8087,7 @@ function $RootScopeProvider(){
7886
8087
  watch = watchers[length];
7887
8088
  // Most common watches are on primitives, in which case we can short
7888
8089
  // circuit it with === operator, only when === fails do we use .equals
7889
- if ((value = watch.get(current)) !== (last = watch.last) &&
8090
+ if (watch && (value = watch.get(current)) !== (last = watch.last) &&
7890
8091
  !(watch.eq
7891
8092
  ? equals(value, last)
7892
8093
  : (typeof value == 'number' && typeof last == 'number'
@@ -7939,6 +8140,9 @@ function $RootScopeProvider(){
7939
8140
  *
7940
8141
  * @description
7941
8142
  * Broadcasted when a scope and its children are being destroyed.
8143
+ *
8144
+ * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to
8145
+ * clean up DOM bindings before an element is removed from the DOM.
7942
8146
  */
7943
8147
 
7944
8148
  /**
@@ -7960,6 +8164,9 @@ function $RootScopeProvider(){
7960
8164
  * Just before a scope is destroyed a `$destroy` event is broadcasted on this scope.
7961
8165
  * Application code can register a `$destroy` event handler that will give it chance to
7962
8166
  * perform any necessary cleanup.
8167
+ *
8168
+ * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to
8169
+ * clean up DOM bindings before an element is removed from the DOM.
7963
8170
  */
7964
8171
  $destroy: function() {
7965
8172
  // we can't destroy the root scope or a scope that has been already destroyed
@@ -8155,7 +8362,7 @@ function $RootScopeProvider(){
8155
8362
  * Afterwards, the event traverses upwards toward the root scope and calls all registered
8156
8363
  * listeners along the way. The event will stop propagating if one of the listeners cancels it.
8157
8364
  *
8158
- * Any exception emmited from the {@link ng.$rootScope.Scope#$on listeners} will be passed
8365
+ * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed
8159
8366
  * onto the {@link ng.$exceptionHandler $exceptionHandler} service.
8160
8367
  *
8161
8368
  * @param {string} name Event name to emit.
@@ -8224,7 +8431,7 @@ function $RootScopeProvider(){
8224
8431
  * Any exception emmited from the {@link ng.$rootScope.Scope#$on listeners} will be passed
8225
8432
  * onto the {@link ng.$exceptionHandler $exceptionHandler} service.
8226
8433
  *
8227
- * @param {string} name Event name to emit.
8434
+ * @param {string} name Event name to broadcast.
8228
8435
  * @param {...*} args Optional set of arguments which will be passed onto the event listeners.
8229
8436
  * @return {Object} Event object, see {@link ng.$rootScope.Scope#$on}
8230
8437
  */
@@ -8364,16 +8571,31 @@ function $SnifferProvider() {
8364
8571
  * it is a global variable. In angular we always refer to it through the
8365
8572
  * `$window` service, so it may be overriden, removed or mocked for testing.
8366
8573
  *
8367
- * All expressions are evaluated with respect to current scope so they don't
8368
- * suffer from window globality.
8574
+ * Expressions, like the one defined for the `ngClick` directive in the example
8575
+ * below, are evaluated with respect to the current scope. Therefore, there is
8576
+ * no risk of inadvertently coding in a dependency on a global value in such an
8577
+ * expression.
8369
8578
  *
8370
8579
  * @example
8371
8580
  <doc:example>
8372
8581
  <doc:source>
8373
- <input ng-init="$window = $service('$window'); greeting='Hello World!'" type="text" ng-model="greeting" />
8374
- <button ng-click="$window.alert(greeting)">ALERT</button>
8582
+ <script>
8583
+ function Ctrl($scope, $window) {
8584
+ $scope.$window = $window;
8585
+ $scope.greeting = 'Hello, World!';
8586
+ }
8587
+ </script>
8588
+ <div ng-controller="Ctrl">
8589
+ <input type="text" ng-model="greeting" />
8590
+ <button ng-click="$window.alert(greeting)">ALERT</button>
8591
+ </div>
8375
8592
  </doc:source>
8376
8593
  <doc:scenario>
8594
+ it('should display the greeting in the input box', function() {
8595
+ input('greeting').enter('Hello, E2E Tests');
8596
+ // If we click the button it will block the test runner
8597
+ // element(':button').click();
8598
+ });
8377
8599
  </doc:scenario>
8378
8600
  </doc:example>
8379
8601
  */
@@ -8526,7 +8748,7 @@ function $HttpProvider() {
8526
8748
  *
8527
8749
  * @description
8528
8750
  * The `$http` service is a core Angular service that facilitates communication with the remote
8529
- * HTTP servers via browser's {@link https://developer.mozilla.org/en/xmlhttprequest
8751
+ * HTTP servers via the browser's {@link https://developer.mozilla.org/en/xmlhttprequest
8530
8752
  * XMLHttpRequest} object or via {@link http://en.wikipedia.org/wiki/JSONP JSONP}.
8531
8753
  *
8532
8754
  * For unit testing applications that use `$http` service, see
@@ -8536,13 +8758,13 @@ function $HttpProvider() {
8536
8758
  * $resource} service.
8537
8759
  *
8538
8760
  * The $http API is based on the {@link ng.$q deferred/promise APIs} exposed by
8539
- * the $q service. While for simple usage patters this doesn't matter much, for advanced usage,
8540
- * it is important to familiarize yourself with these apis and guarantees they provide.
8761
+ * the $q service. While for simple usage patterns this doesn't matter much, for advanced usage
8762
+ * it is important to familiarize yourself with these APIs and the guarantees they provide.
8541
8763
  *
8542
8764
  *
8543
8765
  * # General usage
8544
8766
  * The `$http` service is a function which takes a single argument — a configuration object —
8545
- * that is used to generate an http request and returns a {@link ng.$q promise}
8767
+ * that is used to generate an HTTP request and returns a {@link ng.$q promise}
8546
8768
  * with two $http specific methods: `success` and `error`.
8547
8769
  *
8548
8770
  * <pre>
@@ -8557,21 +8779,21 @@ function $HttpProvider() {
8557
8779
  * });
8558
8780
  * </pre>
8559
8781
  *
8560
- * Since the returned value of calling the $http function is a Promise object, you can also use
8782
+ * Since the returned value of calling the $http function is a `promise`, you can also use
8561
8783
  * the `then` method to register callbacks, and these callbacks will receive a single argument –
8562
- * an object representing the response. See the api signature and type info below for more
8784
+ * an object representing the response. See the API signature and type info below for more
8563
8785
  * details.
8564
8786
  *
8565
- * A response status code that falls in the [200, 300) range is considered a success status and
8787
+ * A response status code between 200 and 299 is considered a success status and
8566
8788
  * will result in the success callback being called. Note that if the response is a redirect,
8567
8789
  * XMLHttpRequest will transparently follow it, meaning that the error callback will not be
8568
8790
  * called for such responses.
8569
8791
  *
8570
8792
  * # Shortcut methods
8571
8793
  *
8572
- * Since all invocation of the $http service require definition of the http method and url and
8573
- * POST and PUT requests require response body/data to be provided as well, shortcut methods
8574
- * were created to simplify using the api:
8794
+ * Since all invocations of the $http service require passing in an HTTP method and URL, and
8795
+ * POST/PUT requests require request data to be provided as well, shortcut methods
8796
+ * were created:
8575
8797
  *
8576
8798
  * <pre>
8577
8799
  * $http.get('/someUrl').success(successCallback);
@@ -8590,25 +8812,25 @@ function $HttpProvider() {
8590
8812
  *
8591
8813
  * # Setting HTTP Headers
8592
8814
  *
8593
- * The $http service will automatically add certain http headers to all requests. These defaults
8815
+ * The $http service will automatically add certain HTTP headers to all requests. These defaults
8594
8816
  * can be fully configured by accessing the `$httpProvider.defaults.headers` configuration
8595
8817
  * object, which currently contains this default configuration:
8596
8818
  *
8597
8819
  * - `$httpProvider.defaults.headers.common` (headers that are common for all requests):
8598
8820
  * - `Accept: application/json, text/plain, * / *`
8599
8821
  * - `X-Requested-With: XMLHttpRequest`
8600
- * - `$httpProvider.defaults.headers.post`: (header defaults for HTTP POST requests)
8822
+ * - `$httpProvider.defaults.headers.post`: (header defaults for POST requests)
8601
8823
  * - `Content-Type: application/json`
8602
- * - `$httpProvider.defaults.headers.put` (header defaults for HTTP PUT requests)
8824
+ * - `$httpProvider.defaults.headers.put` (header defaults for PUT requests)
8603
8825
  * - `Content-Type: application/json`
8604
8826
  *
8605
- * To add or overwrite these defaults, simply add or remove a property from this configuration
8827
+ * To add or overwrite these defaults, simply add or remove a property from these configuration
8606
8828
  * objects. To add headers for an HTTP method other than POST or PUT, simply add a new object
8607
- * with name equal to the lower-cased http method name, e.g.
8829
+ * with the lowercased HTTP method name as the key, e.g.
8608
8830
  * `$httpProvider.defaults.headers.get['My-Header']='value'`.
8609
8831
  *
8610
- * Additionally, the defaults can be set at runtime via the `$http.defaults` object in a similar
8611
- * fassion as described above.
8832
+ * Additionally, the defaults can be set at runtime via the `$http.defaults` object in the same
8833
+ * fashion.
8612
8834
  *
8613
8835
  *
8614
8836
  * # Transforming Requests and Responses
@@ -8618,36 +8840,36 @@ function $HttpProvider() {
8618
8840
  *
8619
8841
  * Request transformations:
8620
8842
  *
8621
- * - if the `data` property of the request config object contains an object, serialize it into
8843
+ * - If the `data` property of the request configuration object contains an object, serialize it into
8622
8844
  * JSON format.
8623
8845
  *
8624
8846
  * Response transformations:
8625
8847
  *
8626
- * - if XSRF prefix is detected, strip it (see Security Considerations section below)
8627
- * - if json response is detected, deserialize it using a JSON parser
8848
+ * - If XSRF prefix is detected, strip it (see Security Considerations section below).
8849
+ * - If JSON response is detected, deserialize it using a JSON parser.
8628
8850
  *
8629
8851
  * To globally augment or override the default transforms, modify the `$httpProvider.defaults.transformRequest` and
8630
- * `$httpProvider.defaults.transformResponse` properties of the `$httpProvider`. These properties are by default an
8852
+ * `$httpProvider.defaults.transformResponse` properties. These properties are by default an
8631
8853
  * array of transform functions, which allows you to `push` or `unshift` a new transformation function into the
8632
8854
  * transformation chain. You can also decide to completely override any default transformations by assigning your
8633
8855
  * transformation functions to these properties directly without the array wrapper.
8634
8856
  *
8635
8857
  * Similarly, to locally override the request/response transforms, augment the `transformRequest` and/or
8636
- * `transformResponse` properties of the config object passed into `$http`.
8858
+ * `transformResponse` properties of the configuration object passed into `$http`.
8637
8859
  *
8638
8860
  *
8639
8861
  * # Caching
8640
8862
  *
8641
- * To enable caching set the configuration property `cache` to `true`. When the cache is
8863
+ * To enable caching, set the configuration property `cache` to `true`. When the cache is
8642
8864
  * enabled, `$http` stores the response from the server in local cache. Next time the
8643
8865
  * response is served from the cache without sending a request to the server.
8644
8866
  *
8645
8867
  * Note that even if the response is served from cache, delivery of the data is asynchronous in
8646
8868
  * the same way that real requests are.
8647
8869
  *
8648
- * If there are multiple GET requests for the same url that should be cached using the same
8870
+ * If there are multiple GET requests for the same URL that should be cached using the same
8649
8871
  * cache, but the cache is not populated yet, only one request to the server will be made and
8650
- * the remaining requests will be fulfilled using the response for the first request.
8872
+ * the remaining requests will be fulfilled using the response from the first request.
8651
8873
  *
8652
8874
  *
8653
8875
  * # Response interceptors
@@ -8672,6 +8894,7 @@ function $HttpProvider() {
8672
8894
  * return function(promise) {
8673
8895
  * return promise.then(function(response) {
8674
8896
  * // do something on success
8897
+ * return response;
8675
8898
  * }, function(response) {
8676
8899
  * // do something on error
8677
8900
  * if (canRecover(response)) {
@@ -8699,7 +8922,7 @@ function $HttpProvider() {
8699
8922
  * When designing web applications, consider security threats from:
8700
8923
  *
8701
8924
  * - {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx
8702
- * JSON Vulnerability}
8925
+ * JSON vulnerability}
8703
8926
  * - {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF}
8704
8927
  *
8705
8928
  * Both server and the client must cooperate in order to eliminate these threats. Angular comes
@@ -8709,8 +8932,8 @@ function $HttpProvider() {
8709
8932
  * ## JSON Vulnerability Protection
8710
8933
  *
8711
8934
  * A {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx
8712
- * JSON Vulnerability} allows third party web-site to turn your JSON resource URL into
8713
- * {@link http://en.wikipedia.org/wiki/JSON#JSONP JSONP} request under some conditions. To
8935
+ * JSON vulnerability} allows third party website to turn your JSON resource URL into
8936
+ * {@link http://en.wikipedia.org/wiki/JSONP JSONP} request under some conditions. To
8714
8937
  * counter this your server can prefix all JSON requests with following string `")]}',\n"`.
8715
8938
  * Angular will automatically strip the prefix before processing it as JSON.
8716
8939
  *
@@ -8731,19 +8954,19 @@ function $HttpProvider() {
8731
8954
  * ## Cross Site Request Forgery (XSRF) Protection
8732
8955
  *
8733
8956
  * {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF} is a technique by which
8734
- * an unauthorized site can gain your user's private data. Angular provides following mechanism
8957
+ * an unauthorized site can gain your user's private data. Angular provides a mechanism
8735
8958
  * to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie
8736
8959
  * called `XSRF-TOKEN` and sets it as the HTTP header `X-XSRF-TOKEN`. Since only JavaScript that
8737
8960
  * runs on your domain could read the cookie, your server can be assured that the XHR came from
8738
8961
  * JavaScript running on your domain.
8739
8962
  *
8740
8963
  * To take advantage of this, your server needs to set a token in a JavaScript readable session
8741
- * cookie called `XSRF-TOKEN` on first HTTP GET request. On subsequent non-GET requests the
8964
+ * cookie called `XSRF-TOKEN` on the first HTTP GET request. On subsequent XHR requests the
8742
8965
  * server can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure
8743
- * that only JavaScript running on your domain could have read the token. The token must be
8744
- * unique for each user and must be verifiable by the server (to prevent the JavaScript making
8966
+ * that only JavaScript running on your domain could have sent the request. The token must be
8967
+ * unique for each user and must be verifiable by the server (to prevent the JavaScript from making
8745
8968
  * up its own tokens). We recommend that the token is a digest of your site's authentication
8746
- * cookie with {@link http://en.wikipedia.org/wiki/Rainbow_table salt for added security}.
8969
+ * cookie with a {@link https://en.wikipedia.org/wiki/Salt_(cryptography) salt} for added security.
8747
8970
  *
8748
8971
  *
8749
8972
  * @param {object} config Object describing the request to be made and how it should be
@@ -8863,17 +9086,40 @@ function $HttpProvider() {
8863
9086
 
8864
9087
  var reqTransformFn = config.transformRequest || $config.transformRequest,
8865
9088
  respTransformFn = config.transformResponse || $config.transformResponse,
8866
- defHeaders = $config.headers,
8867
- reqHeaders = extend({'X-XSRF-TOKEN': $browser.cookies()['XSRF-TOKEN']},
8868
- defHeaders.common, defHeaders[lowercase(config.method)], config.headers),
8869
- reqData = transformData(config.data, headersGetter(reqHeaders), reqTransformFn),
9089
+ reqHeaders = extend({}, config.headers),
9090
+ defHeaders = extend(
9091
+ {'X-XSRF-TOKEN': $browser.cookies()['XSRF-TOKEN']},
9092
+ $config.headers.common,
9093
+ $config.headers[lowercase(config.method)]
9094
+ ),
9095
+ reqData,
9096
+ defHeaderName, lowercaseDefHeaderName, headerName,
8870
9097
  promise;
8871
9098
 
9099
+ // using for-in instead of forEach to avoid unecessary iteration after header has been found
9100
+ defaultHeadersIteration:
9101
+ for(defHeaderName in defHeaders) {
9102
+ lowercaseDefHeaderName = lowercase(defHeaderName);
9103
+ for(headerName in config.headers) {
9104
+ if (lowercase(headerName) === lowercaseDefHeaderName) {
9105
+ continue defaultHeadersIteration;
9106
+ }
9107
+ }
9108
+ reqHeaders[defHeaderName] = defHeaders[defHeaderName];
9109
+ }
9110
+
8872
9111
  // strip content-type if data is undefined
8873
9112
  if (isUndefined(config.data)) {
8874
- delete reqHeaders['Content-Type'];
9113
+ for(var header in reqHeaders) {
9114
+ if (lowercase(header) === 'content-type') {
9115
+ delete reqHeaders[header];
9116
+ break;
9117
+ }
9118
+ }
8875
9119
  }
8876
9120
 
9121
+ reqData = transformData(config.data, headersGetter(reqHeaders), reqTransformFn);
9122
+
8877
9123
  // send request
8878
9124
  promise = sendReq(config, reqData, reqHeaders);
8879
9125
 
@@ -8921,7 +9167,7 @@ function $HttpProvider() {
8921
9167
  * @methodOf ng.$http
8922
9168
  *
8923
9169
  * @description
8924
- * Shortcut method to perform `GET` request
9170
+ * Shortcut method to perform `GET` request.
8925
9171
  *
8926
9172
  * @param {string} url Relative or absolute URL specifying the destination of the request
8927
9173
  * @param {Object=} config Optional configuration object
@@ -8934,7 +9180,7 @@ function $HttpProvider() {
8934
9180
  * @methodOf ng.$http
8935
9181
  *
8936
9182
  * @description
8937
- * Shortcut method to perform `DELETE` request
9183
+ * Shortcut method to perform `DELETE` request.
8938
9184
  *
8939
9185
  * @param {string} url Relative or absolute URL specifying the destination of the request
8940
9186
  * @param {Object=} config Optional configuration object
@@ -8947,7 +9193,7 @@ function $HttpProvider() {
8947
9193
  * @methodOf ng.$http
8948
9194
  *
8949
9195
  * @description
8950
- * Shortcut method to perform `HEAD` request
9196
+ * Shortcut method to perform `HEAD` request.
8951
9197
  *
8952
9198
  * @param {string} url Relative or absolute URL specifying the destination of the request
8953
9199
  * @param {Object=} config Optional configuration object
@@ -8960,7 +9206,7 @@ function $HttpProvider() {
8960
9206
  * @methodOf ng.$http
8961
9207
  *
8962
9208
  * @description
8963
- * Shortcut method to perform `JSONP` request
9209
+ * Shortcut method to perform `JSONP` request.
8964
9210
  *
8965
9211
  * @param {string} url Relative or absolute URL specifying the destination of the request.
8966
9212
  * Should contain `JSON_CALLBACK` string.
@@ -8975,7 +9221,7 @@ function $HttpProvider() {
8975
9221
  * @methodOf ng.$http
8976
9222
  *
8977
9223
  * @description
8978
- * Shortcut method to perform `POST` request
9224
+ * Shortcut method to perform `POST` request.
8979
9225
  *
8980
9226
  * @param {string} url Relative or absolute URL specifying the destination of the request
8981
9227
  * @param {*} data Request content
@@ -8989,7 +9235,7 @@ function $HttpProvider() {
8989
9235
  * @methodOf ng.$http
8990
9236
  *
8991
9237
  * @description
8992
- * Shortcut method to perform `PUT` request
9238
+ * Shortcut method to perform `PUT` request.
8993
9239
  *
8994
9240
  * @param {string} url Relative or absolute URL specifying the destination of the request
8995
9241
  * @param {*} data Request content
@@ -9041,7 +9287,7 @@ function $HttpProvider() {
9041
9287
 
9042
9288
 
9043
9289
  /**
9044
- * Makes the request
9290
+ * Makes the request.
9045
9291
  *
9046
9292
  * !!! ACCESSES CLOSURE VARS:
9047
9293
  * $httpBackend, $config, $log, $rootScope, defaultCache, $http.pendingRequests
@@ -9388,17 +9634,17 @@ function $TimeoutProvider() {
9388
9634
  * block and delegates any exceptions to
9389
9635
  * {@link ng.$exceptionHandler $exceptionHandler} service.
9390
9636
  *
9391
- * The return value of registering a timeout function is a promise which will be resolved when
9637
+ * The return value of registering a timeout function is a promise, which will be resolved when
9392
9638
  * the timeout is reached and the timeout function is executed.
9393
9639
  *
9394
- * To cancel a the timeout request, call `$timeout.cancel(promise)`.
9640
+ * To cancel a timeout request, call `$timeout.cancel(promise)`.
9395
9641
  *
9396
9642
  * In tests you can use {@link ngMock.$timeout `$timeout.flush()`} to
9397
9643
  * synchronously flush the queue of deferred functions.
9398
9644
  *
9399
- * @param {function()} fn A function, who's execution should be delayed.
9645
+ * @param {function()} fn A function, whose execution should be delayed.
9400
9646
  * @param {number=} [delay=0] Delay in milliseconds.
9401
- * @param {boolean=} [invokeApply=true] If set to false skips model dirty checking, otherwise
9647
+ * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
9402
9648
  * will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
9403
9649
  * @returns {Promise} Promise that will be resolved when the timeout is reached. The value this
9404
9650
  * promise will be resolved with is the return value of the `fn` function.
@@ -9416,17 +9662,15 @@ function $TimeoutProvider() {
9416
9662
  deferred.reject(e);
9417
9663
  $exceptionHandler(e);
9418
9664
  }
9665
+ finally {
9666
+ delete deferreds[promise.$$timeoutId];
9667
+ }
9419
9668
 
9420
9669
  if (!skipApply) $rootScope.$apply();
9421
9670
  }, delay);
9422
9671
 
9423
- cleanup = function() {
9424
- delete deferreds[promise.$$timeoutId];
9425
- };
9426
-
9427
9672
  promise.$$timeoutId = timeoutId;
9428
9673
  deferreds[timeoutId] = deferred;
9429
- promise.then(cleanup, cleanup);
9430
9674
 
9431
9675
  return promise;
9432
9676
  }
@@ -9438,7 +9682,7 @@ function $TimeoutProvider() {
9438
9682
  * @methodOf ng.$timeout
9439
9683
  *
9440
9684
  * @description
9441
- * Cancels a task associated with the `promise`. As a result of this the promise will be
9685
+ * Cancels a task associated with the `promise`. As a result of this, the promise will be
9442
9686
  * resolved with a rejection.
9443
9687
  *
9444
9688
  * @param {Promise=} promise Promise returned by the `$timeout` function.
@@ -9448,6 +9692,7 @@ function $TimeoutProvider() {
9448
9692
  timeout.cancel = function(promise) {
9449
9693
  if (promise && promise.$$timeoutId in deferreds) {
9450
9694
  deferreds[promise.$$timeoutId].reject('canceled');
9695
+ delete deferreds[promise.$$timeoutId];
9451
9696
  return $browser.defer.cancel(promise.$$timeoutId);
9452
9697
  }
9453
9698
  return false;
@@ -9526,7 +9771,7 @@ function $TimeoutProvider() {
9526
9771
  *
9527
9772
  * The general syntax in templates is as follows:
9528
9773
  *
9529
- * {{ expression | [ filter_name ] }}
9774
+ * {{ expression [| filter_name[:parameter_value] ... ] }}
9530
9775
  *
9531
9776
  * @param {String} name Name of the filter function to retrieve
9532
9777
  * @return {Function} the filter function
@@ -9611,7 +9856,7 @@ function $FilterProvider($provide) {
9611
9856
  <hr>
9612
9857
  Any: <input ng-model="search.$"> <br>
9613
9858
  Name only <input ng-model="search.name"><br>
9614
- Phone only <input ng-model="search.phone"å><br>
9859
+ Phone only <input ng-model="search.phone"><br>
9615
9860
  <table id="searchObjResults">
9616
9861
  <tr><th>Name</th><th>Phone</th></tr>
9617
9862
  <tr ng-repeat="friend in friends | filter:search">
@@ -9784,7 +10029,9 @@ function currencyFilter($locale) {
9784
10029
  * If the input is not a number an empty string is returned.
9785
10030
  *
9786
10031
  * @param {number|string} number Number to format.
9787
- * @param {(number|string)=} [fractionSize=2] Number of decimal places to round the number to.
10032
+ * @param {(number|string)=} fractionSize Number of decimal places to round the number to.
10033
+ * If this is not provided then the fraction size is computed from the current locale's number
10034
+ * formatting pattern. In the case of the default locale, it will be 3.
9788
10035
  * @returns {string} Number rounded to decimalPlaces and places a “,” after each third digit.
9789
10036
  *
9790
10037
  * @example
@@ -9891,6 +10138,11 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
9891
10138
  }
9892
10139
 
9893
10140
  if (fractionSize && fractionSize !== "0") formatedText += decimalSep + fraction.substr(0, fractionSize);
10141
+ } else {
10142
+
10143
+ if (fractionSize > 0 && number > -1 && number < 1) {
10144
+ formatedText = number.toFixed(fractionSize);
10145
+ }
9894
10146
  }
9895
10147
 
9896
10148
  parts.push(isNegative ? pattern.negPre : pattern.posPre);
@@ -9914,6 +10166,7 @@ function padNumber(num, digits, trim) {
9914
10166
 
9915
10167
 
9916
10168
  function dateGetter(name, size, offset, trim) {
10169
+ offset = offset || 0;
9917
10170
  return function(date) {
9918
10171
  var value = date['get' + name]();
9919
10172
  if (offset > 0 || value > -offset)
@@ -10013,7 +10266,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
10013
10266
  * * `'short'`: equivalent to `'M/d/yy h:mm a'` for en_US locale (e.g. 9/3/10 12:05 pm)
10014
10267
  * * `'fullDate'`: equivalent to `'EEEE, MMMM d,y'` for en_US locale
10015
10268
  * (e.g. Friday, September 3, 2010)
10016
- * * `'longDate'`: equivalent to `'MMMM d, y'` for en_US locale (e.g. September 3, 2010
10269
+ * * `'longDate'`: equivalent to `'MMMM d, y'` for en_US locale (e.g. September 3, 2010)
10017
10270
  * * `'mediumDate'`: equivalent to `'MMM d, y'` for en_US locale (e.g. Sep 3, 2010)
10018
10271
  * * `'shortDate'`: equivalent to `'M/d/yy'` for en_US locale (e.g. 9/3/10)
10019
10272
  * * `'mediumTime'`: equivalent to `'h:mm:ss a'` for en_US locale (e.g. 12:05:08 pm)
@@ -10021,10 +10274,10 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
10021
10274
  *
10022
10275
  * `format` string can contain literal values. These need to be quoted with single quotes (e.g.
10023
10276
  * `"h 'in the morning'"`). In order to output single quote, use two single quotes in a sequence
10024
- * (e.g. `"h o''clock"`).
10277
+ * (e.g. `"h 'o''clock'"`).
10025
10278
  *
10026
10279
  * @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or
10027
- * number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.SSSZ and it's
10280
+ * number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.SSSZ and its
10028
10281
  * shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is
10029
10282
  * specified in the string input, the time is considered to be in the local timezone.
10030
10283
  * @param {string=} format Formatting rules (see Description). If not specified,
@@ -10388,8 +10641,10 @@ function orderByFilter($parse){
10388
10641
  var t1 = typeof v1;
10389
10642
  var t2 = typeof v2;
10390
10643
  if (t1 == t2) {
10391
- if (t1 == "string") v1 = v1.toLowerCase();
10392
- if (t1 == "string") v2 = v2.toLowerCase();
10644
+ if (t1 == "string") {
10645
+ v1 = v1.toLowerCase();
10646
+ v2 = v2.toLowerCase();
10647
+ }
10393
10648
  if (v1 === v2) return 0;
10394
10649
  return v1 < v2 ? -1 : 1;
10395
10650
  } else {
@@ -10809,7 +11064,7 @@ function FormController(element, attrs) {
10809
11064
  errors = form.$error = {};
10810
11065
 
10811
11066
  // init state
10812
- form.$name = attrs.name;
11067
+ form.$name = attrs.name || attrs.ngForm;
10813
11068
  form.$dirty = false;
10814
11069
  form.$pristine = true;
10815
11070
  form.$valid = true;
@@ -10829,12 +11084,32 @@ function FormController(element, attrs) {
10829
11084
  addClass((isValid ? VALID_CLASS : INVALID_CLASS) + validationErrorKey);
10830
11085
  }
10831
11086
 
11087
+ /**
11088
+ * @ngdoc function
11089
+ * @name ng.directive:form.FormController#$addControl
11090
+ * @methodOf ng.directive:form.FormController
11091
+ *
11092
+ * @description
11093
+ * Register a control with the form.
11094
+ *
11095
+ * Input elements using ngModelController do this automatically when they are linked.
11096
+ */
10832
11097
  form.$addControl = function(control) {
10833
11098
  if (control.$name && !form.hasOwnProperty(control.$name)) {
10834
11099
  form[control.$name] = control;
10835
11100
  }
10836
11101
  };
10837
11102
 
11103
+ /**
11104
+ * @ngdoc function
11105
+ * @name ng.directive:form.FormController#$removeControl
11106
+ * @methodOf ng.directive:form.FormController
11107
+ *
11108
+ * @description
11109
+ * Deregister a control from the form.
11110
+ *
11111
+ * Input elements using ngModelController do this automatically when they are destroyed.
11112
+ */
10838
11113
  form.$removeControl = function(control) {
10839
11114
  if (control.$name && form[control.$name] === control) {
10840
11115
  delete form[control.$name];
@@ -10844,6 +11119,16 @@ function FormController(element, attrs) {
10844
11119
  });
10845
11120
  };
10846
11121
 
11122
+ /**
11123
+ * @ngdoc function
11124
+ * @name ng.directive:form.FormController#$setValidity
11125
+ * @methodOf ng.directive:form.FormController
11126
+ *
11127
+ * @description
11128
+ * Sets the validity of a form control.
11129
+ *
11130
+ * This method will also propagate to parent forms.
11131
+ */
10847
11132
  form.$setValidity = function(validationToken, isValid, control) {
10848
11133
  var queue = errors[validationToken];
10849
11134
 
@@ -10882,6 +11167,17 @@ function FormController(element, attrs) {
10882
11167
  }
10883
11168
  };
10884
11169
 
11170
+ /**
11171
+ * @ngdoc function
11172
+ * @name ng.directive:form.FormController#$setDirty
11173
+ * @methodOf ng.directive:form.FormController
11174
+ *
11175
+ * @description
11176
+ * Sets the form to a dirty state.
11177
+ *
11178
+ * This method can be called to add the 'ng-dirty' class and set the form to a dirty
11179
+ * state (ng-dirty class). This method will also propagate to parent forms.
11180
+ */
10885
11181
  form.$setDirty = function() {
10886
11182
  element.removeClass(PRISTINE_CLASS).addClass(DIRTY_CLASS);
10887
11183
  form.$dirty = true;
@@ -11058,7 +11354,7 @@ var formDirective = formDirectiveFactory();
11058
11354
  var ngFormDirective = formDirectiveFactory(true);
11059
11355
 
11060
11356
  var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;
11061
- var EMAIL_REGEXP = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/;
11357
+ var EMAIL_REGEXP = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}$/;
11062
11358
  var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/;
11063
11359
 
11064
11360
  var inputType = {
@@ -11142,8 +11438,8 @@ var inputType = {
11142
11438
  *
11143
11439
  * @param {string} ngModel Assignable angular expression to data-bind to.
11144
11440
  * @param {string=} name Property name of the form under which the control is published.
11145
- * @param {string=} min Sets the `min` validation error key if the value entered is less then `min`.
11146
- * @param {string=} max Sets the `max` validation error key if the value entered is greater then `min`.
11441
+ * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
11442
+ * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
11147
11443
  * @param {string=} required Sets `required` validation error key if the value is not entered.
11148
11444
  * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
11149
11445
  * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
@@ -11169,9 +11465,9 @@ var inputType = {
11169
11465
  <form name="myForm" ng-controller="Ctrl">
11170
11466
  Number: <input type="number" name="input" ng-model="value"
11171
11467
  min="0" max="99" required>
11172
- <span class="error" ng-show="myForm.list.$error.required">
11468
+ <span class="error" ng-show="myForm.input.$error.required">
11173
11469
  Required!</span>
11174
- <span class="error" ng-show="myForm.list.$error.number">
11470
+ <span class="error" ng-show="myForm.input.$error.number">
11175
11471
  Not valid number!</span>
11176
11472
  <tt>value = {{value}}</tt><br/>
11177
11473
  <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
@@ -11292,6 +11588,8 @@ var inputType = {
11292
11588
  * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the
11293
11589
  * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
11294
11590
  * patterns defined as scope expressions.
11591
+ * @param {string=} ngChange Angular expression to be executed when input changes due to user
11592
+ * interaction with the input element.
11295
11593
  *
11296
11594
  * @example
11297
11595
  <doc:example>
@@ -11455,6 +11753,15 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
11455
11753
  } else {
11456
11754
  var timeout;
11457
11755
 
11756
+ var deferListener = function() {
11757
+ if (!timeout) {
11758
+ timeout = $browser.defer(function() {
11759
+ listener();
11760
+ timeout = null;
11761
+ });
11762
+ }
11763
+ };
11764
+
11458
11765
  element.bind('keydown', function(event) {
11459
11766
  var key = event.keyCode;
11460
11767
 
@@ -11462,16 +11769,16 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
11462
11769
  // command modifiers arrows
11463
11770
  if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return;
11464
11771
 
11465
- if (!timeout) {
11466
- timeout = $browser.defer(function() {
11467
- listener();
11468
- timeout = null;
11469
- });
11470
- }
11772
+ deferListener();
11471
11773
  });
11472
11774
 
11473
11775
  // if user paste into input using mouse, we need "change" event to catch it
11474
11776
  element.bind('change', listener);
11777
+
11778
+ // if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it
11779
+ if ($sniffer.hasEvent('paste')) {
11780
+ element.bind('paste cut', deferListener);
11781
+ }
11475
11782
  }
11476
11783
 
11477
11784
 
@@ -11770,7 +12077,7 @@ function checkboxInputType(scope, element, attr, ctrl) {
11770
12077
  <tt>myForm.userName.$valid = {{myForm.userName.$valid}}</tt><br>
11771
12078
  <tt>myForm.userName.$error = {{myForm.userName.$error}}</tt><br>
11772
12079
  <tt>myForm.lastName.$valid = {{myForm.lastName.$valid}}</tt><br>
11773
- <tt>myForm.userName.$error = {{myForm.lastName.$error}}</tt><br>
12080
+ <tt>myForm.lastName.$error = {{myForm.lastName.$error}}</tt><br>
11774
12081
  <tt>myForm.$valid = {{myForm.$valid}}</tt><br>
11775
12082
  <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br>
11776
12083
  <tt>myForm.$error.minlength = {{!!myForm.$error.minlength}}</tt><br>
@@ -11841,12 +12148,25 @@ var VALID_CLASS = 'ng-valid',
11841
12148
  *
11842
12149
  * @property {string} $viewValue Actual string value in the view.
11843
12150
  * @property {*} $modelValue The value in the model, that the control is bound to.
11844
- * @property {Array.<Function>} $parsers Whenever the control reads value from the DOM, it executes
11845
- * all of these functions to sanitize / convert the value as well as validate.
11846
- *
11847
- * @property {Array.<Function>} $formatters Whenever the model value changes, it executes all of
11848
- * these functions to convert the value as well as validate.
11849
- *
12151
+ * @property {Array.<Function>} $parsers Array of functions to execute, as a pipeline, whenever
12152
+ the control reads value from the DOM. Each function is called, in turn, passing the value
12153
+ through to the next. Used to sanitize / convert the value as well as validation.
12154
+
12155
+ For validation, the parsers should update the validity state using
12156
+ {@link ng.directive:ngModel.NgModelController#$setValidity $setValidity()},
12157
+ and return `undefined` for invalid values.
12158
+ *
12159
+ * @property {Array.<Function>} $formatters Array of functions to execute, as a pipeline, whenever
12160
+ * the model value changes. Each function is called, in turn, passing the value through to the
12161
+ * next. Used to format / convert values for display in the control and validation.
12162
+ * <pre>
12163
+ * function formatter(value) {
12164
+ * if (value) {
12165
+ * return value.toUpperCase();
12166
+ * }
12167
+ * }
12168
+ * ngModel.$formatters.push(formatter);
12169
+ * </pre>
11850
12170
  * @property {Object} $error An bject hash with all errors as keys.
11851
12171
  *
11852
12172
  * @property {boolean} $pristine True if user has not interacted with the control yet.
@@ -11861,6 +12181,10 @@ var VALID_CLASS = 'ng-valid',
11861
12181
  * specifically does not contain any logic which deals with DOM rendering or listening to
11862
12182
  * DOM events. The `NgModelController` is meant to be extended by other directives where, the
11863
12183
  * directive provides DOM manipulation and the `NgModelController` provides the data-binding.
12184
+ * Note that you cannot use `NgModelController` in a directive with an isolated scope,
12185
+ * as, in that case, the `ng-model` value gets put into the isolated scope and does not get
12186
+ * propogated to the parent scope.
12187
+ *
11864
12188
  *
11865
12189
  * This example shows how to use `NgModelController` with a custom control to achieve
11866
12190
  * data-binding. Notice how different directives (`contenteditable`, `ng-model`, and `required`)
@@ -11901,7 +12225,13 @@ var VALID_CLASS = 'ng-valid',
11901
12225
 
11902
12226
  // Write data to the model
11903
12227
  function read() {
11904
- ngModel.$setViewValue(element.html());
12228
+ var html = element.html();
12229
+ // When we clear the content editable the browser leaves a <br> behind
12230
+ // If strip-br attribute is provided then we strip this out
12231
+ if( attrs.stripBr && html == '<br>' ) {
12232
+ html = '';
12233
+ }
12234
+ ngModel.$setViewValue(html);
11905
12235
  }
11906
12236
  }
11907
12237
  };
@@ -11911,6 +12241,7 @@ var VALID_CLASS = 'ng-valid',
11911
12241
  <form name="myForm">
11912
12242
  <div contenteditable
11913
12243
  name="myWidget" ng-model="userContent"
12244
+ strip-br="true"
11914
12245
  required>Change me!</div>
11915
12246
  <span ng-show="myForm.myWidget.$error.required">Required!</span>
11916
12247
  <hr>
@@ -12033,8 +12364,8 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
12033
12364
  * For example {@link ng.directive:input input} or
12034
12365
  * {@link ng.directive:select select} directives call it.
12035
12366
  *
12036
- * It internally calls all `formatters` and if resulted value is valid, updates the model and
12037
- * calls all registered change listeners.
12367
+ * It internally calls all `$parsers` (including validators) and updates the `$modelValue` and the actual model path.
12368
+ * Lastly it calls all registered change listeners.
12038
12369
  *
12039
12370
  * @param {string} value Value from the view.
12040
12371
  */
@@ -12099,7 +12430,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
12099
12430
  * @element input
12100
12431
  *
12101
12432
  * @description
12102
- * Is directive that tells Angular to do two-way data binding. It works together with `input`,
12433
+ * Is a directive that tells Angular to do two-way data binding. It works together with `input`,
12103
12434
  * `select`, `textarea`. You can easily write your own directives to use `ngModel` as well.
12104
12435
  *
12105
12436
  * `ngModel` is responsible for:
@@ -12111,6 +12442,10 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
12111
12442
  * - setting related css class onto the element (`ng-valid`, `ng-invalid`, `ng-dirty`, `ng-pristine`),
12112
12443
  * - register the control with parent {@link ng.directive:form form}.
12113
12444
  *
12445
+ * Note: `ngModel` will try to bind to the property given by evaluating the expression on the
12446
+ * current scope. If the property doesn't already exist on this scope, it will be created
12447
+ * implicitly and added to the scope.
12448
+ *
12114
12449
  * For basic examples, how to use `ngModel`, see:
12115
12450
  *
12116
12451
  * - {@link ng.directive:input input}
@@ -12251,8 +12586,9 @@ var requiredDirective = function() {
12251
12586
  </script>
12252
12587
  <form name="myForm" ng-controller="Ctrl">
12253
12588
  List: <input name="namesInput" ng-model="names" ng-list required>
12254
- <span class="error" ng-show="myForm.list.$error.required">
12589
+ <span class="error" ng-show="myForm.namesInput.$error.required">
12255
12590
  Required!</span>
12591
+ <br>
12256
12592
  <tt>names = {{names}}</tt><br/>
12257
12593
  <tt>myForm.namesInput.$valid = {{myForm.namesInput.$valid}}</tt><br/>
12258
12594
  <tt>myForm.namesInput.$error = {{myForm.namesInput.$error}}</tt><br/>
@@ -12264,12 +12600,14 @@ var requiredDirective = function() {
12264
12600
  it('should initialize to model', function() {
12265
12601
  expect(binding('names')).toEqual('["igor","misko","vojta"]');
12266
12602
  expect(binding('myForm.namesInput.$valid')).toEqual('true');
12603
+ expect(element('span.error').css('display')).toBe('none');
12267
12604
  });
12268
12605
 
12269
12606
  it('should be invalid if empty', function() {
12270
12607
  input('names').enter('');
12271
12608
  expect(binding('names')).toEqual('[]');
12272
12609
  expect(binding('myForm.namesInput.$valid')).toEqual('false');
12610
+ expect(element('span.error').css('display')).not().toBe('none');
12273
12611
  });
12274
12612
  </doc:scenario>
12275
12613
  </doc:example>
@@ -12319,7 +12657,7 @@ var ngValueDirective = function() {
12319
12657
  } else {
12320
12658
  return function(scope, elm, attr) {
12321
12659
  scope.$watch(attr.ngValue, function valueWatchAction(value) {
12322
- attr.$set('value', value, false);
12660
+ attr.$set('value', value);
12323
12661
  });
12324
12662
  };
12325
12663
  }
@@ -12339,10 +12677,9 @@ var ngValueDirective = function() {
12339
12677
  * Typically, you don't use `ngBind` directly, but instead you use the double curly markup like
12340
12678
  * `{{ expression }}` which is similar but less verbose.
12341
12679
  *
12342
- * Once scenario in which the use of `ngBind` is prefered over `{{ expression }}` binding is when
12343
- * it's desirable to put bindings into template that is momentarily displayed by the browser in its
12344
- * raw state before Angular compiles it. Since `ngBind` is an element attribute, it makes the
12345
- * bindings invisible to the user while the page is loading.
12680
+ * It is preferrable to use `ngBind` instead of `{{ expression }}` when a template is momentarily
12681
+ * displayed by the browser in its raw state before Angular compiles it. Since `ngBind` is an
12682
+ * element attribute, it makes the bindings invisible to the user while the page is loading.
12346
12683
  *
12347
12684
  * An alternative solution to this problem would be using the
12348
12685
  * {@link ng.directive:ngCloak ngCloak} directive.
@@ -12388,10 +12725,11 @@ var ngBindDirective = ngDirective(function(scope, element, attr) {
12388
12725
  *
12389
12726
  * @description
12390
12727
  * The `ngBindTemplate` directive specifies that the element
12391
- * text should be replaced with the template in ngBindTemplate.
12392
- * Unlike ngBind the ngBindTemplate can contain multiple `{{` `}}`
12393
- * expressions. (This is required since some HTML elements
12394
- * can not have SPAN elements such as TITLE, or OPTION to name a few.)
12728
+ * text content should be replaced with the interpolation of the template
12729
+ * in the `ngBindTemplate` attribute.
12730
+ * Unlike `ngBind`, the `ngBindTemplate` can contain multiple `{{` `}}`
12731
+ * expressions. This directive is needed since some HTML elements
12732
+ * (such as TITLE and OPTION) cannot contain SPAN elements.
12395
12733
  *
12396
12734
  * @element ANY
12397
12735
  * @param {string} ngBindTemplate template of form
@@ -12480,9 +12818,9 @@ function classDirective(name, selector) {
12480
12818
 
12481
12819
  if (name !== 'ngClass') {
12482
12820
  scope.$watch('$index', function($index, old$index) {
12483
- var mod = $index % 2;
12484
- if (mod !== old$index % 2) {
12485
- if (mod == selector) {
12821
+ var mod = $index & 1;
12822
+ if (mod !== old$index & 1) {
12823
+ if (mod === selector) {
12486
12824
  addClass(scope.$eval(attr[name]));
12487
12825
  } else {
12488
12826
  removeClass(scope.$eval(attr[name]));
@@ -12494,12 +12832,12 @@ function classDirective(name, selector) {
12494
12832
 
12495
12833
  function ngClassWatchAction(newVal) {
12496
12834
  if (selector === true || scope.$index % 2 === selector) {
12497
- if (oldVal && (newVal !== oldVal)) {
12835
+ if (oldVal && !equals(newVal,oldVal)) {
12498
12836
  removeClass(oldVal);
12499
12837
  }
12500
12838
  addClass(newVal);
12501
12839
  }
12502
- oldVal = newVal;
12840
+ oldVal = copy(newVal);
12503
12841
  }
12504
12842
 
12505
12843
 
@@ -12527,8 +12865,8 @@ function classDirective(name, selector) {
12527
12865
  * @name ng.directive:ngClass
12528
12866
  *
12529
12867
  * @description
12530
- * The `ngClass` allows you to set CSS class on HTML element dynamically by databinding an
12531
- * expression that represents all classes to be added.
12868
+ * The `ngClass` allows you to set CSS classes on HTML an element, dynamically, by databinding
12869
+ * an expression that represents all classes to be added.
12532
12870
  *
12533
12871
  * The directive won't add duplicate classes if a particular class was already set.
12534
12872
  *
@@ -12538,7 +12876,9 @@ function classDirective(name, selector) {
12538
12876
  * @element ANY
12539
12877
  * @param {expression} ngClass {@link guide/expression Expression} to eval. The result
12540
12878
  * of the evaluation can be a string representing space delimited class
12541
- * names, an array, or a map of class names to boolean values.
12879
+ * names, an array, or a map of class names to boolean values. In the case of a map, the
12880
+ * names of the properties whose values are truthy will be added as css classes to the
12881
+ * element.
12542
12882
  *
12543
12883
  * @example
12544
12884
  <example>
@@ -12625,7 +12965,7 @@ var ngClassOddDirective = classDirective('Odd', 0);
12625
12965
  * @name ng.directive:ngClassEven
12626
12966
  *
12627
12967
  * @description
12628
- * The `ngClassOdd` and `ngClassEven` works exactly as
12968
+ * The `ngClassOdd` and `ngClassEven` directives work exactly as
12629
12969
  * {@link ng.directive:ngClass ngClass}, except it works in
12630
12970
  * conjunction with `ngRepeat` and takes affect only on odd (even) rows.
12631
12971
  *
@@ -12684,7 +13024,7 @@ var ngClassEvenDirective = classDirective('Even', 1);
12684
13024
  *
12685
13025
  * <pre>
12686
13026
  * [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
12687
- * display: none;
13027
+ * display: none !important;
12688
13028
  * }
12689
13029
  * </pre>
12690
13030
  *
@@ -12742,8 +13082,7 @@ var ngCloakDirective = ngDirective({
12742
13082
  * * Controller — The `ngController` directive specifies a Controller class; the class has
12743
13083
  * methods that typically express the business logic behind the application.
12744
13084
  *
12745
- * Note that an alternative way to define controllers is via the `{@link ng.$route}`
12746
- * service.
13085
+ * Note that an alternative way to define controllers is via the {@link ng.$route $route} service.
12747
13086
  *
12748
13087
  * @element ANY
12749
13088
  * @scope
@@ -12753,11 +13092,9 @@ var ngCloakDirective = ngDirective({
12753
13092
  *
12754
13093
  * @example
12755
13094
  * Here is a simple form for editing user contact information. Adding, removing, clearing, and
12756
- * greeting are methods declared on the controller (see source tab). These methods can
12757
- * easily be called from the angular markup. Notice that the scope becomes the `this` for the
12758
- * controller's instance. This allows for easy access to the view data from the controller. Also
12759
- * notice that any changes to the data are automatically reflected in the View without the need
12760
- * for a manual update.
13095
+ * greeting are methods declared on the $scope by the controller (see source tab). These methods can
13096
+ * easily be called from the angular markup. Notice that any changes to the data are automatically
13097
+ * reflected in the View without the need for a manual update.
12761
13098
  <doc:example>
12762
13099
  <doc:source>
12763
13100
  <script>
@@ -12834,16 +13171,32 @@ var ngControllerDirective = [function() {
12834
13171
  * @name ng.directive:ngCsp
12835
13172
  * @priority 1000
12836
13173
  *
13174
+ * @element html
12837
13175
  * @description
12838
13176
  * Enables [CSP (Content Security Policy)](https://developer.mozilla.org/en/Security/CSP) support.
12839
- * This directive should be used on the root element of the application (typically the `<html>`
12840
- * element or other element with the {@link ng.directive:ngApp ngApp}
12841
- * directive).
12842
- *
12843
- * If enabled the performance of template expression evaluator will suffer slightly, so don't enable
12844
- * this mode unless you need it.
12845
- *
12846
- * @element html
13177
+ *
13178
+ * This is necessary when developing things like Google Chrome Extensions.
13179
+ *
13180
+ * CSP forbids apps to use `eval` or `Function(string)` generated functions (among other things).
13181
+ * For us to be compatible, we just need to implement the "getterFn" in $parse without violating
13182
+ * any of these restrictions.
13183
+ *
13184
+ * AngularJS uses `Function(string)` generated functions as a speed optimization. By applying `ngCsp`
13185
+ * it is be possible to opt into the CSP compatible mode. When this mode is on AngularJS will
13186
+ * evaluate all expressions up to 30% slower than in non-CSP mode, but no security violations will
13187
+ * be raised.
13188
+ *
13189
+ * In order to use this feature put `ngCsp` directive on the root element of the application.
13190
+ *
13191
+ * @example
13192
+ * This example shows how to apply the `ngCsp` directive to the `html` tag.
13193
+ <pre>
13194
+ <!doctype html>
13195
+ <html ng-app ng-csp>
13196
+ ...
13197
+ ...
13198
+ </html>
13199
+ </pre>
12847
13200
  */
12848
13201
 
12849
13202
  var ngCspDirective = ['$sniffer', function($sniffer) {
@@ -12892,7 +13245,7 @@ var ngCspDirective = ['$sniffer', function($sniffer) {
12892
13245
  */
12893
13246
  var ngEventDirectives = {};
12894
13247
  forEach(
12895
- 'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave'.split(' '),
13248
+ 'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave submit'.split(' '),
12896
13249
  function(name) {
12897
13250
  var directiveName = directiveNormalize('ng-' + name);
12898
13251
  ngEventDirectives[directiveName] = ['$parse', function($parse) {
@@ -13019,6 +13372,54 @@ forEach(
13019
13372
  */
13020
13373
 
13021
13374
 
13375
+ /**
13376
+ * @ngdoc directive
13377
+ * @name ng.directive:ngKeydown
13378
+ *
13379
+ * @description
13380
+ * Specify custom behavior on keydown event.
13381
+ *
13382
+ * @element ANY
13383
+ * @param {expression} ngKeydown {@link guide/expression Expression} to evaluate upon
13384
+ * keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
13385
+ *
13386
+ * @example
13387
+ * See {@link ng.directive:ngClick ngClick}
13388
+ */
13389
+
13390
+
13391
+ /**
13392
+ * @ngdoc directive
13393
+ * @name ng.directive:ngKeyup
13394
+ *
13395
+ * @description
13396
+ * Specify custom behavior on keyup event.
13397
+ *
13398
+ * @element ANY
13399
+ * @param {expression} ngKeyup {@link guide/expression Expression} to evaluate upon
13400
+ * keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
13401
+ *
13402
+ * @example
13403
+ * See {@link ng.directive:ngClick ngClick}
13404
+ */
13405
+
13406
+
13407
+ /**
13408
+ * @ngdoc directive
13409
+ * @name ng.directive:ngKeypress
13410
+ *
13411
+ * @description
13412
+ * Specify custom behavior on keypress event.
13413
+ *
13414
+ * @element ANY
13415
+ * @param {expression} ngKeypress {@link guide/expression Expression} to evaluate upon
13416
+ * keypress. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
13417
+ *
13418
+ * @example
13419
+ * See {@link ng.directive:ngClick ngClick}
13420
+ */
13421
+
13422
+
13022
13423
  /**
13023
13424
  * @ngdoc directive
13024
13425
  * @name ng.directive:ngSubmit
@@ -13027,10 +13428,11 @@ forEach(
13027
13428
  * Enables binding angular expressions to onsubmit events.
13028
13429
  *
13029
13430
  * Additionally it prevents the default action (which for form means sending the request to the
13030
- * server and reloading the current page).
13431
+ * server and reloading the current page) **but only if the form does not contain an `action`
13432
+ * attribute**.
13031
13433
  *
13032
13434
  * @element form
13033
- * @param {expression} ngSubmit {@link guide/expression Expression} to eval.
13435
+ * @param {expression} ngSubmit {@link guide/expression Expression} to eval. (Event object is available as `$event`)
13034
13436
  *
13035
13437
  * @example
13036
13438
  <doc:example>
@@ -13070,11 +13472,6 @@ forEach(
13070
13472
  </doc:scenario>
13071
13473
  </doc:example>
13072
13474
  */
13073
- var ngSubmitDirective = ngDirective(function(scope, element, attrs) {
13074
- element.bind('submit', function() {
13075
- scope.$apply(attrs.ngSubmit);
13076
- });
13077
- });
13078
13475
 
13079
13476
  /**
13080
13477
  * @ngdoc directive
@@ -13282,7 +13679,7 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
13282
13679
  * @description
13283
13680
  * # Overview
13284
13681
  * `ngPluralize` is a directive that displays messages according to en-US localization rules.
13285
- * These rules are bundled with angular.js and the rules can be overridden
13682
+ * These rules are bundled with angular.js, but can be overridden
13286
13683
  * (see {@link guide/i18n Angular i18n} dev guide). You configure ngPluralize directive
13287
13684
  * by specifying the mappings between
13288
13685
  * {@link http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
@@ -13295,8 +13692,8 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
13295
13692
  *
13296
13693
  * While a pural category may match many numbers (for example, in en-US locale, "other" can match
13297
13694
  * any number that is not 1), an explicit number rule can only match one number. For example, the
13298
- * explicit number rule for "3" matches the number 3. You will see the use of plural categories
13299
- * and explicit number rules throughout later parts of this documentation.
13695
+ * explicit number rule for "3" matches the number 3. There are examples of plural categories
13696
+ * and explicit number rules throughout the rest of this documentation.
13300
13697
  *
13301
13698
  * # Configuring ngPluralize
13302
13699
  * You configure ngPluralize by providing 2 attributes: `count` and `when`.
@@ -13306,8 +13703,7 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
13306
13703
  * Angular expression}; these are evaluated on the current scope for its bound value.
13307
13704
  *
13308
13705
  * The `when` attribute specifies the mappings between plural categories and the actual
13309
- * string to be displayed. The value of the attribute should be a JSON object so that Angular
13310
- * can interpret it correctly.
13706
+ * string to be displayed. The value of the attribute should be a JSON object.
13311
13707
  *
13312
13708
  * The following example shows how to configure ngPluralize:
13313
13709
  *
@@ -13468,7 +13864,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
13468
13864
  if (!isNaN(value)) {
13469
13865
  //if explicit number rule such as 1, 2, 3... is defined, just use it. Otherwise,
13470
13866
  //check it against pluralization rules in $locale service
13471
- if (!whens[value]) value = $locale.pluralCat(value - offset);
13867
+ if (!(value in whens)) value = $locale.pluralCat(value - offset);
13472
13868
  return whensExpFns[value](scope, element, true);
13473
13869
  } else {
13474
13870
  return '';
@@ -13931,8 +14327,7 @@ var ngSwitchDefaultDirective = ngDirective({
13931
14327
  return {
13932
14328
  restrict: 'E',
13933
14329
  transclude: true,
13934
- scope: 'isolate',
13935
- locals: { title:'bind' },
14330
+ scope: { title:'@' },
13936
14331
  template: '<div style="border: 1px solid black;">' +
13937
14332
  '<div style="background-color: gray">{{title}}</div>' +
13938
14333
  '<div ng-transclude></div>' +
@@ -14187,8 +14582,8 @@ var scriptDirective = ['$templateCache', function($templateCache) {
14187
14582
  * Optionally `ngOptions` attribute can be used to dynamically generate a list of `<option>`
14188
14583
  * elements for a `<select>` element using an array or an object obtained by evaluating the
14189
14584
  * `ngOptions` expression.
14190
- *˝˝
14191
- * When an item in the select menu is select, the value of array element or object property
14585
+ *
14586
+ * When an item in the `<select>` menu is selected, the value of array element or object property
14192
14587
  * represented by the selected option will be bound to the model identified by the `ngModel`
14193
14588
  * directive of the parent select element.
14194
14589
  *
@@ -14201,7 +14596,8 @@ var scriptDirective = ['$templateCache', function($templateCache) {
14201
14596
  * `select` model to be bound to a non-string value. This is because an option element can currently
14202
14597
  * be bound to string values only.
14203
14598
  *
14204
- * @param {string} name assignable expression to data-bind to.
14599
+ * @param {string} ngModel Assignable angular expression to data-bind to.
14600
+ * @param {string=} name Property name of the form under which the control is published.
14205
14601
  * @param {string=} required The control is considered valid only if value is entered.
14206
14602
  * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
14207
14603
  * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
@@ -14568,10 +14964,6 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
14568
14964
 
14569
14965
  if (multiple) {
14570
14966
  selectedSet = new HashMap(modelValue);
14571
- } else if (modelValue === null || nullOption) {
14572
- // if we are not multiselect, and we are null then we have to add the nullOption
14573
- optionGroups[''].push({selected:modelValue === null, id:'', label:''});
14574
- selectedSet = true;
14575
14967
  }
14576
14968
 
14577
14969
  // We now build up the list of options we need (we merge later)
@@ -14596,9 +14988,14 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
14596
14988
  selected: selected // determine if we should be selected
14597
14989
  });
14598
14990
  }
14599
- if (!multiple && !selectedSet) {
14600
- // nothing was selected, we have to insert the undefined item
14601
- optionGroups[''].unshift({id:'?', label:'', selected:true});
14991
+ if (!multiple) {
14992
+ if (nullOption || modelValue === null) {
14993
+ // insert null option if we have a placeholder, or the model is null
14994
+ optionGroups[''].unshift({id:'', label:'', selected:!selectedSet});
14995
+ } else if (!selectedSet) {
14996
+ // option could not be found, we have to insert the undefined item
14997
+ optionGroups[''].unshift({id:'?', label:'', selected:true});
14998
+ }
14602
14999
  }
14603
15000
 
14604
15001
  // Now we need to update the list of DOM nodes to match the optionGroups we computed above
@@ -14642,7 +15039,8 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
14642
15039
  if (existingOption.id !== option.id) {
14643
15040
  lastElement.val(existingOption.id = option.id);
14644
15041
  }
14645
- if (existingOption.element.selected !== option.selected) {
15042
+ // lastElement.prop('selected') provided by jQuery has side-effects
15043
+ if (lastElement[0].selected !== option.selected) {
14646
15044
  lastElement.prop('selected', (existingOption.selected = option.selected));
14647
15045
  }
14648
15046
  } else {
@@ -14757,4 +15155,4 @@ var styleDirective = valueFn({
14757
15155
  });
14758
15156
 
14759
15157
  })(window, document);
14760
- angular.element(document).find('head').append('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak{display:none;}ng\\:form{display:block;}</style>');
15158
+ angular.element(document).find('head').append('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak{display:none !important;}ng\\:form{display:block;}</style>');