From b2592583c47a121f8f0401175e050b962c9589ff Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 24 May 2019 18:54:29 +0200 Subject: [PATCH 1/3] maintain caret at current line when position is on newline part --- src/editor/caret.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/editor/caret.js b/src/editor/caret.js index 974c8802a4..5ff9dbc950 100644 --- a/src/editor/caret.js +++ b/src/editor/caret.js @@ -20,13 +20,23 @@ export function setCaretPosition(editor, model, caretPosition) { sel.removeAllRanges(); const range = document.createRange(); const {parts} = model; + const {index} = caretPosition; + let {offset} = caretPosition; let lineIndex = 0; let nodeIndex = -1; - for (let i = 0; i <= caretPosition.index; ++i) { + for (let i = 0; i <= index; ++i) { const part = parts[i]; if (part && part.type === "newline") { - lineIndex += 1; - nodeIndex = -1; + if (i < index) { + lineIndex += 1; + nodeIndex = -1; + } else { + // if index points at a newline part, + // put the caret at the end of the previous part + // so it stays on the same line + const prevPart = parts[i - 1]; + offset = prevPart ? prevPart.text.length : 0; + } } else { nodeIndex += 1; } @@ -34,7 +44,7 @@ export function setCaretPosition(editor, model, caretPosition) { let focusNode; const lineNode = editor.childNodes[lineIndex]; if (lineNode) { - if (lineNode.childNodes.length === 0 && caretPosition.offset === 0) { + if (lineNode.childNodes.length === 0 && offset === 0) { focusNode = lineNode; } else { focusNode = lineNode.childNodes[nodeIndex]; @@ -50,7 +60,7 @@ export function setCaretPosition(editor, model, caretPosition) { range.collapse(false); } else { // make sure we have a text node - range.setStart(focusNode, caretPosition.offset); + range.setStart(focusNode, offset); range.collapse(true); } sel.addRange(range); From 4fc23022f435e193793f56c09abe46e6bd4814d9 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Tue, 28 May 2019 10:01:16 +0200 Subject: [PATCH 2/3] remove all non-first-br nodes on new empty line, not just first one nextSibling returned null after calling removeNode, so get the nextSibling first --- src/editor/render.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/editor/render.js b/src/editor/render.js index caea18e3ca..58ef0eaee1 100644 --- a/src/editor/render.js +++ b/src/editor/render.js @@ -61,12 +61,13 @@ export function renderModel(editor, model) { let foundBR = false; let partNode = lineContainer.firstChild; while (partNode) { + const nextNode = partNode.nextSibling; if (!foundBR && partNode.tagName === "BR") { foundBR = true; } else { lineContainer.removeChild(partNode); } - partNode = partNode.nextSibling; + partNode = nextNode; } if (!foundBR) { lineContainer.appendChild(document.createElement("br")); From 6b680ff6811bec3a01670c3c1f14f102ffed3b62 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Tue, 28 May 2019 10:34:29 +0200 Subject: [PATCH 3/3] fallback to setting caret on line node for empty lines instead of setting at the end of the editor --- src/editor/caret.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/editor/caret.js b/src/editor/caret.js index 5ff9dbc950..f93e9604d5 100644 --- a/src/editor/caret.js +++ b/src/editor/caret.js @@ -44,14 +44,11 @@ export function setCaretPosition(editor, model, caretPosition) { let focusNode; const lineNode = editor.childNodes[lineIndex]; if (lineNode) { - if (lineNode.childNodes.length === 0 && offset === 0) { + focusNode = lineNode.childNodes[nodeIndex]; + if (!focusNode) { focusNode = lineNode; - } else { - focusNode = lineNode.childNodes[nodeIndex]; - - if (focusNode && focusNode.nodeType === Node.ELEMENT_NODE) { - focusNode = focusNode.childNodes[0]; - } + } else if (focusNode.nodeType === Node.ELEMENT_NODE) { + focusNode = focusNode.childNodes[0]; } } // node not found, set caret at end