pdfjs-viewer-highlight-echo 5.4.456 → 5.4.460
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/build/pdf.min.mjs +4 -4
- package/build/pdf.mjs +76 -16
- package/build/pdf.mjs.map +1 -1
- package/build/pdf.sandbox.min.mjs +2 -2
- package/build/pdf.sandbox.mjs +2 -2
- package/build/pdf.worker.min.mjs +3 -3
- package/build/pdf.worker.mjs +3 -3
- package/config/highlights.json +46 -16
- package/image_decoders/pdf.image_decoders.min.mjs +2 -2
- package/image_decoders/pdf.image_decoders.mjs +2 -2
- package/legacy/build/pdf.min.mjs +4 -4
- package/legacy/build/pdf.mjs +76 -16
- package/legacy/build/pdf.mjs.map +1 -1
- package/legacy/build/pdf.sandbox.min.mjs +2 -2
- package/legacy/build/pdf.sandbox.mjs +2 -2
- package/legacy/build/pdf.worker.min.mjs +3 -3
- package/legacy/build/pdf.worker.mjs +3 -3
- package/legacy/image_decoders/pdf.image_decoders.min.mjs +2 -2
- package/legacy/image_decoders/pdf.image_decoders.mjs +2 -2
- package/legacy/web/config/highlights.json +46 -16
- package/legacy/web/pdf_viewer.mjs +3 -3
- package/legacy/web/viewer.mjs +395 -45
- package/legacy/web/viewer.mjs.map +1 -1
- package/package.json +1 -1
- package/types/src/display/editor/editor.d.ts +3 -0
- package/types/src/display/editor/toolbar.d.ts +2 -0
- package/types/src/display/editor/tools.d.ts +1 -1
- package/web/config/highlights.json +46 -16
- package/web/pdf_viewer.mjs +3 -3
- package/web/viewer.mjs +348 -45
- package/web/viewer.mjs.map +1 -1
package/legacy/web/viewer.mjs
CHANGED
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
|
-
* pdfjsVersion = 5.4.
|
|
25
|
-
* pdfjsBuild =
|
|
24
|
+
* pdfjsVersion = 5.4.460
|
|
25
|
+
* pdfjsBuild = 8489d7097
|
|
26
26
|
*/
|
|
27
27
|
/******/ var __webpack_modules__ = ({
|
|
28
28
|
|
|
@@ -58,6 +58,45 @@ module.exports = function (argument, usingIterator) {
|
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
|
|
61
|
+
/***/ }),
|
|
62
|
+
|
|
63
|
+
/***/ 116:
|
|
64
|
+
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
var $ = __webpack_require__(6518);
|
|
68
|
+
var call = __webpack_require__(9565);
|
|
69
|
+
var iterate = __webpack_require__(2652);
|
|
70
|
+
var aCallable = __webpack_require__(9306);
|
|
71
|
+
var anObject = __webpack_require__(8551);
|
|
72
|
+
var getIteratorDirect = __webpack_require__(1767);
|
|
73
|
+
var iteratorClose = __webpack_require__(9539);
|
|
74
|
+
var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(4549);
|
|
75
|
+
|
|
76
|
+
var findWithoutClosingOnEarlyError = iteratorHelperWithoutClosingOnEarlyError('find', TypeError);
|
|
77
|
+
|
|
78
|
+
// `Iterator.prototype.find` method
|
|
79
|
+
// https://tc39.es/ecma262/#sec-iterator.prototype.find
|
|
80
|
+
$({ target: 'Iterator', proto: true, real: true, forced: findWithoutClosingOnEarlyError }, {
|
|
81
|
+
find: function find(predicate) {
|
|
82
|
+
anObject(this);
|
|
83
|
+
try {
|
|
84
|
+
aCallable(predicate);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
iteratorClose(this, 'throw', error);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (findWithoutClosingOnEarlyError) return call(findWithoutClosingOnEarlyError, this, predicate);
|
|
90
|
+
|
|
91
|
+
var record = getIteratorDirect(this);
|
|
92
|
+
var counter = 0;
|
|
93
|
+
return iterate(record, function (value, stop) {
|
|
94
|
+
if (predicate(value, counter++)) return stop(value);
|
|
95
|
+
}, { IS_RECORD: true, INTERRUPTED: true }).result;
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
|
|
61
100
|
/***/ }),
|
|
62
101
|
|
|
63
102
|
/***/ 283:
|
|
@@ -12232,6 +12271,7 @@ class PDFFilterView {
|
|
|
12232
12271
|
this.eventBus.dispatch("filterhighlightselected", {
|
|
12233
12272
|
source: this,
|
|
12234
12273
|
pageNumber: page,
|
|
12274
|
+
id: this.highlightData.id,
|
|
12235
12275
|
location: {
|
|
12236
12276
|
x,
|
|
12237
12277
|
y,
|
|
@@ -12379,18 +12419,28 @@ class PDFFilterViewer {
|
|
|
12379
12419
|
}
|
|
12380
12420
|
}
|
|
12381
12421
|
|
|
12422
|
+
// EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.find.js
|
|
12423
|
+
var es_iterator_find = __webpack_require__(116);
|
|
12382
12424
|
;// ./web/filter_highlight_overlay.js
|
|
12425
|
+
|
|
12426
|
+
|
|
12427
|
+
|
|
12428
|
+
|
|
12429
|
+
|
|
12430
|
+
|
|
12383
12431
|
class FilterHighlightOverlay {
|
|
12384
12432
|
#eventBus = null;
|
|
12385
12433
|
#currentOverlay = null;
|
|
12386
12434
|
#uiManager = null;
|
|
12435
|
+
#lastPageNumber = null;
|
|
12436
|
+
#highlightEditorsByPage = new Map();
|
|
12387
12437
|
constructor(eventBus) {
|
|
12388
12438
|
this.#eventBus = eventBus;
|
|
12389
12439
|
this.#addEventListeners();
|
|
12390
12440
|
}
|
|
12391
12441
|
#addEventListeners() {
|
|
12392
12442
|
this.#eventBus._on("filterhighlightselected", evt => {
|
|
12393
|
-
this.showHighlight(evt.pageNumber, evt.location);
|
|
12443
|
+
this.showHighlight(evt.pageNumber, evt.location, evt.id);
|
|
12394
12444
|
});
|
|
12395
12445
|
this.#eventBus._on("annotationeditoruimanager", ({
|
|
12396
12446
|
uiManager
|
|
@@ -12398,8 +12448,85 @@ class FilterHighlightOverlay {
|
|
|
12398
12448
|
this.#uiManager = uiManager;
|
|
12399
12449
|
});
|
|
12400
12450
|
}
|
|
12401
|
-
|
|
12402
|
-
|
|
12451
|
+
storeHighlightEditorsForCurPageNum(id, pageNumber, uiManager) {
|
|
12452
|
+
const editorList = Array.from(uiManager.getEditors(pageNumber - 1));
|
|
12453
|
+
console.log(`DEBUG - Found ${editorList.length} editor(s) for page ${pageNumber}`);
|
|
12454
|
+
let highlightDivIds = [];
|
|
12455
|
+
highlightDivIds = this.#highlightEditorsByPage.get(pageNumber) || [];
|
|
12456
|
+
for (const editor of editorList) {
|
|
12457
|
+
if (editor && editor.constructor.name === 'HighlightEditor') {
|
|
12458
|
+
const divId = editor.div?.id;
|
|
12459
|
+
if (divId) {
|
|
12460
|
+
const exists = highlightDivIds.some(item => item.highlightDivId === divId);
|
|
12461
|
+
if (!exists) {
|
|
12462
|
+
highlightDivIds.push({
|
|
12463
|
+
textId: id,
|
|
12464
|
+
highlightDivId: divId
|
|
12465
|
+
});
|
|
12466
|
+
}
|
|
12467
|
+
console.log(`DEBUG - Found HighlightEditor with div ID:`, {
|
|
12468
|
+
textId: id,
|
|
12469
|
+
highlightDivId: divId
|
|
12470
|
+
});
|
|
12471
|
+
}
|
|
12472
|
+
}
|
|
12473
|
+
}
|
|
12474
|
+
if (highlightDivIds.length > 0) {
|
|
12475
|
+
this.#highlightEditorsByPage.set(pageNumber, highlightDivIds);
|
|
12476
|
+
console.log(`DEBUG - Stored ${highlightDivIds.length} highlight editor(s) for page ${pageNumber}:`, highlightDivIds);
|
|
12477
|
+
}
|
|
12478
|
+
}
|
|
12479
|
+
findHighlightByDivId(divId) {
|
|
12480
|
+
for (const [pageNumber, highlights] of this.#highlightEditorsByPage.entries()) {
|
|
12481
|
+
const found = highlights.find(item => item.highlightDivId === divId);
|
|
12482
|
+
if (found) {
|
|
12483
|
+
return {
|
|
12484
|
+
...found,
|
|
12485
|
+
pageNumber
|
|
12486
|
+
};
|
|
12487
|
+
}
|
|
12488
|
+
}
|
|
12489
|
+
return null;
|
|
12490
|
+
}
|
|
12491
|
+
findHighlightsByTextId(textId) {
|
|
12492
|
+
const results = [];
|
|
12493
|
+
for (const [pageNumber, highlights] of this.#highlightEditorsByPage.entries()) {
|
|
12494
|
+
const matches = highlights.filter(item => item.textId === textId);
|
|
12495
|
+
matches.forEach(match => results.push({
|
|
12496
|
+
...match,
|
|
12497
|
+
pageNumber
|
|
12498
|
+
}));
|
|
12499
|
+
}
|
|
12500
|
+
return results;
|
|
12501
|
+
}
|
|
12502
|
+
async showHighlight(pageNumber, location, id) {
|
|
12503
|
+
let highlightDivIds = [];
|
|
12504
|
+
highlightDivIds = this.#highlightEditorsByPage.get(pageNumber) || [];
|
|
12505
|
+
const filteredHighlights = highlightDivIds.filter(item => item.textId === id);
|
|
12506
|
+
if (filteredHighlights.length > 0) {
|
|
12507
|
+
console.log(`DEBUG - Highlights already exist for page ${pageNumber}, textId ${id}, skipping creation.`);
|
|
12508
|
+
filteredHighlights.forEach(item => {
|
|
12509
|
+
const uiManager = this.#uiManager || window.PDFViewerApplication?.pdfViewer?.annotationEditorUIManager;
|
|
12510
|
+
if (uiManager) {
|
|
12511
|
+
const editorList = Array.from(uiManager.getEditors(pageNumber - 1));
|
|
12512
|
+
const editor = editorList.find(e => e.div?.id === item.highlightDivId);
|
|
12513
|
+
if (editor) {
|
|
12514
|
+
console.log("DEBUG - Reusing existing highlight editor:", editor);
|
|
12515
|
+
if (editor.div) {
|
|
12516
|
+
editor.div.style.display = '';
|
|
12517
|
+
editor.div.classList.add('selectedEditor');
|
|
12518
|
+
if (typeof editor.select === 'function') {
|
|
12519
|
+
editor.select();
|
|
12520
|
+
}
|
|
12521
|
+
uiManager.setSelected(editor);
|
|
12522
|
+
}
|
|
12523
|
+
}
|
|
12524
|
+
}
|
|
12525
|
+
});
|
|
12526
|
+
return;
|
|
12527
|
+
}
|
|
12528
|
+
console.log(`DEBUG - No existing highlights for page ${pageNumber}, proceeding to create.`);
|
|
12529
|
+
this.#lastPageNumber = pageNumber;
|
|
12403
12530
|
const uiManager = this.#uiManager || window.PDFViewerApplication?.pdfViewer?.annotationEditorUIManager;
|
|
12404
12531
|
if (!uiManager) {
|
|
12405
12532
|
console.error("UI Manager not initialized. Please enable annotation editing mode.");
|
|
@@ -12410,9 +12537,10 @@ class FilterHighlightOverlay {
|
|
|
12410
12537
|
console.error("Page view not found for page", pageNumber);
|
|
12411
12538
|
return;
|
|
12412
12539
|
}
|
|
12413
|
-
|
|
12414
|
-
|
|
12415
|
-
|
|
12540
|
+
try {
|
|
12541
|
+
await this.#waitForTextLayer(pageView);
|
|
12542
|
+
} catch (error) {
|
|
12543
|
+
console.error("Failed to load text layer:", error);
|
|
12416
12544
|
return;
|
|
12417
12545
|
}
|
|
12418
12546
|
const textLayer = pageView.textLayer.div;
|
|
@@ -12420,12 +12548,14 @@ class FilterHighlightOverlay {
|
|
|
12420
12548
|
console.error("Text layer div not found");
|
|
12421
12549
|
return;
|
|
12422
12550
|
}
|
|
12551
|
+
console.log("DEBUG - Text layer before extraction, total spans:", textLayer.querySelectorAll("span[role='presentation']").length);
|
|
12552
|
+
console.log("Extracting text from location:", location);
|
|
12423
12553
|
const textInfo = this.#extractTextFromLocation(textLayer, pageView, location);
|
|
12554
|
+
console.log("Extracting text Info:", textInfo);
|
|
12424
12555
|
if (!textInfo) {
|
|
12425
12556
|
console.error("Could not extract text from location", location);
|
|
12426
12557
|
return;
|
|
12427
12558
|
}
|
|
12428
|
-
console.log("Extracted text info:", textInfo);
|
|
12429
12559
|
const selection = document.getSelection();
|
|
12430
12560
|
selection.removeAllRanges();
|
|
12431
12561
|
const range = document.createRange();
|
|
@@ -12435,14 +12565,51 @@ class FilterHighlightOverlay {
|
|
|
12435
12565
|
selection.addRange(range);
|
|
12436
12566
|
console.log("Selection created:", selection.toString());
|
|
12437
12567
|
setTimeout(() => {
|
|
12438
|
-
uiManager.highlightSelection("filter_view");
|
|
12568
|
+
const editor = uiManager.highlightSelection("filter_view");
|
|
12439
12569
|
selection.removeAllRanges();
|
|
12570
|
+
setTimeout(() => {
|
|
12571
|
+
this.storeHighlightEditorsForCurPageNum(id, pageNumber, uiManager);
|
|
12572
|
+
}, 50);
|
|
12440
12573
|
}, 100);
|
|
12441
12574
|
} catch (error) {
|
|
12442
12575
|
console.error("Error creating selection:", error);
|
|
12443
12576
|
selection.removeAllRanges();
|
|
12444
12577
|
}
|
|
12445
12578
|
}
|
|
12579
|
+
async #waitForTextLayer(pageView) {
|
|
12580
|
+
if (pageView.textLayer?.div) {
|
|
12581
|
+
return;
|
|
12582
|
+
}
|
|
12583
|
+
if (pageView.renderingState < 3) {
|
|
12584
|
+
await new Promise(resolve => {
|
|
12585
|
+
const checkRendering = () => {
|
|
12586
|
+
if (pageView.renderingState >= 3) {
|
|
12587
|
+
resolve();
|
|
12588
|
+
} else {
|
|
12589
|
+
setTimeout(checkRendering, 50);
|
|
12590
|
+
}
|
|
12591
|
+
};
|
|
12592
|
+
checkRendering();
|
|
12593
|
+
});
|
|
12594
|
+
}
|
|
12595
|
+
if (pageView.textLayer?.renderingDone) {
|
|
12596
|
+
await pageView.textLayer.renderingDone;
|
|
12597
|
+
return;
|
|
12598
|
+
}
|
|
12599
|
+
return new Promise((resolve, reject) => {
|
|
12600
|
+
const timeout = setTimeout(() => {
|
|
12601
|
+
reject(new Error("Text layer rendering timeout"));
|
|
12602
|
+
}, 5000);
|
|
12603
|
+
const handler = evt => {
|
|
12604
|
+
if (evt.pageNumber === pageView.id) {
|
|
12605
|
+
clearTimeout(timeout);
|
|
12606
|
+
this.#eventBus._off("textlayerrendered", handler);
|
|
12607
|
+
resolve();
|
|
12608
|
+
}
|
|
12609
|
+
};
|
|
12610
|
+
this.#eventBus._on("textlayerrendered", handler);
|
|
12611
|
+
});
|
|
12612
|
+
}
|
|
12446
12613
|
#convertLocationToBoxes(pageView, location) {
|
|
12447
12614
|
if (!pageView.div) {
|
|
12448
12615
|
return null;
|
|
@@ -12456,15 +12623,20 @@ class FilterHighlightOverlay {
|
|
|
12456
12623
|
const viewport = pageView.viewport;
|
|
12457
12624
|
const [x1, y1] = viewport.convertToViewportPoint(x, y + height);
|
|
12458
12625
|
const [x2, y2] = viewport.convertToViewportPoint(x + width, y);
|
|
12459
|
-
const
|
|
12460
|
-
const
|
|
12626
|
+
const pageRect = pageView.div.getBoundingClientRect();
|
|
12627
|
+
const scaleX = pageRect.width / viewport.width || 1;
|
|
12628
|
+
const scaleY = pageRect.height / viewport.height || 1;
|
|
12629
|
+
const pageWidth = pageRect.width;
|
|
12630
|
+
const pageHeight = pageRect.height;
|
|
12461
12631
|
const minX = Math.min(x1, x2);
|
|
12462
12632
|
const minY = Math.min(y1, y2);
|
|
12633
|
+
const boxWidth = Math.abs(x2 - x1);
|
|
12634
|
+
const boxHeight = Math.abs(y2 - y1);
|
|
12463
12635
|
return [{
|
|
12464
|
-
x: minX / pageWidth,
|
|
12465
|
-
y: minY / pageHeight,
|
|
12466
|
-
width:
|
|
12467
|
-
height:
|
|
12636
|
+
x: minX * scaleX / pageWidth,
|
|
12637
|
+
y: minY * scaleY / pageHeight,
|
|
12638
|
+
width: boxWidth * scaleX / pageWidth,
|
|
12639
|
+
height: boxHeight * scaleY / pageHeight
|
|
12468
12640
|
}];
|
|
12469
12641
|
}
|
|
12470
12642
|
#extractTextFromLocation(textLayer, pageView, location) {
|
|
@@ -12483,38 +12655,130 @@ class FilterHighlightOverlay {
|
|
|
12483
12655
|
const overlayHeight = Math.abs(y2 - y1);
|
|
12484
12656
|
const pageRect = pageView.div.getBoundingClientRect();
|
|
12485
12657
|
const textLayerRect = textLayer.getBoundingClientRect();
|
|
12486
|
-
|
|
12487
|
-
|
|
12488
|
-
|
|
12489
|
-
|
|
12490
|
-
|
|
12491
|
-
|
|
12658
|
+
console.log("DEBUG - pageRect:", {
|
|
12659
|
+
left: pageRect.left,
|
|
12660
|
+
top: pageRect.top,
|
|
12661
|
+
width: pageRect.width,
|
|
12662
|
+
height: pageRect.height
|
|
12663
|
+
});
|
|
12664
|
+
console.log("DEBUG - viewport:", {
|
|
12665
|
+
width: viewport.width,
|
|
12666
|
+
height: viewport.height
|
|
12667
|
+
});
|
|
12668
|
+
const scaleX = pageRect.width / viewport.width || 1;
|
|
12669
|
+
const scaleY = pageRect.height / viewport.height || 1;
|
|
12670
|
+
const overlayPageLeft = overlayLeft * scaleX;
|
|
12671
|
+
const overlayPageTop = overlayTop * scaleY;
|
|
12672
|
+
const overlayPageRight = overlayPageLeft + overlayWidth * scaleX;
|
|
12673
|
+
const overlayPageBottom = overlayPageTop + overlayHeight * scaleY;
|
|
12674
|
+
console.log("DEBUG - overlay bounds (page-relative):", {
|
|
12675
|
+
left: overlayPageLeft,
|
|
12676
|
+
top: overlayPageTop,
|
|
12677
|
+
right: overlayPageRight,
|
|
12678
|
+
bottom: overlayPageBottom
|
|
12679
|
+
});
|
|
12680
|
+
const textElements = Array.from(textLayer.querySelectorAll("span[role='presentation']"));
|
|
12681
|
+
console.log("DEBUG - total text spans:", textElements.length);
|
|
12682
|
+
const candidates = [];
|
|
12683
|
+
let debugSkipped = 0;
|
|
12492
12684
|
for (const span of textElements) {
|
|
12493
12685
|
const rect = span.getBoundingClientRect();
|
|
12494
|
-
const
|
|
12495
|
-
const
|
|
12496
|
-
const
|
|
12497
|
-
const
|
|
12498
|
-
if (
|
|
12499
|
-
|
|
12500
|
-
|
|
12501
|
-
if (!firstNode) {
|
|
12502
|
-
firstNode = textNode;
|
|
12503
|
-
firstOffset = 0;
|
|
12504
|
-
}
|
|
12505
|
-
lastNode = textNode;
|
|
12506
|
-
lastOffset = textNode.textContent.length;
|
|
12507
|
-
collectedText += textNode.textContent;
|
|
12508
|
-
}
|
|
12686
|
+
const spanPageLeft = rect.left - pageRect.left;
|
|
12687
|
+
const spanPageTop = rect.top - pageRect.top;
|
|
12688
|
+
const spanPageRight = rect.right - pageRect.left;
|
|
12689
|
+
const spanPageBottom = rect.bottom - pageRect.top;
|
|
12690
|
+
if (spanPageRight <= overlayPageLeft || spanPageLeft >= overlayPageRight || spanPageBottom <= overlayPageTop || spanPageTop >= overlayPageBottom) {
|
|
12691
|
+
debugSkipped++;
|
|
12692
|
+
continue;
|
|
12509
12693
|
}
|
|
12694
|
+
const textNode = span.firstChild;
|
|
12695
|
+
if (!textNode || textNode.nodeType !== Node.TEXT_NODE) {
|
|
12696
|
+
continue;
|
|
12697
|
+
}
|
|
12698
|
+
candidates.push({
|
|
12699
|
+
span,
|
|
12700
|
+
rect: {
|
|
12701
|
+
left: spanPageLeft,
|
|
12702
|
+
top: spanPageTop,
|
|
12703
|
+
right: spanPageRight,
|
|
12704
|
+
bottom: spanPageBottom,
|
|
12705
|
+
width: rect.width,
|
|
12706
|
+
height: rect.height
|
|
12707
|
+
},
|
|
12708
|
+
textNode
|
|
12709
|
+
});
|
|
12710
|
+
}
|
|
12711
|
+
console.log("DEBUG - candidates found:", candidates.length, "skipped:", debugSkipped);
|
|
12712
|
+
if (candidates.length > 0) {
|
|
12713
|
+
console.log("DEBUG - first candidate:", {
|
|
12714
|
+
text: candidates[0].textNode.textContent.substring(0, 20),
|
|
12715
|
+
rect: candidates[0].rect
|
|
12716
|
+
});
|
|
12717
|
+
console.log("DEBUG - last candidate:", {
|
|
12718
|
+
text: candidates[candidates.length - 1].textNode.textContent.substring(0, 20),
|
|
12719
|
+
rect: candidates[candidates.length - 1].rect
|
|
12720
|
+
});
|
|
12510
12721
|
}
|
|
12511
|
-
if (
|
|
12722
|
+
if (candidates.length === 0) {
|
|
12512
12723
|
return null;
|
|
12513
12724
|
}
|
|
12725
|
+
candidates.sort((a, b) => {
|
|
12726
|
+
const topDiff = a.rect.top - b.rect.top;
|
|
12727
|
+
if (Math.abs(topDiff) > 1) return topDiff;
|
|
12728
|
+
return a.rect.left - b.rect.left;
|
|
12729
|
+
});
|
|
12730
|
+
const first = candidates[0];
|
|
12731
|
+
const last = candidates[candidates.length - 1];
|
|
12732
|
+
const makeOffset = (candidate, overlayL, overlayR, isStart) => {
|
|
12733
|
+
const textLen = candidate.textNode.textContent.length || 0;
|
|
12734
|
+
const rectWidth = candidate.rect.width || 0;
|
|
12735
|
+
const rectLeft = candidate.rect.left;
|
|
12736
|
+
const rectRight = candidate.rect.right;
|
|
12737
|
+
if (textLen === 0 || rectWidth === 0) {
|
|
12738
|
+
return isStart ? 0 : textLen;
|
|
12739
|
+
}
|
|
12740
|
+
const coveredLeft = Math.max(rectLeft, overlayL);
|
|
12741
|
+
const coveredRight = Math.min(rectRight, overlayR);
|
|
12742
|
+
const coveredWidth = Math.max(0, coveredRight - coveredLeft);
|
|
12743
|
+
const coverageRatio = coveredWidth / rectWidth;
|
|
12744
|
+
if (isStart) {
|
|
12745
|
+
if (overlayL <= rectLeft + rectWidth * 0.1) {
|
|
12746
|
+
return 0;
|
|
12747
|
+
}
|
|
12748
|
+
const relStart = Math.max(0, overlayL - rectLeft);
|
|
12749
|
+
const startRatio = Math.max(0, Math.min(1, relStart / rectWidth));
|
|
12750
|
+
return Math.floor(startRatio * textLen);
|
|
12751
|
+
} else {
|
|
12752
|
+
if (overlayR >= rectRight - rectWidth * 0.1) {
|
|
12753
|
+
return textLen;
|
|
12754
|
+
}
|
|
12755
|
+
const relEnd = Math.min(rectRight, overlayR) - rectLeft;
|
|
12756
|
+
const endRatio = Math.max(0, Math.min(1, relEnd / rectWidth));
|
|
12757
|
+
return Math.ceil(endRatio * textLen);
|
|
12758
|
+
}
|
|
12759
|
+
};
|
|
12760
|
+
const firstOffset = makeOffset(first, overlayPageLeft, overlayPageRight, true);
|
|
12761
|
+
const lastOffset = makeOffset(last, overlayPageLeft, overlayPageRight, false);
|
|
12762
|
+
let collectedText = "";
|
|
12763
|
+
console.log("Candidates found:", candidates.length);
|
|
12764
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
12765
|
+
const {
|
|
12766
|
+
textNode
|
|
12767
|
+
} = candidates[i];
|
|
12768
|
+
if (i === 0 && i === candidates.length - 1) {
|
|
12769
|
+
collectedText += textNode.textContent.substring(firstOffset, lastOffset);
|
|
12770
|
+
} else if (i === 0) {
|
|
12771
|
+
collectedText += textNode.textContent.substring(firstOffset);
|
|
12772
|
+
} else if (i === candidates.length - 1) {
|
|
12773
|
+
collectedText += textNode.textContent.substring(0, lastOffset);
|
|
12774
|
+
} else {
|
|
12775
|
+
collectedText += textNode.textContent;
|
|
12776
|
+
}
|
|
12777
|
+
}
|
|
12514
12778
|
return {
|
|
12515
|
-
anchorNode:
|
|
12779
|
+
anchorNode: first.textNode,
|
|
12516
12780
|
anchorOffset: firstOffset,
|
|
12517
|
-
focusNode:
|
|
12781
|
+
focusNode: last.textNode,
|
|
12518
12782
|
focusOffset: lastOffset,
|
|
12519
12783
|
text: collectedText.trim()
|
|
12520
12784
|
};
|
|
@@ -12526,12 +12790,29 @@ class FilterHighlightOverlay {
|
|
|
12526
12790
|
}
|
|
12527
12791
|
return pdfViewer._pages[pageNumber - 1];
|
|
12528
12792
|
}
|
|
12529
|
-
clearHighlight() {
|
|
12793
|
+
async clearHighlight() {
|
|
12530
12794
|
if (this.#currentOverlay) {
|
|
12531
|
-
|
|
12532
|
-
|
|
12795
|
+
console.log("DEBUG - Clearing previous highlights");
|
|
12796
|
+
const uiManager = this.#uiManager || window.PDFViewerApplication?.pdfViewer?.annotationEditorUIManager;
|
|
12797
|
+
if (uiManager) {
|
|
12798
|
+
const editors = uiManager.getEditors();
|
|
12799
|
+
console.log("DEBUG - Editors:", editors, "Type:", typeof editors);
|
|
12800
|
+
if (editors) {
|
|
12801
|
+
const editorList = editors instanceof Map ? Array.from(editors.values()) : Array.isArray(editors) ? editors : Object.values(editors);
|
|
12802
|
+
for (const editor of editorList) {
|
|
12803
|
+
if (editor && typeof editor.remove === 'function') {
|
|
12804
|
+
try {
|
|
12805
|
+
console.log("DEBUG - Removing editor:", editor);
|
|
12806
|
+
editor.remove();
|
|
12807
|
+
} catch (e) {
|
|
12808
|
+
console.warn("Error removing editor:", e);
|
|
12809
|
+
}
|
|
12810
|
+
}
|
|
12811
|
+
}
|
|
12812
|
+
}
|
|
12533
12813
|
}
|
|
12534
12814
|
this.#currentOverlay = null;
|
|
12815
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
12535
12816
|
}
|
|
12536
12817
|
}
|
|
12537
12818
|
}
|
|
@@ -18153,7 +18434,7 @@ class PDFViewer {
|
|
|
18153
18434
|
#textLayerMode = TextLayerMode.ENABLE;
|
|
18154
18435
|
#viewerAlert = null;
|
|
18155
18436
|
constructor(options) {
|
|
18156
|
-
const viewerVersion = "5.4.
|
|
18437
|
+
const viewerVersion = "5.4.460";
|
|
18157
18438
|
if (version !== viewerVersion) {
|
|
18158
18439
|
throw new Error(`The API version "${version}" does not match the Viewer version "${viewerVersion}".`);
|
|
18159
18440
|
}
|
|
@@ -22181,7 +22462,76 @@ const PDFViewerApplication = {
|
|
|
22181
22462
|
await (this.pdfDocument?.annotationStorage.size > 0 ? this.save() : this.download());
|
|
22182
22463
|
classList.remove("wait");
|
|
22183
22464
|
},
|
|
22184
|
-
async saveSelectionAsJson() {
|
|
22465
|
+
async saveSelectionAsJson(params = null) {
|
|
22466
|
+
console.log("params:", params);
|
|
22467
|
+
if (params?.methodOfCreation === "editor_save_button" && params?.editorInfo) {
|
|
22468
|
+
const {
|
|
22469
|
+
editorInfo
|
|
22470
|
+
} = params;
|
|
22471
|
+
const pageView = this.pdfViewer.getPageView(editorInfo.pageIndex);
|
|
22472
|
+
if (!pageView) {
|
|
22473
|
+
console.warn("Could not find page view for editor");
|
|
22474
|
+
return;
|
|
22475
|
+
}
|
|
22476
|
+
const pageElement = this.pdfViewer.viewer.querySelector(`.page[data-page-number="${editorInfo.pageNumber}"]`);
|
|
22477
|
+
if (!pageElement) {
|
|
22478
|
+
console.warn("Could not find page element for editor");
|
|
22479
|
+
return;
|
|
22480
|
+
}
|
|
22481
|
+
const textLayer = pageElement.querySelector(".textLayer");
|
|
22482
|
+
if (!textLayer) {
|
|
22483
|
+
console.warn("Could not find text layer for editor");
|
|
22484
|
+
return;
|
|
22485
|
+
}
|
|
22486
|
+
const textLayerRect = textLayer.getBoundingClientRect();
|
|
22487
|
+
const x = editorInfo.screenRect.left - textLayerRect.left;
|
|
22488
|
+
const y = editorInfo.screenRect.top - textLayerRect.top;
|
|
22489
|
+
const width = editorInfo.screenRect.width;
|
|
22490
|
+
const height = editorInfo.screenRect.height;
|
|
22491
|
+
const pdfCoords = pageView.getPagePoint(x, y);
|
|
22492
|
+
const pdfCoordsEnd = pageView.getPagePoint(x + width, y + height);
|
|
22493
|
+
const location = [Math.round(pdfCoords[0]), Math.round(pdfCoords[1]), Math.round(pdfCoordsEnd[0]), Math.round(pdfCoordsEnd[1])];
|
|
22494
|
+
const data = {
|
|
22495
|
+
page: editorInfo.pageNumber,
|
|
22496
|
+
text: editorInfo.textContent,
|
|
22497
|
+
location,
|
|
22498
|
+
timestamp: Date.now(),
|
|
22499
|
+
documentUrl: this.url || window.location.href
|
|
22500
|
+
};
|
|
22501
|
+
console.log("Selection data sent to parent window within Editor:", data);
|
|
22502
|
+
if (this.isViewerEmbedded && window.parent !== window) {
|
|
22503
|
+
try {
|
|
22504
|
+
window.parent.postMessage({
|
|
22505
|
+
type: "pdfjs-selection",
|
|
22506
|
+
source: "pdf.js",
|
|
22507
|
+
data
|
|
22508
|
+
}, "*");
|
|
22509
|
+
console.log("Selection data sent to parent window:", data);
|
|
22510
|
+
} catch (postError) {
|
|
22511
|
+
console.error("Error posting message to parent:", postError);
|
|
22512
|
+
}
|
|
22513
|
+
}
|
|
22514
|
+
try {
|
|
22515
|
+
const customEvent = new CustomEvent("pdfselectioncaptured", {
|
|
22516
|
+
bubbles: true,
|
|
22517
|
+
cancelable: false,
|
|
22518
|
+
detail: data
|
|
22519
|
+
});
|
|
22520
|
+
if (this.isViewerEmbedded) {
|
|
22521
|
+
try {
|
|
22522
|
+
parent.document.dispatchEvent(customEvent);
|
|
22523
|
+
} catch {
|
|
22524
|
+
document.dispatchEvent(customEvent);
|
|
22525
|
+
}
|
|
22526
|
+
} else {
|
|
22527
|
+
document.dispatchEvent(customEvent);
|
|
22528
|
+
}
|
|
22529
|
+
} catch (eventError) {
|
|
22530
|
+
console.error("Error dispatching custom event:", eventError);
|
|
22531
|
+
}
|
|
22532
|
+
console.log("Selection saved and transferred (from editor):", data);
|
|
22533
|
+
return;
|
|
22534
|
+
}
|
|
22185
22535
|
try {
|
|
22186
22536
|
const selection = window.getSelection();
|
|
22187
22537
|
if (!selection || selection.rangeCount === 0) {
|