From ac272642bfcf99bef098cbc38253d2b09ad4a73a Mon Sep 17 00:00:00 2001 From: Mohamed Moussa Date: Thu, 30 Mar 2017 17:10:50 -0700 Subject: [PATCH] Fixed bugs with deletion between blocks and atomic block deletion test case --- src/model/modifier/DraftModifier.js | 17 ++++++---- .../__tests__/RichTextEditorUtil-test.js | 6 +++- .../modifier/getCharacterRemovalRange.js | 32 +++++++++++++------ 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/model/modifier/DraftModifier.js b/src/model/modifier/DraftModifier.js index 6422122dee..eabde2b7b4 100644 --- a/src/model/modifier/DraftModifier.js +++ b/src/model/modifier/DraftModifier.js @@ -140,12 +140,17 @@ var DraftModifier = { removalDirection: DraftRemovalDirection, ): ContentState { let startKey, endKey, startBlock, endBlock; - startKey = removalDirection === 'forward' - ? rangeToRemove.getAnchorKey() - : rangeToRemove.getFocusKey(); - endKey = removalDirection === 'forward' - ? rangeToRemove.getFocusKey() - : rangeToRemove.getAnchorKey(); + if (rangeToRemove.getIsBackward()) { + rangeToRemove = rangeToRemove.merge({ + anchorKey: rangeToRemove.getFocusKey(), + anchorOffset: rangeToRemove.getFocusOffset(), + focusKey: rangeToRemove.getAnchorKey(), + focusOffset: rangeToRemove.getAnchorOffset(), + isBackward: false, + }); + } + startKey = rangeToRemove.getAnchorKey(); + endKey = rangeToRemove.getFocusKey(); startBlock = contentState.getBlockForKey(startKey); endBlock = contentState.getBlockForKey(endKey); const startOffset = rangeToRemove.getStartOffset(); diff --git a/src/model/modifier/__tests__/RichTextEditorUtil-test.js b/src/model/modifier/__tests__/RichTextEditorUtil-test.js index f9bf48e4af..e6d74e7b90 100644 --- a/src/model/modifier/__tests__/RichTextEditorUtil-test.js +++ b/src/model/modifier/__tests__/RichTextEditorUtil-test.js @@ -23,7 +23,11 @@ describe('RichTextEditorUtil', () => { const {editorState, selectionState} = getSampleStateForTesting(); function insertAtomicBlock(targetEditorState) { - const entityKey = 'foo'; + const entityKey = targetEditorState.getCurrentContent().createEntity( + 'TEST', + 'IMMUTABLE', + null, + ).getLastCreatedEntityKey(); const character = ' '; const movedSelection = EditorState.moveSelectionToEnd(targetEditorState); return AtomicBlockUtils.insertAtomicBlock( diff --git a/src/model/modifier/getCharacterRemovalRange.js b/src/model/modifier/getCharacterRemovalRange.js index 5e3b5c637b..ea5a1fa696 100644 --- a/src/model/modifier/getCharacterRemovalRange.js +++ b/src/model/modifier/getCharacterRemovalRange.js @@ -47,15 +47,6 @@ function getCharacterRemovalRange( return selectionState; } var newSelectionState = selectionState; - if (selectionState.getIsBackward()) { - newSelectionState = selectionState.merge({ - anchorKey: selectionState.getFocusKey(), - anchorOffset: selectionState.getFocusOffset(), - focusKey: selectionState.getAnchorKey(), - focusOffset: selectionState.getAnchorOffset(), - isBackward: false, - }); - } if (startEntityKey && (startEntityKey === endEntityKey)) { newSelectionState = getEntityRemovalRange( entityMap, @@ -63,6 +54,8 @@ function getCharacterRemovalRange( newSelectionState, direction, startEntityKey, + true, + true, ); } else if (startEntityKey && endEntityKey) { const startSelectionState = getEntityRemovalRange( @@ -71,6 +64,8 @@ function getCharacterRemovalRange( newSelectionState, direction, startEntityKey, + false, + true, ); const endSelectionState = getEntityRemovalRange( entityMap, @@ -78,6 +73,8 @@ function getCharacterRemovalRange( newSelectionState, direction, endEntityKey, + false, + false, ); newSelectionState = newSelectionState.merge({ anchorOffset: startSelectionState.getAnchorOffset(), @@ -91,6 +88,8 @@ function getCharacterRemovalRange( newSelectionState, direction, startEntityKey, + false, + true, ); newSelectionState = newSelectionState.merge({ anchorOffset: startSelectionState.getStartOffset(), @@ -103,6 +102,8 @@ function getCharacterRemovalRange( newSelectionState, direction, endEntityKey, + false, + false, ); newSelectionState = newSelectionState.merge({ focusOffset: endSelectionState.getEndOffset(), @@ -118,11 +119,14 @@ function getEntityRemovalRange( selectionState: SelectionState, direction: DraftRemovalDirection, entityKey: string, + isEntireSelectionWithinEntity: boolean, + isEntityAtStart: boolean, ): SelectionState { var start = selectionState.getStartOffset(); var end = selectionState.getEndOffset(); var entity = entityMap.__get(entityKey); var mutability = entity.getMutability(); + const sideToConsider = isEntityAtStart ? start : end; // `MUTABLE` entities can just have the specified range of text removed // directly. No adjustments are needed. @@ -132,7 +136,7 @@ function getEntityRemovalRange( // Find the entity range that overlaps with our removal range. var entityRanges = getRangesForDraftEntity(block, entityKey).filter( - (range) => start < range.end && end > range.start, + (range) => sideToConsider <= range.end && sideToConsider >= range.start, ); invariant( @@ -153,6 +157,14 @@ function getEntityRemovalRange( // For `SEGMENTED` entity types, determine the appropriate segment to // remove. + if (!isEntireSelectionWithinEntity) { + if (isEntityAtStart) { + end = entityRange.end; + } else { + start = entityRange.start; + } + } + var removalRange = DraftEntitySegments.getRemovalRange( start, end,