|
@@ -2,39 +2,27 @@ import { ANNOTATION_TYPE } from '../constants';
|
|
|
import { AnnotationType, PositionType } from '../constants/type';
|
|
|
import { parseAnnotationObject } from './annotation';
|
|
|
|
|
|
-const EXTEND_RANGE = 2;
|
|
|
-
|
|
|
-type ScalePositionFunc = (
|
|
|
- ({
|
|
|
- top, left, bottom, right,
|
|
|
- }: PositionType, scale: number) => PositionType
|
|
|
-);
|
|
|
-
|
|
|
-type GetMarkupWithSelectionFunc = (
|
|
|
- ({
|
|
|
- color, type, opacity, scale,
|
|
|
- }: {
|
|
|
- color: string;
|
|
|
- type: string;
|
|
|
- opacity: number;
|
|
|
- scale: number;
|
|
|
- }) => AnnotationType | null
|
|
|
-);
|
|
|
-
|
|
|
-const scalePosition: ScalePositionFunc = ({
|
|
|
- top, left, bottom, right,
|
|
|
-}, scale) => ({
|
|
|
- top: top / scale,
|
|
|
- left: left / scale,
|
|
|
- bottom: bottom / scale,
|
|
|
- right: right / scale,
|
|
|
-});
|
|
|
+type GetMarkupWithSelectionFunc = ({
|
|
|
+ color,
|
|
|
+ type,
|
|
|
+ opacity,
|
|
|
+ scale,
|
|
|
+}: {
|
|
|
+ color: string;
|
|
|
+ type: string;
|
|
|
+ opacity: number;
|
|
|
+ scale: number;
|
|
|
+}) => AnnotationType | null;
|
|
|
|
|
|
export const getMarkupWithSelection: GetMarkupWithSelectionFunc = ({
|
|
|
- color, type, opacity, scale,
|
|
|
+ color,
|
|
|
+ type,
|
|
|
+ opacity,
|
|
|
+ scale,
|
|
|
}) => {
|
|
|
- const selection: any = document.getSelection();
|
|
|
- if (!selection.rangeCount) return null;
|
|
|
+ const selection: Selection | null = window.getSelection();
|
|
|
+
|
|
|
+ if (!selection || !selection.rangeCount) return null;
|
|
|
|
|
|
const {
|
|
|
startContainer,
|
|
@@ -46,30 +34,38 @@ export const getMarkupWithSelection: GetMarkupWithSelectionFunc = ({
|
|
|
const endElement = endContainer.parentNode as HTMLElement;
|
|
|
const startPage = startElement?.parentNode?.parentNode as HTMLElement;
|
|
|
const endPage = endElement?.parentNode?.parentNode as HTMLElement;
|
|
|
- const startPageNum = parseInt(startPage.getAttribute('data-page-num') as string, 10);
|
|
|
- const endPageNum = parseInt(endPage.getAttribute('data-page-num') as string, 10);
|
|
|
- const textLayer = startPage.querySelector('[data-id="text-layer"]') as HTMLElement;
|
|
|
+ const startPageNum = parseInt(
|
|
|
+ startPage.getAttribute('data-page-num') as string,
|
|
|
+ 10
|
|
|
+ );
|
|
|
+ const endPageNum = parseInt(
|
|
|
+ endPage.getAttribute('data-page-num') as string,
|
|
|
+ 10
|
|
|
+ );
|
|
|
+ const textLayer = startPage.querySelector(
|
|
|
+ '[data-id="text-layer"]'
|
|
|
+ ) as HTMLElement;
|
|
|
const pageHeight = startPage.offsetHeight;
|
|
|
|
|
|
if (startPageNum !== endPageNum) return null;
|
|
|
if (startOffset === endOffset && startOffset === endOffset) return null;
|
|
|
|
|
|
- const startEle = startElement.cloneNode(true) as HTMLElement;
|
|
|
- const endEle = endElement.cloneNode(true) as HTMLElement;
|
|
|
+ const startCloneEle = startElement.cloneNode(true) as HTMLElement;
|
|
|
+ const endCloneEle = endElement.cloneNode(true) as HTMLElement;
|
|
|
|
|
|
const startText = startElement.innerText.substring(0, startOffset);
|
|
|
- const endText = endEle.innerText.substring(endOffset);
|
|
|
+ const endText = endElement.innerText.substring(endOffset);
|
|
|
|
|
|
- startEle.innerText = startText;
|
|
|
- endEle.innerText = endText;
|
|
|
- textLayer.appendChild(startEle);
|
|
|
- textLayer.appendChild(endEle);
|
|
|
+ startCloneEle.innerText = startText;
|
|
|
+ endCloneEle.innerText = endText;
|
|
|
+ textLayer.appendChild(startCloneEle);
|
|
|
+ textLayer.appendChild(endCloneEle);
|
|
|
|
|
|
- const startEleWidth = startEle.offsetWidth;
|
|
|
- const endEleWidth = endEle.offsetWidth;
|
|
|
+ const startExtraWidth = startCloneEle.getBoundingClientRect().width;
|
|
|
+ const endExtraWidth = endCloneEle.getBoundingClientRect().width;
|
|
|
|
|
|
- textLayer.removeChild(startEle);
|
|
|
- textLayer.removeChild(endEle);
|
|
|
+ textLayer.removeChild(startCloneEle);
|
|
|
+ textLayer.removeChild(endCloneEle);
|
|
|
|
|
|
const info: AnnotationType = {
|
|
|
obj_type: '',
|
|
@@ -82,73 +78,68 @@ export const getMarkupWithSelection: GetMarkupWithSelectionFunc = ({
|
|
|
};
|
|
|
const position: PositionType[] = [];
|
|
|
|
|
|
+ const startRect = startElement.getBoundingClientRect();
|
|
|
+ const endRect = endElement.getBoundingClientRect();
|
|
|
+
|
|
|
// left to right and up to down select
|
|
|
- let startX = startElement.offsetLeft + startEleWidth;
|
|
|
- let startY = startElement.offsetTop - EXTEND_RANGE;
|
|
|
- let endX = endElement.offsetLeft + endElement.offsetWidth - endEleWidth;
|
|
|
- let endY = endElement.offsetTop + endElement.offsetHeight + EXTEND_RANGE;
|
|
|
+ let startX = startElement.offsetLeft + startExtraWidth;
|
|
|
+ let startY = startElement.offsetTop;
|
|
|
+ let endX = endElement.offsetLeft + endRect.width - endExtraWidth;
|
|
|
+ let endY = endElement.offsetTop + endRect.height;
|
|
|
|
|
|
if (startX > endX && startY >= endY) {
|
|
|
// right to left and down to up select
|
|
|
- startX = endElement.offsetLeft + startEleWidth;
|
|
|
- startY = endElement.offsetTop - EXTEND_RANGE;
|
|
|
- endX = startElement.offsetLeft + startElement.offsetWidth - endEleWidth;
|
|
|
- endY = startElement.offsetTop + startElement.offsetHeight + EXTEND_RANGE;
|
|
|
+ startX = endElement.offsetLeft + startExtraWidth;
|
|
|
+ startY = endElement.offsetTop;
|
|
|
+ endX = startElement.offsetLeft + startRect.width - endExtraWidth;
|
|
|
+ endY = startElement.offsetTop + startRect.height;
|
|
|
}
|
|
|
+ // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
|
// @ts-ignore
|
|
|
const textElements = [...textLayer.childNodes];
|
|
|
|
|
|
- textElements.forEach((ele: any) => {
|
|
|
- const {
|
|
|
- offsetTop, offsetLeft, offsetHeight, offsetWidth,
|
|
|
- } = ele;
|
|
|
+ textElements.forEach((ele: HTMLElement) => {
|
|
|
+ const { offsetTop, offsetLeft, offsetHeight, offsetWidth } = ele;
|
|
|
const offsetRight = offsetLeft + offsetWidth;
|
|
|
const offsetBottom = offsetTop + offsetHeight;
|
|
|
- let coords = {
|
|
|
- top: 0, left: 0, right: 0, bottom: 0,
|
|
|
+ const coords = {
|
|
|
+ top: offsetTop,
|
|
|
+ bottom: offsetBottom,
|
|
|
+ left: offsetLeft,
|
|
|
+ right: offsetRight,
|
|
|
};
|
|
|
|
|
|
- if (offsetTop >= startY && offsetBottom <= endY) {
|
|
|
- if (startElement === endElement) {
|
|
|
+ if (
|
|
|
+ offsetTop >= startY + offsetHeight &&
|
|
|
+ offsetBottom <= endY - offsetHeight
|
|
|
+ ) {
|
|
|
+ position.push(coords);
|
|
|
+ } else if (offsetTop >= startY - 2 && offsetBottom <= endY + 2) {
|
|
|
+ if (startElement === endElement && startElement === ele) {
|
|
|
// start and end same element
|
|
|
- coords = {
|
|
|
- top: offsetTop,
|
|
|
- bottom: offsetBottom,
|
|
|
- left: startX,
|
|
|
- right: endX,
|
|
|
- };
|
|
|
+ coords.left = startX;
|
|
|
+ coords.right = endX;
|
|
|
+ position.push(coords);
|
|
|
} else if (startElement === ele) {
|
|
|
// start element
|
|
|
- coords = {
|
|
|
- top: offsetTop,
|
|
|
- bottom: offsetBottom,
|
|
|
- left: startX,
|
|
|
- right: offsetRight,
|
|
|
- };
|
|
|
+ coords.left = startX;
|
|
|
+ position.push(coords);
|
|
|
} else if (endElement === ele) {
|
|
|
// end element
|
|
|
- coords = {
|
|
|
- top: offsetTop,
|
|
|
- bottom: offsetBottom,
|
|
|
- left: offsetLeft,
|
|
|
- right: endX,
|
|
|
- };
|
|
|
+ coords.right = endX;
|
|
|
+ position.push(coords);
|
|
|
} else if (
|
|
|
- (offsetLeft >= startX && offsetRight <= endX)
|
|
|
- || (offsetTop > (startY + 5) && offsetBottom < (endY - 5))
|
|
|
- || (offsetLeft >= startX && offsetBottom <= startY + offsetHeight + 5)
|
|
|
- || (offsetRight <= endX && offsetTop >= endX - offsetHeight - 5)
|
|
|
+ (startX < offsetLeft && endX > offsetRight) ||
|
|
|
+ (offsetLeft > startX &&
|
|
|
+ offsetTop <= startY + 2 &&
|
|
|
+ endY > startY + offsetHeight) ||
|
|
|
+ (offsetRight < endX &&
|
|
|
+ offsetBottom >= endY - 2 &&
|
|
|
+ startY < endY - offsetHeight)
|
|
|
) {
|
|
|
// middle element
|
|
|
- coords = {
|
|
|
- top: offsetTop,
|
|
|
- bottom: offsetBottom,
|
|
|
- left: offsetLeft,
|
|
|
- right: offsetRight,
|
|
|
- };
|
|
|
+ position.push(coords);
|
|
|
}
|
|
|
-
|
|
|
- position.push(scalePosition(coords, scale));
|
|
|
}
|
|
|
});
|
|
|
|
|
@@ -163,4 +154,4 @@ export const getMarkupWithSelection: GetMarkupWithSelectionFunc = ({
|
|
|
return parseAnnotationObject(info, pageHeight, scale);
|
|
|
};
|
|
|
|
|
|
-export default parseAnnotationObject;
|
|
|
+export default getMarkupWithSelection;
|