@anaralabs/lector 3.5.8 → 3.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +213 -35
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1055,39 +1055,69 @@ var shouldMergeRects = (rect1, rect2) => {
|
|
|
1055
1055
|
const horizontallyClose = Math.abs(rect1.left + rect1.width - rect2.left) < MERGE_THRESHOLD || Math.abs(rect2.left + rect2.width - rect1.left) < MERGE_THRESHOLD || rect1.left < rect2.left + rect2.width && rect2.left < rect1.left + rect1.width;
|
|
1056
1056
|
return verticalOverlap && horizontallyClose;
|
|
1057
1057
|
};
|
|
1058
|
-
var mergeRects = (rect1, rect2) => {
|
|
1059
|
-
return {
|
|
1060
|
-
left: Math.min(rect1.left, rect2.left),
|
|
1061
|
-
top: Math.min(rect1.top, rect2.top),
|
|
1062
|
-
width: Math.max(rect1.left + rect1.width, rect2.left + rect2.width) - Math.min(rect1.left, rect2.left),
|
|
1063
|
-
height: Math.max(rect1.top + rect1.height, rect2.top + rect2.height) - Math.min(rect1.top, rect2.top),
|
|
1064
|
-
pageNumber: rect1.pageNumber
|
|
1065
|
-
};
|
|
1066
|
-
};
|
|
1067
1058
|
var consolidateRects = (rects) => {
|
|
1068
1059
|
if (rects.length <= 1) return rects;
|
|
1069
|
-
const
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1060
|
+
const result = [];
|
|
1061
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1062
|
+
for (let i = 0; i < rects.length; i++) {
|
|
1063
|
+
if (visited.has(i)) continue;
|
|
1064
|
+
const currentRect = rects[i];
|
|
1065
|
+
if (!currentRect) continue;
|
|
1066
|
+
const currentGroup = [currentRect];
|
|
1067
|
+
visited.add(i);
|
|
1068
|
+
let foundNew = true;
|
|
1069
|
+
while (foundNew) {
|
|
1070
|
+
foundNew = false;
|
|
1071
|
+
for (let j = 0; j < rects.length; j++) {
|
|
1072
|
+
if (visited.has(j)) continue;
|
|
1073
|
+
const candidateRect = rects[j];
|
|
1074
|
+
if (!candidateRect) continue;
|
|
1075
|
+
const shouldMergeWithGroup = currentGroup.some(
|
|
1076
|
+
(groupRect) => doRectsOverlap(groupRect, candidateRect)
|
|
1077
|
+
);
|
|
1078
|
+
if (shouldMergeWithGroup) {
|
|
1079
|
+
currentGroup.push(candidateRect);
|
|
1080
|
+
visited.add(j);
|
|
1081
|
+
foundNew = true;
|
|
1082
|
+
}
|
|
1084
1083
|
}
|
|
1085
1084
|
}
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1085
|
+
result.push(mergeRectGroup(currentGroup));
|
|
1086
|
+
}
|
|
1087
|
+
return result;
|
|
1088
|
+
};
|
|
1089
|
+
var doRectsOverlap = (rect1, rect2) => {
|
|
1090
|
+
const horizontalOverlap = rect1.left < rect2.left + rect2.width && rect2.left < rect1.left + rect1.width;
|
|
1091
|
+
const verticalOverlap = rect1.top < rect2.top + rect2.height && rect2.top < rect1.top + rect1.height;
|
|
1092
|
+
const closeEnough = shouldMergeRects(rect1, rect2);
|
|
1093
|
+
return horizontalOverlap && verticalOverlap || closeEnough;
|
|
1094
|
+
};
|
|
1095
|
+
var mergeRectGroup = (rects) => {
|
|
1096
|
+
if (rects.length === 1) {
|
|
1097
|
+
const rect = rects[0];
|
|
1098
|
+
if (!rect) throw new Error("Invalid rect in group");
|
|
1099
|
+
return rect;
|
|
1100
|
+
}
|
|
1101
|
+
const firstRect = rects[0];
|
|
1102
|
+
if (!firstRect) throw new Error("Invalid first rect in group");
|
|
1103
|
+
let minLeft = firstRect.left;
|
|
1104
|
+
let minTop = firstRect.top;
|
|
1105
|
+
let maxRight = firstRect.left + firstRect.width;
|
|
1106
|
+
let maxBottom = firstRect.top + firstRect.height;
|
|
1107
|
+
rects.forEach((rect) => {
|
|
1108
|
+
if (!rect) return;
|
|
1109
|
+
minLeft = Math.min(minLeft, rect.left);
|
|
1110
|
+
minTop = Math.min(minTop, rect.top);
|
|
1111
|
+
maxRight = Math.max(maxRight, rect.left + rect.width);
|
|
1112
|
+
maxBottom = Math.max(maxBottom, rect.top + rect.height);
|
|
1113
|
+
});
|
|
1114
|
+
return {
|
|
1115
|
+
left: minLeft,
|
|
1116
|
+
top: minTop,
|
|
1117
|
+
width: maxRight - minLeft,
|
|
1118
|
+
height: maxBottom - minTop,
|
|
1119
|
+
pageNumber: firstRect.pageNumber
|
|
1120
|
+
};
|
|
1091
1121
|
};
|
|
1092
1122
|
var useSelectionDimensions = () => {
|
|
1093
1123
|
const store = PDFStore.useContext();
|
|
@@ -1127,7 +1157,8 @@ var useSelectionDimensions = () => {
|
|
|
1127
1157
|
});
|
|
1128
1158
|
textLayerMap.forEach((rects) => {
|
|
1129
1159
|
if (rects.length > 0) {
|
|
1130
|
-
|
|
1160
|
+
const consolidated = consolidateRects(rects);
|
|
1161
|
+
highlights.push(...consolidated);
|
|
1131
1162
|
}
|
|
1132
1163
|
});
|
|
1133
1164
|
return {
|
|
@@ -1522,24 +1553,171 @@ var HighlightLayer = forwardRef(({ asChild, className, style, ...props }, ref) =
|
|
|
1522
1553
|
}) });
|
|
1523
1554
|
});
|
|
1524
1555
|
HighlightLayer.displayName = "HighlightLayer";
|
|
1556
|
+
var createTextSelectionManager = () => {
|
|
1557
|
+
const textLayers = /* @__PURE__ */ new Map();
|
|
1558
|
+
let selectionChangeAbortController = null;
|
|
1559
|
+
let isPointerDown = false;
|
|
1560
|
+
let prevRange = null;
|
|
1561
|
+
let isFirefox;
|
|
1562
|
+
const removeGlobalSelectionListener = (textLayerDiv) => {
|
|
1563
|
+
textLayers.delete(textLayerDiv);
|
|
1564
|
+
if (textLayers.size === 0) {
|
|
1565
|
+
selectionChangeAbortController?.abort();
|
|
1566
|
+
selectionChangeAbortController = null;
|
|
1567
|
+
}
|
|
1568
|
+
};
|
|
1569
|
+
const enableGlobalSelectionListener = () => {
|
|
1570
|
+
if (selectionChangeAbortController) {
|
|
1571
|
+
return;
|
|
1572
|
+
}
|
|
1573
|
+
selectionChangeAbortController = new AbortController();
|
|
1574
|
+
const { signal } = selectionChangeAbortController;
|
|
1575
|
+
const reset = (endDiv, textLayer) => {
|
|
1576
|
+
if (endDiv.parentNode !== textLayer) {
|
|
1577
|
+
textLayer.appendChild(endDiv);
|
|
1578
|
+
}
|
|
1579
|
+
endDiv.style.width = "";
|
|
1580
|
+
endDiv.style.height = "";
|
|
1581
|
+
textLayer.classList.remove("selecting");
|
|
1582
|
+
};
|
|
1583
|
+
document.addEventListener("pointerdown", () => {
|
|
1584
|
+
isPointerDown = true;
|
|
1585
|
+
}, { signal });
|
|
1586
|
+
document.addEventListener("pointerup", () => {
|
|
1587
|
+
isPointerDown = false;
|
|
1588
|
+
textLayers.forEach(reset);
|
|
1589
|
+
}, { signal });
|
|
1590
|
+
window.addEventListener("blur", () => {
|
|
1591
|
+
isPointerDown = false;
|
|
1592
|
+
textLayers.forEach(reset);
|
|
1593
|
+
}, { signal });
|
|
1594
|
+
document.addEventListener("keyup", () => {
|
|
1595
|
+
if (!isPointerDown) {
|
|
1596
|
+
textLayers.forEach(reset);
|
|
1597
|
+
}
|
|
1598
|
+
}, { signal });
|
|
1599
|
+
document.addEventListener("selectionchange", () => {
|
|
1600
|
+
const selection = document.getSelection();
|
|
1601
|
+
if (!selection || selection.rangeCount === 0) {
|
|
1602
|
+
textLayers.forEach(reset);
|
|
1603
|
+
return;
|
|
1604
|
+
}
|
|
1605
|
+
const activeTextLayers = /* @__PURE__ */ new Set();
|
|
1606
|
+
for (let i = 0; i < selection.rangeCount; i++) {
|
|
1607
|
+
const range = selection.getRangeAt(i);
|
|
1608
|
+
for (const textLayerDiv of textLayers.keys()) {
|
|
1609
|
+
if (!activeTextLayers.has(textLayerDiv) && range.intersectsNode(textLayerDiv)) {
|
|
1610
|
+
activeTextLayers.add(textLayerDiv);
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
for (const [textLayerDiv, endDiv] of textLayers) {
|
|
1615
|
+
if (activeTextLayers.has(textLayerDiv)) {
|
|
1616
|
+
textLayerDiv.classList.add("selecting");
|
|
1617
|
+
} else {
|
|
1618
|
+
reset(endDiv, textLayerDiv);
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
if (isFirefox === void 0) {
|
|
1622
|
+
const firstTextLayer = textLayers.keys().next().value;
|
|
1623
|
+
if (firstTextLayer) {
|
|
1624
|
+
isFirefox = getComputedStyle(firstTextLayer).getPropertyValue("-moz-user-select") === "none";
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
if (isFirefox) {
|
|
1628
|
+
return;
|
|
1629
|
+
}
|
|
1630
|
+
try {
|
|
1631
|
+
const range = selection.getRangeAt(0);
|
|
1632
|
+
const modifyStart = prevRange && (range.compareBoundaryPoints(Range.END_TO_END, prevRange) === 0 || range.compareBoundaryPoints(Range.START_TO_END, prevRange) === 0);
|
|
1633
|
+
let anchor = modifyStart ? range.startContainer : range.endContainer;
|
|
1634
|
+
if (anchor.nodeType === Node.TEXT_NODE) {
|
|
1635
|
+
anchor = anchor.parentNode;
|
|
1636
|
+
}
|
|
1637
|
+
const parentTextLayer = anchor.parentElement?.closest(".textLayer");
|
|
1638
|
+
const endDiv = textLayers.get(parentTextLayer);
|
|
1639
|
+
if (endDiv && parentTextLayer) {
|
|
1640
|
+
endDiv.style.width = parentTextLayer.style.width;
|
|
1641
|
+
endDiv.style.height = parentTextLayer.style.height;
|
|
1642
|
+
const insertTarget = modifyStart ? anchor : anchor.nextSibling;
|
|
1643
|
+
if (anchor.parentElement && insertTarget) {
|
|
1644
|
+
anchor.parentElement.insertBefore(endDiv, insertTarget);
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
prevRange = range.cloneRange();
|
|
1648
|
+
} catch {
|
|
1649
|
+
}
|
|
1650
|
+
}, { signal });
|
|
1651
|
+
};
|
|
1652
|
+
const bindMouseEvents2 = (textLayerDiv, endOfContent) => {
|
|
1653
|
+
if (textLayerDiv._textSelectionBound) {
|
|
1654
|
+
return;
|
|
1655
|
+
}
|
|
1656
|
+
textLayerDiv._textSelectionBound = true;
|
|
1657
|
+
textLayers.set(textLayerDiv, endOfContent);
|
|
1658
|
+
enableGlobalSelectionListener();
|
|
1659
|
+
const handleMouseDown = () => {
|
|
1660
|
+
textLayerDiv.classList.add("selecting");
|
|
1661
|
+
};
|
|
1662
|
+
textLayerDiv.addEventListener("mousedown", handleMouseDown);
|
|
1663
|
+
textLayerDiv._cleanupTextSelection = () => {
|
|
1664
|
+
textLayerDiv.removeEventListener("mousedown", handleMouseDown);
|
|
1665
|
+
removeGlobalSelectionListener(textLayerDiv);
|
|
1666
|
+
delete textLayerDiv._textSelectionBound;
|
|
1667
|
+
};
|
|
1668
|
+
};
|
|
1669
|
+
return bindMouseEvents2;
|
|
1670
|
+
};
|
|
1671
|
+
var bindMouseEvents = createTextSelectionManager();
|
|
1525
1672
|
var useTextLayer = () => {
|
|
1526
1673
|
const textContainerRef = useRef(null);
|
|
1674
|
+
const textLayerRef = useRef(null);
|
|
1675
|
+
const isRenderingRef = useRef(false);
|
|
1527
1676
|
const pageNumber = usePDFPageNumber();
|
|
1528
1677
|
const pdfPageProxy = usePdf((state) => state.getPdfPageProxy(pageNumber));
|
|
1529
1678
|
useEffect(() => {
|
|
1530
|
-
|
|
1679
|
+
const textContainer = textContainerRef.current;
|
|
1680
|
+
if (!textContainer || isRenderingRef.current) {
|
|
1531
1681
|
return;
|
|
1532
1682
|
}
|
|
1683
|
+
isRenderingRef.current = true;
|
|
1684
|
+
textContainer.innerHTML = "";
|
|
1685
|
+
if (textLayerRef.current) {
|
|
1686
|
+
textLayerRef.current.cancel();
|
|
1687
|
+
textLayerRef.current = null;
|
|
1688
|
+
}
|
|
1533
1689
|
const textLayer = new TextLayer({
|
|
1534
1690
|
textContentSource: pdfPageProxy.streamTextContent(),
|
|
1535
|
-
container:
|
|
1691
|
+
container: textContainer,
|
|
1536
1692
|
viewport: pdfPageProxy.getViewport({ scale: 1 })
|
|
1537
1693
|
});
|
|
1538
|
-
|
|
1694
|
+
textLayerRef.current = textLayer;
|
|
1695
|
+
textLayer.render().then(() => {
|
|
1696
|
+
if (textLayerRef.current === textLayer && textContainer) {
|
|
1697
|
+
const endOfContent = document.createElement("div");
|
|
1698
|
+
endOfContent.className = "endOfContent";
|
|
1699
|
+
textContainer.appendChild(endOfContent);
|
|
1700
|
+
bindMouseEvents(textContainer, endOfContent);
|
|
1701
|
+
}
|
|
1702
|
+
}).catch((error) => {
|
|
1703
|
+
if (error.name !== "AbortException") {
|
|
1704
|
+
console.error("TextLayer rendering error:", error);
|
|
1705
|
+
}
|
|
1706
|
+
}).finally(() => {
|
|
1707
|
+
isRenderingRef.current = false;
|
|
1708
|
+
});
|
|
1539
1709
|
return () => {
|
|
1540
|
-
|
|
1710
|
+
isRenderingRef.current = false;
|
|
1711
|
+
if (textLayerRef.current) {
|
|
1712
|
+
textLayerRef.current.cancel();
|
|
1713
|
+
textLayerRef.current = null;
|
|
1714
|
+
}
|
|
1715
|
+
if (textContainer?._cleanupTextSelection) {
|
|
1716
|
+
textContainer._cleanupTextSelection();
|
|
1717
|
+
delete textContainer._cleanupTextSelection;
|
|
1718
|
+
}
|
|
1541
1719
|
};
|
|
1542
|
-
}, [pdfPageProxy]);
|
|
1720
|
+
}, [pdfPageProxy.pageNumber]);
|
|
1543
1721
|
return {
|
|
1544
1722
|
textContainerRef,
|
|
1545
1723
|
pageNumber: pdfPageProxy.pageNumber
|