@eternalheart/react-file-preview 1.4.0 → 1.5.1
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-BBYKNNLb.mjs +329 -0
- package/lib/chunks/index-BBYKNNLb.mjs.map +1 -0
- package/lib/chunks/index-BFh22D_W.mjs +78 -0
- package/lib/chunks/index-BFh22D_W.mjs.map +1 -0
- package/lib/chunks/{index-DoFsoBKL.mjs → index-BKXvtJh5.mjs} +27 -25
- package/lib/chunks/index-BKXvtJh5.mjs.map +1 -0
- package/lib/chunks/index-Bw3Fh4b5.mjs +116 -0
- package/lib/chunks/index-Bw3Fh4b5.mjs.map +1 -0
- package/lib/chunks/{index-kALp0tqz.mjs → index-CEC_DHgr.mjs} +22 -20
- package/lib/chunks/index-CEC_DHgr.mjs.map +1 -0
- package/lib/chunks/{index-CzM2mxrD.mjs → index-COOUxB5e.mjs} +130 -128
- package/lib/chunks/{index-CzM2mxrD.mjs.map → index-COOUxB5e.mjs.map} +1 -1
- package/lib/chunks/index-CU1Lc3lV.mjs +120 -0
- package/lib/chunks/index-CU1Lc3lV.mjs.map +1 -0
- package/lib/chunks/index-CgFv7B_G.mjs +359 -0
- package/lib/chunks/index-CgFv7B_G.mjs.map +1 -0
- package/lib/chunks/index-Cn4ZyhGM.mjs +587 -0
- package/lib/chunks/index-Cn4ZyhGM.mjs.map +1 -0
- package/lib/chunks/{index-DaAXRBWL.mjs → index-DGNNEnWE.mjs} +864 -862
- package/lib/chunks/{index-DaAXRBWL.mjs.map → index-DGNNEnWE.mjs.map} +1 -1
- package/lib/chunks/index-DLk08ylq.mjs +313 -0
- package/lib/chunks/index-DLk08ylq.mjs.map +1 -0
- package/lib/chunks/index-DVtPyN-s.mjs +200 -0
- package/lib/chunks/index-DVtPyN-s.mjs.map +1 -0
- package/lib/chunks/index-DreA69iU.mjs +2409 -0
- package/lib/chunks/index-DreA69iU.mjs.map +1 -0
- package/lib/chunks/{index-Cp68OevR.mjs → index-Dta7iGov.mjs} +1299 -1297
- package/lib/chunks/{index-Cp68OevR.mjs.map → index-Dta7iGov.mjs.map} +1 -1
- package/lib/chunks/index-fQGAUFAX.mjs +275 -0
- package/lib/chunks/index-fQGAUFAX.mjs.map +1 -0
- package/lib/chunks/{index-C_BJatqr.mjs → index-fSw6Hl5e.mjs} +42 -40
- package/lib/chunks/index-fSw6Hl5e.mjs.map +1 -0
- package/lib/chunks/index-jvNrkVkp.mjs +291 -0
- package/lib/chunks/index-jvNrkVkp.mjs.map +1 -0
- package/lib/chunks/index-oVJyD-FV.mjs +107 -0
- package/lib/chunks/index-oVJyD-FV.mjs.map +1 -0
- package/lib/chunks/{index-DuP0Tlpo.mjs → index-vRLKumL8.mjs} +43 -41
- package/lib/chunks/index-vRLKumL8.mjs.map +1 -0
- package/lib/chunks/useShikiHighlight-C6nJcETW.mjs +36 -0
- package/lib/chunks/useShikiHighlight-C6nJcETW.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 +0 -529
- 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,291 @@
|
|
|
1
|
+
import { jsx as i, jsxs as L } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as ht, useRef as f, useState as g, useCallback as d, useEffect as v, useImperativeHandle as mt } from "react";
|
|
3
|
+
import bt from "@likecoin/epub-ts";
|
|
4
|
+
import { List as gt, ChevronLeft as wt, ChevronRight as yt, Minimize2 as vt, Maximize2 as xt, X as kt } from "lucide-react";
|
|
5
|
+
import { u as Tt, a as Rt } from "./index-DreA69iU.mjs";
|
|
6
|
+
import { R as Nt } from "./RendererError-D5i8eSpN.mjs";
|
|
7
|
+
if (typeof document < "u" && !document.getElementById("rfp-epub-styles")) {
|
|
8
|
+
const l = document.createElement("style");
|
|
9
|
+
l.id = "rfp-epub-styles", l.textContent = `
|
|
10
|
+
.epub-container { overflow-y: auto !important; scrollbar-width: thin; }
|
|
11
|
+
.epub-container::-webkit-scrollbar { width: 8px; }
|
|
12
|
+
.epub-container::-webkit-scrollbar-track { background: transparent; }
|
|
13
|
+
.epub-container::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.15); border-radius: 4px; }
|
|
14
|
+
.epub-container::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,0.3); }
|
|
15
|
+
.epub-view > iframe { background: white; }
|
|
16
|
+
`, document.head.appendChild(l);
|
|
17
|
+
}
|
|
18
|
+
const Ct = 794, At = ht(
|
|
19
|
+
({ url: l }, st) => {
|
|
20
|
+
const h = Tt(), ct = Rt(), w = f(null), M = f(null), p = f(null), C = f(0), x = f(null), J = f(!1), [ft, P] = g(!0), [S, K] = g(null), [y, lt] = g(!1), [k, Q] = g([]), [T, W] = g(!1), [Y, Z] = g(""), [E, q] = g(0), [A, X] = g(0), tt = f([]);
|
|
21
|
+
tt.current = k, J.current = y;
|
|
22
|
+
const G = f(/* @__PURE__ */ new Set()), m = d(() => {
|
|
23
|
+
G.current.forEach((t) => t());
|
|
24
|
+
}, []);
|
|
25
|
+
v(() => {
|
|
26
|
+
m();
|
|
27
|
+
}, [E, m]), v(() => {
|
|
28
|
+
m();
|
|
29
|
+
}, [A, m]), v(() => {
|
|
30
|
+
m();
|
|
31
|
+
}, [y, m]), v(() => {
|
|
32
|
+
m();
|
|
33
|
+
}, [k.length, m]);
|
|
34
|
+
const F = d(() => {
|
|
35
|
+
var t;
|
|
36
|
+
(t = p.current) == null || t.prev();
|
|
37
|
+
}, []), I = d(() => {
|
|
38
|
+
var t;
|
|
39
|
+
(t = p.current) == null || t.next();
|
|
40
|
+
}, []), R = f(null), _ = f(0), O = f((t) => {
|
|
41
|
+
var o, a;
|
|
42
|
+
const e = R.current;
|
|
43
|
+
if (!e) return;
|
|
44
|
+
const r = e;
|
|
45
|
+
if (r.scrollTop + r.clientHeight >= r.scrollHeight - 200)
|
|
46
|
+
try {
|
|
47
|
+
const n = (o = p.current) == null ? void 0 : o.manager;
|
|
48
|
+
(a = n == null ? void 0 : n.check) == null || a.call(n, 500, 500);
|
|
49
|
+
} catch {
|
|
50
|
+
}
|
|
51
|
+
}), N = d(() => {
|
|
52
|
+
R.current && (R.current.removeEventListener("scroll", O.current), R.current = null), cancelAnimationFrame(_.current);
|
|
53
|
+
const t = () => {
|
|
54
|
+
var r;
|
|
55
|
+
const e = ((r = w.current) == null ? void 0 : r.querySelector(".epub-container")) ?? null;
|
|
56
|
+
if (!e) {
|
|
57
|
+
_.current = requestAnimationFrame(t);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
R.current = e, e.addEventListener("scroll", O.current, { passive: !0 });
|
|
61
|
+
};
|
|
62
|
+
_.current = requestAnimationFrame(t);
|
|
63
|
+
}, []), $ = d(() => {
|
|
64
|
+
const t = !J.current;
|
|
65
|
+
lt(t), setTimeout(() => {
|
|
66
|
+
const e = w.current, r = p.current;
|
|
67
|
+
!e || !r || (r.resize(e.offsetWidth, e.offsetHeight), x.current && r.display(x.current), N());
|
|
68
|
+
}, 350);
|
|
69
|
+
}, [N]), j = d(() => {
|
|
70
|
+
W((t) => !t);
|
|
71
|
+
}, []), pt = d((t) => {
|
|
72
|
+
var e;
|
|
73
|
+
Z(t), (e = p.current) == null || e.display(t), W(!1);
|
|
74
|
+
}, []), et = d(() => [
|
|
75
|
+
{
|
|
76
|
+
items: [
|
|
77
|
+
{ type: "button", icon: /* @__PURE__ */ i(gt, { className: "rfp-w-4 rfp-h-4" }), tooltip: h("toolbar.toc"), action: j, disabled: k.length === 0, active: T }
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
items: [
|
|
82
|
+
{ type: "button", icon: /* @__PURE__ */ i(wt, { className: "rfp-w-4 rfp-h-4" }), tooltip: h("toolbar.prev_page"), action: F, disabled: E <= 1 },
|
|
83
|
+
{ type: "text", content: `${E} / ${A}`, minWidth: "4rem" },
|
|
84
|
+
{ type: "button", icon: /* @__PURE__ */ i(yt, { className: "rfp-w-4 rfp-h-4" }), tooltip: h("toolbar.next_page"), action: I, disabled: E >= A }
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
items: [
|
|
89
|
+
{ type: "button", icon: y ? /* @__PURE__ */ i(vt, { className: "rfp-w-4 rfp-h-4" }) : /* @__PURE__ */ i(xt, { className: "rfp-w-4 rfp-h-4" }), tooltip: h(y ? "toolbar.normal_width" : "toolbar.full_width"), action: $, active: y }
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
], [E, A, y, T, k.length, h, F, I, j, $]);
|
|
93
|
+
mt(st, () => ({
|
|
94
|
+
getToolbarGroups: et,
|
|
95
|
+
onToolbarChange: (t) => (G.current.add(t), () => G.current.delete(t)),
|
|
96
|
+
prevPage: F,
|
|
97
|
+
nextPage: I,
|
|
98
|
+
toggleFullWidth: $,
|
|
99
|
+
toggleToc: j
|
|
100
|
+
}), [et, F, I, $, j]), v(() => {
|
|
101
|
+
const t = w.current;
|
|
102
|
+
if (!t || !l) return;
|
|
103
|
+
P(!0), K(null), Q([]), W(!1), t.innerHTML = "", x.current = null, C.current = 0;
|
|
104
|
+
let e = !1;
|
|
105
|
+
const r = window.setTimeout(() => {
|
|
106
|
+
e || u();
|
|
107
|
+
}, 0), u = async () => {
|
|
108
|
+
try {
|
|
109
|
+
let o = l;
|
|
110
|
+
l.startsWith("blob:") && (o = await (await ct(l)).arrayBuffer());
|
|
111
|
+
const a = bt(o);
|
|
112
|
+
M.current = a;
|
|
113
|
+
const n = a.renderTo(t, {
|
|
114
|
+
manager: "continuous",
|
|
115
|
+
flow: "scrolled",
|
|
116
|
+
width: "100%",
|
|
117
|
+
height: "100%"
|
|
118
|
+
});
|
|
119
|
+
p.current = n, n.themes.register("default", {
|
|
120
|
+
body: {
|
|
121
|
+
background: "#ffffff !important",
|
|
122
|
+
color: "#1a1a1a !important",
|
|
123
|
+
"font-family": '"Noto Serif SC", "Source Han Serif SC", Georgia, "Times New Roman", serif !important',
|
|
124
|
+
"font-size": "16px !important",
|
|
125
|
+
"line-height": "2 !important",
|
|
126
|
+
padding: "40px 60px !important",
|
|
127
|
+
"max-width": "100% !important",
|
|
128
|
+
"box-sizing": "border-box !important",
|
|
129
|
+
"word-break": "break-word !important",
|
|
130
|
+
"overflow-wrap": "break-word !important"
|
|
131
|
+
},
|
|
132
|
+
p: { "text-indent": "2em !important", margin: "0.8em 0 !important" },
|
|
133
|
+
h1: { "text-align": "center !important", margin: "1.5em 0 1em !important" },
|
|
134
|
+
h2: { margin: "1.2em 0 0.8em !important" },
|
|
135
|
+
h3: { margin: "1em 0 0.6em !important" },
|
|
136
|
+
img: { "max-width": "100% !important", height: "auto !important" },
|
|
137
|
+
a: { color: "#2563eb !important", "text-decoration": "none !important" }
|
|
138
|
+
}), n.themes.select("default"), await a.ready, a.locations.generate(1024).then(() => {
|
|
139
|
+
var H, z;
|
|
140
|
+
if (e) return;
|
|
141
|
+
C.current = a.locations.length();
|
|
142
|
+
const b = (H = p.current) == null ? void 0 : H.currentLocation(), s = ((z = b == null ? void 0 : b.start) == null ? void 0 : z.location) ?? 0;
|
|
143
|
+
q(s + 1), X(C.current);
|
|
144
|
+
}).catch(() => {
|
|
145
|
+
});
|
|
146
|
+
const c = await a.loaded.navigation;
|
|
147
|
+
if (!e && Array.isArray(c == null ? void 0 : c.toc) && Q(c.toc), await n.display(), e) return;
|
|
148
|
+
q(1), X(C.current || 1), P(!1), n.on("relocated", (b) => {
|
|
149
|
+
var nt, ot, it;
|
|
150
|
+
const s = b;
|
|
151
|
+
if ((nt = s == null ? void 0 : s.start) != null && nt.cfi && (x.current = s.start.cfi), (ot = s == null ? void 0 : s.start) != null && ot.href) {
|
|
152
|
+
const U = s.start.href, V = [], at = (dt) => {
|
|
153
|
+
for (const B of dt) {
|
|
154
|
+
const D = B.href.split("#")[0];
|
|
155
|
+
D && (U === D || U.endsWith("/" + D) || U.endsWith(D)) && V.push(B.href), B.subitems && at(B.subitems);
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
at(tt.current), V.length === 1 && Z(V[0]);
|
|
159
|
+
}
|
|
160
|
+
const H = (it = s == null ? void 0 : s.start) == null ? void 0 : it.location, z = C.current;
|
|
161
|
+
typeof H == "number" && z > 0 && (q(H + 1), X(z));
|
|
162
|
+
});
|
|
163
|
+
} catch (o) {
|
|
164
|
+
console.error("EPUB 加载错误:", o), e || (K(h("epub.load_failed")), P(!1));
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
return () => {
|
|
168
|
+
var o, a, n;
|
|
169
|
+
e = !0, window.clearTimeout(r);
|
|
170
|
+
try {
|
|
171
|
+
(a = (o = p.current) == null ? void 0 : o.destroy) == null || a.call(o);
|
|
172
|
+
} catch {
|
|
173
|
+
}
|
|
174
|
+
try {
|
|
175
|
+
(n = M.current) == null || n.destroy();
|
|
176
|
+
} catch {
|
|
177
|
+
}
|
|
178
|
+
p.current = null, M.current = null;
|
|
179
|
+
};
|
|
180
|
+
}, [l]), v(() => {
|
|
181
|
+
const t = w.current;
|
|
182
|
+
if (!t) return;
|
|
183
|
+
let e = !0, r = { width: 0, height: 0 }, u = null;
|
|
184
|
+
const o = () => {
|
|
185
|
+
const n = w.current, c = p.current;
|
|
186
|
+
if (!(!n || !c)) {
|
|
187
|
+
if (c.resize(n.offsetWidth, n.offsetHeight), x.current)
|
|
188
|
+
try {
|
|
189
|
+
c.display(x.current);
|
|
190
|
+
} catch {
|
|
191
|
+
}
|
|
192
|
+
N();
|
|
193
|
+
}
|
|
194
|
+
}, a = new ResizeObserver(() => {
|
|
195
|
+
const n = w.current;
|
|
196
|
+
if (!n) return;
|
|
197
|
+
if (e) {
|
|
198
|
+
e = !1, r = { width: n.offsetWidth, height: n.offsetHeight };
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const c = { width: n.offsetWidth, height: n.offsetHeight }, b = Math.abs(r.width - c.width), s = Math.abs(r.height - c.height);
|
|
202
|
+
b < 10 && s < 10 || (r = c, u !== null && clearTimeout(u), u = window.setTimeout(() => {
|
|
203
|
+
o();
|
|
204
|
+
}, 350));
|
|
205
|
+
});
|
|
206
|
+
return a.observe(t), () => {
|
|
207
|
+
a.disconnect(), u !== null && clearTimeout(u);
|
|
208
|
+
};
|
|
209
|
+
}, [N]), v(() => (N(), () => {
|
|
210
|
+
var t;
|
|
211
|
+
cancelAnimationFrame(_.current), (t = R.current) == null || t.removeEventListener("scroll", O.current);
|
|
212
|
+
}), [l, N]);
|
|
213
|
+
const ut = d((t) => t === Y, [Y]), rt = (t, e = 0) => /* @__PURE__ */ i("ul", { style: { marginLeft: e > 0 ? 16 : 0 }, children: t.map((r, u) => {
|
|
214
|
+
const o = ut(r.href);
|
|
215
|
+
return /* @__PURE__ */ L("li", { children: [
|
|
216
|
+
/* @__PURE__ */ i(
|
|
217
|
+
"button",
|
|
218
|
+
{
|
|
219
|
+
onClick: () => pt(r.href),
|
|
220
|
+
className: `rfp-w-full rfp-text-left rfp-py-2 rfp-px-3 rfp-text-sm rfp-rounded rfp-transition-all rfp-truncate ${o ? "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"}`,
|
|
221
|
+
title: r.label,
|
|
222
|
+
children: r.label.trim()
|
|
223
|
+
}
|
|
224
|
+
),
|
|
225
|
+
r.subitems && r.subitems.length > 0 && rt(r.subitems, e + 1)
|
|
226
|
+
] }, `${r.href}-${u}`);
|
|
227
|
+
}) });
|
|
228
|
+
return /* @__PURE__ */ L("div", { className: "rfp-relative rfp-w-full rfp-h-full rfp-flex rfp-justify-center rfp-bg-surface-1 rfp-overflow-hidden", children: [
|
|
229
|
+
S && /* @__PURE__ */ i(Nt, { message: S }),
|
|
230
|
+
ft && !S && /* @__PURE__ */ i("div", { className: "rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-z-10", children: /* @__PURE__ */ i("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" }) }),
|
|
231
|
+
k.length > 0 && /* @__PURE__ */ L(
|
|
232
|
+
"div",
|
|
233
|
+
{
|
|
234
|
+
className: "rfp-absolute rfp-inset-0 rfp-z-20 rfp-flex rfp-transition-opacity rfp-duration-300",
|
|
235
|
+
style: {
|
|
236
|
+
opacity: T ? 1 : 0,
|
|
237
|
+
pointerEvents: T ? "auto" : "none"
|
|
238
|
+
},
|
|
239
|
+
children: [
|
|
240
|
+
/* @__PURE__ */ L(
|
|
241
|
+
"div",
|
|
242
|
+
{
|
|
243
|
+
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",
|
|
244
|
+
style: { transform: T ? "translateX(0)" : "translateX(-100%)" },
|
|
245
|
+
children: [
|
|
246
|
+
/* @__PURE__ */ L("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: [
|
|
247
|
+
/* @__PURE__ */ i("span", { className: "rfp-text-fg-primary rfp-font-medium rfp-text-sm", children: h("toolbar.toc") }),
|
|
248
|
+
/* @__PURE__ */ i(
|
|
249
|
+
"button",
|
|
250
|
+
{
|
|
251
|
+
onClick: () => W(!1),
|
|
252
|
+
className: "rfp-text-fg-tertiary hover:rfp-text-fg-primary rfp-transition-colors",
|
|
253
|
+
children: /* @__PURE__ */ i(kt, { className: "rfp-w-4 rfp-h-4" })
|
|
254
|
+
}
|
|
255
|
+
)
|
|
256
|
+
] }),
|
|
257
|
+
/* @__PURE__ */ i("div", { className: "rfp-flex-1 rfp-overflow-y-auto rfp-py-4 rfp-px-1", children: rt(k) })
|
|
258
|
+
]
|
|
259
|
+
}
|
|
260
|
+
),
|
|
261
|
+
/* @__PURE__ */ i(
|
|
262
|
+
"div",
|
|
263
|
+
{
|
|
264
|
+
className: "rfp-flex-1 rfp-transition-opacity rfp-duration-300",
|
|
265
|
+
style: { background: T ? "rgba(0,0,0,0.3)" : "transparent" },
|
|
266
|
+
onClick: () => W(!1)
|
|
267
|
+
}
|
|
268
|
+
)
|
|
269
|
+
]
|
|
270
|
+
}
|
|
271
|
+
),
|
|
272
|
+
!S && /* @__PURE__ */ i(
|
|
273
|
+
"div",
|
|
274
|
+
{
|
|
275
|
+
ref: w,
|
|
276
|
+
className: "rfp-h-full rfp-bg-surface-toolbar rfp-shadow-lg",
|
|
277
|
+
style: {
|
|
278
|
+
width: y ? "100%" : `${Ct}px`,
|
|
279
|
+
maxWidth: "100%",
|
|
280
|
+
transition: "width 0.3s ease",
|
|
281
|
+
overflow: "hidden"
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
)
|
|
285
|
+
] });
|
|
286
|
+
}
|
|
287
|
+
);
|
|
288
|
+
export {
|
|
289
|
+
At as EpubRenderer
|
|
290
|
+
};
|
|
291
|
+
//# sourceMappingURL=index-jvNrkVkp.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-jvNrkVkp.mjs","sources":["../../src/renderers/Epub/index.tsx"],"sourcesContent":["import { useEffect, useRef, useState, useCallback, useImperativeHandle, forwardRef } from 'react';\nimport ePub from '@likecoin/epub-ts';\nimport { X, ChevronLeft, ChevronRight, Maximize2, Minimize2, List } from 'lucide-react';\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\n// 全局注入 epubjs 容器样式(只注入一次)\nif (typeof document !== 'undefined' && !document.getElementById('rfp-epub-styles')) {\n const styleEl = document.createElement('style');\n styleEl.id = 'rfp-epub-styles';\n styleEl.textContent = `\n .epub-container { overflow-y: auto !important; scrollbar-width: thin; }\n .epub-container::-webkit-scrollbar { width: 8px; }\n .epub-container::-webkit-scrollbar-track { background: transparent; }\n .epub-container::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.15); border-radius: 4px; }\n .epub-container::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,0.3); }\n .epub-view > iframe { background: white; }\n `;\n document.head.appendChild(styleEl);\n}\n\nexport interface TocItem {\n label: string;\n href: string;\n subitems?: TocItem[];\n}\n\nexport interface EpubRendererHandle extends RendererHandle {\n prevPage: () => void;\n nextPage: () => void;\n toggleFullWidth: () => void;\n toggleToc: () => void;\n}\n\ninterface EpubRendererProps {\n url: string;\n}\n\ninterface RenditionLike {\n display: (target?: string) => Promise<unknown>;\n next: () => Promise<unknown>;\n prev: () => Promise<unknown>;\n on: (event: string, cb: (...args: unknown[]) => void) => void;\n resize: (width: number, height: number) => void;\n currentLocation: () => unknown;\n destroy?: () => void;\n themes: {\n register: (name: string, styles: Record<string, unknown>) => void;\n select: (name: string) => void;\n };\n}\n\ninterface BookLike {\n ready: Promise<unknown>;\n loaded: { navigation: Promise<unknown> };\n locations: {\n generate: (chars: number) => Promise<string[]>;\n length: () => number;\n locationFromCfi: (cfi: string) => number;\n };\n renderTo: (el: HTMLElement, opts: Record<string, unknown>) => RenditionLike;\n destroy: () => void;\n}\n\nconst A4_WIDTH = 794;\n\nexport const EpubRenderer = forwardRef<EpubRendererHandle, EpubRendererProps>(\n ({ url }, ref) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const viewerRef = useRef<HTMLDivElement>(null);\n const bookRef = useRef<BookLike | null>(null);\n const renditionRef = useRef<RenditionLike | null>(null);\n\n const totalLocationsRef = useRef(0);\n const lastCfiRef = useRef<string | null>(null);\n const isFullWidthRef = useRef(false);\n\n // 内部状态管理\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [isFullWidth, setIsFullWidth] = useState(false);\n const [toc, setToc] = useState<TocItem[]>([]);\n const [showToc, setShowToc] = useState(false);\n const [activeTocHref, setActiveTocHref] = useState<string>('');\n const [currentChapter, setCurrentChapter] = useState(0);\n const [totalChapters, setTotalChapters] = useState(0);\n const tocRef = useRef<TocItem[]>([]);\n tocRef.current = toc;\n\n isFullWidthRef.current = isFullWidth;\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 const handlePrev = useCallback(() => {\n renditionRef.current?.prev();\n }, []);\n\n const handleNext = useCallback(() => {\n renditionRef.current?.next();\n }, []);\n\n // 滚动监听:接近底部时强制触发 check 加载后续 section\n const scrollContainerRef = useRef<Element | null>(null);\n const scrollRafRef = useRef(0);\n\n const onScrollRef = useRef((_e?: Event) => {\n const container = scrollContainerRef.current;\n if (!container) return;\n const el = container as HTMLElement;\n const nearBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - 200;\n if (nearBottom) {\n try {\n const mgr = (renditionRef.current as unknown as { manager?: { check?: (t?: number, e?: number) => Promise<unknown> } })?.manager;\n mgr?.check?.(500, 500);\n } catch { /* ignore */ }\n }\n });\n\n const reattachScrollListener = useCallback(() => {\n // 清理旧监听\n if (scrollContainerRef.current) {\n scrollContainerRef.current.removeEventListener('scroll', onScrollRef.current);\n scrollContainerRef.current = null;\n }\n cancelAnimationFrame(scrollRafRef.current);\n\n const tryAttach = () => {\n const container = viewerRef.current?.querySelector('.epub-container') ?? null;\n if (!container) {\n scrollRafRef.current = requestAnimationFrame(tryAttach);\n return;\n }\n scrollContainerRef.current = container;\n container.addEventListener('scroll', onScrollRef.current, { passive: true });\n };\n scrollRafRef.current = requestAnimationFrame(tryAttach);\n }, []);\n\n const toggleFullWidth = useCallback(() => {\n const newVal = !isFullWidthRef.current;\n setIsFullWidth(newVal);\n // 等 CSS transition 完成后再 resize 并恢复位置\n setTimeout(() => {\n const viewer = viewerRef.current;\n const rendition = renditionRef.current;\n if (!viewer || !rendition) return;\n rendition.resize(viewer.offsetWidth, viewer.offsetHeight);\n // 重排后恢复阅读位置\n if (lastCfiRef.current) {\n rendition.display(lastCfiRef.current);\n }\n // resize/display 可能重建 .epub-container,需要重新绑定滚动监听\n reattachScrollListener();\n }, 350);\n }, [reattachScrollListener]);\n\n const toggleToc = useCallback(() => {\n setShowToc(prev => !prev);\n }, []);\n\n const handleTocClick = useCallback((href: string) => {\n setActiveTocHref(href);\n renditionRef.current?.display(href);\n setShowToc(false);\n }, []);\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 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 useEffect(() => {\n const viewer = viewerRef.current;\n // 只有 URL 有效时才加载(避免空字符串或已 revoke 的 blob URL)\n if (!viewer || !url) return;\n\n setLoading(true);\n setError(null);\n setToc([]);\n setShowToc(false);\n viewer.innerHTML = '';\n lastCfiRef.current = null;\n totalLocationsRef.current = 0;\n\n let cancelled = false;\n // StrictMode 下 effect 会立即 mount→unmount→mount\n // 用 microtask 延迟初始化,让第一次的 cleanup 先执行,避免 epubjs 内部状态被污染\n const loadTimer = window.setTimeout(() => {\n if (cancelled) return;\n load();\n }, 0);\n\n const load = async () => {\n try {\n let bookInput: string | ArrayBuffer = url;\n if (url.startsWith('blob:')) {\n const resp = await fetcher(url);\n bookInput = await resp.arrayBuffer();\n }\n\n const book = ePub(bookInput) as unknown as BookLike;\n bookRef.current = book;\n\n const rendition = book.renderTo(viewer, {\n manager: 'continuous',\n flow: 'scrolled',\n width: '100%',\n height: '100%',\n });\n renditionRef.current = rendition;\n\n rendition.themes.register('default', {\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 padding: '40px 60px !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: { 'text-indent': '2em !important', margin: '0.8em 0 !important' },\n h1: { 'text-align': 'center !important', margin: '1.5em 0 1em !important' },\n h2: { margin: '1.2em 0 0.8em !important' },\n h3: { margin: '1em 0 0.6em !important' },\n img: { 'max-width': '100% !important', height: 'auto !important' },\n a: { color: '#2563eb !important', 'text-decoration': 'none !important' },\n });\n rendition.themes.select('default');\n\n await book.ready;\n\n // 异步生成 locations 索引(用于实时页数)\n book.locations.generate(1024).then(() => {\n if (cancelled) return;\n totalLocationsRef.current = book.locations.length();\n // 更新内部状态\n const loc = renditionRef.current?.currentLocation() as { start?: { location?: number; cfi?: string } } | undefined;\n const cur = loc?.start?.location ?? 0;\n setCurrentChapter(cur + 1);\n setTotalChapters(totalLocationsRef.current);\n }).catch(() => { /* ignore */ });\n\n // 获取目录\n const nav = await book.loaded.navigation as { toc?: TocItem[] };\n if (!cancelled && Array.isArray(nav?.toc)) {\n setToc(nav.toc);\n }\n\n await rendition.display();\n\n if (cancelled) return;\n setCurrentChapter(1);\n setTotalChapters(totalLocationsRef.current || 1);\n\n setLoading(false);\n\n rendition.on('relocated', (location: unknown) => {\n const loc = location as { start?: { cfi?: string; location?: number; href?: string } };\n if (loc?.start?.cfi) {\n lastCfiRef.current = loc.start.cfi;\n }\n if (loc?.start?.href) {\n // 根据 spine href 查找匹配的 TOC 项\n const spineHref = loc.start.href;\n const matches: string[] = [];\n const collect = (items: TocItem[]) => {\n for (const item of items) {\n const base = item.href.split('#')[0];\n if (base && (spineHref === base || spineHref.endsWith('/' + base) || spineHref.endsWith(base))) {\n matches.push(item.href);\n }\n if (item.subitems) collect(item.subitems);\n }\n };\n collect(tocRef.current);\n if (matches.length === 1) {\n // 唯一匹配,直接设置\n setActiveTocHref(matches[0]);\n }\n // 多个匹配(同一文件不同 anchor)时保持当前选中(由点击设置)\n }\n const cur = loc?.start?.location;\n const total = totalLocationsRef.current;\n if (typeof cur === 'number' && total > 0) {\n setCurrentChapter(cur + 1);\n setTotalChapters(total);\n }\n });\n\n } catch (err) {\n console.error('EPUB 加载错误:', err);\n if (!cancelled) {\n setError(t('epub.load_failed'));\n setLoading(false);\n }\n }\n };\n\n return () => {\n cancelled = true;\n window.clearTimeout(loadTimer);\n try { renditionRef.current?.destroy?.(); } catch { /* ignore */ }\n try { bookRef.current?.destroy(); } catch { /* ignore */ }\n renditionRef.current = null;\n bookRef.current = null;\n };\n }, [url]);\n\n // 监听容器尺寸变化:等待 transition 完成后才 resize,避免 transition 期间频繁触发导致频闪\n useEffect(() => {\n const viewer = viewerRef.current;\n if (!viewer) return;\n\n let isInitialRender = true;\n let lastDimensions = { width: 0, height: 0 };\n let resizeTimeout: number | null = null;\n\n const doResize = () => {\n const v = viewerRef.current;\n const rendition = renditionRef.current;\n if (!v || !rendition) return;\n rendition.resize(v.offsetWidth, v.offsetHeight);\n // resize 后恢复阅读位置\n if (lastCfiRef.current) {\n try { rendition.display(lastCfiRef.current); } catch { /* ignore */ }\n }\n // resize/display 可能重建 .epub-container,需要重新绑定滚动监听\n reattachScrollListener();\n };\n\n const observer = new ResizeObserver(() => {\n const v = viewerRef.current;\n if (!v) return;\n\n if (isInitialRender) {\n isInitialRender = false;\n lastDimensions = { width: v.offsetWidth, height: v.offsetHeight };\n return;\n }\n\n const newDimensions = { width: v.offsetWidth, height: v.offsetHeight };\n const widthDiff = Math.abs(lastDimensions.width - newDimensions.width);\n const heightDiff = Math.abs(lastDimensions.height - newDimensions.height);\n\n // 微小变化不触发,避免抖动\n if (widthDiff < 10 && heightDiff < 10) return;\n\n lastDimensions = newDimensions;\n\n // 防抖:等待 transition 完成(350ms)后才重新渲染\n if (resizeTimeout !== null) clearTimeout(resizeTimeout);\n resizeTimeout = window.setTimeout(() => {\n doResize();\n }, 350);\n });\n\n observer.observe(viewer);\n\n return () => {\n observer.disconnect();\n if (resizeTimeout !== null) clearTimeout(resizeTimeout);\n };\n }, [reattachScrollListener]);\n\n useEffect(() => {\n reattachScrollListener();\n return () => {\n cancelAnimationFrame(scrollRafRef.current);\n scrollContainerRef.current?.removeEventListener('scroll', onScrollRef.current);\n };\n }, [url, reattachScrollListener]);\n\n const isActive = useCallback((href: string) => {\n return href === activeTocHref;\n }, [activeTocHref]);\n\n const renderTocItems = (items: TocItem[], depth = 0) => (\n <ul style={{ marginLeft: depth > 0 ? 16 : 0 }}>\n {items.map((item, i) => {\n const active = isActive(item.href);\n return (\n <li key={`${item.href}-${i}`}>\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 ${active\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 {item.subitems && item.subitems.length > 0 && renderTocItems(item.subitems, depth + 1)}\n </li>\n );\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={{\n opacity: showToc ? 1 : 0,\n pointerEvents: showToc ? 'auto' : 'none',\n }}\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={viewerRef}\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 overflow: 'hidden',\n }}\n />\n )}\n </div>\n );\n }\n);\n"],"names":["styleEl","A4_WIDTH","EpubRenderer","forwardRef","url","ref","t","useTranslator","fetcher","useFetcher","viewerRef","useRef","bookRef","renditionRef","totalLocationsRef","lastCfiRef","isFullWidthRef","loading","setLoading","useState","error","setError","isFullWidth","setIsFullWidth","toc","setToc","showToc","setShowToc","activeTocHref","setActiveTocHref","currentChapter","setCurrentChapter","totalChapters","setTotalChapters","tocRef","listenersRef","notifyToolbarChange","useCallback","listener","useEffect","handlePrev","_a","handleNext","scrollContainerRef","scrollRafRef","onScrollRef","_e","container","el","mgr","_b","reattachScrollListener","tryAttach","toggleFullWidth","newVal","viewer","rendition","toggleToc","prev","handleTocClick","href","getToolbarGroups","List","jsx","ChevronLeft","ChevronRight","Minimize2","Maximize2","useImperativeHandle","cancelled","loadTimer","load","bookInput","book","ePub","loc","cur","nav","location","spineHref","matches","collect","items","item","base","_c","total","err","isInitialRender","lastDimensions","resizeTimeout","doResize","v","observer","newDimensions","widthDiff","heightDiff","isActive","renderTocItems","depth","i","active","jsxs","RendererError","X"],"mappings":";;;;;;AAUA,IAAI,OAAO,WAAa,OAAe,CAAC,SAAS,eAAe,iBAAiB,GAAG;AAClF,QAAMA,IAAU,SAAS,cAAc,OAAO;AAC9C,EAAAA,EAAQ,KAAK,mBACbA,EAAQ,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAQtB,SAAS,KAAK,YAAYA,CAAO;AACnC;AA6CA,MAAMC,KAAW,KAEJC,KAAeC;AAAA,EAC1B,CAAC,EAAE,KAAAC,EAAA,GAAOC,OAAQ;AAChB,UAAMC,IAAIC,GAAA,GACJC,KAAUC,GAAA,GACVC,IAAYC,EAAuB,IAAI,GACvCC,IAAUD,EAAwB,IAAI,GACtCE,IAAeF,EAA6B,IAAI,GAEhDG,IAAoBH,EAAO,CAAC,GAC5BI,IAAaJ,EAAsB,IAAI,GACvCK,IAAiBL,EAAO,EAAK,GAG7B,CAACM,IAASC,CAAU,IAAIC,EAAS,EAAI,GACrC,CAACC,GAAOC,CAAQ,IAAIF,EAAwB,IAAI,GAChD,CAACG,GAAaC,EAAc,IAAIJ,EAAS,EAAK,GAC9C,CAACK,GAAKC,CAAM,IAAIN,EAAoB,CAAA,CAAE,GACtC,CAACO,GAASC,CAAU,IAAIR,EAAS,EAAK,GACtC,CAACS,GAAeC,CAAgB,IAAIV,EAAiB,EAAE,GACvD,CAACW,GAAgBC,CAAiB,IAAIZ,EAAS,CAAC,GAChD,CAACa,GAAeC,CAAgB,IAAId,EAAS,CAAC,GAC9Ce,KAASvB,EAAkB,EAAE;AACnC,IAAAuB,GAAO,UAAUV,GAEjBR,EAAe,UAAUM;AAGzB,UAAMa,IAAexB,EAAwB,oBAAI,KAAK,GAChDyB,IAAsBC,EAAY,MAAM;AAC5C,MAAAF,EAAa,QAAQ,QAAQ,CAAAG,MAAYA,EAAA,CAAU;AAAA,IACrD,GAAG,CAAA,CAAE;AAGL,IAAAC,EAAU,MAAM;AACd,MAAAH,EAAA;AAAA,IACF,GAAG,CAACN,GAAgBM,CAAmB,CAAC,GAExCG,EAAU,MAAM;AACd,MAAAH,EAAA;AAAA,IACF,GAAG,CAACJ,GAAeI,CAAmB,CAAC,GAEvCG,EAAU,MAAM;AACd,MAAAH,EAAA;AAAA,IACF,GAAG,CAACd,GAAac,CAAmB,CAAC,GAErCG,EAAU,MAAM;AACd,MAAAH,EAAA;AAAA,IACF,GAAG,CAACZ,EAAI,QAAQY,CAAmB,CAAC;AAEpC,UAAMI,IAAaH,EAAY,MAAM;;AACnC,OAAAI,IAAA5B,EAAa,YAAb,QAAA4B,EAAsB;AAAA,IACxB,GAAG,CAAA,CAAE,GAECC,IAAaL,EAAY,MAAM;;AACnC,OAAAI,IAAA5B,EAAa,YAAb,QAAA4B,EAAsB;AAAA,IACxB,GAAG,CAAA,CAAE,GAGCE,IAAqBhC,EAAuB,IAAI,GAChDiC,IAAejC,EAAO,CAAC,GAEvBkC,IAAclC,EAAO,CAACmC,MAAe;;AACzC,YAAMC,IAAYJ,EAAmB;AACrC,UAAI,CAACI,EAAW;AAChB,YAAMC,IAAKD;AAEX,UADmBC,EAAG,YAAYA,EAAG,gBAAgBA,EAAG,eAAe;AAErE,YAAI;AACF,gBAAMC,KAAOR,IAAA5B,EAAa,YAAb,gBAAA4B,EAA4G;AACzH,WAAAS,IAAAD,KAAA,gBAAAA,EAAK,UAAL,QAAAC,EAAA,KAAAD,GAAa,KAAK;AAAA,QACpB,QAAQ;AAAA,QAAe;AAAA,IAE3B,CAAC,GAEKE,IAAyBd,EAAY,MAAM;AAE/C,MAAIM,EAAmB,YACrBA,EAAmB,QAAQ,oBAAoB,UAAUE,EAAY,OAAO,GAC5EF,EAAmB,UAAU,OAE/B,qBAAqBC,EAAa,OAAO;AAEzC,YAAMQ,IAAY,MAAM;;AACtB,cAAML,MAAYN,IAAA/B,EAAU,YAAV,gBAAA+B,EAAmB,cAAc,uBAAsB;AACzE,YAAI,CAACM,GAAW;AACd,UAAAH,EAAa,UAAU,sBAAsBQ,CAAS;AACtD;AAAA,QACF;AACA,QAAAT,EAAmB,UAAUI,GAC7BA,EAAU,iBAAiB,UAAUF,EAAY,SAAS,EAAE,SAAS,IAAM;AAAA,MAC7E;AACA,MAAAD,EAAa,UAAU,sBAAsBQ,CAAS;AAAA,IACxD,GAAG,CAAA,CAAE,GAECC,IAAkBhB,EAAY,MAAM;AACxC,YAAMiB,IAAS,CAACtC,EAAe;AAC/B,MAAAO,GAAe+B,CAAM,GAErB,WAAW,MAAM;AACf,cAAMC,IAAS7C,EAAU,SACnB8C,IAAY3C,EAAa;AAC/B,QAAI,CAAC0C,KAAU,CAACC,MAChBA,EAAU,OAAOD,EAAO,aAAaA,EAAO,YAAY,GAEpDxC,EAAW,WACbyC,EAAU,QAAQzC,EAAW,OAAO,GAGtCoC,EAAA;AAAA,MACF,GAAG,GAAG;AAAA,IACR,GAAG,CAACA,CAAsB,CAAC,GAErBM,IAAYpB,EAAY,MAAM;AAClC,MAAAV,EAAW,CAAA+B,MAAQ,CAACA,CAAI;AAAA,IAC1B,GAAG,CAAA,CAAE,GAECC,KAAiBtB,EAAY,CAACuB,MAAiB;;AACnD,MAAA/B,EAAiB+B,CAAI,IACrBnB,IAAA5B,EAAa,YAAb,QAAA4B,EAAsB,QAAQmB,IAC9BjC,EAAW,EAAK;AAAA,IAClB,GAAG,CAAA,CAAE,GAGCkC,KAAmBxB,EAAY,MAAsB;AAAA,MACzD;AAAA,QACE,OAAO;AAAA,UACL,EAAE,MAAM,UAAU,wBAAOyB,IAAA,EAAK,WAAU,mBAAkB,GAAI,SAASxD,EAAE,aAAa,GAAG,QAAQmD,GAAW,UAAUjC,EAAI,WAAW,GAAG,QAAQE,EAAA;AAAA,QAAQ;AAAA,MAC1J;AAAA,MAEF;AAAA,QACE,OAAO;AAAA,UACL,EAAE,MAAM,UAAU,MAAM,gBAAAqC,EAACC,MAAY,WAAU,kBAAA,CAAkB,GAAI,SAAS1D,EAAE,mBAAmB,GAAG,QAAQkC,GAAY,UAAUV,KAAkB,EAAA;AAAA,UACtJ,EAAE,MAAM,QAAQ,SAAS,GAAGA,CAAc,MAAME,CAAa,IAAI,UAAU,OAAA;AAAA,UAC3E,EAAE,MAAM,UAAU,MAAM,gBAAA+B,EAACE,MAAa,WAAU,kBAAA,CAAkB,GAAI,SAAS3D,EAAE,mBAAmB,GAAG,QAAQoC,GAAY,UAAUZ,KAAkBE,EAAA;AAAA,QAAc;AAAA,MACvK;AAAA,MAEF;AAAA,QACE,OAAO;AAAA,UACL,EAAE,MAAM,UAAU,MAAMV,IAAc,gBAAAyC,EAACG,IAAA,EAAU,WAAU,kBAAA,CAAkB,IAAK,gBAAAH,EAACI,IAAA,EAAU,WAAU,mBAAkB,GAAI,SAAuB7D,EAAdgB,IAAgB,yBAA4B,oBAAN,GAA6B,QAAQ+B,GAAiB,QAAQ/B,EAAA;AAAA,QAAY;AAAA,MACxP;AAAA,IACF,GACC,CAACQ,GAAgBE,GAAeV,GAAaI,GAASF,EAAI,QAAQlB,GAAGkC,GAAYE,GAAYe,GAAWJ,CAAe,CAAC;AAE3H,IAAAe,GAAoB/D,IAAK,OAAO;AAAA,MAC9B,kBAAAwD;AAAA,MACA,iBAAiB,CAACvB,OAChBH,EAAa,QAAQ,IAAIG,CAAQ,GAC1B,MAAMH,EAAa,QAAQ,OAAOG,CAAQ;AAAA,MAEnD,UAAUE;AAAA,MACV,UAAUE;AAAA,MACV,iBAAAW;AAAA,MACA,WAAAI;AAAA,IAAA,IACE,CAACI,IAAkBrB,GAAYE,GAAYW,GAAiBI,CAAS,CAAC,GAE1ElB,EAAU,MAAM;AACd,YAAMgB,IAAS7C,EAAU;AAEzB,UAAI,CAAC6C,KAAU,CAACnD,EAAK;AAErB,MAAAc,EAAW,EAAI,GACfG,EAAS,IAAI,GACbI,EAAO,CAAA,CAAE,GACTE,EAAW,EAAK,GAChB4B,EAAO,YAAY,IACnBxC,EAAW,UAAU,MACrBD,EAAkB,UAAU;AAE5B,UAAIuD,IAAY;AAGhB,YAAMC,IAAY,OAAO,WAAW,MAAM;AACxC,QAAID,KACJE,EAAA;AAAA,MACF,GAAG,CAAC,GAEEA,IAAO,YAAY;AACvB,YAAI;AACF,cAAIC,IAAkCpE;AACtC,UAAIA,EAAI,WAAW,OAAO,MAExBoE,IAAY,OADC,MAAMhE,GAAQJ,CAAG,GACP,YAAA;AAGzB,gBAAMqE,IAAOC,GAAKF,CAAS;AAC3B,UAAA5D,EAAQ,UAAU6D;AAElB,gBAAMjB,IAAYiB,EAAK,SAASlB,GAAQ;AAAA,YACtC,SAAS;AAAA,YACT,MAAM;AAAA,YACN,OAAO;AAAA,YACP,QAAQ;AAAA,UAAA,CACT;AACD,UAAA1C,EAAa,UAAU2C,GAEvBA,EAAU,OAAO,SAAS,WAAW;AAAA,YACnC,MAAM;AAAA,cACJ,YAAY;AAAA,cACZ,OAAO;AAAA,cACP,eAAe;AAAA,cACf,aAAa;AAAA,cACb,eAAe;AAAA,cACf,SAAS;AAAA,cACT,aAAa;AAAA,cACb,cAAc;AAAA,cACd,cAAc;AAAA,cACd,iBAAiB;AAAA,YAAA;AAAA,YAEnB,GAAG,EAAE,eAAe,kBAAkB,QAAQ,qBAAA;AAAA,YAC9C,IAAI,EAAE,cAAc,qBAAqB,QAAQ,yBAAA;AAAA,YACjD,IAAI,EAAE,QAAQ,2BAAA;AAAA,YACd,IAAI,EAAE,QAAQ,yBAAA;AAAA,YACd,KAAK,EAAE,aAAa,mBAAmB,QAAQ,kBAAA;AAAA,YAC/C,GAAG,EAAE,OAAO,sBAAsB,mBAAmB,kBAAA;AAAA,UAAkB,CACxE,GACDA,EAAU,OAAO,OAAO,SAAS,GAEjC,MAAMiB,EAAK,OAGXA,EAAK,UAAU,SAAS,IAAI,EAAE,KAAK,MAAM;;AACvC,gBAAIJ,EAAW;AACf,YAAAvD,EAAkB,UAAU2D,EAAK,UAAU,OAAA;AAE3C,kBAAME,KAAMlC,IAAA5B,EAAa,YAAb,gBAAA4B,EAAsB,mBAC5BmC,MAAM1B,IAAAyB,KAAA,gBAAAA,EAAK,UAAL,gBAAAzB,EAAY,aAAY;AACpC,YAAAnB,EAAkB6C,IAAM,CAAC,GACzB3C,EAAiBnB,EAAkB,OAAO;AAAA,UAC5C,CAAC,EAAE,MAAM,MAAM;AAAA,UAAe,CAAC;AAG/B,gBAAM+D,IAAM,MAAMJ,EAAK,OAAO;AAO9B,cANI,CAACJ,KAAa,MAAM,QAAQQ,KAAA,gBAAAA,EAAK,GAAG,KACtCpD,EAAOoD,EAAI,GAAG,GAGhB,MAAMrB,EAAU,QAAA,GAEZa,EAAW;AACf,UAAAtC,EAAkB,CAAC,GACnBE,EAAiBnB,EAAkB,WAAW,CAAC,GAE/CI,EAAW,EAAK,GAEhBsC,EAAU,GAAG,aAAa,CAACsB,MAAsB;;AAC/C,kBAAMH,IAAMG;AAIZ,iBAHIrC,KAAAkC,KAAA,gBAAAA,EAAK,UAAL,QAAAlC,GAAY,QACd1B,EAAW,UAAU4D,EAAI,MAAM,OAE7BzB,KAAAyB,KAAA,gBAAAA,EAAK,UAAL,QAAAzB,GAAY,MAAM;AAEpB,oBAAM6B,IAAYJ,EAAI,MAAM,MACtBK,IAAoB,CAAA,GACpBC,KAAU,CAACC,OAAqB;AACpC,2BAAWC,KAAQD,IAAO;AACxB,wBAAME,IAAOD,EAAK,KAAK,MAAM,GAAG,EAAE,CAAC;AACnC,kBAAIC,MAASL,MAAcK,KAAQL,EAAU,SAAS,MAAMK,CAAI,KAAKL,EAAU,SAASK,CAAI,MAC1FJ,EAAQ,KAAKG,EAAK,IAAI,GAEpBA,EAAK,YAAUF,GAAQE,EAAK,QAAQ;AAAA,gBAC1C;AAAA,cACF;AACA,cAAAF,GAAQ/C,GAAO,OAAO,GAClB8C,EAAQ,WAAW,KAErBnD,EAAiBmD,EAAQ,CAAC,CAAC;AAAA,YAG/B;AACA,kBAAMJ,KAAMS,KAAAV,KAAA,gBAAAA,EAAK,UAAL,gBAAAU,GAAY,UAClBC,IAAQxE,EAAkB;AAChC,YAAI,OAAO8D,KAAQ,YAAYU,IAAQ,MACrCvD,EAAkB6C,IAAM,CAAC,GACzB3C,EAAiBqD,CAAK;AAAA,UAE1B,CAAC;AAAA,QAEH,SAASC,GAAK;AACZ,kBAAQ,MAAM,cAAcA,CAAG,GAC1BlB,MACHhD,EAASf,EAAE,kBAAkB,CAAC,GAC9BY,EAAW,EAAK;AAAA,QAEpB;AAAA,MACF;AAEA,aAAO,MAAM;;AACX,QAAAmD,IAAY,IACZ,OAAO,aAAaC,CAAS;AAC7B,YAAI;AAAE,WAAApB,KAAAT,IAAA5B,EAAa,YAAb,gBAAA4B,EAAsB,YAAtB,QAAAS,EAAA,KAAAT;AAAA,QAAmC,QAAQ;AAAA,QAAe;AAChE,YAAI;AAAE,WAAA4C,IAAAzE,EAAQ,YAAR,QAAAyE,EAAiB;AAAA,QAAW,QAAQ;AAAA,QAAe;AACzD,QAAAxE,EAAa,UAAU,MACvBD,EAAQ,UAAU;AAAA,MACpB;AAAA,IACF,GAAG,CAACR,CAAG,CAAC,GAGRmC,EAAU,MAAM;AACd,YAAMgB,IAAS7C,EAAU;AACzB,UAAI,CAAC6C,EAAQ;AAEb,UAAIiC,IAAkB,IAClBC,IAAiB,EAAE,OAAO,GAAG,QAAQ,EAAA,GACrCC,IAA+B;AAEnC,YAAMC,IAAW,MAAM;AACrB,cAAMC,IAAIlF,EAAU,SACd8C,IAAY3C,EAAa;AAC/B,YAAI,GAAC+E,KAAK,CAACpC,IAGX;AAAA,cAFAA,EAAU,OAAOoC,EAAE,aAAaA,EAAE,YAAY,GAE1C7E,EAAW;AACb,gBAAI;AAAE,cAAAyC,EAAU,QAAQzC,EAAW,OAAO;AAAA,YAAG,QAAQ;AAAA,YAAe;AAGtE,UAAAoC,EAAA;AAAA;AAAA,MACF,GAEM0C,IAAW,IAAI,eAAe,MAAM;AACxC,cAAMD,IAAIlF,EAAU;AACpB,YAAI,CAACkF,EAAG;AAER,YAAIJ,GAAiB;AACnB,UAAAA,IAAkB,IAClBC,IAAiB,EAAE,OAAOG,EAAE,aAAa,QAAQA,EAAE,aAAA;AACnD;AAAA,QACF;AAEA,cAAME,IAAgB,EAAE,OAAOF,EAAE,aAAa,QAAQA,EAAE,aAAA,GAClDG,IAAY,KAAK,IAAIN,EAAe,QAAQK,EAAc,KAAK,GAC/DE,IAAa,KAAK,IAAIP,EAAe,SAASK,EAAc,MAAM;AAGxE,QAAIC,IAAY,MAAMC,IAAa,OAEnCP,IAAiBK,GAGbJ,MAAkB,QAAM,aAAaA,CAAa,GACtDA,IAAgB,OAAO,WAAW,MAAM;AACtC,UAAAC,EAAA;AAAA,QACF,GAAG,GAAG;AAAA,MACR,CAAC;AAED,aAAAE,EAAS,QAAQtC,CAAM,GAEhB,MAAM;AACX,QAAAsC,EAAS,WAAA,GACLH,MAAkB,QAAM,aAAaA,CAAa;AAAA,MACxD;AAAA,IACF,GAAG,CAACvC,CAAsB,CAAC,GAE3BZ,EAAU,OACRY,EAAA,GACO,MAAM;;AACX,2BAAqBP,EAAa,OAAO,IACzCH,IAAAE,EAAmB,YAAnB,QAAAF,EAA4B,oBAAoB,UAAUI,EAAY;AAAA,IACxE,IACC,CAACzC,GAAK+C,CAAsB,CAAC;AAEhC,UAAM8C,KAAW5D,EAAY,CAACuB,MACrBA,MAAShC,GACf,CAACA,CAAa,CAAC,GAEZsE,KAAiB,CAAChB,GAAkBiB,IAAQ,MAChD,gBAAApC,EAAC,QAAG,OAAO,EAAE,YAAYoC,IAAQ,IAAI,KAAK,KACvC,YAAM,IAAI,CAAChB,GAAMiB,MAAM;AACtB,YAAMC,IAASJ,GAASd,EAAK,IAAI;AACjC,+BACG,MAAA,EACC,UAAA;AAAA,QAAA,gBAAApB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,MAAMJ,GAAewB,EAAK,IAAI;AAAA,YACvC,WAAW,sGAAsGkB,IAC3G,yDACA,wEACJ;AAAA,YACF,OAAOlB,EAAK;AAAA,YAEX,UAAAA,EAAK,MAAM,KAAA;AAAA,UAAK;AAAA,QAAA;AAAA,QAElBA,EAAK,YAAYA,EAAK,SAAS,SAAS,KAAKe,GAAef,EAAK,UAAUgB,IAAQ,CAAC;AAAA,MAAA,EAAA,GAX9E,GAAGhB,EAAK,IAAI,IAAIiB,CAAC,EAY1B;AAAA,IAEJ,CAAC,EAAA,CACH;AAGF,WACE,gBAAAE,EAAC,OAAA,EAAI,WAAU,uGACZ,UAAA;AAAA,MAAAlF,KAAS,gBAAA2C,EAACwC,IAAA,EAAc,SAASnF,EAAA,CAAO;AAAA,MAExCH,MAAW,CAACG,KACX,gBAAA2C,EAAC,OAAA,EAAI,WAAU,kFACb,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,oHAAA,CAAoH,EAAA,CACrI;AAAA,MAIDvC,EAAI,SAAS,KACZ,gBAAA8E;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO;AAAA,YACL,SAAS5E,IAAU,IAAI;AAAA,YACvB,eAAeA,IAAU,SAAS;AAAA,UAAA;AAAA,UAGpC,UAAA;AAAA,YAAA,gBAAA4E;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO,EAAE,WAAW5E,IAAU,kBAAkB,oBAAA;AAAA,gBAEhD,UAAA;AAAA,kBAAA,gBAAA4E,EAAC,OAAA,EAAI,WAAU,uHACb,UAAA;AAAA,oBAAA,gBAAAvC,EAAC,QAAA,EAAK,WAAU,mDAAmD,UAAAzD,EAAE,aAAa,GAAE;AAAA,oBACpF,gBAAAyD;AAAA,sBAAC;AAAA,sBAAA;AAAA,wBACC,SAAS,MAAMpC,EAAW,EAAK;AAAA,wBAC/B,WAAU;AAAA,wBAEV,UAAA,gBAAAoC,EAACyC,IAAA,EAAE,WAAU,kBAAA,CAAkB;AAAA,sBAAA;AAAA,oBAAA;AAAA,kBACjC,GACF;AAAA,oCACC,OAAA,EAAI,WAAU,oDACZ,UAAAN,GAAe1E,CAAG,EAAA,CACrB;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAEF,gBAAAuC;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO,EAAE,YAAYrC,IAAU,oBAAoB,cAAA;AAAA,gBACnD,SAAS,MAAMC,EAAW,EAAK;AAAA,cAAA;AAAA,YAAA;AAAA,UACjC;AAAA,QAAA;AAAA,MAAA;AAAA,MAIH,CAACP,KACA,gBAAA2C;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAKrD;AAAA,UACL,WAAU;AAAA,UACV,OAAO;AAAA,YACL,OAAOY,IAAc,SAAS,GAAGrB,EAAQ;AAAA,YACzC,UAAU;AAAA,YACV,YAAY;AAAA,YACZ,UAAU;AAAA,UAAA;AAAA,QACZ;AAAA,MAAA;AAAA,IACF,GAEJ;AAAA,EAEJ;AACF;"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { jsx as t, jsxs as P } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as T, useState as l, useRef as D, useEffect as b, useCallback as N, useImperativeHandle as I } from "react";
|
|
3
|
+
import R from "mammoth";
|
|
4
|
+
import { u as S, a as k } from "./index-DreA69iU.mjs";
|
|
5
|
+
import { R as $ } from "./RendererError-D5i8eSpN.mjs";
|
|
6
|
+
const H = 1123, _ = 60, v = 50, j = H - _ * 2, L = 24, E = {
|
|
7
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
8
|
+
lineHeight: "1.8",
|
|
9
|
+
color: "#333"
|
|
10
|
+
}, O = T(({ url: i }, G) => {
|
|
11
|
+
const c = S(), p = k(), [n, u] = l(""), [A, d] = l(!0), [m, h] = l(null), [x, g] = l([]), f = D(null);
|
|
12
|
+
b(() => {
|
|
13
|
+
if (!i) return;
|
|
14
|
+
(async () => {
|
|
15
|
+
d(!0), h(null), u("");
|
|
16
|
+
try {
|
|
17
|
+
const e = await p(i);
|
|
18
|
+
if (!e.ok)
|
|
19
|
+
throw new Error("文件加载失败");
|
|
20
|
+
const r = await e.arrayBuffer(), o = await R.convertToHtml({ arrayBuffer: r });
|
|
21
|
+
u(o.value);
|
|
22
|
+
} catch (e) {
|
|
23
|
+
console.error("Docx 解析错误:", e), h(c("docx.parse_failed"));
|
|
24
|
+
} finally {
|
|
25
|
+
d(!1);
|
|
26
|
+
}
|
|
27
|
+
})();
|
|
28
|
+
}, [i, p, c]);
|
|
29
|
+
const y = N(() => {
|
|
30
|
+
const s = f.current;
|
|
31
|
+
if (!s || !n) return;
|
|
32
|
+
const e = Array.from(s.children);
|
|
33
|
+
if (e.length === 0) {
|
|
34
|
+
g([n]);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const r = [[]];
|
|
38
|
+
let o = 0;
|
|
39
|
+
for (const a of e) {
|
|
40
|
+
const w = a.offsetHeight;
|
|
41
|
+
o > 0 && o + w > j && (r.push([]), o = 0), r[r.length - 1].push(a.outerHTML), o += w;
|
|
42
|
+
}
|
|
43
|
+
r.length === 0 && r.push([]), g(r.map((a) => a.join("")));
|
|
44
|
+
}, [n]);
|
|
45
|
+
return b(() => {
|
|
46
|
+
!n || !f.current || requestAnimationFrame(() => {
|
|
47
|
+
y();
|
|
48
|
+
});
|
|
49
|
+
}, [n, y]), I(G, () => ({
|
|
50
|
+
getToolbarGroups: () => []
|
|
51
|
+
}), []), A ? /* @__PURE__ */ t("div", { className: "rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full", children: /* @__PURE__ */ t("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" }) }) : m ? /* @__PURE__ */ t($, { message: m }) : /* @__PURE__ */ P(
|
|
52
|
+
"div",
|
|
53
|
+
{
|
|
54
|
+
className: "rfp-docx-container rfp-w-full rfp-h-full rfp-overflow-auto rfp-py-6 rfp-px-4",
|
|
55
|
+
style: { background: "rgba(0, 0, 0, 0.15)" },
|
|
56
|
+
children: [
|
|
57
|
+
/* @__PURE__ */ t(
|
|
58
|
+
"div",
|
|
59
|
+
{
|
|
60
|
+
ref: f,
|
|
61
|
+
dangerouslySetInnerHTML: { __html: n },
|
|
62
|
+
style: {
|
|
63
|
+
...E,
|
|
64
|
+
position: "absolute",
|
|
65
|
+
visibility: "hidden",
|
|
66
|
+
width: `${794 - v * 2}px`,
|
|
67
|
+
pointerEvents: "none"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
),
|
|
71
|
+
/* @__PURE__ */ t(
|
|
72
|
+
"div",
|
|
73
|
+
{
|
|
74
|
+
className: "rfp-flex rfp-flex-col rfp-items-center",
|
|
75
|
+
style: { gap: `${L}px` },
|
|
76
|
+
children: (x.length > 0 ? x : [""]).map((s, e) => /* @__PURE__ */ t(
|
|
77
|
+
"div",
|
|
78
|
+
{
|
|
79
|
+
style: {
|
|
80
|
+
width: "100%",
|
|
81
|
+
maxWidth: "794px",
|
|
82
|
+
minHeight: `${H}px`,
|
|
83
|
+
background: "white",
|
|
84
|
+
boxShadow: "0 4px 6px rgba(0, 0, 0, 0.07), 0 10px 20px rgba(0, 0, 0, 0.10)",
|
|
85
|
+
flexShrink: 0,
|
|
86
|
+
padding: `${_}px ${v}px`
|
|
87
|
+
},
|
|
88
|
+
children: /* @__PURE__ */ t(
|
|
89
|
+
"div",
|
|
90
|
+
{
|
|
91
|
+
dangerouslySetInnerHTML: { __html: s },
|
|
92
|
+
style: E
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
},
|
|
96
|
+
e
|
|
97
|
+
))
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
export {
|
|
105
|
+
O as DocxRenderer
|
|
106
|
+
};
|
|
107
|
+
//# sourceMappingURL=index-oVJyD-FV.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-oVJyD-FV.mjs","sources":["../../src/renderers/Docx/index.tsx"],"sourcesContent":["import { useState, useEffect, useRef, useCallback, forwardRef, useImperativeHandle } from 'react';\nimport mammoth from 'mammoth';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { RendererError } from '../RendererError';\nimport type { RendererHandle } from '../base.types';\n\ninterface DocxRendererProps {\n url: string;\n}\n\n// A4 page dimensions (96dpi)\nconst PAGE_HEIGHT = 1123;\nconst PAGE_PADDING_Y = 60;\nconst PAGE_PADDING_X = 50;\nconst PAGE_CONTENT_HEIGHT = PAGE_HEIGHT - PAGE_PADDING_Y * 2;\nconst PAGE_GAP = 24;\n\nconst contentStyle: React.CSSProperties = {\n fontFamily: 'system-ui, -apple-system, sans-serif',\n lineHeight: '1.8',\n color: '#333',\n};\n\nexport const DocxRenderer = forwardRef<RendererHandle, DocxRendererProps>(({ url }, ref) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [html, setHtml] = useState<string>('');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [pages, setPages] = useState<string[]>([]);\n const measureRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n // 只有 URL 有效时才加载(避免空字符串或已 revoke 的 blob URL)\n if (!url) return;\n\n const loadDocx = async () => {\n setLoading(true);\n setError(null);\n setHtml('');\n\n try {\n const response = await fetcher(url);\n if (!response.ok) {\n throw new Error('文件加载失败');\n }\n\n const arrayBuffer = await response.arrayBuffer();\n const result = await mammoth.convertToHtml({ arrayBuffer });\n setHtml(result.value);\n } catch (err) {\n console.error('Docx 解析错误:', err);\n setError(t('docx.parse_failed'));\n } finally {\n setLoading(false);\n }\n };\n\n loadDocx();\n }, [url, fetcher, t]);\n\n const paginate = useCallback(() => {\n const container = measureRef.current;\n if (!container || !html) return;\n\n const children = Array.from(container.children) as HTMLElement[];\n if (children.length === 0) {\n setPages([html]);\n return;\n }\n\n const result: string[][] = [[]];\n let currentPageUsed = 0;\n\n for (const child of children) {\n const h = child.offsetHeight;\n\n // If adding this block would exceed page content area and page isn't empty,\n // start a new page\n if (currentPageUsed > 0 && currentPageUsed + h > PAGE_CONTENT_HEIGHT) {\n result.push([]);\n currentPageUsed = 0;\n }\n\n result[result.length - 1].push(child.outerHTML);\n currentPageUsed += h;\n }\n\n // At least one page\n if (result.length === 0) result.push([]);\n\n setPages(result.map(blocks => blocks.join('')));\n }, [html]);\n\n useEffect(() => {\n if (!html || !measureRef.current) return;\n requestAnimationFrame(() => {\n paginate();\n });\n }, [html, paginate]);\n\n // 暴露接口给父组件\n useImperativeHandle(ref, () => ({\n getToolbarGroups: () => [],\n }), []);\n\n if (loading) {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\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 if (error) {\n return <RendererError message={error} />;\n }\n\n return (\n <div\n className=\"rfp-docx-container rfp-w-full rfp-h-full rfp-overflow-auto rfp-py-6 rfp-px-4\"\n style={{ background: 'rgba(0, 0, 0, 0.15)' }}\n >\n {/* Hidden measurement div — same width as page content area */}\n <div\n ref={measureRef}\n dangerouslySetInnerHTML={{ __html: html }}\n style={{\n ...contentStyle,\n position: 'absolute',\n visibility: 'hidden',\n width: `${794 - PAGE_PADDING_X * 2}px`,\n pointerEvents: 'none',\n }}\n />\n\n {/* Visible pages */}\n <div\n className=\"rfp-flex rfp-flex-col rfp-items-center\"\n style={{ gap: `${PAGE_GAP}px` }}\n >\n {(pages.length > 0 ? pages : ['']).map((pageHtml, i) => (\n <div\n key={i}\n style={{\n width: '100%',\n maxWidth: '794px',\n minHeight: `${PAGE_HEIGHT}px`,\n background: 'white',\n boxShadow: '0 4px 6px rgba(0, 0, 0, 0.07), 0 10px 20px rgba(0, 0, 0, 0.10)',\n flexShrink: 0,\n padding: `${PAGE_PADDING_Y}px ${PAGE_PADDING_X}px`,\n }}\n >\n <div\n dangerouslySetInnerHTML={{ __html: pageHtml }}\n style={contentStyle}\n />\n </div>\n ))}\n </div>\n </div>\n );\n});\n"],"names":["PAGE_HEIGHT","PAGE_PADDING_Y","PAGE_PADDING_X","PAGE_CONTENT_HEIGHT","PAGE_GAP","contentStyle","DocxRenderer","forwardRef","url","ref","t","useTranslator","fetcher","useFetcher","html","setHtml","useState","loading","setLoading","error","setError","pages","setPages","measureRef","useRef","useEffect","response","arrayBuffer","result","mammoth","err","paginate","useCallback","container","children","currentPageUsed","child","h","blocks","useImperativeHandle","jsx","RendererError","jsxs","pageHtml","i"],"mappings":";;;;;AAYA,MAAMA,IAAc,MACdC,IAAiB,IACjBC,IAAiB,IACjBC,IAAsBH,IAAcC,IAAiB,GACrDG,IAAW,IAEXC,IAAoC;AAAA,EACxC,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,OAAO;AACT,GAEaC,IAAeC,EAA8C,CAAC,EAAE,KAAAC,EAAA,GAAOC,MAAQ;AAC1F,QAAMC,IAAIC,EAAA,GACJC,IAAUC,EAAA,GACV,CAACC,GAAMC,CAAO,IAAIC,EAAiB,EAAE,GACrC,CAACC,GAASC,CAAU,IAAIF,EAAS,EAAI,GACrC,CAACG,GAAOC,CAAQ,IAAIJ,EAAwB,IAAI,GAChD,CAACK,GAAOC,CAAQ,IAAIN,EAAmB,CAAA,CAAE,GACzCO,IAAaC,EAAuB,IAAI;AAE9C,EAAAC,EAAU,MAAM;AAEd,QAAI,CAACjB,EAAK;AAwBV,KAtBiB,YAAY;AAC3B,MAAAU,EAAW,EAAI,GACfE,EAAS,IAAI,GACbL,EAAQ,EAAE;AAEV,UAAI;AACF,cAAMW,IAAW,MAAMd,EAAQJ,CAAG;AAClC,YAAI,CAACkB,EAAS;AACZ,gBAAM,IAAI,MAAM,QAAQ;AAG1B,cAAMC,IAAc,MAAMD,EAAS,YAAA,GAC7BE,IAAS,MAAMC,EAAQ,cAAc,EAAE,aAAAF,GAAa;AAC1D,QAAAZ,EAAQa,EAAO,KAAK;AAAA,MACtB,SAASE,GAAK;AACZ,gBAAQ,MAAM,cAAcA,CAAG,GAC/BV,EAASV,EAAE,mBAAmB,CAAC;AAAA,MACjC,UAAA;AACE,QAAAQ,EAAW,EAAK;AAAA,MAClB;AAAA,IACF,GAEA;AAAA,EACF,GAAG,CAACV,GAAKI,GAASF,CAAC,CAAC;AAEpB,QAAMqB,IAAWC,EAAY,MAAM;AACjC,UAAMC,IAAYV,EAAW;AAC7B,QAAI,CAACU,KAAa,CAACnB,EAAM;AAEzB,UAAMoB,IAAW,MAAM,KAAKD,EAAU,QAAQ;AAC9C,QAAIC,EAAS,WAAW,GAAG;AACzB,MAAAZ,EAAS,CAACR,CAAI,CAAC;AACf;AAAA,IACF;AAEA,UAAMc,IAAqB,CAAC,EAAE;AAC9B,QAAIO,IAAkB;AAEtB,eAAWC,KAASF,GAAU;AAC5B,YAAMG,IAAID,EAAM;AAIhB,MAAID,IAAkB,KAAKA,IAAkBE,IAAIlC,MAC/CyB,EAAO,KAAK,EAAE,GACdO,IAAkB,IAGpBP,EAAOA,EAAO,SAAS,CAAC,EAAE,KAAKQ,EAAM,SAAS,GAC9CD,KAAmBE;AAAA,IACrB;AAGA,IAAIT,EAAO,WAAW,KAAGA,EAAO,KAAK,CAAA,CAAE,GAEvCN,EAASM,EAAO,IAAI,CAAAU,MAAUA,EAAO,KAAK,EAAE,CAAC,CAAC;AAAA,EAChD,GAAG,CAACxB,CAAI,CAAC;AAcT,SAZAW,EAAU,MAAM;AACd,IAAI,CAACX,KAAQ,CAACS,EAAW,WACzB,sBAAsB,MAAM;AAC1B,MAAAQ,EAAA;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAACjB,GAAMiB,CAAQ,CAAC,GAGnBQ,EAAoB9B,GAAK,OAAO;AAAA,IAC9B,kBAAkB,MAAM,CAAA;AAAA,EAAC,IACvB,CAAA,CAAE,GAEFQ,IAEA,gBAAAuB,EAAC,SAAI,WAAU,sEACb,4BAAC,OAAA,EAAI,WAAU,qHAAoH,EAAA,CACrI,IAIArB,IACK,gBAAAqB,EAACC,GAAA,EAAc,SAAStB,EAAA,CAAO,IAItC,gBAAAuB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,YAAY,sBAAA;AAAA,MAGrB,UAAA;AAAA,QAAA,gBAAAF;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAKjB;AAAA,YACL,yBAAyB,EAAE,QAAQT,EAAA;AAAA,YACnC,OAAO;AAAA,cACL,GAAGT;AAAA,cACH,UAAU;AAAA,cACV,YAAY;AAAA,cACZ,OAAO,GAAG,MAAMH,IAAiB,CAAC;AAAA,cAClC,eAAe;AAAA,YAAA;AAAA,UACjB;AAAA,QAAA;AAAA,QAIF,gBAAAsC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO,EAAE,KAAK,GAAGpC,CAAQ,KAAA;AAAA,YAEvB,WAAAiB,EAAM,SAAS,IAAIA,IAAQ,CAAC,EAAE,GAAG,IAAI,CAACsB,GAAUC,MAChD,gBAAAJ;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,OAAO;AAAA,kBACL,OAAO;AAAA,kBACP,UAAU;AAAA,kBACV,WAAW,GAAGxC,CAAW;AAAA,kBACzB,YAAY;AAAA,kBACZ,WAAW;AAAA,kBACX,YAAY;AAAA,kBACZ,SAAS,GAAGC,CAAc,MAAMC,CAAc;AAAA,gBAAA;AAAA,gBAGhD,UAAA,gBAAAsC;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,yBAAyB,EAAE,QAAQG,EAAA;AAAA,oBACnC,OAAOtC;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACT;AAAA,cAdKuC;AAAA,YAAA,CAgBR;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAAA;AAGN,CAAC;"}
|
|
@@ -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-DreA69iU.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-vRLKumL8.mjs.map
|