content: import _extends from 'babel-runtime/helpers/extends';
  import React from 'react';
  import PropTypes from 'prop-types';
  import { findDOMNode } from 'react-dom';
  import createReactClass from 'create-react-class';
  import contains from 'rc-util/es/Dom/contains';
  import addEventListener from 'rc-util/lib/Dom/addEventListener';
  import Popup from './Popup';
  import { getAlignFromPlacement, getPopupClassNameFromAlign as _getPopupClassNameFromAlign } from './utils';
  import getContainerRenderMixin from 'rc-util/lib/getContainerRenderMixin';
  
  function noop() {}
  
  function returnEmptyString() {
    return '';
  }
  
  function returnDocument() {
    return window.document;
  }
  
  var ALL_HANDLERS = ['onClick', 'onMouseDown', 'onTouchStart', 'onMouseEnter', 'onMouseLeave', 'onFocus', 'onBlur'];
  
  var Trigger = createReactClass({
    displayName: 'Trigger',
    propTypes: {
      children: PropTypes.any,
      action: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
      showAction: PropTypes.any,
      hideAction: PropTypes.any,
      getPopupClassNameFromAlign: PropTypes.any,
      onPopupVisibleChange: PropTypes.func,
      afterPopupVisibleChange: PropTypes.func,
      popup: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
      popupStyle: PropTypes.object,
      prefixCls: PropTypes.string,
      popupClassName: PropTypes.string,
      popupPlacement: PropTypes.string,
      builtinPlacements: PropTypes.object,
      popupTransitionName: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
      popupAnimation: PropTypes.any,
      mouseEnterDelay: PropTypes.number,
      mouseLeaveDelay: PropTypes.number,
      zIndex: PropTypes.number,
      focusDelay: PropTypes.number,
      blurDelay: PropTypes.number,
      getPopupContainer: PropTypes.func,
      getDocument: PropTypes.func,
      destroyPopupOnHide: PropTypes.bool,
      mask: PropTypes.bool,
      maskClosable: PropTypes.bool,
      onPopupAlign: PropTypes.func,
      popupAlign: PropTypes.object,
      popupVisible: PropTypes.bool,
      maskTransitionName: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
      maskAnimation: PropTypes.string
    },
  
    mixins: [getContainerRenderMixin({
      autoMount: false,
  
      isVisible: function isVisible(instance) {
        return instance.state.popupVisible;
      },
      getContainer: function getContainer(instance) {
        var props = instance.props;
  
        var popupContainer = document.createElement('div');
                    popupContainer.style.position = 'absolute';
        popupContainer.style.top = '0';
        popupContainer.style.left = '0';
        popupContainer.style.width = '100%';
        var mountNode = props.getPopupContainer ? props.getPopupContainer(findDOMNode(instance)) : props.getDocument().body;
        mountNode.appendChild(popupContainer);
        return popupContainer;
      }
    })],
  
    getDefaultProps: function getDefaultProps() {
      return {
        prefixCls: 'rc-trigger-popup',
        getPopupClassNameFromAlign: returnEmptyString,
        getDocument: returnDocument,
        onPopupVisibleChange: noop,
        afterPopupVisibleChange: noop,
        onPopupAlign: noop,
        popupClassName: '',
        mouseEnterDelay: 0,
        mouseLeaveDelay: 0.1,
        focusDelay: 0,
        blurDelay: 0.15,
        popupStyle: {},
        destroyPopupOnHide: false,
        popupAlign: {},
        defaultPopupVisible: false,
        mask: false,
        maskClosable: true,
        action: [],
        showAction: [],
        hideAction: []
      };
    },
    getInitialState: function getInitialState() {
      var props = this.props;
      var popupVisible = void 0;
      if ('popupVisible' in props) {
        popupVisible = !!props.popupVisible;
      } else {
        popupVisible = !!props.defaultPopupVisible;
      }
      return {
        popupVisible: popupVisible
      };
    },
    componentWillMount: function componentWillMount() {
      var _this = this;
  
      ALL_HANDLERS.forEach(function (h) {
        _this['fire' + h] = function (e) {
          _this.fireEvents(h, e);
        };
      });
    },
    componentDidMount: function componentDidMount() {
      this.componentDidUpdate({}, {
        popupVisible: this.state.popupVisible
      });
    },
    componentWillReceiveProps: function componentWillReceiveProps(_ref) {
      var popupVisible = _ref.popupVisible;
  
      if (popupVisible !== undefined) {
        this.setState({
          popupVisible: popupVisible
        });
      }
    },
    componentDidUpdate: function componentDidUpdate(_, prevState) {
      var props = this.props;
      var state = this.state;
      this.renderComponent(null, function () {
        if (prevState.popupVisible !== state.popupVisible) {
          props.afterPopupVisibleChange(state.popupVisible);
        }
      });
  
                      if (state.popupVisible) {
        var currentDocument = void 0;
        if (!this.clickOutsideHandler && this.isClickToHide()) {
          currentDocument = props.getDocument();
          this.clickOutsideHandler = addEventListener(currentDocument, 'mousedown', this.onDocumentClick);
        }
              if (!this.touchOutsideHandler) {
          currentDocument = currentDocument || props.getDocument();
          this.touchOutsideHandler = addEventListener(currentDocument, 'touchstart', this.onDocumentClick);
        }
        return;
      }
  
      this.clearOutsideHandler();
    },
    componentWillUnmount: function componentWillUnmount() {
      this.clearDelayTimer();
      this.clearOutsideHandler();
    },
    onMouseEnter: function onMouseEnter(e) {
      this.fireEvents('onMouseEnter', e);
      this.delaySetPopupVisible(true, this.props.mouseEnterDelay);
    },
    onMouseLeave: function onMouseLeave(e) {
      this.fireEvents('onMouseLeave', e);
      this.delaySetPopupVisible(false, this.props.mouseLeaveDelay);
    },
    onPopupMouseEnter: function onPopupMouseEnter() {
      this.clearDelayTimer();
    },
    onPopupMouseLeave: function onPopupMouseLeave(e) {
              if (e.relatedTarget && !e.relatedTarget.setTimeout && this._component && contains(this._component.getPopupDomNode(), e.relatedTarget)) {
        return;
      }
      this.delaySetPopupVisible(false, this.props.mouseLeaveDelay);
    },
    onFocus: function onFocus(e) {
      this.fireEvents('onFocus', e);
          this.clearDelayTimer();
      if (this.isFocusToShow()) {
        this.focusTime = Date.now();
        this.delaySetPopupVisible(true, this.props.focusDelay);
      }
    },
    onMouseDown: function onMouseDown(e) {
      this.fireEvents('onMouseDown', e);
      this.preClickTime = Date.now();
    },
    onTouchStart: function onTouchStart(e) {
      this.fireEvents('onTouchStart', e);
      this.preTouchTime = Date.now();
    },
    onBlur: function onBlur(e) {
      this.fireEvents('onBlur', e);
      this.clearDelayTimer();
      if (this.isBlurToHide()) {
        this.delaySetPopupVisible(false, this.props.blurDelay);
      }
    },
    onClick: function onClick(event) {
      this.fireEvents('onClick', event);
          if (this.focusTime) {
        var preTime = void 0;
        if (this.preClickTime && this.preTouchTime) {
          preTime = Math.min(this.preClickTime, this.preTouchTime);
        } else if (this.preClickTime) {
          preTime = this.preClickTime;
        } else if (this.preTouchTime) {
          preTime = this.preTouchTime;
        }
        if (Math.abs(preTime - this.focusTime) < 20) {
          return;
        }
        this.focusTime = 0;
      }
      this.preClickTime = 0;
      this.preTouchTime = 0;
      event.preventDefault();
      var nextVisible = !this.state.popupVisible;
      if (this.isClickToHide() && !nextVisible || nextVisible && this.isClickToShow()) {
        this.setPopupVisible(!this.state.popupVisible);
      }
    },
    onDocumentClick: function onDocumentClick(event) {
      if (this.props.mask && !this.props.maskClosable) {
        return;
      }
      var target = event.target;
      var root = findDOMNode(this);
      var popupNode = this.getPopupDomNode();
      if (!contains(root, target) && !contains(popupNode, target)) {
        this.close();
      }
    },
    getPopupDomNode: function getPopupDomNode() {
          if (this._component && this._component.getPopupDomNode) {
        return this._component.getPopupDomNode();
      }
      return null;
    },
    getRootDomNode: function getRootDomNode() {
      return findDOMNode(this);
    },
    getPopupClassNameFromAlign: function getPopupClassNameFromAlign(align) {
      var className = [];
      var props = this.props;
      var popupPlacement = props.popupPlacement,
          builtinPlacements = props.builtinPlacements,
          prefixCls = props.prefixCls;
  
      if (popupPlacement && builtinPlacements) {
        className.push(_getPopupClassNameFromAlign(builtinPlacements, prefixCls, align));
      }
      if (props.getPopupClassNameFromAlign) {
        className.push(props.getPopupClassNameFromAlign(align));
      }
      return className.join(' ');
    },
    getPopupAlign: function getPopupAlign() {
      var props = this.props;
      var popupPlacement = props.popupPlacement,
          popupAlign = props.popupAlign,
          builtinPlacements = props.builtinPlacements;
  
      if (popupPlacement && builtinPlacements) {
        return getAlignFromPlacement(builtinPlacements, popupPlacement, popupAlign);
      }
      return popupAlign;
    },
    getComponent: function getComponent() {
      var props = this.props,
          state = this.state;
  
      var mouseProps = {};
      if (this.isMouseEnterToShow()) {
        mouseProps.onMouseEnter = this.onPopupMouseEnter;
      }
      if (this.isMouseLeaveToHide()) {
        mouseProps.onMouseLeave = this.onPopupMouseLeave;
      }
      return React.createElement(
        Popup,
        _extends({
          prefixCls: props.prefixCls,
          destroyPopupOnHide: props.destroyPopupOnHide,
          visible: state.popupVisible,
          className: props.popupClassName,
          action: props.action,
          align: this.getPopupAlign(),
          onAlign: props.onPopupAlign,
          animation: props.popupAnimation,
          getClassNameFromAlign: this.getPopupClassNameFromAlign
        }, mouseProps, {
          getRootDomNode: this.getRootDomNode,
          style: props.popupStyle,
          mask: props.mask,
          zIndex: props.zIndex,
          transitionName: props.popupTransitionName,
          maskAnimation: props.maskAnimation,
          maskTransitionName: props.maskTransitionName
        }),
        typeof props.popup === 'function' ? props.popup() : props.popup
      );
    },
    setPopupVisible: function setPopupVisible(popupVisible) {
      this.clearDelayTimer();
      if (this.state.popupVisible !== popupVisible) {
        if (!('popupVisible' in this.props)) {
          this.setState({
            popupVisible: popupVisible
          });
        }
        this.props.onPopupVisibleChange(popupVisible);
      }
    },
    delaySetPopupVisible: function delaySetPopupVisible(visible, delayS) {
      var _this2 = this;
  
      var delay = delayS * 1000;
      this.clearDelayTimer();
      if (delay) {
        this.delayTimer = setTimeout(function () {
          _this2.setPopupVisible(visible);
          _this2.clearDelayTimer();
        }, delay);
      } else {
        this.setPopupVisible(visible);
      }
    },
    clearDelayTimer: function clearDelayTimer() {
      if (this.delayTimer) {
        clearTimeout(this.delayTimer);
        this.delayTimer = null;
      }
    },
    clearOutsideHandler: function clearOutsideHandler() {
      if (this.clickOutsideHandler) {
        this.clickOutsideHandler.remove();
        this.clickOutsideHandler = null;
      }
  
      if (this.touchOutsideHandler) {
        this.touchOutsideHandler.remove();
        this.touchOutsideHandler = null;
      }
    },
    createTwoChains: function createTwoChains(event) {
      var childPros = this.props.children.props;
      var props = this.props;
      if (childPros[event] && props[event]) {
        return this['fire' + event];
      }
      return childPros[event] || props[event];
    },
    isClickToShow: function isClickToShow() {
      var _props = this.props,
          action = _props.action,
          showAction = _props.showAction;
  
      return action.indexOf('click') !== -1 || showAction.indexOf('click') !== -1;
    },
    isClickToHide: function isClickToHide() {
      var _props2 = this.props,
          action = _props2.action,
          hideAction = _props2.hideAction;
  
      return action.indexOf('click') !== -1 || hideAction.indexOf('click') !== -1;
    },
    isMouseEnterToShow: function isMouseEnterToShow() {
      var _props3 = this.props,
          action = _props3.action,
          showAction = _props3.showAction;
  
      return action.indexOf('hover') !== -1 || showAction.indexOf('mouseEnter') !== -1;
    },
    isMouseLeaveToHide: function isMouseLeaveToHide() {
      var _props4 = this.props,
          action = _props4.action,
          hideAction = _props4.hideAction;
  
      return action.indexOf('hover') !== -1 || hideAction.indexOf('mouseLeave') !== -1;
    },
    isFocusToShow: function isFocusToShow() {
      var _props5 = this.props,
          action = _props5.action,
          showAction = _props5.showAction;
  
      return action.indexOf('focus') !== -1 || showAction.indexOf('focus') !== -1;
    },
    isBlurToHide: function isBlurToHide() {
      var _props6 = this.props,
          action = _props6.action,
          hideAction = _props6.hideAction;
  
      return action.indexOf('focus') !== -1 || hideAction.indexOf('blur') !== -1;
    },
    forcePopupAlign: function forcePopupAlign() {
      if (this.state.popupVisible && this._component && this._component.alignInstance) {
        this._component.alignInstance.forceAlign();
      }
    },
    fireEvents: function fireEvents(type, e) {
      var childCallback = this.props.children.props[type];
      if (childCallback) {
        childCallback(e);
      }
      var callback = this.props[type];
      if (callback) {
        callback(e);
      }
    },
    close: function close() {
      this.setPopupVisible(false);
    },
    render: function render() {
      var props = this.props;
      var children = props.children;
      var child = React.Children.only(children);
      var newChildProps = {};
      if (this.isClickToHide() || this.isClickToShow()) {
        newChildProps.onClick = this.onClick;
        newChildProps.onMouseDown = this.onMouseDown;
        newChildProps.onTouchStart = this.onTouchStart;
      } else {
        newChildProps.onClick = this.createTwoChains('onClick');
        newChildProps.onMouseDown = this.createTwoChains('onMouseDown');
        newChildProps.onTouchStart = this.createTwoChains('onTouchStart');
      }
      if (this.isMouseEnterToShow()) {
        newChildProps.onMouseEnter = this.onMouseEnter;
      } else {
        newChildProps.onMouseEnter = this.createTwoChains('onMouseEnter');
      }
      if (this.isMouseLeaveToHide()) {
        newChildProps.onMouseLeave = this.onMouseLeave;
      } else {
        newChildProps.onMouseLeave = this.createTwoChains('onMouseLeave');
      }
      if (this.isFocusToShow() || this.isBlurToHide()) {
        newChildProps.onFocus = this.onFocus;
        newChildProps.onBlur = this.onBlur;
      } else {
        newChildProps.onFocus = this.createTwoChains('onFocus');
        newChildProps.onBlur = this.createTwoChains('onBlur');
      }
  
      return React.cloneElement(child, newChildProps);
    }
  });
  
  export default Trigger;