diff --git a/lib/__tests__/handleKeyCommand.js b/lib/__tests__/handleKeyCommand.js index 4b9cce5..6eb4a98 100644 --- a/lib/__tests__/handleKeyCommand.js +++ b/lib/__tests__/handleKeyCommand.js @@ -1,4 +1,9 @@ -const { EditorState, ContentState, SelectionState } = require('draft-js'); +const { + EditorState, + ContentState, + ContentBlock, + SelectionState +} = require('draft-js'); const handleKeyCommand = require('../handleKeyCommand'); const toPlainText = editorState => @@ -119,6 +124,39 @@ it('should not do anything on backspace if something is selected', () => { expect(handleKeyCommand(editorState, 'backspace')).toEqual(undefined); }); +it('should skip handling when text beginning from the content-block beginning', () => { + const firstBlock = new ContentBlock({ + key: 'a1', + text: 'const a = 1;', + type: 'unstyled' + }); + const secondBlock = new ContentBlock({ + key: 'a2', + text: 'function () {', + type: 'code-block' + }); + const currentContent = ContentState.createFromBlockArray([ + firstBlock, + secondBlock + ]); + const selectSecondBlock = SelectionState.createEmpty( + currentContent + .getBlockMap() + .last() + .getKey() + ) + .set('anchorOffset', 0) + .set('focusOffset', 0); + const editorState = EditorState.create({ + allowUndo: true, + currentContent, + selection: selectSecondBlock + }); + + const after = handleKeyCommand(editorState, 'backspace'); + expect(toPlainText(after)).toEqual(toPlainText(editorState)); +}); + it('should not do anything for any other command', () => { const editorState = createWithText(''); expect(handleKeyCommand(editorState, 'enter')).toEqual(undefined); diff --git a/lib/utils/getLineAnchorForOffset.js b/lib/utils/getLineAnchorForOffset.js index 67f7dd5..0dee69c 100644 --- a/lib/utils/getLineAnchorForOffset.js +++ b/lib/utils/getLineAnchorForOffset.js @@ -40,7 +40,7 @@ function getLineAnchorForOffset(text, offset, sep) { } return new LineAnchor({ - line: lineIndex - 1, + line: lineIndex === 0 ? 0 : lineIndex - 1, offset: offset - lastLineIndex }); } diff --git a/lib/utils/removeIndent.js b/lib/utils/removeIndent.js index 43bf101..1282443 100644 --- a/lib/utils/removeIndent.js +++ b/lib/utils/removeIndent.js @@ -1,5 +1,6 @@ var Draft = require('draft-js'); var endsWith = require('ends-with'); +var detectIndent = require('detect-indent'); var getNewLine = require('./getNewLine'); var getIndentation = require('./getIndentation'); @@ -25,7 +26,6 @@ function removeIndent(editorState) { var currentBlock = contentState.getBlockForKey(startKey); var blockText = currentBlock.getText(); - // Detect newline separator and indentation var newLine = getNewLine(blockText); var indent = getIndentation(blockText); @@ -36,6 +36,31 @@ function removeIndent(editorState) { var currentLine = lines.get(lineAnchor.getLine()); var beforeSelection = currentLine.slice(0, lineAnchor.getOffset()); + // Detect newline separator and indentation + var currentIndent = detectIndent(currentLine); + + // if previous block was not `code-block` and we are at the beginning of line, + // we don't do any action to prevent current `code-block` removing + if ( + currentIndent.amount < 1 && + lineAnchor.getLine() === 0 && + startOffset === 0 + ) { + var lastBlockBefore = contentState + .getBlockMap() + .takeUntil((value, key) => { + return key.match(startKey); + }) + .last(); + + if ( + !(lastBlockBefore instanceof Draft.ContentBlock) || + lastBlockBefore.getType() !== 'code-block' + ) { + return editorState; + } + } + // If the line before selection ending with the indentation? if (!endsWith(beforeSelection, indent)) { return;