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/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,35 +1,61 @@
|
|
|
1
1
|
[
|
|
2
2
|
{
|
|
3
|
+
"id": "highlight-1",
|
|
3
4
|
"location": [
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
25,
|
|
6
|
+
505,
|
|
7
|
+
256,
|
|
8
|
+
407
|
|
8
9
|
],
|
|
9
|
-
"page":
|
|
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",
|
|
26
|
+
"location": [
|
|
27
|
+
22,
|
|
28
|
+
500,
|
|
29
|
+
563,
|
|
30
|
+
267
|
|
31
|
+
],
|
|
32
|
+
"page": 1,
|
|
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.");
|
|
@@ -7615,9 +7695,10 @@ class FilterHighlightOverlay {
|
|
|
7615
7695
|
console.error("Page view not found for page", pageNumber);
|
|
7616
7696
|
return;
|
|
7617
7697
|
}
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7698
|
+
try {
|
|
7699
|
+
await this.#waitForTextLayer(pageView);
|
|
7700
|
+
} catch (error) {
|
|
7701
|
+
console.error("Failed to load text layer:", error);
|
|
7621
7702
|
return;
|
|
7622
7703
|
}
|
|
7623
7704
|
const textLayer = pageView.textLayer.div;
|
|
@@ -7625,12 +7706,14 @@ class FilterHighlightOverlay {
|
|
|
7625
7706
|
console.error("Text layer div not found");
|
|
7626
7707
|
return;
|
|
7627
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);
|
|
7628
7711
|
const textInfo = this.#extractTextFromLocation(textLayer, pageView, location);
|
|
7712
|
+
console.log("Extracting text Info:", textInfo);
|
|
7629
7713
|
if (!textInfo) {
|
|
7630
7714
|
console.error("Could not extract text from location", location);
|
|
7631
7715
|
return;
|
|
7632
7716
|
}
|
|
7633
|
-
console.log("Extracted text info:", textInfo);
|
|
7634
7717
|
const selection = document.getSelection();
|
|
7635
7718
|
selection.removeAllRanges();
|
|
7636
7719
|
const range = document.createRange();
|
|
@@ -7640,14 +7723,51 @@ class FilterHighlightOverlay {
|
|
|
7640
7723
|
selection.addRange(range);
|
|
7641
7724
|
console.log("Selection created:", selection.toString());
|
|
7642
7725
|
setTimeout(() => {
|
|
7643
|
-
uiManager.highlightSelection("filter_view");
|
|
7726
|
+
const editor = uiManager.highlightSelection("filter_view");
|
|
7644
7727
|
selection.removeAllRanges();
|
|
7728
|
+
setTimeout(() => {
|
|
7729
|
+
this.storeHighlightEditorsForCurPageNum(id, pageNumber, uiManager);
|
|
7730
|
+
}, 50);
|
|
7645
7731
|
}, 100);
|
|
7646
7732
|
} catch (error) {
|
|
7647
7733
|
console.error("Error creating selection:", error);
|
|
7648
7734
|
selection.removeAllRanges();
|
|
7649
7735
|
}
|
|
7650
7736
|
}
|
|
7737
|
+
async #waitForTextLayer(pageView) {
|
|
7738
|
+
if (pageView.textLayer?.div) {
|
|
7739
|
+
return;
|
|
7740
|
+
}
|
|
7741
|
+
if (pageView.renderingState < 3) {
|
|
7742
|
+
await new Promise(resolve => {
|
|
7743
|
+
const checkRendering = () => {
|
|
7744
|
+
if (pageView.renderingState >= 3) {
|
|
7745
|
+
resolve();
|
|
7746
|
+
} else {
|
|
7747
|
+
setTimeout(checkRendering, 50);
|
|
7748
|
+
}
|
|
7749
|
+
};
|
|
7750
|
+
checkRendering();
|
|
7751
|
+
});
|
|
7752
|
+
}
|
|
7753
|
+
if (pageView.textLayer?.renderingDone) {
|
|
7754
|
+
await pageView.textLayer.renderingDone;
|
|
7755
|
+
return;
|
|
7756
|
+
}
|
|
7757
|
+
return new Promise((resolve, reject) => {
|
|
7758
|
+
const timeout = setTimeout(() => {
|
|
7759
|
+
reject(new Error("Text layer rendering timeout"));
|
|
7760
|
+
}, 5000);
|
|
7761
|
+
const handler = evt => {
|
|
7762
|
+
if (evt.pageNumber === pageView.id) {
|
|
7763
|
+
clearTimeout(timeout);
|
|
7764
|
+
this.#eventBus._off("textlayerrendered", handler);
|
|
7765
|
+
resolve();
|
|
7766
|
+
}
|
|
7767
|
+
};
|
|
7768
|
+
this.#eventBus._on("textlayerrendered", handler);
|
|
7769
|
+
});
|
|
7770
|
+
}
|
|
7651
7771
|
#convertLocationToBoxes(pageView, location) {
|
|
7652
7772
|
if (!pageView.div) {
|
|
7653
7773
|
return null;
|
|
@@ -7661,15 +7781,20 @@ class FilterHighlightOverlay {
|
|
|
7661
7781
|
const viewport = pageView.viewport;
|
|
7662
7782
|
const [x1, y1] = viewport.convertToViewportPoint(x, y + height);
|
|
7663
7783
|
const [x2, y2] = viewport.convertToViewportPoint(x + width, y);
|
|
7664
|
-
const
|
|
7665
|
-
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;
|
|
7666
7789
|
const minX = Math.min(x1, x2);
|
|
7667
7790
|
const minY = Math.min(y1, y2);
|
|
7791
|
+
const boxWidth = Math.abs(x2 - x1);
|
|
7792
|
+
const boxHeight = Math.abs(y2 - y1);
|
|
7668
7793
|
return [{
|
|
7669
|
-
x: minX / pageWidth,
|
|
7670
|
-
y: minY / pageHeight,
|
|
7671
|
-
width:
|
|
7672
|
-
height:
|
|
7794
|
+
x: minX * scaleX / pageWidth,
|
|
7795
|
+
y: minY * scaleY / pageHeight,
|
|
7796
|
+
width: boxWidth * scaleX / pageWidth,
|
|
7797
|
+
height: boxHeight * scaleY / pageHeight
|
|
7673
7798
|
}];
|
|
7674
7799
|
}
|
|
7675
7800
|
#extractTextFromLocation(textLayer, pageView, location) {
|
|
@@ -7688,38 +7813,130 @@ class FilterHighlightOverlay {
|
|
|
7688
7813
|
const overlayHeight = Math.abs(y2 - y1);
|
|
7689
7814
|
const pageRect = pageView.div.getBoundingClientRect();
|
|
7690
7815
|
const textLayerRect = textLayer.getBoundingClientRect();
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
7696
|
-
|
|
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;
|
|
7697
7842
|
for (const span of textElements) {
|
|
7698
7843
|
const rect = span.getBoundingClientRect();
|
|
7699
|
-
const
|
|
7700
|
-
const
|
|
7701
|
-
const
|
|
7702
|
-
const
|
|
7703
|
-
if (
|
|
7704
|
-
|
|
7705
|
-
|
|
7706
|
-
|
|
7707
|
-
|
|
7708
|
-
|
|
7709
|
-
|
|
7710
|
-
lastNode = textNode;
|
|
7711
|
-
lastOffset = textNode.textContent.length;
|
|
7712
|
-
collectedText += textNode.textContent;
|
|
7713
|
-
}
|
|
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;
|
|
7714
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
|
+
});
|
|
7715
7868
|
}
|
|
7716
|
-
|
|
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
|
+
});
|
|
7879
|
+
}
|
|
7880
|
+
if (candidates.length === 0) {
|
|
7717
7881
|
return null;
|
|
7718
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
|
+
}
|
|
7719
7936
|
return {
|
|
7720
|
-
anchorNode:
|
|
7937
|
+
anchorNode: first.textNode,
|
|
7721
7938
|
anchorOffset: firstOffset,
|
|
7722
|
-
focusNode:
|
|
7939
|
+
focusNode: last.textNode,
|
|
7723
7940
|
focusOffset: lastOffset,
|
|
7724
7941
|
text: collectedText.trim()
|
|
7725
7942
|
};
|
|
@@ -7731,12 +7948,29 @@ class FilterHighlightOverlay {
|
|
|
7731
7948
|
}
|
|
7732
7949
|
return pdfViewer._pages[pageNumber - 1];
|
|
7733
7950
|
}
|
|
7734
|
-
clearHighlight() {
|
|
7951
|
+
async clearHighlight() {
|
|
7735
7952
|
if (this.#currentOverlay) {
|
|
7736
|
-
|
|
7737
|
-
|
|
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
|
+
}
|
|
7738
7971
|
}
|
|
7739
7972
|
this.#currentOverlay = null;
|
|
7973
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
7740
7974
|
}
|
|
7741
7975
|
}
|
|
7742
7976
|
}
|
|
@@ -13288,7 +13522,7 @@ class PDFViewer {
|
|
|
13288
13522
|
#textLayerMode = TextLayerMode.ENABLE;
|
|
13289
13523
|
#viewerAlert = null;
|
|
13290
13524
|
constructor(options) {
|
|
13291
|
-
const viewerVersion = "5.4.
|
|
13525
|
+
const viewerVersion = "5.4.460";
|
|
13292
13526
|
if (version !== viewerVersion) {
|
|
13293
13527
|
throw new Error(`The API version "${version}" does not match the Viewer version "${viewerVersion}".`);
|
|
13294
13528
|
}
|
|
@@ -17295,7 +17529,76 @@ const PDFViewerApplication = {
|
|
|
17295
17529
|
await (this.pdfDocument?.annotationStorage.size > 0 ? this.save() : this.download());
|
|
17296
17530
|
classList.remove("wait");
|
|
17297
17531
|
},
|
|
17298
|
-
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
|
+
}
|
|
17299
17602
|
try {
|
|
17300
17603
|
const selection = window.getSelection();
|
|
17301
17604
|
if (!selection || selection.rangeCount === 0) {
|