Fix keyboard selection controls

This commit is contained in:
Dominic Gannaway
2020-11-11 19:04:19 +00:00
committed by acywatson
parent 8a988b51d2
commit 77cabffa4b
3 changed files with 112 additions and 2 deletions

View File

@ -456,6 +456,107 @@ export class Selection {
currentBlock.normalizeTextNodes(true);
}
}
moveWordBackward() {
const anchorNode = this.getAnchorNode();
const focusNode = this.getFocusNode();
if (anchorNode === null || focusNode === null) {
return;
}
const isAnchorBefore = anchorNode.isBefore(focusNode);
const anchorOffset = this.anchorOffset;
const focusOffset = this.focusOffset;
const firstNode = isAnchorBefore ? anchorNode : focusNode;
const textContent = firstNode.getTextContent();
const textContentLength = textContent.length;
let prevSibling = firstNode.getPreviousSibling();
let offset = isAnchorBefore ? anchorOffset : focusOffset;
if (anchorNode === focusNode) {
offset = focusOffset > anchorOffset ? anchorOffset : focusOffset;
}
const trimmedTextContentLength = textContent.trimStart().length;
if (
prevSibling !== null &&
(offset === 0 || textContentLength - trimmedTextContentLength > offset)
) {
while (prevSibling !== null) {
if (
prevSibling.isText() &&
!prevSibling.isImmutable() &&
!prevSibling.isSegmented()
) {
break;
}
prevSibling = prevSibling.getPreviousSibling();
}
if (prevSibling !== null) {
((prevSibling: any): TextNode).select();
}
} else {
const trimmedContent = textContent.slice(0, offset).trimEnd();
let index = trimmedContent.lastIndexOf(' ');
if (index === -1) {
index = 0;
} else {
index++;
}
this.anchorOffset = index;
this.focusOffset = index;
this.markDirty();
}
}
moveWordForward() {
const anchorNode = this.getAnchorNode();
const focusNode = this.getFocusNode();
if (anchorNode === null || focusNode === null) {
return;
}
const isAnchorBefore = anchorNode.isBefore(focusNode);
const anchorOffset = this.anchorOffset;
const focusOffset = this.focusOffset;
const lastNode = isAnchorBefore ? focusNode : anchorNode;
const textContent = lastNode.getTextContent();
const textContentLength = textContent.length;
let nextSibling = lastNode.getNextSibling();
let offset = isAnchorBefore ? focusOffset : anchorOffset;
if (anchorNode === focusNode) {
offset = focusOffset > anchorOffset ? focusOffset : anchorOffset;
}
let trimmedTextContentLength = textContent.trimEnd().length;
if (
nextSibling !== null &&
(offset === textContentLength || offset >= trimmedTextContentLength)
) {
while (nextSibling !== null) {
if (
nextSibling.isText() &&
!nextSibling.isImmutable() &&
!nextSibling.isSegmented()
) {
break;
}
nextSibling = nextSibling.getNextSibling();
}
if (nextSibling !== null) {
((nextSibling: any): TextNode).select(0, 0);
}
} else {
const trimmedContent = textContent.slice(offset).trimStart();
trimmedTextContentLength = trimmedContent.length;
let index = trimmedContent.indexOf(' ');
if (index === -1) {
index = textContentLength;
} else {
index = textContentLength - trimmedTextContentLength + index;
}
this.anchorOffset = index;
this.focusOffset = index;
this.markDirty();
}
}
moveBackward() {
const anchorNode = this.getAnchorNode();
const focusNode = this.getFocusNode();

View File

@ -185,10 +185,11 @@ function setTextContent(
dom.appendChild(document.createElement('br'));
}
return;
} else if (nextText.endsWith('\n')) {
nextText += '\n';
}
}
if (nextText.endsWith('\n')) {
nextText += '\n';
}
if (firstChild == null || hasBreakNode) {
dom.textContent = nextText === '' ? zeroWidthString : nextText;
} else if (prevText !== nextText) {

View File

@ -7,6 +7,8 @@ import {
isLineBreak,
isMoveBackward,
isMoveForward,
isMoveWordBackward,
isMoveWordForward,
isParagraph,
} from './hotKeys';
@ -115,6 +117,12 @@ function onKeyDown(event, view, state) {
} else if (isMoveForward(event)) {
event.preventDefault();
selection.moveForward();
} else if (isMoveWordBackward(event)) {
event.preventDefault();
selection.moveWordBackward();
} else if (isMoveWordForward(event)) {
event.preventDefault();
selection.moveWordForward();
}
}