UNPKG

@pdf-viewer/react

Version:

A react-pdf-viewer component for React and Next.js. Suitable for react-pdf document.

77 lines (76 loc) 2.92 kB
import { useCallback as p, useEffect as b } from "react"; const D = ({ onTextSelect: s, pagesRef: n }) => { const f = p(() => { const e = n == null ? void 0 : n.querySelectorAll('[data-rp$="-textLayer"]'); return e ? Array.from(e) : []; }, [n]), N = p(() => { const e = document.getSelection(); if (!e || e.rangeCount === 0 || e.toString().trim() === "") return null; const E = e.toString(), a = /* @__PURE__ */ new Map(), O = f(); for (let i = 0; i < e.rangeCount; i++) { const t = e.getRangeAt(i); O.forEach((d) => { if (t.intersectsNode(d)) { const g = d.getAttribute("data-rp"), T = g == null ? void 0 : g.match(/page-(\d+)-textLayer/); if (T) { const h = parseInt(T[1]), C = d.closest('[data-rp*="page-"]'); if (!C) return; const c = C.getBoundingClientRect(); a.has(h) || a.set(h, { rects: [], pageRect: c }); const y = a.get(h), _ = document.createTreeWalker(d, NodeFilter.SHOW_TEXT, null); let u; for (; u = _.nextNode(); ) if (t.intersectsNode(u) && u.parentElement) { const o = document.createRange(); o.selectNodeContents(u); const A = t.compareBoundaryPoints(Range.START_TO_START, o) > 0 ? t.startContainer : o.startContainer, B = t.compareBoundaryPoints(Range.START_TO_START, o) > 0 ? t.startOffset : o.startOffset, R = t.compareBoundaryPoints(Range.END_TO_END, o) < 0 ? t.endContainer : o.endContainer, S = t.compareBoundaryPoints(Range.END_TO_END, o) < 0 ? t.endOffset : o.endOffset, m = document.createRange(); m.setStart(A, B), m.setEnd(R, S); const r = m.getBoundingClientRect(); if (r.width === 0 || r.height === 0) continue; const P = { left: r.left - c.left, top: r.top - c.top, right: r.right - c.left, bottom: r.bottom - c.top, width: r.width, height: r.height }; y.rects.push(P); } } } }); } const w = Array.from(a.entries()).sort(([i], [t]) => i - t).map(([i, t]) => ({ pageNumber: i, pageBasedBoundingRects: t.rects, pageDimension: { width: t.pageRect.width, height: t.pageRect.height }, pagePositionInWindow: { x: t.pageRect.left, y: t.pageRect.top } })); return { text: E, pageSelections: w }; }, [f]), l = p(() => { const e = N(); e && (s == null || s(e)); }, [N, s]); b(() => (n == null || n.addEventListener("pointerup", l), () => { n == null || n.removeEventListener("pointerup", l); }), [n, l]); }; export { D as useTextSelection };