@file-viewer/core 2.0.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.
Files changed (166) hide show
  1. package/LICENSE +160 -0
  2. package/README.en.md +78 -0
  3. package/README.md +83 -0
  4. package/dist/assets.d.ts +62 -0
  5. package/dist/assets.js +260 -0
  6. package/dist/browser.d.ts +1 -0
  7. package/dist/browser.js +1 -0
  8. package/dist/capabilities.d.ts +24 -0
  9. package/dist/capabilities.js +95 -0
  10. package/dist/document.d.ts +9 -0
  11. package/dist/document.js +86 -0
  12. package/dist/documentDom/anchors.d.ts +7 -0
  13. package/dist/documentDom/anchors.js +196 -0
  14. package/dist/documentDom/index.d.ts +5 -0
  15. package/dist/documentDom/index.js +3 -0
  16. package/dist/documentDom/providers.d.ts +13 -0
  17. package/dist/documentDom/providers.js +52 -0
  18. package/dist/documentDom/scroll.d.ts +12 -0
  19. package/dist/documentDom/scroll.js +42 -0
  20. package/dist/documentDom.d.ts +5 -0
  21. package/dist/documentDom.js +3 -0
  22. package/dist/documentEvents.d.ts +73 -0
  23. package/dist/documentEvents.js +150 -0
  24. package/dist/documentSearch.d.ts +50 -0
  25. package/dist/documentSearch.js +459 -0
  26. package/dist/documentZoom.d.ts +47 -0
  27. package/dist/documentZoom.js +184 -0
  28. package/dist/export.d.ts +26 -0
  29. package/dist/export.js +466 -0
  30. package/dist/formats.d.ts +305 -0
  31. package/dist/formats.js +207 -0
  32. package/dist/headless.d.ts +25 -0
  33. package/dist/headless.js +14 -0
  34. package/dist/index.d.ts +78 -0
  35. package/dist/index.js +118 -0
  36. package/dist/lifecycleFacade.d.ts +46 -0
  37. package/dist/lifecycleFacade.js +68 -0
  38. package/dist/loading.d.ts +59 -0
  39. package/dist/loading.js +489 -0
  40. package/dist/operations.d.ts +287 -0
  41. package/dist/operations.js +485 -0
  42. package/dist/options.d.ts +16 -0
  43. package/dist/options.js +92 -0
  44. package/dist/presentation.d.ts +14 -0
  45. package/dist/presentation.js +16 -0
  46. package/dist/printLayout.d.ts +19 -0
  47. package/dist/printLayout.js +83 -0
  48. package/dist/registry.d.ts +2 -0
  49. package/dist/registry.js +63 -0
  50. package/dist/rendererDispatcher.d.ts +21 -0
  51. package/dist/rendererDispatcher.js +42 -0
  52. package/dist/rendererHandler.d.ts +165 -0
  53. package/dist/rendererHandler.js +354 -0
  54. package/dist/renderers/archive.d.ts +2 -0
  55. package/dist/renderers/archive.js +547 -0
  56. package/dist/renderers/archiveCache.d.ts +10 -0
  57. package/dist/renderers/archiveCache.js +96 -0
  58. package/dist/renderers/archiveFallback.d.ts +7 -0
  59. package/dist/renderers/archiveFallback.js +166 -0
  60. package/dist/renderers/archiveShared.d.ts +23 -0
  61. package/dist/renderers/archiveShared.js +71 -0
  62. package/dist/renderers/audio.d.ts +8 -0
  63. package/dist/renderers/audio.js +219 -0
  64. package/dist/renderers/cad.d.ts +2 -0
  65. package/dist/renderers/cad.js +445 -0
  66. package/dist/renderers/code.d.ts +11 -0
  67. package/dist/renderers/code.js +233 -0
  68. package/dist/renderers/data.d.ts +7 -0
  69. package/dist/renderers/data.js +370 -0
  70. package/dist/renderers/drawing.d.ts +10 -0
  71. package/dist/renderers/drawing.js +537 -0
  72. package/dist/renderers/eda.d.ts +2 -0
  73. package/dist/renderers/eda.js +434 -0
  74. package/dist/renderers/edaParser.d.ts +77 -0
  75. package/dist/renderers/edaParser.js +569 -0
  76. package/dist/renderers/email.d.ts +2 -0
  77. package/dist/renderers/email.js +463 -0
  78. package/dist/renderers/epub.d.ts +2 -0
  79. package/dist/renderers/epub.js +330 -0
  80. package/dist/renderers/geo.d.ts +2 -0
  81. package/dist/renderers/geo.js +284 -0
  82. package/dist/renderers/image.d.ts +2 -0
  83. package/dist/renderers/image.js +179 -0
  84. package/dist/renderers/index.d.ts +21 -0
  85. package/dist/renderers/index.js +207 -0
  86. package/dist/renderers/markdown.d.ts +2 -0
  87. package/dist/renderers/markdown.js +83 -0
  88. package/dist/renderers/model.d.ts +2 -0
  89. package/dist/renderers/model.js +566 -0
  90. package/dist/renderers/ofd.d.ts +2 -0
  91. package/dist/renderers/ofd.js +255 -0
  92. package/dist/renderers/openDocument.d.ts +2 -0
  93. package/dist/renderers/openDocument.js +122 -0
  94. package/dist/renderers/pdf.d.ts +3 -0
  95. package/dist/renderers/pdf.js +846 -0
  96. package/dist/renderers/pdfStyles.d.ts +1 -0
  97. package/dist/renderers/pdfStyles.js +1 -0
  98. package/dist/renderers/pptx.d.ts +2 -0
  99. package/dist/renderers/pptx.js +202 -0
  100. package/dist/renderers/spreadsheet/state.d.ts +80 -0
  101. package/dist/renderers/spreadsheet/state.js +96 -0
  102. package/dist/renderers/spreadsheet/view.d.ts +25 -0
  103. package/dist/renderers/spreadsheet/view.js +833 -0
  104. package/dist/renderers/spreadsheet/worker/index.d.ts +2 -0
  105. package/dist/renderers/spreadsheet/worker/index.js +1 -0
  106. package/dist/renderers/spreadsheet/worker/sheetjs/SheetJsModel.d.ts +73 -0
  107. package/dist/renderers/spreadsheet/worker/sheetjs/SheetJsModel.js +623 -0
  108. package/dist/renderers/spreadsheet/worker/sheetjs/color.d.ts +2 -0
  109. package/dist/renderers/spreadsheet/worker/sheetjs/color.js +73 -0
  110. package/dist/renderers/spreadsheet/worker/sheetjs/index.d.ts +1 -0
  111. package/dist/renderers/spreadsheet/worker/sheetjs/index.js +1 -0
  112. package/dist/renderers/spreadsheet/worker/sheetjs/parser.d.ts +18 -0
  113. package/dist/renderers/spreadsheet/worker/sheetjs/parser.js +106 -0
  114. package/dist/renderers/spreadsheet/worker/sheetjs/sheet.worker.d.ts +1 -0
  115. package/dist/renderers/spreadsheet/worker/sheetjs/sheet.worker.js +11 -0
  116. package/dist/renderers/spreadsheet/worker/type.d.ts +57 -0
  117. package/dist/renderers/spreadsheet/worker/type.js +1 -0
  118. package/dist/renderers/spreadsheet.d.ts +3 -0
  119. package/dist/renderers/spreadsheet.js +929 -0
  120. package/dist/renderers/typst.d.ts +8 -0
  121. package/dist/renderers/typst.js +415 -0
  122. package/dist/renderers/umd/parser.d.ts +30 -0
  123. package/dist/renderers/umd/parser.js +408 -0
  124. package/dist/renderers/umd.d.ts +2 -0
  125. package/dist/renderers/umd.js +297 -0
  126. package/dist/renderers/video.d.ts +8 -0
  127. package/dist/renderers/video.js +108 -0
  128. package/dist/renderers/wordDoc.d.ts +5 -0
  129. package/dist/renderers/wordDoc.js +284 -0
  130. package/dist/renderers/wordDocx.d.ts +5 -0
  131. package/dist/renderers/wordDocx.js +501 -0
  132. package/dist/renderers/wordDocx.worker.d.ts +1 -0
  133. package/dist/renderers/wordDocx.worker.js +96 -0
  134. package/dist/source.d.ts +18 -0
  135. package/dist/source.js +152 -0
  136. package/dist/sourceLoading.d.ts +566 -0
  137. package/dist/sourceLoading.js +918 -0
  138. package/dist/state.d.ts +16 -0
  139. package/dist/state.js +81 -0
  140. package/dist/types.d.ts +446 -0
  141. package/dist/types.js +1 -0
  142. package/dist/viewer.d.ts +8 -0
  143. package/dist/viewer.js +285 -0
  144. package/dist/viewerOperations.d.ts +88 -0
  145. package/dist/viewerOperations.js +242 -0
  146. package/dist/watermark.d.ts +15 -0
  147. package/dist/watermark.js +81 -0
  148. package/dist/worker.d.ts +34 -0
  149. package/dist/worker.js +101 -0
  150. package/package.json +109 -0
  151. package/vendor/ofd/dltech/jbig2/arithmetic_decoder.js +183 -0
  152. package/vendor/ofd/dltech/jbig2/ccitt.js +1070 -0
  153. package/vendor/ofd/dltech/jbig2/compatibility.js +12 -0
  154. package/vendor/ofd/dltech/jbig2/core_utils.js +180 -0
  155. package/vendor/ofd/dltech/jbig2/is_node.js +27 -0
  156. package/vendor/ofd/dltech/jbig2/jbig2.js +2589 -0
  157. package/vendor/ofd/dltech/jbig2/jbig2_stream.js +81 -0
  158. package/vendor/ofd/dltech/jbig2/primitives.js +387 -0
  159. package/vendor/ofd/dltech/jbig2/stream.js +1348 -0
  160. package/vendor/ofd/dltech/jbig2/util.js +972 -0
  161. package/vendor/ofd/dltech/ofd/ofd.d.ts +11 -0
  162. package/vendor/ofd/dltech/ofd/ofd.js +100 -0
  163. package/vendor/ofd/dltech/ofd/ofd_parser.js +395 -0
  164. package/vendor/ofd/dltech/ofd/ofd_render.js +473 -0
  165. package/vendor/ofd/dltech/ofd/ofd_util.js +350 -0
  166. package/vendor/ofd/dltech/ofd/pipeline.js +26 -0
@@ -0,0 +1,846 @@
1
+ import { getDocument, GlobalWorkerOptions, PDFWorker as PdfJsWorker, PixelsPerInch, version, } from 'pdfjs-dist/legacy/build/pdf.mjs';
2
+ import { EventBus, GenericL10n, PDFFindController, PDFLinkService, PDFViewer, } from 'pdfjs-dist/legacy/web/pdf_viewer.mjs';
3
+ import { registerFileViewerSearchProvider, registerFileViewerZoomProvider, unregisterFileViewerSearchProvider, unregisterFileViewerZoomProvider, } from '../documentDom.js';
4
+ import { createFileViewerZoomChangeEmitter } from '../documentZoom.js';
5
+ import { buildPrintPageStyle, formatCssPixels, } from '../printLayout.js';
6
+ import { DEFAULT_PDF_RANGE_CHUNK_SIZE } from '../sourceLoading.js';
7
+ import { pdfViewerStyle } from './pdfStyles.js';
8
+ export const DEFAULT_FILE_VIEWER_PDF_WORKER_URL = `https://npm.onmicrosoft.cn/pdfjs-dist@${version}/legacy/build/pdf.worker.mjs`;
9
+ const MIN_SCALE = 0.2;
10
+ const MAX_SCALE = 3;
11
+ const SCALE_STEP = 0.1;
12
+ const FIT_HORIZONTAL_PADDING = 28;
13
+ const PAGE_BORDER_WIDTH = 18;
14
+ const PDF_EXPORT_MAX_PAGE_PIXELS = 8000000;
15
+ const createStyle = (documentRef) => {
16
+ const style = documentRef.createElement('style');
17
+ style.textContent = pdfViewerStyle;
18
+ return style;
19
+ };
20
+ const createElement = (documentRef, tagName, className, text) => {
21
+ const element = documentRef.createElement(tagName);
22
+ if (className) {
23
+ element.className = className;
24
+ }
25
+ if (text !== undefined) {
26
+ element.textContent = text;
27
+ }
28
+ return element;
29
+ };
30
+ const createButton = (documentRef, className, title, label) => {
31
+ const button = createElement(documentRef, 'button', className);
32
+ button.type = 'button';
33
+ button.title = title;
34
+ button.setAttribute('aria-label', title);
35
+ if (label !== undefined) {
36
+ const labelNode = createElement(documentRef, 'span', undefined, label);
37
+ labelNode.setAttribute('aria-hidden', 'true');
38
+ button.append(labelNode);
39
+ }
40
+ return button;
41
+ };
42
+ const normalizeRotation = (rotation) => {
43
+ const normalized = ((Math.round(rotation / 90) * 90) % 360 + 360) % 360;
44
+ return (normalized === 90 || normalized === 180 || normalized === 270 ? normalized : 0);
45
+ };
46
+ const clampScale = (scale) => Number(Math.min(MAX_SCALE, Math.max(MIN_SCALE, scale)).toFixed(2));
47
+ const createPdfSearchState = (query = '') => ({
48
+ query,
49
+ total: 0,
50
+ currentIndex: -1,
51
+ current: null,
52
+ matches: [],
53
+ });
54
+ const escapeAttribute = (value) => value
55
+ .replace(/&/g, '&')
56
+ .replace(/"/g, '"')
57
+ .replace(/</g, '&lt;')
58
+ .replace(/>/g, '&gt;');
59
+ const waitForPaint = (view) => new Promise(resolve => {
60
+ if (view === null || view === void 0 ? void 0 : view.requestAnimationFrame) {
61
+ view.requestAnimationFrame(() => resolve());
62
+ return;
63
+ }
64
+ globalThis.setTimeout(resolve, 0);
65
+ });
66
+ const resolvePdfWorkerUrl = (options, documentUrl) => {
67
+ const configured = options === null || options === void 0 ? void 0 : options.workerUrl;
68
+ if (!configured) {
69
+ return DEFAULT_FILE_VIEWER_PDF_WORKER_URL;
70
+ }
71
+ try {
72
+ return documentUrl ? new URL(configured, documentUrl).href : configured;
73
+ }
74
+ catch {
75
+ return configured;
76
+ }
77
+ };
78
+ const buildOutlineItems = (items, prefix = 'outline') => items.map((item, index) => {
79
+ const id = `${prefix}-${index}`;
80
+ const children = Array.isArray(item.items)
81
+ ? buildOutlineItems(item.items, id)
82
+ : [];
83
+ return {
84
+ id,
85
+ title: item.title || `目录 ${index + 1}`,
86
+ dest: item.dest || null,
87
+ items: children,
88
+ expanded: index < 4,
89
+ };
90
+ });
91
+ export default async function renderPdf(buffer, target, context) {
92
+ var _a, _b;
93
+ const documentRef = target.ownerDocument || document;
94
+ const targetWindow = documentRef.defaultView || (typeof window !== 'undefined' ? window : null);
95
+ if (!targetWindow) {
96
+ throw new Error('PDF preview requires a browser window');
97
+ }
98
+ const options = (_a = context === null || context === void 0 ? void 0 : context.options) === null || _a === void 0 ? void 0 : _a.pdf;
99
+ const navigationEnabled = (options === null || options === void 0 ? void 0 : options.navigation) !== false;
100
+ const toolbarVisible = (options === null || options === void 0 ? void 0 : options.toolbar) !== false;
101
+ const zoomEmitter = createFileViewerZoomChangeEmitter();
102
+ let navVisible = (options === null || options === void 0 ? void 0 : options.navigation) === false ? false : (options === null || options === void 0 ? void 0 : options.defaultNavigationVisible) !== false;
103
+ let navMode = 'pages';
104
+ let loadStatus = 'loading';
105
+ let errorMessage = '';
106
+ let currentPage = 1;
107
+ let pageCount = 0;
108
+ let currentScale = 1;
109
+ let autoFitWidth = true;
110
+ let currentRotation = normalizeRotation((_b = options === null || options === void 0 ? void 0 : options.rotation) !== null && _b !== void 0 ? _b : 0);
111
+ let outlineItems = [];
112
+ let resizeObserver = null;
113
+ let fitFrame = 0;
114
+ let destroyed = false;
115
+ let loadVersion = 0;
116
+ let pdfSearchState = createPdfSearchState();
117
+ let pdfMatchesCount = { current: 0, total: 0 };
118
+ let pdfSearchOptions;
119
+ let pdfSearchWaiters = [];
120
+ const pdfContext = {
121
+ viewer: null,
122
+ linkService: null,
123
+ eventBus: null,
124
+ findController: null,
125
+ resource: null,
126
+ document: null,
127
+ search: '',
128
+ };
129
+ const root = createElement(documentRef, 'div', 'pdf-shell');
130
+ root.dataset.viewerSearchProvider = 'pdf';
131
+ root.dataset.viewerZoomProvider = 'pdf';
132
+ const toolbar = createElement(documentRef, 'div', 'pdf-toolbar');
133
+ const navToggleButton = createButton(documentRef, 'pdf-icon-button', '切换导航窗格');
134
+ navToggleButton.setAttribute('aria-pressed', String(navVisible));
135
+ navToggleButton.append(createElement(documentRef, 'span', 'pdf-panel-icon'));
136
+ const pageGroup = createElement(documentRef, 'div', 'pdf-toolbar-group');
137
+ const previousPageButton = createButton(documentRef, 'pdf-icon-button', '上一页', '‹');
138
+ const pageMeter = createElement(documentRef, 'span', 'pdf-page-meter');
139
+ const pageMeterCurrent = createElement(documentRef, 'strong', undefined, '1');
140
+ const pageMeterTotal = createElement(documentRef, 'span', undefined, '/ -');
141
+ pageMeter.append(pageMeterCurrent, pageMeterTotal);
142
+ const nextPageButton = createButton(documentRef, 'pdf-icon-button', '下一页', '›');
143
+ pageGroup.append(previousPageButton, pageMeter, nextPageButton);
144
+ const zoomGroup = createElement(documentRef, 'div', 'pdf-toolbar-group pdf-toolbar-group--zoom');
145
+ const zoomOutButton = createButton(documentRef, 'pdf-icon-button', '缩小', '−');
146
+ const scaleButton = createElement(documentRef, 'button', 'pdf-scale-button', '100%');
147
+ scaleButton.type = 'button';
148
+ scaleButton.title = '适合宽度';
149
+ const zoomInButton = createButton(documentRef, 'pdf-icon-button', '放大', '+');
150
+ zoomGroup.append(zoomOutButton, scaleButton, zoomInButton);
151
+ const rotateGroup = createElement(documentRef, 'div', 'pdf-toolbar-group pdf-toolbar-group--rotate');
152
+ const rotateLeftButton = createButton(documentRef, 'pdf-icon-button', '向左旋转', '↺');
153
+ const rotationMeter = createElement(documentRef, 'span', 'pdf-rotation-meter', `${currentRotation}°`);
154
+ const rotateRightButton = createButton(documentRef, 'pdf-icon-button', '向右旋转', '↻');
155
+ rotateGroup.append(rotateLeftButton, rotationMeter, rotateRightButton);
156
+ if (navigationEnabled) {
157
+ toolbar.append(navToggleButton);
158
+ }
159
+ toolbar.append(pageGroup, zoomGroup, rotateGroup);
160
+ const content = createElement(documentRef, 'div', 'pdf-content');
161
+ const navPane = createElement(documentRef, 'aside', 'pdf-nav-pane');
162
+ const navHead = createElement(documentRef, 'div', 'pdf-nav-head');
163
+ const navTitle = createElement(documentRef, 'span', undefined, '页面导航');
164
+ const navCount = createElement(documentRef, 'strong', undefined, '0 页');
165
+ navHead.append(navTitle, navCount);
166
+ const navTabs = createElement(documentRef, 'div', 'pdf-nav-tabs');
167
+ navTabs.setAttribute('role', 'tablist');
168
+ navTabs.setAttribute('aria-label', 'PDF 导航类型');
169
+ const pagesTab = createButton(documentRef, '', '页面');
170
+ const outlineTab = createButton(documentRef, '', '目录');
171
+ pagesTab.textContent = '页面';
172
+ outlineTab.textContent = '目录';
173
+ pagesTab.setAttribute('role', 'tab');
174
+ outlineTab.setAttribute('role', 'tab');
175
+ navTabs.append(pagesTab, outlineTab);
176
+ const navList = createElement(documentRef, 'div');
177
+ navPane.append(navHead, navTabs, navList);
178
+ const viewport = createElement(documentRef, 'div', 'pdf-viewport');
179
+ const container = createElement(documentRef, 'div', 'pdf-wrapper');
180
+ container.dataset.viewerScrollContainer = 'true';
181
+ const pdfViewerRoot = createElement(documentRef, 'div', 'pdfViewer');
182
+ const stateNode = createElement(documentRef, 'div', 'pdf-state', '正在加载 PDF...');
183
+ container.append(pdfViewerRoot, stateNode);
184
+ viewport.append(container);
185
+ content.append(navPane, viewport);
186
+ root.append(content);
187
+ if (toolbarVisible) {
188
+ root.insertBefore(toolbar, content);
189
+ }
190
+ target.replaceChildren(createStyle(documentRef), root);
191
+ const scaleText = () => `${Math.round(currentScale * 100)}%`;
192
+ const rotationText = () => `${currentRotation}°`;
193
+ const canGoPrevious = () => currentPage > 1;
194
+ const canGoNext = () => currentPage < pageCount;
195
+ const canZoomOut = () => currentScale > MIN_SCALE;
196
+ const canZoomIn = () => currentScale < MAX_SCALE;
197
+ const outlineCount = () => {
198
+ const countItems = (items) => (items.reduce((total, item) => total + 1 + countItems(item.items), 0));
199
+ return countItems(outlineItems);
200
+ };
201
+ const flattenedOutlineItems = () => {
202
+ const result = [];
203
+ const visit = (items, depth) => {
204
+ items.forEach(item => {
205
+ result.push({ item, depth });
206
+ if (item.expanded && item.items.length) {
207
+ visit(item.items, depth + 1);
208
+ }
209
+ });
210
+ };
211
+ visit(outlineItems, 0);
212
+ return result;
213
+ };
214
+ const renderNavList = () => {
215
+ navList.replaceChildren();
216
+ navList.className = navMode === 'pages' ? 'pdf-page-list' : 'pdf-outline-list';
217
+ if (navMode === 'pages') {
218
+ for (let page = 1; page <= pageCount; page += 1) {
219
+ const button = createElement(documentRef, 'button', 'pdf-page-button');
220
+ button.type = 'button';
221
+ button.classList.toggle('pdf-page-button--active', page === currentPage);
222
+ button.append(createElement(documentRef, 'span', 'pdf-page-thumb', String(page)), createElement(documentRef, 'span', 'pdf-page-label', `第 ${page} 页`));
223
+ button.addEventListener('click', () => goToPage(page));
224
+ navList.append(button);
225
+ }
226
+ return;
227
+ }
228
+ const entries = flattenedOutlineItems();
229
+ entries.forEach(entry => {
230
+ const button = createElement(documentRef, 'button', 'pdf-outline-button');
231
+ button.type = 'button';
232
+ button.style.setProperty('--outline-depth', String(entry.depth));
233
+ const toggle = createElement(documentRef, 'span', 'pdf-outline-toggle');
234
+ toggle.classList.toggle('pdf-outline-toggle--open', entry.item.expanded);
235
+ toggle.classList.toggle('pdf-outline-toggle--empty', !entry.item.items.length);
236
+ toggle.setAttribute('aria-hidden', 'true');
237
+ toggle.addEventListener('click', event => {
238
+ event.stopPropagation();
239
+ toggleOutlineItem(entry.item);
240
+ });
241
+ button.append(toggle, createElement(documentRef, 'span', 'pdf-outline-title', entry.item.title));
242
+ button.addEventListener('click', () => goToOutlineItem(entry.item));
243
+ navList.append(button);
244
+ });
245
+ if (!entries.length) {
246
+ navList.append(createElement(documentRef, 'div', 'pdf-outline-empty', '当前 PDF 没有可用目录'));
247
+ }
248
+ };
249
+ const syncUi = () => {
250
+ root.classList.toggle('pdf-shell--nav-hidden', !navigationEnabled || !navVisible);
251
+ root.classList.toggle('pdf-shell--toolbar-hidden', !toolbarVisible);
252
+ navToggleButton.classList.toggle('pdf-icon-button--active', navVisible);
253
+ navToggleButton.setAttribute('aria-pressed', String(navVisible));
254
+ navPane.hidden = !navigationEnabled || !navVisible;
255
+ pagesTab.classList.toggle('active', navMode === 'pages');
256
+ outlineTab.classList.toggle('active', navMode === 'outline');
257
+ pagesTab.setAttribute('aria-selected', navMode === 'pages' ? 'true' : 'false');
258
+ outlineTab.setAttribute('aria-selected', navMode === 'outline' ? 'true' : 'false');
259
+ navTitle.textContent = navMode === 'pages' ? '页面导航' : '目录导航';
260
+ navCount.textContent = navMode === 'pages' ? `${pageCount} 页` : `${outlineCount()} 项`;
261
+ pageMeterCurrent.textContent = String(currentPage);
262
+ pageMeterTotal.textContent = `/ ${pageCount || '-'}`;
263
+ scaleButton.textContent = scaleText();
264
+ rotationMeter.textContent = rotationText();
265
+ previousPageButton.disabled = !canGoPrevious();
266
+ nextPageButton.disabled = !canGoNext();
267
+ zoomOutButton.disabled = !canZoomOut();
268
+ zoomInButton.disabled = !canZoomIn();
269
+ stateNode.hidden = loadStatus === 'ready';
270
+ stateNode.classList.toggle('pdf-state--error', loadStatus === 'error');
271
+ stateNode.textContent = loadStatus === 'error' ? errorMessage : '正在加载 PDF...';
272
+ renderNavList();
273
+ };
274
+ const createPdfWorker = () => {
275
+ if (!(targetWindow === null || targetWindow === void 0 ? void 0 : targetWindow.Worker)) {
276
+ return null;
277
+ }
278
+ GlobalWorkerOptions.workerSrc = resolvePdfWorkerUrl(options, documentRef.URL || undefined);
279
+ try {
280
+ return PdfJsWorker.create({ name: 'file-viewer-pdf-worker' });
281
+ }
282
+ catch (error) {
283
+ console.warn('[file-viewer] PDF Worker 无法创建,回退到 PDF.js 默认加载策略。', error);
284
+ return null;
285
+ }
286
+ };
287
+ const resolvePdfSearchWaiters = (state) => {
288
+ const waiters = pdfSearchWaiters;
289
+ pdfSearchWaiters = [];
290
+ waiters.forEach(waiter => {
291
+ targetWindow.clearTimeout(waiter.timer);
292
+ waiter.resolve(state);
293
+ });
294
+ };
295
+ const readPdfMatchesCount = () => {
296
+ var _a;
297
+ const findController = pdfContext.findController;
298
+ if (!findController) {
299
+ return { current: 0, total: 0 };
300
+ }
301
+ const pageMatches = findController.pageMatches || [];
302
+ const selected = findController.selected;
303
+ const total = pageMatches.reduce((sum, matches) => sum + ((matches === null || matches === void 0 ? void 0 : matches.length) || 0), 0);
304
+ let current = 0;
305
+ if (selected && selected.pageIdx >= 0 && selected.matchIdx >= 0 && total > 0) {
306
+ for (let index = 0; index < selected.pageIdx; index += 1) {
307
+ current += ((_a = pageMatches[index]) === null || _a === void 0 ? void 0 : _a.length) || 0;
308
+ }
309
+ current += selected.matchIdx + 1;
310
+ }
311
+ return { current, total };
312
+ };
313
+ const commitPdfSearchState = (matchesCount = readPdfMatchesCount(), query = pdfContext.search, shouldResolve = false) => {
314
+ var _a;
315
+ pdfMatchesCount = matchesCount;
316
+ const current = Math.max(0, matchesCount.current || 0);
317
+ const total = Math.max(0, matchesCount.total || 0);
318
+ const selected = (_a = pdfContext.findController) === null || _a === void 0 ? void 0 : _a.selected;
319
+ const page = selected && selected.pageIdx >= 0 ? selected.pageIdx + 1 : undefined;
320
+ pdfSearchState = {
321
+ query,
322
+ total,
323
+ currentIndex: current > 0 ? current - 1 : -1,
324
+ current: current > 0
325
+ ? {
326
+ id: `pdf-search-match-${current}`,
327
+ index: current - 1,
328
+ text: query,
329
+ anchor: null,
330
+ page,
331
+ }
332
+ : null,
333
+ matches: [],
334
+ };
335
+ if (shouldResolve) {
336
+ resolvePdfSearchWaiters(pdfSearchState);
337
+ }
338
+ return pdfSearchState;
339
+ };
340
+ const waitForPdfSearchState = (query) => new Promise(resolve => {
341
+ const timer = targetWindow.setTimeout(() => {
342
+ const waiterIndex = pdfSearchWaiters.findIndex(waiter => waiter.resolve === resolve);
343
+ if (waiterIndex >= 0) {
344
+ pdfSearchWaiters.splice(waiterIndex, 1);
345
+ }
346
+ resolve(commitPdfSearchState(readPdfMatchesCount(), query));
347
+ }, 1200);
348
+ pdfSearchWaiters.push({ resolve, timer });
349
+ });
350
+ const handlePdfFindMatchesCount = (event) => {
351
+ if (event.matchesCount) {
352
+ commitPdfSearchState(event.matchesCount, pdfContext.search);
353
+ }
354
+ };
355
+ const handlePdfFindControlState = (event) => {
356
+ var _a;
357
+ const query = typeof event.rawQuery === 'string' ? event.rawQuery : pdfContext.search;
358
+ pdfContext.search = query;
359
+ const matchesCount = ((_a = event.matchesCount) === null || _a === void 0 ? void 0 : _a.total) ? event.matchesCount : readPdfMatchesCount();
360
+ const shouldResolve = event.state !== 3 && (matchesCount.total > 0 || event.state === 1);
361
+ commitPdfSearchState(matchesCount, query, shouldResolve);
362
+ };
363
+ const clampHorizontalScroll = (scrollLeft) => {
364
+ const maxScrollLeft = Math.max(0, container.scrollWidth - container.clientWidth);
365
+ return Math.min(Math.max(0, scrollLeft), maxScrollLeft);
366
+ };
367
+ const restoreHorizontalScroll = (scrollLeft) => {
368
+ container.scrollLeft = clampHorizontalScroll(scrollLeft);
369
+ };
370
+ const stabilizeHorizontalScroll = (scrollLeft) => {
371
+ restoreHorizontalScroll(scrollLeft);
372
+ void waitForPaint(targetWindow).then(() => restoreHorizontalScroll(scrollLeft));
373
+ targetWindow.requestAnimationFrame(() => {
374
+ restoreHorizontalScroll(scrollLeft);
375
+ targetWindow.requestAnimationFrame(() => restoreHorizontalScroll(scrollLeft));
376
+ });
377
+ targetWindow.setTimeout(() => restoreHorizontalScroll(scrollLeft), 120);
378
+ };
379
+ const runPdfFind = async (query, searchOptionsInput, type, findPrevious = false) => {
380
+ if (!pdfContext.eventBus) {
381
+ return commitPdfSearchState({ current: 0, total: 0 }, query);
382
+ }
383
+ pdfContext.search = query;
384
+ pdfSearchOptions = searchOptionsInput || pdfSearchOptions;
385
+ const searchOptions = searchOptionsInput || pdfSearchOptions;
386
+ const previousScrollLeft = clampHorizontalScroll(container.scrollLeft || 0);
387
+ pdfContext.eventBus.dispatch('find', {
388
+ source: root,
389
+ type,
390
+ query,
391
+ phraseSearch: true,
392
+ caseSensitive: !!(searchOptions === null || searchOptions === void 0 ? void 0 : searchOptions.caseSensitive),
393
+ entireWord: !!(searchOptions === null || searchOptions === void 0 ? void 0 : searchOptions.wholeWord),
394
+ highlightAll: true,
395
+ findPrevious,
396
+ matchDiacritics: false,
397
+ });
398
+ try {
399
+ return await waitForPdfSearchState(query);
400
+ }
401
+ finally {
402
+ stabilizeHorizontalScroll(previousScrollLeft);
403
+ }
404
+ };
405
+ const clearPdfFind = () => {
406
+ var _a;
407
+ pdfContext.search = '';
408
+ pdfSearchOptions = undefined;
409
+ pdfMatchesCount = { current: 0, total: 0 };
410
+ (_a = pdfContext.eventBus) === null || _a === void 0 ? void 0 : _a.dispatch('findbarclose', {
411
+ source: root,
412
+ });
413
+ return commitPdfSearchState(pdfMatchesCount, '', true);
414
+ };
415
+ const getPdfZoomState = () => ({
416
+ scale: currentScale,
417
+ label: scaleText(),
418
+ canZoomIn: !!pdfContext.viewer && canZoomIn(),
419
+ canZoomOut: !!pdfContext.viewer && canZoomOut(),
420
+ canReset: !!pdfContext.viewer,
421
+ minScale: MIN_SCALE,
422
+ maxScale: MAX_SCALE,
423
+ });
424
+ const setScale = (scale) => {
425
+ if (!pdfContext.viewer) {
426
+ return;
427
+ }
428
+ const normalizedScale = clampScale(scale);
429
+ pdfContext.viewer.currentScale = normalizedScale;
430
+ currentScale = normalizedScale;
431
+ zoomEmitter.emit();
432
+ syncUi();
433
+ };
434
+ const getPageWidthAtScaleOne = (pdfViewer) => {
435
+ var _a;
436
+ const pageView = pdfViewer.getPageView(0);
437
+ const pdfPage = pageView === null || pageView === void 0 ? void 0 : pageView.pdfPage;
438
+ if (pdfPage) {
439
+ return pdfPage.getViewport({
440
+ scale: PixelsPerInch.PDF_TO_CSS_UNITS,
441
+ rotation: currentRotation,
442
+ }).width;
443
+ }
444
+ const viewportWidth = (_a = pageView === null || pageView === void 0 ? void 0 : pageView.viewport) === null || _a === void 0 ? void 0 : _a.width;
445
+ if (viewportWidth && currentScale) {
446
+ return viewportWidth / currentScale;
447
+ }
448
+ return 0;
449
+ };
450
+ const getFitWidthScale = (pdfViewer) => {
451
+ const pageWidth = getPageWidthAtScaleOne(pdfViewer);
452
+ const containerWidth = container.clientWidth || targetWindow.innerWidth;
453
+ const availableWidth = Math.max(containerWidth - FIT_HORIZONTAL_PADDING - PAGE_BORDER_WIDTH, 96);
454
+ return pageWidth ? clampScale(availableWidth / pageWidth) : 1;
455
+ };
456
+ const fitToWidth = () => {
457
+ if (!pdfContext.viewer) {
458
+ return;
459
+ }
460
+ autoFitWidth = true;
461
+ setScale(getFitWidthScale(pdfContext.viewer));
462
+ void waitForPaint(targetWindow).then(() => {
463
+ var _a;
464
+ (_a = pdfContext.viewer) === null || _a === void 0 ? void 0 : _a.update();
465
+ });
466
+ };
467
+ const scheduleFitToWidth = () => {
468
+ if (!autoFitWidth || !pdfContext.viewer) {
469
+ return;
470
+ }
471
+ targetWindow.cancelAnimationFrame(fitFrame);
472
+ fitFrame = targetWindow.requestAnimationFrame(() => fitToWidth());
473
+ };
474
+ const zoomIn = () => {
475
+ autoFitWidth = false;
476
+ setScale(currentScale + SCALE_STEP);
477
+ };
478
+ const zoomOut = () => {
479
+ autoFitWidth = false;
480
+ setScale(currentScale - SCALE_STEP);
481
+ };
482
+ const applyRotation = (rotation) => {
483
+ const normalized = normalizeRotation(rotation);
484
+ currentRotation = normalized;
485
+ if (!pdfContext.viewer) {
486
+ syncUi();
487
+ return;
488
+ }
489
+ pdfContext.viewer.pagesRotation = normalized;
490
+ void waitForPaint(targetWindow).then(() => {
491
+ var _a;
492
+ if (autoFitWidth) {
493
+ fitToWidth();
494
+ return;
495
+ }
496
+ (_a = pdfContext.viewer) === null || _a === void 0 ? void 0 : _a.update();
497
+ syncUi();
498
+ });
499
+ };
500
+ const runWithStableHorizontalScroll = (action) => {
501
+ const previousScrollLeft = clampHorizontalScroll(container.scrollLeft || 0);
502
+ const result = action();
503
+ stabilizeHorizontalScroll(previousScrollLeft);
504
+ if (result && typeof result.then === 'function') {
505
+ void Promise.resolve(result).finally(() => stabilizeHorizontalScroll(previousScrollLeft));
506
+ }
507
+ };
508
+ function goToPage(pageNumber) {
509
+ if (!pdfContext.viewer || !pageCount) {
510
+ return;
511
+ }
512
+ const nextPage = Math.min(pageCount, Math.max(1, pageNumber));
513
+ runWithStableHorizontalScroll(() => {
514
+ pdfContext.viewer.currentPageNumber = nextPage;
515
+ currentPage = nextPage;
516
+ syncUi();
517
+ });
518
+ }
519
+ const toggleNav = () => {
520
+ if (!navigationEnabled) {
521
+ return;
522
+ }
523
+ navVisible = !navVisible;
524
+ syncUi();
525
+ void waitForPaint(targetWindow).then(() => {
526
+ var _a;
527
+ if (autoFitWidth) {
528
+ fitToWidth();
529
+ return;
530
+ }
531
+ (_a = pdfContext.viewer) === null || _a === void 0 ? void 0 : _a.update();
532
+ });
533
+ };
534
+ const setNavMode = (mode) => {
535
+ navMode = mode;
536
+ syncUi();
537
+ };
538
+ const toggleOutlineItem = (item) => {
539
+ if (!item.items.length) {
540
+ return;
541
+ }
542
+ item.expanded = !item.expanded;
543
+ syncUi();
544
+ };
545
+ const goToOutlineItem = (item) => {
546
+ if (!item.dest || !pdfContext.linkService) {
547
+ return;
548
+ }
549
+ runWithStableHorizontalScroll(() => pdfContext.linkService.goToDestination(item.dest));
550
+ };
551
+ const destroyPdfResource = async (resource) => {
552
+ var _a;
553
+ if (!resource) {
554
+ return;
555
+ }
556
+ try {
557
+ await resource.loadingTask.destroy();
558
+ }
559
+ catch (error) {
560
+ console.warn('PDF 加载任务销毁失败', error);
561
+ }
562
+ finally {
563
+ (_a = resource.worker) === null || _a === void 0 ? void 0 : _a.destroy();
564
+ }
565
+ };
566
+ const loadOutline = async (pdfDocument) => {
567
+ try {
568
+ const outline = await pdfDocument.getOutline();
569
+ if (destroyed || pdfContext.document !== pdfDocument) {
570
+ return;
571
+ }
572
+ outlineItems = Array.isArray(outline)
573
+ ? buildOutlineItems(outline)
574
+ : [];
575
+ syncUi();
576
+ }
577
+ catch (error) {
578
+ console.warn('PDF 大纲读取失败', error);
579
+ outlineItems = [];
580
+ syncUi();
581
+ }
582
+ };
583
+ const getPdfExportRatio = (width, height, mode) => {
584
+ const preferredRatio = mode === 'print' ? 1.75 : 1.5;
585
+ const maxRatio = Math.sqrt(PDF_EXPORT_MAX_PAGE_PIXELS / Math.max(width * height, 1));
586
+ return Math.max(0.75, Math.min(preferredRatio, maxRatio));
587
+ };
588
+ const getPdfPrintPageSize = async (pageNumber = 1) => {
589
+ var _a, _b;
590
+ const pdfDocument = pdfContext.document;
591
+ if (!pdfDocument) {
592
+ throw new Error('PDF 尚未加载完成,请稍后再试');
593
+ }
594
+ const page = await pdfDocument.getPage(Math.min(Math.max(pageNumber, 1), pdfDocument.numPages));
595
+ const viewport = page.getViewport({
596
+ scale: PixelsPerInch.PDF_TO_CSS_UNITS,
597
+ rotation: currentRotation,
598
+ });
599
+ (_b = (_a = page).cleanup) === null || _b === void 0 ? void 0 : _b.call(_a);
600
+ return {
601
+ width: Math.ceil(viewport.width),
602
+ height: Math.ceil(viewport.height),
603
+ };
604
+ };
605
+ const buildPdfPrintStyle = async () => {
606
+ const size = await getPdfPrintPageSize();
607
+ return buildPrintPageStyle({
608
+ selector: '.viewer-export-content .pdf-export-page',
609
+ width: size.width,
610
+ height: size.height,
611
+ });
612
+ };
613
+ const renderPdfPagesForExport = async (exportOptions) => {
614
+ var _a, _b;
615
+ const pdfDocument = pdfContext.document;
616
+ if (!pdfDocument) {
617
+ throw new Error('PDF 尚未加载完成,请稍后再试');
618
+ }
619
+ const pagesHtml = [];
620
+ for (let pageNumber = 1; pageNumber <= pdfDocument.numPages; pageNumber += 1) {
621
+ if (destroyed) {
622
+ throw new Error('PDF 已卸载,无法继续打印');
623
+ }
624
+ const page = await pdfDocument.getPage(pageNumber);
625
+ const baseViewport = page.getViewport({
626
+ scale: PixelsPerInch.PDF_TO_CSS_UNITS,
627
+ rotation: currentRotation,
628
+ });
629
+ const pageWidth = Math.ceil(baseViewport.width);
630
+ const pageHeight = Math.ceil(baseViewport.height);
631
+ const exportRatio = getPdfExportRatio(baseViewport.width, baseViewport.height, exportOptions.mode);
632
+ const renderViewport = page.getViewport({
633
+ scale: PixelsPerInch.PDF_TO_CSS_UNITS * exportRatio,
634
+ rotation: currentRotation,
635
+ });
636
+ const canvas = documentRef.createElement('canvas');
637
+ const canvasContext = canvas.getContext('2d');
638
+ if (!canvasContext) {
639
+ throw new Error('当前浏览器无法创建 PDF 打印画布');
640
+ }
641
+ canvas.width = Math.ceil(renderViewport.width);
642
+ canvas.height = Math.ceil(renderViewport.height);
643
+ await page.render({ canvas, canvasContext, viewport: renderViewport }).promise;
644
+ const pageTitle = `${exportOptions.title} - 第 ${pageNumber} 页`;
645
+ const pageStyle = [
646
+ `--viewer-print-page-width:${formatCssPixels(pageWidth)}`,
647
+ `--viewer-print-page-height:${formatCssPixels(pageHeight)}`,
648
+ `width:${formatCssPixels(pageWidth)}`,
649
+ `height:${formatCssPixels(pageHeight)}`,
650
+ ].join(';');
651
+ pagesHtml.push(`<section class="pdf-export-page viewer-print-page" style="${pageStyle}" aria-label="${escapeAttribute(pageTitle)}"><img src="${canvas.toDataURL('image/png')}" alt="${escapeAttribute(pageTitle)}" /></section>`);
652
+ canvas.width = 0;
653
+ canvas.height = 0;
654
+ (_b = (_a = page).cleanup) === null || _b === void 0 ? void 0 : _b.call(_a);
655
+ }
656
+ return `<div class="pdf-export-document">${pagesHtml.join('')}</div>`;
657
+ };
658
+ const loadFile = async () => {
659
+ var _a, _b;
660
+ const requestVersion = ++loadVersion;
661
+ loadStatus = 'loading';
662
+ errorMessage = '';
663
+ pdfContext.document = null;
664
+ outlineItems = [];
665
+ (_a = context === null || context === void 0 ? void 0 : context.registerExportAdapter) === null || _a === void 0 ? void 0 : _a.call(context, null);
666
+ syncUi();
667
+ let resource = null;
668
+ try {
669
+ if (destroyed || requestVersion !== loadVersion) {
670
+ return;
671
+ }
672
+ const eventBus = new EventBus();
673
+ const pdfLinkService = new PDFLinkService({ eventBus });
674
+ const pdfFindController = new PDFFindController({
675
+ eventBus,
676
+ linkService: pdfLinkService,
677
+ updateMatchesCountOnProgress: true,
678
+ });
679
+ const pdfViewer = new PDFViewer({
680
+ container,
681
+ eventBus,
682
+ linkService: pdfLinkService,
683
+ findController: pdfFindController,
684
+ l10n: new GenericL10n('zh-CN'),
685
+ enableAutoLinking: false,
686
+ });
687
+ pdfContext.viewer = pdfViewer;
688
+ pdfContext.linkService = pdfLinkService;
689
+ pdfContext.eventBus = eventBus;
690
+ pdfContext.findController = pdfFindController;
691
+ pdfLinkService.setViewer(pdfViewer);
692
+ eventBus.on('updatefindmatchescount', handlePdfFindMatchesCount);
693
+ eventBus.on('updatefindcontrolstate', handlePdfFindControlState);
694
+ eventBus.on('pagesinit', () => {
695
+ var _a;
696
+ applyRotation(currentRotation);
697
+ fitToWidth();
698
+ loadStatus = 'ready';
699
+ syncUi();
700
+ (_a = context === null || context === void 0 ? void 0 : context.onProgressiveRender) === null || _a === void 0 ? void 0 : _a.call(context);
701
+ if (pdfContext.search) {
702
+ eventBus.dispatch('find', { type: '', query: pdfContext.search });
703
+ }
704
+ });
705
+ eventBus.on('pagechanging', ({ pageNumber }) => {
706
+ currentPage = pageNumber;
707
+ syncUi();
708
+ });
709
+ eventBus.on('scalechanging', ({ scale }) => {
710
+ currentScale = clampScale(scale);
711
+ zoomEmitter.emit();
712
+ syncUi();
713
+ });
714
+ if (!(context === null || context === void 0 ? void 0 : context.streamUrl) && !buffer.byteLength) {
715
+ throw new Error('PDF 缺少可读取的数据源');
716
+ }
717
+ const worker = createPdfWorker();
718
+ const source = (context === null || context === void 0 ? void 0 : context.streamUrl)
719
+ ? {
720
+ url: context.streamUrl,
721
+ rangeChunkSize: (options === null || options === void 0 ? void 0 : options.rangeChunkSize) || DEFAULT_PDF_RANGE_CHUNK_SIZE,
722
+ withCredentials: (options === null || options === void 0 ? void 0 : options.withCredentials) === true,
723
+ }
724
+ : {
725
+ data: buffer,
726
+ };
727
+ const loadingTask = getDocument({
728
+ ...source,
729
+ worker: worker || undefined,
730
+ cMapUrl: `https://npm.onmicrosoft.cn/pdfjs-dist@${version}/cmaps/`,
731
+ wasmUrl: `https://npm.onmicrosoft.cn/pdfjs-dist@${version}/wasm/`,
732
+ useWorkerFetch: true,
733
+ cMapPacked: true,
734
+ enableXfa: true,
735
+ });
736
+ resource = { loadingTask, worker };
737
+ pdfContext.resource = resource;
738
+ const pdfDocument = await loadingTask.promise;
739
+ if (destroyed || requestVersion !== loadVersion || pdfContext.resource !== resource) {
740
+ if (pdfContext.resource === resource) {
741
+ pdfContext.resource = null;
742
+ await destroyPdfResource(resource);
743
+ }
744
+ return;
745
+ }
746
+ pageCount = pdfDocument.numPages;
747
+ currentPage = 1;
748
+ pdfContext.document = pdfDocument;
749
+ (_b = context === null || context === void 0 ? void 0 : context.registerExportAdapter) === null || _b === void 0 ? void 0 : _b.call(context, {
750
+ includeDocumentStyles: false,
751
+ printStyle: buildPdfPrintStyle,
752
+ toHtml: renderPdfPagesForExport,
753
+ });
754
+ void loadOutline(pdfDocument);
755
+ pdfViewer.setDocument(pdfDocument);
756
+ pdfLinkService.setDocument(pdfDocument, null);
757
+ syncUi();
758
+ }
759
+ catch (error) {
760
+ if (pdfContext.resource === resource) {
761
+ pdfContext.resource = null;
762
+ void destroyPdfResource(resource);
763
+ }
764
+ if (destroyed || requestVersion !== loadVersion) {
765
+ return;
766
+ }
767
+ loadStatus = 'error';
768
+ errorMessage = error instanceof Error ? error.message : 'PDF 加载失败';
769
+ syncUi();
770
+ }
771
+ };
772
+ registerFileViewerSearchProvider(root, {
773
+ search: (query, searchOptions) => runPdfFind(query, searchOptions, '', false),
774
+ next: () => pdfContext.search
775
+ ? runPdfFind(pdfContext.search, undefined, 'again', false)
776
+ : pdfSearchState,
777
+ previous: () => pdfContext.search
778
+ ? runPdfFind(pdfContext.search, undefined, 'again', true)
779
+ : pdfSearchState,
780
+ clear: clearPdfFind,
781
+ getState: () => pdfSearchState,
782
+ });
783
+ registerFileViewerZoomProvider(root, {
784
+ zoomIn: () => {
785
+ zoomIn();
786
+ return getPdfZoomState();
787
+ },
788
+ zoomOut: () => {
789
+ zoomOut();
790
+ return getPdfZoomState();
791
+ },
792
+ resetZoom: () => {
793
+ fitToWidth();
794
+ return getPdfZoomState();
795
+ },
796
+ setZoom: scale => {
797
+ autoFitWidth = false;
798
+ setScale(scale);
799
+ return getPdfZoomState();
800
+ },
801
+ getState: getPdfZoomState,
802
+ subscribe: zoomEmitter.subscribe,
803
+ });
804
+ navToggleButton.addEventListener('click', toggleNav);
805
+ previousPageButton.addEventListener('click', () => goToPage(currentPage - 1));
806
+ nextPageButton.addEventListener('click', () => goToPage(currentPage + 1));
807
+ zoomOutButton.addEventListener('click', zoomOut);
808
+ zoomInButton.addEventListener('click', zoomIn);
809
+ scaleButton.addEventListener('click', fitToWidth);
810
+ rotateLeftButton.addEventListener('click', () => applyRotation(currentRotation - 90));
811
+ rotateRightButton.addEventListener('click', () => applyRotation(currentRotation + 90));
812
+ pagesTab.addEventListener('click', () => setNavMode('pages'));
813
+ outlineTab.addEventListener('click', () => setNavMode('outline'));
814
+ if (targetWindow.ResizeObserver) {
815
+ resizeObserver = new targetWindow.ResizeObserver(() => scheduleFitToWidth());
816
+ resizeObserver.observe(container);
817
+ }
818
+ syncUi();
819
+ void loadFile();
820
+ return {
821
+ $el: root,
822
+ unmount() {
823
+ var _a;
824
+ destroyed = true;
825
+ loadVersion += 1;
826
+ targetWindow.cancelAnimationFrame(fitFrame);
827
+ resizeObserver === null || resizeObserver === void 0 ? void 0 : resizeObserver.disconnect();
828
+ resizeObserver = null;
829
+ unregisterFileViewerSearchProvider(root);
830
+ unregisterFileViewerZoomProvider(root);
831
+ outlineItems = [];
832
+ (_a = context === null || context === void 0 ? void 0 : context.registerExportAdapter) === null || _a === void 0 ? void 0 : _a.call(context, null);
833
+ const resource = pdfContext.resource;
834
+ pdfContext.viewer = null;
835
+ pdfContext.linkService = null;
836
+ pdfContext.eventBus = null;
837
+ pdfContext.findController = null;
838
+ pdfContext.document = null;
839
+ pdfContext.resource = null;
840
+ pdfSearchWaiters.forEach(waiter => targetWindow.clearTimeout(waiter.timer));
841
+ pdfSearchWaiters = [];
842
+ void destroyPdfResource(resource);
843
+ target.replaceChildren();
844
+ },
845
+ };
846
+ }