@embedpdf/plugin-stamp 2.11.0
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/LICENSE +21 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +980 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/actions.d.ts +14 -0
- package/dist/lib/defaults/name-map.d.ts +2 -0
- package/dist/lib/handlers/rubber-stamp.handler.d.ts +4 -0
- package/dist/lib/index.d.ts +11 -0
- package/dist/lib/manifest.d.ts +4 -0
- package/dist/lib/reducer.d.ts +5 -0
- package/dist/lib/stamp-plugin.d.ts +54 -0
- package/dist/lib/tools.d.ts +58 -0
- package/dist/lib/types.d.ts +135 -0
- package/dist/preact/adapter.d.ts +5 -0
- package/dist/preact/annotation.d.ts +1 -0
- package/dist/preact/core.d.ts +1 -0
- package/dist/preact/index.cjs +2 -0
- package/dist/preact/index.cjs.map +1 -0
- package/dist/preact/index.d.ts +1 -0
- package/dist/preact/index.js +147 -0
- package/dist/preact/index.js.map +1 -0
- package/dist/react/adapter.d.ts +2 -0
- package/dist/react/annotation.d.ts +1 -0
- package/dist/react/core.d.ts +1 -0
- package/dist/react/index.cjs +2 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +146 -0
- package/dist/react/index.js.map +1 -0
- package/dist/shared/components/index.d.ts +3 -0
- package/dist/shared/components/stamp-img.d.ts +10 -0
- package/dist/shared/components/stamp-preview-renderers.d.ts +2 -0
- package/dist/shared/components/stamp-renderer-registration.d.ts +1 -0
- package/dist/shared/hooks/index.d.ts +1 -0
- package/dist/shared/hooks/use-stamp.d.ts +18 -0
- package/dist/shared/index.d.ts +4 -0
- package/dist/shared-preact/components/index.d.ts +3 -0
- package/dist/shared-preact/components/stamp-img.d.ts +10 -0
- package/dist/shared-preact/components/stamp-preview-renderers.d.ts +2 -0
- package/dist/shared-preact/components/stamp-renderer-registration.d.ts +1 -0
- package/dist/shared-preact/hooks/index.d.ts +1 -0
- package/dist/shared-preact/hooks/use-stamp.d.ts +18 -0
- package/dist/shared-preact/index.d.ts +4 -0
- package/dist/shared-react/components/index.d.ts +3 -0
- package/dist/shared-react/components/stamp-img.d.ts +10 -0
- package/dist/shared-react/components/stamp-preview-renderers.d.ts +2 -0
- package/dist/shared-react/components/stamp-renderer-registration.d.ts +1 -0
- package/dist/shared-react/hooks/index.d.ts +1 -0
- package/dist/shared-react/hooks/use-stamp.d.ts +18 -0
- package/dist/shared-react/index.d.ts +4 -0
- package/dist/svelte/components/StampImg.svelte.d.ts +10 -0
- package/dist/svelte/components/StampPreview.svelte.d.ts +10 -0
- package/dist/svelte/components/StampRendererRegistration.svelte.d.ts +18 -0
- package/dist/svelte/components/index.d.ts +2 -0
- package/dist/svelte/components/stamp-preview-renderers.d.ts +2 -0
- package/dist/svelte/hooks/index.d.ts +1 -0
- package/dist/svelte/hooks/use-stamp.svelte.d.ts +23 -0
- package/dist/svelte/index.cjs +2 -0
- package/dist/svelte/index.cjs.map +1 -0
- package/dist/svelte/index.d.ts +4 -0
- package/dist/svelte/index.js +223 -0
- package/dist/svelte/index.js.map +1 -0
- package/dist/vue/components/index.d.ts +2 -0
- package/dist/vue/components/stamp-img.vue.d.ts +9 -0
- package/dist/vue/components/stamp-preview-renderers.d.ts +2 -0
- package/dist/vue/components/stamp-preview.vue.d.ts +10 -0
- package/dist/vue/components/stamp-renderer-registration.vue.d.ts +13 -0
- package/dist/vue/hooks/index.d.ts +1 -0
- package/dist/vue/hooks/use-stamp.d.ts +262 -0
- package/dist/vue/index.cjs +2 -0
- package/dist/vue/index.cjs.map +1 -0
- package/dist/vue/index.d.ts +4 -0
- package/dist/vue/index.js +235 -0
- package/dist/vue/index.js.map +1 -0
- package/package.json +84 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,980 @@
|
|
|
1
|
+
import { BasePlugin, createEmitter, createScopedEmitter } from "@embedpdf/core";
|
|
2
|
+
import { PdfAnnotationSubtype, uuidV4, PdfAnnotationName, Task, PdfErrorCode } from "@embedpdf/models";
|
|
3
|
+
import { applyInsertUpright, clampAnnotationToPage, defineAnnotationTool } from "@embedpdf/plugin-annotation";
|
|
4
|
+
const STAMP_PLUGIN_ID = "stamp";
|
|
5
|
+
const manifest = {
|
|
6
|
+
id: STAMP_PLUGIN_ID,
|
|
7
|
+
name: "Stamp Plugin",
|
|
8
|
+
version: "1.0.0",
|
|
9
|
+
provides: ["stamp"],
|
|
10
|
+
requires: ["annotation"],
|
|
11
|
+
optional: ["i18n"],
|
|
12
|
+
defaultConfig: {
|
|
13
|
+
defaultLibrary: {
|
|
14
|
+
id: "custom",
|
|
15
|
+
name: "Custom Stamps",
|
|
16
|
+
nameKey: "stamp.library.custom",
|
|
17
|
+
categories: ["custom", "sidebar"]
|
|
18
|
+
},
|
|
19
|
+
manifests: [
|
|
20
|
+
{
|
|
21
|
+
url: "https://cdn.jsdelivr.net/npm/@embedpdf/default-stamps/{locale}/manifest.json",
|
|
22
|
+
fallbackLocale: "en"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const ADD_STAMP_LIBRARY = "STAMP/ADD_LIBRARY";
|
|
28
|
+
const REMOVE_STAMP_LIBRARY = "STAMP/REMOVE_LIBRARY";
|
|
29
|
+
function addStampLibrary(id) {
|
|
30
|
+
return { type: ADD_STAMP_LIBRARY, payload: id };
|
|
31
|
+
}
|
|
32
|
+
function removeStampLibrary(id) {
|
|
33
|
+
return { type: REMOVE_STAMP_LIBRARY, payload: id };
|
|
34
|
+
}
|
|
35
|
+
const rubberStampHandlerFactory = {
|
|
36
|
+
annotationType: PdfAnnotationSubtype.STAMP,
|
|
37
|
+
create(context) {
|
|
38
|
+
const { onPreview, onCommit, getTool, pageSize, pageRotation, getToolContext } = context;
|
|
39
|
+
return {
|
|
40
|
+
onPointerMove: (pos) => {
|
|
41
|
+
const ctx = getToolContext();
|
|
42
|
+
if (!(ctx == null ? void 0 : ctx.stampSize)) return;
|
|
43
|
+
const { width, height } = ctx.stampSize;
|
|
44
|
+
onPreview({
|
|
45
|
+
type: PdfAnnotationSubtype.STAMP,
|
|
46
|
+
bounds: {
|
|
47
|
+
origin: { x: pos.x - width / 2, y: pos.y - height / 2 },
|
|
48
|
+
size: { width, height }
|
|
49
|
+
},
|
|
50
|
+
data: {
|
|
51
|
+
rect: {
|
|
52
|
+
origin: { x: pos.x - width / 2, y: pos.y - height / 2 },
|
|
53
|
+
size: { width, height }
|
|
54
|
+
},
|
|
55
|
+
ghostUrl: ctx.ghostUrl,
|
|
56
|
+
pageRotation
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
},
|
|
60
|
+
onPointerDown: (pos) => {
|
|
61
|
+
var _a;
|
|
62
|
+
const tool = getTool();
|
|
63
|
+
const ctx = getToolContext();
|
|
64
|
+
if (!tool || !(ctx == null ? void 0 : ctx.stampSize)) return;
|
|
65
|
+
const { width, height } = ctx.stampSize;
|
|
66
|
+
const rect = {
|
|
67
|
+
origin: { x: pos.x - width / 2, y: pos.y - height / 2 },
|
|
68
|
+
size: { width, height }
|
|
69
|
+
};
|
|
70
|
+
let anno = {
|
|
71
|
+
...tool.defaults,
|
|
72
|
+
rect,
|
|
73
|
+
type: PdfAnnotationSubtype.STAMP,
|
|
74
|
+
name: ctx.stamp.name ?? tool.defaults.name ?? PdfAnnotationName.Custom,
|
|
75
|
+
subject: ctx.stamp.subject ?? tool.defaults.subject ?? "Custom Stamp",
|
|
76
|
+
flags: tool.defaults.flags ?? ["print"],
|
|
77
|
+
pageIndex: context.pageIndex,
|
|
78
|
+
id: uuidV4(),
|
|
79
|
+
created: /* @__PURE__ */ new Date()
|
|
80
|
+
};
|
|
81
|
+
if ((_a = tool.behavior) == null ? void 0 : _a.insertUpright) {
|
|
82
|
+
anno = applyInsertUpright(anno, pageRotation, false);
|
|
83
|
+
}
|
|
84
|
+
anno = clampAnnotationToPage(anno, pageSize);
|
|
85
|
+
onCommit(anno, { appearance: ctx.appearance });
|
|
86
|
+
onPreview(null);
|
|
87
|
+
},
|
|
88
|
+
onPointerLeave: () => {
|
|
89
|
+
onPreview(null);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
const RUBBER_STAMP_TOOL_ID = "rubberStamp";
|
|
95
|
+
const rubberStampTool = defineAnnotationTool({
|
|
96
|
+
id: RUBBER_STAMP_TOOL_ID,
|
|
97
|
+
name: "Rubber Stamp",
|
|
98
|
+
labelKey: "stamp.rubberStamp",
|
|
99
|
+
categories: ["annotation", "stamp", "insert"],
|
|
100
|
+
matchScore: () => 0,
|
|
101
|
+
interaction: {
|
|
102
|
+
exclusive: true,
|
|
103
|
+
cursor: "copy",
|
|
104
|
+
isDraggable: true,
|
|
105
|
+
isResizable: true,
|
|
106
|
+
isRotatable: false,
|
|
107
|
+
lockAspectRatio: true,
|
|
108
|
+
isGroupDraggable: true,
|
|
109
|
+
isGroupResizable: false,
|
|
110
|
+
isGroupRotatable: false
|
|
111
|
+
},
|
|
112
|
+
defaults: {
|
|
113
|
+
type: PdfAnnotationSubtype.STAMP
|
|
114
|
+
},
|
|
115
|
+
behavior: {
|
|
116
|
+
deactivateToolAfterCreate: true,
|
|
117
|
+
selectAfterCreate: true,
|
|
118
|
+
insertUpright: true,
|
|
119
|
+
useAppearanceStream: true
|
|
120
|
+
},
|
|
121
|
+
pointerHandler: rubberStampHandlerFactory
|
|
122
|
+
});
|
|
123
|
+
const stampTools = [rubberStampTool];
|
|
124
|
+
const ANNOTATION_NAME_MAP = {
|
|
125
|
+
Approved: PdfAnnotationName.Approved,
|
|
126
|
+
Experimental: PdfAnnotationName.Experimental,
|
|
127
|
+
NotApproved: PdfAnnotationName.NotApproved,
|
|
128
|
+
AsIs: PdfAnnotationName.AsIs,
|
|
129
|
+
Expired: PdfAnnotationName.Expired,
|
|
130
|
+
NotForPublicRelease: PdfAnnotationName.NotForPublicRelease,
|
|
131
|
+
Confidential: PdfAnnotationName.Confidential,
|
|
132
|
+
Final: PdfAnnotationName.Final,
|
|
133
|
+
Sold: PdfAnnotationName.Sold,
|
|
134
|
+
Departmental: PdfAnnotationName.Departmental,
|
|
135
|
+
ForComment: PdfAnnotationName.ForComment,
|
|
136
|
+
TopSecret: PdfAnnotationName.TopSecret,
|
|
137
|
+
Draft: PdfAnnotationName.Draft,
|
|
138
|
+
ForPublicRelease: PdfAnnotationName.ForPublicRelease,
|
|
139
|
+
Completed: PdfAnnotationName.Completed,
|
|
140
|
+
Void: PdfAnnotationName.Void,
|
|
141
|
+
PreliminaryResults: PdfAnnotationName.PreliminaryResults,
|
|
142
|
+
InformationOnly: PdfAnnotationName.InformationOnly,
|
|
143
|
+
Rejected: PdfAnnotationName.Rejected,
|
|
144
|
+
Witness: PdfAnnotationName.Witness,
|
|
145
|
+
InitialHere: PdfAnnotationName.InitialHere,
|
|
146
|
+
SignHere: PdfAnnotationName.SignHere,
|
|
147
|
+
Accepted: PdfAnnotationName.Accepted,
|
|
148
|
+
Custom: PdfAnnotationName.Custom,
|
|
149
|
+
Image: PdfAnnotationName.Image
|
|
150
|
+
};
|
|
151
|
+
function parseAnnotationName(name) {
|
|
152
|
+
if (!name) return PdfAnnotationName.Custom;
|
|
153
|
+
return ANNOTATION_NAME_MAP[name] ?? PdfAnnotationName.Custom;
|
|
154
|
+
}
|
|
155
|
+
const _StampPlugin = class _StampPlugin extends BasePlugin {
|
|
156
|
+
constructor(id, registry, config) {
|
|
157
|
+
var _a, _b;
|
|
158
|
+
super(id, registry);
|
|
159
|
+
this.config = config;
|
|
160
|
+
this.instanceId = uuidV4();
|
|
161
|
+
this.libraries = /* @__PURE__ */ new Map();
|
|
162
|
+
this.libraryChange$ = createEmitter();
|
|
163
|
+
this.activeStamp$ = createScopedEmitter((documentId, activeStamp) => ({ documentId, activeStamp }));
|
|
164
|
+
this.managedManifests = [];
|
|
165
|
+
this.annotation = null;
|
|
166
|
+
this.i18n = null;
|
|
167
|
+
this.localeUnsubscribe = null;
|
|
168
|
+
this.toolChangeUnsubscribe = null;
|
|
169
|
+
this.currentGhostUrl = null;
|
|
170
|
+
this.annotation = ((_a = registry.getPlugin("annotation")) == null ? void 0 : _a.provides()) ?? null;
|
|
171
|
+
if (this.annotation) {
|
|
172
|
+
for (const tool of stampTools) {
|
|
173
|
+
this.annotation.addTool(tool);
|
|
174
|
+
}
|
|
175
|
+
this.toolChangeUnsubscribe = this.annotation.onActiveToolChange(({ documentId, tool }) => {
|
|
176
|
+
if ((tool == null ? void 0 : tool.id) !== RUBBER_STAMP_TOOL_ID) {
|
|
177
|
+
if (this.currentGhostUrl) {
|
|
178
|
+
URL.revokeObjectURL(this.currentGhostUrl);
|
|
179
|
+
this.currentGhostUrl = null;
|
|
180
|
+
}
|
|
181
|
+
this.activeStamp$.emit(documentId, null);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
this.i18n = ((_b = registry.getPlugin("i18n")) == null ? void 0 : _b.provides()) ?? null;
|
|
186
|
+
}
|
|
187
|
+
async initialize() {
|
|
188
|
+
if (this.config.libraries) {
|
|
189
|
+
for (const libConfig of this.config.libraries) {
|
|
190
|
+
await this.loadLibraryInternal(libConfig).toPromise();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (this.config.manifests && this.config.manifests.length > 0) {
|
|
194
|
+
await this.initializeManifests();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
buildCapability() {
|
|
198
|
+
return {
|
|
199
|
+
getLibraries: () => this.getLibraries(),
|
|
200
|
+
getStampsByCategory: (category) => this.getStampsByCategory(category),
|
|
201
|
+
renderStamp: (libraryId, pageIndex, width, dpr) => this.renderStamp(libraryId, pageIndex, width, dpr),
|
|
202
|
+
loadLibrary: (config) => this.loadLibrary(config),
|
|
203
|
+
loadLibraryFromManifest: (url) => this.loadLibraryFromManifest(url),
|
|
204
|
+
createNewLibrary: (name, options) => this.createNewLibrary(name, options),
|
|
205
|
+
addStampToLibrary: (libraryId, stamp, pdf) => this.addStampToLibrary(libraryId, stamp, pdf),
|
|
206
|
+
removeStampFromLibrary: (libraryId, stampId) => this.removeStampFromLibrary(libraryId, stampId),
|
|
207
|
+
updateStamp: (libraryId, stampId, updates) => this.updateStamp(libraryId, stampId, updates),
|
|
208
|
+
updateLibrary: (libraryId, updates) => this.updateLibrary(libraryId, updates),
|
|
209
|
+
removeLibrary: (id) => this.removeLibrary(id),
|
|
210
|
+
exportLibrary: (id) => this.exportLibrary(id),
|
|
211
|
+
forDocument: (documentId) => this.createStampScope(documentId),
|
|
212
|
+
onActiveStampChange: this.activeStamp$.onGlobal,
|
|
213
|
+
onLibraryChange: this.libraryChange$.on
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
getLibraries() {
|
|
217
|
+
return Array.from(this.libraries.values());
|
|
218
|
+
}
|
|
219
|
+
getStampsByCategory(category) {
|
|
220
|
+
var _a, _b;
|
|
221
|
+
const results = [];
|
|
222
|
+
for (const library of this.libraries.values()) {
|
|
223
|
+
const libraryMatches = ((_a = library.categories) == null ? void 0 : _a.includes(category)) ?? false;
|
|
224
|
+
for (const stamp of library.stamps) {
|
|
225
|
+
const stampMatches = ((_b = stamp.categories) == null ? void 0 : _b.includes(category)) ?? false;
|
|
226
|
+
if (libraryMatches || stampMatches) {
|
|
227
|
+
results.push({ library, stamp });
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return results;
|
|
232
|
+
}
|
|
233
|
+
renderStamp(libraryId, pageIndex, width, dpr) {
|
|
234
|
+
const library = this.libraries.get(libraryId);
|
|
235
|
+
if (!library) {
|
|
236
|
+
const task = new Task();
|
|
237
|
+
task.reject({
|
|
238
|
+
code: PdfErrorCode.NotFound,
|
|
239
|
+
message: `Stamp library not found: ${libraryId}`
|
|
240
|
+
});
|
|
241
|
+
return task;
|
|
242
|
+
}
|
|
243
|
+
const page = library.document.pages[pageIndex];
|
|
244
|
+
if (!page) {
|
|
245
|
+
const task = new Task();
|
|
246
|
+
task.reject({
|
|
247
|
+
code: PdfErrorCode.NotFound,
|
|
248
|
+
message: `Page ${pageIndex} not found in stamp library: ${libraryId}`
|
|
249
|
+
});
|
|
250
|
+
return task;
|
|
251
|
+
}
|
|
252
|
+
const scaleFactor = width / page.size.width;
|
|
253
|
+
return this.engine.renderPageRect(
|
|
254
|
+
library.document,
|
|
255
|
+
page,
|
|
256
|
+
{ origin: { x: 0, y: 0 }, size: page.size },
|
|
257
|
+
{
|
|
258
|
+
scaleFactor,
|
|
259
|
+
dpr: dpr ?? 1,
|
|
260
|
+
withAnnotations: true,
|
|
261
|
+
rotation: page.rotation,
|
|
262
|
+
transparentBackground: true
|
|
263
|
+
}
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
loadLibrary(config) {
|
|
267
|
+
return this.loadLibraryInternal(config);
|
|
268
|
+
}
|
|
269
|
+
createNewLibrary(name, options) {
|
|
270
|
+
const task = new Task();
|
|
271
|
+
const libraryId = (options == null ? void 0 : options.id) ?? this.generateLibraryId();
|
|
272
|
+
const documentId = this.getLibraryDocumentId(libraryId);
|
|
273
|
+
this.engine.createDocument(documentId).wait(
|
|
274
|
+
(doc) => {
|
|
275
|
+
const library = {
|
|
276
|
+
id: libraryId,
|
|
277
|
+
name,
|
|
278
|
+
nameKey: options == null ? void 0 : options.nameKey,
|
|
279
|
+
document: doc,
|
|
280
|
+
stamps: [],
|
|
281
|
+
categories: options == null ? void 0 : options.categories,
|
|
282
|
+
readonly: (options == null ? void 0 : options.readonly) ?? false
|
|
283
|
+
};
|
|
284
|
+
this.libraries.set(libraryId, library);
|
|
285
|
+
this.dispatch(addStampLibrary(libraryId));
|
|
286
|
+
this.emitLibraryChange();
|
|
287
|
+
task.resolve(libraryId);
|
|
288
|
+
},
|
|
289
|
+
(error) => {
|
|
290
|
+
this.logger.error(
|
|
291
|
+
"StampPlugin",
|
|
292
|
+
"CreateNewLibrary",
|
|
293
|
+
`Failed to create library: ${name}`,
|
|
294
|
+
error
|
|
295
|
+
);
|
|
296
|
+
task.fail(error);
|
|
297
|
+
}
|
|
298
|
+
);
|
|
299
|
+
return task;
|
|
300
|
+
}
|
|
301
|
+
addStampToLibrary(libraryId, stamp, pdf) {
|
|
302
|
+
const task = new Task();
|
|
303
|
+
const library = this.libraries.get(libraryId);
|
|
304
|
+
if (!library) {
|
|
305
|
+
task.reject({
|
|
306
|
+
code: PdfErrorCode.NotFound,
|
|
307
|
+
message: `Stamp library not found: ${libraryId}`
|
|
308
|
+
});
|
|
309
|
+
return task;
|
|
310
|
+
}
|
|
311
|
+
if (library.readonly) {
|
|
312
|
+
task.reject({
|
|
313
|
+
code: PdfErrorCode.NotSupport,
|
|
314
|
+
message: `Cannot add stamps to readonly library: ${libraryId}`
|
|
315
|
+
});
|
|
316
|
+
return task;
|
|
317
|
+
}
|
|
318
|
+
const tempDocId = `stamp-temp-${Date.now()}`;
|
|
319
|
+
this.engine.openDocumentBuffer({ id: tempDocId, content: pdf }).wait(
|
|
320
|
+
(tempDoc) => {
|
|
321
|
+
this.engine.importPages(library.document, tempDoc, [0]).wait(
|
|
322
|
+
(newPages) => {
|
|
323
|
+
const newPage = newPages[0];
|
|
324
|
+
library.document.pages.push(newPage);
|
|
325
|
+
library.document.pageCount = library.document.pages.length;
|
|
326
|
+
const stampDef = {
|
|
327
|
+
...stamp,
|
|
328
|
+
id: uuidV4(),
|
|
329
|
+
pageIndex: newPage.index
|
|
330
|
+
};
|
|
331
|
+
library.stamps.push(stampDef);
|
|
332
|
+
this.engine.closeDocument(tempDoc).wait(
|
|
333
|
+
() => {
|
|
334
|
+
this.emitLibraryChange();
|
|
335
|
+
task.resolve();
|
|
336
|
+
},
|
|
337
|
+
() => {
|
|
338
|
+
this.emitLibraryChange();
|
|
339
|
+
task.resolve();
|
|
340
|
+
}
|
|
341
|
+
);
|
|
342
|
+
},
|
|
343
|
+
(error) => {
|
|
344
|
+
this.logger.error("StampPlugin", "AddStampToLibrary", "Failed to import page", error);
|
|
345
|
+
this.engine.closeDocument(tempDoc).wait(
|
|
346
|
+
() => task.fail(error),
|
|
347
|
+
() => task.fail(error)
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
);
|
|
351
|
+
},
|
|
352
|
+
(error) => {
|
|
353
|
+
this.logger.error(
|
|
354
|
+
"StampPlugin",
|
|
355
|
+
"AddStampToLibrary",
|
|
356
|
+
"Failed to open temp document",
|
|
357
|
+
error
|
|
358
|
+
);
|
|
359
|
+
task.fail(error);
|
|
360
|
+
}
|
|
361
|
+
);
|
|
362
|
+
return task;
|
|
363
|
+
}
|
|
364
|
+
createStampScope(documentId) {
|
|
365
|
+
return {
|
|
366
|
+
createStampFromAnnotation: (annotation, stamp, libraryId) => this.createStampFromAnnotation(documentId, annotation, stamp, libraryId),
|
|
367
|
+
createStampFromAnnotations: (annotations, stamp, libraryId) => this.createStampFromAnnotations(documentId, annotations, stamp, libraryId),
|
|
368
|
+
activateStampPlacement: (libraryId, stamp) => this.activateStampPlacement(documentId, libraryId, stamp),
|
|
369
|
+
activateStampPlacementById: (libraryId, stampId) => this.activateStampPlacementById(documentId, libraryId, stampId),
|
|
370
|
+
getActiveStamp: () => this.getActiveStamp(documentId),
|
|
371
|
+
onActiveStampChange: this.activeStamp$.forScope(documentId)
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
activateStampPlacementById(documentId, libraryId, stampId) {
|
|
375
|
+
const task = new Task();
|
|
376
|
+
const library = this.libraries.get(libraryId);
|
|
377
|
+
if (!library) {
|
|
378
|
+
task.reject({
|
|
379
|
+
code: PdfErrorCode.NotFound,
|
|
380
|
+
message: `Stamp library not found: ${libraryId}`
|
|
381
|
+
});
|
|
382
|
+
return task;
|
|
383
|
+
}
|
|
384
|
+
const stamp = library.stamps.find((s) => s.id === stampId);
|
|
385
|
+
if (!stamp) {
|
|
386
|
+
task.reject({
|
|
387
|
+
code: PdfErrorCode.NotFound,
|
|
388
|
+
message: `Stamp ${stampId} not found in library: ${libraryId}`
|
|
389
|
+
});
|
|
390
|
+
return task;
|
|
391
|
+
}
|
|
392
|
+
return this.activateStampPlacement(documentId, libraryId, stamp);
|
|
393
|
+
}
|
|
394
|
+
getActiveStamp(documentId) {
|
|
395
|
+
return this.activeStamp$.getValue(documentId) ?? null;
|
|
396
|
+
}
|
|
397
|
+
activateStampPlacement(documentId, libraryId, stamp) {
|
|
398
|
+
const task = new Task();
|
|
399
|
+
const library = this.libraries.get(libraryId);
|
|
400
|
+
if (!library) {
|
|
401
|
+
task.reject({
|
|
402
|
+
code: PdfErrorCode.NotFound,
|
|
403
|
+
message: `Stamp library not found: ${libraryId}`
|
|
404
|
+
});
|
|
405
|
+
return task;
|
|
406
|
+
}
|
|
407
|
+
const page = library.document.pages[stamp.pageIndex];
|
|
408
|
+
if (!page) {
|
|
409
|
+
task.reject({
|
|
410
|
+
code: PdfErrorCode.NotFound,
|
|
411
|
+
message: `Page ${stamp.pageIndex} not found in library`
|
|
412
|
+
});
|
|
413
|
+
return task;
|
|
414
|
+
}
|
|
415
|
+
const stampSize = page.size;
|
|
416
|
+
this.engine.extractPages(library.document, [stamp.pageIndex]).wait(
|
|
417
|
+
(appearance) => {
|
|
418
|
+
this.renderStamp(libraryId, stamp.pageIndex, stampSize.width, 2).wait(
|
|
419
|
+
(blob) => {
|
|
420
|
+
var _a;
|
|
421
|
+
if (this.currentGhostUrl) {
|
|
422
|
+
URL.revokeObjectURL(this.currentGhostUrl);
|
|
423
|
+
}
|
|
424
|
+
const ghostUrl = URL.createObjectURL(blob);
|
|
425
|
+
this.currentGhostUrl = ghostUrl;
|
|
426
|
+
(_a = this.annotation) == null ? void 0 : _a.setActiveTool(RUBBER_STAMP_TOOL_ID, {
|
|
427
|
+
appearance,
|
|
428
|
+
ghostUrl,
|
|
429
|
+
stampSize,
|
|
430
|
+
libraryId,
|
|
431
|
+
stamp
|
|
432
|
+
});
|
|
433
|
+
this.activeStamp$.emit(documentId, { libraryId, stamp });
|
|
434
|
+
task.resolve();
|
|
435
|
+
},
|
|
436
|
+
(error) => {
|
|
437
|
+
this.logger.error(
|
|
438
|
+
"StampPlugin",
|
|
439
|
+
"ActivateStampPlacement",
|
|
440
|
+
"Failed to render stamp preview",
|
|
441
|
+
error
|
|
442
|
+
);
|
|
443
|
+
task.fail(error);
|
|
444
|
+
}
|
|
445
|
+
);
|
|
446
|
+
},
|
|
447
|
+
(error) => {
|
|
448
|
+
this.logger.error(
|
|
449
|
+
"StampPlugin",
|
|
450
|
+
"ActivateStampPlacement",
|
|
451
|
+
"Failed to extract stamp page",
|
|
452
|
+
error
|
|
453
|
+
);
|
|
454
|
+
task.fail(error);
|
|
455
|
+
}
|
|
456
|
+
);
|
|
457
|
+
return task;
|
|
458
|
+
}
|
|
459
|
+
createStampFromAnnotation(documentId, annotation, stamp, libraryId) {
|
|
460
|
+
const task = new Task();
|
|
461
|
+
const docState = this.getCoreDocument(documentId);
|
|
462
|
+
if (!(docState == null ? void 0 : docState.document)) {
|
|
463
|
+
task.reject({ code: PdfErrorCode.DocNotOpen, message: "document is not open" });
|
|
464
|
+
return task;
|
|
465
|
+
}
|
|
466
|
+
const doc = docState.document;
|
|
467
|
+
const page = doc.pages[annotation.pageIndex];
|
|
468
|
+
if (!page) {
|
|
469
|
+
task.reject({
|
|
470
|
+
code: PdfErrorCode.NotFound,
|
|
471
|
+
message: `page ${annotation.pageIndex} not found`
|
|
472
|
+
});
|
|
473
|
+
return task;
|
|
474
|
+
}
|
|
475
|
+
this.resolveTargetLibrary(libraryId).wait(
|
|
476
|
+
(targetId) => {
|
|
477
|
+
this.engine.exportAnnotationAppearanceAsPdf(doc, page, annotation).wait(
|
|
478
|
+
(pdf) => {
|
|
479
|
+
this.addStampToLibrary(targetId, stamp, pdf).wait(
|
|
480
|
+
() => task.resolve(),
|
|
481
|
+
(error) => task.fail(error)
|
|
482
|
+
);
|
|
483
|
+
},
|
|
484
|
+
(error) => {
|
|
485
|
+
this.logger.error(
|
|
486
|
+
"StampPlugin",
|
|
487
|
+
"CreateStampFromAnnotation",
|
|
488
|
+
"Failed to export annotation",
|
|
489
|
+
error
|
|
490
|
+
);
|
|
491
|
+
task.fail(error);
|
|
492
|
+
}
|
|
493
|
+
);
|
|
494
|
+
},
|
|
495
|
+
(error) => task.fail(error)
|
|
496
|
+
);
|
|
497
|
+
return task;
|
|
498
|
+
}
|
|
499
|
+
createStampFromAnnotations(documentId, annotations, stamp, libraryId) {
|
|
500
|
+
const task = new Task();
|
|
501
|
+
if (annotations.length === 0) {
|
|
502
|
+
task.reject({ code: PdfErrorCode.NotFound, message: "no annotations provided" });
|
|
503
|
+
return task;
|
|
504
|
+
}
|
|
505
|
+
const docState = this.getCoreDocument(documentId);
|
|
506
|
+
if (!(docState == null ? void 0 : docState.document)) {
|
|
507
|
+
task.reject({ code: PdfErrorCode.DocNotOpen, message: "document is not open" });
|
|
508
|
+
return task;
|
|
509
|
+
}
|
|
510
|
+
const doc = docState.document;
|
|
511
|
+
const page = doc.pages[annotations[0].pageIndex];
|
|
512
|
+
if (!page) {
|
|
513
|
+
task.reject({
|
|
514
|
+
code: PdfErrorCode.NotFound,
|
|
515
|
+
message: `page ${annotations[0].pageIndex} not found`
|
|
516
|
+
});
|
|
517
|
+
return task;
|
|
518
|
+
}
|
|
519
|
+
this.resolveTargetLibrary(libraryId).wait(
|
|
520
|
+
(targetId) => {
|
|
521
|
+
this.engine.exportAnnotationsAppearanceAsPdf(doc, page, annotations).wait(
|
|
522
|
+
(pdf) => {
|
|
523
|
+
this.addStampToLibrary(targetId, stamp, pdf).wait(
|
|
524
|
+
() => task.resolve(),
|
|
525
|
+
(error) => task.fail(error)
|
|
526
|
+
);
|
|
527
|
+
},
|
|
528
|
+
(error) => {
|
|
529
|
+
this.logger.error(
|
|
530
|
+
"StampPlugin",
|
|
531
|
+
"CreateStampFromAnnotations",
|
|
532
|
+
"Failed to export annotations",
|
|
533
|
+
error
|
|
534
|
+
);
|
|
535
|
+
task.fail(error);
|
|
536
|
+
}
|
|
537
|
+
);
|
|
538
|
+
},
|
|
539
|
+
(error) => task.fail(error)
|
|
540
|
+
);
|
|
541
|
+
return task;
|
|
542
|
+
}
|
|
543
|
+
resolveTargetLibrary(libraryId) {
|
|
544
|
+
if (libraryId && this.libraries.has(libraryId)) {
|
|
545
|
+
const task = new Task();
|
|
546
|
+
task.resolve(libraryId);
|
|
547
|
+
return task;
|
|
548
|
+
}
|
|
549
|
+
const defaults = this.config.defaultLibrary;
|
|
550
|
+
if (this.config.defaultLibrary === false || !defaults) {
|
|
551
|
+
const task = new Task();
|
|
552
|
+
task.reject({
|
|
553
|
+
code: PdfErrorCode.NotSupport,
|
|
554
|
+
message: "Default library creation is disabled"
|
|
555
|
+
});
|
|
556
|
+
return task;
|
|
557
|
+
}
|
|
558
|
+
const defaultId = defaults.id ?? "custom";
|
|
559
|
+
if (this.libraries.has(defaultId)) {
|
|
560
|
+
const task = new Task();
|
|
561
|
+
task.resolve(defaultId);
|
|
562
|
+
return task;
|
|
563
|
+
}
|
|
564
|
+
return this.createNewLibrary(defaults.name ?? "Custom Stamps", {
|
|
565
|
+
id: defaultId,
|
|
566
|
+
nameKey: defaults.nameKey,
|
|
567
|
+
categories: defaults.categories
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
removeLibrary(id) {
|
|
571
|
+
const task = new Task();
|
|
572
|
+
const library = this.libraries.get(id);
|
|
573
|
+
if (!library) {
|
|
574
|
+
task.resolve();
|
|
575
|
+
return task;
|
|
576
|
+
}
|
|
577
|
+
this.engine.closeDocument(library.document).wait(
|
|
578
|
+
() => {
|
|
579
|
+
this.libraries.delete(id);
|
|
580
|
+
this.dispatch(removeStampLibrary(id));
|
|
581
|
+
this.emitLibraryChange();
|
|
582
|
+
task.resolve();
|
|
583
|
+
},
|
|
584
|
+
() => {
|
|
585
|
+
this.logger.warn(
|
|
586
|
+
"StampPlugin",
|
|
587
|
+
"RemoveLibrary",
|
|
588
|
+
`Failed to close document for library: ${id}`
|
|
589
|
+
);
|
|
590
|
+
this.libraries.delete(id);
|
|
591
|
+
this.dispatch(removeStampLibrary(id));
|
|
592
|
+
this.emitLibraryChange();
|
|
593
|
+
task.resolve();
|
|
594
|
+
}
|
|
595
|
+
);
|
|
596
|
+
return task;
|
|
597
|
+
}
|
|
598
|
+
exportLibrary(id) {
|
|
599
|
+
const task = new Task();
|
|
600
|
+
const library = this.libraries.get(id);
|
|
601
|
+
if (!library) {
|
|
602
|
+
task.reject({
|
|
603
|
+
code: PdfErrorCode.NotFound,
|
|
604
|
+
message: `Stamp library not found: ${id}`
|
|
605
|
+
});
|
|
606
|
+
return task;
|
|
607
|
+
}
|
|
608
|
+
this.engine.saveAsCopy(library.document).wait(
|
|
609
|
+
(pdf) => {
|
|
610
|
+
task.resolve({
|
|
611
|
+
name: library.name,
|
|
612
|
+
pdf,
|
|
613
|
+
stamps: library.stamps,
|
|
614
|
+
categories: library.categories
|
|
615
|
+
});
|
|
616
|
+
},
|
|
617
|
+
(error) => {
|
|
618
|
+
this.logger.error("StampPlugin", "ExportLibrary", `Failed to export library: ${id}`, error);
|
|
619
|
+
task.fail(error);
|
|
620
|
+
}
|
|
621
|
+
);
|
|
622
|
+
return task;
|
|
623
|
+
}
|
|
624
|
+
loadLibraryInternal(config) {
|
|
625
|
+
const task = new Task();
|
|
626
|
+
const libraryId = config.id ?? this.generateLibraryId();
|
|
627
|
+
const documentId = this.getLibraryDocumentId(libraryId);
|
|
628
|
+
const engineTask = typeof config.pdf === "string" ? this.engine.openDocumentUrl({ id: documentId, url: config.pdf }) : this.engine.openDocumentBuffer({ id: documentId, content: config.pdf });
|
|
629
|
+
engineTask.wait(
|
|
630
|
+
(doc) => {
|
|
631
|
+
const stamps = config.stamps.map((s) => s.id ? s : { ...s, id: uuidV4() });
|
|
632
|
+
const library = {
|
|
633
|
+
id: libraryId,
|
|
634
|
+
name: config.name,
|
|
635
|
+
nameKey: config.nameKey,
|
|
636
|
+
document: doc,
|
|
637
|
+
stamps,
|
|
638
|
+
categories: config.categories,
|
|
639
|
+
readonly: config.readonly ?? false
|
|
640
|
+
};
|
|
641
|
+
this.libraries.set(libraryId, library);
|
|
642
|
+
this.dispatch(addStampLibrary(libraryId));
|
|
643
|
+
this.emitLibraryChange();
|
|
644
|
+
task.resolve(libraryId);
|
|
645
|
+
},
|
|
646
|
+
(error) => {
|
|
647
|
+
this.logger.error(
|
|
648
|
+
"StampPlugin",
|
|
649
|
+
"LoadLibrary",
|
|
650
|
+
`Failed to load stamp library: ${config.name}`,
|
|
651
|
+
error
|
|
652
|
+
);
|
|
653
|
+
task.fail(error);
|
|
654
|
+
}
|
|
655
|
+
);
|
|
656
|
+
return task;
|
|
657
|
+
}
|
|
658
|
+
removeStampFromLibrary(libraryId, stampId) {
|
|
659
|
+
const task = new Task();
|
|
660
|
+
const library = this.libraries.get(libraryId);
|
|
661
|
+
if (!library) {
|
|
662
|
+
task.reject({
|
|
663
|
+
code: PdfErrorCode.NotFound,
|
|
664
|
+
message: `Stamp library not found: ${libraryId}`
|
|
665
|
+
});
|
|
666
|
+
return task;
|
|
667
|
+
}
|
|
668
|
+
if (library.readonly) {
|
|
669
|
+
task.reject({
|
|
670
|
+
code: PdfErrorCode.NotSupport,
|
|
671
|
+
message: `Cannot remove stamps from readonly library: ${libraryId}`
|
|
672
|
+
});
|
|
673
|
+
return task;
|
|
674
|
+
}
|
|
675
|
+
const stampIdx = library.stamps.findIndex((s) => s.id === stampId);
|
|
676
|
+
if (stampIdx === -1) {
|
|
677
|
+
task.reject({
|
|
678
|
+
code: PdfErrorCode.NotFound,
|
|
679
|
+
message: `Stamp ${stampId} not found in library: ${libraryId}`
|
|
680
|
+
});
|
|
681
|
+
return task;
|
|
682
|
+
}
|
|
683
|
+
const pageIndex = library.stamps[stampIdx].pageIndex;
|
|
684
|
+
this.engine.deletePage(library.document, pageIndex).wait(
|
|
685
|
+
() => {
|
|
686
|
+
library.stamps.splice(stampIdx, 1);
|
|
687
|
+
library.document.pages.splice(pageIndex, 1);
|
|
688
|
+
library.document.pageCount = library.document.pages.length;
|
|
689
|
+
for (const s of library.stamps) {
|
|
690
|
+
if (s.pageIndex > pageIndex) {
|
|
691
|
+
s.pageIndex--;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
for (let i = 0; i < library.document.pages.length; i++) {
|
|
695
|
+
library.document.pages[i].index = i;
|
|
696
|
+
}
|
|
697
|
+
this.emitLibraryChange();
|
|
698
|
+
task.resolve();
|
|
699
|
+
},
|
|
700
|
+
(error) => {
|
|
701
|
+
this.logger.error(
|
|
702
|
+
"StampPlugin",
|
|
703
|
+
"RemoveStampFromLibrary",
|
|
704
|
+
`Failed to delete page for stamp ${stampId}`,
|
|
705
|
+
error
|
|
706
|
+
);
|
|
707
|
+
task.fail(error);
|
|
708
|
+
}
|
|
709
|
+
);
|
|
710
|
+
return task;
|
|
711
|
+
}
|
|
712
|
+
updateStamp(libraryId, stampId, updates) {
|
|
713
|
+
const task = new Task();
|
|
714
|
+
const library = this.libraries.get(libraryId);
|
|
715
|
+
if (!library) {
|
|
716
|
+
task.reject({
|
|
717
|
+
code: PdfErrorCode.NotFound,
|
|
718
|
+
message: `Stamp library not found: ${libraryId}`
|
|
719
|
+
});
|
|
720
|
+
return task;
|
|
721
|
+
}
|
|
722
|
+
if (library.readonly) {
|
|
723
|
+
task.reject({
|
|
724
|
+
code: PdfErrorCode.NotSupport,
|
|
725
|
+
message: `Cannot update stamps in readonly library: ${libraryId}`
|
|
726
|
+
});
|
|
727
|
+
return task;
|
|
728
|
+
}
|
|
729
|
+
const stamp = library.stamps.find((s) => s.id === stampId);
|
|
730
|
+
if (!stamp) {
|
|
731
|
+
task.reject({
|
|
732
|
+
code: PdfErrorCode.NotFound,
|
|
733
|
+
message: `Stamp ${stampId} not found in library: ${libraryId}`
|
|
734
|
+
});
|
|
735
|
+
return task;
|
|
736
|
+
}
|
|
737
|
+
Object.assign(stamp, updates);
|
|
738
|
+
this.emitLibraryChange();
|
|
739
|
+
task.resolve();
|
|
740
|
+
return task;
|
|
741
|
+
}
|
|
742
|
+
updateLibrary(libraryId, updates) {
|
|
743
|
+
const task = new Task();
|
|
744
|
+
const library = this.libraries.get(libraryId);
|
|
745
|
+
if (!library) {
|
|
746
|
+
task.reject({
|
|
747
|
+
code: PdfErrorCode.NotFound,
|
|
748
|
+
message: `Stamp library not found: ${libraryId}`
|
|
749
|
+
});
|
|
750
|
+
return task;
|
|
751
|
+
}
|
|
752
|
+
if (library.readonly) {
|
|
753
|
+
task.reject({
|
|
754
|
+
code: PdfErrorCode.NotSupport,
|
|
755
|
+
message: `Cannot update readonly library: ${libraryId}`
|
|
756
|
+
});
|
|
757
|
+
return task;
|
|
758
|
+
}
|
|
759
|
+
if (updates.name !== void 0) library.name = updates.name;
|
|
760
|
+
if (updates.nameKey !== void 0) library.nameKey = updates.nameKey;
|
|
761
|
+
if (updates.categories !== void 0) library.categories = updates.categories;
|
|
762
|
+
if (updates.readonly !== void 0) library.readonly = updates.readonly;
|
|
763
|
+
this.emitLibraryChange();
|
|
764
|
+
task.resolve();
|
|
765
|
+
return task;
|
|
766
|
+
}
|
|
767
|
+
loadLibraryFromManifest(url) {
|
|
768
|
+
return this.loadManifestUrl(url, true);
|
|
769
|
+
}
|
|
770
|
+
async initializeManifests() {
|
|
771
|
+
var _a;
|
|
772
|
+
const currentLocale = ((_a = this.i18n) == null ? void 0 : _a.getLocale()) ?? "en";
|
|
773
|
+
for (const source of this.config.manifests) {
|
|
774
|
+
const localeAware = source.url.includes("{locale}");
|
|
775
|
+
const locale = localeAware ? currentLocale : "";
|
|
776
|
+
const resolvedUrl = source.url.replace("{locale}", locale || currentLocale);
|
|
777
|
+
const managed = {
|
|
778
|
+
source,
|
|
779
|
+
localeAware,
|
|
780
|
+
currentLocale: localeAware ? currentLocale : "",
|
|
781
|
+
libraryId: null
|
|
782
|
+
};
|
|
783
|
+
this.managedManifests.push(managed);
|
|
784
|
+
try {
|
|
785
|
+
const libraryId = await this.loadManifestUrl(resolvedUrl, true).toPromise();
|
|
786
|
+
managed.libraryId = libraryId;
|
|
787
|
+
} catch {
|
|
788
|
+
if (localeAware && source.fallbackLocale && source.fallbackLocale !== currentLocale) {
|
|
789
|
+
const fallbackUrl = source.url.replace("{locale}", source.fallbackLocale);
|
|
790
|
+
try {
|
|
791
|
+
const libraryId = await this.loadManifestUrl(fallbackUrl, true).toPromise();
|
|
792
|
+
managed.libraryId = libraryId;
|
|
793
|
+
managed.currentLocale = source.fallbackLocale;
|
|
794
|
+
} catch {
|
|
795
|
+
this.logger.warn(
|
|
796
|
+
"StampPlugin",
|
|
797
|
+
"InitManifests",
|
|
798
|
+
`Failed to load manifest (including fallback): ${source.url}`
|
|
799
|
+
);
|
|
800
|
+
}
|
|
801
|
+
} else {
|
|
802
|
+
this.logger.warn(
|
|
803
|
+
"StampPlugin",
|
|
804
|
+
"InitManifests",
|
|
805
|
+
`Failed to load manifest: ${resolvedUrl}`
|
|
806
|
+
);
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
if (this.i18n) {
|
|
811
|
+
this.localeUnsubscribe = this.i18n.onLocaleChange((event) => {
|
|
812
|
+
this.handleLocaleChange(event.currentLocale);
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
async handleLocaleChange(newLocale) {
|
|
817
|
+
for (const managed of this.managedManifests) {
|
|
818
|
+
if (!managed.localeAware || managed.currentLocale === newLocale) {
|
|
819
|
+
continue;
|
|
820
|
+
}
|
|
821
|
+
if (managed.libraryId) {
|
|
822
|
+
try {
|
|
823
|
+
await this.removeLibrary(managed.libraryId).toPromise();
|
|
824
|
+
} catch {
|
|
825
|
+
}
|
|
826
|
+
managed.libraryId = null;
|
|
827
|
+
}
|
|
828
|
+
const resolvedUrl = managed.source.url.replace("{locale}", newLocale);
|
|
829
|
+
try {
|
|
830
|
+
const libraryId = await this.loadManifestUrl(resolvedUrl, true).toPromise();
|
|
831
|
+
managed.libraryId = libraryId;
|
|
832
|
+
managed.currentLocale = newLocale;
|
|
833
|
+
} catch {
|
|
834
|
+
const fallback = managed.source.fallbackLocale ?? "en";
|
|
835
|
+
if (fallback !== newLocale) {
|
|
836
|
+
const fallbackUrl = managed.source.url.replace("{locale}", fallback);
|
|
837
|
+
try {
|
|
838
|
+
const libraryId = await this.loadManifestUrl(fallbackUrl, true).toPromise();
|
|
839
|
+
managed.libraryId = libraryId;
|
|
840
|
+
managed.currentLocale = fallback;
|
|
841
|
+
} catch {
|
|
842
|
+
this.logger.warn(
|
|
843
|
+
"StampPlugin",
|
|
844
|
+
"LocaleChange",
|
|
845
|
+
`Failed to load manifest for locale ${newLocale} (including fallback): ${managed.source.url}`
|
|
846
|
+
);
|
|
847
|
+
}
|
|
848
|
+
} else {
|
|
849
|
+
this.logger.warn(
|
|
850
|
+
"StampPlugin",
|
|
851
|
+
"LocaleChange",
|
|
852
|
+
`Failed to load manifest for locale ${newLocale}: ${managed.source.url}`
|
|
853
|
+
);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
loadManifestUrl(url, readonly) {
|
|
859
|
+
const task = new Task();
|
|
860
|
+
fetch(url).then((response) => {
|
|
861
|
+
if (!response.ok) {
|
|
862
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
863
|
+
}
|
|
864
|
+
return response.json();
|
|
865
|
+
}).then((manifest2) => {
|
|
866
|
+
const pdfUrl = this.resolveManifestPdfUrl(url, manifest2.pdf);
|
|
867
|
+
const stamps = manifest2.stamps.map((entry) => ({
|
|
868
|
+
id: entry.id ?? uuidV4(),
|
|
869
|
+
pageIndex: entry.pageIndex,
|
|
870
|
+
name: parseAnnotationName(entry.name),
|
|
871
|
+
subject: entry.subject,
|
|
872
|
+
subjectKey: entry.subjectKey,
|
|
873
|
+
label: entry.label,
|
|
874
|
+
categories: entry.categories
|
|
875
|
+
}));
|
|
876
|
+
const config = {
|
|
877
|
+
id: manifest2.id,
|
|
878
|
+
name: manifest2.name,
|
|
879
|
+
nameKey: manifest2.nameKey,
|
|
880
|
+
pdf: pdfUrl,
|
|
881
|
+
stamps,
|
|
882
|
+
categories: manifest2.categories,
|
|
883
|
+
readonly
|
|
884
|
+
};
|
|
885
|
+
this.loadLibraryInternal(config).wait(
|
|
886
|
+
(libraryId) => task.resolve(libraryId),
|
|
887
|
+
(error) => task.fail(error)
|
|
888
|
+
);
|
|
889
|
+
}).catch((error) => {
|
|
890
|
+
this.logger.error("StampPlugin", "LoadManifest", `Failed to fetch manifest: ${url}`, error);
|
|
891
|
+
task.reject({
|
|
892
|
+
code: PdfErrorCode.NotFound,
|
|
893
|
+
message: `Failed to load stamp manifest: ${url}`
|
|
894
|
+
});
|
|
895
|
+
});
|
|
896
|
+
return task;
|
|
897
|
+
}
|
|
898
|
+
resolveManifestPdfUrl(manifestUrl, pdfPath) {
|
|
899
|
+
if (pdfPath.startsWith("http://") || pdfPath.startsWith("https://") || pdfPath.startsWith("/")) {
|
|
900
|
+
return pdfPath;
|
|
901
|
+
}
|
|
902
|
+
const base = manifestUrl.substring(0, manifestUrl.lastIndexOf("/") + 1);
|
|
903
|
+
return base + pdfPath;
|
|
904
|
+
}
|
|
905
|
+
generateLibraryId() {
|
|
906
|
+
return uuidV4();
|
|
907
|
+
}
|
|
908
|
+
getLibraryDocumentId(libraryId) {
|
|
909
|
+
return `stamp-doc-${this.instanceId}-${libraryId}`;
|
|
910
|
+
}
|
|
911
|
+
emitLibraryChange() {
|
|
912
|
+
this.libraryChange$.emit(this.getLibraries());
|
|
913
|
+
}
|
|
914
|
+
async destroy() {
|
|
915
|
+
if (this.currentGhostUrl) {
|
|
916
|
+
URL.revokeObjectURL(this.currentGhostUrl);
|
|
917
|
+
this.currentGhostUrl = null;
|
|
918
|
+
}
|
|
919
|
+
if (this.toolChangeUnsubscribe) {
|
|
920
|
+
this.toolChangeUnsubscribe();
|
|
921
|
+
this.toolChangeUnsubscribe = null;
|
|
922
|
+
}
|
|
923
|
+
if (this.localeUnsubscribe) {
|
|
924
|
+
this.localeUnsubscribe();
|
|
925
|
+
this.localeUnsubscribe = null;
|
|
926
|
+
}
|
|
927
|
+
this.activeStamp$.clear();
|
|
928
|
+
const libs = Array.from(this.libraries.values());
|
|
929
|
+
for (const library of libs) {
|
|
930
|
+
try {
|
|
931
|
+
await this.engine.closeDocument(library.document).toPromise();
|
|
932
|
+
} catch {
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
this.libraries.clear();
|
|
936
|
+
this.managedManifests.length = 0;
|
|
937
|
+
super.destroy();
|
|
938
|
+
}
|
|
939
|
+
};
|
|
940
|
+
_StampPlugin.id = STAMP_PLUGIN_ID;
|
|
941
|
+
let StampPlugin = _StampPlugin;
|
|
942
|
+
const initialState = {
|
|
943
|
+
libraryIds: []
|
|
944
|
+
};
|
|
945
|
+
const stampReducer = (state = initialState, action) => {
|
|
946
|
+
switch (action.type) {
|
|
947
|
+
case ADD_STAMP_LIBRARY:
|
|
948
|
+
return {
|
|
949
|
+
...state,
|
|
950
|
+
libraryIds: [...state.libraryIds, action.payload]
|
|
951
|
+
};
|
|
952
|
+
case REMOVE_STAMP_LIBRARY:
|
|
953
|
+
return {
|
|
954
|
+
...state,
|
|
955
|
+
libraryIds: state.libraryIds.filter((id) => id !== action.payload)
|
|
956
|
+
};
|
|
957
|
+
default:
|
|
958
|
+
return state;
|
|
959
|
+
}
|
|
960
|
+
};
|
|
961
|
+
const StampPluginPackage = {
|
|
962
|
+
manifest,
|
|
963
|
+
create: (registry, config) => new StampPlugin(STAMP_PLUGIN_ID, registry, config),
|
|
964
|
+
reducer: stampReducer,
|
|
965
|
+
initialState
|
|
966
|
+
};
|
|
967
|
+
export {
|
|
968
|
+
ADD_STAMP_LIBRARY,
|
|
969
|
+
REMOVE_STAMP_LIBRARY,
|
|
970
|
+
RUBBER_STAMP_TOOL_ID,
|
|
971
|
+
STAMP_PLUGIN_ID,
|
|
972
|
+
StampPlugin,
|
|
973
|
+
StampPluginPackage,
|
|
974
|
+
addStampLibrary,
|
|
975
|
+
initialState,
|
|
976
|
+
manifest,
|
|
977
|
+
removeStampLibrary,
|
|
978
|
+
stampReducer
|
|
979
|
+
};
|
|
980
|
+
//# sourceMappingURL=index.js.map
|