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