angularjs-rails 1.2.26 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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