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