@files-preview-app/preview-file 1.3.2 → 1.3.3
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.md +36 -9
- package/dist/angular.cjs +389 -196
- package/dist/angular.cjs.map +1 -1
- package/dist/angular.d.cts +5 -0
- package/dist/angular.d.ts +5 -0
- package/dist/angular.js +389 -196
- package/dist/angular.js.map +1 -1
- package/dist/index.cjs +370 -193
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +370 -193
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +374 -193
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +4 -0
- package/dist/react.d.ts +4 -0
- package/dist/react.js +374 -193
- package/dist/react.js.map +1 -1
- package/dist/vue.cjs +373 -194
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.d.cts +3 -1
- package/dist/vue.d.ts +3 -1
- package/dist/vue.js +373 -194
- package/dist/vue.js.map +1 -1
- package/package.json +1 -1
package/dist/react.js
CHANGED
|
@@ -3476,26 +3476,6 @@ var ExcelPlugin = class {
|
|
|
3476
3476
|
instance.zoomIn?.();
|
|
3477
3477
|
}
|
|
3478
3478
|
},
|
|
3479
|
-
{
|
|
3480
|
-
id: "fit-page",
|
|
3481
|
-
icon: "fit-page",
|
|
3482
|
-
label: "Fit to View",
|
|
3483
|
-
type: "button",
|
|
3484
|
-
group: "zoom",
|
|
3485
|
-
execute: () => {
|
|
3486
|
-
instance.fitToPage?.();
|
|
3487
|
-
}
|
|
3488
|
-
},
|
|
3489
|
-
{
|
|
3490
|
-
id: "rotate-cw",
|
|
3491
|
-
icon: "rotate-cw",
|
|
3492
|
-
label: "Rotate",
|
|
3493
|
-
type: "button",
|
|
3494
|
-
group: "view",
|
|
3495
|
-
execute: () => {
|
|
3496
|
-
instance.rotateCW?.();
|
|
3497
|
-
}
|
|
3498
|
-
},
|
|
3499
3479
|
{
|
|
3500
3480
|
id: "download",
|
|
3501
3481
|
icon: "download",
|
|
@@ -3556,12 +3536,11 @@ var ExcelPlugin = class {
|
|
|
3556
3536
|
container.appendChild(tabsArea);
|
|
3557
3537
|
ctx.container.appendChild(container);
|
|
3558
3538
|
let scale = 1;
|
|
3559
|
-
let rotation = 0;
|
|
3560
3539
|
let currentSheetIndex = 1;
|
|
3561
3540
|
let sheetNames = [];
|
|
3562
3541
|
let wb = null;
|
|
3563
3542
|
const applyTransform = () => {
|
|
3564
|
-
contentArea.style.transform = `scale(${scale})
|
|
3543
|
+
contentArea.style.transform = `scale(${scale})`;
|
|
3565
3544
|
contentArea.style.transformOrigin = "top left";
|
|
3566
3545
|
};
|
|
3567
3546
|
const calculateFitScale = () => {
|
|
@@ -3569,7 +3548,7 @@ var ExcelPlugin = class {
|
|
|
3569
3548
|
if (!table) return 1;
|
|
3570
3549
|
const availW = Math.max(280, container.clientWidth - 48);
|
|
3571
3550
|
const tW = table.offsetWidth || 800;
|
|
3572
|
-
return Math.max(0.
|
|
3551
|
+
return Math.max(0.4, Math.min(1, availW / tW));
|
|
3573
3552
|
};
|
|
3574
3553
|
try {
|
|
3575
3554
|
wb = XLSX.read(new Uint8Array(ctx.buffer), { type: "array", cellDates: true });
|
|
@@ -3624,7 +3603,16 @@ var ExcelPlugin = class {
|
|
|
3624
3603
|
}
|
|
3625
3604
|
});
|
|
3626
3605
|
ctx.emit("page-change", { page: currentSheetIndex, total: sheetNames.length });
|
|
3606
|
+
requestAnimationFrame(() => {
|
|
3607
|
+
scale = calculateFitScale();
|
|
3608
|
+
applyTransform();
|
|
3609
|
+
});
|
|
3627
3610
|
};
|
|
3611
|
+
const ro = new ResizeObserver(() => {
|
|
3612
|
+
scale = calculateFitScale();
|
|
3613
|
+
applyTransform();
|
|
3614
|
+
});
|
|
3615
|
+
ro.observe(container);
|
|
3628
3616
|
if (sheetNames.length > 0) {
|
|
3629
3617
|
sheetNames.forEach((name, idx) => {
|
|
3630
3618
|
const btn = document.createElement("button");
|
|
@@ -3651,6 +3639,7 @@ var ExcelPlugin = class {
|
|
|
3651
3639
|
`;
|
|
3652
3640
|
}
|
|
3653
3641
|
const cleanup = () => {
|
|
3642
|
+
ro.disconnect();
|
|
3654
3643
|
container.remove();
|
|
3655
3644
|
ctx.container.innerHTML = "";
|
|
3656
3645
|
};
|
|
@@ -3672,16 +3661,11 @@ var ExcelPlugin = class {
|
|
|
3672
3661
|
},
|
|
3673
3662
|
fitToPage: () => {
|
|
3674
3663
|
scale = calculateFitScale();
|
|
3675
|
-
rotation = 0;
|
|
3676
3664
|
applyTransform();
|
|
3677
3665
|
},
|
|
3678
3666
|
rotateCW: () => {
|
|
3679
|
-
rotation = (rotation + 90) % 360;
|
|
3680
|
-
applyTransform();
|
|
3681
3667
|
},
|
|
3682
3668
|
rotateCCW: () => {
|
|
3683
|
-
rotation = (rotation - 90 + 360) % 360;
|
|
3684
|
-
applyTransform();
|
|
3685
3669
|
},
|
|
3686
3670
|
goToPage: (page) => {
|
|
3687
3671
|
if (page > 0 && page <= sheetNames.length) {
|
|
@@ -3779,38 +3763,15 @@ var CsvPlugin = class {
|
|
|
3779
3763
|
return ext === ".csv" || ext === ".tsv" || mime === "text/csv" || mime === "text/tab-separated-values";
|
|
3780
3764
|
}
|
|
3781
3765
|
getToolbarActions(instance) {
|
|
3782
|
-
const totalPages = instance.getPageCount?.() ?? 1;
|
|
3783
3766
|
const actions = [];
|
|
3784
3767
|
actions.push({
|
|
3785
3768
|
id: "thumbnails",
|
|
3786
3769
|
icon: "thumbnails",
|
|
3787
|
-
label: "
|
|
3770
|
+
label: "Sheet Thumbnails",
|
|
3788
3771
|
type: "button",
|
|
3789
3772
|
group: "navigation",
|
|
3790
3773
|
execute: () => instance.toggleThumbnails?.()
|
|
3791
3774
|
});
|
|
3792
|
-
if (totalPages > 1) {
|
|
3793
|
-
actions.push({
|
|
3794
|
-
id: "page-nav",
|
|
3795
|
-
icon: "",
|
|
3796
|
-
label: "Page Navigation",
|
|
3797
|
-
type: "page-nav",
|
|
3798
|
-
group: "navigation",
|
|
3799
|
-
value: instance.getCurrentPage?.() ?? 1,
|
|
3800
|
-
max: totalPages,
|
|
3801
|
-
execute: (action, page) => {
|
|
3802
|
-
const cur = instance.getCurrentPage?.() ?? 1;
|
|
3803
|
-
const max = instance.getPageCount?.() ?? 1;
|
|
3804
|
-
if (action === "prev") {
|
|
3805
|
-
if (cur > 1) instance.goToPage?.(cur - 1);
|
|
3806
|
-
} else if (action === "next") {
|
|
3807
|
-
if (cur < max) instance.goToPage?.(cur + 1);
|
|
3808
|
-
} else if (typeof page === "number") {
|
|
3809
|
-
instance.goToPage?.(page);
|
|
3810
|
-
}
|
|
3811
|
-
}
|
|
3812
|
-
});
|
|
3813
|
-
}
|
|
3814
3775
|
actions.push(
|
|
3815
3776
|
{
|
|
3816
3777
|
id: "zoom-out",
|
|
@@ -3832,16 +3793,6 @@ var CsvPlugin = class {
|
|
|
3832
3793
|
instance.zoomIn?.();
|
|
3833
3794
|
}
|
|
3834
3795
|
},
|
|
3835
|
-
{
|
|
3836
|
-
id: "fit-page",
|
|
3837
|
-
icon: "fit-page",
|
|
3838
|
-
label: "Fit to View",
|
|
3839
|
-
type: "button",
|
|
3840
|
-
group: "zoom",
|
|
3841
|
-
execute: () => {
|
|
3842
|
-
instance.fitToPage?.();
|
|
3843
|
-
}
|
|
3844
|
-
},
|
|
3845
3796
|
{
|
|
3846
3797
|
id: "download",
|
|
3847
3798
|
icon: "download",
|
|
@@ -3884,131 +3835,135 @@ var CsvPlugin = class {
|
|
|
3884
3835
|
container.style.overflow = "auto";
|
|
3885
3836
|
container.style.padding = "16px";
|
|
3886
3837
|
container.style.boxSizing = "border-box";
|
|
3887
|
-
|
|
3838
|
+
const tableWrapper = document.createElement("div");
|
|
3839
|
+
tableWrapper.style.transformOrigin = "top left";
|
|
3888
3840
|
const delimiter = ctx.metadata.extension === ".tsv" ? " " : ",";
|
|
3889
3841
|
const allLines = text.split(/\r?\n/).filter((r) => r.trim().length > 0);
|
|
3890
3842
|
const headerLine = allLines[0] || "";
|
|
3891
3843
|
const headerCells = headerLine.split(delimiter);
|
|
3892
3844
|
const dataLines = allLines.slice(1);
|
|
3893
|
-
const ROWS_PER_PAGE = 100;
|
|
3894
|
-
const totalPages = Math.max(1, Math.ceil(dataLines.length / ROWS_PER_PAGE));
|
|
3895
|
-
let currentPage = 1;
|
|
3896
3845
|
const table = document.createElement("table");
|
|
3897
3846
|
table.style.borderCollapse = "collapse";
|
|
3898
|
-
table.style.
|
|
3847
|
+
table.style.minWidth = "100%";
|
|
3899
3848
|
table.style.fontFamily = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, monospace';
|
|
3900
3849
|
table.style.fontSize = "13px";
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
const
|
|
3917
|
-
|
|
3918
|
-
const
|
|
3919
|
-
|
|
3920
|
-
const
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
td.style.border = "1px solid #d0d7de";
|
|
3927
|
-
td.style.padding = "6px 12px";
|
|
3928
|
-
td.style.whiteSpace = "nowrap";
|
|
3929
|
-
tr.appendChild(td);
|
|
3930
|
-
});
|
|
3931
|
-
table.appendChild(tr);
|
|
3850
|
+
table.style.background = "#ffffff";
|
|
3851
|
+
table.style.border = "1px solid #d0d7de";
|
|
3852
|
+
const headerTr = document.createElement("tr");
|
|
3853
|
+
headerCells.forEach((cell) => {
|
|
3854
|
+
const th = document.createElement("th");
|
|
3855
|
+
th.textContent = cell.trim();
|
|
3856
|
+
th.style.border = "1px solid #d0d7de";
|
|
3857
|
+
th.style.padding = "8px 12px";
|
|
3858
|
+
th.style.backgroundColor = "#f6f8fa";
|
|
3859
|
+
th.style.fontWeight = "600";
|
|
3860
|
+
th.style.whiteSpace = "nowrap";
|
|
3861
|
+
headerTr.appendChild(th);
|
|
3862
|
+
});
|
|
3863
|
+
table.appendChild(headerTr);
|
|
3864
|
+
dataLines.forEach((row, idx) => {
|
|
3865
|
+
const tr = document.createElement("tr");
|
|
3866
|
+
if (idx % 2 === 1) tr.style.backgroundColor = "#f8fafc";
|
|
3867
|
+
const cells = row.split(delimiter);
|
|
3868
|
+
cells.forEach((cell) => {
|
|
3869
|
+
const td = document.createElement("td");
|
|
3870
|
+
td.textContent = cell.trim();
|
|
3871
|
+
td.style.border = "1px solid #d0d7de";
|
|
3872
|
+
td.style.padding = "6px 12px";
|
|
3873
|
+
td.style.whiteSpace = "nowrap";
|
|
3874
|
+
tr.appendChild(td);
|
|
3932
3875
|
});
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
container.appendChild(table);
|
|
3876
|
+
table.appendChild(tr);
|
|
3877
|
+
});
|
|
3878
|
+
tableWrapper.appendChild(table);
|
|
3879
|
+
container.appendChild(tableWrapper);
|
|
3938
3880
|
ctx.container.appendChild(container);
|
|
3939
3881
|
let scale = 1;
|
|
3882
|
+
const calculateFitScale = () => {
|
|
3883
|
+
const availW = Math.max(280, container.clientWidth - 48);
|
|
3884
|
+
const tW = table.offsetWidth || 800;
|
|
3885
|
+
return Math.max(0.4, Math.min(1, availW / tW));
|
|
3886
|
+
};
|
|
3940
3887
|
const applyScale = () => {
|
|
3941
|
-
|
|
3942
|
-
container.style.transformOrigin = "top left";
|
|
3888
|
+
tableWrapper.style.transform = `scale(${scale})`;
|
|
3943
3889
|
};
|
|
3890
|
+
requestAnimationFrame(() => {
|
|
3891
|
+
scale = calculateFitScale();
|
|
3892
|
+
applyScale();
|
|
3893
|
+
});
|
|
3894
|
+
const ro = new ResizeObserver(() => {
|
|
3895
|
+
scale = calculateFitScale();
|
|
3896
|
+
applyScale();
|
|
3897
|
+
});
|
|
3898
|
+
ro.observe(container);
|
|
3944
3899
|
const cleanup = () => {
|
|
3900
|
+
ro.disconnect();
|
|
3945
3901
|
container.remove();
|
|
3946
3902
|
ctx.container.innerHTML = "";
|
|
3947
3903
|
};
|
|
3948
3904
|
ctx.signal.addEventListener("abort", cleanup);
|
|
3949
3905
|
return {
|
|
3950
3906
|
destroy: cleanup,
|
|
3951
|
-
getPageCount: () =>
|
|
3952
|
-
getCurrentPage: () =>
|
|
3953
|
-
goToPage: (
|
|
3907
|
+
getPageCount: () => 1,
|
|
3908
|
+
getCurrentPage: () => 1,
|
|
3909
|
+
goToPage: () => {
|
|
3910
|
+
},
|
|
3954
3911
|
getThumbnails: () => {
|
|
3955
|
-
const
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
c.
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
c.fillText(val.trim().slice(0, 6), 8 + ci * colW, y + 9);
|
|
3912
|
+
const sheetName = ctx.metadata.name?.replace(/\.[^/.]+$/, "") || "Sheet1";
|
|
3913
|
+
return [{
|
|
3914
|
+
index: 0,
|
|
3915
|
+
label: sheetName,
|
|
3916
|
+
render: async (canvas) => {
|
|
3917
|
+
canvas.width = 140;
|
|
3918
|
+
canvas.height = 100;
|
|
3919
|
+
const c = canvas.getContext("2d");
|
|
3920
|
+
if (!c) return;
|
|
3921
|
+
c.fillStyle = "#ffffff";
|
|
3922
|
+
c.fillRect(0, 0, canvas.width, canvas.height);
|
|
3923
|
+
c.fillStyle = "#107c41";
|
|
3924
|
+
c.fillRect(0, 0, canvas.width, 16);
|
|
3925
|
+
c.fillStyle = "#ffffff";
|
|
3926
|
+
c.font = 'bold 8px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
3927
|
+
c.fillText(`\u{1F4CA} ${sheetName.slice(0, 16)}`, 6, 11);
|
|
3928
|
+
const startY = 17;
|
|
3929
|
+
const rowH = 13;
|
|
3930
|
+
const colW = 30;
|
|
3931
|
+
const cols = headerCells.slice(0, 4).map((h) => h.trim() || "Col");
|
|
3932
|
+
c.fillStyle = "#f1f5f9";
|
|
3933
|
+
c.fillRect(0, startY, canvas.width, rowH);
|
|
3934
|
+
c.strokeStyle = "#cbd5e1";
|
|
3935
|
+
c.lineWidth = 0.8;
|
|
3936
|
+
c.strokeRect(0, startY, canvas.width, rowH);
|
|
3937
|
+
c.fillStyle = "#64748b";
|
|
3938
|
+
c.font = "bold 7px sans-serif";
|
|
3939
|
+
for (let ci = 0; ci < cols.length; ci++) {
|
|
3940
|
+
c.fillText(cols[ci].slice(0, 5), 14 + ci * colW, startY + 9);
|
|
3941
|
+
}
|
|
3942
|
+
for (let ri = 0; ri < Math.min(5, dataLines.length); ri++) {
|
|
3943
|
+
const y = startY + (ri + 1) * rowH;
|
|
3944
|
+
if (y > canvas.height - 2) break;
|
|
3945
|
+
c.fillStyle = "#f8fafc";
|
|
3946
|
+
c.fillRect(0, y, 12, rowH);
|
|
3947
|
+
c.fillStyle = "#94a3b8";
|
|
3948
|
+
c.font = "6px sans-serif";
|
|
3949
|
+
c.fillText(String(ri + 1), 3, y + 9);
|
|
3950
|
+
c.strokeStyle = "#e2e8f0";
|
|
3951
|
+
c.strokeRect(0, y, canvas.width, rowH);
|
|
3952
|
+
const rowCells = dataLines[ri].split(delimiter);
|
|
3953
|
+
c.fillStyle = "#334155";
|
|
3954
|
+
c.font = "6px sans-serif";
|
|
3955
|
+
for (let ci = 0; ci < cols.length; ci++) {
|
|
3956
|
+
const val = (rowCells[ci] || "").trim();
|
|
3957
|
+
if (val) {
|
|
3958
|
+
c.fillText(val.slice(0, 6), 14 + ci * colW, y + 9);
|
|
4003
3959
|
}
|
|
4004
3960
|
}
|
|
4005
|
-
c.strokeStyle = "#cbd5e1";
|
|
4006
|
-
c.lineWidth = 1;
|
|
4007
|
-
c.strokeRect(0.5, 0.5, canvas.width - 1, canvas.height - 1);
|
|
4008
3961
|
}
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
3962
|
+
c.strokeStyle = "#cbd5e1";
|
|
3963
|
+
c.lineWidth = 1;
|
|
3964
|
+
c.strokeRect(0.5, 0.5, canvas.width - 1, canvas.height - 1);
|
|
3965
|
+
}
|
|
3966
|
+
}];
|
|
4012
3967
|
},
|
|
4013
3968
|
zoomIn: () => {
|
|
4014
3969
|
scale += 0.1;
|
|
@@ -4024,11 +3979,13 @@ var CsvPlugin = class {
|
|
|
4024
3979
|
applyScale();
|
|
4025
3980
|
},
|
|
4026
3981
|
fitToPage: () => {
|
|
4027
|
-
|
|
4028
|
-
const tW = table.offsetWidth || 600;
|
|
4029
|
-
scale = Math.max(0.35, Math.min(1, availW / tW));
|
|
3982
|
+
scale = calculateFitScale();
|
|
4030
3983
|
applyScale();
|
|
4031
3984
|
},
|
|
3985
|
+
rotateCW: () => {
|
|
3986
|
+
},
|
|
3987
|
+
rotateCCW: () => {
|
|
3988
|
+
},
|
|
4032
3989
|
download: () => {
|
|
4033
3990
|
const blob = new Blob([ctx.buffer], { type: "text/csv" });
|
|
4034
3991
|
const url = URL.createObjectURL(blob);
|
|
@@ -4140,26 +4097,6 @@ var CodePlugin = class {
|
|
|
4140
4097
|
instance.zoomIn?.();
|
|
4141
4098
|
}
|
|
4142
4099
|
},
|
|
4143
|
-
{
|
|
4144
|
-
id: "fit-page",
|
|
4145
|
-
icon: "fit-page",
|
|
4146
|
-
label: "Fit to View",
|
|
4147
|
-
type: "button",
|
|
4148
|
-
group: "zoom",
|
|
4149
|
-
execute: () => {
|
|
4150
|
-
instance.fitToPage?.();
|
|
4151
|
-
}
|
|
4152
|
-
},
|
|
4153
|
-
{
|
|
4154
|
-
id: "rotate-cw",
|
|
4155
|
-
icon: "rotate-cw",
|
|
4156
|
-
label: "Rotate",
|
|
4157
|
-
type: "button",
|
|
4158
|
-
group: "view",
|
|
4159
|
-
execute: () => {
|
|
4160
|
-
instance.rotateCW?.();
|
|
4161
|
-
}
|
|
4162
|
-
},
|
|
4163
4100
|
{
|
|
4164
4101
|
id: "copy",
|
|
4165
4102
|
icon: "copy",
|
|
@@ -5303,6 +5240,148 @@ var ThreeDPlugin = class {
|
|
|
5303
5240
|
function threeDPlugin() {
|
|
5304
5241
|
return new ThreeDPlugin();
|
|
5305
5242
|
}
|
|
5243
|
+
function cleanRtfText(raw) {
|
|
5244
|
+
return raw.replace(/\\bin\d+\s/g, "").replace(/{\\\*[^}]+}/g, "").replace(/\\u(-?\d+)\??/g, (_, code) => {
|
|
5245
|
+
let num = parseInt(code, 10);
|
|
5246
|
+
if (num < 0) num += 65536;
|
|
5247
|
+
return String.fromCharCode(num);
|
|
5248
|
+
}).replace(/\\'([0-9a-fA-F]{2})/g, (_, hex) => {
|
|
5249
|
+
return String.fromCharCode(parseInt(hex, 16));
|
|
5250
|
+
}).replace(/\\tab\b/g, " ").replace(/\\emdash\b/g, "\u2014").replace(/\\endash\b/g, "\u2013").replace(/\\bullet\b/g, "\u2022").replace(/\\lquote\b/g, "\u2018").replace(/\\rquote\b/g, "\u2019").replace(/\\ldblquote\b/g, "\u201C").replace(/\\rdblquote\b/g, "\u201D").replace(/\\\w+(?:-?\d+)?\s?/g, " ").replace(/[{}\r\n]/g, " ").replace(/\s+/g, " ").trim();
|
|
5251
|
+
}
|
|
5252
|
+
function parseRtfTables(rtfText) {
|
|
5253
|
+
const rowSegments = rtfText.split(/\\row\b/);
|
|
5254
|
+
if (rowSegments.length <= 1) return [];
|
|
5255
|
+
const rawTables = [];
|
|
5256
|
+
let currentTable = null;
|
|
5257
|
+
let charOffset = 0;
|
|
5258
|
+
for (let i = 0; i < rowSegments.length - 1; i++) {
|
|
5259
|
+
const segment = rowSegments[i];
|
|
5260
|
+
const segmentStart = charOffset;
|
|
5261
|
+
const segmentEnd = charOffset + segment.length + 4;
|
|
5262
|
+
const cellParts = segment.split(/\\cell\b/);
|
|
5263
|
+
if (cellParts.length > 1) {
|
|
5264
|
+
const cellxMatches = [...segment.matchAll(/\\cellx(\d+)/g)].map((m) => parseInt(m[1], 10));
|
|
5265
|
+
let cellWidths = [];
|
|
5266
|
+
if (cellxMatches.length > 0) {
|
|
5267
|
+
let seq = [cellxMatches[0]];
|
|
5268
|
+
for (let k = 1; k < cellxMatches.length; k++) {
|
|
5269
|
+
if (cellxMatches[k] > cellxMatches[k - 1]) seq.push(cellxMatches[k]);
|
|
5270
|
+
else break;
|
|
5271
|
+
}
|
|
5272
|
+
let prev = 0;
|
|
5273
|
+
cellWidths = seq.map((x) => {
|
|
5274
|
+
const w = x - prev;
|
|
5275
|
+
prev = x;
|
|
5276
|
+
return w;
|
|
5277
|
+
});
|
|
5278
|
+
}
|
|
5279
|
+
const cells = [];
|
|
5280
|
+
for (let c = 0; c < cellParts.length - 1; c++) {
|
|
5281
|
+
let rawCell = cellParts[c];
|
|
5282
|
+
if (c === 0) {
|
|
5283
|
+
const lastTrowd = rawCell.lastIndexOf("\\trowd");
|
|
5284
|
+
if (lastTrowd !== -1) rawCell = rawCell.slice(lastTrowd);
|
|
5285
|
+
}
|
|
5286
|
+
cells.push(cleanRtfText(rawCell));
|
|
5287
|
+
}
|
|
5288
|
+
const isNewTable = !currentTable || segmentStart - currentTable.lastEnd > 2500;
|
|
5289
|
+
if (isNewTable) {
|
|
5290
|
+
const prevTextSlice = rtfText.slice(Math.max(0, segmentStart - 4e3), segmentStart);
|
|
5291
|
+
const cleanPrev = cleanRtfText(prevTextSlice);
|
|
5292
|
+
const anchorBefore = cleanPrev.slice(-80).trim();
|
|
5293
|
+
currentTable = {
|
|
5294
|
+
id: `RTF_TABLE_${rawTables.length}`,
|
|
5295
|
+
startPos: segmentStart,
|
|
5296
|
+
lastEnd: segmentEnd,
|
|
5297
|
+
rows: [],
|
|
5298
|
+
columnWidths: cellWidths,
|
|
5299
|
+
anchorBefore,
|
|
5300
|
+
anchorAfter: ""
|
|
5301
|
+
};
|
|
5302
|
+
rawTables.push(currentTable);
|
|
5303
|
+
}
|
|
5304
|
+
if (currentTable) {
|
|
5305
|
+
currentTable.rows.push({
|
|
5306
|
+
cells,
|
|
5307
|
+
widths: cellWidths.length === cells.length ? cellWidths : currentTable.columnWidths
|
|
5308
|
+
});
|
|
5309
|
+
currentTable.lastEnd = segmentEnd;
|
|
5310
|
+
}
|
|
5311
|
+
}
|
|
5312
|
+
charOffset += segment.length + 4;
|
|
5313
|
+
}
|
|
5314
|
+
rawTables.forEach((tbl) => {
|
|
5315
|
+
const afterSlice = rtfText.slice(tbl.lastEnd, Math.min(rtfText.length, tbl.lastEnd + 2e3));
|
|
5316
|
+
const cleanAfter = cleanRtfText(afterSlice);
|
|
5317
|
+
tbl.anchorAfter = cleanAfter.slice(0, 80).trim();
|
|
5318
|
+
});
|
|
5319
|
+
return rawTables.map((tbl) => {
|
|
5320
|
+
const totalW = (tbl.columnWidths || []).reduce((a, b) => a + b, 0);
|
|
5321
|
+
const colPercents = totalW > 0 ? tbl.columnWidths.map((w) => Math.round(w / totalW * 100)) : [];
|
|
5322
|
+
return {
|
|
5323
|
+
id: tbl.id,
|
|
5324
|
+
rows: tbl.rows.map((r) => r.cells),
|
|
5325
|
+
colPercents,
|
|
5326
|
+
anchorBefore: tbl.anchorBefore,
|
|
5327
|
+
anchorAfter: tbl.anchorAfter
|
|
5328
|
+
};
|
|
5329
|
+
});
|
|
5330
|
+
}
|
|
5331
|
+
function renderRtfTableElement(table) {
|
|
5332
|
+
const tableEl = document.createElement("table");
|
|
5333
|
+
tableEl.className = "fp-rtf-table";
|
|
5334
|
+
tableEl.style.width = "100%";
|
|
5335
|
+
tableEl.style.borderCollapse = "collapse";
|
|
5336
|
+
tableEl.style.margin = "16px 0 20px";
|
|
5337
|
+
tableEl.style.fontSize = "10pt";
|
|
5338
|
+
tableEl.style.lineHeight = "1.5";
|
|
5339
|
+
tableEl.style.border = "1px solid #cbd5e1";
|
|
5340
|
+
tableEl.style.borderRadius = "4px";
|
|
5341
|
+
tableEl.style.boxSizing = "border-box";
|
|
5342
|
+
tableEl.style.backgroundColor = "#ffffff";
|
|
5343
|
+
const thead = document.createElement("thead");
|
|
5344
|
+
const tbody = document.createElement("tbody");
|
|
5345
|
+
table.rows.forEach((rowCells, rIdx) => {
|
|
5346
|
+
const tr = document.createElement("tr");
|
|
5347
|
+
const isHeader = rIdx === 0;
|
|
5348
|
+
if (isHeader) {
|
|
5349
|
+
tr.style.backgroundColor = "#f8fafc";
|
|
5350
|
+
tr.style.borderBottom = "2px solid #cbd5e1";
|
|
5351
|
+
} else {
|
|
5352
|
+
tr.style.borderBottom = "1px solid #e2e8f0";
|
|
5353
|
+
if (rIdx % 2 === 0) {
|
|
5354
|
+
tr.style.backgroundColor = "#fcfdfe";
|
|
5355
|
+
}
|
|
5356
|
+
}
|
|
5357
|
+
rowCells.forEach((cellText, cIdx) => {
|
|
5358
|
+
const cellEl = document.createElement(isHeader ? "th" : "td");
|
|
5359
|
+
cellEl.style.padding = "8px 12px";
|
|
5360
|
+
cellEl.style.border = "1px solid #cbd5e1";
|
|
5361
|
+
cellEl.style.verticalAlign = "top";
|
|
5362
|
+
cellEl.style.color = isHeader ? "#0f172a" : "#1e293b";
|
|
5363
|
+
cellEl.style.fontWeight = isHeader ? "600" : "normal";
|
|
5364
|
+
if (table.colPercents && table.colPercents[cIdx]) {
|
|
5365
|
+
cellEl.style.width = `${table.colPercents[cIdx]}%`;
|
|
5366
|
+
}
|
|
5367
|
+
if (/^\d+$/.test(cellText.trim()) || cellText.trim() === "#") {
|
|
5368
|
+
cellEl.style.textAlign = "center";
|
|
5369
|
+
} else {
|
|
5370
|
+
cellEl.style.textAlign = "left";
|
|
5371
|
+
}
|
|
5372
|
+
cellEl.textContent = cellText;
|
|
5373
|
+
tr.appendChild(cellEl);
|
|
5374
|
+
});
|
|
5375
|
+
if (isHeader) {
|
|
5376
|
+
thead.appendChild(tr);
|
|
5377
|
+
} else {
|
|
5378
|
+
tbody.appendChild(tr);
|
|
5379
|
+
}
|
|
5380
|
+
});
|
|
5381
|
+
tableEl.appendChild(thead);
|
|
5382
|
+
tableEl.appendChild(tbody);
|
|
5383
|
+
return tableEl;
|
|
5384
|
+
}
|
|
5306
5385
|
var RtfPlugin = class {
|
|
5307
5386
|
id = "rtf";
|
|
5308
5387
|
name = "Rich Text Format (RTF)";
|
|
@@ -5338,6 +5417,14 @@ var RtfPlugin = class {
|
|
|
5338
5417
|
}
|
|
5339
5418
|
});
|
|
5340
5419
|
actions.push(
|
|
5420
|
+
{
|
|
5421
|
+
id: "thumbnails",
|
|
5422
|
+
icon: "thumbnails",
|
|
5423
|
+
label: "Thumbnails",
|
|
5424
|
+
type: "button",
|
|
5425
|
+
group: "view",
|
|
5426
|
+
execute: () => instance.toggleThumbnails?.()
|
|
5427
|
+
},
|
|
5341
5428
|
{
|
|
5342
5429
|
id: "zoom-out",
|
|
5343
5430
|
icon: "zoom-out",
|
|
@@ -5465,6 +5552,8 @@ var RtfPlugin = class {
|
|
|
5465
5552
|
if (typeof RTFJS.loggingEnabled === "function") {
|
|
5466
5553
|
RTFJS.loggingEnabled(false);
|
|
5467
5554
|
}
|
|
5555
|
+
const rawText = new TextDecoder("latin1").decode(ctx.buffer);
|
|
5556
|
+
const tables = parseRtfTables(rawText);
|
|
5468
5557
|
const doc = new RTFJS.Document(ctx.buffer, {});
|
|
5469
5558
|
const htmlElements = await doc.render();
|
|
5470
5559
|
const contentNodes = [];
|
|
@@ -5479,6 +5568,20 @@ var RtfPlugin = class {
|
|
|
5479
5568
|
if (hasChildBlocks && !["table", "tr", "td", "th", "ul", "ol", "li"].includes(tag)) {
|
|
5480
5569
|
extractBlocks(Array.from(item.children));
|
|
5481
5570
|
} else {
|
|
5571
|
+
const svgs = item.querySelectorAll("svg, img");
|
|
5572
|
+
svgs.forEach((s) => {
|
|
5573
|
+
const el = s;
|
|
5574
|
+
el.style.maxWidth = "100%";
|
|
5575
|
+
el.style.maxHeight = "360px";
|
|
5576
|
+
el.style.display = "block";
|
|
5577
|
+
el.style.margin = "12px auto";
|
|
5578
|
+
if (s.tagName.toLowerCase() === "svg") {
|
|
5579
|
+
s.removeAttribute("width");
|
|
5580
|
+
s.removeAttribute("height");
|
|
5581
|
+
el.style.width = "100%";
|
|
5582
|
+
el.style.maxHeight = "360px";
|
|
5583
|
+
}
|
|
5584
|
+
});
|
|
5482
5585
|
if (tag === "p" || tag === "div") {
|
|
5483
5586
|
item.style.display = "block";
|
|
5484
5587
|
item.style.marginBottom = "12px";
|
|
@@ -5489,14 +5592,46 @@ var RtfPlugin = class {
|
|
|
5489
5592
|
}
|
|
5490
5593
|
};
|
|
5491
5594
|
extractBlocks(htmlElements);
|
|
5595
|
+
tables.forEach((table) => {
|
|
5596
|
+
const tableEl = renderRtfTableElement(table);
|
|
5597
|
+
let inserted = false;
|
|
5598
|
+
if (table.anchorBefore && table.anchorBefore.length > 10) {
|
|
5599
|
+
const keyword = table.anchorBefore.slice(-35).trim();
|
|
5600
|
+
for (let i = 0; i < contentNodes.length; i++) {
|
|
5601
|
+
if (contentNodes[i].textContent?.includes(keyword)) {
|
|
5602
|
+
contentNodes.splice(i + 1, 0, tableEl);
|
|
5603
|
+
inserted = true;
|
|
5604
|
+
break;
|
|
5605
|
+
}
|
|
5606
|
+
}
|
|
5607
|
+
}
|
|
5608
|
+
if (!inserted && table.anchorAfter && table.anchorAfter.length > 10) {
|
|
5609
|
+
const keyword = table.anchorAfter.slice(0, 35).trim();
|
|
5610
|
+
for (let i = 0; i < contentNodes.length; i++) {
|
|
5611
|
+
if (contentNodes[i].textContent?.includes(keyword)) {
|
|
5612
|
+
contentNodes.splice(i, 0, tableEl);
|
|
5613
|
+
inserted = true;
|
|
5614
|
+
break;
|
|
5615
|
+
}
|
|
5616
|
+
}
|
|
5617
|
+
}
|
|
5618
|
+
if (!inserted) {
|
|
5619
|
+
if (contentNodes.length > 2) {
|
|
5620
|
+
contentNodes.splice(2, 0, tableEl);
|
|
5621
|
+
} else {
|
|
5622
|
+
contentNodes.push(tableEl);
|
|
5623
|
+
}
|
|
5624
|
+
}
|
|
5625
|
+
});
|
|
5492
5626
|
wrapper.innerHTML = "";
|
|
5493
5627
|
contentNodes.forEach((node) => wrapper.appendChild(node));
|
|
5494
5628
|
const childHeights = contentNodes.map((c) => {
|
|
5495
5629
|
const rectH = c.getBoundingClientRect ? c.getBoundingClientRect().height : 0;
|
|
5496
5630
|
const offH = c.offsetHeight || 0;
|
|
5631
|
+
const realH = Math.max(rectH, offH);
|
|
5632
|
+
if (realH > 0) return realH;
|
|
5497
5633
|
const textLen = c.textContent?.trim().length || 0;
|
|
5498
|
-
|
|
5499
|
-
return Math.max(rectH, offH, estH);
|
|
5634
|
+
return Math.max(24, Math.ceil(textLen / 95) * 22 + 12);
|
|
5500
5635
|
});
|
|
5501
5636
|
wrapper.innerHTML = "";
|
|
5502
5637
|
const createRtfCard = () => {
|
|
@@ -5505,7 +5640,7 @@ var RtfPlugin = class {
|
|
|
5505
5640
|
card.style.backgroundColor = "#ffffff";
|
|
5506
5641
|
card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08)";
|
|
5507
5642
|
card.style.borderRadius = "4px";
|
|
5508
|
-
card.style.padding = "
|
|
5643
|
+
card.style.padding = "64px 56px";
|
|
5509
5644
|
card.style.width = "816px";
|
|
5510
5645
|
card.style.minHeight = "1056px";
|
|
5511
5646
|
card.style.boxSizing = "border-box";
|
|
@@ -5519,22 +5654,35 @@ var RtfPlugin = class {
|
|
|
5519
5654
|
wrapper.appendChild(curCard);
|
|
5520
5655
|
pageElements = [curCard];
|
|
5521
5656
|
let curH = 0;
|
|
5522
|
-
const maxH =
|
|
5657
|
+
const maxH = 928;
|
|
5523
5658
|
for (let i = 0; i < contentNodes.length; i++) {
|
|
5524
5659
|
const child = contentNodes[i];
|
|
5525
5660
|
const chH = childHeights[i];
|
|
5526
|
-
|
|
5527
|
-
curH
|
|
5528
|
-
|
|
5661
|
+
const isChildEmpty = (child.textContent || "").trim().length === 0 && !child.querySelector("table, img, svg, canvas");
|
|
5662
|
+
if (curH === 0 && isChildEmpty) {
|
|
5663
|
+
continue;
|
|
5664
|
+
}
|
|
5665
|
+
if (curH + chH > maxH && curCard.childNodes.length > 0) {
|
|
5529
5666
|
curCard = createRtfCard();
|
|
5530
5667
|
wrapper.appendChild(curCard);
|
|
5531
5668
|
pageElements.push(curCard);
|
|
5532
5669
|
curH = 0;
|
|
5533
5670
|
}
|
|
5671
|
+
curCard.appendChild(child);
|
|
5672
|
+
curH += chH;
|
|
5673
|
+
}
|
|
5674
|
+
pageElements = pageElements.filter((card) => {
|
|
5675
|
+
const hasText = (card.textContent || "").trim().length > 0;
|
|
5676
|
+
const hasMedia = card.querySelector("table, img, svg, canvas") !== null;
|
|
5677
|
+
return hasText || hasMedia;
|
|
5678
|
+
});
|
|
5679
|
+
if (pageElements.length === 0) {
|
|
5680
|
+
pageElements = [curCard];
|
|
5534
5681
|
}
|
|
5535
5682
|
} catch (err) {
|
|
5536
5683
|
console.warn("[RtfPlugin] RTF render error, fallback text:", err);
|
|
5537
5684
|
const text = new TextDecoder("latin1").decode(ctx.buffer);
|
|
5685
|
+
const tables = parseRtfTables(text);
|
|
5538
5686
|
const rawPages = text.split(/\\page\b/).map((segment) => {
|
|
5539
5687
|
return segment.replace(/\\par[d]?/g, "\n").replace(/\\[a-zA-Z0-9\-]+/g, "").replace(/[{}]/g, "").trim();
|
|
5540
5688
|
}).filter((p) => p.length > 0);
|
|
@@ -5545,7 +5693,7 @@ var RtfPlugin = class {
|
|
|
5545
5693
|
pageCard.style.backgroundColor = "#ffffff";
|
|
5546
5694
|
pageCard.style.boxShadow = "0 2px 12px rgba(0,0,0,0.08)";
|
|
5547
5695
|
pageCard.style.borderRadius = "4px";
|
|
5548
|
-
pageCard.style.padding = "
|
|
5696
|
+
pageCard.style.padding = "64px 56px";
|
|
5549
5697
|
pageCard.style.width = "816px";
|
|
5550
5698
|
pageCard.style.minHeight = "1056px";
|
|
5551
5699
|
pageCard.style.boxSizing = "border-box";
|
|
@@ -5556,6 +5704,9 @@ var RtfPlugin = class {
|
|
|
5556
5704
|
pageCard.style.whiteSpace = "pre-wrap";
|
|
5557
5705
|
pageCard.style.display = i === 0 ? "block" : "none";
|
|
5558
5706
|
pageCard.textContent = pages[i];
|
|
5707
|
+
if (i === 1 && tables.length > 0) {
|
|
5708
|
+
tables.forEach((tbl) => pageCard.appendChild(renderRtfTableElement(tbl)));
|
|
5709
|
+
}
|
|
5559
5710
|
wrapper.appendChild(pageCard);
|
|
5560
5711
|
pageElements.push(pageCard);
|
|
5561
5712
|
}
|
|
@@ -5586,6 +5737,32 @@ var RtfPlugin = class {
|
|
|
5586
5737
|
getPageCount: () => totalPages,
|
|
5587
5738
|
getCurrentPage: () => currentPage,
|
|
5588
5739
|
goToPage: (page) => showPage(page),
|
|
5740
|
+
getThumbnails: async () => {
|
|
5741
|
+
const items = [];
|
|
5742
|
+
for (let idx = 0; idx < totalPages; idx++) {
|
|
5743
|
+
const pageIdx = idx;
|
|
5744
|
+
items.push({
|
|
5745
|
+
index: pageIdx,
|
|
5746
|
+
label: `Page ${pageIdx + 1}`,
|
|
5747
|
+
render: async (canvas) => {
|
|
5748
|
+
const ctx2d = canvas.getContext("2d");
|
|
5749
|
+
if (!ctx2d) return;
|
|
5750
|
+
canvas.width = 140;
|
|
5751
|
+
canvas.height = 180;
|
|
5752
|
+
ctx2d.fillStyle = "#ffffff";
|
|
5753
|
+
ctx2d.fillRect(0, 0, 140, 180);
|
|
5754
|
+
ctx2d.strokeStyle = "#cbd5e1";
|
|
5755
|
+
ctx2d.lineWidth = 1;
|
|
5756
|
+
ctx2d.strokeRect(0.5, 0.5, 139, 179);
|
|
5757
|
+
ctx2d.fillStyle = "#334155";
|
|
5758
|
+
ctx2d.font = 'bold 11px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
5759
|
+
ctx2d.textAlign = "center";
|
|
5760
|
+
ctx2d.fillText(`Page ${pageIdx + 1}`, 70, 95);
|
|
5761
|
+
}
|
|
5762
|
+
});
|
|
5763
|
+
}
|
|
5764
|
+
return items;
|
|
5765
|
+
},
|
|
5589
5766
|
zoomIn: () => {
|
|
5590
5767
|
isUserZoomed = true;
|
|
5591
5768
|
scale += 0.15;
|
|
@@ -7623,6 +7800,8 @@ var FilePreview = memo(forwardRef(
|
|
|
7623
7800
|
onError,
|
|
7624
7801
|
onPageChange,
|
|
7625
7802
|
onZoomChange,
|
|
7803
|
+
onRotate,
|
|
7804
|
+
onDestroy,
|
|
7626
7805
|
className,
|
|
7627
7806
|
style
|
|
7628
7807
|
}, ref) => {
|
|
@@ -7645,6 +7824,8 @@ var FilePreview = memo(forwardRef(
|
|
|
7645
7824
|
if (onError) unsubs.push(viewer.on("error", (e) => onError(e instanceof Error ? e : new Error(String(e)))));
|
|
7646
7825
|
if (onPageChange) unsubs.push(viewer.on("page-change", onPageChange));
|
|
7647
7826
|
if (onZoomChange) unsubs.push(viewer.on("zoom-change", onZoomChange));
|
|
7827
|
+
if (onRotate) unsubs.push(viewer.on("rotate", onRotate));
|
|
7828
|
+
if (onDestroy) unsubs.push(viewer.on("destroy", onDestroy));
|
|
7648
7829
|
return () => {
|
|
7649
7830
|
unsubs.forEach((fn) => fn());
|
|
7650
7831
|
viewer.destroy();
|