@files-preview-app/preview-file 1.3.2 → 1.3.4
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 +472 -208
- 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 +472 -208
- package/dist/angular.js.map +1 -1
- package/dist/index.cjs +453 -205
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +453 -205
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +457 -205
- 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 +457 -205
- package/dist/react.js.map +1 -1
- package/dist/vue.cjs +456 -206
- 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 +456 -206
- 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,166 @@ 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
|
+
}
|
|
5499
|
+
function extractMediaFingerprint(el) {
|
|
5500
|
+
const img = el.tagName.toLowerCase() === "img" ? el : el.querySelector("img");
|
|
5501
|
+
if (img && img.src) {
|
|
5502
|
+
const s = img.src;
|
|
5503
|
+
return s.length > 300 ? `img_${s.slice(0, 80)}_${s.length}_${s.slice(-80)}` : `img_${s}`;
|
|
5504
|
+
}
|
|
5505
|
+
const innerImg = el.querySelector("image");
|
|
5506
|
+
if (innerImg) {
|
|
5507
|
+
const h = innerImg.getAttribute("xlink:href") || innerImg.getAttribute("href") || "";
|
|
5508
|
+
if (h) return h.length > 300 ? `svgimg_${h.slice(0, 80)}_${h.length}_${h.slice(-80)}` : `svgimg_${h}`;
|
|
5509
|
+
}
|
|
5510
|
+
const svg = el.tagName.toLowerCase() === "svg" ? el : el.querySelector("svg");
|
|
5511
|
+
if (svg) {
|
|
5512
|
+
const vb = svg.getAttribute("viewBox") || "";
|
|
5513
|
+
return `svg_${vb}_${svg.innerHTML.length}`;
|
|
5514
|
+
}
|
|
5515
|
+
return null;
|
|
5516
|
+
}
|
|
5420
5517
|
var RtfPlugin = class {
|
|
5421
5518
|
id = "rtf";
|
|
5422
5519
|
name = "Rich Text Format (RTF)";
|
|
@@ -5452,6 +5549,14 @@ var RtfPlugin = class {
|
|
|
5452
5549
|
}
|
|
5453
5550
|
});
|
|
5454
5551
|
actions.push(
|
|
5552
|
+
{
|
|
5553
|
+
id: "thumbnails",
|
|
5554
|
+
icon: "thumbnails",
|
|
5555
|
+
label: "Thumbnails",
|
|
5556
|
+
type: "button",
|
|
5557
|
+
group: "view",
|
|
5558
|
+
execute: () => instance.toggleThumbnails?.()
|
|
5559
|
+
},
|
|
5455
5560
|
{
|
|
5456
5561
|
id: "zoom-out",
|
|
5457
5562
|
icon: "zoom-out",
|
|
@@ -5579,9 +5684,29 @@ var RtfPlugin = class {
|
|
|
5579
5684
|
if (typeof RTFJS__namespace.loggingEnabled === "function") {
|
|
5580
5685
|
RTFJS__namespace.loggingEnabled(false);
|
|
5581
5686
|
}
|
|
5582
|
-
const
|
|
5687
|
+
const rawText = new TextDecoder("latin1").decode(ctx.buffer);
|
|
5688
|
+
const tables = parseRtfTables(rawText);
|
|
5689
|
+
const seenMediaSignatures = /* @__PURE__ */ new Set();
|
|
5690
|
+
const doc = new RTFJS__namespace.Document(ctx.buffer, {
|
|
5691
|
+
onPicture: (isLegacy, createPic) => {
|
|
5692
|
+
if (isLegacy === true) {
|
|
5693
|
+
return null;
|
|
5694
|
+
}
|
|
5695
|
+
const pic = createPic();
|
|
5696
|
+
if (!pic) return null;
|
|
5697
|
+
const fp = extractMediaFingerprint(pic);
|
|
5698
|
+
if (fp) {
|
|
5699
|
+
if (seenMediaSignatures.has(fp)) {
|
|
5700
|
+
return null;
|
|
5701
|
+
}
|
|
5702
|
+
seenMediaSignatures.add(fp);
|
|
5703
|
+
}
|
|
5704
|
+
return pic;
|
|
5705
|
+
}
|
|
5706
|
+
});
|
|
5583
5707
|
const htmlElements = await doc.render();
|
|
5584
5708
|
const contentNodes = [];
|
|
5709
|
+
const seenInContentBlocks = /* @__PURE__ */ new Set();
|
|
5585
5710
|
const extractBlocks = (nodes) => {
|
|
5586
5711
|
for (const item of nodes) {
|
|
5587
5712
|
if (!item || !(item instanceof HTMLElement)) continue;
|
|
@@ -5593,6 +5718,32 @@ var RtfPlugin = class {
|
|
|
5593
5718
|
if (hasChildBlocks && !["table", "tr", "td", "th", "ul", "ol", "li"].includes(tag)) {
|
|
5594
5719
|
extractBlocks(Array.from(item.children));
|
|
5595
5720
|
} else {
|
|
5721
|
+
const fp = extractMediaFingerprint(item);
|
|
5722
|
+
if (fp) {
|
|
5723
|
+
if (seenInContentBlocks.has(fp)) {
|
|
5724
|
+
continue;
|
|
5725
|
+
}
|
|
5726
|
+
seenInContentBlocks.add(fp);
|
|
5727
|
+
}
|
|
5728
|
+
const hasMedia = item.querySelector("img, svg, canvas, table") !== null || ["img", "svg", "table"].includes(tag);
|
|
5729
|
+
const textContent = (item.textContent || "").trim();
|
|
5730
|
+
if (!hasMedia && textContent.length === 0) {
|
|
5731
|
+
continue;
|
|
5732
|
+
}
|
|
5733
|
+
const svgs = item.querySelectorAll("svg, img");
|
|
5734
|
+
svgs.forEach((s) => {
|
|
5735
|
+
const el = s;
|
|
5736
|
+
el.style.maxWidth = "100%";
|
|
5737
|
+
el.style.maxHeight = "360px";
|
|
5738
|
+
el.style.display = "block";
|
|
5739
|
+
el.style.margin = "12px auto";
|
|
5740
|
+
if (s.tagName.toLowerCase() === "svg") {
|
|
5741
|
+
s.removeAttribute("width");
|
|
5742
|
+
s.removeAttribute("height");
|
|
5743
|
+
el.style.width = "100%";
|
|
5744
|
+
el.style.maxHeight = "360px";
|
|
5745
|
+
}
|
|
5746
|
+
});
|
|
5596
5747
|
if (tag === "p" || tag === "div") {
|
|
5597
5748
|
item.style.display = "block";
|
|
5598
5749
|
item.style.marginBottom = "12px";
|
|
@@ -5603,52 +5754,120 @@ var RtfPlugin = class {
|
|
|
5603
5754
|
}
|
|
5604
5755
|
};
|
|
5605
5756
|
extractBlocks(htmlElements);
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5757
|
+
tables.forEach((table) => {
|
|
5758
|
+
const tableEl = renderRtfTableElement(table);
|
|
5759
|
+
let inserted = false;
|
|
5760
|
+
if (table.anchorBefore && table.anchorBefore.length > 10) {
|
|
5761
|
+
const keyword = table.anchorBefore.slice(-35).trim();
|
|
5762
|
+
for (let i = 0; i < contentNodes.length; i++) {
|
|
5763
|
+
if (contentNodes[i].textContent?.includes(keyword)) {
|
|
5764
|
+
contentNodes.splice(i + 1, 0, tableEl);
|
|
5765
|
+
inserted = true;
|
|
5766
|
+
break;
|
|
5767
|
+
}
|
|
5768
|
+
}
|
|
5769
|
+
}
|
|
5770
|
+
if (!inserted && table.anchorAfter && table.anchorAfter.length > 10) {
|
|
5771
|
+
const keyword = table.anchorAfter.slice(0, 35).trim();
|
|
5772
|
+
for (let i = 0; i < contentNodes.length; i++) {
|
|
5773
|
+
if (contentNodes[i].textContent?.includes(keyword)) {
|
|
5774
|
+
contentNodes.splice(i, 0, tableEl);
|
|
5775
|
+
inserted = true;
|
|
5776
|
+
break;
|
|
5777
|
+
}
|
|
5778
|
+
}
|
|
5779
|
+
}
|
|
5780
|
+
if (!inserted) {
|
|
5781
|
+
if (contentNodes.length > 2) {
|
|
5782
|
+
contentNodes.splice(2, 0, tableEl);
|
|
5783
|
+
} else {
|
|
5784
|
+
contentNodes.push(tableEl);
|
|
5785
|
+
}
|
|
5786
|
+
}
|
|
5614
5787
|
});
|
|
5615
|
-
|
|
5616
|
-
const createRtfCard = () => {
|
|
5788
|
+
const createRtfCard = (pageNum) => {
|
|
5617
5789
|
const card = document.createElement("div");
|
|
5618
5790
|
card.className = "fp-rtf-page-card";
|
|
5791
|
+
card.setAttribute("data-page-number", String(pageNum));
|
|
5619
5792
|
card.style.backgroundColor = "#ffffff";
|
|
5620
|
-
card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08)";
|
|
5793
|
+
card.style.boxShadow = "0 4px 24px rgba(0,0,0,0.08), 0 1px 3px rgba(0,0,0,0.04)";
|
|
5621
5794
|
card.style.borderRadius = "4px";
|
|
5622
|
-
card.style.padding = "
|
|
5795
|
+
card.style.padding = "64px 56px";
|
|
5623
5796
|
card.style.width = "816px";
|
|
5624
5797
|
card.style.minHeight = "1056px";
|
|
5798
|
+
card.style.maxHeight = "1056px";
|
|
5799
|
+
card.style.overflow = "hidden";
|
|
5625
5800
|
card.style.boxSizing = "border-box";
|
|
5626
5801
|
card.style.marginBottom = "24px";
|
|
5627
5802
|
card.style.fontFamily = 'Calibri, "Segoe UI", Arial, sans-serif';
|
|
5628
5803
|
card.style.lineHeight = "1.6";
|
|
5629
5804
|
card.style.color = "#1e293b";
|
|
5805
|
+
card.style.position = "relative";
|
|
5630
5806
|
return card;
|
|
5631
5807
|
};
|
|
5632
|
-
|
|
5808
|
+
wrapper.innerHTML = "";
|
|
5809
|
+
const measureCard = createRtfCard(0);
|
|
5810
|
+
measureCard.style.maxHeight = "none";
|
|
5811
|
+
measureCard.style.height = "auto";
|
|
5812
|
+
wrapper.appendChild(measureCard);
|
|
5813
|
+
contentNodes.forEach((node) => measureCard.appendChild(node));
|
|
5814
|
+
const childHeights = contentNodes.map((c) => {
|
|
5815
|
+
const rect = c.getBoundingClientRect ? c.getBoundingClientRect() : null;
|
|
5816
|
+
const rectH = rect ? rect.height : 0;
|
|
5817
|
+
const offH = c.offsetHeight || 0;
|
|
5818
|
+
let realH = Math.max(rectH, offH);
|
|
5819
|
+
try {
|
|
5820
|
+
const cs = window.getComputedStyle(c);
|
|
5821
|
+
realH += (parseFloat(cs.marginTop) || 0) + (parseFloat(cs.marginBottom) || 0);
|
|
5822
|
+
} catch {
|
|
5823
|
+
}
|
|
5824
|
+
const hasMedia = c.querySelector("img, svg") !== null || ["img", "svg"].includes(c.tagName.toLowerCase());
|
|
5825
|
+
const hasTable = c.querySelector("table") !== null || c.tagName.toLowerCase() === "table";
|
|
5826
|
+
if (hasMedia) {
|
|
5827
|
+
realH = Math.max(realH, 300);
|
|
5828
|
+
} else if (hasTable) {
|
|
5829
|
+
realH = Math.max(realH, 240);
|
|
5830
|
+
}
|
|
5831
|
+
if (realH > 0) return realH;
|
|
5832
|
+
const textLen = c.textContent?.trim().length || 0;
|
|
5833
|
+
return Math.max(28, Math.ceil(textLen / 75) * 26 + 16);
|
|
5834
|
+
});
|
|
5835
|
+
wrapper.innerHTML = "";
|
|
5836
|
+
let curCard = createRtfCard(1);
|
|
5633
5837
|
wrapper.appendChild(curCard);
|
|
5634
5838
|
pageElements = [curCard];
|
|
5635
5839
|
let curH = 0;
|
|
5636
|
-
const maxH =
|
|
5840
|
+
const maxH = 860;
|
|
5637
5841
|
for (let i = 0; i < contentNodes.length; i++) {
|
|
5638
5842
|
const child = contentNodes[i];
|
|
5639
5843
|
const chH = childHeights[i];
|
|
5640
|
-
|
|
5641
|
-
curH
|
|
5642
|
-
|
|
5643
|
-
|
|
5844
|
+
const isChildEmpty = (child.textContent || "").trim().length === 0 && !child.querySelector("table, img, svg, canvas");
|
|
5845
|
+
if (curH === 0 && isChildEmpty) {
|
|
5846
|
+
continue;
|
|
5847
|
+
}
|
|
5848
|
+
const isTable = child.querySelector("table") !== null || child.tagName.toLowerCase() === "table";
|
|
5849
|
+
const shouldBreakBeforeTable = isTable && curH > 400 && curCard.childNodes.length > 0;
|
|
5850
|
+
if ((curH + chH > maxH || shouldBreakBeforeTable) && curCard.childNodes.length > 0) {
|
|
5851
|
+
curCard = createRtfCard(pageElements.length + 1);
|
|
5644
5852
|
wrapper.appendChild(curCard);
|
|
5645
5853
|
pageElements.push(curCard);
|
|
5646
5854
|
curH = 0;
|
|
5647
5855
|
}
|
|
5856
|
+
curCard.appendChild(child);
|
|
5857
|
+
curH += chH;
|
|
5858
|
+
}
|
|
5859
|
+
pageElements = pageElements.filter((card) => {
|
|
5860
|
+
const hasText = (card.textContent || "").trim().length > 0;
|
|
5861
|
+
const hasMedia = card.querySelector("table, img, svg, canvas") !== null;
|
|
5862
|
+
return hasText || hasMedia;
|
|
5863
|
+
});
|
|
5864
|
+
if (pageElements.length === 0) {
|
|
5865
|
+
pageElements = [curCard];
|
|
5648
5866
|
}
|
|
5649
5867
|
} catch (err) {
|
|
5650
5868
|
console.warn("[RtfPlugin] RTF render error, fallback text:", err);
|
|
5651
5869
|
const text = new TextDecoder("latin1").decode(ctx.buffer);
|
|
5870
|
+
const tables = parseRtfTables(text);
|
|
5652
5871
|
const rawPages = text.split(/\\page\b/).map((segment) => {
|
|
5653
5872
|
return segment.replace(/\\par[d]?/g, "\n").replace(/\\[a-zA-Z0-9\-]+/g, "").replace(/[{}]/g, "").trim();
|
|
5654
5873
|
}).filter((p) => p.length > 0);
|
|
@@ -5659,7 +5878,7 @@ var RtfPlugin = class {
|
|
|
5659
5878
|
pageCard.style.backgroundColor = "#ffffff";
|
|
5660
5879
|
pageCard.style.boxShadow = "0 2px 12px rgba(0,0,0,0.08)";
|
|
5661
5880
|
pageCard.style.borderRadius = "4px";
|
|
5662
|
-
pageCard.style.padding = "
|
|
5881
|
+
pageCard.style.padding = "64px 56px";
|
|
5663
5882
|
pageCard.style.width = "816px";
|
|
5664
5883
|
pageCard.style.minHeight = "1056px";
|
|
5665
5884
|
pageCard.style.boxSizing = "border-box";
|
|
@@ -5670,6 +5889,9 @@ var RtfPlugin = class {
|
|
|
5670
5889
|
pageCard.style.whiteSpace = "pre-wrap";
|
|
5671
5890
|
pageCard.style.display = i === 0 ? "block" : "none";
|
|
5672
5891
|
pageCard.textContent = pages[i];
|
|
5892
|
+
if (i === 1 && tables.length > 0) {
|
|
5893
|
+
tables.forEach((tbl) => pageCard.appendChild(renderRtfTableElement(tbl)));
|
|
5894
|
+
}
|
|
5673
5895
|
wrapper.appendChild(pageCard);
|
|
5674
5896
|
pageElements.push(pageCard);
|
|
5675
5897
|
}
|
|
@@ -5700,6 +5922,32 @@ var RtfPlugin = class {
|
|
|
5700
5922
|
getPageCount: () => totalPages,
|
|
5701
5923
|
getCurrentPage: () => currentPage,
|
|
5702
5924
|
goToPage: (page) => showPage(page),
|
|
5925
|
+
getThumbnails: async () => {
|
|
5926
|
+
const items = [];
|
|
5927
|
+
for (let idx = 0; idx < totalPages; idx++) {
|
|
5928
|
+
const pageIdx = idx;
|
|
5929
|
+
items.push({
|
|
5930
|
+
index: pageIdx,
|
|
5931
|
+
label: `Page ${pageIdx + 1}`,
|
|
5932
|
+
render: async (canvas) => {
|
|
5933
|
+
const ctx2d = canvas.getContext("2d");
|
|
5934
|
+
if (!ctx2d) return;
|
|
5935
|
+
canvas.width = 140;
|
|
5936
|
+
canvas.height = 180;
|
|
5937
|
+
ctx2d.fillStyle = "#ffffff";
|
|
5938
|
+
ctx2d.fillRect(0, 0, 140, 180);
|
|
5939
|
+
ctx2d.strokeStyle = "#cbd5e1";
|
|
5940
|
+
ctx2d.lineWidth = 1;
|
|
5941
|
+
ctx2d.strokeRect(0.5, 0.5, 139, 179);
|
|
5942
|
+
ctx2d.fillStyle = "#334155";
|
|
5943
|
+
ctx2d.font = 'bold 11px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
5944
|
+
ctx2d.textAlign = "center";
|
|
5945
|
+
ctx2d.fillText(`Page ${pageIdx + 1}`, 70, 95);
|
|
5946
|
+
}
|
|
5947
|
+
});
|
|
5948
|
+
}
|
|
5949
|
+
return items;
|
|
5950
|
+
},
|
|
5703
5951
|
zoomIn: () => {
|
|
5704
5952
|
isUserZoomed = true;
|
|
5705
5953
|
scale += 0.15;
|