scripts/core/editor3/helpers/insertAtomicBlockWithoutEmptyLines.ts
import {
BlockMapBuilder,
CharacterMetadata,
ContentBlock,
ContentState,
Modifier,
EditorState,
genKey,
} from 'draft-js';
import {getAllCustomDataFromEditor, setAllCustomDataForEditor__deprecated} from './editor3CustomData';
import Immutable from 'immutable';
var List = Immutable.List,
Repeat = Immutable.Repeat;
function getInsertionTarget(contentState, selectionState) {
var afterRemoval = Modifier.removeRange(contentState, selectionState, 'backward');
var targetSelection = afterRemoval.getSelectionAfter();
var afterSplit = Modifier.splitBlock(afterRemoval, targetSelection);
// return unsplit content if after the splitting first line is empty
if (afterSplit.getBlockForKey(afterSplit.getSelectionBefore().getAnchorKey()).getText().length < 1) {
return {
contentState: afterRemoval,
selectionState: targetSelection,
};
}
var insertionTarget = afterSplit.getSelectionAfter();
return {
contentState: afterSplit,
selectionState: insertionTarget,
};
}
function insertAtomicBlockWithoutEmptyLines(
editorState: EditorState,
entityKey: string,
character: string,
): { editorState: EditorState, blockKey: string } {
var selectionState = editorState.getSelection();
var target = getInsertionTarget(editorState.getCurrentContent(), selectionState);
var asAtomicBlock = Modifier.setBlockType(target.contentState, target.selectionState, 'atomic');
var charData = CharacterMetadata.create({entity: entityKey});
var fragmentArray = [];
if (asAtomicBlock.getFirstBlock().getKey() === target.selectionState.getAnchorKey()) {
fragmentArray.push(new ContentBlock({
key: genKey(),
type: 'unstyled',
text: '',
characterList: List(),
}));
}
fragmentArray.push(new ContentBlock({
key: genKey(),
type: 'atomic',
text: character,
characterList: List(Repeat(charData, character.length)),
}));
if (
// check if atomic is the last block in the editor
asAtomicBlock.getLastBlock().getKey() === target.selectionState.getAnchorKey()
||
// check if cursor is not at the end of the block
target.selectionState.getFocusOffset()
!== target.contentState.getBlockForKey(target.selectionState.getFocusKey()).getText().length
) {
fragmentArray.push(new ContentBlock({
key: genKey(),
type: 'unstyled',
text: '',
characterList: List(),
}));
}
var fragment = BlockMapBuilder.createFromArray(fragmentArray);
const customData = getAllCustomDataFromEditor(editorState);
var withAtomicBlock = Modifier.replaceWithFragment(asAtomicBlock, target.selectionState, fragment);
var newContent: ContentState = withAtomicBlock.merge({
selectionBefore: selectionState,
selectionAfter: withAtomicBlock.getSelectionAfter().set('hasFocus', true),
}) as ContentState;
const {block: blockKeyForEntity} = newContent.getBlocksAsArray()
.map((b) => ({entity: b.getEntityAt(0), block: b.getKey()}))
.find((b) => b.entity === entityKey);
let newEditorState = EditorState.push(editorState, newContent, 'insert-fragment');
// for the first block recover the initial block data because on replaceWithFragment the block data is
// replaced with the data from pasted fragment
newEditorState = setAllCustomDataForEditor__deprecated(newEditorState, customData);
newEditorState = EditorState.push(editorState, newEditorState.getCurrentContent(), 'insert-fragment');
return {
editorState: newEditorState,
blockKey: blockKeyForEntity,
};
}
export default insertAtomicBlockWithoutEmptyLines;