facebookarchive/draft-js

Avoid empty unstyled blocks

Open

#636 opened on Sep 8, 2016

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

Repository metrics

Stars
 (22,554 stars)
PR merge metrics
 (No merged PRs in 30d)

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