wix-style-react
Version:
wix-style-react
203 lines (188 loc) • 7.64 kB
JavaScript
"use strict";
exports.__esModule = true;
exports.default = void 0;
var _draftJs = require("draft-js");
var _draftJsExportHtml = require("draft-js-export-html");
var _UrlUtils = require("../utils/UrlUtils");
var _RichTextInputAreaTypes = require("./RichTextInputAreaTypes");
/** Returns whether the specified style is applied on a block */
var hasStyle = (editorState, style) => {
var currentStyle = editorState.getCurrentInlineStyle();
return currentStyle.has(style);
};
/** Returns whether a block with the specified type exists */
var hasBlockType = (editorState, blockType) => {
var selection = editorState.getSelection();
var currentBlockType = editorState.getCurrentContent().getBlockForKey(selection.getStartKey()).getType();
return currentBlockType === blockType;
};
/** Returns whether the specified entity is applied on a block */
var hasEntity = (editorState, entity) => {
var selection = editorState.getSelection();
var contentState = editorState.getCurrentContent();
var currentKey = contentState.getBlockForKey(selection.getStartKey()).getEntityAt(selection.getStartOffset());
if (currentKey) {
var currentEntity = contentState.getEntity(currentKey);
return currentEntity.type === entity;
}
return false;
};
/** Returns whether the block of the selected text is linked to an entity */
var hasRemovableEntityInSelection = editorState => {
if (_hasSelectedText(editorState)) {
var {
contentBlock,
startOffset
} = _getSelectedBlock(editorState);
// Finds the entity that's related to the selected text
var entity = contentBlock.getEntityAt(startOffset);
if (entity) {
return true;
}
}
return false;
};
/** Returns an EditorState with the rendered selection.
* Mainly useful in order to maintain the selection after creating new state */
var keepCurrentSelection = editorState => _draftJs.EditorState.forceSelection(editorState, editorState.getSelection());
/** Returns an EditorState so that the specified style is toggled on the selection */
var toggleStyle = (editorState, toggledStyle) => {
return _draftJs.RichUtils.toggleInlineStyle(keepCurrentSelection(editorState), toggledStyle);
};
/** Returns an EditorState so that the specified block type is toggled on the selection */
var toggleBlockType = (editorState, toggledBlockType) => {
return _draftJs.RichUtils.toggleBlockType(keepCurrentSelection(editorState), toggledBlockType);
};
var toggleLink = (editorState, linkData) => {
if (hasRemovableEntityInSelection(editorState)) {
var {
contentBlock,
startOffset
} = _getSelectedBlock(editorState);
var entity = contentBlock.getEntityAt(startOffset);
return _removeEntityFromBlock(editorState, contentBlock, entity);
}
return _attachLinkEntityToText(editorState, linkData);
};
var getSelectedText = editorState => {
var {
contentBlock,
startOffset,
endOffset
} = _getSelectedBlock(editorState);
return contentBlock.getText().slice(startOffset, endOffset);
};
var findLinkEntities = (contentBlock, callback, contentState) => {
contentBlock.findEntityRanges(character => {
var entityKey = character.getEntity();
return entityKey !== null && contentState.getEntity(entityKey).getType() === _RichTextInputAreaTypes.entityTypes.link;
}, callback);
};
var convertToHtml = editorState => {
var markupConfig = {
inlineStyles: {
ITALIC: {
element: 'em'
}
},
entityStyleFn: entity => {
var entityType = entity.get('type').toLowerCase();
if (entityType === 'link') {
var {
url
} = entity.getData();
return {
element: 'a',
attributes: {
rel: 'noopener noreferrer',
target: '_blank',
href: (0, _UrlUtils.prependHTTP)(url)
}
};
}
}
};
var html = (0, _draftJsExportHtml.stateToHTML)(editorState.getCurrentContent(), markupConfig);
// Getting rid of unexceptional extra empty line-breaks manually until it would be adopted and supported by `stateToHTML`:
// http://github.com/sstur/draft-js-utils/pull/84
return html.replace(/<p><br>/g, '<p>');
};
var isEditorFocused = editorState => editorState.getSelection().getHasFocus();
/** Returns true in case the editor's content does not contain any block which has a non-default type or text.
It means that if the user changes the block type before entering any text, the content will be considered as non-empty.
*/
var isEditorEmpty = editorState => !editorState.getCurrentContent().hasText() && editorState.getCurrentContent().getBlockMap().first().getType() === _RichTextInputAreaTypes.blockTypes.unstyled;
// Returns whether a text is selected
var _hasSelectedText = editorState => !editorState.getSelection().isCollapsed();
var _getSelectedBlock = editorState => {
var selection = editorState.getSelection();
var currentContent = editorState.getCurrentContent();
// Resolves the current block of the selection
var anchorKey = selection.getAnchorKey();
var currentBlock = currentContent.getBlockForKey(anchorKey);
// Resolves the current block with extra information
return {
contentBlock: currentBlock,
startOffset: selection.getStartOffset(),
endOffset: selection.getEndOffset(),
startKey: selection.getStartKey(),
endKey: selection.getEndKey()
};
};
var _attachLinkEntityToText = (editorState, _ref) => {
var {
text,
url
} = _ref;
var contentState = editorState.getCurrentContent();
var selectionState = editorState.getSelection();
var contentStateWithEntity = contentState.createEntity('LINK', 'MUTABLE', {
url
});
var entityKey = contentStateWithEntity.getLastCreatedEntityKey();
var startPosition = selectionState.getStartOffset();
var endPosition = startPosition + text.length;
// A key for the block that containing the start of the selection range
var blockKey = selectionState.getStartKey();
// Replaces the content in specified selection range with text
var contentStateWithText = _draftJs.Modifier.replaceText(contentState, selectionState, text);
var newSelectionState = new _draftJs.SelectionState({
anchorOffset: startPosition,
anchorKey: blockKey,
focusOffset: endPosition,
focusKey: blockKey
});
var newEditorState = _draftJs.EditorState.push(editorState, contentStateWithText, 'insert-characters');
return _draftJs.RichUtils.toggleLink(newEditorState, newSelectionState, entityKey);
};
var _removeEntityFromBlock = (editorState, contentBlock, entity) => {
var contentState = editorState.getCurrentContent();
var selectionState = editorState.getSelection();
var selectionWithEntity = null;
contentBlock.findEntityRanges(character => character.getEntity() === entity, (start, end) => {
// Creates a selection state that contains the whole text that's linked to the entity
selectionWithEntity = selectionState.merge({
anchorOffset: start,
focusOffset: end
});
});
// Removes the linking between the text and entity
var contentStateWithoutEntity = _draftJs.Modifier.applyEntity(contentState, selectionWithEntity, null);
var newEditorState = _draftJs.EditorState.push(editorState, contentStateWithoutEntity, 'apply-entity');
return _draftJs.RichUtils.toggleLink(newEditorState, selectionState, null);
};
var _default = exports.default = {
hasStyle,
hasBlockType,
hasEntity,
hasRemovableEntityInSelection,
toggleStyle,
toggleBlockType,
toggleLink,
getSelectedText,
findLinkEntities,
convertToHtml,
isEditorFocused,
isEditorEmpty
};
//# sourceMappingURL=EditorUtilities.js.map