@file-viewer/core 2.1.30 → 2.2.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.
@@ -19,15 +19,15 @@ const imageMimeMap = {
19
19
  webp: 'image/webp',
20
20
  };
21
21
  const imageStyle = `
22
- .image-viewer{position:relative;width:100%;height:100%;overflow:auto;background:#eef1f4;box-sizing:border-box}
22
+ .image-viewer{position:relative;width:100%;height:100%;overflow:auto;background:var(--file-viewer-render-surface-background,#eef1f4);box-sizing:border-box}
23
23
  .image-stage{min-width:100%;min-height:100%;display:flex;align-items:center;justify-content:center;padding:24px;box-sizing:border-box}
24
24
  .image-stage img{display:block;width:auto;max-width:none;margin:0 auto;border:0;box-shadow:0 18px 48px rgba(15,23,42,.16);background:#fff;cursor:zoom-in}
25
25
  .image-lightbox{position:fixed;inset:0;z-index:2147483000;display:flex;align-items:center;justify-content:center;padding:40px;background:rgba(15,23,42,.88);box-sizing:border-box}
26
26
  .image-lightbox[hidden]{display:none}
27
27
  .image-lightbox img{display:block;max-width:100%;max-height:100%;object-fit:contain;background:#fff;box-shadow:0 30px 80px rgba(0,0,0,.4);cursor:zoom-out}
28
28
  .image-lightbox button{position:absolute;top:20px;right:20px;width:40px;height:40px;border:0;border-radius:999px;background:rgba(255,255,255,.92);color:#172033;font-size:24px;line-height:40px;cursor:pointer;box-shadow:0 12px 28px rgba(0,0,0,.18)}
29
- [data-viewer-theme='dark'] .image-viewer{background:#101820}
30
- @media (prefers-color-scheme:dark){[data-viewer-theme='system'] .image-viewer{background:#101820}}
29
+ [data-viewer-theme='dark'] .image-viewer{background:var(--file-viewer-render-surface-background,#101820)}
30
+ @media (prefers-color-scheme:dark){[data-viewer-theme='system'] .image-viewer{background:var(--file-viewer-render-surface-background,#101820)}}
31
31
  @media (max-width:767px){.image-stage{padding:12px}.image-lightbox{padding:16px}.image-lightbox button{top:12px;right:12px}}
32
32
  `;
33
33
  const createStyle = (documentRef) => {
@@ -33,9 +33,22 @@ export declare const coreLiteRendererDefinitions: ({
33
33
  readonly zoom: "provider";
34
34
  readonly search: true;
35
35
  };
36
+ } | {
37
+ readonly id: "office-presentation-binary";
38
+ readonly label: "PowerPoint 97–2003";
39
+ readonly category: "office";
40
+ readonly extensions: readonly ["ppt"];
41
+ readonly async: true;
42
+ readonly capabilities: {
43
+ readonly download: true;
44
+ readonly print: "adapter";
45
+ readonly exportHtml: "adapter";
46
+ readonly zoom: "provider";
47
+ readonly search: false;
48
+ };
36
49
  } | {
37
50
  readonly id: "office-presentation";
38
- readonly label: "PowerPoint";
51
+ readonly label: "PowerPoint OpenXML";
39
52
  readonly category: "office";
40
53
  readonly extensions: readonly ["pptx", "pptm", "potx", "potm", "ppsx", "ppsm"];
41
54
  readonly async: true;
@@ -63,7 +76,7 @@ export declare const coreLiteRendererDefinitions: ({
63
76
  readonly id: "spreadsheet-openxml";
64
77
  readonly label: "Spreadsheet";
65
78
  readonly category: "office";
66
- readonly extensions: readonly ["xlsx", "xltx", "xlsm", "xlsb", "xls", "xlt", "xltm", "csv", "ods", "fods", "numbers"];
79
+ readonly extensions: readonly ["xlsx", "xltx", "xlsm", "xlsb", "xls", "xlt", "xltm", "csv", "tsv", "ods", "fods", "numbers"];
67
80
  readonly async: true;
68
81
  readonly capabilities: {
69
82
  readonly download: true;
@@ -162,6 +162,14 @@ export interface CreateFileViewerRenderSurfaceActionHandlersInput<Session extend
162
162
  onRefreshViewStateProvider?: () => void;
163
163
  }
164
164
  export declare const DEFAULT_FILE_VIEWER_RENDER_TARGET_CLASS = "file-render";
165
+ export declare const FILE_VIEWER_RENDER_SURFACE_BACKGROUND_PROPERTY = "--file-viewer-render-surface-background";
166
+ export declare const normalizeFileViewerRenderSurfaceBackground: (value: unknown) => string | null;
167
+ /**
168
+ * Keeps the public UI option and the renderer-facing CSS custom property in
169
+ * sync. Custom properties inherit through Shadow DOM, so setting this on the
170
+ * render host covers both scoped and shadow-isolated renderer targets.
171
+ */
172
+ export declare const syncFileViewerRenderSurfaceBackground: (target: HTMLElement | null | undefined, options?: Pick<FileViewerOptions, "ui"> | null) => string | null;
165
173
  export declare const isFileViewerShadowRoot: (value: unknown) => value is ShadowRoot;
166
174
  export declare const getFileViewerShadowRootForNode: (node: Node | null | undefined) => ShadowRoot | null;
167
175
  export declare const normalizeFileViewerStyleIsolation: (isolation?: FileViewerStyleIsolation) => FileViewerStyleIsolation;
@@ -13,8 +13,35 @@ import { findFileViewerViewStateProvider } from '../features/document/dom/index.
13
13
  import { registerFileViewerGenericViewStateProvider } from '../features/document/viewState.js';
14
14
  export const FILE_VIEWER_RENDER_SESSION_DISPOSE_ERROR_MESSAGE = '预览内容卸载失败';
15
15
  export const DEFAULT_FILE_VIEWER_RENDER_TARGET_CLASS = 'file-render';
16
+ export const FILE_VIEWER_RENDER_SURFACE_BACKGROUND_PROPERTY = '--file-viewer-render-surface-background';
16
17
  const FILE_VIEWER_RENDER_HOST_CLASS = 'file-render-host';
17
18
  const FILE_VIEWER_SHADOW_RENDER_TARGET_CLASS = 'file-render-shadow-target';
19
+ export const normalizeFileViewerRenderSurfaceBackground = (value) => {
20
+ if (typeof value !== 'string') {
21
+ return null;
22
+ }
23
+ const normalized = value.trim();
24
+ return normalized && normalized.toLowerCase() !== 'auto' ? normalized : null;
25
+ };
26
+ /**
27
+ * Keeps the public UI option and the renderer-facing CSS custom property in
28
+ * sync. Custom properties inherit through Shadow DOM, so setting this on the
29
+ * render host covers both scoped and shadow-isolated renderer targets.
30
+ */
31
+ export const syncFileViewerRenderSurfaceBackground = (target, options) => {
32
+ var _a;
33
+ if (!target) {
34
+ return null;
35
+ }
36
+ const background = normalizeFileViewerRenderSurfaceBackground((_a = options === null || options === void 0 ? void 0 : options.ui) === null || _a === void 0 ? void 0 : _a.surfaceBackground);
37
+ if (background) {
38
+ target.style.setProperty(FILE_VIEWER_RENDER_SURFACE_BACKGROUND_PROPERTY, background);
39
+ }
40
+ else {
41
+ target.style.removeProperty(FILE_VIEWER_RENDER_SURFACE_BACKGROUND_PROPERTY);
42
+ }
43
+ return background;
44
+ };
18
45
  export const isFileViewerShadowRoot = (value) => {
19
46
  if (!value || typeof value !== 'object') {
20
47
  return false;
@@ -14,7 +14,7 @@ import { openFileViewerPrintMaskDesignerAsync } from '../features/printMaskLoade
14
14
  import { applyFileViewerZoomAvailability, createUnsupportedAvailability, getRendererAvailability, } from '../registry/capabilities.js';
15
15
  import { buildFileViewerLifecycleContextFromNormalizedSource, buildFileViewerOperationContext, runFileViewerBeforeOperation, runFileViewerLifecycleHook, } from '../lifecycle/operations.js';
16
16
  import { collectFileViewerRendererPlugins, createRendererRegistry, getFileViewerAutoRendererPresetVersion, hasFileViewerRendererPresetName, installFileViewerRendererPlugins, listFileViewerAutoRendererPresets, resolveFileViewerRendererPresetInputs, } from '../registry/registry.js';
17
- import { createFileRenderHandlerLoader, applyFileViewerRenderSurfaceState, createFileViewerRenderSurfaceState, createFileViewerRenderSurface, removeFileViewerRenderTarget, } from '../rendering/handler.js';
17
+ import { createFileRenderHandlerLoader, applyFileViewerRenderSurfaceState, createFileViewerRenderSurfaceState, createFileViewerRenderSurface, removeFileViewerRenderTarget, syncFileViewerRenderSurfaceBackground, } from '../rendering/handler.js';
18
18
  import { createFileViewerCoreRendererRegistry } from '../renderers/index.js';
19
19
  import { createFileViewerRequestScope } from '../source/loading.js';
20
20
  import { normalizeSource } from '../source/index.js';
@@ -222,6 +222,7 @@ export const createViewer = (container, createOptions = {}) => {
222
222
  target.style.height = '100%';
223
223
  surface.container.style.height = '100%';
224
224
  }
225
+ syncFileViewerRenderSurfaceBackground(target, options);
225
226
  currentRenderTarget = target;
226
227
  return surface;
227
228
  };
@@ -482,7 +483,7 @@ export const createViewer = (container, createOptions = {}) => {
482
483
  const renderer = registry.getByExtension(normalized.extension);
483
484
  const startedAt = Date.now();
484
485
  await emitLifecycle(options, createOptions.onEvent, 'load-start', normalized, version, startedAt);
485
- const surface = createRenderTarget((renderer === null || renderer === void 0 ? void 0 : renderer.id) !== 'office-presentation');
486
+ const surface = createRenderTarget((renderer === null || renderer === void 0 ? void 0 : renderer.id) !== 'office-presentation' && (renderer === null || renderer === void 0 ? void 0 : renderer.id) !== 'office-presentation-binary');
486
487
  const target = surface.container;
487
488
  const targetHost = surface.host || target;
488
489
  currentDocumentRoot = target;
@@ -561,6 +562,7 @@ export const createViewer = (container, createOptions = {}) => {
561
562
  ...options,
562
563
  ...nextOptions,
563
564
  };
565
+ syncFileViewerRenderSurfaceBackground(currentRenderTarget, options);
564
566
  syncWatermarkOverlay();
565
567
  if ('fit' in nextOptions && nextOptions.fit !== previousFit) {
566
568
  fitController.resetAutoFit();
@@ -42,6 +42,13 @@ export const FILE_VIEWER_LOADING_THEME_MAP = {
42
42
  label: '表格数据',
43
43
  hint: '正在准备行列数据和基础样式。'
44
44
  },
45
+ tsv: {
46
+ accent: '#21a366',
47
+ soft: 'rgba(33, 163, 102, 0.12)',
48
+ badge: 'X',
49
+ label: '表格数据',
50
+ hint: '正在准备行列数据和基础样式。'
51
+ },
45
52
  ppt: {
46
53
  accent: '#f28b27',
47
54
  soft: 'rgba(242, 139, 39, 0.12)',
@@ -364,6 +371,7 @@ const FILE_VIEWER_LOADING_COPY_KEYS = {
364
371
  xls: { label: 'loading.sheet.label', hint: 'loading.sheet.hint' },
365
372
  xlsx: { label: 'loading.sheet.label', hint: 'loading.sheet.hint' },
366
373
  csv: { label: 'loading.csv.label', hint: 'loading.csv.hint' },
374
+ tsv: { label: 'loading.csv.label', hint: 'loading.csv.hint' },
367
375
  ppt: { label: 'loading.presentation.label', hint: 'loading.presentation.hint' },
368
376
  pptx: { label: 'loading.presentation.label', hint: 'loading.presentation.hint' },
369
377
  pdf: { label: 'loading.pdf.label', hint: 'loading.pdf.hint' },
@@ -26,6 +26,7 @@ const extensionLabel = (extension) => {
26
26
  const rendererPackageById = {
27
27
  'office-word-openxml': '@file-viewer/renderer-word',
28
28
  'office-word-binary': '@file-viewer/renderer-word',
29
+ 'office-presentation-binary': '@file-viewer/renderer-presentation',
29
30
  'office-presentation': '@file-viewer/renderer-presentation',
30
31
  'open-document': '@file-viewer/renderer-word',
31
32
  'spreadsheet-openxml': '@file-viewer/renderer-spreadsheet',
@@ -52,6 +53,7 @@ const rendererPackageById = {
52
53
  const officeRendererIds = new Set([
53
54
  'office-word-openxml',
54
55
  'office-word-binary',
56
+ 'office-presentation-binary',
55
57
  'office-presentation',
56
58
  'open-document',
57
59
  'spreadsheet-openxml',
@@ -218,6 +220,14 @@ const resolveKnownFileViewerErrorMessage = (message, i18n) => {
218
220
  const key = FILE_VIEWER_KNOWN_ERROR_MESSAGE_KEYS[message.trim()];
219
221
  return key ? translateFileViewerMessage(i18n, key) : message;
220
222
  };
223
+ const readFileViewerErrorProperty = (error, key) => {
224
+ try {
225
+ return error[key];
226
+ }
227
+ catch {
228
+ return undefined;
229
+ }
230
+ };
221
231
  export const normalizeFileViewerErrorMessage = (error, i18n) => {
222
232
  if (error instanceof Error) {
223
233
  return resolveKnownFileViewerErrorMessage(error.message, i18n);
@@ -228,7 +238,20 @@ export const normalizeFileViewerErrorMessage = (error, i18n) => {
228
238
  if (error === undefined || error === null) {
229
239
  return translateFileViewerMessage(i18n, 'error.unknown');
230
240
  }
231
- return String(error);
241
+ if (typeof error === 'object') {
242
+ const message = readFileViewerErrorProperty(error, 'message');
243
+ if (typeof message === 'string' && message.trim()) {
244
+ return resolveKnownFileViewerErrorMessage(message, i18n);
245
+ }
246
+ const reason = readFileViewerErrorProperty(error, 'reason');
247
+ if (reason !== undefined && reason !== error) {
248
+ return normalizeFileViewerErrorMessage(reason, i18n);
249
+ }
250
+ }
251
+ const fallback = String(error);
252
+ return fallback === '[object Object]'
253
+ ? translateFileViewerMessage(i18n, 'error.unknown')
254
+ : fallback;
232
255
  };
233
256
  export const formatFileViewerErrorMessage = (prefix, error, i18n) => {
234
257
  const detail = normalizeFileViewerErrorMessage(error, i18n);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@file-viewer/core",
3
- "version": "2.1.30",
3
+ "version": "2.2.0",
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",