@epam/pdf-highlighter-kit 0.0.9 → 0.0.13

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.
Files changed (39) hide show
  1. package/README.md +16 -2
  2. package/dist/PDFHighlightViewer.d.ts +15 -5
  3. package/dist/PDFHighlightViewer.d.ts.map +1 -1
  4. package/dist/PDFHighlightViewer.js +75 -40
  5. package/dist/PDFHighlightViewer.js.map +1 -1
  6. package/dist/api.d.ts +5 -5
  7. package/dist/api.d.ts.map +1 -1
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js.map +1 -1
  10. package/dist/core/pdf-engine.d.ts +2 -2
  11. package/dist/core/pdf-engine.d.ts.map +1 -1
  12. package/dist/core/pdf-engine.js +2 -8
  13. package/dist/core/pdf-engine.js.map +1 -1
  14. package/dist/core/performance-optimizer.d.ts +10 -10
  15. package/dist/core/performance-optimizer.d.ts.map +1 -1
  16. package/dist/core/performance-optimizer.js +2 -1
  17. package/dist/core/performance-optimizer.js.map +1 -1
  18. package/dist/core/viewport-manager.d.ts +18 -7
  19. package/dist/core/viewport-manager.d.ts.map +1 -1
  20. package/dist/core/viewport-manager.js +84 -35
  21. package/dist/core/viewport-manager.js.map +1 -1
  22. package/dist/index.d.ts +7 -7
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +6 -6
  25. package/dist/index.js.map +1 -1
  26. package/dist/types.d.ts +18 -9
  27. package/dist/types.d.ts.map +1 -1
  28. package/dist/types.js.map +1 -1
  29. package/dist/utils/label-style.d.ts.map +1 -1
  30. package/dist/utils/label-style.js +3 -2
  31. package/dist/utils/label-style.js.map +1 -1
  32. package/dist/utils/pdf-utils.d.ts +3 -2
  33. package/dist/utils/pdf-utils.d.ts.map +1 -1
  34. package/dist/utils/pdf-utils.js +2 -2
  35. package/dist/utils/pdf-utils.js.map +1 -1
  36. package/dist/utils/worker-loader-simple.d.ts.map +1 -1
  37. package/dist/utils/worker-loader-simple.js +4 -1
  38. package/dist/utils/worker-loader-simple.js.map +1 -1
  39. package/package.json +1 -1
package/README.md CHANGED
@@ -201,9 +201,14 @@ export interface ViewerOptions {
201
201
 
202
202
  // Page dimensions for which bbox coordinates were calculated
203
203
  bboxSourceDimensions?: BBoxDimensions;
204
+
205
+ // Only show these document page numbers (1-based). If empty or omitted, all pages are shown.
206
+ selectedPages?: number[];
204
207
  }
205
208
  ```
206
209
 
210
+ **Displaying only selected pages:** Use `selectedPages` to show a subset of the document (e.g. `[1, 3, 5]` or `[2, 4, 6, 8]`). The full PDF is still loaded; only the listed pages get DOM containers and participate in scrolling and rendering. Page numbers in the API (e.g. `setPage`, events, highlights) remain physical document page numbers. You can pass `selectedPages` in `init` options or per load via `loadPDF(source, { selectedPages })`; the latter overrides the init value for that load. `getTotalPages()` returns the length of the displayed list when `selectedPages` is set.
211
+
207
212
  ## API Reference
208
213
 
209
214
  ### Main Methods
@@ -212,9 +217,18 @@ export interface ViewerOptions {
212
217
 
213
218
  Initialize the viewer with a container element and optional configuration.
214
219
 
215
- #### `loadPDF(source: string | ArrayBuffer | Blob): Promise<void>`
220
+ #### `loadPDF(source: string | ArrayBuffer | Blob, options?: LoadPDFOptions): Promise<void>`
221
+
222
+ Load a PDF document from URL or ArrayBuffer. Optional second argument:
223
+
224
+ ```ts
225
+ interface LoadPDFOptions {
226
+ /** Only show these document page numbers (1-based). If empty or omitted, all pages are shown. */
227
+ selectedPages?: number[];
228
+ }
229
+ ```
216
230
 
217
- Load a PDF document from URL or ArrayBuffer.
231
+ Example: `await viewer.loadPDF(url, { selectedPages: [1, 3, 5] });` shows only pages 1, 3, and 5. When `options.selectedPages` is provided, it overrides `ViewerOptions.selectedPages` for this load.
218
232
 
219
233
  #### `loadHighlights(highlights: InputHighlightData[]): void`
220
234
 
@@ -1,5 +1,5 @@
1
1
  import { PDFHighlightViewer as IPDFHighlightViewer } from './api';
2
- import { ViewerOptions, TextRange, SelectionWithMetadata, PerformanceMetrics, HighlightAnalytics, AccessibilityFeatures, InteractionMode, InputHighlightData, HighlightStyle, HighlightLabelStyle, ZoomValue, ThumbnailOptions } from './types';
2
+ import { PDFSource, ViewerOptions, LoadPDFOptions, TextRange, SelectionWithMetadata, PerformanceMetrics, HighlightAnalytics, AccessibilityFeatures, InteractionMode, InputHighlightData, HighlightStyle, HighlightLabelStyle, ZoomValue, ThumbnailOptions } from './types';
3
3
  type EventCallback = (data?: unknown) => void;
4
4
  export declare class PDFHighlightViewer implements IPDFHighlightViewer {
5
5
  private pdfEngine;
@@ -15,6 +15,10 @@ export declare class PDFHighlightViewer implements IPDFHighlightViewer {
15
15
  private currentPage;
16
16
  private currentScale;
17
17
  private totalPages;
18
+ /** Actual number of pages in the loaded PDF (1..documentNumPages). */
19
+ private documentNumPages;
20
+ /** When set, only these physical page numbers are shown; null = all pages. */
21
+ private selectedPages;
18
22
  private selectedTermId;
19
23
  private isInitialized;
20
24
  private navIndex;
@@ -58,9 +62,15 @@ export declare class PDFHighlightViewer implements IPDFHighlightViewer {
58
62
  * Handle keyboard navigation
59
63
  */
60
64
  private handleKeyboardNavigation;
61
- loadPDF(source: string | ArrayBuffer | Blob): Promise<void>;
65
+ loadPDF(source: PDFSource, options?: LoadPDFOptions): Promise<void>;
62
66
  /**
63
- * Create DOM containers for all pages with real PDF dimensions
67
+ * Normalize selectedPages: filter to 1..numPages, dedupe, sort. Empty result => null (show all).
68
+ */
69
+ private normalizeSelectedPages;
70
+ /** List of physical page numbers to display (either selectedPages or 1..documentNumPages). */
71
+ private getDisplayedPageList;
72
+ /**
73
+ * Create DOM containers for displayed pages only (selectedPages or all)
64
74
  */
65
75
  private createPageContainers;
66
76
  /**
@@ -125,7 +135,7 @@ export declare class PDFHighlightViewer implements IPDFHighlightViewer {
125
135
  getSelection: () => string;
126
136
  getSelectionWithContext: () => SelectionWithMetadata | null;
127
137
  clearSelection: () => void;
128
- selectText: (range: TextRange) => void;
138
+ selectText: (_range: TextRange) => void;
129
139
  copySelection: (format?: "plain" | "formatted" | "citation") => void;
130
140
  createHighlightFromSelection: (style?: HighlightStyle) => InputHighlightData | null;
131
141
  };
@@ -188,7 +198,7 @@ export declare class PDFHighlightViewer implements IPDFHighlightViewer {
188
198
  private toPageCoordinateDimensions;
189
199
  private normalizeBBoxForPage;
190
200
  /**
191
- * Build spatial indices for all pages
201
+ * Build spatial indices for displayed pages only
192
202
  */
193
203
  private buildAllSpatialIndices;
194
204
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"PDFHighlightViewer.d.ts","sourceRoot":"","sources":["../src/PDFHighlightViewer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PDFHighlightViewer.d.ts","sourceRoot":"","sources":["../src/PDFHighlightViewer.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,10 @@ export class PDFHighlightViewer {
23
23
  this.currentPage = 1;
24
24
  this.currentScale = 1.5;
25
25
  this.totalPages = 0;
26
+ /** Actual number of pages in the loaded PDF (1..documentNumPages). */
27
+ this.documentNumPages = 0;
28
+ /** When set, only these physical page numbers are shown; null = all pages. */
29
+ this.selectedPages = null;
26
30
  this.selectedTermId = null;
27
31
  this.isInitialized = false;
28
32
  this.navIndex = -1;
@@ -56,9 +60,8 @@ export class PDFHighlightViewer {
56
60
  clearSelection: () => {
57
61
  this.interactionHandler.clearSelection();
58
62
  },
59
- selectText: (range) => {
63
+ selectText: (_range) => {
60
64
  // TODO: Implement programmatic text selection
61
- console.log('selectText not yet implemented:', range);
62
65
  },
63
66
  copySelection: (format = 'plain') => {
64
67
  const selection = this.textSelection.getSelection();
@@ -441,23 +444,30 @@ export class PDFHighlightViewer {
441
444
  * Handle keyboard navigation
442
445
  */
443
446
  handleKeyboardNavigation(event) {
447
+ const displayed = this.getDisplayedPageList();
448
+ if (displayed.length === 0)
449
+ return;
450
+ const currentIdx = displayed.indexOf(this.currentPage);
451
+ const idx = currentIdx >= 0 ? currentIdx : 0;
444
452
  switch (event.key) {
445
453
  case 'PageDown':
446
454
  case 'ArrowDown':
447
- this.setPage(Math.min(this.totalPages, this.currentPage + 1));
455
+ if (idx < displayed.length - 1)
456
+ this.setPage(displayed[idx + 1]);
448
457
  event.preventDefault();
449
458
  break;
450
459
  case 'PageUp':
451
460
  case 'ArrowUp':
452
- this.setPage(Math.max(1, this.currentPage - 1));
461
+ if (idx > 0)
462
+ this.setPage(displayed[idx - 1]);
453
463
  event.preventDefault();
454
464
  break;
455
465
  case 'Home':
456
- this.setPage(1);
466
+ this.setPage(displayed[0]);
457
467
  event.preventDefault();
458
468
  break;
459
469
  case 'End':
460
- this.setPage(this.totalPages);
470
+ this.setPage(displayed[displayed.length - 1]);
461
471
  event.preventDefault();
462
472
  break;
463
473
  case '+':
@@ -474,20 +484,23 @@ export class PDFHighlightViewer {
474
484
  // =============================================================================
475
485
  // PDF Management
476
486
  // =============================================================================
477
- async loadPDF(source) {
487
+ async loadPDF(source, options) {
478
488
  if (!this.isInitialized) {
479
489
  throw new Error('Viewer must be initialized before loading PDF');
480
490
  }
481
491
  try {
482
- // Load document with PDF engine
483
492
  await this.pdfEngine.loadDocument(source);
484
493
  const docInfo = this.pdfEngine.getDocumentInfo();
485
- this.totalPages = docInfo.numPages;
486
- // Update viewport manager with total pages
494
+ this.documentNumPages = docInfo.numPages;
495
+ const rawSelected = options?.selectedPages ?? this.options.selectedPages;
496
+ const selectedPages = this.normalizeSelectedPages(rawSelected, this.documentNumPages);
497
+ this.selectedPages = selectedPages;
498
+ this.totalPages = selectedPages !== null ? selectedPages.length : this.documentNumPages;
499
+ this.viewportManager.setSelectedPages(selectedPages);
487
500
  this.viewportManager.setTotalPages(this.totalPages);
488
- // Create page containers
489
501
  await this.createPageContainers();
490
- // Load initial pages
502
+ const displayed = this.getDisplayedPageList();
503
+ this.currentPage = displayed.length > 0 ? displayed[0] : 1;
491
504
  await this.loadInitialPages();
492
505
  if (this.options.enableVirtualScrolling === false) {
493
506
  await this.renderAllPagesBatched(2);
@@ -500,17 +513,45 @@ export class PDFHighlightViewer {
500
513
  }
501
514
  }
502
515
  /**
503
- * Create DOM containers for all pages with real PDF dimensions
516
+ * Normalize selectedPages: filter to 1..numPages, dedupe, sort. Empty result => null (show all).
517
+ */
518
+ normalizeSelectedPages(raw, numPages) {
519
+ if (!raw || raw.length === 0)
520
+ return null;
521
+ const set = new Set();
522
+ for (const p of raw) {
523
+ if (Number.isInteger(p) && p >= 1 && p <= numPages)
524
+ set.add(p);
525
+ }
526
+ if (set.size === 0)
527
+ return null;
528
+ return Array.from(set).sort((a, b) => a - b);
529
+ }
530
+ /** List of physical page numbers to display (either selectedPages or 1..documentNumPages). */
531
+ getDisplayedPageList() {
532
+ if (this.selectedPages !== null && this.selectedPages.length > 0) {
533
+ return this.selectedPages;
534
+ }
535
+ const list = [];
536
+ for (let i = 1; i <= this.documentNumPages; i++) {
537
+ list.push(i);
538
+ }
539
+ return list;
540
+ }
541
+ /**
542
+ * Create DOM containers for displayed pages only (selectedPages or all)
504
543
  */
505
544
  async createPageContainers() {
506
545
  if (!this.pdfContainer)
507
546
  return;
508
- // Clear existing containers
509
547
  this.pdfContainer.innerHTML = '';
510
548
  this.pageContainers.clear();
511
- const firstPageDimensions = await this.getPageDimensions(1);
549
+ const displayed = this.getDisplayedPageList();
550
+ if (displayed.length === 0)
551
+ return;
552
+ const firstPageDimensions = await this.getPageDimensions(displayed[0]);
512
553
  const avgPageHeight = firstPageDimensions.height;
513
- for (let pageNumber = 1; pageNumber <= this.totalPages; pageNumber++) {
554
+ for (const pageNumber of displayed) {
514
555
  const pageContainer = document.createElement('div');
515
556
  pageContainer.className = 'pdf-page-container';
516
557
  pageContainer.setAttribute('data-page-number', pageNumber.toString());
@@ -522,7 +563,6 @@ export class PDFHighlightViewer {
522
563
  this.pdfContainer.appendChild(pageContainer);
523
564
  this.pageContainers.set(pageNumber, pageContainer);
524
565
  }
525
- // Update viewport manager with real page dimensions
526
566
  this.viewportManager.updateDimensions(this.container?.clientHeight || 600, avgPageHeight);
527
567
  }
528
568
  /**
@@ -531,19 +571,19 @@ export class PDFHighlightViewer {
531
571
  async loadInitialPages() {
532
572
  if (!this.container)
533
573
  return;
534
- // Get what should be visible at the top
535
574
  const visiblePages = this.viewportManager.getVisiblePages(0, this.container.clientHeight);
536
- // Load first page immediately
575
+ const firstPage = this.getDisplayedPageList()[0];
576
+ if (firstPage === undefined)
577
+ return;
537
578
  try {
538
- await this.renderPage(1);
579
+ await this.renderPage(firstPage);
539
580
  }
540
581
  catch (error) {
541
582
  console.error('Failed to load initial page:', error);
542
583
  }
543
- // Load other visible pages with small delay
544
584
  setTimeout(() => {
545
585
  visiblePages
546
- .filter((page) => page > 1)
586
+ .filter((page) => page !== firstPage)
547
587
  .forEach((pageNumber) => {
548
588
  this.renderPage(pageNumber).catch((error) => {
549
589
  console.error(`Failed to load initial page ${pageNumber}:`, error);
@@ -552,13 +592,15 @@ export class PDFHighlightViewer {
552
592
  }, 100);
553
593
  }
554
594
  async renderAllPagesBatched(batchSize = 2) {
555
- for (let i = 1; i <= this.totalPages; i += batchSize) {
595
+ const displayed = this.getDisplayedPageList();
596
+ for (let i = 0; i < displayed.length; i += batchSize) {
556
597
  const batch = [];
557
- for (let j = i; j < i + batchSize && j <= this.totalPages; j++) {
558
- const pageContainer = this.pageContainers.get(j);
598
+ for (let j = i; j < i + batchSize && j < displayed.length; j++) {
599
+ const pageNumber = displayed[j];
600
+ const pageContainer = this.pageContainers.get(pageNumber);
559
601
  if (pageContainer && !pageContainer.classList.contains('rendered')) {
560
- batch.push(this.renderPage(j).catch((error) => {
561
- console.debug(`Failed to render page ${j}:`, error);
602
+ batch.push(this.renderPage(pageNumber).catch((error) => {
603
+ console.error(`Failed to render page ${pageNumber}:`, error);
562
604
  }));
563
605
  }
564
606
  }
@@ -575,10 +617,8 @@ export class PDFHighlightViewer {
575
617
  return;
576
618
  // Check if already rendered
577
619
  if (pageContainer.classList.contains('rendered')) {
578
- console.log(`Page ${pageNumber}: skipping, already has 'rendered' class`);
579
620
  return;
580
621
  }
581
- console.log(`Page ${pageNumber}: rendering at scale ${this.currentScale}`);
582
622
  try {
583
623
  // Add loading state
584
624
  pageContainer.classList.add('loading');
@@ -615,7 +655,8 @@ export class PDFHighlightViewer {
615
655
  });
616
656
  }
617
657
  setPage(pageNumber) {
618
- if (pageNumber < 1 || pageNumber > this.totalPages)
658
+ const displayed = this.getDisplayedPageList();
659
+ if (!displayed.includes(pageNumber))
619
660
  return;
620
661
  if (this.container) {
621
662
  this.container.scrollTop = this.getPageScrollTop(pageNumber);
@@ -882,7 +923,6 @@ export class PDFHighlightViewer {
882
923
  if (!this.container)
883
924
  return;
884
925
  const pageToKeep = this.currentPage;
885
- console.log('Zoom changed to:', this.currentScale);
886
926
  // Clear ALL cached data for the new scale
887
927
  this.pdfEngine.clearAllPageCache();
888
928
  this.pageDimensions.clear(); // Clear dimension cache
@@ -916,7 +956,6 @@ export class PDFHighlightViewer {
916
956
  // Recompute visible pages after scroll restore for correct rendering
917
957
  const scrollTopAfterRestore = this.container.scrollTop;
918
958
  const visiblePagesAfterRestore = this.viewportManager.getVisiblePages(scrollTopAfterRestore, containerHeight);
919
- console.log('Re-rendering visible pages at new scale:', visiblePagesAfterRestore);
920
959
  // Render visible pages immediately
921
960
  for (const pageNumber of visiblePagesAfterRestore) {
922
961
  try {
@@ -1074,11 +1113,9 @@ export class PDFHighlightViewer {
1074
1113
  }
1075
1114
  enableProfiling() {
1076
1115
  // TODO: Enable detailed performance profiling
1077
- console.log('Profiling enabled');
1078
1116
  }
1079
1117
  disableProfiling() {
1080
1118
  // TODO: Disable detailed performance profiling
1081
- console.log('Profiling disabled');
1082
1119
  }
1083
1120
  // =============================================================================
1084
1121
  // Event Management
@@ -1507,10 +1544,10 @@ export class PDFHighlightViewer {
1507
1544
  };
1508
1545
  }
1509
1546
  /**
1510
- * Build spatial indices for all pages
1547
+ * Build spatial indices for displayed pages only
1511
1548
  */
1512
1549
  buildAllSpatialIndices() {
1513
- for (let pageNumber = 1; pageNumber <= this.totalPages; pageNumber++) {
1550
+ for (const pageNumber of this.getDisplayedPageList()) {
1514
1551
  this.buildSpatialIndexForPage(pageNumber);
1515
1552
  }
1516
1553
  }
@@ -1741,8 +1778,6 @@ export class PDFHighlightViewer {
1741
1778
  textLayer.appendChild(textSpan);
1742
1779
  });
1743
1780
  pageContainer.appendChild(textLayer);
1744
- console.log(`Text layer added to page ${pageNumber} with ${textContent.items.length} text items`);
1745
- console.log('Text span style applied:', textLayer.children[0]?.getAttribute('style'));
1746
1781
  }
1747
1782
  catch (error) {
1748
1783
  console.error(`Failed to add text layer to page ${pageNumber}:`, error);
@@ -1758,8 +1793,8 @@ export class PDFHighlightViewer {
1758
1793
  const targetHeight = (coord.y2 - coord.y1) * scale;
1759
1794
  const existingHighlights = highlightLayer.children;
1760
1795
  let overlappingCount = 0;
1761
- for (let i = 0; i < existingHighlights.length; i++) {
1762
- const existing = existingHighlights[i];
1796
+ for (const existingHighlight of existingHighlights) {
1797
+ const existing = existingHighlight;
1763
1798
  const existingLeft = parseFloat(existing.style.left);
1764
1799
  const existingTop = parseFloat(existing.style.top);
1765
1800
  const existingWidth = parseFloat(existing.style.width);