"use strict";

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard")["default"];

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));

var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));

var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));

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

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

function cuttable(node) {
  var type = (0, _typeof2["default"])(node);
  return type === 'string' || type === 'number';
}

function getNodesLen(nodeList) {
  var totalLen = 0;
  nodeList.forEach(function (node) {
    if (cuttable(node)) {
      totalLen += String(node).length;
    } else {
      totalLen += 1;
    }
  });
  return totalLen;
}

function sliceNodes(nodeList, len) {
  var currLen = 0;
  var currentNodeList = [];

  for (var i = 0; i < nodeList.length; i += 1) {
    // 匹配返回
    if (currLen === len) {
      return currentNodeList;
    }

    var node = nodeList[i];
    var canCut = cuttable(node);
    var nodeLen = canCut ? String(node).length : 1;
    var nextLen = currLen + nodeLen; // 超过但不是当前的长度，需要削减

    if (nextLen > len) {
      var restLen = len - currLen;
      currentNodeList.push(String(node).slice(0, restLen));
      return currentNodeList;
    }

    currentNodeList.push(node);
    currLen = nextLen;
  }

  return nodeList;
}

var NONE = 0;
var PREPARE = 1;
var WALKING = 2;
var DONE_WITH_ELLIPSIS = 3;
var DONE_WITHOUT_ELLIPSIS = 4;

var Ellipsis = function Ellipsis(_ref) {
  var enabledMeasure = _ref.enabledMeasure,
      children = _ref.children,
      text = _ref.text,
      width = _ref.width,
      rows = _ref.rows,
      onEllipsis = _ref.onEllipsis;

  var _useState = (0, _react.useState)([0, 0, 0]),
      _useState2 = (0, _slicedToArray2["default"])(_useState, 2),
      cutLength = _useState2[0],
      setCutLength = _useState2[1];

  var _useState3 = (0, _react.useState)(NONE),
      _useState4 = (0, _slicedToArray2["default"])(_useState3, 2),
      walkingState = _useState4[0],
      setWalkingState = _useState4[1];

  var _cutLength = (0, _slicedToArray2["default"])(cutLength, 3),
      startLen = _cutLength[0],
      midLen = _cutLength[1],
      endLen = _cutLength[2];

  var _useState5 = (0, _react.useState)(0),
      _useState6 = (0, _slicedToArray2["default"])(_useState5, 2),
      singleRowHeight = _useState6[0],
      setSingleRowHeight = _useState6[1];

  var singleRowRef = (0, _react.useRef)(null);
  var midRowRef = (0, _react.useRef)(null);
  var nodeList = (0, _react.useMemo)(function () {
    return (0, _utils.toArray)(text);
  }, [text]);
  var totalLen = (0, _react.useMemo)(function () {
    return getNodesLen(nodeList);
  }, [nodeList]);
  var mergedChildren = (0, _react.useMemo)(function () {
    if (!enabledMeasure || walkingState !== DONE_WITH_ELLIPSIS) {
      return children(nodeList, false);
    }

    return children(sliceNodes(nodeList, midLen), midLen < totalLen);
  }, [enabledMeasure, walkingState, children, nodeList, midLen, totalLen]); // ======================== Walk ========================

  (0, _react.useLayoutEffect)(function () {
    if (enabledMeasure && width && totalLen) {
      setWalkingState(PREPARE);
      setCutLength([0, Math.ceil(totalLen / 2), totalLen]);
    }
  }, [enabledMeasure, width, text, totalLen, rows]);
  (0, _react.useLayoutEffect)(function () {
    if (walkingState === PREPARE) {
      var _singleRowRef$current;

      setSingleRowHeight(((_singleRowRef$current = singleRowRef.current) === null || _singleRowRef$current === void 0 ? void 0 : _singleRowRef$current.offsetHeight) || 0);
    }
  }, [walkingState]);
  (0, _react.useLayoutEffect)(function () {
    if (singleRowHeight) {
      if (walkingState === PREPARE) {
        var _midRowRef$current;

        // 忽略位置是否足够
        var midHeight = ((_midRowRef$current = midRowRef.current) === null || _midRowRef$current === void 0 ? void 0 : _midRowRef$current.offsetHeight) || 0;
        var maxHeight = rows * singleRowHeight;

        if (midHeight <= maxHeight) {
          setWalkingState(DONE_WITHOUT_ELLIPSIS);
          onEllipsis(false);
        } else {
          setWalkingState(WALKING);
        }
      } else if (walkingState === WALKING) {
        if (startLen !== endLen) {
          var _midRowRef$current2;

          var _midHeight = ((_midRowRef$current2 = midRowRef.current) === null || _midRowRef$current2 === void 0 ? void 0 : _midRowRef$current2.offsetHeight) || 0;

          var _maxHeight = rows * singleRowHeight;

          var nextStartLen = startLen;
          var nextEndLen = endLen; // 当等于最后的时候

          if (startLen === endLen - 1) {
            nextEndLen = startLen;
          } else if (_midHeight <= _maxHeight) {
            nextStartLen = midLen;
          } else {
            nextEndLen = midLen;
          }

          var nextMidLen = Math.ceil((nextStartLen + nextEndLen) / 2);
          setCutLength([nextStartLen, nextMidLen, nextEndLen]);
        } else {
          setWalkingState(DONE_WITH_ELLIPSIS);
          onEllipsis(true);
        }
      }
    }
  }, [walkingState, startLen, endLen, rows, singleRowHeight]); // ======================= Render =======================

  var measureStyle = {
    width: width,
    whiteSpace: 'normal',
    margin: 0,
    padding: 0
  };

  var renderMeasure = function renderMeasure(content, ref, style) {
    return /*#__PURE__*/_react["default"].createElement("span", {
      "aria-hidden": true,
      ref: ref,
      style: (0, _objectSpread2["default"])({
        position: 'fixed',
        display: 'block',
        left: 0,
        top: 0,
        zIndex: -9999,
        visibility: 'hidden',
        pointerEvents: 'none'
      }, style)
    }, content);
  };

  var renderMeasureSlice = function renderMeasureSlice(len, ref) {
    var sliceNodeList = sliceNodes(nodeList, len);
    return renderMeasure(children(sliceNodeList, true), ref, measureStyle);
  };

  return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, mergedChildren, enabledMeasure && walkingState !== DONE_WITH_ELLIPSIS && walkingState !== DONE_WITHOUT_ELLIPSIS && /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, renderMeasure('lg', singleRowRef, {
    wordBreak: 'keep-all',
    whiteSpace: 'nowrap'
  }), walkingState === PREPARE ? renderMeasure(children(nodeList, false), midRowRef, measureStyle) : renderMeasureSlice(midLen, midRowRef)));
};

Ellipsis.displayName = 'Ellipsis';
var _default = Ellipsis;
exports["default"] = _default;
//# sourceMappingURL=Ellipsis.js.map
