@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.cjs
CHANGED
|
@@ -3509,26 +3509,6 @@ var ExcelPlugin = class {
|
|
|
3509
3509
|
instance.zoomIn?.();
|
|
3510
3510
|
}
|
|
3511
3511
|
},
|
|
3512
|
-
{
|
|
3513
|
-
id: "fit-page",
|
|
3514
|
-
icon: "fit-page",
|
|
3515
|
-
label: "Fit to View",
|
|
3516
|
-
type: "button",
|
|
3517
|
-
group: "zoom",
|
|
3518
|
-
execute: () => {
|
|
3519
|
-
instance.fitToPage?.();
|
|
3520
|
-
}
|
|
3521
|
-
},
|
|
3522
|
-
{
|
|
3523
|
-
id: "rotate-cw",
|
|
3524
|
-
icon: "rotate-cw",
|
|
3525
|
-
label: "Rotate",
|
|
3526
|
-
type: "button",
|
|
3527
|
-
group: "view",
|
|
3528
|
-
execute: () => {
|
|
3529
|
-
instance.rotateCW?.();
|
|
3530
|
-
}
|
|
3531
|
-
},
|
|
3532
3512
|
{
|
|
3533
3513
|
id: "download",
|
|
3534
3514
|
icon: "download",
|
|
@@ -3589,12 +3569,11 @@ var ExcelPlugin = class {
|
|
|
3589
3569
|
container.appendChild(tabsArea);
|
|
3590
3570
|
ctx.container.appendChild(container);
|
|
3591
3571
|
let scale = 1;
|
|
3592
|
-
let rotation = 0;
|
|
3593
3572
|
let currentSheetIndex = 1;
|
|
3594
3573
|
let sheetNames = [];
|
|
3595
3574
|
let wb = null;
|
|
3596
3575
|
const applyTransform = () => {
|
|
3597
|
-
contentArea.style.transform = `scale(${scale})
|
|
3576
|
+
contentArea.style.transform = `scale(${scale})`;
|
|
3598
3577
|
contentArea.style.transformOrigin = "top left";
|
|
3599
3578
|
};
|
|
3600
3579
|
const calculateFitScale = () => {
|
|
@@ -3602,7 +3581,7 @@ var ExcelPlugin = class {
|
|
|
3602
3581
|
if (!table) return 1;
|
|
3603
3582
|
const availW = Math.max(280, container.clientWidth - 48);
|
|
3604
3583
|
const tW = table.offsetWidth || 800;
|
|
3605
|
-
return Math.max(0.
|
|
3584
|
+
return Math.max(0.4, Math.min(1, availW / tW));
|
|
3606
3585
|
};
|
|
3607
3586
|
try {
|
|
3608
3587
|
wb = XLSX__namespace.read(new Uint8Array(ctx.buffer), { type: "array", cellDates: true });
|
|
@@ -3657,7 +3636,16 @@ var ExcelPlugin = class {
|
|
|
3657
3636
|
}
|
|
3658
3637
|
});
|
|
3659
3638
|
ctx.emit("page-change", { page: currentSheetIndex, total: sheetNames.length });
|
|
3639
|
+
requestAnimationFrame(() => {
|
|
3640
|
+
scale = calculateFitScale();
|
|
3641
|
+
applyTransform();
|
|
3642
|
+
});
|
|
3660
3643
|
};
|
|
3644
|
+
const ro = new ResizeObserver(() => {
|
|
3645
|
+
scale = calculateFitScale();
|
|
3646
|
+
applyTransform();
|
|
3647
|
+
});
|
|
3648
|
+
ro.observe(container);
|
|
3661
3649
|
if (sheetNames.length > 0) {
|
|
3662
3650
|
sheetNames.forEach((name, idx) => {
|
|
3663
3651
|
const btn = document.createElement("button");
|
|
@@ -3684,6 +3672,7 @@ var ExcelPlugin = class {
|
|
|
3684
3672
|
`;
|
|
3685
3673
|
}
|
|
3686
3674
|
const cleanup = () => {
|
|
3675
|
+
ro.disconnect();
|
|
3687
3676
|
container.remove();
|
|
3688
3677
|
ctx.container.innerHTML = "";
|
|
3689
3678
|
};
|
|
@@ -3705,16 +3694,11 @@ var ExcelPlugin = class {
|
|
|
3705
3694
|
},
|
|
3706
3695
|
fitToPage: () => {
|
|
3707
3696
|
scale = calculateFitScale();
|
|
3708
|
-
rotation = 0;
|
|
3709
3697
|
applyTransform();
|
|
3710
3698
|
},
|
|
3711
3699
|
rotateCW: () => {
|
|
3712
|
-
rotation = (rotation + 90) % 360;
|
|
3713
|
-
applyTransform();
|
|
3714
3700
|
},
|
|
3715
3701
|
rotateCCW: () => {
|
|
3716
|
-
rotation = (rotation - 90 + 360) % 360;
|
|
3717
|
-
applyTransform();
|
|
3718
3702
|
},
|
|
3719
3703
|
goToPage: (page) => {
|
|
3720
3704
|
if (page > 0 && page <= sheetNames.length) {
|
|
@@ -3812,38 +3796,15 @@ var CsvPlugin = class {
|
|
|
3812
3796
|
return ext === ".csv" || ext === ".tsv" || mime === "text/csv" || mime === "text/tab-separated-values";
|
|
3813
3797
|
}
|
|
3814
3798
|
getToolbarActions(instance) {
|
|
3815
|
-
const totalPages = instance.getPageCount?.() ?? 1;
|
|
3816
3799
|
const actions = [];
|
|
3817
3800
|
actions.push({
|
|
3818
3801
|
id: "thumbnails",
|
|
3819
3802
|
icon: "thumbnails",
|
|
3820
|
-
label: "
|
|
3803
|
+
label: "Sheet Thumbnails",
|
|
3821
3804
|
type: "button",
|
|
3822
3805
|
group: "navigation",
|
|
3823
3806
|
execute: () => instance.toggleThumbnails?.()
|
|
3824
3807
|
});
|
|
3825
|
-
if (totalPages > 1) {
|
|
3826
|
-
actions.push({
|
|
3827
|
-
id: "page-nav",
|
|
3828
|
-
icon: "",
|
|
3829
|
-
label: "Page Navigation",
|
|
3830
|
-
type: "page-nav",
|
|
3831
|
-
group: "navigation",
|
|
3832
|
-
value: instance.getCurrentPage?.() ?? 1,
|
|
3833
|
-
max: totalPages,
|
|
3834
|
-
execute: (action, page) => {
|
|
3835
|
-
const cur = instance.getCurrentPage?.() ?? 1;
|
|
3836
|
-
const max = instance.getPageCount?.() ?? 1;
|
|
3837
|
-
if (action === "prev") {
|
|
3838
|
-
if (cur > 1) instance.goToPage?.(cur - 1);
|
|
3839
|
-
} else if (action === "next") {
|
|
3840
|
-
if (cur < max) instance.goToPage?.(cur + 1);
|
|
3841
|
-
} else if (typeof page === "number") {
|
|
3842
|
-
instance.goToPage?.(page);
|
|
3843
|
-
}
|
|
3844
|
-
}
|
|
3845
|
-
});
|
|
3846
|
-
}
|
|
3847
3808
|
actions.push(
|
|
3848
3809
|
{
|
|
3849
3810
|
id: "zoom-out",
|
|
@@ -3865,16 +3826,6 @@ var CsvPlugin = class {
|
|
|
3865
3826
|
instance.zoomIn?.();
|
|
3866
3827
|
}
|
|
3867
3828
|
},
|
|
3868
|
-
{
|
|
3869
|
-
id: "fit-page",
|
|
3870
|
-
icon: "fit-page",
|
|
3871
|
-
label: "Fit to View",
|
|
3872
|
-
type: "button",
|
|
3873
|
-
group: "zoom",
|
|
3874
|
-
execute: () => {
|
|
3875
|
-
instance.fitToPage?.();
|
|
3876
|
-
}
|
|
3877
|
-
},
|
|
3878
3829
|
{
|
|
3879
3830
|
id: "download",
|
|
3880
3831
|
icon: "download",
|
|
@@ -3917,131 +3868,135 @@ var CsvPlugin = class {
|
|
|
3917
3868
|
container.style.overflow = "auto";
|
|
3918
3869
|
container.style.padding = "16px";
|
|
3919
3870
|
container.style.boxSizing = "border-box";
|
|
3920
|
-
|
|
3871
|
+
const tableWrapper = document.createElement("div");
|
|
3872
|
+
tableWrapper.style.transformOrigin = "top left";
|
|
3921
3873
|
const delimiter = ctx.metadata.extension === ".tsv" ? " " : ",";
|
|
3922
3874
|
const allLines = text.split(/\r?\n/).filter((r) => r.trim().length > 0);
|
|
3923
3875
|
const headerLine = allLines[0] || "";
|
|
3924
3876
|
const headerCells = headerLine.split(delimiter);
|
|
3925
3877
|
const dataLines = allLines.slice(1);
|
|
3926
|
-
const ROWS_PER_PAGE = 100;
|
|
3927
|
-
const totalPages = Math.max(1, Math.ceil(dataLines.length / ROWS_PER_PAGE));
|
|
3928
|
-
let currentPage = 1;
|
|
3929
3878
|
const table = document.createElement("table");
|
|
3930
3879
|
table.style.borderCollapse = "collapse";
|
|
3931
|
-
table.style.
|
|
3880
|
+
table.style.minWidth = "100%";
|
|
3932
3881
|
table.style.fontFamily = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, monospace';
|
|
3933
3882
|
table.style.fontSize = "13px";
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
const
|
|
3950
|
-
|
|
3951
|
-
const
|
|
3952
|
-
|
|
3953
|
-
const
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
td.style.border = "1px solid #d0d7de";
|
|
3960
|
-
td.style.padding = "6px 12px";
|
|
3961
|
-
td.style.whiteSpace = "nowrap";
|
|
3962
|
-
tr.appendChild(td);
|
|
3963
|
-
});
|
|
3964
|
-
table.appendChild(tr);
|
|
3883
|
+
table.style.background = "#ffffff";
|
|
3884
|
+
table.style.border = "1px solid #d0d7de";
|
|
3885
|
+
const headerTr = document.createElement("tr");
|
|
3886
|
+
headerCells.forEach((cell) => {
|
|
3887
|
+
const th = document.createElement("th");
|
|
3888
|
+
th.textContent = cell.trim();
|
|
3889
|
+
th.style.border = "1px solid #d0d7de";
|
|
3890
|
+
th.style.padding = "8px 12px";
|
|
3891
|
+
th.style.backgroundColor = "#f6f8fa";
|
|
3892
|
+
th.style.fontWeight = "600";
|
|
3893
|
+
th.style.whiteSpace = "nowrap";
|
|
3894
|
+
headerTr.appendChild(th);
|
|
3895
|
+
});
|
|
3896
|
+
table.appendChild(headerTr);
|
|
3897
|
+
dataLines.forEach((row, idx) => {
|
|
3898
|
+
const tr = document.createElement("tr");
|
|
3899
|
+
if (idx % 2 === 1) tr.style.backgroundColor = "#f8fafc";
|
|
3900
|
+
const cells = row.split(delimiter);
|
|
3901
|
+
cells.forEach((cell) => {
|
|
3902
|
+
const td = document.createElement("td");
|
|
3903
|
+
td.textContent = cell.trim();
|
|
3904
|
+
td.style.border = "1px solid #d0d7de";
|
|
3905
|
+
td.style.padding = "6px 12px";
|
|
3906
|
+
td.style.whiteSpace = "nowrap";
|
|
3907
|
+
tr.appendChild(td);
|
|
3965
3908
|
});
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
container.appendChild(table);
|
|
3909
|
+
table.appendChild(tr);
|
|
3910
|
+
});
|
|
3911
|
+
tableWrapper.appendChild(table);
|
|
3912
|
+
container.appendChild(tableWrapper);
|
|
3971
3913
|
ctx.container.appendChild(container);
|
|
3972
3914
|
let scale = 1;
|
|
3915
|
+
const calculateFitScale = () => {
|
|
3916
|
+
const availW = Math.max(280, container.clientWidth - 48);
|
|
3917
|
+
const tW = table.offsetWidth || 800;
|
|
3918
|
+
return Math.max(0.4, Math.min(1, availW / tW));
|
|
3919
|
+
};
|
|
3973
3920
|
const applyScale = () => {
|
|
3974
|
-
|
|
3975
|
-
container.style.transformOrigin = "top left";
|
|
3921
|
+
tableWrapper.style.transform = `scale(${scale})`;
|
|
3976
3922
|
};
|
|
3923
|
+
requestAnimationFrame(() => {
|
|
3924
|
+
scale = calculateFitScale();
|
|
3925
|
+
applyScale();
|
|
3926
|
+
});
|
|
3927
|
+
const ro = new ResizeObserver(() => {
|
|
3928
|
+
scale = calculateFitScale();
|
|
3929
|
+
applyScale();
|
|
3930
|
+
});
|
|
3931
|
+
ro.observe(container);
|
|
3977
3932
|
const cleanup = () => {
|
|
3933
|
+
ro.disconnect();
|
|
3978
3934
|
container.remove();
|
|
3979
3935
|
ctx.container.innerHTML = "";
|
|
3980
3936
|
};
|
|
3981
3937
|
ctx.signal.addEventListener("abort", cleanup);
|
|
3982
3938
|
return {
|
|
3983
3939
|
destroy: cleanup,
|
|
3984
|
-
getPageCount: () =>
|
|
3985
|
-
getCurrentPage: () =>
|
|
3986
|
-
goToPage: (
|
|
3940
|
+
getPageCount: () => 1,
|
|
3941
|
+
getCurrentPage: () => 1,
|
|
3942
|
+
goToPage: () => {
|
|
3943
|
+
},
|
|
3987
3944
|
getThumbnails: () => {
|
|
3988
|
-
const
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
c.
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
c.fillText(val.trim().slice(0, 6), 8 + ci * colW, y + 9);
|
|
3945
|
+
const sheetName = ctx.metadata.name?.replace(/\.[^/.]+$/, "") || "Sheet1";
|
|
3946
|
+
return [{
|
|
3947
|
+
index: 0,
|
|
3948
|
+
label: sheetName,
|
|
3949
|
+
render: async (canvas) => {
|
|
3950
|
+
canvas.width = 140;
|
|
3951
|
+
canvas.height = 100;
|
|
3952
|
+
const c = canvas.getContext("2d");
|
|
3953
|
+
if (!c) return;
|
|
3954
|
+
c.fillStyle = "#ffffff";
|
|
3955
|
+
c.fillRect(0, 0, canvas.width, canvas.height);
|
|
3956
|
+
c.fillStyle = "#107c41";
|
|
3957
|
+
c.fillRect(0, 0, canvas.width, 16);
|
|
3958
|
+
c.fillStyle = "#ffffff";
|
|
3959
|
+
c.font = 'bold 8px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
3960
|
+
c.fillText(`\u{1F4CA} ${sheetName.slice(0, 16)}`, 6, 11);
|
|
3961
|
+
const startY = 17;
|
|
3962
|
+
const rowH = 13;
|
|
3963
|
+
const colW = 30;
|
|
3964
|
+
const cols = headerCells.slice(0, 4).map((h) => h.trim() || "Col");
|
|
3965
|
+
c.fillStyle = "#f1f5f9";
|
|
3966
|
+
c.fillRect(0, startY, canvas.width, rowH);
|
|
3967
|
+
c.strokeStyle = "#cbd5e1";
|
|
3968
|
+
c.lineWidth = 0.8;
|
|
3969
|
+
c.strokeRect(0, startY, canvas.width, rowH);
|
|
3970
|
+
c.fillStyle = "#64748b";
|
|
3971
|
+
c.font = "bold 7px sans-serif";
|
|
3972
|
+
for (let ci = 0; ci < cols.length; ci++) {
|
|
3973
|
+
c.fillText(cols[ci].slice(0, 5), 14 + ci * colW, startY + 9);
|
|
3974
|
+
}
|
|
3975
|
+
for (let ri = 0; ri < Math.min(5, dataLines.length); ri++) {
|
|
3976
|
+
const y = startY + (ri + 1) * rowH;
|
|
3977
|
+
if (y > canvas.height - 2) break;
|
|
3978
|
+
c.fillStyle = "#f8fafc";
|
|
3979
|
+
c.fillRect(0, y, 12, rowH);
|
|
3980
|
+
c.fillStyle = "#94a3b8";
|
|
3981
|
+
c.font = "6px sans-serif";
|
|
3982
|
+
c.fillText(String(ri + 1), 3, y + 9);
|
|
3983
|
+
c.strokeStyle = "#e2e8f0";
|
|
3984
|
+
c.strokeRect(0, y, canvas.width, rowH);
|
|
3985
|
+
const rowCells = dataLines[ri].split(delimiter);
|
|
3986
|
+
c.fillStyle = "#334155";
|
|
3987
|
+
c.font = "6px sans-serif";
|
|
3988
|
+
for (let ci = 0; ci < cols.length; ci++) {
|
|
3989
|
+
const val = (rowCells[ci] || "").trim();
|
|
3990
|
+
if (val) {
|
|
3991
|
+
c.fillText(val.slice(0, 6), 14 + ci * colW, y + 9);
|
|
4036
3992
|
}
|
|
4037
3993
|
}
|
|
4038
|
-
c.strokeStyle = "#cbd5e1";
|
|
4039
|
-
c.lineWidth = 1;
|
|
4040
|
-
c.strokeRect(0.5, 0.5, canvas.width - 1, canvas.height - 1);
|
|
4041
3994
|
}
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
3995
|
+
c.strokeStyle = "#cbd5e1";
|
|
3996
|
+
c.lineWidth = 1;
|
|
3997
|
+
c.strokeRect(0.5, 0.5, canvas.width - 1, canvas.height - 1);
|
|
3998
|
+
}
|
|
3999
|
+
}];
|
|
4045
4000
|
},
|
|
4046
4001
|
zoomIn: () => {
|
|
4047
4002
|
scale += 0.1;
|
|
@@ -4057,11 +4012,13 @@ var CsvPlugin = class {
|
|
|
4057
4012
|
applyScale();
|
|
4058
4013
|
},
|
|
4059
4014
|
fitToPage: () => {
|
|
4060
|
-
|
|
4061
|
-
const tW = table.offsetWidth || 600;
|
|
4062
|
-
scale = Math.max(0.35, Math.min(1, availW / tW));
|
|
4015
|
+
scale = calculateFitScale();
|
|
4063
4016
|
applyScale();
|
|
4064
4017
|
},
|
|
4018
|
+
rotateCW: () => {
|
|
4019
|
+
},
|
|
4020
|
+
rotateCCW: () => {
|
|
4021
|
+
},
|
|
4065
4022
|
download: () => {
|
|
4066
4023
|
const blob = new Blob([ctx.buffer], { type: "text/csv" });
|
|
4067
4024
|
const url = URL.createObjectURL(blob);
|
|
@@ -4173,26 +4130,6 @@ var CodePlugin = class {
|
|
|
4173
4130
|
instance.zoomIn?.();
|
|
4174
4131
|
}
|
|
4175
4132
|
},
|
|
4176
|
-
{
|
|
4177
|
-
id: "fit-page",
|
|
4178
|
-
icon: "fit-page",
|
|
4179
|
-
label: "Fit to View",
|
|
4180
|
-
type: "button",
|
|
4181
|
-
group: "zoom",
|
|
4182
|
-
execute: () => {
|
|
4183
|
-
instance.fitToPage?.();
|
|
4184
|
-
}
|
|
4185
|
-
},
|
|
4186
|
-
{
|
|
4187
|
-
id: "rotate-cw",
|
|
4188
|
-
icon: "rotate-cw",
|
|
4189
|
-
label: "Rotate",
|
|
4190
|
-
type: "button",
|
|
4191
|
-
group: "view",
|
|
4192
|
-
execute: () => {
|
|
4193
|
-
instance.rotateCW?.();
|
|
4194
|
-
}
|
|
4195
|
-
},
|
|
4196
4133
|
{
|
|
4197
4134
|
id: "copy",
|
|
4198
4135
|
icon: "copy",
|
|
@@ -5336,6 +5273,148 @@ var ThreeDPlugin = class {
|
|
|
5336
5273
|
function threeDPlugin() {
|
|
5337
5274
|
return new ThreeDPlugin();
|
|
5338
5275
|
}
|
|
5276
|
+
function cleanRtfText(raw) {
|
|
5277
|
+
return raw.replace(/\\bin\d+\s/g, "").replace(/{\\\*[^}]+}/g, "").replace(/\\u(-?\d+)\??/g, (_, code) => {
|
|
5278
|
+
let num = parseInt(code, 10);
|
|
5279
|
+
if (num < 0) num += 65536;
|
|
5280
|
+
return String.fromCharCode(num);
|
|
5281
|
+
}).replace(/\\'([0-9a-fA-F]{2})/g, (_, hex) => {
|
|
5282
|
+
return String.fromCharCode(parseInt(hex, 16));
|
|
5283
|
+
}).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();
|
|
5284
|
+
}
|
|
5285
|
+
function parseRtfTables(rtfText) {
|
|
5286
|
+
const rowSegments = rtfText.split(/\\row\b/);
|
|
5287
|
+
if (rowSegments.length <= 1) return [];
|
|
5288
|
+
const rawTables = [];
|
|
5289
|
+
let currentTable = null;
|
|
5290
|
+
let charOffset = 0;
|
|
5291
|
+
for (let i = 0; i < rowSegments.length - 1; i++) {
|
|
5292
|
+
const segment = rowSegments[i];
|
|
5293
|
+
const segmentStart = charOffset;
|
|
5294
|
+
const segmentEnd = charOffset + segment.length + 4;
|
|
5295
|
+
const cellParts = segment.split(/\\cell\b/);
|
|
5296
|
+
if (cellParts.length > 1) {
|
|
5297
|
+
const cellxMatches = [...segment.matchAll(/\\cellx(\d+)/g)].map((m) => parseInt(m[1], 10));
|
|
5298
|
+
let cellWidths = [];
|
|
5299
|
+
if (cellxMatches.length > 0) {
|
|
5300
|
+
let seq = [cellxMatches[0]];
|
|
5301
|
+
for (let k = 1; k < cellxMatches.length; k++) {
|
|
5302
|
+
if (cellxMatches[k] > cellxMatches[k - 1]) seq.push(cellxMatches[k]);
|
|
5303
|
+
else break;
|
|
5304
|
+
}
|
|
5305
|
+
let prev = 0;
|
|
5306
|
+
cellWidths = seq.map((x) => {
|
|
5307
|
+
const w = x - prev;
|
|
5308
|
+
prev = x;
|
|
5309
|
+
return w;
|
|
5310
|
+
});
|
|
5311
|
+
}
|
|
5312
|
+
const cells = [];
|
|
5313
|
+
for (let c = 0; c < cellParts.length - 1; c++) {
|
|
5314
|
+
let rawCell = cellParts[c];
|
|
5315
|
+
if (c === 0) {
|
|
5316
|
+
const lastTrowd = rawCell.lastIndexOf("\\trowd");
|
|
5317
|
+
if (lastTrowd !== -1) rawCell = rawCell.slice(lastTrowd);
|
|
5318
|
+
}
|
|
5319
|
+
cells.push(cleanRtfText(rawCell));
|
|
5320
|
+
}
|
|
5321
|
+
const isNewTable = !currentTable || segmentStart - currentTable.lastEnd > 2500;
|
|
5322
|
+
if (isNewTable) {
|
|
5323
|
+
const prevTextSlice = rtfText.slice(Math.max(0, segmentStart - 4e3), segmentStart);
|
|
5324
|
+
const cleanPrev = cleanRtfText(prevTextSlice);
|
|
5325
|
+
const anchorBefore = cleanPrev.slice(-80).trim();
|
|
5326
|
+
currentTable = {
|
|
5327
|
+
id: `RTF_TABLE_${rawTables.length}`,
|
|
5328
|
+
startPos: segmentStart,
|
|
5329
|
+
lastEnd: segmentEnd,
|
|
5330
|
+
rows: [],
|
|
5331
|
+
columnWidths: cellWidths,
|
|
5332
|
+
anchorBefore,
|
|
5333
|
+
anchorAfter: ""
|
|
5334
|
+
};
|
|
5335
|
+
rawTables.push(currentTable);
|
|
5336
|
+
}
|
|
5337
|
+
if (currentTable) {
|
|
5338
|
+
currentTable.rows.push({
|
|
5339
|
+
cells,
|
|
5340
|
+
widths: cellWidths.length === cells.length ? cellWidths : currentTable.columnWidths
|
|
5341
|
+
});
|
|
5342
|
+
currentTable.lastEnd = segmentEnd;
|
|
5343
|
+
}
|
|
5344
|
+
}
|
|
5345
|
+
charOffset += segment.length + 4;
|
|
5346
|
+
}
|
|
5347
|
+
rawTables.forEach((tbl) => {
|
|
5348
|
+
const afterSlice = rtfText.slice(tbl.lastEnd, Math.min(rtfText.length, tbl.lastEnd + 2e3));
|
|
5349
|
+
const cleanAfter = cleanRtfText(afterSlice);
|
|
5350
|
+
tbl.anchorAfter = cleanAfter.slice(0, 80).trim();
|
|
5351
|
+
});
|
|
5352
|
+
return rawTables.map((tbl) => {
|
|
5353
|
+
const totalW = (tbl.columnWidths || []).reduce((a, b) => a + b, 0);
|
|
5354
|
+
const colPercents = totalW > 0 ? tbl.columnWidths.map((w) => Math.round(w / totalW * 100)) : [];
|
|
5355
|
+
return {
|
|
5356
|
+
id: tbl.id,
|
|
5357
|
+
rows: tbl.rows.map((r) => r.cells),
|
|
5358
|
+
colPercents,
|
|
5359
|
+
anchorBefore: tbl.anchorBefore,
|
|
5360
|
+
anchorAfter: tbl.anchorAfter
|
|
5361
|
+
};
|
|
5362
|
+
});
|
|
5363
|
+
}
|
|
5364
|
+
function renderRtfTableElement(table) {
|
|
5365
|
+
const tableEl = document.createElement("table");
|
|
5366
|
+
tableEl.className = "fp-rtf-table";
|
|
5367
|
+
tableEl.style.width = "100%";
|
|
5368
|
+
tableEl.style.borderCollapse = "collapse";
|
|
5369
|
+
tableEl.style.margin = "16px 0 20px";
|
|
5370
|
+
tableEl.style.fontSize = "10pt";
|
|
5371
|
+
tableEl.style.lineHeight = "1.5";
|
|
5372
|
+
tableEl.style.border = "1px solid #cbd5e1";
|
|
5373
|
+
tableEl.style.borderRadius = "4px";
|
|
5374
|
+
tableEl.style.boxSizing = "border-box";
|
|
5375
|
+
tableEl.style.backgroundColor = "#ffffff";
|
|
5376
|
+
const thead = document.createElement("thead");
|
|
5377
|
+
const tbody = document.createElement("tbody");
|
|
5378
|
+
table.rows.forEach((rowCells, rIdx) => {
|
|
5379
|
+
const tr = document.createElement("tr");
|
|
5380
|
+
const isHeader = rIdx === 0;
|
|
5381
|
+
if (isHeader) {
|
|
5382
|
+
tr.style.backgroundColor = "#f8fafc";
|
|
5383
|
+
tr.style.borderBottom = "2px solid #cbd5e1";
|
|
5384
|
+
} else {
|
|
5385
|
+
tr.style.borderBottom = "1px solid #e2e8f0";
|
|
5386
|
+
if (rIdx % 2 === 0) {
|
|
5387
|
+
tr.style.backgroundColor = "#fcfdfe";
|
|
5388
|
+
}
|
|
5389
|
+
}
|
|
5390
|
+
rowCells.forEach((cellText, cIdx) => {
|
|
5391
|
+
const cellEl = document.createElement(isHeader ? "th" : "td");
|
|
5392
|
+
cellEl.style.padding = "8px 12px";
|
|
5393
|
+
cellEl.style.border = "1px solid #cbd5e1";
|
|
5394
|
+
cellEl.style.verticalAlign = "top";
|
|
5395
|
+
cellEl.style.color = isHeader ? "#0f172a" : "#1e293b";
|
|
5396
|
+
cellEl.style.fontWeight = isHeader ? "600" : "normal";
|
|
5397
|
+
if (table.colPercents && table.colPercents[cIdx]) {
|
|
5398
|
+
cellEl.style.width = `${table.colPercents[cIdx]}%`;
|
|
5399
|
+
}
|
|
5400
|
+
if (/^\d+$/.test(cellText.trim()) || cellText.trim() === "#") {
|
|
5401
|
+
cellEl.style.textAlign = "center";
|
|
5402
|
+
} else {
|
|
5403
|
+
cellEl.style.textAlign = "left";
|
|
5404
|
+
}
|
|
5405
|
+
cellEl.textContent = cellText;
|
|
5406
|
+
tr.appendChild(cellEl);
|
|
5407
|
+
});
|
|
5408
|
+
if (isHeader) {
|
|
5409
|
+
thead.appendChild(tr);
|
|
5410
|
+
} else {
|
|
5411
|
+
tbody.appendChild(tr);
|
|
5412
|
+
}
|
|
5413
|
+
});
|
|
5414
|
+
tableEl.appendChild(thead);
|
|
5415
|
+
tableEl.appendChild(tbody);
|
|
5416
|
+
return tableEl;
|
|
5417
|
+
}
|
|
5339
5418
|
var RtfPlugin = class {
|
|
5340
5419
|
id = "rtf";
|
|
5341
5420
|
name = "Rich Text Format (RTF)";
|
|
@@ -5371,6 +5450,14 @@ var RtfPlugin = class {
|
|
|
5371
5450
|
}
|
|
5372
5451
|
});
|
|
5373
5452
|
actions.push(
|
|
5453
|
+
{
|
|
5454
|
+
id: "thumbnails",
|
|
5455
|
+
icon: "thumbnails",
|
|
5456
|
+
label: "Thumbnails",
|
|
5457
|
+
type: "button",
|
|
5458
|
+
group: "view",
|
|
5459
|
+
execute: () => instance.toggleThumbnails?.()
|
|
5460
|
+
},
|
|
5374
5461
|
{
|
|
5375
5462
|
id: "zoom-out",
|
|
5376
5463
|
icon: "zoom-out",
|
|
@@ -5498,6 +5585,8 @@ var RtfPlugin = class {
|
|
|
5498
5585
|
if (typeof RTFJS__namespace.loggingEnabled === "function") {
|
|
5499
5586
|
RTFJS__namespace.loggingEnabled(false);
|
|
5500
5587
|
}
|
|
5588
|
+
const rawText = new TextDecoder("latin1").decode(ctx.buffer);
|
|
5589
|
+
const tables = parseRtfTables(rawText);
|
|
5501
5590
|
const doc = new RTFJS__namespace.Document(ctx.buffer, {});
|
|
5502
5591
|
const htmlElements = await doc.render();
|
|
5503
5592
|
const contentNodes = [];
|
|
@@ -5512,6 +5601,20 @@ var RtfPlugin = class {
|
|
|
5512
5601
|
if (hasChildBlocks && !["table", "tr", "td", "th", "ul", "ol", "li"].includes(tag)) {
|
|
5513
5602
|
extractBlocks(Array.from(item.children));
|
|
5514
5603
|
} else {
|
|
5604
|
+
const svgs = item.querySelectorAll("svg, img");
|
|
5605
|
+
svgs.forEach((s) => {
|
|
5606
|
+
const el = s;
|
|
5607
|
+
el.style.maxWidth = "100%";
|
|
5608
|
+
el.style.maxHeight = "360px";
|
|
5609
|
+
el.style.display = "block";
|
|
5610
|
+
el.style.margin = "12px auto";
|
|
5611
|
+
if (s.tagName.toLowerCase() === "svg") {
|
|
5612
|
+
s.removeAttribute("width");
|
|
5613
|
+
s.removeAttribute("height");
|
|
5614
|
+
el.style.width = "100%";
|
|
5615
|
+
el.style.maxHeight = "360px";
|
|
5616
|
+
}
|
|
5617
|
+
});
|
|
5515
5618
|
if (tag === "p" || tag === "div") {
|
|
5516
5619
|
item.style.display = "block";
|
|
5517
5620
|
item.style.marginBottom = "12px";
|
|
@@ -5522,14 +5625,46 @@ var RtfPlugin = class {
|
|
|
5522
5625
|
}
|
|
5523
5626
|
};
|
|
5524
5627
|
extractBlocks(htmlElements);
|
|
5628
|
+
tables.forEach((table) => {
|
|
5629
|
+
const tableEl = renderRtfTableElement(table);
|
|
5630
|
+
let inserted = false;
|
|
5631
|
+
if (table.anchorBefore && table.anchorBefore.length > 10) {
|
|
5632
|
+
const keyword = table.anchorBefore.slice(-35).trim();
|
|
5633
|
+
for (let i = 0; i < contentNodes.length; i++) {
|
|
5634
|
+
if (contentNodes[i].textContent?.includes(keyword)) {
|
|
5635
|
+
contentNodes.splice(i + 1, 0, tableEl);
|
|
5636
|
+
inserted = true;
|
|
5637
|
+
break;
|
|
5638
|
+
}
|
|
5639
|
+
}
|
|
5640
|
+
}
|
|
5641
|
+
if (!inserted && table.anchorAfter && table.anchorAfter.length > 10) {
|
|
5642
|
+
const keyword = table.anchorAfter.slice(0, 35).trim();
|
|
5643
|
+
for (let i = 0; i < contentNodes.length; i++) {
|
|
5644
|
+
if (contentNodes[i].textContent?.includes(keyword)) {
|
|
5645
|
+
contentNodes.splice(i, 0, tableEl);
|
|
5646
|
+
inserted = true;
|
|
5647
|
+
break;
|
|
5648
|
+
}
|
|
5649
|
+
}
|
|
5650
|
+
}
|
|
5651
|
+
if (!inserted) {
|
|
5652
|
+
if (contentNodes.length > 2) {
|
|
5653
|
+
contentNodes.splice(2, 0, tableEl);
|
|
5654
|
+
} else {
|
|
5655
|
+
contentNodes.push(tableEl);
|
|
5656
|
+
}
|
|
5657
|
+
}
|
|
5658
|
+
});
|
|
5525
5659
|
wrapper.innerHTML = "";
|
|
5526
5660
|
contentNodes.forEach((node) => wrapper.appendChild(node));
|
|
5527
5661
|
const childHeights = contentNodes.map((c) => {
|
|
5528
5662
|
const rectH = c.getBoundingClientRect ? c.getBoundingClientRect().height : 0;
|
|
5529
5663
|
const offH = c.offsetHeight || 0;
|
|
5664
|
+
const realH = Math.max(rectH, offH);
|
|
5665
|
+
if (realH > 0) return realH;
|
|
5530
5666
|
const textLen = c.textContent?.trim().length || 0;
|
|
5531
|
-
|
|
5532
|
-
return Math.max(rectH, offH, estH);
|
|
5667
|
+
return Math.max(24, Math.ceil(textLen / 95) * 22 + 12);
|
|
5533
5668
|
});
|
|
5534
5669
|
wrapper.innerHTML = "";
|
|
5535
5670
|
const createRtfCard = () => {
|
|
@@ -5538,7 +5673,7 @@ var RtfPlugin = class {
|
|
|
5538
5673
|
card.style.backgroundColor = "#ffffff";
|
|
5539
5674
|
card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08)";
|
|
5540
5675
|
card.style.borderRadius = "4px";
|
|
5541
|
-
card.style.padding = "
|
|
5676
|
+
card.style.padding = "64px 56px";
|
|
5542
5677
|
card.style.width = "816px";
|
|
5543
5678
|
card.style.minHeight = "1056px";
|
|
5544
5679
|
card.style.boxSizing = "border-box";
|
|
@@ -5552,22 +5687,35 @@ var RtfPlugin = class {
|
|
|
5552
5687
|
wrapper.appendChild(curCard);
|
|
5553
5688
|
pageElements = [curCard];
|
|
5554
5689
|
let curH = 0;
|
|
5555
|
-
const maxH =
|
|
5690
|
+
const maxH = 928;
|
|
5556
5691
|
for (let i = 0; i < contentNodes.length; i++) {
|
|
5557
5692
|
const child = contentNodes[i];
|
|
5558
5693
|
const chH = childHeights[i];
|
|
5559
|
-
|
|
5560
|
-
curH
|
|
5561
|
-
|
|
5694
|
+
const isChildEmpty = (child.textContent || "").trim().length === 0 && !child.querySelector("table, img, svg, canvas");
|
|
5695
|
+
if (curH === 0 && isChildEmpty) {
|
|
5696
|
+
continue;
|
|
5697
|
+
}
|
|
5698
|
+
if (curH + chH > maxH && curCard.childNodes.length > 0) {
|
|
5562
5699
|
curCard = createRtfCard();
|
|
5563
5700
|
wrapper.appendChild(curCard);
|
|
5564
5701
|
pageElements.push(curCard);
|
|
5565
5702
|
curH = 0;
|
|
5566
5703
|
}
|
|
5704
|
+
curCard.appendChild(child);
|
|
5705
|
+
curH += chH;
|
|
5706
|
+
}
|
|
5707
|
+
pageElements = pageElements.filter((card) => {
|
|
5708
|
+
const hasText = (card.textContent || "").trim().length > 0;
|
|
5709
|
+
const hasMedia = card.querySelector("table, img, svg, canvas") !== null;
|
|
5710
|
+
return hasText || hasMedia;
|
|
5711
|
+
});
|
|
5712
|
+
if (pageElements.length === 0) {
|
|
5713
|
+
pageElements = [curCard];
|
|
5567
5714
|
}
|
|
5568
5715
|
} catch (err) {
|
|
5569
5716
|
console.warn("[RtfPlugin] RTF render error, fallback text:", err);
|
|
5570
5717
|
const text = new TextDecoder("latin1").decode(ctx.buffer);
|
|
5718
|
+
const tables = parseRtfTables(text);
|
|
5571
5719
|
const rawPages = text.split(/\\page\b/).map((segment) => {
|
|
5572
5720
|
return segment.replace(/\\par[d]?/g, "\n").replace(/\\[a-zA-Z0-9\-]+/g, "").replace(/[{}]/g, "").trim();
|
|
5573
5721
|
}).filter((p) => p.length > 0);
|
|
@@ -5578,7 +5726,7 @@ var RtfPlugin = class {
|
|
|
5578
5726
|
pageCard.style.backgroundColor = "#ffffff";
|
|
5579
5727
|
pageCard.style.boxShadow = "0 2px 12px rgba(0,0,0,0.08)";
|
|
5580
5728
|
pageCard.style.borderRadius = "4px";
|
|
5581
|
-
pageCard.style.padding = "
|
|
5729
|
+
pageCard.style.padding = "64px 56px";
|
|
5582
5730
|
pageCard.style.width = "816px";
|
|
5583
5731
|
pageCard.style.minHeight = "1056px";
|
|
5584
5732
|
pageCard.style.boxSizing = "border-box";
|
|
@@ -5589,6 +5737,9 @@ var RtfPlugin = class {
|
|
|
5589
5737
|
pageCard.style.whiteSpace = "pre-wrap";
|
|
5590
5738
|
pageCard.style.display = i === 0 ? "block" : "none";
|
|
5591
5739
|
pageCard.textContent = pages[i];
|
|
5740
|
+
if (i === 1 && tables.length > 0) {
|
|
5741
|
+
tables.forEach((tbl) => pageCard.appendChild(renderRtfTableElement(tbl)));
|
|
5742
|
+
}
|
|
5592
5743
|
wrapper.appendChild(pageCard);
|
|
5593
5744
|
pageElements.push(pageCard);
|
|
5594
5745
|
}
|
|
@@ -5619,6 +5770,32 @@ var RtfPlugin = class {
|
|
|
5619
5770
|
getPageCount: () => totalPages,
|
|
5620
5771
|
getCurrentPage: () => currentPage,
|
|
5621
5772
|
goToPage: (page) => showPage(page),
|
|
5773
|
+
getThumbnails: async () => {
|
|
5774
|
+
const items = [];
|
|
5775
|
+
for (let idx = 0; idx < totalPages; idx++) {
|
|
5776
|
+
const pageIdx = idx;
|
|
5777
|
+
items.push({
|
|
5778
|
+
index: pageIdx,
|
|
5779
|
+
label: `Page ${pageIdx + 1}`,
|
|
5780
|
+
render: async (canvas) => {
|
|
5781
|
+
const ctx2d = canvas.getContext("2d");
|
|
5782
|
+
if (!ctx2d) return;
|
|
5783
|
+
canvas.width = 140;
|
|
5784
|
+
canvas.height = 180;
|
|
5785
|
+
ctx2d.fillStyle = "#ffffff";
|
|
5786
|
+
ctx2d.fillRect(0, 0, 140, 180);
|
|
5787
|
+
ctx2d.strokeStyle = "#cbd5e1";
|
|
5788
|
+
ctx2d.lineWidth = 1;
|
|
5789
|
+
ctx2d.strokeRect(0.5, 0.5, 139, 179);
|
|
5790
|
+
ctx2d.fillStyle = "#334155";
|
|
5791
|
+
ctx2d.font = 'bold 11px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
5792
|
+
ctx2d.textAlign = "center";
|
|
5793
|
+
ctx2d.fillText(`Page ${pageIdx + 1}`, 70, 95);
|
|
5794
|
+
}
|
|
5795
|
+
});
|
|
5796
|
+
}
|
|
5797
|
+
return items;
|
|
5798
|
+
},
|
|
5622
5799
|
zoomIn: () => {
|
|
5623
5800
|
isUserZoomed = true;
|
|
5624
5801
|
scale += 0.15;
|
|
@@ -7656,6 +7833,8 @@ var FilePreview = react.memo(react.forwardRef(
|
|
|
7656
7833
|
onError,
|
|
7657
7834
|
onPageChange,
|
|
7658
7835
|
onZoomChange,
|
|
7836
|
+
onRotate,
|
|
7837
|
+
onDestroy,
|
|
7659
7838
|
className,
|
|
7660
7839
|
style
|
|
7661
7840
|
}, ref) => {
|
|
@@ -7678,6 +7857,8 @@ var FilePreview = react.memo(react.forwardRef(
|
|
|
7678
7857
|
if (onError) unsubs.push(viewer.on("error", (e) => onError(e instanceof Error ? e : new Error(String(e)))));
|
|
7679
7858
|
if (onPageChange) unsubs.push(viewer.on("page-change", onPageChange));
|
|
7680
7859
|
if (onZoomChange) unsubs.push(viewer.on("zoom-change", onZoomChange));
|
|
7860
|
+
if (onRotate) unsubs.push(viewer.on("rotate", onRotate));
|
|
7861
|
+
if (onDestroy) unsubs.push(viewer.on("destroy", onDestroy));
|
|
7681
7862
|
return () => {
|
|
7682
7863
|
unsubs.forEach((fn) => fn());
|
|
7683
7864
|
viewer.destroy();
|