2023-10-01 21:12:51 -05:00
|
|
|
|
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();
|
|
|
|
|
}
|
2023-10-01 21:23:12 -05:00
|
|
|
|
// Replace nbsp with regular space;
|
|
|
|
|
// eslint-disable-next-line no-irregular-whitespace
|
|
|
|
|
textContent = textContent.replace(/ /g, ' ');
|
2023-10-01 21:12:51 -05:00
|
|
|
|
|
|
|
|
|
return textContent;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// ---
|
|
|
|
|
|
|
|
|
|
export { getTextContentsOfRange };
|