angularjs-rails 1.2.5 → 1.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0d8933c1324250cfba866c3dd12c3c9054aac5c7
4
- data.tar.gz: 677f8bbe17a31cbdff41ee78325f5e319dc826de
3
+ metadata.gz: bc56ac22062a8c136ecb9f7b07f8c54d0f48a70e
4
+ data.tar.gz: 4e331e06924e8274c7f21027dfcdd4cd237ea3ce
5
5
  SHA512:
6
- metadata.gz: 1ddb02111fef232c6770f9c475cb2316b6f7681701d13eb99613c0886e384173d9773f215e0f2a9b4959e129719a4c608eedaa071fd79719d34c40ef342aed01
7
- data.tar.gz: 1e767d36276b0b61e9b17b7fc5b359806a9acf8a2775e8c5dbce67b5e9694a866da24aba72b09724460ee9ced3e2ad37f75da384234e457d3d3e4138f4c7aebe
6
+ metadata.gz: d027dd3efdd99229f00f3d0634922f483528fe3f0ebb524b0bd52b75a0d2b4df629718b0def626204ae310038ee210070d8a96dcc96fc4541b7ac737e463fc8d
7
+ data.tar.gz: 6fb1639521fcc3a058b61f693a19b8ed12f84f48847d85edf4ef7f3cc0499da861a4da8725e276cbb4c7ddead2d5e29c2bf754b38491f9936bdad4830212f0b7
@@ -1,6 +1,6 @@
1
1
  module AngularJS
2
2
  module Rails
3
- VERSION = "1.2.5"
3
+ VERSION = "1.2.6"
4
4
  UNSTABLE_VERSION = "1.1.5"
5
5
  end
6
6
  end
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.5
2
+ * @license AngularJS v1.2.6
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -294,6 +294,13 @@ angular.module('ngAnimate', ['ng'])
294
294
  });
295
295
  });
296
296
 
297
+ var classNameFilter = $animateProvider.classNameFilter();
298
+ var isAnimatableClassName = !classNameFilter
299
+ ? function() { return true; }
300
+ : function(className) {
301
+ return classNameFilter.test(className);
302
+ };
303
+
297
304
  function lookup(name) {
298
305
  if (name) {
299
306
  var matches = [],
@@ -575,17 +582,20 @@ angular.module('ngAnimate', ['ng'])
575
582
  and the onComplete callback will be fired once the animation is fully complete.
576
583
  */
577
584
  function performAnimation(animationEvent, className, element, parentElement, afterElement, domOperation, doneCallback) {
578
- var node = extractElementNode(element);
585
+ var currentClassName, classes, node = extractElementNode(element);
586
+ if(node) {
587
+ currentClassName = node.className;
588
+ classes = currentClassName + ' ' + className;
589
+ }
590
+
579
591
  //transcluded directives may sometimes fire an animation using only comment nodes
580
592
  //best to catch this early on to prevent any animation operations from occurring
581
- if(!node) {
593
+ if(!node || !isAnimatableClassName(classes)) {
582
594
  fireDOMOperation();
583
595
  closeAnimation();
584
596
  return;
585
597
  }
586
598
 
587
- var currentClassName = node.className;
588
- var classes = currentClassName + ' ' + className;
589
599
  var animationLookup = (' ' + classes).replace(/\s+/g,'.');
590
600
  if (!parentElement) {
591
601
  parentElement = afterElement ? afterElement.parent() : element.parent();
@@ -887,27 +897,73 @@ angular.module('ngAnimate', ['ng'])
887
897
  var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount';
888
898
  var NG_ANIMATE_PARENT_KEY = '$$ngAnimateKey';
889
899
  var NG_ANIMATE_CSS_DATA_KEY = '$$ngAnimateCSS3Data';
890
- var NG_ANIMATE_FALLBACK_CLASS_NAME = 'ng-animate-start';
891
- var NG_ANIMATE_FALLBACK_ACTIVE_CLASS_NAME = 'ng-animate-active';
892
900
  var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;
901
+ var CLOSING_TIME_BUFFER = 1.5;
902
+ var ONE_SECOND = 1000;
893
903
 
904
+ var animationCounter = 0;
894
905
  var lookupCache = {};
895
906
  var parentCounter = 0;
907
+ var animationReflowQueue = [];
908
+ var animationElementQueue = [];
909
+ var animationTimer;
910
+ var closingAnimationTime = 0;
911
+ var timeOut = false;
912
+ function afterReflow(element, callback) {
913
+ $timeout.cancel(animationTimer);
896
914
 
897
- var animationReflowQueue = [], animationTimer, timeOut = false;
898
- function afterReflow(callback) {
899
915
  animationReflowQueue.push(callback);
900
- $timeout.cancel(animationTimer);
916
+
917
+ var node = extractElementNode(element);
918
+ element = angular.element(node);
919
+ animationElementQueue.push(element);
920
+
921
+ var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY);
922
+ closingAnimationTime = Math.max(closingAnimationTime,
923
+ (elementData.maxDelay + elementData.maxDuration) * CLOSING_TIME_BUFFER * ONE_SECOND);
924
+
925
+ //by placing a counter we can avoid an accidental
926
+ //race condition which may close an animation when
927
+ //a follow-up animation is midway in its animation
928
+ elementData.animationCount = animationCounter;
929
+
901
930
  animationTimer = $timeout(function() {
902
931
  forEach(animationReflowQueue, function(fn) {
903
932
  fn();
904
933
  });
934
+
935
+ //copy the list of elements so that successive
936
+ //animations won't conflict if they're added before
937
+ //the closing animation timeout has run
938
+ var elementQueueSnapshot = [];
939
+ var animationCounterSnapshot = animationCounter;
940
+ forEach(animationElementQueue, function(elm) {
941
+ elementQueueSnapshot.push(elm);
942
+ });
943
+
944
+ $timeout(function() {
945
+ closeAllAnimations(elementQueueSnapshot, animationCounterSnapshot);
946
+ elementQueueSnapshot = null;
947
+ }, closingAnimationTime, false);
948
+
905
949
  animationReflowQueue = [];
950
+ animationElementQueue = [];
906
951
  animationTimer = null;
907
952
  lookupCache = {};
953
+ closingAnimationTime = 0;
954
+ animationCounter++;
908
955
  }, 10, false);
909
956
  }
910
957
 
958
+ function closeAllAnimations(elements, count) {
959
+ forEach(elements, function(element) {
960
+ var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY);
961
+ if(elementData && elementData.animationCount == count) {
962
+ (elementData.closeAnimationFn || noop)();
963
+ }
964
+ });
965
+ }
966
+
911
967
  function getElementAnimationDetails(element, cacheKey) {
912
968
  var data = cacheKey ? lookupCache[cacheKey] : null;
913
969
  if(!data) {
@@ -1013,6 +1069,7 @@ angular.module('ngAnimate', ['ng'])
1013
1069
  timeout is empty (this would cause a flicker bug normally
1014
1070
  in the page. There is also no point in performing an animation
1015
1071
  that only has a delay and no duration */
1072
+ var maxDelay = Math.max(timings.transitionDelay, timings.animationDelay);
1016
1073
  var maxDuration = Math.max(timings.transitionDuration, timings.animationDuration);
1017
1074
  if(maxDuration === 0) {
1018
1075
  element.removeClass(className);
@@ -1022,13 +1079,9 @@ angular.module('ngAnimate', ['ng'])
1022
1079
  //temporarily disable the transition so that the enter styles
1023
1080
  //don't animate twice (this is here to avoid a bug in Chrome/FF).
1024
1081
  var activeClassName = '';
1025
- if(timings.transitionDuration > 0) {
1026
- element.addClass(NG_ANIMATE_FALLBACK_CLASS_NAME);
1027
- activeClassName += NG_ANIMATE_FALLBACK_ACTIVE_CLASS_NAME + ' ';
1028
- blockTransitions(element);
1029
- } else {
1082
+ timings.transitionDuration > 0 ?
1083
+ blockTransitions(element) :
1030
1084
  blockKeyframeAnimations(element);
1031
- }
1032
1085
 
1033
1086
  forEach(className.split(' '), function(klass, i) {
1034
1087
  activeClassName += (i > 0 ? ' ' : '') + klass + '-active';
@@ -1038,6 +1091,7 @@ angular.module('ngAnimate', ['ng'])
1038
1091
  className : className,
1039
1092
  activeClassName : activeClassName,
1040
1093
  maxDuration : maxDuration,
1094
+ maxDelay : maxDelay,
1041
1095
  classes : className + ' ' + activeClassName,
1042
1096
  timings : timings,
1043
1097
  stagger : stagger,
@@ -1072,30 +1126,28 @@ angular.module('ngAnimate', ['ng'])
1072
1126
  }
1073
1127
 
1074
1128
  function animateRun(element, className, activeAnimationComplete) {
1075
- var data = element.data(NG_ANIMATE_CSS_DATA_KEY);
1129
+ var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY);
1076
1130
  var node = extractElementNode(element);
1077
- if(node.className.indexOf(className) == -1 || !data) {
1131
+ if(node.className.indexOf(className) == -1 || !elementData) {
1078
1132
  activeAnimationComplete();
1079
1133
  return;
1080
1134
  }
1081
1135
 
1082
- var timings = data.timings;
1083
- var stagger = data.stagger;
1084
- var maxDuration = data.maxDuration;
1085
- var activeClassName = data.activeClassName;
1086
- var maxDelayTime = Math.max(timings.transitionDelay, timings.animationDelay) * 1000;
1136
+ var timings = elementData.timings;
1137
+ var stagger = elementData.stagger;
1138
+ var maxDuration = elementData.maxDuration;
1139
+ var activeClassName = elementData.activeClassName;
1140
+ var maxDelayTime = Math.max(timings.transitionDelay, timings.animationDelay) * ONE_SECOND;
1087
1141
  var startTime = Date.now();
1088
1142
  var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT;
1089
- var ii = data.ii;
1143
+ var ii = elementData.ii;
1090
1144
 
1091
- var applyFallbackStyle, style = '', appliedStyles = [];
1145
+ var style = '', appliedStyles = [];
1092
1146
  if(timings.transitionDuration > 0) {
1093
1147
  var propertyStyle = timings.transitionPropertyStyle;
1094
1148
  if(propertyStyle.indexOf('all') == -1) {
1095
- applyFallbackStyle = true;
1096
- var fallbackProperty = $sniffer.msie ? '-ms-zoom' : 'border-spacing';
1097
- style += CSS_PREFIX + 'transition-property: ' + propertyStyle + ', ' + fallbackProperty + '; ';
1098
- style += CSS_PREFIX + 'transition-duration: ' + timings.transitionDurationStyle + ', ' + timings.transitionDuration + 's; ';
1149
+ style += CSS_PREFIX + 'transition-property: ' + propertyStyle + ';';
1150
+ style += CSS_PREFIX + 'transition-duration: ' + timings.transitionDurationStyle + 's;';
1099
1151
  appliedStyles.push(CSS_PREFIX + 'transition-property');
1100
1152
  appliedStyles.push(CSS_PREFIX + 'transition-duration');
1101
1153
  }
@@ -1104,10 +1156,6 @@ angular.module('ngAnimate', ['ng'])
1104
1156
  if(ii > 0) {
1105
1157
  if(stagger.transitionDelay > 0 && stagger.transitionDuration === 0) {
1106
1158
  var delayStyle = timings.transitionDelayStyle;
1107
- if(applyFallbackStyle) {
1108
- delayStyle += ', ' + timings.transitionDelay + 's';
1109
- }
1110
-
1111
1159
  style += CSS_PREFIX + 'transition-delay: ' +
1112
1160
  prepareStaggerDelay(delayStyle, stagger.transitionDelay, ii) + '; ';
1113
1161
  appliedStyles.push(CSS_PREFIX + 'transition-delay');
@@ -1130,11 +1178,16 @@ angular.module('ngAnimate', ['ng'])
1130
1178
 
1131
1179
  element.on(css3AnimationEvents, onAnimationProgress);
1132
1180
  element.addClass(activeClassName);
1181
+ elementData.closeAnimationFn = function() {
1182
+ onEnd();
1183
+ activeAnimationComplete();
1184
+ };
1185
+ return onEnd;
1133
1186
 
1134
1187
  // This will automatically be called by $animate so
1135
1188
  // there is no need to attach this internally to the
1136
1189
  // timeout done method.
1137
- return function onEnd(cancelled) {
1190
+ function onEnd(cancelled) {
1138
1191
  element.off(css3AnimationEvents, onAnimationProgress);
1139
1192
  element.removeClass(activeClassName);
1140
1193
  animateClose(element, className);
@@ -1142,7 +1195,7 @@ angular.module('ngAnimate', ['ng'])
1142
1195
  for (var i in appliedStyles) {
1143
1196
  node.style.removeProperty(appliedStyles[i]);
1144
1197
  }
1145
- };
1198
+ }
1146
1199
 
1147
1200
  function onAnimationProgress(event) {
1148
1201
  event.stopPropagation();
@@ -1208,7 +1261,7 @@ angular.module('ngAnimate', ['ng'])
1208
1261
  //data from the element which will not make the 2nd animation
1209
1262
  //happen in the first place
1210
1263
  var cancel = preReflowCancellation;
1211
- afterReflow(function() {
1264
+ afterReflow(element, function() {
1212
1265
  unblockTransitions(element);
1213
1266
  unblockKeyframeAnimations(element);
1214
1267
  //once the reflow is complete then we point cancel to
@@ -1224,7 +1277,6 @@ angular.module('ngAnimate', ['ng'])
1224
1277
 
1225
1278
  function animateClose(element, className) {
1226
1279
  element.removeClass(className);
1227
- element.removeClass(NG_ANIMATE_FALLBACK_CLASS_NAME);
1228
1280
  element.removeData(NG_ANIMATE_CSS_DATA_KEY);
1229
1281
  }
1230
1282
 
@@ -1274,7 +1326,7 @@ angular.module('ngAnimate', ['ng'])
1274
1326
  beforeAddClass : function(element, className, animationCompleted) {
1275
1327
  var cancellationMethod = animateBefore(element, suffixClasses(className, '-add'));
1276
1328
  if(cancellationMethod) {
1277
- afterReflow(function() {
1329
+ afterReflow(element, function() {
1278
1330
  unblockTransitions(element);
1279
1331
  unblockKeyframeAnimations(element);
1280
1332
  animationCompleted();
@@ -1291,7 +1343,7 @@ angular.module('ngAnimate', ['ng'])
1291
1343
  beforeRemoveClass : function(element, className, animationCompleted) {
1292
1344
  var cancellationMethod = animateBefore(element, suffixClasses(className, '-remove'));
1293
1345
  if(cancellationMethod) {
1294
- afterReflow(function() {
1346
+ afterReflow(element, function() {
1295
1347
  unblockTransitions(element);
1296
1348
  unblockKeyframeAnimations(element);
1297
1349
  animationCompleted();
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.5
2
+ * @license AngularJS v1.2.6
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.5
2
+ * @license AngularJS v1.2.6
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -69,7 +69,7 @@ function minErr(module) {
69
69
  return match;
70
70
  });
71
71
 
72
- message = message + '\nhttp://errors.angularjs.org/1.2.5/' +
72
+ message = message + '\nhttp://errors.angularjs.org/1.2.6/' +
73
73
  (module ? module + '/' : '') + code;
74
74
  for (i = 2; i < arguments.length; i++) {
75
75
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.5
2
+ * @license AngularJS v1.2.6
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.5
2
+ * @license AngularJS v1.2.6
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -40,7 +40,7 @@ function shallowClearAndCopy(src, dst) {
40
40
  });
41
41
 
42
42
  for (var key in src) {
43
- if (src.hasOwnProperty(key) && key.substr(0, 2) !== '$$') {
43
+ if (src.hasOwnProperty(key) && key.charAt(0) !== '$' && key.charAt(1) !== '$') {
44
44
  dst[key] = src[key];
45
45
  }
46
46
  }
@@ -95,7 +95,7 @@ function shallowClearAndCopy(src, dst) {
95
95
  * when a param value needs to be obtained for a request (unless the param was overridden).
96
96
  *
97
97
  * Each key value in the parameter object is first bound to url template if present and then any
98
- * excess keys are appended to the url search query after the `?`.
98
+ * excess keys are appended to the url seapph query after the `?`.
99
99
  *
100
100
  * Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in
101
101
  * URL `/path/greet?salutation=Hello`.
@@ -242,7 +242,7 @@ function shallowClearAndCopy(src, dst) {
242
242
  newCard.name = "Mike Smith";
243
243
  newCard.$save();
244
244
  // POST: /user/123/card {number:'0123', name:'Mike Smith'}
245
- // server returns: {id:789, number:'01234', name: 'Mike Smith'};
245
+ // server returns: {id:789, number:'0123', name: 'Mike Smith'};
246
246
  expect(newCard.id).toEqual(789);
247
247
  * </pre>
248
248
  *
@@ -277,6 +277,35 @@ function shallowClearAndCopy(src, dst) {
277
277
  });
278
278
  });
279
279
  </pre>
280
+
281
+ * # Creating a custom 'PUT' request
282
+ * In this example we create a custom method on our resource to make a PUT request
283
+ * <pre>
284
+ * var app = angular.module('app', ['ngResource', 'ngRoute']);
285
+ *
286
+ * // Some APIs expect a PUT request in the format URL/object/ID
287
+ * // Here we are creating an 'update' method
288
+ * app.factory('Notes', ['$resource', function($resource) {
289
+ * return $resource('/notes/:id', null,
290
+ * {
291
+ * 'update': { method:'PUT' }
292
+ * });
293
+ * }]);
294
+ *
295
+ * // In our controller we get the ID from the URL using ngRoute and $routeParams
296
+ * // We pass in $routeParams and our Notes factory along with $scope
297
+ * app.controller('NotesCtrl', ['$scope', '$routeParams', 'Notes',
298
+ function($scope, $routeParams, Notes) {
299
+ * // First get a note object from the factory
300
+ * var note = Notes.get({ id:$routeParams.id });
301
+ * $id = note.id;
302
+ *
303
+ * // Now call update passing in the ID first then the object you are updating
304
+ * Notes.update({ id:$id }, note);
305
+ *
306
+ * // This will PUT /notes/ID with the note object in the request payload
307
+ * }]);
308
+ * </pre>
280
309
  */
281
310
  angular.module('ngResource', ['ng']).
282
311
  factory('$resource', ['$http', '$q', function($http, $q) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.5
2
+ * @license AngularJS v1.2.6
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.5
2
+ * @license AngularJS v1.2.6
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -9790,7 +9790,7 @@ if ( typeof module === "object" && module && typeof module.exports === "object"
9790
9790
  })( window );
9791
9791
 
9792
9792
  /**
9793
- * @license AngularJS v1.2.5
9793
+ * @license AngularJS v1.2.6
9794
9794
  * (c) 2010-2014 Google, Inc. http://angularjs.org
9795
9795
  * License: MIT
9796
9796
  */
@@ -9860,7 +9860,7 @@ function minErr(module) {
9860
9860
  return match;
9861
9861
  });
9862
9862
 
9863
- message = message + '\nhttp://errors.angularjs.org/1.2.5/' +
9863
+ message = message + '\nhttp://errors.angularjs.org/1.2.6/' +
9864
9864
  (module ? module + '/' : '') + code;
9865
9865
  for (i = 2; i < arguments.length; i++) {
9866
9866
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -10084,7 +10084,9 @@ function forEach(obj, iterator, context) {
10084
10084
  if (obj) {
10085
10085
  if (isFunction(obj)){
10086
10086
  for (key in obj) {
10087
- if (key != 'prototype' && key != 'length' && key != 'name' && obj.hasOwnProperty(key)) {
10087
+ // Need to check if hasOwnProperty exists,
10088
+ // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
10089
+ if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
10088
10090
  iterator.call(context, obj[key], key);
10089
10091
  }
10090
10092
  }
@@ -10640,7 +10642,7 @@ function shallowCopy(src, dst) {
10640
10642
  for(var key in src) {
10641
10643
  // shallowCopy is only ever called by $compile nodeLinkFn, which has control over src
10642
10644
  // so we don't need to worry about using our custom hasOwnProperty here
10643
- if (src.hasOwnProperty(key) && key.substr(0, 2) !== '$$') {
10645
+ if (src.hasOwnProperty(key) && key.charAt(0) !== '$' && key.charAt(1) !== '$') {
10644
10646
  dst[key] = src[key];
10645
10647
  }
10646
10648
  }
@@ -11621,11 +11623,11 @@ function setupModuleLoader(window) {
11621
11623
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
11622
11624
  */
11623
11625
  var version = {
11624
- full: '1.2.5', // all of these placeholder strings will be replaced by grunt's
11626
+ full: '1.2.6', // all of these placeholder strings will be replaced by grunt's
11625
11627
  major: 1, // package task
11626
11628
  minor: 2,
11627
- dot: 5,
11628
- codeName: 'singularity-expansion'
11629
+ dot: 6,
11630
+ codeName: 'taco-salsafication'
11629
11631
  };
11630
11632
 
11631
11633
 
@@ -11801,6 +11803,7 @@ function publishExternalAPI(angular){
11801
11803
  * - [`next()`](http://api.jquery.com/next/) - Does not support selectors
11802
11804
  * - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
11803
11805
  * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces or selectors
11806
+ * - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors
11804
11807
  * - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors
11805
11808
  * - [`prepend()`](http://api.jquery.com/prepend/)
11806
11809
  * - [`prop()`](http://api.jquery.com/prop/)
@@ -12392,7 +12395,10 @@ function createEventHandler(element, events) {
12392
12395
  return event.defaultPrevented || event.returnValue === false;
12393
12396
  };
12394
12397
 
12395
- forEach(events[type || event.type], function(fn) {
12398
+ // Copy event handlers in case event handlers array is modified during execution.
12399
+ var eventHandlersCopy = shallowCopy(events[type || event.type] || []);
12400
+
12401
+ forEach(eventHandlersCopy, function(fn) {
12396
12402
  fn.call(element, event);
12397
12403
  });
12398
12404
 
@@ -12488,6 +12494,19 @@ forEach({
12488
12494
 
12489
12495
  off: jqLiteOff,
12490
12496
 
12497
+ one: function(element, type, fn) {
12498
+ element = jqLite(element);
12499
+
12500
+ //add the listener twice so that when it is called
12501
+ //you can remove the original function and still be
12502
+ //able to call element.off(ev, fn) normally
12503
+ element.on(type, function onFn() {
12504
+ element.off(type, fn);
12505
+ element.off(type, onFn);
12506
+ });
12507
+ element.on(type, fn);
12508
+ },
12509
+
12491
12510
  replaceWith: function(element, replaceNode) {
12492
12511
  var index, parent = element.parentNode;
12493
12512
  jqLiteDealoc(element);
@@ -13181,15 +13200,15 @@ function annotate(fn) {
13181
13200
  * {@link AUTO.$provide#methods_service $provide.service(class)} that is defined as a CoffeeScript class.
13182
13201
  * <pre>
13183
13202
  * class Ping
13184
- * constructor: (@$http)->
13185
- * send: ()=>
13203
+ * constructor: (@$http) ->
13204
+ * send: () =>
13186
13205
  * @$http.get('/ping')
13187
13206
  *
13188
13207
  * $provide.service('ping', ['$http', Ping])
13189
13208
  * </pre>
13190
13209
  * You would then inject and use this service like this:
13191
13210
  * <pre>
13192
- * someModule.controller 'Ctrl', ['ping', (ping)->
13211
+ * someModule.controller 'Ctrl', ['ping', (ping) ->
13193
13212
  * ping.send()
13194
13213
  * ]
13195
13214
  * </pre>
@@ -13656,6 +13675,28 @@ var $AnimateProvider = ['$provide', function($provide) {
13656
13675
  $provide.factory(key, factory);
13657
13676
  };
13658
13677
 
13678
+ /**
13679
+ * @ngdoc function
13680
+ * @name ng.$animateProvider#classNameFilter
13681
+ * @methodOf ng.$animateProvider
13682
+ *
13683
+ * @description
13684
+ * Sets and/or returns the CSS class regular expression that is checked when performing
13685
+ * an animation. Upon bootstrap the classNameFilter value is not set at all and will
13686
+ * therefore enable $animate to attempt to perform an animation on any element.
13687
+ * When setting the classNameFilter value, animations will only be performed on elements
13688
+ * that successfully match the filter expression. This in turn can boost performance
13689
+ * for low-powered devices as well as applications containing a lot of structural operations.
13690
+ * @param {RegExp=} expression The className expression which will be checked against all animations
13691
+ * @return {RegExp} The current CSS className expression value. If null then there is no expression value
13692
+ */
13693
+ this.classNameFilter = function(expression) {
13694
+ if(arguments.length === 1) {
13695
+ this.$$classNameFilter = (expression instanceof RegExp) ? expression : null;
13696
+ }
13697
+ return this.$$classNameFilter;
13698
+ };
13699
+
13659
13700
  this.$get = ['$timeout', function($timeout) {
13660
13701
 
13661
13702
  /**
@@ -14903,14 +14944,14 @@ function $TemplateCacheProvider() {
14903
14944
  * example would not point to the clone, but rather to the original template that was cloned. In
14904
14945
  * this case, you can access the clone via the cloneAttachFn:
14905
14946
  * <pre>
14906
- * var templateHTML = angular.element('<p>{{total}}</p>'),
14947
+ * var templateElement = angular.element('<p>{{total}}</p>'),
14907
14948
  * scope = ....;
14908
14949
  *
14909
- * var clonedElement = $compile(templateHTML)(scope, function(clonedElement, scope) {
14950
+ * var clonedElement = $compile(templateElement)(scope, function(clonedElement, scope) {
14910
14951
  * //attach the clone to DOM document at the right place
14911
14952
  * });
14912
14953
  *
14913
- * //now we have reference to the cloned DOM via `clone`
14954
+ * //now we have reference to the cloned DOM via `clonedElement`
14914
14955
  * </pre>
14915
14956
  *
14916
14957
  *
@@ -15252,6 +15293,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15252
15293
  var compositeLinkFn =
15253
15294
  compileNodes($compileNodes, transcludeFn, $compileNodes,
15254
15295
  maxPriority, ignoreDirective, previousCompileContext);
15296
+ safeAddClass($compileNodes, 'ng-scope');
15255
15297
  return function publicLinkFn(scope, cloneConnectFn, transcludeControllers){
15256
15298
  assertArg(scope, 'scope');
15257
15299
  // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart
@@ -15266,12 +15308,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15266
15308
 
15267
15309
  // Attach scope only to non-text nodes.
15268
15310
  for(var i = 0, ii = $linkNode.length; i<ii; i++) {
15269
- var node = $linkNode[i];
15270
- if (node.nodeType == 1 /* element */ || node.nodeType == 9 /* document */) {
15311
+ var node = $linkNode[i],
15312
+ nodeType = node.nodeType;
15313
+ if (nodeType === 1 /* element */ || nodeType === 9 /* document */) {
15271
15314
  $linkNode.eq(i).data('$scope', scope);
15272
15315
  }
15273
15316
  }
15274
- safeAddClass($linkNode, 'ng-scope');
15317
+
15275
15318
  if (cloneConnectFn) cloneConnectFn($linkNode, scope);
15276
15319
  if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode);
15277
15320
  return $linkNode;
@@ -15299,15 +15342,15 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15299
15342
  * @param {DOMElement=} $rootElement If the nodeList is the root of the compilation tree then
15300
15343
  * the rootElement must be set the jqLite collection of the compile root. This is
15301
15344
  * needed so that the jqLite collection items can be replaced with widgets.
15302
- * @param {number=} max directive priority
15345
+ * @param {number=} maxPriority Max directive priority.
15303
15346
  * @returns {?function} A composite linking function of all of the matched directives or null.
15304
15347
  */
15305
15348
  function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority, ignoreDirective,
15306
15349
  previousCompileContext) {
15307
15350
  var linkFns = [],
15308
- nodeLinkFn, childLinkFn, directives, attrs, linkFnFound;
15351
+ attrs, directives, nodeLinkFn, childNodes, childLinkFn, linkFnFound;
15309
15352
 
15310
- for(var i = 0; i < nodeList.length; i++) {
15353
+ for (var i = 0; i < nodeList.length; i++) {
15311
15354
  attrs = new Attributes();
15312
15355
 
15313
15356
  // we must always refer to nodeList[i] since the nodes can be replaced underneath us.
@@ -15319,16 +15362,19 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15319
15362
  null, [], [], previousCompileContext)
15320
15363
  : null;
15321
15364
 
15365
+ if (nodeLinkFn && nodeLinkFn.scope) {
15366
+ safeAddClass(jqLite(nodeList[i]), 'ng-scope');
15367
+ }
15368
+
15322
15369
  childLinkFn = (nodeLinkFn && nodeLinkFn.terminal ||
15323
- !nodeList[i].childNodes ||
15324
- !nodeList[i].childNodes.length)
15370
+ !(childNodes = nodeList[i].childNodes) ||
15371
+ !childNodes.length)
15325
15372
  ? null
15326
- : compileNodes(nodeList[i].childNodes,
15373
+ : compileNodes(childNodes,
15327
15374
  nodeLinkFn ? nodeLinkFn.transclude : transcludeFn);
15328
15375
 
15329
- linkFns.push(nodeLinkFn);
15330
- linkFns.push(childLinkFn);
15331
- linkFnFound = (linkFnFound || nodeLinkFn || childLinkFn);
15376
+ linkFns.push(nodeLinkFn, childLinkFn);
15377
+ linkFnFound = linkFnFound || nodeLinkFn || childLinkFn;
15332
15378
  //use the previous context only for the first element in the virtual group
15333
15379
  previousCompileContext = null;
15334
15380
  }
@@ -15340,9 +15386,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15340
15386
  var nodeLinkFn, childLinkFn, node, $node, childScope, childTranscludeFn, i, ii, n;
15341
15387
 
15342
15388
  // copy nodeList so that linking doesn't break due to live list updates.
15343
- var stableNodeList = [];
15344
- for (i = 0, ii = nodeList.length; i < ii; i++) {
15345
- stableNodeList.push(nodeList[i]);
15389
+ var nodeListLength = nodeList.length,
15390
+ stableNodeList = new Array(nodeListLength);
15391
+ for (i = 0; i < nodeListLength; i++) {
15392
+ stableNodeList[i] = nodeList[i];
15346
15393
  }
15347
15394
 
15348
15395
  for(i = 0, n = 0, ii = linkFns.length; i < ii; n++) {
@@ -15355,7 +15402,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15355
15402
  if (nodeLinkFn.scope) {
15356
15403
  childScope = scope.$new();
15357
15404
  $node.data('$scope', childScope);
15358
- safeAddClass($node, 'ng-scope');
15359
15405
  } else {
15360
15406
  childScope = scope;
15361
15407
  }
@@ -15438,9 +15484,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15438
15484
 
15439
15485
  nName = directiveNormalize(name.toLowerCase());
15440
15486
  attrsMap[nName] = name;
15441
- attrs[nName] = value = trim((msie && name == 'href')
15442
- ? decodeURIComponent(node.getAttribute(name, 2))
15443
- : attr.value);
15487
+ attrs[nName] = value = trim(attr.value);
15444
15488
  if (getBooleanAttrName(node, nName)) {
15445
15489
  attrs[nName] = true; // presence means true
15446
15490
  }
@@ -18035,6 +18079,14 @@ function $IntervalProvider() {
18035
18079
  * In tests you can use {@link ngMock.$interval#methods_flush `$interval.flush(millis)`} to
18036
18080
  * move forward by `millis` milliseconds and trigger any functions scheduled to run in that
18037
18081
  * time.
18082
+ *
18083
+ * <div class="alert alert-warning">
18084
+ * **Note**: Intervals created by this service must be explicitly destroyed when you are finished
18085
+ * with them. In particular they are not automatically destroyed when a controller's scope or a
18086
+ * directive's element are destroyed.
18087
+ * You should take this into consideration and make sure to always cancel the interval at the
18088
+ * appropriate moment. See the example below for more details on how and when to do this.
18089
+ * </div>
18038
18090
  *
18039
18091
  * @param {function()} fn A function that should be called repeatedly.
18040
18092
  * @param {number} delay Number of milliseconds between each function call.
@@ -18043,6 +18095,95 @@ function $IntervalProvider() {
18043
18095
  * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
18044
18096
  * will invoke `fn` within the {@link ng.$rootScope.Scope#methods_$apply $apply} block.
18045
18097
  * @returns {promise} A promise which will be notified on each iteration.
18098
+ *
18099
+ * @example
18100
+ <doc:example module="time">
18101
+ <doc:source>
18102
+ <script>
18103
+ function Ctrl2($scope,$interval) {
18104
+ $scope.format = 'M/d/yy h:mm:ss a';
18105
+ $scope.blood_1 = 100;
18106
+ $scope.blood_2 = 120;
18107
+
18108
+ var stop;
18109
+ $scope.fight = function() {
18110
+ // Don't start a new fight if we are already fighting
18111
+ if ( angular.isDefined(stop) ) return;
18112
+
18113
+ stop = $interval(function() {
18114
+ if ($scope.blood_1 > 0 && $scope.blood_2 > 0) {
18115
+ $scope.blood_1 = $scope.blood_1 - 3;
18116
+ $scope.blood_2 = $scope.blood_2 - 4;
18117
+ } else {
18118
+ $scope.stopFight();
18119
+ }
18120
+ }, 100);
18121
+ };
18122
+
18123
+ $scope.stopFight = function() {
18124
+ if (angular.isDefined(stop)) {
18125
+ $interval.cancel(stop);
18126
+ stop = undefined;
18127
+ }
18128
+ };
18129
+
18130
+ $scope.resetFight = function() {
18131
+ $scope.blood_1 = 100;
18132
+ $scope.blood_2 = 120;
18133
+ }
18134
+
18135
+ $scope.$on('$destroy', function() {
18136
+ // Make sure that the interval is destroyed too
18137
+ $scope.stopFight();
18138
+ });
18139
+ }
18140
+
18141
+ angular.module('time', [])
18142
+ // Register the 'myCurrentTime' directive factory method.
18143
+ // We inject $interval and dateFilter service since the factory method is DI.
18144
+ .directive('myCurrentTime', function($interval, dateFilter) {
18145
+ // return the directive link function. (compile function not needed)
18146
+ return function(scope, element, attrs) {
18147
+ var format, // date format
18148
+ stopTime; // so that we can cancel the time updates
18149
+
18150
+ // used to update the UI
18151
+ function updateTime() {
18152
+ element.text(dateFilter(new Date(), format));
18153
+ }
18154
+
18155
+ // watch the expression, and update the UI on change.
18156
+ scope.$watch(attrs.myCurrentTime, function(value) {
18157
+ format = value;
18158
+ updateTime();
18159
+ });
18160
+
18161
+ stopTime = $interval(updateTime, 1000);
18162
+
18163
+ // listen on DOM destroy (removal) event, and cancel the next UI update
18164
+ // to prevent updating time ofter the DOM element was removed.
18165
+ element.bind('$destroy', function() {
18166
+ $interval.cancel(stopTime);
18167
+ });
18168
+ }
18169
+ });
18170
+ </script>
18171
+
18172
+ <div>
18173
+ <div ng-controller="Ctrl2">
18174
+ Date format: <input ng-model="format"> <hr/>
18175
+ Current time is: <span my-current-time="format"></span>
18176
+ <hr/>
18177
+ Blood 1 : <font color='red'>{{blood_1}}</font>
18178
+ Blood 2 : <font color='red'>{{blood_2}}</font>
18179
+ <button type="button" data-ng-click="fight()">Fight</button>
18180
+ <button type="button" data-ng-click="stopFight()">StopFight</button>
18181
+ <button type="button" data-ng-click="resetFight()">resetFight</button>
18182
+ </div>
18183
+ </div>
18184
+
18185
+ </doc:source>
18186
+ </doc:example>
18046
18187
  */
18047
18188
  function interval(fn, delay, count, invokeApply) {
18048
18189
  var setInterval = $window.setInterval,
@@ -18801,6 +18942,13 @@ function $LocationProvider(){
18801
18942
  }
18802
18943
 
18803
18944
  var absHref = elm.prop('href');
18945
+
18946
+ if (isObject(absHref) && absHref.toString() === '[object SVGAnimatedString]') {
18947
+ // SVGAnimatedString.animVal should be identical to SVGAnimatedString.baseVal, unless during
18948
+ // an animation.
18949
+ absHref = urlResolve(absHref.animVal).href;
18950
+ }
18951
+
18804
18952
  var rewrittenUrl = $location.$$rewrite(absHref);
18805
18953
 
18806
18954
  if (absHref && !elm.attr('target') && rewrittenUrl && !event.isDefaultPrevented()) {
@@ -19009,9 +19157,16 @@ function $LogProvider(){
19009
19157
 
19010
19158
  function consoleLog(type) {
19011
19159
  var console = $window.console || {},
19012
- logFn = console[type] || console.log || noop;
19160
+ logFn = console[type] || console.log || noop,
19161
+ hasApply = false;
19162
+
19163
+ // Note: reading logFn.apply throws an error in IE11 in IE8 document mode.
19164
+ // The reason behind this is that console.log has type "object" in IE8...
19165
+ try {
19166
+ hasApply = !! logFn.apply;
19167
+ } catch (e) {}
19013
19168
 
19014
- if (logFn.apply) {
19169
+ if (hasApply) {
19015
19170
  return function() {
19016
19171
  var args = [];
19017
19172
  forEach(arguments, function(arg) {
@@ -19921,19 +20076,19 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
19921
20076
  ? function cspSafeGetter(scope, locals) {
19922
20077
  var pathVal = (locals && locals.hasOwnProperty(key0)) ? locals : scope;
19923
20078
 
19924
- if (pathVal === null || pathVal === undefined) return pathVal;
20079
+ if (pathVal == null) return pathVal;
19925
20080
  pathVal = pathVal[key0];
19926
20081
 
19927
- if (!key1 || pathVal === null || pathVal === undefined) return pathVal;
20082
+ if (pathVal == null) return key1 ? undefined : pathVal;
19928
20083
  pathVal = pathVal[key1];
19929
20084
 
19930
- if (!key2 || pathVal === null || pathVal === undefined) return pathVal;
20085
+ if (pathVal == null) return key2 ? undefined : pathVal;
19931
20086
  pathVal = pathVal[key2];
19932
20087
 
19933
- if (!key3 || pathVal === null || pathVal === undefined) return pathVal;
20088
+ if (pathVal == null) return key3 ? undefined : pathVal;
19934
20089
  pathVal = pathVal[key3];
19935
20090
 
19936
- if (!key4 || pathVal === null || pathVal === undefined) return pathVal;
20091
+ if (pathVal == null) return key4 ? undefined : pathVal;
19937
20092
  pathVal = pathVal[key4];
19938
20093
 
19939
20094
  return pathVal;
@@ -19942,7 +20097,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
19942
20097
  var pathVal = (locals && locals.hasOwnProperty(key0)) ? locals : scope,
19943
20098
  promise;
19944
20099
 
19945
- if (pathVal === null || pathVal === undefined) return pathVal;
20100
+ if (pathVal == null) return pathVal;
19946
20101
 
19947
20102
  pathVal = pathVal[key0];
19948
20103
  if (pathVal && pathVal.then) {
@@ -19954,7 +20109,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
19954
20109
  }
19955
20110
  pathVal = pathVal.$$v;
19956
20111
  }
19957
- if (!key1 || pathVal === null || pathVal === undefined) return pathVal;
20112
+ if (pathVal == null) return key1 ? undefined : pathVal;
19958
20113
 
19959
20114
  pathVal = pathVal[key1];
19960
20115
  if (pathVal && pathVal.then) {
@@ -19966,7 +20121,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
19966
20121
  }
19967
20122
  pathVal = pathVal.$$v;
19968
20123
  }
19969
- if (!key2 || pathVal === null || pathVal === undefined) return pathVal;
20124
+ if (pathVal == null) return key2 ? undefined : pathVal;
19970
20125
 
19971
20126
  pathVal = pathVal[key2];
19972
20127
  if (pathVal && pathVal.then) {
@@ -19978,7 +20133,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
19978
20133
  }
19979
20134
  pathVal = pathVal.$$v;
19980
20135
  }
19981
- if (!key3 || pathVal === null || pathVal === undefined) return pathVal;
20136
+ if (pathVal == null) return key3 ? undefined : pathVal;
19982
20137
 
19983
20138
  pathVal = pathVal[key3];
19984
20139
  if (pathVal && pathVal.then) {
@@ -19990,7 +20145,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
19990
20145
  }
19991
20146
  pathVal = pathVal.$$v;
19992
20147
  }
19993
- if (!key4 || pathVal === null || pathVal === undefined) return pathVal;
20148
+ if (pathVal == null) return key4 ? undefined : pathVal;
19994
20149
 
19995
20150
  pathVal = pathVal[key4];
19996
20151
  if (pathVal && pathVal.then) {
@@ -20006,6 +20161,26 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
20006
20161
  };
20007
20162
  }
20008
20163
 
20164
+ function simpleGetterFn1(key0, fullExp) {
20165
+ ensureSafeMemberName(key0, fullExp);
20166
+
20167
+ return function simpleGetterFn1(scope, locals) {
20168
+ if (scope == null) return undefined;
20169
+ return ((locals && locals.hasOwnProperty(key0)) ? locals : scope)[key0];
20170
+ };
20171
+ }
20172
+
20173
+ function simpleGetterFn2(key0, key1, fullExp) {
20174
+ ensureSafeMemberName(key0, fullExp);
20175
+ ensureSafeMemberName(key1, fullExp);
20176
+
20177
+ return function simpleGetterFn2(scope, locals) {
20178
+ if (scope == null) return undefined;
20179
+ scope = ((locals && locals.hasOwnProperty(key0)) ? locals : scope)[key0];
20180
+ return scope == null ? undefined : scope[key1];
20181
+ };
20182
+ }
20183
+
20009
20184
  function getterFn(path, options, fullExp) {
20010
20185
  // Check whether the cache has this getter already.
20011
20186
  // We can use hasOwnProperty directly on the cache because we ensure,
@@ -20018,7 +20193,13 @@ function getterFn(path, options, fullExp) {
20018
20193
  pathKeysLength = pathKeys.length,
20019
20194
  fn;
20020
20195
 
20021
- if (options.csp) {
20196
+ // When we have only 1 or 2 tokens, use optimized special case closures.
20197
+ // http://jsperf.com/angularjs-parse-getter/6
20198
+ if (!options.unwrapPromises && pathKeysLength === 1) {
20199
+ fn = simpleGetterFn1(pathKeys[0], fullExp);
20200
+ } else if (!options.unwrapPromises && pathKeysLength === 2) {
20201
+ fn = simpleGetterFn2(pathKeys[0], pathKeys[1], fullExp);
20202
+ } else if (options.csp) {
20022
20203
  if (pathKeysLength < 6) {
20023
20204
  fn = cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4], fullExp,
20024
20205
  options);
@@ -20036,11 +20217,10 @@ function getterFn(path, options, fullExp) {
20036
20217
  };
20037
20218
  }
20038
20219
  } else {
20039
- var code = 'var l, fn, p;\n';
20220
+ var code = 'var p;\n';
20040
20221
  forEach(pathKeys, function(key, index) {
20041
20222
  ensureSafeMemberName(key, fullExp);
20042
- code += 'if(s === null || s === undefined) return s;\n' +
20043
- 'l=s;\n' +
20223
+ code += 'if(s == null) return undefined;\n' +
20044
20224
  's='+ (index
20045
20225
  // we simply dereference 's' on any .dot notation
20046
20226
  ? 's'
@@ -20063,10 +20243,10 @@ function getterFn(path, options, fullExp) {
20063
20243
  /* jshint -W054 */
20064
20244
  var evaledFnGetter = new Function('s', 'k', 'pw', code); // s=scope, k=locals, pw=promiseWarning
20065
20245
  /* jshint +W054 */
20066
- evaledFnGetter.toString = function() { return code; };
20067
- fn = function(scope, locals) {
20246
+ evaledFnGetter.toString = valueFn(code);
20247
+ fn = options.unwrapPromises ? function(scope, locals) {
20068
20248
  return evaledFnGetter(scope, locals, promiseWarning);
20069
- };
20249
+ } : evaledFnGetter;
20070
20250
  }
20071
20251
 
20072
20252
  // Only cache the value if it's not going to mess up the cache object
@@ -23077,6 +23257,7 @@ function $SnifferProvider() {
23077
23257
  vendorPrefix: vendorPrefix,
23078
23258
  transitions : transitions,
23079
23259
  animations : animations,
23260
+ android: android,
23080
23261
  msie : msie,
23081
23262
  msieDocumentMode: documentMode
23082
23263
  };
@@ -23114,93 +23295,6 @@ function $TimeoutProvider() {
23114
23295
  * @returns {Promise} Promise that will be resolved when the timeout is reached. The value this
23115
23296
  * promise will be resolved with is the return value of the `fn` function.
23116
23297
  *
23117
- * @example
23118
- <doc:example module="time">
23119
- <doc:source>
23120
- <script>
23121
- function Ctrl2($scope,$timeout) {
23122
- $scope.format = 'M/d/yy h:mm:ss a';
23123
- $scope.blood_1 = 100;
23124
- $scope.blood_2 = 120;
23125
-
23126
- var stop;
23127
- $scope.fight = function() {
23128
- stop = $timeout(function() {
23129
- if ($scope.blood_1 > 0 && $scope.blood_2 > 0) {
23130
- $scope.blood_1 = $scope.blood_1 - 3;
23131
- $scope.blood_2 = $scope.blood_2 - 4;
23132
- $scope.fight();
23133
- } else {
23134
- $timeout.cancel(stop);
23135
- }
23136
- }, 100);
23137
- };
23138
-
23139
- $scope.stopFight = function() {
23140
- $timeout.cancel(stop);
23141
- };
23142
-
23143
- $scope.resetFight = function() {
23144
- $scope.blood_1 = 100;
23145
- $scope.blood_2 = 120;
23146
- }
23147
- }
23148
-
23149
- angular.module('time', [])
23150
- // Register the 'myCurrentTime' directive factory method.
23151
- // We inject $timeout and dateFilter service since the factory method is DI.
23152
- .directive('myCurrentTime', function($timeout, dateFilter) {
23153
- // return the directive link function. (compile function not needed)
23154
- return function(scope, element, attrs) {
23155
- var format, // date format
23156
- timeoutId; // timeoutId, so that we can cancel the time updates
23157
-
23158
- // used to update the UI
23159
- function updateTime() {
23160
- element.text(dateFilter(new Date(), format));
23161
- }
23162
-
23163
- // watch the expression, and update the UI on change.
23164
- scope.$watch(attrs.myCurrentTime, function(value) {
23165
- format = value;
23166
- updateTime();
23167
- });
23168
-
23169
- // schedule update in one second
23170
- function updateLater() {
23171
- // save the timeoutId for canceling
23172
- timeoutId = $timeout(function() {
23173
- updateTime(); // update DOM
23174
- updateLater(); // schedule another update
23175
- }, 1000);
23176
- }
23177
-
23178
- // listen on DOM destroy (removal) event, and cancel the next UI update
23179
- // to prevent updating time ofter the DOM element was removed.
23180
- element.bind('$destroy', function() {
23181
- $timeout.cancel(timeoutId);
23182
- });
23183
-
23184
- updateLater(); // kick off the UI update process.
23185
- }
23186
- });
23187
- </script>
23188
-
23189
- <div>
23190
- <div ng-controller="Ctrl2">
23191
- Date format: <input ng-model="format"> <hr/>
23192
- Current time is: <span my-current-time="format"></span>
23193
- <hr/>
23194
- Blood 1 : <font color='red'>{{blood_1}}</font>
23195
- Blood 2 : <font color='red'>{{blood_2}}</font>
23196
- <button type="button" data-ng-click="fight()">Fight</button>
23197
- <button type="button" data-ng-click="stopFight()">StopFight</button>
23198
- <button type="button" data-ng-click="resetFight()">resetFight</button>
23199
- </div>
23200
- </div>
23201
-
23202
- </doc:source>
23203
- </doc:example>
23204
23298
  */
23205
23299
  function timeout(fn, delay, invokeApply) {
23206
23300
  var deferred = $q.defer(),
@@ -24512,6 +24606,7 @@ var htmlAnchorDirective = valueFn({
24512
24606
  * @ngdoc directive
24513
24607
  * @name ng.directive:ngHref
24514
24608
  * @restrict A
24609
+ * @priority 99
24515
24610
  *
24516
24611
  * @description
24517
24612
  * Using Angular markup like `{{hash}}` in an href attribute will
@@ -24595,6 +24690,7 @@ var htmlAnchorDirective = valueFn({
24595
24690
  * @ngdoc directive
24596
24691
  * @name ng.directive:ngSrc
24597
24692
  * @restrict A
24693
+ * @priority 99
24598
24694
  *
24599
24695
  * @description
24600
24696
  * Using Angular markup like `{{hash}}` in a `src` attribute doesn't
@@ -24620,6 +24716,7 @@ var htmlAnchorDirective = valueFn({
24620
24716
  * @ngdoc directive
24621
24717
  * @name ng.directive:ngSrcset
24622
24718
  * @restrict A
24719
+ * @priority 99
24623
24720
  *
24624
24721
  * @description
24625
24722
  * Using Angular markup like `{{hash}}` in a `srcset` attribute doesn't
@@ -24645,6 +24742,7 @@ var htmlAnchorDirective = valueFn({
24645
24742
  * @ngdoc directive
24646
24743
  * @name ng.directive:ngDisabled
24647
24744
  * @restrict A
24745
+ * @priority 100
24648
24746
  *
24649
24747
  * @description
24650
24748
  *
@@ -24688,6 +24786,7 @@ var htmlAnchorDirective = valueFn({
24688
24786
  * @ngdoc directive
24689
24787
  * @name ng.directive:ngChecked
24690
24788
  * @restrict A
24789
+ * @priority 100
24691
24790
  *
24692
24791
  * @description
24693
24792
  * The HTML specification does not require browsers to preserve the values of boolean attributes
@@ -24722,6 +24821,7 @@ var htmlAnchorDirective = valueFn({
24722
24821
  * @ngdoc directive
24723
24822
  * @name ng.directive:ngReadonly
24724
24823
  * @restrict A
24824
+ * @priority 100
24725
24825
  *
24726
24826
  * @description
24727
24827
  * The HTML specification does not require browsers to preserve the values of boolean attributes
@@ -24731,7 +24831,6 @@ var htmlAnchorDirective = valueFn({
24731
24831
  * The `ngReadonly` directive solves this problem for the `readonly` attribute.
24732
24832
  * This complementary directive is not removed by the browser and so provides
24733
24833
  * a permanent reliable place to store the binding information.
24734
-
24735
24834
  * @example
24736
24835
  <doc:example>
24737
24836
  <doc:source>
@@ -24757,6 +24856,7 @@ var htmlAnchorDirective = valueFn({
24757
24856
  * @ngdoc directive
24758
24857
  * @name ng.directive:ngSelected
24759
24858
  * @restrict A
24859
+ * @priority 100
24760
24860
  *
24761
24861
  * @description
24762
24862
  * The HTML specification does not require browsers to preserve the values of boolean attributes
@@ -24766,6 +24866,7 @@ var htmlAnchorDirective = valueFn({
24766
24866
  * The `ngSelected` directive solves this problem for the `selected` atttribute.
24767
24867
  * This complementary directive is not removed by the browser and so provides
24768
24868
  * a permanent reliable place to store the binding information.
24869
+ *
24769
24870
  * @example
24770
24871
  <doc:example>
24771
24872
  <doc:source>
@@ -24793,6 +24894,7 @@ var htmlAnchorDirective = valueFn({
24793
24894
  * @ngdoc directive
24794
24895
  * @name ng.directive:ngOpen
24795
24896
  * @restrict A
24897
+ * @priority 100
24796
24898
  *
24797
24899
  * @description
24798
24900
  * The HTML specification does not require browsers to preserve the values of boolean attributes
@@ -24802,8 +24904,6 @@ var htmlAnchorDirective = valueFn({
24802
24904
  * The `ngOpen` directive solves this problem for the `open` attribute.
24803
24905
  * This complementary directive is not removed by the browser and so provides
24804
24906
  * a permanent reliable place to store the binding information.
24805
-
24806
- *
24807
24907
  * @example
24808
24908
  <doc:example>
24809
24909
  <doc:source>
@@ -25648,15 +25748,17 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
25648
25748
  // In composition mode, users are still inputing intermediate text buffer,
25649
25749
  // hold the listener until composition is done.
25650
25750
  // More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent
25651
- var composing = false;
25751
+ if (!$sniffer.android) {
25752
+ var composing = false;
25652
25753
 
25653
- element.on('compositionstart', function() {
25654
- composing = true;
25655
- });
25754
+ element.on('compositionstart', function(data) {
25755
+ composing = true;
25756
+ });
25656
25757
 
25657
- element.on('compositionend', function() {
25658
- composing = false;
25659
- });
25758
+ element.on('compositionend', function() {
25759
+ composing = false;
25760
+ });
25761
+ }
25660
25762
 
25661
25763
  var listener = function() {
25662
25764
  if (composing) return;
@@ -27221,7 +27323,7 @@ var ngClassEvenDirective = classDirective('Even', 1);
27221
27323
  *
27222
27324
  * Legacy browsers, like IE7, do not provide attribute selector support (added in CSS 2.1) so they
27223
27325
  * cannot match the `[ng\:cloak]` selector. To work around this limitation, you must add the css
27224
- * class `ngCloak` in addition to the `ngCloak` directive as shown in the example below.
27326
+ * class `ng-cloak` in addition to the `ngCloak` directive as shown in the example below.
27225
27327
  *
27226
27328
  * @element ANY
27227
27329
  *
@@ -27532,7 +27634,14 @@ forEach(
27532
27634
  * a dblclick. (The Event object is available as `$event`)
27533
27635
  *
27534
27636
  * @example
27535
- * See {@link ng.directive:ngClick ngClick}
27637
+ <doc:example>
27638
+ <doc:source>
27639
+ <button ng-dblclick="count = count + 1" ng-init="count=0">
27640
+ Increment (on double click)
27641
+ </button>
27642
+ count: {{count}}
27643
+ </doc:source>
27644
+ </doc:example>
27536
27645
  */
27537
27646
 
27538
27647
 
@@ -27548,7 +27657,14 @@ forEach(
27548
27657
  * mousedown. (Event object is available as `$event`)
27549
27658
  *
27550
27659
  * @example
27551
- * See {@link ng.directive:ngClick ngClick}
27660
+ <doc:example>
27661
+ <doc:source>
27662
+ <button ng-mousedown="count = count + 1" ng-init="count=0">
27663
+ Increment (on mouse down)
27664
+ </button>
27665
+ count: {{count}}
27666
+ </doc:source>
27667
+ </doc:example>
27552
27668
  */
27553
27669
 
27554
27670
 
@@ -27564,7 +27680,14 @@ forEach(
27564
27680
  * mouseup. (Event object is available as `$event`)
27565
27681
  *
27566
27682
  * @example
27567
- * See {@link ng.directive:ngClick ngClick}
27683
+ <doc:example>
27684
+ <doc:source>
27685
+ <button ng-mouseup="count = count + 1" ng-init="count=0">
27686
+ Increment (on mouse up)
27687
+ </button>
27688
+ count: {{count}}
27689
+ </doc:source>
27690
+ </doc:example>
27568
27691
  */
27569
27692
 
27570
27693
  /**
@@ -27579,7 +27702,14 @@ forEach(
27579
27702
  * mouseover. (Event object is available as `$event`)
27580
27703
  *
27581
27704
  * @example
27582
- * See {@link ng.directive:ngClick ngClick}
27705
+ <doc:example>
27706
+ <doc:source>
27707
+ <button ng-mouseover="count = count + 1" ng-init="count=0">
27708
+ Increment (when mouse is over)
27709
+ </button>
27710
+ count: {{count}}
27711
+ </doc:source>
27712
+ </doc:example>
27583
27713
  */
27584
27714
 
27585
27715
 
@@ -27595,7 +27725,14 @@ forEach(
27595
27725
  * mouseenter. (Event object is available as `$event`)
27596
27726
  *
27597
27727
  * @example
27598
- * See {@link ng.directive:ngClick ngClick}
27728
+ <doc:example>
27729
+ <doc:source>
27730
+ <button ng-mouseenter="count = count + 1" ng-init="count=0">
27731
+ Increment (when mouse enters)
27732
+ </button>
27733
+ count: {{count}}
27734
+ </doc:source>
27735
+ </doc:example>
27599
27736
  */
27600
27737
 
27601
27738
 
@@ -27611,7 +27748,14 @@ forEach(
27611
27748
  * mouseleave. (Event object is available as `$event`)
27612
27749
  *
27613
27750
  * @example
27614
- * See {@link ng.directive:ngClick ngClick}
27751
+ <doc:example>
27752
+ <doc:source>
27753
+ <button ng-mouseleave="count = count + 1" ng-init="count=0">
27754
+ Increment (when mouse leaves)
27755
+ </button>
27756
+ count: {{count}}
27757
+ </doc:source>
27758
+ </doc:example>
27615
27759
  */
27616
27760
 
27617
27761
 
@@ -27627,7 +27771,14 @@ forEach(
27627
27771
  * mousemove. (Event object is available as `$event`)
27628
27772
  *
27629
27773
  * @example
27630
- * See {@link ng.directive:ngClick ngClick}
27774
+ <doc:example>
27775
+ <doc:source>
27776
+ <button ng-mousemove="count = count + 1" ng-init="count=0">
27777
+ Increment (when mouse moves)
27778
+ </button>
27779
+ count: {{count}}
27780
+ </doc:source>
27781
+ </doc:example>
27631
27782
  */
27632
27783
 
27633
27784
 
@@ -27643,7 +27794,12 @@ forEach(
27643
27794
  * keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
27644
27795
  *
27645
27796
  * @example
27646
- * See {@link ng.directive:ngClick ngClick}
27797
+ <doc:example>
27798
+ <doc:source>
27799
+ <input ng-keydown="count = count + 1" ng-init="count=0">
27800
+ key down count: {{count}}
27801
+ </doc:source>
27802
+ </doc:example>
27647
27803
  */
27648
27804
 
27649
27805
 
@@ -27659,7 +27815,12 @@ forEach(
27659
27815
  * keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
27660
27816
  *
27661
27817
  * @example
27662
- * See {@link ng.directive:ngClick ngClick}
27818
+ <doc:example>
27819
+ <doc:source>
27820
+ <input ng-keyup="count = count + 1" ng-init="count=0">
27821
+ key up count: {{count}}
27822
+ </doc:source>
27823
+ </doc:example>
27663
27824
  */
27664
27825
 
27665
27826
 
@@ -27675,7 +27836,12 @@ forEach(
27675
27836
  * keypress. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
27676
27837
  *
27677
27838
  * @example
27678
- * See {@link ng.directive:ngClick ngClick}
27839
+ <doc:example>
27840
+ <doc:source>
27841
+ <input ng-keypress="count = count + 1" ng-init="count=0">
27842
+ key press count: {{count}}
27843
+ </doc:source>
27844
+ </doc:example>
27679
27845
  */
27680
27846
 
27681
27847
 
@@ -27774,7 +27940,12 @@ forEach(
27774
27940
  * copy. (Event object is available as `$event`)
27775
27941
  *
27776
27942
  * @example
27777
- * See {@link ng.directive:ngClick ngClick}
27943
+ <doc:example>
27944
+ <doc:source>
27945
+ <input ng-copy="copied=true" ng-init="copied=false; value='copy me'" ng-model="value">
27946
+ copied: {{copied}}
27947
+ </doc:source>
27948
+ </doc:example>
27778
27949
  */
27779
27950
 
27780
27951
  /**
@@ -27789,7 +27960,12 @@ forEach(
27789
27960
  * cut. (Event object is available as `$event`)
27790
27961
  *
27791
27962
  * @example
27792
- * See {@link ng.directive:ngClick ngClick}
27963
+ <doc:example>
27964
+ <doc:source>
27965
+ <input ng-cut="cut=true" ng-init="cut=false; value='cut me'" ng-model="value">
27966
+ cut: {{cut}}
27967
+ </doc:source>
27968
+ </doc:example>
27793
27969
  */
27794
27970
 
27795
27971
  /**
@@ -27804,7 +27980,12 @@ forEach(
27804
27980
  * paste. (Event object is available as `$event`)
27805
27981
  *
27806
27982
  * @example
27807
- * See {@link ng.directive:ngClick ngClick}
27983
+ <doc:example>
27984
+ <doc:source>
27985
+ <input ng-paste="paste=true" ng-init="paste=false" placeholder='paste here'>
27986
+ pasted: {{paste}}
27987
+ </doc:source>
27988
+ </doc:example>
27808
27989
  */
27809
27990
 
27810
27991
  /**
@@ -27866,9 +28047,6 @@ forEach(
27866
28047
  padding:10px;
27867
28048
  }
27868
28049
 
27869
- /&#42;
27870
- The transition styles can also be placed on the CSS base class above
27871
- &#42;/
27872
28050
  .animate-if.ng-enter, .animate-if.ng-leave {
27873
28051
  -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
27874
28052
  transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
@@ -28176,7 +28354,7 @@ var ngIncludeFillContentDirective = ['$compile',
28176
28354
  * current scope.
28177
28355
  *
28178
28356
  * <div class="alert alert-error">
28179
- * The only appropriate use of `ngInit` for aliasing special properties of
28357
+ * The only appropriate use of `ngInit` is for aliasing special properties of
28180
28358
  * {@link api/ng.directive:ngRepeat `ngRepeat`}, as seen in the demo below. Besides this case, you
28181
28359
  * should use {@link guide/controller controllers} rather than `ngInit`
28182
28360
  * to initialize values on a scope.
@@ -28675,7 +28853,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
28675
28853
  $$tlb: true,
28676
28854
  link: function($scope, $element, $attr, ctrl, $transclude){
28677
28855
  var expression = $attr.ngRepeat;
28678
- var match = expression.match(/^\s*(.+)\s+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/),
28856
+ var match = expression.match(/^\s*(.+)\s+in\s+([\r\n\s\S]*?)\s*(\s+track\s+by\s+(.+)\s*)?$/),
28679
28857
  trackByExp, trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn,
28680
28858
  lhs, rhs, valueIdentifier, keyIdentifier,
28681
28859
  hashFnLocals = {$id: hashKey};
@@ -29733,18 +29911,10 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
29733
29911
  selectCtrl.init(ngModelCtrl, nullOption, unknownOption);
29734
29912
 
29735
29913
  // required validator
29736
- if (multiple && (attr.required || attr.ngRequired)) {
29737
- var requiredValidator = function(value) {
29738
- ngModelCtrl.$setValidity('required', !attr.required || (value && value.length));
29739
- return value;
29914
+ if (multiple) {
29915
+ ngModelCtrl.$isEmpty = function(value) {
29916
+ return !value || value.length === 0;
29740
29917
  };
29741
-
29742
- ngModelCtrl.$parsers.push(requiredValidator);
29743
- ngModelCtrl.$formatters.unshift(requiredValidator);
29744
-
29745
- attr.$observe('required', function() {
29746
- requiredValidator(ngModelCtrl.$viewValue);
29747
- });
29748
29918
  }
29749
29919
 
29750
29920
  if (optionsExp) setupAsOptions(scope, element, ngModelCtrl);
@@ -32370,5 +32540,5 @@ if (config.autotest) {
32370
32540
  })(window, document);
32371
32541
 
32372
32542
 
32373
- !angular.$$csp() && 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 {\n display: none !important;\n}\n\nng\\:form {\n display: block;\n}\n\n/* The styles below ensure that the CSS transition will ALWAYS\n * animate and close. A nasty bug occurs with CSS transitions where\n * when the active class isn\'t set, or if the active class doesn\'t\n * contain any styles to transition to, then, if ngAnimate is used,\n * it will appear as if the webpage is broken due to the forever hanging\n * animations. The border-spacing (!ie) and zoom (ie) CSS properties are\n * used below since they trigger a transition without making the browser\n * animate anything and they\'re both highly underused CSS properties */\n.ng-animate-start { border-spacing:1px 1px; -ms-zoom:1.0001; }\n.ng-animate-active { border-spacing:0px 0px; -ms-zoom:1; }\n</style>');
32543
+ !angular.$$csp() && 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 {\n display: none !important;\n}\n\nng\\:form {\n display: block;\n}\n</style>');
32374
32544
  !angular.$$csp() && 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>');