"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports["default"] = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _react = _interopRequireDefault(require("react"));
var _draftJs = require("draft-js");
var _Tag = _interopRequireDefault(require("../Tag"));
var _constants = require("./constants");
var _VariableInputSt = require("./VariableInput.st.css.js");
var _index = require("../index");
var _jsxFileName = "/home/builduser/work/57e038ea7326c1ec/packages/wix-design-system/dist/cjs/VariableInput/EditorUtilities.jsx",
  _this = void 0;
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
var insertContent = function insertContent(editorState, selectionOffset, modifyFn) {
  var contentState = editorState.getCurrentContent();
  var selectionState = editorState.getSelection();
  if (!selectionState.isCollapsed()) {
    // Remove selection range when adding content
    contentState = _draftJs.Modifier.removeRange(contentState, selectionState, 'backward');
    selectionState = contentState.getSelectionAfter();
  }
  var newContent = modifyFn(contentState, selectionState);
  var newEditorState = _draftJs.EditorState.push(editorState, newContent, 'insert-characters');
  var newSelection = newEditorState.getSelection();
  return _moveSelectionTo(newEditorState, newSelection.getAnchorKey(), newSelection.getAnchorOffset() + selectionOffset);
};

/** Insert text in current cursor position */
var insertText = function insertText(editorState, text) {
  return insertContent(editorState, 0, function (contentState, selectionState) {
    return _draftJs.Modifier.insertText(contentState, selectionState, text);
  });
};

/** Insert new entity in current cursor position, with the given text and value */
var insertEntity = function insertEntity(editorState, _ref) {
  var text = _ref.text,
    value = _ref.value,
    tagProps = _ref.tagProps;
  return insertContent(editorState, 1, function (contentState, selectionState) {
    contentState = contentState.createEntity(_constants.entityTypes.variable, 'IMMUTABLE', {
      value: value,
      text: text,
      tagProps: tagProps
    });
    var entityKey = contentState.getLastCreatedEntityKey();
    contentState = _draftJs.Modifier.insertText(contentState, selectionState, ' '); // space after entity
    contentState = _draftJs.Modifier.insertText(contentState, selectionState, " ".concat(text, " "), null, entityKey);
    return contentState;
  });
};
var _escapeRegExp = function _escapeRegExp(text) {
  return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
};
/** Get variable with given prefix and suffix in the given string */
var getMatchesInString = function getMatchesInString(str, prefix, suffix) {
  var escPrefixFirstChar = _escapeRegExp(prefix[0]);
  var escPrefix = _escapeRegExp(prefix);
  var escSuffix = _escapeRegExp(suffix);
  var pattern = "(?:".concat(escPrefixFirstChar, ")*(").concat(escPrefix, "(.*?)").concat(escSuffix, ")");
  var regex = new RegExp(pattern, 'g');
  var part;
  var parts = [];
  while ((part = regex.exec(str)) !== null) {
    parts.push(part);
  }
  return parts;
};
/** Check if editor has unparsed entities */
var hasUnparsedEntity = function hasUnparsedEntity(editorState, prefix, suffix) {
  return getMatchesInString(editorState.getCurrentContent().getPlainText(), prefix, suffix).length > 0;
};
/** Convert editor content state, to string with placeholders instead of entities */
var convertToString = function convertToString(_ref2) {
  var editorState = _ref2.editorState,
    prefix = _ref2.prefix,
    suffix = _ref2.suffix;
  var rawJS = (0, _draftJs.convertToRaw)(editorState.getCurrentContent());
  var rawString = rawJS.blocks.map(function (block) {
    var baseString = Array.from(block.text);
    var indexOffset = 0;
    block.entityRanges.forEach(function (entityRange) {
      var entity = rawJS.entityMap[entityRange.key.toString()];
      if (entity.type !== _constants.entityTypes.variable) {
        return baseString;
      }
      var entityData = entity.data;
      var placeholder = prefix + entityData.value + suffix;
      baseString.splice(entityRange.offset + indexOffset, entityRange.length, placeholder);
      indexOffset += 1 - entityRange.length;
    });
    return baseString.join('');
  }).join('\n');
  return rawString;
};
/** Convert string to editor content state */
var stringToContentState = function stringToContentState(_ref3) {
  var _ref3$str = _ref3.str,
    str = _ref3$str === void 0 ? '' : _ref3$str,
    _ref3$variableParser = _ref3.variableParser,
    variableParser = _ref3$variableParser === void 0 ? function () {} : _ref3$variableParser,
    _ref3$variableTagProp = _ref3.variableTagPropsParser,
    variableTagPropsParser = _ref3$variableTagProp === void 0 ? function () {} : _ref3$variableTagProp,
    _ref3$prefix = _ref3.prefix,
    prefix = _ref3$prefix === void 0 ? '' : _ref3$prefix,
    _ref3$suffix = _ref3.suffix,
    suffix = _ref3$suffix === void 0 ? '' : _ref3$suffix;
  var entityIndex = 0;
  var entityMap = [];
  var blocks = str.split('\n').map(function (row) {
    var rowStr = row;
    var indexOffset = 0;
    var entityRanges = [];
    getMatchesInString(row, prefix, suffix).forEach(function (match) {
      var _match = (0, _slicedToArray2["default"])(match, 3),
        wholeMatch = _match[0],
        placeholder = _match[1],
        value = _match[2];
      var matchIndex = match.index + wholeMatch.indexOf(placeholder);
      var text = variableParser(value) || false;
      var tagProps = variableTagPropsParser(value);
      if (text) {
        var utfOffset = getUtfOffsetValue(row.substr(0, matchIndex));
        var contentPlaceholder = " ".concat(text, " ");
        var offset = matchIndex + indexOffset - utfOffset;
        rowStr = rowStr.replace(placeholder, contentPlaceholder);
        entityRanges.push({
          offset: offset,
          length: contentPlaceholder.length,
          key: entityIndex
        });
        entityMap[entityIndex.toString()] = {
          type: _constants.entityTypes.variable,
          mutability: 'IMMUTABLE',
          data: {
            value: value,
            text: text,
            tagProps: tagProps
          }
        };
        entityIndex++;
        indexOffset += contentPlaceholder.length - placeholder.length;
      }
    });
    return {
      key: (0, _draftJs.genKey)(),
      text: rowStr,
      type: 'unstyled',
      depth: 0,
      inlineStyleRanges: [],
      entityRanges: entityRanges,
      data: {}
    };
  });
  return (0, _draftJs.convertFromRaw)({
    blocks: blocks,
    entityMap: entityMap
  });
};
var decoratorFactory = function decoratorFactory(_ref4) {
  var _ref4$tag = _ref4.tag,
    size = _ref4$tag.size,
    disabled = _ref4$tag.disabled;
  return new _draftJs.CompositeDecorator([{
    strategy: function strategy(contentBlock, callback, contentState) {
      contentBlock.findEntityRanges(function (character) {
        var entityKey = character.getEntity();
        return entityKey !== null && contentState.getEntity(entityKey).getType() === _constants.entityTypes.variable;
      }, callback);
    },
    component: function component(props) {
      var offsetKey = props.offsetKey,
        contentState = props.contentState,
        entityKey = props.entityKey;
      var _contentState$getEnti = contentState.getEntity(entityKey).getData(),
        text = _contentState$getEnti.text,
        tagProps = _contentState$getEnti.tagProps;
      /** We adding a space before and after the Tag,
       * to prevent from the cursor to enter the Tag while moving it.  */
      return /*#__PURE__*/_react["default"].createElement("span", {
        "data-offset-key": offsetKey,
        contentEditable: false,
        className: _VariableInputSt.classes.tagWrapper,
        __self: _this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 203,
          columnNumber: 11
        }
      }, /*#__PURE__*/_react["default"].createElement("span", {
        className: _VariableInputSt.classes.textWrapper,
        __self: _this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 208,
          columnNumber: 13
        }
      }, " "), /*#__PURE__*/_react["default"].createElement(_Tag["default"], (0, _extends2["default"])({
        id: "variableinput-tag-".concat(entityKey),
        dataHook: _constants.dataHooks.tag,
        removable: false
      }, !disabled && {
        theme: 'dark'
      }, tagProps, {
        size: size,
        disabled: disabled,
        className: _VariableInputSt.classes.tag,
        __self: _this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 209,
          columnNumber: 13
        }
      }), text), /*#__PURE__*/_react["default"].createElement("span", {
        className: _VariableInputSt.classes.textWrapper,
        __self: _this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 221,
          columnNumber: 13
        }
      }), ' ');
    }
  }]);
};
/** When pushing content to EditorState selection is resets, we keep the selection and reset it after push */
var pushAndKeepSelection = function pushAndKeepSelection(_ref5) {
  var editorState = _ref5.editorState,
    content = _ref5.content;
  var selectionStateBefore = editorState.getSelection();
  var blockIndex = Object.keys(editorState.getCurrentContent().getBlockMap().toJS()).indexOf(selectionStateBefore.getAnchorKey());
  var updatedEditorState = _draftJs.EditorState.push(editorState, content);
  var blockMap = updatedEditorState.getCurrentContent().getBlockMap().toJS();
  var blockKeys = Object.keys(blockMap);
  var blockKey = blockKeys[blockIndex];
  var blockOffset = selectionStateBefore.getAnchorOffset();
  if (!blockKey || blockOffset > blockMap[blockKey].text.length) {
    // Block not exists in new array, getting the last block and move to end
    return _draftJs.EditorState.moveSelectionToEnd(updatedEditorState);
  }
  // Keep selection in the same location after updating content, keys are updating
  var selectionAfter = updatedEditorState.getSelection().merge({
    anchorKey: blockKey,
    anchorOffset: blockOffset,
    focusKey: blockKey,
    focusOffset: blockOffset,
    hasFocus: false
  });
  return _draftJs.EditorState.acceptSelection(updatedEditorState, selectionAfter);
};
/** Move selection to edge of entity */
var moveToEdge = function moveToEdge(editorState) {
  var forceEnd = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  var selectionOffset = editorState.getSelection().getFocusOffset();
  var key = editorState.getSelection().getFocusKey();
  var jumpToIndex = _findEntityEdgeIndex(editorState.getCurrentContent(), key, selectionOffset, forceEnd);
  if (jumpToIndex !== selectionOffset) {
    return _moveSelectionTo(editorState, key, jumpToIndex);
  }
  return editorState;
};
var _moveSelectionTo = function _moveSelectionTo(editorState, key, offset) {
  var selection = new _draftJs.SelectionState({
    anchorKey: key,
    anchorOffset: offset,
    focusKey: key,
    focusOffset: offset
  });
  return _draftJs.EditorState.forceSelection(editorState, selection);
};
var _findEntityEdgeIndex = function _findEntityEdgeIndex(currentContent, selectionKey, startIndex, forceEnd) {
  var characterList = currentContent.getBlockForKey(selectionKey).getCharacterList().toJS();
  var entityKey = characterList[startIndex] && characterList[startIndex].entity;
  if (!entityKey) {
    return startIndex;
  }
  var beforeOffset = startIndex;
  for (; beforeOffset >= 0; beforeOffset--) {
    if (characterList[beforeOffset].entity !== entityKey) {
      beforeOffset++;
      break;
    }
  }
  beforeOffset = Math.max(beforeOffset, 0);
  var afterOffset = characterList.findIndex(function (value, index) {
    return index >= startIndex && value.entity !== entityKey;
  });
  if (afterOffset === -1) {
    afterOffset = characterList.length;
  }
  if (!forceEnd && beforeOffset === startIndex) {
    // In case we clicked just at the beginning
    return beforeOffset;
  }
  return afterOffset;
};
/** Returns true if content has changed */
var isContentChanged = function isContentChanged(editorStateBefore, editorStateAfter) {
  return editorStateBefore.getCurrentContent().getPlainText() !== editorStateAfter.getCurrentContent().getPlainText();
};
/** Returns true if state lost focus */
var isBlured = function isBlured(editorStateBefore, editorStateAfter) {
  return editorStateBefore.getSelection().getHasFocus() && !editorStateAfter.getSelection().getHasFocus();
};
var getUtfOffsetValue = function getUtfOffsetValue(aString) {
  return aString.split('').length - Array.from(aString).length;
};
var findEntityRangeByKey = function findEntityRangeByKey(editorState, variableKey) {
  var contentState = editorState.getCurrentContent();
  var rawContent = (0, _draftJs.convertToRaw)(contentState);
  var entityMap = rawContent.entityMap,
    blocks = rawContent.blocks;
  var targetEntityKey = Object.keys(entityMap).find(function (key) {
    var entity = entityMap[key];
    return entity.type === _constants.entityTypes.variable && entity.data.value === variableKey;
  });
  if (targetEntityKey) {
    var _iterator = _createForOfIteratorHelper(blocks),
      _step;
    try {
      for (_iterator.s(); !(_step = _iterator.n()).done;) {
        var block = _step.value;
        var _iterator2 = _createForOfIteratorHelper(block.entityRanges),
          _step2;
        try {
          for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
            var range = _step2.value;
            if (range.key.toString() === targetEntityKey) {
              return {
                blockKey: block.key,
                start: range.offset,
                end: range.offset + range.length
              };
            }
          }
        } catch (err) {
          _iterator2.e(err);
        } finally {
          _iterator2.f();
        }
      }
    } catch (err) {
      _iterator.e(err);
    } finally {
      _iterator.f();
    }
  }
  return null;
};
var _default = exports["default"] = {
  insertText: insertText,
  insertEntity: insertEntity,
  getMatchesInString: getMatchesInString,
  convertToString: convertToString,
  stringToContentState: stringToContentState,
  decoratorFactory: decoratorFactory,
  pushAndKeepSelection: pushAndKeepSelection,
  hasUnparsedEntity: hasUnparsedEntity,
  moveToEdge: moveToEdge,
  isContentChanged: isContentChanged,
  isBlured: isBlured,
  findEntityRangeByKey: findEntityRangeByKey
};