@embedpdf/plugin-annotation 1.0.6 → 1.0.7

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.
@@ -4,133 +4,169 @@ import { AnnotationPlugin } from "@embedpdf/plugin-annotation";
4
4
  var useAnnotationPlugin = () => usePlugin(AnnotationPlugin.id);
5
5
  var useAnnotationCapability = () => useCapability(AnnotationPlugin.id);
6
6
 
7
- // src/preact/components/annotation-layer.tsx
8
- import { useEffect, useMemo, useState } from "preact/hooks";
9
-
10
- // ../models/dist/index.js
11
- var PdfSoftHyphenMarker = "\xAD";
12
- var PdfZeroWidthSpace = "\u200B";
13
- var PdfWordJoiner = "\u2060";
14
- var PdfBomOrZwnbsp = "\uFEFF";
15
- var PdfNonCharacterFFFE = "\uFFFE";
16
- var PdfNonCharacterFFFF = "\uFFFF";
17
- var PdfUnwantedTextMarkers = Object.freeze([
18
- PdfSoftHyphenMarker,
19
- PdfZeroWidthSpace,
20
- PdfWordJoiner,
21
- PdfBomOrZwnbsp,
22
- PdfNonCharacterFFFE,
23
- PdfNonCharacterFFFF
24
- ]);
25
- var PdfUnwantedTextRegex = new RegExp(`[${PdfUnwantedTextMarkers.join("")}]`, "g");
26
- var PdfAnnotationSubtype = /* @__PURE__ */ ((PdfAnnotationSubtype2) => {
27
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["UNKNOWN"] = 0] = "UNKNOWN";
28
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["TEXT"] = 1] = "TEXT";
29
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["LINK"] = 2] = "LINK";
30
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["FREETEXT"] = 3] = "FREETEXT";
31
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["LINE"] = 4] = "LINE";
32
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["SQUARE"] = 5] = "SQUARE";
33
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["CIRCLE"] = 6] = "CIRCLE";
34
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["POLYGON"] = 7] = "POLYGON";
35
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["POLYLINE"] = 8] = "POLYLINE";
36
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["HIGHLIGHT"] = 9] = "HIGHLIGHT";
37
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["UNDERLINE"] = 10] = "UNDERLINE";
38
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["SQUIGGLY"] = 11] = "SQUIGGLY";
39
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["STRIKEOUT"] = 12] = "STRIKEOUT";
40
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["STAMP"] = 13] = "STAMP";
41
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["CARET"] = 14] = "CARET";
42
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["INK"] = 15] = "INK";
43
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["POPUP"] = 16] = "POPUP";
44
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["FILEATTACHMENT"] = 17] = "FILEATTACHMENT";
45
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["SOUND"] = 18] = "SOUND";
46
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["MOVIE"] = 19] = "MOVIE";
47
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["WIDGET"] = 20] = "WIDGET";
48
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["SCREEN"] = 21] = "SCREEN";
49
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["PRINTERMARK"] = 22] = "PRINTERMARK";
50
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["TRAPNET"] = 23] = "TRAPNET";
51
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["WATERMARK"] = 24] = "WATERMARK";
52
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["THREED"] = 25] = "THREED";
53
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["RICHMEDIA"] = 26] = "RICHMEDIA";
54
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["XFAWIDGET"] = 27] = "XFAWIDGET";
55
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["REDACT"] = 28] = "REDACT";
56
- return PdfAnnotationSubtype2;
57
- })(PdfAnnotationSubtype || {});
58
-
59
- // src/lib/selectors.ts
60
- var getAnnotationsByPageIndex = (state, pageIndex) => {
61
- return state.annotations[pageIndex] || [];
62
- };
7
+ // src/preact/components/annotations.tsx
8
+ import { PdfAnnotationSubtype } from "@embedpdf/models";
9
+ import { usePointerHandlers } from "@embedpdf/plugin-interaction-manager/preact";
10
+ import {
11
+ getAnnotationsByPageIndex,
12
+ getSelectedAnnotationByPageIndex
13
+ } from "@embedpdf/plugin-annotation";
14
+ import { useMemo, useState, useEffect } from "preact/hooks";
63
15
 
64
- // src/preact/components/annotations/highlight.tsx
16
+ // src/preact/components/selectable-container.tsx
65
17
  import { useCallback } from "preact/hooks";
66
- import { Fragment, jsx } from "preact/jsx-runtime";
67
- function HighlightAnnotation({
68
- annotation,
18
+ import { useSelectionCapability } from "@embedpdf/plugin-selection/preact";
19
+ import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
20
+ function SelectableAnnotationContainer({
21
+ trackedAnnotation,
69
22
  scale,
70
23
  isSelected = false,
71
- pageIndex
24
+ pageIndex,
25
+ children
72
26
  }) {
73
27
  const { provides: annotationProvides } = useAnnotationCapability();
74
- const highlightColor = annotation.color || { red: 255, green: 255, blue: 0, alpha: 76 };
75
- const rgbaColor = `rgba(${highlightColor.red}, ${highlightColor.green}, ${highlightColor.blue}, ${highlightColor.alpha / 255})`;
28
+ const { provides: selectionProvides } = useSelectionCapability();
76
29
  const handleClick = useCallback(
77
30
  (e) => {
78
31
  e.stopPropagation();
79
- if (annotationProvides) {
80
- annotationProvides.selectAnnotation(pageIndex, annotation.id);
32
+ if (annotationProvides && selectionProvides) {
33
+ annotationProvides.selectAnnotation(pageIndex, trackedAnnotation.localId);
34
+ selectionProvides.clear();
81
35
  }
82
36
  },
83
- [annotationProvides, isSelected, pageIndex, annotation.id]
37
+ [annotationProvides, selectionProvides, isSelected, pageIndex, trackedAnnotation.localId]
84
38
  );
85
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
39
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
40
+ children,
41
+ /* @__PURE__ */ jsx(
42
+ "div",
43
+ {
44
+ className: "markup-annotation",
45
+ style: {
46
+ position: "absolute",
47
+ mixBlendMode: "multiply",
48
+ cursor: "pointer",
49
+ outline: isSelected ? "2px solid #007ACC" : "none",
50
+ outlineOffset: isSelected ? "1px" : "0px",
51
+ left: `${trackedAnnotation.object.rect.origin.x * scale}px`,
52
+ top: `${trackedAnnotation.object.rect.origin.y * scale}px`,
53
+ width: `${trackedAnnotation.object.rect.size.width * scale}px`,
54
+ height: `${trackedAnnotation.object.rect.size.height * scale}px`,
55
+ zIndex: 1
56
+ },
57
+ onMouseDown: handleClick
58
+ }
59
+ )
60
+ ] });
61
+ }
62
+
63
+ // src/preact/components/text-markup/highlight.tsx
64
+ import { Fragment as Fragment2, jsx as jsx2 } from "preact/jsx-runtime";
65
+ function Highlight({ color = "#FFFF00", opacity = 0.5, rects, scale }) {
66
+ return /* @__PURE__ */ jsx2(Fragment2, { children: rects.map((b, i) => /* @__PURE__ */ jsx2(
86
67
  "div",
87
68
  {
88
- className: "highlight-annotation",
89
69
  style: {
90
70
  position: "absolute",
91
- mixBlendMode: "multiply",
92
- cursor: "pointer",
93
- outline: isSelected ? "2px solid #007ACC" : "none",
94
- left: `${annotation.rect.origin.x * scale}px`,
95
- top: `${annotation.rect.origin.y * scale}px`,
96
- width: `${annotation.rect.size.width * scale}px`,
97
- height: `${annotation.rect.size.height * scale}px`
98
- },
99
- onMouseDown: handleClick,
100
- children: annotation.segmentRects.map((rect, index) => /* @__PURE__ */ jsx(
101
- "div",
102
- {
103
- style: {
104
- position: "absolute",
105
- left: `${(rect.origin.x - annotation.rect.origin.x) * scale}px`,
106
- top: `${(rect.origin.y - annotation.rect.origin.y) * scale}px`,
107
- width: `${rect.size.width * scale}px`,
108
- height: `${rect.size.height * scale}px`,
109
- backgroundColor: rgbaColor
110
- }
111
- },
112
- index
113
- ))
114
- }
115
- ) });
71
+ left: b.origin.x * scale,
72
+ top: b.origin.y * scale,
73
+ width: b.size.width * scale,
74
+ height: b.size.height * scale,
75
+ background: color,
76
+ opacity,
77
+ pointerEvents: "none"
78
+ }
79
+ },
80
+ i
81
+ )) });
116
82
  }
117
83
 
118
- // src/preact/components/annotation-layer.tsx
119
- import { usePointerHandlers } from "@embedpdf/plugin-interaction-manager/preact";
120
- import { jsx as jsx2 } from "preact/jsx-runtime";
121
- function AnnotationLayer({ pageIndex, scale, style, ...props }) {
84
+ // src/preact/components/text-markup/underline.tsx
85
+ import { Fragment as Fragment3, jsx as jsx3 } from "preact/jsx-runtime";
86
+ function Underline({ color = "#FFFF00", opacity = 0.5, rects, scale }) {
87
+ const thickness = 2 * scale;
88
+ return /* @__PURE__ */ jsx3(Fragment3, { children: rects.map((r, i) => /* @__PURE__ */ jsx3(
89
+ "div",
90
+ {
91
+ style: {
92
+ position: "absolute",
93
+ left: r.origin.x * scale,
94
+ top: (r.origin.y + r.size.height) * scale - thickness,
95
+ width: r.size.width * scale,
96
+ height: thickness,
97
+ background: color,
98
+ opacity,
99
+ pointerEvents: "none"
100
+ }
101
+ },
102
+ i
103
+ )) });
104
+ }
105
+
106
+ // src/preact/components/text-markup/strikeout.tsx
107
+ import { Fragment as Fragment4, jsx as jsx4 } from "preact/jsx-runtime";
108
+ function Strikeout({ color = "#FFFF00", opacity = 0.5, rects, scale }) {
109
+ const thickness = 2 * scale;
110
+ return /* @__PURE__ */ jsx4(Fragment4, { children: rects.map((r, i) => /* @__PURE__ */ jsx4(
111
+ "div",
112
+ {
113
+ style: {
114
+ position: "absolute",
115
+ left: r.origin.x * scale,
116
+ top: (r.origin.y + r.size.height / 2) * scale - thickness / 2,
117
+ width: r.size.width * scale,
118
+ height: thickness,
119
+ background: color,
120
+ opacity,
121
+ pointerEvents: "none"
122
+ }
123
+ },
124
+ i
125
+ )) });
126
+ }
127
+
128
+ // src/preact/components/text-markup/squiggly.tsx
129
+ import { Fragment as Fragment5, jsx as jsx5 } from "preact/jsx-runtime";
130
+ function Squiggly({ color = "#FFFF00", opacity = 0.5, rects, scale }) {
131
+ const amplitude = 2 * scale;
132
+ const period = 6 * scale;
133
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${period}" height="${amplitude * 2}" viewBox="0 0 ${period} ${amplitude * 2}">
134
+ <path d="M0 ${amplitude} Q ${period / 4} 0 ${period / 2} ${amplitude} T ${period} ${amplitude}"
135
+ fill="none" stroke="${color}" stroke-width="${amplitude}" stroke-linecap="round"/>
136
+ </svg>`;
137
+ const svgDataUri = `url("data:image/svg+xml;utf8,${encodeURIComponent(svg)}")`;
138
+ return /* @__PURE__ */ jsx5(Fragment5, { children: rects.map((r, i) => /* @__PURE__ */ jsx5(
139
+ "div",
140
+ {
141
+ style: {
142
+ position: "absolute",
143
+ left: r.origin.x * scale,
144
+ top: (r.origin.y + r.size.height) * scale - amplitude,
145
+ width: r.size.width * scale,
146
+ height: amplitude * 2,
147
+ backgroundImage: svgDataUri,
148
+ backgroundRepeat: "repeat-x",
149
+ backgroundSize: `${period}px ${amplitude * 2}px`,
150
+ opacity,
151
+ pointerEvents: "none"
152
+ }
153
+ },
154
+ i
155
+ )) });
156
+ }
157
+
158
+ // src/preact/components/annotations.tsx
159
+ import { Fragment as Fragment6, jsx as jsx6 } from "preact/jsx-runtime";
160
+ function Annotations({ pageIndex, scale }) {
122
161
  const { provides: annotationProvides } = useAnnotationCapability();
123
162
  const [annotations, setAnnotations] = useState([]);
124
163
  const { register } = usePointerHandlers({ pageIndex });
125
- const [selectionState, setSelectionState] = useState({ selectedPageIndex: void 0, selectedAnnotationId: void 0 });
164
+ const [selectionState, setSelectionState] = useState(null);
126
165
  useEffect(() => {
127
166
  if (annotationProvides) {
128
167
  annotationProvides.onStateChange((state) => {
129
168
  setAnnotations(getAnnotationsByPageIndex(state, pageIndex));
130
- setSelectionState({
131
- selectedPageIndex: state.selectedAnnotation?.pageIndex,
132
- selectedAnnotationId: state.selectedAnnotation?.annotationId
133
- });
169
+ setSelectionState(getSelectedAnnotationByPageIndex(state, pageIndex));
134
170
  });
135
171
  }
136
172
  }, [annotationProvides]);
@@ -147,31 +183,177 @@ function AnnotationLayer({ pageIndex, scale, style, ...props }) {
147
183
  useEffect(() => {
148
184
  return register(handlers);
149
185
  }, [register, handlers]);
150
- return /* @__PURE__ */ jsx2(
186
+ return /* @__PURE__ */ jsx6(Fragment6, { children: annotations.map((annotation) => {
187
+ const isSelected = selectionState?.localId === annotation.localId;
188
+ switch (annotation.object.type) {
189
+ case PdfAnnotationSubtype.UNDERLINE:
190
+ return /* @__PURE__ */ jsx6(
191
+ SelectableAnnotationContainer,
192
+ {
193
+ trackedAnnotation: annotation,
194
+ scale,
195
+ isSelected,
196
+ pageIndex,
197
+ children: /* @__PURE__ */ jsx6(
198
+ Underline,
199
+ {
200
+ color: annotation.object.color,
201
+ opacity: annotation.object.opacity,
202
+ rects: annotation.object.segmentRects,
203
+ scale
204
+ }
205
+ )
206
+ },
207
+ annotation.localId
208
+ );
209
+ case PdfAnnotationSubtype.STRIKEOUT:
210
+ return /* @__PURE__ */ jsx6(
211
+ SelectableAnnotationContainer,
212
+ {
213
+ trackedAnnotation: annotation,
214
+ scale,
215
+ isSelected,
216
+ pageIndex,
217
+ children: /* @__PURE__ */ jsx6(
218
+ Strikeout,
219
+ {
220
+ color: annotation.object.color,
221
+ opacity: annotation.object.opacity,
222
+ rects: annotation.object.segmentRects,
223
+ scale
224
+ }
225
+ )
226
+ },
227
+ annotation.localId
228
+ );
229
+ case PdfAnnotationSubtype.SQUIGGLY:
230
+ return /* @__PURE__ */ jsx6(
231
+ SelectableAnnotationContainer,
232
+ {
233
+ trackedAnnotation: annotation,
234
+ scale,
235
+ isSelected,
236
+ pageIndex,
237
+ children: /* @__PURE__ */ jsx6(
238
+ Squiggly,
239
+ {
240
+ color: annotation.object.color,
241
+ opacity: annotation.object.opacity,
242
+ rects: annotation.object.segmentRects,
243
+ scale
244
+ }
245
+ )
246
+ },
247
+ annotation.localId
248
+ );
249
+ case PdfAnnotationSubtype.HIGHLIGHT:
250
+ return /* @__PURE__ */ jsx6(
251
+ SelectableAnnotationContainer,
252
+ {
253
+ trackedAnnotation: annotation,
254
+ scale,
255
+ isSelected,
256
+ pageIndex,
257
+ children: /* @__PURE__ */ jsx6(
258
+ Highlight,
259
+ {
260
+ color: annotation.object.color,
261
+ opacity: annotation.object.opacity,
262
+ rects: annotation.object.segmentRects,
263
+ scale
264
+ }
265
+ )
266
+ },
267
+ annotation.localId
268
+ );
269
+ default:
270
+ return null;
271
+ }
272
+ }) });
273
+ }
274
+
275
+ // src/preact/components/text-markup.tsx
276
+ import { PdfAnnotationSubtype as PdfAnnotationSubtype2 } from "@embedpdf/models";
277
+ import { useSelectionCapability as useSelectionCapability2 } from "@embedpdf/plugin-selection/preact";
278
+ import { useEffect as useEffect2, useState as useState2 } from "preact/hooks";
279
+ import { jsx as jsx7 } from "preact/jsx-runtime";
280
+ function TextMarkup({ pageIndex, scale }) {
281
+ const { provides: selectionProvides } = useSelectionCapability2();
282
+ const { provides: annotationProvides } = useAnnotationCapability();
283
+ const [rects, setRects] = useState2([]);
284
+ const [activeTool, setActiveTool] = useState2({ mode: null, defaults: null });
285
+ useEffect2(() => {
286
+ if (!selectionProvides) return;
287
+ const off = selectionProvides.onSelectionChange(() => {
288
+ setRects(selectionProvides.getHighlightRectsForPage(pageIndex));
289
+ });
290
+ return off;
291
+ }, [selectionProvides, pageIndex]);
292
+ useEffect2(() => {
293
+ if (!annotationProvides) return;
294
+ const off = annotationProvides.onActiveToolChange(setActiveTool);
295
+ return off;
296
+ }, [annotationProvides]);
297
+ switch (activeTool.mode) {
298
+ case PdfAnnotationSubtype2.UNDERLINE:
299
+ return /* @__PURE__ */ jsx7(
300
+ Underline,
301
+ {
302
+ color: activeTool.defaults?.color,
303
+ opacity: activeTool.defaults?.opacity,
304
+ rects,
305
+ scale
306
+ }
307
+ );
308
+ case PdfAnnotationSubtype2.HIGHLIGHT:
309
+ return /* @__PURE__ */ jsx7(
310
+ Highlight,
311
+ {
312
+ color: activeTool.defaults?.color,
313
+ opacity: activeTool.defaults?.opacity,
314
+ rects,
315
+ scale
316
+ }
317
+ );
318
+ case PdfAnnotationSubtype2.STRIKEOUT:
319
+ return /* @__PURE__ */ jsx7(
320
+ Strikeout,
321
+ {
322
+ color: activeTool.defaults?.color,
323
+ opacity: activeTool.defaults?.opacity,
324
+ rects,
325
+ scale
326
+ }
327
+ );
328
+ case PdfAnnotationSubtype2.SQUIGGLY:
329
+ return /* @__PURE__ */ jsx7(
330
+ Squiggly,
331
+ {
332
+ color: activeTool.defaults?.color,
333
+ opacity: activeTool.defaults?.opacity,
334
+ rects,
335
+ scale
336
+ }
337
+ );
338
+ default:
339
+ return null;
340
+ }
341
+ }
342
+
343
+ // src/preact/components/annotation-layer.tsx
344
+ import { jsx as jsx8, jsxs as jsxs2 } from "preact/jsx-runtime";
345
+ function AnnotationLayer({ pageIndex, scale, style, ...props }) {
346
+ return /* @__PURE__ */ jsxs2(
151
347
  "div",
152
348
  {
153
349
  style: {
154
350
  ...style
155
351
  },
156
352
  ...props,
157
- children: annotations.map((annotation) => {
158
- const isSelected = selectionState.selectedPageIndex === pageIndex && selectionState.selectedAnnotationId === annotation.id;
159
- switch (annotation.type) {
160
- case PdfAnnotationSubtype.HIGHLIGHT:
161
- return /* @__PURE__ */ jsx2(
162
- HighlightAnnotation,
163
- {
164
- annotation,
165
- scale,
166
- isSelected,
167
- pageIndex
168
- },
169
- annotation.id
170
- );
171
- default:
172
- return null;
173
- }
174
- })
353
+ children: [
354
+ /* @__PURE__ */ jsx8(Annotations, { pageIndex, scale }),
355
+ /* @__PURE__ */ jsx8(TextMarkup, { pageIndex, scale })
356
+ ]
175
357
  }
176
358
  );
177
359
  }