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:
parent
9aa62781d0
commit
3937c10b55
2 changed files with 65 additions and 52 deletions
|
@ -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
62
source/range/Contents.ts
Normal 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 };
|
Loading…
Reference in a new issue