pdf-search-highlight 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +112 -9
- package/dist/{PDFSearchViewer-rNp5NirR.d.cts → PDFSearchViewer-DzKHoKTp.d.cts} +52 -27
- package/dist/{PDFSearchViewer-rNp5NirR.d.ts → PDFSearchViewer-DzKHoKTp.d.ts} +52 -27
- package/dist/{chunk-Y5LFTIMY.cjs → chunk-GDUHZCFR.cjs} +158 -12
- package/dist/chunk-GDUHZCFR.cjs.map +1 -0
- package/dist/{chunk-AA4UECNB.js → chunk-XFH7JUDJ.js} +151 -5
- package/dist/chunk-XFH7JUDJ.js.map +1 -0
- package/dist/core/index.cjs +4 -2
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +21 -4
- package/dist/core/index.d.ts +21 -4
- package/dist/core/index.js +3 -1
- package/dist/pdf-search-highlight.css +27 -1
- package/dist/react/index.cjs +36 -24
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +16 -4
- package/dist/react/index.d.ts +16 -4
- package/dist/react/index.js +18 -6
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-AA4UECNB.js.map +0 -1
- package/dist/chunk-Y5LFTIMY.cjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# pdf-search-highlight
|
|
2
2
|
|
|
3
|
-
PDF viewer with text search and highlight. Render PDF, search text with flexible whitespace matching or fuzzy (approximate) matching, and navigate between highlighted results. Zoom in/out and download PDF files.
|
|
3
|
+
PDF viewer with text search and highlight. Render PDF, search text with flexible whitespace matching or fuzzy (approximate) matching, and navigate between highlighted results. Supports multi-context search with different highlight colors. Zoom in/out and download PDF files.
|
|
4
4
|
|
|
5
5
|
Built on [pdf.js](https://mozilla.github.io/pdf.js/). Works with Vanilla JS and React.
|
|
6
6
|
|
|
@@ -15,6 +15,7 @@ npm install pdf-search-highlight pdfjs-dist
|
|
|
15
15
|
- Render PDF pages (canvas + text layer)
|
|
16
16
|
- Search with flexible whitespace matching — handles inconsistent PDF text splitting
|
|
17
17
|
- Fuzzy (approximate) search — find text even with typos or OCR errors
|
|
18
|
+
- **Multi-context search** — search multiple queries simultaneously, each highlighted with a different color
|
|
18
19
|
- Cross-span highlight using `<mark>` elements
|
|
19
20
|
- Navigate between matches (next/prev, auto-scroll)
|
|
20
21
|
- Zoom in/out with configurable scale
|
|
@@ -52,6 +53,19 @@ search.next();
|
|
|
52
53
|
search.prev();
|
|
53
54
|
search.clear();
|
|
54
55
|
|
|
56
|
+
// Multi-context search — each query gets a different highlight color
|
|
57
|
+
search.searchMultiple([
|
|
58
|
+
{ query: 'contract' },
|
|
59
|
+
{ query: 'payment' },
|
|
60
|
+
{ query: 'deadline' },
|
|
61
|
+
]);
|
|
62
|
+
|
|
63
|
+
// With per-context options
|
|
64
|
+
search.searchMultiple([
|
|
65
|
+
{ query: 'contract' },
|
|
66
|
+
{ query: 'payement', options: { fuzzy: true, fuzzyThreshold: 0.7 } },
|
|
67
|
+
]);
|
|
68
|
+
|
|
55
69
|
// Zoom
|
|
56
70
|
renderer.setScale(1.5);
|
|
57
71
|
const newPages = await renderer.renderAllPages();
|
|
@@ -76,6 +90,14 @@ await viewer.loadPDF(file);
|
|
|
76
90
|
viewer.search('query');
|
|
77
91
|
viewer.nextMatch();
|
|
78
92
|
|
|
93
|
+
// Multi-context search
|
|
94
|
+
viewer.searchMultiple([
|
|
95
|
+
{ query: 'contract' },
|
|
96
|
+
{ query: 'payment' },
|
|
97
|
+
{ query: 'deadline' },
|
|
98
|
+
]);
|
|
99
|
+
viewer.nextMatch(); // navigates through ALL matches in document order
|
|
100
|
+
|
|
79
101
|
// Zoom
|
|
80
102
|
await viewer.zoomIn();
|
|
81
103
|
await viewer.zoomOut();
|
|
@@ -87,6 +109,9 @@ await viewer.download('document.pdf');
|
|
|
87
109
|
// Events
|
|
88
110
|
viewer.on('load', ({ pageCount }) => console.log('Pages:', pageCount));
|
|
89
111
|
viewer.on('search', ({ query, total }) => console.log('Found:', total));
|
|
112
|
+
viewer.on('searchmultiple', ({ contexts, total, totalsPerContext }) => {
|
|
113
|
+
console.log('Multi-search:', total, 'total matches');
|
|
114
|
+
});
|
|
90
115
|
viewer.on('matchchange', ({ current, total }) => console.log(`${current + 1}/${total}`));
|
|
91
116
|
viewer.on('zoom', ({ scale }) => console.log('Scale:', scale));
|
|
92
117
|
viewer.on('error', ({ error, context }) => console.error(context, error));
|
|
@@ -101,16 +126,25 @@ import 'pdf-search-highlight/styles.css';
|
|
|
101
126
|
function App() {
|
|
102
127
|
const { containerRef, pages, loadPDF, zoomIn, zoomOut, download, scale } =
|
|
103
128
|
usePDFRenderer(pdfjsLib);
|
|
104
|
-
const { search, next, prev, current, total } =
|
|
129
|
+
const { search, searchMultiple, next, prev, current, total } =
|
|
130
|
+
useSearchController(pages);
|
|
105
131
|
|
|
106
132
|
return (
|
|
107
133
|
<>
|
|
108
|
-
{/*
|
|
134
|
+
{/* Single search */}
|
|
109
135
|
<input onChange={e => search(e.target.value)} />
|
|
110
136
|
<span>{total > 0 ? `${current + 1}/${total}` : ''}</span>
|
|
111
137
|
<button onClick={prev}>Prev</button>
|
|
112
138
|
<button onClick={next}>Next</button>
|
|
113
139
|
|
|
140
|
+
{/* Multi-context search */}
|
|
141
|
+
<button onClick={() => searchMultiple([
|
|
142
|
+
{ query: 'contract' },
|
|
143
|
+
{ query: 'payment' },
|
|
144
|
+
])}>
|
|
145
|
+
Search Multiple
|
|
146
|
+
</button>
|
|
147
|
+
|
|
114
148
|
{/* Zoom & download */}
|
|
115
149
|
<button onClick={zoomOut}>-</button>
|
|
116
150
|
<button onClick={zoomIn}>+</button>
|
|
@@ -139,8 +173,11 @@ function App() {
|
|
|
139
173
|
pdfjsLib={pdfjsLib}
|
|
140
174
|
source={file}
|
|
141
175
|
searchQuery={query}
|
|
176
|
+
// OR multi-context search:
|
|
177
|
+
// searchContexts={[{ query: 'contract' }, { query: 'payment' }]}
|
|
142
178
|
onLoad={({ pageCount }) => console.log('Pages:', pageCount)}
|
|
143
179
|
onSearch={({ query, total }) => console.log('Found:', total)}
|
|
180
|
+
onSearchMultiple={({ contexts, total }) => console.log('Multi:', total)}
|
|
144
181
|
onMatchChange={({ current, total }) => console.log(`${current + 1}/${total}`)}
|
|
145
182
|
onZoom={({ scale }) => console.log('Scale:', scale)}
|
|
146
183
|
style={{ height: '80vh', overflow: 'auto' }}
|
|
@@ -149,6 +186,7 @@ function App() {
|
|
|
149
186
|
|
|
150
187
|
// Imperative access via ref
|
|
151
188
|
// ref.current.nextMatch()
|
|
189
|
+
// ref.current.searchMultiple([{ query: 'a' }, { query: 'b' }])
|
|
152
190
|
// ref.current.zoomIn()
|
|
153
191
|
// ref.current.download('doc.pdf')
|
|
154
192
|
}
|
|
@@ -171,7 +209,7 @@ function App() {
|
|
|
171
209
|
| Export | Description |
|
|
172
210
|
|---|---|
|
|
173
211
|
| `usePDFRenderer(pdfjsLib, options?)` | Hook: render PDF, returns `{ containerRef, pages, loadPDF, scale, setScale, zoomIn, zoomOut, download, ... }` |
|
|
174
|
-
| `useSearchController(pages, options?)` | Hook: search + highlight, returns `{ search, next, prev, goTo, clear, current, total }` |
|
|
212
|
+
| `useSearchController(pages, options?)` | Hook: search + highlight, returns `{ search, searchMultiple, next, prev, goTo, clear, current, total }` |
|
|
175
213
|
| `PDFSearchViewer` | All-in-one component with ref handle for imperative control |
|
|
176
214
|
|
|
177
215
|
### PDFRenderer
|
|
@@ -200,17 +238,28 @@ const search = new SearchController({
|
|
|
200
238
|
});
|
|
201
239
|
|
|
202
240
|
search.setPages(pages);
|
|
241
|
+
|
|
242
|
+
// Single search
|
|
203
243
|
search.search('query', { caseSensitive: false, flexibleWhitespace: true });
|
|
204
244
|
search.search('query', { fuzzy: true, fuzzyThreshold: 0.6 });
|
|
245
|
+
|
|
246
|
+
// Multi-context search
|
|
247
|
+
search.searchMultiple([
|
|
248
|
+
{ query: 'contract' },
|
|
249
|
+
{ query: 'payment' },
|
|
250
|
+
{ query: 'deadline', options: { fuzzy: true } },
|
|
251
|
+
]);
|
|
252
|
+
|
|
205
253
|
search.next();
|
|
206
254
|
search.prev();
|
|
207
255
|
search.goTo(5);
|
|
208
256
|
search.clear();
|
|
209
257
|
search.onChange = ({ current, total, query }) => {};
|
|
210
258
|
|
|
211
|
-
search.current
|
|
212
|
-
search.total
|
|
213
|
-
search.query
|
|
259
|
+
search.current // current match index
|
|
260
|
+
search.total // total matches
|
|
261
|
+
search.query // last single query
|
|
262
|
+
search.contexts // last multi-context queries
|
|
214
263
|
```
|
|
215
264
|
|
|
216
265
|
### PDFSearchViewer (Core)
|
|
@@ -220,6 +269,13 @@ const viewer = new PDFSearchViewer(container, pdfjsLib, options);
|
|
|
220
269
|
|
|
221
270
|
await viewer.loadPDF(source);
|
|
222
271
|
viewer.search('query', { caseSensitive: true });
|
|
272
|
+
|
|
273
|
+
// Multi-context search
|
|
274
|
+
viewer.searchMultiple([
|
|
275
|
+
{ query: 'contract' },
|
|
276
|
+
{ query: 'payment' },
|
|
277
|
+
]);
|
|
278
|
+
|
|
223
279
|
viewer.nextMatch();
|
|
224
280
|
viewer.prevMatch();
|
|
225
281
|
viewer.clearSearch();
|
|
@@ -233,6 +289,7 @@ await viewer.download('file.pdf'); // Download PDF
|
|
|
233
289
|
|
|
234
290
|
viewer.on('load', (data) => {}); // { pageCount }
|
|
235
291
|
viewer.on('search', (data) => {}); // { query, total }
|
|
292
|
+
viewer.on('searchmultiple', (data) => {}); // { contexts, total, totalsPerContext }
|
|
236
293
|
viewer.on('matchchange', (data) => {}); // { current, total }
|
|
237
294
|
viewer.on('zoom', (data) => {}); // { scale }
|
|
238
295
|
viewer.on('error', (data) => {}); // { error, context }
|
|
@@ -256,8 +313,42 @@ interface SearchOptions {
|
|
|
256
313
|
fuzzy?: boolean; // Default: false — enable approximate matching
|
|
257
314
|
fuzzyThreshold?: number; // Default: 0.6 — similarity 0.0–1.0
|
|
258
315
|
}
|
|
316
|
+
|
|
317
|
+
interface SearchContext {
|
|
318
|
+
query: string; // The search query
|
|
319
|
+
options?: SearchOptions; // Optional per-context overrides
|
|
320
|
+
}
|
|
259
321
|
```
|
|
260
322
|
|
|
323
|
+
### Multi-Context Search
|
|
324
|
+
|
|
325
|
+
Search for multiple terms simultaneously, each highlighted with a different color:
|
|
326
|
+
|
|
327
|
+
```js
|
|
328
|
+
// Each context gets an auto-assigned color (highlight-0 through highlight-7, cycles)
|
|
329
|
+
search.searchMultiple([
|
|
330
|
+
{ query: 'contract' }, // Yellow
|
|
331
|
+
{ query: 'payment' }, // Cyan
|
|
332
|
+
{ query: 'deadline' }, // Green
|
|
333
|
+
{ query: 'penalty' }, // Orange
|
|
334
|
+
]);
|
|
335
|
+
|
|
336
|
+
// Per-context options override shared options
|
|
337
|
+
search.searchMultiple(
|
|
338
|
+
[
|
|
339
|
+
{ query: 'contract' },
|
|
340
|
+
{ query: 'payement', options: { fuzzy: true, fuzzyThreshold: 0.7 } },
|
|
341
|
+
],
|
|
342
|
+
{ caseSensitive: false } // shared options
|
|
343
|
+
);
|
|
344
|
+
|
|
345
|
+
// Navigate through ALL matches in document order
|
|
346
|
+
search.next(); // goes to next match regardless of which context
|
|
347
|
+
search.prev(); // goes to previous match
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
8 colors are provided by default (CSS classes `highlight-0` through `highlight-7`). Colors cycle for more than 8 contexts.
|
|
351
|
+
|
|
261
352
|
### Custom CSS
|
|
262
353
|
|
|
263
354
|
Override any class name:
|
|
@@ -279,12 +370,23 @@ const renderer = new PDFRenderer(container, {
|
|
|
279
370
|
Default styles:
|
|
280
371
|
|
|
281
372
|
```css
|
|
373
|
+
/* Single search */
|
|
282
374
|
.highlight {
|
|
283
375
|
background: rgba(255, 230, 0, 0.45) !important;
|
|
284
376
|
}
|
|
285
377
|
.highlight.active {
|
|
286
378
|
background: rgba(233, 69, 96, 0.55) !important;
|
|
287
379
|
}
|
|
380
|
+
|
|
381
|
+
/* Multi-context search (8 colors) */
|
|
382
|
+
.highlight-0 { /* Yellow */ }
|
|
383
|
+
.highlight-1 { /* Cyan */ }
|
|
384
|
+
.highlight-2 { /* Green */ }
|
|
385
|
+
.highlight-3 { /* Orange */ }
|
|
386
|
+
.highlight-4 { /* Purple */ }
|
|
387
|
+
.highlight-5 { /* Pink */ }
|
|
388
|
+
.highlight-6 { /* Blue */ }
|
|
389
|
+
.highlight-7 { /* Lime */ }
|
|
288
390
|
```
|
|
289
391
|
|
|
290
392
|
## How it works
|
|
@@ -294,8 +396,9 @@ Default styles:
|
|
|
294
396
|
3. **Flexible whitespace**: Query `"and expensive"` becomes regex `a\s*n\s*d\s*e\s*x\s*p\s*e\s*n\s*s\s*i\s*v\s*e` — matches regardless of whitespace differences in PDF text
|
|
295
397
|
4. **Fuzzy search**: Semi-global Levenshtein alignment finds substrings within edit distance ≤ `queryLength × (1 - threshold)` — handles typos, OCR errors, and garbled text extraction
|
|
296
398
|
5. **Highlight**: Regex/fuzzy matches on concatenated text → charMap maps back to spans → split span DOM into text nodes + `<mark>` elements
|
|
297
|
-
6. **
|
|
298
|
-
7. **
|
|
399
|
+
6. **Multi-context**: Each context runs independently, matches are sorted by document position, and each context's `<mark>` elements receive a distinct CSS class (`highlight-0`, `highlight-1`, ...)
|
|
400
|
+
7. **Navigate**: Prev/next with wrap-around, auto-scroll to active match — in multi-context mode, navigation cycles through all matches across all contexts
|
|
401
|
+
8. **Zoom**: Re-renders all pages at new scale, search highlights are automatically re-applied
|
|
299
402
|
|
|
300
403
|
## License
|
|
301
404
|
|
|
@@ -70,32 +70,6 @@ interface SearchOptions {
|
|
|
70
70
|
fuzzyThreshold?: number;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
type PDFSearchViewerEventMap = {
|
|
74
|
-
/** Fired when PDF finishes loading. */
|
|
75
|
-
load: {
|
|
76
|
-
pageCount: number;
|
|
77
|
-
};
|
|
78
|
-
/** Fired when a search completes. */
|
|
79
|
-
search: {
|
|
80
|
-
query: string;
|
|
81
|
-
total: number;
|
|
82
|
-
};
|
|
83
|
-
/** Fired when active match changes (via next/prev). */
|
|
84
|
-
matchchange: {
|
|
85
|
-
current: number;
|
|
86
|
-
total: number;
|
|
87
|
-
};
|
|
88
|
-
/** Fired when zoom/scale changes. */
|
|
89
|
-
zoom: {
|
|
90
|
-
scale: number;
|
|
91
|
-
};
|
|
92
|
-
/** Fired on error. */
|
|
93
|
-
error: {
|
|
94
|
-
error: Error;
|
|
95
|
-
context: string;
|
|
96
|
-
};
|
|
97
|
-
};
|
|
98
|
-
|
|
99
73
|
/**
|
|
100
74
|
* A single search match, potentially spanning multiple spans.
|
|
101
75
|
* Each match contains an array of <mark> elements that highlight
|
|
@@ -125,6 +99,48 @@ interface PageData {
|
|
|
125
99
|
/** All text spans on this page. */
|
|
126
100
|
spans: SpanData[];
|
|
127
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* A single search context for multi-context search.
|
|
104
|
+
* Each context represents a separate query highlighted with a distinct color.
|
|
105
|
+
*/
|
|
106
|
+
interface SearchContext {
|
|
107
|
+
/** The query string to search for. */
|
|
108
|
+
query: string;
|
|
109
|
+
/** Optional per-context search options (overrides shared options). */
|
|
110
|
+
options?: SearchOptions;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
type PDFSearchViewerEventMap = {
|
|
114
|
+
/** Fired when PDF finishes loading. */
|
|
115
|
+
load: {
|
|
116
|
+
pageCount: number;
|
|
117
|
+
};
|
|
118
|
+
/** Fired when a search completes. */
|
|
119
|
+
search: {
|
|
120
|
+
query: string;
|
|
121
|
+
total: number;
|
|
122
|
+
};
|
|
123
|
+
/** Fired when a multi-context search completes. */
|
|
124
|
+
searchmultiple: {
|
|
125
|
+
contexts: SearchContext[];
|
|
126
|
+
total: number;
|
|
127
|
+
totalsPerContext: number[];
|
|
128
|
+
};
|
|
129
|
+
/** Fired when active match changes (via next/prev). */
|
|
130
|
+
matchchange: {
|
|
131
|
+
current: number;
|
|
132
|
+
total: number;
|
|
133
|
+
};
|
|
134
|
+
/** Fired when zoom/scale changes. */
|
|
135
|
+
zoom: {
|
|
136
|
+
scale: number;
|
|
137
|
+
};
|
|
138
|
+
/** Fired on error. */
|
|
139
|
+
error: {
|
|
140
|
+
error: Error;
|
|
141
|
+
context: string;
|
|
142
|
+
};
|
|
143
|
+
};
|
|
128
144
|
|
|
129
145
|
type PDFSource = File | ArrayBuffer | Uint8Array | string;
|
|
130
146
|
/**
|
|
@@ -153,6 +169,8 @@ declare class PDFSearchViewer extends EventEmitter<PDFSearchViewerEventMap> {
|
|
|
153
169
|
private pageData;
|
|
154
170
|
private lastQuery;
|
|
155
171
|
private lastSearchOptions;
|
|
172
|
+
private lastContexts;
|
|
173
|
+
private lastIsMultiContext;
|
|
156
174
|
private destroyed;
|
|
157
175
|
constructor(container: HTMLElement, pdfjsLib: any, options?: PDFSearchViewerOptions);
|
|
158
176
|
/**
|
|
@@ -164,6 +182,13 @@ declare class PDFSearchViewer extends EventEmitter<PDFSearchViewerEventMap> {
|
|
|
164
182
|
* Clears previous highlights and creates new ones.
|
|
165
183
|
*/
|
|
166
184
|
search(query: string, options?: SearchOptions): number;
|
|
185
|
+
/**
|
|
186
|
+
* Search for multiple query contexts across all pages.
|
|
187
|
+
* Each context is highlighted with a different color (highlight-0, highlight-1, ...).
|
|
188
|
+
* Navigation (nextMatch/prevMatch) cycles through ALL matches in document order.
|
|
189
|
+
* Returns total number of matches across all contexts.
|
|
190
|
+
*/
|
|
191
|
+
searchMultiple(contexts: SearchContext[], sharedOptions?: SearchOptions): number;
|
|
167
192
|
/**
|
|
168
193
|
* Navigate to next match (wraps around).
|
|
169
194
|
*/
|
|
@@ -206,4 +231,4 @@ declare class PDFSearchViewer extends EventEmitter<PDFSearchViewerEventMap> {
|
|
|
206
231
|
destroy(): void;
|
|
207
232
|
}
|
|
208
233
|
|
|
209
|
-
export { type ClassNames as C, EventEmitter as E, type PageData as P, type SearchOptions as S, type
|
|
234
|
+
export { type ClassNames as C, EventEmitter as E, type PageData as P, type SearchOptions as S, type SearchContext as a, type PDFSearchViewerOptions as b, type SpanData as c, type SearchMatch as d, PDFSearchViewer as e, type PDFSearchViewerEventMap as f, type PDFSource as g };
|
|
@@ -70,32 +70,6 @@ interface SearchOptions {
|
|
|
70
70
|
fuzzyThreshold?: number;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
type PDFSearchViewerEventMap = {
|
|
74
|
-
/** Fired when PDF finishes loading. */
|
|
75
|
-
load: {
|
|
76
|
-
pageCount: number;
|
|
77
|
-
};
|
|
78
|
-
/** Fired when a search completes. */
|
|
79
|
-
search: {
|
|
80
|
-
query: string;
|
|
81
|
-
total: number;
|
|
82
|
-
};
|
|
83
|
-
/** Fired when active match changes (via next/prev). */
|
|
84
|
-
matchchange: {
|
|
85
|
-
current: number;
|
|
86
|
-
total: number;
|
|
87
|
-
};
|
|
88
|
-
/** Fired when zoom/scale changes. */
|
|
89
|
-
zoom: {
|
|
90
|
-
scale: number;
|
|
91
|
-
};
|
|
92
|
-
/** Fired on error. */
|
|
93
|
-
error: {
|
|
94
|
-
error: Error;
|
|
95
|
-
context: string;
|
|
96
|
-
};
|
|
97
|
-
};
|
|
98
|
-
|
|
99
73
|
/**
|
|
100
74
|
* A single search match, potentially spanning multiple spans.
|
|
101
75
|
* Each match contains an array of <mark> elements that highlight
|
|
@@ -125,6 +99,48 @@ interface PageData {
|
|
|
125
99
|
/** All text spans on this page. */
|
|
126
100
|
spans: SpanData[];
|
|
127
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* A single search context for multi-context search.
|
|
104
|
+
* Each context represents a separate query highlighted with a distinct color.
|
|
105
|
+
*/
|
|
106
|
+
interface SearchContext {
|
|
107
|
+
/** The query string to search for. */
|
|
108
|
+
query: string;
|
|
109
|
+
/** Optional per-context search options (overrides shared options). */
|
|
110
|
+
options?: SearchOptions;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
type PDFSearchViewerEventMap = {
|
|
114
|
+
/** Fired when PDF finishes loading. */
|
|
115
|
+
load: {
|
|
116
|
+
pageCount: number;
|
|
117
|
+
};
|
|
118
|
+
/** Fired when a search completes. */
|
|
119
|
+
search: {
|
|
120
|
+
query: string;
|
|
121
|
+
total: number;
|
|
122
|
+
};
|
|
123
|
+
/** Fired when a multi-context search completes. */
|
|
124
|
+
searchmultiple: {
|
|
125
|
+
contexts: SearchContext[];
|
|
126
|
+
total: number;
|
|
127
|
+
totalsPerContext: number[];
|
|
128
|
+
};
|
|
129
|
+
/** Fired when active match changes (via next/prev). */
|
|
130
|
+
matchchange: {
|
|
131
|
+
current: number;
|
|
132
|
+
total: number;
|
|
133
|
+
};
|
|
134
|
+
/** Fired when zoom/scale changes. */
|
|
135
|
+
zoom: {
|
|
136
|
+
scale: number;
|
|
137
|
+
};
|
|
138
|
+
/** Fired on error. */
|
|
139
|
+
error: {
|
|
140
|
+
error: Error;
|
|
141
|
+
context: string;
|
|
142
|
+
};
|
|
143
|
+
};
|
|
128
144
|
|
|
129
145
|
type PDFSource = File | ArrayBuffer | Uint8Array | string;
|
|
130
146
|
/**
|
|
@@ -153,6 +169,8 @@ declare class PDFSearchViewer extends EventEmitter<PDFSearchViewerEventMap> {
|
|
|
153
169
|
private pageData;
|
|
154
170
|
private lastQuery;
|
|
155
171
|
private lastSearchOptions;
|
|
172
|
+
private lastContexts;
|
|
173
|
+
private lastIsMultiContext;
|
|
156
174
|
private destroyed;
|
|
157
175
|
constructor(container: HTMLElement, pdfjsLib: any, options?: PDFSearchViewerOptions);
|
|
158
176
|
/**
|
|
@@ -164,6 +182,13 @@ declare class PDFSearchViewer extends EventEmitter<PDFSearchViewerEventMap> {
|
|
|
164
182
|
* Clears previous highlights and creates new ones.
|
|
165
183
|
*/
|
|
166
184
|
search(query: string, options?: SearchOptions): number;
|
|
185
|
+
/**
|
|
186
|
+
* Search for multiple query contexts across all pages.
|
|
187
|
+
* Each context is highlighted with a different color (highlight-0, highlight-1, ...).
|
|
188
|
+
* Navigation (nextMatch/prevMatch) cycles through ALL matches in document order.
|
|
189
|
+
* Returns total number of matches across all contexts.
|
|
190
|
+
*/
|
|
191
|
+
searchMultiple(contexts: SearchContext[], sharedOptions?: SearchOptions): number;
|
|
167
192
|
/**
|
|
168
193
|
* Navigate to next match (wraps around).
|
|
169
194
|
*/
|
|
@@ -206,4 +231,4 @@ declare class PDFSearchViewer extends EventEmitter<PDFSearchViewerEventMap> {
|
|
|
206
231
|
destroy(): void;
|
|
207
232
|
}
|
|
208
233
|
|
|
209
|
-
export { type ClassNames as C, EventEmitter as E, type PageData as P, type SearchOptions as S, type
|
|
234
|
+
export { type ClassNames as C, EventEmitter as E, type PageData as P, type SearchOptions as S, type SearchContext as a, type PDFSearchViewerOptions as b, type SpanData as c, type SearchMatch as d, PDFSearchViewer as e, type PDFSearchViewerEventMap as f, type PDFSource as g };
|