Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

3 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /**
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * @format
  8. * @flow
  9. * @emails oncall+draft_js
  10. */
  11. 'use strict';
  12. import type { BlockMap } from "./BlockMap";
  13. import type ContentState from "./ContentState";
  14. import type SelectionState from "./SelectionState";
  15. const ContentBlockNode = require("./ContentBlockNode");
  16. const generateRandomKey = require("./generateRandomKey");
  17. const Immutable = require("immutable");
  18. const invariant = require("fbjs/lib/invariant");
  19. const modifyBlockForContentState = require("./modifyBlockForContentState");
  20. const {
  21. List,
  22. Map
  23. } = Immutable;
  24. const transformBlock = (key: ?string, blockMap: BlockMap, func: (block: ContentBlockNode) => ContentBlockNode): void => {
  25. if (!key) {
  26. return;
  27. }
  28. const block = blockMap.get(key);
  29. if (!block) {
  30. return;
  31. }
  32. blockMap.set(key, func(block));
  33. };
  34. const updateBlockMapLinks = (blockMap: BlockMap, originalBlock: ContentBlockNode, belowBlock: ContentBlockNode): BlockMap => {
  35. return blockMap.withMutations(blocks => {
  36. const originalBlockKey = originalBlock.getKey();
  37. const belowBlockKey = belowBlock.getKey(); // update block parent
  38. transformBlock(originalBlock.getParentKey(), blocks, block => {
  39. const parentChildrenList = block.getChildKeys();
  40. const insertionIndex = parentChildrenList.indexOf(originalBlockKey) + 1;
  41. const newChildrenArray = parentChildrenList.toArray();
  42. newChildrenArray.splice(insertionIndex, 0, belowBlockKey);
  43. return block.merge({
  44. children: List(newChildrenArray)
  45. });
  46. }); // update original next block
  47. transformBlock(originalBlock.getNextSiblingKey(), blocks, block => block.merge({
  48. prevSibling: belowBlockKey
  49. })); // update original block
  50. transformBlock(originalBlockKey, blocks, block => block.merge({
  51. nextSibling: belowBlockKey
  52. })); // update below block
  53. transformBlock(belowBlockKey, blocks, block => block.merge({
  54. prevSibling: originalBlockKey
  55. }));
  56. });
  57. };
  58. const splitBlockInContentState = (contentState: ContentState, selectionState: SelectionState): ContentState => {
  59. invariant(selectionState.isCollapsed(), 'Selection range must be collapsed.');
  60. const key = selectionState.getAnchorKey();
  61. const blockMap = contentState.getBlockMap();
  62. const blockToSplit = blockMap.get(key);
  63. const text = blockToSplit.getText();
  64. if (!text) {
  65. const blockType = blockToSplit.getType();
  66. if (blockType === 'unordered-list-item' || blockType === 'ordered-list-item') {
  67. return modifyBlockForContentState(contentState, selectionState, block => block.merge({
  68. type: 'unstyled',
  69. depth: 0
  70. }));
  71. }
  72. }
  73. const offset = selectionState.getAnchorOffset();
  74. const chars = blockToSplit.getCharacterList();
  75. const keyBelow = generateRandomKey();
  76. const isExperimentalTreeBlock = blockToSplit instanceof ContentBlockNode;
  77. const blockAbove = blockToSplit.merge({
  78. text: text.slice(0, offset),
  79. characterList: chars.slice(0, offset)
  80. });
  81. const blockBelow = blockAbove.merge({
  82. key: keyBelow,
  83. text: text.slice(offset),
  84. characterList: chars.slice(offset),
  85. data: Map()
  86. });
  87. const blocksBefore = blockMap.toSeq().takeUntil(v => v === blockToSplit);
  88. const blocksAfter = blockMap.toSeq().skipUntil(v => v === blockToSplit).rest();
  89. let newBlocks = blocksBefore.concat([[key, blockAbove], [keyBelow, blockBelow]], blocksAfter).toOrderedMap();
  90. if (isExperimentalTreeBlock) {
  91. invariant(blockToSplit.getChildKeys().isEmpty(), 'ContentBlockNode must not have children');
  92. newBlocks = updateBlockMapLinks(newBlocks, blockAbove, blockBelow);
  93. }
  94. return contentState.merge({
  95. blockMap: newBlocks,
  96. selectionBefore: selectionState,
  97. selectionAfter: selectionState.merge({
  98. anchorKey: keyBelow,
  99. anchorOffset: 0,
  100. focusKey: keyBelow,
  101. focusOffset: 0,
  102. isBackward: false
  103. })
  104. });
  105. };
  106. module.exports = splitBlockInContentState;