@embedpdf/plugin-selection 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.
Files changed (41) hide show
  1. package/dist/contract/host.cjs +16 -2
  2. package/dist/contract/host.cjs.map +1 -0
  3. package/dist/contract/host.d.cts +3 -2
  4. package/dist/contract/host.d.ts +3 -2
  5. package/dist/contract/host.js +16 -2
  6. package/dist/contract/host.js.map +1 -0
  7. package/dist/contract-BUiw1d8F.cjs +36 -0
  8. package/dist/contract-BUiw1d8F.cjs.map +1 -0
  9. package/dist/contract-DBXA64ep.js +26 -0
  10. package/dist/contract-DBXA64ep.js.map +1 -0
  11. package/dist/contract-DLs4vXVt.d.cts +252 -0
  12. package/dist/contract-DLs4vXVt.d.ts +252 -0
  13. package/dist/contract.cjs +3 -6
  14. package/dist/contract.d.cts +2 -7
  15. package/dist/contract.d.ts +2 -7
  16. package/dist/contract.js +2 -7
  17. package/dist/host-contract-DO2aLU2e.d.ts +34 -0
  18. package/dist/host-contract-Ddo4PcJJ.d.cts +34 -0
  19. package/dist/index.cjs +777 -51
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +97 -29
  22. package/dist/index.d.ts +97 -29
  23. package/dist/index.js +772 -51
  24. package/dist/index.js.map +1 -1
  25. package/package.json +5 -9
  26. package/dist/contract.cjs.map +0 -1
  27. package/dist/contract.js.map +0 -1
  28. package/dist/internal.cjs +0 -13
  29. package/dist/internal.d.cts +0 -63
  30. package/dist/internal.d.ts +0 -63
  31. package/dist/internal.js +0 -4
  32. package/dist/reducer-BAOQ2CJ8.cjs +0 -732
  33. package/dist/reducer-BAOQ2CJ8.cjs.map +0 -1
  34. package/dist/reducer-DbKtk9Xl.js +0 -685
  35. package/dist/reducer-DbKtk9Xl.js.map +0 -1
  36. package/dist/types-BVUcOsCh.js +0 -14
  37. package/dist/types-BVUcOsCh.js.map +0 -1
  38. package/dist/types-CUrUVl6K.d.cts +0 -292
  39. package/dist/types-CUrUVl6K.d.ts +0 -292
  40. package/dist/types-D9kEBMFj.cjs +0 -18
  41. package/dist/types-D9kEBMFj.cjs.map +0 -1
@@ -1,3 +1,17 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_types = require("../types-D9kEBMFj.cjs");
3
- exports.SelectionToken = require_types.SelectionToken;
2
+ const require_contract = require("../contract-BUiw1d8F.cjs");
3
+ //#region src/host-contract.ts
4
+ /**
5
+ * @embedpdf/plugin-selection/contract/host — the host lens.
6
+ *
7
+ * What render layers, the interaction hub and sibling plugins need on top
8
+ * of the public contract: gesture bracketing, geometry warming and the
9
+ * highlight-visibility handshake. Same runtime token as the public one,
10
+ * typed wider. Never use this from application code.
11
+ */
12
+ const SelectionToken = (0, require("@embedpdf/core").createHostToken)(require_contract.SelectionToken);
13
+ //#endregion
14
+ exports.SELECTION_DEFAULTS = require_contract.SELECTION_DEFAULTS;
15
+ exports.SelectionToken = SelectionToken;
16
+
17
+ //# sourceMappingURL=host.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.cjs","names":["PublicSelectionToken"],"sources":["../../src/host-contract.ts"],"sourcesContent":["/**\n * @embedpdf/plugin-selection/contract/host — the host lens.\n *\n * What render layers, the interaction hub and sibling plugins need on top\n * of the public contract: gesture bracketing, geometry warming and the\n * highlight-visibility handshake. Same runtime token as the public one,\n * typed wider. Never use this from application code.\n */\nimport { createHostToken, type PageRef } from '@embedpdf/core';\nimport type { Point } from '@embedpdf/core-geometry';\nimport { SelectionToken as PublicSelectionToken, type SelectionCapability } from './contract';\n\nexport * from './contract';\n\nexport interface SelectionHostCapability extends SelectionCapability {\n /** Warm a page's text geometry. Resolves once loaded; resolves immediately\n * (nothing requested) without `doc.text.select` or for an unknown page. A\n * failed read resolves too — the layer simply has nothing to paint. */\n ensureLoaded(page: PageRef): Promise<void>;\n /** Whether the page's text geometry is loaded and current. */\n isLoaded(page: PageRef): boolean;\n /** Is a page-space point on (or near) text? Drives the I-beam cursor. */\n isOverText(page: PageRef, point: Point): boolean;\n /**\n * A pointer gesture that drives the selection opened (pointer-down). From\n * here until {@link endGesture}, `isSelecting()` is true and\n * selection-scoped UI hides. Programmatic writes never open a gesture.\n */\n beginGesture(): void;\n /** Open a caret selection at a page point (the first drag step). Returns\n * false when the point has no text — the caller lets the gesture go. */\n beginGestureAt(page: PageRef, point: Point): boolean;\n /** The gesture ended (pointer-up). Settles first, then emits `onCommitted`\n * when a selection is in place. */\n endGesture(): void;\n /** Suppress / restore the default highlight visual (a consumer drawing its\n * own preview — the markup ghost). */\n setHighlightVisible(visible: boolean): void;\n isHighlightVisible(): boolean;\n}\n\nexport const SelectionToken = createHostToken<SelectionHostCapability>(PublicSelectionToken);\n"],"mappings":";;;;;;;;;;;AAyCA,MAAa,kBAAA,2BAAA,CAAA,CAAA,gBAAA,CAA0DA,iBAAAA,cAAoB"}
@@ -1,2 +1,3 @@
1
- import { a as SelectionHostCapability, d as SelectionToken, n as SelectionAction, s as SelectionRange, t as GlyphPointer, u as SelectionState } from "../types-CUrUVl6K.cjs";
2
- export { type GlyphPointer, type SelectionAction, type SelectionHostCapability, type SelectionRange, type SelectionState, SelectionToken };
1
+ import { a as SelectionClearedEvent, c as SelectionEndpoint, d as SelectionSnapshot, f as TextPosition, h as SelectionSegment, i as SelectionChangedEvent, l as SelectionRangeInput, n as SelectionAnchor, o as SelectionCommittedEvent, p as TextRange, r as SelectionCapability, s as SelectionConfig, t as SELECTION_DEFAULTS, u as SelectionSettings } from "../contract-DLs4vXVt.cjs";
2
+ import { n as SelectionToken, t as SelectionHostCapability } from "../host-contract-Ddo4PcJJ.cjs";
3
+ export { SELECTION_DEFAULTS, SelectionAnchor, SelectionCapability, SelectionChangedEvent, SelectionClearedEvent, SelectionCommittedEvent, SelectionConfig, SelectionEndpoint, SelectionHostCapability, SelectionRangeInput, type SelectionSegment, SelectionSettings, SelectionSnapshot, SelectionToken, TextPosition, TextRange };
@@ -1,2 +1,3 @@
1
- import { a as SelectionHostCapability, d as SelectionToken, n as SelectionAction, s as SelectionRange, t as GlyphPointer, u as SelectionState } from "../types-CUrUVl6K.js";
2
- export { type GlyphPointer, type SelectionAction, type SelectionHostCapability, type SelectionRange, type SelectionState, SelectionToken };
1
+ import { a as SelectionClearedEvent, c as SelectionEndpoint, d as SelectionSnapshot, f as TextPosition, h as SelectionSegment, i as SelectionChangedEvent, l as SelectionRangeInput, n as SelectionAnchor, o as SelectionCommittedEvent, p as TextRange, r as SelectionCapability, s as SelectionConfig, t as SELECTION_DEFAULTS, u as SelectionSettings } from "../contract-DLs4vXVt.js";
2
+ import { n as SelectionToken, t as SelectionHostCapability } from "../host-contract-DO2aLU2e.js";
3
+ export { SELECTION_DEFAULTS, SelectionAnchor, SelectionCapability, SelectionChangedEvent, SelectionClearedEvent, SelectionCommittedEvent, SelectionConfig, SelectionEndpoint, SelectionHostCapability, SelectionRangeInput, type SelectionSegment, SelectionSettings, SelectionSnapshot, SelectionToken, TextPosition, TextRange };
@@ -1,2 +1,16 @@
1
- import { t as SelectionToken } from "../types-BVUcOsCh.js";
2
- export { SelectionToken };
1
+ import { n as SelectionToken$1, t as SELECTION_DEFAULTS } from "../contract-DBXA64ep.js";
2
+ import { createHostToken } from "@embedpdf/core";
3
+ //#region src/host-contract.ts
4
+ /**
5
+ * @embedpdf/plugin-selection/contract/host — the host lens.
6
+ *
7
+ * What render layers, the interaction hub and sibling plugins need on top
8
+ * of the public contract: gesture bracketing, geometry warming and the
9
+ * highlight-visibility handshake. Same runtime token as the public one,
10
+ * typed wider. Never use this from application code.
11
+ */
12
+ const SelectionToken = createHostToken(SelectionToken$1);
13
+ //#endregion
14
+ export { SELECTION_DEFAULTS, SelectionToken };
15
+
16
+ //# sourceMappingURL=host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.js","names":["PublicSelectionToken"],"sources":["../../src/host-contract.ts"],"sourcesContent":["/**\n * @embedpdf/plugin-selection/contract/host — the host lens.\n *\n * What render layers, the interaction hub and sibling plugins need on top\n * of the public contract: gesture bracketing, geometry warming and the\n * highlight-visibility handshake. Same runtime token as the public one,\n * typed wider. Never use this from application code.\n */\nimport { createHostToken, type PageRef } from '@embedpdf/core';\nimport type { Point } from '@embedpdf/core-geometry';\nimport { SelectionToken as PublicSelectionToken, type SelectionCapability } from './contract';\n\nexport * from './contract';\n\nexport interface SelectionHostCapability extends SelectionCapability {\n /** Warm a page's text geometry. Resolves once loaded; resolves immediately\n * (nothing requested) without `doc.text.select` or for an unknown page. A\n * failed read resolves too — the layer simply has nothing to paint. */\n ensureLoaded(page: PageRef): Promise<void>;\n /** Whether the page's text geometry is loaded and current. */\n isLoaded(page: PageRef): boolean;\n /** Is a page-space point on (or near) text? Drives the I-beam cursor. */\n isOverText(page: PageRef, point: Point): boolean;\n /**\n * A pointer gesture that drives the selection opened (pointer-down). From\n * here until {@link endGesture}, `isSelecting()` is true and\n * selection-scoped UI hides. Programmatic writes never open a gesture.\n */\n beginGesture(): void;\n /** Open a caret selection at a page point (the first drag step). Returns\n * false when the point has no text — the caller lets the gesture go. */\n beginGestureAt(page: PageRef, point: Point): boolean;\n /** The gesture ended (pointer-up). Settles first, then emits `onCommitted`\n * when a selection is in place. */\n endGesture(): void;\n /** Suppress / restore the default highlight visual (a consumer drawing its\n * own preview — the markup ghost). */\n setHighlightVisible(visible: boolean): void;\n isHighlightVisible(): boolean;\n}\n\nexport const SelectionToken = createHostToken<SelectionHostCapability>(PublicSelectionToken);\n"],"mappings":";;;;;;;;;;;AAyCA,MAAa,iBAAiB,gBAAyCA,gBAAoB"}
@@ -0,0 +1,36 @@
1
+ //#region src/token.ts
2
+ /** The package token — created once here; `contract.ts` re-exports it and
3
+ * `host-contract.ts` widens it. */
4
+ const SelectionToken = (0, require("@embedpdf/core").createCapabilityToken)("selection", {
5
+ hint: `add selectionPlugin() from '@embedpdf/plugin-selection' to your plugins list`,
6
+ promises: {
7
+ readText: true,
8
+ readTextInRange: true
9
+ }
10
+ });
11
+ //#endregion
12
+ //#region src/contract.ts
13
+ /** What the selection settings are when the app registers none. */
14
+ const SELECTION_DEFAULTS = {
15
+ dragThreshold: 4,
16
+ color: null,
17
+ handles: {
18
+ color: null,
19
+ shadow: "0 1px 4px rgb(0 0 0 / 0.35)"
20
+ }
21
+ };
22
+ //#endregion
23
+ Object.defineProperty(exports, "SELECTION_DEFAULTS", {
24
+ enumerable: true,
25
+ get: function() {
26
+ return SELECTION_DEFAULTS;
27
+ }
28
+ });
29
+ Object.defineProperty(exports, "SelectionToken", {
30
+ enumerable: true,
31
+ get: function() {
32
+ return SelectionToken;
33
+ }
34
+ });
35
+
36
+ //# sourceMappingURL=contract-BUiw1d8F.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-BUiw1d8F.cjs","names":[],"sources":["../src/token.ts","../src/contract.ts"],"sourcesContent":["/** The package token — created once here; `contract.ts` re-exports it and\n * `host-contract.ts` widens it. */\nimport { createCapabilityToken } from '@embedpdf/core';\n\nimport type { SelectionCapability } from './contract';\n\nexport const SelectionToken = createCapabilityToken<SelectionCapability>('selection', {\n hint: `add selectionPlugin() from '@embedpdf/plugin-selection' to your plugins list`,\n // Without a document, an adapter's stand-in rejects these with `not-ready`, as the\n // capability would; the type asks for every member that returns a promise.\n promises: {\n readText: true,\n readTextInRange: true,\n },\n});\n","/**\n * @embedpdf/plugin-selection/contract — the public selection vocabulary.\n *\n * Selection ranges live in character space (half-open `TextRange`, the same\n * space search hits address). Geometry needs `doc.text.select`, text\n * extraction needs `doc.text.copy`, and neither permission implies the other.\n * Segments, endpoints and anchors are in page space (page space: y-down,\n * PDF units, crop-relative), the space every layer paints in.\n */\nimport type {\n DeepPartial,\n EventHook,\n OperationOptions,\n PageRef,\n SettingsApi,\n} from '@embedpdf/core';\nimport type { Point, Rect, Quad } from '@embedpdf/core-geometry';\nimport type { SelectionSegment } from './geometry';\n\nexport type { SelectionSegment } from './geometry';\n\n// ── settings ────────────────────────────────────────────────────────────────\n\n/**\n * The selection plugin's settings. `selectionPlugin(config)` registers them\n * over {@link SELECTION_DEFAULTS}, and `updateSettings()` changes them for\n * every document while the app runs. The colors and the shadow can also come\n * from CSS (`--epdf-text-selection`, `--epdf-text-selection-handle`,\n * `--epdf-text-selection-handle-shadow`), which wins over the setting.\n */\nexport interface SelectionSettings {\n /** How far, in viewport pixels, the pointer travels before a press becomes a drag that selects. */\n readonly dragThreshold: number;\n /** The color of selected text: a CSS color, or `null` for the viewer's accent at 35%. */\n readonly color: string | null;\n /** The grips at the selection's ends, on touch screens. */\n readonly handles: {\n /** A CSS color, or `null` for the viewer's accent. */\n readonly color: string | null;\n /** A CSS `box-shadow`. */\n readonly shadow: string;\n };\n}\n\n/** What the selection settings are when the app registers none. */\nexport const SELECTION_DEFAULTS: SelectionSettings = {\n dragThreshold: 4,\n color: null,\n handles: { color: null, shadow: '0 1px 4px rgb(0 0 0 / 0.35)' },\n};\n\n/** What `selectionPlugin(config)` takes: any of the settings, merged over the defaults. */\nexport type SelectionConfig = DeepPartial<SelectionSettings>;\n\n// ── the range vocabulary ────────────────────────────────────────────────────\n\n/**\n * A position in a page's character space — the space the engine's geometry\n * runs tile (`PageGeometryRun.charStart`) and search hits address\n * (`SearchMatch.charStart`). Not a string offset into extracted text; the\n * two spaces are joined by the engine's `charMap` (see engine-core\n * `text/charmap.ts`), which `readText()` applies for you.\n */\nexport interface TextPosition {\n page: PageRef;\n /** Character index, 0-based. */\n index: number;\n}\n\n/**\n * A half-open range in character space: `start` inclusive, `end` exclusive,\n * in document order (`start` at or before `end`). `end.index` may be 0 to\n * end a range exactly at a page boundary.\n */\nexport interface TextRange {\n start: TextPosition;\n end: TextPosition;\n}\n\n/**\n * What {@link SelectionCapability.select} accepts: a cross-page\n * {@link TextRange}, or a single-page span — the shape of a search hit, so\n * `select({ page: hit.page, start: hit.charStart, count: hit.charCount })`\n * needs no conversion.\n */\nexport type SelectionRangeInput = TextRange | { page: PageRef; start: number; count: number };\n\n// ── the read model ──────────────────────────────────────────────────────────\n\n/**\n * A selection boundary, anchored to the boundary glyph's own oriented cell.\n * `advance` is the reading direction of the segment it belongs to (+1 = the\n * frame's +x), so caret consumers place at the trailing edge without\n * re-deriving bidi from geometry. `rect` is the AABB (scroll targets).\n */\nexport interface SelectionEndpoint {\n page: PageRef;\n glyphQuad: Quad;\n advance: 1 | -1;\n rect: Rect;\n}\n\n/** Where selection-scoped floating UI attaches: a page + the selection's\n * union box on it, in page space. See {@link SelectionCapability.getAnchor}. */\nexport interface SelectionAnchor {\n page: PageRef;\n bounds: Rect;\n}\n\nexport interface SelectionSnapshot {\n /** Per-page canonical segments — the one geometry consumers act on.\n * Boxes are derived views (`segment.rect`, or `listRects()`). */\n readonly pages: readonly { page: PageRef; segments: readonly SelectionSegment[] }[];\n readonly start: SelectionEndpoint | null;\n readonly end: SelectionEndpoint | null;\n readonly direction: 'forward' | 'backward';\n /**\n * The selection as a half-open character range in document order — a\n * valid {@link SelectionCapability.select} input (persist and restore).\n * Null when nothing is selected. Until a boundary page's text geometry\n * has loaded, its index may still exceed the page's character count\n * (`selectAll` settles as geometry arrives); consumers of the range\n * (`select`, `readTextInRange`) clamp, so round-tripping is always safe.\n */\n readonly range: TextRange | null;\n}\n\n// ── events ──────────────────────────────────────────────────────────────────\n\n/**\n * The selection's range or segments changed: a gesture step, a programmatic\n * select, a boundary page's text geometry arriving, or a clear. Selection is\n * session state, so the event carries no document origin.\n */\nexport interface SelectionChangedEvent {\n readonly range: TextRange | null;\n /** The pages that carry a segment right now. */\n readonly pages: readonly PageRef[];\n}\n\n/** A selection gesture ended (pointer-up, handle release) with a selection in\n * place — the commit point markup creation and clipboard prefetch act on.\n * Never fires for programmatic selection. */\nexport interface SelectionCommittedEvent {\n readonly range: TextRange;\n}\n\n/** The selection went from a range to nothing. */\nexport type SelectionClearedEvent = Record<string, never>;\n\n// ── the public capability ───────────────────────────────────────────────────\n\n/**\n * The public selection API — the documented, stable surface for application\n * code (toolbars, context menus, automation).\n *\n * The permission model: geometry enables selection (`doc.text.select`),\n * text enables extraction (`doc.text.copy`) — neither implies the other.\n * Everything here except the `readText` pair works with the select scope\n * alone, so a deployment can allow selecting and highlighting while denying\n * copy. Writes without the scope throw `PluginError('permission-denied')`;\n * gate UI with {@link canSelect} / {@link canCopy}.\n *\n * Every gesture has a programmatic twin: drag = {@link select} (or\n * `beginGestureAt` + {@link extendTo} for point-driven code on the host\n * lens), double-click = {@link selectWordAt}, triple-click =\n * {@link selectLineAt}, handle drag = {@link extendTo}, click on empty space\n * = {@link clear}, select-all = {@link selectAll}.\n *\n * A page argument is a `PageRef` or a zero-based index. A verb given a page\n * that isn't in the document throws `not-found`; a read returns empty.\n *\n * The settings (`getSettings`, `updateSettings`, `resetSettings`,\n * `onSettingsChanged`) belong to the plugin, not to a document: a change\n * reaches every open document.\n *\n * Framework-only plumbing (gesture bracketing, geometry warming, the\n * highlight-visibility handshake) lives on `SelectionHostCapability`,\n * reachable through `@embedpdf/plugin-selection/contract/host`. Both are the\n * same runtime object — two typed lenses on one token.\n */\nexport interface SelectionCapability extends SettingsApi<SelectionSettings> {\n // ── authorization (mirrors the engine's own enforcement) ──\n /** Whether this caller may create selections at all (`doc.text.select`). */\n canSelect(): boolean;\n /** Whether this caller may extract literal text (`doc.text.copy`). */\n canCopy(): boolean;\n\n // ── writes (character space, half-open) ──\n /**\n * Select a range — the same path gestures use, so the highlight, events\n * and markup bridges behave identically. An empty range clears. Throws\n * `permission-denied` without `doc.text.select`, `not-found` for a page\n * that is not in this document. Fires `onChanged`, or `onCleared`.\n */\n select(range: SelectionRangeInput): void;\n /** Select every character of the document. Throws `permission-denied` without `doc.text.select`. */\n selectAll(): void;\n /**\n * Select every character on one page. Throws `permission-denied` without\n * `doc.text.select`, `not-found` for a page that is not in this document.\n */\n selectPage(page: PageRef | number): void;\n /**\n * Select the word around a page point. Returns false when the point has no\n * selectable text (geometry not loaded yet, or no glyph there). Throws\n * `permission-denied` without `doc.text.select`, `not-found` for a page that\n * is not in this document.\n */\n selectWordAt(page: PageRef | number, point: Point): boolean;\n /** Select the visual line around a page point. Same result and errors as {@link selectWordAt}. */\n selectLineAt(page: PageRef | number, point: Point): boolean;\n /**\n * Extend the current selection to a page point (a drag step). No selection\n * → no-op; a page whose geometry has not loaded is warmed and the extension\n * lands when it arrives. Errors as {@link selectPage}.\n */\n extendTo(page: PageRef | number, point: Point): void;\n /** Clear the selection. Always allowed. Fires `onCleared` when something was selected. */\n clear(): void;\n\n // ── reads ──\n /** Whether anything is selected. */\n hasSelection(): boolean;\n /**\n * Whether the user is still selecting: from the press of a drag, a\n * double-click or a handle until it lifts. A selection made from code is\n * never in progress.\n */\n isSelecting(): boolean;\n /** Per-page segments, endpoints, direction and the range. Reference-stable\n * until the selection changes. */\n getSnapshot(): SelectionSnapshot;\n /** The selected character range, or null. */\n getRange(): TextRange | null;\n /** The pages the current selection covers (those with at least one\n * segment), in document order — so a cross-page action can fan out per page. */\n listSelectedPages(): readonly PageRef[];\n /** Per-line oriented segments for a page, in page space — build your own\n * highlight layer from these. Reference-stable per page. */\n listSegments(page: PageRef | number): readonly SelectionSegment[];\n /** The segments' AABBs — for consumers that genuinely want boxes (scroll,\n * conservative regions). Never a substitute for the oriented quads in\n * geometry that gets drawn or persisted. */\n listRects(page: PageRef | number): readonly Rect[];\n /**\n * Where selection-scoped floating UI should attach: the union box of the\n * selection's segments on its end page (where the gesture finished),\n * falling back to the last page with materialized segments while a\n * boundary page's geometry is still loading. One anchor regardless of\n * cross-page selection. Null when nothing is selected (or nothing has\n * materialized yet).\n */\n getAnchor(): SelectionAnchor | null;\n\n // ── text extraction (requires doc.text.copy) ──\n /**\n * The selected text. Each page's text snapshot is fetched once per content\n * version and sliced through the engine's `charMap`; pages are joined with\n * `\\n`. Resolves `''` when nothing is selected. Rejects `permission-denied`\n * without `doc.text.copy`, and `operation-cancelled` when `options.signal`\n * fires. Clipboard writes are deliberately not here — this package is\n * DOM-free; use `@embedpdf/web`'s clipboard helpers.\n */\n readText(options?: OperationOptions): Promise<string>;\n /**\n * Text for any range, without touching the selection. Rejects as\n * {@link readText} does, and `not-found` for a page that is not in this\n * document.\n */\n readTextInRange(range: TextRange, options?: OperationOptions): Promise<string>;\n\n // ── events ──\n /** The range or its segments changed, whoever changed them. */\n readonly onChanged: EventHook<SelectionChangedEvent>;\n /** A selection gesture ended with a selection in place. */\n readonly onCommitted: EventHook<SelectionCommittedEvent>;\n /** The selection went from a range to nothing: a clear, an empty range, or\n * its pages' content changed or left the document. */\n readonly onCleared: EventHook<SelectionClearedEvent>;\n}\n\nexport { SelectionToken } from './token';\n"],"mappings":";;;AAMA,MAAa,kBAAA,2BAAA,CAAA,CAAA,sBAAA,CAA4D,aAAa;CACpF,MAAM;CAGN,UAAU;EACR,UAAU;EACV,iBAAiB;CACnB;AACF,CAAC;;;;AC+BD,MAAa,qBAAwC;CACnD,eAAe;CACf,OAAO;CACP,SAAS;EAAE,OAAO;EAAM,QAAQ;CAA8B;AAChE"}
@@ -0,0 +1,26 @@
1
+ import { createCapabilityToken } from "@embedpdf/core";
2
+ //#region src/token.ts
3
+ /** The package token — created once here; `contract.ts` re-exports it and
4
+ * `host-contract.ts` widens it. */
5
+ const SelectionToken = createCapabilityToken("selection", {
6
+ hint: `add selectionPlugin() from '@embedpdf/plugin-selection' to your plugins list`,
7
+ promises: {
8
+ readText: true,
9
+ readTextInRange: true
10
+ }
11
+ });
12
+ //#endregion
13
+ //#region src/contract.ts
14
+ /** What the selection settings are when the app registers none. */
15
+ const SELECTION_DEFAULTS = {
16
+ dragThreshold: 4,
17
+ color: null,
18
+ handles: {
19
+ color: null,
20
+ shadow: "0 1px 4px rgb(0 0 0 / 0.35)"
21
+ }
22
+ };
23
+ //#endregion
24
+ export { SelectionToken as n, SELECTION_DEFAULTS as t };
25
+
26
+ //# sourceMappingURL=contract-DBXA64ep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-DBXA64ep.js","names":[],"sources":["../src/token.ts","../src/contract.ts"],"sourcesContent":["/** The package token — created once here; `contract.ts` re-exports it and\n * `host-contract.ts` widens it. */\nimport { createCapabilityToken } from '@embedpdf/core';\n\nimport type { SelectionCapability } from './contract';\n\nexport const SelectionToken = createCapabilityToken<SelectionCapability>('selection', {\n hint: `add selectionPlugin() from '@embedpdf/plugin-selection' to your plugins list`,\n // Without a document, an adapter's stand-in rejects these with `not-ready`, as the\n // capability would; the type asks for every member that returns a promise.\n promises: {\n readText: true,\n readTextInRange: true,\n },\n});\n","/**\n * @embedpdf/plugin-selection/contract — the public selection vocabulary.\n *\n * Selection ranges live in character space (half-open `TextRange`, the same\n * space search hits address). Geometry needs `doc.text.select`, text\n * extraction needs `doc.text.copy`, and neither permission implies the other.\n * Segments, endpoints and anchors are in page space (page space: y-down,\n * PDF units, crop-relative), the space every layer paints in.\n */\nimport type {\n DeepPartial,\n EventHook,\n OperationOptions,\n PageRef,\n SettingsApi,\n} from '@embedpdf/core';\nimport type { Point, Rect, Quad } from '@embedpdf/core-geometry';\nimport type { SelectionSegment } from './geometry';\n\nexport type { SelectionSegment } from './geometry';\n\n// ── settings ────────────────────────────────────────────────────────────────\n\n/**\n * The selection plugin's settings. `selectionPlugin(config)` registers them\n * over {@link SELECTION_DEFAULTS}, and `updateSettings()` changes them for\n * every document while the app runs. The colors and the shadow can also come\n * from CSS (`--epdf-text-selection`, `--epdf-text-selection-handle`,\n * `--epdf-text-selection-handle-shadow`), which wins over the setting.\n */\nexport interface SelectionSettings {\n /** How far, in viewport pixels, the pointer travels before a press becomes a drag that selects. */\n readonly dragThreshold: number;\n /** The color of selected text: a CSS color, or `null` for the viewer's accent at 35%. */\n readonly color: string | null;\n /** The grips at the selection's ends, on touch screens. */\n readonly handles: {\n /** A CSS color, or `null` for the viewer's accent. */\n readonly color: string | null;\n /** A CSS `box-shadow`. */\n readonly shadow: string;\n };\n}\n\n/** What the selection settings are when the app registers none. */\nexport const SELECTION_DEFAULTS: SelectionSettings = {\n dragThreshold: 4,\n color: null,\n handles: { color: null, shadow: '0 1px 4px rgb(0 0 0 / 0.35)' },\n};\n\n/** What `selectionPlugin(config)` takes: any of the settings, merged over the defaults. */\nexport type SelectionConfig = DeepPartial<SelectionSettings>;\n\n// ── the range vocabulary ────────────────────────────────────────────────────\n\n/**\n * A position in a page's character space — the space the engine's geometry\n * runs tile (`PageGeometryRun.charStart`) and search hits address\n * (`SearchMatch.charStart`). Not a string offset into extracted text; the\n * two spaces are joined by the engine's `charMap` (see engine-core\n * `text/charmap.ts`), which `readText()` applies for you.\n */\nexport interface TextPosition {\n page: PageRef;\n /** Character index, 0-based. */\n index: number;\n}\n\n/**\n * A half-open range in character space: `start` inclusive, `end` exclusive,\n * in document order (`start` at or before `end`). `end.index` may be 0 to\n * end a range exactly at a page boundary.\n */\nexport interface TextRange {\n start: TextPosition;\n end: TextPosition;\n}\n\n/**\n * What {@link SelectionCapability.select} accepts: a cross-page\n * {@link TextRange}, or a single-page span — the shape of a search hit, so\n * `select({ page: hit.page, start: hit.charStart, count: hit.charCount })`\n * needs no conversion.\n */\nexport type SelectionRangeInput = TextRange | { page: PageRef; start: number; count: number };\n\n// ── the read model ──────────────────────────────────────────────────────────\n\n/**\n * A selection boundary, anchored to the boundary glyph's own oriented cell.\n * `advance` is the reading direction of the segment it belongs to (+1 = the\n * frame's +x), so caret consumers place at the trailing edge without\n * re-deriving bidi from geometry. `rect` is the AABB (scroll targets).\n */\nexport interface SelectionEndpoint {\n page: PageRef;\n glyphQuad: Quad;\n advance: 1 | -1;\n rect: Rect;\n}\n\n/** Where selection-scoped floating UI attaches: a page + the selection's\n * union box on it, in page space. See {@link SelectionCapability.getAnchor}. */\nexport interface SelectionAnchor {\n page: PageRef;\n bounds: Rect;\n}\n\nexport interface SelectionSnapshot {\n /** Per-page canonical segments — the one geometry consumers act on.\n * Boxes are derived views (`segment.rect`, or `listRects()`). */\n readonly pages: readonly { page: PageRef; segments: readonly SelectionSegment[] }[];\n readonly start: SelectionEndpoint | null;\n readonly end: SelectionEndpoint | null;\n readonly direction: 'forward' | 'backward';\n /**\n * The selection as a half-open character range in document order — a\n * valid {@link SelectionCapability.select} input (persist and restore).\n * Null when nothing is selected. Until a boundary page's text geometry\n * has loaded, its index may still exceed the page's character count\n * (`selectAll` settles as geometry arrives); consumers of the range\n * (`select`, `readTextInRange`) clamp, so round-tripping is always safe.\n */\n readonly range: TextRange | null;\n}\n\n// ── events ──────────────────────────────────────────────────────────────────\n\n/**\n * The selection's range or segments changed: a gesture step, a programmatic\n * select, a boundary page's text geometry arriving, or a clear. Selection is\n * session state, so the event carries no document origin.\n */\nexport interface SelectionChangedEvent {\n readonly range: TextRange | null;\n /** The pages that carry a segment right now. */\n readonly pages: readonly PageRef[];\n}\n\n/** A selection gesture ended (pointer-up, handle release) with a selection in\n * place — the commit point markup creation and clipboard prefetch act on.\n * Never fires for programmatic selection. */\nexport interface SelectionCommittedEvent {\n readonly range: TextRange;\n}\n\n/** The selection went from a range to nothing. */\nexport type SelectionClearedEvent = Record<string, never>;\n\n// ── the public capability ───────────────────────────────────────────────────\n\n/**\n * The public selection API — the documented, stable surface for application\n * code (toolbars, context menus, automation).\n *\n * The permission model: geometry enables selection (`doc.text.select`),\n * text enables extraction (`doc.text.copy`) — neither implies the other.\n * Everything here except the `readText` pair works with the select scope\n * alone, so a deployment can allow selecting and highlighting while denying\n * copy. Writes without the scope throw `PluginError('permission-denied')`;\n * gate UI with {@link canSelect} / {@link canCopy}.\n *\n * Every gesture has a programmatic twin: drag = {@link select} (or\n * `beginGestureAt` + {@link extendTo} for point-driven code on the host\n * lens), double-click = {@link selectWordAt}, triple-click =\n * {@link selectLineAt}, handle drag = {@link extendTo}, click on empty space\n * = {@link clear}, select-all = {@link selectAll}.\n *\n * A page argument is a `PageRef` or a zero-based index. A verb given a page\n * that isn't in the document throws `not-found`; a read returns empty.\n *\n * The settings (`getSettings`, `updateSettings`, `resetSettings`,\n * `onSettingsChanged`) belong to the plugin, not to a document: a change\n * reaches every open document.\n *\n * Framework-only plumbing (gesture bracketing, geometry warming, the\n * highlight-visibility handshake) lives on `SelectionHostCapability`,\n * reachable through `@embedpdf/plugin-selection/contract/host`. Both are the\n * same runtime object — two typed lenses on one token.\n */\nexport interface SelectionCapability extends SettingsApi<SelectionSettings> {\n // ── authorization (mirrors the engine's own enforcement) ──\n /** Whether this caller may create selections at all (`doc.text.select`). */\n canSelect(): boolean;\n /** Whether this caller may extract literal text (`doc.text.copy`). */\n canCopy(): boolean;\n\n // ── writes (character space, half-open) ──\n /**\n * Select a range — the same path gestures use, so the highlight, events\n * and markup bridges behave identically. An empty range clears. Throws\n * `permission-denied` without `doc.text.select`, `not-found` for a page\n * that is not in this document. Fires `onChanged`, or `onCleared`.\n */\n select(range: SelectionRangeInput): void;\n /** Select every character of the document. Throws `permission-denied` without `doc.text.select`. */\n selectAll(): void;\n /**\n * Select every character on one page. Throws `permission-denied` without\n * `doc.text.select`, `not-found` for a page that is not in this document.\n */\n selectPage(page: PageRef | number): void;\n /**\n * Select the word around a page point. Returns false when the point has no\n * selectable text (geometry not loaded yet, or no glyph there). Throws\n * `permission-denied` without `doc.text.select`, `not-found` for a page that\n * is not in this document.\n */\n selectWordAt(page: PageRef | number, point: Point): boolean;\n /** Select the visual line around a page point. Same result and errors as {@link selectWordAt}. */\n selectLineAt(page: PageRef | number, point: Point): boolean;\n /**\n * Extend the current selection to a page point (a drag step). No selection\n * → no-op; a page whose geometry has not loaded is warmed and the extension\n * lands when it arrives. Errors as {@link selectPage}.\n */\n extendTo(page: PageRef | number, point: Point): void;\n /** Clear the selection. Always allowed. Fires `onCleared` when something was selected. */\n clear(): void;\n\n // ── reads ──\n /** Whether anything is selected. */\n hasSelection(): boolean;\n /**\n * Whether the user is still selecting: from the press of a drag, a\n * double-click or a handle until it lifts. A selection made from code is\n * never in progress.\n */\n isSelecting(): boolean;\n /** Per-page segments, endpoints, direction and the range. Reference-stable\n * until the selection changes. */\n getSnapshot(): SelectionSnapshot;\n /** The selected character range, or null. */\n getRange(): TextRange | null;\n /** The pages the current selection covers (those with at least one\n * segment), in document order — so a cross-page action can fan out per page. */\n listSelectedPages(): readonly PageRef[];\n /** Per-line oriented segments for a page, in page space — build your own\n * highlight layer from these. Reference-stable per page. */\n listSegments(page: PageRef | number): readonly SelectionSegment[];\n /** The segments' AABBs — for consumers that genuinely want boxes (scroll,\n * conservative regions). Never a substitute for the oriented quads in\n * geometry that gets drawn or persisted. */\n listRects(page: PageRef | number): readonly Rect[];\n /**\n * Where selection-scoped floating UI should attach: the union box of the\n * selection's segments on its end page (where the gesture finished),\n * falling back to the last page with materialized segments while a\n * boundary page's geometry is still loading. One anchor regardless of\n * cross-page selection. Null when nothing is selected (or nothing has\n * materialized yet).\n */\n getAnchor(): SelectionAnchor | null;\n\n // ── text extraction (requires doc.text.copy) ──\n /**\n * The selected text. Each page's text snapshot is fetched once per content\n * version and sliced through the engine's `charMap`; pages are joined with\n * `\\n`. Resolves `''` when nothing is selected. Rejects `permission-denied`\n * without `doc.text.copy`, and `operation-cancelled` when `options.signal`\n * fires. Clipboard writes are deliberately not here — this package is\n * DOM-free; use `@embedpdf/web`'s clipboard helpers.\n */\n readText(options?: OperationOptions): Promise<string>;\n /**\n * Text for any range, without touching the selection. Rejects as\n * {@link readText} does, and `not-found` for a page that is not in this\n * document.\n */\n readTextInRange(range: TextRange, options?: OperationOptions): Promise<string>;\n\n // ── events ──\n /** The range or its segments changed, whoever changed them. */\n readonly onChanged: EventHook<SelectionChangedEvent>;\n /** A selection gesture ended with a selection in place. */\n readonly onCommitted: EventHook<SelectionCommittedEvent>;\n /** The selection went from a range to nothing: a clear, an empty range, or\n * its pages' content changed or left the document. */\n readonly onCleared: EventHook<SelectionClearedEvent>;\n}\n\nexport { SelectionToken } from './token';\n"],"mappings":";;;;AAMA,MAAa,iBAAiB,sBAA2C,aAAa;CACpF,MAAM;CAGN,UAAU;EACR,UAAU;EACV,iBAAiB;CACnB;AACF,CAAC;;;;AC+BD,MAAa,qBAAwC;CACnD,eAAe;CACf,OAAO;CACP,SAAS;EAAE,OAAO;EAAM,QAAQ;CAA8B;AAChE"}
@@ -0,0 +1,252 @@
1
+ import { DeepPartial, EventHook, OperationOptions, PageRef, SettingsApi } from "@embedpdf/core";
2
+ import { Point, Quad, Rect } from "@embedpdf/core-geometry";
3
+ import { PdfTextSegment } from "@embedpdf/engine-core/runtime";
4
+ //#region src/geometry.d.ts
5
+ /**
6
+ * One merged visual line of a selection, as the engine's layout gives it.
7
+ * `quad` carries the corners, named in the line's own frame; `advance` is the
8
+ * reading direction along the baseline (+1 = toward the right end), derived
9
+ * from the glyph sequence, so geometry and bidi stay separate concerns.
10
+ * `rect` is its bounding box.
11
+ */
12
+ type SelectionSegment = PdfTextSegment;
13
+ //#endregion
14
+ //#region src/token.d.ts
15
+ declare const SelectionToken: import("@embedpdf/core").CapabilityToken<SelectionCapability>;
16
+ //#endregion
17
+ //#region src/contract.d.ts
18
+ /**
19
+ * The selection plugin's settings. `selectionPlugin(config)` registers them
20
+ * over {@link SELECTION_DEFAULTS}, and `updateSettings()` changes them for
21
+ * every document while the app runs. The colors and the shadow can also come
22
+ * from CSS (`--epdf-text-selection`, `--epdf-text-selection-handle`,
23
+ * `--epdf-text-selection-handle-shadow`), which wins over the setting.
24
+ */
25
+ interface SelectionSettings {
26
+ /** How far, in viewport pixels, the pointer travels before a press becomes a drag that selects. */
27
+ readonly dragThreshold: number;
28
+ /** The color of selected text: a CSS color, or `null` for the viewer's accent at 35%. */
29
+ readonly color: string | null;
30
+ /** The grips at the selection's ends, on touch screens. */
31
+ readonly handles: {
32
+ /** A CSS color, or `null` for the viewer's accent. */
33
+ readonly color: string | null;
34
+ /** A CSS `box-shadow`. */
35
+ readonly shadow: string;
36
+ };
37
+ }
38
+ /** What the selection settings are when the app registers none. */
39
+ declare const SELECTION_DEFAULTS: SelectionSettings;
40
+ /** What `selectionPlugin(config)` takes: any of the settings, merged over the defaults. */
41
+ type SelectionConfig = DeepPartial<SelectionSettings>;
42
+ /**
43
+ * A position in a page's character space — the space the engine's geometry
44
+ * runs tile (`PageGeometryRun.charStart`) and search hits address
45
+ * (`SearchMatch.charStart`). Not a string offset into extracted text; the
46
+ * two spaces are joined by the engine's `charMap` (see engine-core
47
+ * `text/charmap.ts`), which `readText()` applies for you.
48
+ */
49
+ interface TextPosition {
50
+ page: PageRef;
51
+ /** Character index, 0-based. */
52
+ index: number;
53
+ }
54
+ /**
55
+ * A half-open range in character space: `start` inclusive, `end` exclusive,
56
+ * in document order (`start` at or before `end`). `end.index` may be 0 to
57
+ * end a range exactly at a page boundary.
58
+ */
59
+ interface TextRange {
60
+ start: TextPosition;
61
+ end: TextPosition;
62
+ }
63
+ /**
64
+ * What {@link SelectionCapability.select} accepts: a cross-page
65
+ * {@link TextRange}, or a single-page span — the shape of a search hit, so
66
+ * `select({ page: hit.page, start: hit.charStart, count: hit.charCount })`
67
+ * needs no conversion.
68
+ */
69
+ type SelectionRangeInput = TextRange | {
70
+ page: PageRef;
71
+ start: number;
72
+ count: number;
73
+ };
74
+ /**
75
+ * A selection boundary, anchored to the boundary glyph's own oriented cell.
76
+ * `advance` is the reading direction of the segment it belongs to (+1 = the
77
+ * frame's +x), so caret consumers place at the trailing edge without
78
+ * re-deriving bidi from geometry. `rect` is the AABB (scroll targets).
79
+ */
80
+ interface SelectionEndpoint {
81
+ page: PageRef;
82
+ glyphQuad: Quad;
83
+ advance: 1 | -1;
84
+ rect: Rect;
85
+ }
86
+ /** Where selection-scoped floating UI attaches: a page + the selection's
87
+ * union box on it, in page space. See {@link SelectionCapability.getAnchor}. */
88
+ interface SelectionAnchor {
89
+ page: PageRef;
90
+ bounds: Rect;
91
+ }
92
+ interface SelectionSnapshot {
93
+ /** Per-page canonical segments — the one geometry consumers act on.
94
+ * Boxes are derived views (`segment.rect`, or `listRects()`). */
95
+ readonly pages: readonly {
96
+ page: PageRef;
97
+ segments: readonly SelectionSegment[];
98
+ }[];
99
+ readonly start: SelectionEndpoint | null;
100
+ readonly end: SelectionEndpoint | null;
101
+ readonly direction: 'forward' | 'backward';
102
+ /**
103
+ * The selection as a half-open character range in document order — a
104
+ * valid {@link SelectionCapability.select} input (persist and restore).
105
+ * Null when nothing is selected. Until a boundary page's text geometry
106
+ * has loaded, its index may still exceed the page's character count
107
+ * (`selectAll` settles as geometry arrives); consumers of the range
108
+ * (`select`, `readTextInRange`) clamp, so round-tripping is always safe.
109
+ */
110
+ readonly range: TextRange | null;
111
+ }
112
+ /**
113
+ * The selection's range or segments changed: a gesture step, a programmatic
114
+ * select, a boundary page's text geometry arriving, or a clear. Selection is
115
+ * session state, so the event carries no document origin.
116
+ */
117
+ interface SelectionChangedEvent {
118
+ readonly range: TextRange | null;
119
+ /** The pages that carry a segment right now. */
120
+ readonly pages: readonly PageRef[];
121
+ }
122
+ /** A selection gesture ended (pointer-up, handle release) with a selection in
123
+ * place — the commit point markup creation and clipboard prefetch act on.
124
+ * Never fires for programmatic selection. */
125
+ interface SelectionCommittedEvent {
126
+ readonly range: TextRange;
127
+ }
128
+ /** The selection went from a range to nothing. */
129
+ type SelectionClearedEvent = Record<string, never>;
130
+ /**
131
+ * The public selection API — the documented, stable surface for application
132
+ * code (toolbars, context menus, automation).
133
+ *
134
+ * The permission model: geometry enables selection (`doc.text.select`),
135
+ * text enables extraction (`doc.text.copy`) — neither implies the other.
136
+ * Everything here except the `readText` pair works with the select scope
137
+ * alone, so a deployment can allow selecting and highlighting while denying
138
+ * copy. Writes without the scope throw `PluginError('permission-denied')`;
139
+ * gate UI with {@link canSelect} / {@link canCopy}.
140
+ *
141
+ * Every gesture has a programmatic twin: drag = {@link select} (or
142
+ * `beginGestureAt` + {@link extendTo} for point-driven code on the host
143
+ * lens), double-click = {@link selectWordAt}, triple-click =
144
+ * {@link selectLineAt}, handle drag = {@link extendTo}, click on empty space
145
+ * = {@link clear}, select-all = {@link selectAll}.
146
+ *
147
+ * A page argument is a `PageRef` or a zero-based index. A verb given a page
148
+ * that isn't in the document throws `not-found`; a read returns empty.
149
+ *
150
+ * The settings (`getSettings`, `updateSettings`, `resetSettings`,
151
+ * `onSettingsChanged`) belong to the plugin, not to a document: a change
152
+ * reaches every open document.
153
+ *
154
+ * Framework-only plumbing (gesture bracketing, geometry warming, the
155
+ * highlight-visibility handshake) lives on `SelectionHostCapability`,
156
+ * reachable through `@embedpdf/plugin-selection/contract/host`. Both are the
157
+ * same runtime object — two typed lenses on one token.
158
+ */
159
+ interface SelectionCapability extends SettingsApi<SelectionSettings> {
160
+ /** Whether this caller may create selections at all (`doc.text.select`). */
161
+ canSelect(): boolean;
162
+ /** Whether this caller may extract literal text (`doc.text.copy`). */
163
+ canCopy(): boolean;
164
+ /**
165
+ * Select a range — the same path gestures use, so the highlight, events
166
+ * and markup bridges behave identically. An empty range clears. Throws
167
+ * `permission-denied` without `doc.text.select`, `not-found` for a page
168
+ * that is not in this document. Fires `onChanged`, or `onCleared`.
169
+ */
170
+ select(range: SelectionRangeInput): void;
171
+ /** Select every character of the document. Throws `permission-denied` without `doc.text.select`. */
172
+ selectAll(): void;
173
+ /**
174
+ * Select every character on one page. Throws `permission-denied` without
175
+ * `doc.text.select`, `not-found` for a page that is not in this document.
176
+ */
177
+ selectPage(page: PageRef | number): void;
178
+ /**
179
+ * Select the word around a page point. Returns false when the point has no
180
+ * selectable text (geometry not loaded yet, or no glyph there). Throws
181
+ * `permission-denied` without `doc.text.select`, `not-found` for a page that
182
+ * is not in this document.
183
+ */
184
+ selectWordAt(page: PageRef | number, point: Point): boolean;
185
+ /** Select the visual line around a page point. Same result and errors as {@link selectWordAt}. */
186
+ selectLineAt(page: PageRef | number, point: Point): boolean;
187
+ /**
188
+ * Extend the current selection to a page point (a drag step). No selection
189
+ * → no-op; a page whose geometry has not loaded is warmed and the extension
190
+ * lands when it arrives. Errors as {@link selectPage}.
191
+ */
192
+ extendTo(page: PageRef | number, point: Point): void;
193
+ /** Clear the selection. Always allowed. Fires `onCleared` when something was selected. */
194
+ clear(): void;
195
+ /** Whether anything is selected. */
196
+ hasSelection(): boolean;
197
+ /**
198
+ * Whether the user is still selecting: from the press of a drag, a
199
+ * double-click or a handle until it lifts. A selection made from code is
200
+ * never in progress.
201
+ */
202
+ isSelecting(): boolean;
203
+ /** Per-page segments, endpoints, direction and the range. Reference-stable
204
+ * until the selection changes. */
205
+ getSnapshot(): SelectionSnapshot;
206
+ /** The selected character range, or null. */
207
+ getRange(): TextRange | null;
208
+ /** The pages the current selection covers (those with at least one
209
+ * segment), in document order — so a cross-page action can fan out per page. */
210
+ listSelectedPages(): readonly PageRef[];
211
+ /** Per-line oriented segments for a page, in page space — build your own
212
+ * highlight layer from these. Reference-stable per page. */
213
+ listSegments(page: PageRef | number): readonly SelectionSegment[];
214
+ /** The segments' AABBs — for consumers that genuinely want boxes (scroll,
215
+ * conservative regions). Never a substitute for the oriented quads in
216
+ * geometry that gets drawn or persisted. */
217
+ listRects(page: PageRef | number): readonly Rect[];
218
+ /**
219
+ * Where selection-scoped floating UI should attach: the union box of the
220
+ * selection's segments on its end page (where the gesture finished),
221
+ * falling back to the last page with materialized segments while a
222
+ * boundary page's geometry is still loading. One anchor regardless of
223
+ * cross-page selection. Null when nothing is selected (or nothing has
224
+ * materialized yet).
225
+ */
226
+ getAnchor(): SelectionAnchor | null;
227
+ /**
228
+ * The selected text. Each page's text snapshot is fetched once per content
229
+ * version and sliced through the engine's `charMap`; pages are joined with
230
+ * `\n`. Resolves `''` when nothing is selected. Rejects `permission-denied`
231
+ * without `doc.text.copy`, and `operation-cancelled` when `options.signal`
232
+ * fires. Clipboard writes are deliberately not here — this package is
233
+ * DOM-free; use `@embedpdf/web`'s clipboard helpers.
234
+ */
235
+ readText(options?: OperationOptions): Promise<string>;
236
+ /**
237
+ * Text for any range, without touching the selection. Rejects as
238
+ * {@link readText} does, and `not-found` for a page that is not in this
239
+ * document.
240
+ */
241
+ readTextInRange(range: TextRange, options?: OperationOptions): Promise<string>;
242
+ /** The range or its segments changed, whoever changed them. */
243
+ readonly onChanged: EventHook<SelectionChangedEvent>;
244
+ /** A selection gesture ended with a selection in place. */
245
+ readonly onCommitted: EventHook<SelectionCommittedEvent>;
246
+ /** The selection went from a range to nothing: a clear, an empty range, or
247
+ * its pages' content changed or left the document. */
248
+ readonly onCleared: EventHook<SelectionClearedEvent>;
249
+ }
250
+ //#endregion
251
+ export { SelectionClearedEvent as a, SelectionEndpoint as c, SelectionSnapshot as d, TextPosition as f, SelectionSegment as h, SelectionChangedEvent as i, SelectionRangeInput as l, SelectionToken as m, SelectionAnchor as n, SelectionCommittedEvent as o, TextRange as p, SelectionCapability as r, SelectionConfig as s, SELECTION_DEFAULTS as t, SelectionSettings as u };
252
+ //# sourceMappingURL=contract-DLs4vXVt.d.cts.map