diff --git a/src/muya/lib/contentState/backspaceCtrl.js b/src/muya/lib/contentState/backspaceCtrl.js index bd351e7e..d65b195c 100644 --- a/src/muya/lib/contentState/backspaceCtrl.js +++ b/src/muya/lib/contentState/backspaceCtrl.js @@ -147,8 +147,7 @@ const backspaceCtrl = ContentState => { } return this.partialRender() } - // fix: #67 problem 1 - if (startBlock.icon) return event.preventDefault() + // fix: unexpect remove all editor html. #67 problem 4 if (startBlock.type === 'figure' && !startBlock.preSibling) { event.preventDefault() @@ -171,12 +170,8 @@ const backspaceCtrl = ContentState => { return this.render() } - if (startBlock.functionType === 'languageInput' && start.offset === 0) { - return event.preventDefault() - } - // If select multiple paragraph or multiple characters in one paragraph, just let - // updateCtrl to handle this case. + // inputCtrl to handle this case. if (start.key !== end.key || start.offset !== end.offset) { return } diff --git a/src/muya/lib/contentState/inputCtrl.js b/src/muya/lib/contentState/inputCtrl.js index 5f9d0e7c..5dda1d97 100644 --- a/src/muya/lib/contentState/inputCtrl.js +++ b/src/muya/lib/contentState/inputCtrl.js @@ -82,6 +82,7 @@ const inputCtrl = ContentState => { if (!start || !end) { return } + const { start: oldStart, end: oldEnd } = this.cursor const key = start.key const block = this.getBlock(key) @@ -92,9 +93,20 @@ const inputCtrl = ContentState => { if (oldStart.key !== oldEnd.key) { const startBlock = this.getBlock(oldStart.key) + const startOutmostBlock = this.findOutMostBlock(startBlock) const endBlock = this.getBlock(oldEnd.key) - - this.removeBlocks(startBlock, endBlock) + const endOutmostBlock = this.findOutMostBlock(endBlock) + if ( + // fix #918. + startBlock.functionType === 'languageInput' && + startOutmostBlock === endOutmostBlock && + !endBlock.nextSibling + ) { + this.removeBlocks(startBlock, endBlock, false) + endBlock.text = '' + } else { + this.removeBlocks(startBlock, endBlock) + } if (this.blocks.length === 1) { needRenderAll = true } diff --git a/src/muya/lib/selection/index.js b/src/muya/lib/selection/index.js index c54ee426..7f1d6a2a 100644 --- a/src/muya/lib/selection/index.js +++ b/src/muya/lib/selection/index.js @@ -439,9 +439,43 @@ class Selection { getCursorRange () { let { anchorNode, anchorOffset, focusNode, focusOffset } = this.doc.getSelection() + // when the first paragraph is task list, press ctrl + a, then press backspace will cause bug + // use code bellow to fix the bug + const findFirstTextNode = anchor => { + if (anchor.nodeType === 3) return anchor + // if it's a empty line, just return the span element. + if ( + anchor.nodeType === 1 && + anchor.nodeName === 'SPAN' && + anchor.textContent === '' && + anchor.classList.contains('ag-line') + ) { + return anchor + } + const children = anchor.childNodes + for (const node of children) { + if ( + /input/i.test(node.nodeName) || + node.nodeType === 1 && node.getAttribute('contenteditable') === 'false' + ) { + continue + } + return findFirstTextNode(node) + } + } + let needFix = false + if (anchorNode.nodeName === 'LI') { + needFix = true + anchorNode = findFirstTextNode(anchorNode) + } + + if (focusNode.nodeName === 'LI') { + needFix = true + focusNode = findFirstTextNode(focusNode) + } + let startParagraph = findNearestParagraph(anchorNode) let endParagraph = findNearestParagraph(focusNode) - if (!startParagraph || !endParagraph) { return { start: null, @@ -449,21 +483,6 @@ class Selection { } } - // when the first paragraph is task list, press ctrl + a, then press backspace will cause bug - // use code bellow to fix the bug - const findFirstTextNode = anchor => { - if (anchor.nodeType === 3) return anchor - const children = anchor.childNodes - for (const node of children) { - if (node.nodeName !== 'INPUT') { - return findFirstTextNode(node) - } - } - } - if (anchorNode.nodeName === 'LI') { - anchorNode = findFirstTextNode(anchorNode) - } - const getOffsetOfParagraph = (node, paragraph) => { let offset = 0 let preSibling = node @@ -481,11 +500,13 @@ class Selection { : offset + getOffsetOfParagraph(node.parentNode, paragraph) } + let result = null + if (startParagraph === endParagraph) { const key = startParagraph.id const offset1 = getOffsetOfParagraph(anchorNode, startParagraph) + anchorOffset const offset2 = getOffsetOfParagraph(focusNode, endParagraph) + focusOffset - return { + result = { start: { key, offset: Math.min(offset1, offset2) }, end: { key, offset: Math.max(offset1, offset2) } } @@ -503,11 +524,15 @@ class Selection { } } if (order) { - return rawCursor + result = rawCursor } else { - return { start: rawCursor.end, end: rawCursor.start } + result = { start: rawCursor.end, end: rawCursor.start } } } + if (needFix) { + this.setCursorRange(result) + } + return result } // topOffset is the line counts above cursor, and bottomOffset is line counts bellow cursor.