@embedpdf/plugin-annotation 3.0.0-next.11 → 3.0.0-next.13

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.
Files changed (46) hide show
  1. package/dist/{capability-DBsr2D-L.js → capability-B_dkoB1K.js} +567 -558
  2. package/dist/capability-B_dkoB1K.js.map +1 -0
  3. package/dist/{capability-Csb9WMm-.cjs → capability-DVx1NmTe.cjs} +568 -577
  4. package/dist/capability-DVx1NmTe.cjs.map +1 -0
  5. package/dist/contract/host.cjs +1 -1
  6. package/dist/contract/host.d.cts +1 -1
  7. package/dist/contract/host.d.ts +1 -1
  8. package/dist/contract/host.js +1 -1
  9. package/dist/contract-CgAcfAE7.d.cts +34 -0
  10. package/dist/contract-CiG2_HBq.d.ts +34 -0
  11. package/dist/contract-DtXE1hjY.js +32 -0
  12. package/dist/contract-DtXE1hjY.js.map +1 -0
  13. package/dist/contract-a4eaQWga.cjs +67 -0
  14. package/dist/contract-a4eaQWga.cjs.map +1 -0
  15. package/dist/contract.cjs +11 -7
  16. package/dist/contract.d.cts +3 -10
  17. package/dist/contract.d.ts +3 -10
  18. package/dist/contract.js +4 -8
  19. package/dist/index.cjs +47 -8
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +3 -3
  22. package/dist/index.d.ts +3 -3
  23. package/dist/index.js +39 -7
  24. package/dist/index.js.map +1 -1
  25. package/dist/internal.cjs +4 -3
  26. package/dist/internal.d.cts +1 -1
  27. package/dist/internal.d.ts +1 -1
  28. package/dist/internal.js +3 -2
  29. package/dist/tools-0NI3b9z8.cjs +536 -0
  30. package/dist/tools-0NI3b9z8.cjs.map +1 -0
  31. package/dist/tools-DBEYx3-c.js +513 -0
  32. package/dist/tools-DBEYx3-c.js.map +1 -0
  33. package/dist/{types-CwytT-TI.js → types-BvB1vUKb.js} +9 -2
  34. package/dist/types-BvB1vUKb.js.map +1 -0
  35. package/dist/{types-otwv-Cdl.d.ts → types-D5V0TIwk.d.ts} +133 -19
  36. package/dist/types-Dlhdw2k_.cjs +31 -0
  37. package/dist/types-Dlhdw2k_.cjs.map +1 -0
  38. package/dist/{types-eLTpocXz.d.cts → types-ObcPYc3-.d.cts} +133 -19
  39. package/package.json +9 -9
  40. package/dist/capability-Csb9WMm-.cjs.map +0 -1
  41. package/dist/capability-DBsr2D-L.js.map +0 -1
  42. package/dist/contract.cjs.map +0 -1
  43. package/dist/contract.js.map +0 -1
  44. package/dist/types-CwytT-TI.js.map +0 -1
  45. package/dist/types-DimcLIic.cjs +0 -17
  46. package/dist/types-DimcLIic.cjs.map +0 -1
@@ -1,8 +1,22 @@
1
- import { AnnotationFlags, AnnotationProps, AnnotationPropsPatch, ChromeNode, ClickCreate, CreationDraftAnchor, Geom, Id, InkStraightenOptions, Model, PropKey, PropSpec, Rect, RenderItem, SnapSettings, Subtype, TextEndAnchor, TextQuad, Vec, ViewEnv } from "@embedpdf/core-annotation";
2
- import { AnnotationAppearanceImage, AnnotationDTO, AnnotationDraft, AnnotationPatch, AnnotationRef, AttachmentContent, AttachmentFileSource, BinarySource, CommentThread, InkIntent, PdfActionTree, PdfLinkTarget, PdfRect } from "@embedpdf/engine-core/runtime";
1
+ import { Annot, AnnotationFlags, AnnotationProps, AnnotationPropsPatch, ChromeNode, ClickCreate, CreationDraftAnchor, Geom, Id, InkStraightenOptions, Model, PropKey, PropSpec, Rect, RenderItem, RichTextRange, SnapSettings, Subtype, TextEndAnchor, TextQuad, Vec, ViewEnv } from "@embedpdf/core-annotation";
2
+ import { AnnotationAppearanceImage, AnnotationDTO, AnnotationDraft, AnnotationPatch, AnnotationRef, AttachmentContent, AttachmentFileSource, BinarySource, CommentThread, InkIntent, PdfActionTree, PdfLinkTarget, PdfRect, RichTextParagraph } from "@embedpdf/engine-core/runtime";
3
3
  import { DocumentEvent, PageObjectNumber } from "@embedpdf/core";
4
4
  import { AnnotCommitEntry, AnnotCommitResult } from "@embedpdf/plugin-actions/contract/host";
5
5
  import { PageRotation } from "@embedpdf/core-geometry";
6
+ //#region src/rich-text.d.ts
7
+ type TextFormat = 'bold' | 'italic' | 'underline';
8
+ /** The editor's selection inside one free-text annotation: flat offsets over
9
+ * the plain projection (paragraphs joined by `\r`). */
10
+ interface TextSelection extends RichTextRange {
11
+ id: string;
12
+ }
13
+ /** The face a run or a body names. */
14
+ interface Face {
15
+ family: string;
16
+ weight?: number;
17
+ italic?: boolean;
18
+ }
19
+ //#endregion
6
20
  //#region src/tools.d.ts
7
21
  /**
8
22
  * How a stamp-family tool resolves the image bytes it places — pure DATA, so a
@@ -28,6 +42,15 @@ interface PromptSourceSpec {
28
42
  kind: 'prompt';
29
43
  accept?: string;
30
44
  }
45
+ /**
46
+ * The tool `armStamp` activates — and the only tool an armed payload survives
47
+ * onto (plus the legacy `annotation-stamp` tag, honoured for embedder configs
48
+ * written before the tags were unified). Placement consults the armed payload
49
+ * BEFORE the active tool's own `source` spec, so a payload must not outlive
50
+ * its tool onto a sibling stamp preset: an `image` preset's click has to open
51
+ * its own picker, not silently place whatever the stamp panel last armed.
52
+ */
53
+ declare const ARMED_STAMP_TOOL_ID = "stamp";
31
54
  /** Declarative result of committing a text selection while a tool is active. */
32
55
  type SelectionAuthoring = {
33
56
  kind: 'markup';
@@ -69,8 +92,8 @@ declare const TOOL_DEFAULT_KEYS: {
69
92
  readonly polygon: readonly ["color", "interiorColor", "opacity", "strokeWidth", "border"];
70
93
  readonly polyline: readonly ["color", "interiorColor", "opacity", "strokeWidth", "border", "lineEndings"];
71
94
  readonly ink: readonly ["color", "opacity", "strokeWidth", "blendMode"];
72
- readonly 'free-text': readonly ["fontFamily", "fontSize", "fontColor", "textAlign", "opacity", "interiorColor", "color", "strokeWidth", "border"];
73
- readonly 'free-text-callout': readonly ["fontFamily", "fontSize", "fontColor", "textAlign", "opacity", "interiorColor", "color", "strokeWidth", "border", "lineEndings"];
95
+ readonly 'free-text': readonly ["fontFamily", "fontSize", "fontColor", "bold", "italic", "underline", "textAlign", "opacity", "interiorColor", "color", "strokeWidth", "border"];
96
+ readonly 'free-text-callout': readonly ["fontFamily", "fontSize", "fontColor", "bold", "italic", "underline", "textAlign", "opacity", "interiorColor", "color", "strokeWidth", "border", "lineEndings"];
74
97
  readonly highlight: readonly ["color", "opacity", "blendMode"];
75
98
  readonly underline: readonly ["color", "opacity", "blendMode"];
76
99
  readonly strikeout: readonly ["color", "opacity", "blendMode"];
@@ -84,6 +107,7 @@ declare const TOOL_DEFAULT_KEYS: {
84
107
  readonly 'widget-text': readonly ["color", "interiorColor", "strokeWidth", "border", "fontFamily", "fontSize", "fontColor", "textAlign"];
85
108
  readonly 'widget-choice': readonly ["color", "interiorColor", "strokeWidth", "border", "fontFamily", "fontSize", "fontColor", "textAlign"];
86
109
  readonly 'widget-toggle': readonly ["color", "interiorColor", "strokeWidth", "border"];
110
+ readonly 'widget-box': readonly ["color", "interiorColor", "strokeWidth", "border"];
87
111
  };
88
112
  type ToolAuthoringKind = keyof typeof TOOL_DEFAULT_KEYS;
89
113
  type ToolDefaultKey<K extends ToolAuthoringKind> = (typeof TOOL_DEFAULT_KEYS)[K][number];
@@ -351,6 +375,13 @@ interface AnnotationState {
351
375
  /** Bumps on every arm/disarm — the render layer's cue to rebuild (or drop)
352
376
  * the ghost preview object URL. Never rendered itself. */
353
377
  stampArmEpoch: number;
378
+ /**
379
+ * The text editor's selection inside the annotation being edited (flat
380
+ * offsets over its plain projection), or null. In the store because it is
381
+ * READ by the property surface: while a range is held, the range keys
382
+ * (`getSelectionProps`) report and take the RUNS, not the body.
383
+ */
384
+ textSelection: TextSelection | null;
354
385
  }
355
386
  /** The armed tool's would-be placement under the cursor (content space). */
356
387
  type ToolGhost = {
@@ -407,6 +438,9 @@ type AnnotationAction = {
407
438
  } | {
408
439
  type: 'SET_TOOL_GHOST';
409
440
  ghost: ToolGhost | null;
441
+ } | {
442
+ type: 'SET_TEXT_SELECTION';
443
+ selection: TextSelection | null;
410
444
  } | {
411
445
  type: 'STAMP_ARM_CHANGED';
412
446
  };
@@ -475,27 +509,38 @@ type SelectionFlags = { [K in keyof AnnotationFlags]: boolean | null; };
475
509
  * A free-text annotation projected for the framework: the box (content space,
476
510
  * live gesture applied) + the plain text + an `editing` flag + a ready-to-spread
477
511
  * CSS style. The framework renders ONE editable element from this and nothing
478
- * more — all the mapping (fonts, colours, alignment) is done here, once.
512
+ * more — all the mapping (fonts, colours, alignment) is done here, once. The
513
+ * element paints the TEXT only: the box's fill and border are the vector
514
+ * scene's (`pageItems`), the same for a plain box and a callout, so the live
515
+ * view matches the baked appearance.
479
516
  */
480
517
  interface TextItem {
481
518
  id: Id;
482
519
  ref: AnnotationRef | null;
483
520
  box: Rect;
484
521
  contents: string;
522
+ /** The rich paragraphs the editor renders and edits (run deltas over the
523
+ * body, which `css` carries). `contents` is their plain projection. */
524
+ richText: {
525
+ paragraphs: RichTextParagraph[];
526
+ };
485
527
  editing: boolean;
486
528
  /** Applied rotation (deg, CW). `box` is the UNROTATED text box; the framework
487
529
  * rotates the editable element about its centre by this. 0/undefined = none. */
488
530
  rot?: number;
489
531
  css: {
490
532
  fontFamily: string;
491
- /** Content units (the framework multiplies by the page scale). */
533
+ /** Content units (the framework multiplies by the page scale). The line
534
+ * height is NOT here: the editor binding states the engine's line model
535
+ * per face on the element itself (`@embedpdf/web`, `lineModelFor`). */
492
536
  fontSize: number;
493
- lineHeight: number;
494
537
  color: string;
538
+ /** The body's formatting (runs override it as inline spans). */
539
+ fontWeight: number;
540
+ fontStyle: 'normal' | 'italic';
541
+ textDecoration: 'none' | 'underline';
495
542
  align: 'left' | 'center' | 'right';
496
543
  padding: number;
497
- /** `/C` box background as a CSS colour, or null for transparent. */
498
- background: string | null;
499
544
  };
500
545
  }
501
546
  /**
@@ -623,6 +668,14 @@ interface AnnotationCapability {
623
668
  * `{ print: false }`, `{ hidden: true }`.
624
669
  */
625
670
  updateSelectionFlags(patch: Partial<AnnotationFlags>): void;
671
+ /**
672
+ * Flip a rich-text format on the selection — the editor's Cmd/Ctrl+B/I/U
673
+ * and a toolbar toggle: the text range's runs while the editor holds one,
674
+ * else the selected free-text bodies. Reads the current state the way
675
+ * {@link getSelectionProps} reports it and writes its inverse through
676
+ * {@link updateSelection}.
677
+ */
678
+ toggleTextFormat(format: TextFormat): void;
626
679
  /**
627
680
  * The selection's `/F` flag state: per-flag `true`/`false`, or `null` when
628
681
  * the selected annotations disagree (indeterminate). `null` overall when
@@ -724,6 +777,13 @@ interface AnnotationCapability {
724
777
  armStamp(input: StampToolInput): Promise<void>;
725
778
  /** Drop the armed stamp payload (a tool change away from 'stamp' does this too). */
726
779
  disarmStamp(): void;
780
+ /**
781
+ * Place a stamp WITHOUT the pointer: the same validation, fit, page clamp,
782
+ * `/Name`, and `/Subj` a click after {@link armStamp} produces — the one
783
+ * placement law, exposed for code. Resolves to the created annotation's
784
+ * ref; the placement is selected like a click's.
785
+ */
786
+ placeStamp(input: StampToolInput, placement: StampPlacement): Promise<AnnotationRef>;
727
787
  /**
728
788
  * Install the ONE file-picker port every click-then-pick tool resolves
729
789
  * through (see {@link FilePickerProvider}) — the stamp `'prompt'` source and
@@ -772,14 +832,18 @@ interface StampToolInput {
772
832
  source: BinarySource;
773
833
  /** Placed width in PDF points (height follows the intrinsic aspect). Default 150. */
774
834
  targetWidth?: number;
835
+ /** The placed annotation's `/Name` — the stamp identifier (standard or custom). */
836
+ name?: string;
837
+ /** The placed annotation's `/Subj`. */
838
+ subject?: string;
775
839
  /**
776
- * A browser-paintable render of `source` for the hover ghost (PNG/JPEG).
777
- * Required for the ghost when `source` is PDF bytes — the browser cannot
778
- * paint those; the caller (e.g. a stamp library) supplies its cached page
779
- * render. Raster sources default to the source itself; omit everywhere
780
- * else and the tool simply shows no ghost.
840
+ * The hover ghost's image. Either fixed bytes (PNG/JPEG) or — for vector
841
+ * sources, which are only ever right at ONE on-screen size — a
842
+ * {@link StampPreviewProvider} the ghost asks for a render at the device
843
+ * pixel width it is displayed at. Raster sources default to themselves;
844
+ * omit and the tool simply shows no ghost.
781
845
  */
782
- preview?: BinarySource;
846
+ preview?: BinarySource | StampPreviewProvider;
783
847
  /**
784
848
  * The source's intrinsic size in PDF points. Raster sources are measured
785
849
  * from their own header, but PDF bytes carry no sniffable dimensions —
@@ -797,6 +861,33 @@ interface ArmedStampPreview {
797
861
  bytes: Uint8Array;
798
862
  mimeType?: string;
799
863
  }
864
+ /**
865
+ * Resolution-aware ghost preview: "give me this stamp at `devicePixelWidth`
866
+ * pixels wide". The annotation plugin buckets the request (see
867
+ * {@link previewBucket}) and caches per bucket for the arm's lifetime, so a
868
+ * zoom gesture never renders per frame and one render serves a zoom range.
869
+ * A stamp library renders its page lazily through its asset engine; a raster
870
+ * returns itself (it cannot get sharper than its pixels).
871
+ */
872
+ type StampPreviewProvider = (devicePixelWidth: number) => Promise<ArmedStampPreview | null>;
873
+ /**
874
+ * Ghost render buckets: powers of two from 128 px up to `cap`. The same policy
875
+ * the page renderer uses — one bitmap per size class, never per zoom step.
876
+ */
877
+ declare function previewBucket(devicePixelWidth: number, cap?: number): number;
878
+ /**
879
+ * Where a programmatic stamp placement lands — the inputs a click supplies.
880
+ * The box is fitted and clamped exactly as the click path does it.
881
+ */
882
+ interface StampPlacement {
883
+ pageObjectNumber: PageObjectNumber;
884
+ /** Anchor in page points (content space): the placement is centred here. */
885
+ at: Vec;
886
+ /** Placed width in PDF points; default the payload's intrinsic size. */
887
+ targetWidth?: number;
888
+ /** Content rotation, degrees clockwise. Default 0. */
889
+ rotation?: number;
890
+ }
800
891
  /**
801
892
  * What the {@link FilePickerProvider} is asked for: which tool clicked (id +
802
893
  * the kind it creates), the tool's `accept` filter, and the page-space point
@@ -925,6 +1016,24 @@ interface AnnotationHostCapability extends AnnotationCapability {
925
1016
  beginTextEditAt(pon: PageObjectNumber, point: Vec, scale?: number, rotation?: PageRotation, zoom?: number): boolean;
926
1017
  /** Apply the editor's plain text — optimistic locally, debounced to the engine. */
927
1018
  setContents(ref: AnnotationRef, text: string): void;
1019
+ /** Apply the editor's rich paragraphs (run deltas over the body) —
1020
+ * optimistic locally, debounced to the engine. The commit is plain
1021
+ * `contents` while nothing overrides the body on a plain annotation, else
1022
+ * `richText`. */
1023
+ setRichText(ref: AnnotationRef, doc: {
1024
+ paragraphs: RichTextParagraph[];
1025
+ }): void;
1026
+ /** The editor's selection inside the annotation (flat offsets over the
1027
+ * plain projection), or null when the editor holds none. While a RANGE is
1028
+ * held, `updateSelection`'s font/size/colour/format keys restyle the
1029
+ * range's runs instead of the body. */
1030
+ setTextSelection(ref: AnnotationRef, range: {
1031
+ start: number;
1032
+ end: number;
1033
+ } | null): void;
1034
+ /** The CSS family list for a face family a run names ("Helvetica" → a web
1035
+ * stack, a registered family → its key, mounted by `mountWebFont`). */
1036
+ cssFontFamily(family: string): string;
928
1037
  /** Leave text-edit (flush any pending write). */
929
1038
  endTextEdit(): void;
930
1039
  /** What's under a content point — for the edit handler's capture decision.
@@ -1040,8 +1149,13 @@ interface AnnotationHostCapability extends AnnotationCapability {
1040
1149
  * Vector ghosts also ride {@link pageItems}; only `kind: 'image'` ghosts
1041
1150
  * need the framework's blit. */
1042
1151
  toolGhost(pon: PageObjectNumber): ToolGhost | null;
1043
- /** The armed stamp's paintable preview bytes, or null (no ghost to show). */
1044
- armedStampPreview(): ArmedStampPreview | null;
1152
+ /**
1153
+ * The armed stamp's paintable preview at (roughly) `devicePixelWidth`
1154
+ * pixels wide — bucketed and cached per bucket for the arm's lifetime —
1155
+ * or null when there is no ghost to show. Omit the width for the
1156
+ * smallest bucket.
1157
+ */
1158
+ armedStampPreview(devicePixelWidth?: number): Promise<ArmedStampPreview | null>;
1045
1159
  /** Bumps on arm/disarm — keys the render layer's preview object-URL lifetime. */
1046
1160
  stampArmEpoch(): number;
1047
1161
  /**
@@ -1082,5 +1196,5 @@ interface AnnotationHostCapability extends AnnotationCapability {
1082
1196
  */
1083
1197
  declare const AnnotationToken: import("@embedpdf/core").CapabilityToken<AnnotationHostCapability>;
1084
1198
  //#endregion
1085
- export { StampSourceSpec as A, AnnotationToolInput as C, PromptSourceSpec as D, InkAuthoringOptions as E, ToolDefaultsFor as M, buildToolRegistry as N, ResolvedTool as O, AnnotationToolDef as S, GhostPolicy as T, SelectionProps as _, AnnotationHydration as a, ThreadDeleteResult as b, Behavior as c, CommentPermissions as d, CommentsApi as f, SelectionFlags as g, LinkNavItem as h, AnnotationHostCapability as i, ToolAuthoringKind as j, SelectionAuthoring as k, ChromeSettings as l, FilePromptRequest as m, AnnotationCapability as n, AnnotationState as o, FilePickerProvider as p, AnnotationConfig as r, AnnotationToken as s, AnnotationAction as t, ChromeSettingsPatch as u, StampToolInput as v, DEFAULT_TOOLS as w, ToolGhost as x, TextItem as y };
1086
- //# sourceMappingURL=types-eLTpocXz.d.cts.map
1199
+ export { InkAuthoringOptions as A, TextSelection as B, ToolGhost as C, AnnotationToolInput as D, AnnotationToolDef as E, ToolAuthoringKind as F, ToolDefaultsFor as I, buildToolRegistry as L, ResolvedTool as M, SelectionAuthoring as N, DEFAULT_TOOLS as O, StampSourceSpec as P, Face as R, ThreadDeleteResult as S, ARMED_STAMP_TOOL_ID as T, SelectionProps as _, AnnotationHydration as a, StampToolInput as b, Behavior as c, CommentPermissions as d, CommentsApi as f, SelectionFlags as g, LinkNavItem as h, AnnotationHostCapability as i, PromptSourceSpec as j, GhostPolicy as k, ChromeSettings as l, FilePromptRequest as m, AnnotationCapability as n, AnnotationState as o, FilePickerProvider as p, AnnotationConfig as r, AnnotationToken as s, AnnotationAction as t, ChromeSettingsPatch as u, StampPlacement as v, previewBucket as w, TextItem as x, StampPreviewProvider as y, TextFormat as z };
1200
+ //# sourceMappingURL=types-ObcPYc3-.d.cts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@embedpdf/plugin-annotation",
3
- "version": "3.0.0-next.11",
3
+ "version": "3.0.0-next.13",
4
4
  "private": false,
5
5
  "description": "Annotation feature plugin: the pure annotation-core wired to the engine repository (optimistic create/patch/delete) + the interaction hub (ambient edit + draw tools). Behaviors (forms) plug in here.",
6
6
  "type": "module",
@@ -34,14 +34,14 @@
34
34
  "dist"
35
35
  ],
36
36
  "dependencies": {
37
- "@embedpdf/core-annotation": "3.0.0-next.11",
38
- "@embedpdf/core-geometry": "3.0.0-next.11",
39
- "@embedpdf/core": "3.0.0-next.11",
40
- "@embedpdf/plugin-selection": "3.0.0-next.11",
41
- "@embedpdf/plugin-interaction": "3.0.0-next.11",
42
- "@embedpdf/engine-core": "3.0.0-next.11",
43
- "@embedpdf/core-acrojs": "3.0.0-next.11",
44
- "@embedpdf/plugin-actions": "3.0.0-next.11"
37
+ "@embedpdf/core": "3.0.0-next.13",
38
+ "@embedpdf/core-annotation": "3.0.0-next.13",
39
+ "@embedpdf/plugin-interaction": "3.0.0-next.13",
40
+ "@embedpdf/core-geometry": "3.0.0-next.13",
41
+ "@embedpdf/plugin-selection": "3.0.0-next.13",
42
+ "@embedpdf/engine-core": "3.0.0-next.13",
43
+ "@embedpdf/core-acrojs": "3.0.0-next.13",
44
+ "@embedpdf/plugin-actions": "3.0.0-next.13"
45
45
  },
46
46
  "devDependencies": {
47
47
  "typescript": "^5.0.0",