UNPKG

wix-style-react

Version:
368 lines (300 loc) • 12.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: 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"); 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; return insertContent(editorState, 1, function (contentState, selectionState) { contentState = contentState.createEntity(_constants.entityTypes.variable, 'IMMUTABLE', { value: value, text: text }); 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$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; 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 } }; 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) { contentBlock.findEntityRanges(function (character) { var entityKey = character.getEntity(); return entityKey === null; }, callback); }, component: function component(_ref5) { var offsetKey = _ref5.offsetKey, children = _ref5.children; return /*#__PURE__*/_react["default"].createElement("span", { "data-offset-key": offsetKey, className: _VariableInputSt.classes.textWrapper }, children); } }, { 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; /** 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 }, /*#__PURE__*/_react["default"].createElement("span", { className: _VariableInputSt.classes.textWrapper }, " "), /*#__PURE__*/_react["default"].createElement(_Tag["default"], (0, _extends2["default"])({ id: "variableinput-tag-".concat(entityKey), dataHook: _constants.dataHooks.tag, removable: false, size: size, disabled: disabled }, !disabled && { theme: 'dark' }), text), /*#__PURE__*/_react["default"].createElement("span", { className: _VariableInputSt.classes.textWrapper }), ' '); } }]); }; /** When pushing content to EditorState selection is resets, we keep the selection and reset it after push */ var pushAndKeepSelection = function pushAndKeepSelection(_ref6) { var editorState = _ref6.editorState, content = _ref6.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 _default = { insertText: insertText, insertEntity: insertEntity, getMatchesInString: getMatchesInString, convertToString: convertToString, stringToContentState: stringToContentState, decoratorFactory: decoratorFactory, pushAndKeepSelection: pushAndKeepSelection, hasUnparsedEntity: hasUnparsedEntity, moveToEdge: moveToEdge, isContentChanged: isContentChanged, isBlured: isBlured }; exports["default"] = _default;