|
36 | 36 | TilingLayer, |
37 | 37 | TilingPluginPackage |
38 | 38 | } from '@embedpdf/plugin-tiling/svelte'; |
| 39 | + import { |
| 40 | + SearchLayer, |
| 41 | + SearchPluginPackage |
| 42 | + } from '@embedpdf/plugin-search/svelte'; |
39 | 43 |
|
40 | 44 | import { SettingsStore } from './stores.ts'; |
41 | 45 | import PDFPluginLoader from './PDFPluginLoader.svelte'; |
42 | 46 | import type { |
43 | 47 | ActiveDocument, |
44 | 48 | DocumentManager, |
45 | 49 | Fullscreen, |
| 50 | + ScrollManager, |
46 | 51 | UseExportReturn, |
47 | 52 | UsePrintReturn, |
| 53 | + UseSearchReturn, |
48 | 54 | UseSpreadReturn, |
49 | 55 | UseZoomReturn |
50 | 56 | } from './types'; |
|
72 | 78 | tileSize: 768, |
73 | 79 | overlapPx: 5, |
74 | 80 | extraRings: 0 |
75 | | - }) |
| 81 | + }), |
| 82 | + createPluginRegistration(SearchPluginPackage) |
76 | 83 | ]; |
77 | 84 |
|
78 | 85 | let docManager: DocumentManager | undefined = $state(undefined); |
|
82 | 89 | let spread: UseSpreadReturn | undefined = $state(undefined); |
83 | 90 | let zoom: UseZoomReturn | undefined = $state(undefined); |
84 | 91 | let fullscreen: Fullscreen | undefined = $state(undefined); |
| 92 | + let search: UseSearchReturn | undefined = $state(undefined); |
| 93 | + let scrollManager: ScrollManager | undefined = $state(undefined); |
85 | 94 | |
86 | 95 | let isPrinting = $state(false); |
87 | 96 |
|
|
117 | 126 | export function fullscreenPdf(): void { |
118 | 127 | fullscreen!.provides?.toggleFullscreen(`#${activeDocument?.activeDocumentId}`) |
119 | 128 | } |
| 129 | +
|
| 130 | + export function searchPdf(query: string): void { |
| 131 | + if (!search) return; |
| 132 | + query === '' ? search.provides?.stopSearch() : search.provides?.searchAllPages(query); |
| 133 | + } |
| 134 | +
|
| 135 | + export function changeSearchResult(dir: 'prev' | 'next'): void { |
| 136 | + dir === 'prev' ? search!.provides?.previousResult() : search!.provides?.nextResult(); |
| 137 | + } |
| 138 | +
|
| 139 | + function scrollToItem(index: number): void { |
| 140 | + const item = search!.state.results[index]; |
| 141 | + if (!item) return; |
| 142 | + const minCoordinates = item.rects.reduce( |
| 143 | + (min, rect) => ({ |
| 144 | + x: Math.min(min.x, rect.origin.x), |
| 145 | + y: Math.min(min.y, rect.origin.y), |
| 146 | + }), |
| 147 | + { x: Infinity, y: Infinity }, |
| 148 | + ); |
| 149 | + scrollManager!.provides?.scrollToPage({ |
| 150 | + pageNumber: item.pageIndex + 1, |
| 151 | + pageCoordinates: minCoordinates, |
| 152 | + alignX: 50, |
| 153 | + alignY: 50 |
| 154 | + }); |
| 155 | + } |
| 156 | +
|
| 157 | + $effect(() => { |
| 158 | + if (search && |
| 159 | + typeof search.state.activeResultIndex === 'number' && |
| 160 | + !search.state.loading && |
| 161 | + search.state.results.length > 0) |
| 162 | + scrollToItem(search.state.activeResultIndex); |
| 163 | + }); |
120 | 164 | </script> |
121 | 165 |
|
122 | 166 | {#if pdfEngine.isLoading || !pdfEngine.engine} |
123 | 167 | <div class='loading-pane'> |
124 | 168 | Loading PDF Engine... |
125 | 169 | </div> |
126 | 170 | {:else} |
127 | | - <div style='height: 80vh;'> |
| 171 | + <div class='pdf-wrapper'> |
128 | 172 | <EmbedPDF engine={pdfEngine.engine} {plugins}> |
129 | 173 | {#snippet children({ activeDocumentId })} |
130 | 174 | {#if activeDocumentId} |
131 | 175 | {@const documentId = activeDocumentId} |
132 | 176 | <DocumentContent {documentId}> |
133 | 177 | {#snippet children(documentContent)} |
134 | 178 | {#if documentContent.isLoaded} |
135 | | - <div |
136 | | - style:width='100%' |
137 | | - style:height='100%' |
138 | | - style:position='relative' |
139 | | - > |
140 | | - <Viewport {documentId} style={$SettingsStore.theme === 'dark' ? 'background-color:#2E3235' : 'background-color:#FFFFFF'}> |
| 179 | + <div class='viewport-wrapper'> |
| 180 | + <Viewport |
| 181 | + {documentId} |
| 182 | + style={$SettingsStore.theme === 'dark' ? 'background-color:#2E3235' : 'background-color:#FFFFFF'} |
| 183 | + > |
141 | 184 | <Scroller {documentId}> |
142 | 185 | {#snippet renderPage(page: RenderPageProps)} |
143 | 186 | <RenderLayer |
|
149 | 192 | {documentId} |
150 | 193 | pageIndex={page.pageIndex} |
151 | 194 | /> |
| 195 | + <SearchLayer |
| 196 | + {documentId} |
| 197 | + pageIndex={page.pageIndex} |
| 198 | + /> |
152 | 199 | {/snippet} |
153 | 200 | </Scroller> |
154 | 201 | <PDFPluginLoader |
|
157 | 204 | bind:exportApi |
158 | 205 | bind:fullscreen |
159 | 206 | bind:print |
| 207 | + bind:scrollManager |
| 208 | + bind:search |
160 | 209 | bind:spread |
161 | 210 | bind:zoom |
162 | 211 | {documentId} |
|
0 commit comments