pdfjs-viewer-highlight-echo 5.4.457 → 5.4.462

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pdfjs-viewer-highlight-echo",
3
- "version": "5.4.457",
3
+ "version": "5.4.462",
4
4
  "main": "build/pdf.mjs",
5
5
  "types": "types/src/pdf.d.ts",
6
6
  "description": "Dafu custom PDF.js distribution",
@@ -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;
@@ -47,6 +47,8 @@ export class HighlightEditor extends AnnotationEditor {
47
47
  color: any;
48
48
  };
49
49
  /** @inheritdoc */
50
+ get contentText(): string;
51
+ /** @inheritdoc */
50
52
  translateInPage(x: any, y: any): void;
51
53
  /** @inheritdoc */
52
54
  get commentButtonPosition(): null;
@@ -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
- 315,
15
- 488,
16
- 239,
17
- -33
38
+ 584,
39
+ 298,
40
+ 669,
41
+ 286
18
42
  ],
19
- "page": 13,
20
- "text": "run dynamic languages efficiently by\nrecording hot …hnique focuses on aggressively inlined loops, and"
43
+ "page": 4,
44
+ "text": "Read more on page 15."
21
45
  },
22
46
  {
47
+ "id": "highlight-4",
23
48
  "location": [
24
- 315,
25
- 186,
26
- 239,
27
- -102
49
+ 46,
50
+ 441,
51
+ 265,
52
+ 411
28
53
  ],
29
54
  "page": 4,
30
- "text": "For example, the search might finds the value of\no.x in the prototype of o, which uses a shared hash-table represen-\ntation that places x in slot 2 of a property vector. Then the recorded\ncan generate LIR that reads o.x with just two or three loads: one to\nget the prototype, possibly one to get the property value vector, and\none more to get slot 2 from the vector. This is a vast simplification\nand speedup compared to the original interpreter code. Inheritance\nrelationships and object representations can change during execu-\ntion, so the simplified code requires guard instructions that ensure\nthe object representation is the same. In TraceMonkey, objects’ rep-"
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,
@@ -21,8 +21,8 @@
21
21
  */
22
22
 
23
23
  /**
24
- * pdfjsVersion = 5.4.457
25
- * pdfjsBuild = d53d4404b
24
+ * pdfjsVersion = 5.4.462
25
+ * pdfjsBuild = 34e1cb08c
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.457";
7658
+ const viewerVersion = "5.4.462";
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.457
25
- * pdfjsBuild = d53d4404b
24
+ * pdfjsVersion = 5.4.462
25
+ * pdfjsBuild = 34e1cb08c
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
- async showHighlight(pageNumber, location) {
7607
- this.clearHighlight();
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
+ console.log(`DEBUG - Found HighlightEditor with div ID and pushed it:`, {
7625
+ textId: id,
7626
+ highlightDivId: divId
7627
+ });
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 pageWidth = viewport.width;
7700
- const pageHeight = viewport.height;
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: Math.abs(x2 - x1) / pageWidth,
7707
- height: Math.abs(y2 - y1) / pageHeight
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
- const textElements = textLayer.querySelectorAll("span[role='presentation']");
7727
- let firstNode = null;
7728
- let firstOffset = 0;
7729
- let lastNode = null;
7730
- let lastOffset = 0;
7731
- let collectedText = "";
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 spanLeft = rect.left - pageRect.left;
7735
- const spanTop = rect.top - pageRect.top;
7736
- const spanRight = rect.right - pageRect.left;
7737
- const spanBottom = rect.bottom - pageRect.top;
7738
- if (spanRight > overlayLeft && spanLeft < overlayLeft + overlayWidth && spanBottom > overlayTop && spanTop < overlayTop + overlayHeight) {
7739
- const textNode = span.firstChild;
7740
- if (textNode && textNode.nodeType === Node.TEXT_NODE) {
7741
- if (!firstNode) {
7742
- firstNode = textNode;
7743
- firstOffset = 0;
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 (!firstNode || !lastNode) {
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: firstNode,
7937
+ anchorNode: first.textNode,
7756
7938
  anchorOffset: firstOffset,
7757
- focusNode: lastNode,
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
- if (typeof this.#currentOverlay.remove === 'function') {
7772
- this.#currentOverlay.remove();
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.457";
13525
+ const viewerVersion = "5.4.462";
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) {