/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format * * @emails oncall+draft_js */ 'use strict'; var ContentBlockNode = require("./ContentBlockNode"); var generateRandomKey = require("./generateRandomKey"); var Immutable = require("immutable"); var invariant = require("fbjs/lib/invariant"); var modifyBlockForContentState = require("./modifyBlockForContentState"); var List = Immutable.List, Map = Immutable.Map; var transformBlock = function transformBlock(key, blockMap, func) { if (!key) { return; } var block = blockMap.get(key); if (!block) { return; } blockMap.set(key, func(block)); }; var updateBlockMapLinks = function updateBlockMapLinks(blockMap, originalBlock, belowBlock) { return blockMap.withMutations(function (blocks) { var originalBlockKey = originalBlock.getKey(); var belowBlockKey = belowBlock.getKey(); // update block parent transformBlock(originalBlock.getParentKey(), blocks, function (block) { var parentChildrenList = block.getChildKeys(); var insertionIndex = parentChildrenList.indexOf(originalBlockKey) + 1; var newChildrenArray = parentChildrenList.toArray(); newChildrenArray.splice(insertionIndex, 0, belowBlockKey); return block.merge({ children: List(newChildrenArray) }); }); // update original next block transformBlock(originalBlock.getNextSiblingKey(), blocks, function (block) { return block.merge({ prevSibling: belowBlockKey }); }); // update original block transformBlock(originalBlockKey, blocks, function (block) { return block.merge({ nextSibling: belowBlockKey }); }); // update below block transformBlock(belowBlockKey, blocks, function (block) { return block.merge({ prevSibling: originalBlockKey }); }); }); }; var splitBlockInContentState = function splitBlockInContentState(contentState, selectionState) { !selectionState.isCollapsed() ? process.env.NODE_ENV !== "production" ? invariant(false, 'Selection range must be collapsed.') : invariant(false) : void 0; var key = selectionState.getAnchorKey(); var blockMap = contentState.getBlockMap(); var blockToSplit = blockMap.get(key); var text = blockToSplit.getText(); if (!text) { var blockType = blockToSplit.getType(); if (blockType === 'unordered-list-item' || blockType === 'ordered-list-item') { return modifyBlockForContentState(contentState, selectionState, function (block) { return block.merge({ type: 'unstyled', depth: 0 }); }); } } var offset = selectionState.getAnchorOffset(); var chars = blockToSplit.getCharacterList(); var keyBelow = generateRandomKey(); var isExperimentalTreeBlock = blockToSplit instanceof ContentBlockNode; var blockAbove = blockToSplit.merge({ text: text.slice(0, offset), characterList: chars.slice(0, offset) }); var blockBelow = blockAbove.merge({ key: keyBelow, text: text.slice(offset), characterList: chars.slice(offset), data: Map() }); var blocksBefore = blockMap.toSeq().takeUntil(function (v) { return v === blockToSplit; }); var blocksAfter = blockMap.toSeq().skipUntil(function (v) { return v === blockToSplit; }).rest(); var newBlocks = blocksBefore.concat([[key, blockAbove], [keyBelow, blockBelow]], blocksAfter).toOrderedMap(); if (isExperimentalTreeBlock) { !blockToSplit.getChildKeys().isEmpty() ? process.env.NODE_ENV !== "production" ? invariant(false, 'ContentBlockNode must not have children') : invariant(false) : void 0; newBlocks = updateBlockMapLinks(newBlocks, blockAbove, blockBelow); } return contentState.merge({ blockMap: newBlocks, selectionBefore: selectionState, selectionAfter: selectionState.merge({ anchorKey: keyBelow, anchorOffset: 0, focusKey: keyBelow, focusOffset: 0, isBackward: false }) }); }; module.exports = splitBlockInContentState;