import _extends from "@babel/runtime/helpers/extends";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/inherits";
import _createSuper from "@babel/runtime/helpers/createSuper";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import React, { Children, cloneElement, Component } from 'react';
import { observer } from 'mobx-react';
import { findDOMNode } from 'react-dom';
import noop from 'lodash/noop';
import classNames from "classnames";
import contains from '../util/Dom/contains';
import addEventListener from '../../_util/addEventListener';
import Popup from './Popup';
import { getAlignFromPlacement, getAlignPopupClassName } from './utils';
import Portal from '../util/Portal';

function returnEmptyString() {
  return '';
}

function returnDocument() {
  return window.document;
}

var ALL_HANDLERS = ['onClick', 'onMouseDown', 'onTouchStart', 'onMouseEnter', 'onMouseLeave', 'onFocus', 'onBlur', 'onContextMenu'];

var Trigger = /*#__PURE__*/function (_Component) {
  _inherits(Trigger, _Component);

  var _super = _createSuper(Trigger);

  function Trigger(_props) {
    var _this;

    _classCallCheck(this, Trigger);

    _this = _super.call(this, _props);

    _defineProperty(_assertThisInitialized(_this), "onMouseEnter", function (e) {
      var mouseEnterDelay = _this.props.mouseEnterDelay;

      _this.fireEvents('onMouseEnter', e);

      _this.delaySetPopupVisible(true, mouseEnterDelay, mouseEnterDelay ? null : e);
    });

    _defineProperty(_assertThisInitialized(_this), "onMouseMove", function (e) {
      _this.fireEvents('onMouseMove', e);

      _this.setPoint(e);
    });

    _defineProperty(_assertThisInitialized(_this), "onMouseLeave", function (e) {
      _this.fireEvents('onMouseLeave', e);

      _this.delaySetPopupVisible(false, _this.props.mouseLeaveDelay);
    });

    _defineProperty(_assertThisInitialized(_this), "onPopupMouseEnter", function () {
      _this.clearDelayTimer();
    });

    _defineProperty(_assertThisInitialized(_this), "onPopupMouseLeave", function (e) {
      // https://github.com/react-component/trigger/pull/13
      // react bug?
      var focusedElement = document.activeElement;

      if (e.relatedTarget && !e.relatedTarget.setTimeout && _this._component && _this._component.getPopupDomNode && contains(_this._component.getPopupDomNode(), e.relatedTarget) || e.relatedTarget.setTimeout && contains(_this._component.getPopupDomNode(), focusedElement)) {
        return;
      }

      _this.delaySetPopupVisible(false, _this.props.mouseLeaveDelay);
    });

    _defineProperty(_assertThisInitialized(_this), "onFocus", function (e) {
      _this.fireEvents('onFocus', e); // incase focusin and focusout


      _this.clearDelayTimer();

      if (_this.isFocusToShow()) {
        _this.focusTime = Date.now();

        _this.delaySetPopupVisible(true, _this.props.focusDelay);
      }
    });

    _defineProperty(_assertThisInitialized(_this), "onMouseDown", function (e) {
      _this.fireEvents('onMouseDown', e);

      _this.preClickTime = Date.now();
    });

    _defineProperty(_assertThisInitialized(_this), "onTouchStart", function (e) {
      _this.fireEvents('onTouchStart', e);

      _this.preTouchTime = Date.now();
    });

    _defineProperty(_assertThisInitialized(_this), "onBlur", function (e) {
      _this.fireEvents('onBlur', e);

      if (!e.isDefaultPrevented()) {
        _this.clearDelayTimer();

        if (_this.isBlurToHide()) {
          _this.delaySetPopupVisible(false, _this.props.blurDelay);
        }
      }
    });

    _defineProperty(_assertThisInitialized(_this), "onContextMenu", function (e) {
      e.preventDefault();

      _this.fireEvents('onContextMenu', e);

      _this.setPopupVisible(true, e);
    });

    _defineProperty(_assertThisInitialized(_this), "onContextMenuClose", function () {
      if (_this.isContextMenuToShow()) {
        _this.close();
      }
    });

    _defineProperty(_assertThisInitialized(_this), "onClick", function (event) {
      _this.fireEvents('onClick', event); // focus will trigger click


      if (_this.focusTime) {
        var preTime;

        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;

      if (event && event.preventDefault) {
        event.preventDefault();
      }

      var nextVisible = !_this.state.popupVisible;

      if (_this.isClickToHide() && !nextVisible || nextVisible && _this.isClickToShow()) {
        _this.setPopupVisible(!_this.state.popupVisible, event);
      }
    });

    _defineProperty(_assertThisInitialized(_this), "onDocumentClick", function (event) {
      if (event.isDefaultPrevented() || _this.props.mask && !_this.props.maskClosable) {
        return;
      }

      var target = event.target;
      var root = findDOMNode(_assertThisInitialized(_this));

      var popupNode = _this.getPopupDomNode();

      if (!contains(root, target) && !contains(popupNode, target)) {
        _this.close();
      }
    });

    _defineProperty(_assertThisInitialized(_this), "getRootDomNode", function () {
      var getRootDomNode = _this.props.getRootDomNode;

      if (getRootDomNode) {
        return getRootDomNode();
      } else {
        return findDOMNode(_assertThisInitialized(_this));
      }
    });

    _defineProperty(_assertThisInitialized(_this), "getPopupClassFromAlign", function (align) {
      var className = [];
      var _this$props = _this.props,
          popupPlacement = _this$props.popupPlacement,
          builtinPlacements = _this$props.builtinPlacements,
          prefixCls = _this$props.prefixCls,
          alignPoint = _this$props.alignPoint,
          getPopupClassNameFromAlign = _this$props.getPopupClassNameFromAlign;

      if (popupPlacement && builtinPlacements) {
        className.push(getAlignPopupClassName(builtinPlacements, prefixCls, align, alignPoint));
      }

      if (getPopupClassNameFromAlign) {
        className.push(getPopupClassNameFromAlign(align));
      }

      return className.join(' ');
    });

    _defineProperty(_assertThisInitialized(_this), "getComponent", function () {
      var _this$props2 = _this.props,
          prefixCls = _this$props2.prefixCls,
          destroyPopupOnHide = _this$props2.destroyPopupOnHide,
          popupClassName = _this$props2.popupClassName,
          action = _this$props2.action,
          onPopupAlign = _this$props2.onPopupAlign,
          popupAnimation = _this$props2.popupAnimation,
          popupTransitionName = _this$props2.popupTransitionName,
          popupStyle = _this$props2.popupStyle,
          mask = _this$props2.mask,
          maskAnimation = _this$props2.maskAnimation,
          maskTransitionName = _this$props2.maskTransitionName,
          zIndex = _this$props2.zIndex,
          popup = _this$props2.popup,
          stretch = _this$props2.stretch,
          alignPoint = _this$props2.alignPoint;
      var _this$state = _this.state,
          popupVisible = _this$state.popupVisible,
          point = _this$state.point;

      var align = _this.getPopupAlign();

      var mouseProps = {};

      if (_this.isMouseEnterToShow()) {
        mouseProps.onMouseEnter = _this.onPopupMouseEnter;
      }

      if (_this.isMouseLeaveToHide()) {
        mouseProps.onMouseLeave = _this.onPopupMouseLeave;
      }

      return /*#__PURE__*/React.createElement(Popup, _extends({
        prefixCls: prefixCls,
        destroyPopupOnHide: destroyPopupOnHide,
        visible: popupVisible,
        point: alignPoint && point,
        className: popupClassName,
        action: action,
        align: align,
        onAlign: onPopupAlign,
        animation: popupAnimation,
        getClassNameFromAlign: _this.getPopupClassFromAlign
      }, mouseProps, {
        stretch: stretch,
        getRootDomNode: _this.getRootDomNode,
        style: popupStyle,
        mask: mask,
        zIndex: zIndex,
        transitionName: popupTransitionName,
        maskAnimation: maskAnimation,
        maskTransitionName: maskTransitionName,
        ref: _this.savePopup
      }), typeof popup === 'function' ? popup() : popup);
    });

    _defineProperty(_assertThisInitialized(_this), "getContainer", function () {
      var _assertThisInitialize = _assertThisInitialized(_this),
          props = _assertThisInitialize.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(_assertThisInitialized(_this))) : props.getDocument().body;
      mountNode.appendChild(popupContainer);
      return popupContainer;
    });

    _defineProperty(_assertThisInitialized(_this), "setPoint", function (point) {
      var alignPoint = _this.props.alignPoint;
      if (!alignPoint || !point) return;

      _this.setState({
        point: {
          pageX: point.pageX,
          pageY: point.pageY
        }
      });
    });

    _defineProperty(_assertThisInitialized(_this), "handlePortalUpdate", function () {
      if (_this.prevPopupVisible !== _this.state.popupVisible) {
        _this.props.afterPopupVisibleChange(_this.state.popupVisible);
      }
    });

    _defineProperty(_assertThisInitialized(_this), "savePopup", function (node) {
      _this._component = node;
    });

    var _popupVisible;

    if ('popupVisible' in _props) {
      _popupVisible = !!_props.popupVisible;
    } else {
      _popupVisible = !!_props.defaultPopupVisible;
    }

    _this.prevPopupVisible = _popupVisible;
    _this.state = {
      popupVisible: _popupVisible
    };
    return _this;
  }

  _createClass(Trigger, [{
    key: "componentWillMount",
    value: function componentWillMount() {
      var _this2 = this;

      ALL_HANDLERS.forEach(function (h) {
        _this2["fire".concat(h)] = function (e) {
          _this2.fireEvents(h, e);
        };
      });
    }
  }, {
    key: "componentDidMount",
    value: function componentDidMount() {
      this.componentDidUpdate({}, {
        popupVisible: this.state.popupVisible
      });
    }
  }, {
    key: "componentWillReceiveProps",
    value: function componentWillReceiveProps(_ref) {
      var popupVisible = _ref.popupVisible;

      if (popupVisible !== undefined) {
        this.setState({
          popupVisible: popupVisible
        });
      }
    }
  }, {
    key: "componentDidUpdate",
    value: function componentDidUpdate(_, prevState) {
      var props = this.props;
      var state = this.state;
      this.prevPopupVisible = prevState.popupVisible; // We must listen to `mousedown` or `touchstart`, edge case:
      // https://github.com/react-component/calendar/issues/250
      // https://github.com/react-component/trigger/issues/50

      if (state.popupVisible) {
        var currentDocument;

        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();
    }
  }, {
    key: "componentWillUnmount",
    value: function componentWillUnmount() {
      this.clearDelayTimer();
      this.clearOutsideHandler();
    }
  }, {
    key: "getPopupDomNode",
    value: function getPopupDomNode() {
      // for test
      if (this._component && this._component.getPopupDomNode) {
        return this._component.getPopupDomNode();
      }

      return null;
    }
  }, {
    key: "getPopupAlign",
    value: 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;
    }
  }, {
    key: "setPopupVisible",
    value: function setPopupVisible(popupVisible, event) {
      var alignPoint = this.props.alignPoint;
      this.clearDelayTimer();

      if (this.state.popupVisible !== popupVisible) {
        if (this.props.beforePopupVisibleChange(popupVisible) !== false) {
          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);
      }
    }
  }, {
    key: "delaySetPopupVisible",
    value: 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);
      }
    }
  }, {
    key: "clearDelayTimer",
    value: function clearDelayTimer() {
      if (this.delayTimer) {
        clearTimeout(this.delayTimer);
        this.delayTimer = null;
      }
    }
  }, {
    key: "clearOutsideHandler",
    value: 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;
      }
    }
  }, {
    key: "createTwoChains",
    value: function createTwoChains(event) {
      var childPros = this.props.children.props;
      var props = this.props;

      if (childPros[event] && props[event]) {
        return this["fire".concat(event)];
      }

      return childPros[event] || props[event];
    }
  }, {
    key: "isClickToShow",
    value: function isClickToShow() {
      var _this$props3 = this.props,
          action = _this$props3.action,
          showAction = _this$props3.showAction;
      return action.indexOf('click') !== -1 || showAction.indexOf('click') !== -1;
    }
  }, {
    key: "isContextMenuToShow",
    value: function isContextMenuToShow() {
      var _this$props4 = this.props,
          action = _this$props4.action,
          showAction = _this$props4.showAction;
      return action.indexOf('contextMenu') !== -1 || showAction.indexOf('contextMenu') !== -1;
    }
  }, {
    key: "isClickToHide",
    value: function isClickToHide() {
      var _this$props5 = this.props,
          action = _this$props5.action,
          hideAction = _this$props5.hideAction;
      return action.indexOf('click') !== -1 || hideAction.indexOf('click') !== -1;
    }
  }, {
    key: "isMouseEnterToShow",
    value: function isMouseEnterToShow() {
      var _this$props6 = this.props,
          action = _this$props6.action,
          showAction = _this$props6.showAction;
      return action.indexOf('hover') !== -1 || showAction.indexOf('mouseEnter') !== -1;
    }
  }, {
    key: "isMouseLeaveToHide",
    value: function isMouseLeaveToHide() {
      var _this$props7 = this.props,
          action = _this$props7.action,
          hideAction = _this$props7.hideAction;
      return action.indexOf('hover') !== -1 || hideAction.indexOf('mouseLeave') !== -1;
    }
  }, {
    key: "isFocusToShow",
    value: function isFocusToShow() {
      var _this$props8 = this.props,
          action = _this$props8.action,
          showAction = _this$props8.showAction;
      return action.indexOf('focus') !== -1 || showAction.indexOf('focus') !== -1;
    }
  }, {
    key: "isBlurToHide",
    value: function isBlurToHide() {
      var _this$props9 = this.props,
          action = _this$props9.action,
          hideAction = _this$props9.hideAction;
      return action.indexOf('focus') !== -1 || hideAction.indexOf('blur') !== -1;
    }
  }, {
    key: "forcePopupAlign",
    value: function forcePopupAlign() {
      if (this.state.popupVisible && this._component && this._component.alignInstance) {
        this._component.alignInstance.forceAlign();
      }
    }
  }, {
    key: "fireEvents",
    value: function fireEvents(type, e) {
      var domEvent = e.hasOwnProperty('isDefaultPrevented') ? e : e.domEvent;
      var childCallback = this.props.children.props[type];

      if (childCallback) {
        childCallback(domEvent);
      }

      if (!domEvent.isDefaultPrevented()) {
        var callback = this.props[type];

        if (callback) {
          callback(domEvent);
        }
      }
    }
  }, {
    key: "close",
    value: function close() {
      this.setPopupVisible(false);
    }
  }, {
    key: "render",
    value: function render() {
      var popupVisible = this.state.popupVisible;
      var _this$props10 = this.props,
          children = _this$props10.children,
          forceRender = _this$props10.forceRender,
          alignPoint = _this$props10.alignPoint,
          className = _this$props10.className;
      var child = 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 = /*#__PURE__*/cloneElement(child, newChildProps);
      var portal; // prevent unmounting after it's rendered

      if (popupVisible || this._component || forceRender) {
        portal = /*#__PURE__*/React.createElement(Portal, {
          key: "portal",
          getContainer: this.getContainer,
          didUpdate: this.handlePortalUpdate
        }, this.getComponent());
      }

      return [trigger, portal];
    }
  }]);

  return Trigger;
}(Component);

_defineProperty(Trigger, "displayName", 'Trigger');

_defineProperty(Trigger, "defaultProps", {
  prefixCls: 'rc-trigger-popup',
  getPopupClassNameFromAlign: returnEmptyString,
  getDocument: returnDocument,
  onPopupVisibleChange: noop,
  beforePopupVisibleChange: 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: []
});

export default observer(Trigger);
//# sourceMappingURL=index.js.map
