deano 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f3d0d672df347a6987023a826cd2d1f477d16639
4
+ data.tar.gz: 587a342461ee8ae9a3c5c1765c6fa6e44a2fdb9a
5
+ SHA512:
6
+ metadata.gz: d2c8e7168301e27311ab189df19bfc505708e8403141df49774c77801b4a41e8f786f2b9ceaa0ee5cdd0af397c38c767bb535a9b86a7bf3983e11b44fb95f1d8
7
+ data.tar.gz: 40de27899b07eef11d234830ba9d3d8d84f01822b6cdd23804d6db8e474e5b775240cc2c7da983916c7f56a51117ac427a2fca6863995d459d11310f3311cab8
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- deano (1.2.0)
4
+ deano (1.2.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -89,3 +89,9 @@ $ deano help
89
89
  3. Commit your changes (`git commit -am 'Add some feature'`)
90
90
  4. Push to the branch (`git push origin my-new-feature`)
91
91
  5. Create new Pull Request
92
+
93
+ ## Contributors
94
+
95
+ * Mark Bates
96
+ * Luke Bergen
97
+ * Allen Wyma
@@ -1,3 +1,3 @@
1
1
  module Deano
2
- VERSION = "1.2.0"
2
+ VERSION = "1.2.1"
3
3
  end
@@ -1,12 +1,10 @@
1
- ruby '1.9.3'
2
-
3
1
  source 'https://rubygems.org'
4
2
 
5
3
  gem 'thin'
6
4
  gem 'sass'
7
5
  gem 'coffee-script'
8
6
  gem 'sinatra'
9
- gem "sinatra-twitter-bootstrap", github: "mifo/sinatra-twitter-bootstrap"
7
+ gem "sinatra-twitter-bootstrap"
10
8
  gem 'sprockets'
11
9
  gem 'shotgun'
12
10
  gem 'foreman', '0.60.0'
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.0.5
2
+ * @license AngularJS v1.0.7
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -34,12 +34,12 @@ var uppercase = function(string){return isString(string) ? string.toUpperCase()
34
34
 
35
35
  var manualLowercase = function(s) {
36
36
  return isString(s)
37
- ? s.replace(/[A-Z]/g, function(ch) {return fromCharCode(ch.charCodeAt(0) | 32);})
37
+ ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})
38
38
  : s;
39
39
  };
40
40
  var manualUppercase = function(s) {
41
41
  return isString(s)
42
- ? s.replace(/[a-z]/g, function(ch) {return fromCharCode(ch.charCodeAt(0) & ~32);})
42
+ ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})
43
43
  : s;
44
44
  };
45
45
 
@@ -52,8 +52,6 @@ if ('i' !== 'I'.toLowerCase()) {
52
52
  uppercase = manualUppercase;
53
53
  }
54
54
 
55
- function fromCharCode(code) {return String.fromCharCode(code);}
56
-
57
55
 
58
56
  var /** holds major version number for IE or NaN for real browsers */
59
57
  msie = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]),
@@ -69,6 +67,29 @@ var /** holds major version number for IE or NaN for real browsers */
69
67
  nodeName_,
70
68
  uid = ['0', '0', '0'];
71
69
 
70
+
71
+ /**
72
+ * @private
73
+ * @param {*} obj
74
+ * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, ...)
75
+ */
76
+ function isArrayLike(obj) {
77
+ if (!obj || (typeof obj.length !== 'number')) return false;
78
+
79
+ // We have on object which has length property. Should we treat it as array?
80
+ if (typeof obj.hasOwnProperty != 'function' &&
81
+ typeof obj.constructor != 'function') {
82
+ // This is here for IE8: it is a bogus object treat it as array;
83
+ return true;
84
+ } else {
85
+ return obj instanceof JQLite || // JQLite
86
+ (jQuery && obj instanceof jQuery) || // jQuery
87
+ toString.call(obj) !== '[object Object]' || // some browser native object
88
+ typeof obj.callee === 'function'; // arguments (on IE8 looks like regular obj)
89
+ }
90
+ }
91
+
92
+
72
93
  /**
73
94
  * @ngdoc function
74
95
  * @name angular.forEach
@@ -96,30 +117,6 @@ var /** holds major version number for IE or NaN for real browsers */
96
117
  * @param {Object=} context Object to become context (`this`) for the iterator function.
97
118
  * @returns {Object|Array} Reference to `obj`.
98
119
  */
99
-
100
-
101
- /**
102
- * @private
103
- * @param {*} obj
104
- * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, ...)
105
- */
106
- function isArrayLike(obj) {
107
- if (!obj || (typeof obj.length !== 'number')) return false;
108
-
109
- // We have on object which has length property. Should we treat it as array?
110
- if (typeof obj.hasOwnProperty != 'function' &&
111
- typeof obj.constructor != 'function') {
112
- // This is here for IE8: it is a bogus object treat it as array;
113
- return true;
114
- } else {
115
- return obj instanceof JQLite || // JQLite
116
- (jQuery && obj instanceof jQuery) || // jQuery
117
- toString.call(obj) !== '[object Object]' || // some browser native object
118
- typeof obj.callee === 'function'; // arguments (on IE8 looks like regular obj)
119
- }
120
- }
121
-
122
-
123
120
  function forEach(obj, iterator, context) {
124
121
  var key;
125
122
  if (obj) {
@@ -203,6 +200,21 @@ function nextUid() {
203
200
  return uid.join('');
204
201
  }
205
202
 
203
+
204
+ /**
205
+ * Set or clear the hashkey for an object.
206
+ * @param obj object
207
+ * @param h the hashkey (!truthy to delete the hashkey)
208
+ */
209
+ function setHashKey(obj, h) {
210
+ if (h) {
211
+ obj.$$hashKey = h;
212
+ }
213
+ else {
214
+ delete obj.$$hashKey;
215
+ }
216
+ }
217
+
206
218
  /**
207
219
  * @ngdoc function
208
220
  * @name angular.extend
@@ -214,8 +226,10 @@ function nextUid() {
214
226
  *
215
227
  * @param {Object} dst Destination object.
216
228
  * @param {...Object} src Source object(s).
229
+ * @returns {Object} Reference to `dst`.
217
230
  */
218
231
  function extend(dst) {
232
+ var h = dst.$$hashKey;
219
233
  forEach(arguments, function(obj){
220
234
  if (obj !== dst) {
221
235
  forEach(obj, function(value, key){
@@ -223,6 +237,8 @@ function extend(dst) {
223
237
  });
224
238
  }
225
239
  });
240
+
241
+ setHashKey(dst,h);
226
242
  return dst;
227
243
  }
228
244
 
@@ -577,12 +593,14 @@ function copy(source, destination){
577
593
  destination.push(copy(source[i]));
578
594
  }
579
595
  } else {
596
+ var h = destination.$$hashKey;
580
597
  forEach(destination, function(value, key){
581
598
  delete destination[key];
582
599
  });
583
600
  for ( var key in source) {
584
601
  destination[key] = copy(source[key]);
585
602
  }
603
+ setHashKey(destination,h);
586
604
  }
587
605
  }
588
606
  return destination;
@@ -622,7 +640,7 @@ function shallowCopy(src, dst) {
622
640
  * During a property comparision, properties of `function` type and properties with names
623
641
  * that begin with `$` are ignored.
624
642
  *
625
- * Scope and DOMWindow objects are being compared only be identify (`===`).
643
+ * Scope and DOMWindow objects are being compared only by identify (`===`).
626
644
  *
627
645
  * @param {*} o1 Object or value to compare.
628
646
  * @param {*} o2 Object or value to compare.
@@ -682,7 +700,7 @@ function sliceArgs(args, startIndex) {
682
700
  *
683
701
  * @description
684
702
  * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for
685
- * `fn`). You can supply optional `args` that are are prebound to the function. This feature is also
703
+ * `fn`). You can supply optional `args` that are prebound to the function. This feature is also
686
704
  * known as [function currying](http://en.wikipedia.org/wiki/Currying).
687
705
  *
688
706
  * @param {Object} self Context which `fn` should be evaluated in.
@@ -861,7 +879,7 @@ function encodeUriQuery(val, pctEncodeSpaces) {
861
879
  replace(/%3A/gi, ':').
862
880
  replace(/%24/g, '$').
863
881
  replace(/%2C/gi, ',').
864
- replace((pctEncodeSpaces ? null : /%20/g), '+');
882
+ replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
865
883
  }
866
884
 
867
885
 
@@ -875,7 +893,7 @@ function encodeUriQuery(val, pctEncodeSpaces) {
875
893
  *
876
894
  * @description
877
895
  *
878
- * Use this directive to auto-bootstrap on application. Only
896
+ * Use this directive to auto-bootstrap an application. Only
879
897
  * one directive can be used per HTML document. The directive
880
898
  * designates the root of the application and is typically placed
881
899
  * at the root of the page.
@@ -950,22 +968,38 @@ function angularInit(element, bootstrap) {
950
968
  * @returns {AUTO.$injector} Returns the newly created injector for this app.
951
969
  */
952
970
  function bootstrap(element, modules) {
953
- element = jqLite(element);
954
- modules = modules || [];
955
- modules.unshift(['$provide', function($provide) {
956
- $provide.value('$rootElement', element);
957
- }]);
958
- modules.unshift('ng');
959
- var injector = createInjector(modules);
960
- injector.invoke(
961
- ['$rootScope', '$rootElement', '$compile', '$injector', function(scope, element, compile, injector){
962
- scope.$apply(function() {
963
- element.data('$injector', injector);
964
- compile(element)(scope);
965
- });
966
- }]
967
- );
968
- return injector;
971
+ var resumeBootstrapInternal = function() {
972
+ element = jqLite(element);
973
+ modules = modules || [];
974
+ modules.unshift(['$provide', function($provide) {
975
+ $provide.value('$rootElement', element);
976
+ }]);
977
+ modules.unshift('ng');
978
+ var injector = createInjector(modules);
979
+ injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
980
+ function(scope, element, compile, injector) {
981
+ scope.$apply(function() {
982
+ element.data('$injector', injector);
983
+ compile(element)(scope);
984
+ });
985
+ }]
986
+ );
987
+ return injector;
988
+ };
989
+
990
+ var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;
991
+
992
+ if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
993
+ return resumeBootstrapInternal();
994
+ }
995
+
996
+ window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
997
+ angular.resumeBootstrap = function(extraModules) {
998
+ forEach(extraModules, function(module) {
999
+ modules.push(module);
1000
+ });
1001
+ resumeBootstrapInternal();
1002
+ };
969
1003
  }
970
1004
 
971
1005
  var SNAKE_CASE_REGEXP = /[A-Z]/g;
@@ -998,7 +1032,7 @@ function bindJQuery() {
998
1032
  }
999
1033
 
1000
1034
  /**
1001
- * throw error of the argument is falsy.
1035
+ * throw error if the argument is falsy.
1002
1036
  */
1003
1037
  function assertArg(arg, name, reason) {
1004
1038
  if (!arg) {
@@ -1272,18 +1306,18 @@ function setupModuleLoader(window) {
1272
1306
  * An object that contains information about the current AngularJS version. This object has the
1273
1307
  * following properties:
1274
1308
  *
1275
- * - `full` – `{string}` – Full version string, such as "0.9.18".
1276
- * - `major` – `{number}` – Major version number, such as "0".
1277
- * - `minor` – `{number}` – Minor version number, such as "9".
1278
- * - `dot` – `{number}` – Dot version number, such as "18".
1279
- * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
1309
+ * - `full` `{string}` Full version string, such as "0.9.18".
1310
+ * - `major` `{number}` Major version number, such as "0".
1311
+ * - `minor` `{number}` Minor version number, such as "9".
1312
+ * - `dot` `{number}` Dot version number, such as "18".
1313
+ * - `codeName` `{string}` Code name of the release, such as "jiggling-armfat".
1280
1314
  */
1281
1315
  var version = {
1282
- full: '1.0.5', // all of these placeholder strings will be replaced by rake's
1283
- major: 1, // compile task
1316
+ full: '1.0.7', // all of these placeholder strings will be replaced by grunt's
1317
+ major: 1, // package task
1284
1318
  minor: 0,
1285
- dot: 5,
1286
- codeName: 'flatulent-propulsion'
1319
+ dot: 7,
1320
+ codeName: 'monochromatic-rainbow'
1287
1321
  };
1288
1322
 
1289
1323
 
@@ -1428,18 +1462,18 @@ function publishExternalAPI(angular){
1428
1462
  * - [after()](http://api.jquery.com/after/)
1429
1463
  * - [append()](http://api.jquery.com/append/)
1430
1464
  * - [attr()](http://api.jquery.com/attr/)
1431
- * - [bind()](http://api.jquery.com/bind/)
1432
- * - [children()](http://api.jquery.com/children/)
1465
+ * - [bind()](http://api.jquery.com/bind/) - Does not support namespaces
1466
+ * - [children()](http://api.jquery.com/children/) - Does not support selectors
1433
1467
  * - [clone()](http://api.jquery.com/clone/)
1434
1468
  * - [contents()](http://api.jquery.com/contents/)
1435
1469
  * - [css()](http://api.jquery.com/css/)
1436
1470
  * - [data()](http://api.jquery.com/data/)
1437
1471
  * - [eq()](http://api.jquery.com/eq/)
1438
- * - [find()](http://api.jquery.com/find/) - Limited to lookups by tag name.
1472
+ * - [find()](http://api.jquery.com/find/) - Limited to lookups by tag name
1439
1473
  * - [hasClass()](http://api.jquery.com/hasClass/)
1440
1474
  * - [html()](http://api.jquery.com/html/)
1441
- * - [next()](http://api.jquery.com/next/)
1442
- * - [parent()](http://api.jquery.com/parent/)
1475
+ * - [next()](http://api.jquery.com/next/) - Does not support selectors
1476
+ * - [parent()](http://api.jquery.com/parent/) - Does not support selectors
1443
1477
  * - [prepend()](http://api.jquery.com/prepend/)
1444
1478
  * - [prop()](http://api.jquery.com/prop/)
1445
1479
  * - [ready()](http://api.jquery.com/ready/)
@@ -1451,7 +1485,7 @@ function publishExternalAPI(angular){
1451
1485
  * - [text()](http://api.jquery.com/text/)
1452
1486
  * - [toggleClass()](http://api.jquery.com/toggleClass/)
1453
1487
  * - [triggerHandler()](http://api.jquery.com/triggerHandler/) - Doesn't pass native event objects to handlers.
1454
- * - [unbind()](http://api.jquery.com/unbind/)
1488
+ * - [unbind()](http://api.jquery.com/unbind/) - Does not support namespaces
1455
1489
  * - [val()](http://api.jquery.com/val/)
1456
1490
  * - [wrap()](http://api.jquery.com/wrap/)
1457
1491
  *
@@ -1998,23 +2032,43 @@ forEach({
1998
2032
 
1999
2033
  if (!eventFns) {
2000
2034
  if (type == 'mouseenter' || type == 'mouseleave') {
2001
- var counter = 0;
2035
+ var contains = document.body.contains || document.body.compareDocumentPosition ?
2036
+ function( a, b ) {
2037
+ var adown = a.nodeType === 9 ? a.documentElement : a,
2038
+ bup = b && b.parentNode;
2039
+ return a === bup || !!( bup && bup.nodeType === 1 && (
2040
+ adown.contains ?
2041
+ adown.contains( bup ) :
2042
+ a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
2043
+ ));
2044
+ } :
2045
+ function( a, b ) {
2046
+ if ( b ) {
2047
+ while ( (b = b.parentNode) ) {
2048
+ if ( b === a ) {
2049
+ return true;
2050
+ }
2051
+ }
2052
+ }
2053
+ return false;
2054
+ };
2002
2055
 
2003
- events.mouseenter = [];
2004
- events.mouseleave = [];
2056
+ events[type] = [];
2005
2057
 
2006
- bindFn(element, 'mouseover', function(event) {
2007
- counter++;
2008
- if (counter == 1) {
2009
- handle(event, 'mouseenter');
2010
- }
2011
- });
2012
- bindFn(element, 'mouseout', function(event) {
2013
- counter --;
2014
- if (counter == 0) {
2015
- handle(event, 'mouseleave');
2058
+ // Refer to jQuery's implementation of mouseenter & mouseleave
2059
+ // Read about mouseenter and mouseleave:
2060
+ // http://www.quirksmode.org/js/events_mouse.html#link8
2061
+ var eventmap = { mouseleave : "mouseout", mouseenter : "mouseover"}
2062
+ bindFn(element, eventmap[type], function(event) {
2063
+ var ret, target = this, related = event.relatedTarget;
2064
+ // For mousenter/leave call the handler if related is outside the target.
2065
+ // NB: No relatedTarget if the mouse left/entered the browser window
2066
+ if ( !related || (related !== target && !contains(target, related)) ){
2067
+ handle(event, type);
2016
2068
  }
2069
+
2017
2070
  });
2071
+
2018
2072
  } else {
2019
2073
  addEventListenerFn(element, type, handle);
2020
2074
  events[type] = [];
@@ -2330,7 +2384,7 @@ function annotate(fn) {
2330
2384
  }
2331
2385
  } else if (isArray(fn)) {
2332
2386
  last = fn.length - 1;
2333
- assertArgFn(fn[last], 'fn')
2387
+ assertArgFn(fn[last], 'fn');
2334
2388
  $inject = fn.slice(0, last);
2335
2389
  } else {
2336
2390
  assertArgFn(fn, 'fn', true);
@@ -2364,19 +2418,19 @@ function annotate(fn) {
2364
2418
  * # Injection Function Annotation
2365
2419
  *
2366
2420
  * JavaScript does not have annotations, and annotations are needed for dependency injection. The
2367
- * following ways are all valid way of annotating function with injection arguments and are equivalent.
2421
+ * following are all valid ways of annotating function with injection arguments and are equivalent.
2368
2422
  *
2369
2423
  * <pre>
2370
2424
  * // inferred (only works if code not minified/obfuscated)
2371
- * $inject.invoke(function(serviceA){});
2425
+ * $injector.invoke(function(serviceA){});
2372
2426
  *
2373
2427
  * // annotated
2374
2428
  * function explicit(serviceA) {};
2375
2429
  * explicit.$inject = ['serviceA'];
2376
- * $inject.invoke(explicit);
2430
+ * $injector.invoke(explicit);
2377
2431
  *
2378
2432
  * // inline
2379
- * $inject.invoke(['serviceA', function(serviceA){}]);
2433
+ * $injector.invoke(['serviceA', function(serviceA){}]);
2380
2434
  * </pre>
2381
2435
  *
2382
2436
  * ## Inference
@@ -2493,7 +2547,7 @@ function annotate(fn) {
2493
2547
  * // ...
2494
2548
  * };
2495
2549
  * tmpFn.$inject = ['$compile', '$rootScope'];
2496
- * injector.invoke(tempFn);
2550
+ * injector.invoke(tmpFn);
2497
2551
  *
2498
2552
  * // To better support inline function the inline annotation is supported
2499
2553
  * injector.invoke(['$compile', '$rootScope', function(obfCompile, obfRootScope) {
@@ -2522,7 +2576,7 @@ function annotate(fn) {
2522
2576
  * @description
2523
2577
  *
2524
2578
  * Use `$provide` to register new providers with the `$injector`. The providers are the factories for the instance.
2525
- * The providers share the same name as the instance they create with the `Provider` suffixed to them.
2579
+ * The providers share the same name as the instance they create with `Provider` suffixed to them.
2526
2580
  *
2527
2581
  * A provider is an object with a `$get()` method. The injector calls the `$get` method to create a new instance of
2528
2582
  * a service. The Provider can have additional methods which would allow for configuration of the provider.
@@ -2546,7 +2600,7 @@ function annotate(fn) {
2546
2600
  *
2547
2601
  * beforeEach(module(function($provide) {
2548
2602
  * $provide.provider('greet', GreetProvider);
2549
- * });
2603
+ * }));
2550
2604
  *
2551
2605
  * it('should greet', inject(function(greet) {
2552
2606
  * expect(greet('angular')).toEqual('Hello angular!');
@@ -2559,9 +2613,7 @@ function annotate(fn) {
2559
2613
  * inject(function(greet) {
2560
2614
  * expect(greet('angular')).toEqual('Ahoj angular!');
2561
2615
  * });
2562
- * )};
2563
- *
2564
- * });
2616
+ * });
2565
2617
  * </pre>
2566
2618
  */
2567
2619
 
@@ -2655,7 +2707,7 @@ function annotate(fn) {
2655
2707
  *
2656
2708
  * @param {string} name The name of the service to decorate.
2657
2709
  * @param {function()} decorator This function will be invoked when the service needs to be
2658
- * instanciated. The function is called using the {@link AUTO.$injector#invoke
2710
+ * instantiated. The function is called using the {@link AUTO.$injector#invoke
2659
2711
  * injector.invoke} method and is therefore fully injectable. Local injection arguments:
2660
2712
  *
2661
2713
  * * `$delegate` - The original service instance, which can be monkey patched, configured,
@@ -2855,6 +2907,8 @@ function createInjector(modulesToLoad) {
2855
2907
  var Constructor = function() {},
2856
2908
  instance, returnedValue;
2857
2909
 
2910
+ // Check if Type is annotated and use just the given function at n-1 as parameter
2911
+ // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);
2858
2912
  Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Type).prototype;
2859
2913
  instance = new Constructor();
2860
2914
  returnedValue = invoke(Type, instance, locals);
@@ -2870,6 +2924,7 @@ function createInjector(modulesToLoad) {
2870
2924
  };
2871
2925
  }
2872
2926
  }
2927
+
2873
2928
  /**
2874
2929
  * @ngdoc function
2875
2930
  * @name ng.$anchorScroll
@@ -3234,7 +3289,13 @@ function Browser(window, document, $log, $sniffer) {
3234
3289
  cookie = cookieArray[i];
3235
3290
  index = cookie.indexOf('=');
3236
3291
  if (index > 0) { //ignore nameless cookies
3237
- lastCookies[unescape(cookie.substring(0, index))] = unescape(cookie.substring(index + 1));
3292
+ var name = unescape(cookie.substring(0, index));
3293
+ // the first value that is seen for a cookie is the most
3294
+ // specific one. values for the same cookie name that
3295
+ // follow are for less specific paths.
3296
+ if (lastCookies[name] === undefined) {
3297
+ lastCookies[name] = unescape(cookie.substring(index + 1));
3298
+ }
3238
3299
  }
3239
3300
  }
3240
3301
  }
@@ -3298,6 +3359,7 @@ function $BrowserProvider(){
3298
3359
  return new Browser($window, $document, $log, $sniffer);
3299
3360
  }];
3300
3361
  }
3362
+
3301
3363
  /**
3302
3364
  * @ngdoc object
3303
3365
  * @name ng.$cacheFactory
@@ -3309,16 +3371,16 @@ function $BrowserProvider(){
3309
3371
  * @param {string} cacheId Name or id of the newly created cache.
3310
3372
  * @param {object=} options Options object that specifies the cache behavior. Properties:
3311
3373
  *
3312
- * - `{number=}` `capacity` — turns the cache into LRU cache.
3374
+ * - `{number=}` `capacity` turns the cache into LRU cache.
3313
3375
  *
3314
3376
  * @returns {object} Newly created cache object with the following set of methods:
3315
3377
  *
3316
- * - `{object}` `info()` — Returns id, size, and options of cache.
3317
- * - `{void}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache.
3318
- * - `{{*}}` `get({string} key)` — Returns cached value for `key` or undefined for cache miss.
3319
- * - `{void}` `remove({string} key)` — Removes a key-value pair from the cache.
3320
- * - `{void}` `removeAll()` — Removes all cached values.
3321
- * - `{void}` `destroy()` — Removes references to this cache from $cacheFactory.
3378
+ * - `{object}` `info()` Returns id, size, and options of cache.
3379
+ * - `{void}` `put({string} key, {*} value)` Puts a new key-value pair into the cache.
3380
+ * - `{{*}}` `get({string} key)` Returns cached value for `key` or undefined for cache miss.
3381
+ * - `{void}` `remove({string} key)` Removes a key-value pair from the cache.
3382
+ * - `{void}` `removeAll()` Removes all cached values.
3383
+ * - `{void}` `destroy()` Removes references to this cache from $cacheFactory.
3322
3384
  *
3323
3385
  */
3324
3386
  function $CacheFactoryProvider() {
@@ -3625,7 +3687,7 @@ function $CompileProvider($provide) {
3625
3687
  COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,
3626
3688
  CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/,
3627
3689
  MULTI_ROOT_TEMPLATE_ERROR = 'Template must have exactly one root element. was: ',
3628
- urlSanitizationWhitelist = /^\s*(https?|ftp|mailto):/;
3690
+ urlSanitizationWhitelist = /^\s*(https?|ftp|mailto|file):/;
3629
3691
 
3630
3692
 
3631
3693
  /**
@@ -3827,7 +3889,7 @@ function $CompileProvider($provide) {
3827
3889
 
3828
3890
  function compile($compileNodes, transcludeFn, maxPriority) {
3829
3891
  if (!($compileNodes instanceof jqLite)) {
3830
- // jquery always rewraps, where as we need to preserve the original selector so that we can modify it.
3892
+ // jquery always rewraps, whereas we need to preserve the original selector so that we can modify it.
3831
3893
  $compileNodes = jqLite($compileNodes);
3832
3894
  }
3833
3895
  // We can not compile top level text elements since text nodes can be merged and we will
@@ -3879,7 +3941,7 @@ function $CompileProvider($provide) {
3879
3941
  * functions return values - the linking functions - are combined into a composite linking
3880
3942
  * function, which is the a linking function for the node.
3881
3943
  *
3882
- * @param {NodeList} nodeList an array of nodes to compile
3944
+ * @param {NodeList} nodeList an array of nodes or NodeList to compile
3883
3945
  * @param {function(angular.Scope[, cloneAttachFn]} transcludeFn A linking function, where the
3884
3946
  * scope argument is auto-generated to the new child of the transcluded parent scope.
3885
3947
  * @param {DOMElement=} $rootElement If the nodeList is the root of the compilation tree then the
@@ -3902,7 +3964,7 @@ function $CompileProvider($provide) {
3902
3964
  ? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement)
3903
3965
  : null;
3904
3966
 
3905
- childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || !nodeList[i].childNodes.length)
3967
+ childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || !nodeList[i].childNodes || !nodeList[i].childNodes.length)
3906
3968
  ? null
3907
3969
  : compileNodes(nodeList[i].childNodes,
3908
3970
  nodeLinkFn ? nodeLinkFn.transclude : transcludeFn);
@@ -4038,9 +4100,9 @@ function $CompileProvider($provide) {
4038
4100
 
4039
4101
 
4040
4102
  /**
4041
- * Once the directives have been collected their compile functions is executed. This method
4103
+ * Once the directives have been collected, their compile functions are executed. This method
4042
4104
  * is responsible for inlining directive templates as well as terminating the application
4043
- * of the directives if the terminal directive has been reached..
4105
+ * of the directives if the terminal directive has been reached.
4044
4106
  *
4045
4107
  * @param {Array} directives Array of collected directives to execute their compile function.
4046
4108
  * this needs to be pre-sorted by priority order.
@@ -4048,11 +4110,11 @@ function $CompileProvider($provide) {
4048
4110
  * @param {Object} templateAttrs The shared attribute function
4049
4111
  * @param {function(angular.Scope[, cloneAttachFn]} transcludeFn A linking function, where the
4050
4112
  * scope argument is auto-generated to the new child of the transcluded parent scope.
4051
- * @param {DOMElement} $rootElement If we are working on the root of the compile tree then this
4052
- * argument has the root jqLite array so that we can replace widgets on it.
4113
+ * @param {JQLite} jqCollection If we are working on the root of the compile tree then this
4114
+ * argument has the root jqLite array so that we can replace nodes on it.
4053
4115
  * @returns linkFn
4054
4116
  */
4055
- function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn, $rootElement) {
4117
+ function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn, jqCollection) {
4056
4118
  var terminalPriority = -Number.MAX_VALUE,
4057
4119
  preLinkFns = [],
4058
4120
  postLinkFns = [],
@@ -4106,7 +4168,7 @@ function $CompileProvider($provide) {
4106
4168
  $compileNode = templateAttrs.$$element =
4107
4169
  jqLite(document.createComment(' ' + directiveName + ': ' + templateAttrs[directiveName] + ' '));
4108
4170
  compileNode = $compileNode[0];
4109
- replaceWith($rootElement, jqLite($template[0]), compileNode);
4171
+ replaceWith(jqCollection, jqLite($template[0]), compileNode);
4110
4172
  childTranscludeFn = compile($template, transcludeFn, terminalPriority);
4111
4173
  } else {
4112
4174
  $template = jqLite(JQLiteClone(compileNode)).contents();
@@ -4130,7 +4192,7 @@ function $CompileProvider($provide) {
4130
4192
  throw new Error(MULTI_ROOT_TEMPLATE_ERROR + directiveValue);
4131
4193
  }
4132
4194
 
4133
- replaceWith($rootElement, $compileNode, compileNode);
4195
+ replaceWith(jqCollection, $compileNode, compileNode);
4134
4196
 
4135
4197
  var newTemplateAttrs = {$attr: {}};
4136
4198
 
@@ -4158,7 +4220,7 @@ function $CompileProvider($provide) {
4158
4220
  assertNoDuplicate('template', templateDirective, directive, $compileNode);
4159
4221
  templateDirective = directive;
4160
4222
  nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i),
4161
- nodeLinkFn, $compileNode, templateAttrs, $rootElement, directive.replace,
4223
+ nodeLinkFn, $compileNode, templateAttrs, jqCollection, directive.replace,
4162
4224
  childTranscludeFn);
4163
4225
  ii = directives.length;
4164
4226
  } else if (directive.compile) {
@@ -4291,7 +4353,7 @@ function $CompileProvider($provide) {
4291
4353
  parentGet = $parse(attrs[attrName]);
4292
4354
  scope[scopeName] = function(locals) {
4293
4355
  return parentGet(parentScope, locals);
4294
- }
4356
+ };
4295
4357
  break;
4296
4358
  }
4297
4359
 
@@ -4461,7 +4523,7 @@ function $CompileProvider($provide) {
4461
4523
 
4462
4524
  directives.unshift(derivedSyncDirective);
4463
4525
  afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs, childTranscludeFn);
4464
- afterTemplateChildLinkFn = compileNodes($compileNode.contents(), childTranscludeFn);
4526
+ afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn);
4465
4527
 
4466
4528
 
4467
4529
  while(linkQueue.length) {
@@ -4726,7 +4788,7 @@ function $ControllerProvider() {
4726
4788
  * @description
4727
4789
  * `$controller` service is responsible for instantiating controllers.
4728
4790
  *
4729
- * It's just simple call to {@link AUTO.$injector $injector}, but extracted into
4791
+ * It's just a simple call to {@link AUTO.$injector $injector}, but extracted into
4730
4792
  * a service, so that one can override this service with {@link https://gist.github.com/1649788
4731
4793
  * BC version}.
4732
4794
  */
@@ -4779,7 +4841,7 @@ function $DocumentProvider(){
4779
4841
  *
4780
4842
  */
4781
4843
  function $ExceptionHandlerProvider() {
4782
- this.$get = ['$log', function($log){
4844
+ this.$get = ['$log', function($log) {
4783
4845
  return function(exception, cause) {
4784
4846
  $log.error.apply($log, arguments);
4785
4847
  };
@@ -4967,7 +5029,7 @@ function $InterpolateProvider() {
4967
5029
  }];
4968
5030
  }
4969
5031
 
4970
- var URL_MATCH = /^([^:]+):\/\/(\w+:{0,1}\w*@)?([\w\.-]*)(:([0-9]+))?(\/[^\?#]*)?(\?([^#]*))?(#(.*))?$/,
5032
+ var URL_MATCH = /^([^:]+):\/\/(\w+:{0,1}\w*@)?(\{?[\w\.-]*\}?)(:([0-9]+))?(\/[^\?#]*)?(\?([^#]*))?(#(.*))?$/,
4971
5033
  PATH_MATCH = /^([^\?#]*)?(\?([^#]*))?(#(.*))?$/,
4972
5034
  HASH_MATCH = PATH_MATCH,
4973
5035
  DEFAULT_PORTS = {'http': 80, 'https': 443, 'ftp': 21};
@@ -5046,7 +5108,8 @@ function convertToHashbangUrl(url, basePath, hashPrefix) {
5046
5108
  var match = matchUrl(url);
5047
5109
 
5048
5110
  // already hashbang url
5049
- if (decodeURIComponent(match.path) == basePath) {
5111
+ if (decodeURIComponent(match.path) == basePath && !isUndefined(match.hash) &&
5112
+ match.hash.indexOf(hashPrefix) === 0) {
5050
5113
  return url;
5051
5114
  // convert html5 url -> hashbang url
5052
5115
  } else {
@@ -5543,6 +5606,10 @@ function $LocationProvider(){
5543
5606
  // update $location when $browser url changes
5544
5607
  $browser.onUrlChange(function(newUrl) {
5545
5608
  if ($location.absUrl() != newUrl) {
5609
+ if ($rootScope.$broadcast('$locationChangeStart', newUrl, $location.absUrl()).defaultPrevented) {
5610
+ $browser.url($location.absUrl());
5611
+ return;
5612
+ }
5546
5613
  $rootScope.$evalAsync(function() {
5547
5614
  var oldUrl = $location.absUrl();
5548
5615
 
@@ -5851,10 +5918,10 @@ function lex(text, csp){
5851
5918
  function readIdent() {
5852
5919
  var ident = "",
5853
5920
  start = index,
5854
- lastDot, peekIndex, methodName;
5921
+ lastDot, peekIndex, methodName, ch;
5855
5922
 
5856
5923
  while (index < text.length) {
5857
- var ch = text.charAt(index);
5924
+ ch = text.charAt(index);
5858
5925
  if (ch == '.' || isIdent(ch) || isNumber(ch)) {
5859
5926
  if (ch == '.') lastDot = index;
5860
5927
  ident += ch;
@@ -5868,7 +5935,7 @@ function lex(text, csp){
5868
5935
  if (lastDot) {
5869
5936
  peekIndex = index;
5870
5937
  while(peekIndex < text.length) {
5871
- var ch = text.charAt(peekIndex);
5938
+ ch = text.charAt(peekIndex);
5872
5939
  if (ch == '(') {
5873
5940
  methodName = ident.substr(lastDot - start + 1);
5874
5941
  ident = ident.substr(0, lastDot - start);
@@ -6121,8 +6188,8 @@ function parser(text, json, $filter, csp){
6121
6188
  text.substring(0, token.index) + "] can not be assigned to", token);
6122
6189
  }
6123
6190
  right = logicalOR();
6124
- return function(self, locals){
6125
- return left.assign(self, right(self, locals), locals);
6191
+ return function(scope, locals){
6192
+ return left.assign(scope, right(scope, locals), locals);
6126
6193
  };
6127
6194
  } else {
6128
6195
  return left;
@@ -6239,12 +6306,12 @@ function parser(text, json, $filter, csp){
6239
6306
  var field = expect().text;
6240
6307
  var getter = getterFn(field, csp);
6241
6308
  return extend(
6242
- function(self, locals) {
6243
- return getter(object(self, locals), locals);
6309
+ function(scope, locals, self) {
6310
+ return getter(self || object(scope, locals), locals);
6244
6311
  },
6245
6312
  {
6246
- assign:function(self, value, locals) {
6247
- return setter(object(self, locals), field, value);
6313
+ assign:function(scope, value, locals) {
6314
+ return setter(object(scope, locals), field, value);
6248
6315
  }
6249
6316
  }
6250
6317
  );
@@ -6285,14 +6352,14 @@ function parser(text, json, $filter, csp){
6285
6352
  } while (expect(','));
6286
6353
  }
6287
6354
  consume(')');
6288
- return function(self, locals){
6355
+ return function(scope, locals){
6289
6356
  var args = [],
6290
- context = contextGetter ? contextGetter(self, locals) : self;
6357
+ context = contextGetter ? contextGetter(scope, locals) : scope;
6291
6358
 
6292
6359
  for ( var i = 0; i < argsFn.length; i++) {
6293
- args.push(argsFn[i](self, locals));
6360
+ args.push(argsFn[i](scope, locals));
6294
6361
  }
6295
- var fnPtr = fn(self, locals) || noop;
6362
+ var fnPtr = fn(scope, locals, context) || noop;
6296
6363
  // IE stupidity!
6297
6364
  return fnPtr.apply
6298
6365
  ? fnPtr.apply(context, args)
@@ -6334,8 +6401,7 @@ function parser(text, json, $filter, csp){
6334
6401
  var object = {};
6335
6402
  for ( var i = 0; i < keyValues.length; i++) {
6336
6403
  var keyValue = keyValues[i];
6337
- var value = keyValue.value(self, locals);
6338
- object[keyValue.key] = value;
6404
+ object[keyValue.key] = keyValue.value(self, locals);
6339
6405
  }
6340
6406
  return object;
6341
6407
  };
@@ -6457,7 +6523,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4) {
6457
6523
  }
6458
6524
  return pathVal;
6459
6525
  };
6460
- };
6526
+ }
6461
6527
 
6462
6528
  function getterFn(path, csp) {
6463
6529
  if (getterFnCache.hasOwnProperty(path)) {
@@ -6472,7 +6538,7 @@ function getterFn(path, csp) {
6472
6538
  fn = (pathKeysLength < 6)
6473
6539
  ? cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4])
6474
6540
  : function(scope, locals) {
6475
- var i = 0, val
6541
+ var i = 0, val;
6476
6542
  do {
6477
6543
  val = cspSafeGetterFn(
6478
6544
  pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++]
@@ -6537,9 +6603,9 @@ function getterFn(path, csp) {
6537
6603
  * @param {string} expression String expression to compile.
6538
6604
  * @returns {function(context, locals)} a function which represents the compiled expression:
6539
6605
  *
6540
- * * `context` – `{object}` – an object against which any expressions embedded in the strings
6606
+ * * `context` `{object}` an object against which any expressions embedded in the strings
6541
6607
  * are evaluated against (tipically a scope object).
6542
- * * `locals` – `{object=}` – local variables context object, useful for overriding values in
6608
+ * * `locals` `{object=}` local variables context object, useful for overriding values in
6543
6609
  * `context`.
6544
6610
  *
6545
6611
  * The return function also has an `assign` property, if the expression is assignable, which
@@ -6628,14 +6694,14 @@ function $ParseProvider() {
6628
6694
  *
6629
6695
  * **Methods**
6630
6696
  *
6631
- * - `resolve(value)` – resolves the derived promise with the `value`. If the value is a rejection
6697
+ * - `resolve(value)` resolves the derived promise with the `value`. If the value is a rejection
6632
6698
  * constructed via `$q.reject`, the promise will be rejected instead.
6633
- * - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to
6699
+ * - `reject(reason)` rejects the derived promise with the `reason`. This is equivalent to
6634
6700
  * resolving it with a rejection constructed via `$q.reject`.
6635
6701
  *
6636
6702
  * **Properties**
6637
6703
  *
6638
- * - promise – `{Promise}` – promise object associated with this deferred.
6704
+ * - promise `{Promise}` promise object associated with this deferred.
6639
6705
  *
6640
6706
  *
6641
6707
  * # The Promise API
@@ -6648,7 +6714,7 @@ function $ParseProvider() {
6648
6714
  *
6649
6715
  * **Methods**
6650
6716
  *
6651
- * - `then(successCallback, errorCallback)` – regardless of when the promise was or will be resolved
6717
+ * - `then(successCallback, errorCallback)` regardless of when the promise was or will be resolved
6652
6718
  * or rejected calls one of the success or error callbacks asynchronously as soon as the result
6653
6719
  * is available. The callbacks are called with a single argument the result or rejection reason.
6654
6720
  *
@@ -6685,27 +6751,27 @@ function $ParseProvider() {
6685
6751
  * models and avoiding unnecessary browser repaints, which would result in flickering UI.
6686
6752
  * - $q promises are recognized by the templating engine in angular, which means that in templates
6687
6753
  * you can treat promises attached to a scope as if they were the resulting values.
6688
- * - Q has many more features that $q, but that comes at a cost of bytes. $q is tiny, but contains
6754
+ * - Q has many more features than $q, but that comes at a cost of bytes. $q is tiny, but contains
6689
6755
  * all the important functionality needed for common async tasks.
6690
- *
6756
+ *
6691
6757
  * # Testing
6692
- *
6758
+ *
6693
6759
  * <pre>
6694
6760
  * it('should simulate promise', inject(function($q, $rootScope) {
6695
6761
  * var deferred = $q.defer();
6696
6762
  * var promise = deferred.promise;
6697
6763
  * var resolvedValue;
6698
- *
6764
+ *
6699
6765
  * promise.then(function(value) { resolvedValue = value; });
6700
6766
  * expect(resolvedValue).toBeUndefined();
6701
- *
6767
+ *
6702
6768
  * // Simulate resolving of promise
6703
6769
  * deferred.resolve(123);
6704
6770
  * // Note that the 'then' function does not get called synchronously.
6705
6771
  * // This is because we want the promise API to always be async, whether or not
6706
6772
  * // it got called synchronously or asynchronously.
6707
6773
  * expect(resolvedValue).toBeUndefined();
6708
- *
6774
+ *
6709
6775
  * // Propagate promise resolution to 'then' functions using $apply().
6710
6776
  * $rootScope.$apply();
6711
6777
  * expect(resolvedValue).toEqual(123);
@@ -6880,10 +6946,7 @@ function qFactory(nextTick, exceptionHandler) {
6880
6946
  * the promise comes from a source that can't be trusted.
6881
6947
  *
6882
6948
  * @param {*} value Value or a promise
6883
- * @returns {Promise} Returns a single promise that will be resolved with an array of values,
6884
- * each value corresponding to the promise at the same index in the `promises` array. If any of
6885
- * the promises is resolved with a rejection, this resulting promise will be resolved with the
6886
- * same rejection.
6949
+ * @returns {Promise} Returns a promise of the passed value or promise
6887
6950
  */
6888
6951
  var when = function(value, callback, errback) {
6889
6952
  var result = defer(),
@@ -7009,27 +7072,27 @@ function $RouteProvider(){
7009
7072
  *
7010
7073
  * Object properties:
7011
7074
  *
7012
- * - `controller` – `{(string|function()=}` – Controller fn that should be associated with newly
7075
+ * - `controller` `{(string|function()=}` Controller fn that should be associated with newly
7013
7076
  * created scope or the name of a {@link angular.Module#controller registered controller}
7014
7077
  * if passed as a string.
7015
- * - `template` – `{string=}` – html template as a string that should be used by
7078
+ * - `template` `{string=}` html template as a string that should be used by
7016
7079
  * {@link ng.directive:ngView ngView} or
7017
7080
  * {@link ng.directive:ngInclude ngInclude} directives.
7018
7081
  * this property takes precedence over `templateUrl`.
7019
- * - `templateUrl` – `{string=}` – path to an html template that should be used by
7082
+ * - `templateUrl` `{string=}` path to an html template that should be used by
7020
7083
  * {@link ng.directive:ngView ngView}.
7021
7084
  * - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
7022
7085
  * be injected into the controller. If any of these dependencies are promises, they will be
7023
7086
  * resolved and converted to a value before the controller is instantiated and the
7024
7087
  * `$routeChangeSuccess` event is fired. The map object is:
7025
7088
  *
7026
- * - `key` – `{string}`: a name of a dependency to be injected into the controller.
7089
+ * - `key` `{string}`: a name of a dependency to be injected into the controller.
7027
7090
  * - `factory` - `{string|function}`: If `string` then it is an alias for a service.
7028
7091
  * Otherwise if function, then it is {@link api/AUTO.$injector#invoke injected}
7029
7092
  * and the return value is treated as the dependency. If the result is a promise, it is resolved
7030
7093
  * before its value is injected into the controller.
7031
7094
  *
7032
- * - `redirectTo` – {(string|function())=} – value to update
7095
+ * - `redirectTo` {(string|function())=} value to update
7033
7096
  * {@link ng.$location $location} path with and trigger route redirection.
7034
7097
  *
7035
7098
  * If `redirectTo` is a function, it will be called with the following parameters:
@@ -7240,8 +7303,9 @@ function $RouteProvider(){
7240
7303
  * {@link ng.directive:ngView ngView} listens for the directive
7241
7304
  * to instantiate the controller and render the view.
7242
7305
  *
7306
+ * @param {Object} angularEvent Synthetic event object.
7243
7307
  * @param {Route} current Current route information.
7244
- * @param {Route} previous Previous route information.
7308
+ * @param {Route|Undefined} previous Previous route information, or undefined if current is first route entered.
7245
7309
  */
7246
7310
 
7247
7311
  /**
@@ -7339,7 +7403,7 @@ function $RouteProvider(){
7339
7403
  var next = parseRoute(),
7340
7404
  last = $route.current;
7341
7405
 
7342
- if (next && last && next.$route === last.$route
7406
+ if (next && last && next.$$route === last.$$route
7343
7407
  && equals(next.pathParams, last.pathParams) && !next.reloadOnSearch && !forceReload) {
7344
7408
  last.params = next.params;
7345
7409
  copy(last.params, $routeParams);
@@ -7418,7 +7482,7 @@ function $RouteProvider(){
7418
7482
  match = inherit(route, {
7419
7483
  params: extend({}, $location.search(), params),
7420
7484
  pathParams: params});
7421
- match.$route = route;
7485
+ match.$$route = route;
7422
7486
  }
7423
7487
  });
7424
7488
  // No route matched; fallback to "otherwise" route
@@ -7478,22 +7542,22 @@ function $RouteParamsProvider() {
7478
7542
  /**
7479
7543
  * DESIGN NOTES
7480
7544
  *
7481
- * The design decisions behind the scope ware heavily favored for speed and memory consumption.
7545
+ * The design decisions behind the scope are heavily favored for speed and memory consumption.
7482
7546
  *
7483
7547
  * The typical use of scope is to watch the expressions, which most of the time return the same
7484
7548
  * value as last time so we optimize the operation.
7485
7549
  *
7486
- * Closures construction is expensive from speed as well as memory:
7487
- * - no closures, instead ups prototypical inheritance for API
7550
+ * Closures construction is expensive in terms of speed as well as memory:
7551
+ * - No closures, instead use prototypical inheritance for API
7488
7552
  * - Internal state needs to be stored on scope directly, which means that private state is
7489
7553
  * exposed as $$____ properties
7490
7554
  *
7491
7555
  * Loop operations are optimized by using while(count--) { ... }
7492
7556
  * - this means that in order to keep the same order of execution as addition we have to add
7493
- * items to the array at the begging (shift) instead of at the end (push)
7557
+ * items to the array at the beginning (shift) instead of at the end (push)
7494
7558
  *
7495
7559
  * Child scopes are created and removed often
7496
- * - Using array would be slow since inserts in meddle are expensive so we use linked list
7560
+ * - Using an array would be slow since inserts in middle are expensive so we use linked list
7497
7561
  *
7498
7562
  * There are few watches then a lot of observers. This is why you don't want the observer to be
7499
7563
  * implemented in the same way as watch. Watch requires return of initialization function which
@@ -7515,7 +7579,7 @@ function $RouteParamsProvider() {
7515
7579
  * @methodOf ng.$rootScopeProvider
7516
7580
  * @description
7517
7581
  *
7518
- * Sets the number of digest iteration the scope should attempt to execute before giving up and
7582
+ * Sets the number of digest iterations the scope should attempt to execute before giving up and
7519
7583
  * assuming that the model is unstable.
7520
7584
  *
7521
7585
  * The current default is 10 iterations.
@@ -7795,7 +7859,7 @@ function $RootScopeProvider(){
7795
7859
  * @function
7796
7860
  *
7797
7861
  * @description
7798
- * Process all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and its children.
7862
+ * Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and its children.
7799
7863
  * Because a {@link ng.$rootScope.Scope#$watch watcher}'s listener can change the model, the
7800
7864
  * `$digest()` keeps calling the {@link ng.$rootScope.Scope#$watch watchers} until no more listeners are
7801
7865
  * firing. This means that it is possible to get into an infinite loop. This function will throw
@@ -8137,7 +8201,7 @@ function $RootScopeProvider(){
8137
8201
  * Afterwards, the event traverses upwards toward the root scope and calls all registered
8138
8202
  * listeners along the way. The event will stop propagating if one of the listeners cancels it.
8139
8203
  *
8140
- * Any exception emmited from the {@link ng.$rootScope.Scope#$on listeners} will be passed
8204
+ * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed
8141
8205
  * onto the {@link ng.$exceptionHandler $exceptionHandler} service.
8142
8206
  *
8143
8207
  * @param {string} name Event name to emit.
@@ -8206,7 +8270,7 @@ function $RootScopeProvider(){
8206
8270
  * Any exception emmited from the {@link ng.$rootScope.Scope#$on listeners} will be passed
8207
8271
  * onto the {@link ng.$exceptionHandler $exceptionHandler} service.
8208
8272
  *
8209
- * @param {string} name Event name to emit.
8273
+ * @param {string} name Event name to broadcast.
8210
8274
  * @param {...*} args Optional set of arguments which will be passed onto the event listeners.
8211
8275
  * @return {Object} Event object, see {@link ng.$rootScope.Scope#$on}
8212
8276
  */
@@ -8352,10 +8416,23 @@ function $SnifferProvider() {
8352
8416
  * @example
8353
8417
  <doc:example>
8354
8418
  <doc:source>
8355
- <input ng-init="$window = $service('$window'); greeting='Hello World!'" type="text" ng-model="greeting" />
8356
- <button ng-click="$window.alert(greeting)">ALERT</button>
8419
+ <script>
8420
+ function Ctrl($scope, $window) {
8421
+ $scope.$window = $window;
8422
+ $scope.greeting = 'Hello, World!';
8423
+ }
8424
+ </script>
8425
+ <div ng-controller="Ctrl">
8426
+ <input type="text" ng-model="greeting" />
8427
+ <button ng-click="$window.alert(greeting)">ALERT</button>
8428
+ </div>
8357
8429
  </doc:source>
8358
8430
  <doc:scenario>
8431
+ it('should display the greeting in the input box', function() {
8432
+ input('greeting').enter('Hello, E2E Tests');
8433
+ // If we click the button it will block the test runner
8434
+ // element(':button').click();
8435
+ });
8359
8436
  </doc:scenario>
8360
8437
  </doc:example>
8361
8438
  */
@@ -8508,7 +8585,7 @@ function $HttpProvider() {
8508
8585
  *
8509
8586
  * @description
8510
8587
  * The `$http` service is a core Angular service that facilitates communication with the remote
8511
- * HTTP servers via browser's {@link https://developer.mozilla.org/en/xmlhttprequest
8588
+ * HTTP servers via the browser's {@link https://developer.mozilla.org/en/xmlhttprequest
8512
8589
  * XMLHttpRequest} object or via {@link http://en.wikipedia.org/wiki/JSONP JSONP}.
8513
8590
  *
8514
8591
  * For unit testing applications that use `$http` service, see
@@ -8518,13 +8595,13 @@ function $HttpProvider() {
8518
8595
  * $resource} service.
8519
8596
  *
8520
8597
  * The $http API is based on the {@link ng.$q deferred/promise APIs} exposed by
8521
- * the $q service. While for simple usage patters this doesn't matter much, for advanced usage,
8522
- * it is important to familiarize yourself with these apis and guarantees they provide.
8598
+ * the $q service. While for simple usage patterns this doesn't matter much, for advanced usage
8599
+ * it is important to familiarize yourself with these APIs and the guarantees they provide.
8523
8600
  *
8524
8601
  *
8525
8602
  * # General usage
8526
- * The `$http` service is a function which takes a single argument — a configuration object —
8527
- * that is used to generate an http request and returns a {@link ng.$q promise}
8603
+ * The `$http` service is a function which takes a single argument a configuration object
8604
+ * that is used to generate an HTTP request and returns a {@link ng.$q promise}
8528
8605
  * with two $http specific methods: `success` and `error`.
8529
8606
  *
8530
8607
  * <pre>
@@ -8539,21 +8616,21 @@ function $HttpProvider() {
8539
8616
  * });
8540
8617
  * </pre>
8541
8618
  *
8542
- * Since the returned value of calling the $http function is a Promise object, you can also use
8543
- * the `then` method to register callbacks, and these callbacks will receive a single argument –
8544
- * an object representing the response. See the api signature and type info below for more
8619
+ * Since the returned value of calling the $http function is a `promise`, you can also use
8620
+ * the `then` method to register callbacks, and these callbacks will receive a single argument
8621
+ * an object representing the response. See the API signature and type info below for more
8545
8622
  * details.
8546
8623
  *
8547
- * A response status code that falls in the [200, 300) range is considered a success status and
8624
+ * A response status code between 200 and 299 is considered a success status and
8548
8625
  * will result in the success callback being called. Note that if the response is a redirect,
8549
8626
  * XMLHttpRequest will transparently follow it, meaning that the error callback will not be
8550
8627
  * called for such responses.
8551
8628
  *
8552
8629
  * # Shortcut methods
8553
8630
  *
8554
- * Since all invocation of the $http service require definition of the http method and url and
8555
- * POST and PUT requests require response body/data to be provided as well, shortcut methods
8556
- * were created to simplify using the api:
8631
+ * Since all invocations of the $http service require passing in an HTTP method and URL, and
8632
+ * POST/PUT requests require request data to be provided as well, shortcut methods
8633
+ * were created:
8557
8634
  *
8558
8635
  * <pre>
8559
8636
  * $http.get('/someUrl').success(successCallback);
@@ -8572,25 +8649,25 @@ function $HttpProvider() {
8572
8649
  *
8573
8650
  * # Setting HTTP Headers
8574
8651
  *
8575
- * The $http service will automatically add certain http headers to all requests. These defaults
8652
+ * The $http service will automatically add certain HTTP headers to all requests. These defaults
8576
8653
  * can be fully configured by accessing the `$httpProvider.defaults.headers` configuration
8577
8654
  * object, which currently contains this default configuration:
8578
8655
  *
8579
8656
  * - `$httpProvider.defaults.headers.common` (headers that are common for all requests):
8580
8657
  * - `Accept: application/json, text/plain, * / *`
8581
8658
  * - `X-Requested-With: XMLHttpRequest`
8582
- * - `$httpProvider.defaults.headers.post`: (header defaults for HTTP POST requests)
8659
+ * - `$httpProvider.defaults.headers.post`: (header defaults for POST requests)
8583
8660
  * - `Content-Type: application/json`
8584
- * - `$httpProvider.defaults.headers.put` (header defaults for HTTP PUT requests)
8661
+ * - `$httpProvider.defaults.headers.put` (header defaults for PUT requests)
8585
8662
  * - `Content-Type: application/json`
8586
8663
  *
8587
- * To add or overwrite these defaults, simply add or remove a property from this configuration
8664
+ * To add or overwrite these defaults, simply add or remove a property from these configuration
8588
8665
  * objects. To add headers for an HTTP method other than POST or PUT, simply add a new object
8589
- * with name equal to the lower-cased http method name, e.g.
8666
+ * with the lowercased HTTP method name as the key, e.g.
8590
8667
  * `$httpProvider.defaults.headers.get['My-Header']='value'`.
8591
8668
  *
8592
- * Additionally, the defaults can be set at runtime via the `$http.defaults` object in a similar
8593
- * fassion as described above.
8669
+ * Additionally, the defaults can be set at runtime via the `$http.defaults` object in the same
8670
+ * fashion.
8594
8671
  *
8595
8672
  *
8596
8673
  * # Transforming Requests and Responses
@@ -8600,32 +8677,36 @@ function $HttpProvider() {
8600
8677
  *
8601
8678
  * Request transformations:
8602
8679
  *
8603
- * - if the `data` property of the request config object contains an object, serialize it into
8680
+ * - If the `data` property of the request configuration object contains an object, serialize it into
8604
8681
  * JSON format.
8605
8682
  *
8606
8683
  * Response transformations:
8607
8684
  *
8608
- * - if XSRF prefix is detected, strip it (see Security Considerations section below)
8609
- * - if json response is detected, deserialize it using a JSON parser
8685
+ * - If XSRF prefix is detected, strip it (see Security Considerations section below).
8686
+ * - If JSON response is detected, deserialize it using a JSON parser.
8610
8687
  *
8611
- * To override these transformation locally, specify transform functions as `transformRequest`
8612
- * and/or `transformResponse` properties of the config object. To globally override the default
8613
- * transforms, override the `$httpProvider.defaults.transformRequest` and
8614
- * `$httpProvider.defaults.transformResponse` properties of the `$httpProvider`.
8688
+ * To globally augment or override the default transforms, modify the `$httpProvider.defaults.transformRequest` and
8689
+ * `$httpProvider.defaults.transformResponse` properties. These properties are by default an
8690
+ * array of transform functions, which allows you to `push` or `unshift` a new transformation function into the
8691
+ * transformation chain. You can also decide to completely override any default transformations by assigning your
8692
+ * transformation functions to these properties directly without the array wrapper.
8693
+ *
8694
+ * Similarly, to locally override the request/response transforms, augment the `transformRequest` and/or
8695
+ * `transformResponse` properties of the configuration object passed into `$http`.
8615
8696
  *
8616
8697
  *
8617
8698
  * # Caching
8618
8699
  *
8619
- * To enable caching set the configuration property `cache` to `true`. When the cache is
8700
+ * To enable caching, set the configuration property `cache` to `true`. When the cache is
8620
8701
  * enabled, `$http` stores the response from the server in local cache. Next time the
8621
8702
  * response is served from the cache without sending a request to the server.
8622
8703
  *
8623
8704
  * Note that even if the response is served from cache, delivery of the data is asynchronous in
8624
8705
  * the same way that real requests are.
8625
8706
  *
8626
- * If there are multiple GET requests for the same url that should be cached using the same
8707
+ * If there are multiple GET requests for the same URL that should be cached using the same
8627
8708
  * cache, but the cache is not populated yet, only one request to the server will be made and
8628
- * the remaining requests will be fulfilled using the response for the first request.
8709
+ * the remaining requests will be fulfilled using the response from the first request.
8629
8710
  *
8630
8711
  *
8631
8712
  * # Response interceptors
@@ -8641,7 +8722,7 @@ function $HttpProvider() {
8641
8722
  *
8642
8723
  * The interceptors are service factories that are registered with the $httpProvider by
8643
8724
  * adding them to the `$httpProvider.responseInterceptors` array. The factory is called and
8644
- * injected with dependencies (if specified) and returns the interceptor — a function that
8725
+ * injected with dependencies (if specified) and returns the interceptor a function that
8645
8726
  * takes a {@link ng.$q promise} and returns the original or a new promise.
8646
8727
  *
8647
8728
  * <pre>
@@ -8677,7 +8758,7 @@ function $HttpProvider() {
8677
8758
  * When designing web applications, consider security threats from:
8678
8759
  *
8679
8760
  * - {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx
8680
- * JSON Vulnerability}
8761
+ * JSON vulnerability}
8681
8762
  * - {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF}
8682
8763
  *
8683
8764
  * Both server and the client must cooperate in order to eliminate these threats. Angular comes
@@ -8687,8 +8768,8 @@ function $HttpProvider() {
8687
8768
  * ## JSON Vulnerability Protection
8688
8769
  *
8689
8770
  * A {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx
8690
- * JSON Vulnerability} allows third party web-site to turn your JSON resource URL into
8691
- * {@link http://en.wikipedia.org/wiki/JSON#JSONP JSONP} request under some conditions. To
8771
+ * JSON vulnerability} allows third party website to turn your JSON resource URL into
8772
+ * {@link http://en.wikipedia.org/wiki/JSONP JSONP} request under some conditions. To
8692
8773
  * counter this your server can prefix all JSON requests with following string `")]}',\n"`.
8693
8774
  * Angular will automatically strip the prefix before processing it as JSON.
8694
8775
  *
@@ -8709,41 +8790,41 @@ function $HttpProvider() {
8709
8790
  * ## Cross Site Request Forgery (XSRF) Protection
8710
8791
  *
8711
8792
  * {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF} is a technique by which
8712
- * an unauthorized site can gain your user's private data. Angular provides following mechanism
8793
+ * an unauthorized site can gain your user's private data. Angular provides a mechanism
8713
8794
  * to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie
8714
8795
  * called `XSRF-TOKEN` and sets it as the HTTP header `X-XSRF-TOKEN`. Since only JavaScript that
8715
8796
  * runs on your domain could read the cookie, your server can be assured that the XHR came from
8716
8797
  * JavaScript running on your domain.
8717
8798
  *
8718
8799
  * To take advantage of this, your server needs to set a token in a JavaScript readable session
8719
- * cookie called `XSRF-TOKEN` on first HTTP GET request. On subsequent non-GET requests the
8800
+ * cookie called `XSRF-TOKEN` on the first HTTP GET request. On subsequent XHR requests the
8720
8801
  * server can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure
8721
- * that only JavaScript running on your domain could have read the token. The token must be
8722
- * unique for each user and must be verifiable by the server (to prevent the JavaScript making
8802
+ * that only JavaScript running on your domain could have sent the request. The token must be
8803
+ * unique for each user and must be verifiable by the server (to prevent the JavaScript from making
8723
8804
  * up its own tokens). We recommend that the token is a digest of your site's authentication
8724
- * cookie with {@link http://en.wikipedia.org/wiki/Rainbow_table salt for added security}.
8805
+ * cookie with a {@link https://en.wikipedia.org/wiki/Salt_(cryptography) salt} for added security.
8725
8806
  *
8726
8807
  *
8727
8808
  * @param {object} config Object describing the request to be made and how it should be
8728
8809
  * processed. The object has following properties:
8729
8810
  *
8730
- * - **method** – `{string}` – HTTP method (e.g. 'GET', 'POST', etc)
8731
- * - **url** – `{string}` – Absolute or relative URL of the resource that is being requested.
8732
- * - **params** – `{Object.<string|Object>}` – Map of strings or objects which will be turned to
8811
+ * - **method** `{string}` HTTP method (e.g. 'GET', 'POST', etc)
8812
+ * - **url** `{string}` Absolute or relative URL of the resource that is being requested.
8813
+ * - **params** `{Object.<string|Object>}` Map of strings or objects which will be turned to
8733
8814
  * `?key1=value1&key2=value2` after the url. If the value is not a string, it will be JSONified.
8734
- * - **data** – `{string|Object}` – Data to be sent as the request message data.
8735
- * - **headers** – `{Object}` – Map of strings representing HTTP headers to send to the server.
8736
- * - **transformRequest** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
8815
+ * - **data** `{string|Object}` Data to be sent as the request message data.
8816
+ * - **headers** `{Object}` Map of strings representing HTTP headers to send to the server.
8817
+ * - **transformRequest** `{function(data, headersGetter)|Array.<function(data, headersGetter)>}`
8737
8818
  * transform function or an array of such functions. The transform function takes the http
8738
8819
  * request body and headers and returns its transformed (typically serialized) version.
8739
- * - **transformResponse** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
8820
+ * - **transformResponse** `{function(data, headersGetter)|Array.<function(data, headersGetter)>}`
8740
8821
  * transform function or an array of such functions. The transform function takes the http
8741
8822
  * response body and headers and returns its transformed (typically deserialized) version.
8742
- * - **cache** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
8823
+ * - **cache** `{boolean|Cache}` If true, a default $http cache will be used to cache the
8743
8824
  * GET request, otherwise if a cache instance built with
8744
8825
  * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
8745
8826
  * caching.
8746
- * - **timeout** – `{number}` – timeout in milliseconds.
8827
+ * - **timeout** `{number}` timeout in milliseconds.
8747
8828
  * - **withCredentials** - `{boolean}` - whether to to set the `withCredentials` flag on the
8748
8829
  * XHR object. See {@link https://developer.mozilla.org/en/http_access_control#section_5
8749
8830
  * requests with credentials} for more information.
@@ -8756,10 +8837,10 @@ function $HttpProvider() {
8756
8837
  * these functions are destructured representation of the response object passed into the
8757
8838
  * `then` method. The response object has these properties:
8758
8839
  *
8759
- * - **data** – `{string|Object}` – The response body transformed with the transform functions.
8760
- * - **status** – `{number}` – HTTP status code of the response.
8761
- * - **headers** – `{function([headerName])}` – Header getter function.
8762
- * - **config** – `{Object}` – The configuration object that was used to generate the request.
8840
+ * - **data** `{string|Object}` The response body transformed with the transform functions.
8841
+ * - **status** `{number}` HTTP status code of the response.
8842
+ * - **headers** `{function([headerName])}` Header getter function.
8843
+ * - **config** `{Object}` The configuration object that was used to generate the request.
8763
8844
  *
8764
8845
  * @property {Array.<Object>} pendingRequests Array of config objects for currently pending
8765
8846
  * requests. This is primarily meant to be used for debugging purposes.
@@ -8899,7 +8980,7 @@ function $HttpProvider() {
8899
8980
  * @methodOf ng.$http
8900
8981
  *
8901
8982
  * @description
8902
- * Shortcut method to perform `GET` request
8983
+ * Shortcut method to perform `GET` request.
8903
8984
  *
8904
8985
  * @param {string} url Relative or absolute URL specifying the destination of the request
8905
8986
  * @param {Object=} config Optional configuration object
@@ -8912,7 +8993,7 @@ function $HttpProvider() {
8912
8993
  * @methodOf ng.$http
8913
8994
  *
8914
8995
  * @description
8915
- * Shortcut method to perform `DELETE` request
8996
+ * Shortcut method to perform `DELETE` request.
8916
8997
  *
8917
8998
  * @param {string} url Relative or absolute URL specifying the destination of the request
8918
8999
  * @param {Object=} config Optional configuration object
@@ -8925,7 +9006,7 @@ function $HttpProvider() {
8925
9006
  * @methodOf ng.$http
8926
9007
  *
8927
9008
  * @description
8928
- * Shortcut method to perform `HEAD` request
9009
+ * Shortcut method to perform `HEAD` request.
8929
9010
  *
8930
9011
  * @param {string} url Relative or absolute URL specifying the destination of the request
8931
9012
  * @param {Object=} config Optional configuration object
@@ -8938,7 +9019,7 @@ function $HttpProvider() {
8938
9019
  * @methodOf ng.$http
8939
9020
  *
8940
9021
  * @description
8941
- * Shortcut method to perform `JSONP` request
9022
+ * Shortcut method to perform `JSONP` request.
8942
9023
  *
8943
9024
  * @param {string} url Relative or absolute URL specifying the destination of the request.
8944
9025
  * Should contain `JSON_CALLBACK` string.
@@ -8953,7 +9034,7 @@ function $HttpProvider() {
8953
9034
  * @methodOf ng.$http
8954
9035
  *
8955
9036
  * @description
8956
- * Shortcut method to perform `POST` request
9037
+ * Shortcut method to perform `POST` request.
8957
9038
  *
8958
9039
  * @param {string} url Relative or absolute URL specifying the destination of the request
8959
9040
  * @param {*} data Request content
@@ -8967,7 +9048,7 @@ function $HttpProvider() {
8967
9048
  * @methodOf ng.$http
8968
9049
  *
8969
9050
  * @description
8970
- * Shortcut method to perform `PUT` request
9051
+ * Shortcut method to perform `PUT` request.
8971
9052
  *
8972
9053
  * @param {string} url Relative or absolute URL specifying the destination of the request
8973
9054
  * @param {*} data Request content
@@ -9019,7 +9100,7 @@ function $HttpProvider() {
9019
9100
 
9020
9101
 
9021
9102
  /**
9022
- * Makes the request
9103
+ * Makes the request.
9023
9104
  *
9024
9105
  * !!! ACCESSES CLOSURE VARS:
9025
9106
  * $httpBackend, $config, $log, $rootScope, defaultCache, $http.pendingRequests
@@ -9129,6 +9210,7 @@ function $HttpProvider() {
9129
9210
 
9130
9211
  }];
9131
9212
  }
9213
+
9132
9214
  var XHR = window.XMLHttpRequest || function() {
9133
9215
  try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {}
9134
9216
  try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {}
@@ -9286,7 +9368,7 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
9286
9368
  * $locale service provides localization rules for various Angular components. As of right now the
9287
9369
  * only public api is:
9288
9370
  *
9289
- * * `id` – `{string}` – locale id formatted as `languageId-countryId` (e.g. `en-us`)
9371
+ * * `id` `{string}` locale id formatted as `languageId-countryId` (e.g. `en-us`)
9290
9372
  */
9291
9373
  function $LocaleProvider(){
9292
9374
  this.$get = function() {
@@ -9365,17 +9447,17 @@ function $TimeoutProvider() {
9365
9447
  * block and delegates any exceptions to
9366
9448
  * {@link ng.$exceptionHandler $exceptionHandler} service.
9367
9449
  *
9368
- * The return value of registering a timeout function is a promise which will be resolved when
9450
+ * The return value of registering a timeout function is a promise, which will be resolved when
9369
9451
  * the timeout is reached and the timeout function is executed.
9370
9452
  *
9371
- * To cancel a the timeout request, call `$timeout.cancel(promise)`.
9453
+ * To cancel a timeout request, call `$timeout.cancel(promise)`.
9372
9454
  *
9373
9455
  * In tests you can use {@link ngMock.$timeout `$timeout.flush()`} to
9374
9456
  * synchronously flush the queue of deferred functions.
9375
9457
  *
9376
- * @param {function()} fn A function, who's execution should be delayed.
9458
+ * @param {function()} fn A function, whose execution should be delayed.
9377
9459
  * @param {number=} [delay=0] Delay in milliseconds.
9378
- * @param {boolean=} [invokeApply=true] If set to false skips model dirty checking, otherwise
9460
+ * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
9379
9461
  * will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
9380
9462
  * @returns {Promise} Promise that will be resolved when the timeout is reached. The value this
9381
9463
  * promise will be resolved with is the return value of the `fn` function.
@@ -9415,7 +9497,7 @@ function $TimeoutProvider() {
9415
9497
  * @methodOf ng.$timeout
9416
9498
  *
9417
9499
  * @description
9418
- * Cancels a task associated with the `promise`. As a result of this the promise will be
9500
+ * Cancels a task associated with the `promise`. As a result of this, the promise will be
9419
9501
  * resolved with a rejection.
9420
9502
  *
9421
9503
  * @param {Promise=} promise Promise returned by the `$timeout` function.
@@ -9441,7 +9523,7 @@ function $TimeoutProvider() {
9441
9523
  *
9442
9524
  * Filters are just functions which transform input to an output. However filters need to be Dependency Injected. To
9443
9525
  * achieve this a filter definition consists of a factory function which is annotated with dependencies and is
9444
- * responsible for creating a the filter function.
9526
+ * responsible for creating a filter function.
9445
9527
  *
9446
9528
  * <pre>
9447
9529
  * // Filter registration
@@ -9503,7 +9585,7 @@ function $TimeoutProvider() {
9503
9585
  *
9504
9586
  * The general syntax in templates is as follows:
9505
9587
  *
9506
- * {{ expression | [ filter_name ] }}
9588
+ * {{ expression [| filter_name[:parameter_value] ... ] }}
9507
9589
  *
9508
9590
  * @param {String} name Name of the filter function to retrieve
9509
9591
  * @return {Function} the filter function
@@ -9579,22 +9661,22 @@ function $FilterProvider($provide) {
9579
9661
 
9580
9662
  Search: <input ng-model="searchText">
9581
9663
  <table id="searchTextResults">
9582
- <tr><th>Name</th><th>Phone</th><tr>
9664
+ <tr><th>Name</th><th>Phone</th></tr>
9583
9665
  <tr ng-repeat="friend in friends | filter:searchText">
9584
9666
  <td>{{friend.name}}</td>
9585
9667
  <td>{{friend.phone}}</td>
9586
- <tr>
9668
+ </tr>
9587
9669
  </table>
9588
9670
  <hr>
9589
9671
  Any: <input ng-model="search.$"> <br>
9590
9672
  Name only <input ng-model="search.name"><br>
9591
- Phone only <input ng-model="search.phone"Ã¥><br>
9673
+ Phone only <input ng-model="search.phone"><br>
9592
9674
  <table id="searchObjResults">
9593
- <tr><th>Name</th><th>Phone</th><tr>
9675
+ <tr><th>Name</th><th>Phone</th></tr>
9594
9676
  <tr ng-repeat="friend in friends | filter:search">
9595
9677
  <td>{{friend.name}}</td>
9596
9678
  <td>{{friend.phone}}</td>
9597
- <tr>
9679
+ </tr>
9598
9680
  </table>
9599
9681
  </doc:source>
9600
9682
  <doc:scenario>
@@ -9762,7 +9844,7 @@ function currencyFilter($locale) {
9762
9844
  *
9763
9845
  * @param {number|string} number Number to format.
9764
9846
  * @param {(number|string)=} [fractionSize=2] Number of decimal places to round the number to.
9765
- * @returns {string} Number rounded to decimalPlaces and places a “,” after each third digit.
9847
+ * @returns {string} Number rounded to decimalPlaces and places a “,” after each third digit.
9766
9848
  *
9767
9849
  * @example
9768
9850
  <doc:example>
@@ -9891,6 +9973,7 @@ function padNumber(num, digits, trim) {
9891
9973
 
9892
9974
 
9893
9975
  function dateGetter(name, size, offset, trim) {
9976
+ offset = offset || 0;
9894
9977
  return function(date) {
9895
9978
  var value = date['get' + name]();
9896
9979
  if (offset > 0 || value > -offset)
@@ -9913,7 +9996,8 @@ function timeZoneGetter(date) {
9913
9996
  var zone = -1 * date.getTimezoneOffset();
9914
9997
  var paddedZone = (zone >= 0) ? "+" : "";
9915
9998
 
9916
- paddedZone += padNumber(zone / 60, 2) + padNumber(Math.abs(zone % 60), 2);
9999
+ paddedZone += padNumber(Math[zone > 0 ? 'floor' : 'ceil'](zone / 60), 2) +
10000
+ padNumber(Math.abs(zone % 60), 2);
9917
10001
 
9918
10002
  return paddedZone;
9919
10003
  }
@@ -9979,7 +10063,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
9979
10063
  * * `'ss'`: Second in minute, padded (00-59)
9980
10064
  * * `'s'`: Second in minute (0-59)
9981
10065
  * * `'a'`: am/pm marker
9982
- * * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-1200)
10066
+ * * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-+1200)
9983
10067
  *
9984
10068
  * `format` string can also be one of the following predefined
9985
10069
  * {@link guide/i18n localizable formats}:
@@ -10000,7 +10084,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
10000
10084
  * (e.g. `"h o''clock"`).
10001
10085
  *
10002
10086
  * @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or
10003
- * number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.SSSZ and it's
10087
+ * number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.SSSZ and its
10004
10088
  * shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is
10005
10089
  * specified in the string input, the time is considered to be in the local timezone.
10006
10090
  * @param {string=} format Formatting rules (see Description). If not specified,
@@ -10291,12 +10375,12 @@ function limitToFilter(){
10291
10375
  (<a href ng-click="predicate = '-name'; reverse=false">^</a>)</th>
10292
10376
  <th><a href="" ng-click="predicate = 'phone'; reverse=!reverse">Phone Number</a></th>
10293
10377
  <th><a href="" ng-click="predicate = 'age'; reverse=!reverse">Age</a></th>
10294
- <tr>
10378
+ </tr>
10295
10379
  <tr ng-repeat="friend in friends | orderBy:predicate:reverse">
10296
10380
  <td>{{friend.name}}</td>
10297
10381
  <td>{{friend.phone}}</td>
10298
10382
  <td>{{friend.age}}</td>
10299
- <tr>
10383
+ </tr>
10300
10384
  </table>
10301
10385
  </div>
10302
10386
  </doc:source>
@@ -10765,7 +10849,7 @@ var nullFormCtrl = {
10765
10849
  * @property {Object} $error Is an object hash, containing references to all invalid controls or
10766
10850
  * forms, where:
10767
10851
  *
10768
- * - keys are validation tokens (error names) — such as `required`, `url` or `email`),
10852
+ * - keys are validation tokens (error names) such as `required`, `url` or `email`),
10769
10853
  * - values are arrays of controls or forms that are invalid with given error.
10770
10854
  *
10771
10855
  * @description
@@ -11118,8 +11202,8 @@ var inputType = {
11118
11202
  *
11119
11203
  * @param {string} ngModel Assignable angular expression to data-bind to.
11120
11204
  * @param {string=} name Property name of the form under which the control is published.
11121
- * @param {string=} min Sets the `min` validation error key if the value entered is less then `min`.
11122
- * @param {string=} max Sets the `max` validation error key if the value entered is greater then `min`.
11205
+ * @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
11206
+ * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
11123
11207
  * @param {string=} required Sets `required` validation error key if the value is not entered.
11124
11208
  * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
11125
11209
  * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
@@ -11431,6 +11515,15 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
11431
11515
  } else {
11432
11516
  var timeout;
11433
11517
 
11518
+ var deferListener = function() {
11519
+ if (!timeout) {
11520
+ timeout = $browser.defer(function() {
11521
+ listener();
11522
+ timeout = null;
11523
+ });
11524
+ }
11525
+ };
11526
+
11434
11527
  element.bind('keydown', function(event) {
11435
11528
  var key = event.keyCode;
11436
11529
 
@@ -11438,16 +11531,16 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
11438
11531
  // command modifiers arrows
11439
11532
  if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return;
11440
11533
 
11441
- if (!timeout) {
11442
- timeout = $browser.defer(function() {
11443
- listener();
11444
- timeout = null;
11445
- });
11446
- }
11534
+ deferListener();
11447
11535
  });
11448
11536
 
11449
11537
  // if user paste into input using mouse, we need "change" event to catch it
11450
11538
  element.bind('change', listener);
11539
+
11540
+ // if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it
11541
+ if ($sniffer.hasEvent('paste')) {
11542
+ element.bind('paste cut', deferListener);
11543
+ }
11451
11544
  }
11452
11545
 
11453
11546
 
@@ -11746,7 +11839,7 @@ function checkboxInputType(scope, element, attr, ctrl) {
11746
11839
  <tt>myForm.userName.$valid = {{myForm.userName.$valid}}</tt><br>
11747
11840
  <tt>myForm.userName.$error = {{myForm.userName.$error}}</tt><br>
11748
11841
  <tt>myForm.lastName.$valid = {{myForm.lastName.$valid}}</tt><br>
11749
- <tt>myForm.userName.$error = {{myForm.lastName.$error}}</tt><br>
11842
+ <tt>myForm.lastName.$error = {{myForm.lastName.$error}}</tt><br>
11750
11843
  <tt>myForm.$valid = {{myForm.$valid}}</tt><br>
11751
11844
  <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br>
11752
11845
  <tt>myForm.$error.minlength = {{!!myForm.$error.minlength}}</tt><br>
@@ -12009,7 +12102,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
12009
12102
  * For example {@link ng.directive:input input} or
12010
12103
  * {@link ng.directive:select select} directives call it.
12011
12104
  *
12012
- * It internally calls all `formatters` and if resulted value is valid, updates the model and
12105
+ * It internally calls all `parsers` and if resulted value is valid, updates the model and
12013
12106
  * calls all registered change listeners.
12014
12107
  *
12015
12108
  * @param {string} value Value from the view.
@@ -12315,7 +12408,7 @@ var ngValueDirective = function() {
12315
12408
  * Typically, you don't use `ngBind` directly, but instead you use the double curly markup like
12316
12409
  * `{{ expression }}` which is similar but less verbose.
12317
12410
  *
12318
- * Once scenario in which the use of `ngBind` is prefered over `{{ expression }}` binding is when
12411
+ * One scenario in which the use of `ngBind` is preferred over `{{ expression }}` binding is when
12319
12412
  * it's desirable to put bindings into template that is momentarily displayed by the browser in its
12320
12413
  * raw state before Angular compiles it. Since `ngBind` is an element attribute, it makes the
12321
12414
  * bindings invisible to the user while the page is loading.
@@ -12456,9 +12549,9 @@ function classDirective(name, selector) {
12456
12549
 
12457
12550
  if (name !== 'ngClass') {
12458
12551
  scope.$watch('$index', function($index, old$index) {
12459
- var mod = $index % 2;
12460
- if (mod !== old$index % 2) {
12461
- if (mod == selector) {
12552
+ var mod = $index & 1;
12553
+ if (mod !== old$index & 1) {
12554
+ if (mod === selector) {
12462
12555
  addClass(scope.$eval(attr[name]));
12463
12556
  } else {
12464
12557
  removeClass(scope.$eval(attr[name]));
@@ -12470,12 +12563,12 @@ function classDirective(name, selector) {
12470
12563
 
12471
12564
  function ngClassWatchAction(newVal) {
12472
12565
  if (selector === true || scope.$index % 2 === selector) {
12473
- if (oldVal && (newVal !== oldVal)) {
12566
+ if (oldVal && !equals(newVal,oldVal)) {
12474
12567
  removeClass(oldVal);
12475
12568
  }
12476
12569
  addClass(newVal);
12477
12570
  }
12478
- oldVal = newVal;
12571
+ oldVal = copy(newVal);
12479
12572
  }
12480
12573
 
12481
12574
 
@@ -12601,7 +12694,7 @@ var ngClassOddDirective = classDirective('Odd', 0);
12601
12694
  * @name ng.directive:ngClassEven
12602
12695
  *
12603
12696
  * @description
12604
- * The `ngClassOdd` and `ngClassEven` works exactly as
12697
+ * The `ngClassOdd` and `ngClassEven` directives work exactly as
12605
12698
  * {@link ng.directive:ngClass ngClass}, except it works in
12606
12699
  * conjunction with `ngRepeat` and takes affect only on odd (even) rows.
12607
12700
  *
@@ -12659,7 +12752,7 @@ var ngClassEvenDirective = classDirective('Even', 1);
12659
12752
  * `angular.min.js` files. Following is the css rule:
12660
12753
  *
12661
12754
  * <pre>
12662
- * [ng\:cloak], [ng-cloak], .ng-cloak {
12755
+ * [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
12663
12756
  * display: none;
12664
12757
  * }
12665
12758
  * </pre>
@@ -12713,13 +12806,12 @@ var ngCloakDirective = ngDirective({
12713
12806
  *
12714
12807
  * MVC components in angular:
12715
12808
  *
12716
- * * Model — The Model is data in scope properties; scopes are attached to the DOM.
12717
- * * View — The template (HTML with data bindings) is rendered into the View.
12718
- * * Controller — The `ngController` directive specifies a Controller class; the class has
12809
+ * * Model The Model is data in scope properties; scopes are attached to the DOM.
12810
+ * * View The template (HTML with data bindings) is rendered into the View.
12811
+ * * Controller The `ngController` directive specifies a Controller class; the class has
12719
12812
  * methods that typically express the business logic behind the application.
12720
12813
  *
12721
- * Note that an alternative way to define controllers is via the `{@link ng.$route}`
12722
- * service.
12814
+ * Note that an alternative way to define controllers is via the {@link ng.$route $route} service.
12723
12815
  *
12724
12816
  * @element ANY
12725
12817
  * @scope
@@ -12810,16 +12902,32 @@ var ngControllerDirective = [function() {
12810
12902
  * @name ng.directive:ngCsp
12811
12903
  * @priority 1000
12812
12904
  *
12905
+ * @element html
12813
12906
  * @description
12814
12907
  * Enables [CSP (Content Security Policy)](https://developer.mozilla.org/en/Security/CSP) support.
12815
- * This directive should be used on the root element of the application (typically the `<html>`
12816
- * element or other element with the {@link ng.directive:ngApp ngApp}
12817
- * directive).
12818
12908
  *
12819
- * If enabled the performance of template expression evaluator will suffer slightly, so don't enable
12820
- * this mode unless you need it.
12909
+ * This is necessary when developing things like Google Chrome Extensions.
12821
12910
  *
12822
- * @element html
12911
+ * CSP forbids apps to use `eval` or `Function(string)` generated functions (among other things).
12912
+ * For us to be compatible, we just need to implement the "getterFn" in $parse without violating
12913
+ * any of these restrictions.
12914
+ *
12915
+ * AngularJS uses `Function(string)` generated functions as a speed optimization. By applying `ngCsp`
12916
+ * it is be possible to opt into the CSP compatible mode. When this mode is on AngularJS will
12917
+ * evaluate all expressions up to 30% slower than in non-CSP mode, but no security violations will
12918
+ * be raised.
12919
+ *
12920
+ * In order to use this feature put `ngCsp` directive on the root element of the application.
12921
+ *
12922
+ * @example
12923
+ * This example shows how to apply the `ngCsp` directive to the `html` tag.
12924
+ <pre>
12925
+ <!doctype html>
12926
+ <html ng-app ng-csp>
12927
+ ...
12928
+ ...
12929
+ </html>
12930
+ </pre>
12823
12931
  */
12824
12932
 
12825
12933
  var ngCspDirective = ['$sniffer', function($sniffer) {
@@ -13444,7 +13552,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
13444
13552
  if (!isNaN(value)) {
13445
13553
  //if explicit number rule such as 1, 2, 3... is defined, just use it. Otherwise,
13446
13554
  //check it against pluralization rules in $locale service
13447
- if (!whens[value]) value = $locale.pluralCat(value - offset);
13555
+ if (!(value in whens)) value = $locale.pluralCat(value - offset);
13448
13556
  return whensExpFns[value](scope, element, true);
13449
13557
  } else {
13450
13558
  return '';
@@ -13467,10 +13575,10 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
13467
13575
  *
13468
13576
  * Special properties are exposed on the local scope of each template instance, including:
13469
13577
  *
13470
- * * `$index` – `{number}` – iterator offset of the repeated element (0..length-1)
13471
- * * `$first` – `{boolean}` – true if the repeated element is first in the iterator.
13472
- * * `$middle` – `{boolean}` – true if the repeated element is between the first and last in the iterator.
13473
- * * `$last` – `{boolean}` – true if the repeated element is last in the iterator.
13578
+ * * `$index` `{number}` iterator offset of the repeated element (0..length-1)
13579
+ * * `$first` `{boolean}` true if the repeated element is first in the iterator.
13580
+ * * `$middle` `{boolean}` true if the repeated element is between the first and last in the iterator.
13581
+ * * `$last` `{boolean}` true if the repeated element is last in the iterator.
13474
13582
  *
13475
13583
  *
13476
13584
  * @element ANY
@@ -13479,12 +13587,12 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
13479
13587
  * @param {repeat_expression} ngRepeat The expression indicating how to enumerate a collection. Two
13480
13588
  * formats are currently supported:
13481
13589
  *
13482
- * * `variable in expression` – where variable is the user defined loop variable and `expression`
13590
+ * * `variable in expression` where variable is the user defined loop variable and `expression`
13483
13591
  * is a scope expression giving the collection to enumerate.
13484
13592
  *
13485
13593
  * For example: `track in cd.tracks`.
13486
13594
  *
13487
- * * `(key, value) in expression` – where `key` and `value` can be any user defined identifiers,
13595
+ * * `(key, value) in expression` where `key` and `value` can be any user defined identifiers,
13488
13596
  * and `expression` is the scope expression giving the collection to enumerate.
13489
13597
  *
13490
13598
  * For example: `(name, age) in {'adam':10, 'amalie':12}`.
@@ -13552,7 +13660,7 @@ var ngRepeatDirective = ngDirective({
13552
13660
  // Same as lastOrder but it has the current state. It will become the
13553
13661
  // lastOrder on the next iteration.
13554
13662
  nextOrder = new HashQueueMap(),
13555
- arrayLength,
13663
+ arrayBound,
13556
13664
  childScope,
13557
13665
  key, value, // key/value of iteration
13558
13666
  array,
@@ -13573,7 +13681,7 @@ var ngRepeatDirective = ngDirective({
13573
13681
  array = collection || [];
13574
13682
  }
13575
13683
 
13576
- arrayLength = array.length;
13684
+ arrayBound = array.length-1;
13577
13685
 
13578
13686
  // we are not using forEach for perf reasons (trying to avoid #call)
13579
13687
  for (index = 0, length = array.length; index < length; index++) {
@@ -13610,7 +13718,7 @@ var ngRepeatDirective = ngDirective({
13610
13718
  childScope.$index = index;
13611
13719
 
13612
13720
  childScope.$first = (index === 0);
13613
- childScope.$last = (index === (arrayLength - 1));
13721
+ childScope.$last = (index === arrayBound);
13614
13722
  childScope.$middle = !(childScope.$first || childScope.$last);
13615
13723
 
13616
13724
  if (!last) {
@@ -13777,11 +13885,13 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
13777
13885
  * @description
13778
13886
  * Conditionally change the DOM structure.
13779
13887
  *
13780
- * @usageContent
13781
- * <ANY ng-switch-when="matchValue1">...</ANY>
13888
+ * @usage
13889
+ * <ANY ng-switch="expression">
13890
+ * <ANY ng-switch-when="matchValue1">...</ANY>
13782
13891
  * <ANY ng-switch-when="matchValue2">...</ANY>
13783
13892
  * ...
13784
13893
  * <ANY ng-switch-default>...</ANY>
13894
+ * </ANY>
13785
13895
  *
13786
13896
  * @scope
13787
13897
  * @param {*} ngSwitch|on expression to match against <tt>ng-switch-when</tt>.
@@ -14161,7 +14271,7 @@ var scriptDirective = ['$templateCache', function($templateCache) {
14161
14271
  * Optionally `ngOptions` attribute can be used to dynamically generate a list of `<option>`
14162
14272
  * elements for a `<select>` element using an array or an object obtained by evaluating the
14163
14273
  * `ngOptions` expression.
14164
- *˝˝
14274
+ *˝˝
14165
14275
  * When an item in the select menu is select, the value of array element or object property
14166
14276
  * represented by the selected option will be bound to the model identified by the `ngModel`
14167
14277
  * directive of the parent select element.
@@ -14175,7 +14285,8 @@ var scriptDirective = ['$templateCache', function($templateCache) {
14175
14285
  * `select` model to be bound to a non-string value. This is because an option element can currently
14176
14286
  * be bound to string values only.
14177
14287
  *
14178
- * @param {string} name assignable expression to data-bind to.
14288
+ * @param {string} ngModel Assignable angular expression to data-bind to.
14289
+ * @param {string=} name Property name of the form under which the control is published.
14179
14290
  * @param {string=} required The control is considered valid only if value is entered.
14180
14291
  * @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
14181
14292
  * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
@@ -14270,7 +14381,7 @@ var scriptDirective = ['$templateCache', function($templateCache) {
14270
14381
 
14271
14382
  var ngOptionsDirective = valueFn({ terminal: true });
14272
14383
  var selectDirective = ['$compile', '$parse', function($compile, $parse) {
14273
- //00001111100000000000222200000000000000000000003333000000000000044444444444444444000000000555555555555555550000000666666666666666660000000000000007777
14384
+ //0000111110000000000022220000000000000000000000333300000000000000444444444444444440000000005555555555555555500000006666666666666666600000000000000077770
14274
14385
  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+(.*)$/,
14275
14386
  nullModelCtrl = {$setViewValue: noop};
14276
14387
 
@@ -14542,10 +14653,6 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
14542
14653
 
14543
14654
  if (multiple) {
14544
14655
  selectedSet = new HashMap(modelValue);
14545
- } else if (modelValue === null || nullOption) {
14546
- // if we are not multiselect, and we are null then we have to add the nullOption
14547
- optionGroups[''].push({selected:modelValue === null, id:'', label:''});
14548
- selectedSet = true;
14549
14656
  }
14550
14657
 
14551
14658
  // We now build up the list of options we need (we merge later)
@@ -14570,9 +14677,14 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
14570
14677
  selected: selected // determine if we should be selected
14571
14678
  });
14572
14679
  }
14573
- if (!multiple && !selectedSet) {
14574
- // nothing was selected, we have to insert the undefined item
14575
- optionGroups[''].unshift({id:'?', label:'', selected:true});
14680
+ if (!multiple) {
14681
+ if (nullOption || modelValue === null) {
14682
+ // insert null option if we have a placeholder, or the model is null
14683
+ optionGroups[''].unshift({id:'', label:'', selected:!selectedSet});
14684
+ } else if (!selectedSet) {
14685
+ // option could not be found, we have to insert the undefined item
14686
+ optionGroups[''].unshift({id:'?', label:'', selected:true});
14687
+ }
14576
14688
  }
14577
14689
 
14578
14690
  // Now we need to update the list of DOM nodes to match the optionGroups we computed above
@@ -14616,7 +14728,8 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
14616
14728
  if (existingOption.id !== option.id) {
14617
14729
  lastElement.val(existingOption.id = option.id);
14618
14730
  }
14619
- if (existingOption.element.selected !== option.selected) {
14731
+ // lastElement.prop('selected') provided by jQuery has side-effects
14732
+ if (lastElement[0].selected !== option.selected) {
14620
14733
  lastElement.prop('selected', (existingOption.selected = option.selected));
14621
14734
  }
14622
14735
  } else {
@@ -14719,6 +14832,7 @@ var styleDirective = valueFn({
14719
14832
  restrict: 'E',
14720
14833
  terminal: true
14721
14834
  });
14835
+
14722
14836
  //try to bind to jquery now so that one can write angular.element().read()
14723
14837
  //but we will rebind on bootstrap again.
14724
14838
  bindJQuery();