@file-viewer/core 2.0.11 → 2.1.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 +2 -2
- package/README.md +2 -2
- package/dist/config/options.d.ts +1 -1
- package/dist/config/options.js +1 -1
- package/dist/contracts/types.d.ts +76 -1
- package/dist/headless.d.ts +3 -3
- package/dist/headless.js +2 -2
- package/dist/index.d.ts +10 -7
- package/dist/index.js +106 -49
- package/dist/lifecycle/operations.d.ts +1 -0
- package/dist/lifecycle/operations.js +65 -6
- package/dist/platform/assets.d.ts +3 -1
- package/dist/platform/assets.js +43 -6
- package/dist/registry/capabilities.d.ts +2 -2
- package/dist/registry/capabilities.js +2 -1
- package/dist/registry/formats.d.ts +20 -7
- package/dist/registry/formats.js +14 -5
- package/dist/registry/registry.d.ts +8 -1
- package/dist/registry/registry.js +29 -0
- package/dist/renderers/image.js +1 -10
- package/dist/renderers/index.d.ts +320 -2
- package/dist/renderers/index.js +27 -157
- package/dist/viewer/createViewer.js +86 -3
- package/package.json +17 -44
- package/dist/renderers/archive.d.ts +0 -2
- package/dist/renderers/archive.js +0 -547
- package/dist/renderers/archiveCache.d.ts +0 -10
- package/dist/renderers/archiveCache.js +0 -96
- package/dist/renderers/archiveFallback.d.ts +0 -7
- package/dist/renderers/archiveFallback.js +0 -166
- package/dist/renderers/archiveShared.d.ts +0 -23
- package/dist/renderers/archiveShared.js +0 -71
- package/dist/renderers/audio.d.ts +0 -8
- package/dist/renderers/audio.js +0 -219
- package/dist/renderers/cad.d.ts +0 -2
- package/dist/renderers/cad.js +0 -446
- package/dist/renderers/code.d.ts +0 -11
- package/dist/renderers/code.js +0 -233
- package/dist/renderers/data.d.ts +0 -7
- package/dist/renderers/data.js +0 -370
- package/dist/renderers/drawing.d.ts +0 -10
- package/dist/renderers/drawing.js +0 -882
- package/dist/renderers/eda.d.ts +0 -2
- package/dist/renderers/eda.js +0 -434
- package/dist/renderers/edaParser.d.ts +0 -77
- package/dist/renderers/edaParser.js +0 -569
- package/dist/renderers/email.d.ts +0 -2
- package/dist/renderers/email.js +0 -463
- package/dist/renderers/epub.d.ts +0 -2
- package/dist/renderers/epub.js +0 -331
- package/dist/renderers/geo.d.ts +0 -2
- package/dist/renderers/geo.js +0 -284
- package/dist/renderers/markdown.d.ts +0 -2
- package/dist/renderers/markdown.js +0 -83
- package/dist/renderers/model.d.ts +0 -2
- package/dist/renderers/model.js +0 -567
- package/dist/renderers/ofd.d.ts +0 -2
- package/dist/renderers/ofd.js +0 -256
- package/dist/renderers/openDocument.d.ts +0 -2
- package/dist/renderers/openDocument.js +0 -122
- package/dist/renderers/pdf.d.ts +0 -3
- package/dist/renderers/pdf.js +0 -1001
- package/dist/renderers/pdfStyles.d.ts +0 -1
- package/dist/renderers/pdfStyles.js +0 -1
- package/dist/renderers/pptx.d.ts +0 -2
- package/dist/renderers/pptx.js +0 -217
- package/dist/renderers/spreadsheet/state.d.ts +0 -80
- package/dist/renderers/spreadsheet/state.js +0 -96
- package/dist/renderers/spreadsheet/view.d.ts +0 -25
- package/dist/renderers/spreadsheet/view.js +0 -833
- package/dist/renderers/spreadsheet/worker/index.d.ts +0 -2
- package/dist/renderers/spreadsheet/worker/index.js +0 -1
- package/dist/renderers/spreadsheet/worker/sheetjs/SheetJsModel.d.ts +0 -73
- package/dist/renderers/spreadsheet/worker/sheetjs/SheetJsModel.js +0 -623
- package/dist/renderers/spreadsheet/worker/sheetjs/color.d.ts +0 -2
- package/dist/renderers/spreadsheet/worker/sheetjs/color.js +0 -73
- package/dist/renderers/spreadsheet/worker/sheetjs/index.d.ts +0 -1
- package/dist/renderers/spreadsheet/worker/sheetjs/index.js +0 -1
- package/dist/renderers/spreadsheet/worker/sheetjs/parser.d.ts +0 -18
- package/dist/renderers/spreadsheet/worker/sheetjs/parser.js +0 -106
- package/dist/renderers/spreadsheet/worker/sheetjs/sheet.worker.d.ts +0 -1
- package/dist/renderers/spreadsheet/worker/sheetjs/sheet.worker.js +0 -11
- package/dist/renderers/spreadsheet/worker/type.d.ts +0 -57
- package/dist/renderers/spreadsheet/worker/type.js +0 -1
- package/dist/renderers/spreadsheet.d.ts +0 -3
- package/dist/renderers/spreadsheet.js +0 -929
- package/dist/renderers/typst.d.ts +0 -8
- package/dist/renderers/typst.js +0 -547
- package/dist/renderers/umd/parser.d.ts +0 -30
- package/dist/renderers/umd/parser.js +0 -408
- package/dist/renderers/umd.d.ts +0 -2
- package/dist/renderers/umd.js +0 -297
- package/dist/renderers/video.d.ts +0 -8
- package/dist/renderers/video.js +0 -108
- package/dist/renderers/wordDoc.d.ts +0 -5
- package/dist/renderers/wordDoc.js +0 -284
- package/dist/renderers/wordDocx.d.ts +0 -5
- package/dist/renderers/wordDocx.js +0 -985
- package/dist/renderers/wordDocx.worker.d.ts +0 -1
- package/dist/renderers/wordDocx.worker.js +0 -96
- package/vendor/ofd/dltech/jbig2/arithmetic_decoder.js +0 -183
- package/vendor/ofd/dltech/jbig2/ccitt.js +0 -1070
- package/vendor/ofd/dltech/jbig2/compatibility.js +0 -12
- package/vendor/ofd/dltech/jbig2/core_utils.js +0 -180
- package/vendor/ofd/dltech/jbig2/is_node.js +0 -27
- package/vendor/ofd/dltech/jbig2/jbig2.js +0 -2589
- package/vendor/ofd/dltech/jbig2/jbig2_stream.js +0 -81
- package/vendor/ofd/dltech/jbig2/primitives.js +0 -387
- package/vendor/ofd/dltech/jbig2/stream.js +0 -1348
- package/vendor/ofd/dltech/jbig2/util.js +0 -972
- package/vendor/ofd/dltech/ofd/ofd.d.ts +0 -11
- package/vendor/ofd/dltech/ofd/ofd.js +0 -100
- package/vendor/ofd/dltech/ofd/ofd_parser.js +0 -395
- package/vendor/ofd/dltech/ofd/ofd_render.js +0 -473
- package/vendor/ofd/dltech/ofd/ofd_util.js +0 -350
- package/vendor/ofd/dltech/ofd/pipeline.js +0 -26
package/dist/renderers/ofd.js
DELETED
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
import { registerFileViewerZoomProvider, unregisterFileViewerZoomProvider, } from '../features/document/dom/index.js';
|
|
2
|
-
import { createFileViewerZoomChangeEmitter } from '../features/document/zoom.js';
|
|
3
|
-
const OFD_MIN_SCALE = 0.35;
|
|
4
|
-
const OFD_MAX_SCALE = 3;
|
|
5
|
-
const OFD_ZOOM_STEP = 0.1;
|
|
6
|
-
const ofdStyle = `
|
|
7
|
-
.ofd-viewer{position:relative;box-sizing:border-box;min-height:100%;background:#e9edf2;color:#172033;font-family:Aptos,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif}
|
|
8
|
-
.ofd-viewer *{box-sizing:border-box}
|
|
9
|
-
.ofd-stage{min-height:100%;padding:18px 0 28px;overflow:auto;scrollbar-gutter:stable}
|
|
10
|
-
.ofd-state{position:absolute;inset:0;z-index:1;display:flex;align-items:center;justify-content:center;background:rgba(246,248,250,.92);color:#64748b;font-size:14px}
|
|
11
|
-
.ofd-state[hidden]{display:none!important}
|
|
12
|
-
.ofd-state.error{color:#b42318}
|
|
13
|
-
.ofd-page-frame{position:relative;display:block;margin:0 auto 20px;overflow:visible}
|
|
14
|
-
.ofd-page{display:block;margin-left:auto!important;margin-right:auto!important;box-shadow:0 10px 26px rgba(15,23,42,.12);transition:transform .16s ease}
|
|
15
|
-
.file-viewer[data-viewer-theme='dark'] .ofd-viewer{background:#172033;color:#e5eef8}
|
|
16
|
-
.file-viewer[data-viewer-theme='dark'] .ofd-state{background:rgba(15,23,42,.9);color:#cbd5e1}
|
|
17
|
-
@media (prefers-color-scheme:dark){.file-viewer[data-viewer-theme='system'] .ofd-viewer{background:#172033;color:#e5eef8}.file-viewer[data-viewer-theme='system'] .ofd-state{background:rgba(15,23,42,.9);color:#cbd5e1}}
|
|
18
|
-
@media print{.ofd-viewer{background:#fff!important}.ofd-stage{padding:0!important;overflow:visible!important}.ofd-page-frame{break-after:page;page-break-after:always;margin:0 auto!important}.ofd-page-frame:last-child{break-after:auto;page-break-after:auto}.ofd-page{box-shadow:none!important;transition:none!important}}
|
|
19
|
-
`;
|
|
20
|
-
const loadOfdModule = (() => {
|
|
21
|
-
let modulePromise = null;
|
|
22
|
-
return () => {
|
|
23
|
-
modulePromise || (modulePromise = import('../../vendor/ofd/dltech/ofd/ofd.js'));
|
|
24
|
-
return modulePromise;
|
|
25
|
-
};
|
|
26
|
-
})();
|
|
27
|
-
const createStyle = (documentRef) => {
|
|
28
|
-
const style = documentRef.createElement('style');
|
|
29
|
-
style.textContent = ofdStyle;
|
|
30
|
-
return style;
|
|
31
|
-
};
|
|
32
|
-
const createElement = (documentRef, tagName, className, text) => {
|
|
33
|
-
const element = documentRef.createElement(tagName);
|
|
34
|
-
if (className) {
|
|
35
|
-
element.className = className;
|
|
36
|
-
}
|
|
37
|
-
if (text !== undefined) {
|
|
38
|
-
element.textContent = text;
|
|
39
|
-
}
|
|
40
|
-
return element;
|
|
41
|
-
};
|
|
42
|
-
const normalizeError = (reason) => {
|
|
43
|
-
if (reason instanceof Error) {
|
|
44
|
-
return reason.message;
|
|
45
|
-
}
|
|
46
|
-
if (typeof reason === 'string') {
|
|
47
|
-
return reason;
|
|
48
|
-
}
|
|
49
|
-
try {
|
|
50
|
-
return JSON.stringify(reason);
|
|
51
|
-
}
|
|
52
|
-
catch {
|
|
53
|
-
return String(reason || 'OFD 文件解析失败');
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
const clampZoom = (value) => Math.min(OFD_MAX_SCALE, Math.max(OFD_MIN_SCALE, Number(value.toFixed(2))));
|
|
57
|
-
const waitForPaint = (view) => new Promise(resolve => {
|
|
58
|
-
if (view === null || view === void 0 ? void 0 : view.requestAnimationFrame) {
|
|
59
|
-
view.requestAnimationFrame(() => resolve());
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
globalThis.setTimeout(resolve, 0);
|
|
63
|
-
});
|
|
64
|
-
const parseWithOfdJs = (ofd, buffer) => {
|
|
65
|
-
return new Promise((resolve, reject) => {
|
|
66
|
-
// 使用 DLTech21/ofd.js 的纯 JS 解析入口,签章验签链路不阻断正文预览。
|
|
67
|
-
ofd.parseOfdDocument({
|
|
68
|
-
ofd: buffer,
|
|
69
|
-
success: documents => resolve(documents),
|
|
70
|
-
fail: reason => reject(reason),
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
};
|
|
74
|
-
const appendPages = (documentRef, target, pages) => {
|
|
75
|
-
const fragment = documentRef.createDocumentFragment();
|
|
76
|
-
pages.forEach(page => {
|
|
77
|
-
const frame = documentRef.createElement('div');
|
|
78
|
-
frame.className = 'ofd-page-frame';
|
|
79
|
-
page.classList.add('ofd-page');
|
|
80
|
-
frame.appendChild(page);
|
|
81
|
-
fragment.appendChild(frame);
|
|
82
|
-
});
|
|
83
|
-
target.appendChild(fragment);
|
|
84
|
-
};
|
|
85
|
-
export default async function renderOfd(buffer, target, context) {
|
|
86
|
-
const documentRef = target.ownerDocument || document;
|
|
87
|
-
const targetWindow = documentRef.defaultView || (typeof window !== 'undefined' ? window : null);
|
|
88
|
-
const zoomEmitter = createFileViewerZoomChangeEmitter();
|
|
89
|
-
let disposed = false;
|
|
90
|
-
let renderVersion = 0;
|
|
91
|
-
let resizeObserver = null;
|
|
92
|
-
let resizeTimer = 0;
|
|
93
|
-
let lastRenderedWidth = 0;
|
|
94
|
-
let state = 'loading';
|
|
95
|
-
let errorMessage = '';
|
|
96
|
-
let zoom = 1;
|
|
97
|
-
let ofdDocumentPromise = null;
|
|
98
|
-
const style = createStyle(documentRef);
|
|
99
|
-
const viewer = createElement(documentRef, 'div', 'ofd-viewer');
|
|
100
|
-
viewer.dataset.viewerZoomProvider = 'ofd';
|
|
101
|
-
const stateNode = createElement(documentRef, 'div', 'ofd-state', '正在解析 OFD...');
|
|
102
|
-
stateNode.setAttribute('aria-live', 'polite');
|
|
103
|
-
const stage = createElement(documentRef, 'div', 'ofd-stage');
|
|
104
|
-
viewer.append(stateNode, stage);
|
|
105
|
-
target.replaceChildren(style, viewer);
|
|
106
|
-
const clearStage = () => {
|
|
107
|
-
stage.replaceChildren();
|
|
108
|
-
};
|
|
109
|
-
const syncState = () => {
|
|
110
|
-
stateNode.hidden = state === 'ready';
|
|
111
|
-
stateNode.classList.toggle('error', state === 'error');
|
|
112
|
-
stateNode.textContent = state === 'error' ? errorMessage : '正在解析 OFD...';
|
|
113
|
-
};
|
|
114
|
-
const getOfdDocument = async (ofd) => {
|
|
115
|
-
// OFD 解压和 XML 解析成本较高,尺寸变化只重排页面,不重复解析压缩包。
|
|
116
|
-
ofdDocumentPromise || (ofdDocumentPromise = parseWithOfdJs(ofd, buffer).then(documents => {
|
|
117
|
-
const ofdDocument = documents[0];
|
|
118
|
-
if (!ofdDocument) {
|
|
119
|
-
throw new Error('OFD 文件中没有可渲染的文档');
|
|
120
|
-
}
|
|
121
|
-
return ofdDocument;
|
|
122
|
-
}));
|
|
123
|
-
return ofdDocumentPromise;
|
|
124
|
-
};
|
|
125
|
-
const getRenderWidth = () => {
|
|
126
|
-
const baseWidth = viewer.getBoundingClientRect().width || stage.getBoundingClientRect().width || 0;
|
|
127
|
-
return Math.max(Math.floor(baseWidth - 48), 240);
|
|
128
|
-
};
|
|
129
|
-
const getZoomState = () => ({
|
|
130
|
-
scale: zoom,
|
|
131
|
-
label: `${Math.round(zoom * 100)}%`,
|
|
132
|
-
canZoomIn: zoom < OFD_MAX_SCALE,
|
|
133
|
-
canZoomOut: zoom > OFD_MIN_SCALE,
|
|
134
|
-
canReset: zoom !== 1,
|
|
135
|
-
minScale: OFD_MIN_SCALE,
|
|
136
|
-
maxScale: OFD_MAX_SCALE,
|
|
137
|
-
});
|
|
138
|
-
const syncPageZoom = () => {
|
|
139
|
-
const HTMLElementCtor = (targetWindow === null || targetWindow === void 0 ? void 0 : targetWindow.HTMLElement) || globalThis.HTMLElement;
|
|
140
|
-
stage.querySelectorAll('.ofd-page-frame').forEach(frame => {
|
|
141
|
-
const page = frame.firstElementChild;
|
|
142
|
-
if (!HTMLElementCtor || !(page instanceof HTMLElementCtor)) {
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
page.style.position = 'absolute';
|
|
146
|
-
page.style.top = '0';
|
|
147
|
-
page.style.left = '50%';
|
|
148
|
-
page.style.transform = `translateX(-50%) scale(${zoom})`;
|
|
149
|
-
page.style.transformOrigin = 'top center';
|
|
150
|
-
page.style.marginLeft = '0';
|
|
151
|
-
page.style.marginRight = '0';
|
|
152
|
-
const pageWidth = page.offsetWidth;
|
|
153
|
-
const pageHeight = page.offsetHeight;
|
|
154
|
-
if (!pageWidth || !pageHeight) {
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
frame.style.width = `${Math.ceil(pageWidth * zoom)}px`;
|
|
158
|
-
frame.style.height = `${Math.ceil(pageHeight * zoom)}px`;
|
|
159
|
-
});
|
|
160
|
-
};
|
|
161
|
-
const setZoom = (nextZoom) => {
|
|
162
|
-
zoom = clampZoom(nextZoom);
|
|
163
|
-
syncPageZoom();
|
|
164
|
-
zoomEmitter.emit();
|
|
165
|
-
return getZoomState();
|
|
166
|
-
};
|
|
167
|
-
registerFileViewerZoomProvider(viewer, {
|
|
168
|
-
zoomIn: () => setZoom(zoom + OFD_ZOOM_STEP),
|
|
169
|
-
zoomOut: () => setZoom(zoom - OFD_ZOOM_STEP),
|
|
170
|
-
resetZoom: () => setZoom(1),
|
|
171
|
-
setZoom,
|
|
172
|
-
getState: getZoomState,
|
|
173
|
-
subscribe: zoomEmitter.subscribe,
|
|
174
|
-
});
|
|
175
|
-
const renderWithOfdJs = async (width) => {
|
|
176
|
-
const ofd = await loadOfdModule();
|
|
177
|
-
const ofdDocument = await getOfdDocument(ofd);
|
|
178
|
-
if (disposed) {
|
|
179
|
-
return [];
|
|
180
|
-
}
|
|
181
|
-
return Promise.resolve(ofd.renderOfd(width, ofdDocument));
|
|
182
|
-
};
|
|
183
|
-
const render = async (options = {}) => {
|
|
184
|
-
var _a;
|
|
185
|
-
if (disposed) {
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
const width = getRenderWidth();
|
|
189
|
-
if (!options.force && state === 'ready' && Math.abs(width - lastRenderedWidth) < 8) {
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
const version = ++renderVersion;
|
|
193
|
-
if (options.showLoading || state !== 'ready') {
|
|
194
|
-
state = 'loading';
|
|
195
|
-
clearStage();
|
|
196
|
-
syncState();
|
|
197
|
-
}
|
|
198
|
-
errorMessage = '';
|
|
199
|
-
try {
|
|
200
|
-
await waitForPaint(targetWindow);
|
|
201
|
-
const pages = await renderWithOfdJs(width);
|
|
202
|
-
if (disposed || version !== renderVersion) {
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
clearStage();
|
|
206
|
-
appendPages(documentRef, stage, pages);
|
|
207
|
-
lastRenderedWidth = width;
|
|
208
|
-
await waitForPaint(targetWindow);
|
|
209
|
-
syncPageZoom();
|
|
210
|
-
state = 'ready';
|
|
211
|
-
syncState();
|
|
212
|
-
zoomEmitter.emit();
|
|
213
|
-
(_a = context === null || context === void 0 ? void 0 : context.onProgressiveRender) === null || _a === void 0 ? void 0 : _a.call(context);
|
|
214
|
-
}
|
|
215
|
-
catch (reason) {
|
|
216
|
-
if (disposed || version !== renderVersion) {
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
console.error(reason);
|
|
220
|
-
state = 'error';
|
|
221
|
-
errorMessage = normalizeError(reason) || 'OFD 文件解析失败';
|
|
222
|
-
syncState();
|
|
223
|
-
}
|
|
224
|
-
};
|
|
225
|
-
const startResizeObserver = () => {
|
|
226
|
-
if (!(targetWindow === null || targetWindow === void 0 ? void 0 : targetWindow.ResizeObserver) || resizeObserver) {
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
resizeObserver = new targetWindow.ResizeObserver(() => {
|
|
230
|
-
targetWindow.clearTimeout(resizeTimer);
|
|
231
|
-
resizeTimer = targetWindow.setTimeout(() => {
|
|
232
|
-
void render({ showLoading: false });
|
|
233
|
-
}, 180);
|
|
234
|
-
});
|
|
235
|
-
resizeObserver.observe(viewer);
|
|
236
|
-
};
|
|
237
|
-
void render({ force: true, showLoading: true }).finally(() => {
|
|
238
|
-
if (!disposed) {
|
|
239
|
-
startResizeObserver();
|
|
240
|
-
}
|
|
241
|
-
});
|
|
242
|
-
return {
|
|
243
|
-
$el: viewer,
|
|
244
|
-
unmount() {
|
|
245
|
-
var _a;
|
|
246
|
-
disposed = true;
|
|
247
|
-
renderVersion += 1;
|
|
248
|
-
targetWindow === null || targetWindow === void 0 ? void 0 : targetWindow.clearTimeout(resizeTimer);
|
|
249
|
-
resizeObserver === null || resizeObserver === void 0 ? void 0 : resizeObserver.disconnect();
|
|
250
|
-
resizeObserver = null;
|
|
251
|
-
unregisterFileViewerZoomProvider(viewer);
|
|
252
|
-
clearStage();
|
|
253
|
-
(_a = context === null || context === void 0 ? void 0 : context.registerExportAdapter) === null || _a === void 0 ? void 0 : _a.call(context, null);
|
|
254
|
-
},
|
|
255
|
-
};
|
|
256
|
-
}
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import JSZip from 'jszip';
|
|
2
|
-
const openDocumentStyle = `
|
|
3
|
-
.odf-viewer{min-height:100%;padding:28px;overflow:auto;background:#dfe5eb;box-sizing:border-box}
|
|
4
|
-
.odf-shell{width:min(100%,980px);margin:0 auto}.odf-shell>header{margin-bottom:18px;padding:18px 22px;border-radius:8px;background:#fff;box-shadow:0 10px 26px rgba(15,23,42,.1);box-sizing:border-box}
|
|
5
|
-
.odf-shell>header span{color:#0f766e;font-size:12px;font-weight:800}.odf-shell>header h2{margin:6px 0 0;color:#132235;font-size:24px}
|
|
6
|
-
.odf-page{min-height:360px;margin:0 auto 18px;padding:42px 48px;border-radius:4px;background:#fff;box-shadow:0 16px 38px rgba(15,23,42,.12);color:#1f2937;box-sizing:border-box}
|
|
7
|
-
.odf-page h3{margin:0 0 20px;color:#334155;font-size:18px}.odf-page p{margin:0 0 12px;font-size:15px;line-height:1.85;white-space:pre-wrap}
|
|
8
|
-
.flyfish-rtf-viewer{min-height:100%;padding:28px;overflow:auto;background:#dfe5eb;color:#1f2937;box-sizing:border-box}
|
|
9
|
-
.flyfish-rtf-header{width:min(100%,900px);margin:0 auto 18px;padding:18px 22px;border-radius:8px;background:#fff;box-shadow:0 10px 26px rgba(15,23,42,.1);box-sizing:border-box}
|
|
10
|
-
.flyfish-rtf-header span{display:block;color:#0f766e;font-size:12px;font-weight:800}.flyfish-rtf-header strong{display:block;margin-top:6px;color:#132235;font-size:24px}
|
|
11
|
-
.flyfish-rtf-paper{width:min(100%,900px);min-height:980px;margin:0 auto;padding:54px 62px;background:#fff;box-shadow:0 16px 38px rgba(15,23,42,.12);line-height:1.75;box-sizing:border-box}.flyfish-rtf-paper p{margin:0 0 12px}
|
|
12
|
-
.file-viewer[data-viewer-theme='dark'] .odf-viewer,.file-viewer[data-viewer-theme='dark'] .flyfish-rtf-viewer{background:#111827}.file-viewer[data-viewer-theme='dark'] .odf-shell>header,.file-viewer[data-viewer-theme='dark'] .odf-page,.file-viewer[data-viewer-theme='dark'] .flyfish-rtf-header,.file-viewer[data-viewer-theme='dark'] .flyfish-rtf-paper{background:#f8fafc;color:#1f2937}
|
|
13
|
-
@media (prefers-color-scheme:dark){.file-viewer[data-viewer-theme='system'] .odf-viewer,.file-viewer[data-viewer-theme='system'] .flyfish-rtf-viewer{background:#111827}.file-viewer[data-viewer-theme='system'] .odf-shell>header,.file-viewer[data-viewer-theme='system'] .odf-page,.file-viewer[data-viewer-theme='system'] .flyfish-rtf-header,.file-viewer[data-viewer-theme='system'] .flyfish-rtf-paper{background:#f8fafc;color:#1f2937}}
|
|
14
|
-
@media (max-width:720px){.odf-viewer,.flyfish-rtf-viewer{padding:14px}.odf-page{padding:28px 24px}.flyfish-rtf-paper{padding:36px 28px}}
|
|
15
|
-
`;
|
|
16
|
-
const createStyle = () => {
|
|
17
|
-
const style = document.createElement('style');
|
|
18
|
-
style.textContent = openDocumentStyle;
|
|
19
|
-
return style;
|
|
20
|
-
};
|
|
21
|
-
const appendText = (parent, tag, text, className) => {
|
|
22
|
-
const element = document.createElement(tag);
|
|
23
|
-
if (className) {
|
|
24
|
-
element.className = className;
|
|
25
|
-
}
|
|
26
|
-
element.textContent = text;
|
|
27
|
-
parent.appendChild(element);
|
|
28
|
-
return element;
|
|
29
|
-
};
|
|
30
|
-
const nodeText = (node) => {
|
|
31
|
-
return (node.textContent || '').replace(/\s+/g, ' ').trim();
|
|
32
|
-
};
|
|
33
|
-
const parseOdf = async (buffer, type) => {
|
|
34
|
-
var _a;
|
|
35
|
-
const zip = await JSZip.loadAsync(buffer);
|
|
36
|
-
const content = await ((_a = zip.file('content.xml')) === null || _a === void 0 ? void 0 : _a.async('text'));
|
|
37
|
-
if (!content) {
|
|
38
|
-
throw new Error('ODF 文件缺少 content.xml');
|
|
39
|
-
}
|
|
40
|
-
const doc = new DOMParser().parseFromString(content, 'application/xml');
|
|
41
|
-
const parseError = doc.querySelector('parsererror');
|
|
42
|
-
if (parseError) {
|
|
43
|
-
throw new Error(parseError.textContent || 'ODF XML 解析失败');
|
|
44
|
-
}
|
|
45
|
-
if (type === 'odp') {
|
|
46
|
-
const slides = Array.from(doc.getElementsByTagName('draw:page'));
|
|
47
|
-
return slides.map((slide, index) => {
|
|
48
|
-
const blocks = Array.from(slide.getElementsByTagName('text:p'))
|
|
49
|
-
.map(nodeText)
|
|
50
|
-
.filter(Boolean);
|
|
51
|
-
return { title: `第 ${index + 1} 页`, blocks: blocks.length ? blocks : ['该页没有可提取文本'] };
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
const blocks = [
|
|
55
|
-
...Array.from(doc.getElementsByTagName('text:h')).map(nodeText),
|
|
56
|
-
...Array.from(doc.getElementsByTagName('text:p')).map(nodeText),
|
|
57
|
-
].filter(Boolean);
|
|
58
|
-
return [{ title: '正文', blocks: blocks.length ? blocks : ['没有提取到可读文本'] }];
|
|
59
|
-
};
|
|
60
|
-
const renderOdfPages = (type, title, pages) => {
|
|
61
|
-
const root = document.createElement('div');
|
|
62
|
-
root.className = 'odf-viewer';
|
|
63
|
-
const shell = document.createElement('section');
|
|
64
|
-
shell.className = 'odf-shell';
|
|
65
|
-
const header = document.createElement('header');
|
|
66
|
-
appendText(header, 'span', type.toUpperCase());
|
|
67
|
-
appendText(header, 'h2', title);
|
|
68
|
-
shell.appendChild(header);
|
|
69
|
-
pages.forEach(page => {
|
|
70
|
-
const article = document.createElement('article');
|
|
71
|
-
article.className = 'odf-page';
|
|
72
|
-
appendText(article, 'h3', page.title);
|
|
73
|
-
page.blocks.forEach(block => appendText(article, 'p', block));
|
|
74
|
-
shell.appendChild(article);
|
|
75
|
-
});
|
|
76
|
-
root.appendChild(shell);
|
|
77
|
-
return root;
|
|
78
|
-
};
|
|
79
|
-
const resolveRtfJs = async () => {
|
|
80
|
-
const rtfModule = await import('rtf.js/dist/RTFJS.bundle.js');
|
|
81
|
-
return rtfModule.RTFJS || rtfModule.default || rtfModule;
|
|
82
|
-
};
|
|
83
|
-
const renderRtf = async (buffer, target) => {
|
|
84
|
-
var _a, _b;
|
|
85
|
-
const RTFJS = await resolveRtfJs();
|
|
86
|
-
(_a = RTFJS.loggingEnabled) === null || _a === void 0 ? void 0 : _a.call(RTFJS, false);
|
|
87
|
-
const doc = new RTFJS.Document(buffer, {});
|
|
88
|
-
const meta = ((_b = doc.metadata) === null || _b === void 0 ? void 0 : _b.call(doc)) || {};
|
|
89
|
-
const elements = await doc.render();
|
|
90
|
-
const stage = document.createElement('div');
|
|
91
|
-
stage.className = 'flyfish-rtf-viewer';
|
|
92
|
-
const header = document.createElement('div');
|
|
93
|
-
header.className = 'flyfish-rtf-header';
|
|
94
|
-
appendText(header, 'span', 'RTF');
|
|
95
|
-
appendText(header, 'strong', meta.title || 'RTF 文档预览');
|
|
96
|
-
const paper = document.createElement('article');
|
|
97
|
-
paper.className = 'flyfish-rtf-paper';
|
|
98
|
-
elements.forEach((element) => paper.appendChild(element));
|
|
99
|
-
stage.append(header, paper);
|
|
100
|
-
target.replaceChildren(createStyle(), stage);
|
|
101
|
-
return {
|
|
102
|
-
$el: target,
|
|
103
|
-
unmount() {
|
|
104
|
-
target.replaceChildren();
|
|
105
|
-
},
|
|
106
|
-
};
|
|
107
|
-
};
|
|
108
|
-
export default async function renderOpenDocument(buffer, target, type) {
|
|
109
|
-
const normalizedType = (type || 'odt').toLowerCase();
|
|
110
|
-
if (normalizedType === 'rtf') {
|
|
111
|
-
return renderRtf(buffer, target);
|
|
112
|
-
}
|
|
113
|
-
const pages = await parseOdf(buffer, normalizedType);
|
|
114
|
-
const title = normalizedType === 'odp' ? 'OpenDocument 演示文稿预览' : 'OpenDocument 文档预览';
|
|
115
|
-
target.replaceChildren(createStyle(), renderOdfPages(normalizedType, title, pages));
|
|
116
|
-
return {
|
|
117
|
-
$el: target,
|
|
118
|
-
unmount() {
|
|
119
|
-
target.replaceChildren();
|
|
120
|
-
},
|
|
121
|
-
};
|
|
122
|
-
}
|
package/dist/renderers/pdf.d.ts
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { FileRenderContext, FileViewerRenderedInstance } from '../contracts/types';
|
|
2
|
-
export declare const DEFAULT_FILE_VIEWER_PDF_WORKER_URL = "vendor/pdf/pdf.worker.mjs";
|
|
3
|
-
export default function renderPdf(buffer: ArrayBuffer, target: HTMLDivElement, context?: FileRenderContext): Promise<FileViewerRenderedInstance>;
|