From 6d75d13d8da61f47eb7fdeb6b414ac724140f00d Mon Sep 17 00:00:00 2001 From: newsiberian Date: Thu, 7 Dec 2017 11:45:09 +0700 Subject: [PATCH 1/2] - added check of prev block type when we try to go to prev line; --- lib/utils/removeIndent.js | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/lib/utils/removeIndent.js b/lib/utils/removeIndent.js index 43bf101..e77ede9 100644 --- a/lib/utils/removeIndent.js +++ b/lib/utils/removeIndent.js @@ -1,8 +1,8 @@ var Draft = require('draft-js'); var endsWith = require('ends-with'); +var detectIndent = require('detect-indent'); var getNewLine = require('./getNewLine'); -var getIndentation = require('./getIndentation'); var getLines = require('./getLines'); var getLineAnchorForOffset = require('./getLineAnchorForOffset'); @@ -26,8 +26,27 @@ function removeIndent(editorState) { var blockText = currentBlock.getText(); // Detect newline separator and indentation + var indent = detectIndent(blockText); + + // 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 (indent.amount < 1) { + var lastBlockBefore = contentState + .getBlockMap() + .takeUntil((value, key) => { + return key.match(startKey); + }) + .last(); + + if ( + !(lastBlockBefore instanceof Draft.ContentBlock) || + lastBlockBefore.getType() !== 'code-block' + ) { + return editorState; + } + } + var newLine = getNewLine(blockText); - var indent = getIndentation(blockText); // Get current line var lines = getLines(blockText, newLine); From d4796f778e4bb22f07e758ef18bac06d01f2ca04 Mon Sep 17 00:00:00 2001 From: newsiberian Date: Mon, 11 Dec 2017 13:31:44 +0700 Subject: [PATCH 2/2] - fixed line index in LineAnchor; - fixed previous commit changes; - added test; --- lib/__tests__/handleKeyCommand.js | 40 ++++++++++++++++++++++++++++- lib/utils/getLineAnchorForOffset.js | 2 +- lib/utils/removeIndent.js | 28 ++++++++++++-------- 3 files changed, 57 insertions(+), 13 deletions(-) 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 e77ede9..1282443 100644 --- a/lib/utils/removeIndent.js +++ b/lib/utils/removeIndent.js @@ -3,6 +3,7 @@ var endsWith = require('ends-with'); var detectIndent = require('detect-indent'); var getNewLine = require('./getNewLine'); +var getIndentation = require('./getIndentation'); var getLines = require('./getLines'); var getLineAnchorForOffset = require('./getLineAnchorForOffset'); @@ -25,12 +26,26 @@ function removeIndent(editorState) { var currentBlock = contentState.getBlockForKey(startKey); var blockText = currentBlock.getText(); + var newLine = getNewLine(blockText); + var indent = getIndentation(blockText); + + // Get current line + var lines = getLines(blockText, newLine); + var lineAnchor = getLineAnchorForOffset(blockText, startOffset, newLine); + + var currentLine = lines.get(lineAnchor.getLine()); + var beforeSelection = currentLine.slice(0, lineAnchor.getOffset()); + // Detect newline separator and indentation - var indent = detectIndent(blockText); + 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 (indent.amount < 1) { + if ( + currentIndent.amount < 1 && + lineAnchor.getLine() === 0 && + startOffset === 0 + ) { var lastBlockBefore = contentState .getBlockMap() .takeUntil((value, key) => { @@ -46,15 +61,6 @@ function removeIndent(editorState) { } } - var newLine = getNewLine(blockText); - - // Get current line - var lines = getLines(blockText, newLine); - var lineAnchor = getLineAnchorForOffset(blockText, startOffset, newLine); - - var currentLine = lines.get(lineAnchor.getLine()); - var beforeSelection = currentLine.slice(0, lineAnchor.getOffset()); - // If the line before selection ending with the indentation? if (!endsWith(beforeSelection, indent)) { return;