0
Fork 0
mirror of https://github.com/fastmail/Squire.git synced 2024-12-22 07:13:08 -05:00

Extract getTextContentsOfRange helper fn

This commit is contained in:
Neil Jenkins 2023-10-02 13:12:51 +11:00
parent 9aa62781d0
commit 3937c10b55
2 changed files with 65 additions and 52 deletions

View file

@ -58,6 +58,7 @@ import {
} from './Clipboard'; } from './Clipboard';
import { keyHandlers, _onKey } from './keyboard/KeyHandlers'; import { keyHandlers, _onKey } from './keyboard/KeyHandlers';
import { linkifyText } from './keyboard/KeyHelpers'; import { linkifyText } from './keyboard/KeyHelpers';
import { getTextContentsOfRange } from './range/Contents';
declare const DOMPurify: any; declare const DOMPurify: any;
@ -1235,58 +1236,8 @@ class Squire {
return this.insertHTML(lines.join(''), isPaste); return this.insertHTML(lines.join(''), isPaste);
} }
getSelectedText(): string { getSelectedText(range?: Range): string {
const range = this.getSelection(); return getTextContentsOfRange(range || this.getSelection());
if (range.collapsed) {
return '';
}
const startContainer = range.startContainer;
const endContainer = range.endContainer;
const walker = new TreeIterator<Element | Text>(
range.commonAncestorContainer,
SHOW_ELEMENT_OR_TEXT,
(node) => {
return isNodeContainedInRange(range, node, true);
},
);
walker.currentNode = startContainer;
let node: Node | null = startContainer;
let textContent = '';
let addedTextInBlock = false;
let value: string;
if (
(!(node instanceof Element) && !(node instanceof Text)) ||
!walker.filter(node)
) {
node = walker.nextNode();
}
while (node) {
if (node instanceof Text) {
value = node.data;
if (value && /\S/.test(value)) {
if (node === endContainer) {
value = value.slice(0, range.endOffset);
}
if (node === startContainer) {
value = value.slice(range.startOffset);
}
textContent += value;
addedTextInBlock = true;
}
} else if (
node.nodeName === 'BR' ||
(addedTextInBlock && !isInline(node))
) {
textContent += '\n';
addedTextInBlock = false;
}
node = walker.nextNode();
}
return textContent;
} }
// --- Inline formatting // --- Inline formatting

62
source/range/Contents.ts Normal file
View file

@ -0,0 +1,62 @@
import { SHOW_ELEMENT_OR_TEXT, TreeIterator } from '../node/TreeIterator';
import { isNodeContainedInRange } from './Boundaries';
import { isInline } from '../node/Category';
// ---
const getTextContentsOfRange = (range: Range) => {
if (range.collapsed) {
return '';
}
const startContainer = range.startContainer;
const endContainer = range.endContainer;
const walker = new TreeIterator<Element | Text>(
range.commonAncestorContainer,
SHOW_ELEMENT_OR_TEXT,
(node) => {
return isNodeContainedInRange(range, node, true);
},
);
walker.currentNode = startContainer;
let node: Node | null = startContainer;
let textContent = '';
let addedTextInBlock = false;
let value: string;
if (
(!(node instanceof Element) && !(node instanceof Text)) ||
!walker.filter(node)
) {
node = walker.nextNode();
}
while (node) {
if (node instanceof Text) {
value = node.data;
if (value && /\S/.test(value)) {
if (node === endContainer) {
value = value.slice(0, range.endOffset);
}
if (node === startContainer) {
value = value.slice(range.startOffset);
}
textContent += value;
addedTextInBlock = true;
}
} else if (
node.nodeName === 'BR' ||
(addedTextInBlock && !isInline(node))
) {
textContent += '\n';
addedTextInBlock = false;
}
node = walker.nextNode();
}
return textContent;
};
// ---
export { getTextContentsOfRange };