angularjs-rails 1.2.15 → 1.2.16

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.3.0-beta.3
2
+ * @license AngularJS v1.3.0-beta.5
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -12,11 +12,8 @@
12
12
  * @name ngAnimate
13
13
  * @description
14
14
  *
15
- * # ngAnimate
16
- *
17
15
  * The `ngAnimate` module provides support for JavaScript, CSS3 transition and CSS3 keyframe animation hooks within existing core and custom directives.
18
16
  *
19
- *
20
17
  * <div doc-module-components="ngAnimate"></div>
21
18
  *
22
19
  * # Usage
@@ -28,17 +25,16 @@
28
25
  *
29
26
  * Below is a more detailed breakdown of the supported animation events provided by pre-existing ng directives:
30
27
  *
31
- * | Directive | Supported Animations |
32
- * |---------------------------------------------------------- |----------------------------------------------------|
33
- * | {@link ng.directive:ngRepeat#usage_animations ngRepeat} | enter, leave and move |
34
- * | {@link ngRoute.directive:ngView#usage_animations ngView} | enter and leave |
35
- * | {@link ng.directive:ngInclude#usage_animations ngInclude} | enter and leave |
36
- * | {@link ng.directive:ngSwitch#usage_animations ngSwitch} | enter and leave |
37
- * | {@link ng.directive:ngIf#usage_animations ngIf} | enter and leave |
38
- * | {@link ng.directive:ngClass#usage_animations ngClass} | add and remove |
39
- * | {@link ng.directive:ngShow#usage_animations ngShow & ngHide} | add and remove (the ng-hide class value) |
40
- * | {@link ng.directive:form#usage_animations form} | add and remove (dirty, pristine, valid, invalid & all other validations) |
41
- * | {@link ng.directive:ngModel#usage_animations ngModel} | add and remove (dirty, pristine, valid, invalid & all other validations) |
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) |
42
38
  *
43
39
  * You can find out more information about animations upon visiting each directive page.
44
40
  *
@@ -112,11 +108,11 @@
112
108
  * -webkit-animation: enter_sequence 1s linear; /&#42; Safari/Chrome &#42;/
113
109
  * animation: enter_sequence 1s linear; /&#42; IE10+ and Future Browsers &#42;/
114
110
  * }
115
- * &#64-webkit-keyframes enter_sequence {
111
+ * @-webkit-keyframes enter_sequence {
116
112
  * from { opacity:0; }
117
113
  * to { opacity:1; }
118
114
  * }
119
- * &#64keyframes enter_sequence {
115
+ * @keyframes enter_sequence {
120
116
  * from { opacity:0; }
121
117
  * to { opacity:1; }
122
118
  * }
@@ -136,7 +132,74 @@
136
132
  * immediately resulting in a DOM element that is at its final state. This final state is when the DOM element
137
133
  * has no CSS transition/animation classes applied to it.
138
134
  *
139
- * <h3>CSS Staggering Animations</h3>
135
+ * ### Structural transition animations
136
+ *
137
+ * Structural transitions (such as enter, leave and move) will always apply a `0s none` transition
138
+ * value to force the browser into rendering the styles defined in the setup (.ng-enter, .ng-leave
139
+ * or .ng-move) class. This means that any active transition animations operating on the element
140
+ * will be cut off to make way for the enter, leave or move animation.
141
+ *
142
+ * ### Class-based transition animations
143
+ *
144
+ * Class-based transitions refer to transition animations that are triggered when a CSS class is
145
+ * added to or removed from the element (via `$animate.addClass`, `$animate.removeClass`,
146
+ * `$animate.setClass`, or by directives such as `ngClass`, `ngModel` and `form`).
147
+ * They are different when compared to structural animations since they **do not cancel existing
148
+ * animations** nor do they **block successive transitions** from rendering on the same element.
149
+ * This distinction allows for **multiple class-based transitions** to be performed on the same element.
150
+ *
151
+ * In addition to ngAnimate supporting the default (natural) functionality of class-based transition
152
+ * animations, ngAnimate also decorates the element with starting and ending CSS classes to aid the
153
+ * developer in further styling the element throughout the transition animation. Earlier versions
154
+ * of ngAnimate may have caused natural CSS transitions to break and not render properly due to
155
+ * $animate temporarily blocking transitions using `0s none` in order to allow the setup CSS class
156
+ * (the `-add` or `-remove` class) to be applied without triggering an animation. However, as of
157
+ * **version 1.3**, this workaround has been removed with ngAnimate and all non-ngAnimate CSS
158
+ * class transitions are compatible with ngAnimate.
159
+ *
160
+ * There is, however, one special case when dealing with class-based transitions in ngAnimate.
161
+ * When rendering class-based transitions that make use of the setup and active CSS classes
162
+ * (e.g. `.fade-add` and `.fade-add-active` for when `.fade` is added) be sure to define
163
+ * the transition value **on the active CSS class** and not the setup class.
164
+ *
165
+ * ```css
166
+ * .fade-add {
167
+ * /&#42; remember to place a 0s transition here
168
+ * to ensure that the styles are applied instantly
169
+ * even if the element already has a transition style &#42;/
170
+ * transition:0s linear all;
171
+ *
172
+ * /&#42; starting CSS styles &#42;/
173
+ * opacity:1;
174
+ * }
175
+ * .fade-add.fade-add-active {
176
+ * /&#42; this will be the length of the animation &#42;/
177
+ * transition:1s linear all;
178
+ * opacity:0;
179
+ * }
180
+ * ```
181
+ *
182
+ * The setup CSS class (in this case `.fade-add`) also has a transition style property, however, it
183
+ * has a duration of zero. This may not be required, however, incase the browser is unable to render
184
+ * the styling present in this CSS class instantly then it could be that the browser is attempting
185
+ * to perform an unnecessary transition.
186
+ *
187
+ * This workaround, however, does not apply to standard class-based transitions that are rendered
188
+ * when a CSS class containing a transition is applied to an element:
189
+ *
190
+ * ```css
191
+ * .fade {
192
+ * /&#42; this works as expected &#42;/
193
+ * transition:1s linear all;
194
+ * opacity:0;
195
+ * }
196
+ * ```
197
+ *
198
+ * Please keep this in mind when coding the CSS markup that will be used within class-based transitions.
199
+ * Also, try not to mix the two class-based animation flavors together since the CSS code may become
200
+ * overly complex.
201
+ *
202
+ * ### CSS Staggering Animations
140
203
  * A Staggering animation is a collection of animations that are issued with a slight delay in between each successive operation resulting in a
141
204
  * curtain-like effect. The ngAnimate module, as of 1.2.0, supports staggering animations and the stagger effect can be
142
205
  * performed by creating a **ng-EVENT-stagger** CSS class and attaching that class to the base CSS class used for
@@ -338,9 +401,12 @@ angular.module('ngAnimate', ['ng'])
338
401
  //operation which performs CSS transition and keyframe
339
402
  //animations sniffing. This is always included for each
340
403
  //element animation procedure if the browser supports
341
- //transitions and/or keyframe animations
404
+ //transitions and/or keyframe animations. The default
405
+ //animation is added to the top of the list to prevent
406
+ //any previous animations from affecting the element styling
407
+ //prior to the element being animated.
342
408
  if ($sniffer.transitions || $sniffer.animations) {
343
- classes.push('');
409
+ matches.push($injector.get(selectors['']));
344
410
  }
345
411
 
346
412
  for(var i=0; i < classes.length; i++) {
@@ -528,18 +594,21 @@ angular.module('ngAnimate', ['ng'])
528
594
  *
529
595
  * Below is a breakdown of each step that occurs during enter animation:
530
596
  *
531
- * | Animation Step | What the element class attribute looks like |
532
- * |----------------------------------------------------------------------------------------------|---------------------------------------------|
533
- * | 1. $animate.enter(...) is called | class="my-animation" |
534
- * | 2. element is inserted into the parentElement element or beside the afterElement element | class="my-animation" |
535
- * | 3. $animate runs any JavaScript-defined animations on the element | class="my-animation ng-animate" |
536
- * | 4. the .ng-enter class is added to the element | class="my-animation ng-animate ng-enter" |
537
- * | 5. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate ng-enter" |
538
- * | 6. $animate waits for 10ms (this performs a reflow) | class="my-animation ng-animate ng-enter" |
539
- * | 7. the .ng-enter-active and .ng-animate-active classes are added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active ng-enter ng-enter-active" |
540
- * | 8. $animate waits for X milliseconds for the animation to complete | class="my-animation ng-animate ng-animate-active ng-enter ng-enter-active" |
541
- * | 9. The animation ends and all generated CSS classes are removed from the element | class="my-animation" |
542
- * | 10. The doneCallback() callback is fired (if provided) | class="my-animation" |
597
+ * | Animation Step | What the element class attribute looks like |
598
+ * |-------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------|
599
+ * | 1. $animate.enter(...) is called | class="my-animation" |
600
+ * | 2. element is inserted into the parentElement element or beside the afterElement element | class="my-animation" |
601
+ * | 3. $animate waits for the next digest to start the animation | class="my-animation ng-animate" |
602
+ * | 4. $animate runs the JavaScript-defined animations detected on the element | class="my-animation ng-animate" |
603
+ * | 5. the .ng-enter class is added to the element | class="my-animation ng-animate ng-enter" |
604
+ * | 6. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate ng-enter" |
605
+ * | 7. $animate blocks all CSS transitions on the element to ensure the .ng-enter class styling is applied right away | class="my-animation ng-animate ng-enter" |
606
+ * | 8. $animate waits for a single animation frame (this performs a reflow) | class="my-animation ng-animate ng-enter" |
607
+ * | 9. $animate removes the CSS transition block placed on the element | class="my-animation ng-animate ng-enter" |
608
+ * | 10. the .ng-enter-active class is added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-enter ng-enter-active" |
609
+ * | 11. $animate waits for the animation to complete (via events and timeout) | class="my-animation ng-animate ng-enter ng-enter-active" |
610
+ * | 12. The animation ends and all generated CSS classes are removed from the element | class="my-animation" |
611
+ * | 13. The doneCallback() callback is fired (if provided) | class="my-animation" |
543
612
  *
544
613
  * @param {DOMElement} element the element that will be the focus of the enter animation
545
614
  * @param {DOMElement} parentElement the parent element of the element that will be the focus of the enter animation
@@ -566,18 +635,21 @@ angular.module('ngAnimate', ['ng'])
566
635
  *
567
636
  * Below is a breakdown of each step that occurs during leave animation:
568
637
  *
569
- * | Animation Step | What the element class attribute looks like |
570
- * |----------------------------------------------------------------------------------------------|---------------------------------------------|
571
- * | 1. $animate.leave(...) is called | class="my-animation" |
572
- * | 2. $animate runs any JavaScript-defined animations on the element | class="my-animation ng-animate" |
573
- * | 3. the .ng-leave class is added to the element | class="my-animation ng-animate ng-leave" |
574
- * | 4. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate ng-leave" |
575
- * | 5. $animate waits for 10ms (this performs a reflow) | class="my-animation ng-animate ng-leave" |
576
- * | 6. the .ng-leave-active and .ng-animate-active classes is added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active ng-leave ng-leave-active" |
577
- * | 7. $animate waits for X milliseconds for the animation to complete | class="my-animation ng-animate ng-animate-active ng-leave ng-leave-active" |
578
- * | 8. The animation ends and all generated CSS classes are removed from the element | class="my-animation" |
579
- * | 9. The element is removed from the DOM | ... |
580
- * | 10. The doneCallback() callback is fired (if provided) | ... |
638
+ * | Animation Step | What the element class attribute looks like |
639
+ * |-------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------|
640
+ * | 1. $animate.leave(...) is called | class="my-animation" |
641
+ * | 2. $animate runs the JavaScript-defined animations detected on the element | class="my-animation ng-animate" |
642
+ * | 3. $animate waits for the next digest to start the animation | class="my-animation ng-animate" |
643
+ * | 4. the .ng-leave class is added to the element | class="my-animation ng-animate ng-leave" |
644
+ * | 5. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate ng-leave" |
645
+ * | 6. $animate blocks all CSS transitions on the element to ensure the .ng-leave class styling is applied right away | class="my-animation ng-animate ng-leave|
646
+ * | 7. $animate waits for a single animation frame (this performs a reflow) | class="my-animation ng-animate ng-leave" |
647
+ * | 8. $animate removes the CSS transition block placed on the element | class="my-animation ng-animate ng-leave” |
648
+ * | 9. the .ng-leave-active class is added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-leave ng-leave-active" |
649
+ * | 10. $animate waits for the animation to complete (via events and timeout) | class="my-animation ng-animate ng-leave ng-leave-active" |
650
+ * | 11. The animation ends and all generated CSS classes are removed from the element | class="my-animation" |
651
+ * | 12. The element is removed from the DOM | ... |
652
+ * | 13. The doneCallback() callback is fired (if provided) | ... |
581
653
  *
582
654
  * @param {DOMElement} element the element that will be the focus of the leave animation
583
655
  * @param {function()=} doneCallback the callback function that will be called once the animation is complete
@@ -604,18 +676,21 @@ angular.module('ngAnimate', ['ng'])
604
676
  *
605
677
  * Below is a breakdown of each step that occurs during move animation:
606
678
  *
607
- * | Animation Step | What the element class attribute looks like |
608
- * |----------------------------------------------------------------------------------------------|---------------------------------------------|
609
- * | 1. $animate.move(...) is called | class="my-animation" |
610
- * | 2. element is moved into the parentElement element or beside the afterElement element | class="my-animation" |
611
- * | 3. $animate runs any JavaScript-defined animations on the element | class="my-animation ng-animate" |
612
- * | 4. the .ng-move class is added to the element | class="my-animation ng-animate ng-move" |
613
- * | 5. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate ng-move" |
614
- * | 6. $animate waits for 10ms (this performs a reflow) | class="my-animation ng-animate ng-move" |
615
- * | 7. the .ng-move-active and .ng-animate-active classes is added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active ng-move ng-move-active" |
616
- * | 8. $animate waits for X milliseconds for the animation to complete | class="my-animation ng-animate ng-animate-active ng-move ng-move-active" |
617
- * | 9. The animation ends and all generated CSS classes are removed from the element | class="my-animation" |
618
- * | 10. The doneCallback() callback is fired (if provided) | class="my-animation" |
679
+ * | Animation Step | What the element class attribute looks like |
680
+ * |------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------|
681
+ * | 1. $animate.move(...) is called | class="my-animation" |
682
+ * | 2. element is moved into the parentElement element or beside the afterElement element | class="my-animation" |
683
+ * | 3. $animate waits for the next digest to start the animation | class="my-animation ng-animate" |
684
+ * | 4. $animate runs the JavaScript-defined animations detected on the element | class="my-animation ng-animate" |
685
+ * | 5. the .ng-move class is added to the element | class="my-animation ng-animate ng-move" |
686
+ * | 6. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate ng-move" |
687
+ * | 7. $animate blocks all CSS transitions on the element to ensure the .ng-move class styling is applied right away | class="my-animation ng-animate ng-move|
688
+ * | 8. $animate waits for a single animation frame (this performs a reflow) | class="my-animation ng-animate ng-move" |
689
+ * | 9. $animate removes the CSS transition block placed on the element | class="my-animation ng-animate ng-move” |
690
+ * | 10. the .ng-move-active class is added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-move ng-move-active" |
691
+ * | 11. $animate waits for the animation to complete (via events and timeout) | class="my-animation ng-animate ng-move ng-move-active" |
692
+ * | 12. The animation ends and all generated CSS classes are removed from the element | class="my-animation" |
693
+ * | 13. The doneCallback() callback is fired (if provided) | class="my-animation" |
619
694
  *
620
695
  * @param {DOMElement} element the element that will be the focus of the move animation
621
696
  * @param {DOMElement} parentElement the parentElement element of the element that will be the focus of the move animation
@@ -640,22 +715,22 @@ angular.module('ngAnimate', ['ng'])
640
715
  * Triggers a custom animation event based off the className variable and then attaches the className value to the element as a CSS class.
641
716
  * Unlike the other animation methods, the animate service will suffix the className value with {@type -add} in order to provide
642
717
  * the animate service the setup and active CSS classes in order to trigger the animation (this will be skipped if no CSS transitions
643
- * or keyframes are defined on the -add or base CSS class).
718
+ * or keyframes are defined on the -add-active or base CSS class).
644
719
  *
645
720
  * Below is a breakdown of each step that occurs during addClass animation:
646
721
  *
647
- * | Animation Step | What the element class attribute looks like |
648
- * |------------------------------------------------------------------------------------------------|---------------------------------------------|
649
- * | 1. $animate.addClass(element, 'super') is called | class="my-animation" |
650
- * | 2. $animate runs any JavaScript-defined animations on the element | class="my-animation ng-animate" |
651
- * | 3. the .super-add class are added to the element | class="my-animation ng-animate super-add" |
652
- * | 4. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate super-add" |
653
- * | 5. $animate waits for 10ms (this performs a reflow) | class="my-animation ng-animate super-add" |
654
- * | 6. the .super, .super-add-active and .ng-animate-active classes are added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active super super-add super-add-active" |
655
- * | 7. $animate waits for X milliseconds for the animation to complete | class="my-animation super super-add super-add-active" |
656
- * | 8. The animation ends and all generated CSS classes are removed from the element | class="my-animation super" |
657
- * | 9. The super class is kept on the element | class="my-animation super" |
658
- * | 10. The doneCallback() callback is fired (if provided) | class="my-animation super" |
722
+ * | Animation Step | What the element class attribute looks like |
723
+ * |----------------------------------------------------------------------------------------------------|------------------------------------------------------------------|
724
+ * | 1. $animate.addClass(element, 'super') is called | class="my-animation" |
725
+ * | 2. $animate runs the JavaScript-defined animations detected on the element | class="my-animation ng-animate" |
726
+ * | 3. the .super-add class is added to the element | class="my-animation ng-animate super-add" |
727
+ * | 4. $animate waits for a single animation frame (this performs a reflow) | class="my-animation ng-animate super-add" |
728
+ * | 5. the .super and .super-add-active classes are added (this triggers the CSS transition/animation) | class="my-animation ng-animate super super-add super-add-active" |
729
+ * | 6. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate super-add" |
730
+ * | 7. $animate waits for the animation to complete (via events and timeout) | class="my-animation super super-add super-add-active" |
731
+ * | 8. The animation ends and all generated CSS classes are removed from the element | class="my-animation super" |
732
+ * | 9. The super class is kept on the element | class="my-animation super" |
733
+ * | 10. The doneCallback() callback is fired (if provided) | class="my-animation super" |
659
734
  *
660
735
  * @param {DOMElement} element the element that will be animated
661
736
  * @param {string} className the CSS class that will be added to the element and then animated
@@ -680,17 +755,17 @@ angular.module('ngAnimate', ['ng'])
680
755
  *
681
756
  * Below is a breakdown of each step that occurs during removeClass animation:
682
757
  *
683
- * | Animation Step | What the element class attribute looks like |
684
- * |-----------------------------------------------------------------------------------------------|---------------------------------------------|
685
- * | 1. $animate.removeClass(element, 'super') is called | class="my-animation super" |
686
- * | 2. $animate runs any JavaScript-defined animations on the element | class="my-animation super ng-animate" |
687
- * | 3. the .super-remove class are added to the element | class="my-animation super ng-animate super-remove"|
688
- * | 4. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation super ng-animate super-remove" |
689
- * | 5. $animate waits for 10ms (this performs a reflow) | class="my-animation super ng-animate super-remove" |
690
- * | 6. the .super-remove-active and .ng-animate-active classes are added and .super is removed (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active super-remove super-remove-active" |
691
- * | 7. $animate waits for X milliseconds for the animation to complete | class="my-animation ng-animate ng-animate-active super-remove super-remove-active" |
692
- * | 8. The animation ends and all generated CSS classes are removed from the element | class="my-animation" |
693
- * | 9. The doneCallback() callback is fired (if provided) | class="my-animation" |
758
+ * | Animation Step | What the element class attribute looks like |
759
+ * |------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------|
760
+ * | 1. $animate.removeClass(element, 'super') is called | class="my-animation super" |
761
+ * | 2. $animate runs the JavaScript-defined animations detected on the element | class="my-animation super ng-animate" |
762
+ * | 3. the .super-remove class is added to the element | class="my-animation super ng-animate super-remove" |
763
+ * | 4. $animate waits for a single animation frame (this performs a reflow) | class="my-animation super ng-animate super-remove" |
764
+ * | 5. the .super-remove-active classes are added and .super is removed (this triggers the CSS transition/animation) | class="my-animation ng-animate super-remove super-remove-active" |
765
+ * | 6. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation super ng-animate super-remove" |
766
+ * | 7. $animate waits for the animation to complete (via events and timeout) | class="my-animation ng-animate super-remove super-remove-active" |
767
+ * | 8. The animation ends and all generated CSS classes are removed from the element | class="my-animation" |
768
+ * | 9. The doneCallback() callback is fired (if provided) | class="my-animation" |
694
769
  *
695
770
  *
696
771
  * @param {DOMElement} element the element that will be animated
@@ -704,20 +779,33 @@ angular.module('ngAnimate', ['ng'])
704
779
  }, doneCallback);
705
780
  },
706
781
 
707
- /**
708
- *
709
- * @ngdoc function
710
- * @name $animate#setClass
711
- * @function
712
- * @description Adds and/or removes the given CSS classes to and from the element.
713
- * Once complete, the done() callback will be fired (if provided).
714
- * @param {DOMElement} element the element which will it's CSS classes changed
715
- * removed from it
716
- * @param {string} add the CSS classes which will be added to the element
717
- * @param {string} remove the CSS class which will be removed from the element
718
- * @param {Function=} done the callback function (if provided) that will be fired after the
719
- * CSS classes have been set on the element
720
- */
782
+ /**
783
+ *
784
+ * @ngdoc method
785
+ * @name $animate#setClass
786
+ *
787
+ * @description Adds and/or removes the given CSS classes to and from the element.
788
+ * Once complete, the done() callback will be fired (if provided).
789
+ *
790
+ * | Animation Step | What the element class attribute looks like |
791
+ * |--------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------|
792
+ * | 1. $animate.removeClass(element, ‘on’, ‘off’) is called | class="my-animation super off” |
793
+ * | 2. $animate runs the JavaScript-defined animations detected on the element | class="my-animation super ng-animate off” |
794
+ * | 3. the .on-add and .off-remove classes are added to the element | class="my-animation ng-animate on-add off-remove off” |
795
+ * | 4. $animate waits for a single animation frame (this performs a reflow) | class="my-animation ng-animate on-add off-remove off” |
796
+ * | 5. the .on, .on-add-active and .off-remove-active classes are added and .off is removed (this triggers the CSS transition/animation) | class="my-animation ng-animate on on-add on-add-active off-remove off-remove-active” |
797
+ * | 6. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate on on-add on-add-active off-remove off-remove-active" |
798
+ * | 7. $animate waits for the animation to complete (via events and timeout) | class="my-animation ng-animate on on-add on-add-active off-remove off-remove-active" |
799
+ * | 8. The animation ends and all generated CSS classes are removed from the element | class="my-animation" |
800
+ * | 9. The doneCallback() callback is fired (if provided) | class="my-animation" |
801
+ *
802
+ * @param {DOMElement} element the element which will it's CSS classes changed
803
+ * removed from it
804
+ * @param {string} add the CSS classes which will be added to the element
805
+ * @param {string} remove the CSS class which will be removed from the element
806
+ * @param {Function=} done the callback function (if provided) that will be fired after the
807
+ * CSS classes have been set on the element
808
+ */
721
809
  setClass : function(element, add, remove, doneCallback) {
722
810
  element = stripCommentsFromElement(element);
723
811
  performAnimation('setClass', [add, remove], element, null, null, function() {
@@ -795,9 +883,9 @@ angular.module('ngAnimate', ['ng'])
795
883
 
796
884
  //only allow animations if the currently running animation is not structural
797
885
  //or if there is no animation running at all
798
- var skipAnimations = runner.isClassBased ?
799
- ngAnimateState.disabled || (lastAnimation && !lastAnimation.isClassBased) :
800
- false;
886
+ var skipAnimations = runner.isClassBased
887
+ ? ngAnimateState.disabled || (lastAnimation && !lastAnimation.isClassBased)
888
+ : false;
801
889
 
802
890
  //skip the animation if animations are disabled, a parent is already being animated,
803
891
  //the element is not currently attached to the document body or then completely close
@@ -1026,8 +1114,11 @@ angular.module('ngAnimate', ['ng'])
1026
1114
  if(parentElement.length === 0) break;
1027
1115
 
1028
1116
  var isRoot = isMatchingElement(parentElement, $rootElement);
1029
- var state = isRoot ? rootAnimateState : parentElement.data(NG_ANIMATE_STATE);
1030
- var result = state && (!!state.disabled || state.running || state.totalActive > 0);
1117
+ var state = isRoot ? rootAnimateState : (parentElement.data(NG_ANIMATE_STATE) || {});
1118
+ var result = state.disabled || state.running
1119
+ ? true
1120
+ : state.last && !state.last.isClassBased;
1121
+
1031
1122
  if(isRoot || result) {
1032
1123
  return result;
1033
1124
  }
@@ -1077,7 +1168,6 @@ angular.module('ngAnimate', ['ng'])
1077
1168
  var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount';
1078
1169
  var NG_ANIMATE_PARENT_KEY = '$$ngAnimateKey';
1079
1170
  var NG_ANIMATE_CSS_DATA_KEY = '$$ngAnimateCSS3Data';
1080
- var NG_ANIMATE_BLOCK_CLASS_NAME = 'ng-animate-block-transitions';
1081
1171
  var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;
1082
1172
  var CLOSING_TIME_BUFFER = 1.5;
1083
1173
  var ONE_SECOND = 1000;
@@ -1115,7 +1205,7 @@ angular.module('ngAnimate', ['ng'])
1115
1205
 
1116
1206
  //but it may not need to cancel out the existing timeout
1117
1207
  //if the timestamp is less than the previous one
1118
- var futureTimestamp = Date.now() + (totalTime * 1000);
1208
+ var futureTimestamp = Date.now() + totalTime;
1119
1209
  if(futureTimestamp <= closingTimestamp) {
1120
1210
  return;
1121
1211
  }
@@ -1214,10 +1304,12 @@ angular.module('ngAnimate', ['ng'])
1214
1304
  parentElement.data(NG_ANIMATE_PARENT_KEY, ++parentCounter);
1215
1305
  parentID = parentCounter;
1216
1306
  }
1217
- return parentID + '-' + extractElementNode(element).className;
1307
+ return parentID + '-' + extractElementNode(element).getAttribute('class');
1218
1308
  }
1219
1309
 
1220
- function animateSetup(animationEvent, element, className, calculationDecorator) {
1310
+ function animateSetup(animationEvent, element, className) {
1311
+ var structural = ['ng-enter','ng-leave','ng-move'].indexOf(className) >= 0;
1312
+
1221
1313
  var cacheKey = getCacheKey(element);
1222
1314
  var eventCacheKey = cacheKey + ' ' + className;
1223
1315
  var itemIndex = lookupCache[eventCacheKey] ? ++lookupCache[eventCacheKey].total : 0;
@@ -1235,110 +1327,84 @@ angular.module('ngAnimate', ['ng'])
1235
1327
  applyClasses && element.removeClass(staggerClassName);
1236
1328
  }
1237
1329
 
1238
- /* the animation itself may need to add/remove special CSS classes
1239
- * before calculating the anmation styles */
1240
- calculationDecorator = calculationDecorator ||
1241
- function(fn) { return fn(); };
1242
-
1243
1330
  element.addClass(className);
1244
1331
 
1245
1332
  var formerData = element.data(NG_ANIMATE_CSS_DATA_KEY) || {};
1246
-
1247
- var timings = calculationDecorator(function() {
1248
- return getElementAnimationDetails(element, eventCacheKey);
1249
- });
1250
-
1333
+ var timings = getElementAnimationDetails(element, eventCacheKey);
1251
1334
  var transitionDuration = timings.transitionDuration;
1252
1335
  var animationDuration = timings.animationDuration;
1253
- if(transitionDuration === 0 && animationDuration === 0) {
1336
+
1337
+ if(structural && transitionDuration === 0 && animationDuration === 0) {
1254
1338
  element.removeClass(className);
1255
1339
  return false;
1256
1340
  }
1257
1341
 
1342
+ var blockTransition = structural && transitionDuration > 0;
1343
+ var blockAnimation = animationDuration > 0 &&
1344
+ stagger.animationDelay > 0 &&
1345
+ stagger.animationDuration === 0;
1346
+
1258
1347
  element.data(NG_ANIMATE_CSS_DATA_KEY, {
1348
+ stagger : stagger,
1349
+ cacheKey : eventCacheKey,
1259
1350
  running : formerData.running || 0,
1260
1351
  itemIndex : itemIndex,
1261
- stagger : stagger,
1262
- timings : timings,
1352
+ blockTransition : blockTransition,
1353
+ blockAnimation : blockAnimation,
1263
1354
  closeAnimationFn : noop
1264
1355
  });
1265
1356
 
1266
- //temporarily disable the transition so that the enter styles
1267
- //don't animate twice (this is here to avoid a bug in Chrome/FF).
1268
- var isCurrentlyAnimating = formerData.running > 0 || animationEvent == 'setClass';
1269
- if(transitionDuration > 0) {
1270
- blockTransitions(element, className, isCurrentlyAnimating);
1271
- }
1272
-
1273
- //staggering keyframe animations work by adjusting the `animation-delay` CSS property
1274
- //on the given element, however, the delay value can only calculated after the reflow
1275
- //since by that time $animate knows how many elements are being animated. Therefore,
1276
- //until the reflow occurs the element needs to be blocked (where the keyframe animation
1277
- //is set to `none 0s`). This blocking mechanism should only be set for when a stagger
1278
- //animation is detected and when the element item index is greater than 0.
1279
- if(animationDuration > 0 && stagger.animationDelay > 0 && stagger.animationDuration === 0) {
1280
- blockKeyframeAnimations(element);
1281
- }
1282
-
1283
- return true;
1284
- }
1285
-
1286
- function isStructuralAnimation(className) {
1287
- return className == 'ng-enter' || className == 'ng-move' || className == 'ng-leave';
1288
- }
1357
+ var node = extractElementNode(element);
1289
1358
 
1290
- function blockTransitions(element, className, isAnimating) {
1291
- if(isStructuralAnimation(className) || !isAnimating) {
1292
- extractElementNode(element).style[TRANSITION_PROP + PROPERTY_KEY] = 'none';
1293
- } else {
1294
- element.addClass(NG_ANIMATE_BLOCK_CLASS_NAME);
1359
+ if(blockTransition) {
1360
+ node.style[TRANSITION_PROP + PROPERTY_KEY] = 'none';
1295
1361
  }
1296
- }
1297
1362
 
1298
- function blockKeyframeAnimations(element) {
1299
- extractElementNode(element).style[ANIMATION_PROP] = 'none 0s';
1300
- }
1301
-
1302
- function unblockTransitions(element, className) {
1303
- var prop = TRANSITION_PROP + PROPERTY_KEY;
1304
- var node = extractElementNode(element);
1305
- if(node.style[prop] && node.style[prop].length > 0) {
1306
- node.style[prop] = '';
1363
+ if(blockAnimation) {
1364
+ node.style[ANIMATION_PROP] = 'none 0s';
1307
1365
  }
1308
- element.removeClass(NG_ANIMATE_BLOCK_CLASS_NAME);
1309
- }
1310
1366
 
1311
- function unblockKeyframeAnimations(element) {
1312
- var prop = ANIMATION_PROP;
1313
- var node = extractElementNode(element);
1314
- if(node.style[prop] && node.style[prop].length > 0) {
1315
- node.style[prop] = '';
1316
- }
1367
+ return true;
1317
1368
  }
1318
1369
 
1319
1370
  function animateRun(animationEvent, element, className, activeAnimationComplete) {
1320
1371
  var node = extractElementNode(element);
1321
1372
  var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY);
1322
- if(node.className.indexOf(className) == -1 || !elementData) {
1373
+ if(node.getAttribute('class').indexOf(className) == -1 || !elementData) {
1323
1374
  activeAnimationComplete();
1324
1375
  return;
1325
1376
  }
1326
1377
 
1378
+ if(elementData.blockTransition) {
1379
+ node.style[TRANSITION_PROP + PROPERTY_KEY] = '';
1380
+ }
1381
+
1382
+ if(elementData.blockAnimation) {
1383
+ node.style[ANIMATION_PROP] = '';
1384
+ }
1385
+
1327
1386
  var activeClassName = '';
1328
1387
  forEach(className.split(' '), function(klass, i) {
1329
1388
  activeClassName += (i > 0 ? ' ' : '') + klass + '-active';
1330
1389
  });
1331
1390
 
1332
- var stagger = elementData.stagger;
1333
- var timings = elementData.timings;
1334
- var itemIndex = elementData.itemIndex;
1391
+ element.addClass(activeClassName);
1392
+ var eventCacheKey = elementData.eventCacheKey + ' ' + activeClassName;
1393
+ var timings = getElementAnimationDetails(element, eventCacheKey);
1394
+
1335
1395
  var maxDuration = Math.max(timings.transitionDuration, timings.animationDuration);
1396
+ if(maxDuration === 0) {
1397
+ element.removeClass(activeClassName);
1398
+ animateClose(element, className);
1399
+ activeAnimationComplete();
1400
+ return;
1401
+ }
1402
+
1336
1403
  var maxDelay = Math.max(timings.transitionDelay, timings.animationDelay);
1404
+ var stagger = elementData.stagger;
1405
+ var itemIndex = elementData.itemIndex;
1337
1406
  var maxDelayTime = maxDelay * ONE_SECOND;
1338
1407
 
1339
- var startTime = Date.now();
1340
- var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT;
1341
-
1342
1408
  var style = '', appliedStyles = [];
1343
1409
  if(timings.transitionDuration > 0) {
1344
1410
  var propertyStyle = timings.transitionPropertyStyle;
@@ -1373,8 +1439,10 @@ angular.module('ngAnimate', ['ng'])
1373
1439
  node.setAttribute('style', oldStyle + ' ' + style);
1374
1440
  }
1375
1441
 
1442
+ var startTime = Date.now();
1443
+ var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT;
1444
+
1376
1445
  element.on(css3AnimationEvents, onAnimationProgress);
1377
- element.addClass(activeClassName);
1378
1446
  elementData.closeAnimationFn = function() {
1379
1447
  onEnd();
1380
1448
  activeAnimationComplete();
@@ -1466,8 +1534,6 @@ angular.module('ngAnimate', ['ng'])
1466
1534
  //happen in the first place
1467
1535
  var cancel = preReflowCancellation;
1468
1536
  afterReflow(element, function() {
1469
- unblockTransitions(element, className);
1470
- unblockKeyframeAnimations(element);
1471
1537
  //once the reflow is complete then we point cancel to
1472
1538
  //the new cancellation function which will remove all of the
1473
1539
  //animation properties from the active animation
@@ -1508,49 +1574,27 @@ angular.module('ngAnimate', ['ng'])
1508
1574
  beforeSetClass : function(element, add, remove, animationCompleted) {
1509
1575
  var className = suffixClasses(remove, '-remove') + ' ' +
1510
1576
  suffixClasses(add, '-add');
1511
- var cancellationMethod = animateBefore('setClass', element, className, function(fn) {
1512
- /* when classes are removed from an element then the transition style
1513
- * that is applied is the transition defined on the element without the
1514
- * CSS class being there. This is how CSS3 functions outside of ngAnimate.
1515
- * http://plnkr.co/edit/j8OzgTNxHTb4n3zLyjGW?p=preview */
1516
- var klass = element.attr('class');
1517
- element.removeClass(remove);
1518
- element.addClass(add);
1519
- var timings = fn();
1520
- element.attr('class', klass);
1521
- return timings;
1522
- });
1523
-
1577
+ var cancellationMethod = animateBefore('setClass', element, className);
1524
1578
  if(cancellationMethod) {
1525
- afterReflow(element, function() {
1526
- unblockTransitions(element, className);
1527
- unblockKeyframeAnimations(element);
1528
- animationCompleted();
1529
- });
1579
+ afterReflow(element, animationCompleted);
1530
1580
  return cancellationMethod;
1531
1581
  }
1532
1582
  animationCompleted();
1533
1583
  },
1534
1584
 
1535
1585
  beforeAddClass : function(element, className, animationCompleted) {
1536
- var cancellationMethod = animateBefore('addClass', element, suffixClasses(className, '-add'), function(fn) {
1537
-
1538
- /* when a CSS class is added to an element then the transition style that
1539
- * is applied is the transition defined on the element when the CSS class
1540
- * is added at the time of the animation. This is how CSS3 functions
1541
- * outside of ngAnimate. */
1542
- element.addClass(className);
1543
- var timings = fn();
1544
- element.removeClass(className);
1545
- return timings;
1546
- });
1586
+ var cancellationMethod = animateBefore('addClass', element, suffixClasses(className, '-add'));
1587
+ if(cancellationMethod) {
1588
+ afterReflow(element, animationCompleted);
1589
+ return cancellationMethod;
1590
+ }
1591
+ animationCompleted();
1592
+ },
1547
1593
 
1594
+ beforeRemoveClass : function(element, className, animationCompleted) {
1595
+ var cancellationMethod = animateBefore('removeClass', element, suffixClasses(className, '-remove'));
1548
1596
  if(cancellationMethod) {
1549
- afterReflow(element, function() {
1550
- unblockTransitions(element, className);
1551
- unblockKeyframeAnimations(element);
1552
- animationCompleted();
1553
- });
1597
+ afterReflow(element, animationCompleted);
1554
1598
  return cancellationMethod;
1555
1599
  }
1556
1600
  animationCompleted();
@@ -1567,30 +1611,6 @@ angular.module('ngAnimate', ['ng'])
1567
1611
  return animateAfter('addClass', element, suffixClasses(className, '-add'), animationCompleted);
1568
1612
  },
1569
1613
 
1570
- beforeRemoveClass : function(element, className, animationCompleted) {
1571
- var cancellationMethod = animateBefore('removeClass', element, suffixClasses(className, '-remove'), function(fn) {
1572
- /* when classes are removed from an element then the transition style
1573
- * that is applied is the transition defined on the element without the
1574
- * CSS class being there. This is how CSS3 functions outside of ngAnimate.
1575
- * http://plnkr.co/edit/j8OzgTNxHTb4n3zLyjGW?p=preview */
1576
- var klass = element.attr('class');
1577
- element.removeClass(className);
1578
- var timings = fn();
1579
- element.attr('class', klass);
1580
- return timings;
1581
- });
1582
-
1583
- if(cancellationMethod) {
1584
- afterReflow(element, function() {
1585
- unblockTransitions(element, className);
1586
- unblockKeyframeAnimations(element);
1587
- animationCompleted();
1588
- });
1589
- return cancellationMethod;
1590
- }
1591
- animationCompleted();
1592
- },
1593
-
1594
1614
  removeClass : function(element, className, animationCompleted) {
1595
1615
  return animateAfter('removeClass', element, suffixClasses(className, '-remove'), animationCompleted);
1596
1616
  }