@@ -1020,8 +1020,11 @@ angular.module('ngAnimate', ['ng'])
1020
1020
if ( parentElement . length === 0 ) break ;
1021
1021
1022
1022
var isRoot = isMatchingElement ( parentElement , $rootElement ) ;
1023
- var state = isRoot ? rootAnimateState : parentElement . data ( NG_ANIMATE_STATE ) ;
1024
- var result = state && ( ! ! state . disabled || state . running || state . totalActive > 0 ) ;
1023
+ var state = isRoot ? rootAnimateState : ( parentElement . data ( NG_ANIMATE_STATE ) || { } ) ;
1024
+ var result = state . disabled || state . running
1025
+ ? true
1026
+ : state . last && ! state . last . isClassBased ;
1027
+
1025
1028
if ( isRoot || result ) {
1026
1029
return result ;
1027
1030
}
@@ -1071,7 +1074,6 @@ angular.module('ngAnimate', ['ng'])
1071
1074
var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount' ;
1072
1075
var NG_ANIMATE_PARENT_KEY = '$$ngAnimateKey' ;
1073
1076
var NG_ANIMATE_CSS_DATA_KEY = '$$ngAnimateCSS3Data' ;
1074
- var NG_ANIMATE_BLOCK_CLASS_NAME = 'ng-animate-block-transitions' ;
1075
1077
var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3 ;
1076
1078
var CLOSING_TIME_BUFFER = 1.5 ;
1077
1079
var ONE_SECOND = 1000 ;
@@ -1211,7 +1213,9 @@ angular.module('ngAnimate', ['ng'])
1211
1213
return parentID + '-' + extractElementNode ( element ) . className ;
1212
1214
}
1213
1215
1214
- function animateSetup ( animationEvent , element , className , calculationDecorator ) {
1216
+ function animateSetup ( animationEvent , element , className ) {
1217
+ var structural = [ 'ng-enter' , 'ng-leave' , 'ng-move' ] . indexOf ( className ) >= 0 ;
1218
+
1215
1219
var cacheKey = getCacheKey ( element ) ;
1216
1220
var eventCacheKey = cacheKey + ' ' + className ;
1217
1221
var itemIndex = lookupCache [ eventCacheKey ] ? ++ lookupCache [ eventCacheKey ] . total : 0 ;
@@ -1229,85 +1233,44 @@ angular.module('ngAnimate', ['ng'])
1229
1233
applyClasses && element . removeClass ( staggerClassName ) ;
1230
1234
}
1231
1235
1232
- /* the animation itself may need to add/remove special CSS classes
1233
- * before calculating the anmation styles */
1234
- calculationDecorator = calculationDecorator ||
1235
- function ( fn ) { return fn ( ) ; } ;
1236
-
1237
1236
element . addClass ( className ) ;
1238
1237
1239
1238
var formerData = element . data ( NG_ANIMATE_CSS_DATA_KEY ) || { } ;
1240
-
1241
- var timings = calculationDecorator ( function ( ) {
1242
- return getElementAnimationDetails ( element , eventCacheKey ) ;
1243
- } ) ;
1244
-
1239
+ var timings = getElementAnimationDetails ( element , eventCacheKey ) ;
1245
1240
var transitionDuration = timings . transitionDuration ;
1246
1241
var animationDuration = timings . animationDuration ;
1247
- if ( transitionDuration === 0 && animationDuration === 0 ) {
1242
+
1243
+ if ( structural && transitionDuration === 0 && animationDuration === 0 ) {
1248
1244
element . removeClass ( className ) ;
1249
1245
return false ;
1250
1246
}
1251
1247
1248
+ var blockTransition = structural && transitionDuration > 0 ;
1249
+ var blockAnimation = animationDuration > 0 &&
1250
+ stagger . animationDelay > 0 &&
1251
+ stagger . animationDuration === 0 ;
1252
+
1252
1253
element . data ( NG_ANIMATE_CSS_DATA_KEY , {
1254
+ stagger : stagger ,
1255
+ cacheKey : eventCacheKey ,
1253
1256
running : formerData . running || 0 ,
1254
1257
itemIndex : itemIndex ,
1255
- stagger : stagger ,
1256
- timings : timings ,
1258
+ blockTransition : blockTransition ,
1259
+ blockAnimation : blockAnimation ,
1257
1260
closeAnimationFn : noop
1258
1261
} ) ;
1259
1262
1260
- //temporarily disable the transition so that the enter styles
1261
- //don't animate twice (this is here to avoid a bug in Chrome/FF).
1262
- var isCurrentlyAnimating = formerData . running > 0 || animationEvent == 'setClass' ;
1263
- if ( transitionDuration > 0 ) {
1264
- blockTransitions ( element , className , isCurrentlyAnimating ) ;
1265
- }
1266
-
1267
- //staggering keyframe animations work by adjusting the `animation-delay` CSS property
1268
- //on the given element, however, the delay value can only calculated after the reflow
1269
- //since by that time $animate knows how many elements are being animated. Therefore,
1270
- //until the reflow occurs the element needs to be blocked (where the keyframe animation
1271
- //is set to `none 0s`). This blocking mechanism should only be set for when a stagger
1272
- //animation is detected and when the element item index is greater than 0.
1273
- if ( animationDuration > 0 && stagger . animationDelay > 0 && stagger . animationDuration === 0 ) {
1274
- blockKeyframeAnimations ( element ) ;
1275
- }
1276
-
1277
- return true ;
1278
- }
1279
-
1280
- function isStructuralAnimation ( className ) {
1281
- return className == 'ng-enter' || className == 'ng-move' || className == 'ng-leave' ;
1282
- }
1263
+ var node = extractElementNode ( element ) ;
1283
1264
1284
- function blockTransitions ( element , className , isAnimating ) {
1285
- if ( isStructuralAnimation ( className ) || ! isAnimating ) {
1286
- extractElementNode ( element ) . style [ TRANSITION_PROP + PROPERTY_KEY ] = 'none' ;
1287
- } else {
1288
- element . addClass ( NG_ANIMATE_BLOCK_CLASS_NAME ) ;
1265
+ if ( blockTransition ) {
1266
+ node . style [ TRANSITION_PROP + PROPERTY_KEY ] = 'none' ;
1289
1267
}
1290
- }
1291
-
1292
- function blockKeyframeAnimations ( element ) {
1293
- extractElementNode ( element ) . style [ ANIMATION_PROP ] = 'none 0s' ;
1294
- }
1295
1268
1296
- function unblockTransitions ( element , className ) {
1297
- var prop = TRANSITION_PROP + PROPERTY_KEY ;
1298
- var node = extractElementNode ( element ) ;
1299
- if ( node . style [ prop ] && node . style [ prop ] . length > 0 ) {
1300
- node . style [ prop ] = '' ;
1269
+ if ( blockAnimation ) {
1270
+ node . style [ ANIMATION_PROP ] = 'none 0s' ;
1301
1271
}
1302
- element . removeClass ( NG_ANIMATE_BLOCK_CLASS_NAME ) ;
1303
- }
1304
1272
1305
- function unblockKeyframeAnimations ( element ) {
1306
- var prop = ANIMATION_PROP ;
1307
- var node = extractElementNode ( element ) ;
1308
- if ( node . style [ prop ] && node . style [ prop ] . length > 0 ) {
1309
- node . style [ prop ] = '' ;
1310
- }
1273
+ return true ;
1311
1274
}
1312
1275
1313
1276
function animateRun ( animationEvent , element , className , activeAnimationComplete ) {
@@ -1318,21 +1281,36 @@ angular.module('ngAnimate', ['ng'])
1318
1281
return ;
1319
1282
}
1320
1283
1284
+ if ( elementData . blockTransition ) {
1285
+ node . style [ TRANSITION_PROP + PROPERTY_KEY ] = '' ;
1286
+ }
1287
+
1288
+ if ( elementData . blockAnimation ) {
1289
+ node . style [ ANIMATION_PROP ] = '' ;
1290
+ }
1291
+
1321
1292
var activeClassName = '' ;
1322
1293
forEach ( className . split ( ' ' ) , function ( klass , i ) {
1323
1294
activeClassName += ( i > 0 ? ' ' : '' ) + klass + '-active' ;
1324
1295
} ) ;
1325
1296
1326
- var stagger = elementData . stagger ;
1327
- var timings = elementData . timings ;
1328
- var itemIndex = elementData . itemIndex ;
1297
+ element . addClass ( activeClassName ) ;
1298
+ var eventCacheKey = elementData . eventCacheKey + ' ' + activeClassName ;
1299
+ var timings = getElementAnimationDetails ( element , eventCacheKey ) ;
1300
+
1329
1301
var maxDuration = Math . max ( timings . transitionDuration , timings . animationDuration ) ;
1302
+ if ( maxDuration === 0 ) {
1303
+ element . removeClass ( activeClassName ) ;
1304
+ animateClose ( element , className ) ;
1305
+ activeAnimationComplete ( ) ;
1306
+ return ;
1307
+ }
1308
+
1330
1309
var maxDelay = Math . max ( timings . transitionDelay , timings . animationDelay ) ;
1310
+ var stagger = elementData . stagger ;
1311
+ var itemIndex = elementData . itemIndex ;
1331
1312
var maxDelayTime = maxDelay * ONE_SECOND ;
1332
1313
1333
- var startTime = Date . now ( ) ;
1334
- var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT ;
1335
-
1336
1314
var style = '' , appliedStyles = [ ] ;
1337
1315
if ( timings . transitionDuration > 0 ) {
1338
1316
var propertyStyle = timings . transitionPropertyStyle ;
@@ -1367,8 +1345,10 @@ angular.module('ngAnimate', ['ng'])
1367
1345
node . setAttribute ( 'style' , oldStyle + ' ' + style ) ;
1368
1346
}
1369
1347
1348
+ var startTime = Date . now ( ) ;
1349
+ var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT ;
1350
+
1370
1351
element . on ( css3AnimationEvents , onAnimationProgress ) ;
1371
- element . addClass ( activeClassName ) ;
1372
1352
elementData . closeAnimationFn = function ( ) {
1373
1353
onEnd ( ) ;
1374
1354
activeAnimationComplete ( ) ;
@@ -1460,8 +1440,6 @@ angular.module('ngAnimate', ['ng'])
1460
1440
//happen in the first place
1461
1441
var cancel = preReflowCancellation ;
1462
1442
afterReflow ( element , function ( ) {
1463
- unblockTransitions ( element , className ) ;
1464
- unblockKeyframeAnimations ( element ) ;
1465
1443
//once the reflow is complete then we point cancel to
1466
1444
//the new cancellation function which will remove all of the
1467
1445
//animation properties from the active animation
@@ -1502,49 +1480,27 @@ angular.module('ngAnimate', ['ng'])
1502
1480
beforeSetClass : function ( element , add , remove , animationCompleted ) {
1503
1481
var className = suffixClasses ( remove , '-remove' ) + ' ' +
1504
1482
suffixClasses ( add , '-add' ) ;
1505
- var cancellationMethod = animateBefore ( 'setClass' , element , className , function ( fn ) {
1506
- /* when classes are removed from an element then the transition style
1507
- * that is applied is the transition defined on the element without the
1508
- * CSS class being there. This is how CSS3 functions outside of ngAnimate.
1509
- * http://plnkr.co/edit/j8OzgTNxHTb4n3zLyjGW?p=preview */
1510
- var klass = element . attr ( 'class' ) ;
1511
- element . removeClass ( remove ) ;
1512
- element . addClass ( add ) ;
1513
- var timings = fn ( ) ;
1514
- element . attr ( 'class' , klass ) ;
1515
- return timings ;
1516
- } ) ;
1517
-
1483
+ var cancellationMethod = animateBefore ( 'setClass' , element , className ) ;
1518
1484
if ( cancellationMethod ) {
1519
- afterReflow ( element , function ( ) {
1520
- unblockTransitions ( element , className ) ;
1521
- unblockKeyframeAnimations ( element ) ;
1522
- animationCompleted ( ) ;
1523
- } ) ;
1485
+ afterReflow ( element , animationCompleted ) ;
1524
1486
return cancellationMethod ;
1525
1487
}
1526
1488
animationCompleted ( ) ;
1527
1489
} ,
1528
1490
1529
1491
beforeAddClass : function ( element , className , animationCompleted ) {
1530
- var cancellationMethod = animateBefore ( 'addClass' , element , suffixClasses ( className , '-add' ) , function ( fn ) {
1531
-
1532
- /* when a CSS class is added to an element then the transition style that
1533
- * is applied is the transition defined on the element when the CSS class
1534
- * is added at the time of the animation. This is how CSS3 functions
1535
- * outside of ngAnimate. */
1536
- element . addClass ( className ) ;
1537
- var timings = fn ( ) ;
1538
- element . removeClass ( className ) ;
1539
- return timings ;
1540
- } ) ;
1492
+ var cancellationMethod = animateBefore ( 'addClass' , element , suffixClasses ( className , '-add' ) ) ;
1493
+ if ( cancellationMethod ) {
1494
+ afterReflow ( element , animationCompleted ) ;
1495
+ return cancellationMethod ;
1496
+ }
1497
+ animationCompleted ( ) ;
1498
+ } ,
1541
1499
1500
+ beforeRemoveClass : function ( element , className , animationCompleted ) {
1501
+ var cancellationMethod = animateBefore ( 'removeClass' , element , suffixClasses ( className , '-remove' ) ) ;
1542
1502
if ( cancellationMethod ) {
1543
- afterReflow ( element , function ( ) {
1544
- unblockTransitions ( element , className ) ;
1545
- unblockKeyframeAnimations ( element ) ;
1546
- animationCompleted ( ) ;
1547
- } ) ;
1503
+ afterReflow ( element , animationCompleted ) ;
1548
1504
return cancellationMethod ;
1549
1505
}
1550
1506
animationCompleted ( ) ;
@@ -1561,30 +1517,6 @@ angular.module('ngAnimate', ['ng'])
1561
1517
return animateAfter ( 'addClass' , element , suffixClasses ( className , '-add' ) , animationCompleted ) ;
1562
1518
} ,
1563
1519
1564
- beforeRemoveClass : function ( element , className , animationCompleted ) {
1565
- var cancellationMethod = animateBefore ( 'removeClass' , element , suffixClasses ( className , '-remove' ) , function ( fn ) {
1566
- /* when classes are removed from an element then the transition style
1567
- * that is applied is the transition defined on the element without the
1568
- * CSS class being there. This is how CSS3 functions outside of ngAnimate.
1569
- * http://plnkr.co/edit/j8OzgTNxHTb4n3zLyjGW?p=preview */
1570
- var klass = element . attr ( 'class' ) ;
1571
- element . removeClass ( className ) ;
1572
- var timings = fn ( ) ;
1573
- element . attr ( 'class' , klass ) ;
1574
- return timings ;
1575
- } ) ;
1576
-
1577
- if ( cancellationMethod ) {
1578
- afterReflow ( element , function ( ) {
1579
- unblockTransitions ( element , className ) ;
1580
- unblockKeyframeAnimations ( element ) ;
1581
- animationCompleted ( ) ;
1582
- } ) ;
1583
- return cancellationMethod ;
1584
- }
1585
- animationCompleted ( ) ;
1586
- } ,
1587
-
1588
1520
removeClass : function ( element , className , animationCompleted ) {
1589
1521
return animateAfter ( 'removeClass' , element , suffixClasses ( className , '-remove' ) , animationCompleted ) ;
1590
1522
}
0 commit comments