From f22c68d2ab0116195fceb759be977a34999c836e Mon Sep 17 00:00:00 2001 From: Jocs Date: Wed, 13 Jun 2018 19:52:15 +0800 Subject: [PATCH] feature: can use delete key now, #301 --- src/editor/contentState/backspaceCtrl.js | 41 ++----------------- src/editor/contentState/deleteCtrl.js | 50 +++++++++++++++++++++++ src/editor/contentState/index.js | 2 + src/editor/contentState/tableBlockCtrl.js | 1 - src/editor/floatBox/index.css | 2 +- src/editor/index.js | 2 + 6 files changed, 59 insertions(+), 39 deletions(-) create mode 100644 src/editor/contentState/deleteCtrl.js diff --git a/src/editor/contentState/backspaceCtrl.js b/src/editor/contentState/backspaceCtrl.js index 51e091d0..46e1c9b3 100644 --- a/src/editor/contentState/backspaceCtrl.js +++ b/src/editor/contentState/backspaceCtrl.js @@ -104,7 +104,6 @@ const backspaceCtrl = ContentState => { const { start, end } = selection.getCursorRange() const startBlock = this.getBlock(start.key) const endBlock = this.getBlock(end.key) - // fix: #67 problem 1 if (startBlock.icon) return event.preventDefault() // fix: unexpect remove all editor html. #67 problem 4 @@ -129,42 +128,10 @@ const backspaceCtrl = ContentState => { return this.render() } - if (start.key !== end.key) { - event.preventDefault() - const { key, offset } = start - const startRemainText = startBlock.type === 'pre' && /code|html/.test(startBlock.functionType) - ? startBlock.text.substring(0, offset - 1) - : startBlock.text.substring(0, offset) - - const endRemainText = endBlock.type === 'pre' && /code|html/.test(endBlock.functionType) - ? endBlock.text.substring(end.offset - 1) - : endBlock.text.substring(end.offset) - - if (offset === 0 && !(/th|td/.test(startBlock.type))) { - if (startBlock.type === 'pre') { - delete startBlock.coords - delete startBlock.functionType - delete startBlock.history - delete startBlock.lang - delete startBlock.selection - this.codeBlocks.delete(key) - } - if (startBlock.type !== 'span') { - startBlock.type = 'span' - const pBlock = this.createBlock('p') - this.insertBefore(pBlock, startBlock) - this.removeBlock(startBlock) - this.appendChild(pBlock, startBlock) - } - } - - startBlock.text = startRemainText + endRemainText - this.removeBlocks(startBlock, endBlock) - this.cursor = { - start: { key, offset }, - end: { key, offset } - } - return this.partialRender() + // If select multiple paragraph or multiple characters in one paragraph, just let + // updateCtrl to handle this case. + if (start.key !== end.key || start.offset !== end.offset) { + return } const node = selection.getSelectionStart() diff --git a/src/editor/contentState/deleteCtrl.js b/src/editor/contentState/deleteCtrl.js new file mode 100644 index 00000000..32f36097 --- /dev/null +++ b/src/editor/contentState/deleteCtrl.js @@ -0,0 +1,50 @@ +import selection from '../selection' + +const deleteCtrl = ContentState => { + ContentState.prototype.deleteHandler = function (event) { + const { start, end } = selection.getCursorRange() + const startBlock = this.getBlock(start.key) + const nextBlock = this.findNextBlockInLocation(startBlock) + + // TODO: @jocs It will delete all the editor and cause error in console when there is only one empty table. same as #67 + if (startBlock.type === 'figure') event.preventDefault() + // If select multiple paragraph or multiple characters in one paragraph, just let + // updateCtrl to handle this case. + if (start.key !== end.key || start.offset !== end.offset) { + return + } + // Only handle h1~h6 span block + const { type, text, key } = startBlock + if ( + /h\d|span/.test(type) && + start.offset === text.length + ) { + event.preventDefault() + if (nextBlock && /h\d|span/.test(nextBlock.type)) { + startBlock.text += nextBlock.text + + const toBeRemoved = [ nextBlock ] + + let parent = this.getParent(nextBlock) + let target = nextBlock + + while (this.isOnlyChild(target)) { + toBeRemoved.push(parent) + target = parent + parent = this.getParent(parent) + } + + toBeRemoved.forEach(b => this.removeBlock(b)) + + const offset = start.offset + this.cursor = { + start: { key, offset }, + end: { key, offset } + } + this.render() + } + } + } +} + +export default deleteCtrl diff --git a/src/editor/contentState/index.js b/src/editor/contentState/index.js index 114406d7..32ede3e0 100644 --- a/src/editor/contentState/index.js +++ b/src/editor/contentState/index.js @@ -6,6 +6,7 @@ import StateRender from '../parser/render' import enterCtrl from './enterCtrl' import updateCtrl from './updateCtrl' import backspaceCtrl from './backspaceCtrl' +import deleteCtrl from './deleteCtrl' import codeBlockCtrl from './codeBlockCtrl' import tableBlockCtrl from './tableBlockCtrl' import selectionCtrl from './selectionCtrl' @@ -28,6 +29,7 @@ const prototypes = [ selectionCtrl, updateCtrl, backspaceCtrl, + deleteCtrl, codeBlockCtrl, arrowCtrl, pasteCtrl, diff --git a/src/editor/contentState/tableBlockCtrl.js b/src/editor/contentState/tableBlockCtrl.js index 3d7a2334..89725338 100644 --- a/src/editor/contentState/tableBlockCtrl.js +++ b/src/editor/contentState/tableBlockCtrl.js @@ -1,6 +1,5 @@ import { isLengthEven } from '../utils' import { TABLE_TOOLS } from '../config' -// import selection from '../selection' const TABLE_BLOCK_REG = /^\|.*?(\\*)\|.*?(\\*)\|/ diff --git a/src/editor/floatBox/index.css b/src/editor/floatBox/index.css index 95b06072..5097a79c 100644 --- a/src/editor/floatBox/index.css +++ b/src/editor/floatBox/index.css @@ -12,7 +12,7 @@ border-radius: 4px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1); list-style: none; - transition: opacity .15s ease-in; + transition: all .15s ease-in; overflow: auto; background: #fff; z-index: 10000; diff --git a/src/editor/index.js b/src/editor/index.js index 6e5683a6..84046f56 100644 --- a/src/editor/index.js +++ b/src/editor/index.js @@ -271,6 +271,8 @@ class Aganippe { const handler = event => { if (event.key === EVENT_KEYS.Backspace) { this.contentState.backspaceHandler(event) + } else if (event.key === EVENT_KEYS.Delete) { + this.contentState.deleteHandler(event) } }