import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";

/**
 * Portal.jsx
 *
 * @Author: jruif
 * @Date: 2018/1/8 上午10:17
 */
import React from 'react';
import ReactDOM from 'react-dom';

function ownerDocument(node) {
  return node && node.ownerDocument || document;
}

function getOwnerDocument(element) {
  return ownerDocument(ReactDOM.findDOMNode(element));
}

function getContainer(container, defaultContainer) {
  container = typeof container === 'function' ? container() : container;
  return ReactDOM.findDOMNode(container) || defaultContainer;
}
/**
 * @ignore
 */


var Portal =
/*#__PURE__*/
function (_React$PureComponent) {
  _inherits(Portal, _React$PureComponent);

  function Portal() {
    var _getPrototypeOf2;

    var _this;

    _classCallCheck(this, Portal);

    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(Portal)).call.apply(_getPrototypeOf2, [this].concat(args)));

    _defineProperty(_assertThisInitialized(_this), "getMountNode", function () {
      return _this.mountNode;
    });

    return _this;
  }

  _createClass(Portal, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      var _this$props = this.props,
          container = _this$props.container,
          disablePortal = _this$props.disablePortal,
          onRendered = _this$props.onRendered;
      this.setMountNode(container); // Only rerender if needed

      if (!disablePortal) {
        this.forceUpdate(onRendered);
      }
    }
  }, {
    key: "componentDidUpdate",
    value: function componentDidUpdate(prevProps) {
      var _this2 = this;

      var _this$props2 = this.props,
          container = _this$props2.container,
          disablePortal = _this$props2.disablePortal,
          onRendered = _this$props2.onRendered;

      if (prevProps.container !== container || prevProps.disablePortal !== disablePortal) {
        this.setMountNode(container); // Only rerender if needed

        if (!disablePortal) {
          this.forceUpdate(function () {
            if (onRendered) {
              // This might be triggered earlier than the componentDidUpdate of a parent element.
              // We need to account for it.
              clearTimeout(_this2.renderedTimer);
              _this2.renderedTimer = setTimeout(onRendered);
            }
          });
        }
      }
    }
  }, {
    key: "componentWillUnmount",
    value: function componentWillUnmount() {
      this.mountNode = null;
      clearTimeout(this.renderedTimer);
    }
  }, {
    key: "setMountNode",
    value: function setMountNode(container) {
      var disablePortal = this.props.disablePortal;

      if (disablePortal) {
        this.mountNode = ReactDOM.findDOMNode(this).parentElement;
        return;
      }

      this.mountNode = getContainer(container, getOwnerDocument(this).body);
    }
  }, {
    key: "render",
    value: function render() {
      var _this$props3 = this.props,
          children = _this$props3.children,
          disablePortal = _this$props3.disablePortal;

      if (disablePortal) {
        return children;
      }

      return this.mountNode ? ReactDOM.createPortal(children, this.mountNode) : null;
    }
  }]);

  return Portal;
}(React.PureComponent);

export default Portal;