rails-angularjs 1.4.0.pre.rc.1 → 1.4.0.pre.rc.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rails-angularjs/version.rb +1 -1
  3. data/vendor/assets/javascripts/angular-animate.js +247 -159
  4. data/vendor/assets/javascripts/angular-animate.min.js +45 -44
  5. data/vendor/assets/javascripts/angular-animate.min.js.map +3 -3
  6. data/vendor/assets/javascripts/angular-aria.js +1 -1
  7. data/vendor/assets/javascripts/angular-aria.min.js +1 -1
  8. data/vendor/assets/javascripts/angular-cookies.js +1 -1
  9. data/vendor/assets/javascripts/angular-cookies.min.js +1 -1
  10. data/vendor/assets/javascripts/angular-loader.js +2 -2
  11. data/vendor/assets/javascripts/angular-loader.min.js +2 -2
  12. data/vendor/assets/javascripts/angular-message-format.js +1 -1
  13. data/vendor/assets/javascripts/angular-message-format.min.js +1 -1
  14. data/vendor/assets/javascripts/angular-messages.js +1 -1
  15. data/vendor/assets/javascripts/angular-messages.min.js +1 -1
  16. data/vendor/assets/javascripts/angular-mocks.js +1 -1
  17. data/vendor/assets/javascripts/angular-resource.js +3 -3
  18. data/vendor/assets/javascripts/angular-resource.min.js +8 -8
  19. data/vendor/assets/javascripts/angular-resource.min.js.map +1 -1
  20. data/vendor/assets/javascripts/angular-route.js +1 -1
  21. data/vendor/assets/javascripts/angular-route.min.js +1 -1
  22. data/vendor/assets/javascripts/angular-sanitize.js +1 -1
  23. data/vendor/assets/javascripts/angular-sanitize.min.js +1 -1
  24. data/vendor/assets/javascripts/angular-scenario.js +316 -143
  25. data/vendor/assets/javascripts/angular-touch.js +12 -10
  26. data/vendor/assets/javascripts/angular-touch.min.js +8 -8
  27. data/vendor/assets/javascripts/angular-touch.min.js.map +2 -2
  28. data/vendor/assets/javascripts/angular.js +316 -143
  29. data/vendor/assets/javascripts/angular.min.js +267 -265
  30. data/vendor/assets/javascripts/angular.min.js.map +3 -3
  31. metadata +2 -3
@@ -9190,7 +9190,7 @@ return jQuery;
9190
9190
  }));
9191
9191
 
9192
9192
  /**
9193
- * @license AngularJS v1.4.0-rc.1
9193
+ * @license AngularJS v1.4.0-rc.2
9194
9194
  * (c) 2010-2015 Google, Inc. http://angularjs.org
9195
9195
  * License: MIT
9196
9196
  */
@@ -9249,7 +9249,7 @@ function minErr(module, ErrorConstructor) {
9249
9249
  return match;
9250
9250
  });
9251
9251
 
9252
- message += '\nhttp://errors.angularjs.org/1.4.0-rc.1/' +
9252
+ message += '\nhttp://errors.angularjs.org/1.4.0-rc.2/' +
9253
9253
  (module ? module + '/' : '') + code;
9254
9254
 
9255
9255
  for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
@@ -9297,6 +9297,7 @@ function minErr(module, ErrorConstructor) {
9297
9297
  isUndefined: true,
9298
9298
  isDefined: true,
9299
9299
  isObject: true,
9300
+ isBlankObject: true,
9300
9301
  isString: true,
9301
9302
  isNumber: true,
9302
9303
  isDate: true,
@@ -9436,6 +9437,7 @@ var
9436
9437
  splice = [].splice,
9437
9438
  push = [].push,
9438
9439
  toString = Object.prototype.toString,
9440
+ getPrototypeOf = Object.getPrototypeOf,
9439
9441
  ngMinErr = minErr('ng'),
9440
9442
 
9441
9443
  /** @name angular */
@@ -9461,7 +9463,9 @@ function isArrayLike(obj) {
9461
9463
  return false;
9462
9464
  }
9463
9465
 
9464
- var length = obj.length;
9466
+ // Support: iOS 8.2 (not reproducible in simulator)
9467
+ // "length" in obj used to prevent JIT error (gh-11508)
9468
+ var length = "length" in Object(obj) && obj.length;
9465
9469
 
9466
9470
  if (obj.nodeType === NODE_TYPE_ELEMENT && length) {
9467
9471
  return true;
@@ -9526,12 +9530,25 @@ function forEach(obj, iterator, context) {
9526
9530
  }
9527
9531
  } else if (obj.forEach && obj.forEach !== forEach) {
9528
9532
  obj.forEach(iterator, context, obj);
9529
- } else {
9533
+ } else if (isBlankObject(obj)) {
9534
+ // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
9535
+ for (key in obj) {
9536
+ iterator.call(context, obj[key], key, obj);
9537
+ }
9538
+ } else if (typeof obj.hasOwnProperty === 'function') {
9539
+ // Slow path for objects inheriting Object.prototype, hasOwnProperty check needed
9530
9540
  for (key in obj) {
9531
9541
  if (obj.hasOwnProperty(key)) {
9532
9542
  iterator.call(context, obj[key], key, obj);
9533
9543
  }
9534
9544
  }
9545
+ } else {
9546
+ // Slow path for objects which do not have a method `hasOwnProperty`
9547
+ for (key in obj) {
9548
+ if (hasOwnProperty.call(obj, key)) {
9549
+ iterator.call(context, obj[key], key, obj);
9550
+ }
9551
+ }
9535
9552
  }
9536
9553
  }
9537
9554
  return obj;
@@ -9757,6 +9774,16 @@ function isObject(value) {
9757
9774
  }
9758
9775
 
9759
9776
 
9777
+ /**
9778
+ * Determine if a value is an object with a null prototype
9779
+ *
9780
+ * @returns {boolean} True if `value` is an `Object` with a null prototype
9781
+ */
9782
+ function isBlankObject(value) {
9783
+ return value !== null && typeof value === 'object' && !getPrototypeOf(value);
9784
+ }
9785
+
9786
+
9760
9787
  /**
9761
9788
  * @ngdoc function
9762
9789
  * @name angular.isString
@@ -10040,7 +10067,7 @@ function copy(source, destination, stackSource, stackDest) {
10040
10067
  destination = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]);
10041
10068
  destination.lastIndex = source.lastIndex;
10042
10069
  } else if (isObject(source)) {
10043
- var emptyObject = Object.create(Object.getPrototypeOf(source));
10070
+ var emptyObject = Object.create(getPrototypeOf(source));
10044
10071
  destination = copy(source, emptyObject, stackSource, stackDest);
10045
10072
  }
10046
10073
  }
@@ -10059,7 +10086,7 @@ function copy(source, destination, stackSource, stackDest) {
10059
10086
  stackDest.push(destination);
10060
10087
  }
10061
10088
 
10062
- var result;
10089
+ var result, key;
10063
10090
  if (isArray(source)) {
10064
10091
  destination.length = 0;
10065
10092
  for (var i = 0; i < source.length; i++) {
@@ -10079,21 +10106,40 @@ function copy(source, destination, stackSource, stackDest) {
10079
10106
  delete destination[key];
10080
10107
  });
10081
10108
  }
10082
- for (var key in source) {
10083
- if (source.hasOwnProperty(key)) {
10084
- result = copy(source[key], null, stackSource, stackDest);
10085
- if (isObject(source[key])) {
10086
- stackSource.push(source[key]);
10087
- stackDest.push(result);
10109
+ if (isBlankObject(source)) {
10110
+ // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
10111
+ for (key in source) {
10112
+ putValue(key, source[key], destination, stackSource, stackDest);
10113
+ }
10114
+ } else if (source && typeof source.hasOwnProperty === 'function') {
10115
+ // Slow path, which must rely on hasOwnProperty
10116
+ for (key in source) {
10117
+ if (source.hasOwnProperty(key)) {
10118
+ putValue(key, source[key], destination, stackSource, stackDest);
10119
+ }
10120
+ }
10121
+ } else {
10122
+ // Slowest path --- hasOwnProperty can't be called as a method
10123
+ for (key in source) {
10124
+ if (hasOwnProperty.call(source, key)) {
10125
+ putValue(key, source[key], destination, stackSource, stackDest);
10088
10126
  }
10089
- destination[key] = result;
10090
10127
  }
10091
10128
  }
10092
10129
  setHashKey(destination,h);
10093
10130
  }
10094
-
10095
10131
  }
10096
10132
  return destination;
10133
+
10134
+ function putValue(key, val, destination, stackSource, stackDest) {
10135
+ // No context allocation, trivial outer scope, easily inlined
10136
+ var result = copy(val, null, stackSource, stackDest);
10137
+ if (isObject(val)) {
10138
+ stackSource.push(val);
10139
+ stackDest.push(result);
10140
+ }
10141
+ destination[key] = result;
10142
+ }
10097
10143
  }
10098
10144
 
10099
10145
  /**
@@ -10174,14 +10220,14 @@ function equals(o1, o2) {
10174
10220
  } else {
10175
10221
  if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) ||
10176
10222
  isArray(o2) || isDate(o2) || isRegExp(o2)) return false;
10177
- keySet = {};
10223
+ keySet = createMap();
10178
10224
  for (key in o1) {
10179
10225
  if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
10180
10226
  if (!equals(o1[key], o2[key])) return false;
10181
10227
  keySet[key] = true;
10182
10228
  }
10183
10229
  for (key in o2) {
10184
- if (!keySet.hasOwnProperty(key) &&
10230
+ if (!(key in keySet) &&
10185
10231
  key.charAt(0) !== '$' &&
10186
10232
  o2[key] !== undefined &&
10187
10233
  !isFunction(o2[key])) return false;
@@ -10218,17 +10264,17 @@ var csp = function() {
10218
10264
  * @name ngJq
10219
10265
  *
10220
10266
  * @element ANY
10221
- * @param {string=} the name of the library available under `window`
10267
+ * @param {string=} ngJq the name of the library available under `window`
10222
10268
  * to be used for angular.element
10223
10269
  * @description
10224
10270
  * Use this directive to force the angular.element library. This should be
10225
10271
  * used to force either jqLite by leaving ng-jq blank or setting the name of
10226
10272
  * the jquery variable under window (eg. jQuery).
10227
10273
  *
10228
- * Since this directive is global for the angular library, it is recommended
10229
- * that it's added to the same element as ng-app or the HTML element, but it is not mandatory.
10230
- * It needs to be noted that only the first instance of `ng-jq` will be used and all others
10231
- * ignored.
10274
+ * Since angular looks for this directive when it is loaded (doesn't wait for the
10275
+ * DOMContentLoaded event), it must be placed on an element that comes before the script
10276
+ * which loads angular. Also, only the first instance of `ng-jq` will be used and all
10277
+ * others ignored.
10232
10278
  *
10233
10279
  * @example
10234
10280
  * This example shows how to force jqLite using the `ngJq` directive to the `html` tag.
@@ -11478,11 +11524,11 @@ function toDebugString(obj) {
11478
11524
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
11479
11525
  */
11480
11526
  var version = {
11481
- full: '1.4.0-rc.1', // all of these placeholder strings will be replaced by grunt's
11527
+ full: '1.4.0-rc.2', // all of these placeholder strings will be replaced by grunt's
11482
11528
  major: 1, // package task
11483
11529
  minor: 4,
11484
11530
  dot: 0,
11485
- codeName: 'sartorial-chronography'
11531
+ codeName: 'rocket-zambonimation'
11486
11532
  };
11487
11533
 
11488
11534
 
@@ -11665,7 +11711,7 @@ function publishExternalAPI(angular) {
11665
11711
  * Angular to manipulate the DOM in a cross-browser compatible way. **jqLite** implements only the most
11666
11712
  * commonly needed functionality with the goal of having a very small footprint.</div>
11667
11713
  *
11668
- * To use jQuery, simply load it before `DOMContentLoaded` event fired.
11714
+ * To use `jQuery`, simply ensure it is loaded before the `angular.js` file.
11669
11715
  *
11670
11716
  * <div class="alert">**Note:** all element references in Angular are always wrapped with jQuery or
11671
11717
  * jqLite; they are never raw DOM references.</div>
@@ -11681,7 +11727,7 @@ function publishExternalAPI(angular) {
11681
11727
  * - [`children()`](http://api.jquery.com/children/) - Does not support selectors
11682
11728
  * - [`clone()`](http://api.jquery.com/clone/)
11683
11729
  * - [`contents()`](http://api.jquery.com/contents/)
11684
- * - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyle()`
11730
+ * - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyle()`. As a setter, does not convert numbers to strings or append 'px'.
11685
11731
  * - [`data()`](http://api.jquery.com/data/)
11686
11732
  * - [`detach()`](http://api.jquery.com/detach/)
11687
11733
  * - [`empty()`](http://api.jquery.com/empty/)
@@ -12925,7 +12971,7 @@ function annotate(fn, strictDi, name) {
12925
12971
  * Return an instance of the service.
12926
12972
  *
12927
12973
  * @param {string} name The name of the instance to retrieve.
12928
- * @param {string} caller An optional string to provide the origin of the function call for error messages.
12974
+ * @param {string=} caller An optional string to provide the origin of the function call for error messages.
12929
12975
  * @return {*} The instance.
12930
12976
  */
12931
12977
 
@@ -12936,8 +12982,8 @@ function annotate(fn, strictDi, name) {
12936
12982
  * @description
12937
12983
  * Invoke the method and supply the method arguments from the `$injector`.
12938
12984
  *
12939
- * @param {!Function} fn The function to invoke. Function parameters are injected according to the
12940
- * {@link guide/di $inject Annotation} rules.
12985
+ * @param {Function|Array.<string|Function>} fn The injectable function to invoke. Function parameters are
12986
+ * injected according to the {@link guide/di $inject Annotation} rules.
12941
12987
  * @param {Object=} self The `this` for the invoked method.
12942
12988
  * @param {Object=} locals Optional object. If preset then any argument names are read from this
12943
12989
  * object first, before the `$injector` is consulted.
@@ -13204,8 +13250,8 @@ function annotate(fn, strictDi, name) {
13204
13250
  * configure your service in a provider.
13205
13251
  *
13206
13252
  * @param {string} name The name of the instance.
13207
- * @param {function()} $getFn The $getFn for the instance creation. Internally this is a short hand
13208
- * for `$provide.provider(name, {$get: $getFn})`.
13253
+ * @param {Function|Array.<string|Function>} $getFn The injectable $getFn for the instance creation.
13254
+ * Internally this is a short hand for `$provide.provider(name, {$get: $getFn})`.
13209
13255
  * @returns {Object} registered provider instance
13210
13256
  *
13211
13257
  * @example
@@ -13240,7 +13286,8 @@ function annotate(fn, strictDi, name) {
13240
13286
  * as a type/class.
13241
13287
  *
13242
13288
  * @param {string} name The name of the instance.
13243
- * @param {Function} constructor A class (constructor function) that will be instantiated.
13289
+ * @param {Function|Array.<string|Function>} constructor An injectable class (constructor function)
13290
+ * that will be instantiated.
13244
13291
  * @returns {Object} registered provider instance
13245
13292
  *
13246
13293
  * @example
@@ -13339,7 +13386,7 @@ function annotate(fn, strictDi, name) {
13339
13386
  * object which replaces or wraps and delegates to the original service.
13340
13387
  *
13341
13388
  * @param {string} name The name of the service to decorate.
13342
- * @param {function()} decorator This function will be invoked when the service needs to be
13389
+ * @param {Function|Array.<string|Function>} decorator This function will be invoked when the service needs to be
13343
13390
  * instantiated and should return the decorated service instance. The function is called using
13344
13391
  * the {@link auto.$injector#invoke injector.invoke} method and is therefore fully injectable.
13345
13392
  * Local injection arguments:
@@ -13868,6 +13915,7 @@ function $AnchorScrollProvider() {
13868
13915
 
13869
13916
  var $animateMinErr = minErr('$animate');
13870
13917
  var ELEMENT_NODE = 1;
13918
+ var NG_ANIMATE_CLASSNAME = 'ng-animate';
13871
13919
 
13872
13920
  function mergeClasses(a,b) {
13873
13921
  if (!a && !b) return '';
@@ -13892,7 +13940,9 @@ function splitClasses(classes) {
13892
13940
  classes = classes.split(' ');
13893
13941
  }
13894
13942
 
13895
- var obj = {};
13943
+ // Use createMap() to prevent class assumptions involving property names in
13944
+ // Object.prototype
13945
+ var obj = createMap();
13896
13946
  forEach(classes, function(klass) {
13897
13947
  // sometimes the split leaves empty string values
13898
13948
  // incase extra spaces were applied to the options
@@ -14097,6 +14147,13 @@ var $AnimateProvider = ['$provide', function($provide) {
14097
14147
  this.classNameFilter = function(expression) {
14098
14148
  if (arguments.length === 1) {
14099
14149
  this.$$classNameFilter = (expression instanceof RegExp) ? expression : null;
14150
+ if (this.$$classNameFilter) {
14151
+ var reservedRegex = new RegExp("(\\s+|\\/)" + NG_ANIMATE_CLASSNAME + "(\\s+|\\/)");
14152
+ if (reservedRegex.test(this.$$classNameFilter.toString())) {
14153
+ throw $animateMinErr('nongcls','$animateProvider.classNameFilter(regex) prohibits accepting a regex value which matches/contains the "{0}" CSS class.', NG_ANIMATE_CLASSNAME);
14154
+
14155
+ }
14156
+ }
14100
14157
  }
14101
14158
  return this.$$classNameFilter;
14102
14159
  };
@@ -15995,6 +16052,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15995
16052
  if (!letter || letter !== lowercase(letter)) {
15996
16053
  throw $compileMinErr('baddir', "Directive name '{0}' is invalid. The first character must be a lowercase letter", name);
15997
16054
  }
16055
+ if (name !== name.trim()) {
16056
+ throw $compileMinErr('baddir',
16057
+ "Directive name '{0}' is invalid. The name should not contain leading or trailing whitespaces",
16058
+ name);
16059
+ }
15998
16060
  }
15999
16061
 
16000
16062
  /**
@@ -18179,34 +18241,14 @@ var JSON_ENDS = {
18179
18241
  };
18180
18242
  var JSON_PROTECTION_PREFIX = /^\)\]\}',?\n/;
18181
18243
 
18182
- function paramSerializerFactory(jQueryMode) {
18183
-
18184
- function serializeValue(v) {
18185
- if (isObject(v)) {
18186
- return isDate(v) ? v.toISOString() : toJson(v);
18187
- }
18188
- return v;
18244
+ function serializeValue(v) {
18245
+ if (isObject(v)) {
18246
+ return isDate(v) ? v.toISOString() : toJson(v);
18189
18247
  }
18190
-
18191
- return function paramSerializer(params) {
18192
- if (!params) return '';
18193
- var parts = [];
18194
- forEachSorted(params, function(value, key) {
18195
- if (value === null || isUndefined(value)) return;
18196
- if (isArray(value) || isObject(value) && jQueryMode) {
18197
- forEach(value, function(v, k) {
18198
- var keySuffix = jQueryMode ? '[' + (!isArray(value) ? k : '') + ']' : '';
18199
- parts.push(encodeUriQuery(key + keySuffix) + '=' + encodeUriQuery(serializeValue(v)));
18200
- });
18201
- } else {
18202
- parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(serializeValue(value)));
18203
- }
18204
- });
18205
-
18206
- return parts.length > 0 ? parts.join('&') : '';
18207
- };
18248
+ return v;
18208
18249
  }
18209
18250
 
18251
+
18210
18252
  function $HttpParamSerializerProvider() {
18211
18253
  /**
18212
18254
  * @ngdoc service
@@ -18221,7 +18263,22 @@ function $HttpParamSerializerProvider() {
18221
18263
  * * `{'foo': {'bar':'baz'}}` results in `foo=%7B%22bar%22%3A%22baz%22%7D"` (stringified and encoded representation of an object)
18222
18264
  * */
18223
18265
  this.$get = function() {
18224
- return paramSerializerFactory(false);
18266
+ return function ngParamSerializer(params) {
18267
+ if (!params) return '';
18268
+ var parts = [];
18269
+ forEachSorted(params, function(value, key) {
18270
+ if (value === null || isUndefined(value)) return;
18271
+ if (isArray(value)) {
18272
+ forEach(value, function(v, k) {
18273
+ parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(serializeValue(v)));
18274
+ });
18275
+ } else {
18276
+ parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(serializeValue(value)));
18277
+ }
18278
+ });
18279
+
18280
+ return parts.join('&');
18281
+ };
18225
18282
  };
18226
18283
  }
18227
18284
 
@@ -18234,7 +18291,30 @@ function $HttpParamSerializerJQLikeProvider() {
18234
18291
  * Alternative $http params serializer that follows jQuery's [`param()`](http://api.jquery.com/jquery.param/) method logic.
18235
18292
  * */
18236
18293
  this.$get = function() {
18237
- return paramSerializerFactory(true);
18294
+ return function jQueryLikeParamSerializer(params) {
18295
+ if (!params) return '';
18296
+ var parts = [];
18297
+ serialize(params, '', true);
18298
+ return parts.join('&');
18299
+
18300
+ function serialize(toSerialize, prefix, topLevel) {
18301
+ if (toSerialize === null || isUndefined(toSerialize)) return;
18302
+ if (isArray(toSerialize)) {
18303
+ forEach(toSerialize, function(value) {
18304
+ serialize(value, prefix + '[]');
18305
+ });
18306
+ } else if (isObject(toSerialize) && !isDate(toSerialize)) {
18307
+ forEachSorted(toSerialize, function(value, key) {
18308
+ serialize(value, prefix +
18309
+ (topLevel ? '' : '[') +
18310
+ key +
18311
+ (topLevel ? '' : ']'));
18312
+ });
18313
+ } else {
18314
+ parts.push(encodeUriQuery(prefix) + '=' + encodeUriQuery(serializeValue(toSerialize)));
18315
+ }
18316
+ }
18317
+ };
18238
18318
  };
18239
18319
  }
18240
18320
 
@@ -20603,11 +20683,19 @@ var locationPrototype = {
20603
20683
  *
20604
20684
  * Return host of current url.
20605
20685
  *
20686
+ * Note: compared to the non-angular version `location.host` which returns `hostname:port`, this returns the `hostname` portion only.
20687
+ *
20606
20688
  *
20607
20689
  * ```js
20608
20690
  * // given url http://example.com/#/some/path?foo=bar&baz=xoxo
20609
20691
  * var host = $location.host();
20610
20692
  * // => "example.com"
20693
+ *
20694
+ * // given url http://user:password@example.com:8080/#/some/path?foo=bar&baz=xoxo
20695
+ * host = $location.host();
20696
+ * // => "example.com"
20697
+ * host = location.host;
20698
+ * // => "example.com:8080"
20611
20699
  * ```
20612
20700
  *
20613
20701
  * @return {string} host of current url.
@@ -23364,9 +23452,11 @@ function $ParseProvider() {
23364
23452
  * provide a progress indication, before the promise is resolved or rejected.
23365
23453
  *
23366
23454
  * This method *returns a new promise* which is resolved or rejected via the return value of the
23367
- * `successCallback`, `errorCallback`. It also notifies via the return value of the
23368
- * `notifyCallback` method. The promise cannot be resolved or rejected from the notifyCallback
23369
- * method.
23455
+ * `successCallback`, `errorCallback` (unless that value is a promise, in which case it is resolved
23456
+ * with the value which is resolved in that promise using
23457
+ * [promise chaining](http://www.html5rocks.com/en/tutorials/es6/promises/#toc-promises-queues)).
23458
+ * It also notifies via the return value of the `notifyCallback` method. The promise cannot be
23459
+ * resolved or rejected from the notifyCallback method.
23370
23460
  *
23371
23461
  * - `catch(errorCallback)` – shorthand for `promise.then(null, errorCallback)`
23372
23462
  *
@@ -23802,7 +23892,7 @@ function $$RAFProvider() { //rAF
23802
23892
  $window.webkitCancelRequestAnimationFrame;
23803
23893
 
23804
23894
  var rafSupported = !!requestAnimationFrame;
23805
- var raf = rafSupported
23895
+ var rafFn = rafSupported
23806
23896
  ? function(fn) {
23807
23897
  var id = requestAnimationFrame(fn);
23808
23898
  return function() {
@@ -23816,9 +23906,47 @@ function $$RAFProvider() { //rAF
23816
23906
  };
23817
23907
  };
23818
23908
 
23819
- raf.supported = rafSupported;
23909
+ queueFn.supported = rafSupported;
23910
+
23911
+ var cancelLastRAF;
23912
+ var taskCount = 0;
23913
+ var taskQueue = [];
23914
+ return queueFn;
23915
+
23916
+ function flush() {
23917
+ for (var i = 0; i < taskQueue.length; i++) {
23918
+ var task = taskQueue[i];
23919
+ if (task) {
23920
+ taskQueue[i] = null;
23921
+ task();
23922
+ }
23923
+ }
23924
+ taskCount = taskQueue.length = 0;
23925
+ }
23926
+
23927
+ function queueFn(asyncFn) {
23928
+ var index = taskQueue.length;
23929
+
23930
+ taskCount++;
23931
+ taskQueue.push(asyncFn);
23820
23932
 
23821
- return raf;
23933
+ if (index === 0) {
23934
+ cancelLastRAF = rafFn(flush);
23935
+ }
23936
+
23937
+ return function cancelQueueFn() {
23938
+ if (index >= 0) {
23939
+ taskQueue[index] = null;
23940
+ index = null;
23941
+
23942
+ if (--taskCount === 0 && cancelLastRAF) {
23943
+ cancelLastRAF();
23944
+ cancelLastRAF = null;
23945
+ taskQueue.length = 0;
23946
+ }
23947
+ }
23948
+ };
23949
+ }
23822
23950
  }];
23823
23951
  }
23824
23952
 
@@ -29124,11 +29252,11 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
29124
29252
  <form name="myForm" ng-controller="FormController" class="my-form">
29125
29253
  userType: <input name="input" ng-model="userType" required>
29126
29254
  <span class="error" ng-show="myForm.input.$error.required">Required!</span><br>
29127
- <tt>userType = {{userType}}</tt><br>
29128
- <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br>
29129
- <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br>
29130
- <tt>myForm.$valid = {{myForm.$valid}}</tt><br>
29131
- <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br>
29255
+ <code>userType = {{userType}}</code><br>
29256
+ <code>myForm.input.$valid = {{myForm.input.$valid}}</code><br>
29257
+ <code>myForm.input.$error = {{myForm.input.$error}}</code><br>
29258
+ <code>myForm.$valid = {{myForm.$valid}}</code><br>
29259
+ <code>myForm.$error.required = {{!!myForm.$error.required}}</code><br>
29132
29260
  </form>
29133
29261
  </file>
29134
29262
  <file name="protractor.js" type="protractor">
@@ -31226,7 +31354,9 @@ function classDirective(name, selector) {
31226
31354
  }
31227
31355
 
31228
31356
  function digestClassCounts(classes, count) {
31229
- var classCounts = element.data('$classCounts') || {};
31357
+ // Use createMap() to prevent class assumptions involving property
31358
+ // names in Object.prototype
31359
+ var classCounts = element.data('$classCounts') || createMap();
31230
31360
  var classesToUpdate = [];
31231
31361
  forEach(classes, function(className) {
31232
31362
  if (count > 0 || classCounts[className]) {
@@ -31609,17 +31739,13 @@ var ngClassEvenDirective = classDirective('Even', 1);
31609
31739
  * document; alternatively, the css rule above must be included in the external stylesheet of the
31610
31740
  * application.
31611
31741
  *
31612
- * Legacy browsers, like IE7, do not provide attribute selector support (added in CSS 2.1) so they
31613
- * cannot match the `[ng\:cloak]` selector. To work around this limitation, you must add the css
31614
- * class `ng-cloak` in addition to the `ngCloak` directive as shown in the example below.
31615
- *
31616
31742
  * @element ANY
31617
31743
  *
31618
31744
  * @example
31619
31745
  <example>
31620
31746
  <file name="index.html">
31621
31747
  <div id="template1" ng-cloak>{{ 'hello' }}</div>
31622
- <div id="template2" ng-cloak class="ng-cloak">{{ 'hello IE7' }}</div>
31748
+ <div id="template2" class="ng-cloak">{{ 'world' }}</div>
31623
31749
  </file>
31624
31750
  <file name="protractor.js" type="protractor">
31625
31751
  it('should remove the template directive and css class', function() {
@@ -33648,7 +33774,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
33648
33774
  * If the validity changes to invalid, the model will be set to `undefined`,
33649
33775
  * unless {@link ngModelOptions `ngModelOptions.allowInvalid`} is `true`.
33650
33776
  * If the validity changes to valid, it will set the model to the last available valid
33651
- * modelValue, i.e. either the last parsed value or the last value set from the scope.
33777
+ * `$modelValue`, i.e. either the last parsed value or the last value set from the scope.
33652
33778
  */
33653
33779
  this.$validate = function() {
33654
33780
  // ignore $validate before model is initialized
@@ -34140,10 +34266,11 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
34140
34266
  var _name = 'Brian';
34141
34267
  $scope.user = {
34142
34268
  name: function(newName) {
34143
- if (angular.isDefined(newName)) {
34144
- _name = newName;
34145
- }
34146
- return _name;
34269
+ // Note that newName can be undefined for two reasons:
34270
+ // 1. Because it is called as a getter and thus called with no arguments
34271
+ // 2. Because the property should actually be set to undefined. This happens e.g. if the
34272
+ // input is invalid
34273
+ return arguments.length ? (_name = newName) : _name;
34147
34274
  }
34148
34275
  };
34149
34276
  }]);
@@ -34357,7 +34484,11 @@ var DEFAULT_REGEXP = /(\s+|^)default(\s+|$)/;
34357
34484
  var _name = 'Brian';
34358
34485
  $scope.user = {
34359
34486
  name: function(newName) {
34360
- return angular.isDefined(newName) ? (_name = newName) : _name;
34487
+ // Note that newName can be undefined for two reasons:
34488
+ // 1. Because it is called as a getter and thus called with no arguments
34489
+ // 2. Because the property should actually be set to undefined. This happens e.g. if the
34490
+ // input is invalid
34491
+ return arguments.length ? (_name = newName) : _name;
34361
34492
  }
34362
34493
  };
34363
34494
  }]);
@@ -34557,11 +34688,21 @@ var ngOptionsMinErr = minErr('ngOptions');
34557
34688
  * be nested into the `<select>` element. This element will then represent the `null` or "not selected"
34558
34689
  * option. See example below for demonstration.
34559
34690
  *
34560
- * <div class="alert alert-warning">
34561
- * **Note:** By default, `ngModel` compares by reference, not value. This is important when binding to an
34562
- * array of objects. See an example [in this jsfiddle](http://jsfiddle.net/qWzTb/). When using `track by`
34563
- * in an `ngOptions` expression, however, deep equality checks will be performed.
34564
- * </div>
34691
+ * ## Complex Models (objects or collections)
34692
+ *
34693
+ * **Note:** By default, `ngModel` watches the model by reference, not value. This is important when
34694
+ * binding any input directive to a model that is an object or a collection.
34695
+ *
34696
+ * Since this is a common situation for `ngOptions` the directive additionally watches the model using
34697
+ * `$watchCollection` when the select has the `multiple` attribute or when there is a `track by` clause in
34698
+ * the options expression. This allows ngOptions to trigger a re-rendering of the options even if the actual
34699
+ * object/collection has not changed identity but only a property on the object or an item in the collection
34700
+ * changes.
34701
+ *
34702
+ * Note that `$watchCollection` does a shallow comparison of the properties of the object (or the items in the collection
34703
+ * if the model is an array). This means that changing a property deeper inside the object/collection that the
34704
+ * first level will not trigger a re-rendering.
34705
+ *
34565
34706
  *
34566
34707
  * ## `select` **`as`**
34567
34708
  *
@@ -34777,9 +34918,13 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
34777
34918
  // Get the value by which we are going to track the option
34778
34919
  // if we have a trackFn then use that (passing scope and locals)
34779
34920
  // otherwise just hash the given viewValue
34780
- var getTrackByValue = trackBy ?
34781
- function(viewValue, locals) { return trackByFn(scope, locals); } :
34782
- function getHashOfValue(viewValue) { return hashKey(viewValue); };
34921
+ var getTrackByValueFn = trackBy ?
34922
+ function(value, locals) { return trackByFn(scope, locals); } :
34923
+ function getHashOfValue(value) { return hashKey(value); };
34924
+ var getTrackByValue = function(value, key) {
34925
+ return getTrackByValueFn(value, getLocals(value, key));
34926
+ };
34927
+
34783
34928
  var displayFn = $parse(match[2] || match[1]);
34784
34929
  var groupByFn = $parse(match[3] || '');
34785
34930
  var disableWhenFn = $parse(match[4] || '');
@@ -34806,6 +34951,7 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
34806
34951
 
34807
34952
  return {
34808
34953
  trackBy: trackBy,
34954
+ getTrackByValue: getTrackByValue,
34809
34955
  getWatchables: $parse(valuesFn, function(values) {
34810
34956
  // Create a collection of things that we would like to watch (watchedArray)
34811
34957
  // so that they can all be watched using a single $watchCollection
@@ -34815,11 +34961,11 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
34815
34961
 
34816
34962
  Object.keys(values).forEach(function getWatchable(key) {
34817
34963
  var locals = getLocals(values[key], key);
34818
- var selectValue = getTrackByValue(values[key], locals);
34964
+ var selectValue = getTrackByValueFn(values[key], locals);
34819
34965
  watchedArray.push(selectValue);
34820
34966
 
34821
34967
  // Only need to watch the displayFn if there is a specific label expression
34822
- if (match[2]) {
34968
+ if (match[2] || match[1]) {
34823
34969
  var label = displayFn(scope, locals);
34824
34970
  watchedArray.push(label);
34825
34971
  }
@@ -34841,17 +34987,29 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
34841
34987
  // The option values were already computed in the `getWatchables` fn,
34842
34988
  // which must have been called to trigger `getOptions`
34843
34989
  var optionValues = valuesFn(scope) || [];
34990
+ var optionValuesKeys;
34844
34991
 
34845
- var keys = Object.keys(optionValues);
34846
- keys.forEach(function getOption(key) {
34847
34992
 
34848
- // Ignore "angular" properties that start with $ or $$
34849
- if (key.charAt(0) === '$') return;
34993
+ if (!keyName && isArrayLike(optionValues)) {
34994
+ optionValuesKeys = optionValues;
34995
+ } else {
34996
+ // if object, extract keys, in enumeration order, unsorted
34997
+ optionValuesKeys = [];
34998
+ for (var itemKey in optionValues) {
34999
+ if (optionValues.hasOwnProperty(itemKey) && itemKey.charAt(0) !== '$') {
35000
+ optionValuesKeys.push(itemKey);
35001
+ }
35002
+ }
35003
+ }
35004
+
35005
+ var optionValuesLength = optionValuesKeys.length;
34850
35006
 
35007
+ for (var index = 0; index < optionValuesLength; index++) {
35008
+ var key = (optionValues === optionValuesKeys) ? index : optionValuesKeys[index];
34851
35009
  var value = optionValues[key];
34852
35010
  var locals = getLocals(value, key);
34853
35011
  var viewValue = viewValueFn(scope, locals);
34854
- var selectValue = getTrackByValue(viewValue, locals);
35012
+ var selectValue = getTrackByValueFn(viewValue, locals);
34855
35013
  var label = displayFn(scope, locals);
34856
35014
  var group = groupByFn(scope, locals);
34857
35015
  var disabled = disableWhenFn(scope, locals);
@@ -34859,13 +35017,13 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
34859
35017
 
34860
35018
  optionItems.push(optionItem);
34861
35019
  selectValueMap[selectValue] = optionItem;
34862
- });
35020
+ }
34863
35021
 
34864
35022
  return {
34865
35023
  items: optionItems,
34866
35024
  selectValueMap: selectValueMap,
34867
35025
  getOptionFromViewValue: function(value) {
34868
- return selectValueMap[getTrackByValue(value, getLocals(value))];
35026
+ return selectValueMap[getTrackByValue(value)];
34869
35027
  },
34870
35028
  getViewValueFromOption: function(option) {
34871
35029
  // If the viewValue could be an object that may be mutated by the application,
@@ -34943,44 +35101,54 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
34943
35101
  };
34944
35102
 
34945
35103
 
34946
- selectCtrl.writeValue = function writeNgOptionsValue(value) {
34947
- var option = options.getOptionFromViewValue(value);
35104
+ // Update the controller methods for multiple selectable options
35105
+ if (!multiple) {
34948
35106
 
34949
- if (option && !option.disabled) {
34950
- if (selectElement[0].value !== option.selectValue) {
34951
- removeUnknownOption();
34952
- removeEmptyOption();
35107
+ selectCtrl.writeValue = function writeNgOptionsValue(value) {
35108
+ var option = options.getOptionFromViewValue(value);
34953
35109
 
34954
- selectElement[0].value = option.selectValue;
34955
- option.element.selected = true;
34956
- option.element.setAttribute('selected', 'selected');
34957
- }
34958
- } else {
34959
- if (value === null || providedEmptyOption) {
34960
- removeUnknownOption();
34961
- renderEmptyOption();
35110
+ if (option && !option.disabled) {
35111
+ if (selectElement[0].value !== option.selectValue) {
35112
+ removeUnknownOption();
35113
+ removeEmptyOption();
35114
+
35115
+ selectElement[0].value = option.selectValue;
35116
+ option.element.selected = true;
35117
+ option.element.setAttribute('selected', 'selected');
35118
+ }
34962
35119
  } else {
34963
- removeEmptyOption();
34964
- renderUnknownOption();
35120
+ if (value === null || providedEmptyOption) {
35121
+ removeUnknownOption();
35122
+ renderEmptyOption();
35123
+ } else {
35124
+ removeEmptyOption();
35125
+ renderUnknownOption();
35126
+ }
34965
35127
  }
34966
- }
34967
- };
35128
+ };
34968
35129
 
34969
- selectCtrl.readValue = function readNgOptionsValue() {
35130
+ selectCtrl.readValue = function readNgOptionsValue() {
34970
35131
 
34971
- var selectedOption = options.selectValueMap[selectElement.val()];
35132
+ var selectedOption = options.selectValueMap[selectElement.val()];
34972
35133
 
34973
- if (selectedOption && !selectedOption.disabled) {
34974
- removeEmptyOption();
34975
- removeUnknownOption();
34976
- return options.getViewValueFromOption(selectedOption);
34977
- }
34978
- return null;
34979
- };
35134
+ if (selectedOption && !selectedOption.disabled) {
35135
+ removeEmptyOption();
35136
+ removeUnknownOption();
35137
+ return options.getViewValueFromOption(selectedOption);
35138
+ }
35139
+ return null;
35140
+ };
34980
35141
 
35142
+ // If we are using `track by` then we must watch the tracked value on the model
35143
+ // since ngModel only watches for object identity change
35144
+ if (ngOptions.trackBy) {
35145
+ scope.$watch(
35146
+ function() { return ngOptions.getTrackByValue(ngModelCtrl.$viewValue); },
35147
+ function() { ngModelCtrl.$render(); }
35148
+ );
35149
+ }
34981
35150
 
34982
- // Update the controller methods for multiple selectable options
34983
- if (multiple) {
35151
+ } else {
34984
35152
 
34985
35153
  ngModelCtrl.$isEmpty = function(value) {
34986
35154
  return !value || value.length === 0;
@@ -35012,6 +35180,22 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
35012
35180
 
35013
35181
  return selections;
35014
35182
  };
35183
+
35184
+ // If we are using `track by` then we must watch these tracked values on the model
35185
+ // since ngModel only watches for object identity change
35186
+ if (ngOptions.trackBy) {
35187
+
35188
+ scope.$watchCollection(function() {
35189
+ if (isArray(ngModelCtrl.$viewValue)) {
35190
+ return ngModelCtrl.$viewValue.map(function(value) {
35191
+ return ngOptions.getTrackByValue(value);
35192
+ });
35193
+ }
35194
+ }, function() {
35195
+ ngModelCtrl.$render();
35196
+ });
35197
+
35198
+ }
35015
35199
  }
35016
35200
 
35017
35201
 
@@ -35038,11 +35222,6 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
35038
35222
  // We will re-render the option elements if the option values or labels change
35039
35223
  scope.$watchCollection(ngOptions.getWatchables, updateOptions);
35040
35224
 
35041
- // We also need to watch to see if the internals of the model changes, since
35042
- // ngModel only watches for object identity change
35043
- if (ngOptions.trackBy) {
35044
- scope.$watch(attr.ngModel, function() { ngModelCtrl.$render(); }, true);
35045
- }
35046
35225
  // ------------------------------------------------------------------ //
35047
35226
 
35048
35227
 
@@ -36386,7 +36565,7 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
36386
36565
  *
36387
36566
  * @scope
36388
36567
  * @priority 1200
36389
- * @param {*} ngSwitch|on expression to match against <tt>ng-switch-when</tt>.
36568
+ * @param {*} ngSwitch|on expression to match against <code>ng-switch-when</code>.
36390
36569
  * On child elements add:
36391
36570
  *
36392
36571
  * * `ngSwitchWhen`: the case statement to match against. If match then this
@@ -36403,7 +36582,7 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
36403
36582
  <div ng-controller="ExampleController">
36404
36583
  <select ng-model="selection" ng-options="item for item in items">
36405
36584
  </select>
36406
- <tt>selection={{selection}}</tt>
36585
+ <code>selection={{selection}}</code>
36407
36586
  <hr/>
36408
36587
  <div class="animate-switch-container"
36409
36588
  ng-switch on="selection">
@@ -36794,12 +36973,6 @@ var SelectController =
36794
36973
  * be nested into the `<select>` element. This element will then represent the `null` or "not selected"
36795
36974
  * option. See example below for demonstration.
36796
36975
  *
36797
- * <div class="alert alert-warning">
36798
- * **Note:** By default, `ngModel` compares by reference, not value. This is important when binding to an
36799
- * array of objects. See an example [in this jsfiddle](http://jsfiddle.net/qWzTb/). When using `track by`
36800
- * in an `ngOptions` expression, however, deep equality checks will be performed.
36801
- * </div>
36802
- *
36803
36976
  */
36804
36977
  var selectDirective = function() {
36805
36978
 
@@ -39276,5 +39449,5 @@ if (config.autotest) {
39276
39449
  })(window, document);
39277
39450
 
39278
39451
 
39279
- !window.angular.$$csp() && window.angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";\n\n[ng\\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],\n.ng-cloak, .x-ng-cloak,\n.ng-hide:not(.ng-hide-animate) {\n display: none !important;\n}\n\nng\\:form {\n display: block;\n}\n\n.ng-animate-shim {\n visibility:hidden;\n}\n\n.ng-animate-anchor {\n position:absolute;\n}\n</style>');
39452
+ !window.angular.$$csp() && window.angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";\n\n[ng\\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],\n.ng-cloak, .x-ng-cloak,\n.ng-hide:not(.ng-hide-animate) {\n display: none !important;\n}\n\nng\\:form {\n display: block;\n}\n\n.ng-animate-shim {\n visibility:hidden;\n}\n\n.ng-anchor {\n position:absolute;\n}\n</style>');
39280
39453
  !window.angular.$$csp() && window.angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";\n/* CSS Document */\n\n/** Structure */\nbody {\n font-family: Arial, sans-serif;\n margin: 0;\n font-size: 14px;\n}\n\n#system-error {\n font-size: 1.5em;\n text-align: center;\n}\n\n#json, #xml {\n display: none;\n}\n\n#header {\n position: fixed;\n width: 100%;\n}\n\n#specs {\n padding-top: 50px;\n}\n\n#header .angular {\n font-family: Courier New, monospace;\n font-weight: bold;\n}\n\n#header h1 {\n font-weight: normal;\n float: left;\n font-size: 30px;\n line-height: 30px;\n margin: 0;\n padding: 10px 10px;\n height: 30px;\n}\n\n#application h2,\n#specs h2 {\n margin: 0;\n padding: 0.5em;\n font-size: 1.1em;\n}\n\n#status-legend {\n margin-top: 10px;\n margin-right: 10px;\n}\n\n#header,\n#application,\n.test-info,\n.test-actions li {\n overflow: hidden;\n}\n\n#application {\n margin: 10px;\n}\n\n#application iframe {\n width: 100%;\n height: 758px;\n}\n\n#application .popout {\n float: right;\n}\n\n#application iframe {\n border: none;\n}\n\n.tests li,\n.test-actions li,\n.test-it li,\n.test-it ol,\n.status-display {\n list-style-type: none;\n}\n\n.tests,\n.test-it ol,\n.status-display {\n margin: 0;\n padding: 0;\n}\n\n.test-info {\n margin-left: 1em;\n margin-top: 0.5em;\n border-radius: 8px 0 0 8px;\n -webkit-border-radius: 8px 0 0 8px;\n -moz-border-radius: 8px 0 0 8px;\n cursor: pointer;\n}\n\n.test-info:hover .test-name {\n text-decoration: underline;\n}\n\n.test-info .closed:before {\n content: \'\\25b8\\00A0\';\n}\n\n.test-info .open:before {\n content: \'\\25be\\00A0\';\n font-weight: bold;\n}\n\n.test-it ol {\n margin-left: 2.5em;\n}\n\n.status-display,\n.status-display li {\n float: right;\n}\n\n.status-display li {\n padding: 5px 10px;\n}\n\n.timer-result,\n.test-title {\n display: inline-block;\n margin: 0;\n padding: 4px;\n}\n\n.test-actions .test-title,\n.test-actions .test-result {\n display: table-cell;\n padding-left: 0.5em;\n padding-right: 0.5em;\n}\n\n.test-actions {\n display: table;\n}\n\n.test-actions li {\n display: table-row;\n}\n\n.timer-result {\n width: 4em;\n padding: 0 10px;\n text-align: right;\n font-family: monospace;\n}\n\n.test-it pre,\n.test-actions pre {\n clear: left;\n color: black;\n margin-left: 6em;\n}\n\n.test-describe {\n padding-bottom: 0.5em;\n}\n\n.test-describe .test-describe {\n margin: 5px 5px 10px 2em;\n}\n\n.test-actions .status-pending .test-title:before {\n content: \'\\00bb\\00A0\';\n}\n\n.scrollpane {\n max-height: 20em;\n overflow: auto;\n}\n\n/** Colors */\n\n#header {\n background-color: #F2C200;\n}\n\n#specs h2 {\n border-top: 2px solid #BABAD1;\n}\n\n#specs h2,\n#application h2 {\n background-color: #efefef;\n}\n\n#application {\n border: 1px solid #BABAD1;\n}\n\n.test-describe .test-describe {\n border-left: 1px solid #BABAD1;\n border-right: 1px solid #BABAD1;\n border-bottom: 1px solid #BABAD1;\n}\n\n.status-display {\n border: 1px solid #777;\n}\n\n.status-display .status-pending,\n.status-pending .test-info {\n background-color: #F9EEBC;\n}\n\n.status-display .status-success,\n.status-success .test-info {\n background-color: #B1D7A1;\n}\n\n.status-display .status-failure,\n.status-failure .test-info {\n background-color: #FF8286;\n}\n\n.status-display .status-error,\n.status-error .test-info {\n background-color: black;\n color: white;\n}\n\n.test-actions .status-success .test-title {\n color: #30B30A;\n}\n\n.test-actions .status-failure .test-title {\n color: #DF0000;\n}\n\n.test-actions .status-error .test-title {\n color: black;\n}\n\n.test-actions .timer-result {\n color: #888;\n}\n</style>');