@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
package/dist/viewer.js ADDED
@@ -0,0 +1,285 @@
1
+ import { createEmptyFileViewerSearchState, } from './document.js';
2
+ import { createFileViewerDocumentFeatureControllerActionHandlers, } from './documentEvents.js';
3
+ import { createFileViewerZoomController } from './documentZoom.js';
4
+ import { DEFAULT_FILE_VIEWER_DOWNLOAD_FILENAME, DEFAULT_FILE_VIEWER_EXPORT_FILENAME, DEFAULT_FILE_VIEWER_PREVIEW_TITLE, createFileViewerOriginalSourceStateFromNormalizedSource, executeFileViewerDownloadOperation, executeFileViewerExportHtmlOperation, executeFileViewerPrintOperation, resolveFileViewerDisplayFilename, resolveFileViewerOperationFilename, } from './viewerOperations.js';
5
+ import { getRendererAvailability, createUnsupportedAvailability } from './capabilities.js';
6
+ import { buildFileViewerLifecycleContextFromNormalizedSource, buildFileViewerOperationContext, runFileViewerBeforeOperation, runFileViewerLifecycleHook, } from './operations.js';
7
+ import { createRendererRegistry } from './registry.js';
8
+ import { applyFileViewerRenderSurfaceState, createFileViewerRenderSurfaceState, } from './rendererHandler.js';
9
+ import { createFileViewerRequestScope } from './sourceLoading.js';
10
+ import { normalizeSource } from './source.js';
11
+ import { buildFileViewerWatermarkInlineStyle } from './watermark.js';
12
+ const emitLifecycle = async (options, onEvent, phase, source, version, startedAt, reason) => {
13
+ const now = Date.now();
14
+ const context = buildFileViewerLifecycleContextFromNormalizedSource({
15
+ phase,
16
+ source,
17
+ version,
18
+ timestamp: now,
19
+ startedAt,
20
+ reason,
21
+ });
22
+ await runFileViewerLifecycleHook(context, options.hooks, error => {
23
+ throw error;
24
+ });
25
+ onEvent === null || onEvent === void 0 ? void 0 : onEvent({ type: phase, payload: context });
26
+ };
27
+ export const createViewer = (container, createOptions = {}) => {
28
+ const registry = createOptions.registry || createRendererRegistry();
29
+ let options = createOptions.options || {};
30
+ let currentSource = null;
31
+ const renderSurfaceState = createFileViewerRenderSurfaceState();
32
+ const requestScope = createFileViewerRequestScope();
33
+ const documentTarget = {
34
+ anchors: { value: [] },
35
+ state: createEmptyFileViewerSearchState(),
36
+ };
37
+ const buildCurrentLifecycleContext = () => {
38
+ const source = currentSource || normalizeSource({});
39
+ return buildFileViewerLifecycleContextFromNormalizedSource({
40
+ phase: 'load-complete',
41
+ source,
42
+ version: requestScope.getCurrentVersion(),
43
+ timestamp: Date.now(),
44
+ });
45
+ };
46
+ const runBeforeViewerOperation = async (operation) => {
47
+ const context = buildFileViewerOperationContext(operation, buildCurrentLifecycleContext());
48
+ return runFileViewerBeforeOperation({
49
+ context,
50
+ options,
51
+ onBefore: nextContext => {
52
+ var _a;
53
+ (_a = createOptions.onEvent) === null || _a === void 0 ? void 0 : _a.call(createOptions, { type: 'operation-before', payload: nextContext });
54
+ },
55
+ onCancel: nextContext => {
56
+ var _a;
57
+ (_a = createOptions.onEvent) === null || _a === void 0 ? void 0 : _a.call(createOptions, { type: 'operation-cancel', payload: nextContext });
58
+ },
59
+ onError(error) {
60
+ throw error;
61
+ },
62
+ });
63
+ };
64
+ const getWatermarkInlineStyle = (override) => {
65
+ if (typeof override === 'string') {
66
+ return override;
67
+ }
68
+ return buildFileViewerWatermarkInlineStyle(options.watermark);
69
+ };
70
+ const getCapabilitiesForExtension = (extension) => {
71
+ const targetExtension = extension || (currentSource === null || currentSource === void 0 ? void 0 : currentSource.extension) || '';
72
+ const renderer = registry.getByExtension(targetExtension);
73
+ if (!renderer) {
74
+ return createUnsupportedAvailability(targetExtension);
75
+ }
76
+ return getRendererAvailability(renderer, renderSurfaceState.session);
77
+ };
78
+ const emitOperationAvailabilityChange = () => {
79
+ var _a;
80
+ (_a = createOptions.onEvent) === null || _a === void 0 ? void 0 : _a.call(createOptions, {
81
+ type: 'operation-availability-change',
82
+ payload: getCapabilitiesForExtension(),
83
+ });
84
+ };
85
+ const emitZoomChange = (state = zoomController.getState()) => {
86
+ var _a;
87
+ (_a = createOptions.onEvent) === null || _a === void 0 ? void 0 : _a.call(createOptions, {
88
+ type: 'zoom-change',
89
+ payload: state,
90
+ });
91
+ };
92
+ const zoomController = createFileViewerZoomController({
93
+ root: () => container,
94
+ beforeZoom: runBeforeViewerOperation,
95
+ });
96
+ const documentActions = createFileViewerDocumentFeatureControllerActionHandlers({
97
+ root: () => container,
98
+ searchTarget: documentTarget,
99
+ searchOptions: () => options.search,
100
+ getAiOptions: () => options.ai,
101
+ onSearchChange: state => {
102
+ var _a;
103
+ (_a = createOptions.onEvent) === null || _a === void 0 ? void 0 : _a.call(createOptions, { type: 'search-change', payload: state });
104
+ },
105
+ onLocationChange: anchor => {
106
+ var _a;
107
+ (_a = createOptions.onEvent) === null || _a === void 0 ? void 0 : _a.call(createOptions, { type: 'location-change', payload: anchor });
108
+ },
109
+ });
110
+ zoomController.observe();
111
+ const destroyCurrent = async (reason = 'replace') => {
112
+ var _a, _b;
113
+ if (!currentSource) {
114
+ return;
115
+ }
116
+ const source = currentSource;
117
+ const startedAt = Date.now();
118
+ const version = requestScope.getCurrentVersion();
119
+ await emitLifecycle(options, createOptions.onEvent, 'unload-start', source, version, startedAt, reason);
120
+ await ((_b = (_a = renderSurfaceState.session) === null || _a === void 0 ? void 0 : _a.destroy) === null || _b === void 0 ? void 0 : _b.call(_a));
121
+ currentSource = null;
122
+ applyFileViewerRenderSurfaceState(renderSurfaceState, {
123
+ session: null,
124
+ exportAdapter: null,
125
+ });
126
+ await documentActions.clearDocumentState();
127
+ zoomController.clearProvider();
128
+ emitOperationAvailabilityChange();
129
+ emitZoomChange();
130
+ await emitLifecycle(options, createOptions.onEvent, 'unload-complete', source, version, startedAt, reason);
131
+ };
132
+ return {
133
+ container,
134
+ async load(source) {
135
+ await destroyCurrent('replace');
136
+ const normalized = normalizeSource(source);
137
+ currentSource = normalized;
138
+ const version = requestScope.requestController.createVersion();
139
+ const renderer = registry.getByExtension(normalized.extension);
140
+ const startedAt = Date.now();
141
+ await emitLifecycle(options, createOptions.onEvent, 'load-start', normalized, version, startedAt);
142
+ if (!(renderer === null || renderer === void 0 ? void 0 : renderer.load)) {
143
+ applyFileViewerRenderSurfaceState(renderSurfaceState, { session: null });
144
+ emitOperationAvailabilityChange();
145
+ emitZoomChange();
146
+ await emitLifecycle(options, createOptions.onEvent, 'load-complete', normalized, version, startedAt);
147
+ return null;
148
+ }
149
+ const session = await renderer.load({
150
+ source: normalized,
151
+ surface: { container },
152
+ options,
153
+ signal: createOptions.signal,
154
+ registerExportAdapter: adapter => {
155
+ applyFileViewerRenderSurfaceState(renderSurfaceState, { exportAdapter: adapter });
156
+ },
157
+ });
158
+ applyFileViewerRenderSurfaceState(renderSurfaceState, { session });
159
+ zoomController.refreshProvider();
160
+ await documentActions.refreshDocumentIndex({ notify: false });
161
+ emitOperationAvailabilityChange();
162
+ emitZoomChange();
163
+ await emitLifecycle(options, createOptions.onEvent, 'load-complete', normalized, version, startedAt);
164
+ return session;
165
+ },
166
+ async destroy(reason = 'component-unmount') {
167
+ await destroyCurrent(reason);
168
+ documentActions.destroyDocumentFeatures();
169
+ zoomController.destroy();
170
+ },
171
+ updateOptions(nextOptions) {
172
+ options = {
173
+ ...options,
174
+ ...nextOptions,
175
+ };
176
+ },
177
+ getCapabilities(extension) {
178
+ return getCapabilitiesForExtension(extension);
179
+ },
180
+ getRenderer(extension) {
181
+ return registry.getByExtension(extension || (currentSource === null || currentSource === void 0 ? void 0 : currentSource.extension) || '');
182
+ },
183
+ getSource() {
184
+ return currentSource;
185
+ },
186
+ registerExportAdapter(adapter) {
187
+ applyFileViewerRenderSurfaceState(renderSurfaceState, { exportAdapter: adapter });
188
+ },
189
+ getExportAdapter() {
190
+ return renderSurfaceState.exportAdapter;
191
+ },
192
+ async download(downloadOptions = {}) {
193
+ const source = createFileViewerOriginalSourceStateFromNormalizedSource(currentSource);
194
+ await executeFileViewerDownloadOperation({
195
+ source,
196
+ filename: downloadOptions.filename || resolveFileViewerOperationFilename({
197
+ source,
198
+ fallback: DEFAULT_FILE_VIEWER_DOWNLOAD_FILENAME,
199
+ }),
200
+ beforeOperation: runBeforeViewerOperation,
201
+ });
202
+ },
203
+ async exportHtml(exportOptions = {}) {
204
+ return executeFileViewerExportHtmlOperation({
205
+ source: container,
206
+ adapter: renderSurfaceState.exportAdapter,
207
+ download: exportOptions.download,
208
+ filename: exportOptions.filename || resolveFileViewerOperationFilename({
209
+ filename: resolveFileViewerDisplayFilename(currentSource),
210
+ fallback: DEFAULT_FILE_VIEWER_EXPORT_FILENAME,
211
+ }),
212
+ title: exportOptions.title || resolveFileViewerOperationFilename({
213
+ filename: resolveFileViewerDisplayFilename(currentSource),
214
+ fallback: DEFAULT_FILE_VIEWER_PREVIEW_TITLE,
215
+ }),
216
+ watermarkInlineStyle: getWatermarkInlineStyle(exportOptions.watermarkInlineStyle),
217
+ beforeOperation: runBeforeViewerOperation,
218
+ });
219
+ },
220
+ async print(printOptions = {}) {
221
+ await executeFileViewerPrintOperation({
222
+ source: container,
223
+ adapter: renderSurfaceState.exportAdapter,
224
+ autoPrint: printOptions.autoPrint,
225
+ openWindow: printOptions.openWindow,
226
+ printWindow: printOptions.printWindow,
227
+ title: printOptions.title || resolveFileViewerOperationFilename({
228
+ filename: resolveFileViewerDisplayFilename(currentSource),
229
+ fallback: DEFAULT_FILE_VIEWER_PREVIEW_TITLE,
230
+ }),
231
+ watermarkInlineStyle: getWatermarkInlineStyle(printOptions.watermarkInlineStyle),
232
+ printAvailable: getCapabilitiesForExtension().print,
233
+ beforeOperation: runBeforeViewerOperation,
234
+ });
235
+ },
236
+ async zoomIn() {
237
+ const state = await zoomController.zoomIn();
238
+ emitZoomChange(state);
239
+ return state;
240
+ },
241
+ async zoomOut() {
242
+ const state = await zoomController.zoomOut();
243
+ emitZoomChange(state);
244
+ return state;
245
+ },
246
+ async resetZoom() {
247
+ const state = await zoomController.resetZoom();
248
+ emitZoomChange(state);
249
+ return state;
250
+ },
251
+ getZoomState() {
252
+ return zoomController.getState();
253
+ },
254
+ search(query) {
255
+ return documentActions.searchDocument(query);
256
+ },
257
+ nextSearchResult() {
258
+ return documentActions.nextSearchResult();
259
+ },
260
+ previousSearchResult() {
261
+ return documentActions.previousSearchResult();
262
+ },
263
+ clearSearch() {
264
+ return documentActions.clearDocumentSearch();
265
+ },
266
+ getSearchState() {
267
+ return documentActions.getSearchState();
268
+ },
269
+ collectDocumentAnchors() {
270
+ return documentActions.collectDocumentAnchors({ notify: false });
271
+ },
272
+ getCurrentDocumentAnchor() {
273
+ return documentActions.getCurrentDocumentAnchor();
274
+ },
275
+ scrollToDocumentAnchor(anchor) {
276
+ return documentActions.scrollToLoadedAnchor(anchor);
277
+ },
278
+ scrollToLine(line) {
279
+ return documentActions.scrollToLine(line);
280
+ },
281
+ getDocumentTextChunks(textOptions) {
282
+ return documentActions.getDocumentTextChunks(textOptions);
283
+ },
284
+ };
285
+ };
@@ -0,0 +1,88 @@
1
+ import type { FileViewerErrorMessageFormatter } from './state';
2
+ import type { FileRenderExportAdapter, FileViewerDownloadOptions, FileViewerExportHtmlOptions, FileViewerOperationType, FileViewerPrintOptions, NormalizedFileViewerSource } from './types';
3
+ export interface FileViewerOriginalSourceState {
4
+ buffer?: ArrayBuffer | null;
5
+ file?: File | Blob | null;
6
+ url?: string | null;
7
+ filename?: string | null;
8
+ mimeType?: string | null;
9
+ }
10
+ export type CreateFileViewerOriginalSourceStateInput = FileViewerOriginalSourceState;
11
+ export declare const DEFAULT_FILE_VIEWER_PREVIEW_TITLE = "file-viewer-preview";
12
+ export declare const DEFAULT_FILE_VIEWER_EXPORT_FILENAME = "preview";
13
+ export declare const DEFAULT_FILE_VIEWER_DOWNLOAD_FILENAME = "preview.bin";
14
+ export interface ResolveFileViewerOperationFilenameInput {
15
+ filename?: string | null;
16
+ source?: FileViewerOriginalSourceState | null;
17
+ fallback?: string;
18
+ }
19
+ export interface FileViewerOperationExecutorBase {
20
+ beforeOperation?: (operation: FileViewerOperationType) => boolean | Promise<boolean>;
21
+ }
22
+ export interface ExecuteFileViewerDownloadOperationInput extends FileViewerOperationExecutorBase, FileViewerDownloadOptions {
23
+ source: FileViewerOriginalSourceState;
24
+ throwOnMissingSource?: boolean;
25
+ }
26
+ export interface ExecuteFileViewerExportHtmlOperationInput extends FileViewerOperationExecutorBase, FileViewerExportHtmlOptions {
27
+ source: HTMLElement | null | undefined;
28
+ adapter?: FileRenderExportAdapter | null;
29
+ }
30
+ export interface ExecuteFileViewerPrintOperationInput extends FileViewerOperationExecutorBase, FileViewerPrintOptions {
31
+ source: HTMLElement | null | undefined;
32
+ adapter?: FileRenderExportAdapter | null;
33
+ printAvailable?: boolean;
34
+ }
35
+ export type FileViewerFileOperationType = Extract<FileViewerOperationType, 'download' | 'export-html' | 'print'>;
36
+ export interface FileViewerOperationActionErrorContext {
37
+ operation: FileViewerFileOperationType;
38
+ error: unknown;
39
+ }
40
+ export type FileViewerOperationActionErrorFormatter = FileViewerErrorMessageFormatter;
41
+ export type FileViewerOperationActionErrorPrefixes = Partial<Record<FileViewerFileOperationType, string>>;
42
+ export declare const FILE_VIEWER_OPERATION_ACTION_ERROR_PREFIXES: {
43
+ readonly download: "下载失败";
44
+ readonly print: "打印失败";
45
+ readonly 'export-html': "导出 HTML 失败";
46
+ };
47
+ export interface ResolveFileViewerOperationActionErrorMessageInput {
48
+ context: FileViewerOperationActionErrorContext;
49
+ formatErrorMessage: FileViewerOperationActionErrorFormatter;
50
+ prefixes?: FileViewerOperationActionErrorPrefixes;
51
+ }
52
+ export interface CreateFileViewerOperationActionHandlersInput extends FileViewerOperationExecutorBase {
53
+ getBuffer?: () => ArrayBuffer | null | undefined;
54
+ getFile?: () => File | Blob | null | undefined;
55
+ getUrl?: () => string | null | undefined;
56
+ getFilename: () => string | null | undefined;
57
+ getMimeType?: () => string | null | undefined;
58
+ getRenderedSource: () => HTMLElement | null | undefined;
59
+ getAdapter?: () => FileRenderExportAdapter | null | undefined;
60
+ getWatermarkInlineStyle?: () => string | null | undefined;
61
+ getPrintAvailable?: () => boolean | undefined;
62
+ onError?: (context: FileViewerOperationActionErrorContext) => void;
63
+ formatErrorMessage?: FileViewerOperationActionErrorFormatter;
64
+ errorPrefixes?: FileViewerOperationActionErrorPrefixes;
65
+ onErrorMessage?: (message: string, context: FileViewerOperationActionErrorContext) => void;
66
+ }
67
+ export interface FileViewerOperationActionHandlers {
68
+ downloadOriginalFile(): Promise<boolean | undefined>;
69
+ exportRenderedHtml(): Promise<string | undefined>;
70
+ printRenderedHtml(): Promise<boolean | undefined>;
71
+ }
72
+ export interface FileViewerPublicOperationActionHandlers {
73
+ downloadOriginalFile(): Promise<void>;
74
+ exportRenderedHtml(): Promise<void>;
75
+ printRenderedHtml(): Promise<void>;
76
+ }
77
+ export declare const createFileViewerOriginalSourceState: ({ buffer, file, url, filename, mimeType, }?: CreateFileViewerOriginalSourceStateInput) => FileViewerOriginalSourceState;
78
+ export declare const resolveFileViewerDisplayFilename: (source?: Pick<NormalizedFileViewerSource, "filename"> | null, fallback?: string) => string;
79
+ export declare const createFileViewerOriginalSourceStateFromNormalizedSource: (source?: NormalizedFileViewerSource | null, fallbackFilename?: string) => FileViewerOriginalSourceState;
80
+ export declare const resolveFileViewerOriginalFilename: (source: FileViewerOriginalSourceState, fallback?: string) => string;
81
+ export declare const resolveFileViewerOperationFilename: ({ filename, source, fallback, }: ResolveFileViewerOperationFilenameInput) => string;
82
+ export declare const resolveFileViewerOperationActionErrorMessage: ({ context, formatErrorMessage, prefixes, }: ResolveFileViewerOperationActionErrorMessageInput) => string;
83
+ export declare const hasFileViewerOriginalSource: (source: FileViewerOriginalSourceState) => boolean;
84
+ export declare const executeFileViewerDownloadOperation: ({ source, filename, beforeOperation, throwOnMissingSource, }: ExecuteFileViewerDownloadOperationInput) => Promise<boolean>;
85
+ export declare const executeFileViewerExportHtmlOperation: ({ download, filename, beforeOperation, ...input }: ExecuteFileViewerExportHtmlOperationInput) => Promise<string>;
86
+ export declare const executeFileViewerPrintOperation: ({ autoPrint, beforeOperation, openWindow, printAvailable, printWindow, ...input }: ExecuteFileViewerPrintOperationInput) => Promise<boolean>;
87
+ export declare const createFileViewerOperationActionHandlers: ({ getBuffer, getFile, getUrl, getFilename, getMimeType, getRenderedSource, getAdapter, getWatermarkInlineStyle, getPrintAvailable, beforeOperation, errorPrefixes, formatErrorMessage, onError, onErrorMessage, }: CreateFileViewerOperationActionHandlersInput) => FileViewerOperationActionHandlers;
88
+ export declare const createFileViewerPublicOperationActionHandlers: (input: CreateFileViewerOperationActionHandlersInput) => FileViewerPublicOperationActionHandlers;
@@ -0,0 +1,242 @@
1
+ import { buildFileViewerRenderedHtmlDocument, triggerFileViewerBlobDownload, triggerFileViewerUrlDownload, waitForFileViewerPrintWindowReady, } from './export.js';
2
+ import { DEFAULT_FILE_VIEWER_SOURCE_FILENAME } from './source.js';
3
+ export const DEFAULT_FILE_VIEWER_PREVIEW_TITLE = 'file-viewer-preview';
4
+ export const DEFAULT_FILE_VIEWER_EXPORT_FILENAME = 'preview';
5
+ export const DEFAULT_FILE_VIEWER_DOWNLOAD_FILENAME = DEFAULT_FILE_VIEWER_SOURCE_FILENAME;
6
+ export const FILE_VIEWER_OPERATION_ACTION_ERROR_PREFIXES = {
7
+ download: '下载失败',
8
+ print: '打印失败',
9
+ 'export-html': '导出 HTML 失败',
10
+ };
11
+ const getBlobFilename = (file) => {
12
+ return file && 'name' in file && typeof file.name === 'string' ? file.name : '';
13
+ };
14
+ const getBlobMimeType = (file) => {
15
+ return file && typeof file.type === 'string' ? file.type : '';
16
+ };
17
+ export const createFileViewerOriginalSourceState = ({ buffer = null, file = null, url = null, filename = null, mimeType = null, } = {}) => {
18
+ return {
19
+ buffer,
20
+ file,
21
+ url,
22
+ filename,
23
+ mimeType: mimeType || getBlobMimeType(file) || null,
24
+ };
25
+ };
26
+ export const resolveFileViewerDisplayFilename = (source, fallback = DEFAULT_FILE_VIEWER_EXPORT_FILENAME) => {
27
+ return (source === null || source === void 0 ? void 0 : source.filename) || fallback;
28
+ };
29
+ export const createFileViewerOriginalSourceStateFromNormalizedSource = (source, fallbackFilename = DEFAULT_FILE_VIEWER_EXPORT_FILENAME) => {
30
+ var _a;
31
+ return createFileViewerOriginalSourceState({
32
+ buffer: source === null || source === void 0 ? void 0 : source.buffer,
33
+ file: source === null || source === void 0 ? void 0 : source.file,
34
+ url: source === null || source === void 0 ? void 0 : source.url,
35
+ filename: resolveFileViewerDisplayFilename(source, fallbackFilename),
36
+ mimeType: (_a = source === null || source === void 0 ? void 0 : source.file) === null || _a === void 0 ? void 0 : _a.type,
37
+ });
38
+ };
39
+ export const resolveFileViewerOriginalFilename = (source, fallback = 'preview') => {
40
+ return source.filename || getBlobFilename(source.file) || fallback;
41
+ };
42
+ export const resolveFileViewerOperationFilename = ({ filename, source, fallback = DEFAULT_FILE_VIEWER_PREVIEW_TITLE, }) => {
43
+ return filename || (source ? resolveFileViewerOriginalFilename(source, '') : '') || fallback;
44
+ };
45
+ export const resolveFileViewerOperationActionErrorMessage = ({ context, formatErrorMessage, prefixes, }) => {
46
+ var _a;
47
+ return formatErrorMessage((_a = prefixes === null || prefixes === void 0 ? void 0 : prefixes[context.operation]) !== null && _a !== void 0 ? _a : FILE_VIEWER_OPERATION_ACTION_ERROR_PREFIXES[context.operation], context.error);
48
+ };
49
+ export const hasFileViewerOriginalSource = (source) => {
50
+ return !!source.buffer || !!source.file || !!source.url;
51
+ };
52
+ const runBeforeOperation = async (beforeOperation, operation) => {
53
+ if (!beforeOperation) {
54
+ return true;
55
+ }
56
+ return await beforeOperation(operation);
57
+ };
58
+ const buildRenderedHtmlDocumentFromOperation = async (mode, { source, title, filename, adapter = null, watermarkInlineStyle, }) => {
59
+ if (!source) {
60
+ throw new Error('当前没有可导出的预览内容');
61
+ }
62
+ return buildFileViewerRenderedHtmlDocument({
63
+ source,
64
+ mode,
65
+ title: resolveFileViewerOperationFilename({
66
+ filename: title || filename,
67
+ fallback: DEFAULT_FILE_VIEWER_PREVIEW_TITLE,
68
+ }),
69
+ adapter,
70
+ watermarkInlineStyle,
71
+ });
72
+ };
73
+ export const executeFileViewerDownloadOperation = async ({ source, filename, beforeOperation, throwOnMissingSource = true, }) => {
74
+ var _a;
75
+ if (!hasFileViewerOriginalSource(source)) {
76
+ if (throwOnMissingSource) {
77
+ throw new Error('当前没有可下载的源文件');
78
+ }
79
+ return false;
80
+ }
81
+ if (!await runBeforeOperation(beforeOperation, 'download')) {
82
+ return false;
83
+ }
84
+ const resolvedFilename = resolveFileViewerOperationFilename({
85
+ filename,
86
+ source,
87
+ fallback: DEFAULT_FILE_VIEWER_DOWNLOAD_FILENAME,
88
+ });
89
+ if (source.buffer) {
90
+ triggerFileViewerBlobDownload(new Blob([source.buffer], { type: source.mimeType || ((_a = source.file) === null || _a === void 0 ? void 0 : _a.type) || 'application/octet-stream' }), resolvedFilename);
91
+ return true;
92
+ }
93
+ if (source.file) {
94
+ triggerFileViewerBlobDownload(source.file, resolvedFilename);
95
+ return true;
96
+ }
97
+ triggerFileViewerUrlDownload(source.url, resolvedFilename);
98
+ return true;
99
+ };
100
+ export const executeFileViewerExportHtmlOperation = async ({ download = true, filename, beforeOperation, ...input }) => {
101
+ if (!await runBeforeOperation(beforeOperation, 'export-html')) {
102
+ return '';
103
+ }
104
+ const html = await buildRenderedHtmlDocumentFromOperation('export', {
105
+ ...input,
106
+ filename,
107
+ });
108
+ if (download !== false) {
109
+ const baseName = resolveFileViewerOperationFilename({
110
+ filename: filename || input.title,
111
+ fallback: DEFAULT_FILE_VIEWER_EXPORT_FILENAME,
112
+ });
113
+ triggerFileViewerBlobDownload(new Blob([html], { type: 'text/html;charset=utf-8' }), `${baseName}.rendered.html`);
114
+ }
115
+ return html;
116
+ };
117
+ export const executeFileViewerPrintOperation = async ({ autoPrint = true, beforeOperation, openWindow, printAvailable = true, printWindow, ...input }) => {
118
+ if (!printAvailable) {
119
+ throw new Error('当前文件类型不支持完整打印,请下载原文件后在本地应用中打印');
120
+ }
121
+ if (!await runBeforeOperation(beforeOperation, 'print')) {
122
+ return false;
123
+ }
124
+ const html = await buildRenderedHtmlDocumentFromOperation('print', input);
125
+ const targetWindow = printWindow ||
126
+ (openWindow === null || openWindow === void 0 ? void 0 : openWindow()) ||
127
+ (typeof window !== 'undefined' ? window.open('', '_blank') : null);
128
+ if (!targetWindow) {
129
+ throw new Error('浏览器拦截了打印窗口');
130
+ }
131
+ targetWindow.document.open();
132
+ targetWindow.document.write(html);
133
+ targetWindow.document.close();
134
+ targetWindow.focus();
135
+ await waitForFileViewerPrintWindowReady(targetWindow);
136
+ if (autoPrint !== false) {
137
+ targetWindow.print();
138
+ }
139
+ return true;
140
+ };
141
+ const handleFileViewerOperationActionError = (operation, error, { errorPrefixes, formatErrorMessage, onError, onErrorMessage, }) => {
142
+ const context = { operation, error };
143
+ onError === null || onError === void 0 ? void 0 : onError(context);
144
+ if (formatErrorMessage && onErrorMessage) {
145
+ onErrorMessage(resolveFileViewerOperationActionErrorMessage({
146
+ context,
147
+ formatErrorMessage,
148
+ prefixes: errorPrefixes,
149
+ }), context);
150
+ }
151
+ };
152
+ export const createFileViewerOperationActionHandlers = ({ getBuffer, getFile, getUrl, getFilename, getMimeType, getRenderedSource, getAdapter, getWatermarkInlineStyle, getPrintAvailable, beforeOperation, errorPrefixes, formatErrorMessage, onError, onErrorMessage, }) => {
153
+ const getOriginalSource = () => {
154
+ var _a, _b, _c, _d;
155
+ const file = (_a = getFile === null || getFile === void 0 ? void 0 : getFile()) !== null && _a !== void 0 ? _a : null;
156
+ return createFileViewerOriginalSourceState({
157
+ buffer: (_b = getBuffer === null || getBuffer === void 0 ? void 0 : getBuffer()) !== null && _b !== void 0 ? _b : null,
158
+ file,
159
+ url: (_c = getUrl === null || getUrl === void 0 ? void 0 : getUrl()) !== null && _c !== void 0 ? _c : null,
160
+ filename: getFilename(),
161
+ mimeType: (_d = getMimeType === null || getMimeType === void 0 ? void 0 : getMimeType()) !== null && _d !== void 0 ? _d : getBlobMimeType(file),
162
+ });
163
+ };
164
+ const getRenderedOperationInput = () => {
165
+ var _a, _b;
166
+ const filename = getFilename() || undefined;
167
+ return {
168
+ source: getRenderedSource(),
169
+ adapter: (_a = getAdapter === null || getAdapter === void 0 ? void 0 : getAdapter()) !== null && _a !== void 0 ? _a : null,
170
+ title: filename,
171
+ filename,
172
+ watermarkInlineStyle: (_b = getWatermarkInlineStyle === null || getWatermarkInlineStyle === void 0 ? void 0 : getWatermarkInlineStyle()) !== null && _b !== void 0 ? _b : undefined,
173
+ beforeOperation,
174
+ };
175
+ };
176
+ return {
177
+ async downloadOriginalFile() {
178
+ try {
179
+ return await executeFileViewerDownloadOperation({
180
+ source: getOriginalSource(),
181
+ beforeOperation,
182
+ throwOnMissingSource: false,
183
+ });
184
+ }
185
+ catch (error) {
186
+ handleFileViewerOperationActionError('download', error, {
187
+ errorPrefixes,
188
+ formatErrorMessage,
189
+ onError,
190
+ onErrorMessage,
191
+ });
192
+ return undefined;
193
+ }
194
+ },
195
+ async exportRenderedHtml() {
196
+ try {
197
+ return await executeFileViewerExportHtmlOperation(getRenderedOperationInput());
198
+ }
199
+ catch (error) {
200
+ handleFileViewerOperationActionError('export-html', error, {
201
+ errorPrefixes,
202
+ formatErrorMessage,
203
+ onError,
204
+ onErrorMessage,
205
+ });
206
+ return undefined;
207
+ }
208
+ },
209
+ async printRenderedHtml() {
210
+ var _a;
211
+ try {
212
+ return await executeFileViewerPrintOperation({
213
+ ...getRenderedOperationInput(),
214
+ printAvailable: (_a = getPrintAvailable === null || getPrintAvailable === void 0 ? void 0 : getPrintAvailable()) !== null && _a !== void 0 ? _a : true,
215
+ });
216
+ }
217
+ catch (error) {
218
+ handleFileViewerOperationActionError('print', error, {
219
+ errorPrefixes,
220
+ formatErrorMessage,
221
+ onError,
222
+ onErrorMessage,
223
+ });
224
+ return undefined;
225
+ }
226
+ },
227
+ };
228
+ };
229
+ export const createFileViewerPublicOperationActionHandlers = (input) => {
230
+ const actions = createFileViewerOperationActionHandlers(input);
231
+ return {
232
+ async downloadOriginalFile() {
233
+ await actions.downloadOriginalFile();
234
+ },
235
+ async exportRenderedHtml() {
236
+ await actions.exportRenderedHtml();
237
+ },
238
+ async printRenderedHtml() {
239
+ await actions.printRenderedHtml();
240
+ },
241
+ };
242
+ };
@@ -0,0 +1,15 @@
1
+ import type { FileViewerWatermarkOptions } from './types';
2
+ export type FileViewerWatermarkStyle = Record<string, string> & {
3
+ backgroundImage: string;
4
+ };
5
+ export interface FileViewerWatermarkPresentationState {
6
+ normalizedWatermark: FileViewerWatermarkOptions | null;
7
+ watermarkStyle: FileViewerWatermarkStyle | undefined;
8
+ watermarkInlineStyle: string;
9
+ }
10
+ export declare const normalizeFileViewerWatermark: (watermark?: boolean | FileViewerWatermarkOptions) => FileViewerWatermarkOptions | null;
11
+ export declare const buildFileViewerWatermarkSvg: (watermark: FileViewerWatermarkOptions) => string;
12
+ export declare const buildFileViewerWatermarkBackgroundImage: (watermark?: boolean | FileViewerWatermarkOptions) => string;
13
+ export declare const buildFileViewerWatermarkStyle: (watermark?: boolean | FileViewerWatermarkOptions) => FileViewerWatermarkStyle | undefined;
14
+ export declare const buildFileViewerWatermarkInlineStyle: (watermark?: boolean | FileViewerWatermarkOptions) => string;
15
+ export declare const resolveFileViewerWatermarkPresentationState: (watermark?: boolean | FileViewerWatermarkOptions) => FileViewerWatermarkPresentationState;