@file-viewer/core 2.1.17 → 2.1.19
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 +4 -1
- package/README.md +4 -1
- package/dist/contracts/types.d.ts +68 -3
- package/dist/features/document/dom/providers.d.ts +5 -3
- package/dist/features/document/dom/providers.js +33 -8
- package/dist/features/document/fit.d.ts +46 -0
- package/dist/features/document/fit.js +348 -0
- package/dist/features/document/viewState.js +64 -4
- package/dist/headless.d.ts +2 -2
- package/dist/headless.js +1 -1
- package/dist/i18n/messages.js +53 -2
- package/dist/index.d.ts +6 -4
- package/dist/index.js +3 -2
- package/dist/lifecycle/operations.d.ts +4 -1
- package/dist/lifecycle/operations.js +39 -2
- package/dist/platform/assets.js +3 -3
- package/dist/renderers/image.d.ts +2 -2
- package/dist/renderers/image.js +67 -16
- package/dist/renderers/index.js +4 -4
- package/dist/rendering/handler.d.ts +33 -5
- package/dist/rendering/handler.js +127 -4
- package/dist/source/loading.d.ts +3 -1
- package/dist/source/loading.js +6 -2
- package/dist/viewer/createViewer.js +66 -11
- package/dist/viewer/operations.js +1 -1
- package/dist/viewer/state.d.ts +2 -2
- package/dist/viewer/state.js +39 -6
- package/package.json +1 -1
|
@@ -13,6 +13,48 @@ 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
|
+
const FILE_VIEWER_RENDER_HOST_CLASS = 'file-render-host';
|
|
17
|
+
const FILE_VIEWER_SHADOW_RENDER_TARGET_CLASS = 'file-render-shadow-target';
|
|
18
|
+
export const isFileViewerShadowRoot = (value) => {
|
|
19
|
+
if (!value || typeof value !== 'object') {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
if (typeof ShadowRoot !== 'undefined' && value instanceof ShadowRoot) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
return value.nodeType === 11 &&
|
|
26
|
+
!!value.host;
|
|
27
|
+
};
|
|
28
|
+
const getElementRootNode = (element) => {
|
|
29
|
+
var _a;
|
|
30
|
+
return ((_a = element === null || element === void 0 ? void 0 : element.getRootNode) === null || _a === void 0 ? void 0 : _a.call(element)) || null;
|
|
31
|
+
};
|
|
32
|
+
export const getFileViewerShadowRootForNode = (node) => {
|
|
33
|
+
var _a;
|
|
34
|
+
if (!node) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
if (isFileViewerShadowRoot(node)) {
|
|
38
|
+
return node;
|
|
39
|
+
}
|
|
40
|
+
const root = (_a = node.getRootNode) === null || _a === void 0 ? void 0 : _a.call(node);
|
|
41
|
+
return isFileViewerShadowRoot(root) ? root : null;
|
|
42
|
+
};
|
|
43
|
+
export const normalizeFileViewerStyleIsolation = (isolation) => {
|
|
44
|
+
return isolation === 'shadow' || isolation === 'scoped' || isolation === 'none'
|
|
45
|
+
? isolation
|
|
46
|
+
: 'auto';
|
|
47
|
+
};
|
|
48
|
+
export const resolveFileViewerStyleIsolation = (options, container) => {
|
|
49
|
+
const isolation = normalizeFileViewerStyleIsolation(options === null || options === void 0 ? void 0 : options.styleIsolation);
|
|
50
|
+
if (isolation === 'auto') {
|
|
51
|
+
return isFileViewerShadowRoot(getElementRootNode(container)) ? 'scoped' : 'none';
|
|
52
|
+
}
|
|
53
|
+
if (isolation === 'shadow' && isFileViewerShadowRoot(getElementRootNode(container))) {
|
|
54
|
+
return 'scoped';
|
|
55
|
+
}
|
|
56
|
+
return isolation;
|
|
57
|
+
};
|
|
16
58
|
const isPromiseLike = (value) => {
|
|
17
59
|
return !!value &&
|
|
18
60
|
(typeof value === 'object' || typeof value === 'function') &&
|
|
@@ -35,6 +77,76 @@ export const createFileViewerRenderTarget = (container, options = {}) => {
|
|
|
35
77
|
container.appendChild(target);
|
|
36
78
|
return target;
|
|
37
79
|
};
|
|
80
|
+
export const createFileViewerRenderSurface = (container, options = {}) => {
|
|
81
|
+
const styleIsolation = resolveFileViewerStyleIsolation({
|
|
82
|
+
styleIsolation: options.styleIsolation,
|
|
83
|
+
}, container);
|
|
84
|
+
const className = options.className || DEFAULT_FILE_VIEWER_RENDER_TARGET_CLASS;
|
|
85
|
+
if (styleIsolation === 'shadow' && typeof container.attachShadow === 'function') {
|
|
86
|
+
const host = container.ownerDocument.createElement('div');
|
|
87
|
+
host.className = `${FILE_VIEWER_RENDER_HOST_CLASS} ${className}`;
|
|
88
|
+
host.dataset.fileViewerStyleIsolation = 'shadow';
|
|
89
|
+
host.style.width = '100%';
|
|
90
|
+
host.style.minWidth = '0';
|
|
91
|
+
host.style.minHeight = '0';
|
|
92
|
+
const shadowRoot = host.attachShadow({ mode: 'open' });
|
|
93
|
+
const target = container.ownerDocument.createElement('div');
|
|
94
|
+
target.className = `${FILE_VIEWER_SHADOW_RENDER_TARGET_CLASS} ${className}`;
|
|
95
|
+
target.dataset.fileViewerStyleIsolation = 'shadow';
|
|
96
|
+
target.style.width = '100%';
|
|
97
|
+
target.style.minWidth = '0';
|
|
98
|
+
target.style.minHeight = '0';
|
|
99
|
+
shadowRoot.appendChild(target);
|
|
100
|
+
container.appendChild(host);
|
|
101
|
+
return {
|
|
102
|
+
host,
|
|
103
|
+
container: target,
|
|
104
|
+
shadowRoot,
|
|
105
|
+
styleIsolation,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
const target = createFileViewerRenderTarget(container, { className });
|
|
109
|
+
target.dataset.fileViewerStyleIsolation = styleIsolation;
|
|
110
|
+
return {
|
|
111
|
+
host: target,
|
|
112
|
+
container: target,
|
|
113
|
+
styleIsolation,
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
const appendStyleElement = (target, css) => {
|
|
117
|
+
const documentRef = target.ownerDocument;
|
|
118
|
+
const style = documentRef.createElement('style');
|
|
119
|
+
style.textContent = css;
|
|
120
|
+
target.appendChild(style);
|
|
121
|
+
return style;
|
|
122
|
+
};
|
|
123
|
+
const canUseAdoptedStyleSheet = (root) => {
|
|
124
|
+
return 'adoptedStyleSheets' in root &&
|
|
125
|
+
typeof CSSStyleSheet !== 'undefined' &&
|
|
126
|
+
typeof CSSStyleSheet.prototype.replaceSync === 'function';
|
|
127
|
+
};
|
|
128
|
+
export const appendFileViewerStyle = (target, css, options = {}) => {
|
|
129
|
+
const shadowRoot = getFileViewerShadowRootForNode(target);
|
|
130
|
+
if (options.adoptedStyleSheet && shadowRoot && canUseAdoptedStyleSheet(shadowRoot)) {
|
|
131
|
+
const sheet = new CSSStyleSheet();
|
|
132
|
+
sheet.replaceSync(css);
|
|
133
|
+
shadowRoot.adoptedStyleSheets = [...shadowRoot.adoptedStyleSheets, sheet];
|
|
134
|
+
return {
|
|
135
|
+
sheet,
|
|
136
|
+
remove() {
|
|
137
|
+
shadowRoot.adoptedStyleSheets = shadowRoot.adoptedStyleSheets.filter(item => item !== sheet);
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
const styleTarget = isFileViewerShadowRoot(target) ? target : target;
|
|
142
|
+
const node = appendStyleElement(styleTarget, css);
|
|
143
|
+
return {
|
|
144
|
+
node,
|
|
145
|
+
remove() {
|
|
146
|
+
node.remove();
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
};
|
|
38
150
|
export const removeFileViewerRenderTarget = (container, target) => {
|
|
39
151
|
if (target.parentNode !== container) {
|
|
40
152
|
return false;
|
|
@@ -161,7 +273,7 @@ export const resetFileViewerRenderSurface = ({ surfaceState, readinessState, con
|
|
|
161
273
|
clearFileViewerRenderSurface(container);
|
|
162
274
|
return session;
|
|
163
275
|
};
|
|
164
|
-
export const runFileViewerRenderSurfaceClear = ({ reason = 'replace', surfaceState, readinessState, container, disposeOptions, onUnloadStart, onUnloadComplete, onClearActiveDocumentContext, onClearDocumentState, onStopZoomObserver, onClearZoomProvider, onStopViewStateObserver, onClearViewStateProvider, }) => {
|
|
276
|
+
export const runFileViewerRenderSurfaceClear = ({ reason = 'replace', surfaceState, readinessState, container, disposeOptions, onUnloadStart, onUnloadComplete, onClearActiveDocumentContext, onClearDocumentState, onStopZoomObserver, onClearZoomProvider, onStopFitObserver, onStopViewStateObserver, onClearViewStateProvider, }) => {
|
|
165
277
|
const unloadContext = onUnloadStart === null || onUnloadStart === void 0 ? void 0 : onUnloadStart(reason);
|
|
166
278
|
let session;
|
|
167
279
|
try {
|
|
@@ -177,6 +289,7 @@ export const runFileViewerRenderSurfaceClear = ({ reason = 'replace', surfaceSta
|
|
|
177
289
|
onClearDocumentState === null || onClearDocumentState === void 0 ? void 0 : onClearDocumentState();
|
|
178
290
|
onStopZoomObserver === null || onStopZoomObserver === void 0 ? void 0 : onStopZoomObserver();
|
|
179
291
|
onClearZoomProvider === null || onClearZoomProvider === void 0 ? void 0 : onClearZoomProvider();
|
|
292
|
+
onStopFitObserver === null || onStopFitObserver === void 0 ? void 0 : onStopFitObserver();
|
|
180
293
|
onStopViewStateObserver === null || onStopViewStateObserver === void 0 ? void 0 : onStopViewStateObserver();
|
|
181
294
|
onClearViewStateProvider === null || onClearViewStateProvider === void 0 ? void 0 : onClearViewStateProvider();
|
|
182
295
|
}
|
|
@@ -187,7 +300,7 @@ export const runFileViewerRenderSurfaceClear = ({ reason = 'replace', surfaceSta
|
|
|
187
300
|
session,
|
|
188
301
|
};
|
|
189
302
|
};
|
|
190
|
-
export const runFileViewerRenderSurfaceMount = async ({ buffer, file, version, sourceUrl, streamUrl, getContainer, surfaceState, readinessState, isCurrent, clearRenderedContent, render, waitForContainer, waitForPaint = waitForFileViewerNextPaint, disposeSession = disposeFileViewerRendererSession, onStartZoomObserver, onStartViewStateObserver, onRefreshDocumentIndex, onRefreshZoomProvider, onRefreshViewStateProvider, }) => {
|
|
303
|
+
export const runFileViewerRenderSurfaceMount = async ({ buffer, file, version, sourceUrl, streamUrl, getContainer, surfaceState, readinessState, isCurrent, clearRenderedContent, render, waitForContainer, waitForPaint = waitForFileViewerNextPaint, disposeSession = disposeFileViewerRendererSession, onStartZoomObserver, onStartFitObserver, onStartViewStateObserver, onApplyInitialFit, onRefreshDocumentIndex, onRefreshZoomProvider, onRefreshViewStateProvider, }) => {
|
|
191
304
|
if (!getContainer()) {
|
|
192
305
|
await (waitForContainer === null || waitForContainer === void 0 ? void 0 : waitForContainer());
|
|
193
306
|
}
|
|
@@ -198,6 +311,7 @@ export const runFileViewerRenderSurfaceMount = async ({ buffer, file, version, s
|
|
|
198
311
|
clearRenderedContent('replace');
|
|
199
312
|
const target = createFileViewerRenderTarget(container);
|
|
200
313
|
onStartZoomObserver === null || onStartZoomObserver === void 0 ? void 0 : onStartZoomObserver();
|
|
314
|
+
onStartFitObserver === null || onStartFitObserver === void 0 ? void 0 : onStartFitObserver();
|
|
201
315
|
onStartViewStateObserver === null || onStartViewStateObserver === void 0 ? void 0 : onStartViewStateObserver();
|
|
202
316
|
await (waitForContainer === null || waitForContainer === void 0 ? void 0 : waitForContainer());
|
|
203
317
|
await waitForPaint();
|
|
@@ -236,6 +350,11 @@ export const runFileViewerRenderSurfaceMount = async ({ buffer, file, version, s
|
|
|
236
350
|
void (onRefreshDocumentIndex === null || onRefreshDocumentIndex === void 0 ? void 0 : onRefreshDocumentIndex());
|
|
237
351
|
onRefreshZoomProvider === null || onRefreshZoomProvider === void 0 ? void 0 : onRefreshZoomProvider();
|
|
238
352
|
onRefreshViewStateProvider === null || onRefreshViewStateProvider === void 0 ? void 0 : onRefreshViewStateProvider();
|
|
353
|
+
if (onApplyInitialFit) {
|
|
354
|
+
await onApplyInitialFit();
|
|
355
|
+
onRefreshZoomProvider === null || onRefreshZoomProvider === void 0 ? void 0 : onRefreshZoomProvider();
|
|
356
|
+
onRefreshViewStateProvider === null || onRefreshViewStateProvider === void 0 ? void 0 : onRefreshViewStateProvider();
|
|
357
|
+
}
|
|
239
358
|
return session;
|
|
240
359
|
}
|
|
241
360
|
catch (error) {
|
|
@@ -243,7 +362,7 @@ export const runFileViewerRenderSurfaceMount = async ({ buffer, file, version, s
|
|
|
243
362
|
throw error;
|
|
244
363
|
}
|
|
245
364
|
};
|
|
246
|
-
export const createFileViewerRenderSurfaceActionHandlers = ({ getContainer, surfaceState, readinessState, isCurrent, render, waitForContainer, waitForPaint, disposeOptions, onUnloadStart, onUnloadComplete, onClearActiveDocumentContext, onClearDocumentState, onStartZoomObserver, onStopZoomObserver, onClearZoomProvider, onStartViewStateObserver, onStopViewStateObserver, onClearViewStateProvider, onRefreshDocumentIndex, onRefreshZoomProvider, onRefreshViewStateProvider, }) => {
|
|
365
|
+
export const createFileViewerRenderSurfaceActionHandlers = ({ getContainer, surfaceState, readinessState, isCurrent, render, waitForContainer, waitForPaint, disposeOptions, onUnloadStart, onUnloadComplete, onClearActiveDocumentContext, onClearDocumentState, onStartZoomObserver, onStopZoomObserver, onClearZoomProvider, onStartFitObserver, onStopFitObserver, onStartViewStateObserver, onStopViewStateObserver, onClearViewStateProvider, onApplyInitialFit, onRefreshDocumentIndex, onRefreshZoomProvider, onRefreshViewStateProvider, }) => {
|
|
247
366
|
const handleDisposeError = (error) => {
|
|
248
367
|
if (disposeOptions === null || disposeOptions === void 0 ? void 0 : disposeOptions.onError) {
|
|
249
368
|
disposeOptions.onError(error);
|
|
@@ -274,6 +393,7 @@ export const createFileViewerRenderSurfaceActionHandlers = ({ getContainer, surf
|
|
|
274
393
|
onClearDocumentState,
|
|
275
394
|
onStopZoomObserver,
|
|
276
395
|
onClearZoomProvider,
|
|
396
|
+
onStopFitObserver,
|
|
277
397
|
onStopViewStateObserver,
|
|
278
398
|
onClearViewStateProvider,
|
|
279
399
|
});
|
|
@@ -295,7 +415,9 @@ export const createFileViewerRenderSurfaceActionHandlers = ({ getContainer, surf
|
|
|
295
415
|
waitForPaint,
|
|
296
416
|
disposeSession: destroyRenderSession,
|
|
297
417
|
onStartZoomObserver,
|
|
418
|
+
onStartFitObserver,
|
|
298
419
|
onStartViewStateObserver,
|
|
420
|
+
onApplyInitialFit,
|
|
299
421
|
onRefreshDocumentIndex,
|
|
300
422
|
onRefreshZoomProvider,
|
|
301
423
|
onRefreshViewStateProvider,
|
|
@@ -308,11 +430,12 @@ export const createFileViewerRenderSurfaceActionHandlers = ({ getContainer, surf
|
|
|
308
430
|
mountRenderedContent,
|
|
309
431
|
};
|
|
310
432
|
};
|
|
311
|
-
export const buildFileRenderContextFromLoadContext = ({ source, options, registerExportAdapter, renderContext, }) => ({
|
|
433
|
+
export const buildFileRenderContextFromLoadContext = ({ source, surface, options, registerExportAdapter, renderContext, }) => ({
|
|
312
434
|
filename: source.filename,
|
|
313
435
|
url: source.url,
|
|
314
436
|
streamUrl: source.url,
|
|
315
437
|
options,
|
|
438
|
+
surface,
|
|
316
439
|
registerExportAdapter,
|
|
317
440
|
...renderContext,
|
|
318
441
|
});
|
package/dist/source/loading.d.ts
CHANGED
|
@@ -430,8 +430,10 @@ export interface RunFileViewerPreviewSourceChangeInput {
|
|
|
430
430
|
export interface RunFileViewerPreviewComponentUnmountInput {
|
|
431
431
|
reason?: FileViewerLifecycleContext['reason'];
|
|
432
432
|
onCancelPreview?: (reason: FileViewerLifecycleContext['reason']) => void;
|
|
433
|
+
onClearRenderedContent?: (reason: FileViewerLifecycleContext['reason']) => void;
|
|
433
434
|
onResetLoading?: () => void;
|
|
434
435
|
onStopZoomObserver?: () => void;
|
|
436
|
+
onStopFitObserver?: () => void;
|
|
435
437
|
onStopViewStateObserver?: () => void;
|
|
436
438
|
}
|
|
437
439
|
export interface FileViewerPreviewComponentUnmountState {
|
|
@@ -502,7 +504,7 @@ export declare const applyFileViewerPreviewRequestResetState: <Target extends Mu
|
|
|
502
504
|
export declare const commitFileViewerPreviewRequestStartState: ({ reason, requestController, previewTarget, onClearRenderedContent, onClearError, }: CommitFileViewerPreviewRequestStartStateInput) => number;
|
|
503
505
|
export declare const cancelFileViewerPreviewRequest: ({ reason, requestController, previewTarget, onClearRenderedContent, onClearError, }: CancelFileViewerPreviewRequestInput) => number;
|
|
504
506
|
export declare const runFileViewerPreviewSourceChange: ({ onRefreshPreview, }?: RunFileViewerPreviewSourceChangeInput) => unknown;
|
|
505
|
-
export declare const runFileViewerPreviewComponentUnmount: ({ reason, onCancelPreview, onResetLoading, onStopZoomObserver, onStopViewStateObserver, }?: RunFileViewerPreviewComponentUnmountInput) => FileViewerPreviewComponentUnmountState;
|
|
507
|
+
export declare const runFileViewerPreviewComponentUnmount: ({ reason, onCancelPreview, onClearRenderedContent, onResetLoading, onStopZoomObserver, onStopFitObserver, onStopViewStateObserver, }?: RunFileViewerPreviewComponentUnmountInput) => FileViewerPreviewComponentUnmountState;
|
|
506
508
|
export declare const applyFileViewerEmptyPreviewState: <Target extends MutableFileViewerPreviewState>(target: Target, state?: FileViewerEmptyPreviewState) => Target;
|
|
507
509
|
export declare const commitFileViewerEmptyPreviewResetState: ({ previewTarget, state, reason, onClearRenderedContent, onResetLoading, }: CommitFileViewerEmptyPreviewResetStateInput) => MutableFileViewerPreviewState;
|
|
508
510
|
export declare const runFileViewerPreviewRequest: <LocalResult = unknown, RemoteResult = unknown>({ file, url, reason, requestController, previewTarget, onPreviewLocalFile, onPreviewRemoteFile, onClearRenderedContent, onClearError, onResetLoading, }: RunFileViewerPreviewRequestInput<LocalResult, RemoteResult>) => Promise<FileViewerPreviewRequestRunState<LocalResult, RemoteResult>>;
|
package/dist/source/loading.js
CHANGED
|
@@ -17,7 +17,7 @@ export const resolveFileViewerPreviewLoadErrorMessage = ({ kind, error, formatEr
|
|
|
17
17
|
: kind === 'stream'
|
|
18
18
|
? translateFileViewerMessage(i18n, 'error.stream')
|
|
19
19
|
: translateFileViewerMessage(i18n, 'error.load');
|
|
20
|
-
return formatErrorMessage((_a = prefixes === null || prefixes === void 0 ? void 0 : prefixes[kind]) !== null && _a !== void 0 ? _a : fallbackPrefix, error);
|
|
20
|
+
return formatErrorMessage((_a = prefixes === null || prefixes === void 0 ? void 0 : prefixes[kind]) !== null && _a !== void 0 ? _a : fallbackPrefix, error, i18n);
|
|
21
21
|
};
|
|
22
22
|
export const resolveFileViewerMissingRemoteDataErrorMessage = ({ message, i18n, } = {}) => message || translateFileViewerMessage(i18n, 'error.remoteDownload');
|
|
23
23
|
export const DEFAULT_FILE_VIEWER_PREVIEW_LOAD_ERROR_LOGGER = error => {
|
|
@@ -182,10 +182,14 @@ export const cancelFileViewerPreviewRequest = ({ reason = 'component-unmount', r
|
|
|
182
182
|
export const runFileViewerPreviewSourceChange = ({ onRefreshPreview, } = {}) => {
|
|
183
183
|
return onRefreshPreview === null || onRefreshPreview === void 0 ? void 0 : onRefreshPreview();
|
|
184
184
|
};
|
|
185
|
-
export const runFileViewerPreviewComponentUnmount = ({ reason = 'component-unmount', onCancelPreview, onResetLoading, onStopZoomObserver, onStopViewStateObserver, } = {}) => {
|
|
185
|
+
export const runFileViewerPreviewComponentUnmount = ({ reason = 'component-unmount', onCancelPreview, onClearRenderedContent, onResetLoading, onStopZoomObserver, onStopFitObserver, onStopViewStateObserver, } = {}) => {
|
|
186
186
|
onCancelPreview === null || onCancelPreview === void 0 ? void 0 : onCancelPreview(reason);
|
|
187
|
+
if (!onCancelPreview) {
|
|
188
|
+
onClearRenderedContent === null || onClearRenderedContent === void 0 ? void 0 : onClearRenderedContent(reason);
|
|
189
|
+
}
|
|
187
190
|
onResetLoading === null || onResetLoading === void 0 ? void 0 : onResetLoading();
|
|
188
191
|
onStopZoomObserver === null || onStopZoomObserver === void 0 ? void 0 : onStopZoomObserver();
|
|
192
|
+
onStopFitObserver === null || onStopFitObserver === void 0 ? void 0 : onStopFitObserver();
|
|
189
193
|
onStopViewStateObserver === null || onStopViewStateObserver === void 0 ? void 0 : onStopViewStateObserver();
|
|
190
194
|
return {
|
|
191
195
|
reason,
|
|
@@ -8,11 +8,12 @@ import { createEmptyFileViewerSearchState, } from '../features/document/model.js
|
|
|
8
8
|
import { createFileViewerDocumentFeatureControllerActionHandlers, } from '../features/document/events.js';
|
|
9
9
|
import { createFileViewerZoomController } from '../features/document/zoom.js';
|
|
10
10
|
import { createFileViewerViewStateController } from '../features/document/viewState.js';
|
|
11
|
+
import { createFileViewerFitController, hasFileViewerExplicitInitialViewState, } from '../features/document/fit.js';
|
|
11
12
|
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';
|
|
12
13
|
import { applyFileViewerZoomAvailability, createUnsupportedAvailability, getRendererAvailability, } from '../registry/capabilities.js';
|
|
13
14
|
import { buildFileViewerLifecycleContextFromNormalizedSource, buildFileViewerOperationContext, runFileViewerBeforeOperation, runFileViewerLifecycleHook, } from '../lifecycle/operations.js';
|
|
14
15
|
import { collectFileViewerRendererPlugins, createRendererRegistry, getFileViewerAutoRendererPresetVersion, hasFileViewerRendererPresetName, installFileViewerRendererPlugins, listFileViewerAutoRendererPresets, resolveFileViewerRendererPresetInputs, } from '../registry/registry.js';
|
|
15
|
-
import { createFileRenderHandlerLoader, applyFileViewerRenderSurfaceState, createFileViewerRenderSurfaceState,
|
|
16
|
+
import { createFileRenderHandlerLoader, applyFileViewerRenderSurfaceState, createFileViewerRenderSurfaceState, createFileViewerRenderSurface, removeFileViewerRenderTarget, } from '../rendering/handler.js';
|
|
16
17
|
import { createFileViewerCoreRendererRegistry } from '../renderers/index.js';
|
|
17
18
|
import { createFileViewerRequestScope } from '../source/loading.js';
|
|
18
19
|
import { normalizeSource } from '../source/index.js';
|
|
@@ -94,6 +95,7 @@ export const createViewer = (container, createOptions = {}) => {
|
|
|
94
95
|
let installedAutoRendererVersion = -1;
|
|
95
96
|
let currentSource = null;
|
|
96
97
|
let currentRenderTarget = null;
|
|
98
|
+
let currentDocumentRoot = null;
|
|
97
99
|
const renderSurfaceState = createFileViewerRenderSurfaceState();
|
|
98
100
|
const requestScope = createFileViewerRequestScope();
|
|
99
101
|
const documentTarget = {
|
|
@@ -190,12 +192,16 @@ export const createViewer = (container, createOptions = {}) => {
|
|
|
190
192
|
}
|
|
191
193
|
};
|
|
192
194
|
const createRenderTarget = (fillHeight = true) => {
|
|
193
|
-
const
|
|
195
|
+
const surface = createFileViewerRenderSurface(container, {
|
|
196
|
+
styleIsolation: options.styleIsolation,
|
|
197
|
+
});
|
|
198
|
+
const target = surface.host || surface.container;
|
|
194
199
|
if (fillHeight) {
|
|
195
200
|
target.style.height = '100%';
|
|
201
|
+
surface.container.style.height = '100%';
|
|
196
202
|
}
|
|
197
203
|
currentRenderTarget = target;
|
|
198
|
-
return
|
|
204
|
+
return surface;
|
|
199
205
|
};
|
|
200
206
|
const disposeStaleSession = async (session, target) => {
|
|
201
207
|
var _a;
|
|
@@ -350,20 +356,41 @@ export const createViewer = (container, createOptions = {}) => {
|
|
|
350
356
|
emitZoomChange(state);
|
|
351
357
|
emitOperationAvailabilityChange();
|
|
352
358
|
};
|
|
359
|
+
const emitFitChange = (result) => {
|
|
360
|
+
var _a;
|
|
361
|
+
(_a = createOptions.onEvent) === null || _a === void 0 ? void 0 : _a.call(createOptions, {
|
|
362
|
+
type: 'fit-change',
|
|
363
|
+
payload: result,
|
|
364
|
+
});
|
|
365
|
+
};
|
|
353
366
|
const zoomController = createFileViewerZoomController({
|
|
354
|
-
root: () => container,
|
|
367
|
+
root: () => currentDocumentRoot || container,
|
|
355
368
|
beforeZoom: runBeforeViewerOperation,
|
|
356
369
|
onChange: state => emitZoomAndOperationAvailabilityChange(state),
|
|
357
370
|
});
|
|
371
|
+
const fitController = createFileViewerFitController({
|
|
372
|
+
root: () => currentDocumentRoot || container,
|
|
373
|
+
getFit: () => options.fit,
|
|
374
|
+
onFit: result => {
|
|
375
|
+
zoomController.refreshProvider();
|
|
376
|
+
viewStateController.refreshProvider();
|
|
377
|
+
emitZoomAndOperationAvailabilityChange();
|
|
378
|
+
emitFitChange(result);
|
|
379
|
+
},
|
|
380
|
+
});
|
|
358
381
|
const viewStateController = createFileViewerViewStateController({
|
|
359
|
-
root: () => container,
|
|
382
|
+
root: () => currentDocumentRoot || container,
|
|
360
383
|
onChange: change => {
|
|
361
384
|
var _a;
|
|
385
|
+
if ((change.source === 'user' || change.source === 'api') &&
|
|
386
|
+
change.action !== 'fit') {
|
|
387
|
+
fitController.markUserInteraction();
|
|
388
|
+
}
|
|
362
389
|
(_a = createOptions.onEvent) === null || _a === void 0 ? void 0 : _a.call(createOptions, { type: 'view-state-change', payload: change });
|
|
363
390
|
},
|
|
364
391
|
});
|
|
365
392
|
const documentActions = createFileViewerDocumentFeatureControllerActionHandlers({
|
|
366
|
-
root: () => container,
|
|
393
|
+
root: () => currentDocumentRoot || container,
|
|
367
394
|
searchTarget: documentTarget,
|
|
368
395
|
searchOptions: () => options.search,
|
|
369
396
|
getAiOptions: () => options.ai,
|
|
@@ -378,6 +405,7 @@ export const createViewer = (container, createOptions = {}) => {
|
|
|
378
405
|
});
|
|
379
406
|
zoomController.observe();
|
|
380
407
|
viewStateController.observe();
|
|
408
|
+
fitController.observe();
|
|
381
409
|
const destroyCurrent = async (reason = 'replace') => {
|
|
382
410
|
var _a;
|
|
383
411
|
const session = renderSurfaceState.session;
|
|
@@ -394,6 +422,7 @@ export const createViewer = (container, createOptions = {}) => {
|
|
|
394
422
|
await ((_a = session === null || session === void 0 ? void 0 : session.destroy) === null || _a === void 0 ? void 0 : _a.call(session));
|
|
395
423
|
removeRenderTarget(target || undefined);
|
|
396
424
|
currentSource = null;
|
|
425
|
+
currentDocumentRoot = null;
|
|
397
426
|
applyFileViewerRenderSurfaceState(renderSurfaceState, {
|
|
398
427
|
session: null,
|
|
399
428
|
exportAdapter: null,
|
|
@@ -402,6 +431,7 @@ export const createViewer = (container, createOptions = {}) => {
|
|
|
402
431
|
await documentActions.clearDocumentState();
|
|
403
432
|
zoomController.clearProvider();
|
|
404
433
|
viewStateController.clearProvider();
|
|
434
|
+
fitController.resetAutoFit();
|
|
405
435
|
emitZoomAndOperationAvailabilityChange();
|
|
406
436
|
if (source) {
|
|
407
437
|
await emitLifecycle(options, createOptions.onEvent, 'unload-complete', source, version, startedAt, reason);
|
|
@@ -421,7 +451,10 @@ export const createViewer = (container, createOptions = {}) => {
|
|
|
421
451
|
const renderer = registry.getByExtension(normalized.extension);
|
|
422
452
|
const startedAt = Date.now();
|
|
423
453
|
await emitLifecycle(options, createOptions.onEvent, 'load-start', normalized, version, startedAt);
|
|
424
|
-
const
|
|
454
|
+
const surface = createRenderTarget((renderer === null || renderer === void 0 ? void 0 : renderer.id) !== 'office-presentation');
|
|
455
|
+
const target = surface.container;
|
|
456
|
+
const targetHost = surface.host || target;
|
|
457
|
+
currentDocumentRoot = target;
|
|
425
458
|
if (!(renderer === null || renderer === void 0 ? void 0 : renderer.load)) {
|
|
426
459
|
renderMissingRendererState(target, normalized.extension, options);
|
|
427
460
|
applyFileViewerRenderSurfaceState(renderSurfaceState, { session: null });
|
|
@@ -434,7 +467,7 @@ export const createViewer = (container, createOptions = {}) => {
|
|
|
434
467
|
try {
|
|
435
468
|
session = await renderer.load({
|
|
436
469
|
source: normalized,
|
|
437
|
-
surface
|
|
470
|
+
surface,
|
|
438
471
|
options,
|
|
439
472
|
signal: createOptions.signal,
|
|
440
473
|
registerExportAdapter: adapter => {
|
|
@@ -446,14 +479,14 @@ export const createViewer = (container, createOptions = {}) => {
|
|
|
446
479
|
}
|
|
447
480
|
catch (error) {
|
|
448
481
|
if (!requestScope.isCurrentRequest(version)) {
|
|
449
|
-
removeRenderTarget(
|
|
482
|
+
removeRenderTarget(targetHost);
|
|
450
483
|
return null;
|
|
451
484
|
}
|
|
452
|
-
removeRenderTarget(
|
|
485
|
+
removeRenderTarget(targetHost);
|
|
453
486
|
throw error;
|
|
454
487
|
}
|
|
455
488
|
if (!requestScope.isCurrentRequest(version)) {
|
|
456
|
-
await disposeStaleSession(session,
|
|
489
|
+
await disposeStaleSession(session, targetHost);
|
|
457
490
|
return null;
|
|
458
491
|
}
|
|
459
492
|
applyFileViewerRenderSurfaceState(renderSurfaceState, { session });
|
|
@@ -461,6 +494,11 @@ export const createViewer = (container, createOptions = {}) => {
|
|
|
461
494
|
zoomController.refreshProvider();
|
|
462
495
|
viewStateController.refreshProvider();
|
|
463
496
|
await documentActions.refreshDocumentIndex({ notify: false });
|
|
497
|
+
await fitController.applyInitialFit({
|
|
498
|
+
skip: hasFileViewerExplicitInitialViewState(options.initialViewState),
|
|
499
|
+
});
|
|
500
|
+
zoomController.refreshProvider();
|
|
501
|
+
viewStateController.refreshProvider();
|
|
464
502
|
emitZoomAndOperationAvailabilityChange();
|
|
465
503
|
await emitLifecycle(options, createOptions.onEvent, 'load-complete', normalized, version, startedAt);
|
|
466
504
|
return session;
|
|
@@ -471,14 +509,20 @@ export const createViewer = (container, createOptions = {}) => {
|
|
|
471
509
|
documentActions.destroyDocumentFeatures();
|
|
472
510
|
zoomController.destroy();
|
|
473
511
|
viewStateController.destroy();
|
|
512
|
+
fitController.destroy();
|
|
474
513
|
removeWatermarkOverlay();
|
|
475
514
|
},
|
|
476
515
|
updateOptions(nextOptions) {
|
|
516
|
+
const previousFit = options.fit;
|
|
477
517
|
options = {
|
|
478
518
|
...options,
|
|
479
519
|
...nextOptions,
|
|
480
520
|
};
|
|
481
521
|
syncWatermarkOverlay();
|
|
522
|
+
if ('fit' in nextOptions && nextOptions.fit !== previousFit) {
|
|
523
|
+
fitController.resetAutoFit();
|
|
524
|
+
fitController.scheduleFit('resize');
|
|
525
|
+
}
|
|
482
526
|
},
|
|
483
527
|
getCapabilities(extension) {
|
|
484
528
|
return getCapabilitiesForExtension(extension);
|
|
@@ -540,20 +584,30 @@ export const createViewer = (container, createOptions = {}) => {
|
|
|
540
584
|
});
|
|
541
585
|
},
|
|
542
586
|
async zoomIn() {
|
|
587
|
+
fitController.markUserInteraction();
|
|
543
588
|
const state = await zoomController.zoomIn();
|
|
544
589
|
emitZoomAndOperationAvailabilityChange(state);
|
|
545
590
|
return state;
|
|
546
591
|
},
|
|
547
592
|
async zoomOut() {
|
|
593
|
+
fitController.markUserInteraction();
|
|
548
594
|
const state = await zoomController.zoomOut();
|
|
549
595
|
emitZoomAndOperationAvailabilityChange(state);
|
|
550
596
|
return state;
|
|
551
597
|
},
|
|
552
598
|
async resetZoom() {
|
|
599
|
+
fitController.markUserInteraction();
|
|
553
600
|
const state = await zoomController.resetZoom();
|
|
554
601
|
emitZoomAndOperationAvailabilityChange(state);
|
|
555
602
|
return state;
|
|
556
603
|
},
|
|
604
|
+
async fitToView(fit) {
|
|
605
|
+
const result = await fitController.fit(fit, { source: 'api', reason: 'api' });
|
|
606
|
+
zoomController.refreshProvider();
|
|
607
|
+
viewStateController.refreshProvider();
|
|
608
|
+
emitZoomAndOperationAvailabilityChange();
|
|
609
|
+
return result;
|
|
610
|
+
},
|
|
557
611
|
getZoomState() {
|
|
558
612
|
return zoomController.getState();
|
|
559
613
|
},
|
|
@@ -561,6 +615,7 @@ export const createViewer = (container, createOptions = {}) => {
|
|
|
561
615
|
return viewStateController.getState();
|
|
562
616
|
},
|
|
563
617
|
applyViewState(state, applyOptions) {
|
|
618
|
+
fitController.markUserInteraction();
|
|
564
619
|
return viewStateController.applyState(state, applyOptions);
|
|
565
620
|
},
|
|
566
621
|
search(query) {
|
|
@@ -50,7 +50,7 @@ export const resolveFileViewerOperationFilename = ({ filename, source, fallback
|
|
|
50
50
|
};
|
|
51
51
|
export const resolveFileViewerOperationActionErrorMessage = ({ context, formatErrorMessage, prefixes, i18n, }) => {
|
|
52
52
|
var _a;
|
|
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);
|
|
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, i18n);
|
|
54
54
|
};
|
|
55
55
|
export const hasFileViewerOriginalSource = (source) => {
|
|
56
56
|
return !!source.buffer || !!source.file || !!source.url;
|
package/dist/viewer/state.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type FileViewerI18nInput } from '../i18n/messages';
|
|
2
2
|
import type { FileViewerRendererCategory, FileViewerStateDescriptor, FileViewerStateTheme } from '../contracts/types';
|
|
3
|
-
export type FileViewerErrorMessageFormatter = (prefix: string, error: unknown) => string;
|
|
3
|
+
export type FileViewerErrorMessageFormatter = (prefix: string, error: unknown, i18n?: FileViewerI18nInput) => string;
|
|
4
4
|
export declare const FILE_VIEWER_PREVIEW_MESSAGES: Readonly<{
|
|
5
5
|
downloading: "正在下载文件资源...";
|
|
6
6
|
streamingPdf: "正在建立 PDF 流式预览...";
|
|
@@ -28,6 +28,6 @@ export declare const createFileViewerPreviewLoadingState: (extension?: string, m
|
|
|
28
28
|
export declare const createFileViewerReadyState: (extension?: string, theme?: FileViewerStateTheme, i18n?: FileViewerI18nInput) => FileViewerStateDescriptor;
|
|
29
29
|
export declare const createFileViewerEmptyState: (extension?: string, theme?: FileViewerStateTheme, i18n?: FileViewerI18nInput) => FileViewerStateDescriptor;
|
|
30
30
|
export declare const createFileViewerUnsupportedState: (extension?: string, theme?: FileViewerStateTheme, i18n?: FileViewerI18nInput) => FileViewerStateDescriptor;
|
|
31
|
-
export declare const normalizeFileViewerErrorMessage: (error: unknown) => string;
|
|
31
|
+
export declare const normalizeFileViewerErrorMessage: (error: unknown, i18n?: FileViewerI18nInput) => string;
|
|
32
32
|
export declare const formatFileViewerErrorMessage: FileViewerErrorMessageFormatter;
|
|
33
33
|
export declare const createFileViewerErrorState: (extension?: string, error?: unknown, theme?: FileViewerStateTheme, i18n?: FileViewerI18nInput) => FileViewerStateDescriptor;
|
package/dist/viewer/state.js
CHANGED
|
@@ -197,20 +197,53 @@ export const createFileViewerUnsupportedState = (extension = '', theme = DEFAULT
|
|
|
197
197
|
recoverable: true,
|
|
198
198
|
});
|
|
199
199
|
};
|
|
200
|
-
|
|
200
|
+
const FILE_VIEWER_KNOWN_ERROR_MESSAGE_KEYS = {
|
|
201
|
+
'Blob is not available in the current execution environment.': 'error.blobUnavailable',
|
|
202
|
+
'Unsupported file source input.': 'error.sourceUnsupported',
|
|
203
|
+
'Failed to read file as ArrayBuffer.': 'error.fileReadArrayBuffer',
|
|
204
|
+
'Failed to read file as data URL.': 'error.fileReadDataUrl',
|
|
205
|
+
'Failed to read file as text.': 'error.fileReadText',
|
|
206
|
+
'Unable to read image data URL.': 'error.imageDataUrlRead',
|
|
207
|
+
'文件不是有效的 DOCX/OOXML 压缩包,可能下载不完整或被服务端错误内容替换,请重新上传或检查文件源。': 'word.error.invalidDocx',
|
|
208
|
+
'ODF 文件缺少 content.xml': 'word.error.missingOdfContent',
|
|
209
|
+
'ODF 文件缺少 content.xml。': 'word.error.missingOdfContent',
|
|
210
|
+
'ODF XML 解析失败': 'word.error.odfXmlParseFailed',
|
|
211
|
+
'ODF XML 解析失败。': 'word.error.odfXmlParseFailed',
|
|
212
|
+
'OFD 文件中没有可渲染的文档': 'ofd.error.empty',
|
|
213
|
+
'OFD 文件解析失败': 'ofd.error.parseFailed',
|
|
214
|
+
'IndexedDB 不可用': 'archive.error.indexedDbUnavailable',
|
|
215
|
+
'Web Worker is not supported by this browser.': 'archive.error.workerUnsupported',
|
|
216
|
+
};
|
|
217
|
+
const resolveKnownFileViewerErrorMessage = (message, i18n) => {
|
|
218
|
+
const key = FILE_VIEWER_KNOWN_ERROR_MESSAGE_KEYS[message.trim()];
|
|
219
|
+
return key ? translateFileViewerMessage(i18n, key) : message;
|
|
220
|
+
};
|
|
221
|
+
export const normalizeFileViewerErrorMessage = (error, i18n) => {
|
|
201
222
|
if (error instanceof Error) {
|
|
202
|
-
return error.message;
|
|
223
|
+
return resolveKnownFileViewerErrorMessage(error.message, i18n);
|
|
224
|
+
}
|
|
225
|
+
if (typeof error === 'string') {
|
|
226
|
+
return resolveKnownFileViewerErrorMessage(error, i18n);
|
|
227
|
+
}
|
|
228
|
+
if (error === undefined || error === null) {
|
|
229
|
+
return translateFileViewerMessage(i18n, 'error.unknown');
|
|
203
230
|
}
|
|
204
231
|
return String(error);
|
|
205
232
|
};
|
|
206
|
-
export const formatFileViewerErrorMessage = (prefix, error) => {
|
|
207
|
-
|
|
233
|
+
export const formatFileViewerErrorMessage = (prefix, error, i18n) => {
|
|
234
|
+
const detail = normalizeFileViewerErrorMessage(error, i18n);
|
|
235
|
+
if (!detail) {
|
|
236
|
+
return prefix;
|
|
237
|
+
}
|
|
238
|
+
return resolveFileViewerLocale(i18n) === 'zh-CN'
|
|
239
|
+
? `${prefix}:${detail}`
|
|
240
|
+
: `${prefix}: ${detail}`;
|
|
208
241
|
};
|
|
209
|
-
export const createFileViewerErrorState = (extension = '', error =
|
|
242
|
+
export const createFileViewerErrorState = (extension = '', error = undefined, theme = DEFAULT_FILE_VIEWER_STATE_THEME, i18n) => createFileViewerStateDescriptor({
|
|
210
243
|
state: 'error',
|
|
211
244
|
extension,
|
|
212
245
|
title: translateFileViewerMessage(i18n, 'state.error.title'),
|
|
213
|
-
message: normalizeFileViewerErrorMessage(error),
|
|
246
|
+
message: normalizeFileViewerErrorMessage(error, i18n),
|
|
214
247
|
theme,
|
|
215
248
|
recoverable: true,
|
|
216
249
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@file-viewer/core",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.19",
|
|
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",
|