text: /**
   * Copyright 2013-2014 Facebook, Inc.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   * http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   *
   * @providesModule ReactTransitionEvents
   */
  
  "use strict";
  
  var ExecutionEnvironment = require('ExecutionEnvironment');
  
  var EVENT_NAME_MAP = {
    transitionend: {
      'transition': 'transitionend',
      'WebkitTransition': 'webkitTransitionEnd',
      'MozTransition': 'mozTransitionEnd',
      'OTransition': 'oTransitionEnd',
      'msTransition': 'MSTransitionEnd'
    },
  
    animationend: {
      'animation': 'animationend',
      'WebkitAnimation': 'webkitAnimationEnd',
      'MozAnimation': 'mozAnimationEnd',
      'OAnimation': 'oAnimationEnd',
      'msAnimation': 'MSAnimationEnd'
    }
  };
  
  var endEvents = [];
  
  function detectEvents() {
    var testEl = document.createElement('div');
    var style = testEl.style;
    for (var baseEventName in EVENT_NAME_MAP) {
      var baseEvents = EVENT_NAME_MAP[baseEventName];
      for (var styleName in baseEvents) {
        if (styleName in style) {
          endEvents.push(baseEvents[styleName]);
          break;
        }
      }
    }
  }
  
  if (ExecutionEnvironment.canUseDOM) {
    detectEvents();
  }
  
  // We use the raw {add|remove}EventListener() call because EventListener
  // does not know how to remove event listeners and we really should
  // clean up. Also, these events are not triggered in older browsers
  // so we should be A-OK here.
  
  function addEventListener(node, eventName, eventListener) {
    node.addEventListener(eventName, eventListener, false);
  }
  
  function removeEventListener(node, eventName, eventListener) {
    node.removeEventListener(eventName, eventListener, false);
  }
  
  var ReactTransitionEvents = {
    addEndEventListener: function(node, eventListener) {
      if (endEvents.length === 0) {
        // If CSS transitions are not supported, trigger an "end animation"
        // event immediately.
        window.setTimeout(eventListener, 0);
        return;
      }
      endEvents.forEach(function(endEvent) {
        addEventListener(node, endEvent, eventListener);
      });
    },
  
    removeEndEventListener: function(node, eventListener) {
      if (endEvents.length === 0) {
        return;
      }
      endEvents.forEach(function(endEvent) {
        removeEventListener(node, endEvent, eventListener);
      });
    }
  };
  
  module.exports = ReactTransitionEvents;
  