text: /**
   * 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 AtomicBlockUtils
   * @typechecks
   * @format
   * 
   */
  
  'use strict';
  
  var BlockMapBuilder = require('./BlockMapBuilder');
  var CharacterMetadata = require('./CharacterMetadata');
  var ContentBlock = require('./ContentBlock');
  var DraftModifier = require('./DraftModifier');
  var EditorState = require('./EditorState');
  var Immutable = require('immutable');
  var SelectionState = require('./SelectionState');
  
  var generateRandomKey = require('./generateRandomKey');
  var moveBlockInContentState = require('./moveBlockInContentState');
  
  var List = Immutable.List,
      Repeat = Immutable.Repeat;
  
  
  var AtomicBlockUtils = {
    insertAtomicBlock: function insertAtomicBlock(editorState, entityKey, character) {
      var contentState = editorState.getCurrentContent();
      var selectionState = editorState.getSelection();
  
      var afterRemoval = DraftModifier.removeRange(contentState, selectionState, 'backward');
  
      var targetSelection = afterRemoval.getSelectionAfter();
      var afterSplit = DraftModifier.splitBlock(afterRemoval, targetSelection);
      var insertionTarget = afterSplit.getSelectionAfter();
  
      var asAtomicBlock = DraftModifier.setBlockType(afterSplit, insertionTarget, 'atomic');
  
      var charData = CharacterMetadata.create({ entity: entityKey });
  
      var fragmentArray = [new ContentBlock({
        key: generateRandomKey(),
        type: 'atomic',
        text: character,
        characterList: List(Repeat(charData, character.length))
      }), new ContentBlock({
        key: generateRandomKey(),
        type: 'unstyled',
        text: '',
        characterList: List()
      })];
  
      var fragment = BlockMapBuilder.createFromArray(fragmentArray);
  
      var withAtomicBlock = DraftModifier.replaceWithFragment(asAtomicBlock, insertionTarget, fragment);
  
      var newContent = withAtomicBlock.merge({
        selectionBefore: selectionState,
        selectionAfter: withAtomicBlock.getSelectionAfter().set('hasFocus', true)
      });
  
      return EditorState.push(editorState, newContent, 'insert-fragment');
    },
  
    moveAtomicBlock: function moveAtomicBlock(editorState, atomicBlock, targetRange, insertionMode) {
      var contentState = editorState.getCurrentContent();
      var selectionState = editorState.getSelection();
  
      var withMovedAtomicBlock = void 0;
  
      if (insertionMode === 'before' || insertionMode === 'after') {
        var targetBlock = contentState.getBlockForKey(insertionMode === 'before' ? targetRange.getStartKey() : targetRange.getEndKey());
  
        withMovedAtomicBlock = moveBlockInContentState(contentState, atomicBlock, targetBlock, insertionMode);
      } else {
        var afterRemoval = DraftModifier.removeRange(contentState, targetRange, 'backward');
  
        var selectionAfterRemoval = afterRemoval.getSelectionAfter();
        var _targetBlock = afterRemoval.getBlockForKey(selectionAfterRemoval.getFocusKey());
  
        if (selectionAfterRemoval.getStartOffset() === 0) {
          withMovedAtomicBlock = moveBlockInContentState(afterRemoval, atomicBlock, _targetBlock, 'before');
        } else if (selectionAfterRemoval.getEndOffset() === _targetBlock.getLength()) {
          withMovedAtomicBlock = moveBlockInContentState(afterRemoval, atomicBlock, _targetBlock, 'after');
        } else {
          var afterSplit = DraftModifier.splitBlock(afterRemoval, selectionAfterRemoval);
  
          var selectionAfterSplit = afterSplit.getSelectionAfter();
          var _targetBlock2 = afterSplit.getBlockForKey(selectionAfterSplit.getFocusKey());
  
          withMovedAtomicBlock = moveBlockInContentState(afterSplit, atomicBlock, _targetBlock2, 'before');
        }
      }
  
      var newContent = withMovedAtomicBlock.merge({
        selectionBefore: selectionState,
        selectionAfter: withMovedAtomicBlock.getSelectionAfter().set('hasFocus', true)
      });
  
      return EditorState.push(editorState, newContent, 'move-block');
    }
  };
  
  module.exports = AtomicBlockUtils;