in src/model/modifier/getCharacterRemovalRange.js [114:179]
function getEntityRemovalRange(
entityMap: EntityMap,
block: BlockNodeRecord,
selectionState: SelectionState,
direction: DraftRemovalDirection,
entityKey: string,
isEntireSelectionWithinEntity: boolean,
isEntityAtStart: boolean,
): SelectionState {
let start = selectionState.getStartOffset();
let end = selectionState.getEndOffset();
const entity = entityMap.get(entityKey);
const mutability = entity.getMutability();
const sideToConsider = isEntityAtStart ? start : end;
// `MUTABLE` entities can just have the specified range of text removed
// directly. No adjustments are needed.
if (mutability === 'MUTABLE') {
return selectionState;
}
// Find the entity range that overlaps with our removal range.
const entityRanges = getRangesForDraftEntity(block, entityKey).filter(
range => sideToConsider <= range.end && sideToConsider >= range.start,
);
invariant(
entityRanges.length == 1,
'There should only be one entity range within this removal range.',
);
const entityRange = entityRanges[0];
// For `IMMUTABLE` entity types, we will remove the entire entity range.
if (mutability === 'IMMUTABLE') {
return selectionState.merge({
anchorOffset: entityRange.start,
focusOffset: entityRange.end,
isBackward: false,
});
}
// For `SEGMENTED` entity types, determine the appropriate segment to
// remove.
if (!isEntireSelectionWithinEntity) {
if (isEntityAtStart) {
end = entityRange.end;
} else {
start = entityRange.start;
}
}
const removalRange = DraftEntitySegments.getRemovalRange(
start,
end,
block.getText().slice(entityRange.start, entityRange.end),
entityRange.start,
direction,
);
return selectionState.merge({
anchorOffset: removalRange.start,
focusOffset: removalRange.end,
isBackward: false,
});
}