angular-gem 1.2.5 → 1.2.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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>');