@embedpdf/plugin-annotation 3.0.0-next.14 → 3.0.0-next.15
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 +129 -0
- package/dist/authoring.cjs +12 -2
- package/dist/authoring.d.cts +2 -2
- package/dist/authoring.d.ts +2 -2
- package/dist/authoring.js +2 -3
- package/dist/contract/host.cjs +18 -2
- package/dist/contract/host.d.cts +3 -2
- package/dist/contract/host.d.ts +3 -2
- package/dist/contract/host.js +3 -2
- package/dist/contract-BK4LHe9v.d.cts +1127 -0
- package/dist/contract-BOo9iZKo.d.ts +1127 -0
- package/dist/contract-CPzpRG3h.cjs +692 -0
- package/dist/contract-CPzpRG3h.cjs.map +1 -0
- package/dist/contract-b2e_LZvu.js +651 -0
- package/dist/contract-b2e_LZvu.js.map +1 -0
- package/dist/contract.cjs +11 -10
- package/dist/contract.d.cts +2 -3
- package/dist/contract.d.ts +2 -3
- package/dist/contract.js +2 -4
- package/dist/host-contract-BbjhS_Fo.d.ts +310 -0
- package/dist/host-contract-CxrQPcPj.js +52 -0
- package/dist/host-contract-CxrQPcPj.js.map +1 -0
- package/dist/{contract-a4eaQWga.cjs → host-contract-DY9jFPPF.cjs} +36 -16
- package/dist/host-contract-DY9jFPPF.cjs.map +1 -0
- package/dist/host-contract-Nzxwh0XS.d.cts +310 -0
- package/dist/index.cjs +4985 -418
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -17
- package/dist/index.d.ts +12 -17
- package/dist/index.js +4937 -390
- package/dist/index.js.map +1 -1
- package/package.json +11 -14
- package/dist/authoring-BhtyfsMx.d.cts +0 -37
- package/dist/authoring-R4ezdnXd.d.ts +0 -37
- package/dist/capability-Bt320iJP.cjs +0 -3249
- package/dist/capability-Bt320iJP.cjs.map +0 -1
- package/dist/capability-CoL4na7g.js +0 -3226
- package/dist/capability-CoL4na7g.js.map +0 -1
- package/dist/contract-C7rcuNp_.d.cts +0 -34
- package/dist/contract-CM2Ovdq_.d.ts +0 -34
- package/dist/contract-DtXE1hjY.js +0 -32
- package/dist/contract-DtXE1hjY.js.map +0 -1
- package/dist/contract-a4eaQWga.cjs.map +0 -1
- package/dist/internal.cjs +0 -8
- package/dist/internal.d.cts +0 -14
- package/dist/internal.d.ts +0 -14
- package/dist/internal.js +0 -5
- package/dist/seam-6pJeKOOJ.cjs +0 -296
- package/dist/seam-6pJeKOOJ.cjs.map +0 -1
- package/dist/seam-C4L_7rDt.js +0 -225
- package/dist/seam-C4L_7rDt.js.map +0 -1
- package/dist/tools-B3i1gjRs.cjs +0 -589
- package/dist/tools-B3i1gjRs.cjs.map +0 -1
- package/dist/tools-DsfqBn_a.js +0 -566
- package/dist/tools-DsfqBn_a.js.map +0 -1
- package/dist/types-BvB1vUKb.js +0 -20
- package/dist/types-BvB1vUKb.js.map +0 -1
- package/dist/types-ChRnKozg.d.cts +0 -1246
- package/dist/types-Dlhdw2k_.cjs +0 -31
- package/dist/types-Dlhdw2k_.cjs.map +0 -1
- package/dist/types-Dmz3eRSG.d.ts +0 -1246
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { c as AnnotationToken$1 } from "./contract-b2e_LZvu.js";
|
|
2
|
+
import { createHostToken } from "@embedpdf/core";
|
|
3
|
+
//#region src/priorities.ts
|
|
4
|
+
/**
|
|
5
|
+
* The interaction-hub priorities of the annotation plugin's handlers — the
|
|
6
|
+
* public contract a sibling plugin builds on when it needs to sit above or
|
|
7
|
+
* below one of them for the same gesture. Priority only breaks ties between
|
|
8
|
+
* simultaneously-eligible handlers (the tool's tags decide eligibility).
|
|
9
|
+
*
|
|
10
|
+
* 100 annotation-edit select/move/resize over an existing annotation
|
|
11
|
+
* 95 annotation-place click-to-place an armed payload on empty page space
|
|
12
|
+
* 55 annotation-draw drag-create under a draw tool (below text-select)
|
|
13
|
+
* 50 annotation-marquee empty-space selection, the final fallback
|
|
14
|
+
*
|
|
15
|
+
* Hover runs in the same order, so a handler's hover sees the cursor claims
|
|
16
|
+
* of every handler above it: a create handler shows its tool's ghost only
|
|
17
|
+
* where nothing above it claims the pointer (an annotation, text).
|
|
18
|
+
*
|
|
19
|
+
* A handler that must win a click over an existing annotation while a
|
|
20
|
+
* placing tool is active (a signature mark dropped onto a signature field)
|
|
21
|
+
* registers above {@link ANNOTATION_EDIT_PRIORITY}, not merely above place:
|
|
22
|
+
* the edit handler captures first over any annotation, a widget included.
|
|
23
|
+
*/
|
|
24
|
+
const ANNOTATION_EDIT_PRIORITY = 100;
|
|
25
|
+
const ANNOTATION_PLACE_PRIORITY = 95;
|
|
26
|
+
const ANNOTATION_DRAW_PRIORITY = 55;
|
|
27
|
+
const ANNOTATION_MARQUEE_PRIORITY = 50;
|
|
28
|
+
//#endregion
|
|
29
|
+
//#region src/host-contract.ts
|
|
30
|
+
/**
|
|
31
|
+
* @embedpdf/plugin-annotation/contract/host — the host lens: render
|
|
32
|
+
* projections, sync, pointer routing, ghosts, the markup bridge and the
|
|
33
|
+
* extension seams. Same runtime token as the public one, typed wider.
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* Ghost render buckets: powers of two from 128 px up to `cap`. The same policy
|
|
37
|
+
* the page renderer uses — one bitmap per size class, never per zoom step.
|
|
38
|
+
*/
|
|
39
|
+
function previewBucket(devicePixelWidth, maxWidth = 4096) {
|
|
40
|
+
return Math.min(maxWidth, 2 ** Math.ceil(Math.log2(Math.max(128, Math.ceil(devicePixelWidth)))));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The annotation capability token, typed to the full
|
|
44
|
+
* {@link AnnotationHostCapability} (the package internals and `/contract/host`
|
|
45
|
+
* use this view). The package root exports the same runtime token narrowed to
|
|
46
|
+
* {@link AnnotationCapability}.
|
|
47
|
+
*/
|
|
48
|
+
const AnnotationToken = createHostToken(AnnotationToken$1);
|
|
49
|
+
//#endregion
|
|
50
|
+
export { ANNOTATION_MARQUEE_PRIORITY as a, ANNOTATION_EDIT_PRIORITY as i, previewBucket as n, ANNOTATION_PLACE_PRIORITY as o, ANNOTATION_DRAW_PRIORITY as r, AnnotationToken as t };
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=host-contract-CxrQPcPj.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-contract-CxrQPcPj.js","names":["PublicAnnotationToken"],"sources":["../src/priorities.ts","../src/host-contract.ts"],"sourcesContent":["/**\n * The interaction-hub priorities of the annotation plugin's handlers — the\n * public contract a sibling plugin builds on when it needs to sit above or\n * below one of them for the same gesture. Priority only breaks ties between\n * simultaneously-eligible handlers (the tool's tags decide eligibility).\n *\n * 100 annotation-edit select/move/resize over an existing annotation\n * 95 annotation-place click-to-place an armed payload on empty page space\n * 55 annotation-draw drag-create under a draw tool (below text-select)\n * 50 annotation-marquee empty-space selection, the final fallback\n *\n * Hover runs in the same order, so a handler's hover sees the cursor claims\n * of every handler above it: a create handler shows its tool's ghost only\n * where nothing above it claims the pointer (an annotation, text).\n *\n * A handler that must win a click over an existing annotation while a\n * placing tool is active (a signature mark dropped onto a signature field)\n * registers above {@link ANNOTATION_EDIT_PRIORITY}, not merely above place:\n * the edit handler captures first over any annotation, a widget included.\n */\nexport const ANNOTATION_EDIT_PRIORITY = 100;\nexport const ANNOTATION_PLACE_PRIORITY = 95;\nexport const ANNOTATION_DRAW_PRIORITY = 55;\nexport const ANNOTATION_MARQUEE_PRIORITY = 50;\n","/**\n * @embedpdf/plugin-annotation/contract/host — the host lens: render\n * projections, sync, pointer routing, ghosts, the markup bridge and the\n * extension seams. Same runtime token as the public one, typed wider.\n */\nimport { createHostToken } from '@embedpdf/core';\nimport type { DocumentEvent, EventHook, PredictedOp, Unsubscribe } from '@embedpdf/core';\nimport type {\n ChromeNode,\n Effect,\n Id,\n Model,\n Rect,\n RenderItem,\n SceneNode,\n KindName,\n TextEndAnchor,\n Quad,\n Point,\n ViewEnv,\n} from '@embedpdf/core-annotation';\nimport type { PageRotation } from '@embedpdf/core-geometry';\nimport type {\n AnnotationAppearanceImage,\n AnnotationPosition,\n AnnotationRef,\n ChangeOp,\n ImageSource,\n PageMeasurementViewport,\n PageRef,\n PdfMeasure,\n RichTextParagraph,\n SerializedEngineError,\n} from '@embedpdf/engine-core/runtime';\nimport type { AnnotCommitEntry, AnnotCommitResult } from '@embedpdf/plugin-actions/contract/host';\nimport type { AppearancePicture } from '@embedpdf/plugin-render/contract/host';\n\nimport type {\n Annotation,\n AnnotationAnchor,\n AnnotationCapability,\n AnnotationSelectionAnchor,\n ArmedStampInfo,\n ArmedStampPreview,\n Behavior,\n LinkNavItem,\n TextItem,\n ImageGhost,\n} from './contract';\nimport { AnnotationToken as PublicAnnotationToken } from './token';\nimport type { ResolvedTool } from './tools/definitions';\n\nexport * from './contract';\nexport type { AnnotationState } from './model';\nexport {\n ANNOTATION_DRAW_PRIORITY,\n ANNOTATION_EDIT_PRIORITY,\n ANNOTATION_MARQUEE_PRIORITY,\n ANNOTATION_PLACE_PRIORITY,\n} from './priorities';\n\n/**\n * One annotation's look at rest in one of its states, as the render layer\n * paints it: the engine's picture, or, while the annotation's create is on\n * its way, the one this device made (a placed stamp's preview), which the\n * engine's replaces. `version` is the record's picture version it shows\n * (`RenderItem.pictureVersion`): one drawn at another version shows another look.\n */\nexport interface AnnotationAppearancePicture extends Pick<\n AnnotationAppearanceImage,\n 'ref' | 'mode' | 'state' | 'rect'\n> {\n readonly image: ImageSource;\n readonly version: number;\n}\n\n/**\n * A sibling plugin that lends this plugin records it owns (the form plugin's\n * widgets), so they are selected, moved, resized, restyled and deleted with\n * the annotation tools. This plugin never stores them: it shows them as the\n * lender says, and an edit of one becomes the lender's ops, in the same change\n * as the rest of the edit.\n */\nexport interface AnnotationLender {\n /** Who owns the records, for a refusal that sends you there (`'form'`). */\n readonly owner: string;\n /**\n * Its records as the engine confirmed them and as they show, each list the\n * same object until it changes; `null` while it lends none.\n */\n records(): {\n readonly confirmed: readonly Annotation[];\n readonly shown: readonly Annotation[];\n } | null;\n /**\n * The ops that write a message's effects on its records, all at once:\n * `model` is the model the message left, `before` the one it started from\n * (a record it deleted is there).\n */\n opsOf(effects: readonly Effect[], model: Model, before: Model): readonly ChangeOp[];\n /** What undoing these ops looks like. */\n undoOf(ops: readonly ChangeOp[]): readonly PredictedOp[];\n /** The ops that move these records of one page to `position` in its drawing order. */\n reorderOps(\n page: PageRef,\n refs: readonly AnnotationRef[],\n position: AnnotationPosition,\n ): readonly ChangeOp[];\n /** Whether this session may change and delete the record. */\n authority(record: Annotation): { readonly update: boolean; readonly delete: boolean };\n /** What its records' pictures on a page depend on: a new value means new pictures. */\n pictureEpoch(page: PageRef): string;\n /** A record's confirmed picture version; kept for one that went, so an undo brings it back with it. */\n pictureVersion(record: AnnotationRef): number;\n /**\n * The record's look as it shows isn't its confirmed look yet, whatever changed it (a restyle,\n * a resize, one just placed, a change the lender made itself): it draws live, by its\n * {@link painter}, until the engine's picture of it is there.\n */\n pending(record: AnnotationRef): boolean;\n /**\n * How the lender draws the record live: the record upright in `box` (its box, or where a\n * gesture has it), in page space; `null` for one it doesn't draw. A record with a painter\n * draws live while a gesture reshapes it, as a square does.\n */\n painter(record: Annotation): ((box: Rect) => readonly SceneNode[]) | null;\n /** Its records' pictures on a page, at rest, in every state, each with its record's picture version. */\n renderAppearances(\n page: PageRef,\n scale: number,\n signal?: AbortSignal,\n ): Promise<readonly AppearancePicture[]>;\n}\n\nexport interface RecalibrationReport {\n page: PageRef;\n scale: PdfMeasure;\n /** Page-wide read failure: no complete annotation set was available to recalculate. */\n error?: SerializedEngineError;\n updated: AnnotationRef[];\n skipped: {\n ref: AnnotationRef;\n reason: 'no-authority' | 'locked' | 'foreign-measure' | 'unavailable';\n }[];\n failed: { ref: AnnotationRef; error: SerializedEngineError }[];\n}\n\nexport interface CapturedAnnotationDraft {\n tool: string;\n page: PageRef;\n from: Point;\n to: Point;\n}\n\n/**\n * Ghost render buckets: powers of two from 128 px up to `cap`. The same policy\n * the page renderer uses — one bitmap per size class, never per zoom step.\n */\nexport function previewBucket(devicePixelWidth: number, maxWidth = 4096): number {\n const px = Math.max(128, Math.ceil(devicePixelWidth));\n return Math.min(maxWidth, 2 ** Math.ceil(Math.log2(px)));\n}\n\n/**\n * The host (framework) surface: everything the render layer, the interaction hub,\n * and sibling plugins need, on top of the public {@link AnnotationCapability}.\n * Host-only: sibling plugins and framework adapters import the token from\n * `@embedpdf/plugin-annotation/contract/host`. Never use it from application code.\n */\nexport interface AnnotationHostCapability extends AnnotationCapability {\n // ── measurement seam ──\n setPageViewports(\n page: PageRef,\n viewports: PageMeasurementViewport[] | undefined,\n fallback: PdfMeasure,\n ): void;\n remeasurePage(page: PageRef, scale: PdfMeasure): Promise<RecalibrationReport>;\n /** A distance draft was captured (the measurement plugin turns it into a calibration). */\n readonly onDraftCaptured: EventHook<CapturedAnnotationDraft>;\n distanceCreationPage(): PageRef | null;\n\n // ── render projections (page space; a view env projects for a rotated / zoomed view) ──\n /**\n * The selection's anchor as a page shows it: its rotation handle where the\n * page's view puts it (screen-sized, so it depends on the zoom), for a menu\n * that stays clear of it. `selection.getAnchor()` is the same without a view.\n */\n getSelectionAnchorIn(view: {\n scale?: number;\n rotation?: PageRotation;\n zoom?: number;\n }): AnnotationSelectionAnchor | null;\n /**\n * Where UI attaches to one annotation (its page and the box around what it\n * shows, a drag in progress included), or `null` for one that isn't here.\n * Without a view, an annotation that keeps its size on screen carries\n * `boundsIn` for the view it's shown in.\n */\n getAnnotationAnchor(ref: AnnotationRef, view?: ViewEnv): AnnotationAnchor | null;\n listPageItems(page: PageRef, view?: ViewEnv): RenderItem[];\n listTextItems(page: PageRef, view?: ViewEnv): TextItem[];\n listChromeNodes(\n page: PageRef,\n scale?: number,\n rotation?: PageRotation,\n zoom?: number,\n ): ChromeNode[];\n listLinkItems(page: PageRef): LinkNavItem[];\n /**\n * What a page's pictures depend on: its baked records at their picture\n * versions, the stamps this session placed, the pictures kept for an undone\n * delete and the lender's widgets. Load the pictures again when it changes,\n * or when the appearance scale (`render.getAppearanceScale`) does.\n */\n getAppearanceEpoch(page: PageRef): string;\n /**\n * Every picture a page's annotations show at rest, in every state, each\n * with its record's picture version: the engine's (through the render\n * plugin; none without it), the lender's, and this session's placed stamps.\n */\n renderAppearances(\n page: PageRef,\n scale: number,\n signal?: AbortSignal,\n ): Promise<AnnotationAppearancePicture[]>;\n\n // ── sync ──\n /**\n * Resolves once the annotations mirror has applied every confirmed change\n * it knows of, including page re-reads that events started.\n */\n whenSynced(): Promise<void>;\n\n // ── text editing (the editor's draft path: shown at once, written after a pause) ──\n getEditingId(): Id | null;\n beginTextEditAt(\n page: PageRef,\n point: Point,\n scale?: number,\n rotation?: PageRotation,\n zoom?: number,\n ): boolean;\n draftContents(ref: AnnotationRef, text: string): void;\n draftRichText(ref: AnnotationRef, doc: { paragraphs: RichTextParagraph[] }): void;\n setTextSelection(ref: AnnotationRef, range: { start: number; end: number } | null): void;\n getCssFontFamily(family: string): string;\n\n // ── pointer routing ──\n getHitKind(\n page: PageRef,\n point: Point,\n scale?: number,\n rotation?: PageRotation,\n zoom?: number,\n touch?: boolean,\n ): 'handle' | 'rotate' | 'group-handle' | 'annot' | 'empty';\n claimsTouchAt(\n page: PageRef,\n point: Point,\n scale?: number,\n rotation?: PageRotation,\n zoom?: number,\n ): boolean;\n getCursorAt(\n page: PageRef,\n point: Point,\n scale?: number,\n rotation?: PageRotation,\n zoom?: number,\n ): string | null;\n hoverAt(\n at: {\n page: PageRef;\n point: Point;\n scale?: number;\n rotation?: PageRotation;\n zoom?: number;\n } | null,\n ): void;\n editPointer(\n phase: 'down' | 'move' | 'up',\n page: PageRef,\n point: Point,\n shift: boolean,\n scale?: number,\n rotation?: PageRotation,\n zoom?: number,\n touch?: boolean,\n ): void;\n marqueePointer(\n phase: 'down' | 'move' | 'up',\n page: PageRef,\n point: Point,\n shift: boolean,\n scale?: number,\n rotation?: PageRotation,\n zoom?: number,\n ): void;\n createPointer(\n tool: string,\n phase: 'down' | 'move' | 'up',\n page: PageRef,\n point: Point,\n finish?: boolean,\n displayRotation?: PageRotation,\n ): void;\n finishInkDraft(): void;\n /** Place with the active tool at a click; `displayRotation` and `zoom` are the page's view there. */\n placeAt(page: PageRef, point: Point, displayRotation?: PageRotation, zoom?: number): boolean;\n placeArmedStamp(page: PageRef, point: Point, displayRotation?: PageRotation): boolean;\n requestStampAt(page: PageRef, point: Point, displayRotation?: PageRotation): boolean;\n\n // ── markup bridge (the selection plugin meets the text tools) ──\n /**\n * Turn the text selection into what the tool makes of it (markup, a caret,\n * a replace-text pair) and clear the selection; `false`, and nothing, for a\n * tool that makes nothing of a selection, without create authority, or\n * without a selection.\n */\n applyToolToSelection(toolId: string): boolean;\n createMarkup(subtype: KindName, page: PageRef, quads: Quad[], preset?: string): void;\n createCaret(page: PageRef, anchor: TextEndAnchor): void;\n createReplaceText(page: PageRef, quads: Quad[], anchor: TextEndAnchor, preset?: string): void;\n previewMarkup(subtype: KindName, quadsByPage: Record<number, Quad[]>, preset?: string): void;\n clearMarkupPreview(): void;\n\n // ── ghosts and previews (tools/ghost.ts) ──\n /**\n * Put the tool's ghost at a hover, what a click there would make;\n * `displayRotation` and `zoom` are the page's view there. The handler that\n * would take the click calls it, only where the click would reach it and\n * the user may create; a tool without a ghost clears it.\n */\n hoverGhostAt(\n toolId: string,\n page: PageRef,\n point: Point,\n displayRotation?: PageRotation,\n zoom?: number,\n ): void;\n clearGhost(): void;\n /**\n * A sibling plugin's placement gesture with one of this plugin's tools (the\n * form palette's drag-to-place): its press and the pointer now. Once it is a\n * drag, the page paints what releasing places; under that the tool's ghost\n * still shows the click.\n */\n previewPlacement(toolId: string, page: PageRef, from: Point, to: Point): void;\n clearPlacementPreview(): void;\n /** The armed stamp's ghost on a page, for the render layer's `<img>`. */\n getImageGhost(page: PageRef): ImageGhost | null;\n /** The armed stamp: a new object on every arm, null when nothing is armed. */\n getArmedStamp(): ArmedStampInfo | null;\n /** Render the armed stamp's ghost preview for a device pixel width (cached per size bucket). */\n renderArmedStampPreview(devicePixelWidth?: number): Promise<ArmedStampPreview | null>;\n\n // ── extension ──\n /**\n * Show a sibling's records with the annotations and edit them with the same\n * tools (see {@link AnnotationLender}). One lender at a time; returns the\n * release.\n */\n lend(lender: AnnotationLender): Unsubscribe;\n listResolvedTools(): ResolvedTool[];\n getResolvedTool(id: string): ResolvedTool | null;\n getToolSubtype(id: string): KindName;\n registerBehavior(behavior: Behavior): Unsubscribe;\n /** The engaged behavior that owns this annotation now, or `null`. */\n getBehaviorFor(annotation: Annotation): Behavior | null;\n pruneEngagedSelection(): void;\n commitScriptEffects(entries: AnnotCommitEntry[]): Promise<AnnotCommitResult>;\n}\n\n/**\n * The annotation capability token, typed to the full\n * {@link AnnotationHostCapability} (the package internals and `/contract/host`\n * use this view). The package root exports the same runtime token narrowed to\n * {@link AnnotationCapability}.\n */\nexport const AnnotationToken = createHostToken<AnnotationHostCapability>(PublicAnnotationToken);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAoBA,MAAa,2BAA2B;AACxC,MAAa,4BAA4B;AACzC,MAAa,2BAA2B;AACxC,MAAa,8BAA8B;;;;;;;;;;;;ACuI3C,SAAgB,cAAc,kBAA0B,WAAW,MAAc;CAE/E,OAAO,KAAK,IAAI,UAAU,KAAK,KAAK,KAAK,KAAK,KADnC,KAAK,IAAI,KAAK,KAAK,KAAK,gBAAgB,CACC,CAAC,CAAC,CAAC;AACzD;;;;;;;AA0NA,MAAa,kBAAkB,gBAA0CA,iBAAqB"}
|
|
@@ -1,31 +1,51 @@
|
|
|
1
|
-
const
|
|
1
|
+
const require_contract = require("./contract-CPzpRG3h.cjs");
|
|
2
|
+
let _embedpdf_core = require("@embedpdf/core");
|
|
2
3
|
//#region src/priorities.ts
|
|
3
4
|
/**
|
|
4
5
|
* The interaction-hub priorities of the annotation plugin's handlers — the
|
|
5
|
-
* public contract a sibling plugin builds on when it needs to sit
|
|
6
|
-
*
|
|
7
|
-
* simultaneously-
|
|
6
|
+
* public contract a sibling plugin builds on when it needs to sit above or
|
|
7
|
+
* below one of them for the same gesture. Priority only breaks ties between
|
|
8
|
+
* simultaneously-eligible handlers (the tool's tags decide eligibility).
|
|
8
9
|
*
|
|
9
|
-
* 1000 annotation-ghost never captures; hides the footprint ghost on every down
|
|
10
10
|
* 100 annotation-edit select/move/resize over an existing annotation
|
|
11
11
|
* 95 annotation-place click-to-place an armed payload on empty page space
|
|
12
12
|
* 55 annotation-draw drag-create under a draw tool (below text-select)
|
|
13
13
|
* 50 annotation-marquee empty-space selection, the final fallback
|
|
14
14
|
*
|
|
15
|
+
* Hover runs in the same order, so a handler's hover sees the cursor claims
|
|
16
|
+
* of every handler above it: a create handler shows its tool's ghost only
|
|
17
|
+
* where nothing above it claims the pointer (an annotation, text).
|
|
18
|
+
*
|
|
15
19
|
* A handler that must win a click over an existing annotation while a
|
|
16
20
|
* placing tool is active (a signature mark dropped onto a signature field)
|
|
17
21
|
* registers above {@link ANNOTATION_EDIT_PRIORITY}, not merely above place:
|
|
18
22
|
* the edit handler captures first over any annotation, a widget included.
|
|
19
23
|
*/
|
|
20
|
-
const ANNOTATION_GHOST_PRIORITY = 1e3;
|
|
21
24
|
const ANNOTATION_EDIT_PRIORITY = 100;
|
|
22
25
|
const ANNOTATION_PLACE_PRIORITY = 95;
|
|
23
26
|
const ANNOTATION_DRAW_PRIORITY = 55;
|
|
24
27
|
const ANNOTATION_MARQUEE_PRIORITY = 50;
|
|
25
28
|
//#endregion
|
|
26
|
-
//#region src/contract.ts
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
+
//#region src/host-contract.ts
|
|
30
|
+
/**
|
|
31
|
+
* @embedpdf/plugin-annotation/contract/host — the host lens: render
|
|
32
|
+
* projections, sync, pointer routing, ghosts, the markup bridge and the
|
|
33
|
+
* extension seams. Same runtime token as the public one, typed wider.
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* Ghost render buckets: powers of two from 128 px up to `cap`. The same policy
|
|
37
|
+
* the page renderer uses — one bitmap per size class, never per zoom step.
|
|
38
|
+
*/
|
|
39
|
+
function previewBucket(devicePixelWidth, maxWidth = 4096) {
|
|
40
|
+
return Math.min(maxWidth, 2 ** Math.ceil(Math.log2(Math.max(128, Math.ceil(devicePixelWidth)))));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The annotation capability token, typed to the full
|
|
44
|
+
* {@link AnnotationHostCapability} (the package internals and `/contract/host`
|
|
45
|
+
* use this view). The package root exports the same runtime token narrowed to
|
|
46
|
+
* {@link AnnotationCapability}.
|
|
47
|
+
*/
|
|
48
|
+
const AnnotationToken = (0, _embedpdf_core.createHostToken)(require_contract.AnnotationToken);
|
|
29
49
|
//#endregion
|
|
30
50
|
Object.defineProperty(exports, "ANNOTATION_DRAW_PRIORITY", {
|
|
31
51
|
enumerable: true,
|
|
@@ -39,12 +59,6 @@ Object.defineProperty(exports, "ANNOTATION_EDIT_PRIORITY", {
|
|
|
39
59
|
return ANNOTATION_EDIT_PRIORITY;
|
|
40
60
|
}
|
|
41
61
|
});
|
|
42
|
-
Object.defineProperty(exports, "ANNOTATION_GHOST_PRIORITY", {
|
|
43
|
-
enumerable: true,
|
|
44
|
-
get: function() {
|
|
45
|
-
return ANNOTATION_GHOST_PRIORITY;
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
62
|
Object.defineProperty(exports, "ANNOTATION_MARQUEE_PRIORITY", {
|
|
49
63
|
enumerable: true,
|
|
50
64
|
get: function() {
|
|
@@ -63,5 +77,11 @@ Object.defineProperty(exports, "AnnotationToken", {
|
|
|
63
77
|
return AnnotationToken;
|
|
64
78
|
}
|
|
65
79
|
});
|
|
80
|
+
Object.defineProperty(exports, "previewBucket", {
|
|
81
|
+
enumerable: true,
|
|
82
|
+
get: function() {
|
|
83
|
+
return previewBucket;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
66
86
|
|
|
67
|
-
//# sourceMappingURL=contract-
|
|
87
|
+
//# sourceMappingURL=host-contract-DY9jFPPF.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-contract-DY9jFPPF.cjs","names":["PublicAnnotationToken"],"sources":["../src/priorities.ts","../src/host-contract.ts"],"sourcesContent":["/**\n * The interaction-hub priorities of the annotation plugin's handlers — the\n * public contract a sibling plugin builds on when it needs to sit above or\n * below one of them for the same gesture. Priority only breaks ties between\n * simultaneously-eligible handlers (the tool's tags decide eligibility).\n *\n * 100 annotation-edit select/move/resize over an existing annotation\n * 95 annotation-place click-to-place an armed payload on empty page space\n * 55 annotation-draw drag-create under a draw tool (below text-select)\n * 50 annotation-marquee empty-space selection, the final fallback\n *\n * Hover runs in the same order, so a handler's hover sees the cursor claims\n * of every handler above it: a create handler shows its tool's ghost only\n * where nothing above it claims the pointer (an annotation, text).\n *\n * A handler that must win a click over an existing annotation while a\n * placing tool is active (a signature mark dropped onto a signature field)\n * registers above {@link ANNOTATION_EDIT_PRIORITY}, not merely above place:\n * the edit handler captures first over any annotation, a widget included.\n */\nexport const ANNOTATION_EDIT_PRIORITY = 100;\nexport const ANNOTATION_PLACE_PRIORITY = 95;\nexport const ANNOTATION_DRAW_PRIORITY = 55;\nexport const ANNOTATION_MARQUEE_PRIORITY = 50;\n","/**\n * @embedpdf/plugin-annotation/contract/host — the host lens: render\n * projections, sync, pointer routing, ghosts, the markup bridge and the\n * extension seams. Same runtime token as the public one, typed wider.\n */\nimport { createHostToken } from '@embedpdf/core';\nimport type { DocumentEvent, EventHook, PredictedOp, Unsubscribe } from '@embedpdf/core';\nimport type {\n ChromeNode,\n Effect,\n Id,\n Model,\n Rect,\n RenderItem,\n SceneNode,\n KindName,\n TextEndAnchor,\n Quad,\n Point,\n ViewEnv,\n} from '@embedpdf/core-annotation';\nimport type { PageRotation } from '@embedpdf/core-geometry';\nimport type {\n AnnotationAppearanceImage,\n AnnotationPosition,\n AnnotationRef,\n ChangeOp,\n ImageSource,\n PageMeasurementViewport,\n PageRef,\n PdfMeasure,\n RichTextParagraph,\n SerializedEngineError,\n} from '@embedpdf/engine-core/runtime';\nimport type { AnnotCommitEntry, AnnotCommitResult } from '@embedpdf/plugin-actions/contract/host';\nimport type { AppearancePicture } from '@embedpdf/plugin-render/contract/host';\n\nimport type {\n Annotation,\n AnnotationAnchor,\n AnnotationCapability,\n AnnotationSelectionAnchor,\n ArmedStampInfo,\n ArmedStampPreview,\n Behavior,\n LinkNavItem,\n TextItem,\n ImageGhost,\n} from './contract';\nimport { AnnotationToken as PublicAnnotationToken } from './token';\nimport type { ResolvedTool } from './tools/definitions';\n\nexport * from './contract';\nexport type { AnnotationState } from './model';\nexport {\n ANNOTATION_DRAW_PRIORITY,\n ANNOTATION_EDIT_PRIORITY,\n ANNOTATION_MARQUEE_PRIORITY,\n ANNOTATION_PLACE_PRIORITY,\n} from './priorities';\n\n/**\n * One annotation's look at rest in one of its states, as the render layer\n * paints it: the engine's picture, or, while the annotation's create is on\n * its way, the one this device made (a placed stamp's preview), which the\n * engine's replaces. `version` is the record's picture version it shows\n * (`RenderItem.pictureVersion`): one drawn at another version shows another look.\n */\nexport interface AnnotationAppearancePicture extends Pick<\n AnnotationAppearanceImage,\n 'ref' | 'mode' | 'state' | 'rect'\n> {\n readonly image: ImageSource;\n readonly version: number;\n}\n\n/**\n * A sibling plugin that lends this plugin records it owns (the form plugin's\n * widgets), so they are selected, moved, resized, restyled and deleted with\n * the annotation tools. This plugin never stores them: it shows them as the\n * lender says, and an edit of one becomes the lender's ops, in the same change\n * as the rest of the edit.\n */\nexport interface AnnotationLender {\n /** Who owns the records, for a refusal that sends you there (`'form'`). */\n readonly owner: string;\n /**\n * Its records as the engine confirmed them and as they show, each list the\n * same object until it changes; `null` while it lends none.\n */\n records(): {\n readonly confirmed: readonly Annotation[];\n readonly shown: readonly Annotation[];\n } | null;\n /**\n * The ops that write a message's effects on its records, all at once:\n * `model` is the model the message left, `before` the one it started from\n * (a record it deleted is there).\n */\n opsOf(effects: readonly Effect[], model: Model, before: Model): readonly ChangeOp[];\n /** What undoing these ops looks like. */\n undoOf(ops: readonly ChangeOp[]): readonly PredictedOp[];\n /** The ops that move these records of one page to `position` in its drawing order. */\n reorderOps(\n page: PageRef,\n refs: readonly AnnotationRef[],\n position: AnnotationPosition,\n ): readonly ChangeOp[];\n /** Whether this session may change and delete the record. */\n authority(record: Annotation): { readonly update: boolean; readonly delete: boolean };\n /** What its records' pictures on a page depend on: a new value means new pictures. */\n pictureEpoch(page: PageRef): string;\n /** A record's confirmed picture version; kept for one that went, so an undo brings it back with it. */\n pictureVersion(record: AnnotationRef): number;\n /**\n * The record's look as it shows isn't its confirmed look yet, whatever changed it (a restyle,\n * a resize, one just placed, a change the lender made itself): it draws live, by its\n * {@link painter}, until the engine's picture of it is there.\n */\n pending(record: AnnotationRef): boolean;\n /**\n * How the lender draws the record live: the record upright in `box` (its box, or where a\n * gesture has it), in page space; `null` for one it doesn't draw. A record with a painter\n * draws live while a gesture reshapes it, as a square does.\n */\n painter(record: Annotation): ((box: Rect) => readonly SceneNode[]) | null;\n /** Its records' pictures on a page, at rest, in every state, each with its record's picture version. */\n renderAppearances(\n page: PageRef,\n scale: number,\n signal?: AbortSignal,\n ): Promise<readonly AppearancePicture[]>;\n}\n\nexport interface RecalibrationReport {\n page: PageRef;\n scale: PdfMeasure;\n /** Page-wide read failure: no complete annotation set was available to recalculate. */\n error?: SerializedEngineError;\n updated: AnnotationRef[];\n skipped: {\n ref: AnnotationRef;\n reason: 'no-authority' | 'locked' | 'foreign-measure' | 'unavailable';\n }[];\n failed: { ref: AnnotationRef; error: SerializedEngineError }[];\n}\n\nexport interface CapturedAnnotationDraft {\n tool: string;\n page: PageRef;\n from: Point;\n to: Point;\n}\n\n/**\n * Ghost render buckets: powers of two from 128 px up to `cap`. The same policy\n * the page renderer uses — one bitmap per size class, never per zoom step.\n */\nexport function previewBucket(devicePixelWidth: number, maxWidth = 4096): number {\n const px = Math.max(128, Math.ceil(devicePixelWidth));\n return Math.min(maxWidth, 2 ** Math.ceil(Math.log2(px)));\n}\n\n/**\n * The host (framework) surface: everything the render layer, the interaction hub,\n * and sibling plugins need, on top of the public {@link AnnotationCapability}.\n * Host-only: sibling plugins and framework adapters import the token from\n * `@embedpdf/plugin-annotation/contract/host`. Never use it from application code.\n */\nexport interface AnnotationHostCapability extends AnnotationCapability {\n // ── measurement seam ──\n setPageViewports(\n page: PageRef,\n viewports: PageMeasurementViewport[] | undefined,\n fallback: PdfMeasure,\n ): void;\n remeasurePage(page: PageRef, scale: PdfMeasure): Promise<RecalibrationReport>;\n /** A distance draft was captured (the measurement plugin turns it into a calibration). */\n readonly onDraftCaptured: EventHook<CapturedAnnotationDraft>;\n distanceCreationPage(): PageRef | null;\n\n // ── render projections (page space; a view env projects for a rotated / zoomed view) ──\n /**\n * The selection's anchor as a page shows it: its rotation handle where the\n * page's view puts it (screen-sized, so it depends on the zoom), for a menu\n * that stays clear of it. `selection.getAnchor()` is the same without a view.\n */\n getSelectionAnchorIn(view: {\n scale?: number;\n rotation?: PageRotation;\n zoom?: number;\n }): AnnotationSelectionAnchor | null;\n /**\n * Where UI attaches to one annotation (its page and the box around what it\n * shows, a drag in progress included), or `null` for one that isn't here.\n * Without a view, an annotation that keeps its size on screen carries\n * `boundsIn` for the view it's shown in.\n */\n getAnnotationAnchor(ref: AnnotationRef, view?: ViewEnv): AnnotationAnchor | null;\n listPageItems(page: PageRef, view?: ViewEnv): RenderItem[];\n listTextItems(page: PageRef, view?: ViewEnv): TextItem[];\n listChromeNodes(\n page: PageRef,\n scale?: number,\n rotation?: PageRotation,\n zoom?: number,\n ): ChromeNode[];\n listLinkItems(page: PageRef): LinkNavItem[];\n /**\n * What a page's pictures depend on: its baked records at their picture\n * versions, the stamps this session placed, the pictures kept for an undone\n * delete and the lender's widgets. Load the pictures again when it changes,\n * or when the appearance scale (`render.getAppearanceScale`) does.\n */\n getAppearanceEpoch(page: PageRef): string;\n /**\n * Every picture a page's annotations show at rest, in every state, each\n * with its record's picture version: the engine's (through the render\n * plugin; none without it), the lender's, and this session's placed stamps.\n */\n renderAppearances(\n page: PageRef,\n scale: number,\n signal?: AbortSignal,\n ): Promise<AnnotationAppearancePicture[]>;\n\n // ── sync ──\n /**\n * Resolves once the annotations mirror has applied every confirmed change\n * it knows of, including page re-reads that events started.\n */\n whenSynced(): Promise<void>;\n\n // ── text editing (the editor's draft path: shown at once, written after a pause) ──\n getEditingId(): Id | null;\n beginTextEditAt(\n page: PageRef,\n point: Point,\n scale?: number,\n rotation?: PageRotation,\n zoom?: number,\n ): boolean;\n draftContents(ref: AnnotationRef, text: string): void;\n draftRichText(ref: AnnotationRef, doc: { paragraphs: RichTextParagraph[] }): void;\n setTextSelection(ref: AnnotationRef, range: { start: number; end: number } | null): void;\n getCssFontFamily(family: string): string;\n\n // ── pointer routing ──\n getHitKind(\n page: PageRef,\n point: Point,\n scale?: number,\n rotation?: PageRotation,\n zoom?: number,\n touch?: boolean,\n ): 'handle' | 'rotate' | 'group-handle' | 'annot' | 'empty';\n claimsTouchAt(\n page: PageRef,\n point: Point,\n scale?: number,\n rotation?: PageRotation,\n zoom?: number,\n ): boolean;\n getCursorAt(\n page: PageRef,\n point: Point,\n scale?: number,\n rotation?: PageRotation,\n zoom?: number,\n ): string | null;\n hoverAt(\n at: {\n page: PageRef;\n point: Point;\n scale?: number;\n rotation?: PageRotation;\n zoom?: number;\n } | null,\n ): void;\n editPointer(\n phase: 'down' | 'move' | 'up',\n page: PageRef,\n point: Point,\n shift: boolean,\n scale?: number,\n rotation?: PageRotation,\n zoom?: number,\n touch?: boolean,\n ): void;\n marqueePointer(\n phase: 'down' | 'move' | 'up',\n page: PageRef,\n point: Point,\n shift: boolean,\n scale?: number,\n rotation?: PageRotation,\n zoom?: number,\n ): void;\n createPointer(\n tool: string,\n phase: 'down' | 'move' | 'up',\n page: PageRef,\n point: Point,\n finish?: boolean,\n displayRotation?: PageRotation,\n ): void;\n finishInkDraft(): void;\n /** Place with the active tool at a click; `displayRotation` and `zoom` are the page's view there. */\n placeAt(page: PageRef, point: Point, displayRotation?: PageRotation, zoom?: number): boolean;\n placeArmedStamp(page: PageRef, point: Point, displayRotation?: PageRotation): boolean;\n requestStampAt(page: PageRef, point: Point, displayRotation?: PageRotation): boolean;\n\n // ── markup bridge (the selection plugin meets the text tools) ──\n /**\n * Turn the text selection into what the tool makes of it (markup, a caret,\n * a replace-text pair) and clear the selection; `false`, and nothing, for a\n * tool that makes nothing of a selection, without create authority, or\n * without a selection.\n */\n applyToolToSelection(toolId: string): boolean;\n createMarkup(subtype: KindName, page: PageRef, quads: Quad[], preset?: string): void;\n createCaret(page: PageRef, anchor: TextEndAnchor): void;\n createReplaceText(page: PageRef, quads: Quad[], anchor: TextEndAnchor, preset?: string): void;\n previewMarkup(subtype: KindName, quadsByPage: Record<number, Quad[]>, preset?: string): void;\n clearMarkupPreview(): void;\n\n // ── ghosts and previews (tools/ghost.ts) ──\n /**\n * Put the tool's ghost at a hover, what a click there would make;\n * `displayRotation` and `zoom` are the page's view there. The handler that\n * would take the click calls it, only where the click would reach it and\n * the user may create; a tool without a ghost clears it.\n */\n hoverGhostAt(\n toolId: string,\n page: PageRef,\n point: Point,\n displayRotation?: PageRotation,\n zoom?: number,\n ): void;\n clearGhost(): void;\n /**\n * A sibling plugin's placement gesture with one of this plugin's tools (the\n * form palette's drag-to-place): its press and the pointer now. Once it is a\n * drag, the page paints what releasing places; under that the tool's ghost\n * still shows the click.\n */\n previewPlacement(toolId: string, page: PageRef, from: Point, to: Point): void;\n clearPlacementPreview(): void;\n /** The armed stamp's ghost on a page, for the render layer's `<img>`. */\n getImageGhost(page: PageRef): ImageGhost | null;\n /** The armed stamp: a new object on every arm, null when nothing is armed. */\n getArmedStamp(): ArmedStampInfo | null;\n /** Render the armed stamp's ghost preview for a device pixel width (cached per size bucket). */\n renderArmedStampPreview(devicePixelWidth?: number): Promise<ArmedStampPreview | null>;\n\n // ── extension ──\n /**\n * Show a sibling's records with the annotations and edit them with the same\n * tools (see {@link AnnotationLender}). One lender at a time; returns the\n * release.\n */\n lend(lender: AnnotationLender): Unsubscribe;\n listResolvedTools(): ResolvedTool[];\n getResolvedTool(id: string): ResolvedTool | null;\n getToolSubtype(id: string): KindName;\n registerBehavior(behavior: Behavior): Unsubscribe;\n /** The engaged behavior that owns this annotation now, or `null`. */\n getBehaviorFor(annotation: Annotation): Behavior | null;\n pruneEngagedSelection(): void;\n commitScriptEffects(entries: AnnotCommitEntry[]): Promise<AnnotCommitResult>;\n}\n\n/**\n * The annotation capability token, typed to the full\n * {@link AnnotationHostCapability} (the package internals and `/contract/host`\n * use this view). The package root exports the same runtime token narrowed to\n * {@link AnnotationCapability}.\n */\nexport const AnnotationToken = createHostToken<AnnotationHostCapability>(PublicAnnotationToken);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAoBA,MAAa,2BAA2B;AACxC,MAAa,4BAA4B;AACzC,MAAa,2BAA2B;AACxC,MAAa,8BAA8B;;;;;;;;;;;;ACuI3C,SAAgB,cAAc,kBAA0B,WAAW,MAAc;CAE/E,OAAO,KAAK,IAAI,UAAU,KAAK,KAAK,KAAK,KAAK,KADnC,KAAK,IAAI,KAAK,KAAK,KAAK,gBAAgB,CACC,CAAC,CAAC,CAAC;AACzD;;;;;;;AA0NA,MAAa,mBAAA,GAAA,eAAA,gBAAA,CAA4DA,iBAAAA,eAAqB"}
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { Bt as ResolvedTool, Et as TextItem, G as ArmedStampInfo, K as ArmedStampPreview, N as AnnotationSelectionAnchor, Y as Behavior, ft as ImageGhost, gt as LinkNavItem, i as AnnotationAnchor, o as AnnotationCapability, qt as TextSelection, r as Annotation$1 } from "./contract-BK4LHe9v.cjs";
|
|
2
|
+
import { ChromeNode, EditableKinds, Effect, Id, KindName, Model, Point, Quad, Rect, RenderItem, SceneNode, Session, SnapSettings, TextEndAnchor, ViewEnv } from "@embedpdf/core-annotation";
|
|
3
|
+
import { EventHook, PredictedOp, Unsubscribe } from "@embedpdf/core";
|
|
4
|
+
import { PageRotation } from "@embedpdf/core-geometry";
|
|
5
|
+
import { AnnotationAppearanceImage, AnnotationPosition, AnnotationRef, ChangeOp, ImageSource, PageMeasurementViewport, PageRef, PdfMeasure, RichTextParagraph, SerializedEngineError } from "@embedpdf/engine-core/runtime";
|
|
6
|
+
import { AnnotCommitEntry, AnnotCommitResult } from "@embedpdf/plugin-actions/contract/host";
|
|
7
|
+
import { AppearancePicture } from "@embedpdf/plugin-render/contract/host";
|
|
8
|
+
//#region src/model.d.ts
|
|
9
|
+
/** Where the active tool's ghost is: the pointer on a page, and how that page shows there. */
|
|
10
|
+
interface GhostPointer {
|
|
11
|
+
readonly toolId: string;
|
|
12
|
+
readonly page: PageRef;
|
|
13
|
+
readonly point: Point;
|
|
14
|
+
/** The page's display rotation at the pointer (an upright tool lays its click out as seen). */
|
|
15
|
+
readonly displayRotation?: PageRotation;
|
|
16
|
+
/** The page's zoom at the pointer (a screen-sized icon's size depends on it). */
|
|
17
|
+
readonly zoom?: number;
|
|
18
|
+
}
|
|
19
|
+
/** A sibling plugin's placement gesture with one of this plugin's tools: its press, and the pointer now. */
|
|
20
|
+
interface ForeignPlacement {
|
|
21
|
+
readonly toolId: string;
|
|
22
|
+
readonly page: PageRef;
|
|
23
|
+
readonly from: Point;
|
|
24
|
+
readonly to: Point;
|
|
25
|
+
}
|
|
26
|
+
interface AnnotationState {
|
|
27
|
+
/** The core's session: selection, hover, the gesture in progress, tool settings. */
|
|
28
|
+
readonly session: Session;
|
|
29
|
+
/**
|
|
30
|
+
* Records this session renders from their description instead of the
|
|
31
|
+
* engine's raster: the ones it edited or created. Another session's edit
|
|
32
|
+
* hands a record back to the raster (see sync/confirmed.ts).
|
|
33
|
+
*/
|
|
34
|
+
readonly vector: Readonly<Record<Id, true>>;
|
|
35
|
+
/**
|
|
36
|
+
* Where the active tool's ghost is: the pointer, while a click there would
|
|
37
|
+
* make something. Only the pointer is state; what the ghost paints is
|
|
38
|
+
* derived from it and the tool's live defaults (tools/ghost.ts).
|
|
39
|
+
*/
|
|
40
|
+
readonly ghostAt: GhostPointer | null;
|
|
41
|
+
/**
|
|
42
|
+
* A placement a sibling plugin's gesture is making with one of this
|
|
43
|
+
* plugin's tools (the form palette's drag-to-place). Once it is a drag it
|
|
44
|
+
* paints as a drawing in progress (tools/ghost.ts).
|
|
45
|
+
*/
|
|
46
|
+
readonly placing: ForeignPlacement | null;
|
|
47
|
+
/**
|
|
48
|
+
* The text editor's selection inside the annotation being edited (flat
|
|
49
|
+
* offsets over its plain text), or null. It is state because the property
|
|
50
|
+
* surface reads it: while a range is held, the text style keys report and
|
|
51
|
+
* change the runs, not the whole body.
|
|
52
|
+
*/
|
|
53
|
+
readonly textSelection: TextSelection | null;
|
|
54
|
+
}
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/priorities.d.ts
|
|
57
|
+
/**
|
|
58
|
+
* The interaction-hub priorities of the annotation plugin's handlers — the
|
|
59
|
+
* public contract a sibling plugin builds on when it needs to sit above or
|
|
60
|
+
* below one of them for the same gesture. Priority only breaks ties between
|
|
61
|
+
* simultaneously-eligible handlers (the tool's tags decide eligibility).
|
|
62
|
+
*
|
|
63
|
+
* 100 annotation-edit select/move/resize over an existing annotation
|
|
64
|
+
* 95 annotation-place click-to-place an armed payload on empty page space
|
|
65
|
+
* 55 annotation-draw drag-create under a draw tool (below text-select)
|
|
66
|
+
* 50 annotation-marquee empty-space selection, the final fallback
|
|
67
|
+
*
|
|
68
|
+
* Hover runs in the same order, so a handler's hover sees the cursor claims
|
|
69
|
+
* of every handler above it: a create handler shows its tool's ghost only
|
|
70
|
+
* where nothing above it claims the pointer (an annotation, text).
|
|
71
|
+
*
|
|
72
|
+
* A handler that must win a click over an existing annotation while a
|
|
73
|
+
* placing tool is active (a signature mark dropped onto a signature field)
|
|
74
|
+
* registers above {@link ANNOTATION_EDIT_PRIORITY}, not merely above place:
|
|
75
|
+
* the edit handler captures first over any annotation, a widget included.
|
|
76
|
+
*/
|
|
77
|
+
declare const ANNOTATION_EDIT_PRIORITY = 100;
|
|
78
|
+
declare const ANNOTATION_PLACE_PRIORITY = 95;
|
|
79
|
+
declare const ANNOTATION_DRAW_PRIORITY = 55;
|
|
80
|
+
declare const ANNOTATION_MARQUEE_PRIORITY = 50;
|
|
81
|
+
//#endregion
|
|
82
|
+
//#region src/host-contract.d.ts
|
|
83
|
+
/**
|
|
84
|
+
* One annotation's look at rest in one of its states, as the render layer
|
|
85
|
+
* paints it: the engine's picture, or, while the annotation's create is on
|
|
86
|
+
* its way, the one this device made (a placed stamp's preview), which the
|
|
87
|
+
* engine's replaces. `version` is the record's picture version it shows
|
|
88
|
+
* (`RenderItem.pictureVersion`): one drawn at another version shows another look.
|
|
89
|
+
*/
|
|
90
|
+
interface AnnotationAppearancePicture extends Pick<AnnotationAppearanceImage, 'ref' | 'mode' | 'state' | 'rect'> {
|
|
91
|
+
readonly image: ImageSource;
|
|
92
|
+
readonly version: number;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* A sibling plugin that lends this plugin records it owns (the form plugin's
|
|
96
|
+
* widgets), so they are selected, moved, resized, restyled and deleted with
|
|
97
|
+
* the annotation tools. This plugin never stores them: it shows them as the
|
|
98
|
+
* lender says, and an edit of one becomes the lender's ops, in the same change
|
|
99
|
+
* as the rest of the edit.
|
|
100
|
+
*/
|
|
101
|
+
interface AnnotationLender {
|
|
102
|
+
/** Who owns the records, for a refusal that sends you there (`'form'`). */
|
|
103
|
+
readonly owner: string;
|
|
104
|
+
/**
|
|
105
|
+
* Its records as the engine confirmed them and as they show, each list the
|
|
106
|
+
* same object until it changes; `null` while it lends none.
|
|
107
|
+
*/
|
|
108
|
+
records(): {
|
|
109
|
+
readonly confirmed: readonly Annotation$1[];
|
|
110
|
+
readonly shown: readonly Annotation$1[];
|
|
111
|
+
} | null;
|
|
112
|
+
/**
|
|
113
|
+
* The ops that write a message's effects on its records, all at once:
|
|
114
|
+
* `model` is the model the message left, `before` the one it started from
|
|
115
|
+
* (a record it deleted is there).
|
|
116
|
+
*/
|
|
117
|
+
opsOf(effects: readonly Effect[], model: Model, before: Model): readonly ChangeOp[];
|
|
118
|
+
/** What undoing these ops looks like. */
|
|
119
|
+
undoOf(ops: readonly ChangeOp[]): readonly PredictedOp[];
|
|
120
|
+
/** The ops that move these records of one page to `position` in its drawing order. */
|
|
121
|
+
reorderOps(page: PageRef, refs: readonly AnnotationRef[], position: AnnotationPosition): readonly ChangeOp[];
|
|
122
|
+
/** Whether this session may change and delete the record. */
|
|
123
|
+
authority(record: Annotation$1): {
|
|
124
|
+
readonly update: boolean;
|
|
125
|
+
readonly delete: boolean;
|
|
126
|
+
};
|
|
127
|
+
/** What its records' pictures on a page depend on: a new value means new pictures. */
|
|
128
|
+
pictureEpoch(page: PageRef): string;
|
|
129
|
+
/** A record's confirmed picture version; kept for one that went, so an undo brings it back with it. */
|
|
130
|
+
pictureVersion(record: AnnotationRef): number;
|
|
131
|
+
/**
|
|
132
|
+
* The record's look as it shows isn't its confirmed look yet, whatever changed it (a restyle,
|
|
133
|
+
* a resize, one just placed, a change the lender made itself): it draws live, by its
|
|
134
|
+
* {@link painter}, until the engine's picture of it is there.
|
|
135
|
+
*/
|
|
136
|
+
pending(record: AnnotationRef): boolean;
|
|
137
|
+
/**
|
|
138
|
+
* How the lender draws the record live: the record upright in `box` (its box, or where a
|
|
139
|
+
* gesture has it), in page space; `null` for one it doesn't draw. A record with a painter
|
|
140
|
+
* draws live while a gesture reshapes it, as a square does.
|
|
141
|
+
*/
|
|
142
|
+
painter(record: Annotation$1): ((box: Rect) => readonly SceneNode[]) | null;
|
|
143
|
+
/** Its records' pictures on a page, at rest, in every state, each with its record's picture version. */
|
|
144
|
+
renderAppearances(page: PageRef, scale: number, signal?: AbortSignal): Promise<readonly AppearancePicture[]>;
|
|
145
|
+
}
|
|
146
|
+
interface RecalibrationReport {
|
|
147
|
+
page: PageRef;
|
|
148
|
+
scale: PdfMeasure;
|
|
149
|
+
/** Page-wide read failure: no complete annotation set was available to recalculate. */
|
|
150
|
+
error?: SerializedEngineError;
|
|
151
|
+
updated: AnnotationRef[];
|
|
152
|
+
skipped: {
|
|
153
|
+
ref: AnnotationRef;
|
|
154
|
+
reason: 'no-authority' | 'locked' | 'foreign-measure' | 'unavailable';
|
|
155
|
+
}[];
|
|
156
|
+
failed: {
|
|
157
|
+
ref: AnnotationRef;
|
|
158
|
+
error: SerializedEngineError;
|
|
159
|
+
}[];
|
|
160
|
+
}
|
|
161
|
+
interface CapturedAnnotationDraft {
|
|
162
|
+
tool: string;
|
|
163
|
+
page: PageRef;
|
|
164
|
+
from: Point;
|
|
165
|
+
to: Point;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Ghost render buckets: powers of two from 128 px up to `cap`. The same policy
|
|
169
|
+
* the page renderer uses — one bitmap per size class, never per zoom step.
|
|
170
|
+
*/
|
|
171
|
+
declare function previewBucket(devicePixelWidth: number, maxWidth?: number): number;
|
|
172
|
+
/**
|
|
173
|
+
* The host (framework) surface: everything the render layer, the interaction hub,
|
|
174
|
+
* and sibling plugins need, on top of the public {@link AnnotationCapability}.
|
|
175
|
+
* Host-only: sibling plugins and framework adapters import the token from
|
|
176
|
+
* `@embedpdf/plugin-annotation/contract/host`. Never use it from application code.
|
|
177
|
+
*/
|
|
178
|
+
interface AnnotationHostCapability extends AnnotationCapability {
|
|
179
|
+
setPageViewports(page: PageRef, viewports: PageMeasurementViewport[] | undefined, fallback: PdfMeasure): void;
|
|
180
|
+
remeasurePage(page: PageRef, scale: PdfMeasure): Promise<RecalibrationReport>;
|
|
181
|
+
/** A distance draft was captured (the measurement plugin turns it into a calibration). */
|
|
182
|
+
readonly onDraftCaptured: EventHook<CapturedAnnotationDraft>;
|
|
183
|
+
distanceCreationPage(): PageRef | null;
|
|
184
|
+
/**
|
|
185
|
+
* The selection's anchor as a page shows it: its rotation handle where the
|
|
186
|
+
* page's view puts it (screen-sized, so it depends on the zoom), for a menu
|
|
187
|
+
* that stays clear of it. `selection.getAnchor()` is the same without a view.
|
|
188
|
+
*/
|
|
189
|
+
getSelectionAnchorIn(view: {
|
|
190
|
+
scale?: number;
|
|
191
|
+
rotation?: PageRotation;
|
|
192
|
+
zoom?: number;
|
|
193
|
+
}): AnnotationSelectionAnchor | null;
|
|
194
|
+
/**
|
|
195
|
+
* Where UI attaches to one annotation (its page and the box around what it
|
|
196
|
+
* shows, a drag in progress included), or `null` for one that isn't here.
|
|
197
|
+
* Without a view, an annotation that keeps its size on screen carries
|
|
198
|
+
* `boundsIn` for the view it's shown in.
|
|
199
|
+
*/
|
|
200
|
+
getAnnotationAnchor(ref: AnnotationRef, view?: ViewEnv): AnnotationAnchor | null;
|
|
201
|
+
listPageItems(page: PageRef, view?: ViewEnv): RenderItem[];
|
|
202
|
+
listTextItems(page: PageRef, view?: ViewEnv): TextItem[];
|
|
203
|
+
listChromeNodes(page: PageRef, scale?: number, rotation?: PageRotation, zoom?: number): ChromeNode[];
|
|
204
|
+
listLinkItems(page: PageRef): LinkNavItem[];
|
|
205
|
+
/**
|
|
206
|
+
* What a page's pictures depend on: its baked records at their picture
|
|
207
|
+
* versions, the stamps this session placed, the pictures kept for an undone
|
|
208
|
+
* delete and the lender's widgets. Load the pictures again when it changes,
|
|
209
|
+
* or when the appearance scale (`render.getAppearanceScale`) does.
|
|
210
|
+
*/
|
|
211
|
+
getAppearanceEpoch(page: PageRef): string;
|
|
212
|
+
/**
|
|
213
|
+
* Every picture a page's annotations show at rest, in every state, each
|
|
214
|
+
* with its record's picture version: the engine's (through the render
|
|
215
|
+
* plugin; none without it), the lender's, and this session's placed stamps.
|
|
216
|
+
*/
|
|
217
|
+
renderAppearances(page: PageRef, scale: number, signal?: AbortSignal): Promise<AnnotationAppearancePicture[]>;
|
|
218
|
+
/**
|
|
219
|
+
* Resolves once the annotations mirror has applied every confirmed change
|
|
220
|
+
* it knows of, including page re-reads that events started.
|
|
221
|
+
*/
|
|
222
|
+
whenSynced(): Promise<void>;
|
|
223
|
+
getEditingId(): Id | null;
|
|
224
|
+
beginTextEditAt(page: PageRef, point: Point, scale?: number, rotation?: PageRotation, zoom?: number): boolean;
|
|
225
|
+
draftContents(ref: AnnotationRef, text: string): void;
|
|
226
|
+
draftRichText(ref: AnnotationRef, doc: {
|
|
227
|
+
paragraphs: RichTextParagraph[];
|
|
228
|
+
}): void;
|
|
229
|
+
setTextSelection(ref: AnnotationRef, range: {
|
|
230
|
+
start: number;
|
|
231
|
+
end: number;
|
|
232
|
+
} | null): void;
|
|
233
|
+
getCssFontFamily(family: string): string;
|
|
234
|
+
getHitKind(page: PageRef, point: Point, scale?: number, rotation?: PageRotation, zoom?: number, touch?: boolean): 'handle' | 'rotate' | 'group-handle' | 'annot' | 'empty';
|
|
235
|
+
claimsTouchAt(page: PageRef, point: Point, scale?: number, rotation?: PageRotation, zoom?: number): boolean;
|
|
236
|
+
getCursorAt(page: PageRef, point: Point, scale?: number, rotation?: PageRotation, zoom?: number): string | null;
|
|
237
|
+
hoverAt(at: {
|
|
238
|
+
page: PageRef;
|
|
239
|
+
point: Point;
|
|
240
|
+
scale?: number;
|
|
241
|
+
rotation?: PageRotation;
|
|
242
|
+
zoom?: number;
|
|
243
|
+
} | null): void;
|
|
244
|
+
editPointer(phase: 'down' | 'move' | 'up', page: PageRef, point: Point, shift: boolean, scale?: number, rotation?: PageRotation, zoom?: number, touch?: boolean): void;
|
|
245
|
+
marqueePointer(phase: 'down' | 'move' | 'up', page: PageRef, point: Point, shift: boolean, scale?: number, rotation?: PageRotation, zoom?: number): void;
|
|
246
|
+
createPointer(tool: string, phase: 'down' | 'move' | 'up', page: PageRef, point: Point, finish?: boolean, displayRotation?: PageRotation): void;
|
|
247
|
+
finishInkDraft(): void;
|
|
248
|
+
/** Place with the active tool at a click; `displayRotation` and `zoom` are the page's view there. */
|
|
249
|
+
placeAt(page: PageRef, point: Point, displayRotation?: PageRotation, zoom?: number): boolean;
|
|
250
|
+
placeArmedStamp(page: PageRef, point: Point, displayRotation?: PageRotation): boolean;
|
|
251
|
+
requestStampAt(page: PageRef, point: Point, displayRotation?: PageRotation): boolean;
|
|
252
|
+
/**
|
|
253
|
+
* Turn the text selection into what the tool makes of it (markup, a caret,
|
|
254
|
+
* a replace-text pair) and clear the selection; `false`, and nothing, for a
|
|
255
|
+
* tool that makes nothing of a selection, without create authority, or
|
|
256
|
+
* without a selection.
|
|
257
|
+
*/
|
|
258
|
+
applyToolToSelection(toolId: string): boolean;
|
|
259
|
+
createMarkup(subtype: KindName, page: PageRef, quads: Quad[], preset?: string): void;
|
|
260
|
+
createCaret(page: PageRef, anchor: TextEndAnchor): void;
|
|
261
|
+
createReplaceText(page: PageRef, quads: Quad[], anchor: TextEndAnchor, preset?: string): void;
|
|
262
|
+
previewMarkup(subtype: KindName, quadsByPage: Record<number, Quad[]>, preset?: string): void;
|
|
263
|
+
clearMarkupPreview(): void;
|
|
264
|
+
/**
|
|
265
|
+
* Put the tool's ghost at a hover, what a click there would make;
|
|
266
|
+
* `displayRotation` and `zoom` are the page's view there. The handler that
|
|
267
|
+
* would take the click calls it, only where the click would reach it and
|
|
268
|
+
* the user may create; a tool without a ghost clears it.
|
|
269
|
+
*/
|
|
270
|
+
hoverGhostAt(toolId: string, page: PageRef, point: Point, displayRotation?: PageRotation, zoom?: number): void;
|
|
271
|
+
clearGhost(): void;
|
|
272
|
+
/**
|
|
273
|
+
* A sibling plugin's placement gesture with one of this plugin's tools (the
|
|
274
|
+
* form palette's drag-to-place): its press and the pointer now. Once it is a
|
|
275
|
+
* drag, the page paints what releasing places; under that the tool's ghost
|
|
276
|
+
* still shows the click.
|
|
277
|
+
*/
|
|
278
|
+
previewPlacement(toolId: string, page: PageRef, from: Point, to: Point): void;
|
|
279
|
+
clearPlacementPreview(): void;
|
|
280
|
+
/** The armed stamp's ghost on a page, for the render layer's `<img>`. */
|
|
281
|
+
getImageGhost(page: PageRef): ImageGhost | null;
|
|
282
|
+
/** The armed stamp: a new object on every arm, null when nothing is armed. */
|
|
283
|
+
getArmedStamp(): ArmedStampInfo | null;
|
|
284
|
+
/** Render the armed stamp's ghost preview for a device pixel width (cached per size bucket). */
|
|
285
|
+
renderArmedStampPreview(devicePixelWidth?: number): Promise<ArmedStampPreview | null>;
|
|
286
|
+
/**
|
|
287
|
+
* Show a sibling's records with the annotations and edit them with the same
|
|
288
|
+
* tools (see {@link AnnotationLender}). One lender at a time; returns the
|
|
289
|
+
* release.
|
|
290
|
+
*/
|
|
291
|
+
lend(lender: AnnotationLender): Unsubscribe;
|
|
292
|
+
listResolvedTools(): ResolvedTool[];
|
|
293
|
+
getResolvedTool(id: string): ResolvedTool | null;
|
|
294
|
+
getToolSubtype(id: string): KindName;
|
|
295
|
+
registerBehavior(behavior: Behavior): Unsubscribe;
|
|
296
|
+
/** The engaged behavior that owns this annotation now, or `null`. */
|
|
297
|
+
getBehaviorFor(annotation: Annotation$1): Behavior | null;
|
|
298
|
+
pruneEngagedSelection(): void;
|
|
299
|
+
commitScriptEffects(entries: AnnotCommitEntry[]): Promise<AnnotCommitResult>;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* The annotation capability token, typed to the full
|
|
303
|
+
* {@link AnnotationHostCapability} (the package internals and `/contract/host`
|
|
304
|
+
* use this view). The package root exports the same runtime token narrowed to
|
|
305
|
+
* {@link AnnotationCapability}.
|
|
306
|
+
*/
|
|
307
|
+
declare const AnnotationToken: import("@embedpdf/core").CapabilityToken<AnnotationHostCapability>;
|
|
308
|
+
//#endregion
|
|
309
|
+
export { CapturedAnnotationDraft as a, ANNOTATION_DRAW_PRIORITY as c, ANNOTATION_PLACE_PRIORITY as d, AnnotationState as f, AnnotationToken as i, ANNOTATION_EDIT_PRIORITY as l, AnnotationHostCapability as n, RecalibrationReport as o, AnnotationLender as r, previewBucket as s, AnnotationAppearancePicture as t, ANNOTATION_MARQUEE_PRIORITY as u };
|
|
310
|
+
//# sourceMappingURL=host-contract-Nzxwh0XS.d.cts.map
|