text: "use strict";
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  
  var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
  
  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  
  var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  
  var _react = require("react");
  
  var _react2 = _interopRequireDefault(_react);
  
  var _propTypes = require("prop-types");
  
  var _propTypes2 = _interopRequireDefault(_propTypes);
  
  var _focusManager = require("../helpers/focusManager");
  
  var focusManager = _interopRequireWildcard(_focusManager);
  
  var _scopeTab = require("../helpers/scopeTab");
  
  var _scopeTab2 = _interopRequireDefault(_scopeTab);
  
  var _ariaAppHider = require("../helpers/ariaAppHider");
  
  var ariaAppHider = _interopRequireWildcard(_ariaAppHider);
  
  var _bodyClassList = require("../helpers/bodyClassList");
  
  var bodyClassList = _interopRequireWildcard(_bodyClassList);
  
  var _safeHTMLElement = require("../helpers/safeHTMLElement");
  
  var _safeHTMLElement2 = _interopRequireDefault(_safeHTMLElement);
  
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  
  function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  
  // so that our CSS is statically analyzable
  var CLASS_NAMES = {
    overlay: "ReactModal__Overlay",
    content: "ReactModal__Content"
  };
  
  var TAB_KEY = 9;
  var ESC_KEY = 27;
  
  var ariaHiddenInstances = 0;
  
  var ModalPortal = function (_Component) {
    _inherits(ModalPortal, _Component);
  
    function ModalPortal(props) {
      _classCallCheck(this, ModalPortal);
  
      var _this = _possibleConstructorReturn(this, (ModalPortal.__proto__ || Object.getPrototypeOf(ModalPortal)).call(this, props));
  
      _this.setFocusAfterRender = function (focus) {
        _this.focusAfterRender = _this.props.shouldFocusAfterRender && focus;
      };
  
      _this.setOverlayRef = function (overlay) {
        _this.overlay = overlay;
        _this.props.overlayRef && _this.props.overlayRef(overlay);
      };
  
      _this.setContentRef = function (content) {
        _this.content = content;
        _this.props.contentRef && _this.props.contentRef(content);
      };
  
      _this.afterClose = function () {
        var _this$props = _this.props,
            appElement = _this$props.appElement,
            ariaHideApp = _this$props.ariaHideApp;
  
        // Remove body class
  
        bodyClassList.remove(_this.props.bodyOpenClassName);
  
        // Reset aria-hidden attribute if all modals have been removed
        if (ariaHideApp && ariaHiddenInstances > 0) {
          ariaHiddenInstances -= 1;
  
          if (ariaHiddenInstances === 0) {
            ariaAppHider.show(appElement);
          }
        }
  
        if (_this.props.shouldFocusAfterRender) {
          if (_this.props.shouldReturnFocusAfterClose) {
            focusManager.returnFocus();
            focusManager.teardownScopedFocus();
          } else {
            focusManager.popWithoutFocus();
          }
        }
      };
  
      _this.open = function () {
        _this.beforeOpen();
        if (_this.state.afterOpen && _this.state.beforeClose) {
          clearTimeout(_this.closeTimer);
          _this.setState({ beforeClose: false });
        } else {
          if (_this.props.shouldFocusAfterRender) {
            focusManager.setupScopedFocus(_this.node);
            focusManager.markForFocusLater();
          }
  
          _this.setState({ isOpen: true }, function () {
            _this.setState({ afterOpen: true });
  
            if (_this.props.isOpen && _this.props.onAfterOpen) {
              _this.props.onAfterOpen();
            }
          });
        }
      };
  
      _this.close = function () {
        if (_this.props.closeTimeoutMS > 0) {
          _this.closeWithTimeout();
        } else {
          _this.closeWithoutTimeout();
        }
      };
  
      _this.focusContent = function () {
        return _this.content && !_this.contentHasFocus() && _this.content.focus();
      };
  
      _this.closeWithTimeout = function () {
        var closesAt = Date.now() + _this.props.closeTimeoutMS;
        _this.setState({ beforeClose: true, closesAt: closesAt }, function () {
          _this.closeTimer = setTimeout(_this.closeWithoutTimeout, _this.state.closesAt - Date.now());
        });
      };
  
      _this.closeWithoutTimeout = function () {
        _this.setState({
          beforeClose: false,
          isOpen: false,
          afterOpen: false,
          closesAt: null
        }, _this.afterClose);
      };
  
      _this.handleKeyDown = function (event) {
        if (event.keyCode === TAB_KEY) {
          (0, _scopeTab2.default)(_this.content, event);
        }
  
        if (_this.props.shouldCloseOnEsc && event.keyCode === ESC_KEY) {
          event.stopPropagation();
          _this.requestClose(event);
        }
      };
  
      _this.handleOverlayOnClick = function (event) {
        if (_this.shouldClose === null) {
          _this.shouldClose = true;
        }
  
        if (_this.shouldClose && _this.props.shouldCloseOnOverlayClick) {
          if (_this.ownerHandlesClose()) {
            _this.requestClose(event);
          } else {
            _this.focusContent();
          }
        }
        _this.shouldClose = null;
        _this.moveFromContentToOverlay = null;
      };
  
      _this.handleOverlayOnMouseUp = function () {
        if (_this.moveFromContentToOverlay === null) {
          _this.shouldClose = false;
        }
        if (_this.props.shouldCloseOnOverlayClick) {
          _this.shouldClose = true;
        }
      };
  
      _this.handleContentOnMouseUp = function () {
        _this.shouldClose = false;
      };
  
      _this.handleOverlayOnMouseDown = function (event) {
        if (!_this.props.shouldCloseOnOverlayClick && event.target == _this.overlay) {
          event.preventDefault();
        }
        _this.moveFromContentToOverlay = false;
      };
  
      _this.handleContentOnClick = function () {
        _this.shouldClose = false;
      };
  
      _this.handleContentOnMouseDown = function () {
        _this.shouldClose = false;
        _this.moveFromContentToOverlay = false;
      };
  
      _this.requestClose = function (event) {
        return _this.ownerHandlesClose() && _this.props.onRequestClose(event);
      };
  
      _this.ownerHandlesClose = function () {
        return _this.props.onRequestClose;
      };
  
      _this.shouldBeClosed = function () {
        return !_this.state.isOpen && !_this.state.beforeClose;
      };
  
      _this.contentHasFocus = function () {
        return document.activeElement === _this.content || _this.content.contains(document.activeElement);
      };
  
      _this.buildClassName = function (which, additional) {
        var classNames = (typeof additional === "undefined" ? "undefined" : _typeof(additional)) === "object" ? additional : {
          base: CLASS_NAMES[which],
          afterOpen: CLASS_NAMES[which] + "--after-open",
          beforeClose: CLASS_NAMES[which] + "--before-close"
        };
        var className = classNames.base;
        if (_this.state.afterOpen) {
          className = className + " " + classNames.afterOpen;
        }
        if (_this.state.beforeClose) {
          className = className + " " + classNames.beforeClose;
        }
        return typeof additional === "string" && additional ? className + " " + additional : className;
      };
  
      _this.ariaAttributes = function (items) {
        return Object.keys(items).reduce(function (acc, name) {
          acc["aria-" + name] = items[name];
          return acc;
        }, {});
      };
  
      _this.state = {
        afterOpen: false,
        beforeClose: false
      };
  
      _this.shouldClose = null;
      _this.moveFromContentToOverlay = null;
      return _this;
    }
  
    _createClass(ModalPortal, [{
      key: "componentDidMount",
      value: function componentDidMount() {
        // Focus needs to be set when mounting and already open
        if (this.props.isOpen) {
          this.setFocusAfterRender(true);
          this.open();
        }
      }
    }, {
      key: "componentWillReceiveProps",
      value: function componentWillReceiveProps(newProps) {
        if (process.env.NODE_ENV !== "production") {
          if (newProps.bodyOpenClassName !== this.props.bodyOpenClassName) {
            // eslint-disable-next-line no-console
            console.warn('React-Modal: "bodyOpenClassName" prop has been modified. ' + "This may cause unexpected behavior when multiple modals are open.");
          }
        }
        // Focus only needs to be set once when the modal is being opened
        if (!this.props.isOpen && newProps.isOpen) {
          this.setFocusAfterRender(true);
          this.open();
        } else if (this.props.isOpen && !newProps.isOpen) {
          this.close();
        }
      }
    }, {
      key: "componentDidUpdate",
      value: function componentDidUpdate() {
        if (this.focusAfterRender) {
          this.focusContent();
          this.setFocusAfterRender(false);
        }
      }
    }, {
      key: "componentWillUnmount",
      value: function componentWillUnmount() {
        this.afterClose();
        clearTimeout(this.closeTimer);
      }
    }, {
      key: "beforeOpen",
      value: function beforeOpen() {
        var _props = this.props,
            appElement = _props.appElement,
            ariaHideApp = _props.ariaHideApp,
            bodyOpenClassName = _props.bodyOpenClassName;
        // Add body class
  
        bodyClassList.add(bodyOpenClassName);
        // Add aria-hidden to appElement
        if (ariaHideApp) {
          ariaHiddenInstances += 1;
          ariaAppHider.hide(appElement);
        }
      }
  
      // Don't steal focus from inner elements
  
    }, {
      key: "render",
      value: function render() {
        var _props2 = this.props,
            className = _props2.className,
            overlayClassName = _props2.overlayClassName,
            defaultStyles = _props2.defaultStyles;
  
        var contentStyles = className ? {} : defaultStyles.content;
        var overlayStyles = overlayClassName ? {} : defaultStyles.overlay;
  
        return this.shouldBeClosed() ? null : _react2.default.createElement(
          "div",
          {
            ref: this.setOverlayRef,
            className: this.buildClassName("overlay", overlayClassName),
            style: _extends({}, overlayStyles, this.props.style.overlay),
            onClick: this.handleOverlayOnClick,
            onMouseDown: this.handleOverlayOnMouseDown,
            onMouseUp: this.handleOverlayOnMouseUp,
            "aria-modal": "true"
          },
          _react2.default.createElement(
            "div",
            _extends({
              ref: this.setContentRef,
              style: _extends({}, contentStyles, this.props.style.content),
              className: this.buildClassName("content", className),
              tabIndex: "-1",
              onKeyDown: this.handleKeyDown,
              onMouseDown: this.handleContentOnMouseDown,
              onMouseUp: this.handleContentOnMouseUp,
              onClick: this.handleContentOnClick,
              role: this.props.role,
              "aria-label": this.props.contentLabel
            }, this.ariaAttributes(this.props.aria || {})),
            this.props.children
          )
        );
      }
    }]);
  
    return ModalPortal;
  }(_react.Component);
  
  ModalPortal.defaultProps = {
    style: {
      overlay: {},
      content: {}
    }
  };
  ModalPortal.propTypes = {
    isOpen: _propTypes2.default.bool.isRequired,
    defaultStyles: _propTypes2.default.shape({
      content: _propTypes2.default.object,
      overlay: _propTypes2.default.object
    }),
    style: _propTypes2.default.shape({
      content: _propTypes2.default.object,
      overlay: _propTypes2.default.object
    }),
    className: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.object]),
    overlayClassName: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.object]),
    bodyOpenClassName: _propTypes2.default.string,
    ariaHideApp: _propTypes2.default.bool,
    appElement: _propTypes2.default.instanceOf(_safeHTMLElement2.default),
    onAfterOpen: _propTypes2.default.func,
    onRequestClose: _propTypes2.default.func,
    closeTimeoutMS: _propTypes2.default.number,
    shouldFocusAfterRender: _propTypes2.default.bool,
    shouldCloseOnOverlayClick: _propTypes2.default.bool,
    shouldReturnFocusAfterClose: _propTypes2.default.bool,
    role: _propTypes2.default.string,
    contentLabel: _propTypes2.default.string,
    aria: _propTypes2.default.object,
    children: _propTypes2.default.node,
    shouldCloseOnEsc: _propTypes2.default.bool,
    overlayRef: _propTypes2.default.func,
    contentRef: _propTypes2.default.func
  };
  exports.default = ModalPortal;
  module.exports = exports["default"];