@file-viewer/core 2.1.1 → 2.1.3

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.
@@ -10,7 +10,7 @@ import { createFileViewerZoomController } from '../features/document/zoom.js';
10
10
  import { DEFAULT_FILE_VIEWER_DOWNLOAD_FILENAME, DEFAULT_FILE_VIEWER_EXPORT_FILENAME, DEFAULT_FILE_VIEWER_PREVIEW_TITLE, createFileViewerOriginalSourceStateFromNormalizedSource, executeFileViewerDownloadOperation, executeFileViewerExportHtmlOperation, executeFileViewerPrintOperation, resolveFileViewerDisplayFilename, resolveFileViewerOperationFilename, } from './operations.js';
11
11
  import { getRendererAvailability, createUnsupportedAvailability } from '../registry/capabilities.js';
12
12
  import { buildFileViewerLifecycleContextFromNormalizedSource, buildFileViewerOperationContext, runFileViewerBeforeOperation, runFileViewerLifecycleHook, } from '../lifecycle/operations.js';
13
- import { collectFileViewerRendererPlugins, createRendererRegistry, installFileViewerRendererPlugins, } from '../registry/registry.js';
13
+ import { collectFileViewerRendererPlugins, createRendererRegistry, getFileViewerAutoRendererPresetVersion, hasFileViewerRendererPresetName, installFileViewerRendererPlugins, listFileViewerAutoRendererPresets, resolveFileViewerRendererPresetInputs, } from '../registry/registry.js';
14
14
  import { createFileRenderHandlerLoader, applyFileViewerRenderSurfaceState, createFileViewerRenderSurfaceState, } from '../rendering/handler.js';
15
15
  import { createFileViewerCoreRendererRegistry } from '../renderers/index.js';
16
16
  import { createFileViewerRequestScope } from '../source/loading.js';
@@ -43,9 +43,19 @@ const createBaseRendererRegistry = (createOptions, options) => {
43
43
  builtinRenderers: options.builtinRenderers,
44
44
  }).registry;
45
45
  };
46
- const renderMissingRendererState = (container, type) => {
46
+ const resolveAutoRenderersEnabled = (options) => {
47
+ const setting = options.autoRenderers;
48
+ if (typeof setting === 'boolean') {
49
+ return setting;
50
+ }
51
+ if ((setting === null || setting === void 0 ? void 0 : setting.enabled) !== undefined) {
52
+ return setting.enabled;
53
+ }
54
+ return (options.rendererMode || 'extend') !== 'replace';
55
+ };
56
+ const renderMissingRendererState = (container, type, options) => {
47
57
  const documentRef = container.ownerDocument;
48
- const state = createFileViewerUnsupportedState(type);
58
+ const state = createFileViewerUnsupportedState(type, undefined, options);
49
59
  const wrapper = documentRef.createElement('div');
50
60
  wrapper.className = 'file-viewer-missing-renderer';
51
61
  wrapper.style.cssText = [
@@ -65,8 +75,7 @@ const renderMissingRendererState = (container, type) => {
65
75
  title.textContent = state.message;
66
76
  title.style.cssText = 'display:block;margin-bottom:8px;color:#172033;font-size:16px;';
67
77
  const description = documentRef.createElement('p');
68
- description.textContent = state.description ||
69
- '当前内置 renderer 配置没有加载该格式。请安装并传入对应 @file-viewer/renderer-* 包,或使用 @file-viewer/preset-all。';
78
+ description.textContent = state.description || state.title;
70
79
  description.style.cssText = 'max-width:520px;margin:0;';
71
80
  content.append(title, description);
72
81
  wrapper.append(content);
@@ -76,8 +85,12 @@ export const createViewer = (container, createOptions = {}) => {
76
85
  let options = createOptions.options || {};
77
86
  let registry = createBaseRendererRegistry(createOptions, options);
78
87
  let installedRendererInput = undefined;
88
+ let installedPresetInput = undefined;
89
+ let installedPresetsInput = undefined;
79
90
  let installedRendererMode = options.rendererMode || 'extend';
80
91
  let installedBuiltinRenderers = options.builtinRenderers || 'all';
92
+ let installedAutoRenderersEnabled = resolveAutoRenderersEnabled(options);
93
+ let installedAutoRendererVersion = -1;
81
94
  let currentSource = null;
82
95
  const renderSurfaceState = createFileViewerRenderSurfaceState();
83
96
  const requestScope = createFileViewerRequestScope();
@@ -88,17 +101,42 @@ export const createViewer = (container, createOptions = {}) => {
88
101
  const ensureRendererPluginsInstalled = async () => {
89
102
  const nextMode = options.rendererMode || 'extend';
90
103
  const nextRendererInput = options.renderers;
104
+ const nextPresetInput = options.preset;
105
+ const nextPresetsInput = options.presets;
91
106
  const nextBuiltinRenderers = options.builtinRenderers || 'all';
107
+ const nextAutoRenderersEnabled = resolveAutoRenderersEnabled(options);
108
+ const needsAutoPresetBucket = nextAutoRenderersEnabled ||
109
+ hasFileViewerRendererPresetName(nextPresetInput) ||
110
+ hasFileViewerRendererPresetName(nextPresetsInput);
111
+ const nextAutoRendererVersion = needsAutoPresetBucket
112
+ ? getFileViewerAutoRendererPresetVersion()
113
+ : 0;
92
114
  if (nextMode === installedRendererMode &&
93
115
  nextRendererInput === installedRendererInput &&
94
- nextBuiltinRenderers === installedBuiltinRenderers) {
116
+ nextPresetInput === installedPresetInput &&
117
+ nextPresetsInput === installedPresetsInput &&
118
+ nextBuiltinRenderers === installedBuiltinRenderers &&
119
+ nextAutoRenderersEnabled === installedAutoRenderersEnabled &&
120
+ nextAutoRendererVersion === installedAutoRendererVersion) {
95
121
  return;
96
122
  }
97
123
  registry = createBaseRendererRegistry(createOptions, options);
98
124
  installedRendererMode = nextMode;
99
125
  installedRendererInput = nextRendererInput;
126
+ installedPresetInput = nextPresetInput;
127
+ installedPresetsInput = nextPresetsInput;
100
128
  installedBuiltinRenderers = nextBuiltinRenderers;
101
- const plugins = collectFileViewerRendererPlugins(nextRendererInput);
129
+ installedAutoRenderersEnabled = nextAutoRenderersEnabled;
130
+ installedAutoRendererVersion = nextAutoRendererVersion;
131
+ const rendererInputs = [];
132
+ if (nextAutoRenderersEnabled) {
133
+ rendererInputs.push(...listFileViewerAutoRendererPresets());
134
+ }
135
+ rendererInputs.push(...resolveFileViewerRendererPresetInputs(nextPresetInput), ...resolveFileViewerRendererPresetInputs(nextPresetsInput));
136
+ if (nextRendererInput) {
137
+ rendererInputs.push(nextRendererInput);
138
+ }
139
+ const plugins = collectFileViewerRendererPlugins(rendererInputs);
102
140
  if (!plugins.length) {
103
141
  return;
104
142
  }
@@ -228,7 +266,7 @@ export const createViewer = (container, createOptions = {}) => {
228
266
  const startedAt = Date.now();
229
267
  await emitLifecycle(options, createOptions.onEvent, 'load-start', normalized, version, startedAt);
230
268
  if (!(renderer === null || renderer === void 0 ? void 0 : renderer.load)) {
231
- renderMissingRendererState(container, normalized.extension);
269
+ renderMissingRendererState(container, normalized.extension, options);
232
270
  applyFileViewerRenderSurfaceState(renderSurfaceState, { session: null });
233
271
  emitOperationAvailabilityChange();
234
272
  emitZoomChange();
@@ -1,3 +1,4 @@
1
+ import { type FileViewerI18nInput } from '../i18n/messages';
1
2
  import type { FileViewerStateTheme } from '../contracts/types';
2
3
  export type FileViewerLoadingTheme = FileViewerStateTheme;
3
4
  export interface FileViewerLoadingState {
@@ -11,6 +12,7 @@ export type MutableFileViewerLoadingState = FileViewerLoadingState;
11
12
  export interface FileViewerLoadingController {
12
13
  readonly state: FileViewerLoadingState;
13
14
  setExtension(nextExtend?: string): FileViewerLoadingState;
15
+ setI18n(nextI18n?: FileViewerI18nInput): FileViewerLoadingState;
14
16
  startLoading(nextMessage: string): FileViewerLoadingState;
15
17
  setLoadingMessage(nextMessage: string): FileViewerLoadingState;
16
18
  stopLoading(): FileViewerLoadingState;
@@ -21,6 +23,7 @@ export interface FileViewerLoadingController {
21
23
  }
22
24
  export interface FileViewerLoadingControllerActionHandlers {
23
25
  setExtension(nextExtend?: string): FileViewerLoadingState;
26
+ setI18n(nextI18n?: FileViewerI18nInput): FileViewerLoadingState;
24
27
  startLoading(nextMessage: string): FileViewerLoadingState;
25
28
  setLoadingMessage(nextMessage: string): FileViewerLoadingState;
26
29
  stopLoading(): FileViewerLoadingState;
@@ -36,16 +39,12 @@ export interface RunFileViewerLoadingExtensionSyncInput<Target extends MutableFi
36
39
  }
37
40
  export declare const FALLBACK_FILE_VIEWER_LOADING_THEME: FileViewerLoadingTheme;
38
41
  export declare const FILE_VIEWER_LOADING_THEME_MAP: Record<string, FileViewerLoadingTheme>;
39
- /**
40
- * 根据扩展名返回统一的加载主题。
41
- * 这样不同预览器可以复用同一套视觉语义,避免颜色、图标和文案各写一份。
42
- */
43
- export declare const resolveFileViewerLoadingTheme: (extend?: string) => FileViewerLoadingTheme;
42
+ export declare const resolveFileViewerLoadingTheme: (extend?: string, i18n?: FileViewerI18nInput) => FileViewerLoadingTheme;
44
43
  export declare const createFileViewerLoadingStyleVars: (theme: FileViewerLoadingTheme) => {
45
44
  '--viewer-accent': string;
46
45
  '--viewer-soft': string;
47
46
  };
48
- export declare const createFileViewerLoadingState: (extend?: string) => FileViewerLoadingState;
47
+ export declare const createFileViewerLoadingState: (extend?: string, i18n?: FileViewerI18nInput) => FileViewerLoadingState;
49
48
  export declare const cloneFileViewerLoadingState: (state: FileViewerLoadingState) => FileViewerLoadingState;
50
49
  export declare const applyFileViewerLoadingState: <Target extends MutableFileViewerLoadingState>(target: Target, source: FileViewerLoadingState) => Target;
51
50
  export declare const syncFileViewerLoadingControllerState: <Target extends MutableFileViewerLoadingState>(target: Target, controller: Pick<FileViewerLoadingController, "getState">, source?: FileViewerLoadingState) => Target;
@@ -56,4 +55,4 @@ export declare const createFileViewerLoadingControllerActionHandlers: <Target ex
56
55
  * 统一管理加载、错误、文案和主题色。
57
56
  * wrapper 只负责把这个加载状态映射到各自框架的响应式系统。
58
57
  */
59
- export declare const createFileViewerLoadingController: (extend?: string) => FileViewerLoadingController;
58
+ export declare const createFileViewerLoadingController: (extend?: string, initialI18n?: FileViewerI18nInput) => FileViewerLoadingController;
@@ -1,3 +1,4 @@
1
+ import { translateFileViewerMessage, } from '../i18n/messages.js';
1
2
  export const FALLBACK_FILE_VIEWER_LOADING_THEME = {
2
3
  accent: '#5f6f82',
3
4
  soft: 'rgba(95, 111, 130, 0.12)',
@@ -357,20 +358,84 @@ export const FILE_VIEWER_LOADING_THEME_MAP = {
357
358
  hint: '正在准备媒体资源和播放组件。'
358
359
  }
359
360
  };
361
+ const FILE_VIEWER_LOADING_COPY_KEYS = {
362
+ doc: { label: 'loading.word.label', hint: 'loading.word.hint' },
363
+ docx: { label: 'loading.word.label', hint: 'loading.wordWorker.hint' },
364
+ xls: { label: 'loading.sheet.label', hint: 'loading.sheet.hint' },
365
+ xlsx: { label: 'loading.sheet.label', hint: 'loading.sheet.hint' },
366
+ csv: { label: 'loading.csv.label', hint: 'loading.csv.hint' },
367
+ ppt: { label: 'loading.presentation.label', hint: 'loading.presentation.hint' },
368
+ pptx: { label: 'loading.presentation.label', hint: 'loading.presentation.hint' },
369
+ pdf: { label: 'loading.pdf.label', hint: 'loading.pdf.hint' },
370
+ ofd: { label: 'loading.ofd.label', hint: 'loading.ofd.hint' },
371
+ zip: { label: 'loading.archive.label', hint: 'loading.archive.hint' },
372
+ rar: { label: 'loading.archive.label', hint: 'loading.archive.hint' },
373
+ '7z': { label: 'loading.archive.label', hint: 'loading.archive.hint' },
374
+ tar: { label: 'loading.archive.label', hint: 'loading.archive.hint' },
375
+ gz: { label: 'loading.archive.label', hint: 'loading.archive.hint' },
376
+ eml: { label: 'loading.email.label', hint: 'loading.email.hint' },
377
+ msg: { label: 'loading.email.label', hint: 'loading.msg.hint' },
378
+ olb: { label: 'loading.eda.label', hint: 'loading.eda.hint' },
379
+ dra: { label: 'loading.eda.label', hint: 'loading.eda.hint' },
380
+ dxf: { label: 'loading.cad.label', hint: 'loading.cad.hint' },
381
+ dwg: { label: 'loading.cad.label', hint: 'loading.dwg.hint' },
382
+ dwf: { label: 'loading.cad.label', hint: 'loading.dwf.hint' },
383
+ dwfx: { label: 'loading.cad.label', hint: 'loading.dwfx.hint' },
384
+ xps: { label: 'loading.cad.label', hint: 'loading.xps.hint' },
385
+ drawio: { label: 'loading.drawio.label', hint: 'loading.drawio.hint' },
386
+ dio: { label: 'loading.drawio.label', hint: 'loading.drawio.hint' },
387
+ excalidraw: { label: 'loading.excalidraw.label', hint: 'loading.excalidraw.hint' },
388
+ epub: { label: 'loading.epub.label', hint: 'loading.epub.hint' },
389
+ umd: { label: 'loading.umd.label', hint: 'loading.umd.hint' },
390
+ png: { label: 'loading.image.label', hint: 'loading.image.hint' },
391
+ jpg: { label: 'loading.image.label', hint: 'loading.image.hint' },
392
+ jpeg: { label: 'loading.image.label', hint: 'loading.image.hint' },
393
+ gif: { label: 'loading.image.label', hint: 'loading.image.hint' },
394
+ webp: { label: 'loading.image.label', hint: 'loading.image.hint' },
395
+ svg: { label: 'loading.image.label', hint: 'loading.image.hint' },
396
+ bmp: { label: 'loading.image.label', hint: 'loading.image.hint' },
397
+ mp4: { label: 'loading.video.label', hint: 'loading.video.hint' },
398
+ mov: { label: 'loading.video.label', hint: 'loading.video.hint' },
399
+ avi: { label: 'loading.video.label', hint: 'loading.video.hint' },
400
+ webm: { label: 'loading.video.label', hint: 'loading.video.hint' },
401
+ m4v: { label: 'loading.video.label', hint: 'loading.video.hint' },
402
+ mp3: { label: 'loading.audio.label', hint: 'loading.audio.hint' },
403
+ mpeg: { label: 'loading.audio.label', hint: 'loading.audio.hint' },
404
+ wav: { label: 'loading.audio.label', hint: 'loading.audio.hint' },
405
+ ogg: { label: 'loading.audio.label', hint: 'loading.audio.hint' },
406
+ oga: { label: 'loading.audio.label', hint: 'loading.audio.hint' },
407
+ opus: { label: 'loading.audio.label', hint: 'loading.audio.hint' },
408
+ m4a: { label: 'loading.audio.label', hint: 'loading.audio.hint' },
409
+ aac: { label: 'loading.audio.label', hint: 'loading.audio.hint' },
410
+ flac: { label: 'loading.audio.label', hint: 'loading.audio.hint' },
411
+ weba: { label: 'loading.audio.label', hint: 'loading.audio.hint' },
412
+ };
360
413
  /**
361
414
  * 根据扩展名返回统一的加载主题。
362
415
  * 这样不同预览器可以复用同一套视觉语义,避免颜色、图标和文案各写一份。
363
416
  */
364
- export const resolveFileViewerLoadingTheme = (extend = '') => {
417
+ const localizeFileViewerLoadingTheme = (theme, extend = '', i18n) => {
365
418
  const normalized = extend.trim().toLowerCase();
366
- return FILE_VIEWER_LOADING_THEME_MAP[normalized] || FALLBACK_FILE_VIEWER_LOADING_THEME;
419
+ const keys = FILE_VIEWER_LOADING_COPY_KEYS[normalized] || {
420
+ label: 'loading.generic.label',
421
+ hint: 'loading.generic.hint',
422
+ };
423
+ return {
424
+ ...theme,
425
+ label: translateFileViewerMessage(i18n, keys.label),
426
+ hint: translateFileViewerMessage(i18n, keys.hint),
427
+ };
428
+ };
429
+ export const resolveFileViewerLoadingTheme = (extend = '', i18n) => {
430
+ const normalized = extend.trim().toLowerCase();
431
+ return localizeFileViewerLoadingTheme(FILE_VIEWER_LOADING_THEME_MAP[normalized] || FALLBACK_FILE_VIEWER_LOADING_THEME, normalized, i18n);
367
432
  };
368
433
  export const createFileViewerLoadingStyleVars = (theme) => ({
369
434
  '--viewer-accent': theme.accent,
370
435
  '--viewer-soft': theme.soft,
371
436
  });
372
- export const createFileViewerLoadingState = (extend = '') => {
373
- const theme = resolveFileViewerLoadingTheme(extend);
437
+ export const createFileViewerLoadingState = (extend = '', i18n) => {
438
+ const theme = resolveFileViewerLoadingTheme(extend, i18n);
374
439
  return {
375
440
  loading: false,
376
441
  error: '',
@@ -412,6 +477,9 @@ export const createFileViewerLoadingControllerActionHandlers = (target, controll
412
477
  extension: nextExtend,
413
478
  });
414
479
  },
480
+ setI18n(nextI18n) {
481
+ return runFileViewerLoadingControllerAction(target, () => controller.setI18n(nextI18n));
482
+ },
415
483
  startLoading(nextMessage) {
416
484
  return runFileViewerLoadingControllerAction(target, () => controller.startLoading(nextMessage));
417
485
  },
@@ -439,10 +507,13 @@ export const createFileViewerLoadingControllerActionHandlers = (target, controll
439
507
  * 统一管理加载、错误、文案和主题色。
440
508
  * wrapper 只负责把这个加载状态映射到各自框架的响应式系统。
441
509
  */
442
- export const createFileViewerLoadingController = (extend = '') => {
443
- const state = createFileViewerLoadingState(extend);
510
+ export const createFileViewerLoadingController = (extend = '', initialI18n) => {
511
+ let currentExtend = extend;
512
+ let currentI18n = initialI18n;
513
+ const state = createFileViewerLoadingState(extend, initialI18n);
444
514
  const updateTheme = (nextExtend) => {
445
- state.theme = resolveFileViewerLoadingTheme(nextExtend);
515
+ currentExtend = nextExtend;
516
+ state.theme = resolveFileViewerLoadingTheme(nextExtend, currentI18n);
446
517
  state.styleVars = createFileViewerLoadingStyleVars(state.theme);
447
518
  };
448
519
  return {
@@ -451,6 +522,11 @@ export const createFileViewerLoadingController = (extend = '') => {
451
522
  updateTheme(nextExtend);
452
523
  return cloneFileViewerLoadingState(state);
453
524
  },
525
+ setI18n(nextI18n) {
526
+ currentI18n = nextI18n;
527
+ updateTheme(currentExtend);
528
+ return cloneFileViewerLoadingState(state);
529
+ },
454
530
  startLoading(nextMessage) {
455
531
  state.loading = true;
456
532
  state.message = nextMessage;
@@ -1,4 +1,5 @@
1
1
  import type { FileViewerErrorMessageFormatter } from './state';
2
+ import { type FileViewerI18nInput } from '../i18n/messages';
2
3
  import type { FileRenderExportAdapter, FileViewerDownloadOptions, FileViewerExportHtmlOptions, FileViewerOperationType, FileViewerPrintOptions, NormalizedFileViewerSource } from '../contracts/types';
3
4
  export interface FileViewerOriginalSourceState {
4
5
  buffer?: ArrayBuffer | null;
@@ -18,6 +19,7 @@ export interface ResolveFileViewerOperationFilenameInput {
18
19
  }
19
20
  export interface FileViewerOperationExecutorBase {
20
21
  beforeOperation?: (operation: FileViewerOperationType) => boolean | Promise<boolean>;
22
+ i18n?: FileViewerI18nInput;
21
23
  }
22
24
  export interface ExecuteFileViewerDownloadOperationInput extends FileViewerOperationExecutorBase, FileViewerDownloadOptions {
23
25
  source: FileViewerOriginalSourceState;
@@ -48,11 +50,13 @@ export interface ResolveFileViewerOperationActionErrorMessageInput {
48
50
  context: FileViewerOperationActionErrorContext;
49
51
  formatErrorMessage: FileViewerOperationActionErrorFormatter;
50
52
  prefixes?: FileViewerOperationActionErrorPrefixes;
53
+ i18n?: FileViewerI18nInput;
51
54
  }
52
55
  export interface CreateFileViewerOperationActionHandlersInput extends FileViewerOperationExecutorBase {
53
56
  getBuffer?: () => ArrayBuffer | null | undefined;
54
57
  getFile?: () => File | Blob | null | undefined;
55
58
  getUrl?: () => string | null | undefined;
59
+ getI18n?: () => FileViewerI18nInput;
56
60
  getFilename: () => string | null | undefined;
57
61
  getMimeType?: () => string | null | undefined;
58
62
  getRenderedSource: () => HTMLElement | null | undefined;
@@ -79,10 +83,10 @@ export declare const resolveFileViewerDisplayFilename: (source?: Pick<Normalized
79
83
  export declare const createFileViewerOriginalSourceStateFromNormalizedSource: (source?: NormalizedFileViewerSource | null, fallbackFilename?: string) => FileViewerOriginalSourceState;
80
84
  export declare const resolveFileViewerOriginalFilename: (source: FileViewerOriginalSourceState, fallback?: string) => string;
81
85
  export declare const resolveFileViewerOperationFilename: ({ filename, source, fallback, }: ResolveFileViewerOperationFilenameInput) => string;
82
- export declare const resolveFileViewerOperationActionErrorMessage: ({ context, formatErrorMessage, prefixes, }: ResolveFileViewerOperationActionErrorMessageInput) => string;
86
+ export declare const resolveFileViewerOperationActionErrorMessage: ({ context, formatErrorMessage, prefixes, i18n, }: ResolveFileViewerOperationActionErrorMessageInput) => string;
83
87
  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 executeFileViewerDownloadOperation: ({ source, filename, beforeOperation, i18n, throwOnMissingSource, }: ExecuteFileViewerDownloadOperationInput) => Promise<boolean>;
89
+ export declare const executeFileViewerExportHtmlOperation: ({ download, filename, beforeOperation, i18n, ...input }: ExecuteFileViewerExportHtmlOperationInput) => Promise<string>;
90
+ export declare const executeFileViewerPrintOperation: ({ autoPrint, beforeOperation, i18n, openWindow, printAvailable, printWindow, ...input }: ExecuteFileViewerPrintOperationInput) => Promise<boolean>;
91
+ export declare const createFileViewerOperationActionHandlers: ({ getBuffer, getFile, getUrl, getI18n, getFilename, getMimeType, getRenderedSource, getAdapter, getWatermarkInlineStyle, getPrintAvailable, beforeOperation, i18n, errorPrefixes, formatErrorMessage, onError, onErrorMessage, }: CreateFileViewerOperationActionHandlersInput) => FileViewerOperationActionHandlers;
88
92
  export declare const createFileViewerPublicOperationActionHandlers: (input: CreateFileViewerOperationActionHandlersInput) => FileViewerPublicOperationActionHandlers;
@@ -1,5 +1,6 @@
1
1
  import { buildFileViewerRenderedHtmlDocument, triggerFileViewerBlobDownload, triggerFileViewerUrlDownload, waitForFileViewerPrintWindowReady, } from '../output/export.js';
2
2
  import { DEFAULT_FILE_VIEWER_SOURCE_FILENAME } from '../source/index.js';
3
+ import { translateFileViewerMessage, } from '../i18n/messages.js';
3
4
  export const DEFAULT_FILE_VIEWER_PREVIEW_TITLE = 'file-viewer-preview';
4
5
  export const DEFAULT_FILE_VIEWER_EXPORT_FILENAME = 'preview';
5
6
  export const DEFAULT_FILE_VIEWER_DOWNLOAD_FILENAME = DEFAULT_FILE_VIEWER_SOURCE_FILENAME;
@@ -8,6 +9,11 @@ export const FILE_VIEWER_OPERATION_ACTION_ERROR_PREFIXES = {
8
9
  print: '打印失败',
9
10
  'export-html': '导出 HTML 失败',
10
11
  };
12
+ const FILE_VIEWER_OPERATION_ACTION_ERROR_MESSAGE_KEYS = {
13
+ download: 'error.download',
14
+ print: 'error.print',
15
+ 'export-html': 'error.exportHtml',
16
+ };
11
17
  const getBlobFilename = (file) => {
12
18
  return file && 'name' in file && typeof file.name === 'string' ? file.name : '';
13
19
  };
@@ -42,9 +48,9 @@ export const resolveFileViewerOriginalFilename = (source, fallback = 'preview')
42
48
  export const resolveFileViewerOperationFilename = ({ filename, source, fallback = DEFAULT_FILE_VIEWER_PREVIEW_TITLE, }) => {
43
49
  return filename || (source ? resolveFileViewerOriginalFilename(source, '') : '') || fallback;
44
50
  };
45
- export const resolveFileViewerOperationActionErrorMessage = ({ context, formatErrorMessage, prefixes, }) => {
51
+ export const resolveFileViewerOperationActionErrorMessage = ({ context, formatErrorMessage, prefixes, i18n, }) => {
46
52
  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);
53
+ return formatErrorMessage((_a = prefixes === null || prefixes === void 0 ? void 0 : prefixes[context.operation]) !== null && _a !== void 0 ? _a : translateFileViewerMessage(i18n, FILE_VIEWER_OPERATION_ACTION_ERROR_MESSAGE_KEYS[context.operation]), context.error);
48
54
  };
49
55
  export const hasFileViewerOriginalSource = (source) => {
50
56
  return !!source.buffer || !!source.file || !!source.url;
@@ -55,9 +61,9 @@ const runBeforeOperation = async (beforeOperation, operation) => {
55
61
  }
56
62
  return await beforeOperation(operation);
57
63
  };
58
- const buildRenderedHtmlDocumentFromOperation = async (mode, { source, title, filename, adapter = null, watermarkInlineStyle, }) => {
64
+ const buildRenderedHtmlDocumentFromOperation = async (mode, { source, title, filename, adapter = null, watermarkInlineStyle, i18n, }) => {
59
65
  if (!source) {
60
- throw new Error('当前没有可导出的预览内容');
66
+ throw new Error(translateFileViewerMessage(i18n, 'error.noExportContent'));
61
67
  }
62
68
  return buildFileViewerRenderedHtmlDocument({
63
69
  source,
@@ -70,11 +76,11 @@ const buildRenderedHtmlDocumentFromOperation = async (mode, { source, title, fil
70
76
  watermarkInlineStyle,
71
77
  });
72
78
  };
73
- export const executeFileViewerDownloadOperation = async ({ source, filename, beforeOperation, throwOnMissingSource = true, }) => {
79
+ export const executeFileViewerDownloadOperation = async ({ source, filename, beforeOperation, i18n, throwOnMissingSource = true, }) => {
74
80
  var _a;
75
81
  if (!hasFileViewerOriginalSource(source)) {
76
82
  if (throwOnMissingSource) {
77
- throw new Error('当前没有可下载的源文件');
83
+ throw new Error(translateFileViewerMessage(i18n, 'error.noDownloadSource'));
78
84
  }
79
85
  return false;
80
86
  }
@@ -97,13 +103,14 @@ export const executeFileViewerDownloadOperation = async ({ source, filename, bef
97
103
  triggerFileViewerUrlDownload(source.url, resolvedFilename);
98
104
  return true;
99
105
  };
100
- export const executeFileViewerExportHtmlOperation = async ({ download = true, filename, beforeOperation, ...input }) => {
106
+ export const executeFileViewerExportHtmlOperation = async ({ download = true, filename, beforeOperation, i18n, ...input }) => {
101
107
  if (!await runBeforeOperation(beforeOperation, 'export-html')) {
102
108
  return '';
103
109
  }
104
110
  const html = await buildRenderedHtmlDocumentFromOperation('export', {
105
111
  ...input,
106
112
  filename,
113
+ i18n,
107
114
  });
108
115
  if (download !== false) {
109
116
  const baseName = resolveFileViewerOperationFilename({
@@ -114,19 +121,19 @@ export const executeFileViewerExportHtmlOperation = async ({ download = true, fi
114
121
  }
115
122
  return html;
116
123
  };
117
- export const executeFileViewerPrintOperation = async ({ autoPrint = true, beforeOperation, openWindow, printAvailable = true, printWindow, ...input }) => {
124
+ export const executeFileViewerPrintOperation = async ({ autoPrint = true, beforeOperation, i18n, openWindow, printAvailable = true, printWindow, ...input }) => {
118
125
  if (!printAvailable) {
119
- throw new Error('当前文件类型不支持完整打印,请下载原文件后在本地应用中打印');
126
+ throw new Error(translateFileViewerMessage(i18n, 'error.printUnavailable'));
120
127
  }
121
128
  if (!await runBeforeOperation(beforeOperation, 'print')) {
122
129
  return false;
123
130
  }
124
- const html = await buildRenderedHtmlDocumentFromOperation('print', input);
131
+ const html = await buildRenderedHtmlDocumentFromOperation('print', { ...input, i18n });
125
132
  const targetWindow = printWindow ||
126
133
  (openWindow === null || openWindow === void 0 ? void 0 : openWindow()) ||
127
134
  (typeof window !== 'undefined' ? window.open('', '_blank') : null);
128
135
  if (!targetWindow) {
129
- throw new Error('浏览器拦截了打印窗口');
136
+ throw new Error(translateFileViewerMessage(i18n, 'error.printWindowBlocked'));
130
137
  }
131
138
  targetWindow.document.open();
132
139
  targetWindow.document.write(html);
@@ -138,7 +145,8 @@ export const executeFileViewerPrintOperation = async ({ autoPrint = true, before
138
145
  }
139
146
  return true;
140
147
  };
141
- const handleFileViewerOperationActionError = (operation, error, { errorPrefixes, formatErrorMessage, onError, onErrorMessage, }) => {
148
+ const handleFileViewerOperationActionError = (operation, error, { errorPrefixes, formatErrorMessage, getI18n, i18n, onError, onErrorMessage, }) => {
149
+ var _a;
142
150
  const context = { operation, error };
143
151
  onError === null || onError === void 0 ? void 0 : onError(context);
144
152
  if (formatErrorMessage && onErrorMessage) {
@@ -146,10 +154,12 @@ const handleFileViewerOperationActionError = (operation, error, { errorPrefixes,
146
154
  context,
147
155
  formatErrorMessage,
148
156
  prefixes: errorPrefixes,
157
+ i18n: (_a = getI18n === null || getI18n === void 0 ? void 0 : getI18n()) !== null && _a !== void 0 ? _a : i18n,
149
158
  }), context);
150
159
  }
151
160
  };
152
- export const createFileViewerOperationActionHandlers = ({ getBuffer, getFile, getUrl, getFilename, getMimeType, getRenderedSource, getAdapter, getWatermarkInlineStyle, getPrintAvailable, beforeOperation, errorPrefixes, formatErrorMessage, onError, onErrorMessage, }) => {
161
+ export const createFileViewerOperationActionHandlers = ({ getBuffer, getFile, getUrl, getI18n, getFilename, getMimeType, getRenderedSource, getAdapter, getWatermarkInlineStyle, getPrintAvailable, beforeOperation, i18n, errorPrefixes, formatErrorMessage, onError, onErrorMessage, }) => {
162
+ const resolveI18n = () => { var _a; return (_a = getI18n === null || getI18n === void 0 ? void 0 : getI18n()) !== null && _a !== void 0 ? _a : i18n; };
153
163
  const getOriginalSource = () => {
154
164
  var _a, _b, _c, _d;
155
165
  const file = (_a = getFile === null || getFile === void 0 ? void 0 : getFile()) !== null && _a !== void 0 ? _a : null;
@@ -171,6 +181,7 @@ export const createFileViewerOperationActionHandlers = ({ getBuffer, getFile, ge
171
181
  filename,
172
182
  watermarkInlineStyle: (_b = getWatermarkInlineStyle === null || getWatermarkInlineStyle === void 0 ? void 0 : getWatermarkInlineStyle()) !== null && _b !== void 0 ? _b : undefined,
173
183
  beforeOperation,
184
+ i18n: resolveI18n(),
174
185
  };
175
186
  };
176
187
  return {
@@ -179,6 +190,7 @@ export const createFileViewerOperationActionHandlers = ({ getBuffer, getFile, ge
179
190
  return await executeFileViewerDownloadOperation({
180
191
  source: getOriginalSource(),
181
192
  beforeOperation,
193
+ i18n: resolveI18n(),
182
194
  throwOnMissingSource: false,
183
195
  });
184
196
  }
@@ -186,6 +198,8 @@ export const createFileViewerOperationActionHandlers = ({ getBuffer, getFile, ge
186
198
  handleFileViewerOperationActionError('download', error, {
187
199
  errorPrefixes,
188
200
  formatErrorMessage,
201
+ getI18n,
202
+ i18n,
189
203
  onError,
190
204
  onErrorMessage,
191
205
  });
@@ -200,6 +214,8 @@ export const createFileViewerOperationActionHandlers = ({ getBuffer, getFile, ge
200
214
  handleFileViewerOperationActionError('export-html', error, {
201
215
  errorPrefixes,
202
216
  formatErrorMessage,
217
+ getI18n,
218
+ i18n,
203
219
  onError,
204
220
  onErrorMessage,
205
221
  });
@@ -218,6 +234,8 @@ export const createFileViewerOperationActionHandlers = ({ getBuffer, getFile, ge
218
234
  handleFileViewerOperationActionError('print', error, {
219
235
  errorPrefixes,
220
236
  formatErrorMessage,
237
+ getI18n,
238
+ i18n,
221
239
  onError,
222
240
  onErrorMessage,
223
241
  });
@@ -1,16 +1,33 @@
1
- import type { FileViewerStateDescriptor, FileViewerStateTheme } from '../contracts/types';
1
+ import { type FileViewerI18nInput } from '../i18n/messages';
2
+ import type { FileViewerRendererCategory, FileViewerStateDescriptor, FileViewerStateTheme } from '../contracts/types';
2
3
  export type FileViewerErrorMessageFormatter = (prefix: string, error: unknown) => string;
3
4
  export declare const FILE_VIEWER_PREVIEW_MESSAGES: Readonly<{
4
5
  downloading: "正在下载文件资源...";
5
6
  streamingPdf: "正在建立 PDF 流式预览...";
6
7
  reading: "正在解析文件内容...";
7
8
  }>;
9
+ export declare const resolveFileViewerPreviewMessages: (i18n?: FileViewerI18nInput) => Readonly<{
10
+ downloading: string;
11
+ streamingPdf: string;
12
+ reading: string;
13
+ }>;
8
14
  export declare const DEFAULT_FILE_VIEWER_STATE_THEME: FileViewerStateTheme;
9
15
  export declare const DEFAULT_FILE_VIEWER_UNSUPPORTED_DESCRIPTION = "\u652F\u6301 Office\u3001PDF\u3001OFD\u3001Typst\u3001\u538B\u7F29\u5305\u3001\u90AE\u4EF6\u3001OLB/DRA\u3001CAD\u3001\u5730\u7406\u6570\u636E\u30013D \u6A21\u578B\u3001Excalidraw\u3001draw.io\u3001EPUB\u3001UMD\u3001Markdown\u3001\u4EE3\u7801/\u6587\u672C\u3001\u56FE\u7247\u3001\u97F3\u89C6\u9891\u3001\u5B57\u4F53\u548C\u6570\u636E\u8D44\u4EA7\u7684\u5728\u7EBF\u9884\u89C8";
10
- export declare const createFileViewerPreviewLoadingState: (extension?: string, message?: "正在解析文件内容...", theme?: FileViewerStateTheme) => FileViewerStateDescriptor;
11
- export declare const createFileViewerReadyState: (extension?: string, theme?: FileViewerStateTheme) => FileViewerStateDescriptor;
12
- export declare const createFileViewerEmptyState: (extension?: string, theme?: FileViewerStateTheme) => FileViewerStateDescriptor;
13
- export declare const createFileViewerUnsupportedState: (extension?: string, theme?: FileViewerStateTheme) => FileViewerStateDescriptor;
16
+ export interface FileViewerRendererInstallHint {
17
+ extension: string;
18
+ rendererId: string;
19
+ rendererLabel: string;
20
+ rendererCategory: FileViewerRendererCategory;
21
+ rendererPackage?: string;
22
+ presetPackage: string;
23
+ vitePreset: string;
24
+ presetLabel: string;
25
+ }
26
+ export declare const resolveFileViewerRendererInstallHint: (extension?: string) => FileViewerRendererInstallHint | null;
27
+ export declare const createFileViewerPreviewLoadingState: (extension?: string, message?: string, theme?: FileViewerStateTheme, i18n?: FileViewerI18nInput) => FileViewerStateDescriptor;
28
+ export declare const createFileViewerReadyState: (extension?: string, theme?: FileViewerStateTheme, i18n?: FileViewerI18nInput) => FileViewerStateDescriptor;
29
+ export declare const createFileViewerEmptyState: (extension?: string, theme?: FileViewerStateTheme, i18n?: FileViewerI18nInput) => FileViewerStateDescriptor;
30
+ export declare const createFileViewerUnsupportedState: (extension?: string, theme?: FileViewerStateTheme, i18n?: FileViewerI18nInput) => FileViewerStateDescriptor;
14
31
  export declare const normalizeFileViewerErrorMessage: (error: unknown) => string;
15
32
  export declare const formatFileViewerErrorMessage: FileViewerErrorMessageFormatter;
16
- export declare const createFileViewerErrorState: (extension?: string, error?: unknown, theme?: FileViewerStateTheme) => FileViewerStateDescriptor;
33
+ export declare const createFileViewerErrorState: (extension?: string, error?: unknown, theme?: FileViewerStateTheme, i18n?: FileViewerI18nInput) => FileViewerStateDescriptor;