From dde1b2949727c297e214c99960141bfad438d7a4 Mon Sep 17 00:00:00 2001 From: Matias Niemelä Date: Mon, 13 Jan 2014 21:51:08 -0500 Subject: feat($animate): provide support for DOM callbacks --- src/ngAnimate/animate.js | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) (limited to 'src/ngAnimate') diff --git a/src/ngAnimate/animate.js b/src/ngAnimate/animate.js index 0417f18e..4f243220 100644 --- a/src/ngAnimate/animate.js +++ b/src/ngAnimate/animate.js @@ -317,6 +317,10 @@ angular.module('ngAnimate', ['ng']) return classNameFilter.test(className); }; + function async(fn) { + return $timeout(fn, 0, false); + } + function lookup(name) { if (name) { var matches = [], @@ -608,6 +612,8 @@ angular.module('ngAnimate', ['ng']) //best to catch this early on to prevent any animation operations from occurring if(!node || !isAnimatableClassName(classes)) { fireDOMOperation(); + fireBeforeCallbackAsync(); + fireAfterCallbackAsync(); closeAnimation(); return; } @@ -627,6 +633,8 @@ angular.module('ngAnimate', ['ng']) //NOTE: IE8 + IE9 should close properly (run closeAnimation()) in case a NO animation is not found. if (animationsDisabled(element, parentElement) || matches.length === 0) { fireDOMOperation(); + fireBeforeCallbackAsync(); + fireAfterCallbackAsync(); closeAnimation(); return; } @@ -665,6 +673,8 @@ angular.module('ngAnimate', ['ng']) //animation do it's thing and close this one early if(animations.length === 0) { fireDOMOperation(); + fireBeforeCallbackAsync(); + fireAfterCallbackAsync(); fireDoneCallbackAsync(); return; } @@ -718,6 +728,8 @@ angular.module('ngAnimate', ['ng']) if((animationEvent == 'addClass' && futureClassName.indexOf(classNameToken) >= 0) || (animationEvent == 'removeClass' && futureClassName.indexOf(classNameToken) == -1)) { fireDOMOperation(); + fireBeforeCallbackAsync(); + fireAfterCallbackAsync(); fireDoneCallbackAsync(); return; } @@ -758,6 +770,10 @@ angular.module('ngAnimate', ['ng']) } function invokeRegisteredAnimationFns(animations, phase, allAnimationFnsComplete) { + phase == 'after' ? + fireAfterCallbackAsync() : + fireBeforeCallbackAsync(); + var endFnName = phase + 'End'; forEach(animations, function(animation, index) { var animationPhaseCompleted = function() { @@ -794,8 +810,27 @@ angular.module('ngAnimate', ['ng']) } } + function fireDOMCallback(animationPhase) { + element.triggerHandler('$animate:' + animationPhase, { + event : animationEvent, + className : className + }); + } + + function fireBeforeCallbackAsync() { + async(function() { + fireDOMCallback('before'); + }); + } + + function fireAfterCallbackAsync() { + async(function() { + fireDOMCallback('after'); + }); + } + function fireDoneCallbackAsync() { - doneCallback && $timeout(doneCallback, 0, false); + doneCallback && async(doneCallback); } //it is less complicated to use a flag than managing and cancelling @@ -819,9 +854,9 @@ angular.module('ngAnimate', ['ng']) if(isClassBased) { cleanup(element); } else { - data.closeAnimationTimeout = $timeout(function() { + data.closeAnimationTimeout = async(function() { cleanup(element); - }, 0, false); + }); element.data(NG_ANIMATE_STATE, data); } } -- cgit v1.2.3 'n6' href='#n6'>6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177