@ntlab/ntjs-assets 2.0.40 → 2.0.41

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 (67) hide show
  1. package/assets/js/pdfjs/build/pdf.mjs +586 -365
  2. package/assets/js/pdfjs/build/pdf.mjs.map +1 -1
  3. package/assets/js/pdfjs/build/pdf.sandbox.mjs +3 -3
  4. package/assets/js/pdfjs/build/pdf.sandbox.mjs.map +1 -1
  5. package/assets/js/pdfjs/build/pdf.worker.mjs +33 -56
  6. package/assets/js/pdfjs/build/pdf.worker.mjs.map +1 -1
  7. package/assets/js/pdfjs/web/images/altText_disclaimer.svg +3 -0
  8. package/assets/js/pdfjs/web/images/altText_spinner.svg +30 -0
  9. package/assets/js/pdfjs/web/images/altText_warning.svg +3 -0
  10. package/assets/js/pdfjs/web/images/messageBar_closingButton.svg +3 -0
  11. package/assets/js/pdfjs/web/images/messageBar_warning.svg +3 -0
  12. package/assets/js/pdfjs/web/locale/be/viewer.ftl +63 -8
  13. package/assets/js/pdfjs/web/locale/bg/viewer.ftl +25 -8
  14. package/assets/js/pdfjs/web/locale/cs/viewer.ftl +63 -8
  15. package/assets/js/pdfjs/web/locale/cy/viewer.ftl +57 -8
  16. package/assets/js/pdfjs/web/locale/da/viewer.ftl +71 -8
  17. package/assets/js/pdfjs/web/locale/de/viewer.ftl +59 -8
  18. package/assets/js/pdfjs/web/locale/dsb/viewer.ftl +57 -8
  19. package/assets/js/pdfjs/web/locale/el/viewer.ftl +71 -8
  20. package/assets/js/pdfjs/web/locale/en-CA/viewer.ftl +57 -8
  21. package/assets/js/pdfjs/web/locale/en-GB/viewer.ftl +71 -8
  22. package/assets/js/pdfjs/web/locale/en-US/viewer.ftl +97 -20
  23. package/assets/js/pdfjs/web/locale/eo/viewer.ftl +57 -2
  24. package/assets/js/pdfjs/web/locale/es-AR/viewer.ftl +71 -8
  25. package/assets/js/pdfjs/web/locale/es-CL/viewer.ftl +71 -8
  26. package/assets/js/pdfjs/web/locale/es-MX/viewer.ftl +34 -6
  27. package/assets/js/pdfjs/web/locale/fi/viewer.ftl +59 -8
  28. package/assets/js/pdfjs/web/locale/fr/viewer.ftl +71 -8
  29. package/assets/js/pdfjs/web/locale/fur/viewer.ftl +59 -8
  30. package/assets/js/pdfjs/web/locale/fy-NL/viewer.ftl +71 -8
  31. package/assets/js/pdfjs/web/locale/gn/viewer.ftl +53 -8
  32. package/assets/js/pdfjs/web/locale/he/viewer.ftl +71 -8
  33. package/assets/js/pdfjs/web/locale/hr/viewer.ftl +143 -4
  34. package/assets/js/pdfjs/web/locale/hsb/viewer.ftl +71 -8
  35. package/assets/js/pdfjs/web/locale/hu/viewer.ftl +71 -2
  36. package/assets/js/pdfjs/web/locale/ia/viewer.ftl +71 -0
  37. package/assets/js/pdfjs/web/locale/is/viewer.ftl +57 -0
  38. package/assets/js/pdfjs/web/locale/it/viewer.ftl +81 -5
  39. package/assets/js/pdfjs/web/locale/ja/viewer.ftl +60 -10
  40. package/assets/js/pdfjs/web/locale/kk/viewer.ftl +71 -8
  41. package/assets/js/pdfjs/web/locale/ko/viewer.ftl +71 -8
  42. package/assets/js/pdfjs/web/locale/nl/viewer.ftl +71 -8
  43. package/assets/js/pdfjs/web/locale/nn-NO/viewer.ftl +57 -2
  44. package/assets/js/pdfjs/web/locale/oc/viewer.ftl +13 -6
  45. package/assets/js/pdfjs/web/locale/pa-IN/viewer.ftl +59 -2
  46. package/assets/js/pdfjs/web/locale/pl/viewer.ftl +57 -8
  47. package/assets/js/pdfjs/web/locale/pt-BR/viewer.ftl +71 -2
  48. package/assets/js/pdfjs/web/locale/pt-PT/viewer.ftl +59 -8
  49. package/assets/js/pdfjs/web/locale/ru/viewer.ftl +71 -8
  50. package/assets/js/pdfjs/web/locale/sc/viewer.ftl +83 -6
  51. package/assets/js/pdfjs/web/locale/sk/viewer.ftl +59 -8
  52. package/assets/js/pdfjs/web/locale/skr/viewer.ftl +49 -2
  53. package/assets/js/pdfjs/web/locale/sl/viewer.ftl +71 -0
  54. package/assets/js/pdfjs/web/locale/sq/viewer.ftl +57 -2
  55. package/assets/js/pdfjs/web/locale/sv-SE/viewer.ftl +71 -8
  56. package/assets/js/pdfjs/web/locale/tg/viewer.ftl +8 -2
  57. package/assets/js/pdfjs/web/locale/th/viewer.ftl +57 -8
  58. package/assets/js/pdfjs/web/locale/tr/viewer.ftl +71 -2
  59. package/assets/js/pdfjs/web/locale/uk/viewer.ftl +33 -2
  60. package/assets/js/pdfjs/web/locale/vi/viewer.ftl +71 -8
  61. package/assets/js/pdfjs/web/locale/zh-CN/viewer.ftl +71 -2
  62. package/assets/js/pdfjs/web/locale/zh-TW/viewer.ftl +71 -0
  63. package/assets/js/pdfjs/web/viewer.css +1250 -790
  64. package/assets/js/pdfjs/web/viewer.html +141 -47
  65. package/assets/js/pdfjs/web/viewer.mjs +1187 -563
  66. package/assets/js/pdfjs/web/viewer.mjs.map +1 -1
  67. package/package.json +1 -1
@@ -446,9 +446,6 @@ function shadow(obj, prop, value, nonSerializable = false) {
446
446
  }
447
447
  const BaseException = function BaseExceptionClosure() {
448
448
  function BaseException(message, name) {
449
- if (this.constructor === BaseException) {
450
- unreachable("Cannot initialize BaseException.");
451
- }
452
449
  this.message = message;
453
450
  this.name = name;
454
451
  }
@@ -833,11 +830,6 @@ const FontRenderOps = {
833
830
  ;// CONCATENATED MODULE: ./src/display/base_factory.js
834
831
 
835
832
  class BaseFilterFactory {
836
- constructor() {
837
- if (this.constructor === BaseFilterFactory) {
838
- unreachable("Cannot initialize BaseFilterFactory.");
839
- }
840
- }
841
833
  addFilter(maps) {
842
834
  return "none";
843
835
  }
@@ -860,9 +852,6 @@ class BaseCanvasFactory {
860
852
  constructor({
861
853
  enableHWA = false
862
854
  } = {}) {
863
- if (this.constructor === BaseCanvasFactory) {
864
- unreachable("Cannot initialize BaseCanvasFactory.");
865
- }
866
855
  this.#enableHWA = enableHWA;
867
856
  }
868
857
  create(width, height) {
@@ -905,9 +894,6 @@ class BaseCMapReaderFactory {
905
894
  baseUrl = null,
906
895
  isCompressed = true
907
896
  }) {
908
- if (this.constructor === BaseCMapReaderFactory) {
909
- unreachable("Cannot initialize BaseCMapReaderFactory.");
910
- }
911
897
  this.baseUrl = baseUrl;
912
898
  this.isCompressed = isCompressed;
913
899
  }
@@ -915,7 +901,7 @@ class BaseCMapReaderFactory {
915
901
  name
916
902
  }) {
917
903
  if (!this.baseUrl) {
918
- throw new Error('The CMap "baseUrl" parameter must be specified, ensure that ' + 'the "cMapUrl" and "cMapPacked" API parameters are provided.');
904
+ throw new Error("Ensure that the `cMapUrl` and `cMapPacked` API parameters are provided.");
919
905
  }
920
906
  if (!name) {
921
907
  throw new Error("CMap name must be specified.");
@@ -934,16 +920,13 @@ class BaseStandardFontDataFactory {
934
920
  constructor({
935
921
  baseUrl = null
936
922
  }) {
937
- if (this.constructor === BaseStandardFontDataFactory) {
938
- unreachable("Cannot initialize BaseStandardFontDataFactory.");
939
- }
940
923
  this.baseUrl = baseUrl;
941
924
  }
942
925
  async fetch({
943
926
  filename
944
927
  }) {
945
928
  if (!this.baseUrl) {
946
- throw new Error('The standard font "baseUrl" parameter must be specified, ensure that ' + 'the "standardFontDataUrl" API parameter is provided.');
929
+ throw new Error("Ensure that the `standardFontDataUrl` API parameter is provided.");
947
930
  }
948
931
  if (!filename) {
949
932
  throw new Error("Font filename must be specified.");
@@ -958,11 +941,6 @@ class BaseStandardFontDataFactory {
958
941
  }
959
942
  }
960
943
  class BaseSVGFactory {
961
- constructor() {
962
- if (this.constructor === BaseSVGFactory) {
963
- unreachable("Cannot initialize BaseSVGFactory.");
964
- }
965
- }
966
944
  create(width, height, skipDimensions = false) {
967
945
  if (width <= 0 || height <= 0) {
968
946
  throw new Error("Invalid SVG dimensions");
@@ -1727,8 +1705,16 @@ class EditorToolbar {
1727
1705
  #colorPicker = null;
1728
1706
  #editor;
1729
1707
  #buttons = null;
1708
+ #altText = null;
1709
+ static #l10nRemove = null;
1730
1710
  constructor(editor) {
1731
1711
  this.#editor = editor;
1712
+ EditorToolbar.#l10nRemove ||= Object.freeze({
1713
+ freetext: "pdfjs-editor-remove-freetext-button",
1714
+ highlight: "pdfjs-editor-remove-highlight-button",
1715
+ ink: "pdfjs-editor-remove-ink-button",
1716
+ stamp: "pdfjs-editor-remove-stamp-button"
1717
+ });
1732
1718
  }
1733
1719
  render() {
1734
1720
  const editToolbar = this.#toolbar = document.createElement("div");
@@ -1789,17 +1775,22 @@ class EditorToolbar {
1789
1775
  }
1790
1776
  show() {
1791
1777
  this.#toolbar.classList.remove("hidden");
1778
+ this.#altText?.shown();
1792
1779
  }
1793
1780
  #addDeleteButton() {
1781
+ const {
1782
+ editorType,
1783
+ _uiManager
1784
+ } = this.#editor;
1794
1785
  const button = document.createElement("button");
1795
1786
  button.className = "delete";
1796
1787
  button.tabIndex = 0;
1797
- button.setAttribute("data-l10n-id", `pdfjs-editor-remove-${this.#editor.editorType}-button`);
1788
+ button.setAttribute("data-l10n-id", EditorToolbar.#l10nRemove[editorType]);
1798
1789
  this.#addListenersToElement(button);
1799
1790
  button.addEventListener("click", e => {
1800
- this.#editor._uiManager.delete();
1791
+ _uiManager.delete();
1801
1792
  }, {
1802
- signal: this.#editor._uiManager._signal
1793
+ signal: _uiManager._signal
1803
1794
  });
1804
1795
  this.#buttons.append(button);
1805
1796
  }
@@ -1808,9 +1799,11 @@ class EditorToolbar {
1808
1799
  divider.className = "divider";
1809
1800
  return divider;
1810
1801
  }
1811
- addAltTextButton(button) {
1802
+ async addAltText(altText) {
1803
+ const button = await altText.render();
1812
1804
  this.#addListenersToElement(button);
1813
1805
  this.#buttons.prepend(button, this.#divider);
1806
+ this.#altText = altText;
1814
1807
  }
1815
1808
  addColorPicker(colorPicker) {
1816
1809
  this.#colorPicker = colorPicker;
@@ -2243,6 +2236,7 @@ class AnnotationEditorUIManager {
2243
2236
  #annotationStorage = null;
2244
2237
  #changedExistingAnnotations = null;
2245
2238
  #commandManager = new CommandManager();
2239
+ #copyPasteAC = null;
2246
2240
  #currentPageIndex = 0;
2247
2241
  #deletedAnnotationsElementIds = new Set();
2248
2242
  #draggingEditors = null;
@@ -2250,14 +2244,17 @@ class AnnotationEditorUIManager {
2250
2244
  #editorsToRescale = new Set();
2251
2245
  #enableHighlightFloatingButton = false;
2252
2246
  #enableUpdatedAddImage = false;
2247
+ #enableNewAltTextWhenAddingImage = false;
2253
2248
  #filterFactory = null;
2254
2249
  #focusMainContainerTimeoutId = null;
2250
+ #focusManagerAC = null;
2255
2251
  #highlightColors = null;
2256
2252
  #highlightWhenShiftUp = false;
2257
2253
  #highlightToolbar = null;
2258
2254
  #idManager = new IdManager();
2259
2255
  #isEnabled = false;
2260
2256
  #isWaiting = false;
2257
+ #keyboardManagerAC = null;
2261
2258
  #lastActiveElement = null;
2262
2259
  #mainHighlightColorPicker = null;
2263
2260
  #mlManager = null;
@@ -2266,17 +2263,6 @@ class AnnotationEditorUIManager {
2266
2263
  #selectedTextNode = null;
2267
2264
  #pageColors = null;
2268
2265
  #showAllStates = null;
2269
- #boundBlur = this.blur.bind(this);
2270
- #boundFocus = this.focus.bind(this);
2271
- #boundCopy = this.copy.bind(this);
2272
- #boundCut = this.cut.bind(this);
2273
- #boundPaste = this.paste.bind(this);
2274
- #boundKeydown = this.keydown.bind(this);
2275
- #boundKeyup = this.keyup.bind(this);
2276
- #boundOnEditingAction = this.onEditingAction.bind(this);
2277
- #boundOnPageChanging = this.onPageChanging.bind(this);
2278
- #boundOnScaleChanging = this.onScaleChanging.bind(this);
2279
- #boundOnRotationChanging = this.onRotationChanging.bind(this);
2280
2266
  #previousStates = {
2281
2267
  isEditing: false,
2282
2268
  isEmpty: true,
@@ -2349,16 +2335,30 @@ class AnnotationEditorUIManager {
2349
2335
  checker: arrowChecker
2350
2336
  }]]));
2351
2337
  }
2352
- constructor(container, viewer, altTextManager, eventBus, pdfDocument, pageColors, highlightColors, enableHighlightFloatingButton, enableUpdatedAddImage, mlManager) {
2353
- this._signal = this.#abortController.signal;
2338
+ constructor(container, viewer, altTextManager, eventBus, pdfDocument, pageColors, highlightColors, enableHighlightFloatingButton, enableUpdatedAddImage, enableNewAltTextWhenAddingImage, mlManager) {
2339
+ const signal = this._signal = this.#abortController.signal;
2354
2340
  this.#container = container;
2355
2341
  this.#viewer = viewer;
2356
2342
  this.#altTextManager = altTextManager;
2357
2343
  this._eventBus = eventBus;
2358
- this._eventBus._on("editingaction", this.#boundOnEditingAction);
2359
- this._eventBus._on("pagechanging", this.#boundOnPageChanging);
2360
- this._eventBus._on("scalechanging", this.#boundOnScaleChanging);
2361
- this._eventBus._on("rotationchanging", this.#boundOnRotationChanging);
2344
+ eventBus._on("editingaction", this.onEditingAction.bind(this), {
2345
+ signal
2346
+ });
2347
+ eventBus._on("pagechanging", this.onPageChanging.bind(this), {
2348
+ signal
2349
+ });
2350
+ eventBus._on("scalechanging", this.onScaleChanging.bind(this), {
2351
+ signal
2352
+ });
2353
+ eventBus._on("rotationchanging", this.onRotationChanging.bind(this), {
2354
+ signal
2355
+ });
2356
+ eventBus._on("setpreference", this.onSetPreference.bind(this), {
2357
+ signal
2358
+ });
2359
+ eventBus._on("switchannotationeditorparams", evt => this.updateParams(evt.type, evt.value), {
2360
+ signal
2361
+ });
2362
2362
  this.#addSelectionListener();
2363
2363
  this.#addDragAndDropListeners();
2364
2364
  this.#addKeyboardManager();
@@ -2368,6 +2368,7 @@ class AnnotationEditorUIManager {
2368
2368
  this.#highlightColors = highlightColors || null;
2369
2369
  this.#enableHighlightFloatingButton = enableHighlightFloatingButton;
2370
2370
  this.#enableUpdatedAddImage = enableUpdatedAddImage;
2371
+ this.#enableNewAltTextWhenAddingImage = enableNewAltTextWhenAddingImage;
2371
2372
  this.#mlManager = mlManager || null;
2372
2373
  this.viewParameters = {
2373
2374
  realScale: PixelsPerInch.PDF_TO_CSS_UNITS,
@@ -2379,10 +2380,6 @@ class AnnotationEditorUIManager {
2379
2380
  this.#abortController?.abort();
2380
2381
  this.#abortController = null;
2381
2382
  this._signal = null;
2382
- this._eventBus._off("editingaction", this.#boundOnEditingAction);
2383
- this._eventBus._off("pagechanging", this.#boundOnPageChanging);
2384
- this._eventBus._off("scalechanging", this.#boundOnScaleChanging);
2385
- this._eventBus._off("rotationchanging", this.#boundOnRotationChanging);
2386
2383
  for (const layer of this.#allLayers.values()) {
2387
2384
  layer.destroy();
2388
2385
  }
@@ -2404,15 +2401,18 @@ class AnnotationEditorUIManager {
2404
2401
  this.#translationTimeoutId = null;
2405
2402
  }
2406
2403
  }
2407
- async mlGuess(data) {
2408
- return this.#mlManager?.guess(data) || null;
2404
+ combinedSignal(ac) {
2405
+ return AbortSignal.any([this._signal, ac.signal]);
2409
2406
  }
2410
- async isMLEnabledFor(name) {
2411
- return !!(await this.#mlManager?.isEnabledFor(name));
2407
+ get mlManager() {
2408
+ return this.#mlManager;
2412
2409
  }
2413
2410
  get useNewAltTextFlow() {
2414
2411
  return this.#enableUpdatedAddImage;
2415
2412
  }
2413
+ get useNewAltTextWhenAddingImage() {
2414
+ return this.#enableNewAltTextWhenAddingImage;
2415
+ }
2416
2416
  get hcmFilter() {
2417
2417
  return shadow(this, "hcmFilter", this.#pageColors ? this.#filterFactory.addHCMFilter(this.#pageColors.foreground, this.#pageColors.background) : "none");
2418
2418
  }
@@ -2428,8 +2428,8 @@ class AnnotationEditorUIManager {
2428
2428
  setMainHighlightColorPicker(colorPicker) {
2429
2429
  this.#mainHighlightColorPicker = colorPicker;
2430
2430
  }
2431
- editAltText(editor) {
2432
- this.#altTextManager?.editAltText(this, editor);
2431
+ editAltText(editor, firstTime = false) {
2432
+ this.#altTextManager?.editAltText(this, editor, firstTime);
2433
2433
  }
2434
2434
  switchToMode(mode, callback) {
2435
2435
  this._eventBus.on("annotationeditormodechanged", callback, {
@@ -2448,6 +2448,16 @@ class AnnotationEditorUIManager {
2448
2448
  value
2449
2449
  });
2450
2450
  }
2451
+ onSetPreference({
2452
+ name,
2453
+ value
2454
+ }) {
2455
+ switch (name) {
2456
+ case "enableNewAltTextWhenAddingImage":
2457
+ this.#enableNewAltTextWhenAddingImage = value;
2458
+ break;
2459
+ }
2460
+ }
2451
2461
  onPageChanging({
2452
2462
  pageNumber
2453
2463
  }) {
@@ -2621,14 +2631,14 @@ class AnnotationEditorUIManager {
2621
2631
  if (!this.isShiftKeyDown) {
2622
2632
  const activeLayer = this.#mode === AnnotationEditorType.HIGHLIGHT ? this.#getLayerForTextLayer(textLayer) : null;
2623
2633
  activeLayer?.toggleDrawing();
2624
- const signal = this._signal;
2634
+ const ac = new AbortController();
2635
+ const signal = this.combinedSignal(ac);
2625
2636
  const pointerup = e => {
2626
2637
  if (e.type === "pointerup" && e.button !== 0) {
2627
2638
  return;
2628
2639
  }
2640
+ ac.abort();
2629
2641
  activeLayer?.toggleDrawing(true);
2630
- window.removeEventListener("pointerup", pointerup);
2631
- window.removeEventListener("blur", pointerup);
2632
2642
  if (e.type === "pointerup") {
2633
2643
  this.#onSelectEnd("main_toolbar");
2634
2644
  }
@@ -2654,17 +2664,21 @@ class AnnotationEditorUIManager {
2654
2664
  });
2655
2665
  }
2656
2666
  #addFocusManager() {
2657
- const signal = this._signal;
2658
- window.addEventListener("focus", this.#boundFocus, {
2667
+ if (this.#focusManagerAC) {
2668
+ return;
2669
+ }
2670
+ this.#focusManagerAC = new AbortController();
2671
+ const signal = this.combinedSignal(this.#focusManagerAC);
2672
+ window.addEventListener("focus", this.focus.bind(this), {
2659
2673
  signal
2660
2674
  });
2661
- window.addEventListener("blur", this.#boundBlur, {
2675
+ window.addEventListener("blur", this.blur.bind(this), {
2662
2676
  signal
2663
2677
  });
2664
2678
  }
2665
2679
  #removeFocusManager() {
2666
- window.removeEventListener("focus", this.#boundFocus);
2667
- window.removeEventListener("blur", this.#boundBlur);
2680
+ this.#focusManagerAC?.abort();
2681
+ this.#focusManagerAC = null;
2668
2682
  }
2669
2683
  blur() {
2670
2684
  this.isShiftKeyDown = false;
@@ -2701,34 +2715,41 @@ class AnnotationEditorUIManager {
2701
2715
  lastActiveElement.focus();
2702
2716
  }
2703
2717
  #addKeyboardManager() {
2704
- const signal = this._signal;
2705
- window.addEventListener("keydown", this.#boundKeydown, {
2718
+ if (this.#keyboardManagerAC) {
2719
+ return;
2720
+ }
2721
+ this.#keyboardManagerAC = new AbortController();
2722
+ const signal = this.combinedSignal(this.#keyboardManagerAC);
2723
+ window.addEventListener("keydown", this.keydown.bind(this), {
2706
2724
  signal
2707
2725
  });
2708
- window.addEventListener("keyup", this.#boundKeyup, {
2726
+ window.addEventListener("keyup", this.keyup.bind(this), {
2709
2727
  signal
2710
2728
  });
2711
2729
  }
2712
2730
  #removeKeyboardManager() {
2713
- window.removeEventListener("keydown", this.#boundKeydown);
2714
- window.removeEventListener("keyup", this.#boundKeyup);
2731
+ this.#keyboardManagerAC?.abort();
2732
+ this.#keyboardManagerAC = null;
2715
2733
  }
2716
2734
  #addCopyPasteListeners() {
2717
- const signal = this._signal;
2718
- document.addEventListener("copy", this.#boundCopy, {
2735
+ if (this.#copyPasteAC) {
2736
+ return;
2737
+ }
2738
+ this.#copyPasteAC = new AbortController();
2739
+ const signal = this.combinedSignal(this.#copyPasteAC);
2740
+ document.addEventListener("copy", this.copy.bind(this), {
2719
2741
  signal
2720
2742
  });
2721
- document.addEventListener("cut", this.#boundCut, {
2743
+ document.addEventListener("cut", this.cut.bind(this), {
2722
2744
  signal
2723
2745
  });
2724
- document.addEventListener("paste", this.#boundPaste, {
2746
+ document.addEventListener("paste", this.paste.bind(this), {
2725
2747
  signal
2726
2748
  });
2727
2749
  }
2728
2750
  #removeCopyPasteListeners() {
2729
- document.removeEventListener("copy", this.#boundCopy);
2730
- document.removeEventListener("cut", this.#boundCut);
2731
- document.removeEventListener("paste", this.#boundPaste);
2751
+ this.#copyPasteAC?.abort();
2752
+ this.#copyPasteAC = null;
2732
2753
  }
2733
2754
  #addDragAndDropListeners() {
2734
2755
  const signal = this._signal;
@@ -3554,16 +3575,21 @@ class AnnotationEditorUIManager {
3554
3575
  ;// CONCATENATED MODULE: ./src/display/editor/alt_text.js
3555
3576
 
3556
3577
  class AltText {
3557
- #altText = "";
3578
+ #altText = null;
3558
3579
  #altTextDecorative = false;
3559
3580
  #altTextButton = null;
3560
3581
  #altTextTooltip = null;
3561
3582
  #altTextTooltipTimeout = null;
3562
3583
  #altTextWasFromKeyBoard = false;
3584
+ #badge = null;
3563
3585
  #editor = null;
3586
+ #guessedText = null;
3587
+ #textWithDisclaimer = null;
3588
+ #useNewAltTextFlow = false;
3564
3589
  static _l10nPromise = null;
3565
3590
  constructor(editor) {
3566
3591
  this.#editor = editor;
3592
+ this.#useNewAltTextFlow = editor._uiManager.useNewAltTextFlow;
3567
3593
  }
3568
3594
  static initialize(l10nPromise) {
3569
3595
  AltText._l10nPromise ||= l10nPromise;
@@ -3571,7 +3597,13 @@ class AltText {
3571
3597
  async render() {
3572
3598
  const altText = this.#altTextButton = document.createElement("button");
3573
3599
  altText.className = "altText";
3574
- const msg = await AltText._l10nPromise.get("pdfjs-editor-alt-text-button-label");
3600
+ let msg;
3601
+ if (this.#useNewAltTextFlow) {
3602
+ altText.classList.add("new");
3603
+ msg = await AltText._l10nPromise.get("pdfjs-editor-new-alt-text-missing-button-label");
3604
+ } else {
3605
+ msg = await AltText._l10nPromise.get("pdfjs-editor-alt-text-button-label");
3606
+ }
3575
3607
  altText.textContent = msg;
3576
3608
  altText.setAttribute("aria-label", msg);
3577
3609
  altText.tabIndex = "0";
@@ -3585,6 +3617,14 @@ class AltText {
3585
3617
  const onClick = event => {
3586
3618
  event.preventDefault();
3587
3619
  this.#editor._uiManager.editAltText(this.#editor);
3620
+ if (this.#useNewAltTextFlow) {
3621
+ this.#editor._reportTelemetry({
3622
+ action: "pdfjs.image.alt_text.image_status_label_clicked",
3623
+ data: {
3624
+ label: this.#label
3625
+ }
3626
+ });
3627
+ }
3588
3628
  };
3589
3629
  altText.addEventListener("click", onClick, {
3590
3630
  capture: true,
@@ -3601,6 +3641,9 @@ class AltText {
3601
3641
  await this.#setState();
3602
3642
  return altText;
3603
3643
  }
3644
+ get #label() {
3645
+ return this.#altText && "added" || this.#altText === null && this.guessedText && "review" || "missing";
3646
+ }
3604
3647
  finish() {
3605
3648
  if (!this.#altTextButton) {
3606
3649
  return;
@@ -3611,8 +3654,55 @@ class AltText {
3611
3654
  this.#altTextWasFromKeyBoard = false;
3612
3655
  }
3613
3656
  isEmpty() {
3657
+ if (this.#useNewAltTextFlow) {
3658
+ return this.#altText === null;
3659
+ }
3614
3660
  return !this.#altText && !this.#altTextDecorative;
3615
3661
  }
3662
+ hasData() {
3663
+ if (this.#useNewAltTextFlow) {
3664
+ return this.#altText !== null || !!this.#guessedText;
3665
+ }
3666
+ return this.isEmpty();
3667
+ }
3668
+ get guessedText() {
3669
+ return this.#guessedText;
3670
+ }
3671
+ async setGuessedText(guessedText) {
3672
+ if (this.#altText !== null) {
3673
+ return;
3674
+ }
3675
+ this.#guessedText = guessedText;
3676
+ this.#textWithDisclaimer = await AltText._l10nPromise.get("pdfjs-editor-new-alt-text-generated-alt-text-with-disclaimer")({
3677
+ generatedAltText: guessedText
3678
+ });
3679
+ this.#setState();
3680
+ }
3681
+ toggleAltTextBadge(visibility = false) {
3682
+ if (!this.#useNewAltTextFlow || this.#altText) {
3683
+ this.#badge?.remove();
3684
+ this.#badge = null;
3685
+ return;
3686
+ }
3687
+ if (!this.#badge) {
3688
+ const badge = this.#badge = document.createElement("div");
3689
+ badge.className = "noAltTextBadge";
3690
+ this.#editor.div.append(badge);
3691
+ }
3692
+ this.#badge.classList.toggle("hidden", !visibility);
3693
+ }
3694
+ serialize(isForCopying) {
3695
+ let altText = this.#altText;
3696
+ if (!isForCopying && this.#guessedText === altText) {
3697
+ altText = this.#textWithDisclaimer;
3698
+ }
3699
+ return {
3700
+ altText,
3701
+ decorative: this.#altTextDecorative,
3702
+ guessedText: this.#guessedText,
3703
+ textWithDisclaimer: this.#textWithDisclaimer
3704
+ };
3705
+ }
3616
3706
  get data() {
3617
3707
  return {
3618
3708
  altText: this.#altText,
@@ -3621,13 +3711,22 @@ class AltText {
3621
3711
  }
3622
3712
  set data({
3623
3713
  altText,
3624
- decorative
3714
+ decorative,
3715
+ guessedText,
3716
+ textWithDisclaimer,
3717
+ cancel = false
3625
3718
  }) {
3719
+ if (guessedText) {
3720
+ this.#guessedText = guessedText;
3721
+ this.#textWithDisclaimer = textWithDisclaimer;
3722
+ }
3626
3723
  if (this.#altText === altText && this.#altTextDecorative === decorative) {
3627
3724
  return;
3628
3725
  }
3629
- this.#altText = altText;
3630
- this.#altTextDecorative = decorative;
3726
+ if (!cancel) {
3727
+ this.#altText = altText;
3728
+ this.#altTextDecorative = decorative;
3729
+ }
3631
3730
  this.#setState();
3632
3731
  }
3633
3732
  toggle(enabled = false) {
@@ -3640,25 +3739,54 @@ class AltText {
3640
3739
  }
3641
3740
  this.#altTextButton.disabled = !enabled;
3642
3741
  }
3742
+ shown() {
3743
+ this.#editor._reportTelemetry({
3744
+ action: "pdfjs.image.alt_text.image_status_label_displayed",
3745
+ data: {
3746
+ label: this.#label
3747
+ }
3748
+ });
3749
+ }
3643
3750
  destroy() {
3644
3751
  this.#altTextButton?.remove();
3645
3752
  this.#altTextButton = null;
3646
3753
  this.#altTextTooltip = null;
3754
+ this.#badge?.remove();
3755
+ this.#badge = null;
3647
3756
  }
3648
3757
  async #setState() {
3649
3758
  const button = this.#altTextButton;
3650
3759
  if (!button) {
3651
3760
  return;
3652
3761
  }
3653
- if (!this.#altText && !this.#altTextDecorative) {
3654
- button.classList.remove("done");
3655
- this.#altTextTooltip?.remove();
3656
- return;
3762
+ if (this.#useNewAltTextFlow) {
3763
+ const label = this.#label;
3764
+ const type = label === "review" ? "to-review" : label;
3765
+ button.classList.toggle("done", !!this.#altText);
3766
+ AltText._l10nPromise.get(`pdfjs-editor-new-alt-text-${type}-button-label`).then(msg => {
3767
+ button.setAttribute("aria-label", msg);
3768
+ for (const child of button.childNodes) {
3769
+ if (child.nodeType === Node.TEXT_NODE) {
3770
+ child.textContent = msg;
3771
+ break;
3772
+ }
3773
+ }
3774
+ });
3775
+ if (!this.#altText) {
3776
+ this.#altTextTooltip?.remove();
3777
+ return;
3778
+ }
3779
+ } else {
3780
+ if (!this.#altText && !this.#altTextDecorative) {
3781
+ button.classList.remove("done");
3782
+ this.#altTextTooltip?.remove();
3783
+ return;
3784
+ }
3785
+ button.classList.add("done");
3786
+ AltText._l10nPromise.get("pdfjs-editor-alt-text-edit-button-label").then(msg => {
3787
+ button.setAttribute("aria-label", msg);
3788
+ });
3657
3789
  }
3658
- button.classList.add("done");
3659
- AltText._l10nPromise.get("pdfjs-editor-alt-text-edit-button-label").then(msg => {
3660
- button.setAttribute("aria-label", msg);
3661
- });
3662
3790
  let tooltip = this.#altTextTooltip;
3663
3791
  if (!tooltip) {
3664
3792
  this.#altTextTooltip = tooltip = document.createElement("span");
@@ -3718,9 +3846,7 @@ class AnnotationEditor {
3718
3846
  #keepAspectRatio = false;
3719
3847
  #resizersDiv = null;
3720
3848
  #savedDimensions = null;
3721
- #boundFocusin = this.focusin.bind(this);
3722
- #boundFocusout = this.focusout.bind(this);
3723
- #editToolbar = null;
3849
+ #focusAC = null;
3724
3850
  #focusedResizerName = "";
3725
3851
  #hasBeenClicked = false;
3726
3852
  #initialPosition = null;
@@ -3731,11 +3857,13 @@ class AnnotationEditor {
3731
3857
  #prevDragX = 0;
3732
3858
  #prevDragY = 0;
3733
3859
  #telemetryTimeouts = null;
3860
+ _editToolbar = null;
3734
3861
  _initialOptions = Object.create(null);
3735
3862
  _isVisible = true;
3736
3863
  _uiManager = null;
3737
3864
  _focusEventsAllowed = true;
3738
- _l10nPromise = null;
3865
+ static _l10nPromise = null;
3866
+ static _l10nResizer = null;
3739
3867
  #isDraggable = false;
3740
3868
  #zIndex = AnnotationEditor._zIndex++;
3741
3869
  static _borderLineWidth = -1;
@@ -3765,9 +3893,6 @@ class AnnotationEditor {
3765
3893
  }], [["Escape", "mac+Escape"], AnnotationEditor.prototype._stopResizingWithKeyboard]]));
3766
3894
  }
3767
3895
  constructor(parameters) {
3768
- if (this.constructor === AnnotationEditor) {
3769
- unreachable("Cannot initialize AnnotationEditor.");
3770
- }
3771
3896
  this.parent = parameters.parent;
3772
3897
  this.id = parameters.id;
3773
3898
  this.width = this.height = null;
@@ -3815,7 +3940,17 @@ class AnnotationEditor {
3815
3940
  fakeEditor._uiManager.addToAnnotationStorage(fakeEditor);
3816
3941
  }
3817
3942
  static initialize(l10n, _uiManager, options) {
3818
- AnnotationEditor._l10nPromise ||= new Map(["pdfjs-editor-alt-text-button-label", "pdfjs-editor-alt-text-edit-button-label", "pdfjs-editor-alt-text-decorative-tooltip", "pdfjs-editor-resizer-label-topLeft", "pdfjs-editor-resizer-label-topMiddle", "pdfjs-editor-resizer-label-topRight", "pdfjs-editor-resizer-label-middleRight", "pdfjs-editor-resizer-label-bottomRight", "pdfjs-editor-resizer-label-bottomMiddle", "pdfjs-editor-resizer-label-bottomLeft", "pdfjs-editor-resizer-label-middleLeft"].map(str => [str, l10n.get(str.replaceAll(/([A-Z])/g, c => `-${c.toLowerCase()}`))]));
3943
+ AnnotationEditor._l10nResizer ||= Object.freeze({
3944
+ topLeft: "pdfjs-editor-resizer-top-left",
3945
+ topMiddle: "pdfjs-editor-resizer-top-middle",
3946
+ topRight: "pdfjs-editor-resizer-top-right",
3947
+ middleRight: "pdfjs-editor-resizer-middle-right",
3948
+ bottomRight: "pdfjs-editor-resizer-bottom-right",
3949
+ bottomMiddle: "pdfjs-editor-resizer-bottom-middle",
3950
+ bottomLeft: "pdfjs-editor-resizer-bottom-left",
3951
+ middleLeft: "pdfjs-editor-resizer-middle-left"
3952
+ });
3953
+ AnnotationEditor._l10nPromise ||= new Map([...["pdfjs-editor-alt-text-button-label", "pdfjs-editor-alt-text-edit-button-label", "pdfjs-editor-alt-text-decorative-tooltip", "pdfjs-editor-new-alt-text-added-button-label", "pdfjs-editor-new-alt-text-missing-button-label", "pdfjs-editor-new-alt-text-to-review-button-label"].map(str => [str, l10n.get(str)]), ...["pdfjs-editor-new-alt-text-generated-alt-text-with-disclaimer"].map(str => [str, l10n.get.bind(l10n, str)])]);
3819
3954
  if (options?.strings) {
3820
3955
  for (const str of options.strings) {
3821
3956
  AnnotationEditor._l10nPromise.set(str, l10n.get(str));
@@ -4165,17 +4300,16 @@ class AnnotationEditor {
4165
4300
  return;
4166
4301
  }
4167
4302
  this.#altText?.toggle(false);
4168
- const boundResizerPointermove = this.#resizerPointermove.bind(this, name);
4169
4303
  const savedDraggable = this._isDraggable;
4170
4304
  this._isDraggable = false;
4171
- const signal = this._uiManager._signal;
4172
- const pointerMoveOptions = {
4305
+ const ac = new AbortController();
4306
+ const signal = this._uiManager.combinedSignal(ac);
4307
+ this.parent.togglePointerEvents(false);
4308
+ window.addEventListener("pointermove", this.#resizerPointermove.bind(this, name), {
4173
4309
  passive: true,
4174
4310
  capture: true,
4175
4311
  signal
4176
- };
4177
- this.parent.togglePointerEvents(false);
4178
- window.addEventListener("pointermove", boundResizerPointermove, pointerMoveOptions);
4312
+ });
4179
4313
  window.addEventListener("contextmenu", noContextMenu, {
4180
4314
  signal
4181
4315
  });
@@ -4187,13 +4321,10 @@ class AnnotationEditor {
4187
4321
  const savedCursor = this.div.style.cursor;
4188
4322
  this.div.style.cursor = this.parent.div.style.cursor = window.getComputedStyle(event.target).cursor;
4189
4323
  const pointerUpCallback = () => {
4324
+ ac.abort();
4190
4325
  this.parent.togglePointerEvents(true);
4191
4326
  this.#altText?.toggle(true);
4192
4327
  this._isDraggable = savedDraggable;
4193
- window.removeEventListener("pointerup", pointerUpCallback);
4194
- window.removeEventListener("blur", pointerUpCallback);
4195
- window.removeEventListener("pointermove", boundResizerPointermove, pointerMoveOptions);
4196
- window.removeEventListener("contextmenu", noContextMenu);
4197
4328
  this.parent.div.style.cursor = savedParentCursor;
4198
4329
  this.div.style.cursor = savedCursor;
4199
4330
  this.#addResizeToUndoStack(savedX, savedY, savedWidth, savedHeight);
@@ -4325,22 +4456,22 @@ class AnnotationEditor {
4325
4456
  this.#altText?.finish();
4326
4457
  }
4327
4458
  async addEditToolbar() {
4328
- if (this.#editToolbar || this.#isInEditMode) {
4329
- return this.#editToolbar;
4459
+ if (this._editToolbar || this.#isInEditMode) {
4460
+ return this._editToolbar;
4330
4461
  }
4331
- this.#editToolbar = new EditorToolbar(this);
4332
- this.div.append(this.#editToolbar.render());
4462
+ this._editToolbar = new EditorToolbar(this);
4463
+ this.div.append(this._editToolbar.render());
4333
4464
  if (this.#altText) {
4334
- this.#editToolbar.addAltTextButton(await this.#altText.render());
4465
+ await this._editToolbar.addAltText(this.#altText);
4335
4466
  }
4336
- return this.#editToolbar;
4467
+ return this._editToolbar;
4337
4468
  }
4338
4469
  removeEditToolbar() {
4339
- if (!this.#editToolbar) {
4470
+ if (!this._editToolbar) {
4340
4471
  return;
4341
4472
  }
4342
- this.#editToolbar.remove();
4343
- this.#editToolbar = null;
4473
+ this._editToolbar.remove();
4474
+ this._editToolbar = null;
4344
4475
  this.#altText?.destroy();
4345
4476
  }
4346
4477
  getClientDimensions() {
@@ -4367,8 +4498,20 @@ class AnnotationEditor {
4367
4498
  }
4368
4499
  this.#altText.data = data;
4369
4500
  }
4501
+ get guessedAltText() {
4502
+ return this.#altText?.guessedText;
4503
+ }
4504
+ async setGuessedAltText(text) {
4505
+ await this.#altText?.setGuessedText(text);
4506
+ }
4507
+ serializeAltText(isForCopying) {
4508
+ return this.#altText?.serialize(isForCopying);
4509
+ }
4370
4510
  hasAltText() {
4371
- return !this.#altText?.isEmpty();
4511
+ return !!this.#altText && !this.#altText.isEmpty();
4512
+ }
4513
+ hasAltTextData() {
4514
+ return this.#altText?.hasData() ?? false;
4372
4515
  }
4373
4516
  render() {
4374
4517
  this.div = document.createElement("div");
@@ -4380,13 +4523,7 @@ class AnnotationEditor {
4380
4523
  this.div.classList.add("hidden");
4381
4524
  }
4382
4525
  this.setInForeground();
4383
- const signal = this._uiManager._signal;
4384
- this.div.addEventListener("focusin", this.#boundFocusin, {
4385
- signal
4386
- });
4387
- this.div.addEventListener("focusout", this.#boundFocusout, {
4388
- signal
4389
- });
4526
+ this.#addFocusListeners();
4390
4527
  const [parentWidth, parentHeight] = this.parentDimensions;
4391
4528
  if (this.parentRotation % 180 !== 0) {
4392
4529
  this.div.style.maxWidth = `${(100 * parentHeight / parentWidth).toFixed(2)}%`;
@@ -4425,18 +4562,13 @@ class AnnotationEditor {
4425
4562
  #setUpDragSession(event) {
4426
4563
  const isSelected = this._uiManager.isSelected(this);
4427
4564
  this._uiManager.setUpDragSession();
4428
- let pointerMoveOptions, pointerMoveCallback;
4429
- const signal = this._uiManager._signal;
4565
+ const ac = new AbortController();
4566
+ const signal = this._uiManager.combinedSignal(ac);
4430
4567
  if (isSelected) {
4431
4568
  this.div.classList.add("moving");
4432
- pointerMoveOptions = {
4433
- passive: true,
4434
- capture: true,
4435
- signal
4436
- };
4437
4569
  this.#prevDragX = event.clientX;
4438
4570
  this.#prevDragY = event.clientY;
4439
- pointerMoveCallback = e => {
4571
+ const pointerMoveCallback = e => {
4440
4572
  const {
4441
4573
  clientX: x,
4442
4574
  clientY: y
@@ -4446,14 +4578,16 @@ class AnnotationEditor {
4446
4578
  this.#prevDragY = y;
4447
4579
  this._uiManager.dragSelectedEditors(tx, ty);
4448
4580
  };
4449
- window.addEventListener("pointermove", pointerMoveCallback, pointerMoveOptions);
4581
+ window.addEventListener("pointermove", pointerMoveCallback, {
4582
+ passive: true,
4583
+ capture: true,
4584
+ signal
4585
+ });
4450
4586
  }
4451
4587
  const pointerUpCallback = () => {
4452
- window.removeEventListener("pointerup", pointerUpCallback);
4453
- window.removeEventListener("blur", pointerUpCallback);
4588
+ ac.abort();
4454
4589
  if (isSelected) {
4455
4590
  this.div.classList.remove("moving");
4456
- window.removeEventListener("pointermove", pointerMoveCallback, pointerMoveOptions);
4457
4591
  }
4458
4592
  this.#hasBeenClicked = false;
4459
4593
  if (!this._uiManager.endDragSession()) {
@@ -4541,15 +4675,22 @@ class AnnotationEditor {
4541
4675
  needsToBeRebuilt() {
4542
4676
  return this.div && !this.isAttachedToDOM;
4543
4677
  }
4544
- rebuild() {
4545
- const signal = this._uiManager._signal;
4546
- this.div?.addEventListener("focusin", this.#boundFocusin, {
4678
+ #addFocusListeners() {
4679
+ if (this.#focusAC || !this.div) {
4680
+ return;
4681
+ }
4682
+ this.#focusAC = new AbortController();
4683
+ const signal = this._uiManager.combinedSignal(this.#focusAC);
4684
+ this.div.addEventListener("focusin", this.focusin.bind(this), {
4547
4685
  signal
4548
4686
  });
4549
- this.div?.addEventListener("focusout", this.#boundFocusout, {
4687
+ this.div.addEventListener("focusout", this.focusout.bind(this), {
4550
4688
  signal
4551
4689
  });
4552
4690
  }
4691
+ rebuild() {
4692
+ this.#addFocusListeners();
4693
+ }
4553
4694
  rotate(_angle) {}
4554
4695
  serialize(isForCopying = false, context = null) {
4555
4696
  unreachable("An editor must be serializable");
@@ -4574,8 +4715,8 @@ class AnnotationEditor {
4574
4715
  return !!this.annotationElementId && (this.deleted || this.serialize() !== null);
4575
4716
  }
4576
4717
  remove() {
4577
- this.div.removeEventListener("focusin", this.#boundFocusin);
4578
- this.div.removeEventListener("focusout", this.#boundFocusout);
4718
+ this.#focusAC?.abort();
4719
+ this.#focusAC = null;
4579
4720
  if (!this.isEmpty()) {
4580
4721
  this.commit();
4581
4722
  }
@@ -4640,7 +4781,7 @@ class AnnotationEditor {
4640
4781
  div.addEventListener("focus", this.#resizerFocus.bind(this, name), {
4641
4782
  signal
4642
4783
  });
4643
- AnnotationEditor._l10nPromise.get(`pdfjs-editor-resizer-label-${name}`).then(msg => div.setAttribute("aria-label", msg));
4784
+ div.setAttribute("data-l10n-id", AnnotationEditor._l10nResizer[name]);
4644
4785
  }
4645
4786
  }
4646
4787
  const first = this.#allResizerDivs[0];
@@ -4666,7 +4807,7 @@ class AnnotationEditor {
4666
4807
  for (const child of children) {
4667
4808
  const div = this.#allResizerDivs[i++];
4668
4809
  const name = div.getAttribute("data-resizer-name");
4669
- AnnotationEditor._l10nPromise.get(`pdfjs-editor-resizer-label-${name}`).then(msg => child.setAttribute("aria-label", msg));
4810
+ child.setAttribute("data-l10n-id", AnnotationEditor._l10nResizer[name]);
4670
4811
  }
4671
4812
  }
4672
4813
  this.#setResizerTabIndex(0);
@@ -4726,15 +4867,16 @@ class AnnotationEditor {
4726
4867
  select() {
4727
4868
  this.makeResizable();
4728
4869
  this.div?.classList.add("selectedEditor");
4729
- if (!this.#editToolbar) {
4870
+ if (!this._editToolbar) {
4730
4871
  this.addEditToolbar().then(() => {
4731
4872
  if (this.div?.classList.contains("selectedEditor")) {
4732
- this.#editToolbar?.show();
4873
+ this._editToolbar?.show();
4733
4874
  }
4734
4875
  });
4735
4876
  return;
4736
4877
  }
4737
- this.#editToolbar?.show();
4878
+ this._editToolbar?.show();
4879
+ this.#altText?.toggleAltTextBadge(false);
4738
4880
  }
4739
4881
  unselect() {
4740
4882
  this.#resizersDiv?.classList.add("hidden");
@@ -4744,7 +4886,8 @@ class AnnotationEditor {
4744
4886
  preventScroll: true
4745
4887
  });
4746
4888
  }
4747
- this.#editToolbar?.hide();
4889
+ this._editToolbar?.hide();
4890
+ this.#altText?.toggleAltTextBadge(true);
4748
4891
  }
4749
4892
  updateParams(type, value) {}
4750
4893
  disableEditing() {}
@@ -5603,11 +5746,6 @@ function applyBoundingBox(ctx, bbox) {
5603
5746
  ctx.clip(region);
5604
5747
  }
5605
5748
  class BaseShadingPattern {
5606
- constructor() {
5607
- if (this.constructor === BaseShadingPattern) {
5608
- unreachable("Cannot initialize BaseShadingPattern.");
5609
- }
5610
- }
5611
5749
  getPattern() {
5612
5750
  unreachable("Abstract method `getPattern` called.");
5613
5751
  }
@@ -10088,25 +10226,30 @@ class PDFNetworkStreamRangeRequestReader {
10088
10226
 
10089
10227
 
10090
10228
 
10091
- const fileUriRegex = /^file:\/\/\/[a-zA-Z]:\//;
10092
- function parseUrl(sourceUrl) {
10093
- const url = NodePackages.get("url");
10094
- const parsedUrl = url.parse(sourceUrl);
10095
- if (parsedUrl.protocol === "file:" || parsedUrl.host) {
10096
- return parsedUrl;
10097
- }
10098
- if (/^[a-z]:[/\\]/i.test(sourceUrl)) {
10099
- return url.parse(`file:///${sourceUrl}`);
10100
- }
10101
- if (!parsedUrl.host) {
10102
- parsedUrl.protocol = "file:";
10229
+ const urlRegex = /^[a-z][a-z0-9\-+.]+:/i;
10230
+ function parseUrlOrPath(sourceUrl) {
10231
+ if (urlRegex.test(sourceUrl)) {
10232
+ return new URL(sourceUrl);
10103
10233
  }
10104
- return parsedUrl;
10234
+ const url = NodePackages.get("url");
10235
+ return new URL(url.pathToFileURL(sourceUrl));
10236
+ }
10237
+ function createRequest(url, headers, callback) {
10238
+ if (url.protocol === "http:") {
10239
+ const http = NodePackages.get("http");
10240
+ return http.request(url, {
10241
+ headers
10242
+ }, callback);
10243
+ }
10244
+ const https = NodePackages.get("https");
10245
+ return https.request(url, {
10246
+ headers
10247
+ }, callback);
10105
10248
  }
10106
10249
  class PDFNodeStream {
10107
10250
  constructor(source) {
10108
10251
  this.source = source;
10109
- this.url = parseUrl(source.url);
10252
+ this.url = parseUrlOrPath(source.url);
10110
10253
  this.isHttp = this.url.protocol === "http:" || this.url.protocol === "https:";
10111
10254
  this.isFsUrl = this.url.protocol === "file:";
10112
10255
  this.httpHeaders = this.isHttp && source.httpHeaders || {};
@@ -10301,17 +10444,6 @@ class BaseRangeReader {
10301
10444
  }
10302
10445
  }
10303
10446
  }
10304
- function createRequestOptions(parsedUrl, headers) {
10305
- return {
10306
- protocol: parsedUrl.protocol,
10307
- auth: parsedUrl.auth,
10308
- host: parsedUrl.hostname,
10309
- port: parsedUrl.port,
10310
- path: parsedUrl.path,
10311
- method: "GET",
10312
- headers
10313
- };
10314
- }
10315
10447
  class PDFNodeStreamFullReader extends BaseFullReader {
10316
10448
  constructor(stream) {
10317
10449
  super(stream);
@@ -10338,14 +10470,7 @@ class PDFNodeStreamFullReader extends BaseFullReader {
10338
10470
  this._contentLength = suggestedLength || this._contentLength;
10339
10471
  this._filename = extractFilenameFromHeader(getResponseHeader);
10340
10472
  };
10341
- this._request = null;
10342
- if (this._url.protocol === "http:") {
10343
- const http = NodePackages.get("http");
10344
- this._request = http.request(createRequestOptions(this._url, stream.httpHeaders), handleResponse);
10345
- } else {
10346
- const https = NodePackages.get("https");
10347
- this._request = https.request(createRequestOptions(this._url, stream.httpHeaders), handleResponse);
10348
- }
10473
+ this._request = createRequest(this._url, stream.httpHeaders, handleResponse);
10349
10474
  this._request.on("error", reason => {
10350
10475
  this._storedError = reason;
10351
10476
  this._headersCapability.reject(reason);
@@ -10373,14 +10498,7 @@ class PDFNodeStreamRangeReader extends BaseRangeReader {
10373
10498
  }
10374
10499
  this._setReadableStream(response);
10375
10500
  };
10376
- this._request = null;
10377
- if (this._url.protocol === "http:") {
10378
- const http = NodePackages.get("http");
10379
- this._request = http.request(createRequestOptions(this._url, this._httpHeaders), handleResponse);
10380
- } else {
10381
- const https = NodePackages.get("https");
10382
- this._request = https.request(createRequestOptions(this._url, this._httpHeaders), handleResponse);
10383
- }
10501
+ this._request = createRequest(this._url, this._httpHeaders, handleResponse);
10384
10502
  this._request.on("error", reason => {
10385
10503
  this._storedError = reason;
10386
10504
  });
@@ -10390,18 +10508,14 @@ class PDFNodeStreamRangeReader extends BaseRangeReader {
10390
10508
  class PDFNodeStreamFsFullReader extends BaseFullReader {
10391
10509
  constructor(stream) {
10392
10510
  super(stream);
10393
- let path = decodeURIComponent(this._url.path);
10394
- if (fileUriRegex.test(this._url.href)) {
10395
- path = path.replace(/^\//, "");
10396
- }
10397
10511
  const fs = NodePackages.get("fs");
10398
- fs.promises.lstat(path).then(stat => {
10512
+ fs.promises.lstat(this._url).then(stat => {
10399
10513
  this._contentLength = stat.size;
10400
- this._setReadableStream(fs.createReadStream(path));
10514
+ this._setReadableStream(fs.createReadStream(this._url));
10401
10515
  this._headersCapability.resolve();
10402
10516
  }, error => {
10403
10517
  if (error.code === "ENOENT") {
10404
- error = new MissingPDFException(`Missing PDF "${path}".`);
10518
+ error = new MissingPDFException(`Missing PDF "${this._url}".`);
10405
10519
  }
10406
10520
  this._storedError = error;
10407
10521
  this._headersCapability.reject(error);
@@ -10411,12 +10525,8 @@ class PDFNodeStreamFsFullReader extends BaseFullReader {
10411
10525
  class PDFNodeStreamFsRangeReader extends BaseRangeReader {
10412
10526
  constructor(stream, start, end) {
10413
10527
  super(stream);
10414
- let path = decodeURIComponent(this._url.path);
10415
- if (fileUriRegex.test(this._url.href)) {
10416
- path = path.replace(/^\//, "");
10417
- }
10418
10528
  const fs = NodePackages.get("fs");
10419
- this._setReadableStream(fs.createReadStream(path, {
10529
+ this._setReadableStream(fs.createReadStream(this._url, {
10420
10530
  start,
10421
10531
  end: end - 1
10422
10532
  }));
@@ -10941,7 +11051,7 @@ function getDocument(src = {}) {
10941
11051
  }
10942
11052
  const docParams = {
10943
11053
  docId,
10944
- apiVersion: "4.5.136",
11054
+ apiVersion: "4.6.82",
10945
11055
  data,
10946
11056
  password,
10947
11057
  disableAutoFetch,
@@ -11726,37 +11836,35 @@ class LoopbackPort {
11726
11836
  this.#listeners.clear();
11727
11837
  }
11728
11838
  }
11729
- const PDFWorkerUtil = {
11730
- isWorkerDisabled: false,
11731
- fakeWorkerId: 0
11732
- };
11733
- {
11734
- if (isNodeJS) {
11735
- PDFWorkerUtil.isWorkerDisabled = true;
11736
- GlobalWorkerOptions.workerSrc ||= "./pdf.worker.mjs";
11737
- }
11738
- PDFWorkerUtil.isSameOrigin = function (baseUrl, otherUrl) {
11739
- let base;
11740
- try {
11741
- base = new URL(baseUrl);
11742
- if (!base.origin || base.origin === "null") {
11743
- return false;
11744
- }
11745
- } catch {
11746
- return false;
11747
- }
11748
- const other = new URL(otherUrl, base);
11749
- return base.origin === other.origin;
11750
- };
11751
- PDFWorkerUtil.createCDNWrapper = function (url) {
11752
- const wrapper = `await import("${url}");`;
11753
- return URL.createObjectURL(new Blob([wrapper], {
11754
- type: "text/javascript"
11755
- }));
11756
- };
11757
- }
11758
11839
  class PDFWorker {
11840
+ static #fakeWorkerId = 0;
11841
+ static #isWorkerDisabled = false;
11759
11842
  static #workerPorts;
11843
+ static {
11844
+ if (isNodeJS) {
11845
+ this.#isWorkerDisabled = true;
11846
+ GlobalWorkerOptions.workerSrc ||= "./pdf.worker.mjs";
11847
+ }
11848
+ this._isSameOrigin = (baseUrl, otherUrl) => {
11849
+ let base;
11850
+ try {
11851
+ base = new URL(baseUrl);
11852
+ if (!base.origin || base.origin === "null") {
11853
+ return false;
11854
+ }
11855
+ } catch {
11856
+ return false;
11857
+ }
11858
+ const other = new URL(otherUrl, base);
11859
+ return base.origin === other.origin;
11860
+ };
11861
+ this._createCDNWrapper = url => {
11862
+ const wrapper = `await import("${url}");`;
11863
+ return URL.createObjectURL(new Blob([wrapper], {
11864
+ type: "text/javascript"
11865
+ }));
11866
+ };
11867
+ }
11760
11868
  constructor({
11761
11869
  name = null,
11762
11870
  port = null,
@@ -11804,7 +11912,7 @@ class PDFWorker {
11804
11912
  this.#resolve();
11805
11913
  }
11806
11914
  _initialize() {
11807
- if (PDFWorkerUtil.isWorkerDisabled || PDFWorker.#mainThreadWorkerMessageHandler) {
11915
+ if (PDFWorker.#isWorkerDisabled || PDFWorker.#mainThreadWorkerMessageHandler) {
11808
11916
  this._setupFakeWorker();
11809
11917
  return;
11810
11918
  }
@@ -11812,8 +11920,8 @@ class PDFWorker {
11812
11920
  workerSrc
11813
11921
  } = PDFWorker;
11814
11922
  try {
11815
- if (!PDFWorkerUtil.isSameOrigin(window.location.href, workerSrc)) {
11816
- workerSrc = PDFWorkerUtil.createCDNWrapper(new URL(workerSrc, window.location).href);
11923
+ if (!PDFWorker._isSameOrigin(window.location.href, workerSrc)) {
11924
+ workerSrc = PDFWorker._createCDNWrapper(new URL(workerSrc, window.location).href);
11817
11925
  }
11818
11926
  const worker = new Worker(workerSrc, {
11819
11927
  type: "module"
@@ -11872,9 +11980,9 @@ class PDFWorker {
11872
11980
  this._setupFakeWorker();
11873
11981
  }
11874
11982
  _setupFakeWorker() {
11875
- if (!PDFWorkerUtil.isWorkerDisabled) {
11983
+ if (!PDFWorker.#isWorkerDisabled) {
11876
11984
  warn("Setting up fake worker.");
11877
- PDFWorkerUtil.isWorkerDisabled = true;
11985
+ PDFWorker.#isWorkerDisabled = true;
11878
11986
  }
11879
11987
  PDFWorker._setupFakeWorkerGlobal.then(WorkerMessageHandler => {
11880
11988
  if (this.destroyed) {
@@ -11883,7 +11991,7 @@ class PDFWorker {
11883
11991
  }
11884
11992
  const port = new LoopbackPort();
11885
11993
  this._port = port;
11886
- const id = `fake${PDFWorkerUtil.fakeWorkerId++}`;
11994
+ const id = `fake${PDFWorker.#fakeWorkerId++}`;
11887
11995
  const workerHandler = new MessageHandler(id + "_worker", id, port);
11888
11996
  WorkerMessageHandler.setup(workerHandler, port);
11889
11997
  this._messageHandler = new MessageHandler(id, id + "_worker", port);
@@ -12724,8 +12832,8 @@ class InternalRenderTask {
12724
12832
  }
12725
12833
  }
12726
12834
  }
12727
- const version = "4.5.136";
12728
- const build = "3a21f03b0";
12835
+ const version = "4.6.82";
12836
+ const build = "9b541910f";
12729
12837
 
12730
12838
  ;// CONCATENATED MODULE: ./src/shared/scripting_utils.js
12731
12839
  function makeColorComp(n) {
@@ -14788,10 +14896,9 @@ class PopupElement {
14788
14896
  if (this.#dateObj) {
14789
14897
  const modificationDate = document.createElement("span");
14790
14898
  modificationDate.classList.add("popupDate");
14791
- modificationDate.setAttribute("data-l10n-id", "pdfjs-annotation-date-string");
14899
+ modificationDate.setAttribute("data-l10n-id", "pdfjs-annotation-date-time-string");
14792
14900
  modificationDate.setAttribute("data-l10n-args", JSON.stringify({
14793
- date: this.#dateObj.toLocaleDateString(),
14794
- time: this.#dateObj.toLocaleTimeString()
14901
+ dateObj: this.#dateObj.valueOf()
14795
14902
  }));
14796
14903
  header.append(modificationDate);
14797
14904
  }
@@ -15564,14 +15671,10 @@ class AnnotationLayer {
15564
15671
 
15565
15672
  const EOL_PATTERN = /\r\n?|\n/g;
15566
15673
  class FreeTextEditor extends AnnotationEditor {
15567
- #boundEditorDivBlur = this.editorDivBlur.bind(this);
15568
- #boundEditorDivFocus = this.editorDivFocus.bind(this);
15569
- #boundEditorDivInput = this.editorDivInput.bind(this);
15570
- #boundEditorDivKeydown = this.editorDivKeydown.bind(this);
15571
- #boundEditorDivPaste = this.editorDivPaste.bind(this);
15572
15674
  #color;
15573
15675
  #content = "";
15574
15676
  #editorDivId = `${this.id}-editor`;
15677
+ #editModeAC = null;
15575
15678
  #fontSize;
15576
15679
  #initialData = null;
15577
15680
  static _freeTextDefaultContent = "";
@@ -15717,20 +15820,21 @@ class FreeTextEditor extends AnnotationEditor {
15717
15820
  this.editorDiv.contentEditable = true;
15718
15821
  this._isDraggable = false;
15719
15822
  this.div.removeAttribute("aria-activedescendant");
15720
- const signal = this._uiManager._signal;
15721
- this.editorDiv.addEventListener("keydown", this.#boundEditorDivKeydown, {
15823
+ this.#editModeAC = new AbortController();
15824
+ const signal = this._uiManager.combinedSignal(this.#editModeAC);
15825
+ this.editorDiv.addEventListener("keydown", this.editorDivKeydown.bind(this), {
15722
15826
  signal
15723
15827
  });
15724
- this.editorDiv.addEventListener("focus", this.#boundEditorDivFocus, {
15828
+ this.editorDiv.addEventListener("focus", this.editorDivFocus.bind(this), {
15725
15829
  signal
15726
15830
  });
15727
- this.editorDiv.addEventListener("blur", this.#boundEditorDivBlur, {
15831
+ this.editorDiv.addEventListener("blur", this.editorDivBlur.bind(this), {
15728
15832
  signal
15729
15833
  });
15730
- this.editorDiv.addEventListener("input", this.#boundEditorDivInput, {
15834
+ this.editorDiv.addEventListener("input", this.editorDivInput.bind(this), {
15731
15835
  signal
15732
15836
  });
15733
- this.editorDiv.addEventListener("paste", this.#boundEditorDivPaste, {
15837
+ this.editorDiv.addEventListener("paste", this.editorDivPaste.bind(this), {
15734
15838
  signal
15735
15839
  });
15736
15840
  }
@@ -15744,11 +15848,8 @@ class FreeTextEditor extends AnnotationEditor {
15744
15848
  this.editorDiv.contentEditable = false;
15745
15849
  this.div.setAttribute("aria-activedescendant", this.#editorDivId);
15746
15850
  this._isDraggable = true;
15747
- this.editorDiv.removeEventListener("keydown", this.#boundEditorDivKeydown);
15748
- this.editorDiv.removeEventListener("focus", this.#boundEditorDivFocus);
15749
- this.editorDiv.removeEventListener("blur", this.#boundEditorDivBlur);
15750
- this.editorDiv.removeEventListener("input", this.#boundEditorDivInput);
15751
- this.editorDiv.removeEventListener("paste", this.#boundEditorDivPaste);
15851
+ this.#editModeAC?.abort();
15852
+ this.#editModeAC = null;
15752
15853
  this.div.focus({
15753
15854
  preventScroll: true
15754
15855
  });
@@ -17016,7 +17117,6 @@ class HighlightEditor extends AnnotationEditor {
17016
17117
  #highlightOutlines = null;
17017
17118
  #id = null;
17018
17119
  #isFreeHighlight = false;
17019
- #boundKeydown = this.#keydown.bind(this);
17020
17120
  #lastPoint = null;
17021
17121
  #opacity;
17022
17122
  #outlineId = null;
@@ -17409,7 +17509,7 @@ class HighlightEditor extends AnnotationEditor {
17409
17509
  if (this.#isFreeHighlight) {
17410
17510
  div.classList.add("free");
17411
17511
  } else {
17412
- this.div.addEventListener("keydown", this.#boundKeydown, {
17512
+ this.div.addEventListener("keydown", this.#keydown.bind(this), {
17413
17513
  signal: this._uiManager._signal
17414
17514
  });
17415
17515
  }
@@ -17527,25 +17627,14 @@ class HighlightEditor extends AnnotationEditor {
17527
17627
  width: parentWidth,
17528
17628
  height: parentHeight
17529
17629
  } = textLayer.getBoundingClientRect();
17530
- const pointerMove = e => {
17531
- this.#highlightMove(parent, e);
17532
- };
17533
- const signal = parent._signal;
17534
- const pointerDownOptions = {
17535
- capture: true,
17536
- passive: false,
17537
- signal
17538
- };
17630
+ const ac = new AbortController();
17631
+ const signal = parent.combinedSignal(ac);
17539
17632
  const pointerDown = e => {
17540
17633
  e.preventDefault();
17541
17634
  e.stopPropagation();
17542
17635
  };
17543
17636
  const pointerUpCallback = e => {
17544
- textLayer.removeEventListener("pointermove", pointerMove);
17545
- window.removeEventListener("blur", pointerUpCallback);
17546
- window.removeEventListener("pointerup", pointerUpCallback);
17547
- window.removeEventListener("pointerdown", pointerDown, pointerDownOptions);
17548
- window.removeEventListener("contextmenu", noContextMenu);
17637
+ ac.abort();
17549
17638
  this.#endHighlight(parent, e);
17550
17639
  };
17551
17640
  window.addEventListener("blur", pointerUpCallback, {
@@ -17554,11 +17643,15 @@ class HighlightEditor extends AnnotationEditor {
17554
17643
  window.addEventListener("pointerup", pointerUpCallback, {
17555
17644
  signal
17556
17645
  });
17557
- window.addEventListener("pointerdown", pointerDown, pointerDownOptions);
17646
+ window.addEventListener("pointerdown", pointerDown, {
17647
+ capture: true,
17648
+ passive: false,
17649
+ signal
17650
+ });
17558
17651
  window.addEventListener("contextmenu", noContextMenu, {
17559
17652
  signal
17560
17653
  });
17561
- textLayer.addEventListener("pointermove", pointerMove, {
17654
+ textLayer.addEventListener("pointermove", this.#highlightMove.bind(this, parent), {
17562
17655
  signal
17563
17656
  });
17564
17657
  this._freeHighlight = new FreeOutliner({
@@ -17647,16 +17740,14 @@ class HighlightEditor extends AnnotationEditor {
17647
17740
  class InkEditor extends AnnotationEditor {
17648
17741
  #baseHeight = 0;
17649
17742
  #baseWidth = 0;
17650
- #boundCanvasPointermove = this.canvasPointermove.bind(this);
17651
- #boundCanvasPointerleave = this.canvasPointerleave.bind(this);
17652
- #boundCanvasPointerup = this.canvasPointerup.bind(this);
17653
- #boundCanvasPointerdown = this.canvasPointerdown.bind(this);
17654
17743
  #canvasContextMenuTimeoutId = null;
17655
17744
  #currentPath2D = new Path2D();
17656
17745
  #disableEditing = false;
17746
+ #drawingAC = null;
17657
17747
  #hasSomethingToDraw = false;
17658
17748
  #isCanvasInitialized = false;
17659
17749
  #observer = null;
17750
+ #pointerdownAC = null;
17660
17751
  #realWidth = 0;
17661
17752
  #realHeight = 0;
17662
17753
  #requestFrameCallback = null;
@@ -17823,9 +17914,7 @@ class InkEditor extends AnnotationEditor {
17823
17914
  }
17824
17915
  super.enableEditMode();
17825
17916
  this._isDraggable = false;
17826
- this.canvas.addEventListener("pointerdown", this.#boundCanvasPointerdown, {
17827
- signal: this._uiManager._signal
17828
- });
17917
+ this.#addPointerdownListener();
17829
17918
  }
17830
17919
  disableEditMode() {
17831
17920
  if (!this.isInEditMode() || this.canvas === null) {
@@ -17834,7 +17923,7 @@ class InkEditor extends AnnotationEditor {
17834
17923
  super.disableEditMode();
17835
17924
  this._isDraggable = !this.isEmpty();
17836
17925
  this.div.classList.remove("editing");
17837
- this.canvas.removeEventListener("pointerdown", this.#boundCanvasPointerdown);
17926
+ this.#removePointerdownListener();
17838
17927
  }
17839
17928
  onceAdded() {
17840
17929
  this._isDraggable = !this.isEmpty();
@@ -17874,20 +17963,21 @@ class InkEditor extends AnnotationEditor {
17874
17963
  ctx.strokeStyle = `${color}${opacityToHex(opacity)}`;
17875
17964
  }
17876
17965
  #startDrawing(x, y) {
17877
- const signal = this._uiManager._signal;
17878
17966
  this.canvas.addEventListener("contextmenu", noContextMenu, {
17879
- signal
17967
+ signal: this._uiManager._signal
17880
17968
  });
17881
- this.canvas.addEventListener("pointerleave", this.#boundCanvasPointerleave, {
17969
+ this.#removePointerdownListener();
17970
+ this.#drawingAC = new AbortController();
17971
+ const signal = this._uiManager.combinedSignal(this.#drawingAC);
17972
+ this.canvas.addEventListener("pointerleave", this.canvasPointerleave.bind(this), {
17882
17973
  signal
17883
17974
  });
17884
- this.canvas.addEventListener("pointermove", this.#boundCanvasPointermove, {
17975
+ this.canvas.addEventListener("pointermove", this.canvasPointermove.bind(this), {
17885
17976
  signal
17886
17977
  });
17887
- this.canvas.addEventListener("pointerup", this.#boundCanvasPointerup, {
17978
+ this.canvas.addEventListener("pointerup", this.canvasPointerup.bind(this), {
17888
17979
  signal
17889
17980
  });
17890
- this.canvas.removeEventListener("pointerdown", this.#boundCanvasPointerdown);
17891
17981
  this.isEditing = true;
17892
17982
  if (!this.#isCanvasInitialized) {
17893
17983
  this.#isCanvasInitialized = true;
@@ -18075,6 +18165,20 @@ class InkEditor extends AnnotationEditor {
18075
18165
  super.focusin(event);
18076
18166
  this.enableEditMode();
18077
18167
  }
18168
+ #addPointerdownListener() {
18169
+ if (this.#pointerdownAC) {
18170
+ return;
18171
+ }
18172
+ this.#pointerdownAC = new AbortController();
18173
+ const signal = this._uiManager.combinedSignal(this.#pointerdownAC);
18174
+ this.canvas.addEventListener("pointerdown", this.canvasPointerdown.bind(this), {
18175
+ signal
18176
+ });
18177
+ }
18178
+ #removePointerdownListener() {
18179
+ this.pointerdownAC?.abort();
18180
+ this.pointerdownAC = null;
18181
+ }
18078
18182
  canvasPointerdown(event) {
18079
18183
  if (event.button !== 0 || !this.isInEditMode() || this.#disableEditing) {
18080
18184
  return;
@@ -18100,12 +18204,9 @@ class InkEditor extends AnnotationEditor {
18100
18204
  this.#endDrawing(event);
18101
18205
  }
18102
18206
  #endDrawing(event) {
18103
- this.canvas.removeEventListener("pointerleave", this.#boundCanvasPointerleave);
18104
- this.canvas.removeEventListener("pointermove", this.#boundCanvasPointermove);
18105
- this.canvas.removeEventListener("pointerup", this.#boundCanvasPointerup);
18106
- this.canvas.addEventListener("pointerdown", this.#boundCanvasPointerdown, {
18107
- signal: this._uiManager._signal
18108
- });
18207
+ this.#drawingAC?.abort();
18208
+ this.#drawingAC = null;
18209
+ this.#addPointerdownListener();
18109
18210
  if (this.#canvasContextMenuTimeoutId) {
18110
18211
  clearTimeout(this.#canvasContextMenuTimeoutId);
18111
18212
  }
@@ -18466,7 +18567,6 @@ class StampEditor extends AnnotationEditor {
18466
18567
  #bitmapFile = null;
18467
18568
  #bitmapFileName = "";
18468
18569
  #canvas = null;
18469
- #hasMLBeenQueried = false;
18470
18570
  #observer = null;
18471
18571
  #resizeTimeoutId = null;
18472
18572
  #isSvg = false;
@@ -18499,6 +18599,25 @@ class StampEditor extends AnnotationEditor {
18499
18599
  bitmapFile: item.getAsFile()
18500
18600
  });
18501
18601
  }
18602
+ altTextFinish() {
18603
+ if (this._uiManager.useNewAltTextFlow) {
18604
+ this.div.hidden = false;
18605
+ }
18606
+ super.altTextFinish();
18607
+ }
18608
+ get telemetryFinalData() {
18609
+ return {
18610
+ type: "stamp",
18611
+ hasAltText: !!this.altTextData?.altText
18612
+ };
18613
+ }
18614
+ static computeTelemetryFinalData(data) {
18615
+ const hasAltTextStats = data.get("hasAltText");
18616
+ return {
18617
+ hasAltText: hasAltTextStats.get(true) ?? 0,
18618
+ hasNoAltText: hasAltTextStats.get(false) ?? 0
18619
+ };
18620
+ }
18502
18621
  #getBitmapFetched(data, fromId = false) {
18503
18622
  if (!data) {
18504
18623
  this.remove();
@@ -18517,9 +18636,76 @@ class StampEditor extends AnnotationEditor {
18517
18636
  #getBitmapDone() {
18518
18637
  this.#bitmapPromise = null;
18519
18638
  this._uiManager.enableWaiting(false);
18520
- if (this.#canvas) {
18521
- this.div.focus();
18639
+ if (!this.#canvas) {
18640
+ return;
18641
+ }
18642
+ if (this._uiManager.useNewAltTextWhenAddingImage && this._uiManager.useNewAltTextFlow && this.#bitmap) {
18643
+ this._editToolbar.hide();
18644
+ this._uiManager.editAltText(this, true);
18645
+ return;
18646
+ }
18647
+ if (!this._uiManager.useNewAltTextWhenAddingImage && this._uiManager.useNewAltTextFlow && this.#bitmap) {
18648
+ this._reportTelemetry({
18649
+ action: "pdfjs.image.image_added",
18650
+ data: {
18651
+ alt_text_modal: false,
18652
+ alt_text_type: "empty"
18653
+ }
18654
+ });
18655
+ try {
18656
+ this.mlGuessAltText();
18657
+ } catch {}
18658
+ }
18659
+ this.div.focus();
18660
+ }
18661
+ async mlGuessAltText(imageData = null, updateAltTextData = true) {
18662
+ if (this.hasAltTextData()) {
18663
+ return null;
18664
+ }
18665
+ const {
18666
+ mlManager
18667
+ } = this._uiManager;
18668
+ if (!mlManager) {
18669
+ throw new Error("No ML.");
18670
+ }
18671
+ if (!(await mlManager.isEnabledFor("altText"))) {
18672
+ throw new Error("ML isn't enabled for alt text.");
18522
18673
  }
18674
+ const {
18675
+ data,
18676
+ width,
18677
+ height
18678
+ } = imageData || this.copyCanvas(null, true).imageData;
18679
+ const response = await mlManager.guess({
18680
+ name: "altText",
18681
+ request: {
18682
+ data,
18683
+ width,
18684
+ height,
18685
+ channels: data.length / (width * height)
18686
+ }
18687
+ });
18688
+ if (!response) {
18689
+ throw new Error("No response from the AI service.");
18690
+ }
18691
+ if (response.error) {
18692
+ throw new Error("Error from the AI service.");
18693
+ }
18694
+ if (response.cancel) {
18695
+ return null;
18696
+ }
18697
+ if (!response.output) {
18698
+ throw new Error("No valid response from the AI service.");
18699
+ }
18700
+ const altText = response.output;
18701
+ await this.setGuessedAltText(altText);
18702
+ if (updateAltTextData && !this.hasAltTextData()) {
18703
+ this.altTextData = {
18704
+ alt: altText,
18705
+ decorative: false
18706
+ };
18707
+ }
18708
+ return altText;
18523
18709
  }
18524
18710
  #getBitmap() {
18525
18711
  if (this.#bitmapId) {
@@ -18552,6 +18738,12 @@ class StampEditor extends AnnotationEditor {
18552
18738
  } else {
18553
18739
  this._uiManager.enableWaiting(true);
18554
18740
  const data = await this._uiManager.imageManager.getFromFile(input.files[0]);
18741
+ this._reportTelemetry({
18742
+ action: "pdfjs.image.image_selected",
18743
+ data: {
18744
+ alt_text_modal: this._uiManager.useNewAltTextFlow
18745
+ }
18746
+ });
18555
18747
  this.#getBitmapFetched(data);
18556
18748
  }
18557
18749
  resolve();
@@ -18656,7 +18848,9 @@ class StampEditor extends AnnotationEditor {
18656
18848
  this._uiManager.enableWaiting(false);
18657
18849
  const canvas = this.#canvas = document.createElement("canvas");
18658
18850
  div.append(canvas);
18659
- div.hidden = false;
18851
+ if (!this._uiManager.useNewAltTextWhenAddingImage || !this._uiManager.useNewAltTextFlow) {
18852
+ div.hidden = false;
18853
+ }
18660
18854
  this.#drawBitmap(width, height);
18661
18855
  this.#createObserver();
18662
18856
  if (!this.#hasBeenAddedInUndoStack) {
@@ -18670,6 +18864,71 @@ class StampEditor extends AnnotationEditor {
18670
18864
  canvas.setAttribute("aria-label", this.#bitmapFileName);
18671
18865
  }
18672
18866
  }
18867
+ copyCanvas(maxDimension, createImageData = false) {
18868
+ if (!maxDimension) {
18869
+ maxDimension = 224;
18870
+ }
18871
+ const {
18872
+ width: bitmapWidth,
18873
+ height: bitmapHeight
18874
+ } = this.#bitmap;
18875
+ const canvas = document.createElement("canvas");
18876
+ let bitmap = this.#bitmap;
18877
+ let width = bitmapWidth,
18878
+ height = bitmapHeight;
18879
+ if (bitmapWidth > maxDimension || bitmapHeight > maxDimension) {
18880
+ const ratio = Math.min(maxDimension / bitmapWidth, maxDimension / bitmapHeight);
18881
+ width = Math.floor(bitmapWidth * ratio);
18882
+ height = Math.floor(bitmapHeight * ratio);
18883
+ if (!this.#isSvg) {
18884
+ bitmap = this.#scaleBitmap(width, height);
18885
+ }
18886
+ }
18887
+ canvas.width = width;
18888
+ canvas.height = height;
18889
+ const ctx = canvas.getContext("2d");
18890
+ ctx.filter = this._uiManager.hcmFilter;
18891
+ let white = "white",
18892
+ black = "#cfcfd8";
18893
+ if (this._uiManager.hcmFilter !== "none") {
18894
+ black = "black";
18895
+ } else if (window.matchMedia?.("(prefers-color-scheme: dark)").matches) {
18896
+ white = "#8f8f9d";
18897
+ black = "#42414d";
18898
+ }
18899
+ const boxDim = 15;
18900
+ const pattern = new OffscreenCanvas(boxDim * 2, boxDim * 2);
18901
+ const patternCtx = pattern.getContext("2d");
18902
+ patternCtx.fillStyle = white;
18903
+ patternCtx.fillRect(0, 0, boxDim * 2, boxDim * 2);
18904
+ patternCtx.fillStyle = black;
18905
+ patternCtx.fillRect(0, 0, boxDim, boxDim);
18906
+ patternCtx.fillRect(boxDim, boxDim, boxDim, boxDim);
18907
+ ctx.fillStyle = ctx.createPattern(pattern, "repeat");
18908
+ ctx.fillRect(0, 0, width, height);
18909
+ if (createImageData) {
18910
+ const offscreen = new OffscreenCanvas(width, height);
18911
+ const offscreenCtx = offscreen.getContext("2d", {
18912
+ willReadFrequently: true
18913
+ });
18914
+ offscreenCtx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, width, height);
18915
+ const data = offscreenCtx.getImageData(0, 0, width, height).data;
18916
+ ctx.drawImage(offscreen, 0, 0);
18917
+ return {
18918
+ canvas,
18919
+ imageData: {
18920
+ width,
18921
+ height,
18922
+ data
18923
+ }
18924
+ };
18925
+ }
18926
+ ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, width, height);
18927
+ return {
18928
+ canvas,
18929
+ imageData: null
18930
+ };
18931
+ }
18673
18932
  #setDimensions(width, height) {
18674
18933
  const [parentWidth, parentHeight] = this.parentDimensions;
18675
18934
  this.width = width / parentWidth;
@@ -18714,37 +18973,6 @@ class StampEditor extends AnnotationEditor {
18714
18973
  }
18715
18974
  return bitmap;
18716
18975
  }
18717
- async #mlGuessAltText(bitmap, width, height) {
18718
- if (this.#hasMLBeenQueried) {
18719
- return;
18720
- }
18721
- this.#hasMLBeenQueried = true;
18722
- const isMLEnabled = await this._uiManager.isMLEnabledFor("altText");
18723
- if (!isMLEnabled || this.hasAltText()) {
18724
- return;
18725
- }
18726
- const offscreen = new OffscreenCanvas(width, height);
18727
- const ctx = offscreen.getContext("2d", {
18728
- willReadFrequently: true
18729
- });
18730
- ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, width, height);
18731
- const response = await this._uiManager.mlGuess({
18732
- service: "moz-image-to-text",
18733
- request: {
18734
- data: ctx.getImageData(0, 0, width, height).data,
18735
- width,
18736
- height,
18737
- channels: 4
18738
- }
18739
- });
18740
- const altText = response?.output || "";
18741
- if (this.parent && altText && !this.hasAltText()) {
18742
- this.altTextData = {
18743
- altText,
18744
- decorative: false
18745
- };
18746
- }
18747
- }
18748
18976
  #drawBitmap(width, height) {
18749
18977
  width = Math.ceil(width);
18750
18978
  height = Math.ceil(height);
@@ -18755,7 +18983,6 @@ class StampEditor extends AnnotationEditor {
18755
18983
  canvas.width = width;
18756
18984
  canvas.height = height;
18757
18985
  const bitmap = this.#isSvg ? this.#bitmap : this.#scaleBitmap(width, height);
18758
- this.#mlGuessAltText(bitmap, width, height);
18759
18986
  const ctx = canvas.getContext("2d");
18760
18987
  ctx.filter = this._uiManager.hcmFilter;
18761
18988
  ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, width, height);
@@ -18850,13 +19077,13 @@ class StampEditor extends AnnotationEditor {
18850
19077
  };
18851
19078
  if (isForCopying) {
18852
19079
  serialized.bitmapUrl = this.#serializeBitmap(true);
18853
- serialized.accessibilityData = this.altTextData;
19080
+ serialized.accessibilityData = this.serializeAltText(true);
18854
19081
  return serialized;
18855
19082
  }
18856
19083
  const {
18857
19084
  decorative,
18858
19085
  altText
18859
- } = this.altTextData;
19086
+ } = this.serializeAltText(false);
18860
19087
  if (!decorative && altText) {
18861
19088
  serialized.accessibilityData = {
18862
19089
  type: "Figure",
@@ -18898,15 +19125,14 @@ class AnnotationEditorLayer {
18898
19125
  #accessibilityManager;
18899
19126
  #allowClick = false;
18900
19127
  #annotationLayer = null;
18901
- #boundPointerup = null;
18902
- #boundPointerdown = null;
18903
- #boundTextLayerPointerDown = null;
19128
+ #clickAC = null;
18904
19129
  #editorFocusTimeoutId = null;
18905
19130
  #editors = new Map();
18906
19131
  #hadPointerDown = false;
18907
19132
  #isCleaningUp = false;
18908
19133
  #isDisabling = false;
18909
19134
  #textLayer = null;
19135
+ #textSelectionAC = null;
18910
19136
  #uiManager;
18911
19137
  static _initialized = false;
18912
19138
  static #editorTypes = new Map([FreeTextEditor, InkEditor, StampEditor, HighlightEditor].map(type => [type._editorType, type]));
@@ -19121,19 +19347,20 @@ class AnnotationEditorLayer {
19121
19347
  }
19122
19348
  enableTextSelection() {
19123
19349
  this.div.tabIndex = -1;
19124
- if (this.#textLayer?.div && !this.#boundTextLayerPointerDown) {
19125
- this.#boundTextLayerPointerDown = this.#textLayerPointerDown.bind(this);
19126
- this.#textLayer.div.addEventListener("pointerdown", this.#boundTextLayerPointerDown, {
19127
- signal: this.#uiManager._signal
19350
+ if (this.#textLayer?.div && !this.#textSelectionAC) {
19351
+ this.#textSelectionAC = new AbortController();
19352
+ const signal = this.#uiManager.combinedSignal(this.#textSelectionAC);
19353
+ this.#textLayer.div.addEventListener("pointerdown", this.#textLayerPointerDown.bind(this), {
19354
+ signal
19128
19355
  });
19129
19356
  this.#textLayer.div.classList.add("highlighting");
19130
19357
  }
19131
19358
  }
19132
19359
  disableTextSelection() {
19133
19360
  this.div.tabIndex = 0;
19134
- if (this.#textLayer?.div && this.#boundTextLayerPointerDown) {
19135
- this.#textLayer.div.removeEventListener("pointerdown", this.#boundTextLayerPointerDown);
19136
- this.#boundTextLayerPointerDown = null;
19361
+ if (this.#textLayer?.div && this.#textSelectionAC) {
19362
+ this.#textSelectionAC.abort();
19363
+ this.#textSelectionAC = null;
19137
19364
  this.#textLayer.div.classList.remove("highlighting");
19138
19365
  }
19139
19366
  }
@@ -19164,27 +19391,21 @@ class AnnotationEditorLayer {
19164
19391
  }
19165
19392
  }
19166
19393
  enableClick() {
19167
- if (this.#boundPointerdown) {
19394
+ if (this.#clickAC) {
19168
19395
  return;
19169
19396
  }
19170
- const signal = this.#uiManager._signal;
19171
- this.#boundPointerdown = this.pointerdown.bind(this);
19172
- this.#boundPointerup = this.pointerup.bind(this);
19173
- this.div.addEventListener("pointerdown", this.#boundPointerdown, {
19397
+ this.#clickAC = new AbortController();
19398
+ const signal = this.#uiManager.combinedSignal(this.#clickAC);
19399
+ this.div.addEventListener("pointerdown", this.pointerdown.bind(this), {
19174
19400
  signal
19175
19401
  });
19176
- this.div.addEventListener("pointerup", this.#boundPointerup, {
19402
+ this.div.addEventListener("pointerup", this.pointerup.bind(this), {
19177
19403
  signal
19178
19404
  });
19179
19405
  }
19180
19406
  disableClick() {
19181
- if (!this.#boundPointerdown) {
19182
- return;
19183
- }
19184
- this.div.removeEventListener("pointerdown", this.#boundPointerdown);
19185
- this.div.removeEventListener("pointerup", this.#boundPointerup);
19186
- this.#boundPointerdown = null;
19187
- this.#boundPointerup = null;
19407
+ this.#clickAC?.abort();
19408
+ this.#clickAC = null;
19188
19409
  }
19189
19410
  attach(editor) {
19190
19411
  this.#editors.set(editor.id, editor);
@@ -19297,8 +19518,8 @@ class AnnotationEditorLayer {
19297
19518
  get #currentEditorType() {
19298
19519
  return AnnotationEditorLayer.#editorTypes.get(this.#uiManager.getMode());
19299
19520
  }
19300
- get _signal() {
19301
- return this.#uiManager._signal;
19521
+ combinedSignal(ac) {
19522
+ return this.#uiManager.combinedSignal(ac);
19302
19523
  }
19303
19524
  #createNewEditor(params) {
19304
19525
  const editorType = this.#currentEditorType;
@@ -19711,8 +19932,8 @@ class DrawLayer {
19711
19932
 
19712
19933
 
19713
19934
 
19714
- const pdfjsVersion = "4.5.136";
19715
- const pdfjsBuild = "3a21f03b0";
19935
+ const pdfjsVersion = "4.6.82";
19936
+ const pdfjsBuild = "9b541910f";
19716
19937
 
19717
19938
  var __webpack_exports__AbortException = __webpack_exports__.AbortException;
19718
19939
  var __webpack_exports__AnnotationEditorLayer = __webpack_exports__.AnnotationEditorLayer;