diff options
| author | Michał Gołębiowski | 2013-09-06 14:48:18 +0200 | 
|---|---|---|
| committer | Matias Niemelä | 2013-10-01 10:00:35 -0400 | 
| commit | f316c314ca260ada1427a3b40c16a8fb44e7b48d (patch) | |
| tree | ab69e4ac10c3728634dd7daadb0df39904a2e1fb /src/ngAnimate | |
| parent | 4033cf28142664c52aa7b4bc95340ac913397ac8 (diff) | |
| download | angular.js-f316c314ca260ada1427a3b40c16a8fb44e7b48d.tar.bz2 | |
refactor($ngAnimate): simplify the animation event rewrite
To avoid code duplication, use single variables for keeping
properties/events names to use. Also, fix some errors that have
happened after the rewrite from moment ago.
Diffstat (limited to 'src/ngAnimate')
| -rw-r--r-- | src/ngAnimate/animate.js | 80 | 
1 files changed, 42 insertions, 38 deletions
diff --git a/src/ngAnimate/animate.js b/src/ngAnimate/animate.js index 7f37f143..44b94563 100644 --- a/src/ngAnimate/animate.js +++ b/src/ngAnimate/animate.js @@ -542,21 +542,35 @@ angular.module('ngAnimate', ['ng'])        }      }]); -    $animateProvider.register('', ['$window','$sniffer', '$timeout', function($window, $sniffer, $timeout) { -      var noop = angular.noop; +    $animateProvider.register('', ['$window', '$sniffer', function($window, $sniffer) {        var forEach = angular.forEach; -      //one day all browsers will have these properties -      var w3cAnimationProp = 'animation'; -      var w3cTransitionProp = 'transition'; -      var w3cAnimationEvent = 'animationend'; -      var w3cTransitionEvent = 'transitionend'; +      // Detect proper transitionend/animationend event names. +      var transitionProp, transitionendEvent, animationProp, animationendEvent; + +      // If unprefixed events are not supported but webkit-prefixed are, use the latter. +      // Otherwise, just use W3C names, browsers not supporting them at all will just ignore them. +      // Note: Chrome implements `window.onwebkitanimationend` and doesn't implement `window.onanimationend` +      // but at the same time dispatches the `animationend` event and not `webkitAnimationEnd`. +      // Register both events in case `window.onanimationend` is not supported because of that, +      // do the same for `transitionend` as Safari is likely to exhibit similar behavior. +      // Also, the only modern browser that uses vendor prefixes for transitions/keyframes is webkit +      // therefore there is no reason to test anymore for other vendor prefixes: http://caniuse.com/#search=transition +      if (window.ontransitionend === undefined && window.onwebkittransitionend !== undefined) { +        transitionProp = 'WebkitTransition'; +        transitionendEvent = 'webkitTransitionEnd transitionend'; +      } else { +        transitionProp = 'transition'; +        transitionendEvent = 'transitionend'; +      } -      //but some still use vendor-prefixed styles -      var vendorAnimationProp = $sniffer.vendorPrefix + 'Animation'; -      var vendorTransitionProp = $sniffer.vendorPrefix + 'Transition'; -      var vendorAnimationEvent = $sniffer.vendorPrefix.toLowerCase() + 'AnimationEnd'; -      var vendorTransitionEvent = $sniffer.vendorPrefix.toLowerCase() + 'TransitionEnd'; +      if (window.onanimationend === undefined && window.onwebkitanimationend !== undefined) { +        animationProp = 'WebkitAnimation'; +        animationendEvent = 'webkitAnimationEnd animationend'; +      } else { +        animationProp = 'animation'; +        animationendEvent = 'animationend'; +      }        var durationKey = 'Duration',            propertyKey = 'Property', @@ -574,8 +588,7 @@ angular.module('ngAnimate', ['ng'])            forEach(element, function(element) {              if (element.nodeType == ELEMENT_NODE) {                var elementStyles = $window.getComputedStyle(element) || {}; -              existingDuration = Math.max(parseMaxTime(elementStyles[w3cTransitionProp + durationKey]), -                                          parseMaxTime(elementStyles[vendorTransitionProp + durationKey]), +              existingDuration = Math.max(parseMaxTime(elementStyles[transitionProp + durationKey]),                                            existingDuration);              }            }); @@ -594,22 +607,16 @@ angular.module('ngAnimate', ['ng'])            if (element.nodeType == ELEMENT_NODE) {              var elementStyles = $window.getComputedStyle(element) || {}; -            var transitionDelay  = Math.max(parseMaxTime(elementStyles[w3cTransitionProp     + delayKey]), -                                            parseMaxTime(elementStyles[vendorTransitionProp  + delayKey])); +            var transitionDelay  = parseMaxTime(elementStyles[transitionProp + delayKey]); -            var animationDelay   = Math.max(parseMaxTime(elementStyles[w3cAnimationProp      + delayKey]), -                                            parseMaxTime(elementStyles[vendorAnimationProp   + delayKey])); +            var animationDelay   = parseMaxTime(elementStyles[animationProp + delayKey]); -            var transitionDuration  = Math.max(parseMaxTime(elementStyles[w3cTransitionProp     + durationKey]), -                                               parseMaxTime(elementStyles[vendorTransitionProp  + durationKey])); +            var transitionDuration = parseMaxTime(elementStyles[transitionProp + durationKey]); -            var animationDuration   = Math.max(parseMaxTime(elementStyles[w3cAnimationProp      + durationKey]), -                                               parseMaxTime(elementStyles[vendorAnimationProp   + durationKey])); +            var animationDuration  = parseMaxTime(elementStyles[animationProp + durationKey]);              if(animationDuration > 0) { -              animationDuration *= Math.max(parseInt(elementStyles[w3cAnimationProp   + animationIterationCountKey]) || 0, -                                           parseInt(elementStyles[vendorAnimationProp + animationIterationCountKey]) || 0, -                                           1); +              animationDuration *= parseInt(elementStyles[animationProp + animationIterationCountKey]) || 1;              }              transitionTime = Math.max(transitionDelay + transitionDuration, transitionTime); @@ -628,8 +635,7 @@ angular.module('ngAnimate', ['ng'])            //temporarily disable the transition so that the enter styles            //don't animate twice (this is here to avoid a bug in Chrome/FF).            if(transitionTime > 0) { -            node.style[w3cTransitionProp + propertyKey] = 'none'; -            node.style[vendorTransitionProp + propertyKey] = 'none'; +            node.style[transitionProp + propertyKey] = 'none';            }            var activeClassName = ''; @@ -637,29 +643,27 @@ angular.module('ngAnimate', ['ng'])              activeClassName += (i > 0 ? ' ' : '') + klass + '-active';            }); -          //this triggers a reflow which allows for the transition animation to kick in +          // This triggers a reflow which allows for the transition animation to kick in.            element.prop('clientWidth');            if(transitionTime > 0) { -            node.style[w3cTransitionProp + propertyKey] = ''; -            node.style[vendorTransitionProp + propertyKey] = ''; +            node.style[transitionProp + propertyKey] = '';            }            element.addClass(activeClassName); -          var css3AnimationEvents = [w3cAnimationEvent,  vendorAnimationEvent, -                                     w3cTransitionEvent, vendorTransitionEvent].join(' '); +          var css3AnimationEvents = animationendEvent + ' ' + transitionendEvent;            element.on(css3AnimationEvents, onAnimationProgress); -          //this will automatically be called by $animate so -          //there is no need to attach this internally to the -          //timeout done method +          // This will automatically be called by $animate so +          // there is no need to attach this internally to the +          // timeout done method.            return function onEnd(cancelled) {              element.off(css3AnimationEvents, onAnimationProgress);              element.removeClass(className);              element.removeClass(activeClassName); -            //only when the animation is cancelled is the done() -            //function not called for this animation therefore -            //this must be also called +            // Only when the animation is cancelled is the done() +            // function not called for this animation therefore +            // this must be also called.              if(cancelled) {                done();              }  | 
