@files-preview-app/preview-file 1.2.9 → 1.3.0
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/angular.cjs +505 -147
- package/dist/angular.cjs.map +1 -1
- package/dist/angular.js +504 -147
- package/dist/angular.js.map +1 -1
- package/dist/index.cjs +548 -147
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +546 -148
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +505 -147
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +504 -147
- package/dist/react.js.map +1 -1
- package/dist/vue.cjs +505 -147
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +504 -147
- package/dist/vue.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -14,6 +14,7 @@ var OBJLoader_js = require('three/examples/jsm/loaders/OBJLoader.js');
|
|
|
14
14
|
var OrbitControls_js = require('three/examples/jsm/controls/OrbitControls.js');
|
|
15
15
|
var RTFJS = require('rtf.js/dist/RTFJS.bundle.js');
|
|
16
16
|
|
|
17
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
17
18
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
18
19
|
|
|
19
20
|
function _interopNamespace(e) {
|
|
@@ -366,16 +367,21 @@ async function sourceToArrayBuffer(source, signal) {
|
|
|
366
367
|
metadata.mimeType = source.type || void 0;
|
|
367
368
|
metadata.extension = extractExtension(source.name);
|
|
368
369
|
buffer = await source.arrayBuffer();
|
|
369
|
-
} else if (source instanceof Blob) {
|
|
370
|
+
} else if (source instanceof Blob || source && typeof source.arrayBuffer === "function" && typeof source.size === "number") {
|
|
370
371
|
metadata.size = source.size;
|
|
371
372
|
metadata.mimeType = source.type || void 0;
|
|
373
|
+
if (source.name) {
|
|
374
|
+
metadata.name = source.name;
|
|
375
|
+
metadata.extension = extractExtension(source.name);
|
|
376
|
+
}
|
|
372
377
|
buffer = await source.arrayBuffer();
|
|
373
|
-
} else if (source instanceof ArrayBuffer) {
|
|
378
|
+
} else if (source instanceof ArrayBuffer || Object.prototype.toString.call(source) === "[object ArrayBuffer]" || source && typeof source.byteLength === "number" && typeof source.slice === "function") {
|
|
374
379
|
buffer = source;
|
|
375
|
-
} else if (source instanceof Uint8Array) {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
380
|
+
} else if (source instanceof Uint8Array || ArrayBuffer.isView(source)) {
|
|
381
|
+
const view = source;
|
|
382
|
+
buffer = view.buffer.slice(
|
|
383
|
+
view.byteOffset,
|
|
384
|
+
view.byteOffset + view.byteLength
|
|
379
385
|
);
|
|
380
386
|
} else {
|
|
381
387
|
throw new Error("Unsupported file source type");
|
|
@@ -504,6 +510,86 @@ function createElement(tag, attrs, ...children) {
|
|
|
504
510
|
}
|
|
505
511
|
return el;
|
|
506
512
|
}
|
|
513
|
+
var DB_NAME = "PreviewFileTransferDB";
|
|
514
|
+
var DB_STORE = "transfers";
|
|
515
|
+
function openDB() {
|
|
516
|
+
return new Promise((resolve, reject) => {
|
|
517
|
+
if (typeof indexedDB === "undefined") {
|
|
518
|
+
return reject(new Error("IndexedDB is not available"));
|
|
519
|
+
}
|
|
520
|
+
const req = indexedDB.open(DB_NAME, 1);
|
|
521
|
+
req.onupgradeneeded = () => {
|
|
522
|
+
const db = req.result;
|
|
523
|
+
if (!db.objectStoreNames.contains(DB_STORE)) {
|
|
524
|
+
db.createObjectStore(DB_STORE, { keyPath: "id" });
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
req.onsuccess = () => resolve(req.result);
|
|
528
|
+
req.onerror = () => reject(req.error);
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
async function saveTransferPayload(id, payload) {
|
|
532
|
+
if (typeof window !== "undefined") {
|
|
533
|
+
try {
|
|
534
|
+
window[id] = payload;
|
|
535
|
+
window.__lastTransfer = payload;
|
|
536
|
+
} catch {
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
try {
|
|
540
|
+
const db = await openDB();
|
|
541
|
+
return new Promise((resolve, reject) => {
|
|
542
|
+
const tx = db.transaction(DB_STORE, "readwrite");
|
|
543
|
+
const store = tx.objectStore(DB_STORE);
|
|
544
|
+
store.put({ id, ...payload, timestamp: Date.now() });
|
|
545
|
+
tx.oncomplete = () => resolve();
|
|
546
|
+
tx.onerror = () => reject(tx.error);
|
|
547
|
+
});
|
|
548
|
+
} catch (e) {
|
|
549
|
+
console.warn("[saveTransferPayload] IndexedDB store warning:", e);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
async function getTransferPayload(id) {
|
|
553
|
+
if (typeof window !== "undefined") {
|
|
554
|
+
try {
|
|
555
|
+
if (window.opener && window.opener[id]) {
|
|
556
|
+
return window.opener[id];
|
|
557
|
+
}
|
|
558
|
+
if (window[id]) {
|
|
559
|
+
return window[id];
|
|
560
|
+
}
|
|
561
|
+
if (window.opener && window.opener.__lastTransfer) {
|
|
562
|
+
return window.opener.__lastTransfer;
|
|
563
|
+
}
|
|
564
|
+
if (window.__lastTransfer) {
|
|
565
|
+
return window.__lastTransfer;
|
|
566
|
+
}
|
|
567
|
+
} catch {
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
try {
|
|
571
|
+
const db = await openDB();
|
|
572
|
+
return new Promise((resolve) => {
|
|
573
|
+
const tx = db.transaction(DB_STORE, "readonly");
|
|
574
|
+
const store = tx.objectStore(DB_STORE);
|
|
575
|
+
const req = store.get(id);
|
|
576
|
+
req.onsuccess = () => {
|
|
577
|
+
if (req.result && req.result.buffer) {
|
|
578
|
+
resolve({
|
|
579
|
+
buffer: req.result.buffer,
|
|
580
|
+
metadata: req.result.metadata,
|
|
581
|
+
options: req.result.options
|
|
582
|
+
});
|
|
583
|
+
} else {
|
|
584
|
+
resolve(null);
|
|
585
|
+
}
|
|
586
|
+
};
|
|
587
|
+
req.onerror = () => resolve(null);
|
|
588
|
+
});
|
|
589
|
+
} catch {
|
|
590
|
+
return null;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
507
593
|
var ICON_ZOOM_IN = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="11" y1="8" x2="11" y2="14"></line><line x1="8" y1="11" x2="14" y2="11"></line></svg>`;
|
|
508
594
|
var ICON_ZOOM_OUT = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="8" y1="11" x2="14" y2="11"></line></svg>`;
|
|
509
595
|
var ICON_FIT_PAGE = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"></rect><line x1="8" y1="12" x2="16" y2="12"></line><polyline points="11 9 8 12 11 15"></polyline><polyline points="13 9 16 12 13 15"></polyline></svg>`;
|
|
@@ -523,6 +609,7 @@ var ICON_COPY = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" str
|
|
|
523
609
|
var ICON_FAST_FORWARD = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 19 22 12 13 5 13 19"></polygon><polygon points="2 19 11 12 2 5 2 19"></polygon></svg>`;
|
|
524
610
|
var ICON_REWIND = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="11 19 2 12 11 5 11 19"></polygon><polygon points="22 19 13 12 22 5 22 19"></polygon></svg>`;
|
|
525
611
|
var ICON_SPEED = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>`;
|
|
612
|
+
var ICON_EXTERNAL_WINDOW = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>`;
|
|
526
613
|
var ICON_MAP = {
|
|
527
614
|
"zoom-in": ICON_ZOOM_IN,
|
|
528
615
|
"zoom-out": ICON_ZOOM_OUT,
|
|
@@ -549,7 +636,9 @@ var ICON_MAP = {
|
|
|
549
636
|
"forward-10": ICON_FAST_FORWARD,
|
|
550
637
|
"rewind": ICON_REWIND,
|
|
551
638
|
"replay-10": ICON_REWIND,
|
|
552
|
-
"speed": ICON_SPEED
|
|
639
|
+
"speed": ICON_SPEED,
|
|
640
|
+
"open-window": ICON_EXTERNAL_WINDOW,
|
|
641
|
+
"external-window": ICON_EXTERNAL_WINDOW
|
|
553
642
|
};
|
|
554
643
|
var ToolbarController = class {
|
|
555
644
|
el;
|
|
@@ -766,7 +855,7 @@ var ThumbnailPanel = class {
|
|
|
766
855
|
}
|
|
767
856
|
}
|
|
768
857
|
};
|
|
769
|
-
var FilePreviewViewer = class {
|
|
858
|
+
var FilePreviewViewer = class _FilePreviewViewer {
|
|
770
859
|
plugins = [];
|
|
771
860
|
activeInstance = null;
|
|
772
861
|
abortController = null;
|
|
@@ -803,6 +892,7 @@ var FilePreviewViewer = class {
|
|
|
803
892
|
* Preview a file in the given container element.
|
|
804
893
|
*/
|
|
805
894
|
async preview(container, source, options = {}) {
|
|
895
|
+
this.currentOptions = options;
|
|
806
896
|
this.abort();
|
|
807
897
|
this.abortController = new AbortController();
|
|
808
898
|
const { signal } = this.abortController;
|
|
@@ -812,7 +902,10 @@ var FilePreviewViewer = class {
|
|
|
812
902
|
this.showLoading();
|
|
813
903
|
try {
|
|
814
904
|
const { buffer, metadata } = await sourceToArrayBuffer(source, signal);
|
|
815
|
-
|
|
905
|
+
if (options.metadata) {
|
|
906
|
+
Object.assign(metadata, options.metadata);
|
|
907
|
+
}
|
|
908
|
+
this.currentBuffer = buffer.slice(0);
|
|
816
909
|
this.currentMetadata = metadata;
|
|
817
910
|
if (signal.aborted) throw new DOMException("Aborted", "AbortError");
|
|
818
911
|
const fileInfo = { metadata, buffer };
|
|
@@ -842,6 +935,7 @@ var FilePreviewViewer = class {
|
|
|
842
935
|
}
|
|
843
936
|
});
|
|
844
937
|
this.activeInstance = instance;
|
|
938
|
+
instance.openInSeparateWindow = () => this.openInSeparateWindow();
|
|
845
939
|
this.hideLoading();
|
|
846
940
|
this.eventEmitter.emit("loaded", { metadata, plugin: matchedPlugin.id });
|
|
847
941
|
if (options.showToolbar !== false && this.toolbar) {
|
|
@@ -851,26 +945,16 @@ var FilePreviewViewer = class {
|
|
|
851
945
|
actions.push({
|
|
852
946
|
id: "fullscreen",
|
|
853
947
|
icon: "fullscreen",
|
|
854
|
-
label: "
|
|
948
|
+
label: "Fullscreen",
|
|
855
949
|
type: "button",
|
|
856
950
|
group: "view",
|
|
857
|
-
execute:
|
|
951
|
+
execute: () => {
|
|
858
952
|
try {
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
if (this.wrapperEl?.requestFullscreen) {
|
|
863
|
-
await this.wrapperEl.requestFullscreen().catch(() => {
|
|
864
|
-
this.wrapperEl?.classList.add("fp-fullscreen-active");
|
|
865
|
-
});
|
|
866
|
-
} else {
|
|
867
|
-
this.wrapperEl?.classList.add("fp-fullscreen-active");
|
|
868
|
-
}
|
|
953
|
+
if (!document.fullscreenElement) {
|
|
954
|
+
this.wrapperEl?.requestFullscreen?.();
|
|
955
|
+
this.wrapperEl?.classList.add("fp-fullscreen-active");
|
|
869
956
|
} else {
|
|
870
|
-
|
|
871
|
-
await document.exitFullscreen().catch(() => {
|
|
872
|
-
});
|
|
873
|
-
}
|
|
957
|
+
document.exitFullscreen?.();
|
|
874
958
|
this.wrapperEl?.classList.remove("fp-fullscreen-active");
|
|
875
959
|
}
|
|
876
960
|
} catch {
|
|
@@ -882,6 +966,28 @@ var FilePreviewViewer = class {
|
|
|
882
966
|
}
|
|
883
967
|
});
|
|
884
968
|
}
|
|
969
|
+
const openWinAction = actions.find((a) => a.id === "open-window");
|
|
970
|
+
if (openWinAction) {
|
|
971
|
+
if (options?._isSeparateWindow) {
|
|
972
|
+
const idx = actions.indexOf(openWinAction);
|
|
973
|
+
if (idx !== -1) actions.splice(idx, 1);
|
|
974
|
+
} else {
|
|
975
|
+
openWinAction.execute = () => {
|
|
976
|
+
this.openInSeparateWindow();
|
|
977
|
+
};
|
|
978
|
+
}
|
|
979
|
+
} else if (!options?._isSeparateWindow) {
|
|
980
|
+
actions.push({
|
|
981
|
+
id: "open-window",
|
|
982
|
+
icon: "open-window",
|
|
983
|
+
label: "Open in Separate Full Window",
|
|
984
|
+
type: "button",
|
|
985
|
+
group: "actions",
|
|
986
|
+
execute: () => {
|
|
987
|
+
this.openInSeparateWindow();
|
|
988
|
+
}
|
|
989
|
+
});
|
|
990
|
+
}
|
|
885
991
|
this.toolbar.update(actions);
|
|
886
992
|
this.toolbar.show();
|
|
887
993
|
}
|
|
@@ -914,6 +1020,104 @@ var FilePreviewViewer = class {
|
|
|
914
1020
|
throw error;
|
|
915
1021
|
}
|
|
916
1022
|
}
|
|
1023
|
+
/**
|
|
1024
|
+
* Opens the current file preview in a separate full browser window.
|
|
1025
|
+
*/
|
|
1026
|
+
openInSeparateWindow() {
|
|
1027
|
+
if (!this.currentBuffer) {
|
|
1028
|
+
console.warn("[FilePreviewViewer] No active file buffer to open in separate window");
|
|
1029
|
+
return null;
|
|
1030
|
+
}
|
|
1031
|
+
if (this.currentOptions.onOpenSeparateWindow) {
|
|
1032
|
+
return this.currentOptions.onOpenSeparateWindow({
|
|
1033
|
+
buffer: this.currentBuffer,
|
|
1034
|
+
metadata: this.currentMetadata || { name: "Document" },
|
|
1035
|
+
options: this.currentOptions
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
const transferId = "fp_win_" + Date.now() + "_" + Math.random().toString(36).slice(2, 8);
|
|
1039
|
+
let clonedBuffer;
|
|
1040
|
+
try {
|
|
1041
|
+
clonedBuffer = this.currentBuffer.slice(0);
|
|
1042
|
+
} catch {
|
|
1043
|
+
clonedBuffer = this.currentBuffer;
|
|
1044
|
+
}
|
|
1045
|
+
const payload = {
|
|
1046
|
+
buffer: clonedBuffer,
|
|
1047
|
+
metadata: this.currentMetadata ? { ...this.currentMetadata } : void 0,
|
|
1048
|
+
options: { ...this.currentOptions, _isSeparateWindow: true }
|
|
1049
|
+
};
|
|
1050
|
+
if (typeof window !== "undefined") {
|
|
1051
|
+
try {
|
|
1052
|
+
window[transferId] = payload;
|
|
1053
|
+
window.__lastTransfer = payload;
|
|
1054
|
+
} catch {
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
saveTransferPayload(transferId, payload).catch((err) => {
|
|
1058
|
+
console.warn("[FilePreviewViewer] Transfer payload save warning:", err);
|
|
1059
|
+
});
|
|
1060
|
+
let targetUrl = null;
|
|
1061
|
+
if (this.currentOptions.standaloneViewerUrl) {
|
|
1062
|
+
const u = new URL(this.currentOptions.standaloneViewerUrl, window.location.href);
|
|
1063
|
+
u.searchParams.set("mode", "fullscreen");
|
|
1064
|
+
u.searchParams.set("transferId", transferId);
|
|
1065
|
+
targetUrl = u.toString();
|
|
1066
|
+
} else if (typeof window !== "undefined" && window.location?.href && !window.location.href.startsWith("about:")) {
|
|
1067
|
+
const u = new URL(window.location.href);
|
|
1068
|
+
u.searchParams.set("mode", "fullscreen");
|
|
1069
|
+
u.searchParams.set("transferId", transferId);
|
|
1070
|
+
targetUrl = u.toString();
|
|
1071
|
+
}
|
|
1072
|
+
if (targetUrl) {
|
|
1073
|
+
const newWin2 = window.open(targetUrl, "_blank");
|
|
1074
|
+
if (!newWin2) {
|
|
1075
|
+
alert("Popup blocker prevented opening the preview in a separate window. Please allow popups for this site.");
|
|
1076
|
+
return null;
|
|
1077
|
+
}
|
|
1078
|
+
return newWin2;
|
|
1079
|
+
}
|
|
1080
|
+
const title = (this.currentMetadata?.name || "Document Preview") + " - Full Preview";
|
|
1081
|
+
const newWin = window.open("", "_blank");
|
|
1082
|
+
if (!newWin) {
|
|
1083
|
+
alert("Popup blocker prevented opening the preview in a separate window. Please allow popups for this site.");
|
|
1084
|
+
return null;
|
|
1085
|
+
}
|
|
1086
|
+
newWin.document.title = title;
|
|
1087
|
+
newWin.document.body.style.margin = "0";
|
|
1088
|
+
newWin.document.body.style.padding = "0";
|
|
1089
|
+
newWin.document.body.style.width = "100vw";
|
|
1090
|
+
newWin.document.body.style.height = "100vh";
|
|
1091
|
+
newWin.document.body.style.overflow = "hidden";
|
|
1092
|
+
newWin.document.body.style.backgroundColor = "#f8fafc";
|
|
1093
|
+
const headNodes = document.querySelectorAll('link[rel="stylesheet"], style');
|
|
1094
|
+
headNodes.forEach((node) => {
|
|
1095
|
+
newWin.document.head.appendChild(node.cloneNode(true));
|
|
1096
|
+
});
|
|
1097
|
+
const root = newWin.document.createElement("div");
|
|
1098
|
+
root.id = "full-window-preview-root";
|
|
1099
|
+
root.style.width = "100%";
|
|
1100
|
+
root.style.height = "100%";
|
|
1101
|
+
root.style.overflow = "hidden";
|
|
1102
|
+
newWin.document.body.appendChild(root);
|
|
1103
|
+
const separateViewer = new _FilePreviewViewer();
|
|
1104
|
+
for (const plugin of this.plugins) {
|
|
1105
|
+
separateViewer.registerPlugin(plugin);
|
|
1106
|
+
}
|
|
1107
|
+
separateViewer.preview(root, this.currentBuffer.slice(0), {
|
|
1108
|
+
...this.currentOptions,
|
|
1109
|
+
showToolbar: true,
|
|
1110
|
+
toolbarPosition: "top",
|
|
1111
|
+
metadata: this.currentMetadata || void 0,
|
|
1112
|
+
_isSeparateWindow: true
|
|
1113
|
+
}).catch((err) => {
|
|
1114
|
+
console.error("[FilePreviewViewer] Error rendering in separate window:", err);
|
|
1115
|
+
});
|
|
1116
|
+
newWin.addEventListener("beforeunload", () => {
|
|
1117
|
+
separateViewer.destroy();
|
|
1118
|
+
});
|
|
1119
|
+
return newWin;
|
|
1120
|
+
}
|
|
917
1121
|
/**
|
|
918
1122
|
* Subscribe to viewer events.
|
|
919
1123
|
*/
|
|
@@ -1319,8 +1523,20 @@ var CfbfReader = class {
|
|
|
1319
1523
|
}
|
|
1320
1524
|
};
|
|
1321
1525
|
if (typeof window !== "undefined" && pdfjsLib__namespace.GlobalWorkerOptions) {
|
|
1322
|
-
if (!pdfjsLib__namespace.GlobalWorkerOptions.workerSrc) {
|
|
1323
|
-
|
|
1526
|
+
if (!pdfjsLib__namespace.GlobalWorkerOptions.workerPort && !pdfjsLib__namespace.GlobalWorkerOptions.workerSrc) {
|
|
1527
|
+
const customWorker = window.__PDF_WORKER_SRC__;
|
|
1528
|
+
if (customWorker) {
|
|
1529
|
+
pdfjsLib__namespace.GlobalWorkerOptions.workerSrc = customWorker;
|
|
1530
|
+
} else {
|
|
1531
|
+
try {
|
|
1532
|
+
pdfjsLib__namespace.GlobalWorkerOptions.workerPort = new Worker(
|
|
1533
|
+
new URL("pdfjs-dist/build/pdf.worker.min.mjs", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))),
|
|
1534
|
+
{ type: "module" }
|
|
1535
|
+
);
|
|
1536
|
+
} catch {
|
|
1537
|
+
pdfjsLib__namespace.GlobalWorkerOptions.workerSrc = "./pdf.worker.min.mjs";
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1324
1540
|
}
|
|
1325
1541
|
}
|
|
1326
1542
|
var PdfPlugin = class {
|
|
@@ -1414,6 +1630,14 @@ var PdfPlugin = class {
|
|
|
1414
1630
|
type: "button",
|
|
1415
1631
|
group: "actions",
|
|
1416
1632
|
execute: () => instance.print?.()
|
|
1633
|
+
},
|
|
1634
|
+
{
|
|
1635
|
+
id: "open-window",
|
|
1636
|
+
icon: "open-window",
|
|
1637
|
+
label: "Open in Separate Full Window",
|
|
1638
|
+
type: "button",
|
|
1639
|
+
group: "actions",
|
|
1640
|
+
execute: () => instance.openInSeparateWindow?.()
|
|
1417
1641
|
}
|
|
1418
1642
|
];
|
|
1419
1643
|
}
|
|
@@ -1463,18 +1687,21 @@ var PdfPlugin = class {
|
|
|
1463
1687
|
indicator.style.pointerEvents = "none";
|
|
1464
1688
|
container.appendChild(indicator);
|
|
1465
1689
|
ctx.container.appendChild(container);
|
|
1690
|
+
const standardFontsUrl = typeof window !== "undefined" && window.__PDF_STANDARD_FONTS_URL__ || "./standard_fonts/";
|
|
1691
|
+
const cmapsUrl = typeof window !== "undefined" && window.__PDF_CMAPS_URL__ || "./cmaps/";
|
|
1466
1692
|
const loadingTask = pdfjsLib__namespace.getDocument({
|
|
1467
|
-
data: new Uint8Array(ctx.buffer),
|
|
1468
|
-
cMapUrl:
|
|
1693
|
+
data: new Uint8Array(ctx.buffer.slice(0)),
|
|
1694
|
+
cMapUrl: cmapsUrl,
|
|
1469
1695
|
cMapPacked: true,
|
|
1470
|
-
standardFontDataUrl:
|
|
1696
|
+
standardFontDataUrl: standardFontsUrl,
|
|
1697
|
+
verbosity: 0
|
|
1471
1698
|
});
|
|
1472
1699
|
const pdfDoc = await loadingTask.promise;
|
|
1473
1700
|
const totalPages = Math.max(1, pdfDoc.numPages);
|
|
1474
1701
|
let currentPage = 1;
|
|
1475
1702
|
let zoomScale = 1;
|
|
1476
1703
|
let rotation = 0;
|
|
1477
|
-
let fitMode = "
|
|
1704
|
+
let fitMode = "page";
|
|
1478
1705
|
let currentRenderTask = null;
|
|
1479
1706
|
const renderPage = async (pageNum) => {
|
|
1480
1707
|
if (currentRenderTask) {
|
|
@@ -1494,15 +1721,15 @@ var PdfPlugin = class {
|
|
|
1494
1721
|
const containerWidth = container.clientWidth || 900;
|
|
1495
1722
|
const containerHeight = container.clientHeight || 700;
|
|
1496
1723
|
const unscaledVp = page.getViewport({ scale: 1, rotation });
|
|
1497
|
-
const availWidth = Math.max(
|
|
1498
|
-
const availHeight = Math.max(
|
|
1724
|
+
const availWidth = Math.max(320, containerWidth - 48);
|
|
1725
|
+
const availHeight = Math.max(550, containerHeight - 88);
|
|
1499
1726
|
const scaleW = availWidth / unscaledVp.width;
|
|
1500
1727
|
const scaleH = availHeight / unscaledVp.height;
|
|
1501
1728
|
let fitScale;
|
|
1502
1729
|
if (fitMode === "page") {
|
|
1503
|
-
fitScale = Math.max(0.
|
|
1730
|
+
fitScale = Math.max(0.4, Math.min(scaleW, scaleH));
|
|
1504
1731
|
} else {
|
|
1505
|
-
fitScale = Math.max(0.65, Math.min(1.
|
|
1732
|
+
fitScale = Math.max(0.65, Math.min(1.25, scaleW));
|
|
1506
1733
|
}
|
|
1507
1734
|
const effectiveScale = (fitScale > 0 ? fitScale : 1) * zoomScale;
|
|
1508
1735
|
const pixelRatio = window.devicePixelRatio || 1;
|
|
@@ -1528,7 +1755,7 @@ var PdfPlugin = class {
|
|
|
1528
1755
|
currentRenderTask = null;
|
|
1529
1756
|
}
|
|
1530
1757
|
};
|
|
1531
|
-
|
|
1758
|
+
renderPage(1);
|
|
1532
1759
|
let resizeTimer = null;
|
|
1533
1760
|
const resizeObserver = new ResizeObserver(() => {
|
|
1534
1761
|
if (resizeTimer) clearTimeout(resizeTimer);
|
|
@@ -1572,7 +1799,7 @@ var PdfPlugin = class {
|
|
|
1572
1799
|
renderPage(currentPage);
|
|
1573
1800
|
},
|
|
1574
1801
|
fitToPage: () => {
|
|
1575
|
-
fitMode = fitMode === "
|
|
1802
|
+
fitMode = fitMode === "page" ? "width" : "page";
|
|
1576
1803
|
zoomScale = 1;
|
|
1577
1804
|
rotation = 0;
|
|
1578
1805
|
renderPage(currentPage);
|
|
@@ -2049,6 +2276,14 @@ var DocxPlugin = class {
|
|
|
2049
2276
|
type: "button",
|
|
2050
2277
|
group: "actions",
|
|
2051
2278
|
execute: () => instance.print?.()
|
|
2279
|
+
},
|
|
2280
|
+
{
|
|
2281
|
+
id: "open-window",
|
|
2282
|
+
icon: "open-window",
|
|
2283
|
+
label: "Open in Separate Full Window",
|
|
2284
|
+
type: "button",
|
|
2285
|
+
group: "actions",
|
|
2286
|
+
execute: () => instance.openInSeparateWindow?.()
|
|
2052
2287
|
}
|
|
2053
2288
|
);
|
|
2054
2289
|
return actions;
|
|
@@ -2108,6 +2343,31 @@ var DocxPlugin = class {
|
|
|
2108
2343
|
}
|
|
2109
2344
|
if (wrapper.children.length > 0 && (wrapper.textContent?.trim().length ?? 0) > 0) {
|
|
2110
2345
|
renderedSuccessfully = true;
|
|
2346
|
+
try {
|
|
2347
|
+
const unzipped = fflate.unzipSync(new Uint8Array(ctx.buffer));
|
|
2348
|
+
const chartKeys = Object.keys(unzipped).filter((k) => k.replace(/^[./\\]+/, "").toLowerCase().startsWith("word/charts/chart") && k.endsWith(".xml")).sort();
|
|
2349
|
+
if (chartKeys.length > 0) {
|
|
2350
|
+
const allDivs = Array.from(wrapper.querySelectorAll("div"));
|
|
2351
|
+
const emptyContainers = allDivs.filter((div) => {
|
|
2352
|
+
const st = div.getAttribute("style") || "";
|
|
2353
|
+
return st.includes("width:") && st.includes("height:") && div.children.length === 0 && (div.textContent?.trim().length ?? 0) === 0;
|
|
2354
|
+
});
|
|
2355
|
+
chartKeys.forEach((cKey, idx) => {
|
|
2356
|
+
const target = emptyContainers[idx];
|
|
2357
|
+
if (target) {
|
|
2358
|
+
const xmlStr = fflate.strFromU8(unzipped[cKey]);
|
|
2359
|
+
const svg = this.parseAndRenderChartSvg(xmlStr);
|
|
2360
|
+
if (svg) {
|
|
2361
|
+
target.innerHTML = svg;
|
|
2362
|
+
target.style.display = "block";
|
|
2363
|
+
target.style.margin = "12px auto";
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
});
|
|
2367
|
+
}
|
|
2368
|
+
} catch (chartErr) {
|
|
2369
|
+
console.warn("[DocxPlugin] Non-critical error rendering DrawingML charts:", chartErr);
|
|
2370
|
+
}
|
|
2111
2371
|
}
|
|
2112
2372
|
} catch (err) {
|
|
2113
2373
|
console.warn("[DocxPlugin] docx-preview failed, triggering native fallback:", err);
|
|
@@ -2139,64 +2399,74 @@ var DocxPlugin = class {
|
|
|
2139
2399
|
}
|
|
2140
2400
|
let sections = Array.from(wrapper.querySelectorAll("section.docx"));
|
|
2141
2401
|
const cards = Array.from(wrapper.querySelectorAll(".fp-docx-page-card"));
|
|
2142
|
-
if (sections.length
|
|
2143
|
-
const
|
|
2144
|
-
const
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
const
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
nextSec.
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
nextArticle
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
nextSec.appendChild(
|
|
2402
|
+
if (sections.length > 0 && cards.length === 0) {
|
|
2403
|
+
const finalSections = [];
|
|
2404
|
+
for (const singleSec of sections) {
|
|
2405
|
+
const contentContainer = singleSec.querySelector("article") || singleSec;
|
|
2406
|
+
const children = Array.from(contentContainer.children);
|
|
2407
|
+
const pageH = singleSec.offsetHeight > 1300 ? 1122 : Math.max(1056, singleSec.offsetHeight);
|
|
2408
|
+
const secH = singleSec.scrollHeight || singleSec.offsetHeight;
|
|
2409
|
+
if (secH > pageH * 1.25 && children.length > 1) {
|
|
2410
|
+
const childHeights = children.map((c) => {
|
|
2411
|
+
const rectH = c.getBoundingClientRect().height;
|
|
2412
|
+
const offH = c.offsetHeight;
|
|
2413
|
+
const textLen = c.textContent?.trim().length || 0;
|
|
2414
|
+
const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
|
|
2415
|
+
return Math.max(rectH, offH, estH);
|
|
2416
|
+
});
|
|
2417
|
+
const parent = singleSec.parentElement || wrapper;
|
|
2418
|
+
const headerEl = singleSec.querySelector("header");
|
|
2419
|
+
const footerEl = singleSec.querySelector("footer");
|
|
2420
|
+
contentContainer.innerHTML = "";
|
|
2421
|
+
singleSec.style.minHeight = `${pageH}px`;
|
|
2422
|
+
singleSec.style.boxSizing = "border-box";
|
|
2423
|
+
let curContent = contentContainer;
|
|
2424
|
+
let curSec = singleSec;
|
|
2425
|
+
let curH = 0;
|
|
2426
|
+
const maxH = pageH - 140;
|
|
2427
|
+
finalSections.push(singleSec);
|
|
2428
|
+
for (let i = 0; i < children.length; i++) {
|
|
2429
|
+
const child = children[i];
|
|
2430
|
+
const chH = childHeights[i];
|
|
2431
|
+
curContent.appendChild(child);
|
|
2432
|
+
curH += chH;
|
|
2433
|
+
if (curH >= maxH && i < children.length - 1) {
|
|
2434
|
+
const nextSec = document.createElement("section");
|
|
2435
|
+
nextSec.className = singleSec.className;
|
|
2436
|
+
nextSec.style.cssText = singleSec.style.cssText;
|
|
2437
|
+
nextSec.style.minHeight = `${pageH}px`;
|
|
2438
|
+
nextSec.style.boxSizing = "border-box";
|
|
2439
|
+
nextSec.style.backgroundColor = "#ffffff";
|
|
2440
|
+
nextSec.style.boxShadow = "0 4px 24px rgba(0, 0, 0, 0.08)";
|
|
2441
|
+
nextSec.style.borderRadius = "4px";
|
|
2442
|
+
nextSec.style.marginBottom = "24px";
|
|
2443
|
+
if (headerEl) {
|
|
2444
|
+
nextSec.appendChild(headerEl.cloneNode(true));
|
|
2445
|
+
}
|
|
2446
|
+
const nextArticle = document.createElement("article");
|
|
2447
|
+
if (contentContainer.tagName.toLowerCase() === "article") {
|
|
2448
|
+
nextArticle.style.cssText = contentContainer.style.cssText;
|
|
2449
|
+
}
|
|
2450
|
+
nextSec.appendChild(nextArticle);
|
|
2451
|
+
if (footerEl) {
|
|
2452
|
+
nextSec.appendChild(footerEl.cloneNode(true));
|
|
2453
|
+
}
|
|
2454
|
+
if (curSec.nextSibling) {
|
|
2455
|
+
parent.insertBefore(nextSec, curSec.nextSibling);
|
|
2456
|
+
} else {
|
|
2457
|
+
parent.appendChild(nextSec);
|
|
2458
|
+
}
|
|
2459
|
+
finalSections.push(nextSec);
|
|
2460
|
+
curSec = nextSec;
|
|
2461
|
+
curContent = nextArticle;
|
|
2462
|
+
curH = 0;
|
|
2191
2463
|
}
|
|
2192
|
-
parent.appendChild(nextSec);
|
|
2193
|
-
newSections.push(nextSec);
|
|
2194
|
-
curContent = nextArticle;
|
|
2195
|
-
curH = 0;
|
|
2196
2464
|
}
|
|
2465
|
+
} else {
|
|
2466
|
+
finalSections.push(singleSec);
|
|
2197
2467
|
}
|
|
2198
|
-
sections = newSections;
|
|
2199
2468
|
}
|
|
2469
|
+
sections = finalSections;
|
|
2200
2470
|
}
|
|
2201
2471
|
const pageElements = sections.length > 0 ? sections : cards;
|
|
2202
2472
|
const totalPages = Math.max(1, pageElements.length);
|
|
@@ -2588,6 +2858,88 @@ var DocxPlugin = class {
|
|
|
2588
2858
|
}
|
|
2589
2859
|
return result;
|
|
2590
2860
|
}
|
|
2861
|
+
parseAndRenderChartSvg(xmlStr, width = 500, height = 260) {
|
|
2862
|
+
const catMatches = [...xmlStr.matchAll(/<c:cat>[\s\S]*?<c:strCache>([\s\S]*?)<\/c:strCache>/g)];
|
|
2863
|
+
let categories = [];
|
|
2864
|
+
if (catMatches.length > 0) {
|
|
2865
|
+
categories = [...catMatches[0][1].matchAll(/<c:v>([^<]+)<\/c:v>/g)].map((m) => m[1]);
|
|
2866
|
+
}
|
|
2867
|
+
if (categories.length === 0) {
|
|
2868
|
+
categories = ["Category 1", "Category 2", "Category 3", "Category 4"];
|
|
2869
|
+
}
|
|
2870
|
+
const defaultColors = ["#004586", "#ff420e", "#ffd320", "#579d1c", "#7e0021", "#83caff"];
|
|
2871
|
+
const sers = [...xmlStr.matchAll(/<c:ser>([\s\S]*?)<\/c:ser>/g)];
|
|
2872
|
+
const series = [];
|
|
2873
|
+
sers.forEach((s, sIdx) => {
|
|
2874
|
+
const titleMatch = s[1].match(/<c:tx>[\s\S]*?<c:v>([^<]+)<\/c:v>/);
|
|
2875
|
+
const title = titleMatch ? titleMatch[1] : `Series ${sIdx + 1}`;
|
|
2876
|
+
const clrMatch = s[1].match(/<a:srgbClr\s+val="([^"]+)"/);
|
|
2877
|
+
const color = clrMatch ? "#" + clrMatch[1] : defaultColors[sIdx % defaultColors.length];
|
|
2878
|
+
const valMatch = s[1].match(/<c:val>[\s\S]*?<c:numCache>([\s\S]*?)<\/c:numCache>/);
|
|
2879
|
+
let values = [];
|
|
2880
|
+
if (valMatch) {
|
|
2881
|
+
values = [...valMatch[1].matchAll(/<c:pt\s+idx="(\d+)">\s*<c:v>([^<]+)<\/c:v>/g)].sort((a, b) => parseInt(a[1], 10) - parseInt(b[1], 10)).map((m) => parseFloat(m[2]) || 0);
|
|
2882
|
+
}
|
|
2883
|
+
series.push({ title, color, values });
|
|
2884
|
+
});
|
|
2885
|
+
if (series.length === 0) return "";
|
|
2886
|
+
let maxVal = 10;
|
|
2887
|
+
series.forEach((s) => s.values.forEach((v) => {
|
|
2888
|
+
if (v > maxVal) maxVal = v;
|
|
2889
|
+
}));
|
|
2890
|
+
maxVal = Math.ceil(maxVal * 1.15);
|
|
2891
|
+
if (maxVal % 2 !== 0) maxVal++;
|
|
2892
|
+
const padLeft = 45;
|
|
2893
|
+
const padBottom = 55;
|
|
2894
|
+
const padTop = 20;
|
|
2895
|
+
const padRight = 20;
|
|
2896
|
+
const plotW = width - padLeft - padRight;
|
|
2897
|
+
const plotH = height - padTop - padBottom;
|
|
2898
|
+
const yTicks = 5;
|
|
2899
|
+
let gridLines = "";
|
|
2900
|
+
for (let i = 0; i <= yTicks; i++) {
|
|
2901
|
+
const val = maxVal / yTicks * i;
|
|
2902
|
+
const y = padTop + plotH - val / maxVal * plotH;
|
|
2903
|
+
gridLines += `<line x1="${padLeft}" y1="${y}" x2="${padLeft + plotW}" y2="${y}" stroke="#e2e8f0" stroke-width="1" />`;
|
|
2904
|
+
gridLines += `<text x="${padLeft - 8}" y="${y + 4}" text-anchor="end" font-size="11" fill="#64748b" font-family="Calibri, sans-serif">${Math.round(val)}</text>`;
|
|
2905
|
+
}
|
|
2906
|
+
const numCats = categories.length;
|
|
2907
|
+
const numSers = series.length;
|
|
2908
|
+
const groupW = plotW / numCats;
|
|
2909
|
+
const barW = Math.max(8, Math.min(28, groupW * 0.7 / numSers));
|
|
2910
|
+
const groupPad = (groupW - barW * numSers) / 2;
|
|
2911
|
+
let bars = "";
|
|
2912
|
+
let catLabels = "";
|
|
2913
|
+
for (let c = 0; c < numCats; c++) {
|
|
2914
|
+
const catX = padLeft + c * groupW;
|
|
2915
|
+
catLabels += `<text x="${catX + groupW / 2}" y="${padTop + plotH + 18}" text-anchor="middle" font-size="11" fill="#334155" font-family="Calibri, sans-serif">${categories[c]}</text>`;
|
|
2916
|
+
for (let s = 0; s < numSers; s++) {
|
|
2917
|
+
const val = series[s].values[c] ?? 0;
|
|
2918
|
+
const bH = Math.max(0, val / maxVal * plotH);
|
|
2919
|
+
const bX = catX + groupPad + s * barW;
|
|
2920
|
+
const bY = padTop + plotH - bH;
|
|
2921
|
+
bars += `<rect x="${bX}" y="${bY}" width="${barW - 2}" height="${bH}" fill="${series[s].color}" rx="1" />`;
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2924
|
+
let legend = "";
|
|
2925
|
+
const legY = height - 12;
|
|
2926
|
+
let legX = padLeft + (plotW - numSers * 100) / 2;
|
|
2927
|
+
series.forEach((s) => {
|
|
2928
|
+
legend += `<rect x="${legX}" y="${legY - 9}" width="10" height="10" fill="${s.color}" rx="2" />`;
|
|
2929
|
+
legend += `<text x="${legX + 15}" y="${legY}" font-size="11" fill="#475569" font-family="Calibri, sans-serif">${s.title}</text>`;
|
|
2930
|
+
legX += 95;
|
|
2931
|
+
});
|
|
2932
|
+
return `
|
|
2933
|
+
<svg viewBox="0 0 ${width} ${height}" width="100%" height="100%" style="background:#ffffff; border-radius:4px; overflow:visible;" xmlns="http://www.w3.org/2000/svg">
|
|
2934
|
+
${gridLines}
|
|
2935
|
+
<line x1="${padLeft}" y1="${padTop + plotH}" x2="${padLeft + plotW}" y2="${padTop + plotH}" stroke="#94a3b8" stroke-width="1.5" />
|
|
2936
|
+
<line x1="${padLeft}" y1="${padTop}" x2="${padLeft}" y2="${padTop + plotH}" stroke="#94a3b8" stroke-width="1.5" />
|
|
2937
|
+
${bars}
|
|
2938
|
+
${catLabels}
|
|
2939
|
+
${legend}
|
|
2940
|
+
</svg>
|
|
2941
|
+
`.trim();
|
|
2942
|
+
}
|
|
2591
2943
|
};
|
|
2592
2944
|
function docxPlugin() {
|
|
2593
2945
|
return new DocxPlugin();
|
|
@@ -3154,6 +3506,16 @@ var CodePlugin = class {
|
|
|
3154
3506
|
execute: () => {
|
|
3155
3507
|
instance.print?.();
|
|
3156
3508
|
}
|
|
3509
|
+
},
|
|
3510
|
+
{
|
|
3511
|
+
id: "open-window",
|
|
3512
|
+
icon: "open-window",
|
|
3513
|
+
label: "Open in Separate Full Window",
|
|
3514
|
+
type: "button",
|
|
3515
|
+
group: "actions",
|
|
3516
|
+
execute: () => {
|
|
3517
|
+
instance.openInSeparateWindow?.();
|
|
3518
|
+
}
|
|
3157
3519
|
}
|
|
3158
3520
|
);
|
|
3159
3521
|
return actions;
|
|
@@ -4322,6 +4684,14 @@ var RtfPlugin = class {
|
|
|
4322
4684
|
type: "button",
|
|
4323
4685
|
group: "actions",
|
|
4324
4686
|
execute: () => instance.print?.()
|
|
4687
|
+
},
|
|
4688
|
+
{
|
|
4689
|
+
id: "open-window",
|
|
4690
|
+
icon: "open-window",
|
|
4691
|
+
label: "Open in Separate Full Window",
|
|
4692
|
+
type: "button",
|
|
4693
|
+
group: "actions",
|
|
4694
|
+
execute: () => instance.openInSeparateWindow?.()
|
|
4325
4695
|
}
|
|
4326
4696
|
);
|
|
4327
4697
|
return actions;
|
|
@@ -4374,59 +4744,54 @@ var RtfPlugin = class {
|
|
|
4374
4744
|
}
|
|
4375
4745
|
const doc = new RTFJS__namespace.Document(ctx.buffer, {});
|
|
4376
4746
|
const htmlElements = await doc.render();
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
const secH = singleEl.offsetHeight || singleEl.scrollHeight;
|
|
4382
|
-
if (secH > 1300 && children.length > 1) {
|
|
4383
|
-
const childHeights = children.map((c) => {
|
|
4384
|
-
const rectH = c.getBoundingClientRect().height;
|
|
4385
|
-
const offH = c.offsetHeight;
|
|
4386
|
-
const textLen = c.textContent?.trim().length || 0;
|
|
4387
|
-
const estH = Math.max(24, Math.ceil(textLen / 80) * 22 + 16);
|
|
4388
|
-
return Math.max(rectH, offH, estH);
|
|
4389
|
-
});
|
|
4390
|
-
wrapper.innerHTML = "";
|
|
4391
|
-
const createRtfCard = () => {
|
|
4392
|
-
const card = document.createElement("div");
|
|
4393
|
-
card.className = "fp-rtf-page-card";
|
|
4394
|
-
card.style.backgroundColor = "#ffffff";
|
|
4395
|
-
card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08)";
|
|
4396
|
-
card.style.borderRadius = "4px";
|
|
4397
|
-
card.style.padding = "72px 56px";
|
|
4398
|
-
card.style.width = "816px";
|
|
4399
|
-
card.style.minHeight = "1056px";
|
|
4400
|
-
card.style.boxSizing = "border-box";
|
|
4401
|
-
card.style.marginBottom = "24px";
|
|
4402
|
-
return card;
|
|
4403
|
-
};
|
|
4404
|
-
let curCard = createRtfCard();
|
|
4405
|
-
wrapper.appendChild(curCard);
|
|
4406
|
-
pageElements = [curCard];
|
|
4407
|
-
let curH = 0;
|
|
4408
|
-
const maxH = 920;
|
|
4409
|
-
for (let i = 0; i < children.length; i++) {
|
|
4410
|
-
const child = children[i];
|
|
4411
|
-
const chH = childHeights[i];
|
|
4412
|
-
curCard.appendChild(child);
|
|
4413
|
-
curH += chH;
|
|
4414
|
-
if (curH >= maxH && i < children.length - 1) {
|
|
4415
|
-
curCard = createRtfCard();
|
|
4416
|
-
wrapper.appendChild(curCard);
|
|
4417
|
-
pageElements.push(curCard);
|
|
4418
|
-
curH = 0;
|
|
4419
|
-
}
|
|
4420
|
-
}
|
|
4747
|
+
const contentNodes = [];
|
|
4748
|
+
for (const item of htmlElements) {
|
|
4749
|
+
if (item.children && item.children.length > 0 && !item.tagName.toLowerCase().startsWith("table")) {
|
|
4750
|
+
contentNodes.push(...Array.from(item.children));
|
|
4421
4751
|
} else {
|
|
4422
|
-
|
|
4752
|
+
contentNodes.push(item);
|
|
4423
4753
|
}
|
|
4424
|
-
}
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4754
|
+
}
|
|
4755
|
+
wrapper.innerHTML = "";
|
|
4756
|
+
contentNodes.forEach((node) => wrapper.appendChild(node));
|
|
4757
|
+
const childHeights = contentNodes.map((c) => {
|
|
4758
|
+
const rectH = c.getBoundingClientRect ? c.getBoundingClientRect().height : 0;
|
|
4759
|
+
const offH = c.offsetHeight || 0;
|
|
4760
|
+
const textLen = c.textContent?.trim().length || 0;
|
|
4761
|
+
const estH = Math.max(24, Math.ceil(textLen / 75) * 22 + 14);
|
|
4762
|
+
return Math.max(rectH, offH, estH);
|
|
4763
|
+
});
|
|
4764
|
+
wrapper.innerHTML = "";
|
|
4765
|
+
const createRtfCard = () => {
|
|
4766
|
+
const card = document.createElement("div");
|
|
4767
|
+
card.className = "fp-rtf-page-card";
|
|
4768
|
+
card.style.backgroundColor = "#ffffff";
|
|
4769
|
+
card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08)";
|
|
4770
|
+
card.style.borderRadius = "4px";
|
|
4771
|
+
card.style.padding = "72px 56px";
|
|
4772
|
+
card.style.width = "816px";
|
|
4773
|
+
card.style.minHeight = "1056px";
|
|
4774
|
+
card.style.boxSizing = "border-box";
|
|
4775
|
+
card.style.marginBottom = "24px";
|
|
4776
|
+
card.style.fontFamily = 'Calibri, "Segoe UI", Arial, sans-serif';
|
|
4777
|
+
card.style.lineHeight = "1.6";
|
|
4778
|
+
return card;
|
|
4779
|
+
};
|
|
4780
|
+
let curCard = createRtfCard();
|
|
4781
|
+
wrapper.appendChild(curCard);
|
|
4782
|
+
pageElements = [curCard];
|
|
4783
|
+
let curH = 0;
|
|
4784
|
+
const maxH = 912;
|
|
4785
|
+
for (let i = 0; i < contentNodes.length; i++) {
|
|
4786
|
+
const child = contentNodes[i];
|
|
4787
|
+
const chH = childHeights[i];
|
|
4788
|
+
curCard.appendChild(child);
|
|
4789
|
+
curH += chH;
|
|
4790
|
+
if (curH >= maxH && i < contentNodes.length - 1) {
|
|
4791
|
+
curCard = createRtfCard();
|
|
4792
|
+
wrapper.appendChild(curCard);
|
|
4793
|
+
pageElements.push(curCard);
|
|
4794
|
+
curH = 0;
|
|
4430
4795
|
}
|
|
4431
4796
|
}
|
|
4432
4797
|
} catch (err) {
|
|
@@ -4795,6 +5160,14 @@ var OpenDocumentPlugin = class {
|
|
|
4795
5160
|
type: "button",
|
|
4796
5161
|
group: "actions",
|
|
4797
5162
|
execute: () => instance.print?.()
|
|
5163
|
+
},
|
|
5164
|
+
{
|
|
5165
|
+
id: "open-window",
|
|
5166
|
+
icon: "open-window",
|
|
5167
|
+
label: "Open in Separate Full Window",
|
|
5168
|
+
type: "button",
|
|
5169
|
+
group: "actions",
|
|
5170
|
+
execute: () => instance.openInSeparateWindow?.()
|
|
4798
5171
|
}
|
|
4799
5172
|
);
|
|
4800
5173
|
return actions;
|
|
@@ -5383,6 +5756,14 @@ var DocPlugin = class {
|
|
|
5383
5756
|
type: "button",
|
|
5384
5757
|
group: "actions",
|
|
5385
5758
|
execute: () => instance.print?.()
|
|
5759
|
+
},
|
|
5760
|
+
{
|
|
5761
|
+
id: "open-window",
|
|
5762
|
+
icon: "open-window",
|
|
5763
|
+
label: "Open in Separate Full Window",
|
|
5764
|
+
type: "button",
|
|
5765
|
+
group: "actions",
|
|
5766
|
+
execute: () => instance.openInSeparateWindow?.()
|
|
5386
5767
|
}
|
|
5387
5768
|
);
|
|
5388
5769
|
return actions;
|
|
@@ -5674,9 +6055,25 @@ var DocPlugin = class {
|
|
|
5674
6055
|
heuristicTextExtraction(buffer) {
|
|
5675
6056
|
return this.extractStringsFromBytes(new Uint8Array(buffer));
|
|
5676
6057
|
}
|
|
6058
|
+
cleanWordDocFields(text) {
|
|
6059
|
+
if (!text) return "";
|
|
6060
|
+
let cleaned = text.replace(
|
|
6061
|
+
/\x13\s*HYPERLINK\s*"?([^"\x14]+)"?\s*\x14([\s\S]*?)\x15/gi,
|
|
6062
|
+
(_match, url, label) => {
|
|
6063
|
+
const cleanUrl = url.trim();
|
|
6064
|
+
const cleanLabel = label.trim() || cleanUrl;
|
|
6065
|
+
return `<a href="${cleanUrl}" target="_blank" rel="noopener noreferrer" style="color: #2563eb; text-decoration: underline;">${cleanLabel}</a>`;
|
|
6066
|
+
}
|
|
6067
|
+
);
|
|
6068
|
+
cleaned = cleaned.replace(/\x13[^\x14\x15]*\x14([^\x15]*)\x15/g, "$1");
|
|
6069
|
+
cleaned = cleaned.replace(/\x13[^\x15]*\x15/g, "");
|
|
6070
|
+
cleaned = cleaned.replace(/[\x13\x14\x15]/g, "");
|
|
6071
|
+
return cleaned;
|
|
6072
|
+
}
|
|
5677
6073
|
splitIntoPages(text) {
|
|
5678
6074
|
if (!text) return [""];
|
|
5679
|
-
const
|
|
6075
|
+
const cleanedText = this.cleanWordDocFields(text);
|
|
6076
|
+
const normalized = cleanedText.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x0B/g, "\n").replace(/\x07\n/g, "\n").replace(/\x07/g, " ");
|
|
5680
6077
|
const explicitParts = normalized.split(/[\x0C\f]|\n\s*[-=_]{3,}\s*(?:PAGE|Page|page break)[\s\d\w-]*[-=_]{3,}\s*\n/i).map((p) => p.trim()).filter((p) => p.length > 0);
|
|
5681
6078
|
if (explicitParts.length === 0) explicitParts.push(normalized);
|
|
5682
6079
|
const maxLinesPerPage = 32;
|
|
@@ -5687,7 +6084,8 @@ var DocPlugin = class {
|
|
|
5687
6084
|
let currentLines = [];
|
|
5688
6085
|
let count = 0;
|
|
5689
6086
|
for (const line of lines) {
|
|
5690
|
-
const
|
|
6087
|
+
const plainLine = line.replace(/<[^>]+>/g, "");
|
|
6088
|
+
const vLines = Math.max(1, Math.ceil((plainLine.length || 1) / charsPerLine));
|
|
5691
6089
|
if (count + vLines > maxLinesPerPage && currentLines.length > 0) {
|
|
5692
6090
|
finalPages.push(currentLines.join("\n"));
|
|
5693
6091
|
currentLines = [];
|
|
@@ -5763,25 +6161,26 @@ var DocPlugin = class {
|
|
|
5763
6161
|
i++;
|
|
5764
6162
|
continue;
|
|
5765
6163
|
}
|
|
6164
|
+
const sanitizeOptions = { ADD_TAGS: ["a"], ADD_ATTR: ["href", "target", "rel", "style"] };
|
|
5766
6165
|
if (line.length < 60 && !line.endsWith(".") && (/^[A-Z0-9\s:_-]+$/.test(line) || line.startsWith("#"))) {
|
|
5767
6166
|
if (inList) {
|
|
5768
6167
|
html += "</ul>";
|
|
5769
6168
|
inList = false;
|
|
5770
6169
|
}
|
|
5771
|
-
html += `<h2 style="font-size: 16px; font-weight: 700; color: #1e3a8a; margin: 16px 0 8px; border-bottom: 1px solid #e2e8f0; padding-bottom: 4px;">${DOMPurify6__default.default.sanitize(line)}</h2>`;
|
|
6170
|
+
html += `<h2 style="font-size: 16px; font-weight: 700; color: #1e3a8a; margin: 16px 0 8px; border-bottom: 1px solid #e2e8f0; padding-bottom: 4px;">${DOMPurify6__default.default.sanitize(line, sanitizeOptions)}</h2>`;
|
|
5772
6171
|
} else if (line.startsWith("\u2022") || line.startsWith("-") || line.startsWith("*")) {
|
|
5773
6172
|
if (!inList) {
|
|
5774
6173
|
html += '<ul style="margin: 8px 0; padding-left: 24px;">';
|
|
5775
6174
|
inList = true;
|
|
5776
6175
|
}
|
|
5777
6176
|
const bulletText = line.replace(/^[•\-\*]\s*/, "");
|
|
5778
|
-
html += `<li style="margin: 4px 0; line-height: 1.15; font-size: 12pt;">${DOMPurify6__default.default.sanitize(bulletText)}</li>`;
|
|
6177
|
+
html += `<li style="margin: 4px 0; line-height: 1.15; font-size: 12pt;">${DOMPurify6__default.default.sanitize(bulletText, sanitizeOptions)}</li>`;
|
|
5779
6178
|
} else {
|
|
5780
6179
|
if (inList) {
|
|
5781
6180
|
html += "</ul>";
|
|
5782
6181
|
inList = false;
|
|
5783
6182
|
}
|
|
5784
|
-
html += `<p style="line-height: 1.15; margin: 0; font-size: 12pt; text-align: justify;">${DOMPurify6__default.default.sanitize(line)}</p>`;
|
|
6183
|
+
html += `<p style="line-height: 1.15; margin: 0; font-size: 12pt; text-align: justify;">${DOMPurify6__default.default.sanitize(line, sanitizeOptions)}</p>`;
|
|
5785
6184
|
}
|
|
5786
6185
|
i++;
|
|
5787
6186
|
}
|
|
@@ -6354,6 +6753,7 @@ exports.excelPlugin = excelPlugin;
|
|
|
6354
6753
|
exports.extractExtension = extractExtension;
|
|
6355
6754
|
exports.formatFileSize = formatFileSize;
|
|
6356
6755
|
exports.getDefaultPlugins = getDefaultPlugins;
|
|
6756
|
+
exports.getTransferPayload = getTransferPayload;
|
|
6357
6757
|
exports.htmlPreviewPlugin = htmlPreviewPlugin;
|
|
6358
6758
|
exports.markdownPlugin = markdownPlugin;
|
|
6359
6759
|
exports.mediaPlugin = mediaPlugin;
|
|
@@ -6366,6 +6766,7 @@ exports.printElement = printElement;
|
|
|
6366
6766
|
exports.rtfPlugin = rtfPlugin;
|
|
6367
6767
|
exports.sanitizeHTML = sanitizeHTML;
|
|
6368
6768
|
exports.sanitizeSVG = sanitizeSVG;
|
|
6769
|
+
exports.saveTransferPayload = saveTransferPayload;
|
|
6369
6770
|
exports.sourceToArrayBuffer = sourceToArrayBuffer;
|
|
6370
6771
|
exports.threeDPlugin = threeDPlugin;
|
|
6371
6772
|
//# sourceMappingURL=index.cjs.map
|