@@ -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 ) ;
@@ -463,6 +463,62 @@ describe("ngAnimate $animateCss", function() {
463
463
} ) ;
464
464
} ) ;
465
465
466
+ they ( "should remove the $prop event listener when the animation is closed" ,
467
+ [ TRANSITIONEND_EVENT , ANIMATIONEND_EVENT ] , function ( event ) {
468
+
469
+ inject ( function ( $animateCss , $rootScope ) {
470
+
471
+ var callLog = { } ,
472
+ origOn = element . on ,
473
+ origOff = element . off ,
474
+ origListener ,
475
+ progress ;
476
+
477
+ callLog [ event ] = 0 ;
478
+
479
+ var proxyListener = function ( ) {
480
+ callLog [ event ] ++ ;
481
+ origListener . apply ( this , arguments ) ;
482
+ } ;
483
+
484
+ // Overwrite the .on function to log calls to the event listeners
485
+ element . on = function ( ) {
486
+ origListener = arguments [ 1 ] ;
487
+ origOn . call ( this , arguments [ 0 ] , proxyListener ) ;
488
+ } ;
489
+
490
+ // Make sure the .off function removes the proxyListener
491
+ element . off = function ( ) {
492
+ origOff . call ( this , arguments [ 0 ] , proxyListener ) ;
493
+ } ;
494
+
495
+ switch ( event ) {
496
+ case TRANSITIONEND_EVENT :
497
+ ss . addRule ( '.ng-enter' , TRANSITION_PROP + '1s linear all;' +
498
+ TRANSITION_PROP + '-duration:10s;' ) ;
499
+
500
+ progress = bind ( this , transitionProgress , element , 10 ) ;
501
+ break ;
502
+ case ANIMATIONEND_EVENT :
503
+ ss . addRule ( '.ng-enter' , ANIMATION_PROP + ':animation 10s;' ) ;
504
+ progress = bind ( this , keyframeProgress , element , 10 ) ;
505
+ break ;
506
+ }
507
+
508
+ var animator = $animateCss ( element , options ) ;
509
+ var runner = animator . start ( ) ;
510
+ triggerAnimationStartFrame ( ) ;
511
+
512
+ progress ( ) ;
513
+ assertAnimationComplete ( true ) ;
514
+
515
+ // Trigger another end event
516
+ progress ( ) ;
517
+
518
+ expect ( callLog [ event ] ) . toBe ( 1 ) ;
519
+ } ) ;
520
+ } ) ;
521
+
466
522
it ( "should use the highest transition duration value detected in the CSS class" , inject ( function ( $animateCss ) {
467
523
ss . addRule ( '.ng-enter' , 'transition:1s linear all;' +
468
524
'transition-duration:10s, 15s, 20s;' ) ;
@@ -1074,6 +1130,50 @@ describe("ngAnimate $animateCss", function() {
1074
1130
expect ( element ) . not . toHaveClass ( 'ng-enter-active' ) ;
1075
1131
} ) ) ;
1076
1132
1133
+ it ( "should remove the transitionend event listeners when the closing timeout closes the animation" ,
1134
+ inject ( function ( $animateCss , $document , $rootElement , $timeout ) {
1135
+
1136
+ var element = jqLite ( '<div></div>' ) ,
1137
+ callLog = 0 ,
1138
+ origOn = element . on ,
1139
+ origOff = element . off ,
1140
+ origListener ,
1141
+ progress ;
1142
+
1143
+ var proxyListener = function ( ) {
1144
+ dump ( 'proxyListener' )
1145
+ callLog ++ ;
1146
+ origListener . apply ( this , arguments ) ;
1147
+ } ;
1148
+
1149
+ // Overwrite the .on function to log calls to the event listeners
1150
+ element . on = function ( ) {
1151
+ origListener = arguments [ 1 ] ;
1152
+ origOn . call ( this , arguments [ 0 ] , proxyListener ) ;
1153
+ } ;
1154
+
1155
+ // Make sure the .off function removes the proxyListener
1156
+ element . off = function ( ) {
1157
+ origOff . call ( this , arguments [ 0 ] , proxyListener ) ;
1158
+ } ;
1159
+
1160
+ ss . addRule ( '.ng-enter' , 'transition:10s linear all;' ) ;
1161
+
1162
+ $rootElement . append ( element ) ;
1163
+ jqLite ( $document [ 0 ] . body ) . append ( $rootElement ) ;
1164
+
1165
+ var animator = $animateCss ( element , { event : 'enter' , structural : true } ) ;
1166
+ animator . start ( ) ;
1167
+ triggerAnimationStartFrame ( ) ;
1168
+ $timeout . flush ( 15000 ) ;
1169
+
1170
+ // Force an transitionend event
1171
+ transitionProgress ( element , 10 ) ;
1172
+
1173
+ expect ( callLog ) . toBe ( 0 ) ;
1174
+
1175
+ } ) ) ;
1176
+
1077
1177
it ( "should close off the animation after 150% of the animation time has passed and consider the detected delay value" ,
1078
1178
inject ( function ( $animateCss , $document , $rootElement , $timeout ) {
1079
1179
0 commit comments