@@ -484,12 +484,12 @@ angular.module('ngAnimate', ['ng'])
484
484
// the matching CSS class.
485
485
if ( status < 0 ) {
486
486
//does it have the class or will it have the class
487
- if ( hasClass || matchingAnimation . event == 'addClass' ) {
487
+ if ( hasClass || matchingAnimation . event == 'addClass' ) {
488
488
toRemove . push ( className ) ;
489
489
}
490
490
} else if ( status > 0 ) {
491
491
//is the class missing or will it be removed?
492
- if ( ! hasClass || matchingAnimation . event == 'removeClass' ) {
492
+ if ( ! hasClass || matchingAnimation . event == 'removeClass' ) {
493
493
toAdd . push ( className ) ;
494
494
}
495
495
}
@@ -544,7 +544,7 @@ angular.module('ngAnimate', ['ng'])
544
544
if ( ! classNameAdd ) {
545
545
className = classNameRemove ;
546
546
animationEvent = 'removeClass' ;
547
- } else if ( ! classNameRemove ) {
547
+ } else if ( ! classNameRemove ) {
548
548
className = classNameAdd ;
549
549
animationEvent = 'addClass' ;
550
550
} else {
@@ -1101,6 +1101,7 @@ angular.module('ngAnimate', ['ng'])
1101
1101
var totalActiveAnimations = ngAnimateState . totalActive || 0 ;
1102
1102
var lastAnimation = ngAnimateState . last ;
1103
1103
var skipAnimation = false ;
1104
+
1104
1105
if ( totalActiveAnimations > 0 ) {
1105
1106
var animationsToCancel = [ ] ;
1106
1107
if ( ! runner . isClassBased ) {
@@ -1384,6 +1385,7 @@ angular.module('ngAnimate', ['ng'])
1384
1385
var PROPERTY_KEY = 'Property' ;
1385
1386
var DELAY_KEY = 'Delay' ;
1386
1387
var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount' ;
1388
+ var ANIMATION_PLAYSTATE_KEY = 'PlayState' ;
1387
1389
var NG_ANIMATE_PARENT_KEY = '$$ngAnimateKey' ;
1388
1390
var NG_ANIMATE_CSS_DATA_KEY = '$$ngAnimateCSS3Data' ;
1389
1391
var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3 ;
@@ -1455,47 +1457,33 @@ angular.module('ngAnimate', ['ng'])
1455
1457
var transitionDelay = 0 ;
1456
1458
var animationDuration = 0 ;
1457
1459
var animationDelay = 0 ;
1458
- var transitionDelayStyle ;
1459
- var animationDelayStyle ;
1460
- var transitionDurationStyle ;
1461
- var transitionPropertyStyle ;
1462
1460
1463
1461
//we want all the styles defined before and after
1464
1462
forEach ( element , function ( element ) {
1465
1463
if ( element . nodeType == ELEMENT_NODE ) {
1466
1464
var elementStyles = $window . getComputedStyle ( element ) || { } ;
1467
1465
1468
- transitionDurationStyle = elementStyles [ TRANSITION_PROP + DURATION_KEY ] ;
1469
-
1466
+ var transitionDurationStyle = elementStyles [ TRANSITION_PROP + DURATION_KEY ] ;
1470
1467
transitionDuration = Math . max ( parseMaxTime ( transitionDurationStyle ) , transitionDuration ) ;
1471
1468
1472
- transitionPropertyStyle = elementStyles [ TRANSITION_PROP + PROPERTY_KEY ] ;
1473
-
1474
- transitionDelayStyle = elementStyles [ TRANSITION_PROP + DELAY_KEY ] ;
1475
-
1469
+ var transitionDelayStyle = elementStyles [ TRANSITION_PROP + DELAY_KEY ] ;
1476
1470
transitionDelay = Math . max ( parseMaxTime ( transitionDelayStyle ) , transitionDelay ) ;
1477
1471
1478
- animationDelayStyle = elementStyles [ ANIMATION_PROP + DELAY_KEY ] ;
1479
-
1480
- animationDelay = Math . max ( parseMaxTime ( animationDelayStyle ) , animationDelay ) ;
1472
+ var animationDelayStyle = elementStyles [ ANIMATION_PROP + DELAY_KEY ] ;
1473
+ animationDelay = Math . max ( parseMaxTime ( elementStyles [ ANIMATION_PROP + DELAY_KEY ] ) , animationDelay ) ;
1481
1474
1482
1475
var aDuration = parseMaxTime ( elementStyles [ ANIMATION_PROP + DURATION_KEY ] ) ;
1483
1476
1484
1477
if ( aDuration > 0 ) {
1485
1478
aDuration *= parseInt ( elementStyles [ ANIMATION_PROP + ANIMATION_ITERATION_COUNT_KEY ] , 10 ) || 1 ;
1486
1479
}
1487
-
1488
1480
animationDuration = Math . max ( aDuration , animationDuration ) ;
1489
1481
}
1490
1482
} ) ;
1491
1483
data = {
1492
1484
total : 0 ,
1493
- transitionPropertyStyle : transitionPropertyStyle ,
1494
- transitionDurationStyle : transitionDurationStyle ,
1495
- transitionDelayStyle : transitionDelayStyle ,
1496
1485
transitionDelay : transitionDelay ,
1497
1486
transitionDuration : transitionDuration ,
1498
- animationDelayStyle : animationDelayStyle ,
1499
1487
animationDelay : animationDelay ,
1500
1488
animationDuration : animationDuration
1501
1489
} ;
@@ -1571,18 +1559,17 @@ angular.module('ngAnimate', ['ng'])
1571
1559
running : formerData . running || 0 ,
1572
1560
itemIndex : itemIndex ,
1573
1561
blockTransition : blockTransition ,
1574
- blockAnimation : blockAnimation ,
1575
1562
closeAnimationFns : closeAnimationFns
1576
1563
} ) ;
1577
1564
1578
1565
var node = extractElementNode ( element ) ;
1579
1566
1580
1567
if ( blockTransition ) {
1581
- node . style [ TRANSITION_PROP + PROPERTY_KEY ] = 'none' ;
1568
+ blockTransitions ( node , true ) ;
1582
1569
}
1583
1570
1584
1571
if ( blockAnimation ) {
1585
- node . style [ ANIMATION_PROP ] = 'none 0s' ;
1572
+ blockAnimations ( node , true ) ;
1586
1573
}
1587
1574
1588
1575
return true ;
@@ -1597,22 +1584,43 @@ angular.module('ngAnimate', ['ng'])
1597
1584
}
1598
1585
1599
1586
if ( elementData . blockTransition ) {
1600
- node . style [ TRANSITION_PROP + PROPERTY_KEY ] = '' ;
1601
- }
1602
-
1603
- if ( elementData . blockAnimation ) {
1604
- node . style [ ANIMATION_PROP ] = '' ;
1587
+ blockTransitions ( node , false ) ;
1605
1588
}
1606
1589
1607
1590
var activeClassName = '' ;
1591
+ var pendingClassName = '' ;
1608
1592
forEach ( className . split ( ' ' ) , function ( klass , i ) {
1609
- activeClassName += ( i > 0 ? ' ' : '' ) + klass + '-active' ;
1593
+ var prefix = ( i > 0 ? ' ' : '' ) + klass ;
1594
+ activeClassName += prefix + '-active' ;
1595
+ pendingClassName += prefix + '-pending' ;
1610
1596
} ) ;
1611
1597
1612
- element . addClass ( activeClassName ) ;
1598
+ var style = '' ;
1599
+ var appliedStyles = [ ] ;
1600
+ var itemIndex = elementData . itemIndex ;
1601
+ var stagger = elementData . stagger ;
1602
+ var staggerTime = 0 ;
1603
+ if ( itemIndex > 0 ) {
1604
+ var transitionStaggerDelay = 0 ;
1605
+ if ( stagger . transitionDelay > 0 && stagger . transitionDuration === 0 ) {
1606
+ transitionStaggerDelay = stagger . transitionDelay * itemIndex ;
1607
+ }
1608
+
1609
+ var animationStaggerDelay = 0 ;
1610
+ if ( stagger . animationDelay > 0 && stagger . animationDuration === 0 ) {
1611
+ animationStaggerDelay = stagger . animationDelay * itemIndex ;
1612
+ appliedStyles . push ( CSS_PREFIX + 'animation-play-state' ) ;
1613
+ }
1614
+
1615
+ staggerTime = Math . round ( Math . max ( transitionStaggerDelay , animationStaggerDelay ) * 100 ) / 100 ;
1616
+ }
1617
+
1618
+ if ( ! staggerTime ) {
1619
+ element . addClass ( activeClassName ) ;
1620
+ }
1621
+
1613
1622
var eventCacheKey = elementData . cacheKey + ' ' + activeClassName ;
1614
1623
var timings = getElementAnimationDetails ( element , eventCacheKey ) ;
1615
-
1616
1624
var maxDuration = Math . max ( timings . transitionDuration , timings . animationDuration ) ;
1617
1625
if ( maxDuration === 0 ) {
1618
1626
element . removeClass ( activeClassName ) ;
@@ -1622,57 +1630,43 @@ angular.module('ngAnimate', ['ng'])
1622
1630
}
1623
1631
1624
1632
var maxDelay = Math . max ( timings . transitionDelay , timings . animationDelay ) ;
1625
- var stagger = elementData . stagger ;
1626
- var itemIndex = elementData . itemIndex ;
1627
1633
var maxDelayTime = maxDelay * ONE_SECOND ;
1628
1634
1629
- var style = '' , appliedStyles = [ ] ;
1630
- if ( timings . transitionDuration > 0 ) {
1631
- var propertyStyle = timings . transitionPropertyStyle ;
1632
- if ( propertyStyle . indexOf ( 'all' ) == - 1 ) {
1633
- style += CSS_PREFIX + 'transition-property: ' + propertyStyle + ';' ;
1634
- style += CSS_PREFIX + 'transition-duration: ' + timings . transitionDurationStyle + ';' ;
1635
- appliedStyles . push ( CSS_PREFIX + 'transition-property' ) ;
1636
- appliedStyles . push ( CSS_PREFIX + 'transition-duration' ) ;
1637
- }
1638
- }
1639
-
1640
- if ( itemIndex > 0 ) {
1641
- if ( stagger . transitionDelay > 0 && stagger . transitionDuration === 0 ) {
1642
- var delayStyle = timings . transitionDelayStyle ;
1643
- style += CSS_PREFIX + 'transition-delay: ' +
1644
- prepareStaggerDelay ( delayStyle , stagger . transitionDelay , itemIndex ) + '; ' ;
1645
- appliedStyles . push ( CSS_PREFIX + 'transition-delay' ) ;
1646
- }
1647
-
1648
- if ( stagger . animationDelay > 0 && stagger . animationDuration === 0 ) {
1649
- style += CSS_PREFIX + 'animation-delay: ' +
1650
- prepareStaggerDelay ( timings . animationDelayStyle , stagger . animationDelay , itemIndex ) + '; ' ;
1651
- appliedStyles . push ( CSS_PREFIX + 'animation-delay' ) ;
1652
- }
1653
- }
1654
-
1655
1635
if ( appliedStyles . length > 0 ) {
1656
1636
//the element being animated may sometimes contain comment nodes in
1657
1637
//the jqLite object, so we're safe to use a single variable to house
1658
1638
//the styles since there is always only one element being animated
1659
1639
var oldStyle = node . getAttribute ( 'style' ) || '' ;
1660
- node . setAttribute ( 'style' , oldStyle + '; ' + style ) ;
1640
+ if ( oldStyle . charAt ( oldStyle . length - 1 ) !== ';' ) {
1641
+ oldStyle += ';' ;
1642
+ }
1643
+ node . setAttribute ( 'style' , oldStyle + ' ' + style ) ;
1661
1644
}
1662
1645
1663
1646
var startTime = Date . now ( ) ;
1664
1647
var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT ;
1648
+ var animationTime = ( maxDelay + maxDuration ) * CLOSING_TIME_BUFFER ;
1649
+ var totalTime = ( staggerTime + animationTime ) * ONE_SECOND ;
1650
+
1651
+ var staggerTimeout ;
1652
+ if ( staggerTime > 0 ) {
1653
+ element . addClass ( pendingClassName ) ;
1654
+ staggerTimeout = $timeout ( function ( ) {
1655
+ staggerTimeout = null ;
1656
+ element . addClass ( activeClassName ) ;
1657
+ element . removeClass ( pendingClassName ) ;
1658
+ if ( timings . animationDuration > 0 ) {
1659
+ blockAnimations ( node , false ) ;
1660
+ }
1661
+ } , staggerTime * ONE_SECOND , false ) ;
1662
+ }
1665
1663
1666
1664
element . on ( css3AnimationEvents , onAnimationProgress ) ;
1667
1665
elementData . closeAnimationFns . push ( function ( ) {
1668
1666
onEnd ( ) ;
1669
1667
activeAnimationComplete ( ) ;
1670
1668
} ) ;
1671
1669
1672
- var staggerTime = itemIndex * ( Math . max ( stagger . animationDelay , stagger . transitionDelay ) || 0 ) ;
1673
- var animationTime = ( maxDelay + maxDuration ) * CLOSING_TIME_BUFFER ;
1674
- var totalTime = ( staggerTime + animationTime ) * ONE_SECOND ;
1675
-
1676
1670
elementData . running ++ ;
1677
1671
animationCloseHandler ( element , totalTime ) ;
1678
1672
return onEnd ;
@@ -1683,6 +1677,10 @@ angular.module('ngAnimate', ['ng'])
1683
1677
function onEnd ( cancelled ) {
1684
1678
element . off ( css3AnimationEvents , onAnimationProgress ) ;
1685
1679
element . removeClass ( activeClassName ) ;
1680
+ element . removeClass ( pendingClassName ) ;
1681
+ if ( staggerTimeout ) {
1682
+ $timeout . cancel ( staggerTimeout ) ;
1683
+ }
1686
1684
animateClose ( element , className ) ;
1687
1685
var node = extractElementNode ( element ) ;
1688
1686
for ( var i in appliedStyles ) {
@@ -1712,13 +1710,12 @@ angular.module('ngAnimate', ['ng'])
1712
1710
}
1713
1711
}
1714
1712
1715
- function prepareStaggerDelay ( delayStyle , staggerDelay , index ) {
1716
- var style = '' ;
1717
- forEach ( delayStyle . split ( ',' ) , function ( val , i ) {
1718
- style += ( i > 0 ? ',' : '' ) +
1719
- ( index * staggerDelay + parseInt ( val , 10 ) ) + 's' ;
1720
- } ) ;
1721
- return style ;
1713
+ function blockTransitions ( node , bool ) {
1714
+ node . style [ TRANSITION_PROP + PROPERTY_KEY ] = bool ? 'none' : '' ;
1715
+ }
1716
+
1717
+ function blockAnimations ( node , bool ) {
1718
+ node . style [ ANIMATION_PROP + ANIMATION_PLAYSTATE_KEY ] = bool ? 'paused' : '' ;
1722
1719
}
1723
1720
1724
1721
function animateBefore ( animationEvent , element , className , calculationDecorator ) {
0 commit comments