@embedpdf/plugin-annotation 1.0.16 → 1.0.18
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.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +189 -189
- package/dist/index.js.map +1 -1
- package/dist/lib/actions.d.ts +8 -26
- package/dist/lib/annotation-plugin.d.ts +1 -1
- package/dist/lib/helpers.d.ts +5 -1
- package/dist/lib/selectors.d.ts +29 -7
- package/dist/lib/types.d.ts +18 -19
- package/dist/preact/index.cjs +1 -1
- package/dist/preact/index.cjs.map +1 -1
- package/dist/preact/index.js +78 -77
- package/dist/preact/index.js.map +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +78 -77
- package/dist/react/index.js.map +1 -1
- package/package.json +9 -9
- package/dist/lib/utils.d.ts +0 -11
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BasePlugin, createBehaviorEmitter, SET_DOCUMENT } from "@embedpdf/core";
|
|
2
|
-
import { PdfAnnotationLineEnding, rectFromPoints, expandRect, rotateAndTranslatePoint,
|
|
2
|
+
import { PdfAnnotationSubtype, PdfAnnotationLineEnding, rectFromPoints, expandRect, rotateAndTranslatePoint, PdfBlendMode, uuidV4, ignore, PdfTaskHelper, PdfErrorCode, Rotation, AppearanceMode, Task, PdfVerticalAlignment, PdfTextAlignment, PdfStandardFont, PdfAnnotationBorderStyle } from "@embedpdf/models";
|
|
3
3
|
const ANNOTATION_PLUGIN_ID = "annotation";
|
|
4
4
|
const manifest = {
|
|
5
5
|
id: ANNOTATION_PLUGIN_ID,
|
|
@@ -10,11 +10,11 @@ const manifest = {
|
|
|
10
10
|
optional: ["history"],
|
|
11
11
|
defaultConfig: {
|
|
12
12
|
enabled: true,
|
|
13
|
-
autoCommit: true
|
|
13
|
+
autoCommit: true,
|
|
14
|
+
annotationAuthor: "Guest"
|
|
14
15
|
}
|
|
15
16
|
};
|
|
16
17
|
const SET_ANNOTATIONS = "ANNOTATION/SET_ANNOTATIONS";
|
|
17
|
-
const REINDEX_PAGE_ANNOTATIONS = "ANNOTATION/REINDEX_PAGE";
|
|
18
18
|
const SELECT_ANNOTATION = "ANNOTATION/SELECT_ANNOTATION";
|
|
19
19
|
const DESELECT_ANNOTATION = "ANNOTATION/DESELECT_ANNOTATION";
|
|
20
20
|
const UPDATE_TOOL_DEFAULTS = "ANNOTATION/UPDATE_TOOL_DEFAULTS";
|
|
@@ -23,20 +23,15 @@ const CREATE_ANNOTATION = "ANNOTATION/CREATE_ANNOTATION";
|
|
|
23
23
|
const PATCH_ANNOTATION = "ANNOTATION/PATCH_ANNOTATION";
|
|
24
24
|
const DELETE_ANNOTATION = "ANNOTATION/DELETE_ANNOTATION";
|
|
25
25
|
const COMMIT_PENDING_CHANGES = "ANNOTATION/COMMIT";
|
|
26
|
-
const STORE_PDF_ID = "ANNOTATION/STORE_PDF_ID";
|
|
27
26
|
const PURGE_ANNOTATION = "ANNOTATION/PURGE_ANNOTATION";
|
|
28
27
|
const SET_ACTIVE_VARIANT = "ANNOTATION/SET_ACTIVE_VARIANT";
|
|
29
28
|
const setAnnotations = (p) => ({
|
|
30
29
|
type: SET_ANNOTATIONS,
|
|
31
30
|
payload: p
|
|
32
31
|
});
|
|
33
|
-
const
|
|
34
|
-
type: REINDEX_PAGE_ANNOTATIONS,
|
|
35
|
-
payload: { pageIndex }
|
|
36
|
-
});
|
|
37
|
-
const selectAnnotation = (pageIndex, localId) => ({
|
|
32
|
+
const selectAnnotation = (pageIndex, id) => ({
|
|
38
33
|
type: SELECT_ANNOTATION,
|
|
39
|
-
payload: { pageIndex,
|
|
34
|
+
payload: { pageIndex, id }
|
|
40
35
|
});
|
|
41
36
|
const deselectAnnotation = () => ({ type: DESELECT_ANNOTATION });
|
|
42
37
|
const updateToolDefaults = (variantKey, patch) => ({ type: UPDATE_TOOL_DEFAULTS, payload: { variantKey, patch } });
|
|
@@ -44,23 +39,19 @@ const addColorPreset = (c) => ({
|
|
|
44
39
|
type: ADD_COLOR_PRESET,
|
|
45
40
|
payload: c
|
|
46
41
|
});
|
|
47
|
-
const createAnnotation = (pageIndex,
|
|
42
|
+
const createAnnotation = (pageIndex, annotation) => ({
|
|
48
43
|
type: CREATE_ANNOTATION,
|
|
49
|
-
payload: { pageIndex,
|
|
44
|
+
payload: { pageIndex, annotation }
|
|
50
45
|
});
|
|
51
|
-
const patchAnnotation = (pageIndex,
|
|
46
|
+
const patchAnnotation = (pageIndex, id, patch) => ({
|
|
52
47
|
type: PATCH_ANNOTATION,
|
|
53
|
-
payload: { pageIndex,
|
|
48
|
+
payload: { pageIndex, id, patch }
|
|
54
49
|
});
|
|
55
|
-
const deleteAnnotation = (pageIndex,
|
|
50
|
+
const deleteAnnotation = (pageIndex, id) => ({
|
|
56
51
|
type: DELETE_ANNOTATION,
|
|
57
|
-
payload: { pageIndex,
|
|
52
|
+
payload: { pageIndex, id }
|
|
58
53
|
});
|
|
59
54
|
const commitPendingChanges = () => ({ type: COMMIT_PENDING_CHANGES });
|
|
60
|
-
const storePdfId = (uid, pdfId) => ({
|
|
61
|
-
type: STORE_PDF_ID,
|
|
62
|
-
payload: { uid, pdfId }
|
|
63
|
-
});
|
|
64
55
|
const purgeAnnotation = (uid) => ({
|
|
65
56
|
type: PURGE_ANNOTATION,
|
|
66
57
|
payload: { uid }
|
|
@@ -69,18 +60,72 @@ const setActiveVariant = (k) => ({
|
|
|
69
60
|
type: SET_ACTIVE_VARIANT,
|
|
70
61
|
payload: k
|
|
71
62
|
});
|
|
72
|
-
const makeUid$1 = (pageIndex, localId) => `p${pageIndex}#${localId}`;
|
|
73
|
-
const parseUid = (uid) => {
|
|
74
|
-
const [pg, rest] = uid.slice(1).split("#");
|
|
75
|
-
return { pageIndex: Number(pg), localId: Number(rest) };
|
|
76
|
-
};
|
|
77
63
|
const makeVariantKey = (subtype, intent) => intent ? `${subtype}#${intent}` : `${subtype}`;
|
|
78
64
|
const parseVariantKey = (key) => {
|
|
79
65
|
const [subStr, intent] = key.split("#");
|
|
80
66
|
return { subtype: Number(subStr), intent };
|
|
81
67
|
};
|
|
82
68
|
const variantKeyFromAnnotation = (a) => makeVariantKey(a.type, a.intent);
|
|
83
|
-
|
|
69
|
+
function isInk(a) {
|
|
70
|
+
return a.object.type === PdfAnnotationSubtype.INK;
|
|
71
|
+
}
|
|
72
|
+
function isCircle(a) {
|
|
73
|
+
return a.object.type === PdfAnnotationSubtype.CIRCLE;
|
|
74
|
+
}
|
|
75
|
+
function isPolygon(a) {
|
|
76
|
+
return a.object.type === PdfAnnotationSubtype.POLYGON;
|
|
77
|
+
}
|
|
78
|
+
function isSquare(a) {
|
|
79
|
+
return a.object.type === PdfAnnotationSubtype.SQUARE;
|
|
80
|
+
}
|
|
81
|
+
function isLine(a) {
|
|
82
|
+
return a.object.type === PdfAnnotationSubtype.LINE;
|
|
83
|
+
}
|
|
84
|
+
function isPolyline(a) {
|
|
85
|
+
return a.object.type === PdfAnnotationSubtype.POLYLINE;
|
|
86
|
+
}
|
|
87
|
+
function isHighlight(a) {
|
|
88
|
+
return a.object.type === PdfAnnotationSubtype.HIGHLIGHT;
|
|
89
|
+
}
|
|
90
|
+
function isUnderline(a) {
|
|
91
|
+
return a.object.type === PdfAnnotationSubtype.UNDERLINE;
|
|
92
|
+
}
|
|
93
|
+
function isStrikeout(a) {
|
|
94
|
+
return a.object.type === PdfAnnotationSubtype.STRIKEOUT;
|
|
95
|
+
}
|
|
96
|
+
function isSquiggly(a) {
|
|
97
|
+
return a.object.type === PdfAnnotationSubtype.SQUIGGLY;
|
|
98
|
+
}
|
|
99
|
+
function isTextMarkup(a) {
|
|
100
|
+
return isHighlight(a) || isUnderline(a) || isStrikeout(a) || isSquiggly(a);
|
|
101
|
+
}
|
|
102
|
+
function isFreeText(a) {
|
|
103
|
+
return a.object.type === PdfAnnotationSubtype.FREETEXT;
|
|
104
|
+
}
|
|
105
|
+
function isStamp(a) {
|
|
106
|
+
return a.object.type === PdfAnnotationSubtype.STAMP;
|
|
107
|
+
}
|
|
108
|
+
function isText(a) {
|
|
109
|
+
return a.object.type === PdfAnnotationSubtype.TEXT;
|
|
110
|
+
}
|
|
111
|
+
function isSidebarAnnotation(a) {
|
|
112
|
+
return isTextMarkup(a) || isInk(a) || isSquare(a) || isCircle(a) || isPolygon(a) || isLine(a) || isPolyline(a) || isFreeText(a) || isStamp(a);
|
|
113
|
+
}
|
|
114
|
+
function isHighlightDefaults(defaults) {
|
|
115
|
+
return defaults.subtype === PdfAnnotationSubtype.HIGHLIGHT;
|
|
116
|
+
}
|
|
117
|
+
function isUnderlineDefaults(defaults) {
|
|
118
|
+
return defaults.subtype === PdfAnnotationSubtype.UNDERLINE;
|
|
119
|
+
}
|
|
120
|
+
function isStrikeoutDefaults(defaults) {
|
|
121
|
+
return defaults.subtype === PdfAnnotationSubtype.STRIKEOUT;
|
|
122
|
+
}
|
|
123
|
+
function isSquigglyDefaults(defaults) {
|
|
124
|
+
return defaults.subtype === PdfAnnotationSubtype.SQUIGGLY;
|
|
125
|
+
}
|
|
126
|
+
function isTextMarkupDefaults(defaults) {
|
|
127
|
+
return isHighlightDefaults(defaults) || isUnderlineDefaults(defaults) || isStrikeoutDefaults(defaults) || isSquigglyDefaults(defaults);
|
|
128
|
+
}
|
|
84
129
|
const getAnnotationsByPageIndex = (s, page) => (s.pages[page] ?? []).map((uid) => s.byUid[uid]);
|
|
85
130
|
const getAnnotations = (s) => {
|
|
86
131
|
const out = {};
|
|
@@ -88,11 +133,6 @@ const getAnnotations = (s) => {
|
|
|
88
133
|
return out;
|
|
89
134
|
};
|
|
90
135
|
const getSelectedAnnotation = (s) => s.selectedUid ? s.byUid[s.selectedUid] : null;
|
|
91
|
-
const getSelectedAnnotationWithPageIndex = (s) => {
|
|
92
|
-
if (!s.selectedUid) return null;
|
|
93
|
-
const { pageIndex, localId } = parseUid(s.selectedUid);
|
|
94
|
-
return { pageIndex, localId, annotation: s.byUid[s.selectedUid].object };
|
|
95
|
-
};
|
|
96
136
|
const getSelectedAnnotationByPageIndex = (s, pageIndex) => {
|
|
97
137
|
if (!s.selectedUid) return null;
|
|
98
138
|
const pageUids = s.pages[pageIndex] ?? [];
|
|
@@ -103,7 +143,7 @@ const getSelectedAnnotationByPageIndex = (s, pageIndex) => {
|
|
|
103
143
|
};
|
|
104
144
|
const isInAnnotationVariant = (s) => s.activeVariant !== null;
|
|
105
145
|
const getSelectedAnnotationVariant = (s) => s.activeVariant;
|
|
106
|
-
const isAnnotationSelected = (s,
|
|
146
|
+
const isAnnotationSelected = (s, id) => s.selectedUid === id;
|
|
107
147
|
function getToolDefaultsBySubtypeAndIntent(state, subtype, intent) {
|
|
108
148
|
const variantKey = makeVariantKey(subtype, intent ?? void 0);
|
|
109
149
|
const fallbackKey = makeVariantKey(subtype);
|
|
@@ -115,6 +155,46 @@ function getToolDefaultsBySubtypeAndIntent(state, subtype, intent) {
|
|
|
115
155
|
}
|
|
116
156
|
return defaults;
|
|
117
157
|
}
|
|
158
|
+
const getSidebarAnnotationsWithRepliesGroupedByPage = (s) => {
|
|
159
|
+
const repliesByParent = {};
|
|
160
|
+
for (const uidList of Object.values(s.pages)) {
|
|
161
|
+
for (const uid of uidList) {
|
|
162
|
+
const ta = s.byUid[uid];
|
|
163
|
+
if (isText(ta)) {
|
|
164
|
+
const parentId = ta.object.inReplyToId;
|
|
165
|
+
if (parentId) (repliesByParent[parentId] || (repliesByParent[parentId] = [])).push(ta);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const out = {};
|
|
170
|
+
for (const [pageStr, uidList] of Object.entries(s.pages)) {
|
|
171
|
+
const page = Number(pageStr);
|
|
172
|
+
const pageAnnotations = [];
|
|
173
|
+
for (const uid of uidList) {
|
|
174
|
+
const ta = s.byUid[uid];
|
|
175
|
+
if (isSidebarAnnotation(ta)) {
|
|
176
|
+
pageAnnotations.push({
|
|
177
|
+
page,
|
|
178
|
+
annotation: ta,
|
|
179
|
+
replies: repliesByParent[ta.object.id] ?? []
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (pageAnnotations.length > 0) {
|
|
184
|
+
out[page] = pageAnnotations;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return out;
|
|
188
|
+
};
|
|
189
|
+
const getSidebarAnnotationsWithReplies = (s) => {
|
|
190
|
+
const grouped = getSidebarAnnotationsWithRepliesGroupedByPage(s);
|
|
191
|
+
const out = [];
|
|
192
|
+
const sortedPages = Object.keys(grouped).map(Number).sort((a, b) => a - b);
|
|
193
|
+
for (const page of sortedPages) {
|
|
194
|
+
out.push(...grouped[page]);
|
|
195
|
+
}
|
|
196
|
+
return out;
|
|
197
|
+
};
|
|
118
198
|
function createArrowHandler(isClosed) {
|
|
119
199
|
const calculateGeometry = (sw) => {
|
|
120
200
|
const len = sw * 9;
|
|
@@ -315,60 +395,6 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
|
|
|
315
395
|
deriveRect,
|
|
316
396
|
lineRectWithEndings
|
|
317
397
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
318
|
-
function isInk(a) {
|
|
319
|
-
return a.object.type === PdfAnnotationSubtype.INK;
|
|
320
|
-
}
|
|
321
|
-
function isCircle(a) {
|
|
322
|
-
return a.object.type === PdfAnnotationSubtype.CIRCLE;
|
|
323
|
-
}
|
|
324
|
-
function isPolygon(a) {
|
|
325
|
-
return a.object.type === PdfAnnotationSubtype.POLYGON;
|
|
326
|
-
}
|
|
327
|
-
function isSquare(a) {
|
|
328
|
-
return a.object.type === PdfAnnotationSubtype.SQUARE;
|
|
329
|
-
}
|
|
330
|
-
function isLine(a) {
|
|
331
|
-
return a.object.type === PdfAnnotationSubtype.LINE;
|
|
332
|
-
}
|
|
333
|
-
function isPolyline(a) {
|
|
334
|
-
return a.object.type === PdfAnnotationSubtype.POLYLINE;
|
|
335
|
-
}
|
|
336
|
-
function isHighlight(a) {
|
|
337
|
-
return a.object.type === PdfAnnotationSubtype.HIGHLIGHT;
|
|
338
|
-
}
|
|
339
|
-
function isUnderline(a) {
|
|
340
|
-
return a.object.type === PdfAnnotationSubtype.UNDERLINE;
|
|
341
|
-
}
|
|
342
|
-
function isStrikeout(a) {
|
|
343
|
-
return a.object.type === PdfAnnotationSubtype.STRIKEOUT;
|
|
344
|
-
}
|
|
345
|
-
function isSquiggly(a) {
|
|
346
|
-
return a.object.type === PdfAnnotationSubtype.SQUIGGLY;
|
|
347
|
-
}
|
|
348
|
-
function isTextMarkup(a) {
|
|
349
|
-
return isHighlight(a) || isUnderline(a) || isStrikeout(a) || isSquiggly(a);
|
|
350
|
-
}
|
|
351
|
-
function isFreeText(a) {
|
|
352
|
-
return a.object.type === PdfAnnotationSubtype.FREETEXT;
|
|
353
|
-
}
|
|
354
|
-
function isStamp(a) {
|
|
355
|
-
return a.object.type === PdfAnnotationSubtype.STAMP;
|
|
356
|
-
}
|
|
357
|
-
function isHighlightDefaults(defaults) {
|
|
358
|
-
return defaults.subtype === PdfAnnotationSubtype.HIGHLIGHT;
|
|
359
|
-
}
|
|
360
|
-
function isUnderlineDefaults(defaults) {
|
|
361
|
-
return defaults.subtype === PdfAnnotationSubtype.UNDERLINE;
|
|
362
|
-
}
|
|
363
|
-
function isStrikeoutDefaults(defaults) {
|
|
364
|
-
return defaults.subtype === PdfAnnotationSubtype.STRIKEOUT;
|
|
365
|
-
}
|
|
366
|
-
function isSquigglyDefaults(defaults) {
|
|
367
|
-
return defaults.subtype === PdfAnnotationSubtype.SQUIGGLY;
|
|
368
|
-
}
|
|
369
|
-
function isTextMarkupDefaults(defaults) {
|
|
370
|
-
return isHighlightDefaults(defaults) || isUnderlineDefaults(defaults) || isStrikeoutDefaults(defaults) || isSquigglyDefaults(defaults);
|
|
371
|
-
}
|
|
372
398
|
const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
373
399
|
constructor(id, registry, engine, config) {
|
|
374
400
|
super(id, registry);
|
|
@@ -415,12 +441,13 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
415
441
|
}
|
|
416
442
|
});
|
|
417
443
|
(_c = this.selection) == null ? void 0 : _c.onEndSelection(() => {
|
|
418
|
-
var _a2, _b2;
|
|
444
|
+
var _a2, _b2, _c2;
|
|
419
445
|
if (!this.state.activeVariant) return;
|
|
420
446
|
const defaults = this.state.toolDefaults[this.state.activeVariant];
|
|
421
447
|
if (!defaults || !isTextMarkupDefaults(defaults)) return;
|
|
422
448
|
const formattedSelection = (_a2 = this.selection) == null ? void 0 : _a2.getFormattedSelection();
|
|
423
|
-
|
|
449
|
+
const selectionText = (_b2 = this.selection) == null ? void 0 : _b2.getSelectedText();
|
|
450
|
+
if (!formattedSelection || !selectionText) return;
|
|
424
451
|
for (const selection of formattedSelection) {
|
|
425
452
|
const rect = selection.rect;
|
|
426
453
|
const segmentRects = selection.segmentRects;
|
|
@@ -428,18 +455,24 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
428
455
|
const color = defaults.color;
|
|
429
456
|
const opacity = defaults.opacity;
|
|
430
457
|
const blendMode = defaults.blendMode ?? PdfBlendMode.Normal;
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
458
|
+
selectionText.wait((text) => {
|
|
459
|
+
this.createAnnotation(selection.pageIndex, {
|
|
460
|
+
type: subtype,
|
|
461
|
+
rect,
|
|
462
|
+
segmentRects,
|
|
463
|
+
color,
|
|
464
|
+
opacity,
|
|
465
|
+
blendMode,
|
|
466
|
+
pageIndex: selection.pageIndex,
|
|
467
|
+
id: uuidV4(),
|
|
468
|
+
author: this.config.annotationAuthor,
|
|
469
|
+
custom: {
|
|
470
|
+
text: text.join("\n")
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
}, ignore);
|
|
441
474
|
}
|
|
442
|
-
(
|
|
475
|
+
(_c2 = this.selection) == null ? void 0 : _c2.clear();
|
|
443
476
|
});
|
|
444
477
|
}
|
|
445
478
|
registerTool(variantKey, defaults) {
|
|
@@ -508,8 +541,8 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
508
541
|
getColorPresets: () => [...this.state.colorPresets],
|
|
509
542
|
addColorPreset: (color) => this.dispatch(addColorPreset(color)),
|
|
510
543
|
createAnnotation: (pageIndex, annotation, ctx) => this.createAnnotation(pageIndex, annotation, ctx),
|
|
511
|
-
updateAnnotation: (pageIndex,
|
|
512
|
-
deleteAnnotation: (pageIndex,
|
|
544
|
+
updateAnnotation: (pageIndex, id, patch) => this.updateAnnotation(pageIndex, id, patch),
|
|
545
|
+
deleteAnnotation: (pageIndex, id) => this.deleteAnnotation(pageIndex, id),
|
|
513
546
|
renderAnnotation: (options) => this.renderAnnotation(options),
|
|
514
547
|
onStateChange: this.state$.on,
|
|
515
548
|
onActiveVariantChange: this.activeVariantChange$.on,
|
|
@@ -581,10 +614,15 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
581
614
|
this.dispatch(selectAnnotation(pageIndex, annotationId));
|
|
582
615
|
}
|
|
583
616
|
createAnnotation(pageIndex, annotation, ctx) {
|
|
584
|
-
const
|
|
617
|
+
const id = annotation.id;
|
|
585
618
|
const execute = () => {
|
|
586
|
-
this.dispatch(
|
|
587
|
-
|
|
619
|
+
this.dispatch(
|
|
620
|
+
createAnnotation(pageIndex, {
|
|
621
|
+
...annotation,
|
|
622
|
+
author: annotation.author ?? this.config.annotationAuthor
|
|
623
|
+
})
|
|
624
|
+
);
|
|
625
|
+
if (ctx) this.pendingContexts.set(id, ctx);
|
|
588
626
|
};
|
|
589
627
|
if (!this.history) {
|
|
590
628
|
execute();
|
|
@@ -594,9 +632,9 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
594
632
|
const command = {
|
|
595
633
|
execute,
|
|
596
634
|
undo: () => {
|
|
597
|
-
this.pendingContexts.delete(
|
|
635
|
+
this.pendingContexts.delete(id);
|
|
598
636
|
this.dispatch(deselectAnnotation());
|
|
599
|
-
this.dispatch(deleteAnnotation(pageIndex,
|
|
637
|
+
this.dispatch(deleteAnnotation(pageIndex, id));
|
|
600
638
|
}
|
|
601
639
|
};
|
|
602
640
|
this.history.register(command, this.ANNOTATION_HISTORY_TOPIC);
|
|
@@ -606,11 +644,14 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
606
644
|
const merged = { ...original, ...patch };
|
|
607
645
|
return { ...patch, rect: deriveRect(merged) };
|
|
608
646
|
}
|
|
609
|
-
updateAnnotation(pageIndex,
|
|
610
|
-
const originalObject = this.state.byUid[
|
|
611
|
-
const finalPatch = this.buildPatch(originalObject,
|
|
647
|
+
updateAnnotation(pageIndex, id, patch) {
|
|
648
|
+
const originalObject = this.state.byUid[id].object;
|
|
649
|
+
const finalPatch = this.buildPatch(originalObject, {
|
|
650
|
+
...patch,
|
|
651
|
+
author: patch.author ?? this.config.annotationAuthor
|
|
652
|
+
});
|
|
612
653
|
if (!this.history) {
|
|
613
|
-
this.dispatch(patchAnnotation(pageIndex,
|
|
654
|
+
this.dispatch(patchAnnotation(pageIndex, id, finalPatch));
|
|
614
655
|
if (this.config.autoCommit !== false) {
|
|
615
656
|
this.commit();
|
|
616
657
|
}
|
|
@@ -620,27 +661,27 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
620
661
|
Object.keys(patch).map((key) => [key, originalObject[key]])
|
|
621
662
|
);
|
|
622
663
|
const command = {
|
|
623
|
-
execute: () => this.dispatch(patchAnnotation(pageIndex,
|
|
624
|
-
undo: () => this.dispatch(patchAnnotation(pageIndex,
|
|
664
|
+
execute: () => this.dispatch(patchAnnotation(pageIndex, id, finalPatch)),
|
|
665
|
+
undo: () => this.dispatch(patchAnnotation(pageIndex, id, originalPatch))
|
|
625
666
|
};
|
|
626
667
|
this.history.register(command, this.ANNOTATION_HISTORY_TOPIC);
|
|
627
668
|
}
|
|
628
|
-
deleteAnnotation(pageIndex,
|
|
669
|
+
deleteAnnotation(pageIndex, id) {
|
|
629
670
|
if (!this.history) {
|
|
630
671
|
this.dispatch(deselectAnnotation());
|
|
631
|
-
this.dispatch(deleteAnnotation(pageIndex,
|
|
672
|
+
this.dispatch(deleteAnnotation(pageIndex, id));
|
|
632
673
|
if (this.config.autoCommit !== false) {
|
|
633
674
|
this.commit();
|
|
634
675
|
}
|
|
635
676
|
return;
|
|
636
677
|
}
|
|
637
|
-
const originalAnnotation = this.state.byUid[
|
|
678
|
+
const originalAnnotation = this.state.byUid[id].object;
|
|
638
679
|
const command = {
|
|
639
680
|
execute: () => {
|
|
640
681
|
this.dispatch(deselectAnnotation());
|
|
641
|
-
this.dispatch(deleteAnnotation(pageIndex,
|
|
682
|
+
this.dispatch(deleteAnnotation(pageIndex, id));
|
|
642
683
|
},
|
|
643
|
-
undo: () => this.dispatch(createAnnotation(pageIndex,
|
|
684
|
+
undo: () => this.dispatch(createAnnotation(pageIndex, originalAnnotation))
|
|
644
685
|
};
|
|
645
686
|
this.history.register(command, this.ANNOTATION_HISTORY_TOPIC);
|
|
646
687
|
}
|
|
@@ -652,63 +693,45 @@ const _AnnotationPlugin = class _AnnotationPlugin extends BasePlugin {
|
|
|
652
693
|
return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: "Document not found" });
|
|
653
694
|
const creations = [];
|
|
654
695
|
const updates = [];
|
|
655
|
-
const
|
|
656
|
-
const affectedPages = /* @__PURE__ */ new Set();
|
|
696
|
+
const deletions = [];
|
|
657
697
|
for (const [uid, ta] of Object.entries(this.state.byUid)) {
|
|
658
698
|
if (ta.commitState === "synced") continue;
|
|
659
|
-
const
|
|
660
|
-
const page = doc.pages.find((p) => p.index === pageIndex);
|
|
699
|
+
const page = doc.pages.find((p) => p.index === ta.object.pageIndex);
|
|
661
700
|
if (!page) continue;
|
|
662
|
-
affectedPages.add(pageIndex);
|
|
663
701
|
switch (ta.commitState) {
|
|
664
702
|
case "new":
|
|
665
|
-
const ctx = this.pendingContexts.get(ta.
|
|
703
|
+
const ctx = this.pendingContexts.get(ta.object.id);
|
|
666
704
|
const task2 = this.engine.createPageAnnotation(doc, page, ta.object, ctx);
|
|
667
|
-
task2.wait((
|
|
668
|
-
this.
|
|
669
|
-
this.pendingContexts.delete(ta.localId);
|
|
705
|
+
task2.wait(() => {
|
|
706
|
+
this.pendingContexts.delete(ta.object.id);
|
|
670
707
|
}, ignore);
|
|
671
708
|
creations.push(task2);
|
|
672
709
|
break;
|
|
673
710
|
case "dirty":
|
|
674
|
-
updates.push(
|
|
675
|
-
this.engine.updatePageAnnotation(doc, page, { ...ta.object, id: ta.pdfId })
|
|
676
|
-
);
|
|
711
|
+
updates.push(this.engine.updatePageAnnotation(doc, page, ta.object));
|
|
677
712
|
break;
|
|
678
713
|
case "deleted":
|
|
679
|
-
|
|
680
|
-
deletionsByPage.set(pageIndex, []);
|
|
681
|
-
}
|
|
682
|
-
deletionsByPage.get(pageIndex).push({ ta, uid });
|
|
714
|
+
deletions.push({ ta, uid });
|
|
683
715
|
break;
|
|
684
716
|
}
|
|
685
717
|
}
|
|
686
718
|
const deletionTasks = [];
|
|
687
|
-
for (const
|
|
688
|
-
const page = doc.pages.find((p) => p.index === pageIndex);
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
const removeTask = this.engine.removePageAnnotation(doc, page, {
|
|
694
|
-
...ta.object,
|
|
695
|
-
id: ta.pdfId
|
|
696
|
-
});
|
|
697
|
-
removeTask.wait(() => {
|
|
698
|
-
this.dispatch(purgeAnnotation(uid));
|
|
699
|
-
task2.resolve(true);
|
|
700
|
-
}, task2.fail);
|
|
701
|
-
deletionTasks.push(task2);
|
|
702
|
-
} else {
|
|
719
|
+
for (const { ta, uid } of deletions) {
|
|
720
|
+
const page = doc.pages.find((p) => p.index === ta.object.pageIndex);
|
|
721
|
+
if (ta.commitState === "deleted" && ta.object.id) {
|
|
722
|
+
const task2 = new Task();
|
|
723
|
+
const removeTask = this.engine.removePageAnnotation(doc, page, ta.object);
|
|
724
|
+
removeTask.wait(() => {
|
|
703
725
|
this.dispatch(purgeAnnotation(uid));
|
|
704
|
-
|
|
726
|
+
task2.resolve(true);
|
|
727
|
+
}, task2.fail);
|
|
728
|
+
deletionTasks.push(task2);
|
|
729
|
+
} else {
|
|
730
|
+
this.dispatch(purgeAnnotation(uid));
|
|
705
731
|
}
|
|
706
732
|
}
|
|
707
733
|
const allWriteTasks = [...creations, ...updates, ...deletionTasks];
|
|
708
734
|
Task.allSettled(allWriteTasks).wait(() => {
|
|
709
|
-
for (const pageIndex of affectedPages) {
|
|
710
|
-
this.dispatch(reindexPageAnnotations(pageIndex));
|
|
711
|
-
}
|
|
712
735
|
this.dispatch(commitPendingChanges());
|
|
713
736
|
task.resolve(true);
|
|
714
737
|
}, task.fail);
|
|
@@ -906,10 +929,9 @@ const reducer = (state, action) => {
|
|
|
906
929
|
for (const uid of oldUidsOnPage) {
|
|
907
930
|
delete newByUid[uid];
|
|
908
931
|
}
|
|
909
|
-
const newUidsOnPage = list.map((a
|
|
910
|
-
const
|
|
911
|
-
|
|
912
|
-
newByUid[uid] = { localId, pdfId: a.id, commitState: "synced", object: a };
|
|
932
|
+
const newUidsOnPage = list.map((a) => {
|
|
933
|
+
const uid = a.id;
|
|
934
|
+
newByUid[uid] = { commitState: "synced", object: a };
|
|
913
935
|
return uid;
|
|
914
936
|
});
|
|
915
937
|
newPages[pageIndex] = newUidsOnPage;
|
|
@@ -922,7 +944,7 @@ const reducer = (state, action) => {
|
|
|
922
944
|
case SELECT_ANNOTATION:
|
|
923
945
|
return {
|
|
924
946
|
...state,
|
|
925
|
-
selectedUid:
|
|
947
|
+
selectedUid: action.payload.id
|
|
926
948
|
};
|
|
927
949
|
case DESELECT_ANNOTATION:
|
|
928
950
|
return { ...state, selectedUid: null };
|
|
@@ -942,22 +964,21 @@ const reducer = (state, action) => {
|
|
|
942
964
|
}
|
|
943
965
|
/* ───── create ───── */
|
|
944
966
|
case CREATE_ANNOTATION: {
|
|
945
|
-
const { pageIndex,
|
|
946
|
-
const uid =
|
|
967
|
+
const { pageIndex, annotation } = action.payload;
|
|
968
|
+
const uid = annotation.id;
|
|
947
969
|
return {
|
|
948
970
|
...state,
|
|
949
971
|
pages: { ...state.pages, [pageIndex]: [...state.pages[pageIndex] ?? [], uid] },
|
|
950
972
|
byUid: {
|
|
951
973
|
...state.byUid,
|
|
952
|
-
[uid]: {
|
|
974
|
+
[uid]: { commitState: "new", object: annotation }
|
|
953
975
|
},
|
|
954
976
|
hasPendingChanges: true
|
|
955
977
|
};
|
|
956
978
|
}
|
|
957
979
|
/* ───── delete ───── */
|
|
958
980
|
case DELETE_ANNOTATION: {
|
|
959
|
-
const { pageIndex,
|
|
960
|
-
const uid = makeUid$1(pageIndex, localId);
|
|
981
|
+
const { pageIndex, id: uid } = action.payload;
|
|
961
982
|
if (!state.byUid[uid]) return state;
|
|
962
983
|
return {
|
|
963
984
|
...state,
|
|
@@ -974,7 +995,7 @@ const reducer = (state, action) => {
|
|
|
974
995
|
}
|
|
975
996
|
/* ───── field edits ───── */
|
|
976
997
|
case PATCH_ANNOTATION: {
|
|
977
|
-
const uid =
|
|
998
|
+
const uid = action.payload.id;
|
|
978
999
|
return patchAnno(state, uid, action.payload.patch);
|
|
979
1000
|
}
|
|
980
1001
|
/* ───── commit bookkeeping ───── */
|
|
@@ -988,30 +1009,6 @@ const reducer = (state, action) => {
|
|
|
988
1009
|
}
|
|
989
1010
|
return { ...state, byUid: cleaned, hasPendingChanges: false };
|
|
990
1011
|
}
|
|
991
|
-
case REINDEX_PAGE_ANNOTATIONS: {
|
|
992
|
-
const { pageIndex } = action.payload;
|
|
993
|
-
const newByUid = { ...state.byUid };
|
|
994
|
-
const uidsOnPage = state.pages[pageIndex] || [];
|
|
995
|
-
const annosOnPage = uidsOnPage.map((uid) => state.byUid[uid]).filter((ta) => ta && ta.commitState !== "deleted");
|
|
996
|
-
annosOnPage.sort((a, b) => (a.pdfId ?? Infinity) - (b.pdfId ?? Infinity));
|
|
997
|
-
annosOnPage.forEach((ta, newPdfId) => {
|
|
998
|
-
const uid = makeUid$1(pageIndex, ta.localId);
|
|
999
|
-
newByUid[uid] = { ...newByUid[uid], pdfId: newPdfId };
|
|
1000
|
-
});
|
|
1001
|
-
return { ...state, byUid: newByUid };
|
|
1002
|
-
}
|
|
1003
|
-
case STORE_PDF_ID: {
|
|
1004
|
-
const { uid, pdfId } = action.payload;
|
|
1005
|
-
const ta = state.byUid[uid];
|
|
1006
|
-
if (!ta) return state;
|
|
1007
|
-
return {
|
|
1008
|
-
...state,
|
|
1009
|
-
byUid: {
|
|
1010
|
-
...state.byUid,
|
|
1011
|
-
[uid]: { ...ta, pdfId, commitState: "synced" }
|
|
1012
|
-
}
|
|
1013
|
-
};
|
|
1014
|
-
}
|
|
1015
1012
|
case PURGE_ANNOTATION: {
|
|
1016
1013
|
const { uid } = action.payload;
|
|
1017
1014
|
const { [uid]: _gone, ...rest } = state.byUid;
|
|
@@ -1036,7 +1033,8 @@ export {
|
|
|
1036
1033
|
getSelectedAnnotation,
|
|
1037
1034
|
getSelectedAnnotationByPageIndex,
|
|
1038
1035
|
getSelectedAnnotationVariant,
|
|
1039
|
-
|
|
1036
|
+
getSidebarAnnotationsWithReplies,
|
|
1037
|
+
getSidebarAnnotationsWithRepliesGroupedByPage,
|
|
1040
1038
|
getToolDefaultsBySubtypeAndIntent,
|
|
1041
1039
|
isAnnotationSelected,
|
|
1042
1040
|
isCircle,
|
|
@@ -1048,12 +1046,14 @@ export {
|
|
|
1048
1046
|
isLine,
|
|
1049
1047
|
isPolygon,
|
|
1050
1048
|
isPolyline,
|
|
1049
|
+
isSidebarAnnotation,
|
|
1051
1050
|
isSquare,
|
|
1052
1051
|
isSquiggly,
|
|
1053
1052
|
isSquigglyDefaults,
|
|
1054
1053
|
isStamp,
|
|
1055
1054
|
isStrikeout,
|
|
1056
1055
|
isStrikeoutDefaults,
|
|
1056
|
+
isText,
|
|
1057
1057
|
isTextMarkup,
|
|
1058
1058
|
isTextMarkupDefaults,
|
|
1059
1059
|
isUnderline,
|