Merge pull request #3029 from matrix-org/bwindels/pill-n-newlines

Fix: maintain caret at current line when position is on newline part
This commit is contained in:
Bruno Windels 2019-05-31 08:44:02 +00:00 committed by GitHub
commit eb8dd52437
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 12 deletions

View file

@ -20,13 +20,23 @@ export function setCaretPosition(editor, model, caretPosition) {
sel.removeAllRanges(); sel.removeAllRanges();
const range = document.createRange(); const range = document.createRange();
const {parts} = model; const {parts} = model;
const {index} = caretPosition;
let {offset} = caretPosition;
let lineIndex = 0; let lineIndex = 0;
let nodeIndex = -1; let nodeIndex = -1;
for (let i = 0; i <= caretPosition.index; ++i) { for (let i = 0; i <= index; ++i) {
const part = parts[i]; const part = parts[i];
if (part && part.type === "newline") { if (part && part.type === "newline") {
if (i < index) {
lineIndex += 1; lineIndex += 1;
nodeIndex = -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 { } else {
nodeIndex += 1; nodeIndex += 1;
} }
@ -34,23 +44,20 @@ export function setCaretPosition(editor, model, caretPosition) {
let focusNode; let focusNode;
const lineNode = editor.childNodes[lineIndex]; const lineNode = editor.childNodes[lineIndex];
if (lineNode) { if (lineNode) {
if (lineNode.childNodes.length === 0 && caretPosition.offset === 0) {
focusNode = lineNode;
} else {
focusNode = lineNode.childNodes[nodeIndex]; focusNode = lineNode.childNodes[nodeIndex];
if (!focusNode) {
if (focusNode && focusNode.nodeType === Node.ELEMENT_NODE) { focusNode = lineNode;
} else if (focusNode.nodeType === Node.ELEMENT_NODE) {
focusNode = focusNode.childNodes[0]; focusNode = focusNode.childNodes[0];
} }
} }
}
// node not found, set caret at end // node not found, set caret at end
if (!focusNode) { if (!focusNode) {
range.selectNodeContents(editor); range.selectNodeContents(editor);
range.collapse(false); range.collapse(false);
} else { } else {
// make sure we have a text node // make sure we have a text node
range.setStart(focusNode, caretPosition.offset); range.setStart(focusNode, offset);
range.collapse(true); range.collapse(true);
} }
sel.addRange(range); sel.addRange(range);

View file

@ -61,12 +61,13 @@ export function renderModel(editor, model) {
let foundBR = false; let foundBR = false;
let partNode = lineContainer.firstChild; let partNode = lineContainer.firstChild;
while (partNode) { while (partNode) {
const nextNode = partNode.nextSibling;
if (!foundBR && partNode.tagName === "BR") { if (!foundBR && partNode.tagName === "BR") {
foundBR = true; foundBR = true;
} else { } else {
lineContainer.removeChild(partNode); lineContainer.removeChild(partNode);
} }
partNode = partNode.nextSibling; partNode = nextNode;
} }
if (!foundBR) { if (!foundBR) {
lineContainer.appendChild(document.createElement("br")); lineContainer.appendChild(document.createElement("br"));