@embedpdf/plugin-selection 2.15.0 → 3.0.0-next.1
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/LICENSE +192 -21
- package/dist/index.cjs +575 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +167 -0
- package/dist/index.d.ts +167 -1
- package/dist/index.js +549 -1508
- package/dist/index.js.map +1 -1
- package/package.json +21 -62
- package/dist/lib/actions.d.ts +0 -103
- package/dist/lib/handlers/index.d.ts +0 -2
- package/dist/lib/handlers/marquee-selection.handler.d.ts +0 -30
- package/dist/lib/handlers/text-selection.handler.d.ts +0 -52
- package/dist/lib/index.d.ts +0 -9
- package/dist/lib/manifest.d.ts +0 -4
- package/dist/lib/reducer.d.ts +0 -5
- package/dist/lib/selection-plugin.d.ts +0 -121
- package/dist/lib/selectors.d.ts +0 -14
- package/dist/lib/types.d.ts +0 -268
- package/dist/lib/utils.d.ts +0 -108
- package/dist/preact/adapter.d.ts +0 -4
- package/dist/preact/core.d.ts +0 -1
- package/dist/preact/index.cjs +0 -2
- package/dist/preact/index.cjs.map +0 -1
- package/dist/preact/index.d.ts +0 -1
- package/dist/preact/index.js +0 -218
- package/dist/preact/index.js.map +0 -1
- package/dist/preact/interaction-manager.d.ts +0 -1
- package/dist/preact/utils.d.ts +0 -1
- package/dist/react/adapter.d.ts +0 -2
- package/dist/react/core.d.ts +0 -1
- package/dist/react/index.cjs +0 -2
- package/dist/react/index.cjs.map +0 -1
- package/dist/react/index.d.ts +0 -1
- package/dist/react/index.js +0 -217
- package/dist/react/index.js.map +0 -1
- package/dist/react/interaction-manager.d.ts +0 -1
- package/dist/react/utils.d.ts +0 -1
- package/dist/shared/components/copy-to-clipboard.d.ts +0 -1
- package/dist/shared/components/index.d.ts +0 -4
- package/dist/shared/components/marquee-selection.d.ts +0 -36
- package/dist/shared/components/selection-layer.d.ts +0 -29
- package/dist/shared/components/text-selection.d.ts +0 -21
- package/dist/shared/hooks/index.d.ts +0 -1
- package/dist/shared/hooks/use-selection.d.ts +0 -11
- package/dist/shared/index.d.ts +0 -5
- package/dist/shared/types.d.ts +0 -7
- package/dist/shared-preact/components/copy-to-clipboard.d.ts +0 -1
- package/dist/shared-preact/components/index.d.ts +0 -4
- package/dist/shared-preact/components/marquee-selection.d.ts +0 -36
- package/dist/shared-preact/components/selection-layer.d.ts +0 -29
- package/dist/shared-preact/components/text-selection.d.ts +0 -21
- package/dist/shared-preact/hooks/index.d.ts +0 -1
- package/dist/shared-preact/hooks/use-selection.d.ts +0 -11
- package/dist/shared-preact/index.d.ts +0 -5
- package/dist/shared-preact/types.d.ts +0 -7
- package/dist/shared-react/components/copy-to-clipboard.d.ts +0 -1
- package/dist/shared-react/components/index.d.ts +0 -4
- package/dist/shared-react/components/marquee-selection.d.ts +0 -36
- package/dist/shared-react/components/selection-layer.d.ts +0 -29
- package/dist/shared-react/components/text-selection.d.ts +0 -21
- package/dist/shared-react/hooks/index.d.ts +0 -1
- package/dist/shared-react/hooks/use-selection.d.ts +0 -11
- package/dist/shared-react/index.d.ts +0 -5
- package/dist/shared-react/types.d.ts +0 -7
- package/dist/svelte/components/CopyToClipboard.svelte.d.ts +0 -3
- package/dist/svelte/components/MarqueeSelection.svelte.d.ts +0 -27
- package/dist/svelte/components/SelectionLayer.svelte.d.ts +0 -32
- package/dist/svelte/components/TextSelection.svelte.d.ts +0 -22
- package/dist/svelte/components/index.d.ts +0 -4
- package/dist/svelte/hooks/index.d.ts +0 -1
- package/dist/svelte/hooks/use-selection.svelte.d.ts +0 -19
- package/dist/svelte/index.cjs +0 -2
- package/dist/svelte/index.cjs.map +0 -1
- package/dist/svelte/index.d.ts +0 -5
- package/dist/svelte/index.js +0 -359
- package/dist/svelte/index.js.map +0 -1
- package/dist/svelte/types.d.ts +0 -7
- package/dist/vue/components/copy-to-clipboard.vue.d.ts +0 -3
- package/dist/vue/components/index.d.ts +0 -4
- package/dist/vue/components/marquee-selection.vue.d.ts +0 -29
- package/dist/vue/components/selection-layer.vue.d.ts +0 -60
- package/dist/vue/components/text-selection.vue.d.ts +0 -51
- package/dist/vue/hooks/index.d.ts +0 -1
- package/dist/vue/hooks/use-selection.d.ts +0 -11
- package/dist/vue/index.cjs +0 -2
- package/dist/vue/index.cjs.map +0 -1
- package/dist/vue/index.d.ts +0 -5
- package/dist/vue/index.js +0 -311
- package/dist/vue/index.js.map +0 -1
- package/dist/vue/types.d.ts +0 -7
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { Position, Rect, Size } from '@embedpdf/models';
|
|
2
|
-
import { EmbedPdfPointerEvent, PointerEventHandlersWithLifecycle } from '@embedpdf/plugin-interaction-manager';
|
|
3
|
-
export interface MarqueeSelectionHandlerOptions {
|
|
4
|
-
/** The page size for clamping */
|
|
5
|
-
pageSize: Size;
|
|
6
|
-
/** Current scale factor for min drag threshold calculation */
|
|
7
|
-
scale: number;
|
|
8
|
-
/** Minimum drag distance in pixels before considering it a marquee (default: 5) */
|
|
9
|
-
minDragPx?: number;
|
|
10
|
-
/** Check if marquee selection is enabled for this mode */
|
|
11
|
-
isEnabled: (modeId: string) => boolean;
|
|
12
|
-
/** Returns whether text selection is currently active (skip marquee if so) */
|
|
13
|
-
isTextSelecting?: () => boolean;
|
|
14
|
-
/** Called when marquee selection begins */
|
|
15
|
-
onBegin: (startPos: Position, modeId: string) => void;
|
|
16
|
-
/** Called during drag with the current marquee rect */
|
|
17
|
-
onChange: (rect: Rect, modeId: string) => void;
|
|
18
|
-
/** Called when marquee selection completes (drag was large enough) */
|
|
19
|
-
onEnd: (rect: Rect, modeId: string) => void;
|
|
20
|
-
/** Called when marquee selection is cancelled (drag too small or cancelled) */
|
|
21
|
-
onCancel: (modeId: string) => void;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Creates a marquee selection handler that allows users to drag a selection rectangle.
|
|
25
|
-
*
|
|
26
|
-
* This handler is meant to be combined with the text selection handler. When text is hit,
|
|
27
|
-
* the text selection handler sets its selecting state, and this handler checks via
|
|
28
|
-
* `isTextSelecting` to avoid activating during text selection.
|
|
29
|
-
*/
|
|
30
|
-
export declare function createMarqueeSelectionHandler(opts: MarqueeSelectionHandlerOptions): PointerEventHandlersWithLifecycle<EmbedPdfPointerEvent>;
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { PdfPageGeometry } from '@embedpdf/models';
|
|
2
|
-
import { EmbedPdfPointerEvent, PointerEventHandlersWithLifecycle } from '@embedpdf/plugin-interaction-manager';
|
|
3
|
-
export interface TextSelectionHandlerOptions {
|
|
4
|
-
/** Returns the page geometry, or undefined if not loaded yet */
|
|
5
|
-
getGeometry: () => PdfPageGeometry | undefined;
|
|
6
|
-
/** Check if selection is enabled for this mode */
|
|
7
|
-
isEnabled: (modeId: string) => boolean;
|
|
8
|
-
/** Called when drag-selection begins on a glyph */
|
|
9
|
-
onBegin: (glyphIndex: number, modeId: string) => void;
|
|
10
|
-
/** Called when drag-selection updates to a new glyph */
|
|
11
|
-
onUpdate: (glyphIndex: number, modeId: string) => void;
|
|
12
|
-
/** Called when drag-selection ends (pointer up) */
|
|
13
|
-
onEnd: (modeId: string) => void;
|
|
14
|
-
/** Called to clear the current selection */
|
|
15
|
-
onClear: (modeId: string) => void;
|
|
16
|
-
/** Returns whether text selection is currently in progress */
|
|
17
|
-
isSelecting: () => boolean;
|
|
18
|
-
/** Set or remove the text cursor */
|
|
19
|
-
setCursor: (cursor: string | null) => void;
|
|
20
|
-
/** Called when the user clicks directly on empty page space (target === currentTarget) */
|
|
21
|
-
onEmptySpaceClick?: (modeId: string) => void;
|
|
22
|
-
/** Called on double-click over a glyph; receives the char index */
|
|
23
|
-
onWordSelect?: (glyphIndex: number, modeId: string) => void;
|
|
24
|
-
/** Called on triple-click over a glyph; receives the char index */
|
|
25
|
-
onLineSelect?: (glyphIndex: number, modeId: string) => void;
|
|
26
|
-
/**
|
|
27
|
-
* Signals whether the text handler has claimed a pointer-down (anchor set)
|
|
28
|
-
* even before the drag threshold is met. Used to prevent the marquee handler
|
|
29
|
-
* from activating concurrently.
|
|
30
|
-
*/
|
|
31
|
-
setHasTextAnchor?: (active: boolean) => void;
|
|
32
|
-
/**
|
|
33
|
-
* Minimum drag distance (in page-coordinate units) before a pointer-down
|
|
34
|
-
* starts an actual selection drag. Default: 3.
|
|
35
|
-
*/
|
|
36
|
-
minDragDistance?: number;
|
|
37
|
-
/** Tolerance factor passed through to glyphAt. Default: 0.9. */
|
|
38
|
-
toleranceFactor?: number;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Creates a text selection handler that manages pointer-based text selection,
|
|
42
|
-
* double-click word selection, triple-click line selection, and a drag threshold.
|
|
43
|
-
*
|
|
44
|
-
* Behaviour modelled after Chromium's PDFiumEngine (pdfium-engine.cc):
|
|
45
|
-
* - Single pointer-down records an anchor but does NOT begin selection until
|
|
46
|
-
* the pointer has moved beyond `minDragDistance`.
|
|
47
|
-
* - Double-click selects the word around the clicked glyph.
|
|
48
|
-
* - Triple-click selects the full visual line.
|
|
49
|
-
* - The marquee handler coordinates via `isTextSelecting` / `hasTextAnchor`
|
|
50
|
-
* to avoid activating during text selection.
|
|
51
|
-
*/
|
|
52
|
-
export declare function createTextSelectionHandler(opts: TextSelectionHandlerOptions): PointerEventHandlersWithLifecycle<EmbedPdfPointerEvent>;
|
package/dist/lib/index.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { PluginPackage } from '@embedpdf/core';
|
|
2
|
-
import { SelectionPluginConfig, SelectionState } from './types';
|
|
3
|
-
import { SelectionPlugin } from './selection-plugin';
|
|
4
|
-
import { SelectionAction } from './actions';
|
|
5
|
-
export declare const SelectionPluginPackage: PluginPackage<SelectionPlugin, SelectionPluginConfig, SelectionState, SelectionAction>;
|
|
6
|
-
export * from './selection-plugin';
|
|
7
|
-
export * from './types';
|
|
8
|
-
export * from './manifest';
|
|
9
|
-
export * from './utils';
|
package/dist/lib/manifest.d.ts
DELETED
package/dist/lib/reducer.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { SelectionDocumentState, SelectionState } from './types';
|
|
2
|
-
import { SelectionAction } from './actions';
|
|
3
|
-
export declare const initialSelectionDocumentState: SelectionDocumentState;
|
|
4
|
-
export declare const initialState: SelectionState;
|
|
5
|
-
export declare const selectionReducer: (state: SelectionState | undefined, action: SelectionAction) => SelectionState;
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import { BasePlugin, PluginRegistry } from '@embedpdf/core';
|
|
2
|
-
import { SelectionAction } from './actions';
|
|
3
|
-
import { SelectionCapability, SelectionPluginConfig, SelectionState, RegisterSelectionOnPageOptions, RegisterMarqueeOnPageOptions, SelectionMenuPlacement } from './types';
|
|
4
|
-
export declare class SelectionPlugin extends BasePlugin<SelectionPluginConfig, SelectionCapability, SelectionState, SelectionAction> {
|
|
5
|
-
static readonly id: "selection";
|
|
6
|
-
/** Modes that should trigger text-selection logic, per document (mode -> config) */
|
|
7
|
-
private enabledModesPerDoc;
|
|
8
|
-
private selecting;
|
|
9
|
-
private anchor;
|
|
10
|
-
/** Whether the text handler has a pending anchor (before drag threshold is met) */
|
|
11
|
-
private hasTextAnchor;
|
|
12
|
-
/** Tracks the page a marquee drag started on, per document */
|
|
13
|
-
private marqueePage;
|
|
14
|
-
/** Page callbacks for rect updates, per document */
|
|
15
|
-
private pageCallbacks;
|
|
16
|
-
/** LRU access order for geometry cache, per document (oldest first) */
|
|
17
|
-
private geoAccessOrder;
|
|
18
|
-
private readonly menuPlacement$;
|
|
19
|
-
private readonly selChange$;
|
|
20
|
-
private readonly textRetrieved$;
|
|
21
|
-
private readonly copyToClipboard$;
|
|
22
|
-
private readonly beginSelection$;
|
|
23
|
-
private readonly endSelection$;
|
|
24
|
-
private readonly marqueeChange$;
|
|
25
|
-
private readonly marqueeEnd$;
|
|
26
|
-
private readonly emptySpaceClick$;
|
|
27
|
-
private interactionManagerCapability;
|
|
28
|
-
private viewportCapability;
|
|
29
|
-
private scrollCapability;
|
|
30
|
-
private readonly menuHeight;
|
|
31
|
-
private readonly config;
|
|
32
|
-
constructor(id: string, registry: PluginRegistry, config: SelectionPluginConfig);
|
|
33
|
-
protected onDocumentLoadingStarted(documentId: string): void;
|
|
34
|
-
protected onDocumentClosed(documentId: string): void;
|
|
35
|
-
initialize(): Promise<void>;
|
|
36
|
-
destroy(): Promise<void>;
|
|
37
|
-
buildCapability(): SelectionCapability;
|
|
38
|
-
private createSelectionScope;
|
|
39
|
-
private getDocumentState;
|
|
40
|
-
/**
|
|
41
|
-
* Subscribe to menu placement changes for a specific document
|
|
42
|
-
* @param documentId - The document ID to subscribe to
|
|
43
|
-
* @param listener - Callback function that receives placement updates
|
|
44
|
-
* @returns Unsubscribe function
|
|
45
|
-
*/
|
|
46
|
-
onMenuPlacement(documentId: string, listener: (placement: SelectionMenuPlacement | null) => void): import('@embedpdf/core').Unsubscribe;
|
|
47
|
-
/**
|
|
48
|
-
* Register text selection on a page. Uses `registerAlways` so any plugin
|
|
49
|
-
* can enable text selection for their mode via `enableForMode()`.
|
|
50
|
-
*/
|
|
51
|
-
registerSelectionOnPage(opts: RegisterSelectionOnPageOptions): () => void;
|
|
52
|
-
/**
|
|
53
|
-
* Register marquee selection on a page. Uses `registerAlways` so any plugin
|
|
54
|
-
* can enable marquee selection for their mode via `enableForMode({ enableMarquee: true })`.
|
|
55
|
-
*/
|
|
56
|
-
registerMarqueeOnPage(opts: RegisterMarqueeOnPageOptions): () => void;
|
|
57
|
-
/**
|
|
58
|
-
* Helper to calculate viewport relative metrics for a page rect.
|
|
59
|
-
* Returns null if the rect cannot be converted to viewport space.
|
|
60
|
-
*/
|
|
61
|
-
private getPlacementMetrics;
|
|
62
|
-
private emitMenuPlacement;
|
|
63
|
-
private recalculateMenuPlacement;
|
|
64
|
-
private notifyPage;
|
|
65
|
-
private notifyAllPages;
|
|
66
|
-
private getNewPageGeometryAndCache;
|
|
67
|
-
private getOrLoadGeometry;
|
|
68
|
-
private touchGeometry;
|
|
69
|
-
private evictGeometryIfNeeded;
|
|
70
|
-
private beginSelection;
|
|
71
|
-
private endSelection;
|
|
72
|
-
private clearSelection;
|
|
73
|
-
/**
|
|
74
|
-
* Programmatically apply (or restore) a text selection without going through
|
|
75
|
-
* the pointer drag flow. Useful for restoring a previously persisted selection
|
|
76
|
-
* or driving selection from code (e.g. search results).
|
|
77
|
-
*
|
|
78
|
-
* Geometry for every page spanned by the range is loaded on demand (the data
|
|
79
|
-
* comes from the WASM engine), so the returned task settles only once the
|
|
80
|
-
* selection rects have actually been computed.
|
|
81
|
-
*
|
|
82
|
-
* Passing `null` is equivalent to calling {@link clearSelection}.
|
|
83
|
-
*
|
|
84
|
-
* @returns a task that resolves once the selection has been applied.
|
|
85
|
-
*/
|
|
86
|
-
private applySelection;
|
|
87
|
-
/**
|
|
88
|
-
* Validate the structure and page bounds of a programmatic selection range.
|
|
89
|
-
* Returns a rejection reason when the input is invalid, or null when it is
|
|
90
|
-
* structurally sound. Glyph-index bounds are enforced separately, after the
|
|
91
|
-
* page geometry has loaded (see {@link clampRangeToGeometry}).
|
|
92
|
-
*/
|
|
93
|
-
private validateRange;
|
|
94
|
-
/**
|
|
95
|
-
* Clamp the glyph indices of a (normalized) range to the number of glyphs
|
|
96
|
-
* available on the corresponding pages. Returns null when none of the
|
|
97
|
-
* spanned pages have any text geometry to select.
|
|
98
|
-
*/
|
|
99
|
-
private clampRangeToGeometry;
|
|
100
|
-
/** Order a range so that `start` never comes after `end`. */
|
|
101
|
-
private normalizeRange;
|
|
102
|
-
private selectWord;
|
|
103
|
-
private selectLine;
|
|
104
|
-
/**
|
|
105
|
-
* Set a selection range without going through the drag begin/update/end flow.
|
|
106
|
-
* Used by double-click (word) and triple-click (line) selection.
|
|
107
|
-
*/
|
|
108
|
-
private applyInstantSelection;
|
|
109
|
-
private updateSelection;
|
|
110
|
-
private updateRectsAndSlices;
|
|
111
|
-
private getSelectedText;
|
|
112
|
-
private copyToClipboard;
|
|
113
|
-
private beginMarquee;
|
|
114
|
-
private updateMarquee;
|
|
115
|
-
private endMarquee;
|
|
116
|
-
private cancelMarquee;
|
|
117
|
-
/** @deprecated — shim for backward compat; delegates to pointerMode config */
|
|
118
|
-
private setMarqueeEnabled;
|
|
119
|
-
/** @deprecated — shim for backward compat; reads pointerMode config */
|
|
120
|
-
private isMarqueeEnabled;
|
|
121
|
-
}
|
package/dist/lib/selectors.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Rect } from '@embedpdf/models';
|
|
2
|
-
import { FormattedSelection, SelectionDocumentState } from './types';
|
|
3
|
-
export declare function selectRectsForPage(state: SelectionDocumentState, page: number): Rect[];
|
|
4
|
-
export declare function selectBoundingRectForPage(state: SelectionDocumentState, page: number): Rect | null;
|
|
5
|
-
export declare function selectRectsAndBoundingRectForPage(state: SelectionDocumentState, page: number): {
|
|
6
|
-
rects: Rect[];
|
|
7
|
-
boundingRect: Rect | null;
|
|
8
|
-
};
|
|
9
|
-
export declare function selectBoundingRectsForAllPages(state: SelectionDocumentState): {
|
|
10
|
-
page: number;
|
|
11
|
-
rect: Rect;
|
|
12
|
-
}[];
|
|
13
|
-
export declare function getFormattedSelectionForPage(state: SelectionDocumentState, page: number): FormattedSelection | null;
|
|
14
|
-
export declare function getFormattedSelection(state: SelectionDocumentState): FormattedSelection[];
|
package/dist/lib/types.d.ts
DELETED
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
import { BasePluginConfig, EventHook } from '@embedpdf/core';
|
|
2
|
-
import { PdfPageGeometry, PdfTask, Rect } from '@embedpdf/models';
|
|
3
|
-
export interface MarqueeSelectionConfig {
|
|
4
|
-
/** Minimum drag distance in pixels before considering it a marquee */
|
|
5
|
-
minDragPx?: number;
|
|
6
|
-
/** Whether marquee selection is enabled (default: true) */
|
|
7
|
-
enabled?: boolean;
|
|
8
|
-
}
|
|
9
|
-
export interface SelectionPluginConfig extends BasePluginConfig {
|
|
10
|
-
/**
|
|
11
|
-
* The approximate height of the selection menu in pixels.
|
|
12
|
-
* Used to determine whether to show the menu above or below the selection.
|
|
13
|
-
* @default 40
|
|
14
|
-
*/
|
|
15
|
-
menuHeight?: number;
|
|
16
|
-
/**
|
|
17
|
-
* Configuration for marquee selection behavior.
|
|
18
|
-
*/
|
|
19
|
-
marquee?: MarqueeSelectionConfig;
|
|
20
|
-
/**
|
|
21
|
-
* Tolerance factor for hit-testing glyphs. Multiplied by average glyph
|
|
22
|
-
* height to derive the tolerance radius. Set to 0 to require exact hits.
|
|
23
|
-
* @default 1.5
|
|
24
|
-
*/
|
|
25
|
-
toleranceFactor?: number;
|
|
26
|
-
/**
|
|
27
|
-
* Minimum drag distance (in page-coordinate units) the pointer must move
|
|
28
|
-
* before a drag-selection starts. Prevents accidental selection on simple clicks.
|
|
29
|
-
* @default 3
|
|
30
|
-
*/
|
|
31
|
-
minSelectionDragDistance?: number;
|
|
32
|
-
/**
|
|
33
|
-
* Maximum number of pages whose geometry data is kept in memory per document.
|
|
34
|
-
* Oldest unused pages are evicted when this limit is exceeded.
|
|
35
|
-
* @default 50
|
|
36
|
-
*/
|
|
37
|
-
maxCachedGeometries?: number;
|
|
38
|
-
}
|
|
39
|
-
export interface SelectionMenuPlacement {
|
|
40
|
-
pageIndex: number;
|
|
41
|
-
rect: Rect;
|
|
42
|
-
spaceAbove: number;
|
|
43
|
-
spaceBelow: number;
|
|
44
|
-
suggestTop: boolean;
|
|
45
|
-
isVisible: boolean;
|
|
46
|
-
}
|
|
47
|
-
export interface GlyphPointer {
|
|
48
|
-
page: number;
|
|
49
|
-
index: number;
|
|
50
|
-
}
|
|
51
|
-
export interface SelectionRangeX {
|
|
52
|
-
start: GlyphPointer;
|
|
53
|
-
end: GlyphPointer;
|
|
54
|
-
}
|
|
55
|
-
export interface SelectionDocumentState {
|
|
56
|
-
/** page → geometry cache */
|
|
57
|
-
geometry: Record<number, PdfPageGeometry>;
|
|
58
|
-
/** current selection or null */
|
|
59
|
-
rects: Record<number, Rect[]>;
|
|
60
|
-
selection: SelectionRangeX | null;
|
|
61
|
-
slices: Record<number, {
|
|
62
|
-
start: number;
|
|
63
|
-
count: number;
|
|
64
|
-
}>;
|
|
65
|
-
active: boolean;
|
|
66
|
-
selecting: boolean;
|
|
67
|
-
}
|
|
68
|
-
export interface SelectionState {
|
|
69
|
-
documents: Record<string, SelectionDocumentState>;
|
|
70
|
-
}
|
|
71
|
-
export interface FormattedSelection {
|
|
72
|
-
pageIndex: number;
|
|
73
|
-
rect: Rect;
|
|
74
|
-
segmentRects: Rect[];
|
|
75
|
-
}
|
|
76
|
-
export interface SelectionRectsCallback {
|
|
77
|
-
rects: Rect[];
|
|
78
|
-
boundingRect: Rect | null;
|
|
79
|
-
}
|
|
80
|
-
export interface RegisterSelectionOnPageOptions {
|
|
81
|
-
documentId: string;
|
|
82
|
-
pageIndex: number;
|
|
83
|
-
onRectsChange: (data: SelectionRectsCallback) => void;
|
|
84
|
-
}
|
|
85
|
-
export interface RegisterMarqueeOnPageOptions {
|
|
86
|
-
documentId: string;
|
|
87
|
-
pageIndex: number;
|
|
88
|
-
/** The current scale factor (for marquee threshold calculation) */
|
|
89
|
-
scale: number;
|
|
90
|
-
/** Called when the marquee rect changes during drag, or null when cancelled/ended */
|
|
91
|
-
onRectChange: (rect: Rect | null) => void;
|
|
92
|
-
}
|
|
93
|
-
export interface TextSelectionStyle {
|
|
94
|
-
/** Background color for text selection highlights. Default: 'rgba(33,150,243)' */
|
|
95
|
-
background?: string;
|
|
96
|
-
}
|
|
97
|
-
export interface MarqueeSelectionStyle {
|
|
98
|
-
/** Fill/background color inside the marquee rectangle. Default: 'rgba(0,122,204,0.15)' */
|
|
99
|
-
background?: string;
|
|
100
|
-
/** Border color of the marquee rectangle. Default: 'rgba(0,122,204,0.8)' */
|
|
101
|
-
borderColor?: string;
|
|
102
|
-
/** Border style. Default: 'dashed' */
|
|
103
|
-
borderStyle?: 'solid' | 'dashed' | 'dotted';
|
|
104
|
-
}
|
|
105
|
-
export interface SelectionMenuPlacementEvent {
|
|
106
|
-
documentId: string;
|
|
107
|
-
placement: SelectionMenuPlacement | null;
|
|
108
|
-
}
|
|
109
|
-
export interface SelectionChangeEvent {
|
|
110
|
-
documentId: string;
|
|
111
|
-
selection: SelectionRangeX | null;
|
|
112
|
-
modeId: string;
|
|
113
|
-
}
|
|
114
|
-
export interface TextRetrievedEvent {
|
|
115
|
-
documentId: string;
|
|
116
|
-
text: string[];
|
|
117
|
-
}
|
|
118
|
-
export interface CopyToClipboardEvent {
|
|
119
|
-
documentId: string;
|
|
120
|
-
text: string;
|
|
121
|
-
}
|
|
122
|
-
export interface BeginSelectionEvent {
|
|
123
|
-
documentId: string;
|
|
124
|
-
page: number;
|
|
125
|
-
index: number;
|
|
126
|
-
modeId: string;
|
|
127
|
-
}
|
|
128
|
-
export interface EndSelectionEvent {
|
|
129
|
-
documentId: string;
|
|
130
|
-
modeId: string;
|
|
131
|
-
}
|
|
132
|
-
export interface MarqueeChangeEvent {
|
|
133
|
-
documentId: string;
|
|
134
|
-
pageIndex: number;
|
|
135
|
-
rect: Rect | null;
|
|
136
|
-
modeId: string;
|
|
137
|
-
}
|
|
138
|
-
export interface MarqueeEndEvent {
|
|
139
|
-
documentId: string;
|
|
140
|
-
pageIndex: number;
|
|
141
|
-
rect: Rect;
|
|
142
|
-
modeId: string;
|
|
143
|
-
}
|
|
144
|
-
export interface EmptySpaceClickEvent {
|
|
145
|
-
documentId: string;
|
|
146
|
-
pageIndex: number;
|
|
147
|
-
modeId: string;
|
|
148
|
-
}
|
|
149
|
-
export interface EnableForModeOptions {
|
|
150
|
-
/**
|
|
151
|
-
* Whether to show selection rects in the SelectionLayer.
|
|
152
|
-
* @deprecated Use `showSelectionRects` instead.
|
|
153
|
-
* @default true
|
|
154
|
-
*/
|
|
155
|
-
showRects?: boolean;
|
|
156
|
-
/**
|
|
157
|
-
* Enable text selection for this mode.
|
|
158
|
-
* @default true
|
|
159
|
-
*/
|
|
160
|
-
enableSelection?: boolean;
|
|
161
|
-
/**
|
|
162
|
-
* Whether to show text selection rects in the SelectionLayer.
|
|
163
|
-
* When false, the selection logic is enabled but the rects are not
|
|
164
|
-
* rendered (useful when a consuming plugin handles its own rendering).
|
|
165
|
-
* Takes precedence over `showRects`.
|
|
166
|
-
* @default true
|
|
167
|
-
*/
|
|
168
|
-
showSelectionRects?: boolean;
|
|
169
|
-
/**
|
|
170
|
-
* Enable marquee selection for this mode.
|
|
171
|
-
* @default false
|
|
172
|
-
*/
|
|
173
|
-
enableMarquee?: boolean;
|
|
174
|
-
/**
|
|
175
|
-
* Whether to show the marquee rect in the MarqueeSelection component.
|
|
176
|
-
* When false, the marquee logic runs but the rect is not rendered
|
|
177
|
-
* (useful when a consuming plugin handles its own rendering).
|
|
178
|
-
* @default true
|
|
179
|
-
*/
|
|
180
|
-
showMarqueeRects?: boolean;
|
|
181
|
-
}
|
|
182
|
-
export interface MarqueeScopeEvent {
|
|
183
|
-
pageIndex: number;
|
|
184
|
-
rect: Rect | null;
|
|
185
|
-
modeId: string;
|
|
186
|
-
}
|
|
187
|
-
export interface MarqueeEndScopeEvent {
|
|
188
|
-
pageIndex: number;
|
|
189
|
-
rect: Rect;
|
|
190
|
-
modeId: string;
|
|
191
|
-
}
|
|
192
|
-
export interface EmptySpaceClickScopeEvent {
|
|
193
|
-
pageIndex: number;
|
|
194
|
-
modeId: string;
|
|
195
|
-
}
|
|
196
|
-
export interface SelectionScope {
|
|
197
|
-
getFormattedSelection(): FormattedSelection[];
|
|
198
|
-
getFormattedSelectionForPage(page: number): FormattedSelection | null;
|
|
199
|
-
getHighlightRectsForPage(page: number): Rect[];
|
|
200
|
-
getHighlightRects(): Record<number, Rect[]>;
|
|
201
|
-
getBoundingRectForPage(page: number): Rect | null;
|
|
202
|
-
getBoundingRects(): {
|
|
203
|
-
page: number;
|
|
204
|
-
rect: Rect;
|
|
205
|
-
}[];
|
|
206
|
-
getSelectedText(): PdfTask<string[]>;
|
|
207
|
-
setSelection(range: SelectionRangeX | null): PdfTask<void>;
|
|
208
|
-
clear(): void;
|
|
209
|
-
copyToClipboard(): void;
|
|
210
|
-
getState(): SelectionDocumentState;
|
|
211
|
-
/**
|
|
212
|
-
* @deprecated Use `enableForMode` with `enableMarquee` option on the capability instead.
|
|
213
|
-
*/
|
|
214
|
-
setMarqueeEnabled(enabled: boolean): void;
|
|
215
|
-
/**
|
|
216
|
-
* @deprecated Use `enableForMode` / `isEnabledForMode` on the capability instead.
|
|
217
|
-
*/
|
|
218
|
-
isMarqueeEnabled(): boolean;
|
|
219
|
-
onSelectionChange: EventHook<SelectionRangeX | null>;
|
|
220
|
-
onTextRetrieved: EventHook<string[]>;
|
|
221
|
-
onCopyToClipboard: EventHook<string>;
|
|
222
|
-
onBeginSelection: EventHook<{
|
|
223
|
-
page: number;
|
|
224
|
-
index: number;
|
|
225
|
-
modeId: string;
|
|
226
|
-
}>;
|
|
227
|
-
onEndSelection: EventHook<{
|
|
228
|
-
modeId: string;
|
|
229
|
-
}>;
|
|
230
|
-
onMarqueeChange: EventHook<MarqueeScopeEvent>;
|
|
231
|
-
onMarqueeEnd: EventHook<MarqueeEndScopeEvent>;
|
|
232
|
-
onEmptySpaceClick: EventHook<EmptySpaceClickScopeEvent>;
|
|
233
|
-
}
|
|
234
|
-
export interface SelectionCapability {
|
|
235
|
-
getFormattedSelection(documentId?: string): FormattedSelection[];
|
|
236
|
-
getFormattedSelectionForPage(page: number, documentId?: string): FormattedSelection | null;
|
|
237
|
-
getHighlightRectsForPage(page: number, documentId?: string): Rect[];
|
|
238
|
-
getHighlightRects(documentId?: string): Record<number, Rect[]>;
|
|
239
|
-
getBoundingRectForPage(page: number, documentId?: string): Rect | null;
|
|
240
|
-
getBoundingRects(documentId?: string): {
|
|
241
|
-
page: number;
|
|
242
|
-
rect: Rect;
|
|
243
|
-
}[];
|
|
244
|
-
getSelectedText(documentId?: string): PdfTask<string[]>;
|
|
245
|
-
setSelection(range: SelectionRangeX | null, documentId?: string): PdfTask<void>;
|
|
246
|
-
clear(documentId?: string): void;
|
|
247
|
-
copyToClipboard(documentId?: string): void;
|
|
248
|
-
getState(documentId?: string): SelectionDocumentState;
|
|
249
|
-
enableForMode(modeId: string, options?: EnableForModeOptions, documentId?: string): void;
|
|
250
|
-
isEnabledForMode(modeId: string, documentId?: string): boolean;
|
|
251
|
-
/**
|
|
252
|
-
* @deprecated Use `enableForMode` with `enableMarquee` option instead.
|
|
253
|
-
*/
|
|
254
|
-
setMarqueeEnabled(enabled: boolean, documentId?: string): void;
|
|
255
|
-
/**
|
|
256
|
-
* @deprecated Use `enableForMode` / `isEnabledForMode` instead.
|
|
257
|
-
*/
|
|
258
|
-
isMarqueeEnabled(documentId?: string): boolean;
|
|
259
|
-
forDocument(documentId: string): SelectionScope;
|
|
260
|
-
onSelectionChange: EventHook<SelectionChangeEvent>;
|
|
261
|
-
onTextRetrieved: EventHook<TextRetrievedEvent>;
|
|
262
|
-
onCopyToClipboard: EventHook<CopyToClipboardEvent>;
|
|
263
|
-
onBeginSelection: EventHook<BeginSelectionEvent>;
|
|
264
|
-
onEndSelection: EventHook<EndSelectionEvent>;
|
|
265
|
-
onMarqueeChange: EventHook<MarqueeChangeEvent>;
|
|
266
|
-
onMarqueeEnd: EventHook<MarqueeEndEvent>;
|
|
267
|
-
onEmptySpaceClick: EventHook<EmptySpaceClickEvent>;
|
|
268
|
-
}
|
package/dist/lib/utils.d.ts
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { PdfPageGeometry, Position, Rect } from '@embedpdf/models';
|
|
2
|
-
import { SelectionRangeX } from './types';
|
|
3
|
-
/**
|
|
4
|
-
* Hit-test helper using runs, with tolerance-based fallback.
|
|
5
|
-
*
|
|
6
|
-
* Adapted from PDFium's FPDFText_GetCharIndexAtPos / CPDF_TextPage::GetIndexAtPos:
|
|
7
|
-
* 1. Exact match: return the glyph whose bounding box contains the point.
|
|
8
|
-
* 2. Tolerance expansion: expand each glyph box by tolerance/2 on every side,
|
|
9
|
-
* then pick the closest glyph by Manhattan distance.
|
|
10
|
-
*
|
|
11
|
-
* @param geo - page geometry
|
|
12
|
-
* @param pt - point in page coordinates
|
|
13
|
-
* @param toleranceFactor - multiplied by average glyph height to derive the
|
|
14
|
-
* tolerance radius. 0 disables the fallback.
|
|
15
|
-
* Default 1.5 (see Chromium's pdfium-page.cc kTolerance).
|
|
16
|
-
* @returns glyph index, or -1 if nothing was hit
|
|
17
|
-
*/
|
|
18
|
-
export declare function glyphAt(geo: PdfPageGeometry, pt: Position, toleranceFactor?: number): number;
|
|
19
|
-
/**
|
|
20
|
-
* Helper: min/max glyph indices on `page` for current sel
|
|
21
|
-
* @param sel - selection range
|
|
22
|
-
* @param geo - page geometry
|
|
23
|
-
* @param page - page index
|
|
24
|
-
* @returns { from: number; to: number } | null
|
|
25
|
-
*/
|
|
26
|
-
export declare function sliceBounds(sel: SelectionRangeX | null, geo: PdfPageGeometry | undefined, page: number): {
|
|
27
|
-
from: number;
|
|
28
|
-
to: number;
|
|
29
|
-
} | null;
|
|
30
|
-
/**
|
|
31
|
-
* Helper: build rects for a slice of the page
|
|
32
|
-
* @param geo - page geometry
|
|
33
|
-
* @param from - from index
|
|
34
|
-
* @param to - to index
|
|
35
|
-
* @param merge - whether to merge adjacent rects (default: true)
|
|
36
|
-
* @returns rects
|
|
37
|
-
*/
|
|
38
|
-
export declare function rectsWithinSlice(geo: PdfPageGeometry, from: number, to: number, merge?: boolean): Rect[];
|
|
39
|
-
/**
|
|
40
|
-
* ============================================================================
|
|
41
|
-
* Rectangle Merging Algorithm
|
|
42
|
-
* ============================================================================
|
|
43
|
-
*
|
|
44
|
-
* The following code is adapted from Chromium's PDF text selection implementation.
|
|
45
|
-
*
|
|
46
|
-
* Copyright 2010 The Chromium Authors
|
|
47
|
-
* Use of this source code is governed by a BSD-style license that can be
|
|
48
|
-
* found in the LICENSE file: https://source.chromium.org/chromium/chromium/src/+/main:LICENSE
|
|
49
|
-
*
|
|
50
|
-
* Original source:
|
|
51
|
-
* https://source.chromium.org/chromium/chromium/src/+/main:pdf/pdfium/pdfium_range.cc
|
|
52
|
-
*
|
|
53
|
-
* Adapted for TypeScript and this project's Rect/geometry types.
|
|
54
|
-
*/
|
|
55
|
-
/**
|
|
56
|
-
* Text run info for rect merging (similar to Chromium's PdfRectTextRunInfo)
|
|
57
|
-
*/
|
|
58
|
-
export interface TextRunInfo {
|
|
59
|
-
rect: Rect;
|
|
60
|
-
charCount: number;
|
|
61
|
-
fontSize?: number;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Helper functions for Rect operations
|
|
65
|
-
*/
|
|
66
|
-
export declare function rectUnion(rect1: Rect, rect2: Rect): Rect;
|
|
67
|
-
export declare function rectIntersect(rect1: Rect, rect2: Rect): Rect;
|
|
68
|
-
export declare function rectIsEmpty(rect: Rect): boolean;
|
|
69
|
-
/**
|
|
70
|
-
* Returns a ratio between [0, 1] representing vertical overlap
|
|
71
|
-
*/
|
|
72
|
-
export declare function getVerticalOverlap(rect1: Rect, rect2: Rect): number;
|
|
73
|
-
/**
|
|
74
|
-
* Returns true if there is sufficient horizontal and vertical overlap
|
|
75
|
-
*/
|
|
76
|
-
export declare function shouldMergeHorizontalRects(textRun1: TextRunInfo, textRun2: TextRunInfo): boolean;
|
|
77
|
-
/**
|
|
78
|
-
* Merge adjacent rectangles based on proximity and overlap.
|
|
79
|
-
*
|
|
80
|
-
* Adapted from Chromium's MergeAdjacentRects (pdfium_range.cc):
|
|
81
|
-
* - The merge DECISION uses the loose `rect` (via shouldMergeHorizontalRects).
|
|
82
|
-
* - The OUTPUT rect always uses loose bounds.
|
|
83
|
-
*/
|
|
84
|
-
export declare function mergeAdjacentRects(textRuns: TextRunInfo[]): Rect[];
|
|
85
|
-
/**
|
|
86
|
-
* Expand a character index to the word surrounding it.
|
|
87
|
-
*
|
|
88
|
-
* Walks backward and forward from `charIndex` within the page geometry
|
|
89
|
-
* until a word-boundary glyph (space or empty) is encountered.
|
|
90
|
-
*
|
|
91
|
-
* @returns `{ from, to }` inclusive indices, or null if charIndex is invalid.
|
|
92
|
-
*/
|
|
93
|
-
export declare function expandToWordBoundary(geo: PdfPageGeometry, charIndex: number): {
|
|
94
|
-
from: number;
|
|
95
|
-
to: number;
|
|
96
|
-
} | null;
|
|
97
|
-
/**
|
|
98
|
-
* Expand a character index to the full visual line (row) it belongs to.
|
|
99
|
-
*
|
|
100
|
-
* Finds all runs whose vertical extent overlaps with the run containing `charIndex`,
|
|
101
|
-
* then returns the first-to-last character span across those runs.
|
|
102
|
-
*
|
|
103
|
-
* @returns `{ from, to }` inclusive indices, or null if charIndex is invalid.
|
|
104
|
-
*/
|
|
105
|
-
export declare function expandToLineBoundary(geo: PdfPageGeometry, charIndex: number): {
|
|
106
|
-
from: number;
|
|
107
|
-
to: number;
|
|
108
|
-
} | null;
|
package/dist/preact/adapter.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export { Fragment } from 'preact';
|
|
2
|
-
export { useEffect, useRef, useState, useCallback, useMemo } from 'preact/hooks';
|
|
3
|
-
export type { ComponentChildren as ReactNode } from 'preact';
|
|
4
|
-
export type HTMLAttributes<T = any> = import('preact').JSX.HTMLAttributes<T extends EventTarget ? T : never>;
|
package/dist/preact/core.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '@embedpdf/core/preact';
|
package/dist/preact/index.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core"),t=require("@embedpdf/plugin-selection"),o=require("preact/jsx-runtime"),i=require("preact"),n=require("preact/hooks"),r=require("@embedpdf/core/preact"),l=require("@embedpdf/utils/preact"),u=()=>r.useCapability(t.SelectionPlugin.id),s=()=>r.usePlugin(t.SelectionPlugin.id);function a({documentId:e,pageIndex:t,scale:i,rotation:u,background:a="rgba(33,150,243)",selectionMenu:d}){var c,g;const{plugin:p}=s(),x=r.useDocumentState(e),b=null==(g=null==(c=null==x?void 0:x.document)?void 0:c.pages)?void 0:g[t],[h,m]=n.useState([]),[f,y]=n.useState(null),[v,S]=n.useState(null);n.useEffect(()=>{if(p&&e)return p.registerSelectionOnPage({documentId:e,pageIndex:t,onRectsChange:({rects:e,boundingRect:t})=>{m(e),y(t)}})},[p,e,t]),n.useEffect(()=>{if(p&&e)return p.onMenuPlacement(e,e=>{S(e)})},[p,e]);const I=n.useMemo(()=>void 0!==i?i:(null==x?void 0:x.scale)??1,[i,null==x?void 0:x.scale]),P=n.useMemo(()=>{if(void 0!==u)return u;return(((null==b?void 0:b.rotation)??0)+((null==x?void 0:x.rotation)??0))%4},[u,null==b?void 0:b.rotation,null==x?void 0:x.rotation]),k=d&&v&&v.pageIndex===t&&v.isVisible;return f?o.jsxs(o.Fragment,{children:[o.jsx("div",{style:{position:"absolute",left:f.origin.x*I,top:f.origin.y*I,width:f.size.width*I,height:f.size.height*I,mixBlendMode:"multiply",isolation:"isolate",pointerEvents:"none"},children:h.map((e,t)=>o.jsx("div",{style:{position:"absolute",left:(e.origin.x-f.origin.x)*I,top:(e.origin.y-f.origin.y)*I,width:e.size.width*I,height:e.size.height*I,background:a}},t))}),k&&o.jsx(l.CounterRotate,{rect:{origin:{x:v.rect.origin.x*I,y:v.rect.origin.y*I},size:{width:v.rect.size.width*I,height:v.rect.size.height*I}},rotation:P,children:e=>d({...e,context:{type:"selection",pageIndex:t},selected:!0,placement:v})})]}):null}const d=({documentId:e,pageIndex:t,scale:i,className:l,background:u,borderColor:a,borderStyle:d="dashed",stroke:c,fill:g})=>{const{plugin:p}=s(),x=r.useDocumentState(e),[b,h]=n.useState(null),m=a??c??"rgba(0,122,204,0.8)",f=u??g??"rgba(0,122,204,0.15)",y=n.useMemo(()=>void 0!==i?i:(null==x?void 0:x.scale)??1,[i,null==x?void 0:x.scale]);return n.useEffect(()=>{if(p&&e)return p.registerMarqueeOnPage({documentId:e,pageIndex:t,scale:y,onRectChange:h})},[p,e,t,y]),b?o.jsx("div",{style:{position:"absolute",pointerEvents:"none",left:b.origin.x*y,top:b.origin.y*y,width:b.size.width*y,height:b.size.height*y,border:`1px ${d} ${m}`,background:f,boxSizing:"border-box",zIndex:1e3},className:l}):null};function c(){const{provides:e}=u();return n.useEffect(()=>{if(e)return e.onCopyToClipboard(({text:e})=>{navigator.clipboard.writeText(e)})},[e]),null}const g=e.createPluginPackage(t.SelectionPluginPackage).addUtility(c).build();exports.CopyToClipboard=c,exports.MarqueeSelection=d,exports.SelectionLayer=function({documentId:e,pageIndex:t,scale:n,rotation:r,background:l,textStyle:u,marqueeStyle:s,marqueeClassName:c,selectionMenu:g}){return o.jsxs(i.Fragment,{children:[o.jsx(a,{documentId:e,pageIndex:t,scale:n,rotation:r,background:(null==u?void 0:u.background)??l,selectionMenu:g}),o.jsx(d,{documentId:e,pageIndex:t,scale:n,background:null==s?void 0:s.background,borderColor:null==s?void 0:s.borderColor,borderStyle:null==s?void 0:s.borderStyle,className:c})]})},exports.SelectionPluginPackage=g,exports.TextSelection=a,exports.useSelectionCapability=u,exports.useSelectionPlugin=s,Object.keys(t).forEach(e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})});
|
|
2
|
-
//# sourceMappingURL=index.cjs.map
|