pdfjs-viewer-highlight-echo 5.4.457 → 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 +41 -11
- 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 +41 -11
- package/legacy/web/pdf_viewer.mjs +3 -3
- package/legacy/web/viewer.mjs +357 -42
- 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 +41 -11
- package/web/pdf_viewer.mjs +3 -3
- package/web/viewer.mjs +310 -42
- package/web/viewer.mjs.map +1 -1
package/package.json
CHANGED
|
@@ -292,6 +292,9 @@ export class AnnotationEditor {
|
|
|
292
292
|
addStandaloneCommentButton(): void;
|
|
293
293
|
removeStandaloneCommentButton(): void;
|
|
294
294
|
hideStandaloneCommentButton(): void;
|
|
295
|
+
addSaveSelectionButton(): HTMLButtonElement;
|
|
296
|
+
addSaveButtonInToolbar(): void;
|
|
297
|
+
removeSaveButtonFromToolbar(): void;
|
|
295
298
|
set comment(text: {
|
|
296
299
|
text: any;
|
|
297
300
|
richText: any;
|
|
@@ -7,6 +7,8 @@ export class EditorToolbar {
|
|
|
7
7
|
hide(): void;
|
|
8
8
|
show(): void;
|
|
9
9
|
addDeleteButton(): void;
|
|
10
|
+
addSaveButton(saveButton: any): void;
|
|
11
|
+
removeSaveButton(): void;
|
|
10
12
|
addAltText(altText: any): Promise<void>;
|
|
11
13
|
addComment(comment: any, beforeElement?: null): void;
|
|
12
14
|
addColorPicker(colorPicker: any): void;
|
|
@@ -76,7 +76,7 @@ export class AnnotationEditorUIManager {
|
|
|
76
76
|
highlightSelection(methodOfCreation?: string, comment?: boolean): void;
|
|
77
77
|
commentSelection(methodOfCreation?: string): void;
|
|
78
78
|
copySelection(methodOfCreation?: string): void;
|
|
79
|
-
saveSelectionAsJson(methodOfCreation?: string): void;
|
|
79
|
+
saveSelectionAsJson(methodOfCreation?: string, editorInfo?: null): void;
|
|
80
80
|
/**
|
|
81
81
|
* Some annotations may have been modified in the annotation layer
|
|
82
82
|
* (e.g. comments added or modified).
|
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
[
|
|
2
2
|
{
|
|
3
|
+
"id": "highlight-1",
|
|
4
|
+
"location": [
|
|
5
|
+
25,
|
|
6
|
+
505,
|
|
7
|
+
256,
|
|
8
|
+
407
|
|
9
|
+
],
|
|
10
|
+
"page": 1,
|
|
11
|
+
"text": "Enviro"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"id": "highlight-2",
|
|
15
|
+
"location": [
|
|
16
|
+
25,
|
|
17
|
+
359,
|
|
18
|
+
276,
|
|
19
|
+
261
|
|
20
|
+
],
|
|
21
|
+
"page": 1,
|
|
22
|
+
"text": "Report"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"id": "highlight-99",
|
|
3
26
|
"location": [
|
|
4
27
|
22,
|
|
5
28
|
500,
|
|
@@ -10,26 +33,29 @@
|
|
|
10
33
|
"text": "Environmental Progress Report"
|
|
11
34
|
},
|
|
12
35
|
{
|
|
36
|
+
"id": "highlight-98",
|
|
13
37
|
"location": [
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
38
|
+
584,
|
|
39
|
+
298,
|
|
40
|
+
669,
|
|
41
|
+
286
|
|
18
42
|
],
|
|
19
|
-
"page":
|
|
20
|
-
"text": "
|
|
43
|
+
"page": 4,
|
|
44
|
+
"text": "Read more on page 15."
|
|
21
45
|
},
|
|
22
46
|
{
|
|
47
|
+
"id": "highlight-4",
|
|
23
48
|
"location": [
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
49
|
+
46,
|
|
50
|
+
441,
|
|
51
|
+
265,
|
|
52
|
+
411
|
|
28
53
|
],
|
|
29
54
|
"page": 4,
|
|
30
|
-
"text": "
|
|
55
|
+
"text": "Reduced our overall GHG emissions by more than 60 percent"
|
|
31
56
|
},
|
|
32
57
|
{
|
|
58
|
+
"id": "highlight-5",
|
|
33
59
|
"location": [
|
|
34
60
|
315,
|
|
35
61
|
572,
|
|
@@ -40,6 +66,7 @@
|
|
|
40
66
|
"text": "igure 5. A tree with two traces, a trunk trace and one branch\ntrace. The trunk trace contains a guard to which a branch trace was\nattached. The branch trace contain a guard that may fail and trigger\na side exit. Both the trunk and the branch trace loop back to the tree\nanchor, which is the beginning of the trace tree."
|
|
41
67
|
},
|
|
42
68
|
{
|
|
69
|
+
"id": "highlight-6",
|
|
43
70
|
"location": [
|
|
44
71
|
54,
|
|
45
72
|
432,
|
|
@@ -50,6 +77,7 @@
|
|
|
50
77
|
"text": "Google’s V8 JS compiler. Our system generates particularly efficient code for programs that benefit most from\ntype specialization, which includes SunSpider Benchmark programs that perform bit manipulation. We type-specialize the code in question\nto use integer arithmetic, which substantially improves performance. For one of the benchmark programs we execute 25 times faster than\nthe SpiderMonkey interpreter, and almost 5 times faster than V8 and SFX. For a large number of benchmarks all three VMs produce similar\nresults. We perform worst on benchmark programs that we do not trace and instead fall back onto the interpreter. This includes the recursive\nbenchmarks access-binary-trees and control-flow-recursive, for which we currently don’t generate any native code.\nIn particular, the bitops benchmarks are short programs that per-\nform many bitwise operations, so TraceMonkey can cover the en-\ntire program with 1 or 2 traces that operate on integers. TraceMon-\nkey runs all the other programs in this set almost entirely as na"
|
|
51
78
|
},
|
|
52
79
|
{
|
|
80
|
+
"id": "highlight-7",
|
|
53
81
|
"location": [
|
|
54
82
|
54,
|
|
55
83
|
370,
|
|
@@ -60,6 +88,7 @@
|
|
|
60
88
|
"text": "he total execution time in processor\nclock cycles by the number of bytecodes executed in the base\ninterpreter shows that on average, a bytecode executes in about\n35 cycles. Native traces take about 9 cycles per bytecode, a 3.9"
|
|
61
89
|
},
|
|
62
90
|
{
|
|
91
|
+
"id": "highlight-8",
|
|
63
92
|
"location": [
|
|
64
93
|
315,
|
|
65
94
|
504,
|
|
@@ -70,6 +99,7 @@
|
|
|
70
99
|
"text": "onclusions\nThis paper described how to run dynamic languages efficiently by\nrecording hot traces and generating type-specialized native code.\nOur techniq"
|
|
71
100
|
},
|
|
72
101
|
{
|
|
102
|
+
"id": "highlight-9",
|
|
73
103
|
"location": [
|
|
74
104
|
315,
|
|
75
105
|
652,
|
package/web/pdf_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
|
/******/ // The require scope
|
|
28
28
|
/******/ var __webpack_require__ = {};
|
|
@@ -7655,7 +7655,7 @@ class PDFViewer {
|
|
|
7655
7655
|
#textLayerMode = TextLayerMode.ENABLE;
|
|
7656
7656
|
#viewerAlert = null;
|
|
7657
7657
|
constructor(options) {
|
|
7658
|
-
const viewerVersion = "5.4.
|
|
7658
|
+
const viewerVersion = "5.4.460";
|
|
7659
7659
|
if (version !== viewerVersion) {
|
|
7660
7660
|
throw new Error(`The API version "${version}" does not match the Viewer version "${viewerVersion}".`);
|
|
7661
7661
|
}
|
package/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
|
/******/ // The require scope
|
|
28
28
|
/******/ var __webpack_require__ = {};
|
|
@@ -7440,6 +7440,7 @@ class PDFFilterView {
|
|
|
7440
7440
|
this.eventBus.dispatch("filterhighlightselected", {
|
|
7441
7441
|
source: this,
|
|
7442
7442
|
pageNumber: page,
|
|
7443
|
+
id: this.highlightData.id,
|
|
7443
7444
|
location: {
|
|
7444
7445
|
x,
|
|
7445
7446
|
y,
|
|
@@ -7589,13 +7590,15 @@ class FilterHighlightOverlay {
|
|
|
7589
7590
|
#eventBus = null;
|
|
7590
7591
|
#currentOverlay = null;
|
|
7591
7592
|
#uiManager = null;
|
|
7593
|
+
#lastPageNumber = null;
|
|
7594
|
+
#highlightEditorsByPage = new Map();
|
|
7592
7595
|
constructor(eventBus) {
|
|
7593
7596
|
this.#eventBus = eventBus;
|
|
7594
7597
|
this.#addEventListeners();
|
|
7595
7598
|
}
|
|
7596
7599
|
#addEventListeners() {
|
|
7597
7600
|
this.#eventBus._on("filterhighlightselected", evt => {
|
|
7598
|
-
this.showHighlight(evt.pageNumber, evt.location);
|
|
7601
|
+
this.showHighlight(evt.pageNumber, evt.location, evt.id);
|
|
7599
7602
|
});
|
|
7600
7603
|
this.#eventBus._on("annotationeditoruimanager", ({
|
|
7601
7604
|
uiManager
|
|
@@ -7603,8 +7606,85 @@ class FilterHighlightOverlay {
|
|
|
7603
7606
|
this.#uiManager = uiManager;
|
|
7604
7607
|
});
|
|
7605
7608
|
}
|
|
7606
|
-
|
|
7607
|
-
|
|
7609
|
+
storeHighlightEditorsForCurPageNum(id, pageNumber, uiManager) {
|
|
7610
|
+
const editorList = Array.from(uiManager.getEditors(pageNumber - 1));
|
|
7611
|
+
console.log(`DEBUG - Found ${editorList.length} editor(s) for page ${pageNumber}`);
|
|
7612
|
+
let highlightDivIds = [];
|
|
7613
|
+
highlightDivIds = this.#highlightEditorsByPage.get(pageNumber) || [];
|
|
7614
|
+
for (const editor of editorList) {
|
|
7615
|
+
if (editor && editor.constructor.name === 'HighlightEditor') {
|
|
7616
|
+
const divId = editor.div?.id;
|
|
7617
|
+
if (divId) {
|
|
7618
|
+
const exists = highlightDivIds.some(item => item.highlightDivId === divId);
|
|
7619
|
+
if (!exists) {
|
|
7620
|
+
highlightDivIds.push({
|
|
7621
|
+
textId: id,
|
|
7622
|
+
highlightDivId: divId
|
|
7623
|
+
});
|
|
7624
|
+
}
|
|
7625
|
+
console.log(`DEBUG - Found HighlightEditor with div ID:`, {
|
|
7626
|
+
textId: id,
|
|
7627
|
+
highlightDivId: divId
|
|
7628
|
+
});
|
|
7629
|
+
}
|
|
7630
|
+
}
|
|
7631
|
+
}
|
|
7632
|
+
if (highlightDivIds.length > 0) {
|
|
7633
|
+
this.#highlightEditorsByPage.set(pageNumber, highlightDivIds);
|
|
7634
|
+
console.log(`DEBUG - Stored ${highlightDivIds.length} highlight editor(s) for page ${pageNumber}:`, highlightDivIds);
|
|
7635
|
+
}
|
|
7636
|
+
}
|
|
7637
|
+
findHighlightByDivId(divId) {
|
|
7638
|
+
for (const [pageNumber, highlights] of this.#highlightEditorsByPage.entries()) {
|
|
7639
|
+
const found = highlights.find(item => item.highlightDivId === divId);
|
|
7640
|
+
if (found) {
|
|
7641
|
+
return {
|
|
7642
|
+
...found,
|
|
7643
|
+
pageNumber
|
|
7644
|
+
};
|
|
7645
|
+
}
|
|
7646
|
+
}
|
|
7647
|
+
return null;
|
|
7648
|
+
}
|
|
7649
|
+
findHighlightsByTextId(textId) {
|
|
7650
|
+
const results = [];
|
|
7651
|
+
for (const [pageNumber, highlights] of this.#highlightEditorsByPage.entries()) {
|
|
7652
|
+
const matches = highlights.filter(item => item.textId === textId);
|
|
7653
|
+
matches.forEach(match => results.push({
|
|
7654
|
+
...match,
|
|
7655
|
+
pageNumber
|
|
7656
|
+
}));
|
|
7657
|
+
}
|
|
7658
|
+
return results;
|
|
7659
|
+
}
|
|
7660
|
+
async showHighlight(pageNumber, location, id) {
|
|
7661
|
+
let highlightDivIds = [];
|
|
7662
|
+
highlightDivIds = this.#highlightEditorsByPage.get(pageNumber) || [];
|
|
7663
|
+
const filteredHighlights = highlightDivIds.filter(item => item.textId === id);
|
|
7664
|
+
if (filteredHighlights.length > 0) {
|
|
7665
|
+
console.log(`DEBUG - Highlights already exist for page ${pageNumber}, textId ${id}, skipping creation.`);
|
|
7666
|
+
filteredHighlights.forEach(item => {
|
|
7667
|
+
const uiManager = this.#uiManager || window.PDFViewerApplication?.pdfViewer?.annotationEditorUIManager;
|
|
7668
|
+
if (uiManager) {
|
|
7669
|
+
const editorList = Array.from(uiManager.getEditors(pageNumber - 1));
|
|
7670
|
+
const editor = editorList.find(e => e.div?.id === item.highlightDivId);
|
|
7671
|
+
if (editor) {
|
|
7672
|
+
console.log("DEBUG - Reusing existing highlight editor:", editor);
|
|
7673
|
+
if (editor.div) {
|
|
7674
|
+
editor.div.style.display = '';
|
|
7675
|
+
editor.div.classList.add('selectedEditor');
|
|
7676
|
+
if (typeof editor.select === 'function') {
|
|
7677
|
+
editor.select();
|
|
7678
|
+
}
|
|
7679
|
+
uiManager.setSelected(editor);
|
|
7680
|
+
}
|
|
7681
|
+
}
|
|
7682
|
+
}
|
|
7683
|
+
});
|
|
7684
|
+
return;
|
|
7685
|
+
}
|
|
7686
|
+
console.log(`DEBUG - No existing highlights for page ${pageNumber}, proceeding to create.`);
|
|
7687
|
+
this.#lastPageNumber = pageNumber;
|
|
7608
7688
|
const uiManager = this.#uiManager || window.PDFViewerApplication?.pdfViewer?.annotationEditorUIManager;
|
|
7609
7689
|
if (!uiManager) {
|
|
7610
7690
|
console.error("UI Manager not initialized. Please enable annotation editing mode.");
|
|
@@ -7626,12 +7706,14 @@ class FilterHighlightOverlay {
|
|
|
7626
7706
|
console.error("Text layer div not found");
|
|
7627
7707
|
return;
|
|
7628
7708
|
}
|
|
7709
|
+
console.log("DEBUG - Text layer before extraction, total spans:", textLayer.querySelectorAll("span[role='presentation']").length);
|
|
7710
|
+
console.log("Extracting text from location:", location);
|
|
7629
7711
|
const textInfo = this.#extractTextFromLocation(textLayer, pageView, location);
|
|
7712
|
+
console.log("Extracting text Info:", textInfo);
|
|
7630
7713
|
if (!textInfo) {
|
|
7631
7714
|
console.error("Could not extract text from location", location);
|
|
7632
7715
|
return;
|
|
7633
7716
|
}
|
|
7634
|
-
console.log("Extracted text info:", textInfo);
|
|
7635
7717
|
const selection = document.getSelection();
|
|
7636
7718
|
selection.removeAllRanges();
|
|
7637
7719
|
const range = document.createRange();
|
|
@@ -7641,8 +7723,11 @@ class FilterHighlightOverlay {
|
|
|
7641
7723
|
selection.addRange(range);
|
|
7642
7724
|
console.log("Selection created:", selection.toString());
|
|
7643
7725
|
setTimeout(() => {
|
|
7644
|
-
uiManager.highlightSelection("filter_view");
|
|
7726
|
+
const editor = uiManager.highlightSelection("filter_view");
|
|
7645
7727
|
selection.removeAllRanges();
|
|
7728
|
+
setTimeout(() => {
|
|
7729
|
+
this.storeHighlightEditorsForCurPageNum(id, pageNumber, uiManager);
|
|
7730
|
+
}, 50);
|
|
7646
7731
|
}, 100);
|
|
7647
7732
|
} catch (error) {
|
|
7648
7733
|
console.error("Error creating selection:", error);
|
|
@@ -7696,15 +7781,20 @@ class FilterHighlightOverlay {
|
|
|
7696
7781
|
const viewport = pageView.viewport;
|
|
7697
7782
|
const [x1, y1] = viewport.convertToViewportPoint(x, y + height);
|
|
7698
7783
|
const [x2, y2] = viewport.convertToViewportPoint(x + width, y);
|
|
7699
|
-
const
|
|
7700
|
-
const
|
|
7784
|
+
const pageRect = pageView.div.getBoundingClientRect();
|
|
7785
|
+
const scaleX = pageRect.width / viewport.width || 1;
|
|
7786
|
+
const scaleY = pageRect.height / viewport.height || 1;
|
|
7787
|
+
const pageWidth = pageRect.width;
|
|
7788
|
+
const pageHeight = pageRect.height;
|
|
7701
7789
|
const minX = Math.min(x1, x2);
|
|
7702
7790
|
const minY = Math.min(y1, y2);
|
|
7791
|
+
const boxWidth = Math.abs(x2 - x1);
|
|
7792
|
+
const boxHeight = Math.abs(y2 - y1);
|
|
7703
7793
|
return [{
|
|
7704
|
-
x: minX / pageWidth,
|
|
7705
|
-
y: minY / pageHeight,
|
|
7706
|
-
width:
|
|
7707
|
-
height:
|
|
7794
|
+
x: minX * scaleX / pageWidth,
|
|
7795
|
+
y: minY * scaleY / pageHeight,
|
|
7796
|
+
width: boxWidth * scaleX / pageWidth,
|
|
7797
|
+
height: boxHeight * scaleY / pageHeight
|
|
7708
7798
|
}];
|
|
7709
7799
|
}
|
|
7710
7800
|
#extractTextFromLocation(textLayer, pageView, location) {
|
|
@@ -7723,38 +7813,130 @@ class FilterHighlightOverlay {
|
|
|
7723
7813
|
const overlayHeight = Math.abs(y2 - y1);
|
|
7724
7814
|
const pageRect = pageView.div.getBoundingClientRect();
|
|
7725
7815
|
const textLayerRect = textLayer.getBoundingClientRect();
|
|
7726
|
-
|
|
7727
|
-
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
|
|
7816
|
+
console.log("DEBUG - pageRect:", {
|
|
7817
|
+
left: pageRect.left,
|
|
7818
|
+
top: pageRect.top,
|
|
7819
|
+
width: pageRect.width,
|
|
7820
|
+
height: pageRect.height
|
|
7821
|
+
});
|
|
7822
|
+
console.log("DEBUG - viewport:", {
|
|
7823
|
+
width: viewport.width,
|
|
7824
|
+
height: viewport.height
|
|
7825
|
+
});
|
|
7826
|
+
const scaleX = pageRect.width / viewport.width || 1;
|
|
7827
|
+
const scaleY = pageRect.height / viewport.height || 1;
|
|
7828
|
+
const overlayPageLeft = overlayLeft * scaleX;
|
|
7829
|
+
const overlayPageTop = overlayTop * scaleY;
|
|
7830
|
+
const overlayPageRight = overlayPageLeft + overlayWidth * scaleX;
|
|
7831
|
+
const overlayPageBottom = overlayPageTop + overlayHeight * scaleY;
|
|
7832
|
+
console.log("DEBUG - overlay bounds (page-relative):", {
|
|
7833
|
+
left: overlayPageLeft,
|
|
7834
|
+
top: overlayPageTop,
|
|
7835
|
+
right: overlayPageRight,
|
|
7836
|
+
bottom: overlayPageBottom
|
|
7837
|
+
});
|
|
7838
|
+
const textElements = Array.from(textLayer.querySelectorAll("span[role='presentation']"));
|
|
7839
|
+
console.log("DEBUG - total text spans:", textElements.length);
|
|
7840
|
+
const candidates = [];
|
|
7841
|
+
let debugSkipped = 0;
|
|
7732
7842
|
for (const span of textElements) {
|
|
7733
7843
|
const rect = span.getBoundingClientRect();
|
|
7734
|
-
const
|
|
7735
|
-
const
|
|
7736
|
-
const
|
|
7737
|
-
const
|
|
7738
|
-
if (
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
|
|
7742
|
-
|
|
7743
|
-
|
|
7744
|
-
|
|
7745
|
-
lastNode = textNode;
|
|
7746
|
-
lastOffset = textNode.textContent.length;
|
|
7747
|
-
collectedText += textNode.textContent;
|
|
7748
|
-
}
|
|
7844
|
+
const spanPageLeft = rect.left - pageRect.left;
|
|
7845
|
+
const spanPageTop = rect.top - pageRect.top;
|
|
7846
|
+
const spanPageRight = rect.right - pageRect.left;
|
|
7847
|
+
const spanPageBottom = rect.bottom - pageRect.top;
|
|
7848
|
+
if (spanPageRight <= overlayPageLeft || spanPageLeft >= overlayPageRight || spanPageBottom <= overlayPageTop || spanPageTop >= overlayPageBottom) {
|
|
7849
|
+
debugSkipped++;
|
|
7850
|
+
continue;
|
|
7851
|
+
}
|
|
7852
|
+
const textNode = span.firstChild;
|
|
7853
|
+
if (!textNode || textNode.nodeType !== Node.TEXT_NODE) {
|
|
7854
|
+
continue;
|
|
7749
7855
|
}
|
|
7856
|
+
candidates.push({
|
|
7857
|
+
span,
|
|
7858
|
+
rect: {
|
|
7859
|
+
left: spanPageLeft,
|
|
7860
|
+
top: spanPageTop,
|
|
7861
|
+
right: spanPageRight,
|
|
7862
|
+
bottom: spanPageBottom,
|
|
7863
|
+
width: rect.width,
|
|
7864
|
+
height: rect.height
|
|
7865
|
+
},
|
|
7866
|
+
textNode
|
|
7867
|
+
});
|
|
7868
|
+
}
|
|
7869
|
+
console.log("DEBUG - candidates found:", candidates.length, "skipped:", debugSkipped);
|
|
7870
|
+
if (candidates.length > 0) {
|
|
7871
|
+
console.log("DEBUG - first candidate:", {
|
|
7872
|
+
text: candidates[0].textNode.textContent.substring(0, 20),
|
|
7873
|
+
rect: candidates[0].rect
|
|
7874
|
+
});
|
|
7875
|
+
console.log("DEBUG - last candidate:", {
|
|
7876
|
+
text: candidates[candidates.length - 1].textNode.textContent.substring(0, 20),
|
|
7877
|
+
rect: candidates[candidates.length - 1].rect
|
|
7878
|
+
});
|
|
7750
7879
|
}
|
|
7751
|
-
if (
|
|
7880
|
+
if (candidates.length === 0) {
|
|
7752
7881
|
return null;
|
|
7753
7882
|
}
|
|
7883
|
+
candidates.sort((a, b) => {
|
|
7884
|
+
const topDiff = a.rect.top - b.rect.top;
|
|
7885
|
+
if (Math.abs(topDiff) > 1) return topDiff;
|
|
7886
|
+
return a.rect.left - b.rect.left;
|
|
7887
|
+
});
|
|
7888
|
+
const first = candidates[0];
|
|
7889
|
+
const last = candidates[candidates.length - 1];
|
|
7890
|
+
const makeOffset = (candidate, overlayL, overlayR, isStart) => {
|
|
7891
|
+
const textLen = candidate.textNode.textContent.length || 0;
|
|
7892
|
+
const rectWidth = candidate.rect.width || 0;
|
|
7893
|
+
const rectLeft = candidate.rect.left;
|
|
7894
|
+
const rectRight = candidate.rect.right;
|
|
7895
|
+
if (textLen === 0 || rectWidth === 0) {
|
|
7896
|
+
return isStart ? 0 : textLen;
|
|
7897
|
+
}
|
|
7898
|
+
const coveredLeft = Math.max(rectLeft, overlayL);
|
|
7899
|
+
const coveredRight = Math.min(rectRight, overlayR);
|
|
7900
|
+
const coveredWidth = Math.max(0, coveredRight - coveredLeft);
|
|
7901
|
+
const coverageRatio = coveredWidth / rectWidth;
|
|
7902
|
+
if (isStart) {
|
|
7903
|
+
if (overlayL <= rectLeft + rectWidth * 0.1) {
|
|
7904
|
+
return 0;
|
|
7905
|
+
}
|
|
7906
|
+
const relStart = Math.max(0, overlayL - rectLeft);
|
|
7907
|
+
const startRatio = Math.max(0, Math.min(1, relStart / rectWidth));
|
|
7908
|
+
return Math.floor(startRatio * textLen);
|
|
7909
|
+
} else {
|
|
7910
|
+
if (overlayR >= rectRight - rectWidth * 0.1) {
|
|
7911
|
+
return textLen;
|
|
7912
|
+
}
|
|
7913
|
+
const relEnd = Math.min(rectRight, overlayR) - rectLeft;
|
|
7914
|
+
const endRatio = Math.max(0, Math.min(1, relEnd / rectWidth));
|
|
7915
|
+
return Math.ceil(endRatio * textLen);
|
|
7916
|
+
}
|
|
7917
|
+
};
|
|
7918
|
+
const firstOffset = makeOffset(first, overlayPageLeft, overlayPageRight, true);
|
|
7919
|
+
const lastOffset = makeOffset(last, overlayPageLeft, overlayPageRight, false);
|
|
7920
|
+
let collectedText = "";
|
|
7921
|
+
console.log("Candidates found:", candidates.length);
|
|
7922
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
7923
|
+
const {
|
|
7924
|
+
textNode
|
|
7925
|
+
} = candidates[i];
|
|
7926
|
+
if (i === 0 && i === candidates.length - 1) {
|
|
7927
|
+
collectedText += textNode.textContent.substring(firstOffset, lastOffset);
|
|
7928
|
+
} else if (i === 0) {
|
|
7929
|
+
collectedText += textNode.textContent.substring(firstOffset);
|
|
7930
|
+
} else if (i === candidates.length - 1) {
|
|
7931
|
+
collectedText += textNode.textContent.substring(0, lastOffset);
|
|
7932
|
+
} else {
|
|
7933
|
+
collectedText += textNode.textContent;
|
|
7934
|
+
}
|
|
7935
|
+
}
|
|
7754
7936
|
return {
|
|
7755
|
-
anchorNode:
|
|
7937
|
+
anchorNode: first.textNode,
|
|
7756
7938
|
anchorOffset: firstOffset,
|
|
7757
|
-
focusNode:
|
|
7939
|
+
focusNode: last.textNode,
|
|
7758
7940
|
focusOffset: lastOffset,
|
|
7759
7941
|
text: collectedText.trim()
|
|
7760
7942
|
};
|
|
@@ -7766,12 +7948,29 @@ class FilterHighlightOverlay {
|
|
|
7766
7948
|
}
|
|
7767
7949
|
return pdfViewer._pages[pageNumber - 1];
|
|
7768
7950
|
}
|
|
7769
|
-
clearHighlight() {
|
|
7951
|
+
async clearHighlight() {
|
|
7770
7952
|
if (this.#currentOverlay) {
|
|
7771
|
-
|
|
7772
|
-
|
|
7953
|
+
console.log("DEBUG - Clearing previous highlights");
|
|
7954
|
+
const uiManager = this.#uiManager || window.PDFViewerApplication?.pdfViewer?.annotationEditorUIManager;
|
|
7955
|
+
if (uiManager) {
|
|
7956
|
+
const editors = uiManager.getEditors();
|
|
7957
|
+
console.log("DEBUG - Editors:", editors, "Type:", typeof editors);
|
|
7958
|
+
if (editors) {
|
|
7959
|
+
const editorList = editors instanceof Map ? Array.from(editors.values()) : Array.isArray(editors) ? editors : Object.values(editors);
|
|
7960
|
+
for (const editor of editorList) {
|
|
7961
|
+
if (editor && typeof editor.remove === 'function') {
|
|
7962
|
+
try {
|
|
7963
|
+
console.log("DEBUG - Removing editor:", editor);
|
|
7964
|
+
editor.remove();
|
|
7965
|
+
} catch (e) {
|
|
7966
|
+
console.warn("Error removing editor:", e);
|
|
7967
|
+
}
|
|
7968
|
+
}
|
|
7969
|
+
}
|
|
7970
|
+
}
|
|
7773
7971
|
}
|
|
7774
7972
|
this.#currentOverlay = null;
|
|
7973
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
7775
7974
|
}
|
|
7776
7975
|
}
|
|
7777
7976
|
}
|
|
@@ -13323,7 +13522,7 @@ class PDFViewer {
|
|
|
13323
13522
|
#textLayerMode = TextLayerMode.ENABLE;
|
|
13324
13523
|
#viewerAlert = null;
|
|
13325
13524
|
constructor(options) {
|
|
13326
|
-
const viewerVersion = "5.4.
|
|
13525
|
+
const viewerVersion = "5.4.460";
|
|
13327
13526
|
if (version !== viewerVersion) {
|
|
13328
13527
|
throw new Error(`The API version "${version}" does not match the Viewer version "${viewerVersion}".`);
|
|
13329
13528
|
}
|
|
@@ -17330,7 +17529,76 @@ const PDFViewerApplication = {
|
|
|
17330
17529
|
await (this.pdfDocument?.annotationStorage.size > 0 ? this.save() : this.download());
|
|
17331
17530
|
classList.remove("wait");
|
|
17332
17531
|
},
|
|
17333
|
-
async saveSelectionAsJson() {
|
|
17532
|
+
async saveSelectionAsJson(params = null) {
|
|
17533
|
+
console.log("params:", params);
|
|
17534
|
+
if (params?.methodOfCreation === "editor_save_button" && params?.editorInfo) {
|
|
17535
|
+
const {
|
|
17536
|
+
editorInfo
|
|
17537
|
+
} = params;
|
|
17538
|
+
const pageView = this.pdfViewer.getPageView(editorInfo.pageIndex);
|
|
17539
|
+
if (!pageView) {
|
|
17540
|
+
console.warn("Could not find page view for editor");
|
|
17541
|
+
return;
|
|
17542
|
+
}
|
|
17543
|
+
const pageElement = this.pdfViewer.viewer.querySelector(`.page[data-page-number="${editorInfo.pageNumber}"]`);
|
|
17544
|
+
if (!pageElement) {
|
|
17545
|
+
console.warn("Could not find page element for editor");
|
|
17546
|
+
return;
|
|
17547
|
+
}
|
|
17548
|
+
const textLayer = pageElement.querySelector(".textLayer");
|
|
17549
|
+
if (!textLayer) {
|
|
17550
|
+
console.warn("Could not find text layer for editor");
|
|
17551
|
+
return;
|
|
17552
|
+
}
|
|
17553
|
+
const textLayerRect = textLayer.getBoundingClientRect();
|
|
17554
|
+
const x = editorInfo.screenRect.left - textLayerRect.left;
|
|
17555
|
+
const y = editorInfo.screenRect.top - textLayerRect.top;
|
|
17556
|
+
const width = editorInfo.screenRect.width;
|
|
17557
|
+
const height = editorInfo.screenRect.height;
|
|
17558
|
+
const pdfCoords = pageView.getPagePoint(x, y);
|
|
17559
|
+
const pdfCoordsEnd = pageView.getPagePoint(x + width, y + height);
|
|
17560
|
+
const location = [Math.round(pdfCoords[0]), Math.round(pdfCoords[1]), Math.round(pdfCoordsEnd[0]), Math.round(pdfCoordsEnd[1])];
|
|
17561
|
+
const data = {
|
|
17562
|
+
page: editorInfo.pageNumber,
|
|
17563
|
+
text: editorInfo.textContent,
|
|
17564
|
+
location,
|
|
17565
|
+
timestamp: Date.now(),
|
|
17566
|
+
documentUrl: this.url || window.location.href
|
|
17567
|
+
};
|
|
17568
|
+
console.log("Selection data sent to parent window within Editor:", data);
|
|
17569
|
+
if (this.isViewerEmbedded && window.parent !== window) {
|
|
17570
|
+
try {
|
|
17571
|
+
window.parent.postMessage({
|
|
17572
|
+
type: "pdfjs-selection",
|
|
17573
|
+
source: "pdf.js",
|
|
17574
|
+
data
|
|
17575
|
+
}, "*");
|
|
17576
|
+
console.log("Selection data sent to parent window:", data);
|
|
17577
|
+
} catch (postError) {
|
|
17578
|
+
console.error("Error posting message to parent:", postError);
|
|
17579
|
+
}
|
|
17580
|
+
}
|
|
17581
|
+
try {
|
|
17582
|
+
const customEvent = new CustomEvent("pdfselectioncaptured", {
|
|
17583
|
+
bubbles: true,
|
|
17584
|
+
cancelable: false,
|
|
17585
|
+
detail: data
|
|
17586
|
+
});
|
|
17587
|
+
if (this.isViewerEmbedded) {
|
|
17588
|
+
try {
|
|
17589
|
+
parent.document.dispatchEvent(customEvent);
|
|
17590
|
+
} catch {
|
|
17591
|
+
document.dispatchEvent(customEvent);
|
|
17592
|
+
}
|
|
17593
|
+
} else {
|
|
17594
|
+
document.dispatchEvent(customEvent);
|
|
17595
|
+
}
|
|
17596
|
+
} catch (eventError) {
|
|
17597
|
+
console.error("Error dispatching custom event:", eventError);
|
|
17598
|
+
}
|
|
17599
|
+
console.log("Selection saved and transferred (from editor):", data);
|
|
17600
|
+
return;
|
|
17601
|
+
}
|
|
17334
17602
|
try {
|
|
17335
17603
|
const selection = window.getSelection();
|
|
17336
17604
|
if (!selection || selection.rangeCount === 0) {
|