pdfjs-dist 2.6.347 → 2.7.570

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.

Potentially problematic release.


This version of pdfjs-dist might be problematic. Click here for more details.

Files changed (158) hide show
  1. package/README.md +3 -3
  2. package/bower.json +1 -1
  3. package/build/pdf.js +2050 -1087
  4. package/build/pdf.js.map +1 -1
  5. package/build/pdf.min.js +1 -1
  6. package/build/pdf.worker.js +18219 -10436
  7. package/build/pdf.worker.js.map +1 -1
  8. package/build/pdf.worker.min.js +1 -1
  9. package/es5/build/pdf.d.ts +1 -0
  10. package/es5/build/pdf.js +6623 -6654
  11. package/es5/build/pdf.js.map +1 -1
  12. package/es5/build/pdf.min.js +1 -1
  13. package/es5/build/pdf.worker.js +20815 -13888
  14. package/es5/build/pdf.worker.js.map +1 -1
  15. package/es5/build/pdf.worker.min.js +1 -1
  16. package/es5/image_decoders/pdf.image_decoders.js +3817 -4946
  17. package/es5/image_decoders/pdf.image_decoders.js.map +1 -1
  18. package/es5/image_decoders/pdf.image_decoders.min.js +1 -1
  19. package/es5/web/pdf_viewer.css +18 -15
  20. package/es5/web/pdf_viewer.js +1094 -514
  21. package/es5/web/pdf_viewer.js.map +1 -1
  22. package/image_decoders/pdf.image_decoders.js +774 -168
  23. package/image_decoders/pdf.image_decoders.js.map +1 -1
  24. package/image_decoders/pdf.image_decoders.min.js +1 -1
  25. package/lib/core/annotation.js +556 -108
  26. package/lib/core/cff_parser.js +7 -1
  27. package/lib/core/charsets.js +1 -1
  28. package/lib/core/cmap.js +20 -1
  29. package/lib/core/core_utils.js +162 -3
  30. package/lib/core/crypto.js +1 -1
  31. package/lib/core/default_appearance.js +132 -0
  32. package/lib/core/document.js +115 -9
  33. package/lib/core/encodings.js +1 -1
  34. package/lib/core/evaluator.js +168 -74
  35. package/lib/core/fonts.js +97 -11
  36. package/lib/core/function.js +5 -10
  37. package/lib/core/glyphlist.js +11 -4529
  38. package/lib/core/image_utils.js +30 -1
  39. package/lib/core/jpg.js +1 -1
  40. package/lib/core/jpx.js +5 -5
  41. package/lib/core/murmurhash3.js +1 -1
  42. package/lib/core/obj.js +123 -39
  43. package/lib/core/pattern.js +4 -4
  44. package/lib/core/primitives.js +24 -5
  45. package/lib/core/standard_fonts.js +1 -1
  46. package/lib/core/stream.js +5 -1
  47. package/lib/core/unicode.js +15 -1387
  48. package/lib/core/worker.js +58 -17
  49. package/lib/core/writer.js +68 -4
  50. package/lib/display/annotation_layer.js +712 -119
  51. package/lib/display/annotation_storage.js +21 -4
  52. package/lib/display/api.js +88 -18
  53. package/lib/display/canvas.js +414 -375
  54. package/lib/display/display_utils.js +11 -4
  55. package/lib/display/fetch_stream.js +3 -3
  56. package/lib/display/font_loader.js +2 -3
  57. package/lib/display/metadata.js +54 -20
  58. package/lib/display/node_stream.js +1 -1
  59. package/lib/display/optional_content_config.js +1 -1
  60. package/lib/display/pattern_helper.js +109 -113
  61. package/lib/display/svg.js +5 -5
  62. package/lib/display/text_layer.js +54 -54
  63. package/lib/display/transport_stream.js +4 -4
  64. package/lib/display/webgl.js +65 -68
  65. package/lib/examples/node/domstubs.js +9 -4
  66. package/lib/pdf.js +2 -2
  67. package/lib/pdf.sandbox.js +311 -0
  68. package/lib/pdf.worker.js +2 -2
  69. package/lib/shared/scripting_utils.js +84 -0
  70. package/lib/shared/util.js +129 -14
  71. package/lib/{display → shared}/xml_parser.js +112 -4
  72. package/lib/test/unit/annotation_spec.js +831 -109
  73. package/lib/test/unit/annotation_storage_spec.js +28 -10
  74. package/lib/test/unit/api_spec.js +190 -160
  75. package/lib/test/unit/bidi_spec.js +6 -6
  76. package/lib/test/unit/cff_parser_spec.js +73 -73
  77. package/lib/test/unit/clitests_helper.js +2 -0
  78. package/lib/test/unit/cmap_spec.js +48 -74
  79. package/lib/test/unit/core_utils_spec.js +34 -0
  80. package/lib/test/unit/crypto_spec.js +162 -199
  81. package/lib/test/unit/custom_spec.js +7 -18
  82. package/lib/test/unit/default_appearance_spec.js +54 -0
  83. package/lib/test/unit/display_svg_spec.js +24 -19
  84. package/lib/test/unit/display_utils_spec.js +1 -1
  85. package/lib/test/unit/document_spec.js +187 -20
  86. package/lib/test/unit/evaluator_spec.js +30 -30
  87. package/lib/test/unit/function_spec.js +165 -165
  88. package/lib/test/unit/jasmine-boot.js +52 -53
  89. package/lib/test/unit/metadata_spec.js +2 -2
  90. package/lib/test/unit/murmurhash3_spec.js +29 -16
  91. package/lib/test/unit/network_spec.js +21 -21
  92. package/lib/test/unit/pdf_find_controller_spec.js +131 -69
  93. package/lib/test/unit/pdf_find_utils_spec.js +10 -10
  94. package/lib/test/unit/scripting_spec.js +1104 -0
  95. package/lib/test/unit/stream_spec.js +8 -8
  96. package/lib/test/unit/test_utils.js +16 -19
  97. package/lib/test/unit/testreporter.js +11 -4
  98. package/lib/test/unit/type1_parser_spec.js +23 -23
  99. package/lib/test/unit/ui_utils_spec.js +78 -35
  100. package/lib/test/unit/unicode_spec.js +7 -7
  101. package/lib/test/unit/util_spec.js +26 -3
  102. package/lib/test/unit/writer_spec.js +16 -1
  103. package/lib/test/unit/xml_spec.js +117 -0
  104. package/lib/web/annotation_layer_builder.js +18 -6
  105. package/lib/web/app.js +579 -161
  106. package/lib/web/app_options.js +14 -0
  107. package/lib/web/base_tree_viewer.js +50 -0
  108. package/lib/web/base_viewer.js +350 -14
  109. package/lib/web/chromecom.js +9 -1
  110. package/lib/web/debugger.js +1 -2
  111. package/lib/web/download_manager.js +0 -15
  112. package/lib/web/firefox_print_service.js +6 -4
  113. package/lib/web/firefoxcom.js +84 -69
  114. package/lib/web/generic_scripting.js +55 -0
  115. package/lib/web/genericcom.js +9 -1
  116. package/lib/web/grab_to_pan.js +1 -1
  117. package/lib/web/interfaces.js +9 -3
  118. package/lib/web/pdf_attachment_viewer.js +1 -3
  119. package/lib/web/pdf_cursor_tools.js +20 -13
  120. package/lib/web/pdf_document_properties.js +48 -61
  121. package/lib/web/pdf_find_bar.js +1 -3
  122. package/lib/web/pdf_find_controller.js +58 -12
  123. package/lib/web/pdf_history.js +43 -21
  124. package/lib/web/pdf_layer_viewer.js +1 -9
  125. package/lib/web/pdf_link_service.js +108 -78
  126. package/lib/web/pdf_outline_viewer.js +166 -10
  127. package/lib/web/pdf_page_view.js +14 -14
  128. package/lib/web/pdf_presentation_mode.js +21 -31
  129. package/lib/web/pdf_rendering_queue.js +8 -1
  130. package/lib/web/pdf_sidebar.js +62 -107
  131. package/lib/web/pdf_sidebar_resizer.js +11 -21
  132. package/lib/web/pdf_single_page_viewer.js +8 -0
  133. package/lib/web/pdf_thumbnail_view.js +26 -26
  134. package/lib/web/pdf_thumbnail_viewer.js +13 -2
  135. package/lib/web/pdf_viewer.component.js +2 -2
  136. package/lib/web/pdf_viewer.js +3 -1
  137. package/lib/web/preferences.js +33 -44
  138. package/lib/web/text_layer_builder.js +2 -9
  139. package/lib/web/ui_utils.js +78 -46
  140. package/lib/web/viewer_compatibility.js +1 -2
  141. package/package.json +4 -1
  142. package/types/display/annotation_layer.d.ts +18 -3
  143. package/types/display/api.d.ts +110 -54
  144. package/types/display/canvas.d.ts +1 -1
  145. package/types/display/display_utils.d.ts +96 -95
  146. package/types/display/fetch_stream.d.ts +2 -2
  147. package/types/display/metadata.d.ts +4 -0
  148. package/types/display/pattern_helper.d.ts +1 -1
  149. package/types/display/text_layer.d.ts +7 -7
  150. package/types/display/transport_stream.d.ts +1 -1
  151. package/types/shared/scripting_utils.d.ts +12 -0
  152. package/types/shared/util.d.ts +281 -250
  153. package/types/shared/xml_parser.d.ts +64 -0
  154. package/web/pdf_viewer.css +18 -15
  155. package/web/pdf_viewer.js +809 -408
  156. package/web/pdf_viewer.js.map +1 -1
  157. package/webpack.js +1 -1
  158. package/types/display/xml_parser.d.ts +0 -35
@@ -32,6 +32,8 @@ var _util = require("../shared/util.js");
32
32
 
33
33
  var _annotation_storage = require("./annotation_storage.js");
34
34
 
35
+ var _scripting_utils = require("../shared/scripting_utils.js");
36
+
35
37
  class AnnotationElementFactory {
36
38
  static create(parameters) {
37
39
  const subtype = parameters.data.annotationType;
@@ -118,7 +120,11 @@ class AnnotationElementFactory {
118
120
  }
119
121
 
120
122
  class AnnotationElement {
121
- constructor(parameters, isRenderable = false, ignoreBorder = false) {
123
+ constructor(parameters, {
124
+ isRenderable = false,
125
+ ignoreBorder = false,
126
+ createQuadrilaterals = false
127
+ } = {}) {
122
128
  this.isRenderable = isRenderable;
123
129
  this.data = parameters.data;
124
130
  this.layer = parameters.layer;
@@ -130,10 +136,17 @@ class AnnotationElement {
130
136
  this.renderInteractiveForms = parameters.renderInteractiveForms;
131
137
  this.svgFactory = parameters.svgFactory;
132
138
  this.annotationStorage = parameters.annotationStorage;
139
+ this.enableScripting = parameters.enableScripting;
140
+ this.hasJSActions = parameters.hasJSActions;
141
+ this._mouseState = parameters.mouseState;
133
142
 
134
143
  if (isRenderable) {
135
144
  this.container = this._createContainer(ignoreBorder);
136
145
  }
146
+
147
+ if (createQuadrilaterals) {
148
+ this.quadrilaterals = this._createQuadrilaterals(ignoreBorder);
149
+ }
137
150
  }
138
151
 
139
152
  _createContainer(ignoreBorder = false) {
@@ -148,7 +161,7 @@ class AnnotationElement {
148
161
  const rect = _util.Util.normalizeRect([data.rect[0], page.view[3] - data.rect[1] + page.view[1], data.rect[2], page.view[3] - data.rect[3] + page.view[1]]);
149
162
 
150
163
  container.style.transform = `matrix(${viewport.transform.join(",")})`;
151
- container.style.transformOrigin = `-${rect[0]}px -${rect[1]}px`;
164
+ container.style.transformOrigin = `${-rect[0]}px ${-rect[1]}px`;
152
165
 
153
166
  if (!ignoreBorder && data.borderStyle.width > 0) {
154
167
  container.style.borderWidth = `${data.borderStyle.width}px`;
@@ -192,7 +205,7 @@ class AnnotationElement {
192
205
  }
193
206
 
194
207
  if (data.color) {
195
- container.style.borderColor = _util.Util.makeCssRgb(data.color[0] | 0, data.color[1] | 0, data.color[2] | 0);
208
+ container.style.borderColor = _util.Util.makeHexColor(data.color[0] | 0, data.color[1] | 0, data.color[2] | 0);
196
209
  } else {
197
210
  container.style.borderWidth = 0;
198
211
  }
@@ -205,7 +218,31 @@ class AnnotationElement {
205
218
  return container;
206
219
  }
207
220
 
208
- _createPopup(container, trigger, data) {
221
+ _createQuadrilaterals(ignoreBorder = false) {
222
+ if (!this.data.quadPoints) {
223
+ return null;
224
+ }
225
+
226
+ const quadrilaterals = [];
227
+ const savedRect = this.data.rect;
228
+
229
+ for (const quadPoint of this.data.quadPoints) {
230
+ this.data.rect = [quadPoint[2].x, quadPoint[2].y, quadPoint[1].x, quadPoint[1].y];
231
+ quadrilaterals.push(this._createContainer(ignoreBorder));
232
+ }
233
+
234
+ this.data.rect = savedRect;
235
+ return quadrilaterals;
236
+ }
237
+
238
+ _createPopup(trigger, data) {
239
+ let container = this.container;
240
+
241
+ if (this.quadrilaterals) {
242
+ trigger = trigger || this.quadrilaterals;
243
+ container = this.quadrilaterals[0];
244
+ }
245
+
209
246
  if (!trigger) {
210
247
  trigger = document.createElement("div");
211
248
  trigger.style.height = container.style.height;
@@ -227,6 +264,13 @@ class AnnotationElement {
227
264
  container.appendChild(popup);
228
265
  }
229
266
 
267
+ _renderQuadrilaterals(className) {
268
+ this.quadrilaterals.forEach(quadrilateral => {
269
+ quadrilateral.className = className;
270
+ });
271
+ return this.quadrilaterals;
272
+ }
273
+
230
274
  render() {
231
275
  (0, _util.unreachable)("Abstract method `AnnotationElement.render` called");
232
276
  }
@@ -235,12 +279,14 @@ class AnnotationElement {
235
279
 
236
280
  class LinkAnnotationElement extends AnnotationElement {
237
281
  constructor(parameters) {
238
- const isRenderable = !!(parameters.data.url || parameters.data.dest || parameters.data.action);
239
- super(parameters, isRenderable);
282
+ const isRenderable = !!(parameters.data.url || parameters.data.dest || parameters.data.action || parameters.data.isTooltipOnly || parameters.data.actions && (parameters.data.actions.Action || parameters.data.actions["Mouse Up"] || parameters.data.actions["Mouse Down"]));
283
+ super(parameters, {
284
+ isRenderable,
285
+ createQuadrilaterals: true
286
+ });
240
287
  }
241
288
 
242
289
  render() {
243
- this.container.className = "linkAnnotation";
244
290
  const {
245
291
  data,
246
292
  linkService
@@ -256,10 +302,23 @@ class LinkAnnotationElement extends AnnotationElement {
256
302
  });
257
303
  } else if (data.action) {
258
304
  this._bindNamedAction(link, data.action);
259
- } else {
305
+ } else if (data.dest) {
260
306
  this._bindLink(link, data.dest);
307
+ } else if (data.actions && (data.actions.Action || data.actions["Mouse Up"] || data.actions["Mouse Down"]) && this.enableScripting && this.hasJSActions) {
308
+ this._bindJSAction(link, data);
309
+ } else {
310
+ this._bindLink(link, "");
261
311
  }
262
312
 
313
+ if (this.quadrilaterals) {
314
+ return this._renderQuadrilaterals("linkAnnotation").map((quadrilateral, index) => {
315
+ const linkElement = index === 0 ? link : link.cloneNode();
316
+ quadrilateral.appendChild(linkElement);
317
+ return quadrilateral;
318
+ });
319
+ }
320
+
321
+ this.container.className = "linkAnnotation";
263
322
  this.container.appendChild(link);
264
323
  return this.container;
265
324
  }
@@ -269,13 +328,13 @@ class LinkAnnotationElement extends AnnotationElement {
269
328
 
270
329
  link.onclick = () => {
271
330
  if (destination) {
272
- this.linkService.navigateTo(destination);
331
+ this.linkService.goToDestination(destination);
273
332
  }
274
333
 
275
334
  return false;
276
335
  };
277
336
 
278
- if (destination) {
337
+ if (destination || destination === "") {
279
338
  link.className = "internalLink";
280
339
  }
281
340
  }
@@ -291,12 +350,40 @@ class LinkAnnotationElement extends AnnotationElement {
291
350
  link.className = "internalLink";
292
351
  }
293
352
 
353
+ _bindJSAction(link, data) {
354
+ link.href = this.linkService.getAnchorUrl("");
355
+ const map = new Map([["Action", "onclick"], ["Mouse Up", "onmouseup"], ["Mouse Down", "onmousedown"]]);
356
+
357
+ for (const name of Object.keys(data.actions)) {
358
+ const jsName = map.get(name);
359
+
360
+ if (!jsName) {
361
+ continue;
362
+ }
363
+
364
+ link[jsName] = () => {
365
+ this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
366
+ source: this,
367
+ detail: {
368
+ id: data.id,
369
+ name
370
+ }
371
+ });
372
+ return false;
373
+ };
374
+ }
375
+
376
+ link.className = "internalLink";
377
+ }
378
+
294
379
  }
295
380
 
296
381
  class TextAnnotationElement extends AnnotationElement {
297
382
  constructor(parameters) {
298
383
  const isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
299
- super(parameters, isRenderable);
384
+ super(parameters, {
385
+ isRenderable
386
+ });
300
387
  }
301
388
 
302
389
  render() {
@@ -312,7 +399,7 @@ class TextAnnotationElement extends AnnotationElement {
312
399
  });
313
400
 
314
401
  if (!this.data.hasPopup) {
315
- this._createPopup(this.container, image, this.data);
402
+ this._createPopup(image, this.data);
316
403
  }
317
404
 
318
405
  this.container.appendChild(image);
@@ -323,26 +410,79 @@ class TextAnnotationElement extends AnnotationElement {
323
410
 
324
411
  class WidgetAnnotationElement extends AnnotationElement {
325
412
  render() {
413
+ if (this.data.alternativeText) {
414
+ this.container.title = this.data.alternativeText;
415
+ }
416
+
326
417
  return this.container;
327
418
  }
328
419
 
420
+ _getKeyModifier(event) {
421
+ return navigator.platform.includes("Win") && event.ctrlKey || navigator.platform.includes("Mac") && event.metaKey;
422
+ }
423
+
424
+ _setEventListener(element, baseName, eventName, valueGetter) {
425
+ if (baseName.includes("mouse")) {
426
+ element.addEventListener(baseName, event => {
427
+ this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
428
+ source: this,
429
+ detail: {
430
+ id: this.data.id,
431
+ name: eventName,
432
+ value: valueGetter(event),
433
+ shift: event.shiftKey,
434
+ modifier: this._getKeyModifier(event)
435
+ }
436
+ });
437
+ });
438
+ } else {
439
+ element.addEventListener(baseName, event => {
440
+ this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
441
+ source: this,
442
+ detail: {
443
+ id: this.data.id,
444
+ name: eventName,
445
+ value: event.target.checked
446
+ }
447
+ });
448
+ });
449
+ }
450
+ }
451
+
452
+ _setEventListeners(element, names, getter) {
453
+ for (const [baseName, eventName] of names) {
454
+ if (eventName === "Action" || this.data.actions?.[eventName]) {
455
+ this._setEventListener(element, baseName, eventName, getter);
456
+ }
457
+ }
458
+ }
459
+
329
460
  }
330
461
 
331
462
  class TextWidgetAnnotationElement extends WidgetAnnotationElement {
332
463
  constructor(parameters) {
333
464
  const isRenderable = parameters.renderInteractiveForms || !parameters.data.hasAppearance && !!parameters.data.fieldValue;
334
- super(parameters, isRenderable);
465
+ super(parameters, {
466
+ isRenderable
467
+ });
335
468
  }
336
469
 
337
470
  render() {
338
- const TEXT_ALIGNMENT = ["left", "center", "right"];
339
471
  const storage = this.annotationStorage;
340
472
  const id = this.data.id;
341
473
  this.container.className = "textWidgetAnnotation";
342
474
  let element = null;
343
475
 
344
476
  if (this.renderInteractiveForms) {
345
- const textContent = storage.getOrCreateValue(id, this.data.fieldValue);
477
+ const textContent = storage.getOrCreateValue(id, {
478
+ value: this.data.fieldValue
479
+ }).value;
480
+ const elementData = {
481
+ userValue: null,
482
+ formattedValue: null,
483
+ beforeInputSelectionRange: null,
484
+ beforeInputValue: null
485
+ };
346
486
 
347
487
  if (this.data.multiLine) {
348
488
  element = document.createElement("textarea");
@@ -353,9 +493,192 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
353
493
  element.setAttribute("value", textContent);
354
494
  }
355
495
 
496
+ elementData.userValue = textContent;
497
+ element.setAttribute("id", id);
356
498
  element.addEventListener("input", function (event) {
357
- storage.setValue(id, event.target.value);
499
+ storage.setValue(id, {
500
+ value: event.target.value
501
+ });
358
502
  });
503
+
504
+ let blurListener = event => {
505
+ if (elementData.formattedValue) {
506
+ event.target.value = elementData.formattedValue;
507
+ }
508
+
509
+ event.target.setSelectionRange(0, 0);
510
+ elementData.beforeInputSelectionRange = null;
511
+ };
512
+
513
+ if (this.enableScripting && this.hasJSActions) {
514
+ element.addEventListener("focus", event => {
515
+ if (elementData.userValue) {
516
+ event.target.value = elementData.userValue;
517
+ }
518
+ });
519
+ element.addEventListener("updatefromsandbox", function (event) {
520
+ const {
521
+ detail
522
+ } = event;
523
+ const actions = {
524
+ value() {
525
+ elementData.userValue = detail.value || "";
526
+ storage.setValue(id, {
527
+ value: elementData.userValue.toString()
528
+ });
529
+
530
+ if (!elementData.formattedValue) {
531
+ event.target.value = elementData.userValue;
532
+ }
533
+ },
534
+
535
+ valueAsString() {
536
+ elementData.formattedValue = detail.valueAsString || "";
537
+
538
+ if (event.target !== document.activeElement) {
539
+ event.target.value = elementData.formattedValue;
540
+ }
541
+
542
+ storage.setValue(id, {
543
+ formattedValue: elementData.formattedValue
544
+ });
545
+ },
546
+
547
+ focus() {
548
+ setTimeout(() => event.target.focus({
549
+ preventScroll: false
550
+ }), 0);
551
+ },
552
+
553
+ userName() {
554
+ event.target.title = detail.userName;
555
+ },
556
+
557
+ hidden() {
558
+ event.target.style.visibility = detail.hidden ? "hidden" : "visible";
559
+ storage.setValue(id, {
560
+ hidden: detail.hidden
561
+ });
562
+ },
563
+
564
+ editable() {
565
+ event.target.disabled = !detail.editable;
566
+ },
567
+
568
+ selRange() {
569
+ const [selStart, selEnd] = detail.selRange;
570
+
571
+ if (selStart >= 0 && selEnd < event.target.value.length) {
572
+ event.target.setSelectionRange(selStart, selEnd);
573
+ }
574
+ },
575
+
576
+ strokeColor() {
577
+ const color = detail.strokeColor;
578
+ event.target.style.color = _scripting_utils.ColorConverters[`${color[0]}_HTML`](color.slice(1));
579
+ }
580
+
581
+ };
582
+ Object.keys(detail).filter(name => name in actions).forEach(name => actions[name]());
583
+ });
584
+
585
+ if (this.data.actions) {
586
+ element.addEventListener("keydown", event => {
587
+ elementData.beforeInputValue = event.target.value;
588
+ let commitKey = -1;
589
+
590
+ if (event.key === "Escape") {
591
+ commitKey = 0;
592
+ } else if (event.key === "Enter") {
593
+ commitKey = 2;
594
+ } else if (event.key === "Tab") {
595
+ commitKey = 3;
596
+ }
597
+
598
+ if (commitKey === -1) {
599
+ return;
600
+ }
601
+
602
+ elementData.userValue = event.target.value;
603
+ this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
604
+ source: this,
605
+ detail: {
606
+ id,
607
+ name: "Keystroke",
608
+ value: event.target.value,
609
+ willCommit: true,
610
+ commitKey,
611
+ selStart: event.target.selectionStart,
612
+ selEnd: event.target.selectionEnd
613
+ }
614
+ });
615
+ });
616
+ const _blurListener = blurListener;
617
+ blurListener = null;
618
+ element.addEventListener("blur", event => {
619
+ if (this._mouseState.isDown) {
620
+ elementData.userValue = event.target.value;
621
+ this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
622
+ source: this,
623
+ detail: {
624
+ id,
625
+ name: "Keystroke",
626
+ value: event.target.value,
627
+ willCommit: true,
628
+ commitKey: 1,
629
+ selStart: event.target.selectionStart,
630
+ selEnd: event.target.selectionEnd
631
+ }
632
+ });
633
+ }
634
+
635
+ _blurListener(event);
636
+ });
637
+ element.addEventListener("mousedown", event => {
638
+ elementData.beforeInputValue = event.target.value;
639
+ elementData.beforeInputSelectionRange = null;
640
+ });
641
+ element.addEventListener("keyup", event => {
642
+ if (event.target.selectionStart === event.target.selectionEnd) {
643
+ elementData.beforeInputSelectionRange = null;
644
+ }
645
+ });
646
+ element.addEventListener("select", event => {
647
+ elementData.beforeInputSelectionRange = [event.target.selectionStart, event.target.selectionEnd];
648
+ });
649
+
650
+ if ("Keystroke" in this.data.actions) {
651
+ element.addEventListener("input", event => {
652
+ let selStart = -1;
653
+ let selEnd = -1;
654
+
655
+ if (elementData.beforeInputSelectionRange) {
656
+ [selStart, selEnd] = elementData.beforeInputSelectionRange;
657
+ }
658
+
659
+ this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
660
+ source: this,
661
+ detail: {
662
+ id,
663
+ name: "Keystroke",
664
+ value: elementData.beforeInputValue,
665
+ change: event.data,
666
+ willCommit: false,
667
+ selStart,
668
+ selEnd
669
+ }
670
+ });
671
+ });
672
+ }
673
+
674
+ this._setEventListeners(element, [["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.value);
675
+ }
676
+ }
677
+
678
+ if (blurListener) {
679
+ element.addEventListener("blur", blurListener);
680
+ }
681
+
359
682
  element.disabled = this.data.readOnly;
360
683
  element.name = this.data.fieldName;
361
684
 
@@ -374,59 +697,49 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
374
697
  element.textContent = this.data.fieldValue;
375
698
  element.style.verticalAlign = "middle";
376
699
  element.style.display = "table-cell";
377
- let font = null;
378
-
379
- if (this.data.fontRefName && this.page.commonObjs.has(this.data.fontRefName)) {
380
- font = this.page.commonObjs.get(this.data.fontRefName);
381
- }
382
-
383
- this._setTextStyle(element, font);
384
700
  }
385
701
 
386
- if (this.data.textAlignment !== null) {
387
- element.style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment];
388
- }
702
+ this._setTextStyle(element);
389
703
 
390
704
  this.container.appendChild(element);
391
705
  return this.container;
392
706
  }
393
707
 
394
- _setTextStyle(element, font) {
708
+ _setTextStyle(element) {
709
+ const TEXT_ALIGNMENT = ["left", "center", "right"];
710
+ const {
711
+ fontSize,
712
+ fontColor
713
+ } = this.data.defaultAppearanceData;
395
714
  const style = element.style;
396
- style.fontSize = `${this.data.fontSize}px`;
397
- style.direction = this.data.fontDirection < 0 ? "rtl" : "ltr";
398
715
 
399
- if (!font) {
400
- return;
716
+ if (fontSize) {
717
+ style.fontSize = `${fontSize}px`;
401
718
  }
402
719
 
403
- let bold = "normal";
720
+ style.color = _util.Util.makeHexColor(fontColor[0], fontColor[1], fontColor[2]);
404
721
 
405
- if (font.black) {
406
- bold = "900";
407
- } else if (font.bold) {
408
- bold = "bold";
722
+ if (this.data.textAlignment !== null) {
723
+ style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment];
409
724
  }
410
-
411
- style.fontWeight = bold;
412
- style.fontStyle = font.italic ? "italic" : "normal";
413
- const fontFamily = font.loadedName ? `"${font.loadedName}", ` : "";
414
- const fallbackName = font.fallbackName || "Helvetica, sans-serif";
415
- style.fontFamily = fontFamily + fallbackName;
416
725
  }
417
726
 
418
727
  }
419
728
 
420
729
  class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
421
730
  constructor(parameters) {
422
- super(parameters, parameters.renderInteractiveForms);
731
+ super(parameters, {
732
+ isRenderable: parameters.renderInteractiveForms
733
+ });
423
734
  }
424
735
 
425
736
  render() {
426
737
  const storage = this.annotationStorage;
427
738
  const data = this.data;
428
739
  const id = data.id;
429
- const value = storage.getOrCreateValue(id, data.fieldValue && data.fieldValue !== "Off");
740
+ const value = storage.getOrCreateValue(id, {
741
+ value: data.fieldValue && data.fieldValue !== "Off"
742
+ }).value;
430
743
  this.container.className = "buttonWidgetAnnotation checkBox";
431
744
  const element = document.createElement("input");
432
745
  element.disabled = data.readOnly;
@@ -437,9 +750,61 @@ class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
437
750
  element.setAttribute("checked", true);
438
751
  }
439
752
 
753
+ element.setAttribute("id", id);
440
754
  element.addEventListener("change", function (event) {
441
- storage.setValue(id, event.target.checked);
755
+ const name = event.target.name;
756
+
757
+ for (const checkbox of document.getElementsByName(name)) {
758
+ if (checkbox !== event.target) {
759
+ checkbox.checked = false;
760
+ storage.setValue(checkbox.parentNode.getAttribute("data-annotation-id"), {
761
+ value: false
762
+ });
763
+ }
764
+ }
765
+
766
+ storage.setValue(id, {
767
+ value: event.target.checked
768
+ });
442
769
  });
770
+
771
+ if (this.enableScripting && this.hasJSActions) {
772
+ element.addEventListener("updatefromsandbox", event => {
773
+ const {
774
+ detail
775
+ } = event;
776
+ const actions = {
777
+ value() {
778
+ event.target.checked = detail.value !== "Off";
779
+ storage.setValue(id, {
780
+ value: event.target.checked
781
+ });
782
+ },
783
+
784
+ focus() {
785
+ setTimeout(() => event.target.focus({
786
+ preventScroll: false
787
+ }), 0);
788
+ },
789
+
790
+ hidden() {
791
+ event.target.style.visibility = detail.hidden ? "hidden" : "visible";
792
+ storage.setValue(id, {
793
+ hidden: detail.hidden
794
+ });
795
+ },
796
+
797
+ editable() {
798
+ event.target.disabled = !detail.editable;
799
+ }
800
+
801
+ };
802
+ Object.keys(detail).filter(name => name in actions).forEach(name => actions[name]());
803
+ });
804
+
805
+ this._setEventListeners(element, [["change", "Validate"], ["change", "Action"], ["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.checked);
806
+ }
807
+
443
808
  this.container.appendChild(element);
444
809
  return this.container;
445
810
  }
@@ -448,7 +813,9 @@ class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
448
813
 
449
814
  class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
450
815
  constructor(parameters) {
451
- super(parameters, parameters.renderInteractiveForms);
816
+ super(parameters, {
817
+ isRenderable: parameters.renderInteractiveForms
818
+ });
452
819
  }
453
820
 
454
821
  render() {
@@ -456,7 +823,9 @@ class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
456
823
  const storage = this.annotationStorage;
457
824
  const data = this.data;
458
825
  const id = data.id;
459
- const value = storage.getOrCreateValue(id, data.fieldValue === data.buttonValue);
826
+ const value = storage.getOrCreateValue(id, {
827
+ value: data.fieldValue === data.buttonValue
828
+ }).value;
460
829
  const element = document.createElement("input");
461
830
  element.disabled = data.readOnly;
462
831
  element.type = "radio";
@@ -466,17 +835,75 @@ class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
466
835
  element.setAttribute("checked", true);
467
836
  }
468
837
 
838
+ element.setAttribute("pdfButtonValue", data.buttonValue);
839
+ element.setAttribute("id", id);
469
840
  element.addEventListener("change", function (event) {
470
- const name = event.target.name;
471
-
472
- for (const radio of document.getElementsByName(name)) {
473
- if (radio !== event.target) {
474
- storage.setValue(radio.parentNode.getAttribute("data-annotation-id"), false);
841
+ const {
842
+ target
843
+ } = event;
844
+
845
+ for (const radio of document.getElementsByName(target.name)) {
846
+ if (radio !== target) {
847
+ storage.setValue(radio.getAttribute("id"), {
848
+ value: false
849
+ });
475
850
  }
476
851
  }
477
852
 
478
- storage.setValue(id, event.target.checked);
853
+ storage.setValue(id, {
854
+ value: target.checked
855
+ });
479
856
  });
857
+
858
+ if (this.enableScripting && this.hasJSActions) {
859
+ element.addEventListener("updatefromsandbox", event => {
860
+ const {
861
+ detail
862
+ } = event;
863
+ const actions = {
864
+ value() {
865
+ const fieldValue = detail.value;
866
+
867
+ for (const radio of document.getElementsByName(event.target.name)) {
868
+ const radioId = radio.getAttribute("id");
869
+
870
+ if (fieldValue === radio.getAttribute("pdfButtonValue")) {
871
+ radio.setAttribute("checked", true);
872
+ storage.setValue(radioId, {
873
+ value: true
874
+ });
875
+ } else {
876
+ storage.setValue(radioId, {
877
+ value: false
878
+ });
879
+ }
880
+ }
881
+ },
882
+
883
+ focus() {
884
+ setTimeout(() => event.target.focus({
885
+ preventScroll: false
886
+ }), 0);
887
+ },
888
+
889
+ hidden() {
890
+ event.target.style.visibility = detail.hidden ? "hidden" : "visible";
891
+ storage.setValue(id, {
892
+ hidden: detail.hidden
893
+ });
894
+ },
895
+
896
+ editable() {
897
+ event.target.disabled = !detail.editable;
898
+ }
899
+
900
+ };
901
+ Object.keys(detail).filter(name => name in actions).forEach(name => actions[name]());
902
+ });
903
+
904
+ this._setEventListeners(element, [["change", "Validate"], ["change", "Action"], ["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.checked);
905
+ }
906
+
480
907
  this.container.appendChild(element);
481
908
  return this.container;
482
909
  }
@@ -487,6 +914,11 @@ class PushButtonWidgetAnnotationElement extends LinkAnnotationElement {
487
914
  render() {
488
915
  const container = super.render();
489
916
  container.className = "buttonWidgetAnnotation pushButton";
917
+
918
+ if (this.data.alternativeText) {
919
+ container.title = this.data.alternativeText;
920
+ }
921
+
490
922
  return container;
491
923
  }
492
924
 
@@ -494,17 +926,22 @@ class PushButtonWidgetAnnotationElement extends LinkAnnotationElement {
494
926
 
495
927
  class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
496
928
  constructor(parameters) {
497
- super(parameters, parameters.renderInteractiveForms);
929
+ super(parameters, {
930
+ isRenderable: parameters.renderInteractiveForms
931
+ });
498
932
  }
499
933
 
500
934
  render() {
501
935
  this.container.className = "choiceWidgetAnnotation";
502
936
  const storage = this.annotationStorage;
503
937
  const id = this.data.id;
504
- storage.getOrCreateValue(id, this.data.fieldValue.length > 0 ? this.data.fieldValue[0] : null);
938
+ storage.getOrCreateValue(id, {
939
+ value: this.data.fieldValue.length > 0 ? this.data.fieldValue[0] : undefined
940
+ });
505
941
  const selectElement = document.createElement("select");
506
942
  selectElement.disabled = this.data.readOnly;
507
943
  selectElement.name = this.data.fieldName;
944
+ selectElement.setAttribute("id", id);
508
945
 
509
946
  if (!this.data.combo) {
510
947
  selectElement.size = this.data.options.length;
@@ -526,11 +963,77 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
526
963
  selectElement.appendChild(optionElement);
527
964
  }
528
965
 
529
- selectElement.addEventListener("input", function (event) {
966
+ function getValue(event) {
530
967
  const options = event.target.options;
531
- const value = options[options.selectedIndex].value;
532
- storage.setValue(id, value);
533
- });
968
+ return options[options.selectedIndex].value;
969
+ }
970
+
971
+ if (this.enableScripting && this.hasJSActions) {
972
+ selectElement.addEventListener("updatefromsandbox", event => {
973
+ const {
974
+ detail
975
+ } = event;
976
+ const actions = {
977
+ value() {
978
+ const options = event.target.options;
979
+ const value = detail.value;
980
+ const i = options.indexOf(value);
981
+
982
+ if (i !== -1) {
983
+ options.selectedIndex = i;
984
+ storage.setValue(id, {
985
+ value
986
+ });
987
+ }
988
+ },
989
+
990
+ focus() {
991
+ setTimeout(() => event.target.focus({
992
+ preventScroll: false
993
+ }), 0);
994
+ },
995
+
996
+ hidden() {
997
+ event.target.style.visibility = detail.hidden ? "hidden" : "visible";
998
+ storage.setValue(id, {
999
+ hidden: detail.hidden
1000
+ });
1001
+ },
1002
+
1003
+ editable() {
1004
+ event.target.disabled = !detail.editable;
1005
+ }
1006
+
1007
+ };
1008
+ Object.keys(detail).filter(name => name in actions).forEach(name => actions[name]());
1009
+ });
1010
+ selectElement.addEventListener("input", event => {
1011
+ const value = getValue(event);
1012
+ storage.setValue(id, {
1013
+ value
1014
+ });
1015
+ this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
1016
+ source: this,
1017
+ detail: {
1018
+ id,
1019
+ name: "Keystroke",
1020
+ changeEx: value,
1021
+ willCommit: true,
1022
+ commitKey: 1,
1023
+ keyDown: false
1024
+ }
1025
+ });
1026
+ });
1027
+
1028
+ this._setEventListeners(selectElement, [["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.checked);
1029
+ } else {
1030
+ selectElement.addEventListener("input", function (event) {
1031
+ storage.setValue(id, {
1032
+ value: getValue(event)
1033
+ });
1034
+ });
1035
+ }
1036
+
534
1037
  this.container.appendChild(selectElement);
535
1038
  return this.container;
536
1039
  }
@@ -540,7 +1043,9 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
540
1043
  class PopupAnnotationElement extends AnnotationElement {
541
1044
  constructor(parameters) {
542
1045
  const isRenderable = !!(parameters.data.title || parameters.data.contents);
543
- super(parameters, isRenderable);
1046
+ super(parameters, {
1047
+ isRenderable
1048
+ });
544
1049
  }
545
1050
 
546
1051
  render() {
@@ -552,24 +1057,29 @@ class PopupAnnotationElement extends AnnotationElement {
552
1057
  }
553
1058
 
554
1059
  const selector = `[data-annotation-id="${this.data.parentId}"]`;
555
- const parentElement = this.layer.querySelector(selector);
1060
+ const parentElements = this.layer.querySelectorAll(selector);
556
1061
 
557
- if (!parentElement) {
1062
+ if (parentElements.length === 0) {
558
1063
  return this.container;
559
1064
  }
560
1065
 
561
1066
  const popup = new PopupElement({
562
1067
  container: this.container,
563
- trigger: parentElement,
1068
+ trigger: Array.from(parentElements),
564
1069
  color: this.data.color,
565
1070
  title: this.data.title,
566
1071
  modificationDate: this.data.modificationDate,
567
1072
  contents: this.data.contents
568
1073
  });
569
- const parentLeft = parseFloat(parentElement.style.left);
570
- const parentWidth = parseFloat(parentElement.style.width);
571
- this.container.style.transformOrigin = `-${parentLeft + parentWidth}px -${parentElement.style.top}`;
572
- this.container.style.left = `${parentLeft + parentWidth}px`;
1074
+ const page = this.page;
1075
+
1076
+ const rect = _util.Util.normalizeRect([this.data.parentRect[0], page.view[3] - this.data.parentRect[1] + page.view[1], this.data.parentRect[2], page.view[3] - this.data.parentRect[3] + page.view[1]]);
1077
+
1078
+ const popupLeft = rect[0] + this.data.parentRect[2] - this.data.parentRect[0];
1079
+ const popupTop = rect[1];
1080
+ this.container.style.transformOrigin = `${-popupLeft}px ${-popupTop}px`;
1081
+ this.container.style.left = `${popupLeft}px`;
1082
+ this.container.style.top = `${popupTop}px`;
573
1083
  this.container.appendChild(popup.render());
574
1084
  return this.container;
575
1085
  }
@@ -602,7 +1112,7 @@ class PopupElement {
602
1112
  const r = BACKGROUND_ENLIGHT * (255 - color[0]) + color[0];
603
1113
  const g = BACKGROUND_ENLIGHT * (255 - color[1]) + color[1];
604
1114
  const b = BACKGROUND_ENLIGHT * (255 - color[2]) + color[2];
605
- popup.style.backgroundColor = _util.Util.makeCssRgb(r | 0, g | 0, b | 0);
1115
+ popup.style.backgroundColor = _util.Util.makeHexColor(r | 0, g | 0, b | 0);
606
1116
  }
607
1117
 
608
1118
  const title = document.createElement("h1");
@@ -625,9 +1135,16 @@ class PopupElement {
625
1135
  const contents = this._formatContents(this.contents);
626
1136
 
627
1137
  popup.appendChild(contents);
628
- this.trigger.addEventListener("click", this._toggle.bind(this));
629
- this.trigger.addEventListener("mouseover", this._show.bind(this, false));
630
- this.trigger.addEventListener("mouseout", this._hide.bind(this, false));
1138
+
1139
+ if (!Array.isArray(this.trigger)) {
1140
+ this.trigger = [this.trigger];
1141
+ }
1142
+
1143
+ this.trigger.forEach(element => {
1144
+ element.addEventListener("click", this._toggle.bind(this));
1145
+ element.addEventListener("mouseover", this._show.bind(this, false));
1146
+ element.addEventListener("mouseout", this._hide.bind(this, false));
1147
+ });
631
1148
  popup.addEventListener("click", this._hide.bind(this, true));
632
1149
  wrapper.appendChild(popup);
633
1150
  return wrapper;
@@ -684,14 +1201,17 @@ class PopupElement {
684
1201
  class FreeTextAnnotationElement extends AnnotationElement {
685
1202
  constructor(parameters) {
686
1203
  const isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
687
- super(parameters, isRenderable, true);
1204
+ super(parameters, {
1205
+ isRenderable,
1206
+ ignoreBorder: true
1207
+ });
688
1208
  }
689
1209
 
690
1210
  render() {
691
1211
  this.container.className = "freeTextAnnotation";
692
1212
 
693
1213
  if (!this.data.hasPopup) {
694
- this._createPopup(this.container, null, this.data);
1214
+ this._createPopup(null, this.data);
695
1215
  }
696
1216
 
697
1217
  return this.container;
@@ -702,7 +1222,10 @@ class FreeTextAnnotationElement extends AnnotationElement {
702
1222
  class LineAnnotationElement extends AnnotationElement {
703
1223
  constructor(parameters) {
704
1224
  const isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
705
- super(parameters, isRenderable, true);
1225
+ super(parameters, {
1226
+ isRenderable,
1227
+ ignoreBorder: true
1228
+ });
706
1229
  }
707
1230
 
708
1231
  render() {
@@ -721,7 +1244,7 @@ class LineAnnotationElement extends AnnotationElement {
721
1244
  svg.appendChild(line);
722
1245
  this.container.append(svg);
723
1246
 
724
- this._createPopup(this.container, line, data);
1247
+ this._createPopup(line, data);
725
1248
 
726
1249
  return this.container;
727
1250
  }
@@ -731,7 +1254,10 @@ class LineAnnotationElement extends AnnotationElement {
731
1254
  class SquareAnnotationElement extends AnnotationElement {
732
1255
  constructor(parameters) {
733
1256
  const isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
734
- super(parameters, isRenderable, true);
1257
+ super(parameters, {
1258
+ isRenderable,
1259
+ ignoreBorder: true
1260
+ });
735
1261
  }
736
1262
 
737
1263
  render() {
@@ -752,7 +1278,7 @@ class SquareAnnotationElement extends AnnotationElement {
752
1278
  svg.appendChild(square);
753
1279
  this.container.append(svg);
754
1280
 
755
- this._createPopup(this.container, square, data);
1281
+ this._createPopup(square, data);
756
1282
 
757
1283
  return this.container;
758
1284
  }
@@ -762,7 +1288,10 @@ class SquareAnnotationElement extends AnnotationElement {
762
1288
  class CircleAnnotationElement extends AnnotationElement {
763
1289
  constructor(parameters) {
764
1290
  const isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
765
- super(parameters, isRenderable, true);
1291
+ super(parameters, {
1292
+ isRenderable,
1293
+ ignoreBorder: true
1294
+ });
766
1295
  }
767
1296
 
768
1297
  render() {
@@ -783,7 +1312,7 @@ class CircleAnnotationElement extends AnnotationElement {
783
1312
  svg.appendChild(circle);
784
1313
  this.container.append(svg);
785
1314
 
786
- this._createPopup(this.container, circle, data);
1315
+ this._createPopup(circle, data);
787
1316
 
788
1317
  return this.container;
789
1318
  }
@@ -793,7 +1322,10 @@ class CircleAnnotationElement extends AnnotationElement {
793
1322
  class PolylineAnnotationElement extends AnnotationElement {
794
1323
  constructor(parameters) {
795
1324
  const isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
796
- super(parameters, isRenderable, true);
1325
+ super(parameters, {
1326
+ isRenderable,
1327
+ ignoreBorder: true
1328
+ });
797
1329
  this.containerClassName = "polylineAnnotation";
798
1330
  this.svgElementName = "svg:polyline";
799
1331
  }
@@ -821,7 +1353,7 @@ class PolylineAnnotationElement extends AnnotationElement {
821
1353
  svg.appendChild(polyline);
822
1354
  this.container.append(svg);
823
1355
 
824
- this._createPopup(this.container, polyline, data);
1356
+ this._createPopup(polyline, data);
825
1357
 
826
1358
  return this.container;
827
1359
  }
@@ -840,14 +1372,17 @@ class PolygonAnnotationElement extends PolylineAnnotationElement {
840
1372
  class CaretAnnotationElement extends AnnotationElement {
841
1373
  constructor(parameters) {
842
1374
  const isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
843
- super(parameters, isRenderable, true);
1375
+ super(parameters, {
1376
+ isRenderable,
1377
+ ignoreBorder: true
1378
+ });
844
1379
  }
845
1380
 
846
1381
  render() {
847
1382
  this.container.className = "caretAnnotation";
848
1383
 
849
1384
  if (!this.data.hasPopup) {
850
- this._createPopup(this.container, null, this.data);
1385
+ this._createPopup(null, this.data);
851
1386
  }
852
1387
 
853
1388
  return this.container;
@@ -858,7 +1393,10 @@ class CaretAnnotationElement extends AnnotationElement {
858
1393
  class InkAnnotationElement extends AnnotationElement {
859
1394
  constructor(parameters) {
860
1395
  const isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
861
- super(parameters, isRenderable, true);
1396
+ super(parameters, {
1397
+ isRenderable,
1398
+ ignoreBorder: true
1399
+ });
862
1400
  this.containerClassName = "inkAnnotation";
863
1401
  this.svgElementName = "svg:polyline";
864
1402
  }
@@ -886,7 +1424,7 @@ class InkAnnotationElement extends AnnotationElement {
886
1424
  polyline.setAttribute("stroke", "transparent");
887
1425
  polyline.setAttribute("fill", "none");
888
1426
 
889
- this._createPopup(this.container, polyline, data);
1427
+ this._createPopup(polyline, data);
890
1428
 
891
1429
  svg.appendChild(polyline);
892
1430
  }
@@ -900,16 +1438,23 @@ class InkAnnotationElement extends AnnotationElement {
900
1438
  class HighlightAnnotationElement extends AnnotationElement {
901
1439
  constructor(parameters) {
902
1440
  const isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
903
- super(parameters, isRenderable, true);
1441
+ super(parameters, {
1442
+ isRenderable,
1443
+ ignoreBorder: true,
1444
+ createQuadrilaterals: true
1445
+ });
904
1446
  }
905
1447
 
906
1448
  render() {
907
- this.container.className = "highlightAnnotation";
908
-
909
1449
  if (!this.data.hasPopup) {
910
- this._createPopup(this.container, null, this.data);
1450
+ this._createPopup(null, this.data);
1451
+ }
1452
+
1453
+ if (this.quadrilaterals) {
1454
+ return this._renderQuadrilaterals("highlightAnnotation");
911
1455
  }
912
1456
 
1457
+ this.container.className = "highlightAnnotation";
913
1458
  return this.container;
914
1459
  }
915
1460
 
@@ -918,16 +1463,23 @@ class HighlightAnnotationElement extends AnnotationElement {
918
1463
  class UnderlineAnnotationElement extends AnnotationElement {
919
1464
  constructor(parameters) {
920
1465
  const isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
921
- super(parameters, isRenderable, true);
1466
+ super(parameters, {
1467
+ isRenderable,
1468
+ ignoreBorder: true,
1469
+ createQuadrilaterals: true
1470
+ });
922
1471
  }
923
1472
 
924
1473
  render() {
925
- this.container.className = "underlineAnnotation";
926
-
927
1474
  if (!this.data.hasPopup) {
928
- this._createPopup(this.container, null, this.data);
1475
+ this._createPopup(null, this.data);
929
1476
  }
930
1477
 
1478
+ if (this.quadrilaterals) {
1479
+ return this._renderQuadrilaterals("underlineAnnotation");
1480
+ }
1481
+
1482
+ this.container.className = "underlineAnnotation";
931
1483
  return this.container;
932
1484
  }
933
1485
 
@@ -936,16 +1488,23 @@ class UnderlineAnnotationElement extends AnnotationElement {
936
1488
  class SquigglyAnnotationElement extends AnnotationElement {
937
1489
  constructor(parameters) {
938
1490
  const isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
939
- super(parameters, isRenderable, true);
1491
+ super(parameters, {
1492
+ isRenderable,
1493
+ ignoreBorder: true,
1494
+ createQuadrilaterals: true
1495
+ });
940
1496
  }
941
1497
 
942
1498
  render() {
943
- this.container.className = "squigglyAnnotation";
944
-
945
1499
  if (!this.data.hasPopup) {
946
- this._createPopup(this.container, null, this.data);
1500
+ this._createPopup(null, this.data);
1501
+ }
1502
+
1503
+ if (this.quadrilaterals) {
1504
+ return this._renderQuadrilaterals("squigglyAnnotation");
947
1505
  }
948
1506
 
1507
+ this.container.className = "squigglyAnnotation";
949
1508
  return this.container;
950
1509
  }
951
1510
 
@@ -954,16 +1513,23 @@ class SquigglyAnnotationElement extends AnnotationElement {
954
1513
  class StrikeOutAnnotationElement extends AnnotationElement {
955
1514
  constructor(parameters) {
956
1515
  const isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
957
- super(parameters, isRenderable, true);
1516
+ super(parameters, {
1517
+ isRenderable,
1518
+ ignoreBorder: true,
1519
+ createQuadrilaterals: true
1520
+ });
958
1521
  }
959
1522
 
960
1523
  render() {
961
- this.container.className = "strikeoutAnnotation";
962
-
963
1524
  if (!this.data.hasPopup) {
964
- this._createPopup(this.container, null, this.data);
1525
+ this._createPopup(null, this.data);
1526
+ }
1527
+
1528
+ if (this.quadrilaterals) {
1529
+ return this._renderQuadrilaterals("strikeoutAnnotation");
965
1530
  }
966
1531
 
1532
+ this.container.className = "strikeoutAnnotation";
967
1533
  return this.container;
968
1534
  }
969
1535
 
@@ -972,14 +1538,17 @@ class StrikeOutAnnotationElement extends AnnotationElement {
972
1538
  class StampAnnotationElement extends AnnotationElement {
973
1539
  constructor(parameters) {
974
1540
  const isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
975
- super(parameters, isRenderable, true);
1541
+ super(parameters, {
1542
+ isRenderable,
1543
+ ignoreBorder: true
1544
+ });
976
1545
  }
977
1546
 
978
1547
  render() {
979
1548
  this.container.className = "stampAnnotation";
980
1549
 
981
1550
  if (!this.data.hasPopup) {
982
- this._createPopup(this.container, null, this.data);
1551
+ this._createPopup(null, this.data);
983
1552
  }
984
1553
 
985
1554
  return this.container;
@@ -989,22 +1558,21 @@ class StampAnnotationElement extends AnnotationElement {
989
1558
 
990
1559
  class FileAttachmentAnnotationElement extends AnnotationElement {
991
1560
  constructor(parameters) {
992
- super(parameters, true);
1561
+ super(parameters, {
1562
+ isRenderable: true
1563
+ });
993
1564
  const {
994
1565
  filename,
995
1566
  content
996
1567
  } = this.data.file;
997
1568
  this.filename = (0, _display_utils.getFilenameFromUrl)(filename);
998
1569
  this.content = content;
999
-
1000
- if (this.linkService.eventBus) {
1001
- this.linkService.eventBus.dispatch("fileattachmentannotation", {
1002
- source: this,
1003
- id: (0, _util.stringToPDFString)(filename),
1004
- filename,
1005
- content
1006
- });
1007
- }
1570
+ this.linkService.eventBus?.dispatch("fileattachmentannotation", {
1571
+ source: this,
1572
+ id: (0, _util.stringToPDFString)(filename),
1573
+ filename,
1574
+ content
1575
+ });
1008
1576
  }
1009
1577
 
1010
1578
  render() {
@@ -1015,7 +1583,7 @@ class FileAttachmentAnnotationElement extends AnnotationElement {
1015
1583
  trigger.addEventListener("dblclick", this._download.bind(this));
1016
1584
 
1017
1585
  if (!this.data.hasPopup && (this.data.title || this.data.contents)) {
1018
- this._createPopup(this.container, trigger, this.data);
1586
+ this._createPopup(trigger, this.data);
1019
1587
  }
1020
1588
 
1021
1589
  this.container.appendChild(trigger);
@@ -1066,21 +1634,46 @@ class AnnotationLayer {
1066
1634
  imageResourcesPath: parameters.imageResourcesPath || "",
1067
1635
  renderInteractiveForms: typeof parameters.renderInteractiveForms === "boolean" ? parameters.renderInteractiveForms : true,
1068
1636
  svgFactory: new _display_utils.DOMSVGFactory(),
1069
- annotationStorage: parameters.annotationStorage || new _annotation_storage.AnnotationStorage()
1637
+ annotationStorage: parameters.annotationStorage || new _annotation_storage.AnnotationStorage(),
1638
+ enableScripting: parameters.enableScripting,
1639
+ hasJSActions: parameters.hasJSActions,
1640
+ mouseState: parameters.mouseState || {
1641
+ isDown: false
1642
+ }
1070
1643
  });
1071
1644
 
1072
1645
  if (element.isRenderable) {
1073
- parameters.div.appendChild(element.render());
1646
+ const rendered = element.render();
1647
+
1648
+ if (data.hidden) {
1649
+ rendered.style.visibility = "hidden";
1650
+ }
1651
+
1652
+ if (Array.isArray(rendered)) {
1653
+ for (const renderedElement of rendered) {
1654
+ parameters.div.appendChild(renderedElement);
1655
+ }
1656
+ } else {
1657
+ if (element instanceof PopupAnnotationElement) {
1658
+ parameters.div.prepend(rendered);
1659
+ } else {
1660
+ parameters.div.appendChild(rendered);
1661
+ }
1662
+ }
1074
1663
  }
1075
1664
  }
1076
1665
  }
1077
1666
 
1078
1667
  static update(parameters) {
1668
+ const transform = `matrix(${parameters.viewport.transform.join(",")})`;
1669
+
1079
1670
  for (const data of parameters.annotations) {
1080
- const element = parameters.div.querySelector(`[data-annotation-id="${data.id}"]`);
1671
+ const elements = parameters.div.querySelectorAll(`[data-annotation-id="${data.id}"]`);
1081
1672
 
1082
- if (element) {
1083
- element.style.transform = `matrix(${parameters.viewport.transform.join(",")})`;
1673
+ if (elements) {
1674
+ elements.forEach(element => {
1675
+ element.style.transform = transform;
1676
+ });
1084
1677
  }
1085
1678
  }
1086
1679