@@ -12,6 +12,16 @@ describe("ngAnimate $animateCss", function() {
12
12
: expect ( className ) . not . toMatch ( regex ) ;
13
13
}
14
14
15
+ function keyframeProgress ( element , duration , delay ) {
16
+ browserTrigger ( element , 'animationend' ,
17
+ { timeStamp : Date . now ( ) + ( ( delay || 1 ) * 1000 ) , elapsedTime : duration } ) ;
18
+ }
19
+
20
+ function transitionProgress ( element , duration , delay ) {
21
+ browserTrigger ( element , 'transitionend' ,
22
+ { timeStamp : Date . now ( ) + ( ( delay || 1 ) * 1000 ) , elapsedTime : duration } ) ;
23
+ }
24
+
15
25
var fakeStyle = {
16
26
color : 'blue'
17
27
} ;
@@ -355,16 +365,6 @@ describe("ngAnimate $animateCss", function() {
355
365
assert . toHaveClass ( 'ng-enter-active' ) ;
356
366
}
357
367
358
- function keyframeProgress ( element , duration , delay ) {
359
- browserTrigger ( element , 'animationend' ,
360
- { timeStamp : Date . now ( ) + ( ( delay || 1 ) * 1000 ) , elapsedTime : duration } ) ;
361
- }
362
-
363
- function transitionProgress ( element , duration , delay ) {
364
- browserTrigger ( element , 'transitionend' ,
365
- { timeStamp : Date . now ( ) + ( ( delay || 1 ) * 1000 ) , elapsedTime : duration } ) ;
366
- }
367
-
368
368
beforeEach ( inject ( function ( $rootElement , $document ) {
369
369
element = jqLite ( '<div></div>' ) ;
370
370
$rootElement . append ( element ) ;
@@ -1404,6 +1404,125 @@ describe("ngAnimate $animateCss", function() {
1404
1404
expect ( count . stagger ) . toBe ( 2 ) ;
1405
1405
} ) ) ;
1406
1406
} ) ;
1407
+
1408
+ describe ( 'transitionend/animationend event listeners' , function ( ) {
1409
+ var element , callLog , proxyListener , origListener , type , progress ;
1410
+
1411
+ beforeEach ( inject ( function ( $rootElement , $document ) {
1412
+
1413
+ element = jqLite ( '<div></div>' ) ;
1414
+ $rootElement . append ( element ) ;
1415
+ jqLite ( $document [ 0 ] . body ) . append ( $rootElement ) ;
1416
+
1417
+ callLog = { } ;
1418
+
1419
+ var origOn = element . on ,
1420
+ origOff = element . off ;
1421
+
1422
+ proxyListener = function ( ) {
1423
+ callLog [ type ] = callLog [ type ] ++ || 1 ;
1424
+ origListener . apply ( this , arguments ) ;
1425
+ } ;
1426
+
1427
+ // Overwrite the .on function to log calls to the event listeners
1428
+ element . on = function ( ) {
1429
+ origListener = arguments [ 1 ] ;
1430
+ type = arguments [ 0 ] ;
1431
+ origOn . call ( this , arguments [ 0 ] , proxyListener ) ;
1432
+ } ;
1433
+
1434
+ // Make sure the .off function removes the proxyListener
1435
+ element . off = function ( ) {
1436
+ origOff . call ( this , arguments [ 0 ] , proxyListener ) ;
1437
+ } ;
1438
+
1439
+ } ) ) ;
1440
+
1441
+ they ( 'should remove the $prop event listeners on cancel' ,
1442
+ [ TRANSITIONEND_EVENT , ANIMATIONEND_EVENT ] ,
1443
+ function ( event ) { inject ( function ( $animateCss ) {
1444
+
1445
+ switch ( event ) {
1446
+ case TRANSITIONEND_EVENT :
1447
+ progress = bind ( this , transitionProgress , element , 10 ) ;
1448
+ break ;
1449
+ case ANIMATIONEND_EVENT :
1450
+ progress = bind ( this , keyframeProgress , element , 10 ) ;
1451
+ break ;
1452
+ }
1453
+
1454
+ var animator = $animateCss ( element , {
1455
+ duration : 10 ,
1456
+ to : { 'background' : 'red' }
1457
+ } ) ;
1458
+
1459
+ var runner = animator . start ( ) ;
1460
+ triggerAnimationStartFrame ( ) ;
1461
+
1462
+ runner . cancel ( ) ;
1463
+
1464
+ // Trigger an end event
1465
+ progress ( ) ;
1466
+
1467
+ expect ( callLog [ event ] ) . toBeFalsy ( ) ;
1468
+ } ) ;
1469
+ } ) ;
1470
+
1471
+ they ( "should remove the $prop event listener when the animation is closed" ,
1472
+ [ TRANSITIONEND_EVENT , ANIMATIONEND_EVENT ] , function ( event ) {
1473
+ inject ( function ( $animateCss ) {
1474
+
1475
+ switch ( event ) {
1476
+ case TRANSITIONEND_EVENT :
1477
+ ss . addRule ( '.ng-enter' , TRANSITION_PROP + '1s linear all;' +
1478
+ TRANSITION_PROP + '-duration:10s;' ) ;
1479
+
1480
+ progress = bind ( this , transitionProgress , element , 10 ) ;
1481
+ break ;
1482
+ case ANIMATIONEND_EVENT :
1483
+ ss . addRule ( '.ng-enter' , ANIMATION_PROP + ':animation 10s;' ) ;
1484
+ progress = bind ( this , keyframeProgress , element , 10 ) ;
1485
+ break ;
1486
+ }
1487
+
1488
+ var animator = $animateCss ( element , {
1489
+ event : 'enter' ,
1490
+ structural : true
1491
+ } ) ;
1492
+
1493
+ var runner = animator . start ( ) ;
1494
+ triggerAnimationStartFrame ( ) ;
1495
+
1496
+ progress ( ) ;
1497
+ expect ( element ) . not . toHaveClass ( 'ng-enter ng-enter-active' )
1498
+
1499
+ // Trigger another end event
1500
+ progress ( ) ;
1501
+
1502
+ expect ( callLog [ event ] ) . toBe ( 1 ) ;
1503
+ } ) ;
1504
+ } ) ;
1505
+
1506
+ it ( "should remove the transitionend event listener when the closing timeout occurs" ,
1507
+ inject ( function ( $animateCss , $document , $rootElement , $timeout ) {
1508
+
1509
+ ss . addRule ( '.ng-enter' , 'transition:10s linear all;' ) ;
1510
+
1511
+ var animator = $animateCss ( element , {
1512
+ event : 'enter' ,
1513
+ structural : true
1514
+ } ) ;
1515
+
1516
+ animator . start ( ) ;
1517
+ triggerAnimationStartFrame ( ) ;
1518
+ $timeout . flush ( 15000 ) ;
1519
+
1520
+ // Force an transitionend event
1521
+ transitionProgress ( element , 10 ) ;
1522
+
1523
+ expect ( callLog [ TRANSITIONEND_EVENT ] ) . toBeFalsy ( ) ;
1524
+ } ) ) ;
1525
+ } ) ;
1407
1526
} ) ;
1408
1527
1409
1528
it ( 'should avoid applying the same cache to an element a follow-up animation is run on the same element' ,
0 commit comments