angularjs-rails 1.2.26 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/lib/angularjs-rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/angular-animate.js +879 -456
  4. data/vendor/assets/javascripts/angular-aria.js +250 -0
  5. data/vendor/assets/javascripts/angular-cookies.js +1 -1
  6. data/vendor/assets/javascripts/angular-loader.js +17 -10
  7. data/vendor/assets/javascripts/angular-messages.js +400 -0
  8. data/vendor/assets/javascripts/angular-mocks.js +220 -110
  9. data/vendor/assets/javascripts/angular-resource.js +287 -247
  10. data/vendor/assets/javascripts/angular-route.js +111 -54
  11. data/vendor/assets/javascripts/angular-sanitize.js +1 -1
  12. data/vendor/assets/javascripts/angular-scenario.js +11579 -8665
  13. data/vendor/assets/javascripts/angular-touch.js +49 -11
  14. data/vendor/assets/javascripts/angular.js +6660 -3106
  15. data/vendor/assets/javascripts/unstable/angular-animate.js +240 -71
  16. data/vendor/assets/javascripts/unstable/angular-aria.js +12 -12
  17. data/vendor/assets/javascripts/unstable/angular-cookies.js +1 -1
  18. data/vendor/assets/javascripts/unstable/angular-loader.js +4 -4
  19. data/vendor/assets/javascripts/unstable/angular-messages.js +1 -1
  20. data/vendor/assets/javascripts/unstable/angular-mocks.js +21 -14
  21. data/vendor/assets/javascripts/unstable/angular-resource.js +2 -2
  22. data/vendor/assets/javascripts/unstable/angular-route.js +1 -1
  23. data/vendor/assets/javascripts/unstable/angular-sanitize.js +1 -1
  24. data/vendor/assets/javascripts/unstable/angular-scenario.js +562 -262
  25. data/vendor/assets/javascripts/unstable/angular-touch.js +1 -1
  26. data/vendor/assets/javascripts/unstable/angular.js +562 -262
  27. metadata +16 -14
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.0-rc.5
2
+ * @license AngularJS v1.3.0
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -25,18 +25,18 @@
25
25
  *
26
26
  * Below is a more detailed breakdown of the supported animation events provided by pre-existing ng directives:
27
27
  *
28
- * | Directive | Supported Animations |
29
- * |-----------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------|
30
- * | {@link ng.directive:ngRepeat#usage_animations ngRepeat} | enter, leave and move |
31
- * | {@link ngRoute.directive:ngView#usage_animations ngView} | enter and leave |
32
- * | {@link ng.directive:ngInclude#usage_animations ngInclude} | enter and leave |
33
- * | {@link ng.directive:ngSwitch#usage_animations ngSwitch} | enter and leave |
34
- * | {@link ng.directive:ngIf#usage_animations ngIf} | enter and leave |
35
- * | {@link ng.directive:ngClass#usage_animations ngClass} | add and remove (the CSS class(es) present) |
36
- * | {@link ng.directive:ngShow#usage_animations ngShow} & {@link ng.directive:ngHide#usage_animations ngHide} | add and remove (the ng-hide class value) |
37
- * | {@link ng.directive:form#usage_animations form} & {@link ng.directive:ngModel#usage_animations ngModel} | add and remove (dirty, pristine, valid, invalid & all other validations) |
38
- * | {@link ngMessages.directive:ngMessage#usage_animations ngMessages} | add and remove (ng-active & ng-inactive) |
39
- * | {@link ngMessages.directive:ngMessage#usage_animations ngMessage} | enter and leave |
28
+ * | Directive | Supported Animations |
29
+ * |----------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------|
30
+ * | {@link ng.directive:ngRepeat#animations ngRepeat} | enter, leave and move |
31
+ * | {@link ngRoute.directive:ngView#animations ngView} | enter and leave |
32
+ * | {@link ng.directive:ngInclude#animations ngInclude} | enter and leave |
33
+ * | {@link ng.directive:ngSwitch#animations ngSwitch} | enter and leave |
34
+ * | {@link ng.directive:ngIf#animations ngIf} | enter and leave |
35
+ * | {@link ng.directive:ngClass#animations ngClass} | add and remove (the CSS class(es) present) |
36
+ * | {@link ng.directive:ngShow#animations ngShow} & {@link ng.directive:ngHide#animations ngHide} | add and remove (the ng-hide class value) |
37
+ * | {@link ng.directive:form#animation-hooks form} & {@link ng.directive:ngModel#animation-hooks ngModel} | add and remove (dirty, pristine, valid, invalid & all other validations) |
38
+ * | {@link module:ngMessages#animations ngMessages} | add and remove (ng-active & ng-inactive) |
39
+ * | {@link module:ngMessages#animations ngMessage} | enter and leave |
40
40
  *
41
41
  * You can find out more information about animations upon visiting each directive page.
42
42
  *
@@ -89,7 +89,7 @@
89
89
  * will automatically extend the wait time to enable animations once **all** of the outbound HTTP requests
90
90
  * are complete.
91
91
  *
92
- * <h2>CSS-defined Animations</h2>
92
+ * ## CSS-defined Animations
93
93
  * The animate service will automatically apply two CSS classes to the animated element and these two CSS classes
94
94
  * are designed to contain the start and end CSS styling. Both CSS transitions and keyframe animations are supported
95
95
  * and can be used to play along with this naming structure.
@@ -326,6 +326,49 @@
326
326
  * and the JavaScript animation is found, then the enter callback will handle that animation (in addition to the CSS keyframe animation
327
327
  * or transition code that is defined via a stylesheet).
328
328
  *
329
+ *
330
+ * ### Applying Directive-specific Styles to an Animation
331
+ * In some cases a directive or service may want to provide `$animate` with extra details that the animation will
332
+ * include into its animation. Let's say for example we wanted to render an animation that animates an element
333
+ * towards the mouse coordinates as to where the user clicked last. By collecting the X/Y coordinates of the click
334
+ * (via the event parameter) we can set the `top` and `left` styles into an object and pass that into our function
335
+ * call to `$animate.addClass`.
336
+ *
337
+ * ```js
338
+ * canvas.on('click', function(e) {
339
+ * $animate.addClass(element, 'on', {
340
+ * to: {
341
+ * left : e.client.x + 'px',
342
+ * top : e.client.y + 'px'
343
+ * }
344
+ * }):
345
+ * });
346
+ * ```
347
+ *
348
+ * Now when the animation runs, and a transition or keyframe animation is picked up, then the animation itself will
349
+ * also include and transition the styling of the `left` and `top` properties into its running animation. If we want
350
+ * to provide some starting animation values then we can do so by placing the starting animations styles into an object
351
+ * called `from` in the same object as the `to` animations.
352
+ *
353
+ * ```js
354
+ * canvas.on('click', function(e) {
355
+ * $animate.addClass(element, 'on', {
356
+ * from: {
357
+ * position: 'absolute',
358
+ * left: '0px',
359
+ * top: '0px'
360
+ * },
361
+ * to: {
362
+ * left : e.client.x + 'px',
363
+ * top : e.client.y + 'px'
364
+ * }
365
+ * }):
366
+ * });
367
+ * ```
368
+ *
369
+ * Once the animation is complete or cancelled then the union of both the before and after styles are applied to the
370
+ * element. If `ngAnimate` is not present then the styles will be applied immediately.
371
+ *
329
372
  */
330
373
 
331
374
  angular.module('ngAnimate', ['ng'])
@@ -384,6 +427,7 @@ angular.module('ngAnimate', ['ng'])
384
427
  var selectors = $animateProvider.$$selectors;
385
428
  var isArray = angular.isArray;
386
429
  var isString = angular.isString;
430
+ var isObject = angular.isObject;
387
431
 
388
432
  var ELEMENT_NODE = 1;
389
433
  var NG_ANIMATE_STATE = '$$ngAnimateState';
@@ -478,8 +522,12 @@ angular.module('ngAnimate', ['ng'])
478
522
  // some plugin code may still be passing in the callback
479
523
  // function as the last param for the $animate methods so
480
524
  // it's best to only allow string or array values for now
481
- if (isArray(options)) return options;
482
- if (isString(options)) return [options];
525
+ if (isObject(options)) {
526
+ if (options.tempClasses && isString(options.tempClasses)) {
527
+ options.tempClasses = options.tempClasses.split(/\s+/);
528
+ }
529
+ return options;
530
+ }
483
531
  }
484
532
 
485
533
  function resolveElementClasses(element, cache, runningAnimations) {
@@ -556,7 +604,7 @@ angular.module('ngAnimate', ['ng'])
556
604
  }
557
605
  }
558
606
 
559
- function animationRunner(element, animationEvent, className) {
607
+ function animationRunner(element, animationEvent, className, options) {
560
608
  //transcluded directives may sometimes fire an animation using only comment nodes
561
609
  //best to catch this early on to prevent any animation operations from occurring
562
610
  var node = element[0];
@@ -564,6 +612,11 @@ angular.module('ngAnimate', ['ng'])
564
612
  return;
565
613
  }
566
614
 
615
+ if (options) {
616
+ options.to = options.to || {};
617
+ options.from = options.from || {};
618
+ }
619
+
567
620
  var classNameAdd;
568
621
  var classNameRemove;
569
622
  if (isArray(className)) {
@@ -581,9 +634,10 @@ angular.module('ngAnimate', ['ng'])
581
634
  }
582
635
 
583
636
  var isSetClassOperation = animationEvent == 'setClass';
584
- var isClassBased = isSetClassOperation ||
585
- animationEvent == 'addClass' ||
586
- animationEvent == 'removeClass';
637
+ var isClassBased = isSetClassOperation
638
+ || animationEvent == 'addClass'
639
+ || animationEvent == 'removeClass'
640
+ || animationEvent == 'animate';
587
641
 
588
642
  var currentClassName = element.attr('class');
589
643
  var classes = currentClassName + ' ' + className;
@@ -651,16 +705,19 @@ angular.module('ngAnimate', ['ng'])
651
705
  };
652
706
  switch(animation.event) {
653
707
  case 'setClass':
654
- cancellations.push(animation.fn(element, classNameAdd, classNameRemove, progress));
708
+ cancellations.push(animation.fn(element, classNameAdd, classNameRemove, progress, options));
709
+ break;
710
+ case 'animate':
711
+ cancellations.push(animation.fn(element, className, options.from, options.to, progress));
655
712
  break;
656
713
  case 'addClass':
657
- cancellations.push(animation.fn(element, classNameAdd || className, progress));
714
+ cancellations.push(animation.fn(element, classNameAdd || className, progress, options));
658
715
  break;
659
716
  case 'removeClass':
660
- cancellations.push(animation.fn(element, classNameRemove || className, progress));
717
+ cancellations.push(animation.fn(element, classNameRemove || className, progress, options));
661
718
  break;
662
719
  default:
663
- cancellations.push(animation.fn(element, progress));
720
+ cancellations.push(animation.fn(element, progress, options));
664
721
  break;
665
722
  }
666
723
  });
@@ -676,6 +733,11 @@ angular.module('ngAnimate', ['ng'])
676
733
  className : className,
677
734
  isClassBased : isClassBased,
678
735
  isSetClassOperation : isSetClassOperation,
736
+ applyStyles : function() {
737
+ if (options) {
738
+ element.css(angular.extend(options.from || {}, options.to || {}));
739
+ }
740
+ },
679
741
  before : function(allCompleteFn) {
680
742
  beforeComplete = allCompleteFn;
681
743
  run(before, beforeCancel, function() {
@@ -767,6 +829,65 @@ angular.module('ngAnimate', ['ng'])
767
829
  *
768
830
  */
769
831
  return {
832
+ /**
833
+ * @ngdoc method
834
+ * @name $animate#animate
835
+ * @kind function
836
+ *
837
+ * @description
838
+ * Performs an inline animation on the element which applies the provided `to` and `from` CSS styles to the element.
839
+ * If any detected CSS transition, keyframe or JavaScript matches the provided `className` value then the animation
840
+ * will take on the provided styles. For example, if a transition animation is set for the given className then the
841
+ * provided `from` and `to` styles will be applied alongside the given transition. If a JavaScript animation is
842
+ * detected then the provided styles will be given in as function paramters.
843
+ *
844
+ * ```js
845
+ * ngModule.animation('.my-inline-animation', function() {
846
+ * return {
847
+ * animate : function(element, className, from, to, done) {
848
+ * //styles
849
+ * }
850
+ * }
851
+ * });
852
+ * ```
853
+ *
854
+ * Below is a breakdown of each step that occurs during the `animate` animation:
855
+ *
856
+ * | Animation Step | What the element class attribute looks like |
857
+ * |-------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------|
858
+ * | 1. $animate.animate(...) is called | class="my-animation" |
859
+ * | 2. $animate waits for the next digest to start the animation | class="my-animation ng-animate" |
860
+ * | 3. $animate runs the JavaScript-defined animations detected on the element | class="my-animation ng-animate" |
861
+ * | 4. the className class value is added to the element | class="my-animation ng-animate className" |
862
+ * | 5. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate className" |
863
+ * | 6. $animate blocks all CSS transitions on the element to ensure the .className class styling is applied right away| class="my-animation ng-animate className" |
864
+ * | 7. $animate applies the provided collection of `from` CSS styles to the element | class="my-animation ng-animate className" |
865
+ * | 8. $animate waits for a single animation frame (this performs a reflow) | class="my-animation ng-animate className" |
866
+ * | 9. $animate removes the CSS transition block placed on the element | class="my-animation ng-animate className" |
867
+ * | 10. the className-active class is added (this triggers the CSS transition/animation) | class="my-animation ng-animate className className-active" |
868
+ * | 11. $animate applies the collection of `to` CSS styles to the element which are then handled by the transition | class="my-animation ng-animate className className-active" |
869
+ * | 12. $animate waits for the animation to complete (via events and timeout) | class="my-animation ng-animate className className-active" |
870
+ * | 13. The animation ends and all generated CSS classes are removed from the element | class="my-animation" |
871
+ * | 14. The returned promise is resolved. | class="my-animation" |
872
+ *
873
+ * @param {DOMElement} element the element that will be the focus of the enter animation
874
+ * @param {object} from a collection of CSS styles that will be applied to the element at the start of the animation
875
+ * @param {object} to a collection of CSS styles that the element will animate towards
876
+ * @param {string=} className an optional CSS class that will be added to the element for the duration of the animation (the default class is `ng-inline-animate`)
877
+ * @param {object=} options an optional collection of options that will be picked up by the CSS transition/animation
878
+ * @return {Promise} the animation callback promise
879
+ */
880
+ animate : function(element, from, to, className, options) {
881
+ className = className || 'ng-inline-animate';
882
+ options = parseAnimateOptions(options) || {};
883
+ options.from = to ? from : null;
884
+ options.to = to ? to : from;
885
+
886
+ return runAnimationPostDigest(function(done) {
887
+ return performAnimation('animate', className, stripCommentsFromElement(element), null, null, noop, options, done);
888
+ });
889
+ },
890
+
770
891
  /**
771
892
  * @ngdoc method
772
893
  * @name $animate#enter
@@ -797,6 +918,7 @@ angular.module('ngAnimate', ['ng'])
797
918
  * @param {DOMElement} element the element that will be the focus of the enter animation
798
919
  * @param {DOMElement} parentElement the parent element of the element that will be the focus of the enter animation
799
920
  * @param {DOMElement} afterElement the sibling element (which is the previous element) of the element that will be the focus of the enter animation
921
+ * @param {object=} options an optional collection of options that will be picked up by the CSS transition/animation
800
922
  * @return {Promise} the animation callback promise
801
923
  */
802
924
  enter : function(element, parentElement, afterElement, options) {
@@ -840,6 +962,7 @@ angular.module('ngAnimate', ['ng'])
840
962
  * | 13. The returned promise is resolved. | ... |
841
963
  *
842
964
  * @param {DOMElement} element the element that will be the focus of the leave animation
965
+ * @param {object=} options an optional collection of styles that will be picked up by the CSS transition/animation
843
966
  * @return {Promise} the animation callback promise
844
967
  */
845
968
  leave : function(element, options) {
@@ -886,6 +1009,7 @@ angular.module('ngAnimate', ['ng'])
886
1009
  * @param {DOMElement} element the element that will be the focus of the move animation
887
1010
  * @param {DOMElement} parentElement the parentElement element of the element that will be the focus of the move animation
888
1011
  * @param {DOMElement} afterElement the sibling element (which is the previous element) of the element that will be the focus of the move animation
1012
+ * @param {object=} options an optional collection of styles that will be picked up by the CSS transition/animation
889
1013
  * @return {Promise} the animation callback promise
890
1014
  */
891
1015
  move : function(element, parentElement, afterElement, options) {
@@ -929,6 +1053,7 @@ angular.module('ngAnimate', ['ng'])
929
1053
  *
930
1054
  * @param {DOMElement} element the element that will be animated
931
1055
  * @param {string} className the CSS class that will be added to the element and then animated
1056
+ * @param {object=} options an optional collection of styles that will be picked up by the CSS transition/animation
932
1057
  * @return {Promise} the animation callback promise
933
1058
  */
934
1059
  addClass : function(element, className, options) {
@@ -962,6 +1087,7 @@ angular.module('ngAnimate', ['ng'])
962
1087
  *
963
1088
  * @param {DOMElement} element the element that will be animated
964
1089
  * @param {string} className the CSS class that will be animated and then removed from the element
1090
+ * @param {object=} options an optional collection of styles that will be picked up by the CSS transition/animation
965
1091
  * @return {Promise} the animation callback promise
966
1092
  */
967
1093
  removeClass : function(element, className, options) {
@@ -993,6 +1119,7 @@ angular.module('ngAnimate', ['ng'])
993
1119
  * @param {string} add the CSS classes which will be added to the element
994
1120
  * @param {string} remove the CSS class which will be removed from the element
995
1121
  * CSS classes have been set on the element
1122
+ * @param {object=} options an optional collection of styles that will be picked up by the CSS transition/animation
996
1123
  * @return {Promise} the animation callback promise
997
1124
  */
998
1125
  setClass : function(element, add, remove, options) {
@@ -1003,10 +1130,7 @@ angular.module('ngAnimate', ['ng'])
1003
1130
  element = stripCommentsFromElement(element);
1004
1131
 
1005
1132
  if (classBasedAnimationsBlocked(element)) {
1006
- // TODO(@caitp/@matsko): Don't use private/undocumented API here --- we should not be
1007
- // changing the DOM synchronously in this case. The `true` parameter must eventually be
1008
- // removed.
1009
- return $delegate.setClass(element, add, remove, true);
1133
+ return $delegate.$$setClassImmediately(element, add, remove, options);
1010
1134
  }
1011
1135
 
1012
1136
  // we're using a combined array for both the add and remove
@@ -1035,7 +1159,7 @@ angular.module('ngAnimate', ['ng'])
1035
1159
 
1036
1160
  if (hasCache) {
1037
1161
  if (options && cache.options) {
1038
- cache.options = cache.options.concat(options);
1162
+ cache.options = angular.extend(cache.options || {}, options);
1039
1163
  }
1040
1164
 
1041
1165
  //the digest cycle will combine all the animations into one function
@@ -1130,9 +1254,8 @@ angular.module('ngAnimate', ['ng'])
1130
1254
  and the onComplete callback will be fired once the animation is fully complete.
1131
1255
  */
1132
1256
  function performAnimation(animationEvent, className, element, parentElement, afterElement, domOperation, options, doneCallback) {
1133
-
1134
1257
  var noopCancel = noop;
1135
- var runner = animationRunner(element, animationEvent, className);
1258
+ var runner = animationRunner(element, animationEvent, className, options);
1136
1259
  if (!runner) {
1137
1260
  fireDOMOperation();
1138
1261
  fireBeforeCallbackAsync();
@@ -1202,7 +1325,10 @@ angular.module('ngAnimate', ['ng'])
1202
1325
  }
1203
1326
  }
1204
1327
 
1205
- if (runner.isClassBased && !runner.isSetClassOperation && !skipAnimation) {
1328
+ if (runner.isClassBased
1329
+ && !runner.isSetClassOperation
1330
+ && animationEvent != 'animate'
1331
+ && !skipAnimation) {
1206
1332
  skipAnimation = (animationEvent == 'addClass') == element.hasClass(className); //opposite of XOR
1207
1333
  }
1208
1334
 
@@ -1237,8 +1363,8 @@ angular.module('ngAnimate', ['ng'])
1237
1363
  //the ng-animate class does nothing, but it's here to allow for
1238
1364
  //parent animations to find and cancel child animations when needed
1239
1365
  element.addClass(NG_ANIMATE_CLASS_NAME);
1240
- if (isArray(options)) {
1241
- forEach(options, function(className) {
1366
+ if (options && options.tempClasses) {
1367
+ forEach(options.tempClasses, function(className) {
1242
1368
  element.addClass(className);
1243
1369
  });
1244
1370
  }
@@ -1310,9 +1436,13 @@ angular.module('ngAnimate', ['ng'])
1310
1436
 
1311
1437
  function closeAnimation() {
1312
1438
  if (!closeAnimation.hasBeenRun) {
1439
+ if (runner) { //the runner doesn't exist if it fails to instantiate
1440
+ runner.applyStyles();
1441
+ }
1442
+
1313
1443
  closeAnimation.hasBeenRun = true;
1314
- if (isArray(options)) {
1315
- forEach(options, function(className) {
1444
+ if (options && options.tempClasses) {
1445
+ forEach(options.tempClasses, function(className) {
1316
1446
  element.removeClass(className);
1317
1447
  });
1318
1448
  }
@@ -1603,7 +1733,7 @@ angular.module('ngAnimate', ['ng'])
1603
1733
  return parentID + '-' + extractElementNode(element).getAttribute('class');
1604
1734
  }
1605
1735
 
1606
- function animateSetup(animationEvent, element, className) {
1736
+ function animateSetup(animationEvent, element, className, styles) {
1607
1737
  var structural = ['ng-enter','ng-leave','ng-move'].indexOf(className) >= 0;
1608
1738
 
1609
1739
  var cacheKey = getCacheKey(element);
@@ -1635,7 +1765,7 @@ angular.module('ngAnimate', ['ng'])
1635
1765
  return false;
1636
1766
  }
1637
1767
 
1638
- var blockTransition = structural && transitionDuration > 0;
1768
+ var blockTransition = styles || (structural && transitionDuration > 0);
1639
1769
  var blockAnimation = animationDuration > 0 &&
1640
1770
  stagger.animationDelay > 0 &&
1641
1771
  stagger.animationDuration === 0;
@@ -1654,6 +1784,9 @@ angular.module('ngAnimate', ['ng'])
1654
1784
 
1655
1785
  if (blockTransition) {
1656
1786
  blockTransitions(node, true);
1787
+ if (styles) {
1788
+ element.css(styles);
1789
+ }
1657
1790
  }
1658
1791
 
1659
1792
  if (blockAnimation) {
@@ -1663,7 +1796,7 @@ angular.module('ngAnimate', ['ng'])
1663
1796
  return true;
1664
1797
  }
1665
1798
 
1666
- function animateRun(animationEvent, element, className, activeAnimationComplete) {
1799
+ function animateRun(animationEvent, element, className, activeAnimationComplete, styles) {
1667
1800
  var node = extractElementNode(element);
1668
1801
  var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY);
1669
1802
  if (node.getAttribute('class').indexOf(className) == -1 || !elementData) {
@@ -1671,10 +1804,6 @@ angular.module('ngAnimate', ['ng'])
1671
1804
  return;
1672
1805
  }
1673
1806
 
1674
- if (elementData.blockTransition) {
1675
- blockTransitions(node, false);
1676
- }
1677
-
1678
1807
  var activeClassName = '';
1679
1808
  var pendingClassName = '';
1680
1809
  forEach(className.split(' '), function(klass, i) {
@@ -1705,6 +1834,9 @@ angular.module('ngAnimate', ['ng'])
1705
1834
 
1706
1835
  if (!staggerTime) {
1707
1836
  element.addClass(activeClassName);
1837
+ if (elementData.blockTransition) {
1838
+ blockTransitions(node, false);
1839
+ }
1708
1840
  }
1709
1841
 
1710
1842
  var eventCacheKey = elementData.cacheKey + ' ' + activeClassName;
@@ -1717,6 +1849,14 @@ angular.module('ngAnimate', ['ng'])
1717
1849
  return;
1718
1850
  }
1719
1851
 
1852
+ if (!staggerTime && styles) {
1853
+ if (!timings.transitionDuration) {
1854
+ element.css('transition', timings.animationDuration + 's linear all');
1855
+ appliedStyles.push('transition');
1856
+ }
1857
+ element.css(styles);
1858
+ }
1859
+
1720
1860
  var maxDelay = Math.max(timings.transitionDelay, timings.animationDelay);
1721
1861
  var maxDelayTime = maxDelay * ONE_SECOND;
1722
1862
 
@@ -1741,11 +1881,24 @@ angular.module('ngAnimate', ['ng'])
1741
1881
  element.addClass(pendingClassName);
1742
1882
  staggerTimeout = $timeout(function() {
1743
1883
  staggerTimeout = null;
1744
- element.addClass(activeClassName);
1745
- element.removeClass(pendingClassName);
1884
+
1885
+ if (timings.transitionDuration > 0) {
1886
+ blockTransitions(node, false);
1887
+ }
1746
1888
  if (timings.animationDuration > 0) {
1747
1889
  blockAnimations(node, false);
1748
1890
  }
1891
+
1892
+ element.addClass(activeClassName);
1893
+ element.removeClass(pendingClassName);
1894
+
1895
+ if (styles) {
1896
+ if (timings.transitionDuration === 0) {
1897
+ element.css('transition', timings.animationDuration + 's linear all');
1898
+ }
1899
+ element.css(styles);
1900
+ appliedStyles.push('transition');
1901
+ }
1749
1902
  }, staggerTime * ONE_SECOND, false);
1750
1903
  }
1751
1904
 
@@ -1762,7 +1915,7 @@ angular.module('ngAnimate', ['ng'])
1762
1915
  // This will automatically be called by $animate so
1763
1916
  // there is no need to attach this internally to the
1764
1917
  // timeout done method.
1765
- function onEnd(cancelled) {
1918
+ function onEnd() {
1766
1919
  element.off(css3AnimationEvents, onAnimationProgress);
1767
1920
  element.removeClass(activeClassName);
1768
1921
  element.removeClass(pendingClassName);
@@ -1806,28 +1959,28 @@ angular.module('ngAnimate', ['ng'])
1806
1959
  node.style[ANIMATION_PROP + ANIMATION_PLAYSTATE_KEY] = bool ? 'paused' : '';
1807
1960
  }
1808
1961
 
1809
- function animateBefore(animationEvent, element, className, calculationDecorator) {
1810
- if (animateSetup(animationEvent, element, className, calculationDecorator)) {
1962
+ function animateBefore(animationEvent, element, className, styles) {
1963
+ if (animateSetup(animationEvent, element, className, styles)) {
1811
1964
  return function(cancelled) {
1812
1965
  cancelled && animateClose(element, className);
1813
1966
  };
1814
1967
  }
1815
1968
  }
1816
1969
 
1817
- function animateAfter(animationEvent, element, className, afterAnimationComplete) {
1970
+ function animateAfter(animationEvent, element, className, afterAnimationComplete, styles) {
1818
1971
  if (element.data(NG_ANIMATE_CSS_DATA_KEY)) {
1819
- return animateRun(animationEvent, element, className, afterAnimationComplete);
1972
+ return animateRun(animationEvent, element, className, afterAnimationComplete, styles);
1820
1973
  } else {
1821
1974
  animateClose(element, className);
1822
1975
  afterAnimationComplete();
1823
1976
  }
1824
1977
  }
1825
1978
 
1826
- function animate(animationEvent, element, className, animationComplete) {
1979
+ function animate(animationEvent, element, className, animationComplete, options) {
1827
1980
  //If the animateSetup function doesn't bother returning a
1828
1981
  //cancellation function then it means that there is no animation
1829
1982
  //to perform at all
1830
- var preReflowCancellation = animateBefore(animationEvent, element, className);
1983
+ var preReflowCancellation = animateBefore(animationEvent, element, className, options.from);
1831
1984
  if (!preReflowCancellation) {
1832
1985
  clearCacheAfterReflow();
1833
1986
  animationComplete();
@@ -1844,7 +1997,7 @@ angular.module('ngAnimate', ['ng'])
1844
1997
  //once the reflow is complete then we point cancel to
1845
1998
  //the new cancellation function which will remove all of the
1846
1999
  //animation properties from the active animation
1847
- cancel = animateAfter(animationEvent, element, className, animationComplete);
2000
+ cancel = animateAfter(animationEvent, element, className, animationComplete, options.to);
1848
2001
  });
1849
2002
 
1850
2003
  return function(cancelled) {
@@ -1866,22 +2019,33 @@ angular.module('ngAnimate', ['ng'])
1866
2019
  }
1867
2020
 
1868
2021
  return {
1869
- enter : function(element, animationCompleted) {
1870
- return animate('enter', element, 'ng-enter', animationCompleted);
2022
+ animate : function(element, className, from, to, animationCompleted, options) {
2023
+ options = options || {};
2024
+ options.from = from;
2025
+ options.to = to;
2026
+ return animate('animate', element, className, animationCompleted, options);
2027
+ },
2028
+
2029
+ enter : function(element, animationCompleted, options) {
2030
+ options = options || {};
2031
+ return animate('enter', element, 'ng-enter', animationCompleted, options);
1871
2032
  },
1872
2033
 
1873
- leave : function(element, animationCompleted) {
1874
- return animate('leave', element, 'ng-leave', animationCompleted);
2034
+ leave : function(element, animationCompleted, options) {
2035
+ options = options || {};
2036
+ return animate('leave', element, 'ng-leave', animationCompleted, options);
1875
2037
  },
1876
2038
 
1877
- move : function(element, animationCompleted) {
1878
- return animate('move', element, 'ng-move', animationCompleted);
2039
+ move : function(element, animationCompleted, options) {
2040
+ options = options || {};
2041
+ return animate('move', element, 'ng-move', animationCompleted, options);
1879
2042
  },
1880
2043
 
1881
- beforeSetClass : function(element, add, remove, animationCompleted) {
2044
+ beforeSetClass : function(element, add, remove, animationCompleted, options) {
2045
+ options = options || {};
1882
2046
  var className = suffixClasses(remove, '-remove') + ' ' +
1883
2047
  suffixClasses(add, '-add');
1884
- var cancellationMethod = animateBefore('setClass', element, className);
2048
+ var cancellationMethod = animateBefore('setClass', element, className, options.from);
1885
2049
  if (cancellationMethod) {
1886
2050
  afterReflow(element, animationCompleted);
1887
2051
  return cancellationMethod;
@@ -1890,8 +2054,9 @@ angular.module('ngAnimate', ['ng'])
1890
2054
  animationCompleted();
1891
2055
  },
1892
2056
 
1893
- beforeAddClass : function(element, className, animationCompleted) {
1894
- var cancellationMethod = animateBefore('addClass', element, suffixClasses(className, '-add'));
2057
+ beforeAddClass : function(element, className, animationCompleted, options) {
2058
+ options = options || {};
2059
+ var cancellationMethod = animateBefore('addClass', element, suffixClasses(className, '-add'), options.from);
1895
2060
  if (cancellationMethod) {
1896
2061
  afterReflow(element, animationCompleted);
1897
2062
  return cancellationMethod;
@@ -1900,8 +2065,9 @@ angular.module('ngAnimate', ['ng'])
1900
2065
  animationCompleted();
1901
2066
  },
1902
2067
 
1903
- beforeRemoveClass : function(element, className, animationCompleted) {
1904
- var cancellationMethod = animateBefore('removeClass', element, suffixClasses(className, '-remove'));
2068
+ beforeRemoveClass : function(element, className, animationCompleted, options) {
2069
+ options = options || {};
2070
+ var cancellationMethod = animateBefore('removeClass', element, suffixClasses(className, '-remove'), options.from);
1905
2071
  if (cancellationMethod) {
1906
2072
  afterReflow(element, animationCompleted);
1907
2073
  return cancellationMethod;
@@ -1910,19 +2076,22 @@ angular.module('ngAnimate', ['ng'])
1910
2076
  animationCompleted();
1911
2077
  },
1912
2078
 
1913
- setClass : function(element, add, remove, animationCompleted) {
2079
+ setClass : function(element, add, remove, animationCompleted, options) {
2080
+ options = options || {};
1914
2081
  remove = suffixClasses(remove, '-remove');
1915
2082
  add = suffixClasses(add, '-add');
1916
2083
  var className = remove + ' ' + add;
1917
- return animateAfter('setClass', element, className, animationCompleted);
2084
+ return animateAfter('setClass', element, className, animationCompleted, options.to);
1918
2085
  },
1919
2086
 
1920
- addClass : function(element, className, animationCompleted) {
1921
- return animateAfter('addClass', element, suffixClasses(className, '-add'), animationCompleted);
2087
+ addClass : function(element, className, animationCompleted, options) {
2088
+ options = options || {};
2089
+ return animateAfter('addClass', element, suffixClasses(className, '-add'), animationCompleted, options.to);
1922
2090
  },
1923
2091
 
1924
- removeClass : function(element, className, animationCompleted) {
1925
- return animateAfter('removeClass', element, suffixClasses(className, '-remove'), animationCompleted);
2092
+ removeClass : function(element, className, animationCompleted, options) {
2093
+ options = options || {};
2094
+ return animateAfter('removeClass', element, suffixClasses(className, '-remove'), animationCompleted, options.to);
1926
2095
  }
1927
2096
  };
1928
2097