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.5
2
+ * @license AngularJS v1.0.8
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -24,6 +24,17 @@
24
24
  * The returned resource object has action methods which provide high-level behaviors without
25
25
  * the need to interact with the low level {@link ng.$http $http} service.
26
26
  *
27
+ * # Installation
28
+ * To use $resource make sure you have included the `angular-resource.js` that comes in Angular
29
+ * package. You can also find this file on Google CDN, bower as well as at
30
+ * {@link http://code.angularjs.org/ code.angularjs.org}.
31
+ *
32
+ * Finally load the module in your application:
33
+ *
34
+ * angular.module('app', ['ngResource']);
35
+ *
36
+ * and you are ready to get started!
37
+ *
27
38
  * @param {string} url A parameterized URL template with parameters prefixed by `:` as in
28
39
  * `/user/:username`. If you are using a URL with a port number (e.g.
29
40
  * `http://example.com:8080/api`), you'll need to escape the colon character before the port
@@ -50,12 +61,12 @@
50
61
  *
51
62
  * Where:
52
63
  *
53
- * - `action` {string} The name of action. This name becomes the name of the method on your
64
+ * - `action` – {string} – The name of action. This name becomes the name of the method on your
54
65
  * resource object.
55
- * - `method` {string} HTTP request method. Valid methods are: `GET`, `POST`, `PUT`, `DELETE`,
66
+ * - `method` – {string} – HTTP request method. Valid methods are: `GET`, `POST`, `PUT`, `DELETE`,
56
67
  * and `JSONP`
57
- * - `params` {object=} Optional set of pre-bound parameters for this action.
58
- * - isArray {boolean=} If true then the returned object for this action is an array, see
68
+ * - `params` – {object=} – Optional set of pre-bound parameters for this action.
69
+ * - isArray – {boolean=} – If true then the returned object for this action is an array, see
59
70
  * `returns` section.
60
71
  *
61
72
  * @returns {Object} A resource "class" object with methods for the default set of resource actions
@@ -268,7 +279,7 @@ angular.module('ngResource', ['ng']).
268
279
  replace(/%3A/gi, ':').
269
280
  replace(/%24/g, '$').
270
281
  replace(/%2C/gi, ',').
271
- replace((pctEncodeSpaces ? null : /%20/g), '+');
282
+ replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
272
283
  }
273
284
 
274
285
  function Route(template, defaults) {
@@ -442,4 +453,5 @@ angular.module('ngResource', ['ng']).
442
453
  return ResourceFactory;
443
454
  }]);
444
455
 
445
- })(window, window.angular);
456
+
457
+ })(window, window.angular);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.0.5
2
+ * @license AngularJS v1.0.8
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -10,6 +10,25 @@
10
10
  * @ngdoc overview
11
11
  * @name ngSanitize
12
12
  * @description
13
+ *
14
+ * The `ngSanitize` module provides functionality to sanitize HTML.
15
+ *
16
+ * # Installation
17
+ * As a separate module, it must be loaded after Angular core is loaded; otherwise, an 'Uncaught Error:
18
+ * No module: ngSanitize' runtime error will occur.
19
+ *
20
+ * <pre>
21
+ * <script src="angular.js"></script>
22
+ * <script src="angular-sanitize.js"></script>
23
+ * </pre>
24
+ *
25
+ * # Usage
26
+ * To make sure the module is available to your application, declare it as a dependency of you application
27
+ * module.
28
+ *
29
+ * <pre>
30
+ * angular.module('app', ['ngSanitize']);
31
+ * </pre>
13
32
  */
14
33
 
15
34
  /*
@@ -129,7 +148,7 @@ var START_TAG_REGEXP = /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:
129
148
  BEGING_END_TAGE_REGEXP = /^<\s*\//,
130
149
  COMMENT_REGEXP = /<!--(.*?)-->/g,
131
150
  CDATA_REGEXP = /<!\[CDATA\[(.*?)]]>/g,
132
- URI_REGEXP = /^((ftp|https?):\/\/|mailto:|#)/,
151
+ URI_REGEXP = /^((ftp|https?):\/\/|mailto:|#)/i,
133
152
  NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g; // Match everything outside of normal chars and " (quote character)
134
153
 
135
154
 
@@ -283,10 +302,10 @@ function htmlParser( html, handler ) {
283
302
 
284
303
  var attrs = {};
285
304
 
286
- rest.replace(ATTR_REGEXP, function(match, name, doubleQuotedValue, singleQoutedValue, unqoutedValue) {
305
+ rest.replace(ATTR_REGEXP, function(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) {
287
306
  var value = doubleQuotedValue
288
- || singleQoutedValue
289
- || unqoutedValue
307
+ || singleQuotedValue
308
+ || unquotedValue
290
309
  || '';
291
310
 
292
311
  attrs[name] = decodeEntities(value);
@@ -422,6 +441,7 @@ angular.module('ngSanitize').directive('ngBindHtml', ['$sanitize', function($san
422
441
  });
423
442
  };
424
443
  }]);
444
+
425
445
  /**
426
446
  * @ngdoc filter
427
447
  * @name ngSanitize.filter:linky
@@ -532,4 +552,5 @@ angular.module('ngSanitize').filter('linky', function() {
532
552
  };
533
553
  });
534
554
 
535
- })(window, window.angular);
555
+
556
+ })(window, window.angular);
@@ -9403,8 +9403,9 @@ if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
9403
9403
 
9404
9404
 
9405
9405
  })( window );
9406
+
9406
9407
  /**
9407
- * @license AngularJS v1.0.5
9408
+ * @license AngularJS v1.0.8
9408
9409
  * (c) 2010-2012 Google, Inc. http://angularjs.org
9409
9410
  * License: MIT
9410
9411
  */
@@ -9439,12 +9440,12 @@ var uppercase = function(string){return isString(string) ? string.toUpperCase()
9439
9440
 
9440
9441
  var manualLowercase = function(s) {
9441
9442
  return isString(s)
9442
- ? s.replace(/[A-Z]/g, function(ch) {return fromCharCode(ch.charCodeAt(0) | 32);})
9443
+ ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})
9443
9444
  : s;
9444
9445
  };
9445
9446
  var manualUppercase = function(s) {
9446
9447
  return isString(s)
9447
- ? s.replace(/[a-z]/g, function(ch) {return fromCharCode(ch.charCodeAt(0) & ~32);})
9448
+ ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})
9448
9449
  : s;
9449
9450
  };
9450
9451
 
@@ -9457,8 +9458,6 @@ if ('i' !== 'I'.toLowerCase()) {
9457
9458
  uppercase = manualUppercase;
9458
9459
  }
9459
9460
 
9460
- function fromCharCode(code) {return String.fromCharCode(code);}
9461
-
9462
9461
 
9463
9462
  var /** holds major version number for IE or NaN for real browsers */
9464
9463
  msie = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]),
@@ -9474,6 +9473,29 @@ var /** holds major version number for IE or NaN for real browsers */
9474
9473
  nodeName_,
9475
9474
  uid = ['0', '0', '0'];
9476
9475
 
9476
+
9477
+ /**
9478
+ * @private
9479
+ * @param {*} obj
9480
+ * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, ...)
9481
+ */
9482
+ function isArrayLike(obj) {
9483
+ if (!obj || (typeof obj.length !== 'number')) return false;
9484
+
9485
+ // We have on object which has length property. Should we treat it as array?
9486
+ if (typeof obj.hasOwnProperty != 'function' &&
9487
+ typeof obj.constructor != 'function') {
9488
+ // This is here for IE8: it is a bogus object treat it as array;
9489
+ return true;
9490
+ } else {
9491
+ return obj instanceof JQLite || // JQLite
9492
+ (jQuery && obj instanceof jQuery) || // jQuery
9493
+ toString.call(obj) !== '[object Object]' || // some browser native object
9494
+ typeof obj.callee === 'function'; // arguments (on IE8 looks like regular obj)
9495
+ }
9496
+ }
9497
+
9498
+
9477
9499
  /**
9478
9500
  * @ngdoc function
9479
9501
  * @name angular.forEach
@@ -9501,30 +9523,6 @@ var /** holds major version number for IE or NaN for real browsers */
9501
9523
  * @param {Object=} context Object to become context (`this`) for the iterator function.
9502
9524
  * @returns {Object|Array} Reference to `obj`.
9503
9525
  */
9504
-
9505
-
9506
- /**
9507
- * @private
9508
- * @param {*} obj
9509
- * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, ...)
9510
- */
9511
- function isArrayLike(obj) {
9512
- if (!obj || (typeof obj.length !== 'number')) return false;
9513
-
9514
- // We have on object which has length property. Should we treat it as array?
9515
- if (typeof obj.hasOwnProperty != 'function' &&
9516
- typeof obj.constructor != 'function') {
9517
- // This is here for IE8: it is a bogus object treat it as array;
9518
- return true;
9519
- } else {
9520
- return obj instanceof JQLite || // JQLite
9521
- (jQuery && obj instanceof jQuery) || // jQuery
9522
- toString.call(obj) !== '[object Object]' || // some browser native object
9523
- typeof obj.callee === 'function'; // arguments (on IE8 looks like regular obj)
9524
- }
9525
- }
9526
-
9527
-
9528
9526
  function forEach(obj, iterator, context) {
9529
9527
  var key;
9530
9528
  if (obj) {
@@ -9608,6 +9606,21 @@ function nextUid() {
9608
9606
  return uid.join('');
9609
9607
  }
9610
9608
 
9609
+
9610
+ /**
9611
+ * Set or clear the hashkey for an object.
9612
+ * @param obj object
9613
+ * @param h the hashkey (!truthy to delete the hashkey)
9614
+ */
9615
+ function setHashKey(obj, h) {
9616
+ if (h) {
9617
+ obj.$$hashKey = h;
9618
+ }
9619
+ else {
9620
+ delete obj.$$hashKey;
9621
+ }
9622
+ }
9623
+
9611
9624
  /**
9612
9625
  * @ngdoc function
9613
9626
  * @name angular.extend
@@ -9619,8 +9632,10 @@ function nextUid() {
9619
9632
  *
9620
9633
  * @param {Object} dst Destination object.
9621
9634
  * @param {...Object} src Source object(s).
9635
+ * @returns {Object} Reference to `dst`.
9622
9636
  */
9623
9637
  function extend(dst) {
9638
+ var h = dst.$$hashKey;
9624
9639
  forEach(arguments, function(obj){
9625
9640
  if (obj !== dst) {
9626
9641
  forEach(obj, function(value, key){
@@ -9628,6 +9643,8 @@ function extend(dst) {
9628
9643
  });
9629
9644
  }
9630
9645
  });
9646
+
9647
+ setHashKey(dst,h);
9631
9648
  return dst;
9632
9649
  }
9633
9650
 
@@ -9671,7 +9688,7 @@ noop.$inject = [];
9671
9688
  *
9672
9689
  <pre>
9673
9690
  function transformer(transformationFn, value) {
9674
- return (transformationFn || identity)(value);
9691
+ return (transformationFn || angular.identity)(value);
9675
9692
  };
9676
9693
  </pre>
9677
9694
  */
@@ -9798,6 +9815,18 @@ function isArray(value) {
9798
9815
  function isFunction(value){return typeof value == 'function';}
9799
9816
 
9800
9817
 
9818
+ /**
9819
+ * Determines if a value is a regular expression object.
9820
+ *
9821
+ * @private
9822
+ * @param {*} value Reference to check.
9823
+ * @returns {boolean} True if `value` is a `RegExp`.
9824
+ */
9825
+ function isRegExp(value) {
9826
+ return toString.apply(value) == '[object RegExp]';
9827
+ }
9828
+
9829
+
9801
9830
  /**
9802
9831
  * Checks if `obj` is a window object.
9803
9832
  *
@@ -9825,9 +9854,20 @@ function isBoolean(value) {
9825
9854
  }
9826
9855
 
9827
9856
 
9828
- function trim(value) {
9829
- return isString(value) ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
9830
- }
9857
+ var trim = (function() {
9858
+ // native trim is way faster: http://jsperf.com/angular-trim-test
9859
+ // but IE doesn't have it... :-(
9860
+ // TODO: we should move this into IE/ES5 polyfill
9861
+ if (!String.prototype.trim) {
9862
+ return function(value) {
9863
+ return isString(value) ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
9864
+ };
9865
+ }
9866
+ return function(value) {
9867
+ return isString(value) ? value.trim() : value;
9868
+ };
9869
+ })();
9870
+
9831
9871
 
9832
9872
  /**
9833
9873
  * @ngdoc function
@@ -9970,6 +10010,8 @@ function copy(source, destination){
9970
10010
  destination = copy(source, []);
9971
10011
  } else if (isDate(source)) {
9972
10012
  destination = new Date(source.getTime());
10013
+ } else if (isRegExp(source)) {
10014
+ destination = new RegExp(source.source);
9973
10015
  } else if (isObject(source)) {
9974
10016
  destination = copy(source, {});
9975
10017
  }
@@ -9982,12 +10024,14 @@ function copy(source, destination){
9982
10024
  destination.push(copy(source[i]));
9983
10025
  }
9984
10026
  } else {
10027
+ var h = destination.$$hashKey;
9985
10028
  forEach(destination, function(value, key){
9986
10029
  delete destination[key];
9987
10030
  });
9988
10031
  for ( var key in source) {
9989
10032
  destination[key] = copy(source[key]);
9990
10033
  }
10034
+ setHashKey(destination,h);
9991
10035
  }
9992
10036
  }
9993
10037
  return destination;
@@ -10015,7 +10059,7 @@ function shallowCopy(src, dst) {
10015
10059
  * @function
10016
10060
  *
10017
10061
  * @description
10018
- * Determines if two objects or two values are equivalent. Supports value types, arrays and
10062
+ * Determines if two objects or two values are equivalent. Supports value types, regular expressions, arrays and
10019
10063
  * objects.
10020
10064
  *
10021
10065
  * Two objects or values are considered equivalent if at least one of the following is true:
@@ -10023,11 +10067,14 @@ function shallowCopy(src, dst) {
10023
10067
  * * Both objects or values pass `===` comparison.
10024
10068
  * * Both objects or values are of the same type and all of their properties pass `===` comparison.
10025
10069
  * * Both values are NaN. (In JavasScript, NaN == NaN => false. But we consider two NaN as equal)
10070
+ * * Both values represent the same regular expression (In JavasScript,
10071
+ * /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual
10072
+ * representation matches).
10026
10073
  *
10027
10074
  * During a property comparision, properties of `function` type and properties with names
10028
10075
  * that begin with `$` are ignored.
10029
10076
  *
10030
- * Scope and DOMWindow objects are being compared only be identify (`===`).
10077
+ * Scope and DOMWindow objects are being compared only by identify (`===`).
10031
10078
  *
10032
10079
  * @param {*} o1 Object or value to compare.
10033
10080
  * @param {*} o2 Object or value to compare.
@@ -10041,6 +10088,7 @@ function equals(o1, o2) {
10041
10088
  if (t1 == t2) {
10042
10089
  if (t1 == 'object') {
10043
10090
  if (isArray(o1)) {
10091
+ if (!isArray(o2)) return false;
10044
10092
  if ((length = o1.length) == o2.length) {
10045
10093
  for(key=0; key<length; key++) {
10046
10094
  if (!equals(o1[key], o2[key])) return false;
@@ -10049,8 +10097,10 @@ function equals(o1, o2) {
10049
10097
  }
10050
10098
  } else if (isDate(o1)) {
10051
10099
  return isDate(o2) && o1.getTime() == o2.getTime();
10100
+ } else if (isRegExp(o1) && isRegExp(o2)) {
10101
+ return o1.toString() == o2.toString();
10052
10102
  } else {
10053
- if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2)) return false;
10103
+ if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) || isArray(o2)) return false;
10054
10104
  keySet = {};
10055
10105
  for(key in o1) {
10056
10106
  if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
@@ -10087,7 +10137,7 @@ function sliceArgs(args, startIndex) {
10087
10137
  *
10088
10138
  * @description
10089
10139
  * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for
10090
- * `fn`). You can supply optional `args` that are are prebound to the function. This feature is also
10140
+ * `fn`). You can supply optional `args` that are prebound to the function. This feature is also
10091
10141
  * known as [function currying](http://en.wikipedia.org/wiki/Currying).
10092
10142
  *
10093
10143
  * @param {Object} self Context which `fn` should be evaluated in.
@@ -10139,13 +10189,15 @@ function toJsonReplacer(key, value) {
10139
10189
  * @function
10140
10190
  *
10141
10191
  * @description
10142
- * Serializes input into a JSON-formatted string.
10192
+ * Serializes input into a JSON-formatted string. Properties with leading $ characters will be
10193
+ * stripped since angular uses this notation internally.
10143
10194
  *
10144
10195
  * @param {Object|Array|Date|string|number} obj Input to be serialized into JSON.
10145
10196
  * @param {boolean=} pretty If set to true, the JSON output will contain newlines and whitespace.
10146
- * @returns {string} Jsonified string representing `obj`.
10197
+ * @returns {string|undefined} Jsonified string representing `obj`.
10147
10198
  */
10148
10199
  function toJson(obj, pretty) {
10200
+ if (typeof obj === 'undefined') return undefined;
10149
10201
  return JSON.stringify(obj, toJsonReplacer, pretty ? ' ' : null);
10150
10202
  }
10151
10203
 
@@ -10205,6 +10257,23 @@ function startingTag(element) {
10205
10257
 
10206
10258
  /////////////////////////////////////////////////
10207
10259
 
10260
+ /**
10261
+ * Tries to decode the URI component without throwing an exception.
10262
+ *
10263
+ * @private
10264
+ * @param str value potential URI component to check.
10265
+ * @returns {boolean} True if `value` can be decoded
10266
+ * with the decodeURIComponent function.
10267
+ */
10268
+ function tryDecodeURIComponent(value) {
10269
+ try {
10270
+ return decodeURIComponent(value);
10271
+ } catch(e) {
10272
+ // Ignore any invalid uri component
10273
+ }
10274
+ }
10275
+
10276
+
10208
10277
  /**
10209
10278
  * Parses an escaped url query string into key-value pairs.
10210
10279
  * @returns Object.<(string|boolean)>
@@ -10212,10 +10281,12 @@ function startingTag(element) {
10212
10281
  function parseKeyValue(/**string*/keyValue) {
10213
10282
  var obj = {}, key_value, key;
10214
10283
  forEach((keyValue || "").split('&'), function(keyValue){
10215
- if (keyValue) {
10284
+ if ( keyValue ) {
10216
10285
  key_value = keyValue.split('=');
10217
- key = decodeURIComponent(key_value[0]);
10218
- obj[key] = isDefined(key_value[1]) ? decodeURIComponent(key_value[1]) : true;
10286
+ key = tryDecodeURIComponent(key_value[0]);
10287
+ if ( isDefined(key) ) {
10288
+ obj[key] = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
10289
+ }
10219
10290
  }
10220
10291
  });
10221
10292
  return obj;
@@ -10266,7 +10337,7 @@ function encodeUriQuery(val, pctEncodeSpaces) {
10266
10337
  replace(/%3A/gi, ':').
10267
10338
  replace(/%24/g, '$').
10268
10339
  replace(/%2C/gi, ',').
10269
- replace((pctEncodeSpaces ? null : /%20/g), '+');
10340
+ replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
10270
10341
  }
10271
10342
 
10272
10343
 
@@ -10280,11 +10351,15 @@ function encodeUriQuery(val, pctEncodeSpaces) {
10280
10351
  *
10281
10352
  * @description
10282
10353
  *
10283
- * Use this directive to auto-bootstrap on application. Only
10284
- * one directive can be used per HTML document. The directive
10354
+ * Use this directive to auto-bootstrap an application. Only
10355
+ * one ngApp directive can be used per HTML document. The directive
10285
10356
  * designates the root of the application and is typically placed
10286
10357
  * at the root of the page.
10287
10358
  *
10359
+ * The first ngApp found in the document will be auto-bootstrapped. To use multiple applications in an
10360
+ * HTML document you must manually bootstrap them using {@link angular.bootstrap}.
10361
+ * Applications cannot be nested.
10362
+ *
10288
10363
  * In the example below if the `ngApp` directive would not be placed
10289
10364
  * on the `html` element then the document would not be compiled
10290
10365
  * and the `{{ 1+2 }}` would not be resolved to `3`.
@@ -10350,27 +10425,46 @@ function angularInit(element, bootstrap) {
10350
10425
  *
10351
10426
  * See: {@link guide/bootstrap Bootstrap}
10352
10427
  *
10428
+ * Note that ngScenario-based end-to-end tests cannot use this function to bootstrap manually.
10429
+ * They must use {@link api/ng.directive:ngApp ngApp}.
10430
+ *
10353
10431
  * @param {Element} element DOM element which is the root of angular application.
10354
10432
  * @param {Array<String|Function>=} modules an array of module declarations. See: {@link angular.module modules}
10355
10433
  * @returns {AUTO.$injector} Returns the newly created injector for this app.
10356
10434
  */
10357
10435
  function bootstrap(element, modules) {
10358
- element = jqLite(element);
10359
- modules = modules || [];
10360
- modules.unshift(['$provide', function($provide) {
10361
- $provide.value('$rootElement', element);
10362
- }]);
10363
- modules.unshift('ng');
10364
- var injector = createInjector(modules);
10365
- injector.invoke(
10366
- ['$rootScope', '$rootElement', '$compile', '$injector', function(scope, element, compile, injector){
10367
- scope.$apply(function() {
10368
- element.data('$injector', injector);
10369
- compile(element)(scope);
10370
- });
10371
- }]
10372
- );
10373
- return injector;
10436
+ var doBootstrap = function() {
10437
+ element = jqLite(element);
10438
+ modules = modules || [];
10439
+ modules.unshift(['$provide', function($provide) {
10440
+ $provide.value('$rootElement', element);
10441
+ }]);
10442
+ modules.unshift('ng');
10443
+ var injector = createInjector(modules);
10444
+ injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
10445
+ function(scope, element, compile, injector) {
10446
+ scope.$apply(function() {
10447
+ element.data('$injector', injector);
10448
+ compile(element)(scope);
10449
+ });
10450
+ }]
10451
+ );
10452
+ return injector;
10453
+ };
10454
+
10455
+ var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;
10456
+
10457
+ if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
10458
+ return doBootstrap();
10459
+ }
10460
+
10461
+ window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
10462
+ angular.resumeBootstrap = function(extraModules) {
10463
+ forEach(extraModules, function(module) {
10464
+ modules.push(module);
10465
+ });
10466
+ doBootstrap();
10467
+ };
10374
10468
  }
10375
10469
 
10376
10470
  var SNAKE_CASE_REGEXP = /[A-Z]/g;
@@ -10393,9 +10487,10 @@ function bindJQuery() {
10393
10487
  injector: JQLitePrototype.injector,
10394
10488
  inheritedData: JQLitePrototype.inheritedData
10395
10489
  });
10396
- JQLitePatchJQueryRemove('remove', true);
10397
- JQLitePatchJQueryRemove('empty');
10398
- JQLitePatchJQueryRemove('html');
10490
+ // Method signature: JQLitePatchJQueryRemove(name, dispatchThis, filterElems, getterIfNoArguments)
10491
+ JQLitePatchJQueryRemove('remove', true, true, false);
10492
+ JQLitePatchJQueryRemove('empty', false, false, false);
10493
+ JQLitePatchJQueryRemove('html', false, false, true);
10399
10494
  } else {
10400
10495
  jqLite = JQLite;
10401
10496
  }
@@ -10403,7 +10498,7 @@ function bindJQuery() {
10403
10498
  }
10404
10499
 
10405
10500
  /**
10406
- * throw error of the argument is falsy.
10501
+ * throw error if the argument is falsy.
10407
10502
  */
10408
10503
  function assertArg(arg, name, reason) {
10409
10504
  if (!arg) {
@@ -10422,6 +10517,33 @@ function assertArgFn(arg, name, acceptArrayAnnotation) {
10422
10517
  return arg;
10423
10518
  }
10424
10519
 
10520
+ /**
10521
+ * Return the value accessible from the object by path. Any undefined traversals are ignored
10522
+ * @param {Object} obj starting object
10523
+ * @param {string} path path to traverse
10524
+ * @param {boolean=true} bindFnToScope
10525
+ * @returns value as accessible by path
10526
+ */
10527
+ //TODO(misko): this function needs to be removed
10528
+ function getter(obj, path, bindFnToScope) {
10529
+ if (!path) return obj;
10530
+ var keys = path.split('.');
10531
+ var key;
10532
+ var lastInstance = obj;
10533
+ var len = keys.length;
10534
+
10535
+ for (var i = 0; i < len; i++) {
10536
+ key = keys[i];
10537
+ if (obj) {
10538
+ obj = (lastInstance = obj)[key];
10539
+ }
10540
+ }
10541
+ if (!bindFnToScope && isFunction(obj)) {
10542
+ return bind(lastInstance, obj);
10543
+ }
10544
+ return obj;
10545
+ }
10546
+
10425
10547
  /**
10426
10548
  * @ngdoc interface
10427
10549
  * @name angular.Module
@@ -10452,8 +10574,8 @@ function setupModuleLoader(window) {
10452
10574
  *
10453
10575
  * # Module
10454
10576
  *
10455
- * A module is a collocation of services, directives, filters, and configuration information. Module
10456
- * is used to configure the {@link AUTO.$injector $injector}.
10577
+ * A module is a collection of services, directives, filters, and configuration information.
10578
+ * `angular.module` is used to configure the {@link AUTO.$injector $injector}.
10457
10579
  *
10458
10580
  * <pre>
10459
10581
  * // Create a new module
@@ -10677,18 +10799,18 @@ function setupModuleLoader(window) {
10677
10799
  * An object that contains information about the current AngularJS version. This object has the
10678
10800
  * following properties:
10679
10801
  *
10680
- * - `full` `{string}` Full version string, such as "0.9.18".
10681
- * - `major` `{number}` Major version number, such as "0".
10682
- * - `minor` `{number}` Minor version number, such as "9".
10683
- * - `dot` `{number}` Dot version number, such as "18".
10684
- * - `codeName` `{string}` Code name of the release, such as "jiggling-armfat".
10802
+ * - `full` – `{string}` – Full version string, such as "0.9.18".
10803
+ * - `major` – `{number}` – Major version number, such as "0".
10804
+ * - `minor` – `{number}` – Minor version number, such as "9".
10805
+ * - `dot` – `{number}` – Dot version number, such as "18".
10806
+ * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
10685
10807
  */
10686
10808
  var version = {
10687
- full: '1.0.5', // all of these placeholder strings will be replaced by rake's
10688
- major: 1, // compile task
10809
+ full: '1.0.8', // all of these placeholder strings will be replaced by grunt's
10810
+ major: 1, // package task
10689
10811
  minor: 0,
10690
- dot: 5,
10691
- codeName: 'flatulent-propulsion'
10812
+ dot: 8,
10813
+ codeName: 'bubble-burst'
10692
10814
  };
10693
10815
 
10694
10816
 
@@ -10757,7 +10879,6 @@ function publishExternalAPI(angular){
10757
10879
  ngPluralize: ngPluralizeDirective,
10758
10880
  ngRepeat: ngRepeatDirective,
10759
10881
  ngShow: ngShowDirective,
10760
- ngSubmit: ngSubmitDirective,
10761
10882
  ngStyle: ngStyleDirective,
10762
10883
  ngSwitch: ngSwitchDirective,
10763
10884
  ngSwitchWhen: ngSwitchWhenDirective,
@@ -10827,24 +10948,25 @@ function publishExternalAPI(angular){
10827
10948
  * Note: All element references in Angular are always wrapped with jQuery or jqLite; they are never
10828
10949
  * raw DOM references.
10829
10950
  *
10830
- * ## Angular's jQuery lite provides the following methods:
10951
+ * ## Angular's jqLite
10952
+ * Angular's lite version of jQuery provides only the following jQuery methods:
10831
10953
  *
10832
10954
  * - [addClass()](http://api.jquery.com/addClass/)
10833
10955
  * - [after()](http://api.jquery.com/after/)
10834
10956
  * - [append()](http://api.jquery.com/append/)
10835
10957
  * - [attr()](http://api.jquery.com/attr/)
10836
- * - [bind()](http://api.jquery.com/bind/)
10837
- * - [children()](http://api.jquery.com/children/)
10958
+ * - [bind()](http://api.jquery.com/bind/) - Does not support namespaces
10959
+ * - [children()](http://api.jquery.com/children/) - Does not support selectors
10838
10960
  * - [clone()](http://api.jquery.com/clone/)
10839
10961
  * - [contents()](http://api.jquery.com/contents/)
10840
10962
  * - [css()](http://api.jquery.com/css/)
10841
10963
  * - [data()](http://api.jquery.com/data/)
10842
10964
  * - [eq()](http://api.jquery.com/eq/)
10843
- * - [find()](http://api.jquery.com/find/) - Limited to lookups by tag name.
10965
+ * - [find()](http://api.jquery.com/find/) - Limited to lookups by tag name
10844
10966
  * - [hasClass()](http://api.jquery.com/hasClass/)
10845
10967
  * - [html()](http://api.jquery.com/html/)
10846
- * - [next()](http://api.jquery.com/next/)
10847
- * - [parent()](http://api.jquery.com/parent/)
10968
+ * - [next()](http://api.jquery.com/next/) - Does not support selectors
10969
+ * - [parent()](http://api.jquery.com/parent/) - Does not support selectors
10848
10970
  * - [prepend()](http://api.jquery.com/prepend/)
10849
10971
  * - [prop()](http://api.jquery.com/prop/)
10850
10972
  * - [ready()](http://api.jquery.com/ready/)
@@ -10856,12 +10978,18 @@ function publishExternalAPI(angular){
10856
10978
  * - [text()](http://api.jquery.com/text/)
10857
10979
  * - [toggleClass()](http://api.jquery.com/toggleClass/)
10858
10980
  * - [triggerHandler()](http://api.jquery.com/triggerHandler/) - Doesn't pass native event objects to handlers.
10859
- * - [unbind()](http://api.jquery.com/unbind/)
10981
+ * - [unbind()](http://api.jquery.com/unbind/) - Does not support namespaces
10860
10982
  * - [val()](http://api.jquery.com/val/)
10861
10983
  * - [wrap()](http://api.jquery.com/wrap/)
10862
10984
  *
10863
- * ## In addtion to the above, Angular provides additional methods to both jQuery and jQuery lite:
10985
+ * ## jQuery/jqLite Extras
10986
+ * Angular also provides the following additional methods and events to both jQuery and jqLite:
10864
10987
  *
10988
+ * ### Events
10989
+ * - `$destroy` - AngularJS intercepts all jqLite/jQuery's DOM destruction apis and fires this event
10990
+ * on all DOM nodes being removed. This can be used to clean up and 3rd party bindings to the DOM
10991
+ * element before it is removed.
10992
+ * ### Methods
10865
10993
  * - `controller(name)` - retrieves the controller of the current element or its parent. By default
10866
10994
  * retrieves controller associated with the `ngController` directive. If `name` is provided as
10867
10995
  * camelCase directive name, then the controller for this directive will be retrieved (e.g.
@@ -10908,37 +11036,38 @@ function camelCase(name) {
10908
11036
  /////////////////////////////////////////////
10909
11037
  // jQuery mutation patch
10910
11038
  //
10911
- // In conjunction with bindJQuery intercepts all jQuery's DOM destruction apis and fires a
11039
+ // In conjunction with bindJQuery intercepts all jQuery's DOM destruction apis and fires a
10912
11040
  // $destroy event on all DOM nodes being removed.
10913
11041
  //
10914
11042
  /////////////////////////////////////////////
10915
11043
 
10916
- function JQLitePatchJQueryRemove(name, dispatchThis) {
11044
+ function JQLitePatchJQueryRemove(name, dispatchThis, filterElems, getterIfNoArguments) {
10917
11045
  var originalJqFn = jQuery.fn[name];
10918
11046
  originalJqFn = originalJqFn.$original || originalJqFn;
10919
11047
  removePatch.$original = originalJqFn;
10920
11048
  jQuery.fn[name] = removePatch;
10921
11049
 
10922
- function removePatch() {
10923
- var list = [this],
11050
+ function removePatch(param) {
11051
+ var list = filterElems && param ? [this.filter(param)] : [this],
10924
11052
  fireEvent = dispatchThis,
10925
11053
  set, setIndex, setLength,
10926
- element, childIndex, childLength, children,
10927
- fns, events;
10928
-
10929
- while(list.length) {
10930
- set = list.shift();
10931
- for(setIndex = 0, setLength = set.length; setIndex < setLength; setIndex++) {
10932
- element = jqLite(set[setIndex]);
10933
- if (fireEvent) {
10934
- element.triggerHandler('$destroy');
10935
- } else {
10936
- fireEvent = !fireEvent;
10937
- }
10938
- for(childIndex = 0, childLength = (children = element.children()).length;
10939
- childIndex < childLength;
10940
- childIndex++) {
10941
- list.push(jQuery(children[childIndex]));
11054
+ element, childIndex, childLength, children;
11055
+
11056
+ if (!getterIfNoArguments || param != null) {
11057
+ while(list.length) {
11058
+ set = list.shift();
11059
+ for(setIndex = 0, setLength = set.length; setIndex < setLength; setIndex++) {
11060
+ element = jqLite(set[setIndex]);
11061
+ if (fireEvent) {
11062
+ element.triggerHandler('$destroy');
11063
+ } else {
11064
+ fireEvent = !fireEvent;
11065
+ }
11066
+ for(childIndex = 0, childLength = (children = element.children()).length;
11067
+ childIndex < childLength;
11068
+ childIndex++) {
11069
+ list.push(jQuery(children[childIndex]));
11070
+ }
10942
11071
  }
10943
11072
  }
10944
11073
  }
@@ -10998,7 +11127,7 @@ function JQLiteUnbind(element, type, fn) {
10998
11127
  removeEventListenerFn(element, type, events[type]);
10999
11128
  delete events[type];
11000
11129
  } else {
11001
- arrayRemove(events[type], fn);
11130
+ arrayRemove(events[type] || [], fn);
11002
11131
  }
11003
11132
  }
11004
11133
  }
@@ -11272,6 +11401,15 @@ forEach({
11272
11401
 
11273
11402
  val: function(element, value) {
11274
11403
  if (isUndefined(value)) {
11404
+ if (nodeName_(element) === 'SELECT' && element.multiple) {
11405
+ var result = [];
11406
+ forEach(element.options, function (option) {
11407
+ if (option.selected) {
11408
+ result.push(option.value || option.text);
11409
+ }
11410
+ });
11411
+ return result.length === 0 ? null : result;
11412
+ }
11275
11413
  return element.value;
11276
11414
  }
11277
11415
  element.value = value;
@@ -11403,23 +11541,43 @@ forEach({
11403
11541
 
11404
11542
  if (!eventFns) {
11405
11543
  if (type == 'mouseenter' || type == 'mouseleave') {
11406
- var counter = 0;
11544
+ var contains = document.body.contains || document.body.compareDocumentPosition ?
11545
+ function( a, b ) {
11546
+ var adown = a.nodeType === 9 ? a.documentElement : a,
11547
+ bup = b && b.parentNode;
11548
+ return a === bup || !!( bup && bup.nodeType === 1 && (
11549
+ adown.contains ?
11550
+ adown.contains( bup ) :
11551
+ a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
11552
+ ));
11553
+ } :
11554
+ function( a, b ) {
11555
+ if ( b ) {
11556
+ while ( (b = b.parentNode) ) {
11557
+ if ( b === a ) {
11558
+ return true;
11559
+ }
11560
+ }
11561
+ }
11562
+ return false;
11563
+ };
11407
11564
 
11408
- events.mouseenter = [];
11409
- events.mouseleave = [];
11565
+ events[type] = [];
11566
+
11567
+ // Refer to jQuery's implementation of mouseenter & mouseleave
11568
+ // Read about mouseenter and mouseleave:
11569
+ // http://www.quirksmode.org/js/events_mouse.html#link8
11570
+ var eventmap = { mouseleave : "mouseout", mouseenter : "mouseover"}
11571
+ bindFn(element, eventmap[type], function(event) {
11572
+ var ret, target = this, related = event.relatedTarget;
11573
+ // For mousenter/leave call the handler if related is outside the target.
11574
+ // NB: No relatedTarget if the mouse left/entered the browser window
11575
+ if ( !related || (related !== target && !contains(target, related)) ){
11576
+ handle(event, type);
11577
+ }
11410
11578
 
11411
- bindFn(element, 'mouseover', function(event) {
11412
- counter++;
11413
- if (counter == 1) {
11414
- handle(event, 'mouseenter');
11415
- }
11416
- });
11417
- bindFn(element, 'mouseout', function(event) {
11418
- counter --;
11419
- if (counter == 0) {
11420
- handle(event, 'mouseleave');
11421
- }
11422
11579
  });
11580
+
11423
11581
  } else {
11424
11582
  addEventListenerFn(element, type, handle);
11425
11583
  events[type] = [];
@@ -11469,12 +11627,7 @@ forEach({
11469
11627
  if (element.nodeType === 1) {
11470
11628
  var index = element.firstChild;
11471
11629
  forEach(new JQLite(node), function(child){
11472
- if (index) {
11473
- element.insertBefore(child, index);
11474
- } else {
11475
- element.appendChild(child);
11476
- index = child;
11477
- }
11630
+ element.insertBefore(child, index);
11478
11631
  });
11479
11632
  }
11480
11633
  },
@@ -11735,7 +11888,7 @@ function annotate(fn) {
11735
11888
  }
11736
11889
  } else if (isArray(fn)) {
11737
11890
  last = fn.length - 1;
11738
- assertArgFn(fn[last], 'fn')
11891
+ assertArgFn(fn[last], 'fn');
11739
11892
  $inject = fn.slice(0, last);
11740
11893
  } else {
11741
11894
  assertArgFn(fn, 'fn', true);
@@ -11769,19 +11922,19 @@ function annotate(fn) {
11769
11922
  * # Injection Function Annotation
11770
11923
  *
11771
11924
  * JavaScript does not have annotations, and annotations are needed for dependency injection. The
11772
- * following ways are all valid way of annotating function with injection arguments and are equivalent.
11925
+ * following are all valid ways of annotating function with injection arguments and are equivalent.
11773
11926
  *
11774
11927
  * <pre>
11775
11928
  * // inferred (only works if code not minified/obfuscated)
11776
- * $inject.invoke(function(serviceA){});
11929
+ * $injector.invoke(function(serviceA){});
11777
11930
  *
11778
11931
  * // annotated
11779
11932
  * function explicit(serviceA) {};
11780
11933
  * explicit.$inject = ['serviceA'];
11781
- * $inject.invoke(explicit);
11934
+ * $injector.invoke(explicit);
11782
11935
  *
11783
11936
  * // inline
11784
- * $inject.invoke(['serviceA', function(serviceA){}]);
11937
+ * $injector.invoke(['serviceA', function(serviceA){}]);
11785
11938
  * </pre>
11786
11939
  *
11787
11940
  * ## Inference
@@ -11898,7 +12051,7 @@ function annotate(fn) {
11898
12051
  * // ...
11899
12052
  * };
11900
12053
  * tmpFn.$inject = ['$compile', '$rootScope'];
11901
- * injector.invoke(tempFn);
12054
+ * injector.invoke(tmpFn);
11902
12055
  *
11903
12056
  * // To better support inline function the inline annotation is supported
11904
12057
  * injector.invoke(['$compile', '$rootScope', function(obfCompile, obfRootScope) {
@@ -11927,7 +12080,7 @@ function annotate(fn) {
11927
12080
  * @description
11928
12081
  *
11929
12082
  * Use `$provide` to register new providers with the `$injector`. The providers are the factories for the instance.
11930
- * The providers share the same name as the instance they create with the `Provider` suffixed to them.
12083
+ * The providers share the same name as the instance they create with `Provider` suffixed to them.
11931
12084
  *
11932
12085
  * A provider is an object with a `$get()` method. The injector calls the `$get` method to create a new instance of
11933
12086
  * a service. The Provider can have additional methods which would allow for configuration of the provider.
@@ -11951,7 +12104,7 @@ function annotate(fn) {
11951
12104
  *
11952
12105
  * beforeEach(module(function($provide) {
11953
12106
  * $provide.provider('greet', GreetProvider);
11954
- * });
12107
+ * }));
11955
12108
  *
11956
12109
  * it('should greet', inject(function(greet) {
11957
12110
  * expect(greet('angular')).toEqual('Hello angular!');
@@ -11964,9 +12117,7 @@ function annotate(fn) {
11964
12117
  * inject(function(greet) {
11965
12118
  * expect(greet('angular')).toEqual('Ahoj angular!');
11966
12119
  * });
11967
- * )};
11968
- *
11969
- * });
12120
+ * });
11970
12121
  * </pre>
11971
12122
  */
11972
12123
 
@@ -12060,7 +12211,7 @@ function annotate(fn) {
12060
12211
  *
12061
12212
  * @param {string} name The name of the service to decorate.
12062
12213
  * @param {function()} decorator This function will be invoked when the service needs to be
12063
- * instanciated. The function is called using the {@link AUTO.$injector#invoke
12214
+ * instantiated. The function is called using the {@link AUTO.$injector#invoke
12064
12215
  * injector.invoke} method and is therefore fully injectable. Local injection arguments:
12065
12216
  *
12066
12217
  * * `$delegate` - The original service instance, which can be monkey patched, configured,
@@ -12260,6 +12411,8 @@ function createInjector(modulesToLoad) {
12260
12411
  var Constructor = function() {},
12261
12412
  instance, returnedValue;
12262
12413
 
12414
+ // Check if Type is annotated and use just the given function at n-1 as parameter
12415
+ // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);
12263
12416
  Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Type).prototype;
12264
12417
  instance = new Constructor();
12265
12418
  returnedValue = invoke(Type, instance, locals);
@@ -12275,6 +12428,7 @@ function createInjector(modulesToLoad) {
12275
12428
  };
12276
12429
  }
12277
12430
  }
12431
+
12278
12432
  /**
12279
12433
  * @ngdoc function
12280
12434
  * @name ng.$anchorScroll
@@ -12466,7 +12620,8 @@ function Browser(window, document, $log, $sniffer) {
12466
12620
  //////////////////////////////////////////////////////////////
12467
12621
 
12468
12622
  var lastBrowserUrl = location.href,
12469
- baseElement = document.find('base');
12623
+ baseElement = document.find('base'),
12624
+ replacedUrl = null;
12470
12625
 
12471
12626
  /**
12472
12627
  * @name ng.$browser#url
@@ -12501,14 +12656,21 @@ function Browser(window, document, $log, $sniffer) {
12501
12656
  baseElement.attr('href', baseElement.attr('href'));
12502
12657
  }
12503
12658
  } else {
12504
- if (replace) location.replace(url);
12505
- else location.href = url;
12659
+ if (replace) {
12660
+ location.replace(url);
12661
+ replacedUrl = url;
12662
+ } else {
12663
+ location.href = url;
12664
+ replacedUrl = null;
12665
+ }
12506
12666
  }
12507
12667
  return self;
12508
12668
  // getter
12509
12669
  } else {
12510
- // the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172
12511
- return location.href.replace(/%27/g,"'");
12670
+ // - the replacedUrl is a workaround for an IE8-9 issue with location.replace method that doesn't update
12671
+ // location.href synchronously
12672
+ // - the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172
12673
+ return replacedUrl || location.href.replace(/%27/g,"'");
12512
12674
  }
12513
12675
  };
12514
12676
 
@@ -12639,7 +12801,13 @@ function Browser(window, document, $log, $sniffer) {
12639
12801
  cookie = cookieArray[i];
12640
12802
  index = cookie.indexOf('=');
12641
12803
  if (index > 0) { //ignore nameless cookies
12642
- lastCookies[unescape(cookie.substring(0, index))] = unescape(cookie.substring(index + 1));
12804
+ var name = unescape(cookie.substring(0, index));
12805
+ // the first value that is seen for a cookie is the most
12806
+ // specific one. values for the same cookie name that
12807
+ // follow are for less specific paths.
12808
+ if (lastCookies[name] === undefined) {
12809
+ lastCookies[name] = unescape(cookie.substring(index + 1));
12810
+ }
12643
12811
  }
12644
12812
  }
12645
12813
  }
@@ -12703,27 +12871,41 @@ function $BrowserProvider(){
12703
12871
  return new Browser($window, $document, $log, $sniffer);
12704
12872
  }];
12705
12873
  }
12874
+
12706
12875
  /**
12707
12876
  * @ngdoc object
12708
12877
  * @name ng.$cacheFactory
12709
12878
  *
12710
12879
  * @description
12711
- * Factory that constructs cache objects.
12880
+ * Factory that constructs cache objects and gives access to them.
12881
+ *
12882
+ * <pre>
12883
+ *
12884
+ * var cache = $cacheFactory('cacheId');
12885
+ * expect($cacheFactory.get('cacheId')).toBe(cache);
12886
+ * expect($cacheFactory.get('noSuchCacheId')).not.toBeDefined();
12887
+ *
12888
+ * cache.put("key", "value");
12889
+ * cache.put("another key", "another value");
12890
+ *
12891
+ * expect(cache.info()).toEqual({id: 'cacheId', size: 2}); // Since we've specified no options on creation
12892
+ *
12893
+ * </pre>
12712
12894
  *
12713
12895
  *
12714
12896
  * @param {string} cacheId Name or id of the newly created cache.
12715
12897
  * @param {object=} options Options object that specifies the cache behavior. Properties:
12716
12898
  *
12717
- * - `{number=}` `capacity` turns the cache into LRU cache.
12899
+ * - `{number=}` `capacity` — turns the cache into LRU cache.
12718
12900
  *
12719
12901
  * @returns {object} Newly created cache object with the following set of methods:
12720
12902
  *
12721
- * - `{object}` `info()` Returns id, size, and options of cache.
12722
- * - `{void}` `put({string} key, {*} value)` Puts a new key-value pair into the cache.
12723
- * - `{{*}}` `get({string} key)` Returns cached value for `key` or undefined for cache miss.
12724
- * - `{void}` `remove({string} key)` Removes a key-value pair from the cache.
12725
- * - `{void}` `removeAll()` Removes all cached values.
12726
- * - `{void}` `destroy()` Removes references to this cache from $cacheFactory.
12903
+ * - `{object}` `info()` — Returns id, size, and options of cache.
12904
+ * - `{void}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache.
12905
+ * - `{{*}}` `get({string} key)` — Returns cached value for `key` or undefined for cache miss.
12906
+ * - `{void}` `remove({string} key)` — Removes a key-value pair from the cache.
12907
+ * - `{void}` `removeAll()` — Removes all cached values.
12908
+ * - `{void}` `destroy()` — Removes references to this cache from $cacheFactory.
12727
12909
  *
12728
12910
  */
12729
12911
  function $CacheFactoryProvider() {
@@ -12840,6 +13022,16 @@ function $CacheFactoryProvider() {
12840
13022
  }
12841
13023
 
12842
13024
 
13025
+ /**
13026
+ * @ngdoc method
13027
+ * @name ng.$cacheFactory#info
13028
+ * @methodOf ng.$cacheFactory
13029
+ *
13030
+ * @description
13031
+ * Get information about all the of the caches that have been created
13032
+ *
13033
+ * @returns {Object} - key-value map of `cacheId` to the result of calling `cache#info`
13034
+ */
12843
13035
  cacheFactory.info = function() {
12844
13036
  var info = {};
12845
13037
  forEach(caches, function(cache, cacheId) {
@@ -12849,6 +13041,17 @@ function $CacheFactoryProvider() {
12849
13041
  };
12850
13042
 
12851
13043
 
13044
+ /**
13045
+ * @ngdoc method
13046
+ * @name ng.$cacheFactory#get
13047
+ * @methodOf ng.$cacheFactory
13048
+ *
13049
+ * @description
13050
+ * Get access to a cache object by the `cacheId` used when it was created.
13051
+ *
13052
+ * @param {string} cacheId Name or id of a cache to access.
13053
+ * @returns {object} Cache object identified by the cacheId or undefined if no such cache.
13054
+ */
12852
13055
  cacheFactory.get = function(cacheId) {
12853
13056
  return caches[cacheId];
12854
13057
  };
@@ -12863,8 +13066,44 @@ function $CacheFactoryProvider() {
12863
13066
  * @name ng.$templateCache
12864
13067
  *
12865
13068
  * @description
12866
- * Cache used for storing html templates.
12867
- *
13069
+ * The first time a template is used, it is loaded in the template cache for quick retrieval. You can
13070
+ * load templates directly into the cache in a `script` tag, or by consuming the `$templateCache`
13071
+ * service directly.
13072
+ *
13073
+ * Adding via the `script` tag:
13074
+ * <pre>
13075
+ * <html ng-app>
13076
+ * <head>
13077
+ * <script type="text/ng-template" id="templateId.html">
13078
+ * This is the content of the template
13079
+ * </script>
13080
+ * </head>
13081
+ * ...
13082
+ * </html>
13083
+ * </pre>
13084
+ *
13085
+ * **Note:** the `script` tag containing the template does not need to be included in the `head` of the document, but
13086
+ * it must be below the `ng-app` definition.
13087
+ *
13088
+ * Adding via the $templateCache service:
13089
+ *
13090
+ * <pre>
13091
+ * var myApp = angular.module('myApp', []);
13092
+ * myApp.run(function($templateCache) {
13093
+ * $templateCache.put('templateId.html', 'This is the content of the template');
13094
+ * });
13095
+ * </pre>
13096
+ *
13097
+ * To retrieve the template later, simply use it in your HTML:
13098
+ * <pre>
13099
+ * <div ng-include=" 'templateId.html' "></div>
13100
+ * </pre>
13101
+ *
13102
+ * or get it via Javascript:
13103
+ * <pre>
13104
+ * $templateCache.get('templateId.html')
13105
+ * </pre>
13106
+ *
12868
13107
  * See {@link ng.$cacheFactory $cacheFactory}.
12869
13108
  *
12870
13109
  */
@@ -13030,7 +13269,7 @@ function $CompileProvider($provide) {
13030
13269
  COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,
13031
13270
  CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/,
13032
13271
  MULTI_ROOT_TEMPLATE_ERROR = 'Template must have exactly one root element. was: ',
13033
- urlSanitizationWhitelist = /^\s*(https?|ftp|mailto):/;
13272
+ urlSanitizationWhitelist = /^\s*(https?|ftp|mailto|file):/;
13034
13273
 
13035
13274
 
13036
13275
  /**
@@ -13040,11 +13279,11 @@ function $CompileProvider($provide) {
13040
13279
  * @function
13041
13280
  *
13042
13281
  * @description
13043
- * Register a new directives with the compiler.
13282
+ * Register a new directive with the compiler.
13044
13283
  *
13045
13284
  * @param {string} name Name of the directive in camel-case. (ie <code>ngBind</code> which will match as
13046
13285
  * <code>ng-bind</code>).
13047
- * @param {function} directiveFactory An injectable directive factroy function. See {@link guide/directive} for more
13286
+ * @param {function|Array} directiveFactory An injectable directive factory function. See {@link guide/directive} for more
13048
13287
  * info.
13049
13288
  * @returns {ng.$compileProvider} Self for chaining.
13050
13289
  */
@@ -13167,7 +13406,7 @@ function $CompileProvider($provide) {
13167
13406
 
13168
13407
  // href property always returns normalized absolute url, so we can match against that
13169
13408
  normalizedVal = urlSanitizationNode.href;
13170
- if (!normalizedVal.match(urlSanitizationWhitelist)) {
13409
+ if (normalizedVal !== '' && !normalizedVal.match(urlSanitizationWhitelist)) {
13171
13410
  this[key] = value = 'unsafe:' + normalizedVal;
13172
13411
  }
13173
13412
  }
@@ -13232,7 +13471,7 @@ function $CompileProvider($provide) {
13232
13471
 
13233
13472
  function compile($compileNodes, transcludeFn, maxPriority) {
13234
13473
  if (!($compileNodes instanceof jqLite)) {
13235
- // jquery always rewraps, where as we need to preserve the original selector so that we can modify it.
13474
+ // jquery always rewraps, whereas we need to preserve the original selector so that we can modify it.
13236
13475
  $compileNodes = jqLite($compileNodes);
13237
13476
  }
13238
13477
  // We can not compile top level text elements since text nodes can be merged and we will
@@ -13284,7 +13523,7 @@ function $CompileProvider($provide) {
13284
13523
  * functions return values - the linking functions - are combined into a composite linking
13285
13524
  * function, which is the a linking function for the node.
13286
13525
  *
13287
- * @param {NodeList} nodeList an array of nodes to compile
13526
+ * @param {NodeList} nodeList an array of nodes or NodeList to compile
13288
13527
  * @param {function(angular.Scope[, cloneAttachFn]} transcludeFn A linking function, where the
13289
13528
  * scope argument is auto-generated to the new child of the transcluded parent scope.
13290
13529
  * @param {DOMElement=} $rootElement If the nodeList is the root of the compilation tree then the
@@ -13307,7 +13546,7 @@ function $CompileProvider($provide) {
13307
13546
  ? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement)
13308
13547
  : null;
13309
13548
 
13310
- childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || !nodeList[i].childNodes.length)
13549
+ childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || !nodeList[i].childNodes || !nodeList[i].childNodes.length)
13311
13550
  ? null
13312
13551
  : compileNodes(nodeList[i].childNodes,
13313
13552
  nodeLinkFn ? nodeLinkFn.transclude : transcludeFn);
@@ -13391,7 +13630,7 @@ function $CompileProvider($provide) {
13391
13630
  for (var attr, name, nName, value, nAttrs = node.attributes,
13392
13631
  j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) {
13393
13632
  attr = nAttrs[j];
13394
- if (attr.specified) {
13633
+ if (!msie || msie >= 8 || attr.specified) {
13395
13634
  name = attr.name;
13396
13635
  nName = directiveNormalize(name.toLowerCase());
13397
13636
  attrsMap[nName] = name;
@@ -13443,9 +13682,9 @@ function $CompileProvider($provide) {
13443
13682
 
13444
13683
 
13445
13684
  /**
13446
- * Once the directives have been collected their compile functions is executed. This method
13685
+ * Once the directives have been collected, their compile functions are executed. This method
13447
13686
  * is responsible for inlining directive templates as well as terminating the application
13448
- * of the directives if the terminal directive has been reached..
13687
+ * of the directives if the terminal directive has been reached.
13449
13688
  *
13450
13689
  * @param {Array} directives Array of collected directives to execute their compile function.
13451
13690
  * this needs to be pre-sorted by priority order.
@@ -13453,11 +13692,11 @@ function $CompileProvider($provide) {
13453
13692
  * @param {Object} templateAttrs The shared attribute function
13454
13693
  * @param {function(angular.Scope[, cloneAttachFn]} transcludeFn A linking function, where the
13455
13694
  * scope argument is auto-generated to the new child of the transcluded parent scope.
13456
- * @param {DOMElement} $rootElement If we are working on the root of the compile tree then this
13457
- * argument has the root jqLite array so that we can replace widgets on it.
13695
+ * @param {JQLite} jqCollection If we are working on the root of the compile tree then this
13696
+ * argument has the root jqLite array so that we can replace nodes on it.
13458
13697
  * @returns linkFn
13459
13698
  */
13460
- function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn, $rootElement) {
13699
+ function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn, jqCollection) {
13461
13700
  var terminalPriority = -Number.MAX_VALUE,
13462
13701
  preLinkFns = [],
13463
13702
  postLinkFns = [],
@@ -13511,7 +13750,7 @@ function $CompileProvider($provide) {
13511
13750
  $compileNode = templateAttrs.$$element =
13512
13751
  jqLite(document.createComment(' ' + directiveName + ': ' + templateAttrs[directiveName] + ' '));
13513
13752
  compileNode = $compileNode[0];
13514
- replaceWith($rootElement, jqLite($template[0]), compileNode);
13753
+ replaceWith(jqCollection, jqLite($template[0]), compileNode);
13515
13754
  childTranscludeFn = compile($template, transcludeFn, terminalPriority);
13516
13755
  } else {
13517
13756
  $template = jqLite(JQLiteClone(compileNode)).contents();
@@ -13535,7 +13774,7 @@ function $CompileProvider($provide) {
13535
13774
  throw new Error(MULTI_ROOT_TEMPLATE_ERROR + directiveValue);
13536
13775
  }
13537
13776
 
13538
- replaceWith($rootElement, $compileNode, compileNode);
13777
+ replaceWith(jqCollection, $compileNode, compileNode);
13539
13778
 
13540
13779
  var newTemplateAttrs = {$attr: {}};
13541
13780
 
@@ -13563,7 +13802,7 @@ function $CompileProvider($provide) {
13563
13802
  assertNoDuplicate('template', templateDirective, directive, $compileNode);
13564
13803
  templateDirective = directive;
13565
13804
  nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i),
13566
- nodeLinkFn, $compileNode, templateAttrs, $rootElement, directive.replace,
13805
+ nodeLinkFn, $compileNode, templateAttrs, jqCollection, directive.replace,
13567
13806
  childTranscludeFn);
13568
13807
  ii = directives.length;
13569
13808
  } else if (directive.compile) {
@@ -13696,7 +13935,7 @@ function $CompileProvider($provide) {
13696
13935
  parentGet = $parse(attrs[attrName]);
13697
13936
  scope[scopeName] = function(locals) {
13698
13937
  return parentGet(parentScope, locals);
13699
- }
13938
+ };
13700
13939
  break;
13701
13940
  }
13702
13941
 
@@ -13866,7 +14105,7 @@ function $CompileProvider($provide) {
13866
14105
 
13867
14106
  directives.unshift(derivedSyncDirective);
13868
14107
  afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs, childTranscludeFn);
13869
- afterTemplateChildLinkFn = compileNodes($compileNode.contents(), childTranscludeFn);
14108
+ afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn);
13870
14109
 
13871
14110
 
13872
14111
  while(linkQueue.length) {
@@ -14131,7 +14370,7 @@ function $ControllerProvider() {
14131
14370
  * @description
14132
14371
  * `$controller` service is responsible for instantiating controllers.
14133
14372
  *
14134
- * It's just simple call to {@link AUTO.$injector $injector}, but extracted into
14373
+ * It's just a simple call to {@link AUTO.$injector $injector}, but extracted into
14135
14374
  * a service, so that one can override this service with {@link https://gist.github.com/1649788
14136
14375
  * BC version}.
14137
14376
  */
@@ -14184,7 +14423,7 @@ function $DocumentProvider(){
14184
14423
  *
14185
14424
  */
14186
14425
  function $ExceptionHandlerProvider() {
14187
- this.$get = ['$log', function($log){
14426
+ this.$get = ['$log', function($log) {
14188
14427
  return function(exception, cause) {
14189
14428
  $log.error.apply($log, arguments);
14190
14429
  };
@@ -14372,7 +14611,7 @@ function $InterpolateProvider() {
14372
14611
  }];
14373
14612
  }
14374
14613
 
14375
- var URL_MATCH = /^([^:]+):\/\/(\w+:{0,1}\w*@)?([\w\.-]*)(:([0-9]+))?(\/[^\?#]*)?(\?([^#]*))?(#(.*))?$/,
14614
+ var URL_MATCH = /^([^:]+):\/\/(\w+:{0,1}\w*@)?(\{?[\w\.-]*\}?)(:([0-9]+))?(\/[^\?#]*)?(\?([^#]*))?(#(.*))?$/,
14376
14615
  PATH_MATCH = /^([^\?#]*)?(\?([^#]*))?(#(.*))?$/,
14377
14616
  HASH_MATCH = PATH_MATCH,
14378
14617
  DEFAULT_PORTS = {'http': 80, 'https': 443, 'ftp': 21};
@@ -14451,7 +14690,8 @@ function convertToHashbangUrl(url, basePath, hashPrefix) {
14451
14690
  var match = matchUrl(url);
14452
14691
 
14453
14692
  // already hashbang url
14454
- if (decodeURIComponent(match.path) == basePath) {
14693
+ if (decodeURIComponent(match.path) == basePath && !isUndefined(match.hash) &&
14694
+ match.hash.indexOf(hashPrefix) === 0) {
14455
14695
  return url;
14456
14696
  // convert html5 url -> hashbang url
14457
14697
  } else {
@@ -14948,6 +15188,10 @@ function $LocationProvider(){
14948
15188
  // update $location when $browser url changes
14949
15189
  $browser.onUrlChange(function(newUrl) {
14950
15190
  if ($location.absUrl() != newUrl) {
15191
+ if ($rootScope.$broadcast('$locationChangeStart', newUrl, $location.absUrl()).defaultPrevented) {
15192
+ $browser.url($location.absUrl());
15193
+ return;
15194
+ }
14951
15195
  $rootScope.$evalAsync(function() {
14952
15196
  var oldUrl = $location.absUrl();
14953
15197
 
@@ -15256,10 +15500,10 @@ function lex(text, csp){
15256
15500
  function readIdent() {
15257
15501
  var ident = "",
15258
15502
  start = index,
15259
- lastDot, peekIndex, methodName;
15503
+ lastDot, peekIndex, methodName, ch;
15260
15504
 
15261
15505
  while (index < text.length) {
15262
- var ch = text.charAt(index);
15506
+ ch = text.charAt(index);
15263
15507
  if (ch == '.' || isIdent(ch) || isNumber(ch)) {
15264
15508
  if (ch == '.') lastDot = index;
15265
15509
  ident += ch;
@@ -15273,7 +15517,7 @@ function lex(text, csp){
15273
15517
  if (lastDot) {
15274
15518
  peekIndex = index;
15275
15519
  while(peekIndex < text.length) {
15276
- var ch = text.charAt(peekIndex);
15520
+ ch = text.charAt(peekIndex);
15277
15521
  if (ch == '(') {
15278
15522
  methodName = ident.substr(lastDot - start + 1);
15279
15523
  ident = ident.substr(0, lastDot - start);
@@ -15526,8 +15770,8 @@ function parser(text, json, $filter, csp){
15526
15770
  text.substring(0, token.index) + "] can not be assigned to", token);
15527
15771
  }
15528
15772
  right = logicalOR();
15529
- return function(self, locals){
15530
- return left.assign(self, right(self, locals), locals);
15773
+ return function(scope, locals){
15774
+ return left.assign(scope, right(scope, locals), locals);
15531
15775
  };
15532
15776
  } else {
15533
15777
  return left;
@@ -15644,12 +15888,12 @@ function parser(text, json, $filter, csp){
15644
15888
  var field = expect().text;
15645
15889
  var getter = getterFn(field, csp);
15646
15890
  return extend(
15647
- function(self, locals) {
15648
- return getter(object(self, locals), locals);
15891
+ function(scope, locals, self) {
15892
+ return getter(self || object(scope, locals), locals);
15649
15893
  },
15650
15894
  {
15651
- assign:function(self, value, locals) {
15652
- return setter(object(self, locals), field, value);
15895
+ assign:function(scope, value, locals) {
15896
+ return setter(object(scope, locals), field, value);
15653
15897
  }
15654
15898
  }
15655
15899
  );
@@ -15690,14 +15934,14 @@ function parser(text, json, $filter, csp){
15690
15934
  } while (expect(','));
15691
15935
  }
15692
15936
  consume(')');
15693
- return function(self, locals){
15937
+ return function(scope, locals){
15694
15938
  var args = [],
15695
- context = contextGetter ? contextGetter(self, locals) : self;
15939
+ context = contextGetter ? contextGetter(scope, locals) : scope;
15696
15940
 
15697
15941
  for ( var i = 0; i < argsFn.length; i++) {
15698
- args.push(argsFn[i](self, locals));
15942
+ args.push(argsFn[i](scope, locals));
15699
15943
  }
15700
- var fnPtr = fn(self, locals) || noop;
15944
+ var fnPtr = fn(scope, locals, context) || noop;
15701
15945
  // IE stupidity!
15702
15946
  return fnPtr.apply
15703
15947
  ? fnPtr.apply(context, args)
@@ -15739,8 +15983,7 @@ function parser(text, json, $filter, csp){
15739
15983
  var object = {};
15740
15984
  for ( var i = 0; i < keyValues.length; i++) {
15741
15985
  var keyValue = keyValues[i];
15742
- var value = keyValue.value(self, locals);
15743
- object[keyValue.key] = value;
15986
+ object[keyValue.key] = keyValue.value(self, locals);
15744
15987
  }
15745
15988
  return object;
15746
15989
  };
@@ -15766,33 +16009,6 @@ function setter(obj, path, setValue) {
15766
16009
  return setValue;
15767
16010
  }
15768
16011
 
15769
- /**
15770
- * Return the value accesible from the object by path. Any undefined traversals are ignored
15771
- * @param {Object} obj starting object
15772
- * @param {string} path path to traverse
15773
- * @param {boolean=true} bindFnToScope
15774
- * @returns value as accesbile by path
15775
- */
15776
- //TODO(misko): this function needs to be removed
15777
- function getter(obj, path, bindFnToScope) {
15778
- if (!path) return obj;
15779
- var keys = path.split('.');
15780
- var key;
15781
- var lastInstance = obj;
15782
- var len = keys.length;
15783
-
15784
- for (var i = 0; i < len; i++) {
15785
- key = keys[i];
15786
- if (obj) {
15787
- obj = (lastInstance = obj)[key];
15788
- }
15789
- }
15790
- if (!bindFnToScope && isFunction(obj)) {
15791
- return bind(lastInstance, obj);
15792
- }
15793
- return obj;
15794
- }
15795
-
15796
16012
  var getterFnCache = {};
15797
16013
 
15798
16014
  /**
@@ -15862,7 +16078,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4) {
15862
16078
  }
15863
16079
  return pathVal;
15864
16080
  };
15865
- };
16081
+ }
15866
16082
 
15867
16083
  function getterFn(path, csp) {
15868
16084
  if (getterFnCache.hasOwnProperty(path)) {
@@ -15877,7 +16093,7 @@ function getterFn(path, csp) {
15877
16093
  fn = (pathKeysLength < 6)
15878
16094
  ? cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4])
15879
16095
  : function(scope, locals) {
15880
- var i = 0, val
16096
+ var i = 0, val;
15881
16097
  do {
15882
16098
  val = cspSafeGetterFn(
15883
16099
  pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++]
@@ -15942,9 +16158,9 @@ function getterFn(path, csp) {
15942
16158
  * @param {string} expression String expression to compile.
15943
16159
  * @returns {function(context, locals)} a function which represents the compiled expression:
15944
16160
  *
15945
- * * `context` `{object}` an object against which any expressions embedded in the strings
16161
+ * * `context` – `{object}` – an object against which any expressions embedded in the strings
15946
16162
  * are evaluated against (tipically a scope object).
15947
- * * `locals` `{object=}` local variables context object, useful for overriding values in
16163
+ * * `locals` – `{object=}` – local variables context object, useful for overriding values in
15948
16164
  * `context`.
15949
16165
  *
15950
16166
  * The return function also has an `assign` property, if the expression is assignable, which
@@ -16033,14 +16249,14 @@ function $ParseProvider() {
16033
16249
  *
16034
16250
  * **Methods**
16035
16251
  *
16036
- * - `resolve(value)` resolves the derived promise with the `value`. If the value is a rejection
16252
+ * - `resolve(value)` – resolves the derived promise with the `value`. If the value is a rejection
16037
16253
  * constructed via `$q.reject`, the promise will be rejected instead.
16038
- * - `reject(reason)` rejects the derived promise with the `reason`. This is equivalent to
16254
+ * - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to
16039
16255
  * resolving it with a rejection constructed via `$q.reject`.
16040
16256
  *
16041
16257
  * **Properties**
16042
16258
  *
16043
- * - promise `{Promise}` promise object associated with this deferred.
16259
+ * - promise – `{Promise}` – promise object associated with this deferred.
16044
16260
  *
16045
16261
  *
16046
16262
  * # The Promise API
@@ -16053,9 +16269,9 @@ function $ParseProvider() {
16053
16269
  *
16054
16270
  * **Methods**
16055
16271
  *
16056
- * - `then(successCallback, errorCallback)` regardless of when the promise was or will be resolved
16057
- * or rejected calls one of the success or error callbacks asynchronously as soon as the result
16058
- * is available. The callbacks are called with a single argument the result or rejection reason.
16272
+ * - `then(successCallback, errorCallback)` – regardless of when the promise was or will be resolved
16273
+ * or rejected, `then` calls one of the success or error callbacks asynchronously as soon as the result
16274
+ * is available. The callbacks are called with a single argument: the result or rejection reason.
16059
16275
  *
16060
16276
  * This method *returns a new promise* which is resolved or rejected via the return value of the
16061
16277
  * `successCallback` or `errorCallback`.
@@ -16063,7 +16279,7 @@ function $ParseProvider() {
16063
16279
  *
16064
16280
  * # Chaining promises
16065
16281
  *
16066
- * Because calling `then` api of a promise returns a new derived promise, it is easily possible
16282
+ * Because calling the `then` method of a promise returns a new derived promise, it is easily possible
16067
16283
  * to create a chain of promises:
16068
16284
  *
16069
16285
  * <pre>
@@ -16071,13 +16287,13 @@ function $ParseProvider() {
16071
16287
  * return result + 1;
16072
16288
  * });
16073
16289
  *
16074
- * // promiseB will be resolved immediately after promiseA is resolved and its value will be
16075
- * // the result of promiseA incremented by 1
16290
+ * // promiseB will be resolved immediately after promiseA is resolved and its value
16291
+ * // will be the result of promiseA incremented by 1
16076
16292
  * </pre>
16077
16293
  *
16078
16294
  * It is possible to create chains of any length and since a promise can be resolved with another
16079
16295
  * promise (which will defer its resolution further), it is possible to pause/defer resolution of
16080
- * the promises at any point in the chain. This makes it possible to implement powerful apis like
16296
+ * the promises at any point in the chain. This makes it possible to implement powerful APIs like
16081
16297
  * $http's response interceptors.
16082
16298
  *
16083
16299
  *
@@ -16090,7 +16306,7 @@ function $ParseProvider() {
16090
16306
  * models and avoiding unnecessary browser repaints, which would result in flickering UI.
16091
16307
  * - $q promises are recognized by the templating engine in angular, which means that in templates
16092
16308
  * you can treat promises attached to a scope as if they were the resulting values.
16093
- * - Q has many more features that $q, but that comes at a cost of bytes. $q is tiny, but contains
16309
+ * - Q has many more features than $q, but that comes at a cost of bytes. $q is tiny, but contains
16094
16310
  * all the important functionality needed for common async tasks.
16095
16311
  *
16096
16312
  * # Testing
@@ -16184,8 +16400,8 @@ function qFactory(nextTick, exceptionHandler) {
16184
16400
  try {
16185
16401
  result.resolve((callback || defaultCallback)(value));
16186
16402
  } catch(e) {
16187
- exceptionHandler(e);
16188
16403
  result.reject(e);
16404
+ exceptionHandler(e);
16189
16405
  }
16190
16406
  };
16191
16407
 
@@ -16193,8 +16409,8 @@ function qFactory(nextTick, exceptionHandler) {
16193
16409
  try {
16194
16410
  result.resolve((errback || defaultErrback)(reason));
16195
16411
  } catch(e) {
16196
- exceptionHandler(e);
16197
16412
  result.reject(e);
16413
+ exceptionHandler(e);
16198
16414
  }
16199
16415
  };
16200
16416
 
@@ -16285,10 +16501,7 @@ function qFactory(nextTick, exceptionHandler) {
16285
16501
  * the promise comes from a source that can't be trusted.
16286
16502
  *
16287
16503
  * @param {*} value Value or a promise
16288
- * @returns {Promise} Returns a single promise that will be resolved with an array of values,
16289
- * each value corresponding to the promise at the same index in the `promises` array. If any of
16290
- * the promises is resolved with a rejection, this resulting promise will be resolved with the
16291
- * same rejection.
16504
+ * @returns {Promise} Returns a promise of the passed value or promise
16292
16505
  */
16293
16506
  var when = function(value, callback, errback) {
16294
16507
  var result = defer(),
@@ -16406,35 +16619,37 @@ function $RouteProvider(){
16406
16619
  * route definition.
16407
16620
  *
16408
16621
  * `path` can contain named groups starting with a colon (`:name`). All characters up to the
16409
- * next slash are matched and stored in `$routeParams` under the given `name` when the route
16410
- * matches.
16622
+ * next slash are matched and stored in `$routeParams` under the given `name` after the route
16623
+ * is resolved.
16411
16624
  *
16412
16625
  * @param {Object} route Mapping information to be assigned to `$route.current` on route
16413
16626
  * match.
16414
16627
  *
16415
16628
  * Object properties:
16416
16629
  *
16417
- * - `controller` `{(string|function()=}` Controller fn that should be associated with newly
16630
+ * - `controller` – `{(string|function()=}` – Controller fn that should be associated with newly
16418
16631
  * created scope or the name of a {@link angular.Module#controller registered controller}
16419
16632
  * if passed as a string.
16420
- * - `template` `{string=}` html template as a string that should be used by
16633
+ * - `template` – `{string=}` – html template as a string that should be used by
16421
16634
  * {@link ng.directive:ngView ngView} or
16422
16635
  * {@link ng.directive:ngInclude ngInclude} directives.
16423
16636
  * this property takes precedence over `templateUrl`.
16424
- * - `templateUrl` `{string=}` path to an html template that should be used by
16637
+ * - `templateUrl` – `{string=}` – path to an html template that should be used by
16425
16638
  * {@link ng.directive:ngView ngView}.
16426
16639
  * - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
16427
16640
  * be injected into the controller. If any of these dependencies are promises, they will be
16428
16641
  * resolved and converted to a value before the controller is instantiated and the
16429
16642
  * `$routeChangeSuccess` event is fired. The map object is:
16430
16643
  *
16431
- * - `key` `{string}`: a name of a dependency to be injected into the controller.
16644
+ * - `key` – `{string}`: a name of a dependency to be injected into the controller.
16432
16645
  * - `factory` - `{string|function}`: If `string` then it is an alias for a service.
16433
16646
  * Otherwise if function, then it is {@link api/AUTO.$injector#invoke injected}
16434
16647
  * and the return value is treated as the dependency. If the result is a promise, it is resolved
16435
- * before its value is injected into the controller.
16648
+ * before its value is injected into the controller. Be aware that `ngRoute.$routeParams` will
16649
+ * still refer to the previous route within these resolve functions. Use `$route.current.params`
16650
+ * to access the new route parameters, instead.
16436
16651
  *
16437
- * - `redirectTo` {(string|function())=} value to update
16652
+ * - `redirectTo` – {(string|function())=} – value to update
16438
16653
  * {@link ng.$location $location} path with and trigger route redirection.
16439
16654
  *
16440
16655
  * If `redirectTo` is a function, it will be called with the following parameters:
@@ -16645,8 +16860,9 @@ function $RouteProvider(){
16645
16860
  * {@link ng.directive:ngView ngView} listens for the directive
16646
16861
  * to instantiate the controller and render the view.
16647
16862
  *
16863
+ * @param {Object} angularEvent Synthetic event object.
16648
16864
  * @param {Route} current Current route information.
16649
- * @param {Route} previous Previous route information.
16865
+ * @param {Route|Undefined} previous Previous route information, or undefined if current is first route entered.
16650
16866
  */
16651
16867
 
16652
16868
  /**
@@ -16744,7 +16960,7 @@ function $RouteProvider(){
16744
16960
  var next = parseRoute(),
16745
16961
  last = $route.current;
16746
16962
 
16747
- if (next && last && next.$route === last.$route
16963
+ if (next && last && next.$$route === last.$$route
16748
16964
  && equals(next.pathParams, last.pathParams) && !next.reloadOnSearch && !forceReload) {
16749
16965
  last.params = next.params;
16750
16966
  copy(last.params, $routeParams);
@@ -16823,7 +17039,7 @@ function $RouteProvider(){
16823
17039
  match = inherit(route, {
16824
17040
  params: extend({}, $location.search(), params),
16825
17041
  pathParams: params});
16826
- match.$route = route;
17042
+ match.$$route = route;
16827
17043
  }
16828
17044
  });
16829
17045
  // No route matched; fallback to "otherwise" route
@@ -16866,6 +17082,10 @@ function $RouteProvider(){
16866
17082
  * The service guarantees that the identity of the `$routeParams` object will remain unchanged
16867
17083
  * (but its properties will likely change) even when a route change occurs.
16868
17084
  *
17085
+ * Note that the `$routeParams` are only updated *after* a route change completes successfully.
17086
+ * This means that you cannot rely on `$routeParams` being correct in route resolve functions.
17087
+ * Instead you can use `$route.current.params` to access the new route's parameters.
17088
+ *
16869
17089
  * @example
16870
17090
  * <pre>
16871
17091
  * // Given:
@@ -16883,22 +17103,22 @@ function $RouteParamsProvider() {
16883
17103
  /**
16884
17104
  * DESIGN NOTES
16885
17105
  *
16886
- * The design decisions behind the scope ware heavily favored for speed and memory consumption.
17106
+ * The design decisions behind the scope are heavily favored for speed and memory consumption.
16887
17107
  *
16888
17108
  * The typical use of scope is to watch the expressions, which most of the time return the same
16889
17109
  * value as last time so we optimize the operation.
16890
17110
  *
16891
- * Closures construction is expensive from speed as well as memory:
16892
- * - no closures, instead ups prototypical inheritance for API
17111
+ * Closures construction is expensive in terms of speed as well as memory:
17112
+ * - No closures, instead use prototypical inheritance for API
16893
17113
  * - Internal state needs to be stored on scope directly, which means that private state is
16894
17114
  * exposed as $$____ properties
16895
17115
  *
16896
17116
  * Loop operations are optimized by using while(count--) { ... }
16897
17117
  * - this means that in order to keep the same order of execution as addition we have to add
16898
- * items to the array at the begging (shift) instead of at the end (push)
17118
+ * items to the array at the beginning (shift) instead of at the end (push)
16899
17119
  *
16900
17120
  * Child scopes are created and removed often
16901
- * - Using array would be slow since inserts in meddle are expensive so we use linked list
17121
+ * - Using an array would be slow since inserts in middle are expensive so we use linked list
16902
17122
  *
16903
17123
  * There are few watches then a lot of observers. This is why you don't want the observer to be
16904
17124
  * implemented in the same way as watch. Watch requires return of initialization function which
@@ -16920,7 +17140,7 @@ function $RouteParamsProvider() {
16920
17140
  * @methodOf ng.$rootScopeProvider
16921
17141
  * @description
16922
17142
  *
16923
- * Sets the number of digest iteration the scope should attempt to execute before giving up and
17143
+ * Sets the number of digest iterations the scope should attempt to execute before giving up and
16924
17144
  * assuming that the model is unstable.
16925
17145
  *
16926
17146
  * The current default is 10 iterations.
@@ -17200,7 +17420,7 @@ function $RootScopeProvider(){
17200
17420
  * @function
17201
17421
  *
17202
17422
  * @description
17203
- * Process all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and its children.
17423
+ * Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and its children.
17204
17424
  * Because a {@link ng.$rootScope.Scope#$watch watcher}'s listener can change the model, the
17205
17425
  * `$digest()` keeps calling the {@link ng.$rootScope.Scope#$watch watchers} until no more listeners are
17206
17426
  * firing. This means that it is possible to get into an infinite loop. This function will throw
@@ -17273,7 +17493,7 @@ function $RootScopeProvider(){
17273
17493
  watch = watchers[length];
17274
17494
  // Most common watches are on primitives, in which case we can short
17275
17495
  // circuit it with === operator, only when === fails do we use .equals
17276
- if ((value = watch.get(current)) !== (last = watch.last) &&
17496
+ if (watch && (value = watch.get(current)) !== (last = watch.last) &&
17277
17497
  !(watch.eq
17278
17498
  ? equals(value, last)
17279
17499
  : (typeof value == 'number' && typeof last == 'number'
@@ -17326,6 +17546,9 @@ function $RootScopeProvider(){
17326
17546
  *
17327
17547
  * @description
17328
17548
  * Broadcasted when a scope and its children are being destroyed.
17549
+ *
17550
+ * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to
17551
+ * clean up DOM bindings before an element is removed from the DOM.
17329
17552
  */
17330
17553
 
17331
17554
  /**
@@ -17347,6 +17570,9 @@ function $RootScopeProvider(){
17347
17570
  * Just before a scope is destroyed a `$destroy` event is broadcasted on this scope.
17348
17571
  * Application code can register a `$destroy` event handler that will give it chance to
17349
17572
  * perform any necessary cleanup.
17573
+ *
17574
+ * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to
17575
+ * clean up DOM bindings before an element is removed from the DOM.
17350
17576
  */
17351
17577
  $destroy: function() {
17352
17578
  // we can't destroy the root scope or a scope that has been already destroyed
@@ -17542,7 +17768,7 @@ function $RootScopeProvider(){
17542
17768
  * Afterwards, the event traverses upwards toward the root scope and calls all registered
17543
17769
  * listeners along the way. The event will stop propagating if one of the listeners cancels it.
17544
17770
  *
17545
- * Any exception emmited from the {@link ng.$rootScope.Scope#$on listeners} will be passed
17771
+ * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed
17546
17772
  * onto the {@link ng.$exceptionHandler $exceptionHandler} service.
17547
17773
  *
17548
17774
  * @param {string} name Event name to emit.
@@ -17611,7 +17837,7 @@ function $RootScopeProvider(){
17611
17837
  * Any exception emmited from the {@link ng.$rootScope.Scope#$on listeners} will be passed
17612
17838
  * onto the {@link ng.$exceptionHandler $exceptionHandler} service.
17613
17839
  *
17614
- * @param {string} name Event name to emit.
17840
+ * @param {string} name Event name to broadcast.
17615
17841
  * @param {...*} args Optional set of arguments which will be passed onto the event listeners.
17616
17842
  * @return {Object} Event object, see {@link ng.$rootScope.Scope#$on}
17617
17843
  */
@@ -17751,16 +17977,31 @@ function $SnifferProvider() {
17751
17977
  * it is a global variable. In angular we always refer to it through the
17752
17978
  * `$window` service, so it may be overriden, removed or mocked for testing.
17753
17979
  *
17754
- * All expressions are evaluated with respect to current scope so they don't
17755
- * suffer from window globality.
17980
+ * Expressions, like the one defined for the `ngClick` directive in the example
17981
+ * below, are evaluated with respect to the current scope. Therefore, there is
17982
+ * no risk of inadvertently coding in a dependency on a global value in such an
17983
+ * expression.
17756
17984
  *
17757
17985
  * @example
17758
17986
  <doc:example>
17759
17987
  <doc:source>
17760
- <input ng-init="$window = $service('$window'); greeting='Hello World!'" type="text" ng-model="greeting" />
17761
- <button ng-click="$window.alert(greeting)">ALERT</button>
17988
+ <script>
17989
+ function Ctrl($scope, $window) {
17990
+ $scope.$window = $window;
17991
+ $scope.greeting = 'Hello, World!';
17992
+ }
17993
+ </script>
17994
+ <div ng-controller="Ctrl">
17995
+ <input type="text" ng-model="greeting" />
17996
+ <button ng-click="$window.alert(greeting)">ALERT</button>
17997
+ </div>
17762
17998
  </doc:source>
17763
17999
  <doc:scenario>
18000
+ it('should display the greeting in the input box', function() {
18001
+ input('greeting').enter('Hello, E2E Tests');
18002
+ // If we click the button it will block the test runner
18003
+ // element(':button').click();
18004
+ });
17764
18005
  </doc:scenario>
17765
18006
  </doc:example>
17766
18007
  */
@@ -17913,7 +18154,7 @@ function $HttpProvider() {
17913
18154
  *
17914
18155
  * @description
17915
18156
  * The `$http` service is a core Angular service that facilitates communication with the remote
17916
- * HTTP servers via browser's {@link https://developer.mozilla.org/en/xmlhttprequest
18157
+ * HTTP servers via the browser's {@link https://developer.mozilla.org/en/xmlhttprequest
17917
18158
  * XMLHttpRequest} object or via {@link http://en.wikipedia.org/wiki/JSONP JSONP}.
17918
18159
  *
17919
18160
  * For unit testing applications that use `$http` service, see
@@ -17923,13 +18164,13 @@ function $HttpProvider() {
17923
18164
  * $resource} service.
17924
18165
  *
17925
18166
  * The $http API is based on the {@link ng.$q deferred/promise APIs} exposed by
17926
- * the $q service. While for simple usage patters this doesn't matter much, for advanced usage,
17927
- * it is important to familiarize yourself with these apis and guarantees they provide.
18167
+ * the $q service. While for simple usage patterns this doesn't matter much, for advanced usage
18168
+ * it is important to familiarize yourself with these APIs and the guarantees they provide.
17928
18169
  *
17929
18170
  *
17930
18171
  * # General usage
17931
- * The `$http` service is a function which takes a single argument a configuration object
17932
- * that is used to generate an http request and returns a {@link ng.$q promise}
18172
+ * The `$http` service is a function which takes a single argument — a configuration object —
18173
+ * that is used to generate an HTTP request and returns a {@link ng.$q promise}
17933
18174
  * with two $http specific methods: `success` and `error`.
17934
18175
  *
17935
18176
  * <pre>
@@ -17944,21 +18185,21 @@ function $HttpProvider() {
17944
18185
  * });
17945
18186
  * </pre>
17946
18187
  *
17947
- * Since the returned value of calling the $http function is a Promise object, you can also use
17948
- * the `then` method to register callbacks, and these callbacks will receive a single argument
17949
- * an object representing the response. See the api signature and type info below for more
18188
+ * Since the returned value of calling the $http function is a `promise`, you can also use
18189
+ * the `then` method to register callbacks, and these callbacks will receive a single argument –
18190
+ * an object representing the response. See the API signature and type info below for more
17950
18191
  * details.
17951
18192
  *
17952
- * A response status code that falls in the [200, 300) range is considered a success status and
18193
+ * A response status code between 200 and 299 is considered a success status and
17953
18194
  * will result in the success callback being called. Note that if the response is a redirect,
17954
18195
  * XMLHttpRequest will transparently follow it, meaning that the error callback will not be
17955
18196
  * called for such responses.
17956
18197
  *
17957
18198
  * # Shortcut methods
17958
18199
  *
17959
- * Since all invocation of the $http service require definition of the http method and url and
17960
- * POST and PUT requests require response body/data to be provided as well, shortcut methods
17961
- * were created to simplify using the api:
18200
+ * Since all invocations of the $http service require passing in an HTTP method and URL, and
18201
+ * POST/PUT requests require request data to be provided as well, shortcut methods
18202
+ * were created:
17962
18203
  *
17963
18204
  * <pre>
17964
18205
  * $http.get('/someUrl').success(successCallback);
@@ -17977,25 +18218,25 @@ function $HttpProvider() {
17977
18218
  *
17978
18219
  * # Setting HTTP Headers
17979
18220
  *
17980
- * The $http service will automatically add certain http headers to all requests. These defaults
18221
+ * The $http service will automatically add certain HTTP headers to all requests. These defaults
17981
18222
  * can be fully configured by accessing the `$httpProvider.defaults.headers` configuration
17982
18223
  * object, which currently contains this default configuration:
17983
18224
  *
17984
18225
  * - `$httpProvider.defaults.headers.common` (headers that are common for all requests):
17985
18226
  * - `Accept: application/json, text/plain, * / *`
17986
18227
  * - `X-Requested-With: XMLHttpRequest`
17987
- * - `$httpProvider.defaults.headers.post`: (header defaults for HTTP POST requests)
18228
+ * - `$httpProvider.defaults.headers.post`: (header defaults for POST requests)
17988
18229
  * - `Content-Type: application/json`
17989
- * - `$httpProvider.defaults.headers.put` (header defaults for HTTP PUT requests)
18230
+ * - `$httpProvider.defaults.headers.put` (header defaults for PUT requests)
17990
18231
  * - `Content-Type: application/json`
17991
18232
  *
17992
- * To add or overwrite these defaults, simply add or remove a property from this configuration
18233
+ * To add or overwrite these defaults, simply add or remove a property from these configuration
17993
18234
  * objects. To add headers for an HTTP method other than POST or PUT, simply add a new object
17994
- * with name equal to the lower-cased http method name, e.g.
18235
+ * with the lowercased HTTP method name as the key, e.g.
17995
18236
  * `$httpProvider.defaults.headers.get['My-Header']='value'`.
17996
18237
  *
17997
- * Additionally, the defaults can be set at runtime via the `$http.defaults` object in a similar
17998
- * fassion as described above.
18238
+ * Additionally, the defaults can be set at runtime via the `$http.defaults` object in the same
18239
+ * fashion.
17999
18240
  *
18000
18241
  *
18001
18242
  * # Transforming Requests and Responses
@@ -18005,32 +18246,36 @@ function $HttpProvider() {
18005
18246
  *
18006
18247
  * Request transformations:
18007
18248
  *
18008
- * - if the `data` property of the request config object contains an object, serialize it into
18249
+ * - If the `data` property of the request configuration object contains an object, serialize it into
18009
18250
  * JSON format.
18010
18251
  *
18011
18252
  * Response transformations:
18012
18253
  *
18013
- * - if XSRF prefix is detected, strip it (see Security Considerations section below)
18014
- * - if json response is detected, deserialize it using a JSON parser
18254
+ * - If XSRF prefix is detected, strip it (see Security Considerations section below).
18255
+ * - If JSON response is detected, deserialize it using a JSON parser.
18015
18256
  *
18016
- * To override these transformation locally, specify transform functions as `transformRequest`
18017
- * and/or `transformResponse` properties of the config object. To globally override the default
18018
- * transforms, override the `$httpProvider.defaults.transformRequest` and
18019
- * `$httpProvider.defaults.transformResponse` properties of the `$httpProvider`.
18257
+ * To globally augment or override the default transforms, modify the `$httpProvider.defaults.transformRequest` and
18258
+ * `$httpProvider.defaults.transformResponse` properties. These properties are by default an
18259
+ * array of transform functions, which allows you to `push` or `unshift` a new transformation function into the
18260
+ * transformation chain. You can also decide to completely override any default transformations by assigning your
18261
+ * transformation functions to these properties directly without the array wrapper.
18262
+ *
18263
+ * Similarly, to locally override the request/response transforms, augment the `transformRequest` and/or
18264
+ * `transformResponse` properties of the configuration object passed into `$http`.
18020
18265
  *
18021
18266
  *
18022
18267
  * # Caching
18023
18268
  *
18024
- * To enable caching set the configuration property `cache` to `true`. When the cache is
18269
+ * To enable caching, set the configuration property `cache` to `true`. When the cache is
18025
18270
  * enabled, `$http` stores the response from the server in local cache. Next time the
18026
18271
  * response is served from the cache without sending a request to the server.
18027
18272
  *
18028
18273
  * Note that even if the response is served from cache, delivery of the data is asynchronous in
18029
18274
  * the same way that real requests are.
18030
18275
  *
18031
- * If there are multiple GET requests for the same url that should be cached using the same
18276
+ * If there are multiple GET requests for the same URL that should be cached using the same
18032
18277
  * cache, but the cache is not populated yet, only one request to the server will be made and
18033
- * the remaining requests will be fulfilled using the response for the first request.
18278
+ * the remaining requests will be fulfilled using the response from the first request.
18034
18279
  *
18035
18280
  *
18036
18281
  * # Response interceptors
@@ -18046,7 +18291,7 @@ function $HttpProvider() {
18046
18291
  *
18047
18292
  * The interceptors are service factories that are registered with the $httpProvider by
18048
18293
  * adding them to the `$httpProvider.responseInterceptors` array. The factory is called and
18049
- * injected with dependencies (if specified) and returns the interceptor a function that
18294
+ * injected with dependencies (if specified) and returns the interceptor — a function that
18050
18295
  * takes a {@link ng.$q promise} and returns the original or a new promise.
18051
18296
  *
18052
18297
  * <pre>
@@ -18055,6 +18300,7 @@ function $HttpProvider() {
18055
18300
  * return function(promise) {
18056
18301
  * return promise.then(function(response) {
18057
18302
  * // do something on success
18303
+ * return response;
18058
18304
  * }, function(response) {
18059
18305
  * // do something on error
18060
18306
  * if (canRecover(response)) {
@@ -18082,7 +18328,7 @@ function $HttpProvider() {
18082
18328
  * When designing web applications, consider security threats from:
18083
18329
  *
18084
18330
  * - {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx
18085
- * JSON Vulnerability}
18331
+ * JSON vulnerability}
18086
18332
  * - {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF}
18087
18333
  *
18088
18334
  * Both server and the client must cooperate in order to eliminate these threats. Angular comes
@@ -18092,8 +18338,8 @@ function $HttpProvider() {
18092
18338
  * ## JSON Vulnerability Protection
18093
18339
  *
18094
18340
  * A {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx
18095
- * JSON Vulnerability} allows third party web-site to turn your JSON resource URL into
18096
- * {@link http://en.wikipedia.org/wiki/JSON#JSONP JSONP} request under some conditions. To
18341
+ * JSON vulnerability} allows third party website to turn your JSON resource URL into
18342
+ * {@link http://en.wikipedia.org/wiki/JSONP JSONP} request under some conditions. To
18097
18343
  * counter this your server can prefix all JSON requests with following string `")]}',\n"`.
18098
18344
  * Angular will automatically strip the prefix before processing it as JSON.
18099
18345
  *
@@ -18114,41 +18360,41 @@ function $HttpProvider() {
18114
18360
  * ## Cross Site Request Forgery (XSRF) Protection
18115
18361
  *
18116
18362
  * {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF} is a technique by which
18117
- * an unauthorized site can gain your user's private data. Angular provides following mechanism
18363
+ * an unauthorized site can gain your user's private data. Angular provides a mechanism
18118
18364
  * to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie
18119
18365
  * called `XSRF-TOKEN` and sets it as the HTTP header `X-XSRF-TOKEN`. Since only JavaScript that
18120
18366
  * runs on your domain could read the cookie, your server can be assured that the XHR came from
18121
18367
  * JavaScript running on your domain.
18122
18368
  *
18123
18369
  * To take advantage of this, your server needs to set a token in a JavaScript readable session
18124
- * cookie called `XSRF-TOKEN` on first HTTP GET request. On subsequent non-GET requests the
18370
+ * cookie called `XSRF-TOKEN` on the first HTTP GET request. On subsequent XHR requests the
18125
18371
  * server can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure
18126
- * that only JavaScript running on your domain could have read the token. The token must be
18127
- * unique for each user and must be verifiable by the server (to prevent the JavaScript making
18372
+ * that only JavaScript running on your domain could have sent the request. The token must be
18373
+ * unique for each user and must be verifiable by the server (to prevent the JavaScript from making
18128
18374
  * up its own tokens). We recommend that the token is a digest of your site's authentication
18129
- * cookie with {@link http://en.wikipedia.org/wiki/Rainbow_table salt for added security}.
18375
+ * cookie with a {@link https://en.wikipedia.org/wiki/Salt_(cryptography) salt} for added security.
18130
18376
  *
18131
18377
  *
18132
18378
  * @param {object} config Object describing the request to be made and how it should be
18133
18379
  * processed. The object has following properties:
18134
18380
  *
18135
- * - **method** `{string}` HTTP method (e.g. 'GET', 'POST', etc)
18136
- * - **url** `{string}` Absolute or relative URL of the resource that is being requested.
18137
- * - **params** `{Object.<string|Object>}` Map of strings or objects which will be turned to
18381
+ * - **method** – `{string}` – HTTP method (e.g. 'GET', 'POST', etc)
18382
+ * - **url** – `{string}` – Absolute or relative URL of the resource that is being requested.
18383
+ * - **params** – `{Object.<string|Object>}` – Map of strings or objects which will be turned to
18138
18384
  * `?key1=value1&key2=value2` after the url. If the value is not a string, it will be JSONified.
18139
- * - **data** `{string|Object}` Data to be sent as the request message data.
18140
- * - **headers** `{Object}` Map of strings representing HTTP headers to send to the server.
18141
- * - **transformRequest** `{function(data, headersGetter)|Array.<function(data, headersGetter)>}`
18385
+ * - **data** – `{string|Object}` – Data to be sent as the request message data.
18386
+ * - **headers** – `{Object}` – Map of strings representing HTTP headers to send to the server.
18387
+ * - **transformRequest** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
18142
18388
  * transform function or an array of such functions. The transform function takes the http
18143
18389
  * request body and headers and returns its transformed (typically serialized) version.
18144
- * - **transformResponse** `{function(data, headersGetter)|Array.<function(data, headersGetter)>}`
18390
+ * - **transformResponse** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
18145
18391
  * transform function or an array of such functions. The transform function takes the http
18146
18392
  * response body and headers and returns its transformed (typically deserialized) version.
18147
- * - **cache** `{boolean|Cache}` If true, a default $http cache will be used to cache the
18393
+ * - **cache** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
18148
18394
  * GET request, otherwise if a cache instance built with
18149
18395
  * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
18150
18396
  * caching.
18151
- * - **timeout** `{number}` timeout in milliseconds.
18397
+ * - **timeout** – `{number}` – timeout in milliseconds.
18152
18398
  * - **withCredentials** - `{boolean}` - whether to to set the `withCredentials` flag on the
18153
18399
  * XHR object. See {@link https://developer.mozilla.org/en/http_access_control#section_5
18154
18400
  * requests with credentials} for more information.
@@ -18161,10 +18407,10 @@ function $HttpProvider() {
18161
18407
  * these functions are destructured representation of the response object passed into the
18162
18408
  * `then` method. The response object has these properties:
18163
18409
  *
18164
- * - **data** `{string|Object}` The response body transformed with the transform functions.
18165
- * - **status** `{number}` HTTP status code of the response.
18166
- * - **headers** `{function([headerName])}` Header getter function.
18167
- * - **config** `{Object}` The configuration object that was used to generate the request.
18410
+ * - **data** – `{string|Object}` – The response body transformed with the transform functions.
18411
+ * - **status** – `{number}` – HTTP status code of the response.
18412
+ * - **headers** – `{function([headerName])}` – Header getter function.
18413
+ * - **config** – `{Object}` – The configuration object that was used to generate the request.
18168
18414
  *
18169
18415
  * @property {Array.<Object>} pendingRequests Array of config objects for currently pending
18170
18416
  * requests. This is primarily meant to be used for debugging purposes.
@@ -18246,17 +18492,40 @@ function $HttpProvider() {
18246
18492
 
18247
18493
  var reqTransformFn = config.transformRequest || $config.transformRequest,
18248
18494
  respTransformFn = config.transformResponse || $config.transformResponse,
18249
- defHeaders = $config.headers,
18250
- reqHeaders = extend({'X-XSRF-TOKEN': $browser.cookies()['XSRF-TOKEN']},
18251
- defHeaders.common, defHeaders[lowercase(config.method)], config.headers),
18252
- reqData = transformData(config.data, headersGetter(reqHeaders), reqTransformFn),
18495
+ reqHeaders = extend({}, config.headers),
18496
+ defHeaders = extend(
18497
+ {'X-XSRF-TOKEN': $browser.cookies()['XSRF-TOKEN']},
18498
+ $config.headers.common,
18499
+ $config.headers[lowercase(config.method)]
18500
+ ),
18501
+ reqData,
18502
+ defHeaderName, lowercaseDefHeaderName, headerName,
18253
18503
  promise;
18254
18504
 
18505
+ // using for-in instead of forEach to avoid unecessary iteration after header has been found
18506
+ defaultHeadersIteration:
18507
+ for(defHeaderName in defHeaders) {
18508
+ lowercaseDefHeaderName = lowercase(defHeaderName);
18509
+ for(headerName in config.headers) {
18510
+ if (lowercase(headerName) === lowercaseDefHeaderName) {
18511
+ continue defaultHeadersIteration;
18512
+ }
18513
+ }
18514
+ reqHeaders[defHeaderName] = defHeaders[defHeaderName];
18515
+ }
18516
+
18255
18517
  // strip content-type if data is undefined
18256
18518
  if (isUndefined(config.data)) {
18257
- delete reqHeaders['Content-Type'];
18519
+ for(var header in reqHeaders) {
18520
+ if (lowercase(header) === 'content-type') {
18521
+ delete reqHeaders[header];
18522
+ break;
18523
+ }
18524
+ }
18258
18525
  }
18259
18526
 
18527
+ reqData = transformData(config.data, headersGetter(reqHeaders), reqTransformFn);
18528
+
18260
18529
  // send request
18261
18530
  promise = sendReq(config, reqData, reqHeaders);
18262
18531
 
@@ -18304,7 +18573,7 @@ function $HttpProvider() {
18304
18573
  * @methodOf ng.$http
18305
18574
  *
18306
18575
  * @description
18307
- * Shortcut method to perform `GET` request
18576
+ * Shortcut method to perform `GET` request.
18308
18577
  *
18309
18578
  * @param {string} url Relative or absolute URL specifying the destination of the request
18310
18579
  * @param {Object=} config Optional configuration object
@@ -18317,7 +18586,7 @@ function $HttpProvider() {
18317
18586
  * @methodOf ng.$http
18318
18587
  *
18319
18588
  * @description
18320
- * Shortcut method to perform `DELETE` request
18589
+ * Shortcut method to perform `DELETE` request.
18321
18590
  *
18322
18591
  * @param {string} url Relative or absolute URL specifying the destination of the request
18323
18592
  * @param {Object=} config Optional configuration object
@@ -18330,7 +18599,7 @@ function $HttpProvider() {
18330
18599
  * @methodOf ng.$http
18331
18600
  *
18332
18601
  * @description
18333
- * Shortcut method to perform `HEAD` request
18602
+ * Shortcut method to perform `HEAD` request.
18334
18603
  *
18335
18604
  * @param {string} url Relative or absolute URL specifying the destination of the request
18336
18605
  * @param {Object=} config Optional configuration object
@@ -18343,7 +18612,7 @@ function $HttpProvider() {
18343
18612
  * @methodOf ng.$http
18344
18613
  *
18345
18614
  * @description
18346
- * Shortcut method to perform `JSONP` request
18615
+ * Shortcut method to perform `JSONP` request.
18347
18616
  *
18348
18617
  * @param {string} url Relative or absolute URL specifying the destination of the request.
18349
18618
  * Should contain `JSON_CALLBACK` string.
@@ -18358,7 +18627,7 @@ function $HttpProvider() {
18358
18627
  * @methodOf ng.$http
18359
18628
  *
18360
18629
  * @description
18361
- * Shortcut method to perform `POST` request
18630
+ * Shortcut method to perform `POST` request.
18362
18631
  *
18363
18632
  * @param {string} url Relative or absolute URL specifying the destination of the request
18364
18633
  * @param {*} data Request content
@@ -18372,7 +18641,7 @@ function $HttpProvider() {
18372
18641
  * @methodOf ng.$http
18373
18642
  *
18374
18643
  * @description
18375
- * Shortcut method to perform `PUT` request
18644
+ * Shortcut method to perform `PUT` request.
18376
18645
  *
18377
18646
  * @param {string} url Relative or absolute URL specifying the destination of the request
18378
18647
  * @param {*} data Request content
@@ -18424,7 +18693,7 @@ function $HttpProvider() {
18424
18693
 
18425
18694
 
18426
18695
  /**
18427
- * Makes the request
18696
+ * Makes the request.
18428
18697
  *
18429
18698
  * !!! ACCESSES CLOSURE VARS:
18430
18699
  * $httpBackend, $config, $log, $rootScope, defaultCache, $http.pendingRequests
@@ -18534,6 +18803,7 @@ function $HttpProvider() {
18534
18803
 
18535
18804
  }];
18536
18805
  }
18806
+
18537
18807
  var XHR = window.XMLHttpRequest || function() {
18538
18808
  try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {}
18539
18809
  try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {}
@@ -18691,7 +18961,7 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
18691
18961
  * $locale service provides localization rules for various Angular components. As of right now the
18692
18962
  * only public api is:
18693
18963
  *
18694
- * * `id` `{string}` locale id formatted as `languageId-countryId` (e.g. `en-us`)
18964
+ * * `id` – `{string}` – locale id formatted as `languageId-countryId` (e.g. `en-us`)
18695
18965
  */
18696
18966
  function $LocaleProvider(){
18697
18967
  this.$get = function() {
@@ -18770,17 +19040,17 @@ function $TimeoutProvider() {
18770
19040
  * block and delegates any exceptions to
18771
19041
  * {@link ng.$exceptionHandler $exceptionHandler} service.
18772
19042
  *
18773
- * The return value of registering a timeout function is a promise which will be resolved when
19043
+ * The return value of registering a timeout function is a promise, which will be resolved when
18774
19044
  * the timeout is reached and the timeout function is executed.
18775
19045
  *
18776
- * To cancel a the timeout request, call `$timeout.cancel(promise)`.
19046
+ * To cancel a timeout request, call `$timeout.cancel(promise)`.
18777
19047
  *
18778
19048
  * In tests you can use {@link ngMock.$timeout `$timeout.flush()`} to
18779
19049
  * synchronously flush the queue of deferred functions.
18780
19050
  *
18781
- * @param {function()} fn A function, who's execution should be delayed.
19051
+ * @param {function()} fn A function, whose execution should be delayed.
18782
19052
  * @param {number=} [delay=0] Delay in milliseconds.
18783
- * @param {boolean=} [invokeApply=true] If set to false skips model dirty checking, otherwise
19053
+ * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
18784
19054
  * will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
18785
19055
  * @returns {Promise} Promise that will be resolved when the timeout is reached. The value this
18786
19056
  * promise will be resolved with is the return value of the `fn` function.
@@ -18798,17 +19068,15 @@ function $TimeoutProvider() {
18798
19068
  deferred.reject(e);
18799
19069
  $exceptionHandler(e);
18800
19070
  }
19071
+ finally {
19072
+ delete deferreds[promise.$$timeoutId];
19073
+ }
18801
19074
 
18802
19075
  if (!skipApply) $rootScope.$apply();
18803
19076
  }, delay);
18804
19077
 
18805
- cleanup = function() {
18806
- delete deferreds[promise.$$timeoutId];
18807
- };
18808
-
18809
19078
  promise.$$timeoutId = timeoutId;
18810
19079
  deferreds[timeoutId] = deferred;
18811
- promise.then(cleanup, cleanup);
18812
19080
 
18813
19081
  return promise;
18814
19082
  }
@@ -18820,7 +19088,7 @@ function $TimeoutProvider() {
18820
19088
  * @methodOf ng.$timeout
18821
19089
  *
18822
19090
  * @description
18823
- * Cancels a task associated with the `promise`. As a result of this the promise will be
19091
+ * Cancels a task associated with the `promise`. As a result of this, the promise will be
18824
19092
  * resolved with a rejection.
18825
19093
  *
18826
19094
  * @param {Promise=} promise Promise returned by the `$timeout` function.
@@ -18830,6 +19098,7 @@ function $TimeoutProvider() {
18830
19098
  timeout.cancel = function(promise) {
18831
19099
  if (promise && promise.$$timeoutId in deferreds) {
18832
19100
  deferreds[promise.$$timeoutId].reject('canceled');
19101
+ delete deferreds[promise.$$timeoutId];
18833
19102
  return $browser.defer.cancel(promise.$$timeoutId);
18834
19103
  }
18835
19104
  return false;
@@ -18846,7 +19115,7 @@ function $TimeoutProvider() {
18846
19115
  *
18847
19116
  * Filters are just functions which transform input to an output. However filters need to be Dependency Injected. To
18848
19117
  * achieve this a filter definition consists of a factory function which is annotated with dependencies and is
18849
- * responsible for creating a the filter function.
19118
+ * responsible for creating a filter function.
18850
19119
  *
18851
19120
  * <pre>
18852
19121
  * // Filter registration
@@ -18908,7 +19177,7 @@ function $TimeoutProvider() {
18908
19177
  *
18909
19178
  * The general syntax in templates is as follows:
18910
19179
  *
18911
- * {{ expression | [ filter_name ] }}
19180
+ * {{ expression [| filter_name[:parameter_value] ... ] }}
18912
19181
  *
18913
19182
  * @param {String} name Name of the filter function to retrieve
18914
19183
  * @return {Function} the filter function
@@ -18984,22 +19253,22 @@ function $FilterProvider($provide) {
18984
19253
 
18985
19254
  Search: <input ng-model="searchText">
18986
19255
  <table id="searchTextResults">
18987
- <tr><th>Name</th><th>Phone</th><tr>
19256
+ <tr><th>Name</th><th>Phone</th></tr>
18988
19257
  <tr ng-repeat="friend in friends | filter:searchText">
18989
19258
  <td>{{friend.name}}</td>
18990
19259
  <td>{{friend.phone}}</td>
18991
- <tr>
19260
+ </tr>
18992
19261
  </table>
18993
19262
  <hr>
18994
19263
  Any: <input ng-model="search.$"> <br>
18995
19264
  Name only <input ng-model="search.name"><br>
18996
- Phone only <input ng-model="search.phone"å><br>
19265
+ Phone only <input ng-model="search.phone"><br>
18997
19266
  <table id="searchObjResults">
18998
- <tr><th>Name</th><th>Phone</th><tr>
19267
+ <tr><th>Name</th><th>Phone</th></tr>
18999
19268
  <tr ng-repeat="friend in friends | filter:search">
19000
19269
  <td>{{friend.name}}</td>
19001
19270
  <td>{{friend.phone}}</td>
19002
- <tr>
19271
+ </tr>
19003
19272
  </table>
19004
19273
  </doc:source>
19005
19274
  <doc:scenario>
@@ -19166,8 +19435,10 @@ function currencyFilter($locale) {
19166
19435
  * If the input is not a number an empty string is returned.
19167
19436
  *
19168
19437
  * @param {number|string} number Number to format.
19169
- * @param {(number|string)=} [fractionSize=2] Number of decimal places to round the number to.
19170
- * @returns {string} Number rounded to decimalPlaces and places a “,” after each third digit.
19438
+ * @param {(number|string)=} fractionSize Number of decimal places to round the number to.
19439
+ * If this is not provided then the fraction size is computed from the current locale's number
19440
+ * formatting pattern. In the case of the default locale, it will be 3.
19441
+ * @returns {string} Number rounded to decimalPlaces and places a “,” after each third digit.
19171
19442
  *
19172
19443
  * @example
19173
19444
  <doc:example>
@@ -19273,6 +19544,11 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
19273
19544
  }
19274
19545
 
19275
19546
  if (fractionSize && fractionSize !== "0") formatedText += decimalSep + fraction.substr(0, fractionSize);
19547
+ } else {
19548
+
19549
+ if (fractionSize > 0 && number > -1 && number < 1) {
19550
+ formatedText = number.toFixed(fractionSize);
19551
+ }
19276
19552
  }
19277
19553
 
19278
19554
  parts.push(isNegative ? pattern.negPre : pattern.posPre);
@@ -19296,6 +19572,7 @@ function padNumber(num, digits, trim) {
19296
19572
 
19297
19573
 
19298
19574
  function dateGetter(name, size, offset, trim) {
19575
+ offset = offset || 0;
19299
19576
  return function(date) {
19300
19577
  var value = date['get' + name]();
19301
19578
  if (offset > 0 || value > -offset)
@@ -19318,7 +19595,8 @@ function timeZoneGetter(date) {
19318
19595
  var zone = -1 * date.getTimezoneOffset();
19319
19596
  var paddedZone = (zone >= 0) ? "+" : "";
19320
19597
 
19321
- paddedZone += padNumber(zone / 60, 2) + padNumber(Math.abs(zone % 60), 2);
19598
+ paddedZone += padNumber(Math[zone > 0 ? 'floor' : 'ceil'](zone / 60), 2) +
19599
+ padNumber(Math.abs(zone % 60), 2);
19322
19600
 
19323
19601
  return paddedZone;
19324
19602
  }
@@ -19384,7 +19662,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
19384
19662
  * * `'ss'`: Second in minute, padded (00-59)
19385
19663
  * * `'s'`: Second in minute (0-59)
19386
19664
  * * `'a'`: am/pm marker
19387
- * * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-1200)
19665
+ * * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-+1200)
19388
19666
  *
19389
19667
  * `format` string can also be one of the following predefined
19390
19668
  * {@link guide/i18n localizable formats}:
@@ -19394,7 +19672,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
19394
19672
  * * `'short'`: equivalent to `'M/d/yy h:mm a'` for en_US locale (e.g. 9/3/10 12:05 pm)
19395
19673
  * * `'fullDate'`: equivalent to `'EEEE, MMMM d,y'` for en_US locale
19396
19674
  * (e.g. Friday, September 3, 2010)
19397
- * * `'longDate'`: equivalent to `'MMMM d, y'` for en_US locale (e.g. September 3, 2010
19675
+ * * `'longDate'`: equivalent to `'MMMM d, y'` for en_US locale (e.g. September 3, 2010)
19398
19676
  * * `'mediumDate'`: equivalent to `'MMM d, y'` for en_US locale (e.g. Sep 3, 2010)
19399
19677
  * * `'shortDate'`: equivalent to `'M/d/yy'` for en_US locale (e.g. 9/3/10)
19400
19678
  * * `'mediumTime'`: equivalent to `'h:mm:ss a'` for en_US locale (e.g. 12:05:08 pm)
@@ -19402,10 +19680,10 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
19402
19680
  *
19403
19681
  * `format` string can contain literal values. These need to be quoted with single quotes (e.g.
19404
19682
  * `"h 'in the morning'"`). In order to output single quote, use two single quotes in a sequence
19405
- * (e.g. `"h o''clock"`).
19683
+ * (e.g. `"h 'o''clock'"`).
19406
19684
  *
19407
19685
  * @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or
19408
- * number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.SSSZ and it's
19686
+ * number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.SSSZ and its
19409
19687
  * shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is
19410
19688
  * specified in the string input, the time is considered to be in the local timezone.
19411
19689
  * @param {string=} format Formatting rules (see Description). If not specified,
@@ -19696,12 +19974,12 @@ function limitToFilter(){
19696
19974
  (<a href ng-click="predicate = '-name'; reverse=false">^</a>)</th>
19697
19975
  <th><a href="" ng-click="predicate = 'phone'; reverse=!reverse">Phone Number</a></th>
19698
19976
  <th><a href="" ng-click="predicate = 'age'; reverse=!reverse">Age</a></th>
19699
- <tr>
19977
+ </tr>
19700
19978
  <tr ng-repeat="friend in friends | orderBy:predicate:reverse">
19701
19979
  <td>{{friend.name}}</td>
19702
19980
  <td>{{friend.phone}}</td>
19703
19981
  <td>{{friend.age}}</td>
19704
- <tr>
19982
+ </tr>
19705
19983
  </table>
19706
19984
  </div>
19707
19985
  </doc:source>
@@ -19769,8 +20047,10 @@ function orderByFilter($parse){
19769
20047
  var t1 = typeof v1;
19770
20048
  var t2 = typeof v2;
19771
20049
  if (t1 == t2) {
19772
- if (t1 == "string") v1 = v1.toLowerCase();
19773
- if (t1 == "string") v2 = v2.toLowerCase();
20050
+ if (t1 == "string") {
20051
+ v1 = v1.toLowerCase();
20052
+ v2 = v2.toLowerCase();
20053
+ }
19774
20054
  if (v1 === v2) return 0;
19775
20055
  return v1 < v2 ? -1 : 1;
19776
20056
  } else {
@@ -20170,7 +20450,7 @@ var nullFormCtrl = {
20170
20450
  * @property {Object} $error Is an object hash, containing references to all invalid controls or
20171
20451
  * forms, where:
20172
20452
  *
20173
- * - keys are validation tokens (error names) such as `required`, `url` or `email`),
20453
+ * - keys are validation tokens (error names) — such as `required`, `url` or `email`),
20174
20454
  * - values are arrays of controls or forms that are invalid with given error.
20175
20455
  *
20176
20456
  * @description
@@ -20190,7 +20470,7 @@ function FormController(element, attrs) {
20190
20470
  errors = form.$error = {};
20191
20471
 
20192
20472
  // init state
20193
- form.$name = attrs.name;
20473
+ form.$name = attrs.name || attrs.ngForm;
20194
20474
  form.$dirty = false;
20195
20475
  form.$pristine = true;
20196
20476
  form.$valid = true;
@@ -20210,12 +20490,32 @@ function FormController(element, attrs) {
20210
20490
  addClass((isValid ? VALID_CLASS : INVALID_CLASS) + validationErrorKey);
20211
20491
  }
20212
20492
 
20493
+ /**
20494
+ * @ngdoc function
20495
+ * @name ng.directive:form.FormController#$addControl
20496
+ * @methodOf ng.directive:form.FormController
20497
+ *
20498
+ * @description
20499
+ * Register a control with the form.
20500
+ *
20501
+ * Input elements using ngModelController do this automatically when they are linked.
20502
+ */
20213
20503
  form.$addControl = function(control) {
20214
20504
  if (control.$name && !form.hasOwnProperty(control.$name)) {
20215
20505
  form[control.$name] = control;
20216
20506
  }
20217
20507
  };
20218
20508
 
20509
+ /**
20510
+ * @ngdoc function
20511
+ * @name ng.directive:form.FormController#$removeControl
20512
+ * @methodOf ng.directive:form.FormController
20513
+ *
20514
+ * @description
20515
+ * Deregister a control from the form.
20516
+ *
20517
+ * Input elements using ngModelController do this automatically when they are destroyed.
20518
+ */
20219
20519
  form.$removeControl = function(control) {
20220
20520
  if (control.$name && form[control.$name] === control) {
20221
20521
  delete form[control.$name];
@@ -20225,6 +20525,16 @@ function FormController(element, attrs) {
20225
20525
  });
20226
20526
  };
20227
20527
 
20528
+ /**
20529
+ * @ngdoc function
20530
+ * @name ng.directive:form.FormController#$setValidity
20531
+ * @methodOf ng.directive:form.FormController
20532
+ *
20533
+ * @description
20534
+ * Sets the validity of a form control.
20535
+ *
20536
+ * This method will also propagate to parent forms.
20537
+ */
20228
20538
  form.$setValidity = function(validationToken, isValid, control) {
20229
20539
  var queue = errors[validationToken];
20230
20540
 
@@ -20263,6 +20573,17 @@ function FormController(element, attrs) {
20263
20573
  }
20264
20574
  };
20265
20575
 
20576
+ /**
20577
+ * @ngdoc function
20578
+ * @name ng.directive:form.FormController#$setDirty
20579
+ * @methodOf ng.directive:form.FormController
20580
+ *
20581
+ * @description
20582
+ * Sets the form to a dirty state.
20583
+ *
20584
+ * This method can be called to add the 'ng-dirty' class and set the form to a dirty
20585
+ * state (ng-dirty class). This method will also propagate to parent forms.
20586
+ */
20266
20587
  form.$setDirty = function() {
20267
20588
  element.removeClass(PRISTINE_CLASS).addClass(DIRTY_CLASS);
20268
20589
  form.$dirty = true;
@@ -20439,7 +20760,7 @@ var formDirective = formDirectiveFactory();
20439
20760
  var ngFormDirective = formDirectiveFactory(true);
20440
20761
 
20441
20762
  var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;
20442
- var EMAIL_REGEXP = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/;
20763
+ var EMAIL_REGEXP = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}$/;
20443
20764
  var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/;
20444
20765
 
20445
20766
  var inputType = {
@@ -20523,8 +20844,8 @@ var inputType = {
20523
20844
  *
20524
20845
  * @param {string} ngModel Assignable angular expression to data-bind to.
20525
20846
  * @param {string=} name Property name of the form under which the control is published.
20526
- * @param {string=} min Sets the `min` validation error key if the value entered is less then `min`.
20527
- * @param {string=} max Sets the `max` validation error key if the value entered is greater then `min`.
20847
+ * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
20848
+ * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
20528
20849
  * @param {string=} required Sets `required` validation error key if the value is not entered.
20529
20850
  * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
20530
20851
  * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
@@ -20550,9 +20871,9 @@ var inputType = {
20550
20871
  <form name="myForm" ng-controller="Ctrl">
20551
20872
  Number: <input type="number" name="input" ng-model="value"
20552
20873
  min="0" max="99" required>
20553
- <span class="error" ng-show="myForm.list.$error.required">
20874
+ <span class="error" ng-show="myForm.input.$error.required">
20554
20875
  Required!</span>
20555
- <span class="error" ng-show="myForm.list.$error.number">
20876
+ <span class="error" ng-show="myForm.input.$error.number">
20556
20877
  Not valid number!</span>
20557
20878
  <tt>value = {{value}}</tt><br/>
20558
20879
  <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
@@ -20673,6 +20994,8 @@ var inputType = {
20673
20994
  * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the
20674
20995
  * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
20675
20996
  * patterns defined as scope expressions.
20997
+ * @param {string=} ngChange Angular expression to be executed when input changes due to user
20998
+ * interaction with the input element.
20676
20999
  *
20677
21000
  * @example
20678
21001
  <doc:example>
@@ -20836,6 +21159,15 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
20836
21159
  } else {
20837
21160
  var timeout;
20838
21161
 
21162
+ var deferListener = function() {
21163
+ if (!timeout) {
21164
+ timeout = $browser.defer(function() {
21165
+ listener();
21166
+ timeout = null;
21167
+ });
21168
+ }
21169
+ };
21170
+
20839
21171
  element.bind('keydown', function(event) {
20840
21172
  var key = event.keyCode;
20841
21173
 
@@ -20843,16 +21175,16 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
20843
21175
  // command modifiers arrows
20844
21176
  if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return;
20845
21177
 
20846
- if (!timeout) {
20847
- timeout = $browser.defer(function() {
20848
- listener();
20849
- timeout = null;
20850
- });
20851
- }
21178
+ deferListener();
20852
21179
  });
20853
21180
 
20854
21181
  // if user paste into input using mouse, we need "change" event to catch it
20855
21182
  element.bind('change', listener);
21183
+
21184
+ // if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it
21185
+ if ($sniffer.hasEvent('paste')) {
21186
+ element.bind('paste cut', deferListener);
21187
+ }
20856
21188
  }
20857
21189
 
20858
21190
 
@@ -21151,7 +21483,7 @@ function checkboxInputType(scope, element, attr, ctrl) {
21151
21483
  <tt>myForm.userName.$valid = {{myForm.userName.$valid}}</tt><br>
21152
21484
  <tt>myForm.userName.$error = {{myForm.userName.$error}}</tt><br>
21153
21485
  <tt>myForm.lastName.$valid = {{myForm.lastName.$valid}}</tt><br>
21154
- <tt>myForm.userName.$error = {{myForm.lastName.$error}}</tt><br>
21486
+ <tt>myForm.lastName.$error = {{myForm.lastName.$error}}</tt><br>
21155
21487
  <tt>myForm.$valid = {{myForm.$valid}}</tt><br>
21156
21488
  <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br>
21157
21489
  <tt>myForm.$error.minlength = {{!!myForm.$error.minlength}}</tt><br>
@@ -21222,12 +21554,25 @@ var VALID_CLASS = 'ng-valid',
21222
21554
  *
21223
21555
  * @property {string} $viewValue Actual string value in the view.
21224
21556
  * @property {*} $modelValue The value in the model, that the control is bound to.
21225
- * @property {Array.<Function>} $parsers Whenever the control reads value from the DOM, it executes
21226
- * all of these functions to sanitize / convert the value as well as validate.
21227
- *
21228
- * @property {Array.<Function>} $formatters Whenever the model value changes, it executes all of
21229
- * these functions to convert the value as well as validate.
21230
- *
21557
+ * @property {Array.<Function>} $parsers Array of functions to execute, as a pipeline, whenever
21558
+ the control reads value from the DOM. Each function is called, in turn, passing the value
21559
+ through to the next. Used to sanitize / convert the value as well as validation.
21560
+
21561
+ For validation, the parsers should update the validity state using
21562
+ {@link ng.directive:ngModel.NgModelController#$setValidity $setValidity()},
21563
+ and return `undefined` for invalid values.
21564
+ *
21565
+ * @property {Array.<Function>} $formatters Array of functions to execute, as a pipeline, whenever
21566
+ * the model value changes. Each function is called, in turn, passing the value through to the
21567
+ * next. Used to format / convert values for display in the control and validation.
21568
+ * <pre>
21569
+ * function formatter(value) {
21570
+ * if (value) {
21571
+ * return value.toUpperCase();
21572
+ * }
21573
+ * }
21574
+ * ngModel.$formatters.push(formatter);
21575
+ * </pre>
21231
21576
  * @property {Object} $error An bject hash with all errors as keys.
21232
21577
  *
21233
21578
  * @property {boolean} $pristine True if user has not interacted with the control yet.
@@ -21242,6 +21587,10 @@ var VALID_CLASS = 'ng-valid',
21242
21587
  * specifically does not contain any logic which deals with DOM rendering or listening to
21243
21588
  * DOM events. The `NgModelController` is meant to be extended by other directives where, the
21244
21589
  * directive provides DOM manipulation and the `NgModelController` provides the data-binding.
21590
+ * Note that you cannot use `NgModelController` in a directive with an isolated scope,
21591
+ * as, in that case, the `ng-model` value gets put into the isolated scope and does not get
21592
+ * propogated to the parent scope.
21593
+ *
21245
21594
  *
21246
21595
  * This example shows how to use `NgModelController` with a custom control to achieve
21247
21596
  * data-binding. Notice how different directives (`contenteditable`, `ng-model`, and `required`)
@@ -21282,7 +21631,13 @@ var VALID_CLASS = 'ng-valid',
21282
21631
 
21283
21632
  // Write data to the model
21284
21633
  function read() {
21285
- ngModel.$setViewValue(element.html());
21634
+ var html = element.html();
21635
+ // When we clear the content editable the browser leaves a <br> behind
21636
+ // If strip-br attribute is provided then we strip this out
21637
+ if( attrs.stripBr && html == '<br>' ) {
21638
+ html = '';
21639
+ }
21640
+ ngModel.$setViewValue(html);
21286
21641
  }
21287
21642
  }
21288
21643
  };
@@ -21292,6 +21647,7 @@ var VALID_CLASS = 'ng-valid',
21292
21647
  <form name="myForm">
21293
21648
  <div contenteditable
21294
21649
  name="myWidget" ng-model="userContent"
21650
+ strip-br="true"
21295
21651
  required>Change me!</div>
21296
21652
  <span ng-show="myForm.myWidget.$error.required">Required!</span>
21297
21653
  <hr>
@@ -21414,8 +21770,8 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
21414
21770
  * For example {@link ng.directive:input input} or
21415
21771
  * {@link ng.directive:select select} directives call it.
21416
21772
  *
21417
- * It internally calls all `formatters` and if resulted value is valid, updates the model and
21418
- * calls all registered change listeners.
21773
+ * It internally calls all `$parsers` (including validators) and updates the `$modelValue` and the actual model path.
21774
+ * Lastly it calls all registered change listeners.
21419
21775
  *
21420
21776
  * @param {string} value Value from the view.
21421
21777
  */
@@ -21480,7 +21836,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
21480
21836
  * @element input
21481
21837
  *
21482
21838
  * @description
21483
- * Is directive that tells Angular to do two-way data binding. It works together with `input`,
21839
+ * Is a directive that tells Angular to do two-way data binding. It works together with `input`,
21484
21840
  * `select`, `textarea`. You can easily write your own directives to use `ngModel` as well.
21485
21841
  *
21486
21842
  * `ngModel` is responsible for:
@@ -21492,6 +21848,10 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
21492
21848
  * - setting related css class onto the element (`ng-valid`, `ng-invalid`, `ng-dirty`, `ng-pristine`),
21493
21849
  * - register the control with parent {@link ng.directive:form form}.
21494
21850
  *
21851
+ * Note: `ngModel` will try to bind to the property given by evaluating the expression on the
21852
+ * current scope. If the property doesn't already exist on this scope, it will be created
21853
+ * implicitly and added to the scope.
21854
+ *
21495
21855
  * For basic examples, how to use `ngModel`, see:
21496
21856
  *
21497
21857
  * - {@link ng.directive:input input}
@@ -21632,8 +21992,9 @@ var requiredDirective = function() {
21632
21992
  </script>
21633
21993
  <form name="myForm" ng-controller="Ctrl">
21634
21994
  List: <input name="namesInput" ng-model="names" ng-list required>
21635
- <span class="error" ng-show="myForm.list.$error.required">
21995
+ <span class="error" ng-show="myForm.namesInput.$error.required">
21636
21996
  Required!</span>
21997
+ <br>
21637
21998
  <tt>names = {{names}}</tt><br/>
21638
21999
  <tt>myForm.namesInput.$valid = {{myForm.namesInput.$valid}}</tt><br/>
21639
22000
  <tt>myForm.namesInput.$error = {{myForm.namesInput.$error}}</tt><br/>
@@ -21645,12 +22006,14 @@ var requiredDirective = function() {
21645
22006
  it('should initialize to model', function() {
21646
22007
  expect(binding('names')).toEqual('["igor","misko","vojta"]');
21647
22008
  expect(binding('myForm.namesInput.$valid')).toEqual('true');
22009
+ expect(element('span.error').css('display')).toBe('none');
21648
22010
  });
21649
22011
 
21650
22012
  it('should be invalid if empty', function() {
21651
22013
  input('names').enter('');
21652
22014
  expect(binding('names')).toEqual('[]');
21653
22015
  expect(binding('myForm.namesInput.$valid')).toEqual('false');
22016
+ expect(element('span.error').css('display')).not().toBe('none');
21654
22017
  });
21655
22018
  </doc:scenario>
21656
22019
  </doc:example>
@@ -21700,7 +22063,7 @@ var ngValueDirective = function() {
21700
22063
  } else {
21701
22064
  return function(scope, elm, attr) {
21702
22065
  scope.$watch(attr.ngValue, function valueWatchAction(value) {
21703
- attr.$set('value', value, false);
22066
+ attr.$set('value', value);
21704
22067
  });
21705
22068
  };
21706
22069
  }
@@ -21720,10 +22083,9 @@ var ngValueDirective = function() {
21720
22083
  * Typically, you don't use `ngBind` directly, but instead you use the double curly markup like
21721
22084
  * `{{ expression }}` which is similar but less verbose.
21722
22085
  *
21723
- * Once scenario in which the use of `ngBind` is prefered over `{{ expression }}` binding is when
21724
- * it's desirable to put bindings into template that is momentarily displayed by the browser in its
21725
- * raw state before Angular compiles it. Since `ngBind` is an element attribute, it makes the
21726
- * bindings invisible to the user while the page is loading.
22086
+ * It is preferrable to use `ngBind` instead of `{{ expression }}` when a template is momentarily
22087
+ * displayed by the browser in its raw state before Angular compiles it. Since `ngBind` is an
22088
+ * element attribute, it makes the bindings invisible to the user while the page is loading.
21727
22089
  *
21728
22090
  * An alternative solution to this problem would be using the
21729
22091
  * {@link ng.directive:ngCloak ngCloak} directive.
@@ -21769,10 +22131,11 @@ var ngBindDirective = ngDirective(function(scope, element, attr) {
21769
22131
  *
21770
22132
  * @description
21771
22133
  * The `ngBindTemplate` directive specifies that the element
21772
- * text should be replaced with the template in ngBindTemplate.
21773
- * Unlike ngBind the ngBindTemplate can contain multiple `{{` `}}`
21774
- * expressions. (This is required since some HTML elements
21775
- * can not have SPAN elements such as TITLE, or OPTION to name a few.)
22134
+ * text content should be replaced with the interpolation of the template
22135
+ * in the `ngBindTemplate` attribute.
22136
+ * Unlike `ngBind`, the `ngBindTemplate` can contain multiple `{{` `}}`
22137
+ * expressions. This directive is needed since some HTML elements
22138
+ * (such as TITLE and OPTION) cannot contain SPAN elements.
21776
22139
  *
21777
22140
  * @element ANY
21778
22141
  * @param {string} ngBindTemplate template of form
@@ -21861,9 +22224,9 @@ function classDirective(name, selector) {
21861
22224
 
21862
22225
  if (name !== 'ngClass') {
21863
22226
  scope.$watch('$index', function($index, old$index) {
21864
- var mod = $index % 2;
21865
- if (mod !== old$index % 2) {
21866
- if (mod == selector) {
22227
+ var mod = $index & 1;
22228
+ if (mod !== old$index & 1) {
22229
+ if (mod === selector) {
21867
22230
  addClass(scope.$eval(attr[name]));
21868
22231
  } else {
21869
22232
  removeClass(scope.$eval(attr[name]));
@@ -21875,12 +22238,12 @@ function classDirective(name, selector) {
21875
22238
 
21876
22239
  function ngClassWatchAction(newVal) {
21877
22240
  if (selector === true || scope.$index % 2 === selector) {
21878
- if (oldVal && (newVal !== oldVal)) {
22241
+ if (oldVal && !equals(newVal,oldVal)) {
21879
22242
  removeClass(oldVal);
21880
22243
  }
21881
22244
  addClass(newVal);
21882
22245
  }
21883
- oldVal = newVal;
22246
+ oldVal = copy(newVal);
21884
22247
  }
21885
22248
 
21886
22249
 
@@ -21908,8 +22271,8 @@ function classDirective(name, selector) {
21908
22271
  * @name ng.directive:ngClass
21909
22272
  *
21910
22273
  * @description
21911
- * The `ngClass` allows you to set CSS class on HTML element dynamically by databinding an
21912
- * expression that represents all classes to be added.
22274
+ * The `ngClass` allows you to set CSS classes on HTML an element, dynamically, by databinding
22275
+ * an expression that represents all classes to be added.
21913
22276
  *
21914
22277
  * The directive won't add duplicate classes if a particular class was already set.
21915
22278
  *
@@ -21919,7 +22282,9 @@ function classDirective(name, selector) {
21919
22282
  * @element ANY
21920
22283
  * @param {expression} ngClass {@link guide/expression Expression} to eval. The result
21921
22284
  * of the evaluation can be a string representing space delimited class
21922
- * names, an array, or a map of class names to boolean values.
22285
+ * names, an array, or a map of class names to boolean values. In the case of a map, the
22286
+ * names of the properties whose values are truthy will be added as css classes to the
22287
+ * element.
21923
22288
  *
21924
22289
  * @example
21925
22290
  <example>
@@ -22006,7 +22371,7 @@ var ngClassOddDirective = classDirective('Odd', 0);
22006
22371
  * @name ng.directive:ngClassEven
22007
22372
  *
22008
22373
  * @description
22009
- * The `ngClassOdd` and `ngClassEven` works exactly as
22374
+ * The `ngClassOdd` and `ngClassEven` directives work exactly as
22010
22375
  * {@link ng.directive:ngClass ngClass}, except it works in
22011
22376
  * conjunction with `ngRepeat` and takes affect only on odd (even) rows.
22012
22377
  *
@@ -22064,8 +22429,8 @@ var ngClassEvenDirective = classDirective('Even', 1);
22064
22429
  * `angular.min.js` files. Following is the css rule:
22065
22430
  *
22066
22431
  * <pre>
22067
- * [ng\:cloak], [ng-cloak], .ng-cloak {
22068
- * display: none;
22432
+ * [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
22433
+ * display: none !important;
22069
22434
  * }
22070
22435
  * </pre>
22071
22436
  *
@@ -22118,13 +22483,12 @@ var ngCloakDirective = ngDirective({
22118
22483
  *
22119
22484
  * MVC components in angular:
22120
22485
  *
22121
- * * Model The Model is data in scope properties; scopes are attached to the DOM.
22122
- * * View The template (HTML with data bindings) is rendered into the View.
22123
- * * Controller The `ngController` directive specifies a Controller class; the class has
22486
+ * * Model — The Model is data in scope properties; scopes are attached to the DOM.
22487
+ * * View — The template (HTML with data bindings) is rendered into the View.
22488
+ * * Controller — The `ngController` directive specifies a Controller class; the class has
22124
22489
  * methods that typically express the business logic behind the application.
22125
22490
  *
22126
- * Note that an alternative way to define controllers is via the `{@link ng.$route}`
22127
- * service.
22491
+ * Note that an alternative way to define controllers is via the {@link ng.$route $route} service.
22128
22492
  *
22129
22493
  * @element ANY
22130
22494
  * @scope
@@ -22134,11 +22498,9 @@ var ngCloakDirective = ngDirective({
22134
22498
  *
22135
22499
  * @example
22136
22500
  * Here is a simple form for editing user contact information. Adding, removing, clearing, and
22137
- * greeting are methods declared on the controller (see source tab). These methods can
22138
- * easily be called from the angular markup. Notice that the scope becomes the `this` for the
22139
- * controller's instance. This allows for easy access to the view data from the controller. Also
22140
- * notice that any changes to the data are automatically reflected in the View without the need
22141
- * for a manual update.
22501
+ * greeting are methods declared on the $scope by the controller (see source tab). These methods can
22502
+ * easily be called from the angular markup. Notice that any changes to the data are automatically
22503
+ * reflected in the View without the need for a manual update.
22142
22504
  <doc:example>
22143
22505
  <doc:source>
22144
22506
  <script>
@@ -22215,16 +22577,32 @@ var ngControllerDirective = [function() {
22215
22577
  * @name ng.directive:ngCsp
22216
22578
  * @priority 1000
22217
22579
  *
22580
+ * @element html
22218
22581
  * @description
22219
22582
  * Enables [CSP (Content Security Policy)](https://developer.mozilla.org/en/Security/CSP) support.
22220
- * This directive should be used on the root element of the application (typically the `<html>`
22221
- * element or other element with the {@link ng.directive:ngApp ngApp}
22222
- * directive).
22223
- *
22224
- * If enabled the performance of template expression evaluator will suffer slightly, so don't enable
22225
- * this mode unless you need it.
22226
- *
22227
- * @element html
22583
+ *
22584
+ * This is necessary when developing things like Google Chrome Extensions.
22585
+ *
22586
+ * CSP forbids apps to use `eval` or `Function(string)` generated functions (among other things).
22587
+ * For us to be compatible, we just need to implement the "getterFn" in $parse without violating
22588
+ * any of these restrictions.
22589
+ *
22590
+ * AngularJS uses `Function(string)` generated functions as a speed optimization. By applying `ngCsp`
22591
+ * it is be possible to opt into the CSP compatible mode. When this mode is on AngularJS will
22592
+ * evaluate all expressions up to 30% slower than in non-CSP mode, but no security violations will
22593
+ * be raised.
22594
+ *
22595
+ * In order to use this feature put `ngCsp` directive on the root element of the application.
22596
+ *
22597
+ * @example
22598
+ * This example shows how to apply the `ngCsp` directive to the `html` tag.
22599
+ <pre>
22600
+ <!doctype html>
22601
+ <html ng-app ng-csp>
22602
+ ...
22603
+ ...
22604
+ </html>
22605
+ </pre>
22228
22606
  */
22229
22607
 
22230
22608
  var ngCspDirective = ['$sniffer', function($sniffer) {
@@ -22273,7 +22651,7 @@ var ngCspDirective = ['$sniffer', function($sniffer) {
22273
22651
  */
22274
22652
  var ngEventDirectives = {};
22275
22653
  forEach(
22276
- 'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave'.split(' '),
22654
+ 'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave submit'.split(' '),
22277
22655
  function(name) {
22278
22656
  var directiveName = directiveNormalize('ng-' + name);
22279
22657
  ngEventDirectives[directiveName] = ['$parse', function($parse) {
@@ -22400,6 +22778,54 @@ forEach(
22400
22778
  */
22401
22779
 
22402
22780
 
22781
+ /**
22782
+ * @ngdoc directive
22783
+ * @name ng.directive:ngKeydown
22784
+ *
22785
+ * @description
22786
+ * Specify custom behavior on keydown event.
22787
+ *
22788
+ * @element ANY
22789
+ * @param {expression} ngKeydown {@link guide/expression Expression} to evaluate upon
22790
+ * keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
22791
+ *
22792
+ * @example
22793
+ * See {@link ng.directive:ngClick ngClick}
22794
+ */
22795
+
22796
+
22797
+ /**
22798
+ * @ngdoc directive
22799
+ * @name ng.directive:ngKeyup
22800
+ *
22801
+ * @description
22802
+ * Specify custom behavior on keyup event.
22803
+ *
22804
+ * @element ANY
22805
+ * @param {expression} ngKeyup {@link guide/expression Expression} to evaluate upon
22806
+ * keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
22807
+ *
22808
+ * @example
22809
+ * See {@link ng.directive:ngClick ngClick}
22810
+ */
22811
+
22812
+
22813
+ /**
22814
+ * @ngdoc directive
22815
+ * @name ng.directive:ngKeypress
22816
+ *
22817
+ * @description
22818
+ * Specify custom behavior on keypress event.
22819
+ *
22820
+ * @element ANY
22821
+ * @param {expression} ngKeypress {@link guide/expression Expression} to evaluate upon
22822
+ * keypress. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
22823
+ *
22824
+ * @example
22825
+ * See {@link ng.directive:ngClick ngClick}
22826
+ */
22827
+
22828
+
22403
22829
  /**
22404
22830
  * @ngdoc directive
22405
22831
  * @name ng.directive:ngSubmit
@@ -22408,10 +22834,11 @@ forEach(
22408
22834
  * Enables binding angular expressions to onsubmit events.
22409
22835
  *
22410
22836
  * Additionally it prevents the default action (which for form means sending the request to the
22411
- * server and reloading the current page).
22837
+ * server and reloading the current page) **but only if the form does not contain an `action`
22838
+ * attribute**.
22412
22839
  *
22413
22840
  * @element form
22414
- * @param {expression} ngSubmit {@link guide/expression Expression} to eval.
22841
+ * @param {expression} ngSubmit {@link guide/expression Expression} to eval. (Event object is available as `$event`)
22415
22842
  *
22416
22843
  * @example
22417
22844
  <doc:example>
@@ -22451,11 +22878,6 @@ forEach(
22451
22878
  </doc:scenario>
22452
22879
  </doc:example>
22453
22880
  */
22454
- var ngSubmitDirective = ngDirective(function(scope, element, attrs) {
22455
- element.bind('submit', function() {
22456
- scope.$apply(attrs.ngSubmit);
22457
- });
22458
- });
22459
22881
 
22460
22882
  /**
22461
22883
  * @ngdoc directive
@@ -22663,7 +23085,7 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
22663
23085
  * @description
22664
23086
  * # Overview
22665
23087
  * `ngPluralize` is a directive that displays messages according to en-US localization rules.
22666
- * These rules are bundled with angular.js and the rules can be overridden
23088
+ * These rules are bundled with angular.js, but can be overridden
22667
23089
  * (see {@link guide/i18n Angular i18n} dev guide). You configure ngPluralize directive
22668
23090
  * by specifying the mappings between
22669
23091
  * {@link http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
@@ -22676,8 +23098,8 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
22676
23098
  *
22677
23099
  * While a pural category may match many numbers (for example, in en-US locale, "other" can match
22678
23100
  * any number that is not 1), an explicit number rule can only match one number. For example, the
22679
- * explicit number rule for "3" matches the number 3. You will see the use of plural categories
22680
- * and explicit number rules throughout later parts of this documentation.
23101
+ * explicit number rule for "3" matches the number 3. There are examples of plural categories
23102
+ * and explicit number rules throughout the rest of this documentation.
22681
23103
  *
22682
23104
  * # Configuring ngPluralize
22683
23105
  * You configure ngPluralize by providing 2 attributes: `count` and `when`.
@@ -22687,8 +23109,7 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
22687
23109
  * Angular expression}; these are evaluated on the current scope for its bound value.
22688
23110
  *
22689
23111
  * The `when` attribute specifies the mappings between plural categories and the actual
22690
- * string to be displayed. The value of the attribute should be a JSON object so that Angular
22691
- * can interpret it correctly.
23112
+ * string to be displayed. The value of the attribute should be a JSON object.
22692
23113
  *
22693
23114
  * The following example shows how to configure ngPluralize:
22694
23115
  *
@@ -22849,7 +23270,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
22849
23270
  if (!isNaN(value)) {
22850
23271
  //if explicit number rule such as 1, 2, 3... is defined, just use it. Otherwise,
22851
23272
  //check it against pluralization rules in $locale service
22852
- if (!whens[value]) value = $locale.pluralCat(value - offset);
23273
+ if (!(value in whens)) value = $locale.pluralCat(value - offset);
22853
23274
  return whensExpFns[value](scope, element, true);
22854
23275
  } else {
22855
23276
  return '';
@@ -22872,10 +23293,10 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
22872
23293
  *
22873
23294
  * Special properties are exposed on the local scope of each template instance, including:
22874
23295
  *
22875
- * * `$index` `{number}` iterator offset of the repeated element (0..length-1)
22876
- * * `$first` `{boolean}` true if the repeated element is first in the iterator.
22877
- * * `$middle` `{boolean}` true if the repeated element is between the first and last in the iterator.
22878
- * * `$last` `{boolean}` true if the repeated element is last in the iterator.
23296
+ * * `$index` – `{number}` – iterator offset of the repeated element (0..length-1)
23297
+ * * `$first` – `{boolean}` – true if the repeated element is first in the iterator.
23298
+ * * `$middle` – `{boolean}` – true if the repeated element is between the first and last in the iterator.
23299
+ * * `$last` – `{boolean}` – true if the repeated element is last in the iterator.
22879
23300
  *
22880
23301
  *
22881
23302
  * @element ANY
@@ -22884,12 +23305,12 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
22884
23305
  * @param {repeat_expression} ngRepeat The expression indicating how to enumerate a collection. Two
22885
23306
  * formats are currently supported:
22886
23307
  *
22887
- * * `variable in expression` where variable is the user defined loop variable and `expression`
23308
+ * * `variable in expression` – where variable is the user defined loop variable and `expression`
22888
23309
  * is a scope expression giving the collection to enumerate.
22889
23310
  *
22890
23311
  * For example: `track in cd.tracks`.
22891
23312
  *
22892
- * * `(key, value) in expression` where `key` and `value` can be any user defined identifiers,
23313
+ * * `(key, value) in expression` – where `key` and `value` can be any user defined identifiers,
22893
23314
  * and `expression` is the scope expression giving the collection to enumerate.
22894
23315
  *
22895
23316
  * For example: `(name, age) in {'adam':10, 'amalie':12}`.
@@ -22957,7 +23378,7 @@ var ngRepeatDirective = ngDirective({
22957
23378
  // Same as lastOrder but it has the current state. It will become the
22958
23379
  // lastOrder on the next iteration.
22959
23380
  nextOrder = new HashQueueMap(),
22960
- arrayLength,
23381
+ arrayBound,
22961
23382
  childScope,
22962
23383
  key, value, // key/value of iteration
22963
23384
  array,
@@ -22978,7 +23399,7 @@ var ngRepeatDirective = ngDirective({
22978
23399
  array = collection || [];
22979
23400
  }
22980
23401
 
22981
- arrayLength = array.length;
23402
+ arrayBound = array.length-1;
22982
23403
 
22983
23404
  // we are not using forEach for perf reasons (trying to avoid #call)
22984
23405
  for (index = 0, length = array.length; index < length; index++) {
@@ -23015,7 +23436,7 @@ var ngRepeatDirective = ngDirective({
23015
23436
  childScope.$index = index;
23016
23437
 
23017
23438
  childScope.$first = (index === 0);
23018
- childScope.$last = (index === (arrayLength - 1));
23439
+ childScope.$last = (index === arrayBound);
23019
23440
  childScope.$middle = !(childScope.$first || childScope.$last);
23020
23441
 
23021
23442
  if (!last) {
@@ -23182,11 +23603,13 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
23182
23603
  * @description
23183
23604
  * Conditionally change the DOM structure.
23184
23605
  *
23185
- * @usageContent
23186
- * <ANY ng-switch-when="matchValue1">...</ANY>
23606
+ * @usage
23607
+ * <ANY ng-switch="expression">
23608
+ * <ANY ng-switch-when="matchValue1">...</ANY>
23187
23609
  * <ANY ng-switch-when="matchValue2">...</ANY>
23188
23610
  * ...
23189
23611
  * <ANY ng-switch-default>...</ANY>
23612
+ * </ANY>
23190
23613
  *
23191
23614
  * @scope
23192
23615
  * @param {*} ngSwitch|on expression to match against <tt>ng-switch-when</tt>.
@@ -23310,8 +23733,7 @@ var ngSwitchDefaultDirective = ngDirective({
23310
23733
  return {
23311
23734
  restrict: 'E',
23312
23735
  transclude: true,
23313
- scope: 'isolate',
23314
- locals: { title:'bind' },
23736
+ scope: { title:'@' },
23315
23737
  template: '<div style="border: 1px solid black;">' +
23316
23738
  '<div style="background-color: gray">{{title}}</div>' +
23317
23739
  '<div ng-transclude></div>' +
@@ -23566,8 +23988,8 @@ var scriptDirective = ['$templateCache', function($templateCache) {
23566
23988
  * Optionally `ngOptions` attribute can be used to dynamically generate a list of `<option>`
23567
23989
  * elements for a `<select>` element using an array or an object obtained by evaluating the
23568
23990
  * `ngOptions` expression.
23569
- *˝˝
23570
- * When an item in the select menu is select, the value of array element or object property
23991
+ *
23992
+ * When an item in the `<select>` menu is selected, the value of array element or object property
23571
23993
  * represented by the selected option will be bound to the model identified by the `ngModel`
23572
23994
  * directive of the parent select element.
23573
23995
  *
@@ -23580,7 +24002,8 @@ var scriptDirective = ['$templateCache', function($templateCache) {
23580
24002
  * `select` model to be bound to a non-string value. This is because an option element can currently
23581
24003
  * be bound to string values only.
23582
24004
  *
23583
- * @param {string} name assignable expression to data-bind to.
24005
+ * @param {string} ngModel Assignable angular expression to data-bind to.
24006
+ * @param {string=} name Property name of the form under which the control is published.
23584
24007
  * @param {string=} required The control is considered valid only if value is entered.
23585
24008
  * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
23586
24009
  * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
@@ -23675,7 +24098,7 @@ var scriptDirective = ['$templateCache', function($templateCache) {
23675
24098
 
23676
24099
  var ngOptionsDirective = valueFn({ terminal: true });
23677
24100
  var selectDirective = ['$compile', '$parse', function($compile, $parse) {
23678
- //00001111100000000000222200000000000000000000003333000000000000044444444444444444000000000555555555555555550000000666666666666666660000000000000007777
24101
+ //0000111110000000000022220000000000000000000000333300000000000000444444444444444440000000005555555555555555500000006666666666666666600000000000000077770
23679
24102
  var NG_OPTIONS_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w\d]*)|(?:\(\s*([\$\w][\$\w\d]*)\s*,\s*([\$\w][\$\w\d]*)\s*\)))\s+in\s+(.*)$/,
23680
24103
  nullModelCtrl = {$setViewValue: noop};
23681
24104
 
@@ -23947,10 +24370,6 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
23947
24370
 
23948
24371
  if (multiple) {
23949
24372
  selectedSet = new HashMap(modelValue);
23950
- } else if (modelValue === null || nullOption) {
23951
- // if we are not multiselect, and we are null then we have to add the nullOption
23952
- optionGroups[''].push({selected:modelValue === null, id:'', label:''});
23953
- selectedSet = true;
23954
24373
  }
23955
24374
 
23956
24375
  // We now build up the list of options we need (we merge later)
@@ -23975,9 +24394,14 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
23975
24394
  selected: selected // determine if we should be selected
23976
24395
  });
23977
24396
  }
23978
- if (!multiple && !selectedSet) {
23979
- // nothing was selected, we have to insert the undefined item
23980
- optionGroups[''].unshift({id:'?', label:'', selected:true});
24397
+ if (!multiple) {
24398
+ if (nullOption || modelValue === null) {
24399
+ // insert null option if we have a placeholder, or the model is null
24400
+ optionGroups[''].unshift({id:'', label:'', selected:!selectedSet});
24401
+ } else if (!selectedSet) {
24402
+ // option could not be found, we have to insert the undefined item
24403
+ optionGroups[''].unshift({id:'?', label:'', selected:true});
24404
+ }
23981
24405
  }
23982
24406
 
23983
24407
  // Now we need to update the list of DOM nodes to match the optionGroups we computed above
@@ -24021,7 +24445,8 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
24021
24445
  if (existingOption.id !== option.id) {
24022
24446
  lastElement.val(existingOption.id = option.id);
24023
24447
  }
24024
- if (existingOption.element.selected !== option.selected) {
24448
+ // lastElement.prop('selected') provided by jQuery has side-effects
24449
+ if (lastElement[0].selected !== option.selected) {
24025
24450
  lastElement.prop('selected', (existingOption.selected = option.selected));
24026
24451
  }
24027
24452
  } else {
@@ -26169,6 +26594,7 @@ angular.scenario.output('xml', function(context, runner, model) {
26169
26594
  angular.scenario.output('object', function(context, runner, model) {
26170
26595
  runner.$window.$result = model.value;
26171
26596
  });
26597
+
26172
26598
  bindJQuery();
26173
26599
  publishExternalAPI(angular);
26174
26600
 
@@ -26191,5 +26617,5 @@ if (config.autotest) {
26191
26617
  }
26192
26618
  })(window, document);
26193
26619
 
26194
- angular.element(document).find('head').append('<style type="text/css">@charset "UTF-8";\n\n[ng\\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],\n.ng-cloak, .x-ng-cloak {\n display: none;\n}\n\nng\\:form {\n display: block;\n}\n</style>');
26620
+ angular.element(document).find('head').append('<style type="text/css">@charset "UTF-8";\n\n[ng\\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],\n.ng-cloak, .x-ng-cloak {\n display: none !important;\n}\n\nng\\:form {\n display: block;\n}\n</style>');
26195
26621
  angular.element(document).find('head').append('<style type="text/css">@charset "UTF-8";\n/* CSS Document */\n\n/** Structure */\nbody {\n font-family: Arial, sans-serif;\n margin: 0;\n font-size: 14px;\n}\n\n#system-error {\n font-size: 1.5em;\n text-align: center;\n}\n\n#json, #xml {\n display: none;\n}\n\n#header {\n position: fixed;\n width: 100%;\n}\n\n#specs {\n padding-top: 50px;\n}\n\n#header .angular {\n font-family: Courier New, monospace;\n font-weight: bold;\n}\n\n#header h1 {\n font-weight: normal;\n float: left;\n font-size: 30px;\n line-height: 30px;\n margin: 0;\n padding: 10px 10px;\n height: 30px;\n}\n\n#application h2,\n#specs h2 {\n margin: 0;\n padding: 0.5em;\n font-size: 1.1em;\n}\n\n#status-legend {\n margin-top: 10px;\n margin-right: 10px;\n}\n\n#header,\n#application,\n.test-info,\n.test-actions li {\n overflow: hidden;\n}\n\n#application {\n margin: 10px;\n}\n\n#application iframe {\n width: 100%;\n height: 758px;\n}\n\n#application .popout {\n float: right;\n}\n\n#application iframe {\n border: none;\n}\n\n.tests li,\n.test-actions li,\n.test-it li,\n.test-it ol,\n.status-display {\n list-style-type: none;\n}\n\n.tests,\n.test-it ol,\n.status-display {\n margin: 0;\n padding: 0;\n}\n\n.test-info {\n margin-left: 1em;\n margin-top: 0.5em;\n border-radius: 8px 0 0 8px;\n -webkit-border-radius: 8px 0 0 8px;\n -moz-border-radius: 8px 0 0 8px;\n cursor: pointer;\n}\n\n.test-info:hover .test-name {\n text-decoration: underline;\n}\n\n.test-info .closed:before {\n content: \'\\25b8\\00A0\';\n}\n\n.test-info .open:before {\n content: \'\\25be\\00A0\';\n font-weight: bold;\n}\n\n.test-it ol {\n margin-left: 2.5em;\n}\n\n.status-display,\n.status-display li {\n float: right;\n}\n\n.status-display li {\n padding: 5px 10px;\n}\n\n.timer-result,\n.test-title {\n display: inline-block;\n margin: 0;\n padding: 4px;\n}\n\n.test-actions .test-title,\n.test-actions .test-result {\n display: table-cell;\n padding-left: 0.5em;\n padding-right: 0.5em;\n}\n\n.test-actions {\n display: table;\n}\n\n.test-actions li {\n display: table-row;\n}\n\n.timer-result {\n width: 4em;\n padding: 0 10px;\n text-align: right;\n font-family: monospace;\n}\n\n.test-it pre,\n.test-actions pre {\n clear: left;\n color: black;\n margin-left: 6em;\n}\n\n.test-describe {\n padding-bottom: 0.5em;\n}\n\n.test-describe .test-describe {\n margin: 5px 5px 10px 2em;\n}\n\n.test-actions .status-pending .test-title:before {\n content: \'\\00bb\\00A0\';\n}\n\n.scrollpane {\n max-height: 20em;\n overflow: auto;\n}\n\n/** Colors */\n\n#header {\n background-color: #F2C200;\n}\n\n#specs h2 {\n border-top: 2px solid #BABAD1;\n}\n\n#specs h2,\n#application h2 {\n background-color: #efefef;\n}\n\n#application {\n border: 1px solid #BABAD1;\n}\n\n.test-describe .test-describe {\n border-left: 1px solid #BABAD1;\n border-right: 1px solid #BABAD1;\n border-bottom: 1px solid #BABAD1;\n}\n\n.status-display {\n border: 1px solid #777;\n}\n\n.status-display .status-pending,\n.status-pending .test-info {\n background-color: #F9EEBC;\n}\n\n.status-display .status-success,\n.status-success .test-info {\n background-color: #B1D7A1;\n}\n\n.status-display .status-failure,\n.status-failure .test-info {\n background-color: #FF8286;\n}\n\n.status-display .status-error,\n.status-error .test-info {\n background-color: black;\n color: white;\n}\n\n.test-actions .status-success .test-title {\n color: #30B30A;\n}\n\n.test-actions .status-failure .test-title {\n color: #DF0000;\n}\n\n.test-actions .status-error .test-title {\n color: black;\n}\n\n.test-actions .timer-result {\n color: #888;\n}\n</style>');