d2-ui
Version:
122 lines (97 loc) • 3.81 kB
JavaScript
/**
* 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 insertFragmentIntoContentState
* @typechecks
*
*/
'use strict';
var BlockMapBuilder = require('./BlockMapBuilder');
var generateRandomKey = require('./generateRandomKey');
var insertIntoList = require('./insertIntoList');
var invariant = require('fbjs/lib/invariant');
function insertFragmentIntoContentState(contentState, selectionState, fragment) {
!selectionState.isCollapsed() ? process.env.NODE_ENV !== 'production' ? invariant(false, '`insertFragment` should only be called with a collapsed selection state.') : invariant(false) : undefined;
var targetKey = selectionState.getStartKey();
var targetOffset = selectionState.getStartOffset();
var blockMap = contentState.getBlockMap();
var fragmentSize = fragment.size;
var finalKey;
var finalOffset;
if (fragmentSize === 1) {
var targetBlock = blockMap.get(targetKey);
var pastedBlock = fragment.first();
var text = targetBlock.getText();
var chars = targetBlock.getCharacterList();
var newBlock = targetBlock.merge({
text: text.slice(0, targetOffset) + pastedBlock.getText() + text.slice(targetOffset),
characterList: insertIntoList(chars, pastedBlock.getCharacterList(), targetOffset)
});
blockMap = blockMap.set(targetKey, newBlock);
finalKey = targetKey;
finalOffset = targetOffset + pastedBlock.getText().length;
return contentState.merge({
blockMap: blockMap.set(targetKey, newBlock),
selectionBefore: selectionState,
selectionAfter: selectionState.merge({
anchorKey: finalKey,
anchorOffset: finalOffset,
focusKey: finalKey,
focusOffset: finalOffset,
isBackward: false
})
});
}
var newBlockArr = [];
contentState.getBlockMap().forEach(function (block, blockKey) {
if (blockKey !== targetKey) {
newBlockArr.push(block);
return;
}
var text = block.getText();
var chars = block.getCharacterList();
// Modify head portion of block.
var blockSize = text.length;
var headText = text.slice(0, targetOffset);
var headCharacters = chars.slice(0, targetOffset);
var appendToHead = fragment.first();
var modifiedHead = block.merge({
text: headText + appendToHead.getText(),
characterList: headCharacters.concat(appendToHead.getCharacterList())
});
newBlockArr.push(modifiedHead);
// Insert fragment blocks after the head and before the tail.
fragment.slice(1, fragmentSize - 1).forEach(function (fragmentBlock) {
newBlockArr.push(fragmentBlock.set('key', generateRandomKey()));
});
// Modify tail portion of block.
var tailText = text.slice(targetOffset, blockSize);
var tailCharacters = chars.slice(targetOffset, blockSize);
var prependToTail = fragment.last();
finalKey = generateRandomKey();
var modifiedTail = prependToTail.merge({
key: finalKey,
text: prependToTail.getText() + tailText,
characterList: prependToTail.getCharacterList().concat(tailCharacters)
});
newBlockArr.push(modifiedTail);
});
finalOffset = fragment.last().getLength();
return contentState.merge({
blockMap: BlockMapBuilder.createFromArray(newBlockArr),
selectionBefore: selectionState,
selectionAfter: selectionState.merge({
anchorKey: finalKey,
anchorOffset: finalOffset,
focusKey: finalKey,
focusOffset: finalOffset,
isBackward: false
})
});
}
module.exports = insertFragmentIntoContentState;