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