@docmentis/udoc-viewer 0.6.34 → 0.6.36
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/README.md +137 -0
- package/dist/package.json +1 -1
- package/dist/src/UDocClient.js +1 -1
- package/dist/src/UDocViewer.d.ts +102 -1
- package/dist/src/UDocViewer.d.ts.map +1 -1
- package/dist/src/UDocViewer.js +187 -4
- package/dist/src/UDocViewer.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/ui/framework/store.d.ts +7 -0
- package/dist/src/ui/framework/store.d.ts.map +1 -1
- package/dist/src/ui/framework/store.js +14 -1
- package/dist/src/ui/framework/store.js.map +1 -1
- package/dist/src/ui/viewer/annotation/types.d.ts +26 -0
- package/dist/src/ui/viewer/annotation/types.d.ts.map +1 -1
- package/dist/src/ui/viewer/components/SubToolbar.d.ts.map +1 -1
- package/dist/src/ui/viewer/components/SubToolbar.js +10 -7
- package/dist/src/ui/viewer/components/SubToolbar.js.map +1 -1
- package/dist/src/ui/viewer/components/Toolbar.d.ts.map +1 -1
- package/dist/src/ui/viewer/components/Toolbar.js +16 -14
- package/dist/src/ui/viewer/components/Toolbar.js.map +1 -1
- package/dist/src/ui/viewer/components/Viewport.d.ts +6 -1
- package/dist/src/ui/viewer/components/Viewport.d.ts.map +1 -1
- package/dist/src/ui/viewer/components/Viewport.js +59 -1
- package/dist/src/ui/viewer/components/Viewport.js.map +1 -1
- package/dist/src/ui/viewer/reducer.d.ts.map +1 -1
- package/dist/src/ui/viewer/reducer.js +55 -40
- package/dist/src/ui/viewer/reducer.js.map +1 -1
- package/dist/src/ui/viewer/shell.d.ts +7 -0
- package/dist/src/ui/viewer/shell.d.ts.map +1 -1
- package/dist/src/ui/viewer/shell.js +3 -3
- package/dist/src/ui/viewer/shell.js.map +1 -1
- package/dist/src/ui/viewer/state.d.ts +30 -17
- package/dist/src/ui/viewer/state.d.ts.map +1 -1
- package/dist/src/ui/viewer/state.js +4 -10
- package/dist/src/ui/viewer/state.js.map +1 -1
- package/dist/src/ui/viewer/tools/AnnotationDrawController.d.ts.map +1 -1
- package/dist/src/ui/viewer/tools/AnnotationDrawController.js +15 -14
- package/dist/src/ui/viewer/tools/AnnotationDrawController.js.map +1 -1
- package/dist/src/ui/viewer/tools/AnnotationSelectController.d.ts.map +1 -1
- package/dist/src/ui/viewer/tools/AnnotationSelectController.js +4 -3
- package/dist/src/ui/viewer/tools/AnnotationSelectController.js.map +1 -1
- package/dist/src/ui/viewer/tools/ViewToolController.js +9 -9
- package/dist/src/ui/viewer/tools/ViewToolController.js.map +1 -1
- package/dist/src/wasm/udoc.d.ts +1 -1
- package/dist/src/wasm/udoc.js +3 -3
- package/dist/src/wasm/udoc_bg.wasm +0 -0
- package/dist/src/wasm/udoc_bg.wasm.d.ts +1 -1
- package/dist/src/worker/worker-inline.js +1 -1
- package/dist/src/worker/worker.js +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -383,6 +383,100 @@ for (let i = 0; i < viewer.pageCount; i++) {
|
|
|
383
383
|
const fullText = pages.join("\n\n");
|
|
384
384
|
```
|
|
385
385
|
|
|
386
|
+
### Annotations
|
|
387
|
+
|
|
388
|
+
Read, create, modify, and delete annotations on PDF documents. Each annotation has a stable `name` (the PDF NM identifier) that survives save/reload, so you can use it as a foreign key from your own data store.
|
|
389
|
+
|
|
390
|
+
**Read.** `getPageAnnotations` returns every annotation on a page — including any in-memory edits and ephemeral overlays — so a single call always reflects what the user is currently seeing.
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
const annotations = await viewer.getPageAnnotations(0); // 0-based page index
|
|
394
|
+
|
|
395
|
+
for (const a of annotations) {
|
|
396
|
+
console.log(a.type, a.name, a.bounds, a.metadata?.author);
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
**Add.** Pass any `Annotation` shape (highlight, underline, ink, freeText, square, etc.) along with a `bounds` rectangle in PDF points. If `name` is omitted the viewer assigns a UUID and returns it on the resolved annotation, so you can keep referencing the new annotation immediately.
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
const created = await viewer.addPageAnnotation(0, {
|
|
404
|
+
type: "highlight",
|
|
405
|
+
bounds: { x: 100, y: 700, width: 200, height: 20 },
|
|
406
|
+
quads: [
|
|
407
|
+
{
|
|
408
|
+
points: [
|
|
409
|
+
{ x: 100, y: 700 },
|
|
410
|
+
{ x: 300, y: 700 },
|
|
411
|
+
{ x: 300, y: 720 },
|
|
412
|
+
{ x: 100, y: 720 },
|
|
413
|
+
],
|
|
414
|
+
},
|
|
415
|
+
],
|
|
416
|
+
color: { r: 1, g: 1, b: 0 },
|
|
417
|
+
metadata: { author: "Alice", contents: "Important" },
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
console.log(created.name); // generated UUID, stable across save/reload
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
**Update / remove.** Both are keyed by `name`. `updatePageAnnotation` replaces the whole annotation but preserves the `name` even if you accidentally pass a different one in the body.
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
await viewer.updatePageAnnotation(0, created.name, {
|
|
427
|
+
...created,
|
|
428
|
+
color: { r: 0, g: 1, b: 0 },
|
|
429
|
+
metadata: { ...created.metadata, contents: "Reviewed" },
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
await viewer.removePageAnnotation(0, created.name);
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
**Save.** PDF write-back happens automatically on `toBytes()` and `download()` whenever there are pending edits — there is no separate save call.
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
const bytes = await viewer.toBytes(); // pending edits flushed into the returned PDF
|
|
439
|
+
await viewer.download("annotated.pdf");
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
**Ephemeral annotations.** Pass `ephemeral: true` to create a viewer-only annotation. Ephemeral annotations render in the canvas like any other, but are excluded from saved PDF bytes and from print output. Use them for live cursors, preview shapes, or transient review markers that shouldn't survive a reload.
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
const cursor = await viewer.addPageAnnotation(0, {
|
|
446
|
+
type: "square",
|
|
447
|
+
bounds: { x: 50, y: 50, width: 30, height: 30 },
|
|
448
|
+
color: { r: 1, g: 0, b: 0 },
|
|
449
|
+
ephemeral: true, // not written on save, not printed
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
// Promote an ephemeral preview into a saved annotation:
|
|
453
|
+
await viewer.updatePageAnnotation(0, cursor.name, { ...cursor, ephemeral: false });
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
**Events.** All four annotation events fire for both UI-driven changes (drawing/markup tools) and API-driven changes, so a single listener covers both.
|
|
457
|
+
|
|
458
|
+
```typescript
|
|
459
|
+
viewer.on("annotation:add", ({ pageIndex, annotation }) => {
|
|
460
|
+
if (annotation.ephemeral) return;
|
|
461
|
+
syncToBackend({ kind: "create", pageIndex, annotation });
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
viewer.on("annotation:update", ({ pageIndex, annotation }) => {
|
|
465
|
+
syncToBackend({ kind: "update", pageIndex, annotation });
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
viewer.on("annotation:remove", ({ pageIndex, annotation }) => {
|
|
469
|
+
syncToBackend({ kind: "delete", pageIndex, name: annotation.name });
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
viewer.on("annotation:select", (selection) => {
|
|
473
|
+
if (!selection) return; // null = deselect
|
|
474
|
+
showInspector(selection.annotation);
|
|
475
|
+
});
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
> Annotation editing currently requires UI mode (a `container` was passed to `createViewer`) and is supported on PDF documents only.
|
|
479
|
+
|
|
386
480
|
### Programmatic Viewer Control
|
|
387
481
|
|
|
388
482
|
Control zoom, view modes, and fullscreen programmatically — useful when toolbars are hidden:
|
|
@@ -417,6 +511,33 @@ viewer.setFullscreen(true);
|
|
|
417
511
|
console.log(viewer.isFullscreen);
|
|
418
512
|
```
|
|
419
513
|
|
|
514
|
+
### Tools
|
|
515
|
+
|
|
516
|
+
Switch the active tool programmatically. The active tool is a tagged union: simple tools (`pointer`, `hand`, `zoom`) carry no sub-tool, while tool sets (`annotate`, `markup`) carry a `sub` for the active sub-tool.
|
|
517
|
+
|
|
518
|
+
```typescript
|
|
519
|
+
// Simple tools
|
|
520
|
+
viewer.setActiveTool({ kind: "pointer" });
|
|
521
|
+
viewer.setActiveTool({ kind: "hand" });
|
|
522
|
+
viewer.setActiveTool({ kind: "zoom" });
|
|
523
|
+
|
|
524
|
+
// Tool sets — sub-tool is required
|
|
525
|
+
viewer.setActiveTool({ kind: "annotate", sub: "freehand" });
|
|
526
|
+
viewer.setActiveTool({ kind: "annotate", sub: "rectangle" });
|
|
527
|
+
viewer.setActiveTool({ kind: "markup", sub: "highlight" });
|
|
528
|
+
|
|
529
|
+
// Calling with the same tool-set kind that's already active toggles back to pointer
|
|
530
|
+
|
|
531
|
+
// Read current tool
|
|
532
|
+
const t = viewer.activeTool;
|
|
533
|
+
if (t.kind === "annotate") {
|
|
534
|
+
console.log("annotating with", t.sub); // "freehand" | "rectangle" | ...
|
|
535
|
+
}
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
`AnnotateSubTool`: `select`, `freehand`, `line`, `arrow`, `rectangle`, `ellipse`, `polygon`, `polyline`.
|
|
539
|
+
`MarkupSubTool`: `select`, `highlight`, `underline`, `strikethrough`, `squiggly`.
|
|
540
|
+
|
|
420
541
|
### UI Visibility Control
|
|
421
542
|
|
|
422
543
|
Show, hide, or disable UI components at runtime:
|
|
@@ -614,6 +735,13 @@ viewer.on("page:change", ({ page, previousPage }) => {
|
|
|
614
735
|
console.log(`Page ${previousPage} -> ${page}`);
|
|
615
736
|
});
|
|
616
737
|
|
|
738
|
+
// Viewport changed (scroll, zoom, layout, or scroll-mode change).
|
|
739
|
+
// Throttled to one fire per animation frame and de-duped — adjacent
|
|
740
|
+
// identical payloads are coalesced. Page indices are 0-based.
|
|
741
|
+
viewer.on("viewport:change", ({ firstVisiblePage, lastVisiblePage, zoom, scrollTop }) => {
|
|
742
|
+
console.log(`Visible: ${firstVisiblePage}–${lastVisiblePage} @ ${zoom}x, scrollTop=${scrollTop}`);
|
|
743
|
+
});
|
|
744
|
+
|
|
617
745
|
// Panel opened/closed
|
|
618
746
|
viewer.on("panel:change", ({ panel, previousPanel }) => {
|
|
619
747
|
console.log(`Panel: ${previousPanel} -> ${panel}`);
|
|
@@ -634,6 +762,15 @@ viewer.on("search:change", ({ matches, activeIndex }) => {
|
|
|
634
762
|
console.log(`${matches.length} matches, active: ${activeIndex}`);
|
|
635
763
|
});
|
|
636
764
|
|
|
765
|
+
// Annotation lifecycle (fired for both UI- and API-driven changes; see the
|
|
766
|
+
// Annotations section above for full payloads)
|
|
767
|
+
viewer.on("annotation:add", ({ pageIndex, annotation }) => {});
|
|
768
|
+
viewer.on("annotation:update", ({ pageIndex, annotation }) => {});
|
|
769
|
+
viewer.on("annotation:remove", ({ pageIndex, annotation }) => {});
|
|
770
|
+
viewer.on("annotation:select", (selection) => {
|
|
771
|
+
// null when the selection is cleared
|
|
772
|
+
});
|
|
773
|
+
|
|
637
774
|
// Error occurred
|
|
638
775
|
viewer.on("error", ({ error, phase }) => {
|
|
639
776
|
console.error(`Error during ${phase}:`, error);
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docmentis/udoc-viewer",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.36",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Universal document viewer for the web — open-source, framework-agnostic viewer powered by a built-from-scratch WebAssembly engine for high-fidelity rendering across PDF, DOCX, PPTX, SVG, and images.",
|
package/dist/src/UDocClient.js
CHANGED
package/dist/src/UDocViewer.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ import { type Annotation } from "./ui/viewer/annotation/index.js";
|
|
|
12
12
|
export type { Annotation } from "./ui/viewer/annotation/index.js";
|
|
13
13
|
export type { SearchMatch } from "./ui/viewer/state.js";
|
|
14
14
|
import type { LayoutPage } from "./worker/index.js";
|
|
15
|
-
import { type ViewMode, type PanelTab, type ScrollMode, type LayoutMode, type ZoomMode, type PageRotation, type SpacingMode, type ThemeMode, type SearchMatch } from "./ui/viewer/state.js";
|
|
15
|
+
import { type ViewMode, type PanelTab, type ScrollMode, type LayoutMode, type ZoomMode, type PageRotation, type SpacingMode, type ThemeMode, type SearchMatch, type ActiveTool } from "./ui/viewer/state.js";
|
|
16
16
|
import { type IPerformanceCounter } from "./performance/index.js";
|
|
17
17
|
/**
|
|
18
18
|
* Options for rendering a page.
|
|
@@ -126,6 +126,38 @@ export interface ViewerEventMap {
|
|
|
126
126
|
matches: SearchMatch[];
|
|
127
127
|
activeIndex: number;
|
|
128
128
|
};
|
|
129
|
+
"annotation:add": {
|
|
130
|
+
pageIndex: number;
|
|
131
|
+
annotation: Annotation;
|
|
132
|
+
};
|
|
133
|
+
"annotation:update": {
|
|
134
|
+
pageIndex: number;
|
|
135
|
+
annotation: Annotation;
|
|
136
|
+
};
|
|
137
|
+
"annotation:remove": {
|
|
138
|
+
pageIndex: number;
|
|
139
|
+
annotation: Annotation;
|
|
140
|
+
};
|
|
141
|
+
"annotation:select": {
|
|
142
|
+
pageIndex: number;
|
|
143
|
+
annotation: Annotation;
|
|
144
|
+
} | null;
|
|
145
|
+
/**
|
|
146
|
+
* Fires when the user's view of the document changes — scroll position,
|
|
147
|
+
* zoom, layout, or scroll-mode changes that affect which pages are
|
|
148
|
+
* visible. Throttled to once per animation frame, and de-duped so
|
|
149
|
+
* adjacent identical payloads are coalesced.
|
|
150
|
+
*/
|
|
151
|
+
"viewport:change": {
|
|
152
|
+
/** First page index (0-based) at least partially visible. */
|
|
153
|
+
firstVisiblePage: number;
|
|
154
|
+
/** Last page index (0-based) at least partially visible. */
|
|
155
|
+
lastVisiblePage: number;
|
|
156
|
+
/** Current zoom factor (1 = 100%). */
|
|
157
|
+
zoom: number;
|
|
158
|
+
/** Vertical scroll offset of the viewport in CSS pixels. */
|
|
159
|
+
scrollTop: number;
|
|
160
|
+
};
|
|
129
161
|
}
|
|
130
162
|
type EventHandler<K extends keyof ViewerEventMap> = (payload: ViewerEventMap[K]) => void;
|
|
131
163
|
/**
|
|
@@ -148,6 +180,7 @@ export declare class UDocViewer {
|
|
|
148
180
|
private currentFormat;
|
|
149
181
|
private sourceFilename;
|
|
150
182
|
private storeUnsub;
|
|
183
|
+
private actionUnsub;
|
|
151
184
|
private fontUsageUnsub;
|
|
152
185
|
private sdkVersion;
|
|
153
186
|
/**
|
|
@@ -228,9 +261,64 @@ export declare class UDocViewer {
|
|
|
228
261
|
getPageInfo(page: number): Promise<PageInfo>;
|
|
229
262
|
/**
|
|
230
263
|
* Get annotations on a specific page.
|
|
264
|
+
*
|
|
265
|
+
* Returns the in-memory state if the page has been edited in this
|
|
266
|
+
* session; otherwise reads from the worker.
|
|
267
|
+
*
|
|
231
268
|
* @param page - Page index (0-based)
|
|
232
269
|
*/
|
|
233
270
|
getPageAnnotations(page: number): Promise<Annotation[]>;
|
|
271
|
+
/**
|
|
272
|
+
* Add a new annotation to a page.
|
|
273
|
+
*
|
|
274
|
+
* If `annotation.name` is omitted, a UUID is generated and assigned. The
|
|
275
|
+
* returned value is the annotation as inserted (with `name` populated),
|
|
276
|
+
* which is the same identifier the engine will write to the PDF's NM
|
|
277
|
+
* entry on save.
|
|
278
|
+
*
|
|
279
|
+
* Pass `ephemeral: true` to create a viewer-only annotation that renders
|
|
280
|
+
* but is excluded from saved PDF bytes and from print output. The same
|
|
281
|
+
* `updatePageAnnotation` / `removePageAnnotation` calls work for both kinds, and
|
|
282
|
+
* `updatePageAnnotation` can flip the `ephemeral` flag to promote a preview
|
|
283
|
+
* into a saved annotation (or demote a saved one to viewer-only).
|
|
284
|
+
*
|
|
285
|
+
* Annotation editing currently requires UI mode (a `container` was passed
|
|
286
|
+
* to `client.createViewer`) and is supported on PDF documents only.
|
|
287
|
+
*
|
|
288
|
+
* @param page - Page index (0-based)
|
|
289
|
+
* @returns The inserted annotation (with `name` populated).
|
|
290
|
+
*/
|
|
291
|
+
addPageAnnotation(page: number, annotation: Annotation): Promise<Annotation>;
|
|
292
|
+
/**
|
|
293
|
+
* Update an existing annotation, identified by its `name` (NM).
|
|
294
|
+
*
|
|
295
|
+
* Looks up the annotation on the given page by `name` and replaces it
|
|
296
|
+
* with the supplied value. The replacement keeps the same `name` even
|
|
297
|
+
* if a different one is passed in `annotation.name`.
|
|
298
|
+
*
|
|
299
|
+
* @param page - Page index (0-based)
|
|
300
|
+
* @param name - The annotation's `name` (NM).
|
|
301
|
+
* @param annotation - The replacement annotation.
|
|
302
|
+
* @returns The updated annotation.
|
|
303
|
+
* @throws If no annotation with the given `name` is found on the page.
|
|
304
|
+
*/
|
|
305
|
+
updatePageAnnotation(page: number, name: string, annotation: Annotation): Promise<Annotation>;
|
|
306
|
+
/**
|
|
307
|
+
* Remove an annotation, identified by its `name` (NM).
|
|
308
|
+
*
|
|
309
|
+
* @param page - Page index (0-based)
|
|
310
|
+
* @param name - The annotation's `name` (NM).
|
|
311
|
+
* @throws If no annotation with the given `name` is found on the page.
|
|
312
|
+
*/
|
|
313
|
+
removePageAnnotation(page: number, name: string): Promise<void>;
|
|
314
|
+
/**
|
|
315
|
+
* Ensure pageAnnotations is populated for a page so that mutator actions
|
|
316
|
+
* have a baseline list to operate on. The reducer's ADD path tolerates a
|
|
317
|
+
* missing page, but UPDATE/REMOVE need the existing annotations loaded
|
|
318
|
+
* so we don't silently lose what the worker has.
|
|
319
|
+
*/
|
|
320
|
+
private ensurePageAnnotationsLoaded;
|
|
321
|
+
private findAnnotationIndex;
|
|
234
322
|
/**
|
|
235
323
|
* Get the layout structure for a specific page.
|
|
236
324
|
* Returns frames, parcels, lines, runs, glyphs, tables, and grids
|
|
@@ -360,6 +448,19 @@ export declare class UDocViewer {
|
|
|
360
448
|
* Show or hide the floating toolbar (page navigation, zoom, view mode controls).
|
|
361
449
|
*/
|
|
362
450
|
setFloatingToolbarVisible(visible: boolean): void;
|
|
451
|
+
/**
|
|
452
|
+
* Currently active tool, as a tagged union. The `kind` is one of `"pointer"`,
|
|
453
|
+
* `"hand"`, `"zoom"`, `"annotate"`, `"markup"`; for `"annotate"` and `"markup"`
|
|
454
|
+
* a `sub` field carries the active sub-tool (`"freehand"`, `"highlight"`, etc.).
|
|
455
|
+
*/
|
|
456
|
+
get activeTool(): ActiveTool;
|
|
457
|
+
/**
|
|
458
|
+
* Switch the currently active tool. Tool-set kinds (`"annotate"`, `"markup"`)
|
|
459
|
+
* require a `sub`, e.g. `{ kind: "annotate", sub: "freehand" }`. Calling
|
|
460
|
+
* this with the same tool-set kind that's already active toggles back to
|
|
461
|
+
* the pointer tool, matching the toolbar UI.
|
|
462
|
+
*/
|
|
463
|
+
setActiveTool(tool: ActiveTool): void;
|
|
363
464
|
/**
|
|
364
465
|
* Enable or disable the fullscreen button.
|
|
365
466
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UDocViewer.d.ts","sourceRoot":"","sources":["../../src/UDocViewer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAc,cAAc,EAAqB,MAAM,mBAAmB,CAAC;AAC/G,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,KAAK,EAAE,iBAAiB,EAAgC,MAAM,uCAAuC,CAAC;AAC7G,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC3F,OAAO,EAA4B,KAAK,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE5F,YAAY,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAIH,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,SAAS,EAEd,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"UDocViewer.d.ts","sourceRoot":"","sources":["../../src/UDocViewer.ts"],"names":[],"mappings":"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"}
|
package/dist/src/UDocViewer.js
CHANGED
|
@@ -9,6 +9,21 @@ import { renderAnnotationsToLayer } from "./ui/viewer/annotation/index.js";
|
|
|
9
9
|
import { extractPageText } from "./ui/viewer/search/index.js";
|
|
10
10
|
import { getFormatDefaults, } from "./ui/viewer/state.js";
|
|
11
11
|
import { PerformanceCounter, NoOpPerformanceCounter } from "./performance/index.js";
|
|
12
|
+
/**
|
|
13
|
+
* Generate a unique annotation identifier suitable for the PDF NM entry.
|
|
14
|
+
* Uses crypto.randomUUID() when available, falling back to a Math.random
|
|
15
|
+
* shim for environments (older Safari, Node < 19) without it.
|
|
16
|
+
*/
|
|
17
|
+
function generateAnnotationId() {
|
|
18
|
+
const cryptoObj = globalThis.crypto;
|
|
19
|
+
if (cryptoObj?.randomUUID)
|
|
20
|
+
return cryptoObj.randomUUID();
|
|
21
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
22
|
+
const r = (Math.random() * 16) | 0;
|
|
23
|
+
const v = c === "x" ? r : (r & 0x3) | 0x8;
|
|
24
|
+
return v.toString(16);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
12
27
|
/**
|
|
13
28
|
* Document viewer component.
|
|
14
29
|
*
|
|
@@ -29,13 +44,14 @@ export class UDocViewer {
|
|
|
29
44
|
currentFormat = null;
|
|
30
45
|
sourceFilename = null;
|
|
31
46
|
storeUnsub = null;
|
|
47
|
+
actionUnsub = null;
|
|
32
48
|
fontUsageUnsub = null;
|
|
33
49
|
sdkVersion;
|
|
34
50
|
/**
|
|
35
51
|
* @internal
|
|
36
52
|
* Use `client.createViewer()` instead.
|
|
37
53
|
*/
|
|
38
|
-
constructor(workerClient, options = {}, showAttribution = true, showLoadingOverlay = true, sdkVersion = "0.6.
|
|
54
|
+
constructor(workerClient, options = {}, showAttribution = true, showLoadingOverlay = true, sdkVersion = "0.6.36") {
|
|
39
55
|
this.workerClient = workerClient;
|
|
40
56
|
this.sdkVersion = sdkVersion;
|
|
41
57
|
this.viewOverrides = this.buildViewModeOverrides(options);
|
|
@@ -73,6 +89,7 @@ export class UDocViewer {
|
|
|
73
89
|
onPasswordSubmit: (password) => this.handlePasswordSubmit(password),
|
|
74
90
|
onDownload: () => this.download(),
|
|
75
91
|
onPrint: (options) => this.print(options),
|
|
92
|
+
onViewportChange: (payload) => this.emit("viewport:change", payload),
|
|
76
93
|
});
|
|
77
94
|
// Subscribe to store state changes to emit public events
|
|
78
95
|
this.storeUnsub = this.uiShell.store.subscribeEffect((prev, next) => {
|
|
@@ -148,6 +165,49 @@ export class UDocViewer {
|
|
|
148
165
|
}
|
|
149
166
|
}
|
|
150
167
|
});
|
|
168
|
+
// Forward annotation mutations as public events. Subscribing at the
|
|
169
|
+
// action layer (rather than diffing state) lets us include the
|
|
170
|
+
// exact affected annotation in the payload — including the removed
|
|
171
|
+
// one, which we look up in `prev` before the reducer dropped it.
|
|
172
|
+
this.actionUnsub = this.uiShell.store.subscribeAction((action, prev, next) => {
|
|
173
|
+
switch (action.type) {
|
|
174
|
+
case "ADD_ANNOTATION":
|
|
175
|
+
this.emit("annotation:add", {
|
|
176
|
+
pageIndex: action.pageIndex,
|
|
177
|
+
annotation: action.annotation,
|
|
178
|
+
});
|
|
179
|
+
break;
|
|
180
|
+
case "UPDATE_ANNOTATION":
|
|
181
|
+
this.emit("annotation:update", {
|
|
182
|
+
pageIndex: action.pageIndex,
|
|
183
|
+
annotation: action.annotation,
|
|
184
|
+
});
|
|
185
|
+
break;
|
|
186
|
+
case "REMOVE_ANNOTATION": {
|
|
187
|
+
const removed = prev.pageAnnotations.get(action.pageIndex)?.[action.annotationIndex];
|
|
188
|
+
if (removed) {
|
|
189
|
+
this.emit("annotation:remove", {
|
|
190
|
+
pageIndex: action.pageIndex,
|
|
191
|
+
annotation: removed,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
case "SELECT_ANNOTATION": {
|
|
197
|
+
const ann = next.pageAnnotations.get(action.pageIndex)?.[action.annotationIndex];
|
|
198
|
+
if (ann) {
|
|
199
|
+
this.emit("annotation:select", {
|
|
200
|
+
pageIndex: action.pageIndex,
|
|
201
|
+
annotation: ann,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
case "DESELECT_ANNOTATION":
|
|
207
|
+
this.emit("annotation:select", null);
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
});
|
|
151
211
|
}
|
|
152
212
|
}
|
|
153
213
|
/**
|
|
@@ -528,13 +588,109 @@ export class UDocViewer {
|
|
|
528
588
|
}
|
|
529
589
|
/**
|
|
530
590
|
* Get annotations on a specific page.
|
|
591
|
+
*
|
|
592
|
+
* Returns the in-memory state if the page has been edited in this
|
|
593
|
+
* session; otherwise reads from the worker.
|
|
594
|
+
*
|
|
531
595
|
* @param page - Page index (0-based)
|
|
532
596
|
*/
|
|
533
597
|
async getPageAnnotations(page) {
|
|
534
598
|
this.ensureLoaded();
|
|
599
|
+
const fromState = this.uiShell?.store.getState().pageAnnotations.get(page);
|
|
600
|
+
if (fromState)
|
|
601
|
+
return fromState;
|
|
535
602
|
const raw = await this.workerClient.getPageAnnotations(this.documentId, page);
|
|
536
603
|
return raw;
|
|
537
604
|
}
|
|
605
|
+
/**
|
|
606
|
+
* Add a new annotation to a page.
|
|
607
|
+
*
|
|
608
|
+
* If `annotation.name` is omitted, a UUID is generated and assigned. The
|
|
609
|
+
* returned value is the annotation as inserted (with `name` populated),
|
|
610
|
+
* which is the same identifier the engine will write to the PDF's NM
|
|
611
|
+
* entry on save.
|
|
612
|
+
*
|
|
613
|
+
* Pass `ephemeral: true` to create a viewer-only annotation that renders
|
|
614
|
+
* but is excluded from saved PDF bytes and from print output. The same
|
|
615
|
+
* `updatePageAnnotation` / `removePageAnnotation` calls work for both kinds, and
|
|
616
|
+
* `updatePageAnnotation` can flip the `ephemeral` flag to promote a preview
|
|
617
|
+
* into a saved annotation (or demote a saved one to viewer-only).
|
|
618
|
+
*
|
|
619
|
+
* Annotation editing currently requires UI mode (a `container` was passed
|
|
620
|
+
* to `client.createViewer`) and is supported on PDF documents only.
|
|
621
|
+
*
|
|
622
|
+
* @param page - Page index (0-based)
|
|
623
|
+
* @returns The inserted annotation (with `name` populated).
|
|
624
|
+
*/
|
|
625
|
+
async addPageAnnotation(page, annotation) {
|
|
626
|
+
this.ensureLoaded();
|
|
627
|
+
this.ensureUiMode();
|
|
628
|
+
await this.ensurePageAnnotationsLoaded(page);
|
|
629
|
+
const withId = annotation.name ? annotation : { ...annotation, name: generateAnnotationId() };
|
|
630
|
+
this.uiShell.dispatch({ type: "ADD_ANNOTATION", pageIndex: page, annotation: withId });
|
|
631
|
+
return withId;
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Update an existing annotation, identified by its `name` (NM).
|
|
635
|
+
*
|
|
636
|
+
* Looks up the annotation on the given page by `name` and replaces it
|
|
637
|
+
* with the supplied value. The replacement keeps the same `name` even
|
|
638
|
+
* if a different one is passed in `annotation.name`.
|
|
639
|
+
*
|
|
640
|
+
* @param page - Page index (0-based)
|
|
641
|
+
* @param name - The annotation's `name` (NM).
|
|
642
|
+
* @param annotation - The replacement annotation.
|
|
643
|
+
* @returns The updated annotation.
|
|
644
|
+
* @throws If no annotation with the given `name` is found on the page.
|
|
645
|
+
*/
|
|
646
|
+
async updatePageAnnotation(page, name, annotation) {
|
|
647
|
+
this.ensureLoaded();
|
|
648
|
+
this.ensureUiMode();
|
|
649
|
+
const index = await this.findAnnotationIndex(page, name);
|
|
650
|
+
const updated = { ...annotation, name };
|
|
651
|
+
this.uiShell.dispatch({
|
|
652
|
+
type: "UPDATE_ANNOTATION",
|
|
653
|
+
pageIndex: page,
|
|
654
|
+
annotationIndex: index,
|
|
655
|
+
annotation: updated,
|
|
656
|
+
});
|
|
657
|
+
return updated;
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Remove an annotation, identified by its `name` (NM).
|
|
661
|
+
*
|
|
662
|
+
* @param page - Page index (0-based)
|
|
663
|
+
* @param name - The annotation's `name` (NM).
|
|
664
|
+
* @throws If no annotation with the given `name` is found on the page.
|
|
665
|
+
*/
|
|
666
|
+
async removePageAnnotation(page, name) {
|
|
667
|
+
this.ensureLoaded();
|
|
668
|
+
this.ensureUiMode();
|
|
669
|
+
const index = await this.findAnnotationIndex(page, name);
|
|
670
|
+
this.uiShell.dispatch({ type: "REMOVE_ANNOTATION", pageIndex: page, annotationIndex: index });
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* Ensure pageAnnotations is populated for a page so that mutator actions
|
|
674
|
+
* have a baseline list to operate on. The reducer's ADD path tolerates a
|
|
675
|
+
* missing page, but UPDATE/REMOVE need the existing annotations loaded
|
|
676
|
+
* so we don't silently lose what the worker has.
|
|
677
|
+
*/
|
|
678
|
+
async ensurePageAnnotationsLoaded(page) {
|
|
679
|
+
const state = this.uiShell.store.getState();
|
|
680
|
+
if (state.pageAnnotations.has(page))
|
|
681
|
+
return;
|
|
682
|
+
const raw = (await this.workerClient.getPageAnnotations(this.documentId, page));
|
|
683
|
+
this.uiShell.dispatch({ type: "SET_PAGE_ANNOTATIONS", pageIndex: page, annotations: raw });
|
|
684
|
+
}
|
|
685
|
+
async findAnnotationIndex(page, name) {
|
|
686
|
+
await this.ensurePageAnnotationsLoaded(page);
|
|
687
|
+
const list = this.uiShell.store.getState().pageAnnotations.get(page) ?? [];
|
|
688
|
+
const index = list.findIndex((a) => a.name === name);
|
|
689
|
+
if (index < 0) {
|
|
690
|
+
throw new Error(`No annotation with name "${name}" on page ${page}`);
|
|
691
|
+
}
|
|
692
|
+
return index;
|
|
693
|
+
}
|
|
538
694
|
/**
|
|
539
695
|
* Get the layout structure for a specific page.
|
|
540
696
|
* Returns frames, parcels, lines, runs, glyphs, tables, and grids
|
|
@@ -813,6 +969,25 @@ export class UDocViewer {
|
|
|
813
969
|
this.ensureUiMode();
|
|
814
970
|
this.uiShell.dispatch({ type: "SET_FLOATING_TOOLBAR_VISIBLE", visible });
|
|
815
971
|
}
|
|
972
|
+
/**
|
|
973
|
+
* Currently active tool, as a tagged union. The `kind` is one of `"pointer"`,
|
|
974
|
+
* `"hand"`, `"zoom"`, `"annotate"`, `"markup"`; for `"annotate"` and `"markup"`
|
|
975
|
+
* a `sub` field carries the active sub-tool (`"freehand"`, `"highlight"`, etc.).
|
|
976
|
+
*/
|
|
977
|
+
get activeTool() {
|
|
978
|
+
return this.uiShell?.getState().activeTool ?? { kind: "pointer" };
|
|
979
|
+
}
|
|
980
|
+
/**
|
|
981
|
+
* Switch the currently active tool. Tool-set kinds (`"annotate"`, `"markup"`)
|
|
982
|
+
* require a `sub`, e.g. `{ kind: "annotate", sub: "freehand" }`. Calling
|
|
983
|
+
* this with the same tool-set kind that's already active toggles back to
|
|
984
|
+
* the pointer tool, matching the toolbar UI.
|
|
985
|
+
*/
|
|
986
|
+
setActiveTool(tool) {
|
|
987
|
+
this.ensureNotDestroyed();
|
|
988
|
+
this.ensureUiMode();
|
|
989
|
+
this.uiShell.dispatch({ type: "SET_ACTIVE_TOOL", tool });
|
|
990
|
+
}
|
|
816
991
|
/**
|
|
817
992
|
* Enable or disable the fullscreen button.
|
|
818
993
|
*/
|
|
@@ -1153,12 +1328,14 @@ export class UDocViewer {
|
|
|
1153
1328
|
*/
|
|
1154
1329
|
async toBytes() {
|
|
1155
1330
|
this.ensureLoaded();
|
|
1156
|
-
// If there are dirty annotation pages, save them into the PDF first
|
|
1331
|
+
// If there are dirty annotation pages, save them into the PDF first.
|
|
1332
|
+
// Ephemeral annotations are excluded — they're viewer-only and never persist.
|
|
1157
1333
|
const state = this.uiShell?.store.getState();
|
|
1158
1334
|
if (state && state.annotationsDirtyPages.size > 0 && this.currentFormat === "pdf") {
|
|
1159
1335
|
const annotationsByPage = {};
|
|
1160
1336
|
for (const [pageIndex, annotations] of state.pageAnnotations) {
|
|
1161
|
-
|
|
1337
|
+
const persistable = annotations.filter((a) => !a.ephemeral);
|
|
1338
|
+
annotationsByPage[String(pageIndex)] = persistable;
|
|
1162
1339
|
}
|
|
1163
1340
|
return this.workerClient.pdfSaveAnnotations(this.documentId, annotationsByPage);
|
|
1164
1341
|
}
|
|
@@ -1296,7 +1473,9 @@ export class UDocViewer {
|
|
|
1296
1473
|
// is sized in inches (1in = 96 CSS px), so we scale by 96/72 to convert
|
|
1297
1474
|
// PDF points to CSS pixels.
|
|
1298
1475
|
const state = this.uiShell?.store.getState();
|
|
1299
|
-
|
|
1476
|
+
// Exclude ephemeral annotations from print output — they're
|
|
1477
|
+
// viewer-only overlays.
|
|
1478
|
+
const pageAnnotations = state?.pageAnnotations.get(pageIndex)?.filter((a) => !a.ephemeral);
|
|
1300
1479
|
let annotationLayer = "";
|
|
1301
1480
|
if (pageAnnotations && pageAnnotations.length > 0) {
|
|
1302
1481
|
const tempLayer = document.createElement("div");
|
|
@@ -1447,6 +1626,10 @@ img { display: block; }
|
|
|
1447
1626
|
this.storeUnsub();
|
|
1448
1627
|
this.storeUnsub = null;
|
|
1449
1628
|
}
|
|
1629
|
+
if (this.actionUnsub) {
|
|
1630
|
+
this.actionUnsub();
|
|
1631
|
+
this.actionUnsub = null;
|
|
1632
|
+
}
|
|
1450
1633
|
if (this.fontUsageUnsub) {
|
|
1451
1634
|
this.fontUsageUnsub();
|
|
1452
1635
|
this.fontUsageUnsub = null;
|