"use strict";

var _typeof = require("@babel/runtime-corejs3/helpers/typeof");

var _WeakMap = require("@babel/runtime-corejs3/core-js-stable/weak-map");

var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor");

var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.contextMenu = contextMenu;

var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/createClass"));

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck"));

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/defineProperty"));

var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/concat"));

var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map"));

var _react = _interopRequireWildcard(require("react"));

var _reactDom = _interopRequireDefault(require("react-dom"));

var _classnames = _interopRequireDefault(require("classnames"));

var _commonViews = require("../../common-views");

var _utils = require("../../utils");

var _others = require("../../utils/others");

var _internals = require("../../internals");

var _styles = require("../../base/styles");

function _getRequireWildcardCache(nodeInterop) { if (typeof _WeakMap !== "function") return null; var cacheBabelInterop = new _WeakMap(); var cacheNodeInterop = new _WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && _Object$getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? _Object$getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

var stateKey = 'contextMenu';

function contextMenu() {
  var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  return function step(pipeline) {
    var popupParent = opts.popupParent || document.body;
    var menuHelper = new MenuHelper();

    var addPopup = function addPopup(menu) {
      var ePopupDiv = document.createElement('div');
      ePopupDiv.setAttribute('class', 'kd-table-popup');
      popupParent.appendChild(ePopupDiv);
      var popupHidden = false;
      var eventList = ['mousedown', 'contextmenu'];

      var hidePopup = function hidePopup(event) {
        if (isEventFromCurrentPopup(event, ePopupDiv) || popupHidden) {
          return;
        }

        popupHidden = true;
        popupParent.removeChild(ePopupDiv);
        eventList.forEach(function (eventType) {
          window.removeEventListener(eventType, hidePopup, true);
        });
      };

      _reactDom.default.render(menu, ePopupDiv, function () {
        setTimeout(function () {
          eventList.forEach(function (eventType) {
            window.addEventListener(eventType, hidePopup, true);
          });
        }, 0);
      });

      return hidePopup;
    };

    var onContextMenu = function onContextMenu(e) {
      if (suppressShowContextMenu(e)) {
        return;
      }

      e.preventDefault();
      showContextMenu(e);
    };

    pipeline.addTableProps({
      onContextMenu: onContextMenu
    });

    var getContextMenuOptions = function getContextMenuOptions(record, column, value, event) {
      var defaultMenuOptions = [];

      if (column) {
        defaultMenuOptions.push(getCopyItem(value));
      }

      if (opts.getContextMenuItems) {
        var params = {
          record: record,
          column: column,
          value: value,
          event: event
        };
        return opts.getContextMenuItems(params);
      }

      return defaultMenuOptions;
    };

    var hideContextMenu = function hideContextMenu() {
      menuHelper.destroy();
    };

    var getPopupParent = function getPopupParent() {
      return popupParent;
    };

    var showContextMenu = function showContextMenu(e) {
      var dataSource = pipeline.getDataSource();
      var cellEle = getCellEleForEvent(e);
      var code;
      var rowIndex;

      if (cellEle) {
        code = cellEle.getAttribute('data-code'), rowIndex = cellEle.getAttribute('data-rowindex');
      } else {
        var rowEle = getRowEleForEvent(e, dataSource);
        rowIndex = rowEle === null || rowEle === void 0 ? void 0 : rowEle.getAttribute('data-rowindex');
      }

      var record = dataSource[rowIndex];
      var column = code !== undefined && (0, _others.findByTree)(pipeline.getColumns(), function (item, index) {
        return item.code === code;
      });

      var value = column && record && _internals.internals.safeGetValue(column, record, rowIndex);

      var options = getContextMenuOptions(record, column, value, e);

      if (options.length === 0) {
        _utils.console.warn('context menu options is empty');

        return;
      }

      var position = positionForMenu(e, popupParent);

      var menu = /*#__PURE__*/_react.default.createElement(Menu, {
        options: options,
        hideContextMenu: hideContextMenu,
        position: position,
        getPopupParent: getPopupParent
      });

      var _hidePopup = addPopup(menu);

      menuHelper.init(_hidePopup);
    };

    return pipeline;
  };
}

function getMenuItemKey(_ref) {
  var name = _ref.name,
      index = _ref.index;

  if (name) {
    var _context;

    var _key = 0;
    name = name + '';

    for (var i = 0; i < name.length; i++) {
      _key += name.charCodeAt(name[i]);
    }

    return (0, _concat.default)(_context = "".concat(_key, "_")).call(_context, index);
  }

  return index;
}

function Menu(props) {
  var _props$options = props.options,
      options = _props$options === void 0 ? [] : _props$options,
      hideContextMenu = props.hideContextMenu,
      position = props.position,
      getPopupParent = props.getPopupParent;
  var menuRef = (0, _react.useRef)();
  (0, _react.useEffect)(function () {
    if (menuRef.current) {
      var popupParent = getPopupParent();
      var x = position.x,
          y = position.y;

      var _keepWithinBounds = keepWithinBounds(popupParent, menuRef.current, x, y),
          _x = _keepWithinBounds.x,
          _y = _keepWithinBounds.y;

      menuRef.current.style.left = _x + 'px';
      menuRef.current.style.top = _y + 'px';
    }
  }, [position]);
  return /*#__PURE__*/_react.default.createElement(_commonViews.ContextMenuStyleWrap, {
    className: _styles.MenuClasses.menu,
    ref: menuRef,
    style: {
      left: position.x,
      top: position.y
    }
  }, /*#__PURE__*/_react.default.createElement("div", {
    className: _styles.MenuClasses.menuList
  }, (0, _map.default)(options).call(options, function (item, index) {
    return /*#__PURE__*/_react.default.createElement(MenuItem, {
      key: item.key ? item.key : getMenuItemKey({
        name: item.name,
        index: index
      }),
      name: item.name,
      action: item.action,
      disabled: item.disabled,
      hideContextMenu: hideContextMenu
    });
  })));
}

function MenuItem(props) {
  var name = props.name,
      action = props.action,
      disabled = props.disabled,
      hideContextMenu = props.hideContextMenu;
  var itemRef = (0, _react.useRef)();

  var handleClick = function handleClick() {
    if (disabled) {
      return;
    }

    hideContextMenu();
    typeof action === 'function' && action();
  };

  var handleMouseEnter = function handleMouseEnter(e) {
    if (disabled) {
      return;
    }

    var itemDom = itemRef.current;

    if (itemDom) {
      itemDom.classList.add(_styles.MenuClasses.menuOptionActive);
    }
  };

  var handleMouseLeave = function handleMouseLeave(e) {
    if (disabled) {
      return;
    }

    var itemDom = itemRef.current;

    if (itemDom) {
      setTimeout(function () {
        itemDom.classList.remove(_styles.MenuClasses.menuOptionActive);
      }, 10);
    }
  };

  return /*#__PURE__*/_react.default.createElement("div", {
    className: (0, _classnames.default)(_styles.MenuClasses.menuOption, (0, _defineProperty2.default)({}, _styles.MenuClasses.menuOptionDisable, disabled)),
    ref: itemRef,
    onClick: handleClick,
    onMouseEnter: handleMouseEnter,
    onMouseLeave: handleMouseLeave
  }, /*#__PURE__*/_react.default.createElement("span", {
    className: _styles.MenuClasses.menuOptionText
  }, name));
}

var MenuHelper = /*#__PURE__*/(0, _createClass2.default)(function MenuHelper() {
  var _this = this;

  (0, _classCallCheck2.default)(this, MenuHelper);

  this.init = function (hidePopup) {
    _this.hidePopup = hidePopup;
  };

  this.destroy = function () {
    _this.hidePopup && _this.hidePopup();
    _this.hidePopup = null;
  };
});
/** 是否点击是外部 start */

function isEventFromCurrentPopup(event, ele) {
  if (!event || !ele) {
    return false;
  }

  if ((0, _utils.isElementInEventPath)(ele, event)) {
    return true;
  }

  return false;
}

function getCellEleInEventPath(path) {
  return (0, _utils.getTargetEleInEventPath)(path, function (ele) {
    return ele && ele.getAttribute('data-role') === 'table-cell';
  });
}

function getRowEleInEventPath(path) {
  return (0, _utils.getTargetEleInEventPath)(path, function (ele) {
    return ele && ele.getAttribute('data-role') === 'table-row';
  });
}
/** 是否点击是外部 end */

/** 计算位置 start */


function calculatePointerRelative(event, popupParent) {
  var parentRect = popupParent.getBoundingClientRect();
  var documentRect = document.documentElement.getBoundingClientRect();
  return {
    x: event.clientX - (popupParent === document.body ? documentRect.left : parentRect.left),
    y: event.clientY - (popupParent === document.body ? documentRect.top : parentRect.top)
  };
}

function positionForMenu(event, popupParent, params) {
  var _calculatePointerRela = calculatePointerRelative(event, popupParent),
      x = _calculatePointerRela.x,
      y = _calculatePointerRela.y;

  if (params) {
    var offsetX = params.offsetX,
        offsetY = params.offsetY;

    if (offsetX) {
      x -= offsetX;
    }

    if (offsetY) {
      y -= offsetY;
    }
  }

  return {
    x: x,
    y: y
  };
}

function keepWithinBounds(popupParent, ePopup, x, y) {
  var parentRect = popupParent.getBoundingClientRect();
  var docElement = document.documentElement;
  var documentRect = docElement.getBoundingClientRect();
  var ePopupRect = ePopup.getBoundingClientRect();
  var parentWidth = parentRect.width;
  var parentHeight = parentRect.height;

  if (popupParent === document.body) {
    parentWidth = documentRect.width;
    parentWidth -= Math.abs(documentRect.left - parentRect.left);
    parentHeight = documentRect.height + docElement.scrollTop;
    parentHeight -= Math.abs(documentRect.top - parentRect.top);
  }

  if (x) {
    var minWidth = Math.min(ePopupRect.width, 120);
    ePopup.style.minWidth = minWidth + 'px';
    var maxX = parentWidth - minWidth;
    x = Math.min(Math.max(x, 0), Math.abs(maxX)); // 目前位置，最大支持的位置
  }

  if (y) {
    var minHeight = Math.min(ePopupRect.height, 180);
    var maxY = parentHeight - minHeight;
    y = Math.min(Math.max(y, 0), Math.abs(maxY)); // 目前位置，最大支持的位置
  }

  return {
    x: x,
    y: y
  };
}
/** 计算位置 end */

/** 获得点击的元素 start */


function getCellEleForEvent(event) {
  return getCellEleInEventPath((0, _utils.getEventPath)(event));
}

function getRowEleForEvent(event, dataSource) {
  return getRowEleInEventPath((0, _utils.getEventPath)(event));
}
/** 获得点击的元素 end */
// 禁止弹出右键菜单


function suppressShowContextMenu(e) {
  var path = (0, _utils.getEventPath)(e.nativeEvent);
  var pointIndex = 0;

  while (pointIndex < path.length) {
    var ele = path[pointIndex];

    if (ele.classList.contains(_styles.Classes.tableBody) || ele.classList.contains(_styles.Classes.tableFooter)) {
      return false;
    }

    pointIndex++;
  }

  return true;
} // 默认选项


function getCopyItem(v) {
  return {
    name: '复制',
    action: function action() {
      (0, _utils.executeOnTempElement)((0, _utils.copyDataToClipboard)(v));
    }
  };
}