@file-viewer/core 2.1.30 → 2.2.1
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.
- package/README.en.md +10 -0
- package/README.md +10 -0
- package/dist/contracts/types.d.ts +81 -2
- package/dist/features/document/fit.d.ts +1 -1
- package/dist/features/document/fit.js +1 -1
- package/dist/features/document/search.js +1 -0
- package/dist/headless.d.ts +2 -2
- package/dist/headless.js +2 -2
- package/dist/i18n/messages.js +8 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/lifecycle/operations.d.ts +1 -1
- package/dist/lifecycle/operations.js +1 -1
- package/dist/platform/assets.d.ts +30 -3
- package/dist/platform/assets.js +338 -50
- package/dist/registry/capabilities.d.ts +2 -2
- package/dist/registry/capabilities.js +2 -2
- package/dist/registry/formats.d.ts +16 -3
- package/dist/registry/formats.js +10 -2
- package/dist/renderers/image.js +3 -3
- package/dist/renderers/index.d.ts +15 -2
- package/dist/rendering/handler.d.ts +8 -0
- package/dist/rendering/handler.js +27 -0
- package/dist/viewer/createViewer.js +4 -2
- package/dist/viewer/loading.js +8 -0
- package/dist/viewer/operations.js +18 -2
- package/dist/viewer/state.js +24 -1
- package/package.json +1 -1
package/dist/renderers/image.js
CHANGED
|
@@ -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
|
|
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
|
|
30
|
-
@media (prefers-color-scheme:dark){[data-viewer-theme='system'] .image-viewer{background
|
|
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();
|
package/dist/viewer/loading.js
CHANGED
|
@@ -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' },
|
|
@@ -93,15 +93,31 @@ export const executeFileViewerDownloadOperation = async ({ source, filename, bef
|
|
|
93
93
|
source,
|
|
94
94
|
fallback: DEFAULT_FILE_VIEWER_DOWNLOAD_FILENAME,
|
|
95
95
|
});
|
|
96
|
-
|
|
96
|
+
// PDF.js transfers ArrayBuffer-backed data to its worker. After a successful
|
|
97
|
+
// render the original buffer can therefore be detached (byteLength === 0),
|
|
98
|
+
// while the File or URL retained by the viewer is still the complete source.
|
|
99
|
+
// Preserve the existing buffer-first contract for non-empty buffers, but do
|
|
100
|
+
// not turn a detached buffer into a zero-byte download.
|
|
101
|
+
if (source.buffer &&
|
|
102
|
+
(source.buffer.byteLength > 0 || (!source.file && !source.url))) {
|
|
97
103
|
triggerFileViewerBlobDownload(new Blob([source.buffer], { type: source.mimeType || ((_a = source.file) === null || _a === void 0 ? void 0 : _a.type) || 'application/octet-stream' }), resolvedFilename);
|
|
98
104
|
return true;
|
|
99
105
|
}
|
|
106
|
+
if (source.file && (source.file.size > 0 || !source.url)) {
|
|
107
|
+
triggerFileViewerBlobDownload(source.file, resolvedFilename);
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
if (source.url) {
|
|
111
|
+
triggerFileViewerUrlDownload(source.url, resolvedFilename);
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
// Empty local files are valid sources. These final fallbacks preserve their
|
|
115
|
+
// intentional zero-byte downloads when no complete File or URL is available.
|
|
100
116
|
if (source.file) {
|
|
101
117
|
triggerFileViewerBlobDownload(source.file, resolvedFilename);
|
|
102
118
|
return true;
|
|
103
119
|
}
|
|
104
|
-
|
|
120
|
+
triggerFileViewerBlobDownload(new Blob([source.buffer], { type: source.mimeType || 'application/octet-stream' }), resolvedFilename);
|
|
105
121
|
return true;
|
|
106
122
|
};
|
|
107
123
|
export const executeFileViewerExportHtmlOperation = async ({ download = true, filename, beforeOperation, i18n, ...input }) => {
|
package/dist/viewer/state.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
3
|
+
"version": "2.2.1",
|
|
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",
|