Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

moveBlockInContentState.js 6.7 KiB

3 år sedan
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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. *
  9. * @emails oncall+draft_js
  10. */
  11. 'use strict';
  12. var ContentBlockNode = require("./ContentBlockNode");
  13. var getNextDelimiterBlockKey = require("./getNextDelimiterBlockKey");
  14. var Immutable = require("immutable");
  15. var invariant = require("fbjs/lib/invariant");
  16. var OrderedMap = Immutable.OrderedMap,
  17. List = Immutable.List;
  18. var transformBlock = function transformBlock(key, blockMap, func) {
  19. if (!key) {
  20. return;
  21. }
  22. var block = blockMap.get(key);
  23. if (!block) {
  24. return;
  25. }
  26. blockMap.set(key, func(block));
  27. };
  28. var updateBlockMapLinks = function updateBlockMapLinks(blockMap, originalBlockToBeMoved, originalTargetBlock, insertionMode, isExperimentalTreeBlock) {
  29. if (!isExperimentalTreeBlock) {
  30. return blockMap;
  31. } // possible values of 'insertionMode' are: 'after', 'before'
  32. var isInsertedAfterTarget = insertionMode === 'after';
  33. var originalBlockKey = originalBlockToBeMoved.getKey();
  34. var originalTargetKey = originalTargetBlock.getKey();
  35. var originalParentKey = originalBlockToBeMoved.getParentKey();
  36. var originalNextSiblingKey = originalBlockToBeMoved.getNextSiblingKey();
  37. var originalPrevSiblingKey = originalBlockToBeMoved.getPrevSiblingKey();
  38. var newParentKey = originalTargetBlock.getParentKey();
  39. var newNextSiblingKey = isInsertedAfterTarget ? originalTargetBlock.getNextSiblingKey() : originalTargetKey;
  40. var newPrevSiblingKey = isInsertedAfterTarget ? originalTargetKey : originalTargetBlock.getPrevSiblingKey();
  41. return blockMap.withMutations(function (blocks) {
  42. // update old parent
  43. transformBlock(originalParentKey, blocks, function (block) {
  44. var parentChildrenList = block.getChildKeys();
  45. return block.merge({
  46. children: parentChildrenList["delete"](parentChildrenList.indexOf(originalBlockKey))
  47. });
  48. }); // update old prev
  49. transformBlock(originalPrevSiblingKey, blocks, function (block) {
  50. return block.merge({
  51. nextSibling: originalNextSiblingKey
  52. });
  53. }); // update old next
  54. transformBlock(originalNextSiblingKey, blocks, function (block) {
  55. return block.merge({
  56. prevSibling: originalPrevSiblingKey
  57. });
  58. }); // update new next
  59. transformBlock(newNextSiblingKey, blocks, function (block) {
  60. return block.merge({
  61. prevSibling: originalBlockKey
  62. });
  63. }); // update new prev
  64. transformBlock(newPrevSiblingKey, blocks, function (block) {
  65. return block.merge({
  66. nextSibling: originalBlockKey
  67. });
  68. }); // update new parent
  69. transformBlock(newParentKey, blocks, function (block) {
  70. var newParentChildrenList = block.getChildKeys();
  71. var targetBlockIndex = newParentChildrenList.indexOf(originalTargetKey);
  72. var insertionIndex = isInsertedAfterTarget ? targetBlockIndex + 1 : targetBlockIndex !== 0 ? targetBlockIndex - 1 : 0;
  73. var newChildrenArray = newParentChildrenList.toArray();
  74. newChildrenArray.splice(insertionIndex, 0, originalBlockKey);
  75. return block.merge({
  76. children: List(newChildrenArray)
  77. });
  78. }); // update block
  79. transformBlock(originalBlockKey, blocks, function (block) {
  80. return block.merge({
  81. nextSibling: newNextSiblingKey,
  82. prevSibling: newPrevSiblingKey,
  83. parent: newParentKey
  84. });
  85. });
  86. });
  87. };
  88. var moveBlockInContentState = function moveBlockInContentState(contentState, blockToBeMoved, targetBlock, insertionMode) {
  89. !(insertionMode !== 'replace') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Replacing blocks is not supported.') : invariant(false) : void 0;
  90. var targetKey = targetBlock.getKey();
  91. var blockKey = blockToBeMoved.getKey();
  92. !(blockKey !== targetKey) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Block cannot be moved next to itself.') : invariant(false) : void 0;
  93. var blockMap = contentState.getBlockMap();
  94. var isExperimentalTreeBlock = blockToBeMoved instanceof ContentBlockNode;
  95. var blocksToBeMoved = [blockToBeMoved];
  96. var blockMapWithoutBlocksToBeMoved = blockMap["delete"](blockKey);
  97. if (isExperimentalTreeBlock) {
  98. blocksToBeMoved = [];
  99. blockMapWithoutBlocksToBeMoved = blockMap.withMutations(function (blocks) {
  100. var nextSiblingKey = blockToBeMoved.getNextSiblingKey();
  101. var nextDelimiterBlockKey = getNextDelimiterBlockKey(blockToBeMoved, blocks);
  102. blocks.toSeq().skipUntil(function (block) {
  103. return block.getKey() === blockKey;
  104. }).takeWhile(function (block) {
  105. var key = block.getKey();
  106. var isBlockToBeMoved = key === blockKey;
  107. var hasNextSiblingAndIsNotNextSibling = nextSiblingKey && key !== nextSiblingKey;
  108. var doesNotHaveNextSiblingAndIsNotDelimiter = !nextSiblingKey && block.getParentKey() && (!nextDelimiterBlockKey || key !== nextDelimiterBlockKey);
  109. return !!(isBlockToBeMoved || hasNextSiblingAndIsNotNextSibling || doesNotHaveNextSiblingAndIsNotDelimiter);
  110. }).forEach(function (block) {
  111. blocksToBeMoved.push(block);
  112. blocks["delete"](block.getKey());
  113. });
  114. });
  115. }
  116. var blocksBefore = blockMapWithoutBlocksToBeMoved.toSeq().takeUntil(function (v) {
  117. return v === targetBlock;
  118. });
  119. var blocksAfter = blockMapWithoutBlocksToBeMoved.toSeq().skipUntil(function (v) {
  120. return v === targetBlock;
  121. }).skip(1);
  122. var slicedBlocks = blocksToBeMoved.map(function (block) {
  123. return [block.getKey(), block];
  124. });
  125. var newBlocks = OrderedMap();
  126. if (insertionMode === 'before') {
  127. var blockBefore = contentState.getBlockBefore(targetKey);
  128. !(!blockBefore || blockBefore.getKey() !== blockToBeMoved.getKey()) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Block cannot be moved next to itself.') : invariant(false) : void 0;
  129. newBlocks = blocksBefore.concat([].concat(slicedBlocks, [[targetKey, targetBlock]]), blocksAfter).toOrderedMap();
  130. } else if (insertionMode === 'after') {
  131. var blockAfter = contentState.getBlockAfter(targetKey);
  132. !(!blockAfter || blockAfter.getKey() !== blockKey) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Block cannot be moved next to itself.') : invariant(false) : void 0;
  133. newBlocks = blocksBefore.concat([[targetKey, targetBlock]].concat(slicedBlocks), blocksAfter).toOrderedMap();
  134. }
  135. return contentState.merge({
  136. blockMap: updateBlockMapLinks(newBlocks, blockToBeMoved, targetBlock, insertionMode, isExperimentalTreeBlock),
  137. selectionBefore: contentState.getSelectionAfter(),
  138. selectionAfter: contentState.getSelectionAfter().merge({
  139. anchorKey: blockKey,
  140. focusKey: blockKey
  141. })
  142. });
  143. };
  144. module.exports = moveBlockInContentState;