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.
@@ -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
  /******/ 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
- async showHighlight(pageNumber, location) {
12402
- this.clearHighlight();
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
+ console.log(`DEBUG - Found HighlightEditor with div ID and pushed it:`, {
12467
+ textId: id,
12468
+ highlightDivId: divId
12469
+ });
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.");
@@ -12421,12 +12548,14 @@ class FilterHighlightOverlay {
12421
12548
  console.error("Text layer div not found");
12422
12549
  return;
12423
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);
12424
12553
  const textInfo = this.#extractTextFromLocation(textLayer, pageView, location);
12554
+ console.log("Extracting text Info:", textInfo);
12425
12555
  if (!textInfo) {
12426
12556
  console.error("Could not extract text from location", location);
12427
12557
  return;
12428
12558
  }
12429
- console.log("Extracted text info:", textInfo);
12430
12559
  const selection = document.getSelection();
12431
12560
  selection.removeAllRanges();
12432
12561
  const range = document.createRange();
@@ -12436,8 +12565,11 @@ class FilterHighlightOverlay {
12436
12565
  selection.addRange(range);
12437
12566
  console.log("Selection created:", selection.toString());
12438
12567
  setTimeout(() => {
12439
- uiManager.highlightSelection("filter_view");
12568
+ const editor = uiManager.highlightSelection("filter_view");
12440
12569
  selection.removeAllRanges();
12570
+ setTimeout(() => {
12571
+ this.storeHighlightEditorsForCurPageNum(id, pageNumber, uiManager);
12572
+ }, 50);
12441
12573
  }, 100);
12442
12574
  } catch (error) {
12443
12575
  console.error("Error creating selection:", error);
@@ -12491,15 +12623,20 @@ class FilterHighlightOverlay {
12491
12623
  const viewport = pageView.viewport;
12492
12624
  const [x1, y1] = viewport.convertToViewportPoint(x, y + height);
12493
12625
  const [x2, y2] = viewport.convertToViewportPoint(x + width, y);
12494
- const pageWidth = viewport.width;
12495
- const pageHeight = viewport.height;
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;
12496
12631
  const minX = Math.min(x1, x2);
12497
12632
  const minY = Math.min(y1, y2);
12633
+ const boxWidth = Math.abs(x2 - x1);
12634
+ const boxHeight = Math.abs(y2 - y1);
12498
12635
  return [{
12499
- x: minX / pageWidth,
12500
- y: minY / pageHeight,
12501
- width: Math.abs(x2 - x1) / pageWidth,
12502
- height: Math.abs(y2 - y1) / pageHeight
12636
+ x: minX * scaleX / pageWidth,
12637
+ y: minY * scaleY / pageHeight,
12638
+ width: boxWidth * scaleX / pageWidth,
12639
+ height: boxHeight * scaleY / pageHeight
12503
12640
  }];
12504
12641
  }
12505
12642
  #extractTextFromLocation(textLayer, pageView, location) {
@@ -12518,38 +12655,130 @@ class FilterHighlightOverlay {
12518
12655
  const overlayHeight = Math.abs(y2 - y1);
12519
12656
  const pageRect = pageView.div.getBoundingClientRect();
12520
12657
  const textLayerRect = textLayer.getBoundingClientRect();
12521
- const textElements = textLayer.querySelectorAll("span[role='presentation']");
12522
- let firstNode = null;
12523
- let firstOffset = 0;
12524
- let lastNode = null;
12525
- let lastOffset = 0;
12526
- let collectedText = "";
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;
12527
12684
  for (const span of textElements) {
12528
12685
  const rect = span.getBoundingClientRect();
12529
- const spanLeft = rect.left - pageRect.left;
12530
- const spanTop = rect.top - pageRect.top;
12531
- const spanRight = rect.right - pageRect.left;
12532
- const spanBottom = rect.bottom - pageRect.top;
12533
- if (spanRight > overlayLeft && spanLeft < overlayLeft + overlayWidth && spanBottom > overlayTop && spanTop < overlayTop + overlayHeight) {
12534
- const textNode = span.firstChild;
12535
- if (textNode && textNode.nodeType === Node.TEXT_NODE) {
12536
- if (!firstNode) {
12537
- firstNode = textNode;
12538
- firstOffset = 0;
12539
- }
12540
- lastNode = textNode;
12541
- lastOffset = textNode.textContent.length;
12542
- collectedText += textNode.textContent;
12543
- }
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;
12693
+ }
12694
+ const textNode = span.firstChild;
12695
+ if (!textNode || textNode.nodeType !== Node.TEXT_NODE) {
12696
+ continue;
12544
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
+ });
12545
12710
  }
12546
- if (!firstNode || !lastNode) {
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
+ });
12721
+ }
12722
+ if (candidates.length === 0) {
12547
12723
  return null;
12548
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
+ }
12549
12778
  return {
12550
- anchorNode: firstNode,
12779
+ anchorNode: first.textNode,
12551
12780
  anchorOffset: firstOffset,
12552
- focusNode: lastNode,
12781
+ focusNode: last.textNode,
12553
12782
  focusOffset: lastOffset,
12554
12783
  text: collectedText.trim()
12555
12784
  };
@@ -12561,12 +12790,29 @@ class FilterHighlightOverlay {
12561
12790
  }
12562
12791
  return pdfViewer._pages[pageNumber - 1];
12563
12792
  }
12564
- clearHighlight() {
12793
+ async clearHighlight() {
12565
12794
  if (this.#currentOverlay) {
12566
- if (typeof this.#currentOverlay.remove === 'function') {
12567
- this.#currentOverlay.remove();
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
+ }
12568
12813
  }
12569
12814
  this.#currentOverlay = null;
12815
+ await new Promise(resolve => setTimeout(resolve, 100));
12570
12816
  }
12571
12817
  }
12572
12818
  }
@@ -18188,7 +18434,7 @@ class PDFViewer {
18188
18434
  #textLayerMode = TextLayerMode.ENABLE;
18189
18435
  #viewerAlert = null;
18190
18436
  constructor(options) {
18191
- const viewerVersion = "5.4.457";
18437
+ const viewerVersion = "5.4.462";
18192
18438
  if (version !== viewerVersion) {
18193
18439
  throw new Error(`The API version "${version}" does not match the Viewer version "${viewerVersion}".`);
18194
18440
  }
@@ -22216,7 +22462,76 @@ const PDFViewerApplication = {
22216
22462
  await (this.pdfDocument?.annotationStorage.size > 0 ? this.save() : this.download());
22217
22463
  classList.remove("wait");
22218
22464
  },
22219
- 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
+ }
22220
22535
  try {
22221
22536
  const selection = window.getSelection();
22222
22537
  if (!selection || selection.rangeCount === 0) {