0
Fork 0
mirror of https://github.com/fastmail/Squire.git synced 2024-12-22 15:23:29 -05:00
Squire/source/range/Contents.ts

66 lines
1.8 KiB
TypeScript
Raw Normal View History

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();
}
// Replace nbsp with regular space;
// eslint-disable-next-line no-irregular-whitespace
textContent = textContent.replace(/ /g, ' ');
return textContent;
};
// ---
export { getTextContentsOfRange };