@file-viewer/core 2.1.2 → 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.
@@ -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,3 +1,4 @@
1
+ import { type FileViewerI18nInput } from '../i18n/messages';
1
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<{
@@ -5,6 +6,11 @@ export declare const FILE_VIEWER_PREVIEW_MESSAGES: Readonly<{
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
16
  export interface FileViewerRendererInstallHint {
@@ -18,10 +24,10 @@ export interface FileViewerRendererInstallHint {
18
24
  presetLabel: string;
19
25
  }
20
26
  export declare const resolveFileViewerRendererInstallHint: (extension?: string) => FileViewerRendererInstallHint | null;
21
- export declare const createFileViewerPreviewLoadingState: (extension?: string, message?: "正在解析文件内容...", theme?: FileViewerStateTheme) => FileViewerStateDescriptor;
22
- export declare const createFileViewerReadyState: (extension?: string, theme?: FileViewerStateTheme) => FileViewerStateDescriptor;
23
- export declare const createFileViewerEmptyState: (extension?: string, theme?: FileViewerStateTheme) => FileViewerStateDescriptor;
24
- export declare const createFileViewerUnsupportedState: (extension?: string, theme?: FileViewerStateTheme) => FileViewerStateDescriptor;
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;
25
31
  export declare const normalizeFileViewerErrorMessage: (error: unknown) => string;
26
32
  export declare const formatFileViewerErrorMessage: FileViewerErrorMessageFormatter;
27
- 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;
@@ -1,10 +1,16 @@
1
1
  import { normalizeFileExtension } from '../source/index.js';
2
2
  import { DEFAULT_RENDERER_DEFINITIONS } from '../registry/formats.js';
3
+ import { resolveFileViewerLocale, translateFileViewerMessage, } from '../i18n/messages.js';
3
4
  export const FILE_VIEWER_PREVIEW_MESSAGES = Object.freeze({
4
5
  downloading: '正在下载文件资源...',
5
6
  streamingPdf: '正在建立 PDF 流式预览...',
6
7
  reading: '正在解析文件内容...',
7
8
  });
9
+ export const resolveFileViewerPreviewMessages = (i18n) => Object.freeze({
10
+ downloading: translateFileViewerMessage(i18n, 'preview.downloading'),
11
+ streamingPdf: translateFileViewerMessage(i18n, 'preview.streamingPdf'),
12
+ reading: translateFileViewerMessage(i18n, 'preview.reading'),
13
+ });
8
14
  export const DEFAULT_FILE_VIEWER_STATE_THEME = Object.freeze({
9
15
  accent: '#5f6f82',
10
16
  soft: 'rgba(95, 111, 130, 0.12)',
@@ -125,44 +131,56 @@ const createFileViewerStateDescriptor = ({ state, extension = '', title, message
125
131
  theme,
126
132
  recoverable,
127
133
  });
128
- export const createFileViewerPreviewLoadingState = (extension = '', message = FILE_VIEWER_PREVIEW_MESSAGES.reading, theme = DEFAULT_FILE_VIEWER_STATE_THEME) => createFileViewerStateDescriptor({
134
+ export const createFileViewerPreviewLoadingState = (extension = '', message, theme = DEFAULT_FILE_VIEWER_STATE_THEME, i18n) => createFileViewerStateDescriptor({
129
135
  state: 'loading',
130
136
  extension,
131
137
  title: theme.label,
132
- message,
138
+ message: message || translateFileViewerMessage(i18n, 'preview.reading'),
133
139
  description: theme.hint,
134
140
  theme,
135
141
  recoverable: false,
136
142
  });
137
- export const createFileViewerReadyState = (extension = '', theme = DEFAULT_FILE_VIEWER_STATE_THEME) => createFileViewerStateDescriptor({
143
+ export const createFileViewerReadyState = (extension = '', theme = DEFAULT_FILE_VIEWER_STATE_THEME, i18n) => createFileViewerStateDescriptor({
138
144
  state: 'ready',
139
145
  extension,
140
- title: '预览完成',
141
- message: '文件内容已完成渲染。',
146
+ title: translateFileViewerMessage(i18n, 'state.ready.title'),
147
+ message: translateFileViewerMessage(i18n, 'state.ready.message'),
142
148
  theme,
143
149
  recoverable: false,
144
150
  });
145
- export const createFileViewerEmptyState = (extension = '', theme = DEFAULT_FILE_VIEWER_STATE_THEME) => createFileViewerStateDescriptor({
151
+ export const createFileViewerEmptyState = (extension = '', theme = DEFAULT_FILE_VIEWER_STATE_THEME, i18n) => createFileViewerStateDescriptor({
146
152
  state: 'empty',
147
153
  extension,
148
- title: '暂无文件',
149
- message: '请选择文件或提供可访问的文件地址后开始预览。',
154
+ title: translateFileViewerMessage(i18n, 'state.empty.title'),
155
+ message: translateFileViewerMessage(i18n, 'state.empty.message'),
150
156
  theme,
151
157
  recoverable: true,
152
158
  });
153
- export const createFileViewerUnsupportedState = (extension = '', theme = DEFAULT_FILE_VIEWER_STATE_THEME) => {
159
+ export const createFileViewerUnsupportedState = (extension = '', theme = DEFAULT_FILE_VIEWER_STATE_THEME, i18n) => {
154
160
  const label = extensionLabel(extension);
155
161
  const installHint = resolveFileViewerRendererInstallHint(extension);
156
162
  if (installHint) {
157
- const rendererTip = installHint.rendererPackage
158
- ? `;如果需要极致裁剪,也可以只安装 ${installHint.rendererPackage}`
163
+ const locale = resolveFileViewerLocale(i18n);
164
+ const localeRendererTip = installHint.rendererPackage
165
+ ? locale === 'zh-CN'
166
+ ? `;如果需要极致裁剪,也可以只安装 ${installHint.rendererPackage}`
167
+ : `; for a strict custom cut, install only ${installHint.rendererPackage}`
159
168
  : '';
160
169
  return createFileViewerStateDescriptor({
161
170
  state: 'unsupported',
162
171
  extension,
163
- title: '需要装配预览能力',
164
- message: `${label} 格式已在支持矩阵中,但当前项目尚未装配 ${installHint.rendererLabel} renderer。`,
165
- description: `推荐安装 ${installHint.presetPackage} 并启用 @file-viewer/vite-plugin(preset: '${installHint.vitePreset}' 或 preset: 'auto')${rendererTip},也可以通过 options.renderers 手动传入对应 renderer。`,
172
+ title: translateFileViewerMessage(i18n, 'state.unsupported.install.title'),
173
+ message: translateFileViewerMessage(i18n, 'state.unsupported.install.message', {
174
+ extension: label,
175
+ rendererLabel: installHint.rendererLabel,
176
+ }),
177
+ description: translateFileViewerMessage(i18n, 'state.unsupported.install.description', {
178
+ extension: label,
179
+ rendererLabel: installHint.rendererLabel,
180
+ presetPackage: installHint.presetPackage,
181
+ vitePreset: installHint.vitePreset,
182
+ rendererTip: localeRendererTip,
183
+ }),
166
184
  theme,
167
185
  recoverable: true,
168
186
  });
@@ -170,9 +188,11 @@ export const createFileViewerUnsupportedState = (extension = '', theme = DEFAULT
170
188
  return createFileViewerStateDescriptor({
171
189
  state: 'unsupported',
172
190
  extension,
173
- title: '暂不支持在线预览',
174
- message: `不支持${label}格式的在线预览,请下载后预览或转换为支持的格式。`,
175
- description: DEFAULT_FILE_VIEWER_UNSUPPORTED_DESCRIPTION,
191
+ title: translateFileViewerMessage(i18n, 'state.unsupported.title'),
192
+ message: translateFileViewerMessage(i18n, 'state.unsupported.message', {
193
+ extension: label,
194
+ }),
195
+ description: translateFileViewerMessage(i18n, 'state.unsupported.description'),
176
196
  theme,
177
197
  recoverable: true,
178
198
  });
@@ -186,10 +206,10 @@ export const normalizeFileViewerErrorMessage = (error) => {
186
206
  export const formatFileViewerErrorMessage = (prefix, error) => {
187
207
  return `${prefix}:${normalizeFileViewerErrorMessage(error)}`;
188
208
  };
189
- export const createFileViewerErrorState = (extension = '', error = '未知错误', theme = DEFAULT_FILE_VIEWER_STATE_THEME) => createFileViewerStateDescriptor({
209
+ export const createFileViewerErrorState = (extension = '', error = '未知错误', theme = DEFAULT_FILE_VIEWER_STATE_THEME, i18n) => createFileViewerStateDescriptor({
190
210
  state: 'error',
191
211
  extension,
192
- title: '预览失败',
212
+ title: translateFileViewerMessage(i18n, 'state.error.title'),
193
213
  message: normalizeFileViewerErrorMessage(error),
194
214
  theme,
195
215
  recoverable: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@file-viewer/core",
3
- "version": "2.1.2",
3
+ "version": "2.1.3",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Framework-neutral modular TypeScript core for Flyfish File Viewer renderer orchestration, lifecycle APIs, search, zoom, print, and export",