@huridocs/react-text-selection-handler
Version:
React pdf handler allows to render a PDF and handle text selection and highlights.
52 lines • 2.12 kB
JavaScript
const getLeafNodes = (node) => {
if (node.nodeType === Node.TEXT_NODE) {
return [node];
}
if (node.nodeType === Node.ELEMENT_NODE) {
const element = node;
if (element.tagName === 'BR') {
return [node];
}
}
return Array.from(node.childNodes).reduce((acc, child) => acc.concat(getLeafNodes(child)), []);
};
const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
export const normalizeSpaces = (text) => {
const pairedCharacters = {
'(': ')',
'[': ']',
'{': '}',
'"': '"',
"'": "'",
};
let result = text;
Object.entries(pairedCharacters).forEach(([openChar, closeChar]) => {
const escapedOpen = escapeRegExp(openChar);
const escapedClose = escapeRegExp(closeChar);
const pattern = new RegExp(`${escapedOpen}\\s*(.*?)\\s*${escapedClose}`, 'g');
result = result.replace(pattern, `${openChar}$1${closeChar}`);
});
const spaceAfterChars = escapeRegExp('$£€@#');
const spaceBeforeChars = escapeRegExp(',.!?:;');
result = result.replace(new RegExp(`([${spaceAfterChars}])\\s+`, 'g'), '$1');
result = result.replace(new RegExp(`\\s+([${spaceBeforeChars}])`, 'g'), '$1');
return result;
};
export const getRangeSelectedText = (range, containerElement) => {
const rangeContent = range.cloneContents();
const elements = getLeafNodes(rangeContent)
.filter(node => containerElement.contains(range.commonAncestorContainer.contains(node) ? node : range.commonAncestorContainer))
.map((node) => {
var _a, _b;
if (node.nodeType === Node.ELEMENT_NODE) {
const element = node;
if (element.tagName === 'BR')
return '\n';
return ((_a = element.textContent) === null || _a === void 0 ? void 0 : _a.trim()) || '';
}
return ((_b = node.textContent) === null || _b === void 0 ? void 0 : _b.trim()) || '';
})
.filter(Boolean);
return normalizeSpaces(elements.join(' '));
};
//# sourceMappingURL=getRangeSelectedText.js.map