kviewer 0.3.1 → 0.3.2

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 (37) hide show
  1. package/dist/module.d.mts +1 -1
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +4 -0
  4. package/dist/runtime/annotation/engine/editor/editor.js +10 -12
  5. package/dist/runtime/annotation/engine/editor/selector.js +3 -1
  6. package/dist/runtime/annotation/engine/tools/arrow.js +24 -14
  7. package/dist/runtime/annotation/engine/tools/circle.js +24 -13
  8. package/dist/runtime/annotation/engine/tools/cloud.js +27 -18
  9. package/dist/runtime/annotation/engine/tools/free-highlight.js +24 -15
  10. package/dist/runtime/annotation/engine/tools/freehand.js +21 -12
  11. package/dist/runtime/annotation/engine/tools/highlight.d.ts +2 -0
  12. package/dist/runtime/annotation/engine/tools/highlight.js +20 -10
  13. package/dist/runtime/annotation/engine/tools/note.js +3 -1
  14. package/dist/runtime/annotation/engine/tools/rectangle.js +19 -8
  15. package/dist/runtime/annotation/engine/tools/signature.js +2 -1
  16. package/dist/runtime/annotation/engine/tools/stamp.js +2 -1
  17. package/dist/runtime/annotation/engine/utils.js +2 -1
  18. package/dist/runtime/annotation/pdf-export/download.js +1 -1
  19. package/dist/runtime/annotation/pdf-export/export.js +1 -1
  20. package/dist/runtime/annotation/pdf-export/parse_polyline.js +5 -1
  21. package/dist/runtime/annotation/pdf-export/parse_stamp.js +4 -4
  22. package/dist/runtime/annotation/pdf-export/unicode-font.js +1 -4
  23. package/dist/runtime/annotation/pdf-import/decode_stamp.js +3 -2
  24. package/dist/runtime/annotation/pdf-import/extract_stamp_appearance.js +1 -1
  25. package/dist/runtime/annotation/pdf-import/utils.js +1 -1
  26. package/dist/runtime/components/FormFieldLayer.d.vue.ts +1 -1
  27. package/dist/runtime/components/FormFieldLayer.vue.d.ts +1 -1
  28. package/dist/runtime/components/PdfPage.vue +3 -3
  29. package/dist/runtime/components/Viewer.vue +3 -1
  30. package/dist/runtime/components/ViewerTabs.vue +1 -1
  31. package/dist/runtime/components/panels/SignaturePicker.vue +8 -2
  32. package/dist/runtime/composables/useSearchIndex.js +1 -1
  33. package/dist/runtime/embed/bridge-host.d.ts +1 -1
  34. package/dist/runtime/embed/bridge-host.js +3 -3
  35. package/dist/runtime/imports.d.ts +19 -0
  36. package/dist/types.d.mts +1 -1
  37. package/package.json +2 -2
package/dist/module.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
- export { ActiveTool, AddFormFieldPayload, CheckboxStyle, ExportPdfOptions, FormFieldDefinition, FormFieldOrigin, FormFieldType, FormFieldValue, KVIEWER_EMBED_PROTOCOL_VERSION, KViewerApi, KViewerEmbedBridgeOptions, KViewerEmbedClient, KViewerEmbedClientOptions, KViewerEmbedEventName, KViewerEmbedEventPayloads, KViewerEmbedMethodName, SignatureData, SignatureHandlers, ViewMode, ViewerBottomToolId, ViewerLayoutToolId, ViewerMenuButtonItem, ViewerMenuCheckboxItem, ViewerMenuItem, ViewerMenuSeparatorItem, ViewerState, ViewerToolEntry, ViewerToolId, ViewerToolSlot, ViewerTopToolId, useKViewerEmbedBridge } from '../dist/runtime/public-types.js';
2
+ export { ActiveTool, AddFormFieldPayload, CheckboxStyle, ExportPdfOptions, FormFieldDefinition, FormFieldOrigin, FormFieldType, FormFieldValue, KVIEWER_EMBED_PROTOCOL_VERSION, KViewerApi, KViewerEmbedBridgeOptions, KViewerEmbedClient, KViewerEmbedClientOptions, KViewerEmbedEventName, KViewerEmbedEventPayloads, KViewerEmbedMethodName, PlacedFieldDefaults, SignatureData, SignatureFieldStatus, SignatureHandlers, ViewMode, ViewerBottomToolId, ViewerLayoutToolId, ViewerMenuButtonItem, ViewerMenuCheckboxItem, ViewerMenuItem, ViewerMenuSeparatorItem, ViewerState, ViewerToolEntry, ViewerToolId, ViewerToolSlot, ViewerTopToolId, useKViewerEmbedBridge } from '../dist/runtime/public-types.js';
3
3
 
4
4
  interface ModuleOptions {
5
5
  /**
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kviewer",
3
3
  "configKey": "kviewer",
4
- "version": "0.3.1",
4
+ "version": "0.3.2",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -56,6 +56,10 @@ const module$1 = defineNuxtModule({
56
56
  locale: options.locale ?? "en"
57
57
  };
58
58
  nuxt.options.css.push("pdfjs-dist/web/pdf_viewer.css");
59
+ const cssnano = nuxt.options.postcss?.plugins?.cssnano;
60
+ if (cssnano && typeof cssnano === "object" && !cssnano.preset) {
61
+ cssnano.preset = ["default", { svgo: false }];
62
+ }
59
63
  nuxt.options.css.push(resolve("./runtime/assets/kviewer.css"));
60
64
  addPlugin(resolve("./runtime/plugin"));
61
65
  addComponentsDir({
@@ -57,18 +57,14 @@ export class Editor {
57
57
  id,
58
58
  pageNumber,
59
59
  konvaString: konvaGroup.toJSON(),
60
- // Do NOT use konvaGroup.getClientRect() directly here — it includes the
61
- // stage's zoom scale, which would inflate annotation coordinates in the
62
- // exported PDF. We divide by scale to get page-space coordinates.
60
+ // Do NOT use konvaGroup.getClientRect() without relativeTo here — it is
61
+ // in absolute stage coordinates, which bake in the stage's zoom scale
62
+ // AND the windowed stage position (setStageWindow shifts stage.position
63
+ // at high zoom). relativeTo undoes both, yielding page-space
64
+ // coordinates regardless of the zoom state at placement time.
63
65
  konvaClientRect: (() => {
64
- const scale = konvaGroup.getStage()?.scaleX() ?? 1;
65
- const raw = konvaGroup.getClientRect();
66
- return {
67
- x: raw.x / scale,
68
- y: raw.y / scale,
69
- width: raw.width / scale,
70
- height: raw.height / scale
71
- };
66
+ const stage = konvaGroup.getStage();
67
+ return stage ? konvaGroup.getClientRect({ relativeTo: stage }) : konvaGroup.getClientRect();
72
68
  })(),
73
69
  title: this.userName,
74
70
  type: annotation.type,
@@ -144,7 +140,9 @@ export class Editor {
144
140
  this.konvaStage.off("click mousedown mousemove mouseup touchstart touchmove touchend");
145
141
  }
146
142
  getBgLayer(konvaStage) {
147
- return konvaStage ? konvaStage.getLayers()[0] : this.konvaStage.getLayers()[0];
143
+ const layer = konvaStage ? konvaStage.getLayers()[0] : this.konvaStage.getLayers()[0];
144
+ if (!layer) throw new Error("Annotation stage has no background layer");
145
+ return layer;
148
146
  }
149
147
  delShapeGroup(id) {
150
148
  this.shapeGroupStore.delete(id);
@@ -99,7 +99,9 @@ export class Selector {
99
99
  });
100
100
  }
101
101
  getBackgroundLayer(konvaStage) {
102
- return konvaStage.getLayers()[0];
102
+ const layer = konvaStage.getLayers()[0];
103
+ if (!layer) throw new Error("Annotation stage has no background layer");
104
+ return layer;
103
105
  }
104
106
  getPageShapeGroups(konvaStage) {
105
107
  return this.getBackgroundLayer(konvaStage).getChildren(
@@ -13,17 +13,21 @@ export class EditorArrow extends Editor {
13
13
  }
14
14
  mouseDownHandler(e) {
15
15
  if (e.currentTarget !== this.konvaStage) return;
16
+ const pos = this.konvaStage.getRelativePointerPosition();
17
+ const annotation = this.currentAnnotation;
18
+ const style = annotation?.style;
19
+ if (!pos || !annotation || !style) return;
16
20
  this.arrow = null;
17
21
  this.isPainting = true;
18
- this.currentShapeGroup = this.createShapeGroup();
19
- this.getBgLayer().add(this.currentShapeGroup.konvaGroup);
20
- const pos = this.konvaStage.getRelativePointerPosition();
22
+ const shapeGroup = this.createShapeGroup();
23
+ this.currentShapeGroup = shapeGroup;
24
+ this.getBgLayer().add(shapeGroup.konvaGroup);
21
25
  this.startPoint = { x: pos.x, y: pos.y };
22
26
  this.arrow = new Konva.Arrow({
23
27
  points: [pos.x, pos.y, pos.x, pos.y],
24
- stroke: this.currentAnnotation.style.color,
25
- strokeWidth: this.currentAnnotation.style.strokeWidth,
26
- fill: this.currentAnnotation.style.color,
28
+ stroke: style.color,
29
+ strokeWidth: style.strokeWidth,
30
+ fill: style.color,
27
31
  pointerLength: 10,
28
32
  pointerWidth: 10,
29
33
  hitStrokeWidth: 20,
@@ -31,15 +35,16 @@ export class EditorArrow extends Editor {
31
35
  lineCap: "round",
32
36
  lineJoin: "round",
33
37
  visible: false,
34
- opacity: this.currentAnnotation.style.opacity
38
+ opacity: style.opacity
35
39
  });
36
- this.currentShapeGroup.konvaGroup.add(this.arrow);
40
+ shapeGroup.konvaGroup.add(this.arrow);
37
41
  window.addEventListener("mouseup", this.globalPointerUpHandler);
38
42
  }
39
43
  mouseMoveHandler(e) {
40
44
  if (!this.isPainting) return;
41
45
  e.evt.preventDefault();
42
46
  const pos = this.konvaStage.getRelativePointerPosition();
47
+ if (!pos) return;
43
48
  const points = [this.startPoint.x, this.startPoint.y, pos.x, pos.y];
44
49
  this.arrow?.show();
45
50
  this.arrow?.setAttrs({ points });
@@ -47,20 +52,24 @@ export class EditorArrow extends Editor {
47
52
  mouseUpHandler() {
48
53
  if (!this.isPainting) return;
49
54
  this.isPainting = false;
50
- const group = this.arrow?.getParent();
51
- if (!this.arrow?.isVisible() && group?.getType() === "Group") {
55
+ const arrow = this.arrow;
56
+ const group = arrow?.getParent();
57
+ if (!arrow || !group) return;
58
+ if (!arrow.isVisible() && group.getType() === "Group") {
52
59
  this.delShapeGroup(group.id());
53
60
  return;
54
61
  }
55
62
  if (this.isTooShort()) {
56
- this.arrow?.destroy();
63
+ arrow.destroy();
57
64
  this.delShapeGroup(group.id());
58
65
  this.arrow = null;
59
66
  return;
60
67
  }
68
+ const style = this.currentAnnotation?.style;
69
+ if (!style) return;
61
70
  this.setShapeGroupDone({
62
71
  id: group.id(),
63
- color: this.currentAnnotation.style.color,
72
+ color: style.color,
64
73
  contentsObj: {
65
74
  text: ""
66
75
  }
@@ -76,8 +85,9 @@ export class EditorArrow extends Editor {
76
85
  if (!this.arrow) return true;
77
86
  const points = this.arrow.points();
78
87
  if (points.length !== 4) return true;
79
- const dx = points[2] - points[0];
80
- const dy = points[3] - points[1];
88
+ const [x1, y1, x2, y2] = points;
89
+ const dx = x2 - x1;
90
+ const dy = y2 - y1;
81
91
  return Math.hypot(dx, dy) < Editor.MinSize;
82
92
  }
83
93
  /**
@@ -23,11 +23,15 @@ export class EditorCircle extends Editor {
23
23
  if (e.currentTarget !== this.konvaStage) {
24
24
  return;
25
25
  }
26
+ const pos = this.konvaStage.getRelativePointerPosition();
27
+ const annotation = this.currentAnnotation;
28
+ const style = annotation?.style;
29
+ if (!pos || !annotation || !style) return;
26
30
  this.ellipse = null;
27
31
  this.isPainting = true;
28
- this.currentShapeGroup = this.createShapeGroup();
29
- this.getBgLayer().add(this.currentShapeGroup.konvaGroup);
30
- const pos = this.konvaStage.getRelativePointerPosition();
32
+ const shapeGroup = this.createShapeGroup();
33
+ this.currentShapeGroup = shapeGroup;
34
+ this.getBgLayer().add(shapeGroup.konvaGroup);
31
35
  this.vertex = { x: pos.x, y: pos.y };
32
36
  this.ellipse = new Konva.Ellipse({
33
37
  radiusX: 0,
@@ -36,14 +40,14 @@ export class EditorCircle extends Editor {
36
40
  y: pos.y,
37
41
  visible: false,
38
42
  // Start hidden
39
- stroke: this.currentAnnotation.style.color,
43
+ stroke: style.color,
40
44
  // Set the ellipse stroke color
41
- strokeWidth: this.currentAnnotation.style.strokeWidth,
45
+ strokeWidth: style.strokeWidth,
42
46
  // Set the ellipse stroke width
43
- opacity: this.currentAnnotation.style.opacity
47
+ opacity: style.opacity
44
48
  // Set the ellipse opacity
45
49
  });
46
- this.currentShapeGroup.konvaGroup.add(this.ellipse);
50
+ shapeGroup.konvaGroup.add(this.ellipse);
47
51
  window.addEventListener("mouseup", this.globalPointerUpHandler);
48
52
  }
49
53
  /**
@@ -55,8 +59,10 @@ export class EditorCircle extends Editor {
55
59
  return;
56
60
  }
57
61
  e.evt.preventDefault();
58
- this.ellipse.show();
59
62
  const pos = this.konvaStage.getRelativePointerPosition();
63
+ const ellipse = this.ellipse;
64
+ if (!pos || !ellipse) return;
65
+ ellipse.show();
60
66
  const radiusX = Math.abs(pos.x - this.vertex.x) / 2;
61
67
  const radiusY = Math.abs(pos.y - this.vertex.y) / 2;
62
68
  const areaAttr = {
@@ -65,7 +71,7 @@ export class EditorCircle extends Editor {
65
71
  radiusX,
66
72
  radiusY
67
73
  };
68
- this.ellipse.setAttrs(areaAttr);
74
+ ellipse.setAttrs(areaAttr);
69
75
  }
70
76
  /**
71
77
  * Handles mouse or touch pointer-up events and finishes drawing the ellipse.
@@ -75,20 +81,24 @@ export class EditorCircle extends Editor {
75
81
  return;
76
82
  }
77
83
  this.isPainting = false;
78
- const group = this.ellipse.getParent();
79
- if (!this.ellipse.isVisible() && group.getType() === "Group") {
84
+ const ellipse = this.ellipse;
85
+ const group = ellipse?.getParent();
86
+ if (!ellipse || !group) return;
87
+ if (!ellipse.isVisible() && group.getType() === "Group") {
80
88
  this.delShapeGroup(group.id());
81
89
  return;
82
90
  }
83
91
  if (this.isTooSmall()) {
84
- this.ellipse.destroy();
92
+ ellipse.destroy();
85
93
  this.delShapeGroup(group.id());
86
94
  this.ellipse = null;
87
95
  return;
88
96
  }
97
+ const style = this.currentAnnotation?.style;
98
+ if (!style) return;
89
99
  this.setShapeGroupDone({
90
100
  id: group.id(),
91
- color: this.currentAnnotation.style.color,
101
+ color: style.color,
92
102
  contentsObj: {
93
103
  text: ""
94
104
  }
@@ -109,6 +119,7 @@ export class EditorCircle extends Editor {
109
119
  * @returns True if the ellipse width or height is smaller than the minimum size, otherwise false.
110
120
  */
111
121
  isTooSmall() {
122
+ if (!this.ellipse) return true;
112
123
  const { width, height } = this.ellipse.size();
113
124
  return Math.max(width, height) < Editor.MinSize;
114
125
  }
@@ -35,23 +35,27 @@ export class EditorCloud extends Editor {
35
35
  }
36
36
  mouseDownHandler(_e) {
37
37
  const pos = this.konvaStage.getRelativePointerPosition();
38
+ const annotation = this.currentAnnotation;
39
+ const style = annotation?.style;
40
+ if (!pos || !annotation || !style) return;
38
41
  this.points.push(pos);
39
42
  if (!this.isPainting) {
40
43
  this.isPainting = true;
41
- this.currentShapeGroup = this.createShapeGroup();
42
- this.getBgLayer().add(this.currentShapeGroup.konvaGroup);
44
+ const shapeGroup = this.createShapeGroup();
45
+ this.currentShapeGroup = shapeGroup;
46
+ this.getBgLayer().add(shapeGroup.konvaGroup);
43
47
  this.cloudPath = new Konva.Path({
44
48
  data: "",
45
- stroke: this.currentAnnotation.style.color,
46
- strokeWidth: this.currentAnnotation.style.strokeWidth,
49
+ stroke: style.color,
50
+ strokeWidth: style.strokeWidth,
47
51
  fillEnabled: false,
48
52
  lineJoin: "round",
49
53
  lineCap: "round",
50
54
  hitStrokeWidth: 20,
51
55
  // Set the hit detection width
52
- opacity: this.currentAnnotation.style.opacity
56
+ opacity: style.opacity
53
57
  });
54
- this.currentShapeGroup.konvaGroup.add(this.cloudPath);
58
+ shapeGroup.konvaGroup.add(this.cloudPath);
55
59
  this.drawStartRect(pos);
56
60
  }
57
61
  this.updateCloudPreview();
@@ -59,6 +63,7 @@ export class EditorCloud extends Editor {
59
63
  mouseMoveHandler(_e) {
60
64
  if (!this.isPainting || !this.cloudPath) return;
61
65
  const pos = this.konvaStage.getRelativePointerPosition();
66
+ if (!pos) return;
62
67
  this.updateCloudPreview(pos);
63
68
  }
64
69
  mouseUpHandler(_e) {
@@ -73,9 +78,12 @@ export class EditorCloud extends Editor {
73
78
  const closedPoints = [...this.points, this.points[0]];
74
79
  const pathData = this.generateCloudPathData(closedPoints);
75
80
  this.cloudPath.data(pathData);
81
+ const shapeGroup = this.currentShapeGroup;
82
+ const style = this.currentAnnotation?.style;
83
+ if (!shapeGroup || !style) return;
76
84
  this.setShapeGroupDone({
77
- id: this.currentShapeGroup.konvaGroup.id(),
78
- color: this.currentAnnotation.style.color,
85
+ id: shapeGroup.konvaGroup.id(),
86
+ color: style.color,
79
87
  contentsObj: { text: "" }
80
88
  });
81
89
  this.cloudPath = null;
@@ -179,7 +187,7 @@ export class EditorCloud extends Editor {
179
187
  height: this.startRectSize,
180
188
  stroke: "#000",
181
189
  strokeWidth: 2,
182
- fill: null,
190
+ fillEnabled: false,
183
191
  cornerRadius: 2,
184
192
  hitStrokeWidth: 10,
185
193
  // Increase the hit detection area
@@ -187,26 +195,27 @@ export class EditorCloud extends Editor {
187
195
  dash: [4, 2],
188
196
  name: "startRect"
189
197
  });
190
- this.getBgLayer().add(this.startRect);
191
- this.startRect.moveToTop();
192
- this.startRect.on(
198
+ const startRect = this.startRect;
199
+ this.getBgLayer().add(startRect);
200
+ startRect.moveToTop();
201
+ startRect.on(
193
202
  "mouseup",
194
203
  (_e) => {
195
204
  this.handleDoubleClick();
196
205
  }
197
206
  );
198
- this.startRect.on(
207
+ startRect.on(
199
208
  "mousemove",
200
209
  (_e) => {
201
- this.startRect.stroke("#1677ff");
202
- this.startRect.getLayer()?.batchDraw();
210
+ startRect.stroke("#1677ff");
211
+ startRect.getLayer()?.batchDraw();
203
212
  }
204
213
  );
205
- this.startRect.on(
214
+ startRect.on(
206
215
  "mouseout",
207
216
  (_e) => {
208
- this.startRect.stroke("#000");
209
- this.startRect.getLayer()?.batchDraw();
217
+ startRect.stroke("#000");
218
+ startRect.getLayer()?.batchDraw();
210
219
  }
211
220
  );
212
221
  }
@@ -16,16 +16,20 @@ export class EditorFreeHighlight extends Editor {
16
16
  if (e.currentTarget !== this.konvaStage) {
17
17
  return;
18
18
  }
19
+ const pos = this.konvaStage.getRelativePointerPosition();
20
+ const annotation = this.currentAnnotation;
21
+ const style = annotation?.style;
22
+ if (!pos || !annotation || !style) return;
19
23
  this.line = null;
20
24
  this.isPainting = true;
21
- this.currentShapeGroup = this.createShapeGroup();
22
- this.getBgLayer().add(this.currentShapeGroup.konvaGroup);
23
- const pos = this.konvaStage.getRelativePointerPosition();
25
+ const shapeGroup = this.createShapeGroup();
26
+ this.currentShapeGroup = shapeGroup;
27
+ this.getBgLayer().add(shapeGroup.konvaGroup);
24
28
  this.line = new Konva.Line({
25
- stroke: this.currentAnnotation.style.color,
26
- strokeWidth: this.currentAnnotation.style.strokeWidth,
27
- opacity: this.currentAnnotation.style.opacity,
28
- hitStrokeWidth: this.currentAnnotation.style.strokeWidth,
29
+ stroke: style.color,
30
+ strokeWidth: style.strokeWidth,
31
+ opacity: style.opacity,
32
+ hitStrokeWidth: style.strokeWidth,
29
33
  lineCap: "round",
30
34
  lineJoin: "round",
31
35
  visible: false,
@@ -33,7 +37,7 @@ export class EditorFreeHighlight extends Editor {
33
37
  points: [pos.x, pos.y]
34
38
  // Initialize the starting point
35
39
  });
36
- this.currentShapeGroup.konvaGroup.add(this.line);
40
+ shapeGroup.konvaGroup.add(this.line);
37
41
  window.addEventListener("mouseup", this.globalPointerUpHandler);
38
42
  }
39
43
  /**
@@ -45,10 +49,12 @@ export class EditorFreeHighlight extends Editor {
45
49
  return;
46
50
  }
47
51
  e.evt.preventDefault();
48
- this.line.show();
49
52
  const pos = this.konvaStage.getRelativePointerPosition();
50
- const newPoints = this.line.points().concat([pos.x, pos.y]);
51
- this.line.points(newPoints);
53
+ const line = this.line;
54
+ if (!pos || !line) return;
55
+ line.show();
56
+ const newPoints = line.points().concat([pos.x, pos.y]);
57
+ line.points(newPoints);
52
58
  }
53
59
  /**
54
60
  * Handles mouse or touch pointer-up events and finishes drawing the freeform curve.
@@ -58,8 +64,9 @@ export class EditorFreeHighlight extends Editor {
58
64
  return;
59
65
  }
60
66
  this.isPainting = false;
61
- const group = this.line?.getParent();
62
- if (group && !this.line.isVisible() && group.getType() === "Group") {
67
+ const line = this.line;
68
+ const group = line?.getParent();
69
+ if (group && line && !line.isVisible() && group.getType() === "Group") {
63
70
  this.delShapeGroup(group.id());
64
71
  return;
65
72
  }
@@ -71,13 +78,14 @@ export class EditorFreeHighlight extends Editor {
71
78
  this.line = null;
72
79
  return;
73
80
  }
74
- if (this.line) {
81
+ const style = this.currentAnnotation?.style;
82
+ if (this.line && group && style) {
75
83
  const originalPoints = this.line.points();
76
84
  const correctedPoints = this.correctLineIfStraight(originalPoints);
77
85
  this.line.points(correctedPoints);
78
86
  this.setShapeGroupDone({
79
87
  id: group.id(),
80
- color: this.currentAnnotation.style.color,
88
+ color: style.color,
81
89
  contentsObj: {
82
90
  text: ""
83
91
  }
@@ -100,6 +108,7 @@ export class EditorFreeHighlight extends Editor {
100
108
  * @returns The corrected points
101
109
  */
102
110
  correctLineIfStraight(points) {
111
+ if (points.length < 4) return points;
103
112
  const THRESHOLD_ANGLE_DEGREES = 2;
104
113
  const startX = points[0];
105
114
  const startY = points[1];
@@ -20,6 +20,10 @@ export class EditorFreeHand extends Editor {
20
20
  if (e.currentTarget !== this.konvaStage) {
21
21
  return;
22
22
  }
23
+ const pos = this.konvaStage.getRelativePointerPosition();
24
+ const annotation = this.currentAnnotation;
25
+ const style = annotation?.style;
26
+ if (!pos || !annotation || !style) return;
23
27
  Editor.TimerClear(this.pageNumber);
24
28
  this.line = null;
25
29
  this.isPainting = true;
@@ -27,13 +31,12 @@ export class EditorFreeHand extends Editor {
27
31
  this.currentShapeGroup = this.createShapeGroup();
28
32
  this.getBgLayer().add(this.currentShapeGroup.konvaGroup);
29
33
  }
30
- const pos = this.konvaStage.getRelativePointerPosition();
31
34
  this.line = new Konva.Line({
32
- stroke: this.currentAnnotation.style.color,
35
+ stroke: style.color,
33
36
  // Set the line color
34
- strokeWidth: this.currentAnnotation.style.strokeWidth,
37
+ strokeWidth: style.strokeWidth,
35
38
  // Set the line width
36
- opacity: this.currentAnnotation.style.opacity,
39
+ opacity: style.opacity,
37
40
  // Set the line opacity
38
41
  lineCap: "round",
39
42
  // Set rounded line caps
@@ -59,10 +62,12 @@ export class EditorFreeHand extends Editor {
59
62
  return;
60
63
  }
61
64
  e.evt.preventDefault();
62
- this.line.show();
63
65
  const pos = this.konvaStage.getRelativePointerPosition();
64
- const newPoints = this.line.points().concat([pos.x, pos.y]);
65
- this.line.points(newPoints);
66
+ const line = this.line;
67
+ if (!pos || !line) return;
68
+ line.show();
69
+ const newPoints = line.points().concat([pos.x, pos.y]);
70
+ line.points(newPoints);
66
71
  }
67
72
  /**
68
73
  * Handles mouse or touch pointer-up events and finishes drawing the freeform curve.
@@ -72,13 +77,17 @@ export class EditorFreeHand extends Editor {
72
77
  return;
73
78
  }
74
79
  this.isPainting = false;
75
- const group = this.line.getParent();
80
+ const line = this.line;
81
+ const group = line?.getParent();
82
+ const style = this.currentAnnotation?.style;
83
+ if (!line || !group || !style) return;
84
+ const color = style.color;
76
85
  if (this.isTooSmall()) {
77
- this.line.destroy();
86
+ line.destroy();
78
87
  Editor.TimerStart(this.pageNumber, () => {
79
88
  this.setShapeGroupDone({
80
89
  id: group.id(),
81
- color: this.currentAnnotation.style.color,
90
+ color,
82
91
  contentsObj: {
83
92
  text: ""
84
93
  }
@@ -90,7 +99,7 @@ export class EditorFreeHand extends Editor {
90
99
  Editor.TimerStart(this.pageNumber, () => {
91
100
  this.setShapeGroupDone({
92
101
  id: group.id(),
93
- color: this.currentAnnotation.style.color,
102
+ color,
94
103
  contentsObj: {
95
104
  text: ""
96
105
  }
@@ -113,7 +122,7 @@ export class EditorFreeHand extends Editor {
113
122
  * @returns True if the line point count is less than 5, otherwise false
114
123
  */
115
124
  isTooSmall() {
116
- return this.line.points().length < Editor.MinSize;
125
+ return !this.line || this.line.points().length < Editor.MinSize;
117
126
  }
118
127
  /**
119
128
  * @description Update annotation styles
@@ -5,6 +5,8 @@ import { Editor, type IEditorOptions } from '../editor/editor.js';
5
5
  * EditorHighLight is a highlight editor class that extends Editor.
6
6
  */
7
7
  export declare class EditorHighLight extends Editor {
8
+ private get activeAnnotation();
9
+ private get activeStyle();
8
10
  /**
9
11
  * Creates an EditorHighLight instance.
10
12
  * @param EditorOptions Options used to initialize the editor
@@ -2,6 +2,15 @@ import Konva from "konva";
2
2
  import { AnnotationType } from "../types.js";
3
3
  import { Editor } from "../editor/editor.js";
4
4
  export class EditorHighLight extends Editor {
5
+ get activeAnnotation() {
6
+ if (!this.currentAnnotation) throw new Error("Highlight editor is not active");
7
+ return this.currentAnnotation;
8
+ }
9
+ get activeStyle() {
10
+ const style = this.activeAnnotation.style;
11
+ if (!style) throw new Error("Highlight annotation has no style");
12
+ return style;
13
+ }
5
14
  /**
6
15
  * Creates an EditorHighLight instance.
7
16
  * @param EditorOptions Options used to initialize the editor
@@ -16,8 +25,9 @@ export class EditorHighLight extends Editor {
16
25
  * @param fixElement Element used as the positioning reference
17
26
  */
18
27
  convertTextSelection(elements, fixElement) {
19
- this.currentShapeGroup = this.createShapeGroup();
20
- this.getBgLayer().add(this.currentShapeGroup.konvaGroup);
28
+ const shapeGroup = this.createShapeGroup();
29
+ this.currentShapeGroup = shapeGroup;
30
+ this.getBgLayer().add(shapeGroup.konvaGroup);
21
31
  const fixBounding = fixElement.getBoundingClientRect();
22
32
  elements.forEach((spanEl) => {
23
33
  const bounding = spanEl.getBoundingClientRect();
@@ -26,14 +36,14 @@ export class EditorHighLight extends Editor {
26
36
  fixBounding
27
37
  );
28
38
  const shape = this.createShape(x, y, width, height);
29
- this.currentShapeGroup.konvaGroup.add(shape);
39
+ shapeGroup.konvaGroup.add(shape);
30
40
  });
31
41
  this.setShapeGroupDone({
32
- id: this.currentShapeGroup.id,
42
+ id: shapeGroup.id,
33
43
  contentsObj: {
34
44
  text: this.getElementOuterText(elements)
35
45
  },
36
- color: this.currentAnnotation.style.color
46
+ color: this.activeStyle.color
37
47
  });
38
48
  }
39
49
  /**
@@ -67,7 +77,7 @@ export class EditorHighLight extends Editor {
67
77
  * @returns A concrete Konva.Shape instance
68
78
  */
69
79
  createShape(x, y, width, height) {
70
- switch (this.currentAnnotation.type) {
80
+ switch (this.activeAnnotation.type) {
71
81
  case AnnotationType.HIGHLIGHT:
72
82
  return this.createHighlightShape(x, y, width, height);
73
83
  case AnnotationType.UNDERLINE:
@@ -76,7 +86,7 @@ export class EditorHighLight extends Editor {
76
86
  return this.createStrikeoutShape(x, y, width, height);
77
87
  default:
78
88
  throw new Error(
79
- `Unsupported annotation type: ${this.currentAnnotation.type}`
89
+ `Unsupported annotation type: ${this.activeAnnotation.type}`
80
90
  );
81
91
  }
82
92
  }
@@ -95,7 +105,7 @@ export class EditorHighLight extends Editor {
95
105
  width,
96
106
  height,
97
107
  opacity: 0.5,
98
- fill: this.currentAnnotation.style.color
108
+ fill: this.activeStyle.color
99
109
  });
100
110
  }
101
111
  /**
@@ -111,7 +121,7 @@ export class EditorHighLight extends Editor {
111
121
  x,
112
122
  y: height + y - 2,
113
123
  width,
114
- stroke: this.currentAnnotation.style.color,
124
+ stroke: this.activeStyle.color,
115
125
  opacity: 1,
116
126
  strokeWidth: 1,
117
127
  hitStrokeWidth: 10,
@@ -131,7 +141,7 @@ export class EditorHighLight extends Editor {
131
141
  x,
132
142
  y: y + height / 2,
133
143
  width,
134
- stroke: this.currentAnnotation.style.color,
144
+ stroke: this.activeStyle.color,
135
145
  opacity: 1,
136
146
  strokeWidth: 1,
137
147
  hitStrokeWidth: 10,
@@ -11,10 +11,12 @@ export class EditorNote extends Editor {
11
11
  }
12
12
  async mouseUpHandler(e) {
13
13
  const color = "rgb(255, 222, 33)";
14
- const { x, y } = this.konvaStage.getRelativePointerPosition();
15
14
  if (e.currentTarget !== this.konvaStage) {
16
15
  return;
17
16
  }
17
+ const pos = this.konvaStage.getRelativePointerPosition();
18
+ if (!pos) return;
19
+ const { x, y } = pos;
18
20
  this.isPainting = true;
19
21
  this.currentShapeGroup = this.createShapeGroup();
20
22
  this.getBgLayer().add(this.currentShapeGroup.konvaGroup);
@@ -23,11 +23,15 @@ export class EditorRectangle extends Editor {
23
23
  if (e.currentTarget !== this.konvaStage) {
24
24
  return;
25
25
  }
26
+ const pos = this.konvaStage.getRelativePointerPosition();
27
+ const annotation = this.currentAnnotation;
28
+ const style = annotation?.style;
29
+ if (!pos || !annotation || !style) return;
26
30
  this.rect = null;
27
31
  this.isPainting = true;
28
- this.currentShapeGroup = this.createShapeGroup();
29
- this.getBgLayer().add(this.currentShapeGroup.konvaGroup);
30
- const pos = this.konvaStage.getRelativePointerPosition();
32
+ const shapeGroup = this.createShapeGroup();
33
+ this.currentShapeGroup = shapeGroup;
34
+ this.getBgLayer().add(shapeGroup.konvaGroup);
31
35
  this.vertex = { x: pos.x, y: pos.y };
32
36
  this.rect = new Konva.Rect({
33
37
  x: pos.x,
@@ -35,11 +39,11 @@ export class EditorRectangle extends Editor {
35
39
  width: 0,
36
40
  height: 0,
37
41
  visible: false,
38
- stroke: this.currentAnnotation.style.color,
39
- strokeWidth: this.currentAnnotation.style.strokeWidth || 2,
40
- opacity: this.currentAnnotation.style.opacity
42
+ stroke: style.color,
43
+ strokeWidth: style.strokeWidth || 2,
44
+ opacity: style.opacity
41
45
  });
42
- this.currentShapeGroup.konvaGroup.add(this.rect);
46
+ shapeGroup.konvaGroup.add(this.rect);
43
47
  window.addEventListener("mouseup", this.globalPointerUpHandler);
44
48
  }
45
49
  /**
@@ -51,8 +55,10 @@ export class EditorRectangle extends Editor {
51
55
  return;
52
56
  }
53
57
  e.evt.preventDefault();
58
+ if (!this.rect) return;
54
59
  this.rect.show();
55
60
  const pos = this.konvaStage.getRelativePointerPosition();
61
+ if (!pos) return;
56
62
  const areaAttr = {
57
63
  x: Math.min(this.vertex.x, pos.x),
58
64
  y: Math.min(this.vertex.y, pos.y),
@@ -69,7 +75,9 @@ export class EditorRectangle extends Editor {
69
75
  return;
70
76
  }
71
77
  this.isPainting = false;
78
+ if (!this.rect) return;
72
79
  const group = this.rect.getParent();
80
+ if (!group) return;
73
81
  if (!this.rect.isVisible() && group.getType() === "Group") {
74
82
  this.delShapeGroup(group.id());
75
83
  return;
@@ -80,9 +88,11 @@ export class EditorRectangle extends Editor {
80
88
  this.rect = null;
81
89
  return;
82
90
  }
91
+ const style = this.currentAnnotation?.style;
92
+ if (!style) return;
83
93
  this.setShapeGroupDone({
84
94
  id: group.id(),
85
- color: this.currentAnnotation.style.color,
95
+ color: style.color,
86
96
  contentsObj: {
87
97
  text: ""
88
98
  }
@@ -103,6 +113,7 @@ export class EditorRectangle extends Editor {
103
113
  * @returns true if the rectangle is too small, false otherwise
104
114
  */
105
115
  isTooSmall() {
116
+ if (!this.rect) return true;
106
117
  const { width, height } = this.rect.size();
107
118
  return Math.max(width, height) < Editor.MinSize;
108
119
  }
@@ -11,7 +11,7 @@ import {
11
11
  import { cursorPreviewSize, placementSize } from "../../utils/placement_size.js";
12
12
  export class EditorSignature extends Editor {
13
13
  signatureUrl;
14
- signatureImage;
14
+ signatureImage = null;
15
15
  constructor(editorOptions, defaultSignatureUrl) {
16
16
  super({ ...editorOptions, editorType: AnnotationType.SIGNATURE });
17
17
  this.signatureUrl = defaultSignatureUrl;
@@ -54,6 +54,7 @@ export class EditorSignature extends Editor {
54
54
  const crosshair = { x: newWidth / 2, y: newHeight / 2 };
55
55
  this.signatureImage = image;
56
56
  this.signatureImage.setAttrs({
57
+ image: image.image(),
57
58
  x: pos.x - crosshair.x,
58
59
  y: pos.y - crosshair.y,
59
60
  width: newWidth,
@@ -14,7 +14,7 @@ import {
14
14
  } from "../../utils/placement_size.js";
15
15
  export class EditorStamp extends Editor {
16
16
  stampUrl;
17
- stampImage;
17
+ stampImage = null;
18
18
  stampWidth = null;
19
19
  stampHeight = null;
20
20
  constructor(editorOptions, defaultStampUrl) {
@@ -92,6 +92,7 @@ export class EditorStamp extends Editor {
92
92
  const crosshair = { x: newWidth / 2, y: newHeight / 2 };
93
93
  this.stampImage = image;
94
94
  this.stampImage.setAttrs({
95
+ image: image.image(),
95
96
  x: pos.x - crosshair.x,
96
97
  y: pos.y - crosshair.y,
97
98
  width: newWidth,
@@ -58,6 +58,7 @@ export function removeCssCustomProperty(propertyName) {
58
58
  }
59
59
  export async function base64ToImageBitmap(base64) {
60
60
  const base64Data = base64.split(",")[1];
61
+ if (!base64Data) throw new Error("Invalid base64 image data");
61
62
  const binaryString = atob(base64Data);
62
63
  const length = binaryString.length;
63
64
  const bytes = new Uint8Array(length);
@@ -134,7 +135,7 @@ export function getPDFDateTimestamp(dateString) {
134
135
  let tzOffset = 0;
135
136
  if (tzMatch) {
136
137
  const sign = tzMatch[1] === "+" ? 1 : -1;
137
- const hours = Number.parseInt(tzMatch[2], 10) || 0;
138
+ const hours = Number.parseInt(tzMatch[2] ?? "0", 10) || 0;
138
139
  const minutes = Number.parseInt(tzMatch[3] || "0", 10) || 0;
139
140
  tzOffset = sign * (hours * 60 + minutes);
140
141
  }
@@ -1,5 +1,5 @@
1
1
  export function downloadPdfBytes(data, fileName) {
2
- const arrayBuffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
2
+ const arrayBuffer = Uint8Array.from(data).buffer;
3
3
  const blob = new Blob([arrayBuffer], { type: "application/pdf" });
4
4
  const link = document.createElement("a");
5
5
  const url = URL.createObjectURL(blob);
@@ -192,7 +192,7 @@ async function flattenPageAnnotations(pdfDoc, page, annotations) {
192
192
  for (const annotation of annotations) {
193
193
  try {
194
194
  const node = Konva.Node.create(annotation.konvaString);
195
- if (node instanceof Konva.Node) {
195
+ if (node instanceof Konva.Group || node instanceof Konva.Shape) {
196
196
  layer.add(node);
197
197
  imageLoaders.push(...loadImagesForNode(node));
198
198
  }
@@ -12,7 +12,11 @@ function parseSvgPathToPoints(data) {
12
12
  const nums = cmd.slice(1).trim().split(/[\s,]+/).map((value) => Number.parseFloat(value));
13
13
  if (type === "M" || type === "L") {
14
14
  for (let i = 0; i < nums.length; i += 2) {
15
- points.push(nums[i], nums[i + 1]);
15
+ const x = nums[i];
16
+ const y = nums[i + 1];
17
+ if (x !== void 0 && y !== void 0) {
18
+ points.push(x, y);
19
+ }
16
20
  }
17
21
  } else if (type === "Q") {
18
22
  if (nums.length >= 4) {
@@ -177,10 +177,10 @@ export class StampParser extends AnnotationParser {
177
177
  ...this.ownerDateEntries(annotation.title, annotation.date),
178
178
  Open: false
179
179
  };
180
- if (apDict) {
181
- stampAnnDict.AP = apDict;
182
- }
183
- const stampAnn = context.obj(stampAnnDict);
180
+ const stampAnn = context.obj({
181
+ ...stampAnnDict,
182
+ ...apDict ? { AP: apDict } : {}
183
+ });
184
184
  const stampAnnRef = context.register(stampAnn);
185
185
  this.addAnnotationToPage(page, stampAnnRef);
186
186
  for (const comment of annotation.comments || []) {
@@ -1,10 +1,7 @@
1
1
  import fontkit from "@pdf-lib/fontkit";
2
2
  let fontBytesPromise = null;
3
3
  let loadFontBytes = async () => {
4
- const { default: fontUrl } = await import(
5
- // @ts-expect-error -- Vite asset import, no type declaration
6
- "../../assets/fonts/LiberationSans-Regular.ttf?url"
7
- );
4
+ const { default: fontUrl } = await import("../../assets/fonts/LiberationSans-Regular.ttf?url");
8
5
  const response = await fetch(fontUrl);
9
6
  if (!response.ok) {
10
7
  throw new Error(`Failed to load Unicode fallback font (${response.status})`);
@@ -16,13 +16,14 @@ export function decodeStampAnnotation(annotation, context) {
16
16
  return null;
17
17
  }
18
18
  const group = createGhostGroup(annotation.id);
19
- group.add(new Konva.Image({
19
+ const imageConfig = {
20
20
  x: rect.x,
21
21
  y: rect.y,
22
22
  width: rect.width > 0 ? rect.width : appearance.width,
23
23
  height: rect.height > 0 ? rect.height : appearance.height,
24
24
  base64: appearance.dataUrl
25
- }));
25
+ };
26
+ group.add(new Konva.Image(imageConfig));
26
27
  const store = createAnnotationStore({
27
28
  annotation,
28
29
  allAnnotations: context.allAnnotations,
@@ -88,7 +88,7 @@ async function renderPageToCanvas(page, canvas, annotationMode, scale) {
88
88
  if (!context) throw new Error("Unable to create canvas context for stamp extraction");
89
89
  const viewport = page.getViewport({ scale });
90
90
  const task = page.render({
91
- canvasContext: context,
91
+ canvas,
92
92
  viewport,
93
93
  annotationMode
94
94
  });
@@ -104,7 +104,7 @@ export function getComments(annotation, allAnnotations) {
104
104
  if (candidate.annotationType !== 1) continue;
105
105
  if (candidate.inReplyTo !== annotation.id) continue;
106
106
  comments.push({
107
- id: candidate.id,
107
+ id: typeof candidate.id === "string" ? candidate.id : "",
108
108
  title: getAnnotationTitle(candidate),
109
109
  date: getAnnotationDate(candidate),
110
110
  content: getAnnotationText(candidate)
@@ -5,7 +5,7 @@ type __VLS_Props = {
5
5
  /** Carries displayed width/height plus the page's `/Rotate` and MediaBox
6
6
  * origin — the single source of truth for mapping `/Rect` to canvas. */
7
7
  pageTransform: PageTransform;
8
- pointerEvents: string;
8
+ pointerEvents: 'auto' | 'none';
9
9
  zIndex: number;
10
10
  };
11
11
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -5,7 +5,7 @@ type __VLS_Props = {
5
5
  /** Carries displayed width/height plus the page's `/Rotate` and MediaBox
6
6
  * origin — the single source of truth for mapping `/Rect` to canvas. */
7
7
  pageTransform: PageTransform;
8
- pointerEvents: string;
8
+ pointerEvents: 'auto' | 'none';
9
9
  zIndex: number;
10
10
  };
11
11
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -272,7 +272,7 @@ async function renderCanvas(opts) {
272
272
  tmp.height = viewport.height;
273
273
  try {
274
274
  currentRenderTask = proxy.render({
275
- canvasContext: tmp.getContext("2d"),
275
+ canvas: tmp,
276
276
  viewport,
277
277
  annotationMode: PDFJS_ANNOTATION_MODE_DISABLE
278
278
  });
@@ -293,7 +293,7 @@ async function renderCanvas(opts) {
293
293
  canvas.height = viewport.height;
294
294
  try {
295
295
  currentRenderTask = proxy.render({
296
- canvasContext: canvas.getContext("2d"),
296
+ canvas,
297
297
  viewport,
298
298
  annotationMode: PDFJS_ANNOTATION_MODE_DISABLE
299
299
  });
@@ -349,7 +349,7 @@ async function renderWindowCanvas() {
349
349
  tmp.height = Math.floor(h * k);
350
350
  try {
351
351
  windowRenderTask = proxy.render({
352
- canvasContext: tmp.getContext("2d"),
352
+ canvas: tmp,
353
353
  viewport,
354
354
  transform: [1, 0, 0, 1, -x * k, -y * k],
355
355
  annotationMode: PDFJS_ANNOTATION_MODE_DISABLE
@@ -1022,7 +1022,9 @@ onMounted(() => {
1022
1022
  if (isIPad()) {
1023
1023
  viewerState.setStylusMode(true);
1024
1024
  }
1025
- setDownloadPdfFn(() => exportPdf({ download: true }));
1025
+ setDownloadPdfFn(async () => {
1026
+ await exportPdf({ download: true });
1027
+ });
1026
1028
  loadDocument();
1027
1029
  window.addEventListener("keydown", onGlobalKeydown);
1028
1030
  });
@@ -48,7 +48,7 @@
48
48
  class="absolute inset-0"
49
49
  >
50
50
  <Viewer
51
- :ref="(el) => setViewerRef(activeTab.id, el)"
51
+ :ref="(el) => setViewerRef(activeTab?.id ?? '', el)"
52
52
  :source="activeTab.source"
53
53
  :active="true"
54
54
  :stamps="stamps"
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <UPopover>
2
+ <UPopover v-model:open="popoverOpen">
3
3
  <button
4
4
  class="relative flex items-center justify-center w-8 h-8 rounded-md transition-colors cursor-pointer"
5
5
  :class="isActive ? 'bg-default text-highlighted' : 'text-muted hover:bg-default/50 hover:text-highlighted'"
@@ -43,7 +43,7 @@
43
43
  color="neutral"
44
44
  size="xs"
45
45
  block
46
- @click="drawModalOpen = true"
46
+ @click="openDrawModal"
47
47
  >
48
48
  {{ t("addSignature") }}
49
49
  </UButton>
@@ -69,10 +69,16 @@ import SignatureDrawModal from "../modals/SignatureDrawModal.vue";
69
69
  const state = useViewerState();
70
70
  const { t } = useKviewerI18n();
71
71
  const drawModalOpen = ref(false);
72
+ const popoverOpen = ref(false);
72
73
  const isActive = computed(() => state.activeTool.value === AnnotationType.SIGNATURE);
73
74
  function selectSignature(sig) {
74
75
  state.activeSignature.value = sig;
75
76
  state.selectTool(AnnotationType.SIGNATURE, sig.imageUrl);
77
+ popoverOpen.value = false;
78
+ }
79
+ function openDrawModal() {
80
+ popoverOpen.value = false;
81
+ drawModalOpen.value = true;
76
82
  }
77
83
  async function onDrawSubmit(imageUrl) {
78
84
  drawModalOpen.value = false;
@@ -15,7 +15,7 @@ export function createSearchIndex() {
15
15
  includeMarkedContent: false,
16
16
  disableNormalization: false
17
17
  });
18
- return content.items.filter((item) => "str" in item).map((item) => item.str).join("");
18
+ return content.items.map((item) => "str" in item ? item.str : "").join("");
19
19
  }
20
20
  async function buildIndex(doc) {
21
21
  destroyed = false;
@@ -32,7 +32,7 @@ export interface KViewerApi {
32
32
  allSigned: boolean;
33
33
  fields: SignatureFieldStatus[];
34
34
  }) => void) => () => void;
35
- formEditMode: Ref<boolean>;
35
+ formEditMode: boolean | Ref<boolean>;
36
36
  setFormEditMode: (enabled: boolean) => void;
37
37
  toggleFormEditMode: () => boolean;
38
38
  allPagesRead: () => boolean;
@@ -1,4 +1,4 @@
1
- import { onScopeDispose, watch } from "vue";
1
+ import { onScopeDispose, unref, watch } from "vue";
2
2
  import {
3
3
  EVENT_KIND,
4
4
  KVIEWER_EMBED_PROTOCOL_VERSION,
@@ -81,7 +81,7 @@ export function useKViewerEmbedBridge(viewerRef, options) {
81
81
  case "getSignatureFieldStatus":
82
82
  return viewer.getSignatureFieldStatus();
83
83
  case "getFormEditMode":
84
- return viewer.formEditMode.value;
84
+ return unref(viewer.formEditMode);
85
85
  case "setFormEditMode": {
86
86
  const [enabled] = req.args;
87
87
  viewer.setFormEditMode(enabled);
@@ -141,7 +141,7 @@ export function useKViewerEmbedBridge(viewerRef, options) {
141
141
  postEvent("ready", { protocolVersion: KVIEWER_EMBED_PROTOCOL_VERSION });
142
142
  stopViewerStateWatches.push(
143
143
  watch(
144
- viewer.formEditMode,
144
+ () => unref(viewer.formEditMode),
145
145
  (enabled) => postEvent("formEditMode-changed", { enabled })
146
146
  ),
147
147
  viewer.onFieldPlaced(
@@ -0,0 +1,19 @@
1
+ declare module '*?url' {
2
+ const url: string;
3
+ export default url;
4
+ }
5
+
6
+ declare module 'pngjs' {
7
+ export class PNG {
8
+ constructor(options?: { width?: number; height?: number });
9
+
10
+ static sync: {
11
+ read(data: Buffer): PNG;
12
+ write(image: PNG): Buffer;
13
+ };
14
+
15
+ width: number;
16
+ height: number;
17
+ data: Buffer;
18
+ }
19
+ }
package/dist/types.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- export { type ActiveTool, type AddFormFieldPayload, type CheckboxStyle, type ExportPdfOptions, type FormFieldDefinition, type FormFieldOrigin, type FormFieldType, type FormFieldValue, type KVIEWER_EMBED_PROTOCOL_VERSION, type KViewerApi, type KViewerEmbedBridgeOptions, type KViewerEmbedClient, type KViewerEmbedClientOptions, type KViewerEmbedEventName, type KViewerEmbedEventPayloads, type KViewerEmbedMethodName, type SignatureData, type SignatureHandlers, type ViewMode, type ViewerBottomToolId, type ViewerLayoutToolId, type ViewerMenuButtonItem, type ViewerMenuCheckboxItem, type ViewerMenuItem, type ViewerMenuSeparatorItem, type ViewerState, type ViewerToolEntry, type ViewerToolId, type ViewerToolSlot, type ViewerTopToolId, type useKViewerEmbedBridge } from '../dist/runtime/public-types.js'
1
+ export { type ActiveTool, type AddFormFieldPayload, type CheckboxStyle, type ExportPdfOptions, type FormFieldDefinition, type FormFieldOrigin, type FormFieldType, type FormFieldValue, type KVIEWER_EMBED_PROTOCOL_VERSION, type KViewerApi, type KViewerEmbedBridgeOptions, type KViewerEmbedClient, type KViewerEmbedClientOptions, type KViewerEmbedEventName, type KViewerEmbedEventPayloads, type KViewerEmbedMethodName, type PlacedFieldDefaults, type SignatureData, type SignatureFieldStatus, type SignatureHandlers, type ViewMode, type ViewerBottomToolId, type ViewerLayoutToolId, type ViewerMenuButtonItem, type ViewerMenuCheckboxItem, type ViewerMenuItem, type ViewerMenuSeparatorItem, type ViewerState, type ViewerToolEntry, type ViewerToolId, type ViewerToolSlot, type ViewerTopToolId, type useKViewerEmbedBridge } from '../dist/runtime/public-types.js'
2
2
 
3
3
  export { default } from './module.mjs'
4
4
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kviewer",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Kabema PDF Editor",
5
5
  "repository": "kabema/kviewer",
6
6
  "license": "MIT",
@@ -65,7 +65,7 @@
65
65
  "lint": "eslint .",
66
66
  "test": "vitest run --exclude '**/e2e/**'",
67
67
  "test:watch": "vitest watch",
68
- "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit",
68
+ "test:types": "pnpm run dev:prepare && pnpm --dir docs exec nuxt prepare && vue-tsc --noEmit && pnpm --dir playground exec vue-tsc --noEmit && pnpm --dir docs exec vue-tsc --noEmit",
69
69
  "test:e2e": "playwright test",
70
70
  "test:e2e:ui": "playwright test --ui"
71
71
  }