text: import _extends from 'babel-runtime/helpers/extends';
  import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
  import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
  import _inherits from 'babel-runtime/helpers/inherits';
  import React from 'react';
  import PropTypes from 'prop-types';
  import { findDOMNode, createPortal } from 'react-dom';
  import contains from 'rc-util/es/Dom/contains';
  import addEventListener from 'rc-util/es/Dom/addEventListener';
  import ContainerRender from 'rc-util/es/ContainerRender';
  import Portal from 'rc-util/es/Portal';
  import classNames from 'classnames';
  
  import { getAlignFromPlacement, getAlignPopupClassName } from './utils';
  import Popup from './Popup';
  
  function noop() {}
  
  function returnEmptyString() {
    return '';
  }
  
  function returnDocument() {
    return window.document;
  }
  
  var ALL_HANDLERS = ['onClick', 'onMouseDown', 'onTouchStart', 'onMouseEnter', 'onMouseLeave', 'onFocus', 'onBlur', 'onContextMenu'];
  
  var IS_REACT_16 = !!createPortal;
  
  var contextTypes = {
    rcTrigger: PropTypes.shape({
      onPopupMouseDown: PropTypes.func
    })
  };
  
  var Trigger = function (_React$Component) {
    _inherits(Trigger, _React$Component);
  
    function Trigger(props) {
      _classCallCheck(this, Trigger);
  
      var _this = _possibleConstructorReturn(this, _React$Component.call(this, props));
  
      _initialiseProps.call(_this);
  
      var popupVisible = void 0;
      if ('popupVisible' in props) {
        popupVisible = !!props.popupVisible;
      } else {
        popupVisible = !!props.defaultPopupVisible;
      }
  
      _this.prevPopupVisible = popupVisible;
  
      _this.state = {
        popupVisible: popupVisible
      };
      return _this;
    }
  
    Trigger.prototype.getChildContext = function getChildContext() {
      return {
        rcTrigger: {
          onPopupMouseDown: this.onPopupMouseDown
        }
      };
    };
  
    Trigger.prototype.componentWillMount = function componentWillMount() {
      var _this2 = this;
  
      ALL_HANDLERS.forEach(function (h) {
        _this2['fire' + h] = function (e) {
          _this2.fireEvents(h, e);
        };
      });
    };
  
    Trigger.prototype.componentDidMount = function componentDidMount() {
      this.componentDidUpdate({}, {
        popupVisible: this.state.popupVisible
      });
    };
  
    Trigger.prototype.componentWillReceiveProps = function componentWillReceiveProps(_ref) {
      var popupVisible = _ref.popupVisible;
  
      if (popupVisible !== undefined) {
        this.setState({
          popupVisible: popupVisible
        });
      }
    };
  
    Trigger.prototype.componentDidUpdate = function componentDidUpdate(_, prevState) {
      var props = this.props;
      var state = this.state;
      var triggerAfterPopupVisibleChange = function triggerAfterPopupVisibleChange() {
        if (prevState.popupVisible !== state.popupVisible) {
          props.afterPopupVisibleChange(state.popupVisible);
        }
      };
      if (!IS_REACT_16) {
        this.renderComponent(null, triggerAfterPopupVisibleChange);
      }
  
      this.prevPopupVisible = prevState.popupVisible;
  
      // We must listen to `mousedown` or `touchstart`, edge case:
      // https://github.com/ant-design/ant-design/issues/5804
      // https://github.com/react-component/calendar/issues/250
      // https://github.com/react-component/trigger/issues/50
      if (state.popupVisible) {
        var currentDocument = void 0;
        if (!this.clickOutsideHandler && (this.isClickToHide() || this.isContextMenuToShow())) {
          currentDocument = props.getDocument();
          this.clickOutsideHandler = addEventListener(currentDocument, 'mousedown', this.onDocumentClick);
        }
        // always hide on mobile
        if (!this.touchOutsideHandler) {
          currentDocument = currentDocument || props.getDocument();
          this.touchOutsideHandler = addEventListener(currentDocument, 'touchstart', this.onDocumentClick);
        }
        // close popup when trigger type contains 'onContextMenu' and document is scrolling.
        if (!this.contextMenuOutsideHandler1 && this.isContextMenuToShow()) {
          currentDocument = currentDocument || props.getDocument();
          this.contextMenuOutsideHandler1 = addEventListener(currentDocument, 'scroll', this.onContextMenuClose);
        }
        // close popup when trigger type contains 'onContextMenu' and window is blur.
        if (!this.contextMenuOutsideHandler2 && this.isContextMenuToShow()) {
          this.contextMenuOutsideHandler2 = addEventListener(window, 'blur', this.onContextMenuClose);
        }
        return;
      }
  
      this.clearOutsideHandler();
    };
  
    Trigger.prototype.componentWillUnmount = function componentWillUnmount() {
      this.clearDelayTimer();
      this.clearOutsideHandler();
      clearTimeout(this.mouseDownTimeout);
    };
  
    Trigger.prototype.getPopupDomNode = function getPopupDomNode() {
      // for test
      if (this._component && this._component.getPopupDomNode) {
        return this._component.getPopupDomNode();
      }
      return null;
    };
  
    Trigger.prototype.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;
    };
  
    /**
     * @param popupVisible    Show or not the popup element
     * @param event           SyntheticEvent, used for `pointAlign`
     */
    Trigger.prototype.setPopupVisible = function setPopupVisible(popupVisible, event) {
      var alignPoint = this.props.alignPoint;
  
  
      this.clearDelayTimer();
  
      if (this.state.popupVisible !== popupVisible) {
        if (!('popupVisible' in this.props)) {
          this.setState({ popupVisible: popupVisible });
        }
        this.props.onPopupVisibleChange(popupVisible);
      }
  
      // Always record the point position since mouseEnterDelay will delay the show
      if (alignPoint && event) {
        this.setPoint(event);
      }
    };
  
    Trigger.prototype.delaySetPopupVisible = function delaySetPopupVisible(visible, delayS, event) {
      var _this3 = this;
  
      var delay = delayS * 1000;
      this.clearDelayTimer();
      if (delay) {
        var point = event ? { pageX: event.pageX, pageY: event.pageY } : null;
        this.delayTimer = setTimeout(function () {
          _this3.setPopupVisible(visible, point);
          _this3.clearDelayTimer();
        }, delay);
      } else {
        this.setPopupVisible(visible, event);
      }
    };
  
    Trigger.prototype.clearDelayTimer = function clearDelayTimer() {
      if (this.delayTimer) {
        clearTimeout(this.delayTimer);
        this.delayTimer = null;
      }
    };
  
    Trigger.prototype.clearOutsideHandler = function clearOutsideHandler() {
      if (this.clickOutsideHandler) {
        this.clickOutsideHandler.remove();
        this.clickOutsideHandler = null;
      }
  
      if (this.contextMenuOutsideHandler1) {
        this.contextMenuOutsideHandler1.remove();
        this.contextMenuOutsideHandler1 = null;
      }
  
      if (this.contextMenuOutsideHandler2) {
        this.contextMenuOutsideHandler2.remove();
        this.contextMenuOutsideHandler2 = null;
      }
  
      if (this.touchOutsideHandler) {
        this.touchOutsideHandler.remove();
        this.touchOutsideHandler = null;
      }
    };
  
    Trigger.prototype.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];
    };
  
    Trigger.prototype.isClickToShow = function isClickToShow() {
      var _props = this.props,
          action = _props.action,
          showAction = _props.showAction;
  
      return action.indexOf('click') !== -1 || showAction.indexOf('click') !== -1;
    };
  
    Trigger.prototype.isContextMenuToShow = function isContextMenuToShow() {
      var _props2 = this.props,
          action = _props2.action,
          showAction = _props2.showAction;
  
      return action.indexOf('contextMenu') !== -1 || showAction.indexOf('contextMenu') !== -1;
    };
  
    Trigger.prototype.isClickToHide = function isClickToHide() {
      var _props3 = this.props,
          action = _props3.action,
          hideAction = _props3.hideAction;
  
      return action.indexOf('click') !== -1 || hideAction.indexOf('click') !== -1;
    };
  
    Trigger.prototype.isMouseEnterToShow = function isMouseEnterToShow() {
      var _props4 = this.props,
          action = _props4.action,
          showAction = _props4.showAction;
  
      return action.indexOf('hover') !== -1 || showAction.indexOf('mouseEnter') !== -1;
    };
  
    Trigger.prototype.isMouseLeaveToHide = function isMouseLeaveToHide() {
      var _props5 = this.props,
          action = _props5.action,
          hideAction = _props5.hideAction;
  
      return action.indexOf('hover') !== -1 || hideAction.indexOf('mouseLeave') !== -1;
    };
  
    Trigger.prototype.isFocusToShow = function isFocusToShow() {
      var _props6 = this.props,
          action = _props6.action,
          showAction = _props6.showAction;
  
      return action.indexOf('focus') !== -1 || showAction.indexOf('focus') !== -1;
    };
  
    Trigger.prototype.isBlurToHide = function isBlurToHide() {
      var _props7 = this.props,
          action = _props7.action,
          hideAction = _props7.hideAction;
  
      return action.indexOf('focus') !== -1 || hideAction.indexOf('blur') !== -1;
    };
  
    Trigger.prototype.forcePopupAlign = function forcePopupAlign() {
      if (this.state.popupVisible && this._component && this._component.alignInstance) {
        this._component.alignInstance.forceAlign();
      }
    };
  
    Trigger.prototype.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);
      }
    };
  
    Trigger.prototype.close = function close() {
      this.setPopupVisible(false);
    };
  
    Trigger.prototype.render = function render() {
      var _this4 = this;
  
      var popupVisible = this.state.popupVisible;
      var _props8 = this.props,
          children = _props8.children,
          forceRender = _props8.forceRender,
          alignPoint = _props8.alignPoint,
          className = _props8.className;
  
      var child = React.Children.only(children);
      var newChildProps = { key: 'trigger' };
  
      if (this.isContextMenuToShow()) {
        newChildProps.onContextMenu = this.onContextMenu;
      } else {
        newChildProps.onContextMenu = this.createTwoChains('onContextMenu');
      }
  
      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;
        if (alignPoint) {
          newChildProps.onMouseMove = this.onMouseMove;
        }
      } 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');
      }
  
      var childrenClassName = classNames(child && child.props && child.props.className, className);
      if (childrenClassName) {
        newChildProps.className = childrenClassName;
      }
      var trigger = React.cloneElement(child, newChildProps);
  
      if (!IS_REACT_16) {
        return React.createElement(
          ContainerRender,
          {
            parent: this,
            visible: popupVisible,
            autoMount: false,
            forceRender: forceRender,
            getComponent: this.getComponent,
            getContainer: this.getContainer
          },
          function (_ref2) {
            var renderComponent = _ref2.renderComponent;
  
            _this4.renderComponent = renderComponent;
            return trigger;
          }
        );
      }
  
      var portal = void 0;
      // prevent unmounting after it's rendered
      if (popupVisible || this._component || forceRender) {
        portal = React.createElement(
          Portal,
          {
            key: 'portal',
            getContainer: this.getContainer,
            didUpdate: this.handlePortalUpdate
          },
          this.getComponent()
        );
      }
  
      return [trigger, portal];
    };
  
    return Trigger;
  }(React.Component);
  
  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,
    className: 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,
    forceRender: PropTypes.bool,
    destroyPopupOnHide: PropTypes.bool,
    mask: PropTypes.bool,
    maskClosable: PropTypes.bool,
    onPopupAlign: PropTypes.func,
    popupAlign: PropTypes.object,
    popupVisible: PropTypes.bool,
    defaultPopupVisible: PropTypes.bool,
    maskTransitionName: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
    maskAnimation: PropTypes.string,
    stretch: PropTypes.string,
    alignPoint: PropTypes.bool // Maybe we can support user pass position in the future
  };
  Trigger.contextTypes = contextTypes;
  Trigger.childContextTypes = contextTypes;
  Trigger.defaultProps = {
    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: []
  };
  
  var _initialiseProps = function _initialiseProps() {
    var _this5 = this;
  
    this.onMouseEnter = function (e) {
      var mouseEnterDelay = _this5.props.mouseEnterDelay;
  
      _this5.fireEvents('onMouseEnter', e);
      _this5.delaySetPopupVisible(true, mouseEnterDelay, mouseEnterDelay ? null : e);
    };
  
    this.onMouseMove = function (e) {
      _this5.fireEvents('onMouseMove', e);
      _this5.setPoint(e);
    };
  
    this.onMouseLeave = function (e) {
      _this5.fireEvents('onMouseLeave', e);
      _this5.delaySetPopupVisible(false, _this5.props.mouseLeaveDelay);
    };
  
    this.onPopupMouseEnter = function () {
      _this5.clearDelayTimer();
    };
  
    this.onPopupMouseLeave = function (e) {
      // https://github.com/react-component/trigger/pull/13
      // react bug?
      if (e.relatedTarget && !e.relatedTarget.setTimeout && _this5._component && _this5._component.getPopupDomNode && contains(_this5._component.getPopupDomNode(), e.relatedTarget)) {
        return;
      }
      _this5.delaySetPopupVisible(false, _this5.props.mouseLeaveDelay);
    };
  
    this.onFocus = function (e) {
      _this5.fireEvents('onFocus', e);
      // incase focusin and focusout
      _this5.clearDelayTimer();
      if (_this5.isFocusToShow()) {
        _this5.focusTime = Date.now();
        _this5.delaySetPopupVisible(true, _this5.props.focusDelay);
      }
    };
  
    this.onMouseDown = function (e) {
      _this5.fireEvents('onMouseDown', e);
      _this5.preClickTime = Date.now();
    };
  
    this.onTouchStart = function (e) {
      _this5.fireEvents('onTouchStart', e);
      _this5.preTouchTime = Date.now();
    };
  
    this.onBlur = function (e) {
      _this5.fireEvents('onBlur', e);
      _this5.clearDelayTimer();
      if (_this5.isBlurToHide()) {
        _this5.delaySetPopupVisible(false, _this5.props.blurDelay);
      }
    };
  
    this.onContextMenu = function (e) {
      e.preventDefault();
      _this5.fireEvents('onContextMenu', e);
      _this5.setPopupVisible(true, e);
    };
  
    this.onContextMenuClose = function () {
      if (_this5.isContextMenuToShow()) {
        _this5.close();
      }
    };
  
    this.onClick = function (event) {
      _this5.fireEvents('onClick', event);
      // focus will trigger click
      if (_this5.focusTime) {
        var preTime = void 0;
        if (_this5.preClickTime && _this5.preTouchTime) {
          preTime = Math.min(_this5.preClickTime, _this5.preTouchTime);
        } else if (_this5.preClickTime) {
          preTime = _this5.preClickTime;
        } else if (_this5.preTouchTime) {
          preTime = _this5.preTouchTime;
        }
        if (Math.abs(preTime - _this5.focusTime) < 20) {
          return;
        }
        _this5.focusTime = 0;
      }
      _this5.preClickTime = 0;
      _this5.preTouchTime = 0;
      if (event && event.preventDefault) {
        event.preventDefault();
      }
      var nextVisible = !_this5.state.popupVisible;
      if (_this5.isClickToHide() && !nextVisible || nextVisible && _this5.isClickToShow()) {
        _this5.setPopupVisible(!_this5.state.popupVisible, event);
      }
    };
  
    this.onPopupMouseDown = function () {
      var _context$rcTrigger = _this5.context.rcTrigger,
          rcTrigger = _context$rcTrigger === undefined ? {} : _context$rcTrigger;
  
      _this5.hasPopupMouseDown = true;
  
      clearTimeout(_this5.mouseDownTimeout);
      _this5.mouseDownTimeout = setTimeout(function () {
        _this5.hasPopupMouseDown = false;
      }, 0);
  
      if (rcTrigger.onPopupMouseDown) {
        rcTrigger.onPopupMouseDown.apply(rcTrigger, arguments);
      }
    };
  
    this.onDocumentClick = function (event) {
      if (_this5.props.mask && !_this5.props.maskClosable) {
        return;
      }
  
      var target = event.target;
      var root = findDOMNode(_this5);
      if (!contains(root, target) && !_this5.hasPopupMouseDown) {
        _this5.close();
      }
    };
  
    this.getRootDomNode = function () {
      return findDOMNode(_this5);
    };
  
    this.getPopupClassNameFromAlign = function (align) {
      var className = [];
      var _props9 = _this5.props,
          popupPlacement = _props9.popupPlacement,
          builtinPlacements = _props9.builtinPlacements,
          prefixCls = _props9.prefixCls,
          alignPoint = _props9.alignPoint,
          getPopupClassNameFromAlign = _props9.getPopupClassNameFromAlign;
  
      if (popupPlacement && builtinPlacements) {
        className.push(getAlignPopupClassName(builtinPlacements, prefixCls, align, alignPoint));
      }
      if (getPopupClassNameFromAlign) {
        className.push(getPopupClassNameFromAlign(align));
      }
      return className.join(' ');
    };
  
    this.getComponent = function () {
      var _props10 = _this5.props,
          prefixCls = _props10.prefixCls,
          destroyPopupOnHide = _props10.destroyPopupOnHide,
          popupClassName = _props10.popupClassName,
          action = _props10.action,
          onPopupAlign = _props10.onPopupAlign,
          popupAnimation = _props10.popupAnimation,
          popupTransitionName = _props10.popupTransitionName,
          popupStyle = _props10.popupStyle,
          mask = _props10.mask,
          maskAnimation = _props10.maskAnimation,
          maskTransitionName = _props10.maskTransitionName,
          zIndex = _props10.zIndex,
          popup = _props10.popup,
          stretch = _props10.stretch,
          alignPoint = _props10.alignPoint;
      var _state = _this5.state,
          popupVisible = _state.popupVisible,
          point = _state.point;
  
  
      var align = _this5.getPopupAlign();
  
      var mouseProps = {};
      if (_this5.isMouseEnterToShow()) {
        mouseProps.onMouseEnter = _this5.onPopupMouseEnter;
      }
      if (_this5.isMouseLeaveToHide()) {
        mouseProps.onMouseLeave = _this5.onPopupMouseLeave;
      }
  
      mouseProps.onMouseDown = _this5.onPopupMouseDown;
      mouseProps.onTouchStart = _this5.onPopupMouseDown;
  
      return React.createElement(
        Popup,
        _extends({
          prefixCls: prefixCls,
          destroyPopupOnHide: destroyPopupOnHide,
          visible: popupVisible,
          point: alignPoint && point,
          className: popupClassName,
          action: action,
          align: align,
          onAlign: onPopupAlign,
          animation: popupAnimation,
          getClassNameFromAlign: _this5.getPopupClassNameFromAlign
        }, mouseProps, {
          stretch: stretch,
          getRootDomNode: _this5.getRootDomNode,
          style: popupStyle,
          mask: mask,
          zIndex: zIndex,
          transitionName: popupTransitionName,
          maskAnimation: maskAnimation,
          maskTransitionName: maskTransitionName,
          ref: _this5.savePopup
        }),
        typeof popup === 'function' ? popup() : popup
      );
    };
  
    this.getContainer = function () {
      var props = _this5.props;
  
      var popupContainer = document.createElement('div');
      // Make sure default popup container will never cause scrollbar appearing
      // https://github.com/react-component/trigger/issues/41
      popupContainer.style.position = 'absolute';
      popupContainer.style.top = '0';
      popupContainer.style.left = '0';
      popupContainer.style.width = '100%';
      var mountNode = props.getPopupContainer ? props.getPopupContainer(findDOMNode(_this5)) : props.getDocument().body;
      mountNode.appendChild(popupContainer);
      return popupContainer;
    };
  
    this.setPoint = function (point) {
      var alignPoint = _this5.props.alignPoint;
  
      if (!alignPoint || !point) return;
  
      _this5.setState({
        point: {
          pageX: point.pageX,
          pageY: point.pageY
        }
      });
    };
  
    this.handlePortalUpdate = function () {
      if (_this5.prevPopupVisible !== _this5.state.popupVisible) {
        _this5.props.afterPopupVisibleChange(_this5.state.popupVisible);
      }
    };
  
    this.savePopup = function (node) {
      _this5._component = node;
    };
  };
  
  export default Trigger;