facebookarchive/draft-js

Avoid empty unstyled blocks

Open

#636 opened on Sep 8, 2016

View on GitHub
 (6 comments) (2 reactions) (0 assignees)JavaScript (22,554 stars) (2,646 forks)batch import
good first issuehelp wanted

Description

I want to remove all empty blocks that has no style. My problem is that when the user clicks on backspace in a styled block with no text, the block is not deleted, it just loses his style and I wish to avoid having unstyled blocks.

I'm looking for some solution to this behavior.

I've tried using Modifier.removeRange (like suggested in #168) to delete all empty blocks (with no style and no text) but it just doesn't work.

Can you please tell me what I'm doing wrong?

const removeEmptyUnstyledBlocks = (editorState) => {
  let contentState = editorState.getCurrentContent();
  const blocks = contentState.getBlocksAsArray();
  const emptyBlocks = blocks.filter(b => b.get('type') === 'unstyled' && b.get('text') === '');
  emptyBlocks.forEach(b => {
    let removalRange = SelectionState.createEmpty().merge({ // I've tried many variations for this
      anchorKey: b.getKey(),
      focusKey: b.getKey(),
      focusOffset: 0,
      anchorOffset: 0,
      isBackward: true,
      hasFocus: true
    });

    contentState = Modifier.removeRange(contentState, removalRange, 'backward');
  });

  return emptyBlocks.length ? EditorState.push(editorState, contentState, 'remove-empty-blocks') : editorState;
};

This doesn't work (look at my comment for a working solution).

Is it even possible to simply remove a block from the editorState's block map? (e.g. using immutable-js deleteIn([...]) function)

Maybe the problem is that the selection is collapsed because the block has no text?

Surely, it would be better if I could totally avoid getting empty blocks instead of fixing the state in every onChange.

Update

I forgot to mention that I'm using this handleKeyCommand function (which handles the backspace command):

  handleKeyCommand(command) {
    const { editorState } = this.state;

    const newState = RichUtils.handleKeyCommand(editorState, command);

    if (newState) {
      this.onChange(newState);
    }

    return !!newState;
  }

And I think this is the right place to take care of my problem.

Contributor guide