@eternalheart/react-file-preview 1.3.10 → 1.3.11

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.
Files changed (114) hide show
  1. package/lib/RequestContext.d.ts +1 -1
  2. package/lib/RequestContext.d.ts.map +1 -1
  3. package/lib/chunks/RendererError-BH6fzLrN.mjs +15 -0
  4. package/lib/chunks/RendererError-BH6fzLrN.mjs.map +1 -0
  5. package/lib/chunks/avifLoader-BP3fgcMm-BnpxLhxp.mjs +56 -0
  6. package/lib/chunks/avifLoader-BP3fgcMm-BnpxLhxp.mjs.map +1 -0
  7. package/lib/chunks/heicLoader-CH_raQNn-1fBLaICM.mjs +37 -0
  8. package/lib/chunks/heicLoader-CH_raQNn-1fBLaICM.mjs.map +1 -0
  9. package/lib/chunks/index-B57rEPin.mjs +54 -0
  10. package/lib/chunks/index-B57rEPin.mjs.map +1 -0
  11. package/lib/chunks/index-BCuRRLYt.mjs +222 -0
  12. package/lib/chunks/index-BCuRRLYt.mjs.map +1 -0
  13. package/lib/chunks/{index-DSAXdrgU.mjs → index-BJ6vTNxc.mjs} +76 -75
  14. package/lib/chunks/index-BJ6vTNxc.mjs.map +1 -0
  15. package/lib/chunks/{index-C5YHI0Zs.mjs → index-BYdqrqnR.mjs} +52 -51
  16. package/lib/chunks/index-BYdqrqnR.mjs.map +1 -0
  17. package/lib/chunks/index-BiyghBxu.mjs +136 -0
  18. package/lib/chunks/index-BiyghBxu.mjs.map +1 -0
  19. package/lib/chunks/{index-CwmZQ-JO.mjs → index-C8CyS_sj.mjs} +67 -64
  20. package/lib/chunks/index-C8CyS_sj.mjs.map +1 -0
  21. package/lib/chunks/index-C8OrFLd5.mjs +594 -0
  22. package/lib/chunks/index-C8OrFLd5.mjs.map +1 -0
  23. package/lib/chunks/{index-DveR0rOk.mjs → index-CCkHAeLh.mjs} +41 -38
  24. package/lib/chunks/index-CCkHAeLh.mjs.map +1 -0
  25. package/lib/chunks/index-CdmkF0CO.mjs +105 -0
  26. package/lib/chunks/index-CdmkF0CO.mjs.map +1 -0
  27. package/lib/chunks/index-CuAALtwC.mjs +2299 -0
  28. package/lib/chunks/index-CuAALtwC.mjs.map +1 -0
  29. package/lib/chunks/index-D660ENHx.mjs +114 -0
  30. package/lib/chunks/index-D660ENHx.mjs.map +1 -0
  31. package/lib/chunks/{index-DN8BQIqo.mjs → index-DBEG73K1.mjs} +79 -78
  32. package/lib/chunks/index-DBEG73K1.mjs.map +1 -0
  33. package/lib/chunks/index-DaFlk9dd.mjs +13097 -0
  34. package/lib/chunks/index-DaFlk9dd.mjs.map +1 -0
  35. package/lib/chunks/index-_mP0FkqE.mjs +113 -0
  36. package/lib/chunks/index-_mP0FkqE.mjs.map +1 -0
  37. package/lib/chunks/{index-tecGXW2S.mjs → index-nLTQXCV7.mjs} +85 -83
  38. package/lib/chunks/index-nLTQXCV7.mjs.map +1 -0
  39. package/lib/chunks/index-nVblatyi.mjs +55 -0
  40. package/lib/chunks/index-nVblatyi.mjs.map +1 -0
  41. package/lib/chunks/{index-DPpUj8Yy.mjs → index-ow-nGpuu.mjs} +99 -98
  42. package/lib/chunks/index-ow-nGpuu.mjs.map +1 -0
  43. package/lib/chunks/index-qOC5xQyK.mjs +96 -0
  44. package/lib/chunks/index-qOC5xQyK.mjs.map +1 -0
  45. package/lib/chunks/index-rUfsiVR8.mjs +12335 -0
  46. package/lib/chunks/index-rUfsiVR8.mjs.map +1 -0
  47. package/lib/chunks/jp2Loader-Bn-qPMbD-Bn-qPMbD.mjs +122 -0
  48. package/lib/chunks/jp2Loader-Bn-qPMbD-Bn-qPMbD.mjs.map +1 -0
  49. package/lib/chunks/psdLoader-Doxw3mWm-DVOGFSlh.mjs +73 -0
  50. package/lib/chunks/psdLoader-Doxw3mWm-DVOGFSlh.mjs.map +1 -0
  51. package/lib/chunks/rawLoader-0mLvxCNp-CJmERiK7.mjs +82 -0
  52. package/lib/chunks/rawLoader-0mLvxCNp-CJmERiK7.mjs.map +1 -0
  53. package/lib/chunks/tiffLoader-CTFKVLqJ-B84NfwhR.mjs +60 -0
  54. package/lib/chunks/tiffLoader-CTFKVLqJ-B84NfwhR.mjs.map +1 -0
  55. package/lib/chunks/{useShikiHighlight-DHFYu0BU.mjs → useShikiHighlight-ClbUXJ2p.mjs} +2 -2
  56. package/lib/chunks/{useShikiHighlight-DHFYu0BU.mjs.map → useShikiHighlight-ClbUXJ2p.mjs.map} +1 -1
  57. package/lib/index.cjs +31 -22
  58. package/lib/index.cjs.map +1 -1
  59. package/lib/index.css +1 -1
  60. package/lib/index.mjs +8 -8
  61. package/lib/renderers/Audio/index.d.ts.map +1 -1
  62. package/lib/renderers/Csv/index.d.ts.map +1 -1
  63. package/lib/renderers/Docx/index.d.ts.map +1 -1
  64. package/lib/renderers/Epub/index.d.ts.map +1 -1
  65. package/lib/renderers/Font/index.d.ts.map +1 -1
  66. package/lib/renderers/Image/index.d.ts +2 -0
  67. package/lib/renderers/Image/index.d.ts.map +1 -1
  68. package/lib/renderers/Json/index.d.ts.map +1 -1
  69. package/lib/renderers/Markdown/index.d.ts.map +1 -1
  70. package/lib/renderers/Mobi/index.d.ts.map +1 -1
  71. package/lib/renderers/Msg/index.d.ts.map +1 -1
  72. package/lib/renderers/Pdf/index.d.ts.map +1 -1
  73. package/lib/renderers/Pptx/index.d.ts.map +1 -1
  74. package/lib/renderers/RendererError.d.ts +8 -0
  75. package/lib/renderers/RendererError.d.ts.map +1 -0
  76. package/lib/renderers/Subtitle/index.d.ts.map +1 -1
  77. package/lib/renderers/Text/index.d.ts.map +1 -1
  78. package/lib/renderers/Video/index.d.ts +1 -0
  79. package/lib/renderers/Video/index.d.ts.map +1 -1
  80. package/lib/renderers/Xlsx/index.d.ts.map +1 -1
  81. package/lib/renderers/Xml/index.d.ts.map +1 -1
  82. package/lib/renderers/Zip/index.d.ts.map +1 -1
  83. package/package.json +13 -5
  84. package/lib/chunks/index-B0JUZ5rS.mjs +0 -110
  85. package/lib/chunks/index-B0JUZ5rS.mjs.map +0 -1
  86. package/lib/chunks/index-BAYc4aBz.mjs +0 -129
  87. package/lib/chunks/index-BAYc4aBz.mjs.map +0 -1
  88. package/lib/chunks/index-BOQJNL71.mjs +0 -103
  89. package/lib/chunks/index-BOQJNL71.mjs.map +0 -1
  90. package/lib/chunks/index-BkU8rK-0.mjs +0 -51
  91. package/lib/chunks/index-BkU8rK-0.mjs.map +0 -1
  92. package/lib/chunks/index-BnDoXBnH.mjs +0 -257
  93. package/lib/chunks/index-BnDoXBnH.mjs.map +0 -1
  94. package/lib/chunks/index-C5YHI0Zs.mjs.map +0 -1
  95. package/lib/chunks/index-CGNWXFy3.mjs +0 -2081
  96. package/lib/chunks/index-CGNWXFy3.mjs.map +0 -1
  97. package/lib/chunks/index-CwmZQ-JO.mjs.map +0 -1
  98. package/lib/chunks/index-CzflrElZ.mjs +0 -52
  99. package/lib/chunks/index-CzflrElZ.mjs.map +0 -1
  100. package/lib/chunks/index-CztCCF7q.mjs +0 -116
  101. package/lib/chunks/index-CztCCF7q.mjs.map +0 -1
  102. package/lib/chunks/index-DKEcGewg.mjs +0 -96
  103. package/lib/chunks/index-DKEcGewg.mjs.map +0 -1
  104. package/lib/chunks/index-DN8BQIqo.mjs.map +0 -1
  105. package/lib/chunks/index-DPpUj8Yy.mjs.map +0 -1
  106. package/lib/chunks/index-DSAXdrgU.mjs.map +0 -1
  107. package/lib/chunks/index-DveR0rOk.mjs.map +0 -1
  108. package/lib/chunks/index-QfO-sASN.mjs +0 -152
  109. package/lib/chunks/index-QfO-sASN.mjs.map +0 -1
  110. package/lib/chunks/index-h9bO9wmq.mjs +0 -99
  111. package/lib/chunks/index-h9bO9wmq.mjs.map +0 -1
  112. package/lib/chunks/index-mvSVNKlQ.mjs +0 -228
  113. package/lib/chunks/index-mvSVNKlQ.mjs.map +0 -1
  114. package/lib/chunks/index-tecGXW2S.mjs.map +0 -1
@@ -15,7 +15,7 @@ export declare function useRequest(): RequestContextValue;
15
15
  export declare function useFetcher(): Fetcher;
16
16
  /**
17
17
  * 解析 file 的可消费 URL:
18
- * - 未配置 shouldFetchAsBlob 或返回 false:直接返回 file.url
18
+ * - 未配置 shouldFetchAsBlob 或返回 false:同步返回 file.url(不入 state,避免切换文件时残留旧值)
19
19
  * - 返回 true:用 fetcher 拉成 blob: URL,组件卸载或 file 变化时 revoke
20
20
  *
21
21
  * 期间返回空字符串(表示 "还没准备好"),调用方应避免空 URL 时挂载到 <img src> 等。
@@ -1 +1 @@
1
- {"version":3,"file":"RequestContext.d.ts","sourceRoot":"","sources":["../src/RequestContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA0E,MAAM,OAAO,CAAC;AAC/F,OAAO,KAAK,EACV,OAAO,EACP,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,iCAAiC,CAAC;AAGzC,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAQD,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAgB1D,CAAC;AAEF,wBAAgB,UAAU,IAAI,mBAAmB,CAEhD;AAED,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,MAAM,CAqDpE"}
1
+ {"version":3,"file":"RequestContext.d.ts","sourceRoot":"","sources":["../src/RequestContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA0E,MAAM,OAAO,CAAC;AAC/F,OAAO,KAAK,EACV,OAAO,EACP,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,iCAAiC,CAAC;AAGzC,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAQD,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAgB1D,CAAC;AAEF,wBAAgB,UAAU,IAAI,mBAAmB,CAEhD;AAED,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,MAAM,CAuDpE"}
@@ -0,0 +1,15 @@
1
+ import { jsx as r, jsxs as p } from "react/jsx-runtime";
2
+ import { AlertCircle as l } from "lucide-react";
3
+ const c = ({
4
+ message: f,
5
+ detail: e,
6
+ showIcon: t = !0
7
+ }) => /* @__PURE__ */ r("div", { className: "rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full", children: /* @__PURE__ */ p("div", { className: "rfp-text-center", children: [
8
+ t && /* @__PURE__ */ r("div", { className: "rfp-w-16 rfp-h-16 rfp-mx-auto rfp-mb-4 rfp-rounded-full rfp-bg-red-500/10 rfp-flex rfp-items-center rfp-justify-center", children: /* @__PURE__ */ r(l, { className: "rfp-w-8 rfp-h-8 rfp-text-red-400" }) }),
9
+ /* @__PURE__ */ r("p", { className: "rfp-text-lg md:rfp-text-xl rfp-font-medium rfp-text-fg-primary rfp-mb-2", children: f }),
10
+ e && /* @__PURE__ */ r("p", { className: "rfp-text-sm rfp-text-fg-tertiary", children: e })
11
+ ] }) });
12
+ export {
13
+ c as R
14
+ };
15
+ //# sourceMappingURL=RendererError-BH6fzLrN.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RendererError-BH6fzLrN.mjs","sources":["../../src/renderers/RendererError.tsx"],"sourcesContent":["import { AlertCircle } from 'lucide-react';\n\ninterface RendererErrorProps {\n message: string;\n detail?: string;\n showIcon?: boolean;\n}\n\nexport const RendererError: React.FC<RendererErrorProps> = ({\n message,\n detail,\n showIcon = true,\n}) => {\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-text-center\">\n {showIcon && (\n <div className=\"rfp-w-16 rfp-h-16 rfp-mx-auto rfp-mb-4 rfp-rounded-full rfp-bg-red-500/10 rfp-flex rfp-items-center rfp-justify-center\">\n <AlertCircle className=\"rfp-w-8 rfp-h-8 rfp-text-red-400\" />\n </div>\n )}\n <p className=\"rfp-text-lg md:rfp-text-xl rfp-font-medium rfp-text-fg-primary rfp-mb-2\">\n {message}\n </p>\n {detail && (\n <p className=\"rfp-text-sm rfp-text-fg-tertiary\">{detail}</p>\n )}\n </div>\n </div>\n );\n};\n"],"names":["RendererError","message","detail","showIcon","jsxs","jsx","AlertCircle"],"mappings":";;AAQO,MAAMA,IAA8C,CAAC;AAAA,EAC1D,SAAAC;AAAA,EACA,QAAAC;AAAA,EACA,UAAAC,IAAW;AACb,wBAEK,OAAA,EAAI,WAAU,sEACb,UAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,mBACZ,UAAA;AAAA,EAAAD,KACC,gBAAAE,EAAC,SAAI,WAAU,0HACb,4BAACC,GAAA,EAAY,WAAU,oCAAmC,EAAA,CAC5D;AAAA,EAEF,gBAAAD,EAAC,KAAA,EAAE,WAAU,2EACV,UAAAJ,GACH;AAAA,EACCC,KACC,gBAAAG,EAAC,KAAA,EAAE,WAAU,oCAAoC,UAAAH,EAAA,CAAO;AAAA,EAAA,CAE5D,EAAA,CACF;"}
@@ -0,0 +1,56 @@
1
+ let a = null;
2
+ async function B() {
3
+ return a !== null ? a : new Promise((n) => {
4
+ const A = new Image();
5
+ A.onload = () => {
6
+ a = A.width === 1 && A.height === 1, n(a);
7
+ }, A.onerror = () => {
8
+ a = !1, n(!1);
9
+ }, A.src = "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAEAAAABAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQAMAAAAABNjb2xybmNseAACAAIABoAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgABogQEDQgMgkQAAAAB8dSLfI=";
10
+ });
11
+ }
12
+ class d {
13
+ /**
14
+ * 检测是否需要解码:仅在浏览器不原生支持 AVIF 时需要
15
+ */
16
+ async needsDecode(A) {
17
+ return A !== "image/avif" ? !1 : !await B();
18
+ }
19
+ /**
20
+ * 解码 AVIF 文件为 PNG Blob
21
+ */
22
+ async decode(A, r) {
23
+ if (await B())
24
+ return A instanceof Blob ? A : new Blob([A], { type: "image/avif" });
25
+ try {
26
+ const e = await import("@jsquash/avif"), l = A instanceof Blob ? await A.arrayBuffer() : A, o = await e.decode(l), t = document.createElement("canvas");
27
+ t.width = o.width, t.height = o.height;
28
+ const i = t.getContext("2d");
29
+ if (!i)
30
+ throw new Error("无法创建 Canvas 2D 上下文");
31
+ return i.putImageData(o, 0, 0), new Promise((c, g) => {
32
+ t.toBlob(
33
+ (s) => {
34
+ s ? c(s) : g(new Error("AVIF Canvas 转换为 PNG 失败"));
35
+ },
36
+ (r == null ? void 0 : r.outputFormat) || "image/png"
37
+ );
38
+ });
39
+ } catch (e) {
40
+ throw new Error(`AVIF 解码失败: ${(e == null ? void 0 : e.message) || "未知错误"}`);
41
+ }
42
+ }
43
+ /**
44
+ * 获取 AVIF 元数据
45
+ */
46
+ async getMetadata(A) {
47
+ return {
48
+ format: "avif"
49
+ };
50
+ }
51
+ }
52
+ const w = new d();
53
+ export {
54
+ w as default
55
+ };
56
+ //# sourceMappingURL=avifLoader-BP3fgcMm-BnpxLhxp.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avifLoader-BP3fgcMm-BnpxLhxp.mjs","sources":["../../../file-preview-core/lib/avifLoader-BP3fgcMm.js"],"sourcesContent":["let e = null;\nasync function c() {\n return e !== null ? e : new Promise((n) => {\n const A = new Image();\n A.onload = () => {\n e = A.width === 1 && A.height === 1, n(e);\n }, A.onerror = () => {\n e = !1, n(!1);\n }, A.src = \"data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAEAAAABAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQAMAAAAABNjb2xybmNseAACAAIABoAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgABogQEDQgMgkQAAAAB8dSLfI=\";\n });\n}\nclass f {\n /**\n * 检测是否需要解码:仅在浏览器不原生支持 AVIF 时需要\n */\n async needsDecode(A) {\n return A !== \"image/avif\" ? !1 : !await c();\n }\n /**\n * 解码 AVIF 文件为 PNG Blob\n */\n async decode(A, r) {\n if (await c())\n return A instanceof Blob ? A : new Blob([A], { type: \"image/avif\" });\n try {\n const a = await import(\"@jsquash/avif\"), i = A instanceof Blob ? await A.arrayBuffer() : A, o = await a.decode(i), t = document.createElement(\"canvas\");\n t.width = o.width, t.height = o.height;\n const s = t.getContext(\"2d\");\n if (!s)\n throw new Error(\"无法创建 Canvas 2D 上下文\");\n return s.putImageData(o, 0, 0), new Promise((g, d) => {\n t.toBlob(\n (B) => {\n B ? g(B) : d(new Error(\"AVIF Canvas 转换为 PNG 失败\"));\n },\n (r == null ? void 0 : r.outputFormat) || \"image/png\"\n );\n });\n } catch (a) {\n throw new Error(`AVIF 解码失败: ${(a == null ? void 0 : a.message) || \"未知错误\"}`);\n }\n }\n /**\n * 获取 AVIF 元数据\n */\n async getMetadata(A) {\n return {\n format: \"avif\"\n };\n }\n}\nconst m = new f();\nexport {\n m as default\n};\n//# sourceMappingURL=avifLoader-BP3fgcMm.js.map\n"],"names":["e","c","f","a","i","s","g","d","B","m"],"mappings":"AAAA,IAAIA,IAAI;AACR,eAAeC,IAAI;AACjB,SAAOD,MAAM,OAAOA,IAAI,IAAI,QAAQ,CAAC,MAAM;AACzC,UAAM,IAAI,IAAI,MAAK;AACnB,MAAE,SAAS,MAAM;AACf,MAAAA,IAAI,EAAE,UAAU,KAAK,EAAE,WAAW,GAAG,EAAEA,CAAC;AAAA,IAC1C,GAAG,EAAE,UAAU,MAAM;AACnB,MAAAA,IAAI,IAAI,EAAE,EAAE;AAAA,IACd,GAAG,EAAE,MAAM;AAAA,EACb,CAAC;AACH;AACA,MAAME,EAAE;AAAA;AAAA;AAAA;AAAA,EAIN,MAAM,YAAY,GAAG;AACnB,WAAO,MAAM,eAAe,KAAK,CAAC,MAAMD,EAAC;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAIA,MAAM,OAAO,GAAG,GAAG;AACjB,QAAI,MAAMA,EAAC;AACT,aAAO,aAAa,OAAO,IAAI,IAAI,KAAK,CAAC,CAAC,GAAG,EAAE,MAAM,cAAc;AACrE,QAAI;AACF,YAAME,IAAI,MAAM,OAAO,eAAe,GAAGC,IAAI,aAAa,OAAO,MAAM,EAAE,YAAW,IAAK,GAAG,IAAI,MAAMD,EAAE,OAAOC,CAAC,GAAG,IAAI,SAAS,cAAc,QAAQ;AACtJ,QAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE;AAChC,YAAMC,IAAI,EAAE,WAAW,IAAI;AAC3B,UAAI,CAACA;AACH,cAAM,IAAI,MAAM,oBAAoB;AACtC,aAAOA,EAAE,aAAa,GAAG,GAAG,CAAC,GAAG,IAAI,QAAQ,CAACC,GAAGC,MAAM;AACpD,UAAE;AAAA,UACA,CAACC,MAAM;AACL,YAAAA,IAAIF,EAAEE,CAAC,IAAID,EAAE,IAAI,MAAM,wBAAwB,CAAC;AAAA,UAClD;AAAA,WACC,KAAK,OAAO,SAAS,EAAE,iBAAiB;AAAA,QACnD;AAAA,MACM,CAAC;AAAA,IACH,SAASJ,GAAG;AACV,YAAM,IAAI,MAAM,eAAeA,KAAK,OAAO,SAASA,EAAE,YAAY,MAAM,EAAE;AAAA,IAC5E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAIA,MAAM,YAAY,GAAG;AACnB,WAAO;AAAA,MACL,QAAQ;AAAA,IACd;AAAA,EACE;AACF;AACK,MAACM,IAAI,IAAIP,EAAC;"}
@@ -0,0 +1,37 @@
1
+ class l {
2
+ /**
3
+ * HEIC 格式浏览器均不原生支持,始终需要解码
4
+ */
5
+ async needsDecode(a) {
6
+ return a === "image/heic" || a === "image/heif";
7
+ }
8
+ /**
9
+ * 解码 HEIC 文件为 JPEG Blob
10
+ */
11
+ async decode(a, r) {
12
+ var n, o;
13
+ try {
14
+ const e = await import("heic2any"), i = a instanceof Blob ? a : new Blob([a], { type: "image/heic" }), t = await e.default({
15
+ blob: i,
16
+ toType: (r == null ? void 0 : r.outputFormat) || "image/jpeg",
17
+ quality: 0.9
18
+ });
19
+ return Array.isArray(t) ? t[0] : t;
20
+ } catch (e) {
21
+ throw (n = e == null ? void 0 : e.message) != null && n.includes("DRM") || (o = e == null ? void 0 : e.message) != null && o.includes("protected") ? new Error("HEIC 解码失败,文件受 DRM 保护") : new Error(`HEIC 解码失败,文件可能损坏: ${(e == null ? void 0 : e.message) || "未知错误"}`);
22
+ }
23
+ }
24
+ /**
25
+ * 获取 HEIC 元数据(当前版本暂不实现,返回空对象)
26
+ */
27
+ async getMetadata(a) {
28
+ return {
29
+ format: "heic"
30
+ };
31
+ }
32
+ }
33
+ const c = new l();
34
+ export {
35
+ c as default
36
+ };
37
+ //# sourceMappingURL=heicLoader-CH_raQNn-1fBLaICM.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heicLoader-CH_raQNn-1fBLaICM.mjs","sources":["../../../file-preview-core/lib/heicLoader-CH_raQNn.js"],"sourcesContent":["class r {\n /**\n * HEIC 格式浏览器均不原生支持,始终需要解码\n */\n async needsDecode(a) {\n return a === \"image/heic\" || a === \"image/heif\";\n }\n /**\n * 解码 HEIC 文件为 JPEG Blob\n */\n async decode(a, t) {\n var s, n;\n try {\n const e = await import(\"heic2any\"), i = a instanceof Blob ? a : new Blob([a], { type: \"image/heic\" }), c = await e.default({\n blob: i,\n toType: (t == null ? void 0 : t.outputFormat) || \"image/jpeg\",\n quality: 0.9\n });\n return Array.isArray(c) ? c[0] : c;\n } catch (e) {\n throw (s = e == null ? void 0 : e.message) != null && s.includes(\"DRM\") || (n = e == null ? void 0 : e.message) != null && n.includes(\"protected\") ? new Error(\"HEIC 解码失败,文件受 DRM 保护\") : new Error(`HEIC 解码失败,文件可能损坏: ${(e == null ? void 0 : e.message) || \"未知错误\"}`);\n }\n }\n /**\n * 获取 HEIC 元数据(当前版本暂不实现,返回空对象)\n */\n async getMetadata(a) {\n return {\n format: \"heic\"\n };\n }\n}\nconst u = new r();\nexport {\n u as default\n};\n//# sourceMappingURL=heicLoader-CH_raQNn.js.map\n"],"names":["r","t","s","n","c","u"],"mappings":"AAAA,MAAMA,EAAE;AAAA;AAAA;AAAA;AAAA,EAIN,MAAM,YAAY,GAAG;AACnB,WAAO,MAAM,gBAAgB,MAAM;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAIA,MAAM,OAAO,GAAGC,GAAG;AACjB,QAAIC,GAAGC;AACP,QAAI;AACF,YAAM,IAAI,MAAM,OAAO,UAAU,GAAG,IAAI,aAAa,OAAO,IAAI,IAAI,KAAK,CAAC,CAAC,GAAG,EAAE,MAAM,aAAY,CAAE,GAAGC,IAAI,MAAM,EAAE,QAAQ;AAAA,QACzH,MAAM;AAAA,QACN,SAASH,KAAK,OAAO,SAASA,EAAE,iBAAiB;AAAA,QACjD,SAAS;AAAA,MACjB,CAAO;AACD,aAAO,MAAM,QAAQG,CAAC,IAAIA,EAAE,CAAC,IAAIA;AAAA,IACnC,SAAS,GAAG;AACV,aAAOF,IAAI,KAAK,OAAO,SAAS,EAAE,YAAY,QAAQA,EAAE,SAAS,KAAK,MAAMC,IAAI,KAAK,OAAO,SAAS,EAAE,YAAY,QAAQA,EAAE,SAAS,WAAW,IAAI,IAAI,MAAM,sBAAsB,IAAI,IAAI,MAAM,sBAAsB,KAAK,OAAO,SAAS,EAAE,YAAY,MAAM,EAAE;AAAA,IACtQ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAIA,MAAM,YAAY,GAAG;AACnB,WAAO;AAAA,MACL,QAAQ;AAAA,IACd;AAAA,EACE;AACF;AACK,MAACE,IAAI,IAAIL,EAAC;"}
@@ -0,0 +1,54 @@
1
+ import { jsx as o } from "react/jsx-runtime";
2
+ import { useState as f, useEffect as u } from "react";
3
+ import { u as h, a as g, E as w } from "./index-CuAALtwC.mjs";
4
+ import { u as b } from "./useShikiHighlight-ClbUXJ2p.mjs";
5
+ import { R as y } from "./RendererError-BH6fzLrN.mjs";
6
+ const N = (r) => {
7
+ try {
8
+ const n = new DOMParser().parseFromString(r, "application/xml");
9
+ if (n.querySelector("parsererror")) return r;
10
+ const e = new XMLSerializer().serializeToString(n);
11
+ return x(e);
12
+ } catch {
13
+ return r;
14
+ }
15
+ }, x = (r) => {
16
+ const l = " ", n = /(>)(<)(\/*)/g;
17
+ let s = r.replace(n, `$1
18
+ $2$3`), t = 0;
19
+ return s.split(`
20
+ `).map((e) => {
21
+ let a = 0;
22
+ /^<\/\w/.test(e) ? t = Math.max(t - 1, 0) : /^<\w[^>]*[^/]>.*$/.test(e) && !/<.+<\/.+>$/.test(e) && (a = 1);
23
+ const i = l.repeat(t) + e;
24
+ return t += a, i;
25
+ }).join(`
26
+ `);
27
+ }, X = ({ url: r }) => {
28
+ const l = h(), n = g(), [s, t] = f(""), [e, a] = f(!0), [i, c] = f(null), { html: d } = b(s, "xml");
29
+ return u(() => {
30
+ const m = new AbortController();
31
+ return (async () => {
32
+ try {
33
+ a(!0), c(null);
34
+ const p = await w(r, { fetcher: n, signal: m.signal });
35
+ t(N(p));
36
+ } catch (p) {
37
+ if (p.name === "AbortError") return;
38
+ console.error(p), c(l("xml.load_failed"));
39
+ } finally {
40
+ a(!1);
41
+ }
42
+ })(), () => m.abort();
43
+ }, [r]), e ? /* @__PURE__ */ o("div", { className: "rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full", 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" }) }) : i ? /* @__PURE__ */ o(y, { message: i }) : /* @__PURE__ */ o("div", { className: "rfp-w-full rfp-h-full rfp-overflow-auto rfp-bg-code-bg", children: d ? /* @__PURE__ */ o(
44
+ "div",
45
+ {
46
+ className: "rfp-shiki-wrapper with-line-numbers",
47
+ dangerouslySetInnerHTML: { __html: d }
48
+ }
49
+ ) : /* @__PURE__ */ o("pre", { className: "rfp-p-6 rfp-text-fg-primary rfp-font-mono rfp-text-sm rfp-whitespace-pre-wrap rfp-break-words", children: s }) });
50
+ };
51
+ export {
52
+ X as XmlRenderer
53
+ };
54
+ //# sourceMappingURL=index-B57rEPin.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-B57rEPin.mjs","sources":["../../src/renderers/Xml/index.tsx"],"sourcesContent":["import { useState, useEffect } from 'react';\nimport { fetchTextUtf8 } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { useShikiHighlight } from '../../hooks/useShikiHighlight';\nimport { RendererError } from '../RendererError';\n\ninterface XmlRendererProps {\n url: string;\n fileName: string;\n}\n\n/**\n * 用 DOMParser 美化 XML:失败则原样返回\n */\nconst prettyPrintXml = (xml: string): string => {\n try {\n const parser = new DOMParser();\n const doc = parser.parseFromString(xml, 'application/xml');\n // 检测解析错误\n const errNode = doc.querySelector('parsererror');\n if (errNode) return xml;\n // 使用 XSLT 或手动缩进:这里手动缩进更稳\n const serializer = new XMLSerializer();\n const serialized = serializer.serializeToString(doc);\n return indentXml(serialized);\n } catch {\n return xml;\n }\n};\n\nconst indentXml = (xml: string): string => {\n const PADDING = ' ';\n const reg = /(>)(<)(\\/*)/g;\n let formatted = xml.replace(reg, '$1\\n$2$3');\n // 自闭合和 CDATA 等不处理\n let pad = 0;\n return formatted\n .split('\\n')\n .map((line) => {\n let indent = 0;\n if (/^<\\/\\w/.test(line)) {\n pad = Math.max(pad - 1, 0);\n } else if (/^<\\w[^>]*[^/]>.*$/.test(line) && !/<.+<\\/.+>$/.test(line)) {\n indent = 1;\n }\n const padded = PADDING.repeat(pad) + line;\n pad += indent;\n return padded;\n })\n .join('\\n');\n};\n\nexport const XmlRenderer: React.FC<XmlRendererProps> = ({ url }) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [content, setContent] = useState<string>('');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const { html: highlighted } = useShikiHighlight(content, 'xml');\n\n useEffect(() => {\n const controller = new AbortController();\n const load = async () => {\n try {\n setLoading(true);\n setError(null);\n const raw = await fetchTextUtf8(url, { fetcher, signal: controller.signal });\n setContent(prettyPrintXml(raw));\n } catch (err: any) {\n if (err.name === 'AbortError') return;\n console.error(err);\n setError(t('xml.load_failed'));\n } finally {\n setLoading(false);\n }\n };\n load();\n return () => controller.abort();\n }, [url]);\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 className=\"rfp-w-full rfp-h-full rfp-overflow-auto rfp-bg-code-bg\">\n {highlighted ? (\n <div\n className=\"rfp-shiki-wrapper with-line-numbers\"\n dangerouslySetInnerHTML={{ __html: highlighted }}\n />\n ) : (\n <pre className=\"rfp-p-6 rfp-text-fg-primary rfp-font-mono rfp-text-sm rfp-whitespace-pre-wrap rfp-break-words\">\n {content}\n </pre>\n )}\n </div>\n );\n};\n"],"names":["prettyPrintXml","xml","doc","serialized","indentXml","PADDING","reg","formatted","pad","line","indent","padded","XmlRenderer","url","t","useTranslator","fetcher","useFetcher","content","setContent","useState","loading","setLoading","error","setError","highlighted","useShikiHighlight","useEffect","controller","raw","fetchTextUtf8","err","jsx","RendererError"],"mappings":";;;;;AAeA,MAAMA,IAAiB,CAACC,MAAwB;AAC9C,MAAI;AAEF,UAAMC,IADS,IAAI,UAAA,EACA,gBAAgBD,GAAK,iBAAiB;AAGzD,QADgBC,EAAI,cAAc,aAAa,EAClC,QAAOD;AAGpB,UAAME,IADa,IAAI,cAAA,EACO,kBAAkBD,CAAG;AACnD,WAAOE,EAAUD,CAAU;AAAA,EAC7B,QAAQ;AACN,WAAOF;AAAA,EACT;AACF,GAEMG,IAAY,CAACH,MAAwB;AACzC,QAAMI,IAAU,MACVC,IAAM;AACZ,MAAIC,IAAYN,EAAI,QAAQK,GAAK;AAAA,KAAU,GAEvCE,IAAM;AACV,SAAOD,EACJ,MAAM;AAAA,CAAI,EACV,IAAI,CAACE,MAAS;AACb,QAAIC,IAAS;AACb,IAAI,SAAS,KAAKD,CAAI,IACpBD,IAAM,KAAK,IAAIA,IAAM,GAAG,CAAC,IAChB,oBAAoB,KAAKC,CAAI,KAAK,CAAC,aAAa,KAAKA,CAAI,MAClEC,IAAS;AAEX,UAAMC,IAASN,EAAQ,OAAOG,CAAG,IAAIC;AACrC,WAAAD,KAAOE,GACAC;AAAA,EACT,CAAC,EACA,KAAK;AAAA,CAAI;AACd,GAEaC,IAA0C,CAAC,EAAE,KAAAC,QAAU;AAClE,QAAMC,IAAIC,EAAA,GACJC,IAAUC,EAAA,GACV,CAACC,GAASC,CAAU,IAAIC,EAAiB,EAAE,GAC3C,CAACC,GAASC,CAAU,IAAIF,EAAS,EAAI,GACrC,CAACG,GAAOC,CAAQ,IAAIJ,EAAwB,IAAI,GAChD,EAAE,MAAMK,EAAA,IAAgBC,EAAkBR,GAAS,KAAK;AAsB9D,SApBAS,EAAU,MAAM;AACd,UAAMC,IAAa,IAAI,gBAAA;AAevB,YAda,YAAY;AACvB,UAAI;AACF,QAAAN,EAAW,EAAI,GACfE,EAAS,IAAI;AACb,cAAMK,IAAM,MAAMC,EAAcjB,GAAK,EAAE,SAAAG,GAAS,QAAQY,EAAW,QAAQ;AAC3E,QAAAT,EAAWnB,EAAe6B,CAAG,CAAC;AAAA,MAChC,SAASE,GAAU;AACjB,YAAIA,EAAI,SAAS,aAAc;AAC/B,gBAAQ,MAAMA,CAAG,GACjBP,EAASV,EAAE,iBAAiB,CAAC;AAAA,MAC/B,UAAA;AACE,QAAAQ,EAAW,EAAK;AAAA,MAClB;AAAA,IACF,GACA,GACO,MAAMM,EAAW,MAAA;AAAA,EAC1B,GAAG,CAACf,CAAG,CAAC,GAEJQ,IAEA,gBAAAW,EAAC,SAAI,WAAU,sEACb,4BAAC,OAAA,EAAI,WAAU,qHAAoH,EAAA,CACrI,IAIAT,IACK,gBAAAS,EAACC,GAAA,EAAc,SAASV,EAAA,CAAO,IAItC,gBAAAS,EAAC,OAAA,EAAI,WAAU,0DACZ,UAAAP,IACC,gBAAAO;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,yBAAyB,EAAE,QAAQP,EAAA;AAAA,IAAY;AAAA,EAAA,IAGjD,gBAAAO,EAAC,OAAA,EAAI,WAAU,iGACZ,aACH,GAEJ;AAEJ;"}
@@ -0,0 +1,222 @@
1
+ import { jsxs as v, jsx as i } from "react/jsx-runtime";
2
+ import { useState as c, useRef as w, useEffect as P, useCallback as $ } from "react";
3
+ import { motion as me } from "framer-motion";
4
+ import { Loader2 as be } from "lucide-react";
5
+ import { u as ge, G as he, q as xe } from "./index-CuAALtwC.mjs";
6
+ import { R as se } from "./RendererError-BH6fzLrN.mjs";
7
+ const Ue = ({
8
+ url: B,
9
+ zoom: K,
10
+ rotation: ae,
11
+ resetKey: Q,
12
+ fileSize: b,
13
+ file: R,
14
+ onZoomChange: d,
15
+ onNaturalWidthChange: T,
16
+ onNaturalHeightChange: F
17
+ }) => {
18
+ const A = ge(), [N, q] = c(!1), [g, J] = c(null), [O, u] = c(!1), [V, z] = c(0), [L, G] = c(null), [C, h] = c(""), [M, S] = c(1), [U, Z] = c(1), [j, k] = c({ x: 0, y: 0 }), [I, ee] = c(!1), [W, ce] = c({ x: 0, y: 0 }), [_, Y] = c(1), [p, oe] = c({ width: 0, height: 0 }), fe = w(null), H = w(null), x = w(null), D = w(null), E = w(null), o = w(/* @__PURE__ */ new Map());
19
+ P(() => {
20
+ let e = !1;
21
+ return (async () => {
22
+ if (h(""), q(!1), J(null), u(!1), G(null), z(0), k({ x: 0, y: 0 }), Y(1), S(1), Z(1), x.current && (URL.revokeObjectURL(x.current), x.current = null), o.current.forEach((r) => URL.revokeObjectURL(r)), o.current.clear(), D.current = null, E.current = null, !R) {
23
+ e || h(B);
24
+ return;
25
+ }
26
+ try {
27
+ const r = await he(R), t = await xe(r);
28
+ if (!t || !await t.needsDecode(r)) {
29
+ e || h(B);
30
+ return;
31
+ }
32
+ u(!0);
33
+ let n;
34
+ if (R instanceof Blob)
35
+ n = R;
36
+ else {
37
+ const a = await fetch(B);
38
+ if (!a.ok) throw new Error("Failed to fetch file");
39
+ n = await a.blob();
40
+ }
41
+ if (e) return;
42
+ if (D.current = n, E.current = t, D.current = n, E.current = t, t.getMetadata)
43
+ try {
44
+ const a = await t.getMetadata(n);
45
+ !e && a.pageCount && a.pageCount > 1 && Z(a.pageCount);
46
+ } catch {
47
+ }
48
+ const f = await t.decode(n, {
49
+ page: 1,
50
+ fullQuality: !1,
51
+ onProgress: (a) => {
52
+ e || z(a);
53
+ }
54
+ });
55
+ if (e) return;
56
+ const m = typeof f == "string" ? f : URL.createObjectURL(f);
57
+ x.current = m, o.current.set(1, m), h(m), u(!1);
58
+ } catch (r) {
59
+ e || (G((r == null ? void 0 : r.message) || "解码失败"), u(!1));
60
+ }
61
+ })(), () => {
62
+ e = !0;
63
+ };
64
+ }, [B, R]);
65
+ const re = $(async (e) => {
66
+ if (!D.current || !E.current || e < 1 || e > U) return;
67
+ const s = o.current.get(e);
68
+ if (s) {
69
+ S(e), h(s);
70
+ return;
71
+ }
72
+ u(!0);
73
+ try {
74
+ const r = await E.current.decode(D.current, { page: e }), t = typeof r == "string" ? r : URL.createObjectURL(r);
75
+ if (o.current.size >= 10) {
76
+ const n = o.current.keys().next().value;
77
+ if (n !== void 0) {
78
+ const f = o.current.get(n);
79
+ f && URL.revokeObjectURL(f), o.current.delete(n);
80
+ }
81
+ }
82
+ o.current.set(e, t), S(e), h(t), u(!1);
83
+ } catch (r) {
84
+ G((r == null ? void 0 : r.message) || "翻页解码失败"), u(!1);
85
+ }
86
+ }, [U]);
87
+ P(() => () => {
88
+ x.current && URL.revokeObjectURL(x.current), o.current.forEach((e) => URL.revokeObjectURL(e)), o.current.clear();
89
+ }, []), P(() => {
90
+ Y(K);
91
+ }, [K]), P(() => {
92
+ Q !== void 0 && k({ x: 0, y: 0 });
93
+ }, [Q]);
94
+ const ie = (e) => {
95
+ q(!0);
96
+ const s = e.currentTarget;
97
+ oe({ width: s.naturalWidth, height: s.naturalHeight }), T == null || T(s.naturalWidth), F == null || F(s.naturalHeight);
98
+ }, X = $((e, s) => {
99
+ const r = H.current;
100
+ if (!r || p.width === 0) return e;
101
+ const t = r.clientWidth, n = r.clientHeight, f = p.width * s, m = p.height * s, a = Math.min(80, t * 0.15, n * 0.15), l = (t + f) / 2 - a, y = (n + m) / 2 - a;
102
+ return {
103
+ x: l > 0 ? Math.max(-l, Math.min(l, e.x)) : 0,
104
+ y: y > 0 ? Math.max(-y, Math.min(y, e.y)) : 0
105
+ };
106
+ }, [p]), le = () => {
107
+ J(A("image.load_failed")), q(!0);
108
+ }, de = () => {
109
+ k({ x: 0, y: 0 }), Y(1), d == null || d(1);
110
+ };
111
+ P(() => {
112
+ const e = H.current;
113
+ if (!e) return;
114
+ const s = (r) => {
115
+ r.preventDefault(), r.stopPropagation();
116
+ const t = e.getBoundingClientRect(), n = r.clientX - t.left - t.width / 2, f = r.clientY - t.top - t.height / 2, m = r.deltaY > 0 ? -0.05 : 0.05;
117
+ Y((a) => {
118
+ const l = Math.max(0.01, Math.min(10, a + m)), y = l / a;
119
+ return k((ne) => X({
120
+ x: n - y * (n - ne.x),
121
+ y: f - y * (f - ne.y)
122
+ }, l)), d == null || d(l), l;
123
+ });
124
+ };
125
+ return e.addEventListener("wheel", s, { passive: !1 }), () => e.removeEventListener("wheel", s);
126
+ }, [d, X]);
127
+ const ue = $((e) => {
128
+ e.button === 0 && (ee(!0), ce({
129
+ x: e.clientX - j.x,
130
+ y: e.clientY - j.y
131
+ }));
132
+ }, [j]), pe = $((e) => {
133
+ I && k(X({
134
+ x: e.clientX - W.x,
135
+ y: e.clientY - W.y
136
+ }, _));
137
+ }, [I, W, _, X]), te = $(() => {
138
+ ee(!1);
139
+ }, []);
140
+ return /* @__PURE__ */ v(
141
+ "div",
142
+ {
143
+ ref: H,
144
+ className: "rfp-relative rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full rfp-overflow-hidden",
145
+ onMouseDown: ue,
146
+ onMouseMove: pe,
147
+ onMouseUp: te,
148
+ onMouseLeave: te,
149
+ style: { cursor: I ? "grabbing" : "grab" },
150
+ children: [
151
+ O && /* @__PURE__ */ v("div", { className: "rfp-absolute rfp-inset-0 rfp-flex rfp-flex-col rfp-items-center rfp-justify-center rfp-bg-surface-1/80 rfp-z-10", children: [
152
+ /* @__PURE__ */ i(be, { className: "rfp-w-12 rfp-h-12 rfp-text-fg-primary rfp-animate-spin" }),
153
+ /* @__PURE__ */ v("p", { className: "rfp-mt-4 rfp-text-fg-secondary", children: [
154
+ "正在解码... ",
155
+ V > 0 && `${Math.round(V)}%`
156
+ ] })
157
+ ] }),
158
+ L && /* @__PURE__ */ i("div", { className: "rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-1/80 rfp-z-10", children: /* @__PURE__ */ i(se, { message: A("image.decode_failed"), detail: L }) }),
159
+ !N && !g && !O && !L && /* @__PURE__ */ i("div", { className: "rfp-flex rfp-items-center rfp-justify-center", 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" }) }),
160
+ g && /* @__PURE__ */ i(se, { message: g }),
161
+ C && /* @__PURE__ */ i(
162
+ me.img,
163
+ {
164
+ ref: fe,
165
+ src: C,
166
+ alt: "Preview",
167
+ className: `rfp-max-w-none rfp-select-none ${!N || g || L ? "rfp-hidden" : ""}`,
168
+ style: {
169
+ transform: `translate(${j.x}px, ${j.y}px) scale(${_}) rotate(${ae}deg)`,
170
+ transformOrigin: "center",
171
+ transition: I ? "none" : "transform 0.3s ease-out"
172
+ },
173
+ onLoad: ie,
174
+ onError: le,
175
+ onDoubleClick: de,
176
+ initial: { opacity: 0 },
177
+ animate: { opacity: N && !g && !L ? 1 : 0 },
178
+ transition: { duration: 0.3 },
179
+ draggable: !1
180
+ }
181
+ ),
182
+ N && !g && p.width > 0 && /* @__PURE__ */ v("div", { className: "rfp-absolute rfp-bottom-2 rfp-right-3 rfp-text-[10px] rfp-text-fg-disabled hover:rfp-text-fg-secondary rfp-transition-colors rfp-pointer-events-auto rfp-select-none rfp-cursor-default", children: [
183
+ p.width,
184
+ " × ",
185
+ p.height,
186
+ b != null && ` · ${b < 1024 ? `${b} B` : b < 1024 * 1024 ? `${(b / 1024).toFixed(1)} KB` : `${(b / (1024 * 1024)).toFixed(1)} MB`}`
187
+ ] }),
188
+ U > 1 && /* @__PURE__ */ v("div", { className: "rfp-absolute rfp-bottom-2 rfp-left-1/2 -rfp-translate-x-1/2 rfp-flex rfp-items-center rfp-gap-2 rfp-px-3 rfp-py-1.5 rfp-bg-surface-toolbar rfp-border rfp-border-line rfp-rounded-lg rfp-text-sm rfp-text-fg-primary rfp-shadow-md", children: [
189
+ /* @__PURE__ */ i(
190
+ "button",
191
+ {
192
+ type: "button",
193
+ onClick: () => re(M - 1),
194
+ disabled: M <= 1 || O,
195
+ className: "rfp-px-2 rfp-py-0.5 rfp-rounded hover:rfp-bg-surface-nav-hover disabled:rfp-opacity-40 disabled:rfp-cursor-not-allowed",
196
+ children: "上一页"
197
+ }
198
+ ),
199
+ /* @__PURE__ */ v("span", { className: "rfp-text-fg-secondary rfp-tabular-nums", children: [
200
+ M,
201
+ " / ",
202
+ U
203
+ ] }),
204
+ /* @__PURE__ */ i(
205
+ "button",
206
+ {
207
+ type: "button",
208
+ onClick: () => re(M + 1),
209
+ disabled: M >= U || O,
210
+ className: "rfp-px-2 rfp-py-0.5 rfp-rounded hover:rfp-bg-surface-nav-hover disabled:rfp-opacity-40 disabled:rfp-cursor-not-allowed",
211
+ children: "下一页"
212
+ }
213
+ )
214
+ ] })
215
+ ]
216
+ }
217
+ );
218
+ };
219
+ export {
220
+ Ue as ImageRenderer
221
+ };
222
+ //# sourceMappingURL=index-BCuRRLYt.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-BCuRRLYt.mjs","sources":["../../src/renderers/Image/index.tsx"],"sourcesContent":["import { useState, useEffect, useRef, useCallback } from 'react';\nimport { motion } from 'framer-motion';\nimport { Loader2 } from 'lucide-react';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { detectImageFormat, getLoaderForMimeType } from '@eternalheart/file-preview-core';\nimport type { PreviewFile } from '@eternalheart/file-preview-core';\nimport { RendererError } from '../RendererError';\n\ninterface ImageRendererProps {\n url: string;\n zoom: number;\n rotation: number;\n resetKey?: number;\n fileSize?: number;\n file?: PreviewFile | File;\n onZoomChange?: (zoom: number) => void;\n onNaturalWidthChange?: (width: number) => void;\n onNaturalHeightChange?: (height: number) => void;\n}\n\nexport const ImageRenderer: React.FC<ImageRendererProps> = ({\n url,\n zoom,\n rotation,\n resetKey,\n fileSize,\n file,\n onZoomChange,\n onNaturalWidthChange,\n onNaturalHeightChange\n}) => {\n const t = useTranslator();\n const [loaded, setLoaded] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [decoding, setDecoding] = useState(false);\n const [decodeProgress, setDecodeProgress] = useState(0);\n const [decodeError, setDecodeError] = useState<string | null>(null);\n const [imageSrc, setImageSrc] = useState<string>('');\n const [currentPage, setCurrentPage] = useState(1);\n const [totalPages, setTotalPages] = useState(1);\n const [position, setPosition] = useState({ x: 0, y: 0 });\n const [isDragging, setIsDragging] = useState(false);\n const [dragStart, setDragStart] = useState({ x: 0, y: 0 });\n const [internalZoom, setInternalZoom] = useState(1);\n const [naturalSize, setNaturalSize] = useState({ width: 0, height: 0 });\n const imgRef = useRef<HTMLImageElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const blobUrlRef = useRef<string | null>(null);\n const fileBlobRef = useRef<Blob | null>(null);\n const loaderRef = useRef<any>(null);\n const pageCacheRef = useRef<Map<number, string>>(new Map());\n\n // 解码逻辑:检测格式并按需解码\n useEffect(() => {\n let cancelled = false;\n\n const decodeIfNeeded = async () => {\n // 重置状态:清空 src 以避免上一张图片的 onLoad/onError 误触发到新文件\n setImageSrc('');\n setLoaded(false);\n setError(null);\n setDecoding(false);\n setDecodeError(null);\n setDecodeProgress(0);\n setPosition({ x: 0, y: 0 });\n setInternalZoom(1);\n setCurrentPage(1);\n setTotalPages(1);\n\n // 清理旧的 blob URL 与缓存\n if (blobUrlRef.current) {\n URL.revokeObjectURL(blobUrlRef.current);\n blobUrlRef.current = null;\n }\n pageCacheRef.current.forEach((url) => URL.revokeObjectURL(url));\n pageCacheRef.current.clear();\n fileBlobRef.current = null;\n loaderRef.current = null;\n\n // 如果没有 file 对象,直接使用 url\n if (!file) {\n if (!cancelled) setImageSrc(url);\n return;\n }\n\n try {\n // 检测图片格式\n const mimeType = await detectImageFormat(file);\n const loader = await getLoaderForMimeType(mimeType);\n\n // 如果不需要解码,直接使用原 URL\n if (!loader || !(await loader.needsDecode(mimeType))) {\n if (!cancelled) setImageSrc(url);\n return;\n }\n\n // 需要解码\n setDecoding(true);\n\n // 获取文件 Blob\n let fileBlob: Blob;\n if (file instanceof Blob) {\n fileBlob = file;\n } else {\n const response = await fetch(url);\n if (!response.ok) throw new Error('Failed to fetch file');\n fileBlob = await response.blob();\n }\n\n if (cancelled) return;\n\n // 缓存 Blob 与 loader 以便后续翻页\n fileBlobRef.current = fileBlob;\n loaderRef.current = loader;\n\n // 缓存 Blob 与 loader 以便后续翻页\n fileBlobRef.current = fileBlob;\n loaderRef.current = loader;\n\n // 获取元数据(用于检测多页 TIFF)\n if (loader.getMetadata) {\n try {\n const metadata = await loader.getMetadata(fileBlob);\n if (!cancelled && metadata.pageCount && metadata.pageCount > 1) {\n setTotalPages(metadata.pageCount);\n }\n } catch {\n // 忽略元数据获取失败\n }\n }\n\n // 调用 loader 解码(第 1 页 / 缩略图模式)\n const decodedBlob = await loader.decode(fileBlob, {\n page: 1,\n fullQuality: false,\n onProgress: (percent: number) => {\n if (!cancelled) {\n setDecodeProgress(percent);\n }\n },\n });\n\n if (cancelled) return;\n\n // 生成 blob URL\n const blobUrl = typeof decodedBlob === 'string'\n ? decodedBlob\n : URL.createObjectURL(decodedBlob);\n\n blobUrlRef.current = blobUrl;\n pageCacheRef.current.set(1, blobUrl);\n setImageSrc(blobUrl);\n setDecoding(false);\n } catch (err: any) {\n if (!cancelled) {\n setDecodeError(err?.message || '解码失败');\n setDecoding(false);\n }\n }\n };\n\n decodeIfNeeded();\n\n return () => {\n cancelled = true;\n };\n }, [url, file]);\n\n // 多页 TIFF 翻页:切换页码时重新解码\n const handlePageChange = useCallback(async (page: number) => {\n if (!fileBlobRef.current || !loaderRef.current) return;\n if (page < 1 || page > totalPages) return;\n\n // 命中缓存:直接切换\n const cached = pageCacheRef.current.get(page);\n if (cached) {\n setCurrentPage(page);\n setImageSrc(cached);\n return;\n }\n\n // 解码新页面\n setDecoding(true);\n try {\n const decodedBlob = await loaderRef.current.decode(fileBlobRef.current, { page });\n const blobUrl = typeof decodedBlob === 'string'\n ? decodedBlob\n : URL.createObjectURL(decodedBlob);\n\n // LRU:缓存超过 10 页时删除最早的\n if (pageCacheRef.current.size >= 10) {\n const firstKey = pageCacheRef.current.keys().next().value;\n if (firstKey !== undefined) {\n const oldUrl = pageCacheRef.current.get(firstKey);\n if (oldUrl) URL.revokeObjectURL(oldUrl);\n pageCacheRef.current.delete(firstKey);\n }\n }\n\n pageCacheRef.current.set(page, blobUrl);\n setCurrentPage(page);\n setImageSrc(blobUrl);\n setDecoding(false);\n } catch (err: any) {\n setDecodeError(err?.message || '翻页解码失败');\n setDecoding(false);\n }\n }, [totalPages]);\n\n // Cleanup blob URL on unmount\n useEffect(() => {\n return () => {\n if (blobUrlRef.current) {\n URL.revokeObjectURL(blobUrlRef.current);\n }\n pageCacheRef.current.forEach((url) => URL.revokeObjectURL(url));\n pageCacheRef.current.clear();\n };\n }, []);\n\n // 当外部 zoom 改变时,同步内部 zoom\n useEffect(() => {\n setInternalZoom(zoom);\n }, [zoom]);\n\n // 适应窗口/原始尺寸等操作时重置位置居中\n useEffect(() => {\n if (resetKey !== undefined) {\n setPosition({ x: 0, y: 0 });\n }\n }, [resetKey]);\n\n const handleLoad = (e: React.SyntheticEvent<HTMLImageElement>) => {\n setLoaded(true);\n const img = e.currentTarget;\n setNaturalSize({ width: img.naturalWidth, height: img.naturalHeight });\n onNaturalWidthChange?.(img.naturalWidth);\n onNaturalHeightChange?.(img.naturalHeight);\n };\n\n // 边界限制:确保图片至少有一部分可见\n const clampPosition = useCallback((pos: { x: number; y: number }, currentZoom: number) => {\n const container = containerRef.current;\n if (!container || naturalSize.width === 0) return pos;\n\n const containerW = container.clientWidth;\n const containerH = container.clientHeight;\n const imgW = naturalSize.width * currentZoom;\n const imgH = naturalSize.height * currentZoom;\n\n // 至少保留 margin px 的图片在视口内\n const margin = Math.min(80, containerW * 0.15, containerH * 0.15);\n const rangeX = (containerW + imgW) / 2 - margin;\n const rangeY = (containerH + imgH) / 2 - margin;\n\n return {\n x: rangeX > 0 ? Math.max(-rangeX, Math.min(rangeX, pos.x)) : 0,\n y: rangeY > 0 ? Math.max(-rangeY, Math.min(rangeY, pos.y)) : 0,\n };\n }, [naturalSize]);\n\n const handleError = () => {\n setError(t('image.load_failed'));\n setLoaded(true);\n };\n\n // 双击复原:居中 + 缩放100%\n const handleDoubleClick = () => {\n setPosition({ x: 0, y: 0 });\n setInternalZoom(1);\n onZoomChange?.(1);\n };\n\n // 鼠标滚轮缩放 —— 以鼠标位置为缩放原点\n // 使用原生事件 + passive: false,确保 preventDefault 生效,\n // 避免滚轮事件冒泡触发外层(如嵌入模式下的页面滚动)\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handleWheelNative = (e: WheelEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const rect = container.getBoundingClientRect();\n const mouseX = e.clientX - rect.left - rect.width / 2;\n const mouseY = e.clientY - rect.top - rect.height / 2;\n\n const delta = e.deltaY > 0 ? -0.05 : 0.05;\n\n setInternalZoom(prev => {\n const newZoom = Math.max(0.01, Math.min(10, prev + delta));\n const scale = newZoom / prev;\n\n setPosition(pos => clampPosition({\n x: mouseX - scale * (mouseX - pos.x),\n y: mouseY - scale * (mouseY - pos.y),\n }, newZoom));\n\n onZoomChange?.(newZoom);\n return newZoom;\n });\n };\n\n container.addEventListener('wheel', handleWheelNative, { passive: false });\n return () => container.removeEventListener('wheel', handleWheelNative);\n }, [onZoomChange, clampPosition]);\n\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\n if (e.button !== 0) return;\n setIsDragging(true);\n setDragStart({\n x: e.clientX - position.x,\n y: e.clientY - position.y,\n });\n }, [position]);\n\n const handleMouseMove = useCallback((e: React.MouseEvent) => {\n if (!isDragging) return;\n setPosition(clampPosition({\n x: e.clientX - dragStart.x,\n y: e.clientY - dragStart.y,\n }, internalZoom));\n }, [isDragging, dragStart, internalZoom, clampPosition]);\n\n const handleMouseUp = useCallback(() => {\n setIsDragging(false);\n }, []);\n\n return (\n <div\n ref={containerRef}\n className=\"rfp-relative rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full rfp-overflow-hidden\"\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n style={{ cursor: isDragging ? 'grabbing' : 'grab' }}\n >\n {/* 解码中 */}\n {decoding && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-flex-col rfp-items-center rfp-justify-center rfp-bg-surface-1/80 rfp-z-10\">\n <Loader2 className=\"rfp-w-12 rfp-h-12 rfp-text-fg-primary rfp-animate-spin\" />\n <p className=\"rfp-mt-4 rfp-text-fg-secondary\">\n 正在解码... {decodeProgress > 0 && `${Math.round(decodeProgress)}%`}\n </p>\n </div>\n )}\n\n {/* 解码错误 */}\n {decodeError && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-1/80 rfp-z-10\">\n <RendererError message={t('image.decode_failed')} detail={decodeError} />\n </div>\n )}\n\n {!loaded && !error && !decoding && !decodeError && (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center\">\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 {error && (\n <RendererError message={error} />\n )}\n\n {imageSrc && (\n <motion.img\n ref={imgRef}\n src={imageSrc}\n alt=\"Preview\"\n className={`rfp-max-w-none rfp-select-none ${!loaded || error || decodeError ? 'rfp-hidden' : ''}`}\n style={{\n transform: `translate(${position.x}px, ${position.y}px) scale(${internalZoom}) rotate(${rotation}deg)`,\n transformOrigin: 'center',\n transition: isDragging ? 'none' : 'transform 0.3s ease-out',\n }}\n onLoad={handleLoad}\n onError={handleError}\n onDoubleClick={handleDoubleClick}\n initial={{ opacity: 0 }}\n animate={{ opacity: loaded && !error && !decodeError ? 1 : 0 }}\n transition={{ duration: 0.3 }}\n draggable={false}\n />\n )}\n\n {/* 右下角分辨率 */}\n {loaded && !error && naturalSize.width > 0 && (\n <div className=\"rfp-absolute rfp-bottom-2 rfp-right-3 rfp-text-[10px] rfp-text-fg-disabled hover:rfp-text-fg-secondary rfp-transition-colors rfp-pointer-events-auto rfp-select-none rfp-cursor-default\">\n {naturalSize.width} × {naturalSize.height}{fileSize != null && ` · ${fileSize < 1024 ? `${fileSize} B` : fileSize < 1024 * 1024 ? `${(fileSize / 1024).toFixed(1)} KB` : `${(fileSize / (1024 * 1024)).toFixed(1)} MB`}`}\n </div>\n )}\n\n {/* 多页 TIFF 翻页器 */}\n {totalPages > 1 && (\n <div className=\"rfp-absolute rfp-bottom-2 rfp-left-1/2 -rfp-translate-x-1/2 rfp-flex rfp-items-center rfp-gap-2 rfp-px-3 rfp-py-1.5 rfp-bg-surface-toolbar rfp-border rfp-border-line rfp-rounded-lg rfp-text-sm rfp-text-fg-primary rfp-shadow-md\">\n <button\n type=\"button\"\n onClick={() => handlePageChange(currentPage - 1)}\n disabled={currentPage <= 1 || decoding}\n className=\"rfp-px-2 rfp-py-0.5 rfp-rounded hover:rfp-bg-surface-nav-hover disabled:rfp-opacity-40 disabled:rfp-cursor-not-allowed\"\n >\n 上一页\n </button>\n <span className=\"rfp-text-fg-secondary rfp-tabular-nums\">\n {currentPage} / {totalPages}\n </span>\n <button\n type=\"button\"\n onClick={() => handlePageChange(currentPage + 1)}\n disabled={currentPage >= totalPages || decoding}\n className=\"rfp-px-2 rfp-py-0.5 rfp-rounded hover:rfp-bg-surface-nav-hover disabled:rfp-opacity-40 disabled:rfp-cursor-not-allowed\"\n >\n 下一页\n </button>\n </div>\n )}\n </div>\n );\n};\n"],"names":["ImageRenderer","url","zoom","rotation","resetKey","fileSize","file","onZoomChange","onNaturalWidthChange","onNaturalHeightChange","t","useTranslator","loaded","setLoaded","useState","error","setError","decoding","setDecoding","decodeProgress","setDecodeProgress","decodeError","setDecodeError","imageSrc","setImageSrc","currentPage","setCurrentPage","totalPages","setTotalPages","position","setPosition","isDragging","setIsDragging","dragStart","setDragStart","internalZoom","setInternalZoom","naturalSize","setNaturalSize","imgRef","useRef","containerRef","blobUrlRef","fileBlobRef","loaderRef","pageCacheRef","useEffect","cancelled","mimeType","detectImageFormat","loader","getLoaderForMimeType","fileBlob","response","metadata","decodedBlob","percent","blobUrl","err","handlePageChange","useCallback","page","cached","firstKey","oldUrl","handleLoad","img","clampPosition","pos","currentZoom","container","containerW","containerH","imgW","imgH","margin","rangeX","rangeY","handleError","handleDoubleClick","handleWheelNative","e","rect","mouseX","mouseY","delta","prev","newZoom","scale","handleMouseDown","handleMouseMove","handleMouseUp","jsxs","jsx","Loader2","RendererError","motion"],"mappings":"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"}