79 lines
2.5 KiB
Plaintext
79 lines
2.5 KiB
Plaintext
/**
|
|
* Copyright (c) 2013-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule keyCommandTransposeCharacters
|
|
* @format
|
|
* @flow
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var DraftModifier = require('./DraftModifier');
|
|
var EditorState = require('./EditorState');
|
|
|
|
var getContentStateFragment = require('./getContentStateFragment');
|
|
|
|
/**
|
|
* Transpose the characters on either side of a collapsed cursor, or
|
|
* if the cursor is at the end of the block, transpose the last two
|
|
* characters.
|
|
*/
|
|
function keyCommandTransposeCharacters(editorState: EditorState): EditorState {
|
|
var selection = editorState.getSelection();
|
|
if (!selection.isCollapsed()) {
|
|
return editorState;
|
|
}
|
|
|
|
var offset = selection.getAnchorOffset();
|
|
if (offset === 0) {
|
|
return editorState;
|
|
}
|
|
|
|
var blockKey = selection.getAnchorKey();
|
|
var content = editorState.getCurrentContent();
|
|
var block = content.getBlockForKey(blockKey);
|
|
var length = block.getLength();
|
|
|
|
// Nothing to transpose if there aren't two characters.
|
|
if (length <= 1) {
|
|
return editorState;
|
|
}
|
|
|
|
var removalRange;
|
|
var finalSelection;
|
|
|
|
if (offset === length) {
|
|
// The cursor is at the end of the block. Swap the last two characters.
|
|
removalRange = selection.set('anchorOffset', offset - 1);
|
|
finalSelection = selection;
|
|
} else {
|
|
removalRange = selection.set('focusOffset', offset + 1);
|
|
finalSelection = removalRange.set('anchorOffset', offset + 1);
|
|
}
|
|
|
|
// Extract the character to move as a fragment. This preserves its
|
|
// styling and entity, if any.
|
|
var movedFragment = getContentStateFragment(content, removalRange);
|
|
var afterRemoval = DraftModifier.removeRange(content, removalRange, 'backward');
|
|
|
|
// After the removal, the insertion target is one character back.
|
|
var selectionAfter = afterRemoval.getSelectionAfter();
|
|
var targetOffset = selectionAfter.getAnchorOffset() - 1;
|
|
var targetRange = selectionAfter.merge({
|
|
anchorOffset: targetOffset,
|
|
focusOffset: targetOffset
|
|
});
|
|
|
|
var afterInsert = DraftModifier.replaceWithFragment(afterRemoval, targetRange, movedFragment);
|
|
|
|
var newEditorState = EditorState.push(editorState, afterInsert, 'insert-fragment');
|
|
|
|
return EditorState.acceptSelection(newEditorState, finalSelection);
|
|
}
|
|
|
|
module.exports = keyCommandTransposeCharacters; |