@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
JavaScript
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
};