@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/index.cjs
CHANGED
|
@@ -3590,26 +3590,6 @@ var ExcelPlugin = class {
|
|
|
3590
3590
|
instance.zoomIn?.();
|
|
3591
3591
|
}
|
|
3592
3592
|
},
|
|
3593
|
-
{
|
|
3594
|
-
id: "fit-page",
|
|
3595
|
-
icon: "fit-page",
|
|
3596
|
-
label: "Fit to View",
|
|
3597
|
-
type: "button",
|
|
3598
|
-
group: "zoom",
|
|
3599
|
-
execute: () => {
|
|
3600
|
-
instance.fitToPage?.();
|
|
3601
|
-
}
|
|
3602
|
-
},
|
|
3603
|
-
{
|
|
3604
|
-
id: "rotate-cw",
|
|
3605
|
-
icon: "rotate-cw",
|
|
3606
|
-
label: "Rotate",
|
|
3607
|
-
type: "button",
|
|
3608
|
-
group: "view",
|
|
3609
|
-
execute: () => {
|
|
3610
|
-
instance.rotateCW?.();
|
|
3611
|
-
}
|
|
3612
|
-
},
|
|
3613
3593
|
{
|
|
3614
3594
|
id: "download",
|
|
3615
3595
|
icon: "download",
|
|
@@ -3670,12 +3650,11 @@ var ExcelPlugin = class {
|
|
|
3670
3650
|
container.appendChild(tabsArea);
|
|
3671
3651
|
ctx.container.appendChild(container);
|
|
3672
3652
|
let scale = 1;
|
|
3673
|
-
let rotation = 0;
|
|
3674
3653
|
let currentSheetIndex = 1;
|
|
3675
3654
|
let sheetNames = [];
|
|
3676
3655
|
let wb = null;
|
|
3677
3656
|
const applyTransform = () => {
|
|
3678
|
-
contentArea.style.transform = `scale(${scale})
|
|
3657
|
+
contentArea.style.transform = `scale(${scale})`;
|
|
3679
3658
|
contentArea.style.transformOrigin = "top left";
|
|
3680
3659
|
};
|
|
3681
3660
|
const calculateFitScale = () => {
|
|
@@ -3683,7 +3662,7 @@ var ExcelPlugin = class {
|
|
|
3683
3662
|
if (!table) return 1;
|
|
3684
3663
|
const availW = Math.max(280, container.clientWidth - 48);
|
|
3685
3664
|
const tW = table.offsetWidth || 800;
|
|
3686
|
-
return Math.max(0.
|
|
3665
|
+
return Math.max(0.4, Math.min(1, availW / tW));
|
|
3687
3666
|
};
|
|
3688
3667
|
try {
|
|
3689
3668
|
wb = XLSX__namespace.read(new Uint8Array(ctx.buffer), { type: "array", cellDates: true });
|
|
@@ -3738,7 +3717,16 @@ var ExcelPlugin = class {
|
|
|
3738
3717
|
}
|
|
3739
3718
|
});
|
|
3740
3719
|
ctx.emit("page-change", { page: currentSheetIndex, total: sheetNames.length });
|
|
3720
|
+
requestAnimationFrame(() => {
|
|
3721
|
+
scale = calculateFitScale();
|
|
3722
|
+
applyTransform();
|
|
3723
|
+
});
|
|
3741
3724
|
};
|
|
3725
|
+
const ro = new ResizeObserver(() => {
|
|
3726
|
+
scale = calculateFitScale();
|
|
3727
|
+
applyTransform();
|
|
3728
|
+
});
|
|
3729
|
+
ro.observe(container);
|
|
3742
3730
|
if (sheetNames.length > 0) {
|
|
3743
3731
|
sheetNames.forEach((name, idx) => {
|
|
3744
3732
|
const btn = document.createElement("button");
|
|
@@ -3765,6 +3753,7 @@ var ExcelPlugin = class {
|
|
|
3765
3753
|
`;
|
|
3766
3754
|
}
|
|
3767
3755
|
const cleanup = () => {
|
|
3756
|
+
ro.disconnect();
|
|
3768
3757
|
container.remove();
|
|
3769
3758
|
ctx.container.innerHTML = "";
|
|
3770
3759
|
};
|
|
@@ -3786,16 +3775,11 @@ var ExcelPlugin = class {
|
|
|
3786
3775
|
},
|
|
3787
3776
|
fitToPage: () => {
|
|
3788
3777
|
scale = calculateFitScale();
|
|
3789
|
-
rotation = 0;
|
|
3790
3778
|
applyTransform();
|
|
3791
3779
|
},
|
|
3792
3780
|
rotateCW: () => {
|
|
3793
|
-
rotation = (rotation + 90) % 360;
|
|
3794
|
-
applyTransform();
|
|
3795
3781
|
},
|
|
3796
3782
|
rotateCCW: () => {
|
|
3797
|
-
rotation = (rotation - 90 + 360) % 360;
|
|
3798
|
-
applyTransform();
|
|
3799
3783
|
},
|
|
3800
3784
|
goToPage: (page) => {
|
|
3801
3785
|
if (page > 0 && page <= sheetNames.length) {
|
|
@@ -3893,38 +3877,15 @@ var CsvPlugin = class {
|
|
|
3893
3877
|
return ext === ".csv" || ext === ".tsv" || mime === "text/csv" || mime === "text/tab-separated-values";
|
|
3894
3878
|
}
|
|
3895
3879
|
getToolbarActions(instance) {
|
|
3896
|
-
const totalPages = instance.getPageCount?.() ?? 1;
|
|
3897
3880
|
const actions = [];
|
|
3898
3881
|
actions.push({
|
|
3899
3882
|
id: "thumbnails",
|
|
3900
3883
|
icon: "thumbnails",
|
|
3901
|
-
label: "
|
|
3884
|
+
label: "Sheet Thumbnails",
|
|
3902
3885
|
type: "button",
|
|
3903
3886
|
group: "navigation",
|
|
3904
3887
|
execute: () => instance.toggleThumbnails?.()
|
|
3905
3888
|
});
|
|
3906
|
-
if (totalPages > 1) {
|
|
3907
|
-
actions.push({
|
|
3908
|
-
id: "page-nav",
|
|
3909
|
-
icon: "",
|
|
3910
|
-
label: "Page Navigation",
|
|
3911
|
-
type: "page-nav",
|
|
3912
|
-
group: "navigation",
|
|
3913
|
-
value: instance.getCurrentPage?.() ?? 1,
|
|
3914
|
-
max: totalPages,
|
|
3915
|
-
execute: (action, page) => {
|
|
3916
|
-
const cur = instance.getCurrentPage?.() ?? 1;
|
|
3917
|
-
const max = instance.getPageCount?.() ?? 1;
|
|
3918
|
-
if (action === "prev") {
|
|
3919
|
-
if (cur > 1) instance.goToPage?.(cur - 1);
|
|
3920
|
-
} else if (action === "next") {
|
|
3921
|
-
if (cur < max) instance.goToPage?.(cur + 1);
|
|
3922
|
-
} else if (typeof page === "number") {
|
|
3923
|
-
instance.goToPage?.(page);
|
|
3924
|
-
}
|
|
3925
|
-
}
|
|
3926
|
-
});
|
|
3927
|
-
}
|
|
3928
3889
|
actions.push(
|
|
3929
3890
|
{
|
|
3930
3891
|
id: "zoom-out",
|
|
@@ -3946,16 +3907,6 @@ var CsvPlugin = class {
|
|
|
3946
3907
|
instance.zoomIn?.();
|
|
3947
3908
|
}
|
|
3948
3909
|
},
|
|
3949
|
-
{
|
|
3950
|
-
id: "fit-page",
|
|
3951
|
-
icon: "fit-page",
|
|
3952
|
-
label: "Fit to View",
|
|
3953
|
-
type: "button",
|
|
3954
|
-
group: "zoom",
|
|
3955
|
-
execute: () => {
|
|
3956
|
-
instance.fitToPage?.();
|
|
3957
|
-
}
|
|
3958
|
-
},
|
|
3959
3910
|
{
|
|
3960
3911
|
id: "download",
|
|
3961
3912
|
icon: "download",
|
|
@@ -3998,131 +3949,135 @@ var CsvPlugin = class {
|
|
|
3998
3949
|
container.style.overflow = "auto";
|
|
3999
3950
|
container.style.padding = "16px";
|
|
4000
3951
|
container.style.boxSizing = "border-box";
|
|
4001
|
-
|
|
3952
|
+
const tableWrapper = document.createElement("div");
|
|
3953
|
+
tableWrapper.style.transformOrigin = "top left";
|
|
4002
3954
|
const delimiter = ctx.metadata.extension === ".tsv" ? " " : ",";
|
|
4003
3955
|
const allLines = text.split(/\r?\n/).filter((r) => r.trim().length > 0);
|
|
4004
3956
|
const headerLine = allLines[0] || "";
|
|
4005
3957
|
const headerCells = headerLine.split(delimiter);
|
|
4006
3958
|
const dataLines = allLines.slice(1);
|
|
4007
|
-
const ROWS_PER_PAGE = 100;
|
|
4008
|
-
const totalPages = Math.max(1, Math.ceil(dataLines.length / ROWS_PER_PAGE));
|
|
4009
|
-
let currentPage = 1;
|
|
4010
3959
|
const table = document.createElement("table");
|
|
4011
3960
|
table.style.borderCollapse = "collapse";
|
|
4012
|
-
table.style.
|
|
3961
|
+
table.style.minWidth = "100%";
|
|
4013
3962
|
table.style.fontFamily = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, monospace';
|
|
4014
3963
|
table.style.fontSize = "13px";
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
const
|
|
4031
|
-
|
|
4032
|
-
const
|
|
4033
|
-
|
|
4034
|
-
const
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
td.style.border = "1px solid #d0d7de";
|
|
4041
|
-
td.style.padding = "6px 12px";
|
|
4042
|
-
td.style.whiteSpace = "nowrap";
|
|
4043
|
-
tr.appendChild(td);
|
|
4044
|
-
});
|
|
4045
|
-
table.appendChild(tr);
|
|
3964
|
+
table.style.background = "#ffffff";
|
|
3965
|
+
table.style.border = "1px solid #d0d7de";
|
|
3966
|
+
const headerTr = document.createElement("tr");
|
|
3967
|
+
headerCells.forEach((cell) => {
|
|
3968
|
+
const th = document.createElement("th");
|
|
3969
|
+
th.textContent = cell.trim();
|
|
3970
|
+
th.style.border = "1px solid #d0d7de";
|
|
3971
|
+
th.style.padding = "8px 12px";
|
|
3972
|
+
th.style.backgroundColor = "#f6f8fa";
|
|
3973
|
+
th.style.fontWeight = "600";
|
|
3974
|
+
th.style.whiteSpace = "nowrap";
|
|
3975
|
+
headerTr.appendChild(th);
|
|
3976
|
+
});
|
|
3977
|
+
table.appendChild(headerTr);
|
|
3978
|
+
dataLines.forEach((row, idx) => {
|
|
3979
|
+
const tr = document.createElement("tr");
|
|
3980
|
+
if (idx % 2 === 1) tr.style.backgroundColor = "#f8fafc";
|
|
3981
|
+
const cells = row.split(delimiter);
|
|
3982
|
+
cells.forEach((cell) => {
|
|
3983
|
+
const td = document.createElement("td");
|
|
3984
|
+
td.textContent = cell.trim();
|
|
3985
|
+
td.style.border = "1px solid #d0d7de";
|
|
3986
|
+
td.style.padding = "6px 12px";
|
|
3987
|
+
td.style.whiteSpace = "nowrap";
|
|
3988
|
+
tr.appendChild(td);
|
|
4046
3989
|
});
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
container.appendChild(table);
|
|
3990
|
+
table.appendChild(tr);
|
|
3991
|
+
});
|
|
3992
|
+
tableWrapper.appendChild(table);
|
|
3993
|
+
container.appendChild(tableWrapper);
|
|
4052
3994
|
ctx.container.appendChild(container);
|
|
4053
3995
|
let scale = 1;
|
|
3996
|
+
const calculateFitScale = () => {
|
|
3997
|
+
const availW = Math.max(280, container.clientWidth - 48);
|
|
3998
|
+
const tW = table.offsetWidth || 800;
|
|
3999
|
+
return Math.max(0.4, Math.min(1, availW / tW));
|
|
4000
|
+
};
|
|
4054
4001
|
const applyScale = () => {
|
|
4055
|
-
|
|
4056
|
-
container.style.transformOrigin = "top left";
|
|
4002
|
+
tableWrapper.style.transform = `scale(${scale})`;
|
|
4057
4003
|
};
|
|
4004
|
+
requestAnimationFrame(() => {
|
|
4005
|
+
scale = calculateFitScale();
|
|
4006
|
+
applyScale();
|
|
4007
|
+
});
|
|
4008
|
+
const ro = new ResizeObserver(() => {
|
|
4009
|
+
scale = calculateFitScale();
|
|
4010
|
+
applyScale();
|
|
4011
|
+
});
|
|
4012
|
+
ro.observe(container);
|
|
4058
4013
|
const cleanup = () => {
|
|
4014
|
+
ro.disconnect();
|
|
4059
4015
|
container.remove();
|
|
4060
4016
|
ctx.container.innerHTML = "";
|
|
4061
4017
|
};
|
|
4062
4018
|
ctx.signal.addEventListener("abort", cleanup);
|
|
4063
4019
|
return {
|
|
4064
4020
|
destroy: cleanup,
|
|
4065
|
-
getPageCount: () =>
|
|
4066
|
-
getCurrentPage: () =>
|
|
4067
|
-
goToPage: (
|
|
4021
|
+
getPageCount: () => 1,
|
|
4022
|
+
getCurrentPage: () => 1,
|
|
4023
|
+
goToPage: () => {
|
|
4024
|
+
},
|
|
4068
4025
|
getThumbnails: () => {
|
|
4069
|
-
const
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
c.
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
c.fillText(val.trim().slice(0, 6), 8 + ci * colW, y + 9);
|
|
4026
|
+
const sheetName = ctx.metadata.name?.replace(/\.[^/.]+$/, "") || "Sheet1";
|
|
4027
|
+
return [{
|
|
4028
|
+
index: 0,
|
|
4029
|
+
label: sheetName,
|
|
4030
|
+
render: async (canvas) => {
|
|
4031
|
+
canvas.width = 140;
|
|
4032
|
+
canvas.height = 100;
|
|
4033
|
+
const c = canvas.getContext("2d");
|
|
4034
|
+
if (!c) return;
|
|
4035
|
+
c.fillStyle = "#ffffff";
|
|
4036
|
+
c.fillRect(0, 0, canvas.width, canvas.height);
|
|
4037
|
+
c.fillStyle = "#107c41";
|
|
4038
|
+
c.fillRect(0, 0, canvas.width, 16);
|
|
4039
|
+
c.fillStyle = "#ffffff";
|
|
4040
|
+
c.font = 'bold 8px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
4041
|
+
c.fillText(`\u{1F4CA} ${sheetName.slice(0, 16)}`, 6, 11);
|
|
4042
|
+
const startY = 17;
|
|
4043
|
+
const rowH = 13;
|
|
4044
|
+
const colW = 30;
|
|
4045
|
+
const cols = headerCells.slice(0, 4).map((h) => h.trim() || "Col");
|
|
4046
|
+
c.fillStyle = "#f1f5f9";
|
|
4047
|
+
c.fillRect(0, startY, canvas.width, rowH);
|
|
4048
|
+
c.strokeStyle = "#cbd5e1";
|
|
4049
|
+
c.lineWidth = 0.8;
|
|
4050
|
+
c.strokeRect(0, startY, canvas.width, rowH);
|
|
4051
|
+
c.fillStyle = "#64748b";
|
|
4052
|
+
c.font = "bold 7px sans-serif";
|
|
4053
|
+
for (let ci = 0; ci < cols.length; ci++) {
|
|
4054
|
+
c.fillText(cols[ci].slice(0, 5), 14 + ci * colW, startY + 9);
|
|
4055
|
+
}
|
|
4056
|
+
for (let ri = 0; ri < Math.min(5, dataLines.length); ri++) {
|
|
4057
|
+
const y = startY + (ri + 1) * rowH;
|
|
4058
|
+
if (y > canvas.height - 2) break;
|
|
4059
|
+
c.fillStyle = "#f8fafc";
|
|
4060
|
+
c.fillRect(0, y, 12, rowH);
|
|
4061
|
+
c.fillStyle = "#94a3b8";
|
|
4062
|
+
c.font = "6px sans-serif";
|
|
4063
|
+
c.fillText(String(ri + 1), 3, y + 9);
|
|
4064
|
+
c.strokeStyle = "#e2e8f0";
|
|
4065
|
+
c.strokeRect(0, y, canvas.width, rowH);
|
|
4066
|
+
const rowCells = dataLines[ri].split(delimiter);
|
|
4067
|
+
c.fillStyle = "#334155";
|
|
4068
|
+
c.font = "6px sans-serif";
|
|
4069
|
+
for (let ci = 0; ci < cols.length; ci++) {
|
|
4070
|
+
const val = (rowCells[ci] || "").trim();
|
|
4071
|
+
if (val) {
|
|
4072
|
+
c.fillText(val.slice(0, 6), 14 + ci * colW, y + 9);
|
|
4117
4073
|
}
|
|
4118
4074
|
}
|
|
4119
|
-
c.strokeStyle = "#cbd5e1";
|
|
4120
|
-
c.lineWidth = 1;
|
|
4121
|
-
c.strokeRect(0.5, 0.5, canvas.width - 1, canvas.height - 1);
|
|
4122
4075
|
}
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4076
|
+
c.strokeStyle = "#cbd5e1";
|
|
4077
|
+
c.lineWidth = 1;
|
|
4078
|
+
c.strokeRect(0.5, 0.5, canvas.width - 1, canvas.height - 1);
|
|
4079
|
+
}
|
|
4080
|
+
}];
|
|
4126
4081
|
},
|
|
4127
4082
|
zoomIn: () => {
|
|
4128
4083
|
scale += 0.1;
|
|
@@ -4138,11 +4093,13 @@ var CsvPlugin = class {
|
|
|
4138
4093
|
applyScale();
|
|
4139
4094
|
},
|
|
4140
4095
|
fitToPage: () => {
|
|
4141
|
-
|
|
4142
|
-
const tW = table.offsetWidth || 600;
|
|
4143
|
-
scale = Math.max(0.35, Math.min(1, availW / tW));
|
|
4096
|
+
scale = calculateFitScale();
|
|
4144
4097
|
applyScale();
|
|
4145
4098
|
},
|
|
4099
|
+
rotateCW: () => {
|
|
4100
|
+
},
|
|
4101
|
+
rotateCCW: () => {
|
|
4102
|
+
},
|
|
4146
4103
|
download: () => {
|
|
4147
4104
|
const blob = new Blob([ctx.buffer], { type: "text/csv" });
|
|
4148
4105
|
const url = URL.createObjectURL(blob);
|
|
@@ -4254,26 +4211,6 @@ var CodePlugin = class {
|
|
|
4254
4211
|
instance.zoomIn?.();
|
|
4255
4212
|
}
|
|
4256
4213
|
},
|
|
4257
|
-
{
|
|
4258
|
-
id: "fit-page",
|
|
4259
|
-
icon: "fit-page",
|
|
4260
|
-
label: "Fit to View",
|
|
4261
|
-
type: "button",
|
|
4262
|
-
group: "zoom",
|
|
4263
|
-
execute: () => {
|
|
4264
|
-
instance.fitToPage?.();
|
|
4265
|
-
}
|
|
4266
|
-
},
|
|
4267
|
-
{
|
|
4268
|
-
id: "rotate-cw",
|
|
4269
|
-
icon: "rotate-cw",
|
|
4270
|
-
label: "Rotate",
|
|
4271
|
-
type: "button",
|
|
4272
|
-
group: "view",
|
|
4273
|
-
execute: () => {
|
|
4274
|
-
instance.rotateCW?.();
|
|
4275
|
-
}
|
|
4276
|
-
},
|
|
4277
4214
|
{
|
|
4278
4215
|
id: "copy",
|
|
4279
4216
|
icon: "copy",
|
|
@@ -5417,6 +5354,148 @@ var ThreeDPlugin = class {
|
|
|
5417
5354
|
function threeDPlugin() {
|
|
5418
5355
|
return new ThreeDPlugin();
|
|
5419
5356
|
}
|
|
5357
|
+
function cleanRtfText(raw) {
|
|
5358
|
+
return raw.replace(/\\bin\d+\s/g, "").replace(/{\\\*[^}]+}/g, "").replace(/\\u(-?\d+)\??/g, (_, code) => {
|
|
5359
|
+
let num = parseInt(code, 10);
|
|
5360
|
+
if (num < 0) num += 65536;
|
|
5361
|
+
return String.fromCharCode(num);
|
|
5362
|
+
}).replace(/\\'([0-9a-fA-F]{2})/g, (_, hex) => {
|
|
5363
|
+
return String.fromCharCode(parseInt(hex, 16));
|
|
5364
|
+
}).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();
|
|
5365
|
+
}
|
|
5366
|
+
function parseRtfTables(rtfText) {
|
|
5367
|
+
const rowSegments = rtfText.split(/\\row\b/);
|
|
5368
|
+
if (rowSegments.length <= 1) return [];
|
|
5369
|
+
const rawTables = [];
|
|
5370
|
+
let currentTable = null;
|
|
5371
|
+
let charOffset = 0;
|
|
5372
|
+
for (let i = 0; i < rowSegments.length - 1; i++) {
|
|
5373
|
+
const segment = rowSegments[i];
|
|
5374
|
+
const segmentStart = charOffset;
|
|
5375
|
+
const segmentEnd = charOffset + segment.length + 4;
|
|
5376
|
+
const cellParts = segment.split(/\\cell\b/);
|
|
5377
|
+
if (cellParts.length > 1) {
|
|
5378
|
+
const cellxMatches = [...segment.matchAll(/\\cellx(\d+)/g)].map((m) => parseInt(m[1], 10));
|
|
5379
|
+
let cellWidths = [];
|
|
5380
|
+
if (cellxMatches.length > 0) {
|
|
5381
|
+
let seq = [cellxMatches[0]];
|
|
5382
|
+
for (let k = 1; k < cellxMatches.length; k++) {
|
|
5383
|
+
if (cellxMatches[k] > cellxMatches[k - 1]) seq.push(cellxMatches[k]);
|
|
5384
|
+
else break;
|
|
5385
|
+
}
|
|
5386
|
+
let prev = 0;
|
|
5387
|
+
cellWidths = seq.map((x) => {
|
|
5388
|
+
const w = x - prev;
|
|
5389
|
+
prev = x;
|
|
5390
|
+
return w;
|
|
5391
|
+
});
|
|
5392
|
+
}
|
|
5393
|
+
const cells = [];
|
|
5394
|
+
for (let c = 0; c < cellParts.length - 1; c++) {
|
|
5395
|
+
let rawCell = cellParts[c];
|
|
5396
|
+
if (c === 0) {
|
|
5397
|
+
const lastTrowd = rawCell.lastIndexOf("\\trowd");
|
|
5398
|
+
if (lastTrowd !== -1) rawCell = rawCell.slice(lastTrowd);
|
|
5399
|
+
}
|
|
5400
|
+
cells.push(cleanRtfText(rawCell));
|
|
5401
|
+
}
|
|
5402
|
+
const isNewTable = !currentTable || segmentStart - currentTable.lastEnd > 2500;
|
|
5403
|
+
if (isNewTable) {
|
|
5404
|
+
const prevTextSlice = rtfText.slice(Math.max(0, segmentStart - 4e3), segmentStart);
|
|
5405
|
+
const cleanPrev = cleanRtfText(prevTextSlice);
|
|
5406
|
+
const anchorBefore = cleanPrev.slice(-80).trim();
|
|
5407
|
+
currentTable = {
|
|
5408
|
+
id: `RTF_TABLE_${rawTables.length}`,
|
|
5409
|
+
startPos: segmentStart,
|
|
5410
|
+
lastEnd: segmentEnd,
|
|
5411
|
+
rows: [],
|
|
5412
|
+
columnWidths: cellWidths,
|
|
5413
|
+
anchorBefore,
|
|
5414
|
+
anchorAfter: ""
|
|
5415
|
+
};
|
|
5416
|
+
rawTables.push(currentTable);
|
|
5417
|
+
}
|
|
5418
|
+
if (currentTable) {
|
|
5419
|
+
currentTable.rows.push({
|
|
5420
|
+
cells,
|
|
5421
|
+
widths: cellWidths.length === cells.length ? cellWidths : currentTable.columnWidths
|
|
5422
|
+
});
|
|
5423
|
+
currentTable.lastEnd = segmentEnd;
|
|
5424
|
+
}
|
|
5425
|
+
}
|
|
5426
|
+
charOffset += segment.length + 4;
|
|
5427
|
+
}
|
|
5428
|
+
rawTables.forEach((tbl) => {
|
|
5429
|
+
const afterSlice = rtfText.slice(tbl.lastEnd, Math.min(rtfText.length, tbl.lastEnd + 2e3));
|
|
5430
|
+
const cleanAfter = cleanRtfText(afterSlice);
|
|
5431
|
+
tbl.anchorAfter = cleanAfter.slice(0, 80).trim();
|
|
5432
|
+
});
|
|
5433
|
+
return rawTables.map((tbl) => {
|
|
5434
|
+
const totalW = (tbl.columnWidths || []).reduce((a, b) => a + b, 0);
|
|
5435
|
+
const colPercents = totalW > 0 ? tbl.columnWidths.map((w) => Math.round(w / totalW * 100)) : [];
|
|
5436
|
+
return {
|
|
5437
|
+
id: tbl.id,
|
|
5438
|
+
rows: tbl.rows.map((r) => r.cells),
|
|
5439
|
+
colPercents,
|
|
5440
|
+
anchorBefore: tbl.anchorBefore,
|
|
5441
|
+
anchorAfter: tbl.anchorAfter
|
|
5442
|
+
};
|
|
5443
|
+
});
|
|
5444
|
+
}
|
|
5445
|
+
function renderRtfTableElement(table) {
|
|
5446
|
+
const tableEl = document.createElement("table");
|
|
5447
|
+
tableEl.className = "fp-rtf-table";
|
|
5448
|
+
tableEl.style.width = "100%";
|
|
5449
|
+
tableEl.style.borderCollapse = "collapse";
|
|
5450
|
+
tableEl.style.margin = "16px 0 20px";
|
|
5451
|
+
tableEl.style.fontSize = "10pt";
|
|
5452
|
+
tableEl.style.lineHeight = "1.5";
|
|
5453
|
+
tableEl.style.border = "1px solid #cbd5e1";
|
|
5454
|
+
tableEl.style.borderRadius = "4px";
|
|
5455
|
+
tableEl.style.boxSizing = "border-box";
|
|
5456
|
+
tableEl.style.backgroundColor = "#ffffff";
|
|
5457
|
+
const thead = document.createElement("thead");
|
|
5458
|
+
const tbody = document.createElement("tbody");
|
|
5459
|
+
table.rows.forEach((rowCells, rIdx) => {
|
|
5460
|
+
const tr = document.createElement("tr");
|
|
5461
|
+
const isHeader = rIdx === 0;
|
|
5462
|
+
if (isHeader) {
|
|
5463
|
+
tr.style.backgroundColor = "#f8fafc";
|
|
5464
|
+
tr.style.borderBottom = "2px solid #cbd5e1";
|
|
5465
|
+
} else {
|
|
5466
|
+
tr.style.borderBottom = "1px solid #e2e8f0";
|
|
5467
|
+
if (rIdx % 2 === 0) {
|
|
5468
|
+
tr.style.backgroundColor = "#fcfdfe";
|
|
5469
|
+
}
|
|
5470
|
+
}
|
|
5471
|
+
rowCells.forEach((cellText, cIdx) => {
|
|
5472
|
+
const cellEl = document.createElement(isHeader ? "th" : "td");
|
|
5473
|
+
cellEl.style.padding = "8px 12px";
|
|
5474
|
+
cellEl.style.border = "1px solid #cbd5e1";
|
|
5475
|
+
cellEl.style.verticalAlign = "top";
|
|
5476
|
+
cellEl.style.color = isHeader ? "#0f172a" : "#1e293b";
|
|
5477
|
+
cellEl.style.fontWeight = isHeader ? "600" : "normal";
|
|
5478
|
+
if (table.colPercents && table.colPercents[cIdx]) {
|
|
5479
|
+
cellEl.style.width = `${table.colPercents[cIdx]}%`;
|
|
5480
|
+
}
|
|
5481
|
+
if (/^\d+$/.test(cellText.trim()) || cellText.trim() === "#") {
|
|
5482
|
+
cellEl.style.textAlign = "center";
|
|
5483
|
+
} else {
|
|
5484
|
+
cellEl.style.textAlign = "left";
|
|
5485
|
+
}
|
|
5486
|
+
cellEl.textContent = cellText;
|
|
5487
|
+
tr.appendChild(cellEl);
|
|
5488
|
+
});
|
|
5489
|
+
if (isHeader) {
|
|
5490
|
+
thead.appendChild(tr);
|
|
5491
|
+
} else {
|
|
5492
|
+
tbody.appendChild(tr);
|
|
5493
|
+
}
|
|
5494
|
+
});
|
|
5495
|
+
tableEl.appendChild(thead);
|
|
5496
|
+
tableEl.appendChild(tbody);
|
|
5497
|
+
return tableEl;
|
|
5498
|
+
}
|
|
5420
5499
|
var RtfPlugin = class {
|
|
5421
5500
|
id = "rtf";
|
|
5422
5501
|
name = "Rich Text Format (RTF)";
|
|
@@ -5452,6 +5531,14 @@ var RtfPlugin = class {
|
|
|
5452
5531
|
}
|
|
5453
5532
|
});
|
|
5454
5533
|
actions.push(
|
|
5534
|
+
{
|
|
5535
|
+
id: "thumbnails",
|
|
5536
|
+
icon: "thumbnails",
|
|
5537
|
+
label: "Thumbnails",
|
|
5538
|
+
type: "button",
|
|
5539
|
+
group: "view",
|
|
5540
|
+
execute: () => instance.toggleThumbnails?.()
|
|
5541
|
+
},
|
|
5455
5542
|
{
|
|
5456
5543
|
id: "zoom-out",
|
|
5457
5544
|
icon: "zoom-out",
|
|
@@ -5579,6 +5666,8 @@ var RtfPlugin = class {
|
|
|
5579
5666
|
if (typeof RTFJS__namespace.loggingEnabled === "function") {
|
|
5580
5667
|
RTFJS__namespace.loggingEnabled(false);
|
|
5581
5668
|
}
|
|
5669
|
+
const rawText = new TextDecoder("latin1").decode(ctx.buffer);
|
|
5670
|
+
const tables = parseRtfTables(rawText);
|
|
5582
5671
|
const doc = new RTFJS__namespace.Document(ctx.buffer, {});
|
|
5583
5672
|
const htmlElements = await doc.render();
|
|
5584
5673
|
const contentNodes = [];
|
|
@@ -5593,6 +5682,20 @@ var RtfPlugin = class {
|
|
|
5593
5682
|
if (hasChildBlocks && !["table", "tr", "td", "th", "ul", "ol", "li"].includes(tag)) {
|
|
5594
5683
|
extractBlocks(Array.from(item.children));
|
|
5595
5684
|
} else {
|
|
5685
|
+
const svgs = item.querySelectorAll("svg, img");
|
|
5686
|
+
svgs.forEach((s) => {
|
|
5687
|
+
const el = s;
|
|
5688
|
+
el.style.maxWidth = "100%";
|
|
5689
|
+
el.style.maxHeight = "360px";
|
|
5690
|
+
el.style.display = "block";
|
|
5691
|
+
el.style.margin = "12px auto";
|
|
5692
|
+
if (s.tagName.toLowerCase() === "svg") {
|
|
5693
|
+
s.removeAttribute("width");
|
|
5694
|
+
s.removeAttribute("height");
|
|
5695
|
+
el.style.width = "100%";
|
|
5696
|
+
el.style.maxHeight = "360px";
|
|
5697
|
+
}
|
|
5698
|
+
});
|
|
5596
5699
|
if (tag === "p" || tag === "div") {
|
|
5597
5700
|
item.style.display = "block";
|
|
5598
5701
|
item.style.marginBottom = "12px";
|
|
@@ -5603,14 +5706,46 @@ var RtfPlugin = class {
|
|
|
5603
5706
|
}
|
|
5604
5707
|
};
|
|
5605
5708
|
extractBlocks(htmlElements);
|
|
5709
|
+
tables.forEach((table) => {
|
|
5710
|
+
const tableEl = renderRtfTableElement(table);
|
|
5711
|
+
let inserted = false;
|
|
5712
|
+
if (table.anchorBefore && table.anchorBefore.length > 10) {
|
|
5713
|
+
const keyword = table.anchorBefore.slice(-35).trim();
|
|
5714
|
+
for (let i = 0; i < contentNodes.length; i++) {
|
|
5715
|
+
if (contentNodes[i].textContent?.includes(keyword)) {
|
|
5716
|
+
contentNodes.splice(i + 1, 0, tableEl);
|
|
5717
|
+
inserted = true;
|
|
5718
|
+
break;
|
|
5719
|
+
}
|
|
5720
|
+
}
|
|
5721
|
+
}
|
|
5722
|
+
if (!inserted && table.anchorAfter && table.anchorAfter.length > 10) {
|
|
5723
|
+
const keyword = table.anchorAfter.slice(0, 35).trim();
|
|
5724
|
+
for (let i = 0; i < contentNodes.length; i++) {
|
|
5725
|
+
if (contentNodes[i].textContent?.includes(keyword)) {
|
|
5726
|
+
contentNodes.splice(i, 0, tableEl);
|
|
5727
|
+
inserted = true;
|
|
5728
|
+
break;
|
|
5729
|
+
}
|
|
5730
|
+
}
|
|
5731
|
+
}
|
|
5732
|
+
if (!inserted) {
|
|
5733
|
+
if (contentNodes.length > 2) {
|
|
5734
|
+
contentNodes.splice(2, 0, tableEl);
|
|
5735
|
+
} else {
|
|
5736
|
+
contentNodes.push(tableEl);
|
|
5737
|
+
}
|
|
5738
|
+
}
|
|
5739
|
+
});
|
|
5606
5740
|
wrapper.innerHTML = "";
|
|
5607
5741
|
contentNodes.forEach((node) => wrapper.appendChild(node));
|
|
5608
5742
|
const childHeights = contentNodes.map((c) => {
|
|
5609
5743
|
const rectH = c.getBoundingClientRect ? c.getBoundingClientRect().height : 0;
|
|
5610
5744
|
const offH = c.offsetHeight || 0;
|
|
5745
|
+
const realH = Math.max(rectH, offH);
|
|
5746
|
+
if (realH > 0) return realH;
|
|
5611
5747
|
const textLen = c.textContent?.trim().length || 0;
|
|
5612
|
-
|
|
5613
|
-
return Math.max(rectH, offH, estH);
|
|
5748
|
+
return Math.max(24, Math.ceil(textLen / 95) * 22 + 12);
|
|
5614
5749
|
});
|
|
5615
5750
|
wrapper.innerHTML = "";
|
|
5616
5751
|
const createRtfCard = () => {
|
|
@@ -5619,7 +5754,7 @@ var RtfPlugin = class {
|
|
|
5619
5754
|
card.style.backgroundColor = "#ffffff";
|
|
5620
5755
|
card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08)";
|
|
5621
5756
|
card.style.borderRadius = "4px";
|
|
5622
|
-
card.style.padding = "
|
|
5757
|
+
card.style.padding = "64px 56px";
|
|
5623
5758
|
card.style.width = "816px";
|
|
5624
5759
|
card.style.minHeight = "1056px";
|
|
5625
5760
|
card.style.boxSizing = "border-box";
|
|
@@ -5633,22 +5768,35 @@ var RtfPlugin = class {
|
|
|
5633
5768
|
wrapper.appendChild(curCard);
|
|
5634
5769
|
pageElements = [curCard];
|
|
5635
5770
|
let curH = 0;
|
|
5636
|
-
const maxH =
|
|
5771
|
+
const maxH = 928;
|
|
5637
5772
|
for (let i = 0; i < contentNodes.length; i++) {
|
|
5638
5773
|
const child = contentNodes[i];
|
|
5639
5774
|
const chH = childHeights[i];
|
|
5640
|
-
|
|
5641
|
-
curH
|
|
5642
|
-
|
|
5775
|
+
const isChildEmpty = (child.textContent || "").trim().length === 0 && !child.querySelector("table, img, svg, canvas");
|
|
5776
|
+
if (curH === 0 && isChildEmpty) {
|
|
5777
|
+
continue;
|
|
5778
|
+
}
|
|
5779
|
+
if (curH + chH > maxH && curCard.childNodes.length > 0) {
|
|
5643
5780
|
curCard = createRtfCard();
|
|
5644
5781
|
wrapper.appendChild(curCard);
|
|
5645
5782
|
pageElements.push(curCard);
|
|
5646
5783
|
curH = 0;
|
|
5647
5784
|
}
|
|
5785
|
+
curCard.appendChild(child);
|
|
5786
|
+
curH += chH;
|
|
5787
|
+
}
|
|
5788
|
+
pageElements = pageElements.filter((card) => {
|
|
5789
|
+
const hasText = (card.textContent || "").trim().length > 0;
|
|
5790
|
+
const hasMedia = card.querySelector("table, img, svg, canvas") !== null;
|
|
5791
|
+
return hasText || hasMedia;
|
|
5792
|
+
});
|
|
5793
|
+
if (pageElements.length === 0) {
|
|
5794
|
+
pageElements = [curCard];
|
|
5648
5795
|
}
|
|
5649
5796
|
} catch (err) {
|
|
5650
5797
|
console.warn("[RtfPlugin] RTF render error, fallback text:", err);
|
|
5651
5798
|
const text = new TextDecoder("latin1").decode(ctx.buffer);
|
|
5799
|
+
const tables = parseRtfTables(text);
|
|
5652
5800
|
const rawPages = text.split(/\\page\b/).map((segment) => {
|
|
5653
5801
|
return segment.replace(/\\par[d]?/g, "\n").replace(/\\[a-zA-Z0-9\-]+/g, "").replace(/[{}]/g, "").trim();
|
|
5654
5802
|
}).filter((p) => p.length > 0);
|
|
@@ -5659,7 +5807,7 @@ var RtfPlugin = class {
|
|
|
5659
5807
|
pageCard.style.backgroundColor = "#ffffff";
|
|
5660
5808
|
pageCard.style.boxShadow = "0 2px 12px rgba(0,0,0,0.08)";
|
|
5661
5809
|
pageCard.style.borderRadius = "4px";
|
|
5662
|
-
pageCard.style.padding = "
|
|
5810
|
+
pageCard.style.padding = "64px 56px";
|
|
5663
5811
|
pageCard.style.width = "816px";
|
|
5664
5812
|
pageCard.style.minHeight = "1056px";
|
|
5665
5813
|
pageCard.style.boxSizing = "border-box";
|
|
@@ -5670,6 +5818,9 @@ var RtfPlugin = class {
|
|
|
5670
5818
|
pageCard.style.whiteSpace = "pre-wrap";
|
|
5671
5819
|
pageCard.style.display = i === 0 ? "block" : "none";
|
|
5672
5820
|
pageCard.textContent = pages[i];
|
|
5821
|
+
if (i === 1 && tables.length > 0) {
|
|
5822
|
+
tables.forEach((tbl) => pageCard.appendChild(renderRtfTableElement(tbl)));
|
|
5823
|
+
}
|
|
5673
5824
|
wrapper.appendChild(pageCard);
|
|
5674
5825
|
pageElements.push(pageCard);
|
|
5675
5826
|
}
|
|
@@ -5700,6 +5851,32 @@ var RtfPlugin = class {
|
|
|
5700
5851
|
getPageCount: () => totalPages,
|
|
5701
5852
|
getCurrentPage: () => currentPage,
|
|
5702
5853
|
goToPage: (page) => showPage(page),
|
|
5854
|
+
getThumbnails: async () => {
|
|
5855
|
+
const items = [];
|
|
5856
|
+
for (let idx = 0; idx < totalPages; idx++) {
|
|
5857
|
+
const pageIdx = idx;
|
|
5858
|
+
items.push({
|
|
5859
|
+
index: pageIdx,
|
|
5860
|
+
label: `Page ${pageIdx + 1}`,
|
|
5861
|
+
render: async (canvas) => {
|
|
5862
|
+
const ctx2d = canvas.getContext("2d");
|
|
5863
|
+
if (!ctx2d) return;
|
|
5864
|
+
canvas.width = 140;
|
|
5865
|
+
canvas.height = 180;
|
|
5866
|
+
ctx2d.fillStyle = "#ffffff";
|
|
5867
|
+
ctx2d.fillRect(0, 0, 140, 180);
|
|
5868
|
+
ctx2d.strokeStyle = "#cbd5e1";
|
|
5869
|
+
ctx2d.lineWidth = 1;
|
|
5870
|
+
ctx2d.strokeRect(0.5, 0.5, 139, 179);
|
|
5871
|
+
ctx2d.fillStyle = "#334155";
|
|
5872
|
+
ctx2d.font = 'bold 11px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
5873
|
+
ctx2d.textAlign = "center";
|
|
5874
|
+
ctx2d.fillText(`Page ${pageIdx + 1}`, 70, 95);
|
|
5875
|
+
}
|
|
5876
|
+
});
|
|
5877
|
+
}
|
|
5878
|
+
return items;
|
|
5879
|
+
},
|
|
5703
5880
|
zoomIn: () => {
|
|
5704
5881
|
isUserZoomed = true;
|
|
5705
5882
|
scale += 0.15;
|