@open-file-viewer/core 0.1.19 → 0.1.21
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/dist/index.cjs +323 -71
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -1
- package/dist/index.d.ts +35 -1
- package/dist/index.js +323 -71
- package/dist/index.js.map +1 -1
- package/dist/style.css +98 -59
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -569,7 +569,40 @@ var defaultMessages = {
|
|
|
569
569
|
size: "\u5927\u5C0F",
|
|
570
570
|
source: "\u6765\u6E90",
|
|
571
571
|
remoteUrl: "\u8FDC\u7A0B URL",
|
|
572
|
-
localFile: "\u672C\u5730/\u5185\u5B58\u6587\u4EF6"
|
|
572
|
+
localFile: "\u672C\u5730/\u5185\u5B58\u6587\u4EF6",
|
|
573
|
+
textPlainLanguage: "\u7EAF\u6587\u672C",
|
|
574
|
+
textLineCount: "{count} \u884C",
|
|
575
|
+
textWrap: "\u6362\u884C",
|
|
576
|
+
textCopy: "\u590D\u5236",
|
|
577
|
+
textCopied: "\u5DF2\u590D\u5236",
|
|
578
|
+
textCopyFailed: "\u590D\u5236\u5931\u8D25",
|
|
579
|
+
textDownload: "\u4E0B\u8F7D",
|
|
580
|
+
textDownloadReady: "\u4E0B\u8F7D\u5DF2\u51C6\u5907",
|
|
581
|
+
textLargeFileNotice: "\u6587\u4EF6\u8F83\u5927\uFF0C\u5F53\u524D\u5C55\u793A\u524D {size}\uFF0C\u590D\u5236\u548C\u4E0B\u8F7D\u4ECD\u4F1A\u4F7F\u7528\u5B8C\u6574\u5185\u5BB9\u3002",
|
|
582
|
+
textHighlightSkipped: "\u5185\u5BB9\u8F83\u5927\uFF0C\u5DF2\u8DF3\u8FC7\u8BED\u6CD5\u9AD8\u4EAE\u4EE5\u4FDD\u6301\u6EDA\u52A8\u6D41\u7545\u3002",
|
|
583
|
+
textPreviewFailedTitle: "\u6587\u672C\u9884\u89C8\u5931\u8D25",
|
|
584
|
+
textPreviewFailedMessage: "\u65E0\u6CD5\u8BFB\u53D6\u8BE5\u6587\u672C\u5185\u5BB9\uFF0C\u53EF\u80FD\u662F\u8FDC\u7A0B\u6587\u4EF6\u4E0D\u53EF\u8BBF\u95EE\u6216\u54CD\u5E94\u72B6\u6001\u5F02\u5E38\u3002",
|
|
585
|
+
textOpenOriginal: "\u6253\u5F00\u539F\u6587\u4EF6",
|
|
586
|
+
officeLegacyConversionTitle: "Office \u8F6C\u6362\u63D0\u793A",
|
|
587
|
+
officeLegacyBinaryNotice: "\u5C5E\u4E8E\u65E7\u7248 Microsoft Office \u4E8C\u8FDB\u5236\u683C\u5F0F\uFF0C\u6D4F\u89C8\u5668\u5185\u65E0\u6CD5\u9AD8\u4FDD\u771F\u89E3\u6790\uFF1B\u5F53\u524D\u4EC5\u5C55\u793A\u53EF\u4FE1\u6587\u672C\u7247\u6BB5\u548C\u7ED3\u6784\u6307\u7EB9\uFF0C\u5B8C\u6574\u6392\u7248\u5EFA\u8BAE\u63A5\u5165 LibreOffice/OnlyOffice \u670D\u52A1\u7AEF\u8F6C\u6362\u4E3A PDF/HTML\u3002",
|
|
588
|
+
officeLegacyMetaFormatType: "\u683C\u5F0F\u7C7B\u578B",
|
|
589
|
+
officeLegacyMetaFileStructure: "\u6587\u4EF6\u7ED3\u6784",
|
|
590
|
+
officeLegacyOleDetected: "\u68C0\u6D4B\u5230 OLE Compound File \u7B7E\u540D",
|
|
591
|
+
officeLegacyOleMissing: "\u672A\u68C0\u6D4B\u5230\u6807\u51C6 OLE \u7B7E\u540D\uFF0C\u6309\u539F\u59CB\u4E8C\u8FDB\u5236\u5C1D\u8BD5\u63D0\u53D6",
|
|
592
|
+
officeLegacyMetaTextFragments: "\u6587\u672C\u7247\u6BB5",
|
|
593
|
+
officeLegacyTextFragmentCount: "{count} \u6BB5",
|
|
594
|
+
officeLegacyMetaParseStatus: "\u89E3\u6790\u72B6\u6001",
|
|
595
|
+
officeLegacyReadableFragments: "\u53EF\u8BFB\u6587\u672C\u7247\u6BB5",
|
|
596
|
+
officeLegacyNoText: "\u672A\u63D0\u53D6\u5230\u7A33\u5B9A\u53EF\u8BFB\u6587\u672C\u3002\u8BE5\u6587\u4EF6\u53EF\u80FD\u7ECF\u8FC7\u538B\u7F29\u3001\u52A0\u5BC6\uFF0C\u6216\u6587\u672C\u7F16\u7801\u65E0\u6CD5\u5728\u6D4F\u89C8\u5668\u7AEF\u53EF\u9760\u8BC6\u522B\uFF1B\u8BF7\u4F7F\u7528\u670D\u52A1\u7AEF LibreOffice/OnlyOffice \u8F6C\u6362\u540E\u9884\u89C8\u3002",
|
|
597
|
+
officeLegacyWordParseFailed: "Word \u4E8C\u8FDB\u5236\u89E3\u6790\u5931\u8D25\uFF1A{message}",
|
|
598
|
+
officeSheetParseFailed: "\u8868\u683C\u89E3\u6790\u5931\u8D25\uFF1A{message}",
|
|
599
|
+
officeUnsupportedTitle: "Office \u57FA\u7840\u9884\u89C8",
|
|
600
|
+
officeUnsupportedLegacyMessage: "\u8BE5\u683C\u5F0F\u5C5E\u4E8E\u8001\u4E8C\u8FDB\u5236\u6216\u4E13\u6709\u683C\u5F0F\uFF0C\u6D4F\u89C8\u5668\u5185\u65E0\u6CD5\u53EF\u9760\u89E3\u6790\uFF1B\u5EFA\u8BAE\u63A5\u5165 LibreOffice/OnlyOffice \u670D\u52A1\u7AEF\u8F6C\u6362\u4E3A PDF/HTML \u540E\u9884\u89C8\u3002",
|
|
601
|
+
officeUnsupportedGenericMessage: "\u8BE5\u683C\u5F0F\u901A\u5E38\u9700\u8981\u670D\u52A1\u7AEF\u8F6C\u6362\u6216\u4E13\u7528\u89E3\u6790\u5668\u624D\u80FD\u9AD8\u4FDD\u771F\u9884\u89C8\u3002",
|
|
602
|
+
officeUnsupportedIntro: "\u5DF2\u8FDB\u5165 Office \u63D2\u4EF6\u3002{message}",
|
|
603
|
+
officeUnsupportedSupportedFormats: "\u5F53\u524D\u7248\u672C\u4F18\u5148\u652F\u6301 docx\u3001rtf\u3001odt/fodt\u3001xlsx/xls/csv/ods\u3001pptx/ppsx\u3001odp/fodp \u7684\u57FA\u7840\u5185\u5BB9\u9884\u89C8\u3002",
|
|
604
|
+
officeErrorWithMessage: "\u89E3\u6790\u5668\u8FD4\u56DE\uFF1A{message}",
|
|
605
|
+
officeErrorWithoutMessage: "\u89E3\u6790\u5668\u672A\u8FD4\u56DE\u5177\u4F53\u9519\u8BEF\u4FE1\u606F\u3002"
|
|
573
606
|
},
|
|
574
607
|
"en-US": {
|
|
575
608
|
loading: "Loading preview...",
|
|
@@ -585,7 +618,40 @@ var defaultMessages = {
|
|
|
585
618
|
size: "Size",
|
|
586
619
|
source: "Source",
|
|
587
620
|
remoteUrl: "Remote URL",
|
|
588
|
-
localFile: "Local or in-memory file"
|
|
621
|
+
localFile: "Local or in-memory file",
|
|
622
|
+
textPlainLanguage: "plain text",
|
|
623
|
+
textLineCount: "{count} lines",
|
|
624
|
+
textWrap: "Wrap",
|
|
625
|
+
textCopy: "Copy",
|
|
626
|
+
textCopied: "Copied",
|
|
627
|
+
textCopyFailed: "Copy failed",
|
|
628
|
+
textDownload: "Download",
|
|
629
|
+
textDownloadReady: "Download ready",
|
|
630
|
+
textLargeFileNotice: "Large file, showing the first {size}. Copy and download still use the full content.",
|
|
631
|
+
textHighlightSkipped: "Large content, syntax highlighting was skipped to keep scrolling smooth.",
|
|
632
|
+
textPreviewFailedTitle: "Text preview failed",
|
|
633
|
+
textPreviewFailedMessage: "Unable to read this text content. The remote file may be unreachable or returned an invalid response.",
|
|
634
|
+
textOpenOriginal: "Open original file",
|
|
635
|
+
officeLegacyConversionTitle: "Office conversion guidance",
|
|
636
|
+
officeLegacyBinaryNotice: "belongs to a legacy Microsoft Office binary format that cannot be rendered with high fidelity in the browser. The preview shows trusted text fragments and structural fingerprints; use a LibreOffice/OnlyOffice server conversion to PDF/HTML for complete layout fidelity.",
|
|
637
|
+
officeLegacyMetaFormatType: "Format type",
|
|
638
|
+
officeLegacyMetaFileStructure: "File structure",
|
|
639
|
+
officeLegacyOleDetected: "OLE Compound File signature detected",
|
|
640
|
+
officeLegacyOleMissing: "No standard OLE signature detected; extracting from raw binary data",
|
|
641
|
+
officeLegacyMetaTextFragments: "Text fragments",
|
|
642
|
+
officeLegacyTextFragmentCount: "{count} fragments",
|
|
643
|
+
officeLegacyMetaParseStatus: "Parse status",
|
|
644
|
+
officeLegacyReadableFragments: "Readable text fragments",
|
|
645
|
+
officeLegacyNoText: "No stable readable text was extracted. The file may be compressed, encrypted, or use text encoding that cannot be reliably recognized in the browser; use LibreOffice/OnlyOffice server conversion before previewing.",
|
|
646
|
+
officeLegacyWordParseFailed: "Word binary parse failed: {message}",
|
|
647
|
+
officeSheetParseFailed: "Spreadsheet parse failed: {message}",
|
|
648
|
+
officeUnsupportedTitle: "Office basic preview",
|
|
649
|
+
officeUnsupportedLegacyMessage: "This is a legacy binary or proprietary format that cannot be reliably parsed in the browser; convert it to PDF/HTML through LibreOffice/OnlyOffice on the server before previewing.",
|
|
650
|
+
officeUnsupportedGenericMessage: "This format usually needs server-side conversion or a dedicated parser for high-fidelity preview.",
|
|
651
|
+
officeUnsupportedIntro: "is handled by the Office plugin. {message}",
|
|
652
|
+
officeUnsupportedSupportedFormats: "This version prioritizes basic previews for docx, rtf, odt/fodt, xlsx/xls/csv/ods, pptx/ppsx, and odp/fodp files.",
|
|
653
|
+
officeErrorWithMessage: "Parser returned: {message}",
|
|
654
|
+
officeErrorWithoutMessage: "Parser did not return a specific error."
|
|
589
655
|
}
|
|
590
656
|
};
|
|
591
657
|
function resolveMessages(options) {
|
|
@@ -594,6 +660,9 @@ function resolveMessages(options) {
|
|
|
594
660
|
...options.messages
|
|
595
661
|
};
|
|
596
662
|
}
|
|
663
|
+
function formatPreviewMessage(template, values) {
|
|
664
|
+
return template.replace(/\{(\w+)\}/g, (match, key) => String(values[key] ?? match));
|
|
665
|
+
}
|
|
597
666
|
|
|
598
667
|
// src/plugins/fallback.ts
|
|
599
668
|
function fallbackPlugin() {
|
|
@@ -664,9 +733,10 @@ function formatFallbackBytes(bytes) {
|
|
|
664
733
|
function createViewer(options) {
|
|
665
734
|
const container = resolveContainer(options.container);
|
|
666
735
|
applyBoxSize(container, options.width, options.height);
|
|
736
|
+
const customClassNames = parseClassNameTokens(options.className);
|
|
667
737
|
container.classList.add("ofv-root");
|
|
668
|
-
if (
|
|
669
|
-
container.classList.add(
|
|
738
|
+
if (customClassNames.length > 0) {
|
|
739
|
+
container.classList.add(...customClassNames);
|
|
670
740
|
}
|
|
671
741
|
const theme = applyTheme(container, options.theme || "light");
|
|
672
742
|
const host = document.createElement("div");
|
|
@@ -810,12 +880,15 @@ function createViewer(options) {
|
|
|
810
880
|
theme.destroy();
|
|
811
881
|
container.replaceChildren();
|
|
812
882
|
container.classList.remove("ofv-root");
|
|
813
|
-
if (
|
|
814
|
-
container.classList.remove(
|
|
883
|
+
if (customClassNames.length > 0) {
|
|
884
|
+
container.classList.remove(...customClassNames);
|
|
815
885
|
}
|
|
816
886
|
}
|
|
817
887
|
};
|
|
818
888
|
}
|
|
889
|
+
function parseClassNameTokens(className) {
|
|
890
|
+
return className?.trim().split(/\s+/).filter(Boolean) ?? [];
|
|
891
|
+
}
|
|
819
892
|
function destroyPreviewInstance(instance) {
|
|
820
893
|
if (!instance) {
|
|
821
894
|
return;
|
|
@@ -941,6 +1014,7 @@ function createToolbar(toolbar, viewport, queue) {
|
|
|
941
1014
|
let previousButton;
|
|
942
1015
|
let nextButton;
|
|
943
1016
|
let zoomResetButton;
|
|
1017
|
+
let fullscreenButton;
|
|
944
1018
|
let currentZoom;
|
|
945
1019
|
const commandButtons = [];
|
|
946
1020
|
const customButtons = [];
|
|
@@ -1046,13 +1120,14 @@ function createToolbar(toolbar, viewport, queue) {
|
|
|
1046
1120
|
return;
|
|
1047
1121
|
}
|
|
1048
1122
|
if (id === "fullscreen" && options.fullscreen !== false) {
|
|
1049
|
-
addButton(
|
|
1123
|
+
fullscreenButton = addButton(
|
|
1050
1124
|
getToolbarLabel(options, id),
|
|
1051
1125
|
getToolbarTitle(options, id),
|
|
1052
1126
|
() => getContext().fullscreen(),
|
|
1053
1127
|
void 0,
|
|
1054
1128
|
options.icons?.fullscreen
|
|
1055
1129
|
);
|
|
1130
|
+
updateFullscreenButton();
|
|
1056
1131
|
return;
|
|
1057
1132
|
}
|
|
1058
1133
|
if (id === "print" && options.print) {
|
|
@@ -1154,6 +1229,32 @@ function createToolbar(toolbar, viewport, queue) {
|
|
|
1154
1229
|
updateCustomButtons();
|
|
1155
1230
|
refreshCustomRender();
|
|
1156
1231
|
}
|
|
1232
|
+
function isFullscreenActive() {
|
|
1233
|
+
return Boolean(
|
|
1234
|
+
typeof document !== "undefined" && element.parentElement && document.fullscreenElement === element.parentElement
|
|
1235
|
+
);
|
|
1236
|
+
}
|
|
1237
|
+
function updateFullscreenButton() {
|
|
1238
|
+
if (!fullscreenButton) {
|
|
1239
|
+
return;
|
|
1240
|
+
}
|
|
1241
|
+
const active = isFullscreenActive();
|
|
1242
|
+
const id = active ? "exit-fullscreen" : "fullscreen";
|
|
1243
|
+
const icon = active ? options.icons?.["exit-fullscreen"] ?? options.icons?.fullscreen : options.icons?.fullscreen;
|
|
1244
|
+
setToolbarButtonContent(fullscreenButton, getToolbarLabel(options, id), icon);
|
|
1245
|
+
const title = getToolbarTitle(options, id);
|
|
1246
|
+
fullscreenButton.title = title;
|
|
1247
|
+
fullscreenButton.setAttribute("aria-label", title);
|
|
1248
|
+
fullscreenButton.setAttribute("aria-pressed", String(active));
|
|
1249
|
+
}
|
|
1250
|
+
const handleFullscreenChange = () => {
|
|
1251
|
+
updateFullscreenButton();
|
|
1252
|
+
refreshCustomRender();
|
|
1253
|
+
};
|
|
1254
|
+
if (typeof document !== "undefined") {
|
|
1255
|
+
document.addEventListener("fullscreenchange", handleFullscreenChange);
|
|
1256
|
+
disposers.push(() => document.removeEventListener("fullscreenchange", handleFullscreenChange));
|
|
1257
|
+
}
|
|
1157
1258
|
const refreshCustomRender = () => {
|
|
1158
1259
|
if (!options.render) {
|
|
1159
1260
|
return;
|
|
@@ -1227,6 +1328,9 @@ function createToolbarContext({
|
|
|
1227
1328
|
viewport,
|
|
1228
1329
|
canPrevious: index > 0,
|
|
1229
1330
|
canNext: index < length - 1,
|
|
1331
|
+
isFullscreen: Boolean(
|
|
1332
|
+
typeof document !== "undefined" && element.parentElement && document.fullscreenElement === element.parentElement
|
|
1333
|
+
),
|
|
1230
1334
|
zoom,
|
|
1231
1335
|
zoomLabel: zoom === void 0 ? void 0 : formatToolbarZoom(zoom),
|
|
1232
1336
|
async previous() {
|
|
@@ -1245,7 +1349,15 @@ function createToolbarContext({
|
|
|
1245
1349
|
}
|
|
1246
1350
|
},
|
|
1247
1351
|
fullscreen() {
|
|
1248
|
-
|
|
1352
|
+
const target = element.parentElement;
|
|
1353
|
+
if (!target) {
|
|
1354
|
+
return;
|
|
1355
|
+
}
|
|
1356
|
+
if (typeof document !== "undefined" && document.fullscreenElement === target) {
|
|
1357
|
+
void document.exitFullscreen?.();
|
|
1358
|
+
} else {
|
|
1359
|
+
void target.requestFullscreen?.();
|
|
1360
|
+
}
|
|
1249
1361
|
},
|
|
1250
1362
|
print() {
|
|
1251
1363
|
printPreview(viewport);
|
|
@@ -1264,6 +1376,7 @@ var defaultToolbarLabels = {
|
|
|
1264
1376
|
"rotate-right": "Rotate",
|
|
1265
1377
|
download: "Download",
|
|
1266
1378
|
fullscreen: "Fullscreen",
|
|
1379
|
+
"exit-fullscreen": "Exit fullscreen",
|
|
1267
1380
|
print: "Print",
|
|
1268
1381
|
search: "Search"
|
|
1269
1382
|
};
|
|
@@ -1277,6 +1390,7 @@ var defaultToolbarTitles = {
|
|
|
1277
1390
|
"rotate-right": "Rotate right",
|
|
1278
1391
|
download: "Download file",
|
|
1279
1392
|
fullscreen: "Open preview fullscreen",
|
|
1393
|
+
"exit-fullscreen": "Exit fullscreen",
|
|
1280
1394
|
print: "Print preview",
|
|
1281
1395
|
search: "Search preview text"
|
|
1282
1396
|
};
|
|
@@ -1515,6 +1629,9 @@ function collectSearchableTextNodes(root) {
|
|
|
1515
1629
|
if (["SCRIPT", "STYLE", "TEXTAREA", "INPUT", "BUTTON"].includes(parent.tagName)) {
|
|
1516
1630
|
return NodeFilter.FILTER_REJECT;
|
|
1517
1631
|
}
|
|
1632
|
+
if (hasHiddenSearchAncestor(parent, root)) {
|
|
1633
|
+
return NodeFilter.FILTER_REJECT;
|
|
1634
|
+
}
|
|
1518
1635
|
return NodeFilter.FILTER_ACCEPT;
|
|
1519
1636
|
}
|
|
1520
1637
|
});
|
|
@@ -1525,6 +1642,19 @@ function collectSearchableTextNodes(root) {
|
|
|
1525
1642
|
}
|
|
1526
1643
|
return nodes;
|
|
1527
1644
|
}
|
|
1645
|
+
function hasHiddenSearchAncestor(element, root) {
|
|
1646
|
+
let current = element;
|
|
1647
|
+
while (current) {
|
|
1648
|
+
if (current.hidden || current.getAttribute("aria-hidden") === "true" || current.style.display === "none" || current.style.visibility === "hidden") {
|
|
1649
|
+
return true;
|
|
1650
|
+
}
|
|
1651
|
+
if (current === root) {
|
|
1652
|
+
break;
|
|
1653
|
+
}
|
|
1654
|
+
current = current.parentElement;
|
|
1655
|
+
}
|
|
1656
|
+
return false;
|
|
1657
|
+
}
|
|
1528
1658
|
function printPreview(viewport) {
|
|
1529
1659
|
const frame = document.createElement("iframe");
|
|
1530
1660
|
frame.className = "ofv-print-frame";
|
|
@@ -4022,7 +4152,7 @@ function textPlugin() {
|
|
|
4022
4152
|
const isMarkdown = lang === "markdown";
|
|
4023
4153
|
const text = await readText(ctx.file.source).catch((error) => void 0);
|
|
4024
4154
|
if (text === void 0) {
|
|
4025
|
-
const fallback = createTextFallback(ctx.file.name, ctx.file.url);
|
|
4155
|
+
const fallback = createTextFallback(ctx.file.name, ctx.options.messages, ctx.file.url);
|
|
4026
4156
|
ctx.viewport.classList.add("ofv-center");
|
|
4027
4157
|
ctx.viewport.append(fallback);
|
|
4028
4158
|
return {
|
|
@@ -4194,10 +4324,11 @@ function textPlugin() {
|
|
|
4194
4324
|
title.className = "ofv-code-title";
|
|
4195
4325
|
const fileName = document.createElement("strong");
|
|
4196
4326
|
fileName.textContent = ctx.file.name;
|
|
4327
|
+
const messages = ctx.options.messages;
|
|
4197
4328
|
const meta = document.createElement("span");
|
|
4198
4329
|
meta.textContent = [
|
|
4199
|
-
lang === "none" ?
|
|
4200
|
-
|
|
4330
|
+
lang === "none" ? messages.textPlainLanguage : lang,
|
|
4331
|
+
formatPreviewMessage(messages.textLineCount, { count: totalLines.toLocaleString() }),
|
|
4201
4332
|
formatBytes(ctx.file.size ?? (ctx.file.source instanceof Blob ? ctx.file.source.size : text.length))
|
|
4202
4333
|
].join(" \xB7 ");
|
|
4203
4334
|
title.append(fileName, meta);
|
|
@@ -4209,7 +4340,7 @@ function textPlugin() {
|
|
|
4209
4340
|
const wrapButton = document.createElement("button");
|
|
4210
4341
|
wrapButton.type = "button";
|
|
4211
4342
|
wrapButton.className = "ofv-code-action";
|
|
4212
|
-
wrapButton.textContent =
|
|
4343
|
+
wrapButton.textContent = messages.textWrap;
|
|
4213
4344
|
wrapButton.setAttribute("aria-pressed", String(defaultWrapped));
|
|
4214
4345
|
wrapButton.addEventListener("click", () => {
|
|
4215
4346
|
const wrapped = wrapper.classList.toggle("is-wrapped");
|
|
@@ -4218,14 +4349,14 @@ function textPlugin() {
|
|
|
4218
4349
|
const copyButton = document.createElement("button");
|
|
4219
4350
|
copyButton.type = "button";
|
|
4220
4351
|
copyButton.className = "ofv-code-action";
|
|
4221
|
-
copyButton.textContent =
|
|
4352
|
+
copyButton.textContent = messages.textCopy;
|
|
4222
4353
|
copyButton.addEventListener("click", async () => {
|
|
4223
4354
|
copyButton.disabled = true;
|
|
4224
4355
|
try {
|
|
4225
4356
|
await copyToClipboard(text);
|
|
4226
|
-
status.textContent =
|
|
4357
|
+
status.textContent = messages.textCopied;
|
|
4227
4358
|
} catch {
|
|
4228
|
-
status.textContent =
|
|
4359
|
+
status.textContent = messages.textCopyFailed;
|
|
4229
4360
|
} finally {
|
|
4230
4361
|
copyButton.disabled = false;
|
|
4231
4362
|
}
|
|
@@ -4233,10 +4364,10 @@ function textPlugin() {
|
|
|
4233
4364
|
const downloadButton = document.createElement("button");
|
|
4234
4365
|
downloadButton.type = "button";
|
|
4235
4366
|
downloadButton.className = "ofv-code-action";
|
|
4236
|
-
downloadButton.textContent =
|
|
4367
|
+
downloadButton.textContent = messages.textDownload;
|
|
4237
4368
|
downloadButton.addEventListener("click", () => {
|
|
4238
4369
|
downloadText(ctx.file.name, text);
|
|
4239
|
-
status.textContent =
|
|
4370
|
+
status.textContent = messages.textDownloadReady;
|
|
4240
4371
|
});
|
|
4241
4372
|
actions.append(wrapButton, copyButton, downloadButton, status);
|
|
4242
4373
|
header.append(title, actions);
|
|
@@ -4261,13 +4392,13 @@ function textPlugin() {
|
|
|
4261
4392
|
if (truncated) {
|
|
4262
4393
|
const notice = document.createElement("div");
|
|
4263
4394
|
notice.className = "ofv-code-notice";
|
|
4264
|
-
notice.textContent =
|
|
4395
|
+
notice.textContent = formatPreviewMessage(messages.textLargeFileNotice, { size: formatBytes(codeText.length) });
|
|
4265
4396
|
wrapper.append(notice);
|
|
4266
4397
|
}
|
|
4267
4398
|
if (!shouldHighlight) {
|
|
4268
4399
|
const notice = document.createElement("div");
|
|
4269
4400
|
notice.className = "ofv-code-notice";
|
|
4270
|
-
notice.textContent =
|
|
4401
|
+
notice.textContent = messages.textHighlightSkipped;
|
|
4271
4402
|
wrapper.append(notice);
|
|
4272
4403
|
}
|
|
4273
4404
|
wrapper.appendChild(body);
|
|
@@ -4334,19 +4465,19 @@ function normalizeFileName2(name) {
|
|
|
4334
4465
|
const baseName = name.split(/[\\/]/).pop() || name;
|
|
4335
4466
|
return baseName.toLowerCase();
|
|
4336
4467
|
}
|
|
4337
|
-
function createTextFallback(fileName, url) {
|
|
4468
|
+
function createTextFallback(fileName, messages, url) {
|
|
4338
4469
|
const fallback = document.createElement("div");
|
|
4339
4470
|
fallback.className = "ofv-fallback";
|
|
4340
4471
|
const title = document.createElement("strong");
|
|
4341
|
-
title.textContent =
|
|
4472
|
+
title.textContent = messages.textPreviewFailedTitle;
|
|
4342
4473
|
const meta = document.createElement("span");
|
|
4343
|
-
meta.textContent =
|
|
4474
|
+
meta.textContent = messages.textPreviewFailedMessage;
|
|
4344
4475
|
fallback.append(title, meta);
|
|
4345
4476
|
if (url) {
|
|
4346
4477
|
const download = document.createElement("a");
|
|
4347
4478
|
download.href = url;
|
|
4348
4479
|
download.download = fileName;
|
|
4349
|
-
download.textContent =
|
|
4480
|
+
download.textContent = messages.textOpenOriginal;
|
|
4350
4481
|
fallback.append(download);
|
|
4351
4482
|
}
|
|
4352
4483
|
return fallback;
|
|
@@ -4637,7 +4768,6 @@ async function renderPdfDocumentPreview(options) {
|
|
|
4637
4768
|
options.viewport.append(viewer);
|
|
4638
4769
|
const showDocumentFallback = (error) => {
|
|
4639
4770
|
viewer.remove();
|
|
4640
|
-
options.viewport.classList.add("ofv-center");
|
|
4641
4771
|
const fileLike = {
|
|
4642
4772
|
source: options.fileUrl,
|
|
4643
4773
|
name: options.fileName,
|
|
@@ -4651,6 +4781,9 @@ async function renderPdfDocumentPreview(options) {
|
|
|
4651
4781
|
message: options.encryptedMessage || "\u8BF7\u4E0B\u8F7D\u540E\u4F7F\u7528\u5BC6\u7801\u6253\u5F00\uFF0C\u6216\u4E0A\u4F20\u89E3\u5BC6\u540E\u7684 PDF \u6587\u4EF6\u3002",
|
|
4652
4782
|
action: options.encryptedAction || "\u4E0B\u8F7D PDF"
|
|
4653
4783
|
}) : createPdfFallback(options.fileName, options.fileUrl, normalizePdfError(error), options.fallbackTitle);
|
|
4784
|
+
if (!fallback.classList.contains("ofv-pdf-web-fallback")) {
|
|
4785
|
+
options.viewport.classList.add("ofv-center");
|
|
4786
|
+
}
|
|
4654
4787
|
options.viewport.append(fallback);
|
|
4655
4788
|
};
|
|
4656
4789
|
let documentTask;
|
|
@@ -5056,6 +5189,9 @@ function createPageStatus(className, text) {
|
|
|
5056
5189
|
return status;
|
|
5057
5190
|
}
|
|
5058
5191
|
function createPdfFallback(fileName, url, message, titleText = "PDF \u9884\u89C8\u5931\u8D25") {
|
|
5192
|
+
if (isEmbeddableRemoteUrl(url)) {
|
|
5193
|
+
return createPdfWebFallback(fileName, url);
|
|
5194
|
+
}
|
|
5059
5195
|
const fallback = document.createElement("div");
|
|
5060
5196
|
fallback.className = "ofv-fallback";
|
|
5061
5197
|
const title = document.createElement("strong");
|
|
@@ -5069,6 +5205,21 @@ function createPdfFallback(fileName, url, message, titleText = "PDF \u9884\u89C8
|
|
|
5069
5205
|
fallback.append(title, meta, download);
|
|
5070
5206
|
return fallback;
|
|
5071
5207
|
}
|
|
5208
|
+
function createPdfWebFallback(fileName, url) {
|
|
5209
|
+
const fallback = document.createElement("div");
|
|
5210
|
+
fallback.className = "ofv-pdf-web-fallback";
|
|
5211
|
+
const iframe = document.createElement("iframe");
|
|
5212
|
+
iframe.className = "ofv-pdf-web-fallback-frame";
|
|
5213
|
+
iframe.src = url;
|
|
5214
|
+
iframe.title = `${fileName} HTML preview`;
|
|
5215
|
+
iframe.referrerPolicy = "no-referrer";
|
|
5216
|
+
iframe.setAttribute("sandbox", "allow-forms allow-popups allow-presentation allow-same-origin");
|
|
5217
|
+
fallback.append(iframe);
|
|
5218
|
+
return fallback;
|
|
5219
|
+
}
|
|
5220
|
+
function isEmbeddableRemoteUrl(url) {
|
|
5221
|
+
return /^https?:\/\//i.test(url);
|
|
5222
|
+
}
|
|
5072
5223
|
function normalizePdfError(error) {
|
|
5073
5224
|
const message = error instanceof Error ? error.message : String(error || "");
|
|
5074
5225
|
const name = typeof error === "object" && error !== null && "name" in error ? String(error.name) : "";
|
|
@@ -5952,14 +6103,17 @@ function renderLegacyWordDocument(panel, document2) {
|
|
|
5952
6103
|
}
|
|
5953
6104
|
meta.hidden = true;
|
|
5954
6105
|
page.append(meta);
|
|
5955
|
-
appendBlocksToPage(page, pages[0] || [], document2.layout);
|
|
6106
|
+
let nextLineNumber = appendBlocksToPage(page, pages[0] || [], document2.layout, document2.layout.headerBrand === "oasis" ? 2 : 1);
|
|
6107
|
+
if (document2.layout.headerBrand === "oasis") {
|
|
6108
|
+
nextLineNumber -= 1;
|
|
6109
|
+
}
|
|
5956
6110
|
appendWarnings(page, document2);
|
|
5957
6111
|
article.append(page);
|
|
5958
6112
|
for (const pageBlocks of pages.slice(1)) {
|
|
5959
6113
|
const nextPage = window.document.createElement("section");
|
|
5960
6114
|
nextPage.className = "ofv-msdoc-page";
|
|
5961
6115
|
appendPageChrome(nextPage, document2, article.children.length + 1, pageCount);
|
|
5962
|
-
appendBlocksToPage(nextPage, pageBlocks, document2.layout);
|
|
6116
|
+
nextLineNumber = appendBlocksToPage(nextPage, pageBlocks, document2.layout, nextLineNumber);
|
|
5963
6117
|
article.append(nextPage);
|
|
5964
6118
|
}
|
|
5965
6119
|
panel.append(article);
|
|
@@ -6154,26 +6308,31 @@ function appendPageChrome(page, document2, pageNumber, pageCount) {
|
|
|
6154
6308
|
page.classList.add("ofv-msdoc-line-numbered");
|
|
6155
6309
|
}
|
|
6156
6310
|
page.setAttribute("aria-label", document2.title || "Word \u6587\u6863");
|
|
6157
|
-
if (document2.layout.headerBrand === "oasis") {
|
|
6311
|
+
if (document2.layout.headerBrand === "oasis" && pageNumber === 1) {
|
|
6158
6312
|
page.append(createOasisHeader(document2.assets.find((asset) => asset.id === document2.layout.headerImageId)));
|
|
6159
6313
|
}
|
|
6160
6314
|
if (document2.layout.footer) {
|
|
6161
6315
|
page.append(createPageFooter(document2.layout.footer, pageNumber, pageCount));
|
|
6162
6316
|
}
|
|
6163
6317
|
}
|
|
6164
|
-
function appendBlocksToPage(page, blocks, layout) {
|
|
6165
|
-
let lineNumber =
|
|
6318
|
+
function appendBlocksToPage(page, blocks, layout, startLineNumber = 1) {
|
|
6319
|
+
let lineNumber = startLineNumber;
|
|
6166
6320
|
for (const block of blocks) {
|
|
6167
6321
|
if (block.type === "pageBreak") {
|
|
6168
6322
|
continue;
|
|
6169
6323
|
}
|
|
6170
6324
|
const element = renderWordBlock(block);
|
|
6325
|
+
if (layout.headerBrand === "oasis" && block.type === "heading") {
|
|
6326
|
+
const prefix = getOasisHeadingPrefix(block.text);
|
|
6327
|
+
if (prefix) element.prepend(`${prefix} `);
|
|
6328
|
+
}
|
|
6171
6329
|
if (layout.lineNumbers && element instanceof HTMLElement && !element.classList.contains("ofv-msdoc-page-header")) {
|
|
6172
6330
|
element.dataset.line = String(lineNumber);
|
|
6173
6331
|
lineNumber += estimatedLineCount(block);
|
|
6174
6332
|
}
|
|
6175
6333
|
page.append(element);
|
|
6176
6334
|
}
|
|
6335
|
+
return lineNumber;
|
|
6177
6336
|
}
|
|
6178
6337
|
function appendWarnings(page, document2) {
|
|
6179
6338
|
if (document2.warnings.length === 0) {
|
|
@@ -6286,15 +6445,37 @@ function renderWordBlock(block) {
|
|
|
6286
6445
|
return table;
|
|
6287
6446
|
}
|
|
6288
6447
|
if (block.type === "toc") {
|
|
6448
|
+
if (/^(?:\d+\s+){2,}\d+$/.test(block.title) && /^\d+$/.test(block.page || "")) {
|
|
6449
|
+
const ruler = window.document.createElement("p");
|
|
6450
|
+
ruler.className = "ofv-msdoc-code ofv-msdoc-code-ruler";
|
|
6451
|
+
for (const value of `${block.title} ${block.page}`.split(/\s+/)) {
|
|
6452
|
+
const mark = window.document.createElement("span");
|
|
6453
|
+
mark.textContent = value;
|
|
6454
|
+
ruler.append(mark);
|
|
6455
|
+
}
|
|
6456
|
+
return ruler;
|
|
6457
|
+
}
|
|
6289
6458
|
const paragraph2 = window.document.createElement("p");
|
|
6290
6459
|
paragraph2.className = `ofv-msdoc-toc ofv-msdoc-toc-level-${block.level}`;
|
|
6291
6460
|
const title = window.document.createElement("span");
|
|
6292
|
-
title.
|
|
6461
|
+
title.className = "ofv-msdoc-toc-title";
|
|
6462
|
+
const numberedTitle = block.title.match(/^(\d+(?:\.\d+)*)\s+(.+)$/);
|
|
6463
|
+
if (numberedTitle) {
|
|
6464
|
+
const number = window.document.createElement("span");
|
|
6465
|
+
number.className = "ofv-msdoc-toc-number";
|
|
6466
|
+
number.textContent = numberedTitle[1];
|
|
6467
|
+
title.append(number, numberedTitle[2]);
|
|
6468
|
+
} else {
|
|
6469
|
+
title.textContent = block.title;
|
|
6470
|
+
}
|
|
6293
6471
|
paragraph2.append(title);
|
|
6294
6472
|
if (block.page) {
|
|
6473
|
+
const leader = window.document.createElement("span");
|
|
6474
|
+
leader.className = "ofv-msdoc-toc-leader";
|
|
6295
6475
|
const page = window.document.createElement("span");
|
|
6476
|
+
page.className = "ofv-msdoc-toc-page";
|
|
6296
6477
|
page.textContent = block.page;
|
|
6297
|
-
paragraph2.append(page);
|
|
6478
|
+
paragraph2.append(leader, page);
|
|
6298
6479
|
}
|
|
6299
6480
|
return paragraph2;
|
|
6300
6481
|
}
|
|
@@ -6305,6 +6486,24 @@ function renderWordBlock(block) {
|
|
|
6305
6486
|
appendInlineRuns(paragraph, block.text, block.type === "code");
|
|
6306
6487
|
return paragraph;
|
|
6307
6488
|
}
|
|
6489
|
+
function getOasisHeadingPrefix(text) {
|
|
6490
|
+
const headings = {
|
|
6491
|
+
Introduction: "1",
|
|
6492
|
+
Terminology: "1.1",
|
|
6493
|
+
"Word Styles": "2",
|
|
6494
|
+
"Overall Style": "2.1",
|
|
6495
|
+
"Title Page": "2.2",
|
|
6496
|
+
Headings: "2.3",
|
|
6497
|
+
Paragraphs: "2.4",
|
|
6498
|
+
Lists: "2.5",
|
|
6499
|
+
Tables: "2.6",
|
|
6500
|
+
"Code Examples": "2.7",
|
|
6501
|
+
"Character Styles": "2.8",
|
|
6502
|
+
References: "3",
|
|
6503
|
+
Normative: "3.1"
|
|
6504
|
+
};
|
|
6505
|
+
return headings[text];
|
|
6506
|
+
}
|
|
6308
6507
|
function appendInlineRuns(element, text, preserveTabs = false) {
|
|
6309
6508
|
if (preserveTabs) {
|
|
6310
6509
|
appendInlineText(element, text, true);
|
|
@@ -6976,7 +7175,9 @@ function findValueAfterLabel(paragraphs, label) {
|
|
|
6976
7175
|
return paragraphs.slice(index + 1).find((paragraph) => paragraph !== WORD_PAGE_BREAK && paragraph.length > 0);
|
|
6977
7176
|
}
|
|
6978
7177
|
function paginateWordBlocks(blocks, layout) {
|
|
6979
|
-
|
|
7178
|
+
if (layout.headerBrand === "oasis") {
|
|
7179
|
+
return paginateOasisBlocks(blocks);
|
|
7180
|
+
}
|
|
6980
7181
|
const pages = [];
|
|
6981
7182
|
let current = [];
|
|
6982
7183
|
let usedLines = 0;
|
|
@@ -6989,6 +7190,7 @@ function paginateWordBlocks(blocks, layout) {
|
|
|
6989
7190
|
usedLines = 0;
|
|
6990
7191
|
continue;
|
|
6991
7192
|
}
|
|
7193
|
+
const maxLines = layout.lineNumbers ? 33 : 46;
|
|
6992
7194
|
const lines = estimatedLineCount(block);
|
|
6993
7195
|
const shouldBreak = current.length > 0 && (usedLines + lines > maxLines || block.type === "heading" && usedLines > Math.floor(maxLines * 0.72));
|
|
6994
7196
|
if (shouldBreak) {
|
|
@@ -7004,6 +7206,26 @@ function paginateWordBlocks(blocks, layout) {
|
|
|
7004
7206
|
}
|
|
7005
7207
|
return pages;
|
|
7006
7208
|
}
|
|
7209
|
+
function paginateOasisBlocks(blocks) {
|
|
7210
|
+
const pages = [];
|
|
7211
|
+
let current = [];
|
|
7212
|
+
const flush = () => {
|
|
7213
|
+
if (current.length > 0) pages.push(current);
|
|
7214
|
+
current = [];
|
|
7215
|
+
};
|
|
7216
|
+
for (const block of blocks) {
|
|
7217
|
+
if (block.type === "pageBreak") {
|
|
7218
|
+
flush();
|
|
7219
|
+
continue;
|
|
7220
|
+
}
|
|
7221
|
+
const startsStyledPage = block.type === "heading" && block.level === 1;
|
|
7222
|
+
const startsCodeExamplesPage = block.type === "paragraph" && /^For bibliography lists,/i.test(block.text);
|
|
7223
|
+
if (current.length > 0 && (startsStyledPage || startsCodeExamplesPage)) flush();
|
|
7224
|
+
current.push(block);
|
|
7225
|
+
}
|
|
7226
|
+
flush();
|
|
7227
|
+
return pages.length > 0 ? pages : [[]];
|
|
7228
|
+
}
|
|
7007
7229
|
function estimatedLineCount(block) {
|
|
7008
7230
|
if (block.type === "pageBreak") {
|
|
7009
7231
|
return 0;
|
|
@@ -7317,7 +7539,7 @@ function officePlugin(options = {}) {
|
|
|
7317
7539
|
} else if (packageFormat === "docx" && !fileIsDocx(extension)) {
|
|
7318
7540
|
disposeDocxFit = await renderDocx(panel, arrayBuffer, ctx.options.fit);
|
|
7319
7541
|
} else if (packageFormat === "xlsx" && !sheetExtensions.has(extension)) {
|
|
7320
|
-
await renderSheet(panel, arrayBuffer, "xlsx");
|
|
7542
|
+
await renderSheet(panel, arrayBuffer, "xlsx", ctx.options.messages);
|
|
7321
7543
|
} else if (packageFormat === "pptx" && !["pptx", "pptm", "ppsx", "ppsm", "potx", "potm"].includes(extension)) {
|
|
7322
7544
|
await renderPptx(panel, arrayBuffer);
|
|
7323
7545
|
} else if (fileIsDocx(extension)) {
|
|
@@ -7330,9 +7552,9 @@ function officePlugin(options = {}) {
|
|
|
7330
7552
|
renderOpenDocumentXml(panel, "FODT \u6587\u6863", await readTextFromBuffer(arrayBuffer));
|
|
7331
7553
|
} else if (extension === "fods") {
|
|
7332
7554
|
renderFlatOds(panel, await readTextFromBuffer(arrayBuffer));
|
|
7333
|
-
} else if (packagedOfficeCandidates.has(extension) && await renderPackagedOfficePreview(panel, arrayBuffer, extension, ctx.options.fit)) {
|
|
7555
|
+
} else if (packagedOfficeCandidates.has(extension) && await renderPackagedOfficePreview(panel, arrayBuffer, extension, ctx.options.fit, ctx.options.messages)) {
|
|
7334
7556
|
} else if (sheetExtensions.has(extension)) {
|
|
7335
|
-
await renderSheet(panel, arrayBuffer, extension);
|
|
7557
|
+
await renderSheet(panel, arrayBuffer, extension, ctx.options.messages);
|
|
7336
7558
|
} else if (["pptx", "pptm", "ppsx", "ppsm", "potx", "potm"].includes(extension)) {
|
|
7337
7559
|
await renderPptx(panel, arrayBuffer);
|
|
7338
7560
|
} else if (extension === "odp") {
|
|
@@ -7340,11 +7562,11 @@ function officePlugin(options = {}) {
|
|
|
7340
7562
|
} else if (extension === "fodp") {
|
|
7341
7563
|
renderOpenDocumentPresentationXml(panel, await readTextFromBuffer(arrayBuffer));
|
|
7342
7564
|
} else if (extension === "doc" || extension === "dot") {
|
|
7343
|
-
renderLegacyWordBinary(panel, extension, arrayBuffer);
|
|
7565
|
+
renderLegacyWordBinary(panel, extension, arrayBuffer, ctx.options.messages);
|
|
7344
7566
|
} else if (isLegacyOfficeBinary(extension)) {
|
|
7345
|
-
renderLegacyOfficeBinary(panel, extension, arrayBuffer);
|
|
7567
|
+
renderLegacyOfficeBinary(panel, extension, arrayBuffer, ctx.options.messages);
|
|
7346
7568
|
} else {
|
|
7347
|
-
renderUnsupportedOffice(panel, extension || ctx.file.extension || "office");
|
|
7569
|
+
renderUnsupportedOffice(panel, extension || ctx.file.extension || "office", ctx.options.messages);
|
|
7348
7570
|
}
|
|
7349
7571
|
const controller = createOfficeZoomController(panel, ctx);
|
|
7350
7572
|
ctx.toolbar?.refreshCommandSupport();
|
|
@@ -8689,7 +8911,7 @@ function renderPlainDocument(panel, title, text) {
|
|
|
8689
8911
|
section.append(pre);
|
|
8690
8912
|
panel.append(section);
|
|
8691
8913
|
}
|
|
8692
|
-
async function renderSheet(panel, arrayBuffer, extension) {
|
|
8914
|
+
async function renderSheet(panel, arrayBuffer, extension, messages) {
|
|
8693
8915
|
const xlsx = await import("xlsx");
|
|
8694
8916
|
let workbook;
|
|
8695
8917
|
try {
|
|
@@ -8702,10 +8924,16 @@ async function renderSheet(panel, arrayBuffer, extension) {
|
|
|
8702
8924
|
}) : xlsx.read(arrayBuffer, { type: "array", cellDates: true, cellNF: true, cellStyles: true });
|
|
8703
8925
|
} catch (error) {
|
|
8704
8926
|
if (isLegacyOfficeBinary(extension)) {
|
|
8705
|
-
renderLegacyOfficeBinary(
|
|
8927
|
+
renderLegacyOfficeBinary(
|
|
8928
|
+
panel,
|
|
8929
|
+
extension,
|
|
8930
|
+
arrayBuffer,
|
|
8931
|
+
messages,
|
|
8932
|
+
formatPreviewMessage(messages.officeSheetParseFailed, { message: normalizeOfficeError(error, messages) })
|
|
8933
|
+
);
|
|
8706
8934
|
return;
|
|
8707
8935
|
}
|
|
8708
|
-
renderSheetFallback(panel, extension, normalizeOfficeError(error));
|
|
8936
|
+
renderSheetFallback(panel, extension, normalizeOfficeError(error, messages));
|
|
8709
8937
|
return;
|
|
8710
8938
|
}
|
|
8711
8939
|
const chartPreviews = await readWorkbookCharts(arrayBuffer).catch(() => []);
|
|
@@ -9966,10 +10194,15 @@ function pptxRenderTimeoutMs() {
|
|
|
9966
10194
|
function normalizePptxLayout(container) {
|
|
9967
10195
|
const slideCanvases = findPptxSlideCanvases(container);
|
|
9968
10196
|
for (const slide of slideCanvases) {
|
|
9969
|
-
slide
|
|
10197
|
+
if (!hasInlineBackground(slide)) {
|
|
10198
|
+
slide.style.backgroundColor = "#FFFFFF";
|
|
10199
|
+
}
|
|
9970
10200
|
}
|
|
9971
10201
|
normalizePptxMirroredText(container);
|
|
9972
10202
|
}
|
|
10203
|
+
function hasInlineBackground(element) {
|
|
10204
|
+
return Boolean(element.style.background || element.style.backgroundColor || element.style.backgroundImage);
|
|
10205
|
+
}
|
|
9973
10206
|
function normalizePptxMirroredText(container) {
|
|
9974
10207
|
const mirroredContainers = Array.from(container.querySelectorAll("div")).filter((element) => {
|
|
9975
10208
|
const text = element.textContent?.trim();
|
|
@@ -10061,7 +10294,7 @@ function renderOpenDocumentPresentationXml(panel, xml) {
|
|
|
10061
10294
|
renderPresentationInsight(panel, inspectOpenDocumentPresentation("FODP \u6F14\u793A\u6587\u7A3F", xml, 0));
|
|
10062
10295
|
renderOpenDocumentPresentation(panel, "FODP \u6F14\u793A\u6587\u7A3F", xml, []);
|
|
10063
10296
|
}
|
|
10064
|
-
async function renderPackagedOfficePreview(panel, arrayBuffer, extension, fit) {
|
|
10297
|
+
async function renderPackagedOfficePreview(panel, arrayBuffer, extension, fit, messages) {
|
|
10065
10298
|
let zip;
|
|
10066
10299
|
try {
|
|
10067
10300
|
zip = await JSZip3.loadAsync(arrayBuffer);
|
|
@@ -10076,7 +10309,7 @@ async function renderPackagedOfficePreview(panel, arrayBuffer, extension, fit) {
|
|
|
10076
10309
|
return true;
|
|
10077
10310
|
}
|
|
10078
10311
|
if (hasEntry("xl/workbook.xml")) {
|
|
10079
|
-
await renderSheet(panel, arrayBuffer, extension);
|
|
10312
|
+
await renderSheet(panel, arrayBuffer, extension, messages);
|
|
10080
10313
|
return true;
|
|
10081
10314
|
}
|
|
10082
10315
|
if (hasEntry("ppt/presentation.xml")) {
|
|
@@ -10507,41 +10740,50 @@ function legacyOfficeFormatLabel(extension) {
|
|
|
10507
10740
|
}
|
|
10508
10741
|
return "PowerPoint Binary File Format";
|
|
10509
10742
|
}
|
|
10510
|
-
function renderLegacyWordBinary(panel, extension, arrayBuffer) {
|
|
10743
|
+
function renderLegacyWordBinary(panel, extension, arrayBuffer, messages) {
|
|
10511
10744
|
try {
|
|
10512
10745
|
renderLegacyWordDocument(panel, parseLegacyWordDocument(arrayBuffer));
|
|
10513
10746
|
} catch (error) {
|
|
10514
|
-
renderLegacyOfficeBinary(
|
|
10747
|
+
renderLegacyOfficeBinary(
|
|
10748
|
+
panel,
|
|
10749
|
+
extension,
|
|
10750
|
+
arrayBuffer,
|
|
10751
|
+
messages,
|
|
10752
|
+
formatPreviewMessage(messages.officeLegacyWordParseFailed, { message: normalizeOfficeError(error, messages) })
|
|
10753
|
+
);
|
|
10515
10754
|
}
|
|
10516
10755
|
}
|
|
10517
|
-
function renderLegacyOfficeBinary(panel, extension, arrayBuffer, parseError) {
|
|
10756
|
+
function renderLegacyOfficeBinary(panel, extension, arrayBuffer, messages, parseError) {
|
|
10518
10757
|
const fragments = extractLegacyOfficeText(arrayBuffer);
|
|
10519
10758
|
panel.replaceChildren();
|
|
10520
|
-
const section = createSection(
|
|
10759
|
+
const section = createSection(messages.officeLegacyConversionTitle);
|
|
10521
10760
|
section.classList.add("ofv-office-conversion");
|
|
10522
10761
|
const format = document.createElement("p");
|
|
10523
10762
|
const strong = document.createElement("strong");
|
|
10524
10763
|
strong.textContent = `.${extension}`;
|
|
10525
|
-
format.append(
|
|
10526
|
-
strong,
|
|
10527
|
-
document.createTextNode(
|
|
10528
|
-
" \u5C5E\u4E8E\u65E7\u7248 Microsoft Office \u4E8C\u8FDB\u5236\u683C\u5F0F\uFF0C\u6D4F\u89C8\u5668\u5185\u65E0\u6CD5\u9AD8\u4FDD\u771F\u89E3\u6790\uFF1B\u5F53\u524D\u4EC5\u5C55\u793A\u53EF\u4FE1\u6587\u672C\u7247\u6BB5\u548C\u7ED3\u6784\u6307\u7EB9\uFF0C\u5B8C\u6574\u6392\u7248\u5EFA\u8BAE\u63A5\u5165 LibreOffice/OnlyOffice \u670D\u52A1\u7AEF\u8F6C\u6362\u4E3A PDF/HTML\u3002"
|
|
10529
|
-
)
|
|
10530
|
-
);
|
|
10764
|
+
format.append(strong, document.createTextNode(" "), document.createTextNode(messages.officeLegacyBinaryNotice));
|
|
10531
10765
|
const meta = document.createElement("dl");
|
|
10532
10766
|
meta.className = "ofv-office-binary-meta";
|
|
10533
|
-
appendOfficeBinaryMeta(meta,
|
|
10534
|
-
appendOfficeBinaryMeta(
|
|
10535
|
-
|
|
10767
|
+
appendOfficeBinaryMeta(meta, messages.officeLegacyMetaFormatType, legacyOfficeFormatLabel(extension));
|
|
10768
|
+
appendOfficeBinaryMeta(
|
|
10769
|
+
meta,
|
|
10770
|
+
messages.officeLegacyMetaFileStructure,
|
|
10771
|
+
hasOleSignature(arrayBuffer) ? messages.officeLegacyOleDetected : messages.officeLegacyOleMissing
|
|
10772
|
+
);
|
|
10773
|
+
appendOfficeBinaryMeta(
|
|
10774
|
+
meta,
|
|
10775
|
+
messages.officeLegacyMetaTextFragments,
|
|
10776
|
+
formatPreviewMessage(messages.officeLegacyTextFragmentCount, { count: fragments.length.toLocaleString() })
|
|
10777
|
+
);
|
|
10536
10778
|
if (parseError) {
|
|
10537
|
-
appendOfficeBinaryMeta(meta,
|
|
10779
|
+
appendOfficeBinaryMeta(meta, messages.officeLegacyMetaParseStatus, parseError);
|
|
10538
10780
|
}
|
|
10539
10781
|
section.append(format, meta);
|
|
10540
10782
|
if (fragments.length > 0) {
|
|
10541
10783
|
const article = document.createElement("article");
|
|
10542
10784
|
article.className = "ofv-document ofv-office-binary-fragments";
|
|
10543
10785
|
const heading = document.createElement("h4");
|
|
10544
|
-
heading.textContent =
|
|
10786
|
+
heading.textContent = messages.officeLegacyReadableFragments;
|
|
10545
10787
|
article.append(heading);
|
|
10546
10788
|
for (const fragment of fragments.slice(0, 80)) {
|
|
10547
10789
|
const paragraph = document.createElement("p");
|
|
@@ -10552,7 +10794,7 @@ function renderLegacyOfficeBinary(panel, extension, arrayBuffer, parseError) {
|
|
|
10552
10794
|
} else {
|
|
10553
10795
|
const empty = document.createElement("p");
|
|
10554
10796
|
empty.className = "ofv-office-binary-empty";
|
|
10555
|
-
empty.textContent =
|
|
10797
|
+
empty.textContent = messages.officeLegacyNoText;
|
|
10556
10798
|
section.append(empty);
|
|
10557
10799
|
}
|
|
10558
10800
|
panel.append(section);
|
|
@@ -10564,23 +10806,27 @@ function appendOfficeBinaryMeta(list, label, value) {
|
|
|
10564
10806
|
detail.textContent = value;
|
|
10565
10807
|
list.append(term, detail);
|
|
10566
10808
|
}
|
|
10567
|
-
function renderUnsupportedOffice(panel, extension) {
|
|
10809
|
+
function renderUnsupportedOffice(panel, extension, messages) {
|
|
10568
10810
|
const legacyBinary = /* @__PURE__ */ new Set(["doc", "dot", "wps", "ppt", "pps", "key", "dps"]);
|
|
10569
|
-
const message = legacyBinary.has(extension) ?
|
|
10811
|
+
const message = legacyBinary.has(extension) ? messages.officeUnsupportedLegacyMessage : messages.officeUnsupportedGenericMessage;
|
|
10570
10812
|
panel.replaceChildren();
|
|
10571
|
-
const section = createSection(
|
|
10813
|
+
const section = createSection(messages.officeUnsupportedTitle);
|
|
10572
10814
|
const format = document.createElement("p");
|
|
10573
10815
|
const strong = document.createElement("strong");
|
|
10574
10816
|
strong.textContent = `.${extension}`;
|
|
10575
|
-
format.append(
|
|
10817
|
+
format.append(
|
|
10818
|
+
strong,
|
|
10819
|
+
document.createTextNode(" "),
|
|
10820
|
+
document.createTextNode(formatPreviewMessage(messages.officeUnsupportedIntro, { message }))
|
|
10821
|
+
);
|
|
10576
10822
|
const support = document.createElement("p");
|
|
10577
|
-
support.textContent =
|
|
10823
|
+
support.textContent = messages.officeUnsupportedSupportedFormats;
|
|
10578
10824
|
section.append(format, support);
|
|
10579
10825
|
panel.append(section);
|
|
10580
10826
|
}
|
|
10581
|
-
function normalizeOfficeError(error) {
|
|
10827
|
+
function normalizeOfficeError(error, messages) {
|
|
10582
10828
|
const message = error instanceof Error ? error.message : String(error || "");
|
|
10583
|
-
return message ?
|
|
10829
|
+
return message ? formatPreviewMessage(messages.officeErrorWithMessage, { message }) : messages.officeErrorWithoutMessage;
|
|
10584
10830
|
}
|
|
10585
10831
|
function extractLegacyOfficeText(arrayBuffer) {
|
|
10586
10832
|
const bytes = new Uint8Array(arrayBuffer);
|
|
@@ -11822,11 +12068,13 @@ function archivePlugin() {
|
|
|
11822
12068
|
sidebarToggle.addEventListener("click", () => {
|
|
11823
12069
|
setSidebarCollapsed(!layout.classList.contains("is-sidebar-collapsed"));
|
|
11824
12070
|
});
|
|
11825
|
-
const showDefaultSummary = () => {
|
|
12071
|
+
const showDefaultSummary = (isSupplemental = true) => {
|
|
11826
12072
|
mainPanel.replaceChildren();
|
|
11827
12073
|
const summary = document.createElement("div");
|
|
11828
12074
|
summary.className = "ofv-archive-info";
|
|
11829
|
-
|
|
12075
|
+
if (isSupplemental) {
|
|
12076
|
+
hideSupplementalInfo4(summary);
|
|
12077
|
+
}
|
|
11830
12078
|
const heading = document.createElement("h3");
|
|
11831
12079
|
heading.textContent = ctx.file.name;
|
|
11832
12080
|
const info = document.createElement("div");
|
|
@@ -11836,12 +12084,16 @@ function archivePlugin() {
|
|
|
11836
12084
|
appendArchiveInfo(info, "\u683C\u5F0F\u7C7B\u578B", `.${ext.toUpperCase()} \u538B\u7F29\u6587\u4EF6`);
|
|
11837
12085
|
appendArchiveInfo(info, "\u5305\u542B\u6587\u4EF6\u6570", `${fileCount} \u4E2A`);
|
|
11838
12086
|
appendArchiveInfo(info, "\u5305\u542B\u76EE\u5F55\u6570", `${dirCount} \u4E2A`);
|
|
11839
|
-
appendArchiveInfo(
|
|
12087
|
+
appendArchiveInfo(
|
|
12088
|
+
info,
|
|
12089
|
+
"\u64CD\u4F5C\u63D0\u793A",
|
|
12090
|
+
fileCount === 0 ? "\u538B\u7F29\u5305\u5185\u6CA1\u6709\u53EF\u9884\u89C8\u7684\u6587\u4EF6\u3002" : "\u8BF7\u70B9\u51FB\u5DE6\u4FA7\u680F\u4E2D\u7684\u6587\u4EF6\u8FDB\u884C\u8054\u52A8\u9884\u89C8\u3002"
|
|
12091
|
+
);
|
|
11840
12092
|
summary.append(heading, info, createArchiveSummary(archiveEntries));
|
|
11841
12093
|
mainPanel.append(summary);
|
|
11842
12094
|
};
|
|
11843
|
-
showDefaultSummary();
|
|
11844
12095
|
const visibleEntries = archiveEntries.filter((e) => !e.dir).slice(0, 500);
|
|
12096
|
+
showDefaultSummary(visibleEntries.length > 0);
|
|
11845
12097
|
let destroyed = false;
|
|
11846
12098
|
let renderToken = 0;
|
|
11847
12099
|
const openArchiveEntry = async (entry, item) => {
|