Skip to content

Commit b453834

Browse files
committed
fix(animation): always run before classes and functions
fixes ionic-team#8842 fixes ionic-team#8769
1 parent 0e53ec3 commit b453834

File tree

1 file changed

+92
-72
lines changed

1 file changed

+92
-72
lines changed

src/animations/animation.ts

+92-72
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { CSS, nativeRaf, transitionEnd, nativeTimeout } from '../util/dom';
2-
import { isDefined } from '../util/util';
2+
import { isDefined, assert } from '../util/util';
33

44

55
/**
@@ -297,7 +297,7 @@ export class Animation {
297297
* Play the animation.
298298
*/
299299
play(opts?: PlayOptions) {
300-
const dur = this.getDuration(opts);
300+
assert(this._raf, '_raf has to be valid');
301301

302302
// this is the top level animation and is in full control
303303
// of when the async play() should actually kick off
@@ -311,22 +311,16 @@ export class Animation {
311311
this._clearAsync();
312312

313313
// recursively kicks off the correct progress step for each child animation
314+
// ******** DOM WRITE ****************
314315
this._playInit(opts);
315316

316-
if (this._isAsync) {
317-
// for the root animation only
318-
// set the async TRANSITION END event
319-
// and run onFinishes when the transition ends
320-
// ******** DOM WRITE ****************
321-
this._asyncEnd(dur, true);
322-
}
323-
324317
// doubling up RAFs since this animation was probably triggered
325318
// from an input event, and just having one RAF would have this code
326319
// run within the same frame as the triggering input event, and the
327320
// input event probably already did way too much work for one frame
328-
this._raf && this._raf(() => {
329-
this._raf && this._raf(this._playDomInspect.bind(this, opts));
321+
this._raf(() => {
322+
assert(this._raf, '_raf has to be valid');
323+
this._raf(this._playDomInspect.bind(this, opts));
330324
});
331325
}
332326

@@ -367,26 +361,29 @@ export class Animation {
367361
* NO RECURSION
368362
* ROOT ANIMATION
369363
*/
370-
_playDomInspect(opts: PlayOptions) {
364+
_playDomInspect(opts: PlayOptions, ) {
371365
// fire off all the "before" function that have DOM READS in them
372366
// elements will be in the DOM, however visibily hidden
373367
// so we can read their dimensions if need be
374368
// ******** DOM READ ****************
375-
this._beforeReadFn();
376-
377-
// ******** DOM READS ABOVE / DOM WRITES BELOW ****************
378-
379-
// fire off all the "before" function that have DOM WRITES in them
380369
// ******** DOM WRITE ****************
381-
this._beforeWriteFn();
370+
this._beforeAnimation();
371+
372+
// for the root animation only
373+
// set the async TRANSITION END event
374+
// and run onFinishes when the transition ends
375+
const dur = this.getDuration(opts);
376+
if (this._isAsync) {
377+
this._asyncEnd(dur, true);
378+
}
382379

383380
// ******** DOM WRITE ****************
384381
this._playProgress(opts);
385382

386-
if (this._isAsync) {
383+
if (this._isAsync && this._raf) {
387384
// this animation has a duration so we need another RAF
388385
// for the CSS TRANSITION properties to kick in
389-
this._raf && this._raf(this._playToStep.bind(this, 1));
386+
this._raf(this._playToStep.bind(this, 1));
390387
}
391388
}
392389

@@ -401,10 +398,6 @@ export class Animation {
401398
this._c[i]._playProgress(opts);
402399
}
403400

404-
// stage all of the before css classes and inline styles
405-
// ******** DOM WRITE ****************
406-
this._before();
407-
408401
if (this._hasDur) {
409402
// set the CSS TRANSITION duration/easing
410403
// ******** DOM WRITE ****************
@@ -418,15 +411,15 @@ export class Animation {
418411

419412
// since there was no animation, immediately run the after
420413
// ******** DOM WRITE ****************
421-
this._after();
414+
this._afterAnimation();
422415

423416
// this animation has no duration, so it has finished
424417
// other animations could still be running
425418
this._didFinish(true);
426419
}
427420
}
428421

429-
/**
422+
/**
430423
* @private
431424
* DOM WRITE
432425
* RECURSION
@@ -517,7 +510,7 @@ export class Animation {
517510

518511
// set the after styles
519512
// ******** DOM WRITE ****************
520-
this._after();
513+
this._afterAnimation();
521514

522515
// remove the will-change properties
523516
// ******** DOM WRITE ****************
@@ -684,38 +677,72 @@ export class Animation {
684677

685678
/**
686679
* @private
680+
* DOM READ
687681
* DOM WRITE
688-
* NO RECURSION
682+
* RECURSION
683+
*/
684+
_beforeAnimation() {
685+
// assert(this._beforeCalled === false, '_before has been called twice');
686+
// this._beforeCalled = true;
687+
688+
// fire off all the "before" function that have DOM READS in them
689+
// elements will be in the DOM, however visibily hidden
690+
// so we can read their dimensions if need be
691+
// ******** DOM READ ****************
692+
this._fireBeforeReadFunc();
693+
694+
// ******** DOM READS ABOVE / DOM WRITES BELOW ****************
695+
696+
// fire off all the "before" function that have DOM WRITES in them
697+
// ******** DOM WRITE ****************
698+
this._fireBeforeWriteFunc();
699+
700+
// stage all of the before css classes and inline styles
701+
// ******** DOM WRITE ****************
702+
this._setBeforeStyles();
703+
}
704+
705+
/**
706+
* @private
707+
* DOM WRITE
708+
* RECURSION
689709
*/
690-
_before() {
710+
_setBeforeStyles() {
711+
for (var i = 0; i < this._cL; i++) {
712+
this._c[i]._setBeforeStyles();
713+
}
714+
691715
// before the animations have started
692-
if (!this._rv) {
693-
let ele: HTMLElement;
694-
for (var i = 0; i < this._eL; i++) {
695-
ele = this._e[i];
716+
// only set before styles if animation is not reversed
717+
if (this._rv) {
718+
return;
719+
}
696720

697-
// css classes to add before the animation
698-
if (this._bfAdd) {
699-
for (var j = 0; j < this._bfAdd.length; j++) {
700-
// ******** DOM WRITE ****************
701-
ele.classList.add(this._bfAdd[j]);
702-
}
721+
let ele: HTMLElement;
722+
for (var i = 0; i < this._eL; i++) {
723+
ele = this._e[i];
724+
725+
// css classes to add before the animation
726+
if (this._bfAdd) {
727+
for (var j = 0; j < this._bfAdd.length; j++) {
728+
// ******** DOM WRITE ****************
729+
ele.classList.add(this._bfAdd[j]);
703730
}
731+
}
704732

705-
// css classes to remove before the animation
706-
if (this._bfRm) {
707-
for (var j = 0; j < this._bfRm.length; j++) {
708-
// ******** DOM WRITE ****************
709-
ele.classList.remove(this._bfRm[j]);
710-
}
733+
// css classes to remove before the animation
734+
if (this._bfRm) {
735+
for (var j = 0; j < this._bfRm.length; j++) {
736+
// ******** DOM WRITE ****************
737+
ele.classList.remove(this._bfRm[j]);
711738
}
739+
}
712740

713-
// inline styles to add before the animation
714-
if (this._bfSty) {
715-
for (var prop in this._bfSty) {
716-
// ******** DOM WRITE ****************
717-
(<any>ele).style[prop] = this._bfSty[prop];
718-
}
741+
// inline styles to add before the animation
742+
if (this._bfSty) {
743+
for (var prop in this._bfSty) {
744+
// ******** DOM WRITE ****************
745+
(<any>ele).style[prop] = this._bfSty[prop];
719746
}
720747
}
721748
}
@@ -726,10 +753,10 @@ export class Animation {
726753
* DOM READ
727754
* RECURSION
728755
*/
729-
_beforeReadFn() {
756+
_fireBeforeReadFunc() {
730757
for (var i = 0; i < this._cL; i++) {
731758
// ******** DOM READ ****************
732-
this._c[i]._beforeReadFn();
759+
this._c[i]._fireBeforeReadFunc();
733760
}
734761

735762
if (this._rdFn) {
@@ -745,10 +772,10 @@ export class Animation {
745772
* DOM WRITE
746773
* RECURSION
747774
*/
748-
_beforeWriteFn() {
775+
_fireBeforeWriteFunc() {
749776
for (var i = 0; i < this._cL; i++) {
750777
// ******** DOM WRITE ****************
751-
this._c[i]._beforeWriteFn();
778+
this._c[i]._fireBeforeWriteFunc();
752779
}
753780

754781
if (this._wrFn) {
@@ -762,9 +789,13 @@ export class Animation {
762789
/**
763790
* @private
764791
* DOM WRITE
765-
* NO RECURSION
792+
* RECURSION
766793
*/
767-
_after() {
794+
_afterAnimation() {
795+
for (var i = 0; i < this._cL; i++) {
796+
this._c[i]._afterAnimation();
797+
}
798+
768799
let ele: HTMLElement;
769800
for (var i = 0; i < this._eL; i++) {
770801
ele = this._e[i];
@@ -828,7 +859,6 @@ export class Animation {
828859
}
829860
}
830861
}
831-
832862
}
833863

834864
/**
@@ -864,15 +894,8 @@ export class Animation {
864894
// ensure all past transition end events have been cleared
865895
this._clearAsync();
866896

867-
// fire off all the "before" function that have DOM READS in them
868-
// elements will be in the DOM, however visibily hidden
869-
// so we can read their dimensions if need be
870-
// ******** DOM READ ****************
871-
this._beforeReadFn();
872-
873-
// fire off all the "before" function that have DOM WRITES in them
874-
// ******** DOM WRITE ****************
875-
this._beforeWriteFn();
897+
// ******** DOM READ/WRITE ****************
898+
this._beforeAnimation();
876899

877900
// ******** DOM WRITE ****************
878901
this._progressStart();
@@ -889,9 +912,6 @@ export class Animation {
889912
this._c[i]._progressStart();
890913
}
891914

892-
// ******** DOM WRITE ****************
893-
this._before();
894-
895915
// force no duration, linear easing
896916
// ******** DOM WRITE ****************
897917
this._setTrans(0, true);
@@ -971,7 +991,7 @@ export class Animation {
971991
// ******** DOM WRITE ****************
972992
this._progress(stepValue);
973993
this._willChg(false);
974-
this._after();
994+
this._afterAnimation();
975995
this._didFinish(shouldComplete);
976996

977997
} else {

0 commit comments

Comments
 (0)