UNPKG

4.43 kBJavaScriptView Raw
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
13var DraftEntitySegments = require("./DraftEntitySegments");
14
15var getRangesForDraftEntity = require("./getRangesForDraftEntity");
16
17var invariant = require("fbjs/lib/invariant");
18/**
19 * Given a SelectionState and a removal direction, determine the entire range
20 * that should be removed from a ContentState. This is based on any entities
21 * within the target, with their `mutability` values taken into account.
22 *
23 * For instance, if we are attempting to remove part of an "immutable" entity
24 * range, the entire entity must be removed. The returned `SelectionState`
25 * will be adjusted accordingly.
26 */
27
28
29function getCharacterRemovalRange(entityMap, startBlock, endBlock, selectionState, direction) {
30 var start = selectionState.getStartOffset();
31 var end = selectionState.getEndOffset();
32 var startEntityKey = startBlock.getEntityAt(start);
33 var endEntityKey = endBlock.getEntityAt(end - 1);
34
35 if (!startEntityKey && !endEntityKey) {
36 return selectionState;
37 }
38
39 var newSelectionState = selectionState;
40
41 if (startEntityKey && startEntityKey === endEntityKey) {
42 newSelectionState = getEntityRemovalRange(entityMap, startBlock, newSelectionState, direction, startEntityKey, true, true);
43 } else if (startEntityKey && endEntityKey) {
44 var startSelectionState = getEntityRemovalRange(entityMap, startBlock, newSelectionState, direction, startEntityKey, false, true);
45 var endSelectionState = getEntityRemovalRange(entityMap, endBlock, newSelectionState, direction, endEntityKey, false, false);
46 newSelectionState = newSelectionState.merge({
47 anchorOffset: startSelectionState.getAnchorOffset(),
48 focusOffset: endSelectionState.getFocusOffset(),
49 isBackward: false
50 });
51 } else if (startEntityKey) {
52 var _startSelectionState = getEntityRemovalRange(entityMap, startBlock, newSelectionState, direction, startEntityKey, false, true);
53
54 newSelectionState = newSelectionState.merge({
55 anchorOffset: _startSelectionState.getStartOffset(),
56 isBackward: false
57 });
58 } else if (endEntityKey) {
59 var _endSelectionState = getEntityRemovalRange(entityMap, endBlock, newSelectionState, direction, endEntityKey, false, false);
60
61 newSelectionState = newSelectionState.merge({
62 focusOffset: _endSelectionState.getEndOffset(),
63 isBackward: false
64 });
65 }
66
67 return newSelectionState;
68}
69
70function getEntityRemovalRange(entityMap, block, selectionState, direction, entityKey, isEntireSelectionWithinEntity, isEntityAtStart) {
71 var start = selectionState.getStartOffset();
72 var end = selectionState.getEndOffset();
73
74 var entity = entityMap.__get(entityKey);
75
76 var mutability = entity.getMutability();
77 var sideToConsider = isEntityAtStart ? start : end; // `MUTABLE` entities can just have the specified range of text removed
78 // directly. No adjustments are needed.
79
80 if (mutability === 'MUTABLE') {
81 return selectionState;
82 } // Find the entity range that overlaps with our removal range.
83
84
85 var entityRanges = getRangesForDraftEntity(block, entityKey).filter(function (range) {
86 return sideToConsider <= range.end && sideToConsider >= range.start;
87 });
88 !(entityRanges.length == 1) ? process.env.NODE_ENV !== "production" ? invariant(false, 'There should only be one entity range within this removal range.') : invariant(false) : void 0;
89 var entityRange = entityRanges[0]; // For `IMMUTABLE` entity types, we will remove the entire entity range.
90
91 if (mutability === 'IMMUTABLE') {
92 return selectionState.merge({
93 anchorOffset: entityRange.start,
94 focusOffset: entityRange.end,
95 isBackward: false
96 });
97 } // For `SEGMENTED` entity types, determine the appropriate segment to
98 // remove.
99
100
101 if (!isEntireSelectionWithinEntity) {
102 if (isEntityAtStart) {
103 end = entityRange.end;
104 } else {
105 start = entityRange.start;
106 }
107 }
108
109 var removalRange = DraftEntitySegments.getRemovalRange(start, end, block.getText().slice(entityRange.start, entityRange.end), entityRange.start, direction);
110 return selectionState.merge({
111 anchorOffset: removalRange.start,
112 focusOffset: removalRange.end,
113 isBackward: false
114 });
115}
116
117module.exports = getCharacterRemovalRange;
\No newline at end of file