@file-viewer/core 2.0.8 → 2.0.10
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 +1 -1
- package/README.md +1 -1
- package/dist/contracts/types.d.ts +32 -0
- package/dist/headless.d.ts +1 -1
- package/dist/headless.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/platform/assets.d.ts +21 -5
- package/dist/platform/assets.js +129 -9
- package/dist/registry/formats.d.ts +1 -1
- package/dist/renderers/drawing.d.ts +1 -1
- package/dist/renderers/drawing.js +89 -15
- package/dist/renderers/pdf.d.ts +1 -1
- package/dist/renderers/pdf.js +163 -15
- package/dist/renderers/typst.js +38 -54
- package/dist/renderers/wordDocx.js +132 -201
- package/dist/renderers/wordDocx.worker.js +2 -2
- package/package.json +8 -10
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { resolveFileViewerDocxWorkerUrl } from '../platform/assets.js';
|
|
1
|
+
import { resolveFileViewerDocxWorkerJsZipUrl, resolveFileViewerDocxWorkerUrl, } from '../platform/assets.js';
|
|
2
2
|
import { applyPrintPageSize, buildPrintPageStyle, formatCssPixels, getElementPrintPageSize } from '../output/printLayout.js';
|
|
3
3
|
import { createFileViewerZoomChangeEmitter as createZoomChangeEmitter, } from '../features/document/zoom.js';
|
|
4
4
|
import { registerFileViewerZoomProvider, unregisterFileViewerZoomProvider } from '../features/document/dom/index.js';
|
|
@@ -7,18 +7,18 @@ const DOCX_DEFAULT_PAGE_SIZE = {
|
|
|
7
7
|
height: 1123
|
|
8
8
|
};
|
|
9
9
|
const DOCX_PROGRESSIVE_BATCH_SIZE = 2;
|
|
10
|
-
const DOCX_WORKER_TIMEOUT =
|
|
10
|
+
const DOCX_WORKER_TIMEOUT = 120000;
|
|
11
11
|
const DOCX_MIN_SCALE = 0.24;
|
|
12
12
|
const DOCX_MAX_SCALE = 3;
|
|
13
13
|
const DOCX_ZOOM_STEP = 0.15;
|
|
14
14
|
const DOCX_EMU_PER_CSS_PIXEL = 9525;
|
|
15
|
-
|
|
15
|
+
const ZIP_SIGNATURE_PK = 0x504b;
|
|
16
16
|
const loadLibrary = (() => {
|
|
17
17
|
const loader = {
|
|
18
18
|
module: null,
|
|
19
19
|
async load() {
|
|
20
20
|
if (!this.module) {
|
|
21
|
-
this.module = import('docx
|
|
21
|
+
this.module = import('@file-viewer/docx');
|
|
22
22
|
}
|
|
23
23
|
return this.module;
|
|
24
24
|
}
|
|
@@ -27,11 +27,58 @@ const loadLibrary = (() => {
|
|
|
27
27
|
return await loader.load();
|
|
28
28
|
};
|
|
29
29
|
})();
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
/**
|
|
31
|
+
* DOCX / DOCM / DOTX / DOTM are OOXML packages, so a valid file must start
|
|
32
|
+
* with a ZIP signature. This catches common enterprise download failures where
|
|
33
|
+
* an object-storage XML error page is saved with a `.docx` extension.
|
|
34
|
+
*/
|
|
35
|
+
const assertValidDocxPackage = (buffer) => {
|
|
36
|
+
const signature = buffer.byteLength >= 4 ? new DataView(buffer).getUint16(0, false) : 0;
|
|
37
|
+
if (signature === ZIP_SIGNATURE_PK) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
throw new Error('文件不是有效的 DOCX/OOXML 压缩包,可能下载不完整或被服务端错误内容替换,请重新上传或检查文件源。');
|
|
41
|
+
};
|
|
42
|
+
const createDocxOptions = (target, context, notifyProgressiveRender) => {
|
|
43
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
44
|
+
const docxOptions = (_a = context === null || context === void 0 ? void 0 : context.options) === null || _a === void 0 ? void 0 : _a.docx;
|
|
45
|
+
const documentBaseUrl = target.ownerDocument.URL || undefined;
|
|
46
|
+
const useWorker = (docxOptions === null || docxOptions === void 0 ? void 0 : docxOptions.worker) !== false;
|
|
47
|
+
const usePagedLayout = (docxOptions === null || docxOptions === void 0 ? void 0 : docxOptions.visualPagination) === true;
|
|
48
|
+
const progress = (event) => {
|
|
49
|
+
if (event.phase === 'render' || event.phase === 'layout' || event.phase === 'done') {
|
|
50
|
+
notifyProgressiveRender();
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
return {
|
|
54
|
+
// Word 会写入 autoSpaceDN/autoSpaceDE 等兼容标签;生产预览保持静默,避免 DOCX 调试告警刷屏。
|
|
55
|
+
debug: false,
|
|
56
|
+
experimental: false,
|
|
57
|
+
useWorker,
|
|
58
|
+
workerUrl: useWorker
|
|
59
|
+
? resolveFileViewerDocxWorkerUrl(docxOptions, documentBaseUrl)
|
|
60
|
+
: undefined,
|
|
61
|
+
workerJsZipUrl: useWorker
|
|
62
|
+
? resolveFileViewerDocxWorkerJsZipUrl(docxOptions, documentBaseUrl)
|
|
63
|
+
: undefined,
|
|
64
|
+
workerFallback: true,
|
|
65
|
+
workerTimeout: (_b = docxOptions === null || docxOptions === void 0 ? void 0 : docxOptions.workerTimeout) !== null && _b !== void 0 ? _b : DOCX_WORKER_TIMEOUT,
|
|
66
|
+
renderPageBatchSize: (_c = docxOptions === null || docxOptions === void 0 ? void 0 : docxOptions.renderPageBatchSize) !== null && _c !== void 0 ? _c : ((docxOptions === null || docxOptions === void 0 ? void 0 : docxOptions.progressive) === false ? Number.MAX_SAFE_INTEGER : DOCX_PROGRESSIVE_BATCH_SIZE),
|
|
67
|
+
renderYieldEveryMs: (_d = docxOptions === null || docxOptions === void 0 ? void 0 : docxOptions.renderYieldEveryMs) !== null && _d !== void 0 ? _d : 16,
|
|
68
|
+
strictWordCompatibility: (_e = docxOptions === null || docxOptions === void 0 ? void 0 : docxOptions.strictWordCompatibility) !== null && _e !== void 0 ? _e : true,
|
|
69
|
+
paginationTolerance: (_f = docxOptions === null || docxOptions === void 0 ? void 0 : docxOptions.paginationTolerance) !== null && _f !== void 0 ? _f : 2,
|
|
70
|
+
breakPages: usePagedLayout,
|
|
71
|
+
maxDynamicPaginationPasses: usePagedLayout
|
|
72
|
+
? (_g = docxOptions === null || docxOptions === void 0 ? void 0 : docxOptions.maxDynamicPaginationPasses) !== null && _g !== void 0 ? _g : 1000
|
|
73
|
+
: 0,
|
|
74
|
+
awaitLayout: (_h = docxOptions === null || docxOptions === void 0 ? void 0 : docxOptions.awaitLayout) !== null && _h !== void 0 ? _h : usePagedLayout,
|
|
75
|
+
preserveComplexFieldResults: (_j = docxOptions === null || docxOptions === void 0 ? void 0 : docxOptions.preserveComplexFieldResults) !== null && _j !== void 0 ? _j : true,
|
|
76
|
+
updatePageReferences: (_k = docxOptions === null || docxOptions === void 0 ? void 0 : docxOptions.updatePageReferences) !== null && _k !== void 0 ? _k : false,
|
|
77
|
+
hideWebHiddenContent: (_l = docxOptions === null || docxOptions === void 0 ? void 0 : docxOptions.hideWebHiddenContent) !== null && _l !== void 0 ? _l : false,
|
|
78
|
+
ignoreLastRenderedPageBreak: (_m = docxOptions === null || docxOptions === void 0 ? void 0 : docxOptions.ignoreLastRenderedPageBreak) !== null && _m !== void 0 ? _m : !usePagedLayout,
|
|
79
|
+
progress
|
|
80
|
+
};
|
|
81
|
+
};
|
|
35
82
|
const getTargetWindow = (target) => {
|
|
36
83
|
return target.ownerDocument.defaultView;
|
|
37
84
|
};
|
|
@@ -40,171 +87,10 @@ const isTargetHTMLElement = (value, target) => {
|
|
|
40
87
|
const HTMLElementCtor = (_a = getTargetWindow(target)) === null || _a === void 0 ? void 0 : _a.HTMLElement;
|
|
41
88
|
return HTMLElementCtor ? value instanceof HTMLElementCtor : value instanceof HTMLElement;
|
|
42
89
|
};
|
|
43
|
-
const shouldUseDocxWorker = (target, context) => {
|
|
44
|
-
var _a, _b;
|
|
45
|
-
const view = getTargetWindow(target);
|
|
46
|
-
return ((_b = (_a = context === null || context === void 0 ? void 0 : context.options) === null || _a === void 0 ? void 0 : _a.docx) === null || _b === void 0 ? void 0 : _b.worker) === true && typeof (view === null || view === void 0 ? void 0 : view.Worker) === 'function';
|
|
47
|
-
};
|
|
48
|
-
const shouldMountDocxProgressively = (context) => {
|
|
49
|
-
var _a, _b;
|
|
50
|
-
return ((_b = (_a = context === null || context === void 0 ? void 0 : context.options) === null || _a === void 0 ? void 0 : _a.docx) === null || _b === void 0 ? void 0 : _b.progressive) === true;
|
|
51
|
-
};
|
|
52
90
|
const shouldPaginateOversizedDocxSections = (context) => {
|
|
53
91
|
var _a, _b;
|
|
54
92
|
return ((_b = (_a = context === null || context === void 0 ? void 0 : context.options) === null || _a === void 0 ? void 0 : _a.docx) === null || _b === void 0 ? void 0 : _b.visualPagination) === true;
|
|
55
93
|
};
|
|
56
|
-
const waitDocxMountFrame = (target) => {
|
|
57
|
-
return new Promise(resolve => {
|
|
58
|
-
const view = getTargetWindow(target);
|
|
59
|
-
if (!view || typeof view.requestAnimationFrame !== 'function') {
|
|
60
|
-
globalThis.setTimeout(resolve, 0);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
view.requestAnimationFrame(() => resolve());
|
|
64
|
-
});
|
|
65
|
-
};
|
|
66
|
-
async function mountDocxPreviewHtml(html, target, context) {
|
|
67
|
-
var _a, _b, _c;
|
|
68
|
-
if (!shouldMountDocxProgressively(context)) {
|
|
69
|
-
target.innerHTML = html;
|
|
70
|
-
(_a = context === null || context === void 0 ? void 0 : context.onProgressiveRender) === null || _a === void 0 ? void 0 : _a.call(context);
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
const template = target.ownerDocument.createElement('template');
|
|
74
|
-
template.innerHTML = html;
|
|
75
|
-
const sourceWrapper = template.content.querySelector('.docx-wrapper');
|
|
76
|
-
if (!sourceWrapper) {
|
|
77
|
-
target.innerHTML = html;
|
|
78
|
-
(_b = context === null || context === void 0 ? void 0 : context.onProgressiveRender) === null || _b === void 0 ? void 0 : _b.call(context);
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
const pages = Array.from(sourceWrapper.children);
|
|
82
|
-
const liveWrapper = sourceWrapper.cloneNode(false);
|
|
83
|
-
let hasNotifiedFirstPaint = false;
|
|
84
|
-
target.innerHTML = '';
|
|
85
|
-
Array.from(template.content.childNodes).forEach(node => {
|
|
86
|
-
if (node === sourceWrapper) {
|
|
87
|
-
target.appendChild(liveWrapper);
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
target.appendChild(node);
|
|
91
|
-
});
|
|
92
|
-
for (let index = 0; index < pages.length; index += DOCX_PROGRESSIVE_BATCH_SIZE) {
|
|
93
|
-
pages.slice(index, index + DOCX_PROGRESSIVE_BATCH_SIZE).forEach(page => {
|
|
94
|
-
liveWrapper.appendChild(page);
|
|
95
|
-
});
|
|
96
|
-
if (!hasNotifiedFirstPaint) {
|
|
97
|
-
hasNotifiedFirstPaint = true;
|
|
98
|
-
(_c = context === null || context === void 0 ? void 0 : context.onProgressiveRender) === null || _c === void 0 ? void 0 : _c.call(context);
|
|
99
|
-
}
|
|
100
|
-
if (index + DOCX_PROGRESSIVE_BATCH_SIZE < pages.length) {
|
|
101
|
-
await waitDocxMountFrame(target);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
function createDocxWorker(target, context) {
|
|
106
|
-
var _a;
|
|
107
|
-
const view = getTargetWindow(target);
|
|
108
|
-
if (!(view === null || view === void 0 ? void 0 : view.Worker)) {
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
const workerUrl = resolveFileViewerDocxWorkerUrl((_a = context === null || context === void 0 ? void 0 : context.options) === null || _a === void 0 ? void 0 : _a.docx, target.ownerDocument.URL || undefined);
|
|
112
|
-
try {
|
|
113
|
-
return new view.Worker(workerUrl, { type: 'module' });
|
|
114
|
-
}
|
|
115
|
-
catch (moduleWorkerError) {
|
|
116
|
-
try {
|
|
117
|
-
return new view.Worker(workerUrl);
|
|
118
|
-
}
|
|
119
|
-
catch (classicWorkerError) {
|
|
120
|
-
console.warn('[file-viewer] DOCX Worker 无法创建,回退到 docx-preview 主线程渲染。', classicWorkerError || moduleWorkerError);
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
async function renderDocxWithWorker(buffer, target, options, context) {
|
|
126
|
-
var _a, _b, _c;
|
|
127
|
-
if (!shouldUseDocxWorker(target, context)) {
|
|
128
|
-
return false;
|
|
129
|
-
}
|
|
130
|
-
const worker = createDocxWorker(target, context);
|
|
131
|
-
if (!worker) {
|
|
132
|
-
return false;
|
|
133
|
-
}
|
|
134
|
-
const view = getTargetWindow(target);
|
|
135
|
-
const id = ++docxWorkerRequestId;
|
|
136
|
-
const timeout = (_c = (_b = (_a = context === null || context === void 0 ? void 0 : context.options) === null || _a === void 0 ? void 0 : _a.docx) === null || _b === void 0 ? void 0 : _b.workerTimeout) !== null && _c !== void 0 ? _c : DOCX_WORKER_TIMEOUT;
|
|
137
|
-
return await new Promise(resolve => {
|
|
138
|
-
let settled = false;
|
|
139
|
-
let timeoutId;
|
|
140
|
-
const cleanup = () => {
|
|
141
|
-
if (timeoutId !== undefined) {
|
|
142
|
-
view === null || view === void 0 ? void 0 : view.clearTimeout(timeoutId);
|
|
143
|
-
}
|
|
144
|
-
worker.removeEventListener('message', handleMessage);
|
|
145
|
-
worker.removeEventListener('error', handleError);
|
|
146
|
-
worker.removeEventListener('messageerror', handleMessageError);
|
|
147
|
-
worker.terminate();
|
|
148
|
-
};
|
|
149
|
-
const fallback = (reason) => {
|
|
150
|
-
if (settled) {
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
settled = true;
|
|
154
|
-
cleanup();
|
|
155
|
-
console.warn('[file-viewer] DOCX Worker 渲染失败,回退到 docx-preview 主线程渲染。', reason);
|
|
156
|
-
resolve(false);
|
|
157
|
-
};
|
|
158
|
-
const handleMessage = (event) => {
|
|
159
|
-
var _a;
|
|
160
|
-
if (((_a = event.data) === null || _a === void 0 ? void 0 : _a.id) !== id) {
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
if (settled) {
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
settled = true;
|
|
167
|
-
cleanup();
|
|
168
|
-
if (event.data.ok) {
|
|
169
|
-
void mountDocxPreviewHtml(event.data.html, target, context)
|
|
170
|
-
.then(() => resolve(true))
|
|
171
|
-
.catch(reason => {
|
|
172
|
-
console.warn('[file-viewer] DOCX 渐进挂载失败,回退到 docx-preview 主线程渲染。', reason);
|
|
173
|
-
resolve(false);
|
|
174
|
-
});
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
console.warn('[file-viewer] DOCX Worker 渲染失败,回退到 docx-preview 主线程渲染。', event.data.message);
|
|
178
|
-
resolve(false);
|
|
179
|
-
};
|
|
180
|
-
const handleError = (event) => {
|
|
181
|
-
fallback(event.error || event.message);
|
|
182
|
-
};
|
|
183
|
-
const handleMessageError = () => {
|
|
184
|
-
fallback('DOCX Worker 消息无法结构化传输');
|
|
185
|
-
};
|
|
186
|
-
worker.addEventListener('message', handleMessage);
|
|
187
|
-
worker.addEventListener('error', handleError);
|
|
188
|
-
worker.addEventListener('messageerror', handleMessageError);
|
|
189
|
-
if (Number.isFinite(timeout) && timeout > 0) {
|
|
190
|
-
timeoutId = view === null || view === void 0 ? void 0 : view.setTimeout(() => {
|
|
191
|
-
fallback(`DOCX Worker 超过 ${timeout}ms 未返回结果`);
|
|
192
|
-
}, timeout);
|
|
193
|
-
}
|
|
194
|
-
const workerBuffer = buffer.slice(0);
|
|
195
|
-
// Worker 内输出 HTML,图片和字体使用 data URL,避免 Worker 生命周期结束后 Blob URL 失效。
|
|
196
|
-
worker.postMessage({
|
|
197
|
-
id,
|
|
198
|
-
buffer: workerBuffer,
|
|
199
|
-
options: {
|
|
200
|
-
...options,
|
|
201
|
-
// docx-preview 的 experimental tab stop 需要真实布局 API,Worker 内无法可靠计算。
|
|
202
|
-
experimental: false,
|
|
203
|
-
useBase64URL: true
|
|
204
|
-
}
|
|
205
|
-
}, [workerBuffer]);
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
94
|
const DOCX_RESPONSIVE_CSS = `
|
|
209
95
|
.docx-fit-viewer {
|
|
210
96
|
box-sizing: border-box;
|
|
@@ -226,7 +112,15 @@ const DOCX_RESPONSIVE_CSS = `
|
|
|
226
112
|
margin: 0 auto 24px;
|
|
227
113
|
overflow: visible;
|
|
228
114
|
}
|
|
229
|
-
.docx-fit-viewer .docx-
|
|
115
|
+
.docx-fit-viewer .docx-flow-frame {
|
|
116
|
+
position: relative;
|
|
117
|
+
width: 100%;
|
|
118
|
+
min-width: 0;
|
|
119
|
+
margin: 0 auto 28px;
|
|
120
|
+
overflow: visible;
|
|
121
|
+
}
|
|
122
|
+
.docx-fit-viewer .docx-page-frame > section.docx,
|
|
123
|
+
.docx-fit-viewer .docx-flow-frame > section.docx {
|
|
230
124
|
position: absolute;
|
|
231
125
|
top: 0;
|
|
232
126
|
left: 50%;
|
|
@@ -238,7 +132,13 @@ const DOCX_RESPONSIVE_CSS = `
|
|
|
238
132
|
overflow: hidden;
|
|
239
133
|
transform-origin: top center;
|
|
240
134
|
}
|
|
241
|
-
.docx-fit-viewer .docx-
|
|
135
|
+
.docx-fit-viewer .docx-flow-frame > section.docx {
|
|
136
|
+
height: auto !important;
|
|
137
|
+
min-height: 0 !important;
|
|
138
|
+
overflow: visible !important;
|
|
139
|
+
}
|
|
140
|
+
.docx-fit-viewer .docx-page-frame > section.docx > article,
|
|
141
|
+
.docx-fit-viewer .docx-flow-frame > section.docx > article {
|
|
242
142
|
position: relative;
|
|
243
143
|
z-index: 1;
|
|
244
144
|
}
|
|
@@ -787,7 +687,7 @@ async function enhanceDocxFallbacks(buffer, target) {
|
|
|
787
687
|
}
|
|
788
688
|
}
|
|
789
689
|
catch (error) {
|
|
790
|
-
console.warn('[file-viewer] DOCX 兼容增强解析失败,已保留 docx
|
|
690
|
+
console.warn('[file-viewer] DOCX 兼容增强解析失败,已保留 @file-viewer/docx 原始渲染结果。', error);
|
|
791
691
|
}
|
|
792
692
|
}
|
|
793
693
|
function installResponsiveStyle(target) {
|
|
@@ -836,7 +736,7 @@ function paginateOversizedSections(target) {
|
|
|
836
736
|
if (!pageHeight || originalNodes.length < 2 || child.scrollHeight <= pageHeight * 1.15) {
|
|
837
737
|
return;
|
|
838
738
|
}
|
|
839
|
-
//
|
|
739
|
+
// 新 DOCX 引擎会优先使用 Word 保存的分页;这里保留预览层兜底分页,覆盖缺少分页标记的旧文件。
|
|
840
740
|
let current = clonePageShell(child, article, pageHeight);
|
|
841
741
|
child.before(current.page);
|
|
842
742
|
originalNodes.forEach(node => {
|
|
@@ -852,7 +752,7 @@ function paginateOversizedSections(target) {
|
|
|
852
752
|
child.remove();
|
|
853
753
|
});
|
|
854
754
|
}
|
|
855
|
-
function
|
|
755
|
+
function wrapDocxSections(target, pagedLayout) {
|
|
856
756
|
const wrapper = target.querySelector('.docx-wrapper');
|
|
857
757
|
if (!wrapper) {
|
|
858
758
|
return [];
|
|
@@ -862,7 +762,7 @@ function wrapDocxPages(target) {
|
|
|
862
762
|
return [];
|
|
863
763
|
}
|
|
864
764
|
const frame = target.ownerDocument.createElement('div');
|
|
865
|
-
frame.className = 'docx-page-frame';
|
|
765
|
+
frame.className = pagedLayout ? 'docx-page-frame' : 'docx-flow-frame';
|
|
866
766
|
child.before(frame);
|
|
867
767
|
frame.appendChild(child);
|
|
868
768
|
return [frame];
|
|
@@ -871,10 +771,11 @@ function wrapDocxPages(target) {
|
|
|
871
771
|
function makeDocxResponsive(target, context) {
|
|
872
772
|
target.classList.add('docx-fit-viewer');
|
|
873
773
|
const style = installResponsiveStyle(target);
|
|
874
|
-
|
|
774
|
+
const pagedLayout = shouldPaginateOversizedDocxSections(context);
|
|
775
|
+
if (pagedLayout) {
|
|
875
776
|
paginateOversizedSections(target);
|
|
876
777
|
}
|
|
877
|
-
const frames =
|
|
778
|
+
const frames = wrapDocxSections(target, pagedLayout);
|
|
878
779
|
const view = getTargetWindow(target);
|
|
879
780
|
const ResizeObserverCtor = view === null || view === void 0 ? void 0 : view.ResizeObserver;
|
|
880
781
|
let resizeFrame = 0;
|
|
@@ -899,8 +800,10 @@ function makeDocxResponsive(target, context) {
|
|
|
899
800
|
}
|
|
900
801
|
page.style.transform = 'translateX(-50%)';
|
|
901
802
|
const pageWidth = page.offsetWidth;
|
|
902
|
-
const
|
|
903
|
-
|
|
803
|
+
const contentHeight = pagedLayout
|
|
804
|
+
? page.offsetHeight
|
|
805
|
+
: Math.max(page.scrollHeight, page.offsetHeight);
|
|
806
|
+
if (!pageWidth || !contentHeight) {
|
|
904
807
|
return;
|
|
905
808
|
}
|
|
906
809
|
const availableWidth = Math.max(target.clientWidth - 28, 120);
|
|
@@ -911,7 +814,7 @@ function makeDocxResponsive(target, context) {
|
|
|
911
814
|
page.style.transform = `translateX(-50%) scale(${scale})`;
|
|
912
815
|
frame.style.width = `${Math.ceil(Math.max(pageWidth * scale, target.clientWidth - 28, 120))}px`;
|
|
913
816
|
frame.style.maxWidth = 'none';
|
|
914
|
-
frame.style.height = `${Math.ceil(
|
|
817
|
+
frame.style.height = `${Math.ceil(contentHeight * scale)}px`;
|
|
915
818
|
});
|
|
916
819
|
currentScale = firstScale;
|
|
917
820
|
zoomEmitter.emit();
|
|
@@ -963,14 +866,28 @@ function getDocxPageElement(frame) {
|
|
|
963
866
|
const HTMLElementCtor = (_a = frame.ownerDocument.defaultView) === null || _a === void 0 ? void 0 : _a.HTMLElement;
|
|
964
867
|
return HTMLElementCtor && page instanceof HTMLElementCtor ? page : null;
|
|
965
868
|
}
|
|
869
|
+
function isDocxFlowFrame(frame) {
|
|
870
|
+
return !!(frame === null || frame === void 0 ? void 0 : frame.classList.contains('docx-flow-frame'));
|
|
871
|
+
}
|
|
966
872
|
function getDocxFramePrintSize(frame) {
|
|
967
873
|
const page = frame ? getDocxPageElement(frame) : null;
|
|
968
|
-
|
|
874
|
+
if (!page) {
|
|
875
|
+
return DOCX_DEFAULT_PAGE_SIZE;
|
|
876
|
+
}
|
|
877
|
+
const size = getElementPrintPageSize(page, DOCX_DEFAULT_PAGE_SIZE);
|
|
878
|
+
if (!isDocxFlowFrame(frame)) {
|
|
879
|
+
return size;
|
|
880
|
+
}
|
|
881
|
+
return {
|
|
882
|
+
width: size.width,
|
|
883
|
+
height: Math.max(page.scrollHeight || 0, page.offsetHeight || 0, DOCX_DEFAULT_PAGE_SIZE.height)
|
|
884
|
+
};
|
|
969
885
|
}
|
|
970
886
|
function normalizeDocxPageForPrint(frame, pageSize) {
|
|
887
|
+
const flowLayout = isDocxFlowFrame(frame);
|
|
971
888
|
const pageWidth = formatCssPixels(pageSize.width);
|
|
972
889
|
const pageHeight = formatCssPixels(pageSize.height);
|
|
973
|
-
applyPrintPageSize(frame, pageSize);
|
|
890
|
+
applyPrintPageSize(frame, pageSize, { heightMode: flowLayout ? 'min' : 'fixed' });
|
|
974
891
|
frame.style.margin = '0 auto 18px';
|
|
975
892
|
const page = getDocxPageElement(frame);
|
|
976
893
|
if (!page) {
|
|
@@ -981,25 +898,31 @@ function normalizeDocxPageForPrint(frame, pageSize) {
|
|
|
981
898
|
page.style.left = 'auto';
|
|
982
899
|
page.style.width = pageWidth;
|
|
983
900
|
page.style.maxWidth = 'none';
|
|
984
|
-
page.style.minHeight = pageHeight;
|
|
985
|
-
page.style.height = pageHeight;
|
|
901
|
+
page.style.minHeight = flowLayout ? '0' : pageHeight;
|
|
902
|
+
page.style.height = flowLayout ? 'auto' : pageHeight;
|
|
986
903
|
page.style.margin = '0 auto';
|
|
987
904
|
page.style.transform = 'none';
|
|
988
905
|
page.style.transformOrigin = 'top left';
|
|
989
|
-
page.style.overflow = 'hidden';
|
|
906
|
+
page.style.overflow = flowLayout ? 'visible' : 'hidden';
|
|
990
907
|
page.style.boxShadow = 'none';
|
|
991
908
|
}
|
|
992
909
|
function buildDocxPrintStyle(target) {
|
|
993
|
-
const firstFrame = target.querySelector('.docx-page-frame');
|
|
910
|
+
const firstFrame = target.querySelector('.docx-page-frame, .docx-flow-frame');
|
|
994
911
|
const pageSize = getDocxFramePrintSize(firstFrame || undefined);
|
|
912
|
+
const selector = (firstFrame === null || firstFrame === void 0 ? void 0 : firstFrame.classList.contains('docx-flow-frame'))
|
|
913
|
+
? '.viewer-export-content .docx-flow-frame'
|
|
914
|
+
: '.viewer-export-content .docx-page-frame';
|
|
995
915
|
return buildPrintPageStyle({
|
|
996
|
-
selector
|
|
916
|
+
selector,
|
|
997
917
|
width: pageSize.width,
|
|
998
|
-
height:
|
|
918
|
+
height: (firstFrame === null || firstFrame === void 0 ? void 0 : firstFrame.classList.contains('docx-flow-frame'))
|
|
919
|
+
? DOCX_DEFAULT_PAGE_SIZE.height
|
|
920
|
+
: pageSize.height,
|
|
921
|
+
heightMode: (firstFrame === null || firstFrame === void 0 ? void 0 : firstFrame.classList.contains('docx-flow-frame')) ? 'min' : 'fixed'
|
|
999
922
|
});
|
|
1000
923
|
}
|
|
1001
924
|
function prepareDocxCloneForExport(target) {
|
|
1002
|
-
const liveFrames = Array.from(target.querySelectorAll('.docx-page-frame'));
|
|
925
|
+
const liveFrames = Array.from(target.querySelectorAll('.docx-page-frame, .docx-flow-frame'));
|
|
1003
926
|
const clone = target.cloneNode(true);
|
|
1004
927
|
const printDocument = target.ownerDocument.createElement('div');
|
|
1005
928
|
printDocument.className = 'docx-print-document';
|
|
@@ -1007,7 +930,7 @@ function prepareDocxCloneForExport(target) {
|
|
|
1007
930
|
.filter(style => { var _a; return !((_a = style.textContent) === null || _a === void 0 ? void 0 : _a.includes('.docx-fit-viewer')); })
|
|
1008
931
|
.map(style => style.outerHTML)
|
|
1009
932
|
.join('');
|
|
1010
|
-
clone.querySelectorAll('.docx-page-frame').forEach((frame, index) => {
|
|
933
|
+
clone.querySelectorAll('.docx-page-frame, .docx-flow-frame').forEach((frame, index) => {
|
|
1011
934
|
normalizeDocxPageForPrint(frame, getDocxFramePrintSize(liveFrames[index]));
|
|
1012
935
|
printDocument.appendChild(frame.cloneNode(true));
|
|
1013
936
|
});
|
|
@@ -1018,16 +941,24 @@ function prepareDocxCloneForExport(target) {
|
|
|
1018
941
|
*/
|
|
1019
942
|
export default async function (buffer, target, context) {
|
|
1020
943
|
var _a;
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
}
|
|
944
|
+
assertValidDocxPackage(buffer);
|
|
945
|
+
let hasNotifiedProgressiveRender = false;
|
|
946
|
+
const notifyProgressiveRender = () => {
|
|
947
|
+
var _a;
|
|
948
|
+
if (hasNotifiedProgressiveRender) {
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
951
|
+
hasNotifiedProgressiveRender = true;
|
|
952
|
+
(_a = context === null || context === void 0 ? void 0 : context.onProgressiveRender) === null || _a === void 0 ? void 0 : _a.call(context);
|
|
953
|
+
};
|
|
954
|
+
const docxOptions = createDocxOptions(target, context, notifyProgressiveRender);
|
|
955
|
+
const { defaultOptions, renderAsync } = await loadLibrary();
|
|
956
|
+
target.dataset.docxWorker = docxOptions.useWorker ? 'self' : 'false';
|
|
957
|
+
await renderAsync(buffer, target, undefined, {
|
|
958
|
+
...defaultOptions,
|
|
959
|
+
...docxOptions
|
|
960
|
+
});
|
|
961
|
+
notifyProgressiveRender();
|
|
1031
962
|
await enhanceDocxFallbacks(buffer, target);
|
|
1032
963
|
const disposeResponsive = makeDocxResponsive(target, context);
|
|
1033
964
|
(_a = context === null || context === void 0 ? void 0 : context.registerExportAdapter) === null || _a === void 0 ? void 0 : _a.call(context, {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { renderAsync } from 'docx
|
|
1
|
+
import { renderAsync } from '@file-viewer/docx';
|
|
2
2
|
import { DOMParser, XMLSerializer } from '@xmldom/xmldom';
|
|
3
3
|
import { parseHTML } from 'linkedom';
|
|
4
4
|
const ctx = self;
|
|
@@ -56,7 +56,7 @@ const installDomRuntime = () => {
|
|
|
56
56
|
const runtime = globalThis;
|
|
57
57
|
runtime.window = window;
|
|
58
58
|
runtime.document = window.document;
|
|
59
|
-
// docx
|
|
59
|
+
// @file-viewer/docx expects browser XML namespace behavior where `<w:body>` has
|
|
60
60
|
// localName === "body"; linkedom keeps prefixes, so XML parsing uses xmldom.
|
|
61
61
|
runtime.DOMParser = BrowserLikeXmlDomParser;
|
|
62
62
|
runtime.Node = window.Node;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@file-viewer/core",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.10",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Framework-neutral TypeScript core for Flyfish File Viewer",
|
|
@@ -58,20 +58,20 @@
|
|
|
58
58
|
"LICENSE"
|
|
59
59
|
],
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"@file-viewer/pptx": "^2.0.8",
|
|
62
|
-
"@flyfish-dev/cad-viewer": "^0.6.4",
|
|
63
61
|
"@excalidraw/excalidraw": "^0.18.1",
|
|
62
|
+
"@file-viewer/docx": "^0.3.10",
|
|
63
|
+
"@file-viewer/pptx": "^2.0.10",
|
|
64
|
+
"@flyfish-dev/cad-viewer": "^0.6.4",
|
|
64
65
|
"@kenjiuno/msgreader": "^1.28.0",
|
|
65
|
-
"@myriaddreamin/typst.ts": "0.7.0",
|
|
66
66
|
"@myriaddreamin/typst-ts-renderer": "0.7.0",
|
|
67
67
|
"@myriaddreamin/typst-ts-web-compiler": "0.7.0",
|
|
68
|
+
"@myriaddreamin/typst.ts": "0.7.0",
|
|
68
69
|
"@tmcw/togeojson": "^7.1.2",
|
|
69
70
|
"@tonejs/midi": "^2.0.28",
|
|
70
71
|
"@xmldom/xmldom": "^0.9.10",
|
|
71
72
|
"ag-psd": "^30.1.1",
|
|
72
73
|
"avsc": "^5.7.9",
|
|
73
74
|
"cfb": "^1.2.2",
|
|
74
|
-
"docx-preview": "^0.3.7",
|
|
75
75
|
"e-virt-table": "^1.3.26",
|
|
76
76
|
"epubjs": "^0.3.93",
|
|
77
77
|
"heic2any": "^0.0.4",
|
|
@@ -87,8 +87,6 @@
|
|
|
87
87
|
"pako": "^2.1.0",
|
|
88
88
|
"pdfjs-dist": "^6.0.227",
|
|
89
89
|
"postal-mime": "^2.7.4",
|
|
90
|
-
"react": "^18.3.1",
|
|
91
|
-
"react-dom": "^18.3.1",
|
|
92
90
|
"roughjs": "^4.6.6",
|
|
93
91
|
"rtf.js": "^3.0.9",
|
|
94
92
|
"shpjs": "^6.2.0",
|
|
@@ -98,10 +96,10 @@
|
|
|
98
96
|
"tinycolor2": "^1.6.0"
|
|
99
97
|
},
|
|
100
98
|
"devDependencies": {
|
|
101
|
-
"@types/
|
|
99
|
+
"@types/pako": "^2.0.4",
|
|
102
100
|
"@types/three": "^0.184.1",
|
|
103
|
-
"
|
|
104
|
-
"
|
|
101
|
+
"@types/tinycolor2": "^1.4.6",
|
|
102
|
+
"typescript": "^6.0.3"
|
|
105
103
|
},
|
|
106
104
|
"license": "Apache-2.0",
|
|
107
105
|
"scripts": {
|