@@ -230,15 +230,19 @@ export class CssAnimator {
230230 }
231231
232232 /**
233- * Execute an 'enter' animation on an element
234- * @param element Element to animate
235- * @returns Resolved when the animation is done
233+ * Animates element on enter or leave
234+ * @param element element to animate
235+ * @param direction 'enter' or 'leave'
236+ * @param doneClass class to apply when done
237+ * @private
236238 */
237- enter ( element : HTMLElement ) : Promise < boolean > {
239+ _stateAnim ( element : HTMLElement , direction : string , doneClass : string ) {
240+ const auClass = 'au-' + direction ;
241+ const auClassActive = auClass + '-active' ;
238242 return new Promise ( ( resolve , reject ) => {
239- let classList = element . classList ;
243+ const classList = element . classList ;
240244
241- this . _triggerDOMEvent ( animationEvent . enterBegin , element ) ;
245+ this . _triggerDOMEvent ( animationEvent [ direction + 'Begin' ] , element ) ;
242246
243247 // Step 1.2: remove done classes
244248 if ( this . useAnimationDoneClasses ) {
@@ -247,8 +251,8 @@ export class CssAnimator {
247251 }
248252
249253 // Step 2: Add animation preparation class
250- classList . add ( 'au-enter' ) ;
251- let prevAnimationNames = this . _getElementAnimationNames ( element ) ;
254+ classList . add ( auClass ) ;
255+ const prevAnimationNames = this . _getElementAnimationNames ( element ) ;
252256
253257 // Step 3: setup event to check whether animations started
254258 let animStart ;
@@ -257,7 +261,7 @@ export class CssAnimator {
257261 animHasStarted = true ;
258262 this . isAnimating = true ;
259263
260- this . _triggerDOMEvent ( animationEvent . enterActive , element ) ;
264+ this . _triggerDOMEvent ( animationEvent [ direction + 'Active' ] , element ) ;
261265
262266 // Stop event propagation, bubbling will otherwise prevent parent animation
263267 evAnimStart . stopPropagation ( ) ;
@@ -268,180 +272,92 @@ export class CssAnimator {
268272 // Step 3.1: Wait for animation to finish
269273 let animEnd ;
270274 this . _addMultipleEventListener ( element , 'webkitAnimationEnd animationend' , animEnd = ( evAnimEnd ) => {
271- if ( ! animHasStarted ) {
275+ if ( ! animHasStarted ) {
272276 return ;
273277 }
274278
275279 // Step 3.1.0: Stop event propagation, bubbling will otherwise prevent parent animation
276280 evAnimEnd . stopPropagation ( ) ;
277281
278282 // Step 3.1.1: remove animation classes
279- classList . remove ( 'au-enter-active' ) ;
280- classList . remove ( 'au-enter' ) ;
283+ classList . remove ( auClassActive ) ;
284+ classList . remove ( auClass ) ;
281285
282286 // Step 3.1.2 remove animationend listener
283287 evAnimEnd . target . removeEventListener ( evAnimEnd . type , animEnd ) ;
284288
285- // Step 3.1.3 in case animation done animations are active, add the defined entered class to the element
289+ // Step 3.1.3 in case animation done animations are active, add the defined done class to the element
286290 if ( this . useAnimationDoneClasses &&
287- this . animationEnteredClass !== undefined &&
288- this . animationEnteredClass !== null ) {
289- classList . add ( this . animationEnteredClass ) ;
291+ doneClass !== undefined &&
292+ doneClass !== null ) {
293+ classList . add ( doneClass ) ;
290294 }
291295
292296 this . isAnimating = false ;
293- this . _triggerDOMEvent ( animationEvent . enterDone , element ) ;
297+ this . _triggerDOMEvent ( animationEvent [ direction + 'Done' ] , element ) ;
294298
295299 resolve ( true ) ;
296300 } , false ) ;
297301
298302 // Step 4: check if parent element is defined to stagger animations otherwise trigger active immediately
299- let parent = element . parentElement ;
303+ const parent = element . parentElement ;
300304 let delay = 0 ;
305+ const attrib = 'data-animator-pending' + direction ;
301306
302- let cleanupAnimation = ( ) => {
307+ const cleanupAnimation = ( ) => {
303308 // Step 5: if no animations scheduled cleanup animation classes
304- let animationNames = this . _getElementAnimationNames ( element ) ;
309+ const animationNames = this . _getElementAnimationNames ( element ) ;
305310 if ( ! this . _animationChangeWithValidKeyframe ( animationNames , prevAnimationNames ) ) {
306- classList . remove ( 'au-enter-active' ) ;
307- classList . remove ( 'au-enter' ) ;
311+ classList . remove ( auClassActive ) ;
312+ classList . remove ( auClass ) ;
308313
309314 this . _removeMultipleEventListener ( element , 'webkitAnimationEnd animationend' , animEnd ) ;
310315 this . _removeMultipleEventListener ( element , 'webkitAnimationStart animationstart' , animStart ) ;
311316
312- this . _triggerDOMEvent ( animationEvent . enterTimeout , element ) ;
317+ this . _triggerDOMEvent ( animationEvent [ direction + 'Timeout' ] , element ) ;
313318 resolve ( false ) ;
314319 }
320+ parent && parent . setAttribute ( attrib , + ( parent . getAttribute ( attrib ) || 1 ) - 1 ) ;
315321 } ;
316322
317323 if ( parent !== null &&
318- parent !== undefined &&
319- (
320- parent . classList . contains ( 'au-stagger' ) ||
321- parent . classList . contains ( 'au-stagger-enter' )
322- ) ) {
323- let elemPos = Array . prototype . indexOf . call ( parent . children , element ) ;
324- delay = this . _getElementAnimationDelay ( parent ) * elemPos ;
325-
324+ parent !== undefined &&
325+ (
326+ parent . classList . contains ( 'au-stagger' ) ||
327+ parent . classList . contains ( 'au-stagger-enter' )
328+ ) ) {
329+ const offset = + ( parent . getAttribute ( attrib ) || 0 ) ;
330+ parent . setAttribute ( attrib , offset + 1 ) ;
331+ delay = this . _getElementAnimationDelay ( parent ) * offset ;
326332 this . _triggerDOMEvent ( animationEvent . staggerNext , element ) ;
327333
328334 setTimeout ( ( ) => {
329- classList . add ( 'au-enter-active' ) ;
335+ classList . add ( auClassActive ) ;
330336 cleanupAnimation ( ) ;
331337 } , delay ) ;
332338 } else {
333- classList . add ( 'au-enter-active' ) ;
339+ classList . add ( auClassActive ) ;
334340 cleanupAnimation ( ) ;
335341 }
336342 } ) ;
337343 }
338344
345+ /**
346+ * Execute an 'enter' animation on an element
347+ * @param element Element to animate
348+ * @returns Resolved when the animation is done
349+ */
350+ enter ( element : HTMLElement ) : Promise < boolean > {
351+ return this . _stateAnim ( element , 'enter ', this . animationEnteredClass ) ;
352+ }
353+
339354 /**
340355 * Execute a 'leave' animation on an element
341356 * @param element Element to animate
342357 * @returns Resolved when the animation is done
343358 */
344359 leave ( element : HTMLElement ) : Promise < boolean > {
345- return new Promise ( ( resolve , reject ) => {
346- let classList = element . classList ;
347-
348- this . _triggerDOMEvent ( animationEvent . leaveBegin , element ) ;
349-
350- // Step 1.1: remove done classes
351- if ( this . useAnimationDoneClasses ) {
352- classList . remove ( this . animationEnteredClass ) ;
353- classList . remove ( this . animationLeftClass ) ;
354- }
355-
356- // Step 2: Add animation preparation class
357- classList . add ( 'au-leave' ) ;
358- let prevAnimationNames = this . _getElementAnimationNames ( element ) ;
359-
360- // Step 3: setup event to check whether animations started
361- let animStart ;
362- let animHasStarted = false ;
363- this . _addMultipleEventListener ( element , 'webkitAnimationStart animationstart' , animStart = ( evAnimStart ) => {
364- animHasStarted = true ;
365- this . isAnimating = true ;
366-
367- this . _triggerDOMEvent ( animationEvent . leaveActive , element ) ;
368-
369- // Stop event propagation, bubbling will otherwise prevent parent animation
370- evAnimStart . stopPropagation ( ) ;
371-
372- evAnimStart . target . removeEventListener ( evAnimStart . type , animStart ) ;
373- } , false ) ;
374-
375- // Step 3.1: Wait for animation to finish
376- let animEnd ;
377- this . _addMultipleEventListener ( element , 'webkitAnimationEnd animationend' , animEnd = ( evAnimEnd ) => {
378- if ( ! animHasStarted ) {
379- return ;
380- }
381-
382- // Step 3.1.0: Stop event propagation, bubbling will otherwise prevent parent animation
383- evAnimEnd . stopPropagation ( ) ;
384-
385- // Step 3.1.1: remove animation classes
386- classList . remove ( 'au-leave-active' ) ;
387- classList . remove ( 'au-leave' ) ;
388-
389- // Step 3.1.2 remove animationend listener
390- evAnimEnd . target . removeEventListener ( evAnimEnd . type , animEnd ) ;
391-
392- // Step 3.1.3 in case animation done animations are active, add the defined left class to the element
393- if ( this . useAnimationDoneClasses &&
394- this . animationLeftClass !== undefined &&
395- this . animationLeftClass !== null ) {
396- classList . add ( this . animationLeftClass ) ;
397- }
398-
399- this . isAnimating = false ;
400- this . _triggerDOMEvent ( animationEvent . leaveDone , element ) ;
401-
402- resolve ( true ) ;
403- } , false ) ;
404-
405-
406- // Step 4: check if parent element is defined to stagger animations otherwise trigger leave immediately
407- let parent = element . parentElement ;
408- let delay = 0 ;
409-
410- let cleanupAnimation = ( ) => {
411- // Step 5: if no animations scheduled cleanup animation classes
412- let animationNames = this . _getElementAnimationNames ( element ) ;
413- if ( ! this . _animationChangeWithValidKeyframe ( animationNames , prevAnimationNames ) ) {
414- classList . remove ( 'au-leave-active' ) ;
415- classList . remove ( 'au-leave' ) ;
416-
417- this . _removeMultipleEventListener ( element , 'webkitAnimationEnd animationend' , animEnd ) ;
418- this . _removeMultipleEventListener ( element , 'webkitAnimationStart animationstart' , animStart ) ;
419-
420- this . _triggerDOMEvent ( animationEvent . leaveTimeout , element ) ;
421- resolve ( false ) ;
422- }
423- } ;
424-
425- if ( parent !== null &&
426- parent !== undefined &&
427- (
428- parent . classList . contains ( 'au-stagger' ) ||
429- parent . classList . contains ( 'au-stagger-leave' )
430- ) ) {
431- let elemPos = Array . prototype . indexOf . call ( parent . children , element ) ;
432- delay = this . _getElementAnimationDelay ( parent ) * elemPos ;
433-
434- this . _triggerDOMEvent ( animationEvent . staggerNext , element ) ;
435-
436- setTimeout ( ( ) => {
437- classList . add ( 'au-leave-active' ) ;
438- cleanupAnimation ( ) ;
439- } , delay ) ;
440- } else {
441- classList . add ( 'au-leave-active' ) ;
442- cleanupAnimation ( ) ;
443- }
444- } ) ;
360+ return this . _stateAnim ( element , 'leave ', this . animationLeftClass ) ;
445361 }
446362
447363 /**
0 commit comments