@eternalheart/react-file-preview 1.4.0 → 1.5.0
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 +437 -60
- package/README.zh-CN.md +437 -60
- package/lib/FilePreviewContent.d.ts +1 -0
- package/lib/FilePreviewContent.d.ts.map +1 -1
- package/lib/FilePreviewEmbed.d.ts +2 -0
- package/lib/FilePreviewEmbed.d.ts.map +1 -1
- package/lib/FilePreviewModal.d.ts +2 -0
- package/lib/FilePreviewModal.d.ts.map +1 -1
- package/lib/chunks/index-2sX2d4iv.mjs +291 -0
- package/lib/chunks/index-2sX2d4iv.mjs.map +1 -0
- package/lib/chunks/index-Bdj8_B80.mjs +120 -0
- package/lib/chunks/index-Bdj8_B80.mjs.map +1 -0
- package/lib/chunks/index-CCcZzLUM.mjs +107 -0
- package/lib/chunks/index-CCcZzLUM.mjs.map +1 -0
- package/lib/chunks/{index-CzM2mxrD.mjs → index-CKdQL1Bk.mjs} +130 -128
- package/lib/chunks/{index-CzM2mxrD.mjs.map → index-CKdQL1Bk.mjs.map} +1 -1
- package/lib/chunks/index-CQYrhe7Z.mjs +275 -0
- package/lib/chunks/index-CQYrhe7Z.mjs.map +1 -0
- package/lib/chunks/{index-DuP0Tlpo.mjs → index-CRZqNMQ7.mjs} +43 -41
- package/lib/chunks/index-CRZqNMQ7.mjs.map +1 -0
- package/lib/chunks/{index-Cp68OevR.mjs → index-CTghYlSh.mjs} +1299 -1297
- package/lib/chunks/{index-Cp68OevR.mjs.map → index-CTghYlSh.mjs.map} +1 -1
- package/lib/chunks/index-CuTz7dbd.mjs +313 -0
- package/lib/chunks/index-CuTz7dbd.mjs.map +1 -0
- package/lib/chunks/index-CuWzRQZw.mjs +116 -0
- package/lib/chunks/index-CuWzRQZw.mjs.map +1 -0
- package/lib/chunks/index-Cz23v-TW.mjs +2409 -0
- package/lib/chunks/index-Cz23v-TW.mjs.map +1 -0
- package/lib/chunks/{index-kALp0tqz.mjs → index-D-Is8qvU.mjs} +22 -20
- package/lib/chunks/index-D-Is8qvU.mjs.map +1 -0
- package/lib/chunks/index-Da3FN2-3.mjs +359 -0
- package/lib/chunks/index-Da3FN2-3.mjs.map +1 -0
- package/lib/chunks/index-Dc6q1OKl.mjs +78 -0
- package/lib/chunks/index-Dc6q1OKl.mjs.map +1 -0
- package/lib/chunks/{index-10O8tfTH.mjs → index-DoGKcq9y.mjs} +194 -192
- package/lib/chunks/index-DoGKcq9y.mjs.map +1 -0
- package/lib/chunks/{index-C_BJatqr.mjs → index-DzCLf1Db.mjs} +42 -40
- package/lib/chunks/index-DzCLf1Db.mjs.map +1 -0
- package/lib/chunks/index-FomaQSaL.mjs +329 -0
- package/lib/chunks/index-FomaQSaL.mjs.map +1 -0
- package/lib/chunks/{index-DaAXRBWL.mjs → index-OXjOFggq.mjs} +864 -862
- package/lib/chunks/{index-DaAXRBWL.mjs.map → index-OXjOFggq.mjs.map} +1 -1
- package/lib/chunks/index-WLepq2g2.mjs +200 -0
- package/lib/chunks/index-WLepq2g2.mjs.map +1 -0
- package/lib/chunks/{index-DoFsoBKL.mjs → index-_B5marES.mjs} +27 -25
- package/lib/chunks/index-_B5marES.mjs.map +1 -0
- package/lib/chunks/useShikiHighlight-Bbs8Fbqs.mjs +36 -0
- package/lib/chunks/useShikiHighlight-Bbs8Fbqs.mjs.map +1 -0
- package/lib/components/preview/FilePreviewToolbar.d.ts +1 -0
- package/lib/components/preview/FilePreviewToolbar.d.ts.map +1 -1
- package/lib/components/preview/ToolbarButton.d.ts +3 -1
- package/lib/components/preview/ToolbarButton.d.ts.map +1 -1
- package/lib/hooks/index.d.ts +0 -6
- package/lib/hooks/index.d.ts.map +1 -1
- package/lib/hooks/useShikiHighlight.d.ts +3 -1
- package/lib/hooks/useShikiHighlight.d.ts.map +1 -1
- package/lib/index.cjs +32 -30
- package/lib/index.cjs.map +1 -1
- package/lib/index.css +1 -1
- package/lib/index.mjs +1 -1
- package/lib/renderers/Audio/index.d.ts +2 -1
- package/lib/renderers/Audio/index.d.ts.map +1 -1
- package/lib/renderers/Csv/index.d.ts +2 -1
- package/lib/renderers/Csv/index.d.ts.map +1 -1
- package/lib/renderers/Docx/index.d.ts +2 -1
- package/lib/renderers/Docx/index.d.ts.map +1 -1
- package/lib/renderers/Epub/index.d.ts +2 -3
- package/lib/renderers/Epub/index.d.ts.map +1 -1
- package/lib/renderers/Font/index.d.ts +2 -1
- package/lib/renderers/Font/index.d.ts.map +1 -1
- package/lib/renderers/Image/index.d.ts +6 -7
- package/lib/renderers/Image/index.d.ts.map +1 -1
- package/lib/renderers/Json/index.d.ts +2 -1
- package/lib/renderers/Json/index.d.ts.map +1 -1
- package/lib/renderers/Markdown/index.d.ts +2 -2
- package/lib/renderers/Markdown/index.d.ts.map +1 -1
- package/lib/renderers/Mobi/index.d.ts +2 -3
- package/lib/renderers/Mobi/index.d.ts.map +1 -1
- package/lib/renderers/Msg/index.d.ts +2 -1
- package/lib/renderers/Msg/index.d.ts.map +1 -1
- package/lib/renderers/Pdf/index.d.ts +4 -8
- package/lib/renderers/Pdf/index.d.ts.map +1 -1
- package/lib/renderers/Pptx/index.d.ts +2 -1
- package/lib/renderers/Pptx/index.d.ts.map +1 -1
- package/lib/renderers/Subtitle/index.d.ts +2 -1
- package/lib/renderers/Subtitle/index.d.ts.map +1 -1
- package/lib/renderers/Text/index.d.ts +2 -3
- package/lib/renderers/Text/index.d.ts.map +1 -1
- package/lib/renderers/Video/index.d.ts +2 -1
- package/lib/renderers/Video/index.d.ts.map +1 -1
- package/lib/renderers/Xlsx/index.d.ts +2 -1
- package/lib/renderers/Xlsx/index.d.ts.map +1 -1
- package/lib/renderers/Xml/index.d.ts +2 -1
- package/lib/renderers/Xml/index.d.ts.map +1 -1
- package/lib/renderers/Zip/index.d.ts +7 -2
- package/lib/renderers/Zip/index.d.ts.map +1 -1
- package/lib/renderers/base.types.d.ts +38 -0
- package/lib/renderers/base.types.d.ts.map +1 -0
- package/lib/renderers/registry.d.ts +36 -0
- package/lib/renderers/registry.d.ts.map +1 -0
- package/lib/renderers/toolbar.types.d.ts +2 -0
- package/lib/renderers/toolbar.types.d.ts.map +1 -1
- package/lib/toolbar/renderItems.d.ts.map +1 -1
- package/package.json +3 -3
- package/lib/chunks/index-0v5STX5f.mjs +0 -105
- package/lib/chunks/index-0v5STX5f.mjs.map +0 -1
- package/lib/chunks/index-10O8tfTH.mjs.map +0 -1
- package/lib/chunks/index-BCyv1HM9.mjs +0 -175
- package/lib/chunks/index-BCyv1HM9.mjs.map +0 -1
- package/lib/chunks/index-Bo90aGhy.mjs +0 -114
- package/lib/chunks/index-Bo90aGhy.mjs.map +0 -1
- package/lib/chunks/index-CEeKt7L3.mjs +0 -2808
- package/lib/chunks/index-CEeKt7L3.mjs.map +0 -1
- package/lib/chunks/index-CWKbnvW6.mjs +0 -270
- package/lib/chunks/index-CWKbnvW6.mjs.map +0 -1
- package/lib/chunks/index-C_BJatqr.mjs.map +0 -1
- package/lib/chunks/index-Cbz5Z6ZK.mjs +0 -263
- package/lib/chunks/index-Cbz5Z6ZK.mjs.map +0 -1
- package/lib/chunks/index-DTYBFuAH.mjs +0 -357
- package/lib/chunks/index-DTYBFuAH.mjs.map +0 -1
- package/lib/chunks/index-DoFsoBKL.mjs.map +0 -1
- package/lib/chunks/index-DuP0Tlpo.mjs.map +0 -1
- package/lib/chunks/index-Dv3RQz86.mjs +0 -270
- package/lib/chunks/index-Dv3RQz86.mjs.map +0 -1
- package/lib/chunks/index-QfpHck8N.mjs +0 -55
- package/lib/chunks/index-QfpHck8N.mjs.map +0 -1
- package/lib/chunks/index-gjSQeou7.mjs +0 -194
- package/lib/chunks/index-gjSQeou7.mjs.map +0 -1
- package/lib/chunks/index-kALp0tqz.mjs.map +0 -1
- package/lib/chunks/index-kCeSnFs-.mjs +0 -54
- package/lib/chunks/index-kCeSnFs-.mjs.map +0 -1
- package/lib/chunks/useShikiHighlight-BA9qgdGA.mjs +0 -23
- package/lib/chunks/useShikiHighlight-BA9qgdGA.mjs.map +0 -1
- package/lib/hooks/rendererReducer.d.ts +0 -10
- package/lib/hooks/rendererReducer.d.ts.map +0 -1
- package/lib/hooks/types.d.ts +0 -152
- package/lib/hooks/types.d.ts.map +0 -1
- package/lib/hooks/useBookRenderer.d.ts +0 -14
- package/lib/hooks/useBookRenderer.d.ts.map +0 -1
- package/lib/hooks/useFilePreviewState.d.ts +0 -10
- package/lib/hooks/useFilePreviewState.d.ts.map +0 -1
- package/lib/hooks/useImageAutoFit.d.ts +0 -13
- package/lib/hooks/useImageAutoFit.d.ts.map +0 -1
- package/lib/hooks/useToolbarConfig.d.ts +0 -25
- package/lib/hooks/useToolbarConfig.d.ts.map +0 -1
- package/lib/renderers/Epub/toolbar.d.ts +0 -13
- package/lib/renderers/Epub/toolbar.d.ts.map +0 -1
- package/lib/renderers/Image/toolbar.d.ts +0 -15
- package/lib/renderers/Image/toolbar.d.ts.map +0 -1
- package/lib/renderers/Markdown/toolbar.d.ts +0 -9
- package/lib/renderers/Markdown/toolbar.d.ts.map +0 -1
- package/lib/renderers/Mobi/toolbar.d.ts +0 -13
- package/lib/renderers/Mobi/toolbar.d.ts.map +0 -1
- package/lib/renderers/Pdf/toolbar.d.ts +0 -16
- package/lib/renderers/Pdf/toolbar.d.ts.map +0 -1
- package/lib/renderers/Text/toolbar.d.ts +0 -12
- package/lib/renderers/Text/toolbar.d.ts.map +0 -1
- package/lib/renderers/Zip/toolbar.d.ts +0 -13
- package/lib/renderers/Zip/toolbar.d.ts.map +0 -1
- package/lib/toolbar/registry.d.ts +0 -51
- package/lib/toolbar/registry.d.ts.map +0 -1
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { jsx as o, jsxs as F } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as Lt, useRef as W, useState as d, useCallback as c, useEffect as C, useImperativeHandle as Pt } from "react";
|
|
3
|
+
import { List as Ft, ChevronLeft as Wt, ChevronRight as _t, Minimize2 as $t, Maximize2 as jt, X as It } from "lucide-react";
|
|
4
|
+
import "foliate-js/view.js";
|
|
5
|
+
import { u as Ht, a as Dt } from "./index-Cz23v-TW.mjs";
|
|
6
|
+
import { R as Xt } from "./RendererError-D5i8eSpN.mjs";
|
|
7
|
+
const Gt = `
|
|
8
|
+
@namespace epub "http://www.idpf.org/2007/ops";
|
|
9
|
+
html { color-scheme: light; }
|
|
10
|
+
body {
|
|
11
|
+
background: #ffffff !important;
|
|
12
|
+
color: #1a1a1a !important;
|
|
13
|
+
font-family: "Noto Serif SC", "Source Han Serif SC", Georgia, "Times New Roman", serif !important;
|
|
14
|
+
font-size: 16px !important;
|
|
15
|
+
line-height: 2 !important;
|
|
16
|
+
max-width: 100% !important;
|
|
17
|
+
box-sizing: border-box !important;
|
|
18
|
+
word-break: break-word !important;
|
|
19
|
+
overflow-wrap: break-word !important;
|
|
20
|
+
}
|
|
21
|
+
p, li, blockquote, dd { line-height: 2; text-align: justify; }
|
|
22
|
+
p { text-indent: 2em; margin: 0.8em 0; }
|
|
23
|
+
h1 { text-align: center; margin: 1.5em 0 1em; }
|
|
24
|
+
h2 { margin: 1.2em 0 0.8em; }
|
|
25
|
+
h3 { margin: 1em 0 0.6em; }
|
|
26
|
+
img { max-width: 100% !important; height: auto !important; }
|
|
27
|
+
a { color: #2563eb; text-decoration: none; }
|
|
28
|
+
pre { white-space: pre-wrap !important; }
|
|
29
|
+
`, Ut = 794, qt = Lt(
|
|
30
|
+
({ url: _ }, yt) => {
|
|
31
|
+
const i = Ht(), vt = Dt(), Y = W(null), l = W(null), Z = W(1), [kt, K] = d(!0), [$, V] = d(null), [R, tt] = d([]), [w, T] = d(!1), [et, j] = d(""), [u, Nt] = d(!1), [E, Ct] = d(0), [I, Rt] = d(0), rt = W(!1);
|
|
32
|
+
rt.current = u;
|
|
33
|
+
const M = c((e, r) => {
|
|
34
|
+
r > 0 && (Z.current = r), Ct(Math.max(1, e + 1)), Rt(Z.current);
|
|
35
|
+
}, []), H = c(() => {
|
|
36
|
+
const e = l.current;
|
|
37
|
+
e && e.prev().catch(() => {
|
|
38
|
+
});
|
|
39
|
+
}, []), D = c(() => {
|
|
40
|
+
const e = l.current;
|
|
41
|
+
e && e.next().catch(() => {
|
|
42
|
+
});
|
|
43
|
+
}, []), X = c(() => T((e) => !e), []), G = c(() => {
|
|
44
|
+
const e = !rt.current;
|
|
45
|
+
Nt(e);
|
|
46
|
+
const r = l.current;
|
|
47
|
+
if (!r) return;
|
|
48
|
+
const t = r.renderer;
|
|
49
|
+
t && t.setAttribute("max-inline-size", e ? "9999" : "720");
|
|
50
|
+
}, []), O = W(/* @__PURE__ */ new Set()), p = c(() => {
|
|
51
|
+
O.current.forEach((e) => e());
|
|
52
|
+
}, []);
|
|
53
|
+
C(() => {
|
|
54
|
+
p();
|
|
55
|
+
}, [E, p]), C(() => {
|
|
56
|
+
p();
|
|
57
|
+
}, [I, p]), C(() => {
|
|
58
|
+
p();
|
|
59
|
+
}, [u, p]), C(() => {
|
|
60
|
+
p();
|
|
61
|
+
}, [R.length, p]);
|
|
62
|
+
const ot = c(() => [
|
|
63
|
+
{
|
|
64
|
+
items: [
|
|
65
|
+
{ type: "button", icon: /* @__PURE__ */ o(Ft, { className: "rfp-w-4 rfp-h-4" }), tooltip: i("toolbar.toc"), action: X, disabled: R.length === 0, active: w }
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
items: [
|
|
70
|
+
{ type: "button", icon: /* @__PURE__ */ o(Wt, { className: "rfp-w-4 rfp-h-4" }), tooltip: i("toolbar.prev_page"), action: H, disabled: E <= 1 },
|
|
71
|
+
{ type: "text", content: `${E} / ${I}`, minWidth: "4rem" },
|
|
72
|
+
{ type: "button", icon: /* @__PURE__ */ o(_t, { className: "rfp-w-4 rfp-h-4" }), tooltip: i("toolbar.next_page"), action: D, disabled: E >= I }
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
items: [
|
|
77
|
+
{ type: "button", icon: u ? /* @__PURE__ */ o($t, { className: "rfp-w-4 rfp-h-4" }) : /* @__PURE__ */ o(jt, { className: "rfp-w-4 rfp-h-4" }), tooltip: i(u ? "toolbar.normal_width" : "toolbar.full_width"), action: G, active: u }
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
], [E, I, u, w, R.length, i, H, D, X, G]), Tt = c((e) => {
|
|
81
|
+
var r;
|
|
82
|
+
j(e), T(!1), (r = l.current) == null || r.goTo(e).catch(() => {
|
|
83
|
+
});
|
|
84
|
+
}, []);
|
|
85
|
+
Pt(yt, () => ({
|
|
86
|
+
getToolbarGroups: ot,
|
|
87
|
+
onToolbarChange: (e) => (O.current.add(e), () => O.current.delete(e)),
|
|
88
|
+
prevPage: H,
|
|
89
|
+
nextPage: D,
|
|
90
|
+
toggleFullWidth: G,
|
|
91
|
+
toggleToc: X
|
|
92
|
+
}), [ot, H, D, G, X]), C(() => {
|
|
93
|
+
const e = (r) => {
|
|
94
|
+
var t;
|
|
95
|
+
(t = r.filename) != null && t.includes("paginator") && r.preventDefault();
|
|
96
|
+
};
|
|
97
|
+
return window.addEventListener("error", e), () => window.removeEventListener("error", e);
|
|
98
|
+
}, []), C(() => {
|
|
99
|
+
const e = Y.current;
|
|
100
|
+
if (!e || !_) return;
|
|
101
|
+
let r = !1, t = null, S = !1;
|
|
102
|
+
const m = /* @__PURE__ */ new Map(), U = async () => {
|
|
103
|
+
var h, b, z, at, st, it;
|
|
104
|
+
if (!r) {
|
|
105
|
+
K(!0), V(null), tt([]), T(!1), j(""), e.replaceChildren();
|
|
106
|
+
try {
|
|
107
|
+
t = document.createElement("foliate-view"), e.appendChild(t), l.current = t, t.addEventListener("relocate", (ft) => {
|
|
108
|
+
var pt, dt, ut, mt, ht, bt, gt, xt;
|
|
109
|
+
const a = ft.detail;
|
|
110
|
+
if (!a) return;
|
|
111
|
+
const f = l.current, ct = ((pt = f == null ? void 0 : f.book) == null ? void 0 : pt.sections.length) ?? 0, s = f == null ? void 0 : f.renderer, q = ((ut = (dt = s == null ? void 0 : s.getContents) == null ? void 0 : dt.call(s)[0]) == null ? void 0 : ut.index) ?? -1;
|
|
112
|
+
if (s && typeof s.page == "number" && typeof s.pages == "number" && s.pages > 2 && q >= 0) {
|
|
113
|
+
S = !0;
|
|
114
|
+
const x = s.pages - 2;
|
|
115
|
+
m.set(q, x);
|
|
116
|
+
let v = 0;
|
|
117
|
+
for (let N = 0; N < q; N++)
|
|
118
|
+
v += m.get(N) ?? 0;
|
|
119
|
+
const A = v + Math.min(x, Math.max(1, s.page)), L = (a.fraction ?? 0) >= 0.999;
|
|
120
|
+
let k;
|
|
121
|
+
if (ct === 1)
|
|
122
|
+
k = x;
|
|
123
|
+
else if (L)
|
|
124
|
+
k = A;
|
|
125
|
+
else {
|
|
126
|
+
const N = ((mt = f == null ? void 0 : f.book) == null ? void 0 : mt.sections) ?? [], wt = ((ht = N[q]) == null ? void 0 : ht.size) ?? 0, zt = wt > 0 ? x / wt : 0;
|
|
127
|
+
let Q = 0;
|
|
128
|
+
for (let P = 0; P < ct; P++)
|
|
129
|
+
if (m.has(P))
|
|
130
|
+
Q += m.get(P);
|
|
131
|
+
else {
|
|
132
|
+
const At = ((bt = N[P]) == null ? void 0 : bt.size) ?? 0;
|
|
133
|
+
Q += Math.max(1, Math.round(At * zt));
|
|
134
|
+
}
|
|
135
|
+
k = Math.max(A, Q);
|
|
136
|
+
}
|
|
137
|
+
M(A - 1, k);
|
|
138
|
+
const J = a.tocItem;
|
|
139
|
+
J != null && J.href && j(J.href);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const y = a.location;
|
|
143
|
+
if (y && typeof y.current == "number" && typeof y.total == "number") {
|
|
144
|
+
S = !0;
|
|
145
|
+
const v = (a.fraction ?? 0) >= 0.999 ? y.current + 1 : y.total;
|
|
146
|
+
M(y.current, v);
|
|
147
|
+
} else {
|
|
148
|
+
const x = ((xt = (gt = l.current) == null ? void 0 : gt.book) == null ? void 0 : xt.sections) ?? [], v = a.index ?? 0, A = a.fraction ?? 0, L = Math.max(x.length, 1), k = Math.round((v + A) / L * L);
|
|
149
|
+
M(k, L);
|
|
150
|
+
}
|
|
151
|
+
const B = a.tocItem;
|
|
152
|
+
B != null && B.href && j(B.href);
|
|
153
|
+
});
|
|
154
|
+
const g = await vt(_);
|
|
155
|
+
if (r) return;
|
|
156
|
+
if (!g.ok) throw new Error(`请求失败: ${g.status}`);
|
|
157
|
+
const Mt = await g.blob();
|
|
158
|
+
if (r) return;
|
|
159
|
+
let lt = "book.mobi";
|
|
160
|
+
try {
|
|
161
|
+
const a = new URL(_, window.location.href).pathname.split("/").pop();
|
|
162
|
+
a && (lt = decodeURIComponent(a));
|
|
163
|
+
} catch {
|
|
164
|
+
}
|
|
165
|
+
const St = new File([Mt], lt);
|
|
166
|
+
if (await t.open(St), r) {
|
|
167
|
+
(b = (h = t.book) == null ? void 0 : h.destroy) == null || b.call(h);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const n = t.renderer;
|
|
171
|
+
if (n && (n.setAttribute("animated", ""), n.setAttribute("max-inline-size", "720"), n.setAttribute("margin", "48"), n.setAttribute("gap", "5%"), await ((z = n.next) == null ? void 0 : z.call(n)), (at = n.setStyles) == null || at.call(n, Gt)), r) return;
|
|
172
|
+
tt(((st = t.book) == null ? void 0 : st.toc) ?? []), K(!1), S || M(0, ((it = t.book) == null ? void 0 : it.sections.length) ?? 1);
|
|
173
|
+
} catch (g) {
|
|
174
|
+
console.warn("[MobiRenderer] Failed to load ebook:", g instanceof Error ? g.message : String(g)), r || (V(i("mobi.load_failed")), K(!1));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
return Promise.resolve().then(U), () => {
|
|
179
|
+
var h, b, z;
|
|
180
|
+
r = !0;
|
|
181
|
+
try {
|
|
182
|
+
(h = t == null ? void 0 : t.close) == null || h.call(t);
|
|
183
|
+
} catch {
|
|
184
|
+
}
|
|
185
|
+
try {
|
|
186
|
+
(z = (b = t == null ? void 0 : t.book) == null ? void 0 : b.destroy) == null || z.call(b);
|
|
187
|
+
} catch {
|
|
188
|
+
}
|
|
189
|
+
if (t && t.parentNode === e)
|
|
190
|
+
try {
|
|
191
|
+
e.removeChild(t);
|
|
192
|
+
} catch {
|
|
193
|
+
}
|
|
194
|
+
l.current === t && (l.current = null);
|
|
195
|
+
};
|
|
196
|
+
}, [_, M, i]);
|
|
197
|
+
const Et = c(
|
|
198
|
+
(e) => !!e && e === et,
|
|
199
|
+
[et]
|
|
200
|
+
), nt = (e, r = 0) => /* @__PURE__ */ o("ul", { style: { listStyle: "none", padding: 0, margin: r > 0 ? "0 0 0 16px" : 0 }, children: e.map((t, S) => {
|
|
201
|
+
var m, U;
|
|
202
|
+
return /* @__PURE__ */ F("li", { children: [
|
|
203
|
+
t.href ? /* @__PURE__ */ o(
|
|
204
|
+
"button",
|
|
205
|
+
{
|
|
206
|
+
onClick: () => Tt(t.href),
|
|
207
|
+
className: `rfp-w-full rfp-text-left rfp-py-2 rfp-px-3 rfp-text-sm rfp-rounded rfp-transition-all rfp-truncate ${Et(t.href) ? "rfp-text-fg-primary rfp-bg-surface-3 rfp-font-medium" : "rfp-text-fg-secondary hover:rfp-text-fg-primary hover:rfp-bg-surface-2"}`,
|
|
208
|
+
title: t.label,
|
|
209
|
+
children: (m = t.label) == null ? void 0 : m.trim()
|
|
210
|
+
}
|
|
211
|
+
) : /* @__PURE__ */ o("div", { className: "rfp-w-full rfp-py-2 rfp-px-3 rfp-text-sm rfp-text-fg-tertiary rfp-truncate", children: (U = t.label) == null ? void 0 : U.trim() }),
|
|
212
|
+
t.subitems && t.subitems.length > 0 && nt(t.subitems, r + 1)
|
|
213
|
+
] }, `${t.href ?? t.label}-${S}`);
|
|
214
|
+
}) });
|
|
215
|
+
return /* @__PURE__ */ F("div", { className: "rfp-relative rfp-w-full rfp-h-full rfp-flex rfp-justify-center rfp-bg-surface-1 rfp-overflow-hidden", children: [
|
|
216
|
+
$ && /* @__PURE__ */ o(Xt, { message: $ }),
|
|
217
|
+
kt && !$ && /* @__PURE__ */ o("div", { className: "rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-z-10", children: /* @__PURE__ */ o("div", { className: "rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin" }) }),
|
|
218
|
+
R.length > 0 && /* @__PURE__ */ F(
|
|
219
|
+
"div",
|
|
220
|
+
{
|
|
221
|
+
className: "rfp-absolute rfp-inset-0 rfp-z-20 rfp-flex rfp-transition-opacity rfp-duration-300",
|
|
222
|
+
style: { opacity: w ? 1 : 0, pointerEvents: w ? "auto" : "none" },
|
|
223
|
+
children: [
|
|
224
|
+
/* @__PURE__ */ F(
|
|
225
|
+
"div",
|
|
226
|
+
{
|
|
227
|
+
className: "rfp-w-72 rfp-max-w-[80%] rfp-h-full rfp-bg-surface-overlay rfp-backdrop-blur-xl rfp-border-r rfp-border-line-weak rfp-flex rfp-flex-col rfp-shadow-2xl rfp-transition-transform rfp-duration-300",
|
|
228
|
+
style: { transform: w ? "translateX(0)" : "translateX(-100%)" },
|
|
229
|
+
children: [
|
|
230
|
+
/* @__PURE__ */ F("div", { className: "rfp-flex rfp-items-center rfp-justify-between rfp-px-4 rfp-py-3 rfp-border-b rfp-border-line-weak rfp-flex-shrink-0", children: [
|
|
231
|
+
/* @__PURE__ */ o("span", { className: "rfp-text-fg-primary rfp-font-medium rfp-text-sm", children: i("toolbar.toc") }),
|
|
232
|
+
/* @__PURE__ */ o(
|
|
233
|
+
"button",
|
|
234
|
+
{
|
|
235
|
+
onClick: () => T(!1),
|
|
236
|
+
className: "rfp-text-fg-tertiary hover:rfp-text-fg-primary rfp-transition-colors",
|
|
237
|
+
children: /* @__PURE__ */ o(It, { className: "rfp-w-4 rfp-h-4" })
|
|
238
|
+
}
|
|
239
|
+
)
|
|
240
|
+
] }),
|
|
241
|
+
/* @__PURE__ */ o("div", { className: "rfp-flex-1 rfp-overflow-y-auto rfp-py-4 rfp-px-1", children: nt(R) })
|
|
242
|
+
]
|
|
243
|
+
}
|
|
244
|
+
),
|
|
245
|
+
/* @__PURE__ */ o(
|
|
246
|
+
"div",
|
|
247
|
+
{
|
|
248
|
+
className: "rfp-flex-1 rfp-transition-opacity rfp-duration-300",
|
|
249
|
+
style: { background: w ? "rgba(0,0,0,0.3)" : "transparent" },
|
|
250
|
+
onClick: () => T(!1)
|
|
251
|
+
}
|
|
252
|
+
)
|
|
253
|
+
]
|
|
254
|
+
}
|
|
255
|
+
),
|
|
256
|
+
!$ && /* @__PURE__ */ o(
|
|
257
|
+
"div",
|
|
258
|
+
{
|
|
259
|
+
ref: Y,
|
|
260
|
+
className: "rfp-h-full rfp-bg-surface-toolbar rfp-shadow-lg",
|
|
261
|
+
style: {
|
|
262
|
+
width: u ? "100%" : `${Ut}px`,
|
|
263
|
+
maxWidth: "100%",
|
|
264
|
+
transition: "width 0.3s ease"
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
)
|
|
268
|
+
] });
|
|
269
|
+
}
|
|
270
|
+
);
|
|
271
|
+
qt.displayName = "MobiRenderer";
|
|
272
|
+
export {
|
|
273
|
+
qt as MobiRenderer
|
|
274
|
+
};
|
|
275
|
+
//# sourceMappingURL=index-CQYrhe7Z.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-CQYrhe7Z.mjs","sources":["../../src/renderers/Mobi/index.tsx"],"sourcesContent":["import {\n useEffect,\n useRef,\n useState,\n useCallback,\n useImperativeHandle,\n forwardRef,\n} from 'react';\nimport { X, ChevronLeft, ChevronRight, Maximize2, Minimize2, List } from 'lucide-react';\nimport 'foliate-js/view.js';\nimport type { FoliateView, TocItem } from 'foliate-js/view.js';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { RendererError } from '../RendererError';\nimport type { RendererHandle } from '../base.types';\nimport type { ToolbarGroup } from '../toolbar.types';\n\nconst READER_CSS = `\n @namespace epub \"http://www.idpf.org/2007/ops\";\n html { color-scheme: light; }\n body {\n background: #ffffff !important;\n color: #1a1a1a !important;\n font-family: \"Noto Serif SC\", \"Source Han Serif SC\", Georgia, \"Times New Roman\", serif !important;\n font-size: 16px !important;\n line-height: 2 !important;\n max-width: 100% !important;\n box-sizing: border-box !important;\n word-break: break-word !important;\n overflow-wrap: break-word !important;\n }\n p, li, blockquote, dd { line-height: 2; text-align: justify; }\n p { text-indent: 2em; margin: 0.8em 0; }\n h1 { text-align: center; margin: 1.5em 0 1em; }\n h2 { margin: 1.2em 0 0.8em; }\n h3 { margin: 1em 0 0.6em; }\n img { max-width: 100% !important; height: auto !important; }\n a { color: #2563eb; text-decoration: none; }\n pre { white-space: pre-wrap !important; }\n`;\n\nconst A4_WIDTH = 794;\n\nexport interface MobiRendererHandle extends RendererHandle {\n prevPage: () => void;\n nextPage: () => void;\n toggleFullWidth: () => void;\n toggleToc: () => void;\n}\n\ninterface MobiRendererProps {\n url: string;\n}\n\nexport const MobiRenderer = forwardRef<MobiRendererHandle, MobiRendererProps>(\n ({ url }, ref) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const hostRef = useRef<HTMLDivElement>(null);\n const viewRef = useRef<FoliateView | null>(null);\n\n // 模拟 epub.js 的 locations 显示\n const totalLocationsRef = useRef(1);\n\n // 内部状态管理\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [toc, setToc] = useState<TocItem[]>([]);\n const [showToc, setShowToc] = useState(false);\n const [activeTocHref, setActiveTocHref] = useState<string>('');\n const [isFullWidth, setIsFullWidth] = useState(false);\n const [currentChapter, setCurrentChapter] = useState(0);\n const [totalChapters, setTotalChapters] = useState(0);\n const isFullWidthRef = useRef(false);\n isFullWidthRef.current = isFullWidth;\n\n const reportProgress = useCallback((current: number, total: number) => {\n if (total > 0) totalLocationsRef.current = total;\n setCurrentChapter(Math.max(1, current + 1));\n setTotalChapters(totalLocationsRef.current);\n }, []);\n\n const handlePrev = useCallback(() => {\n const view = viewRef.current;\n if (!view) return;\n view.prev().catch(() => {});\n }, []);\n\n const handleNext = useCallback(() => {\n const view = viewRef.current;\n if (!view) return;\n view.next().catch(() => {});\n }, []);\n\n const toggleToc = useCallback(() => setShowToc((prev) => !prev), []);\n\n const toggleFullWidth = useCallback(() => {\n const newVal = !isFullWidthRef.current;\n setIsFullWidth(newVal);\n // 宽度改变后 paginator 需要重新分页\n const view = viewRef.current;\n if (!view) return;\n const renderer = (view as unknown as { renderer?: HTMLElement }).renderer;\n if (renderer) {\n renderer.setAttribute('max-inline-size', newVal ? '9999' : '720');\n }\n }, []);\n\n // 事件发射器:用于通知主组件工具栏状态变化\n const listenersRef = useRef<Set<() => void>>(new Set());\n const notifyToolbarChange = useCallback(() => {\n listenersRef.current.forEach(listener => listener());\n }, []);\n\n // 监听影响工具栏的状态变化\n useEffect(() => {\n notifyToolbarChange();\n }, [currentChapter, notifyToolbarChange]);\n\n useEffect(() => {\n notifyToolbarChange();\n }, [totalChapters, notifyToolbarChange]);\n\n useEffect(() => {\n notifyToolbarChange();\n }, [isFullWidth, notifyToolbarChange]);\n\n useEffect(() => {\n notifyToolbarChange();\n }, [toc.length, notifyToolbarChange]);\n\n // 工具栏配置\n const getToolbarGroups = useCallback((): ToolbarGroup[] => [\n {\n items: [\n { type: 'button', icon: <List className=\"rfp-w-4 rfp-h-4\" />, tooltip: t('toolbar.toc'), action: toggleToc, disabled: toc.length === 0, active: showToc },\n ],\n },\n {\n items: [\n { type: 'button', icon: <ChevronLeft className=\"rfp-w-4 rfp-h-4\" />, tooltip: t('toolbar.prev_page'), action: handlePrev, disabled: currentChapter <= 1 },\n { type: 'text', content: `${currentChapter} / ${totalChapters}`, minWidth: '4rem' },\n { type: 'button', icon: <ChevronRight className=\"rfp-w-4 rfp-h-4\" />, tooltip: t('toolbar.next_page'), action: handleNext, disabled: currentChapter >= totalChapters },\n ],\n },\n {\n items: [\n { type: 'button', icon: isFullWidth ? <Minimize2 className=\"rfp-w-4 rfp-h-4\" /> : <Maximize2 className=\"rfp-w-4 rfp-h-4\" />, tooltip: isFullWidth ? t('toolbar.normal_width') : t('toolbar.full_width'), action: toggleFullWidth, active: isFullWidth },\n ],\n },\n ], [currentChapter, totalChapters, isFullWidth, showToc, toc.length, t, handlePrev, handleNext, toggleToc, toggleFullWidth]);\n\n const handleTocClick = useCallback((href: string) => {\n setActiveTocHref(href);\n setShowToc(false);\n viewRef.current?.goTo(href).catch(() => {});\n }, []);\n\n useImperativeHandle(ref, () => ({\n getToolbarGroups,\n onToolbarChange: (listener: () => void) => {\n listenersRef.current.add(listener);\n return () => listenersRef.current.delete(listener);\n },\n prevPage: handlePrev,\n nextPage: handleNext,\n toggleFullWidth,\n toggleToc,\n }), [getToolbarGroups, handlePrev, handleNext, toggleFullWidth, toggleToc]);\n\n // 吞掉 foliate-js paginator 卸载/切换窗口期由 ResizeObserver 触发的 uncaught error。\n // 上游 bug:Paginator.destroy 里 unobserve 目标错了(unobserve(this) 而非 unobserve(container)),\n // observer 从未真正解除,view 已经半 destroy 时仍会触发一次 render,此时 #view / iframe body 已 null。\n // 已知触发:\n // - \"Cannot destructure property 'style' of 'el' as it is null\" (setStylesImportant)\n // - \"Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'\" (#replaceBackground)\n useEffect(() => {\n const handler = (e: ErrorEvent) => {\n if (e.filename?.includes('paginator')) {\n e.preventDefault();\n }\n };\n window.addEventListener('error', handler);\n return () => window.removeEventListener('error', handler);\n }, []);\n\n useEffect(() => {\n const host = hostRef.current;\n // 只有 URL 有效时才加载(避免空字符串或已 revoke 的 blob URL)\n if (!host || !url) return;\n\n let cancelled = false;\n let view: FoliateView | null = null;\n let progressReported = false;\n // 多 section 文件的页码累加器:记录各 section 的实际页数\n const sectionPagesMap = new Map<number, number>();\n\n const load = async () => {\n if (cancelled) return;\n\n setLoading(true);\n setError(null);\n setToc([]);\n setShowToc(false);\n setActiveTocHref('');\n host.replaceChildren();\n\n try {\n view = document.createElement('foliate-view') as FoliateView;\n host.appendChild(view);\n viewRef.current = view;\n\n // 先注册事件\n view.addEventListener('relocate', (e: Event) => {\n const detail = (e as CustomEvent).detail;\n if (!detail) return;\n\n const currentView = viewRef.current;\n const sectionCount = currentView?.book?.sections.length ?? 0;\n const renderer = (currentView as unknown as {\n renderer?: {\n page?: number;\n pages?: number;\n getContents?: () => Array<{ index: number }>;\n };\n } | null)?.renderer;\n\n // 用 Paginator 的 page/pages 得到精确翻页数:\n // - 单 section:pages - 2 就是全书总页数\n // - 多 section:记录已翻过的 section 的 pages,累加得到全书页码\n const sectionIdx = renderer?.getContents?.()[0]?.index ?? -1;\n if (\n renderer\n && typeof renderer.page === 'number'\n && typeof renderer.pages === 'number'\n && renderer.pages > 2\n && sectionIdx >= 0\n ) {\n progressReported = true;\n const curSectionPages = renderer.pages - 2;\n // 更新当前 section 的实际页数(每次进入该 section 都刷新,防止首次未 render 完整)\n sectionPagesMap.set(sectionIdx, curSectionPages);\n\n // 累加已确知的前置 section pages\n let pagesBefore = 0;\n for (let i = 0; i < sectionIdx; i++) {\n pagesBefore += sectionPagesMap.get(i) ?? 0;\n }\n const currentPage = pagesBefore + Math.min(curSectionPages, Math.max(1, renderer.page));\n\n // total 策略:\n // - 单 section:pages - 2 就是全书精确页数\n // - 多 section:用\"当前 section 字符/页数比\"外推未访问 section 的 pages。\n // 同一本书字体、行距、页宽恒定,比率稳定,比 SectionProgress 字符估算准得多。\n // 翻到末页(fraction ≈ 1)时用 currentPage 覆盖,得到真实总数。\n const atEnd = (detail.fraction ?? 0) >= 0.999;\n let total: number;\n if (sectionCount === 1) {\n total = curSectionPages;\n } else if (atEnd) {\n total = currentPage;\n } else {\n const sections = currentView?.book?.sections ?? [];\n const curSize = (sections[sectionIdx] as { size?: number } | undefined)?.size ?? 0;\n const ratio = curSize > 0 ? curSectionPages / curSize : 0;\n let est = 0;\n for (let i = 0; i < sectionCount; i++) {\n if (sectionPagesMap.has(i)) {\n est += sectionPagesMap.get(i)!;\n } else {\n const s = (sections[i] as { size?: number } | undefined)?.size ?? 0;\n est += Math.max(1, Math.round(s * ratio));\n }\n }\n total = Math.max(currentPage, est);\n }\n\n reportProgress(currentPage - 1, total);\n const tocItem = detail.tocItem as { href?: string } | undefined;\n if (tocItem?.href) setActiveTocHref(tocItem.href);\n return;\n }\n\n // 兜底:SectionProgress.location(基于字符数估算)\n const loc = detail.location as { current?: number; total?: number } | undefined;\n if (loc && typeof loc.current === 'number' && typeof loc.total === 'number') {\n progressReported = true;\n // 当翻到末尾时(fraction 达到 1 表示全书 100%),用 current + 1 作为实际可达的 total,\n // 覆盖 SectionProgress 基于字符数向上取整的估算值(会高估)\n const atEnd = (detail.fraction ?? 0) >= 0.999;\n const actualTotal = atEnd ? loc.current + 1 : loc.total;\n reportProgress(loc.current, actualTotal);\n } else {\n // fallback:用 section 级别估算\n const sections = viewRef.current?.book?.sections ?? [];\n const idx = detail.index ?? 0;\n const frac = detail.fraction ?? 0;\n const total = Math.max(sections.length, 1);\n const current = Math.round((idx + frac) / total * total);\n reportProgress(current, total);\n }\n const tocItem = detail.tocItem as { href?: string } | undefined;\n if (tocItem?.href) {\n setActiveTocHref(tocItem.href);\n }\n });\n\n const res = await fetcher(url);\n if (cancelled) return;\n if (!res.ok) throw new Error(`请求失败: ${res.status}`);\n const blob = await res.blob();\n if (cancelled) return;\n let name = 'book.mobi';\n try {\n const u = new URL(url, window.location.href);\n const base = u.pathname.split('/').pop();\n if (base) name = decodeURIComponent(base);\n } catch { /* blob: URL */ }\n const file = new File([blob], name);\n\n await view.open(file);\n if (cancelled) { view.book?.destroy?.(); return; }\n\n // 配置 paginator:paginated 模式(默认),带动画\n const renderer = (view as unknown as { renderer: HTMLElement & {\n setStyles?: (css: string) => void;\n next?: () => Promise<void>;\n } }).renderer;\n\n if (renderer) {\n // flow=\"paginated\" 是默认值,不需要显式设置\n renderer.setAttribute('animated', '');\n renderer.setAttribute('max-inline-size', '720');\n renderer.setAttribute('margin', '48');\n renderer.setAttribute('gap', '5%');\n // 必须调 next() 渲染首页\n await renderer.next?.();\n // setStyles 依赖 view.document 存在,必须在 next() 触发首次渲染后调用\n renderer.setStyles?.(READER_CSS);\n }\n if (cancelled) return;\n\n setToc(view.book?.toc ?? []);\n setLoading(false);\n // 只在 relocate 事件从未报告 progress 时使用 sections.length 作为 fallback,\n // 避免覆盖 SectionProgress 报告的更准确的 total(通常在首页 render 时通过 relocate 已报告)\n if (!progressReported) {\n reportProgress(0, view.book?.sections.length ?? 1);\n }\n } catch (err) {\n // MOBI/EPUB 加载错误通常是文件损坏或 DRM 保护,用 warn 级别记录\n console.warn('[MobiRenderer] Failed to load ebook:', err instanceof Error ? err.message : String(err));\n if (!cancelled) {\n setError(t('mobi.load_failed'));\n setLoading(false);\n }\n }\n };\n\n // 延迟到 microtask 队列执行,让 StrictMode 的第一次 cleanup 有机会取消,\n // 避免两个并发的 view.open() 污染 foliate-js MOBI 解析器内部状态\n Promise.resolve().then(load);\n\n return () => {\n cancelled = true;\n try { (view as unknown as { close?: () => void })?.close?.(); } catch { /* ignore */ }\n try { view?.book?.destroy?.(); } catch { /* ignore */ }\n if (view && view.parentNode === host) {\n try { host.removeChild(view); } catch { /* ignore */ }\n }\n if (viewRef.current === view) viewRef.current = null;\n };\n }, [url, reportProgress, t]);\n\n const isActive = useCallback(\n (href: string | undefined) => !!href && href === activeTocHref,\n [activeTocHref]\n );\n\n const renderTocItems = (items: TocItem[], depth = 0) => (\n <ul style={{ listStyle: 'none', padding: 0, margin: depth > 0 ? '0 0 0 16px' : 0 }}>\n {items.map((item, i) => (\n <li key={`${item.href ?? item.label}-${i}`}>\n {item.href ? (\n <button\n onClick={() => handleTocClick(item.href!)}\n className={`rfp-w-full rfp-text-left rfp-py-2 rfp-px-3 rfp-text-sm rfp-rounded rfp-transition-all rfp-truncate ${\n isActive(item.href)\n ? 'rfp-text-fg-primary rfp-bg-surface-3 rfp-font-medium'\n : 'rfp-text-fg-secondary hover:rfp-text-fg-primary hover:rfp-bg-surface-2'\n }`}\n title={item.label}\n >\n {item.label?.trim()}\n </button>\n ) : (\n <div className=\"rfp-w-full rfp-py-2 rfp-px-3 rfp-text-sm rfp-text-fg-tertiary rfp-truncate\">\n {item.label?.trim()}\n </div>\n )}\n {item.subitems && item.subitems.length > 0 && renderTocItems(item.subitems, depth + 1)}\n </li>\n ))}\n </ul>\n );\n\n return (\n <div className=\"rfp-relative rfp-w-full rfp-h-full rfp-flex rfp-justify-center rfp-bg-surface-1 rfp-overflow-hidden\">\n {error && <RendererError message={error} />}\n\n {loading && !error && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-z-10\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n )}\n\n {/* 目录侧栏 */}\n {toc.length > 0 && (\n <div\n className=\"rfp-absolute rfp-inset-0 rfp-z-20 rfp-flex rfp-transition-opacity rfp-duration-300\"\n style={{ opacity: showToc ? 1 : 0, pointerEvents: showToc ? 'auto' : 'none' }}\n >\n <div\n className=\"rfp-w-72 rfp-max-w-[80%] rfp-h-full rfp-bg-surface-overlay rfp-backdrop-blur-xl rfp-border-r rfp-border-line-weak rfp-flex rfp-flex-col rfp-shadow-2xl rfp-transition-transform rfp-duration-300\"\n style={{ transform: showToc ? 'translateX(0)' : 'translateX(-100%)' }}\n >\n <div className=\"rfp-flex rfp-items-center rfp-justify-between rfp-px-4 rfp-py-3 rfp-border-b rfp-border-line-weak rfp-flex-shrink-0\">\n <span className=\"rfp-text-fg-primary rfp-font-medium rfp-text-sm\">{t('toolbar.toc')}</span>\n <button\n onClick={() => setShowToc(false)}\n className=\"rfp-text-fg-tertiary hover:rfp-text-fg-primary rfp-transition-colors\"\n >\n <X className=\"rfp-w-4 rfp-h-4\" />\n </button>\n </div>\n <div className=\"rfp-flex-1 rfp-overflow-y-auto rfp-py-4 rfp-px-1\">\n {renderTocItems(toc)}\n </div>\n </div>\n <div\n className=\"rfp-flex-1 rfp-transition-opacity rfp-duration-300\"\n style={{ background: showToc ? 'rgba(0,0,0,0.3)' : 'transparent' }}\n onClick={() => setShowToc(false)}\n />\n </div>\n )}\n\n {!error && (\n <div\n ref={hostRef}\n className=\"rfp-h-full rfp-bg-surface-toolbar rfp-shadow-lg\"\n style={{\n width: isFullWidth ? '100%' : `${A4_WIDTH}px`,\n maxWidth: '100%',\n transition: 'width 0.3s ease',\n }}\n />\n )}\n </div>\n );\n }\n);\n\nMobiRenderer.displayName = 'MobiRenderer';\n"],"names":["READER_CSS","A4_WIDTH","MobiRenderer","forwardRef","url","ref","t","useTranslator","fetcher","useFetcher","hostRef","useRef","viewRef","totalLocationsRef","loading","setLoading","useState","error","setError","toc","setToc","showToc","setShowToc","activeTocHref","setActiveTocHref","isFullWidth","setIsFullWidth","currentChapter","setCurrentChapter","totalChapters","setTotalChapters","isFullWidthRef","reportProgress","useCallback","current","total","handlePrev","view","handleNext","toggleToc","prev","toggleFullWidth","newVal","renderer","listenersRef","notifyToolbarChange","listener","useEffect","getToolbarGroups","List","jsx","ChevronLeft","ChevronRight","Minimize2","Maximize2","handleTocClick","href","_a","useImperativeHandle","handler","e","host","cancelled","progressReported","sectionPagesMap","load","detail","currentView","sectionCount","sectionIdx","curSectionPages","pagesBefore","i","currentPage","atEnd","sections","_d","curSize","_e","ratio","est","s","_f","tocItem","loc","actualTotal","_h","_g","idx","frac","res","blob","name","base","file","_b","_c","err","isActive","renderTocItems","items","depth","item","jsxs","RendererError","X"],"mappings":"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"}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { jsxs as E, jsx as i } from "react/jsx-runtime";
|
|
2
|
-
import { useState as
|
|
3
|
-
import
|
|
4
|
-
import
|
|
2
|
+
import { forwardRef as z, useState as T, useRef as c, useCallback as y, useEffect as D, useImperativeHandle as H } from "react";
|
|
3
|
+
import W from "exceljs";
|
|
4
|
+
import j from "x-data-spreadsheet";
|
|
5
5
|
/* empty css */
|
|
6
|
-
import { u as
|
|
7
|
-
import { R as
|
|
8
|
-
const
|
|
9
|
-
const u =
|
|
10
|
-
if (!
|
|
11
|
-
const t =
|
|
12
|
-
return { width: n, height:
|
|
13
|
-
}, []),
|
|
14
|
-
if (!
|
|
15
|
-
|
|
16
|
-
const { width: t, height: s } = l(), n = t < 640,
|
|
6
|
+
import { u as I, a as L, I as S } from "./index-Cz23v-TW.mjs";
|
|
7
|
+
import { R as _ } from "./RendererError-D5i8eSpN.mjs";
|
|
8
|
+
const J = z(({ url: m }, k) => {
|
|
9
|
+
const u = I(), M = L(), [w, x] = T(!0), [b, v] = T(null), r = c(null), g = c(null), f = c(null), d = c(null), a = c(null), R = c({ width: 0, height: 0 }), l = y(() => {
|
|
10
|
+
if (!r.current) return { width: 800, height: 600 };
|
|
11
|
+
const t = r.current.clientWidth, s = r.current.clientHeight, n = t > 100 ? t : 800, e = s > 100 ? s : 600;
|
|
12
|
+
return { width: n, height: e };
|
|
13
|
+
}, []), p = y(() => {
|
|
14
|
+
if (!r.current || !f.current) return;
|
|
15
|
+
r.current.innerHTML = "", g.current = null;
|
|
16
|
+
const { width: t, height: s } = l(), n = t < 640, e = new j(r.current, {
|
|
17
17
|
mode: "read",
|
|
18
18
|
showToolbar: !1,
|
|
19
19
|
showContextmenu: !1,
|
|
@@ -33,53 +33,53 @@ const q = ({ url: m }) => {
|
|
|
33
33
|
width: () => t
|
|
34
34
|
}
|
|
35
35
|
});
|
|
36
|
-
|
|
36
|
+
e.loadData(f.current), g.current = e;
|
|
37
37
|
}, [l]);
|
|
38
|
-
return
|
|
39
|
-
if (!
|
|
38
|
+
return D(() => {
|
|
39
|
+
if (!r.current) return;
|
|
40
40
|
let t = !0;
|
|
41
41
|
const s = () => {
|
|
42
42
|
if (t) {
|
|
43
43
|
t = !1, R.current = l();
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
|
-
const n = l(),
|
|
47
|
-
o < 10 &&
|
|
48
|
-
f.current &&
|
|
46
|
+
const n = l(), e = R.current, o = Math.abs(e.width - n.width), h = Math.abs(e.height - n.height);
|
|
47
|
+
o < 10 && h < 10 || (R.current = n, a.current && clearTimeout(a.current), a.current = window.setTimeout(() => {
|
|
48
|
+
f.current && p();
|
|
49
49
|
}, 500));
|
|
50
50
|
};
|
|
51
51
|
return d.current = new ResizeObserver(() => {
|
|
52
52
|
s();
|
|
53
|
-
}), d.current.observe(
|
|
53
|
+
}), d.current.observe(r.current), () => {
|
|
54
54
|
d.current && d.current.disconnect(), a.current && clearTimeout(a.current);
|
|
55
55
|
};
|
|
56
|
-
}, [l,
|
|
56
|
+
}, [l, p]), D(() => {
|
|
57
57
|
if (!m) return;
|
|
58
58
|
let t = !0;
|
|
59
59
|
const s = async () => {
|
|
60
|
-
if (
|
|
60
|
+
if (r.current) {
|
|
61
61
|
x(!0), v(null);
|
|
62
62
|
try {
|
|
63
|
-
const
|
|
63
|
+
const e = await M(m, {
|
|
64
64
|
mode: "cors",
|
|
65
65
|
credentials: "omit",
|
|
66
66
|
redirect: "follow"
|
|
67
67
|
});
|
|
68
|
-
if (!
|
|
69
|
-
throw
|
|
70
|
-
const o = await
|
|
68
|
+
if (!e.ok)
|
|
69
|
+
throw e.status === 404 ? new Error(u("xlsx.not_found")) : e.status === 403 ? new Error("无权限访问此文件") : new Error(`文件加载失败 (${e.status})`);
|
|
70
|
+
const o = await e.arrayBuffer();
|
|
71
71
|
if (o.byteLength === 0)
|
|
72
72
|
throw new Error("文件为空");
|
|
73
|
-
const
|
|
74
|
-
await
|
|
75
|
-
const
|
|
73
|
+
const h = new W.Workbook();
|
|
74
|
+
await h.xlsx.load(o);
|
|
75
|
+
const N = S(h);
|
|
76
76
|
if (!t) return;
|
|
77
|
-
f.current =
|
|
78
|
-
} catch (
|
|
77
|
+
f.current = N, p(), x(!1);
|
|
78
|
+
} catch (e) {
|
|
79
79
|
if (t) {
|
|
80
|
-
console.error("Excel 解析错误:",
|
|
80
|
+
console.error("Excel 解析错误:", e);
|
|
81
81
|
let o = u("xlsx.parse_failed");
|
|
82
|
-
|
|
82
|
+
e instanceof Error && (o = e.message), v(o), x(!1);
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
}
|
|
@@ -89,25 +89,27 @@ const q = ({ url: m }) => {
|
|
|
89
89
|
});
|
|
90
90
|
}, 100);
|
|
91
91
|
return () => {
|
|
92
|
-
t = !1, clearTimeout(n), f.current = null,
|
|
92
|
+
t = !1, clearTimeout(n), f.current = null, r.current && (r.current.innerHTML = ""), g.current = null;
|
|
93
93
|
};
|
|
94
|
-
}, [m,
|
|
94
|
+
}, [m, p]), H(k, () => ({
|
|
95
|
+
getToolbarGroups: () => []
|
|
96
|
+
}), []), /* @__PURE__ */ E("div", { className: "rfp-relative rfp-flex rfp-flex-col rfp-items-center rfp-w-full rfp-h-full", children: [
|
|
95
97
|
w && /* @__PURE__ */ i("div", { className: "rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10", children: /* @__PURE__ */ E("div", { className: "rfp-text-center", children: [
|
|
96
98
|
/* @__PURE__ */ i("div", { className: "rfp-w-10 rfp-h-10 md:rfp-w-12 md:rfp-h-12 rfp-mx-auto rfp-mb-3 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin" }),
|
|
97
99
|
/* @__PURE__ */ i("p", { className: "rfp-text-xs md:rfp-text-sm rfp-text-fg-secondary rfp-font-medium", children: u("xlsx.loading") })
|
|
98
100
|
] }) }),
|
|
99
|
-
b && !w && /* @__PURE__ */ i("div", { className: "rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10", children: /* @__PURE__ */ i(
|
|
101
|
+
b && !w && /* @__PURE__ */ i("div", { className: "rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10", children: /* @__PURE__ */ i(_, { message: u("xlsx.load_failed"), detail: b }) }),
|
|
100
102
|
!b && /* @__PURE__ */ i(
|
|
101
103
|
"div",
|
|
102
104
|
{
|
|
103
|
-
ref:
|
|
105
|
+
ref: r,
|
|
104
106
|
className: "xlsx-spreadsheet-container rfp-w-full rfp-h-full",
|
|
105
107
|
style: { opacity: w ? 0 : 1 }
|
|
106
108
|
}
|
|
107
109
|
)
|
|
108
110
|
] });
|
|
109
|
-
};
|
|
111
|
+
});
|
|
110
112
|
export {
|
|
111
|
-
|
|
113
|
+
J as XlsxRenderer
|
|
112
114
|
};
|
|
113
|
-
//# sourceMappingURL=index-
|
|
115
|
+
//# sourceMappingURL=index-CRZqNMQ7.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-CRZqNMQ7.mjs","sources":["../../src/renderers/Xlsx/index.tsx"],"sourcesContent":["import { useState, useEffect, useRef, useCallback, forwardRef, useImperativeHandle } from 'react';\nimport ExcelJS from 'exceljs';\nimport Spreadsheet from 'x-data-spreadsheet';\nimport 'x-data-spreadsheet/dist/xspreadsheet.css';\nimport { convertWorkbookToSpreadsheetData } from '../../utils/excelDataConverter';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { RendererError } from '../RendererError';\nimport type { RendererHandle } from '../base.types';\n\ninterface XlsxRendererProps {\n url: string;\n}\n\nexport const XlsxRenderer = forwardRef<RendererHandle, XlsxRendererProps>(({ url }, ref) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const spreadsheetRef = useRef<Spreadsheet | null>(null);\n const sheetDataRef = useRef<Record<string, unknown>[] | null>(null);\n const resizeObserverRef = useRef<ResizeObserver | null>(null);\n const resizeTimeoutRef = useRef<number | null>(null);\n const lastDimensionsRef = useRef({ width: 0, height: 0 });\n\n const calculateDimensions = useCallback(() => {\n if (!containerRef.current) return { width: 800, height: 600 };\n const rawWidth = containerRef.current.clientWidth;\n const rawHeight = containerRef.current.clientHeight;\n const width = rawWidth > 100 ? rawWidth : 800;\n const height = rawHeight > 100 ? rawHeight : 600;\n return { width, height };\n }, []);\n\n const mountSpreadsheet = useCallback(() => {\n if (!containerRef.current || !sheetDataRef.current) return;\n\n // 清空容器\n containerRef.current.innerHTML = '';\n spreadsheetRef.current = null;\n\n const { width, height } = calculateDimensions();\n const isMobile = width < 640;\n\n const s = new Spreadsheet(containerRef.current, {\n mode: 'read',\n showToolbar: false,\n showContextmenu: false,\n showGrid: true,\n row: {\n len: 100,\n height: 25,\n },\n col: {\n len: 26,\n width: isMobile ? 80 : 100,\n indexWidth: isMobile ? 40 : 60,\n minWidth: isMobile ? 40 : 60,\n },\n view: {\n height: () => height,\n width: () => width,\n },\n });\n\n s.loadData(sheetDataRef.current as unknown as Record<string, unknown>);\n spreadsheetRef.current = s;\n }, [calculateDimensions]);\n\n // 监听容器尺寸变化\n useEffect(() => {\n if (!containerRef.current) return;\n\n let isInitialRender = true;\n\n const updateDimensions = () => {\n if (isInitialRender) {\n isInitialRender = false;\n lastDimensionsRef.current = calculateDimensions();\n return;\n }\n\n const newDimensions = calculateDimensions();\n const lastDimensions = lastDimensionsRef.current;\n const widthDiff = Math.abs(lastDimensions.width - newDimensions.width);\n const heightDiff = Math.abs(lastDimensions.height - newDimensions.height);\n\n if (widthDiff < 10 && heightDiff < 10) return;\n\n lastDimensionsRef.current = newDimensions;\n\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n\n resizeTimeoutRef.current = window.setTimeout(() => {\n if (sheetDataRef.current) {\n mountSpreadsheet();\n }\n }, 500);\n };\n\n resizeObserverRef.current = new ResizeObserver(() => {\n updateDimensions();\n });\n\n resizeObserverRef.current.observe(containerRef.current);\n\n return () => {\n if (resizeObserverRef.current) {\n resizeObserverRef.current.disconnect();\n }\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n };\n }, [calculateDimensions, mountSpreadsheet]);\n\n useEffect(() => {\n // 只有 URL 有效时才加载(避免空字符串或已 revoke 的 blob URL)\n if (!url) return;\n\n let isMounted = true;\n\n const loadExcel = async () => {\n if (!containerRef.current) return;\n\n setLoading(true);\n setError(null);\n\n try {\n const response = await fetcher(url, {\n mode: 'cors',\n credentials: 'omit',\n redirect: 'follow',\n });\n\n if (!response.ok) {\n if (response.status === 404) {\n throw new Error(t('xlsx.not_found'));\n } else if (response.status === 403) {\n throw new Error('无权限访问此文件');\n } else {\n throw new Error(`文件加载失败 (${response.status})`);\n }\n }\n\n const arrayBuffer = await response.arrayBuffer();\n\n if (arrayBuffer.byteLength === 0) {\n throw new Error('文件为空');\n }\n\n // 使用 exceljs 解析\n const workbook = new ExcelJS.Workbook();\n await workbook.xlsx.load(arrayBuffer);\n\n // 转换为 x-data-spreadsheet 数据格式\n const sheetData = convertWorkbookToSpreadsheetData(workbook);\n\n if (!isMounted) return;\n\n sheetDataRef.current = sheetData as unknown as Record<string, unknown>[];\n\n // 挂载 x-data-spreadsheet\n mountSpreadsheet();\n\n setLoading(false);\n } catch (err) {\n if (isMounted) {\n console.error('Excel 解析错误:', err);\n let errorMsg = t('xlsx.parse_failed');\n if (err instanceof Error) {\n errorMsg = err.message;\n }\n setError(errorMsg);\n setLoading(false);\n }\n }\n };\n\n const timer = setTimeout(() => {\n requestAnimationFrame(() => {\n loadExcel();\n });\n }, 100);\n\n return () => {\n isMounted = false;\n clearTimeout(timer);\n sheetDataRef.current = null;\n if (containerRef.current) {\n containerRef.current.innerHTML = '';\n }\n spreadsheetRef.current = null;\n };\n }, [url, mountSpreadsheet]);\n\n // 暴露接口给父组件\n useImperativeHandle(ref, () => ({\n getToolbarGroups: () => [],\n }), []);\n\n return (\n <div className=\"rfp-relative rfp-flex rfp-flex-col rfp-items-center rfp-w-full rfp-h-full\">\n {/* 加载状态 */}\n {loading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10\">\n <div className=\"rfp-text-center\">\n <div className=\"rfp-w-10 rfp-h-10 md:rfp-w-12 md:rfp-h-12 rfp-mx-auto rfp-mb-3 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n <p className=\"rfp-text-xs md:rfp-text-sm rfp-text-fg-secondary rfp-font-medium\">{t('xlsx.loading')}</p>\n </div>\n </div>\n )}\n\n {/* 错误状态 */}\n {error && !loading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10\">\n <RendererError message={t('xlsx.load_failed')} detail={error} />\n </div>\n )}\n\n {/* Spreadsheet 容器 */}\n {!error && (\n <div\n ref={containerRef}\n className=\"xlsx-spreadsheet-container rfp-w-full rfp-h-full\"\n style={{ opacity: loading ? 0 : 1 }}\n />\n )}\n </div>\n );\n});\n"],"names":["XlsxRenderer","forwardRef","url","ref","t","useTranslator","fetcher","useFetcher","loading","setLoading","useState","error","setError","containerRef","useRef","spreadsheetRef","sheetDataRef","resizeObserverRef","resizeTimeoutRef","lastDimensionsRef","calculateDimensions","useCallback","rawWidth","rawHeight","width","height","mountSpreadsheet","isMobile","s","Spreadsheet","useEffect","isInitialRender","updateDimensions","newDimensions","lastDimensions","widthDiff","heightDiff","isMounted","loadExcel","response","arrayBuffer","workbook","ExcelJS","sheetData","convertWorkbookToSpreadsheetData","err","errorMsg","timer","useImperativeHandle","jsxs","jsx","RendererError"],"mappings":"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"}
|