200 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			200 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						|
 | 
						|
Object.defineProperty(exports, "__esModule", {
 | 
						|
  value: true
 | 
						|
});
 | 
						|
 | 
						|
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
 | 
						|
 | 
						|
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
 | 
						|
 | 
						|
var _keys = require('babel-runtime/core-js/object/keys');
 | 
						|
 | 
						|
var _keys2 = _interopRequireDefault(_keys);
 | 
						|
 | 
						|
var _style = require('dom-helpers/style');
 | 
						|
 | 
						|
var _style2 = _interopRequireDefault(_style);
 | 
						|
 | 
						|
var _ownerDocument = require('dom-helpers/ownerDocument');
 | 
						|
 | 
						|
var _ownerDocument2 = _interopRequireDefault(_ownerDocument);
 | 
						|
 | 
						|
var _scrollbarSize = require('dom-helpers/util/scrollbarSize');
 | 
						|
 | 
						|
var _scrollbarSize2 = _interopRequireDefault(_scrollbarSize);
 | 
						|
 | 
						|
var _isOverflowing = require('./isOverflowing');
 | 
						|
 | 
						|
var _isOverflowing2 = _interopRequireDefault(_isOverflowing);
 | 
						|
 | 
						|
var _manageAriaHidden = require('./manageAriaHidden');
 | 
						|
 | 
						|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 | 
						|
 | 
						|
function findIndexOf(data, callback) {
 | 
						|
  var idx = -1;
 | 
						|
  data.some(function (item, index) {
 | 
						|
    if (callback(item)) {
 | 
						|
      idx = index;
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
    return false;
 | 
						|
  });
 | 
						|
  return idx;
 | 
						|
}
 | 
						|
 | 
						|
function findContainer(data, modal) {
 | 
						|
  return findIndexOf(data, function (item) {
 | 
						|
    return item.modals.indexOf(modal) !== -1;
 | 
						|
  });
 | 
						|
}
 | 
						|
 | 
						|
function getPaddingRight(node) {
 | 
						|
  return parseInt((0, _style2.default)(node, 'paddingRight') || 0, 10);
 | 
						|
}
 | 
						|
 | 
						|
function setContainerStyle(data, container) {
 | 
						|
  var style = { overflow: 'hidden' };
 | 
						|
 | 
						|
  // We are only interested in the actual `style` here because we will override it.
 | 
						|
  data.style = {
 | 
						|
    overflow: container.style.overflow,
 | 
						|
    paddingRight: container.style.paddingRight
 | 
						|
  };
 | 
						|
 | 
						|
  if (data.overflowing) {
 | 
						|
    var scrollbarSize = (0, _scrollbarSize2.default)();
 | 
						|
 | 
						|
    // Use computed style, here to get the real padding to add our scrollbar width.
 | 
						|
    style.paddingRight = getPaddingRight(container) + scrollbarSize + 'px';
 | 
						|
 | 
						|
    // .mui-fixed is a global helper.
 | 
						|
    var fixedNodes = (0, _ownerDocument2.default)(container).querySelectorAll('.mui-fixed');
 | 
						|
    for (var i = 0; i < fixedNodes.length; i += 1) {
 | 
						|
      var paddingRight = getPaddingRight(fixedNodes[i]);
 | 
						|
      data.prevPaddings.push(paddingRight);
 | 
						|
      fixedNodes[i].style.paddingRight = paddingRight + scrollbarSize + 'px';
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  (0, _keys2.default)(style).forEach(function (key) {
 | 
						|
    container.style[key] = style[key];
 | 
						|
  });
 | 
						|
}
 | 
						|
 | 
						|
function removeContainerStyle(data, container) {
 | 
						|
  (0, _keys2.default)(data.style).forEach(function (key) {
 | 
						|
    container.style[key] = data.style[key];
 | 
						|
  });
 | 
						|
 | 
						|
  var fixedNodes = (0, _ownerDocument2.default)(container).querySelectorAll('.mui-fixed');
 | 
						|
  for (var i = 0; i < fixedNodes.length; i += 1) {
 | 
						|
    fixedNodes[i].style.paddingRight = data.prevPaddings[i] + 'px';
 | 
						|
  }
 | 
						|
}
 | 
						|
/**
 | 
						|
 * @ignore - do not document.
 | 
						|
 *
 | 
						|
 * Proper state managment for containers and the modals in those containers.
 | 
						|
 * Simplified, but inspired by react-overlay's ModalManager class
 | 
						|
 * Used by the Modal to ensure proper styling of containers.
 | 
						|
 */
 | 
						|
 | 
						|
var ModalManager = function ModalManager() {
 | 
						|
  var _this = this;
 | 
						|
 | 
						|
  var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
 | 
						|
      _ref$hideSiblingNodes = _ref.hideSiblingNodes,
 | 
						|
      hideSiblingNodes = _ref$hideSiblingNodes === undefined ? true : _ref$hideSiblingNodes,
 | 
						|
      _ref$handleContainerO = _ref.handleContainerOverflow,
 | 
						|
      handleContainerOverflow = _ref$handleContainerO === undefined ? true : _ref$handleContainerO;
 | 
						|
 | 
						|
  (0, _classCallCheck3.default)(this, ModalManager);
 | 
						|
 | 
						|
  this.add = function (modal, container) {
 | 
						|
    var modalIdx = _this.modals.indexOf(modal);
 | 
						|
    var containerIdx = _this.containers.indexOf(container);
 | 
						|
 | 
						|
    if (modalIdx !== -1) {
 | 
						|
      return modalIdx;
 | 
						|
    }
 | 
						|
 | 
						|
    modalIdx = _this.modals.length;
 | 
						|
    _this.modals.push(modal);
 | 
						|
 | 
						|
    if (_this.hideSiblingNodes) {
 | 
						|
      (0, _manageAriaHidden.hideSiblings)(container, modal.mountNode);
 | 
						|
    }
 | 
						|
 | 
						|
    if (containerIdx !== -1) {
 | 
						|
      _this.data[containerIdx].modals.push(modal);
 | 
						|
      return modalIdx;
 | 
						|
    }
 | 
						|
 | 
						|
    var data = {
 | 
						|
      modals: [modal],
 | 
						|
      overflowing: (0, _isOverflowing2.default)(container),
 | 
						|
      prevPaddings: []
 | 
						|
    };
 | 
						|
 | 
						|
    if (_this.handleContainerOverflow) {
 | 
						|
      setContainerStyle(data, container);
 | 
						|
    }
 | 
						|
 | 
						|
    _this.containers.push(container);
 | 
						|
    _this.data.push(data);
 | 
						|
 | 
						|
    return modalIdx;
 | 
						|
  };
 | 
						|
 | 
						|
  this.remove = function (modal) {
 | 
						|
    var modalIdx = _this.modals.indexOf(modal);
 | 
						|
 | 
						|
    if (modalIdx === -1) {
 | 
						|
      return modalIdx;
 | 
						|
    }
 | 
						|
 | 
						|
    var containerIdx = findContainer(_this.data, modal);
 | 
						|
    var data = _this.data[containerIdx];
 | 
						|
    var container = _this.containers[containerIdx];
 | 
						|
 | 
						|
    data.modals.splice(data.modals.indexOf(modal), 1);
 | 
						|
    _this.modals.splice(modalIdx, 1);
 | 
						|
 | 
						|
    // If that was the last modal in a container, clean up the container.
 | 
						|
    if (data.modals.length === 0) {
 | 
						|
      if (_this.handleContainerOverflow) {
 | 
						|
        removeContainerStyle(data, container);
 | 
						|
      }
 | 
						|
 | 
						|
      if (_this.hideSiblingNodes) {
 | 
						|
        (0, _manageAriaHidden.showSiblings)(container, modal.mountNode);
 | 
						|
      }
 | 
						|
      _this.containers.splice(containerIdx, 1);
 | 
						|
      _this.data.splice(containerIdx, 1);
 | 
						|
    } else if (_this.hideSiblingNodes) {
 | 
						|
      // Otherwise make sure the next top modal is visible to a SR.
 | 
						|
      (0, _manageAriaHidden.ariaHidden)(false, data.modals[data.modals.length - 1].mountNode);
 | 
						|
    }
 | 
						|
 | 
						|
    return modalIdx;
 | 
						|
  };
 | 
						|
 | 
						|
  this.isTopModal = function (modal) {
 | 
						|
    return !!_this.modals.length && _this.modals[_this.modals.length - 1] === modal;
 | 
						|
  };
 | 
						|
 | 
						|
  this.hideSiblingNodes = hideSiblingNodes;
 | 
						|
  this.handleContainerOverflow = handleContainerOverflow;
 | 
						|
  // this.modals[modalIdx] = modal
 | 
						|
  this.modals = [];
 | 
						|
  // this.containers[containerIdx] = container
 | 
						|
  this.containers = [];
 | 
						|
  // this.data[containerIdx] = {
 | 
						|
  //   modals: [],
 | 
						|
  // }
 | 
						|
  this.data = [];
 | 
						|
};
 | 
						|
 | 
						|
exports.default = ModalManager; |