@embedpdf/plugin-selection 1.0.11 → 1.0.12

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 (55) hide show
  1. package/dist/index.cjs +2 -450
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.ts +1 -210
  4. package/dist/index.js +27 -53
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/actions.d.ts +57 -0
  7. package/dist/lib/index.d.ts +9 -0
  8. package/dist/lib/manifest.d.ts +4 -0
  9. package/dist/lib/reducer.d.ts +4 -0
  10. package/dist/lib/selection-plugin.d.ts +29 -0
  11. package/dist/lib/selectors.d.ts +14 -0
  12. package/dist/lib/types.d.ts +63 -0
  13. package/dist/lib/utils.d.ts +70 -0
  14. package/dist/preact/adapter.d.ts +4 -0
  15. package/dist/preact/core.d.ts +1 -0
  16. package/dist/preact/index.cjs +2 -170
  17. package/dist/preact/index.cjs.map +1 -1
  18. package/dist/preact/index.d.ts +1 -25
  19. package/dist/preact/index.js +10 -20
  20. package/dist/preact/index.js.map +1 -1
  21. package/dist/preact/interaction-manager.d.ts +1 -0
  22. package/dist/react/adapter.d.ts +2 -0
  23. package/dist/react/core.d.ts +1 -0
  24. package/dist/react/index.cjs +2 -170
  25. package/dist/react/index.cjs.map +1 -1
  26. package/dist/react/index.d.ts +1 -25
  27. package/dist/react/index.js +9 -20
  28. package/dist/react/index.js.map +1 -1
  29. package/dist/react/interaction-manager.d.ts +1 -0
  30. package/dist/shared-preact/components/copy-to-clipboard.d.ts +1 -0
  31. package/dist/shared-preact/components/index.d.ts +2 -0
  32. package/dist/shared-preact/components/selection-layer.d.ts +7 -0
  33. package/dist/shared-preact/hooks/index.d.ts +1 -0
  34. package/dist/shared-preact/hooks/use-selection.d.ts +11 -0
  35. package/dist/shared-preact/index.d.ts +2 -0
  36. package/dist/shared-react/components/copy-to-clipboard.d.ts +1 -0
  37. package/dist/shared-react/components/index.d.ts +2 -0
  38. package/dist/shared-react/components/selection-layer.d.ts +7 -0
  39. package/dist/shared-react/hooks/index.d.ts +1 -0
  40. package/dist/shared-react/hooks/use-selection.d.ts +11 -0
  41. package/dist/shared-react/index.d.ts +2 -0
  42. package/dist/vue/components/copy-to-clipboard.vue.d.ts +2 -0
  43. package/dist/vue/components/index.d.ts +2 -0
  44. package/dist/vue/components/selection-layer.vue.d.ts +9 -0
  45. package/dist/vue/hooks/index.d.ts +1 -0
  46. package/dist/vue/hooks/use-selection.d.ts +11 -0
  47. package/dist/vue/index.cjs +2 -0
  48. package/dist/vue/index.cjs.map +1 -0
  49. package/dist/vue/index.d.ts +2 -0
  50. package/dist/vue/index.js +145 -0
  51. package/dist/vue/index.js.map +1 -0
  52. package/package.json +23 -14
  53. package/dist/index.d.cts +0 -210
  54. package/dist/preact/index.d.cts +0 -25
  55. package/dist/react/index.d.cts +0 -25
@@ -0,0 +1,145 @@
1
+ import { useCapability, usePlugin } from "@embedpdf/core/vue";
2
+ import { SelectionPlugin, glyphAt } from "@embedpdf/plugin-selection";
3
+ import { defineComponent, ref, watchEffect, computed, createElementBlock, createCommentVNode, openBlock, normalizeStyle, Fragment, renderList } from "vue";
4
+ import { ignore, PdfErrorCode } from "@embedpdf/models";
5
+ import { useInteractionManagerCapability, usePointerHandlers, useCursor } from "@embedpdf/plugin-interaction-manager/vue";
6
+ const useSelectionCapability = () => useCapability(SelectionPlugin.id);
7
+ const useSelectionPlugin = () => usePlugin(SelectionPlugin.id);
8
+ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
9
+ __name: "selection-layer",
10
+ props: {
11
+ pageIndex: {},
12
+ scale: {},
13
+ background: { default: "rgba(33, 150, 243)" }
14
+ },
15
+ setup(__props) {
16
+ const props = __props;
17
+ const { provides: sel } = useSelectionCapability();
18
+ const { provides: im } = useInteractionManagerCapability();
19
+ const { register } = usePointerHandlers({ pageIndex: props.pageIndex });
20
+ const { setCursor, removeCursor } = useCursor();
21
+ const rects = ref([]);
22
+ const boundingRect = ref(null);
23
+ watchEffect((onCleanup) => {
24
+ if (sel.value) {
25
+ const unsubscribe = sel.value.onSelectionChange(() => {
26
+ var _a;
27
+ const mode = (_a = im.value) == null ? void 0 : _a.getActiveMode();
28
+ if (mode === "default") {
29
+ rects.value = sel.value.getHighlightRectsForPage(props.pageIndex);
30
+ boundingRect.value = sel.value.getBoundingRectForPage(props.pageIndex);
31
+ } else {
32
+ rects.value = [];
33
+ boundingRect.value = null;
34
+ }
35
+ });
36
+ onCleanup(unsubscribe);
37
+ }
38
+ });
39
+ let geoCache;
40
+ watchEffect((onCleanup) => {
41
+ if (sel.value) {
42
+ const task = sel.value.getGeometry(props.pageIndex);
43
+ task.wait((g) => geoCache = g, ignore);
44
+ onCleanup(() => {
45
+ task.abort({
46
+ code: PdfErrorCode.Cancelled,
47
+ message: "SelectionLayer unmounted"
48
+ });
49
+ });
50
+ }
51
+ });
52
+ const handlers = computed(
53
+ () => ({
54
+ onPointerDown: (point, _evt, modeId) => {
55
+ if (!sel.value || !sel.value.isEnabledForMode(modeId)) return;
56
+ sel.value.clear();
57
+ const task = sel.value.getGeometry(props.pageIndex);
58
+ task.wait((geo) => {
59
+ const g = glyphAt(geo, point);
60
+ if (g !== -1) sel.value.begin(props.pageIndex, g);
61
+ }, ignore);
62
+ },
63
+ onPointerMove: (point, _evt, modeId) => {
64
+ if (!sel.value || !sel.value.isEnabledForMode(modeId)) return;
65
+ const g = geoCache ? glyphAt(geoCache, point) : -1;
66
+ if (g !== -1) {
67
+ setCursor("selection-text", "text", 10);
68
+ sel.value.update(props.pageIndex, g);
69
+ } else {
70
+ removeCursor("selection-text");
71
+ }
72
+ },
73
+ onPointerUp: (_point, _evt, modeId) => {
74
+ if (!sel.value || !sel.value.isEnabledForMode(modeId)) return;
75
+ sel.value.end();
76
+ },
77
+ onHandlerActiveEnd: (modeId) => {
78
+ if (!sel.value || !sel.value.isEnabledForMode(modeId)) return;
79
+ sel.value.clear();
80
+ }
81
+ })
82
+ );
83
+ watchEffect((onCleanup) => {
84
+ if (register) {
85
+ const cleanup = register(handlers.value);
86
+ if (cleanup) onCleanup(cleanup);
87
+ }
88
+ });
89
+ return (_ctx, _cache) => {
90
+ return boundingRect.value ? (openBlock(), createElementBlock("div", {
91
+ key: 0,
92
+ style: normalizeStyle({
93
+ position: "absolute",
94
+ left: `${boundingRect.value.origin.x * _ctx.scale}px`,
95
+ top: `${boundingRect.value.origin.y * _ctx.scale}px`,
96
+ width: `${boundingRect.value.size.width * _ctx.scale}px`,
97
+ height: `${boundingRect.value.size.height * _ctx.scale}px`,
98
+ mixBlendMode: "multiply",
99
+ isolation: "isolate",
100
+ pointerEvents: "none"
101
+ })
102
+ }, [
103
+ (openBlock(true), createElementBlock(Fragment, null, renderList(rects.value, (rect, i) => {
104
+ return openBlock(), createElementBlock("div", {
105
+ key: i,
106
+ style: normalizeStyle({
107
+ position: "absolute",
108
+ left: `${(rect.origin.x - boundingRect.value.origin.x) * _ctx.scale}px`,
109
+ top: `${(rect.origin.y - boundingRect.value.origin.y) * _ctx.scale}px`,
110
+ width: `${rect.size.width * _ctx.scale}px`,
111
+ height: `${rect.size.height * _ctx.scale}px`,
112
+ background: _ctx.background
113
+ })
114
+ }, null, 4);
115
+ }), 128))
116
+ ], 4)) : createCommentVNode("", true);
117
+ };
118
+ }
119
+ });
120
+ const _sfc_main = /* @__PURE__ */ defineComponent({
121
+ __name: "copy-to-clipboard",
122
+ setup(__props) {
123
+ const { provides: sel } = useSelectionCapability();
124
+ watchEffect((onCleanup) => {
125
+ if (sel.value) {
126
+ const unsubscribe = sel.value.onCopyToClipboard((text) => {
127
+ navigator.clipboard.writeText(text).catch((err) => {
128
+ console.error("Failed to copy text to clipboard:", err);
129
+ });
130
+ });
131
+ onCleanup(unsubscribe);
132
+ }
133
+ });
134
+ return (_ctx, _cache) => {
135
+ return null;
136
+ };
137
+ }
138
+ });
139
+ export {
140
+ _sfc_main as CopyToClipboard,
141
+ _sfc_main$1 as SelectionLayer,
142
+ useSelectionCapability,
143
+ useSelectionPlugin
144
+ };
145
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../src/vue/hooks/use-selection.ts","../../src/vue/components/selection-layer.vue","../../src/vue/components/copy-to-clipboard.vue"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/vue';\nimport { SelectionPlugin } from '@embedpdf/plugin-selection';\n\n/**\n * Hook to get the selection plugin's capability API.\n * This provides methods for controlling and listening to selection events.\n */\nexport const useSelectionCapability = () => useCapability<SelectionPlugin>(SelectionPlugin.id);\n\n/**\n * Hook to get the raw selection plugin instance.\n * Useful for accessing plugin-specific properties or methods not exposed in the capability.\n */\nexport const useSelectionPlugin = () => usePlugin<SelectionPlugin>(SelectionPlugin.id);\n","<script setup lang=\"ts\">\nimport { ref, watchEffect, computed } from 'vue';\nimport { ignore, PdfErrorCode, PdfPageGeometry, Rect } from '@embedpdf/models';\nimport {\n useCursor,\n useInteractionManagerCapability,\n usePointerHandlers,\n} from '@embedpdf/plugin-interaction-manager/vue';\nimport { PointerEventHandlersWithLifecycle } from '@embedpdf/plugin-interaction-manager';\nimport { glyphAt } from '@embedpdf/plugin-selection';\nimport { useSelectionCapability } from '../hooks';\n\ninterface Props {\n pageIndex: number;\n scale: number;\n background?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n background: 'rgba(33, 150, 243)', // Default selection color\n});\n\nconst { provides: sel } = useSelectionCapability();\nconst { provides: im } = useInteractionManagerCapability();\nconst { register } = usePointerHandlers({ pageIndex: props.pageIndex });\nconst { setCursor, removeCursor } = useCursor();\n\nconst rects = ref<Rect[]>([]);\nconst boundingRect = ref<Rect | null>(null);\n\n// Subscribe to selection changes and update the rendered rectangles\nwatchEffect((onCleanup) => {\n if (sel.value) {\n const unsubscribe = sel.value.onSelectionChange(() => {\n const mode = im.value?.getActiveMode();\n if (mode === 'default') {\n rects.value = sel.value!.getHighlightRectsForPage(props.pageIndex);\n boundingRect.value = sel.value!.getBoundingRectForPage(props.pageIndex);\n } else {\n rects.value = [];\n boundingRect.value = null;\n }\n });\n onCleanup(unsubscribe);\n }\n});\n\n// Cache page geometry for faster hit-testing during pointer moves\nlet geoCache: PdfPageGeometry | undefined;\nwatchEffect((onCleanup) => {\n if (sel.value) {\n const task = sel.value.getGeometry(props.pageIndex);\n task.wait((g) => (geoCache = g), ignore);\n\n onCleanup(() => {\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'SelectionLayer unmounted',\n });\n });\n }\n});\n\nconst handlers = computed(\n (): PointerEventHandlersWithLifecycle<PointerEvent> => ({\n onPointerDown: (point, _evt, modeId) => {\n if (!sel.value || !sel.value.isEnabledForMode(modeId)) return;\n sel.value.clear();\n const task = sel.value.getGeometry(props.pageIndex);\n task.wait((geo) => {\n const g = glyphAt(geo, point);\n if (g !== -1) sel.value!.begin(props.pageIndex, g);\n }, ignore);\n },\n onPointerMove: (point, _evt, modeId) => {\n if (!sel.value || !sel.value.isEnabledForMode(modeId)) return;\n const g = geoCache ? glyphAt(geoCache, point) : -1;\n if (g !== -1) {\n setCursor('selection-text', 'text', 10);\n sel.value.update(props.pageIndex, g);\n } else {\n removeCursor('selection-text');\n }\n },\n onPointerUp: (_point, _evt, modeId) => {\n if (!sel.value || !sel.value.isEnabledForMode(modeId)) return;\n sel.value.end();\n },\n onHandlerActiveEnd: (modeId) => {\n if (!sel.value || !sel.value.isEnabledForMode(modeId)) return;\n sel.value.clear();\n },\n }),\n);\n\n// Register the pointer handlers with the interaction manager\nwatchEffect((onCleanup) => {\n if (register) {\n const cleanup = register(handlers.value);\n if (cleanup) onCleanup(cleanup);\n }\n});\n</script>\n\n<template>\n <div\n v-if=\"boundingRect\"\n :style=\"{\n position: 'absolute',\n left: `${boundingRect.origin.x * scale}px`,\n top: `${boundingRect.origin.y * scale}px`,\n width: `${boundingRect.size.width * scale}px`,\n height: `${boundingRect.size.height * scale}px`,\n mixBlendMode: 'multiply',\n isolation: 'isolate',\n pointerEvents: 'none',\n }\"\n >\n <div\n v-for=\"(rect, i) in rects\"\n :key=\"i\"\n :style=\"{\n position: 'absolute',\n left: `${(rect.origin.x - boundingRect.origin.x) * scale}px`,\n top: `${(rect.origin.y - boundingRect.origin.y) * scale}px`,\n width: `${rect.size.width * scale}px`,\n height: `${rect.size.height * scale}px`,\n background: background,\n }\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { watchEffect } from 'vue';\nimport { useSelectionCapability } from '../hooks';\n\nconst { provides: sel } = useSelectionCapability();\n\n// This effect runs when the component is mounted and the capability is available.\n// It automatically handles unsubscribing when the component is unmounted.\nwatchEffect((onCleanup) => {\n if (sel.value) {\n const unsubscribe = sel.value.onCopyToClipboard((text) => {\n // Use the Clipboard API to write the text\n navigator.clipboard.writeText(text).catch((err) => {\n console.error('Failed to copy text to clipboard:', err);\n });\n });\n\n // Register the cleanup function to run on unmount or re-run\n onCleanup(unsubscribe);\n }\n});\n</script>\n\n<template>\n <!-- This component renders nothing to the DOM -->\n</template>\n"],"names":["_createElementBlock","_normalizeStyle","scale","_openBlock","_Fragment","_renderList","background"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@embedpdf/plugin-selection",
3
- "version": "1.0.11",
3
+ "version": "1.0.12",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -20,25 +20,32 @@
20
20
  "types": "./dist/react/index.d.ts",
21
21
  "import": "./dist/react/index.js",
22
22
  "require": "./dist/react/index.cjs"
23
+ },
24
+ "./vue": {
25
+ "types": "./dist/vue/index.d.ts",
26
+ "import": "./dist/vue/index.js",
27
+ "require": "./dist/vue/index.cjs"
23
28
  }
24
29
  },
25
30
  "dependencies": {
26
- "@embedpdf/models": "1.0.11"
31
+ "@embedpdf/models": "1.0.12"
27
32
  },
28
33
  "devDependencies": {
29
34
  "@types/react": "^18.2.0",
30
- "tsup": "^8.0.0",
31
35
  "typescript": "^5.0.0",
32
- "@embedpdf/plugin-interaction-manager": "1.0.11",
33
- "@embedpdf/plugin-viewport": "1.0.11"
36
+ "@embedpdf/build": "1.0.0",
37
+ "@embedpdf/core": "1.0.12",
38
+ "@embedpdf/plugin-viewport": "1.0.12",
39
+ "@embedpdf/plugin-interaction-manager": "1.0.12"
34
40
  },
35
41
  "peerDependencies": {
36
42
  "react": ">=16.8.0",
37
43
  "react-dom": ">=16.8.0",
38
44
  "preact": "^10.26.4",
39
- "@embedpdf/core": "1.0.11",
40
- "@embedpdf/plugin-viewport": "1.0.11",
41
- "@embedpdf/plugin-interaction-manager": "1.0.11"
45
+ "vue": ">=3.2.0",
46
+ "@embedpdf/core": "1.0.12",
47
+ "@embedpdf/plugin-viewport": "1.0.12",
48
+ "@embedpdf/plugin-interaction-manager": "1.0.12"
42
49
  },
43
50
  "files": [
44
51
  "dist",
@@ -57,11 +64,13 @@
57
64
  "access": "public"
58
65
  },
59
66
  "scripts": {
60
- "build": "PROJECT_CWD=$(pwd) pnpm -w p:build",
61
- "build:watch": "PROJECT_CWD=$(pwd) pnpm -w p:build:watch",
62
- "clean": "PROJECT_CWD=$(pwd) pnpm -w p:clean",
63
- "lint": "PROJECT_CWD=$(pwd) pnpm -w p:lint",
64
- "lint:fix": "PROJECT_CWD=$(pwd) pnpm -w p:lint:fix",
65
- "typecheck": "PROJECT_CWD=$(pwd) pnpm -w p:typecheck"
67
+ "build:base": "vite build --mode base",
68
+ "build:react": "vite build --mode react",
69
+ "build:preact": "vite build --mode preact",
70
+ "build:vue": "vite build --mode vue",
71
+ "build": "pnpm run clean && concurrently -c auto -n base,react,preact,vue \"vite build --mode base\" \"vite build --mode react\" \"vite build --mode preact\" \"vite build --mode vue\"",
72
+ "clean": "rimraf dist",
73
+ "lint": "eslint src --color",
74
+ "lint:fix": "eslint src --color --fix"
66
75
  }
67
76
  }
package/dist/index.d.cts DELETED
@@ -1,210 +0,0 @@
1
- import { BasePluginConfig, EventHook, Action, BasePlugin, PluginRegistry, PluginManifest, PluginPackage } from '@embedpdf/core';
2
- import { PdfTask, PdfPageGeometry, Rect, PdfEngine, Position } from '@embedpdf/models';
3
-
4
- interface SelectionPluginConfig extends BasePluginConfig {
5
- }
6
- interface GlyphPointer {
7
- page: number;
8
- index: number;
9
- }
10
- interface SelectionRangeX {
11
- start: GlyphPointer;
12
- end: GlyphPointer;
13
- }
14
- interface SelectionState {
15
- /** page → geometry cache */
16
- geometry: Record<number, PdfPageGeometry>;
17
- /** current selection or null */
18
- rects: Record<number, Rect[]>;
19
- selection: SelectionRangeX | null;
20
- slices: Record<number, {
21
- start: number;
22
- count: number;
23
- }>;
24
- active: boolean;
25
- selecting: boolean;
26
- }
27
- interface FormattedSelection {
28
- pageIndex: number;
29
- rect: Rect;
30
- segmentRects: Rect[];
31
- }
32
- interface SelectionCapability {
33
- getGeometry(page: number): PdfTask<PdfPageGeometry>;
34
- getFormattedSelection(): FormattedSelection[];
35
- getFormattedSelectionForPage(page: number): FormattedSelection | null;
36
- getHighlightRectsForPage(page: number): Rect[];
37
- getHighlightRects(): Record<number, Rect[]>;
38
- getBoundingRectForPage(page: number): Rect | null;
39
- getBoundingRects(): {
40
- page: number;
41
- rect: Rect;
42
- }[];
43
- getSelectedText(): PdfTask<string[]>;
44
- copyToClipboard(): void;
45
- begin(page: number, glyphIdx: number): void;
46
- update(page: number, glyphIdx: number): void;
47
- end(): void;
48
- clear(): void;
49
- onSelectionChange: EventHook<SelectionRangeX | null>;
50
- onTextRetrieved: EventHook<string[]>;
51
- onCopyToClipboard: EventHook<string>;
52
- onBeginSelection: EventHook<{
53
- page: number;
54
- index: number;
55
- }>;
56
- onEndSelection: EventHook<void>;
57
- /** Tell the selection plugin that text selection should stay
58
- enabled while <modeId> is active. */
59
- enableForMode(modeId: string): void;
60
- /** Quick check used by SelectionLayer during pointer events. */
61
- isEnabledForMode(modeId: string): boolean;
62
- /** Get the current state of the selection plugin. */
63
- getState(): SelectionState;
64
- }
65
-
66
- declare const CACHE_PAGE_GEOMETRY = "CACHE_PAGE_GEOMETRY";
67
- declare const SET_SELECTION = "SET_SELECTION";
68
- declare const START_SELECTION = "START_SELECTION";
69
- declare const END_SELECTION = "END_SELECTION";
70
- declare const CLEAR_SELECTION = "CLEAR_SELECTION";
71
- declare const SET_RECTS = "SET_RECTS";
72
- declare const SET_SLICES = "SET_SLICES";
73
- declare const RESET = "RESET";
74
- interface CachePageGeometryAction extends Action {
75
- type: typeof CACHE_PAGE_GEOMETRY;
76
- payload: {
77
- page: number;
78
- geo: PdfPageGeometry;
79
- };
80
- }
81
- interface SetSelectionAction extends Action {
82
- type: typeof SET_SELECTION;
83
- payload: SelectionRangeX | null;
84
- }
85
- interface StartSelectionAction extends Action {
86
- type: typeof START_SELECTION;
87
- }
88
- interface EndSelectionAction extends Action {
89
- type: typeof END_SELECTION;
90
- }
91
- interface ClearSelectionAction extends Action {
92
- type: typeof CLEAR_SELECTION;
93
- }
94
- interface SetRectsAction extends Action {
95
- type: typeof SET_RECTS;
96
- payload: Record<number, Rect[]>;
97
- }
98
- interface SetSlicesAction extends Action {
99
- type: typeof SET_SLICES;
100
- payload: Record<number, {
101
- start: number;
102
- count: number;
103
- }>;
104
- }
105
- interface ResetAction extends Action {
106
- type: typeof RESET;
107
- }
108
- type SelectionAction = CachePageGeometryAction | SetSelectionAction | StartSelectionAction | EndSelectionAction | ClearSelectionAction | SetRectsAction | SetSlicesAction | ResetAction;
109
-
110
- declare class SelectionPlugin extends BasePlugin<SelectionPluginConfig, SelectionCapability, SelectionState, SelectionAction> {
111
- private engine;
112
- static readonly id: "selection";
113
- /** Modes that should trigger text-selection logic */
114
- private enabledModes;
115
- private selecting;
116
- private anchor?;
117
- private readonly selChange$;
118
- private readonly textRetrieved$;
119
- private readonly copyToClipboard$;
120
- private readonly beginSelection$;
121
- private readonly endSelection$;
122
- constructor(id: string, registry: PluginRegistry, engine: PdfEngine);
123
- initialize(): Promise<void>;
124
- destroy(): Promise<void>;
125
- buildCapability(): SelectionCapability;
126
- private getOrLoadGeometry;
127
- private beginSelection;
128
- private endSelection;
129
- private clearSelection;
130
- private updateSelection;
131
- private updateRectsAndSlices;
132
- private getSelectedText;
133
- private copyToClipboard;
134
- }
135
-
136
- declare const SELECTION_PLUGIN_ID = "selection";
137
- declare const manifest: PluginManifest<SelectionPluginConfig>;
138
-
139
- /**
140
- * Hit-test helper using runs
141
- * @param geo - page geometry
142
- * @param pt - point
143
- * @returns glyph index
144
- */
145
- declare function glyphAt(geo: PdfPageGeometry, pt: Position): number;
146
- /**
147
- * Helper: min/max glyph indices on `page` for current sel
148
- * @param sel - selection range
149
- * @param geo - page geometry
150
- * @param page - page index
151
- * @returns { from: number; to: number } | null
152
- */
153
- declare function sliceBounds(sel: SelectionRangeX | null, geo: PdfPageGeometry | undefined, page: number): {
154
- from: number;
155
- to: number;
156
- } | null;
157
- /**
158
- * Helper: build rects for a slice of the page
159
- * @param geo - page geometry
160
- * @param from - from index
161
- * @param to - to index
162
- * @param merge - whether to merge adjacent rects (default: true)
163
- * @returns rects
164
- */
165
- declare function rectsWithinSlice(geo: PdfPageGeometry, from: number, to: number, merge?: boolean): Rect[];
166
- /**
167
- * ============================================================================
168
- * Rectangle Merging Algorithm
169
- * ============================================================================
170
- *
171
- * The following code is adapted from Chromium's PDF text selection implementation.
172
- *
173
- * Copyright 2010 The Chromium Authors
174
- * Use of this source code is governed by a BSD-style license that can be
175
- * found in the LICENSE file: https://source.chromium.org/chromium/chromium/src/+/main:LICENSE
176
- *
177
- * Original source:
178
- * https://source.chromium.org/chromium/chromium/src/+/main:pdf/pdfium/pdfium_range.cc
179
- *
180
- * Adapted for TypeScript and this project's Rect/geometry types.
181
- */
182
- /**
183
- * Text run info for rect merging (similar to Chromium's ScreenRectTextRunInfo)
184
- */
185
- interface TextRunInfo {
186
- rect: Rect;
187
- charCount: number;
188
- }
189
- /**
190
- * Helper functions for Rect operations
191
- */
192
- declare function rectUnion(rect1: Rect, rect2: Rect): Rect;
193
- declare function rectIntersect(rect1: Rect, rect2: Rect): Rect;
194
- declare function rectIsEmpty(rect: Rect): boolean;
195
- /**
196
- * Returns a ratio between [0, 1] representing vertical overlap
197
- */
198
- declare function getVerticalOverlap(rect1: Rect, rect2: Rect): number;
199
- /**
200
- * Returns true if there is sufficient horizontal and vertical overlap
201
- */
202
- declare function shouldMergeHorizontalRects(textRun1: TextRunInfo, textRun2: TextRunInfo): boolean;
203
- /**
204
- * Merge adjacent rectangles based on proximity and overlap (similar to Chromium's algorithm)
205
- */
206
- declare function mergeAdjacentRects(textRuns: TextRunInfo[]): Rect[];
207
-
208
- declare const SelectionPluginPackage: PluginPackage<SelectionPlugin, SelectionPluginConfig, SelectionState, SelectionAction>;
209
-
210
- export { type FormattedSelection, type GlyphPointer, SELECTION_PLUGIN_ID, type SelectionCapability, SelectionPlugin, type SelectionPluginConfig, SelectionPluginPackage, type SelectionRangeX, type SelectionState, type TextRunInfo, getVerticalOverlap, glyphAt, manifest, mergeAdjacentRects, rectIntersect, rectIsEmpty, rectUnion, rectsWithinSlice, shouldMergeHorizontalRects, sliceBounds };
@@ -1,25 +0,0 @@
1
- import * as _embedpdf_plugin_selection from '@embedpdf/plugin-selection';
2
- import { SelectionPlugin } from '@embedpdf/plugin-selection';
3
- import * as preact from 'preact';
4
-
5
- declare const useSelectionCapability: () => {
6
- provides: Readonly<_embedpdf_plugin_selection.SelectionCapability> | null;
7
- isLoading: boolean;
8
- ready: Promise<void>;
9
- };
10
- declare const useSelectionPlugin: () => {
11
- plugin: SelectionPlugin | null;
12
- isLoading: boolean;
13
- ready: Promise<void>;
14
- };
15
-
16
- type Props = {
17
- pageIndex: number;
18
- scale: number;
19
- background?: string;
20
- };
21
- declare function SelectionLayer({ pageIndex, scale, background }: Props): preact.JSX.Element | null;
22
-
23
- declare function CopyToClipboard(): null;
24
-
25
- export { CopyToClipboard, SelectionLayer, useSelectionCapability, useSelectionPlugin };
@@ -1,25 +0,0 @@
1
- import * as _embedpdf_plugin_selection from '@embedpdf/plugin-selection';
2
- import { SelectionPlugin } from '@embedpdf/plugin-selection';
3
- import * as react_jsx_runtime from 'react/jsx-runtime';
4
-
5
- declare const useSelectionCapability: () => {
6
- provides: Readonly<_embedpdf_plugin_selection.SelectionCapability> | null;
7
- isLoading: boolean;
8
- ready: Promise<void>;
9
- };
10
- declare const useSelectionPlugin: () => {
11
- plugin: SelectionPlugin | null;
12
- isLoading: boolean;
13
- ready: Promise<void>;
14
- };
15
-
16
- type Props = {
17
- pageIndex: number;
18
- scale: number;
19
- background?: string;
20
- };
21
- declare function SelectionLayer({ pageIndex, scale, background }: Props): react_jsx_runtime.JSX.Element | null;
22
-
23
- declare function CopyToClipboard(): null;
24
-
25
- export { CopyToClipboard, SelectionLayer, useSelectionCapability, useSelectionPlugin };