@embedpdf/plugin-selection 3.0.0-next.0 → 3.0.0-next.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,167 +1,97 @@
1
- import { PageObjectNumber, PluginContext } from "@embedpdf/core";
2
- import { InteractionCapability, InteractionHandler } from "@embedpdf/plugin-interaction";
3
- import { Point, Rect } from "@embedpdf/core-geometry";
4
- import { PageGeometrySnapshot, PdfRect } from "@embedpdf/engine-core/runtime";
5
- //#region src/types.d.ts
6
- /** A glyph address: a page + a flat glyph index within that page's geometry. */
7
- interface GlyphPointer {
8
- pon: PageObjectNumber;
9
- glyph: number;
10
- }
11
- /** Anchor = where the drag began, focus = the current end. Inclusive. */
12
- interface SelectionRange {
13
- anchor: GlyphPointer;
14
- focus: GlyphPointer;
15
- }
16
- interface SelectionEndpoint {
17
- pon: PageObjectNumber;
18
- rect: Rect;
19
- }
20
- interface SelectionSnapshot {
21
- pages: Array<{
22
- pon: PageObjectNumber;
23
- rects: Rect[];
24
- }>;
25
- start: SelectionEndpoint | null;
26
- end: SelectionEndpoint | null;
27
- direction: 'forward' | 'backward';
28
- }
29
- interface SelectionState {
30
- selection: SelectionRange | null;
31
- /** Derived highlight rects per page, in CONTENT space (y-down, PDF units). */
32
- rects: Record<number, Rect[]>;
33
- /** Pages whose text geometry has loaded (so the layer re-renders when ready). */
34
- loaded: Record<number, boolean>;
35
- /** When a consumer owns the selection visual (e.g. a markup tool draws its own
36
- * preview), the default highlight rects are suppressed. */
37
- highlightHidden: boolean;
38
- }
39
- type SelectionAction = {
40
- type: 'PAGE_LOADED';
41
- pon: PageObjectNumber;
42
- } | {
43
- type: 'SET';
44
- selection: SelectionRange;
45
- rects: Record<number, Rect[]>;
46
- } | {
47
- type: 'CLEAR';
48
- } | {
49
- type: 'SET_HIGHLIGHT_HIDDEN';
50
- hidden: boolean;
51
- };
52
- interface SelectionCapability {
53
- /** Warm a page's text geometry (idempotent). Layers call this when a page mounts. */
54
- ensurePage(pon: PageObjectNumber): void;
55
- isLoaded(pon: PageObjectNumber): boolean;
56
- /** Is a content-space point on (or near) text? Drives the I-beam vs pointer cursor. */
57
- isOverText(pon: PageObjectNumber, point: Point): boolean;
58
- /** Begin a caret selection at a page point. Returns false if not near any text. */
59
- beginAt(pon: PageObjectNumber, point: Point): boolean;
60
- /** Double-click: select the word around the point. */
61
- selectWord(pon: PageObjectNumber, point: Point): void;
62
- /** Triple-click: select the whole visual line around the point. */
63
- selectLine(pon: PageObjectNumber, point: Point): void;
64
- /** Extend the current selection to a page point (drag). */
65
- extendTo(pon: PageObjectNumber, point: Point): void;
66
- end(): void;
67
- clear(): void;
68
- /** Coherent read-model for consumers that create annotations or selection UI. */
69
- snapshot(): SelectionSnapshot;
70
- /** Highlight rects for a page, in content space — the layer's only input. */
71
- rectsForPage(pon: PageObjectNumber): Rect[];
72
- hasSelection(): boolean;
73
- /** The pages the current selection covers (those with at least one rect) — so a
74
- * cross-page action (e.g. text-markup creation) can fan out per page. */
75
- selectedPages(): PageObjectNumber[];
76
- /** Fires whenever the selection rects change (e.g. drag-extend) — for live preview. */
77
- onChange(cb: () => void): () => void;
78
- /** Fires when a selection gesture ends (pointer-up) — the commit point. */
79
- onCommit(cb: () => void): () => void;
80
- /** Suppress / restore the default highlight visual (a consumer drawing its own). */
81
- setHighlightVisible(visible: boolean): void;
82
- highlightVisible(): boolean;
83
- }
84
- declare const SelectionToken: import("@embedpdf/core").CapabilityToken<SelectionCapability>;
85
- //#endregion
1
+ import { a as SelectionHostCapability, c as SelectionRangeInput, f as TextPosition, h as SelectionSegment, i as SelectionEndpoint, l as SelectionSnapshot, n as SelectionAction, o as SelectionMenuAnchor, p as TextRange, r as SelectionCapability, u as SelectionState } from "./types-DCsyRlZS.js";
2
+ import { CapabilityToken, PageObjectNumber } from "@embedpdf/core";
3
+ import { Point, TextQuad } from "@embedpdf/core-geometry";
86
4
  //#region src/selection.plugin.d.ts
87
5
  /**
88
6
  * Text selection — document-scoped, requires the interaction hub. In `init` it
89
7
  * registers ITS pointer handler with the hub; the hub owns the pointer stream
90
8
  * and arbitration. Works with `<Stage>` or a standalone `<PageView>` — selection
91
9
  * only needs the page coordinate context + the engine's text geometry.
92
- */
93
- declare const selectionPlugin: () => import("@embedpdf/core").PluginDef<SelectionState, SelectionAction, SelectionCapability>;
94
- //#endregion
95
- //#region src/capability.d.ts
96
- /**
97
- * The selection capability. The reducer state holds the selection range, the
98
- * derived content-space rects (per page), and per-page loaded flags; the (large,
99
- * non-serializable) per-page text geometry is cached HERE in the closure.
100
10
  *
101
- * Selection is cross-page: glyphs are ordered globally by (pageIndex, glyph), so
102
- * a drag from page 2 into page 4 selects the tail of 2, all of 3, and the head of
103
- * 4. `recompute` rebuilds the merged line rects for every loaded page in the span
104
- * and re-runs whenever a mid-span page finishes loading.
11
+ * Registry/content invalidation is wired inside the capability itself
12
+ * (revision watch + document event subscription), so headless/programmatic
13
+ * use gets the same reconciliation as the full viewer.
105
14
  */
106
- declare function createSelectionCapability(ctx: PluginContext<SelectionState, SelectionAction>): SelectionCapability;
15
+ declare const selectionPlugin: () => import("@embedpdf/core").PluginDef<SelectionState, SelectionAction, SelectionHostCapability>;
107
16
  //#endregion
108
- //#region src/handler.d.ts
109
- /**
110
- * The text-selection pointer handler. It is live only under tools that enable the
111
- * `'text-select'` tag (the built-in `pointer` tool does; `pan` does not — so
112
- * switching to pan disables text selection with zero special-casing here).
113
- *
114
- * - single click → deselect; records an anchor but selects NOTHING until
115
- * the pointer moves past the drag threshold (Chrome/Acrobat feel)
116
- * - single-click + drag → caret selection from the anchor (extends across pages)
117
- * - double-click → select the word
118
- * - triple-click → select the visual line
119
- * - down off-text → deselect, and DON'T capture (so it can't block)
120
- * - hover → I-beam only when over text, else the pointer cursor
121
- */
122
- declare function createTextSelectHandler(selection: SelectionCapability, interaction: InteractionCapability): InteractionHandler;
123
- //#endregion
124
- //#region src/reducer.d.ts
125
- declare const initialSelectionState: SelectionState;
126
- declare const selectionReducer: (state: SelectionState, action: SelectionAction) => SelectionState;
127
- //#endregion
128
- //#region src/geometry.d.ts
129
- /** One glyph in content space. `loose` builds selection rects; `tight` hit-tests. */
130
- interface GlyphInfo {
131
- loose: Rect;
132
- tight?: Rect;
133
- flags: number;
17
+ //#region src/handles.d.ts
18
+ /** What handle geometry & drags need from the hosting view. */
19
+ interface SelectionHandleView {
20
+ /** Page content point → overlay px. Must be POINT-exact (compose
21
+ * `pageToWorld` with `toScreen`); an AABB projector loses orientation. */
22
+ toOverlay(pon: PageObjectNumber, pt: Point): Point | null;
23
+ /** Overlay px → the page under it, or null over a gap. */
24
+ pageAt(overlay: Point): {
25
+ pon: PageObjectNumber;
26
+ point: Point;
27
+ } | null;
28
+ /** Overlay px → a SPECIFIC page's content space, unclamped. */
29
+ pointOnPage(pon: PageObjectNumber, overlay: Point): Point | null;
30
+ }
31
+ /** One selection boundary, as the handle needs it (a `SelectionEndpoint` slice). */
32
+ interface SelectionHandleEndpoint {
33
+ pon: PageObjectNumber;
34
+ /** The boundary glyph's own oriented cell, page content space. */
35
+ glyphQuad: TextQuad;
36
+ /** Reading direction of its segment (+1 = the frame's +x) — decides which
37
+ * side of the cell is the selection's leading edge. */
38
+ advance: 1 | -1;
134
39
  }
135
- /** A contiguous run of glyphs (a text object). `rect` is its loose enclosing box. */
136
- interface RunInfo {
137
- start: number;
138
- count: number;
139
- rect: Rect;
140
- fontSize?: number;
40
+ /** The gesture verbs a handle drag drives — `SelectionHostCapability` satisfies it. */
41
+ interface SelectionHandleTarget {
42
+ beginAt(pon: PageObjectNumber, point: Point): boolean;
43
+ extendTo(pon: PageObjectNumber, point: Point): void;
44
+ end(): void;
45
+ }
46
+ declare const HANDLE_HEAD = 12;
47
+ declare const HANDLE_BAR = 2;
48
+ declare const HANDLE_PAD = 14;
49
+ interface SelectionHandleGeom {
50
+ /** The projected edge, ascent corner first, overlay px. */
51
+ bar: {
52
+ from: Point;
53
+ to: Point;
54
+ };
55
+ /** The glyph's ink height on screen — zoom scaling comes free. */
56
+ length: number;
57
+ /** Degrees clockwise; 0 when the text is upright on screen. */
58
+ rotation: number;
59
+ /** True within the epsilon of upright: render with NO transform. */
60
+ upright: boolean;
61
+ /** Centre of the grab head, overlay px. */
62
+ head: Point;
141
63
  }
142
- /** A page's text laid out in content space: a flat glyph list + the run structure. */
143
- interface PageText {
144
- glyphs: GlyphInfo[];
145
- runs: RunInfo[];
64
+ /**
65
+ * The handle's geometry for one endpoint, in overlay space. Null when the
66
+ * endpoint's page isn't laid out (or the cell is degenerate) — render nothing.
67
+ */
68
+ declare function selectionHandleGeom(view: SelectionHandleView, ep: SelectionHandleEndpoint, role: 'start' | 'end'): SelectionHandleGeom | null;
69
+ interface SelectionHandleDragSession {
70
+ /** Feed the pointer's current overlay position. */
71
+ move(overlay: Point): void;
72
+ /** The pointer released (or was cancelled): settle the gesture. */
73
+ end(): void;
146
74
  }
147
75
  /**
148
- * Flatten a page's text geometry into content-space glyphs + runs. Rotation does
149
- * NOT enter here — the overlay rides the page's CSS rotation, so glyphs stay in
150
- * un-rotated content space (the crop-relative y-flip is the only conversion).
76
+ * One armed handle drag. Dragging a handle extends from the OPPOSITE
77
+ * endpoint: the first movement re-roots the selection gesture at that
78
+ * endpoint's cell centre, and every position then extends toward the pointer
79
+ * — snapping to glyphs and crossing pages exactly like a pointer drag,
80
+ * firing the same change/commit signals. Over a gap the point projects onto
81
+ * the last page hit (unclamped), so the selection keeps tracking instead of
82
+ * freezing at a page edge. `end()` commits only if the drag actually
83
+ * re-rooted; an untouched press settles nothing.
151
84
  */
152
- declare function buildPageText(snapshot: PageGeometrySnapshot, crop: PdfRect, rotation: 0 | 90 | 180 | 270, userUnit: number): PageText;
85
+ declare function createSelectionHandleDrag(selection: SelectionHandleTarget, view: SelectionHandleView, opposite: SelectionHandleEndpoint, draggedPon: PageObjectNumber): SelectionHandleDragSession;
86
+ //#endregion
87
+ //#region src/index.d.ts
153
88
  /**
154
- * The glyph index at a content-space point, or null when nothing is near (so the
155
- * caller can show the pointer cursor off-text). PDFium `GetIndexAtPos`: exact
156
- * tight-box containment first, then a tolerance pass (closest by Manhattan
157
- * distance within `toleranceFactor × average glyph height`).
89
+ * The selection capability token, narrowed to the public
90
+ * {@link SelectionCapability} lens. It is the SAME runtime token the plugin
91
+ * provides — the host-only surface (pointer gestures, geometry warming) is
92
+ * reachable only via `@embedpdf/plugin-selection/internal`.
158
93
  */
159
- declare function glyphAt(text: PageText, p: Point, toleranceFactor?: number): number | null;
160
- /** Double-click: the word around `i` (walk to space/empty glyphs both ways). */
161
- declare function expandToWord(text: PageText, i: number): [number, number];
162
- /** Triple-click: the full visual line — runs whose vertical extent overlaps the anchor run's. */
163
- declare function expandToLine(text: PageText, i: number): [number, number];
164
- declare function rectsForRange(text: PageText, from: number, to: number): Rect[];
94
+ declare const SelectionToken: CapabilityToken<SelectionCapability>;
165
95
  //#endregion
166
- export { type GlyphInfo, type GlyphPointer, type PageText, type RunInfo, type SelectionAction, type SelectionCapability, type SelectionEndpoint, type SelectionRange, type SelectionSnapshot, type SelectionState, SelectionToken, buildPageText, createSelectionCapability, createTextSelectHandler, expandToLine, expandToWord, glyphAt, initialSelectionState, rectsForRange, selectionPlugin, selectionReducer };
96
+ export { HANDLE_BAR, HANDLE_HEAD, HANDLE_PAD, type SelectionCapability, type SelectionEndpoint, type SelectionHandleDragSession, type SelectionHandleEndpoint, type SelectionHandleGeom, type SelectionHandleTarget, type SelectionHandleView, type SelectionMenuAnchor, type SelectionRangeInput, type SelectionSegment, type SelectionSnapshot, SelectionToken, type TextPosition, type TextRange, createSelectionHandleDrag, selectionHandleGeom, selectionPlugin };
167
97
  //# sourceMappingURL=index.d.ts.map