@@ -258,6 +258,19 @@ angular.module('ngAnimate', ['ng'])
258
258
var NG_ANIMATE_CLASS_NAME = 'ng-animate' ;
259
259
var rootAnimateState = { running : true } ;
260
260
261
+ function extractElementNode ( element ) {
262
+ for ( var i = 0 ; i < element . length ; i ++ ) {
263
+ var elm = element [ i ] ;
264
+ if ( elm . nodeType == ELEMENT_NODE ) {
265
+ return elm ;
266
+ }
267
+ }
268
+ }
269
+
270
+ function isMatchingElement ( elm1 , elm2 ) {
271
+ return extractElementNode ( elm1 ) == extractElementNode ( elm2 ) ;
272
+ }
273
+
261
274
$provide . decorator ( '$animate' , [ '$delegate' , '$injector' , '$sniffer' , '$rootElement' , '$timeout' , '$rootScope' , '$document' ,
262
275
function ( $delegate , $injector , $sniffer , $rootElement , $timeout , $rootScope , $document ) {
263
276
@@ -556,7 +569,16 @@ angular.module('ngAnimate', ['ng'])
556
569
and the onComplete callback will be fired once the animation is fully complete.
557
570
*/
558
571
function performAnimation ( animationEvent , className , element , parentElement , afterElement , domOperation , doneCallback ) {
559
- var currentClassName = element . attr ( 'class' ) || '' ;
572
+ var node = extractElementNode ( element ) ;
573
+ //transcluded directives may sometimes fire an animation using only comment nodes
574
+ //best to catch this early on to prevent any animation operations from occurring
575
+ if ( ! node ) {
576
+ fireDOMOperation ( ) ;
577
+ closeAnimation ( ) ;
578
+ return ;
579
+ }
580
+
581
+ var currentClassName = node . className ;
560
582
var classes = currentClassName + ' ' + className ;
561
583
var animationLookup = ( ' ' + classes ) . replace ( / \s + / g, '.' ) ;
562
584
if ( ! parentElement ) {
@@ -760,11 +782,7 @@ angular.module('ngAnimate', ['ng'])
760
782
}
761
783
762
784
function cancelChildAnimations ( element ) {
763
- var node = element [ 0 ] ;
764
- if ( node . nodeType != ELEMENT_NODE ) {
765
- return ;
766
- }
767
-
785
+ var node = extractElementNode ( element ) ;
768
786
forEach ( node . querySelectorAll ( '.' + NG_ANIMATE_CLASS_NAME ) , function ( element ) {
769
787
element = angular . element ( element ) ;
770
788
var data = element . data ( NG_ANIMATE_STATE ) ;
@@ -788,7 +806,7 @@ angular.module('ngAnimate', ['ng'])
788
806
}
789
807
790
808
function cleanup ( element ) {
791
- if ( element [ 0 ] == $rootElement [ 0 ] ) {
809
+ if ( isMatchingElement ( element , $rootElement ) ) {
792
810
if ( ! rootAnimateState . disabled ) {
793
811
rootAnimateState . running = false ;
794
812
rootAnimateState . structural = false ;
@@ -802,7 +820,7 @@ angular.module('ngAnimate', ['ng'])
802
820
function animationsDisabled ( element , parentElement ) {
803
821
if ( rootAnimateState . disabled ) return true ;
804
822
805
- if ( element [ 0 ] == $rootElement [ 0 ] ) {
823
+ if ( isMatchingElement ( element , $rootElement ) ) {
806
824
return rootAnimateState . disabled || rootAnimateState . running ;
807
825
}
808
826
@@ -812,7 +830,7 @@ angular.module('ngAnimate', ['ng'])
812
830
//any animations on it
813
831
if ( parentElement . length === 0 ) break ;
814
832
815
- var isRoot = parentElement [ 0 ] == $rootElement [ 0 ] ;
833
+ var isRoot = isMatchingElement ( parentElement , $rootElement ) ;
816
834
var state = isRoot ? rootAnimateState : parentElement . data ( NG_ANIMATE_STATE ) ;
817
835
var result = state && ( ! ! state . disabled || ! ! state . running ) ;
818
836
if ( isRoot || result ) {
@@ -960,7 +978,7 @@ angular.module('ngAnimate', ['ng'])
960
978
parentElement . data ( NG_ANIMATE_PARENT_KEY , ++ parentCounter ) ;
961
979
parentID = parentCounter ;
962
980
}
963
- return parentID + '-' + element [ 0 ] . className ;
981
+ return parentID + '-' + extractElementNode ( element ) . className ;
964
982
}
965
983
966
984
function animateSetup ( element , className ) {
@@ -995,7 +1013,6 @@ angular.module('ngAnimate', ['ng'])
995
1013
return false ;
996
1014
}
997
1015
998
- var node = element [ 0 ] ;
999
1016
//temporarily disable the transition so that the enter styles
1000
1017
//don't animate twice (this is here to avoid a bug in Chrome/FF).
1001
1018
var activeClassName = '' ;
@@ -1025,35 +1042,37 @@ angular.module('ngAnimate', ['ng'])
1025
1042
}
1026
1043
1027
1044
function blockTransitions ( element ) {
1028
- element [ 0 ] . style [ TRANSITION_PROP + PROPERTY_KEY ] = 'none' ;
1045
+ extractElementNode ( element ) . style [ TRANSITION_PROP + PROPERTY_KEY ] = 'none' ;
1029
1046
}
1030
1047
1031
1048
function blockKeyframeAnimations ( element ) {
1032
- element [ 0 ] . style [ ANIMATION_PROP ] = 'none 0s' ;
1049
+ extractElementNode ( element ) . style [ ANIMATION_PROP ] = 'none 0s' ;
1033
1050
}
1034
1051
1035
1052
function unblockTransitions ( element ) {
1036
- var node = element [ 0 ] , prop = TRANSITION_PROP + PROPERTY_KEY ;
1053
+ var prop = TRANSITION_PROP + PROPERTY_KEY ;
1054
+ var node = extractElementNode ( element ) ;
1037
1055
if ( node . style [ prop ] && node . style [ prop ] . length > 0 ) {
1038
1056
node . style [ prop ] = '' ;
1039
1057
}
1040
1058
}
1041
1059
1042
1060
function unblockKeyframeAnimations ( element ) {
1043
- var node = element [ 0 ] , prop = ANIMATION_PROP ;
1061
+ var prop = ANIMATION_PROP ;
1062
+ var node = extractElementNode ( element ) ;
1044
1063
if ( node . style [ prop ] && node . style [ prop ] . length > 0 ) {
1045
- element [ 0 ] . style [ prop ] = '' ;
1064
+ node . style [ prop ] = '' ;
1046
1065
}
1047
1066
}
1048
1067
1049
1068
function animateRun ( element , className , activeAnimationComplete ) {
1050
1069
var data = element . data ( NG_ANIMATE_CSS_DATA_KEY ) ;
1051
- if ( ! element . hasClass ( className ) || ! data ) {
1070
+ var node = extractElementNode ( element ) ;
1071
+ if ( node . className . indexOf ( className ) == - 1 || ! data ) {
1052
1072
activeAnimationComplete ( ) ;
1053
1073
return ;
1054
1074
}
1055
1075
1056
- var node = element [ 0 ] ;
1057
1076
var timings = data . timings ;
1058
1077
var stagger = data . stagger ;
1059
1078
var maxDuration = data . maxDuration ;
@@ -1096,6 +1115,9 @@ angular.module('ngAnimate', ['ng'])
1096
1115
}
1097
1116
1098
1117
if ( appliedStyles . length > 0 ) {
1118
+ //the element being animated may sometimes contain comment nodes in
1119
+ //the jqLite object, so we're safe to use a single variable to house
1120
+ //the styles since there is always only one element being animated
1099
1121
var oldStyle = node . getAttribute ( 'style' ) || '' ;
1100
1122
node . setAttribute ( 'style' , oldStyle + ' ' + style ) ;
1101
1123
}
@@ -1110,6 +1132,7 @@ angular.module('ngAnimate', ['ng'])
1110
1132
element . off ( css3AnimationEvents , onAnimationProgress ) ;
1111
1133
element . removeClass ( activeClassName ) ;
1112
1134
animateClose ( element , className ) ;
1135
+ var node = extractElementNode ( element ) ;
1113
1136
for ( var i in appliedStyles ) {
1114
1137
node . style . removeProperty ( appliedStyles [ i ] ) ;
1115
1138
}
@@ -1209,7 +1232,7 @@ angular.module('ngAnimate', ['ng'])
1209
1232
}
1210
1233
1211
1234
var parentElement = element . parent ( ) ;
1212
- var clone = angular . element ( element [ 0 ] . cloneNode ( ) ) ;
1235
+ var clone = angular . element ( extractElementNode ( element ) . cloneNode ( ) ) ;
1213
1236
1214
1237
//make the element super hidden and override any CSS style values
1215
1238
clone . attr ( 'style' , 'position:absolute; top:-9999px; left:-9999px' ) ;
0 commit comments