@eternalheart/vue-file-preview 1.3.11 → 1.3.13

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 (229) hide show
  1. package/README.md +27 -0
  2. package/README.zh-CN.md +27 -0
  3. package/lib/FilePreviewContent.vue.d.ts.map +1 -1
  4. package/lib/chunks/{index-DLPnWmJm.mjs → index-B2lqsdp7.mjs} +2 -2
  5. package/lib/chunks/{index-DLPnWmJm.mjs.map → index-B2lqsdp7.mjs.map} +1 -1
  6. package/lib/chunks/{index-hRgOoqVw.mjs → index-BHi1WRQZ.mjs} +2 -2
  7. package/lib/chunks/{index-hRgOoqVw.mjs.map → index-BHi1WRQZ.mjs.map} +1 -1
  8. package/lib/chunks/{index-BHPmd4HF.mjs → index-BTW1xwB9.mjs} +2 -2
  9. package/lib/chunks/{index-BHPmd4HF.mjs.map → index-BTW1xwB9.mjs.map} +1 -1
  10. package/lib/chunks/{index-C0vSFXmh.mjs → index-BvegaxQF.mjs} +2 -2
  11. package/lib/chunks/{index-C0vSFXmh.mjs.map → index-BvegaxQF.mjs.map} +1 -1
  12. package/lib/chunks/{index-C65zV1vs.mjs → index-CYt6tpQC.mjs} +2 -2
  13. package/lib/chunks/{index-C65zV1vs.mjs.map → index-CYt6tpQC.mjs.map} +1 -1
  14. package/lib/chunks/{index-t1Plo3ud.mjs → index-Cjnw238n.mjs} +2 -2
  15. package/lib/chunks/{index-t1Plo3ud.mjs.map → index-Cjnw238n.mjs.map} +1 -1
  16. package/lib/chunks/{index-BT-U9HYI.mjs → index-Ctd0JQ6K.mjs} +2 -2
  17. package/lib/chunks/{index-BT-U9HYI.mjs.map → index-Ctd0JQ6K.mjs.map} +1 -1
  18. package/lib/chunks/index-CyrFxdIJ.mjs +318 -0
  19. package/lib/chunks/index-CyrFxdIJ.mjs.map +1 -0
  20. package/lib/chunks/{index-Cu1up6RM.mjs → index-DBw8tvyb.mjs} +2 -2
  21. package/lib/chunks/{index-Cu1up6RM.mjs.map → index-DBw8tvyb.mjs.map} +1 -1
  22. package/lib/chunks/{index-BKu5DkdG.mjs → index-DEoR7aDN.mjs} +2 -2
  23. package/lib/chunks/{index-BKu5DkdG.mjs.map → index-DEoR7aDN.mjs.map} +1 -1
  24. package/lib/chunks/{index-CMgtGmRN.mjs → index-DIe0vHlt.mjs} +9 -9
  25. package/lib/chunks/{index-CMgtGmRN.mjs.map → index-DIe0vHlt.mjs.map} +1 -1
  26. package/lib/chunks/index-DT9dPz8I.mjs +279 -0
  27. package/lib/chunks/index-DT9dPz8I.mjs.map +1 -0
  28. package/lib/chunks/{index-B9RAbllH.mjs → index-DTtHrdBl.mjs} +6 -6
  29. package/lib/chunks/{index-B9RAbllH.mjs.map → index-DTtHrdBl.mjs.map} +1 -1
  30. package/lib/chunks/{index-Dln8hyPZ.mjs → index-DX_NBPzS.mjs} +2 -2
  31. package/lib/chunks/{index-Dln8hyPZ.mjs.map → index-DX_NBPzS.mjs.map} +1 -1
  32. package/lib/chunks/{index-BA-SUKkf.mjs → index-Dw1U4YqT.mjs} +2 -2
  33. package/lib/chunks/{index-BA-SUKkf.mjs.map → index-Dw1U4YqT.mjs.map} +1 -1
  34. package/lib/chunks/{index-DNFQFaF3.mjs → index-DyipSoKh.mjs} +2 -2
  35. package/lib/chunks/{index-DNFQFaF3.mjs.map → index-DyipSoKh.mjs.map} +1 -1
  36. package/lib/chunks/{index-B3-ezDVJ.mjs → index-GGGDPwxX.mjs} +2 -2
  37. package/lib/chunks/{index-B3-ezDVJ.mjs.map → index-GGGDPwxX.mjs.map} +1 -1
  38. package/lib/chunks/{index-CQFN4h-t.mjs → index-Oxwizt6-.mjs} +609 -581
  39. package/lib/chunks/index-Oxwizt6-.mjs.map +1 -0
  40. package/lib/chunks/{index-CY2vJrBJ.mjs → index-Zwl5J-Uw.mjs} +2 -2
  41. package/lib/chunks/{index-CY2vJrBJ.mjs.map → index-Zwl5J-Uw.mjs.map} +1 -1
  42. package/lib/components/NavArrows.vue.d.ts +17 -0
  43. package/lib/components/NavArrows.vue.d.ts.map +1 -0
  44. package/lib/components/ResizableSplit.vue.d.ts +17 -2
  45. package/lib/components/ResizableSplit.vue.d.ts.map +1 -1
  46. package/lib/index.cjs +32 -32
  47. package/lib/index.cjs.map +1 -1
  48. package/lib/index.css +1 -1
  49. package/lib/index.mjs +1 -1
  50. package/lib/renderers/Image/index.vue.d.ts.map +1 -1
  51. package/lib/renderers/Text/index.vue.d.ts.map +1 -1
  52. package/lib/renderers/Xml/index.vue.d.ts.map +1 -1
  53. package/lib/renderers/Zip/index.vue.d.ts.map +1 -1
  54. package/package.json +1 -1
  55. package/lib/chunks/index-CQFN4h-t.mjs.map +0 -1
  56. package/lib/chunks/index-ijv9F2cZ.mjs +0 -280
  57. package/lib/chunks/index-ijv9F2cZ.mjs.map +0 -1
  58. package/lib/chunks/index-y7gaKu36.mjs +0 -234
  59. package/lib/chunks/index-y7gaKu36.mjs.map +0 -1
  60. package/lib/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
  61. package/lib/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
  62. package/lib/pdfjs/cmaps/78-H.bcmap +0 -0
  63. package/lib/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
  64. package/lib/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
  65. package/lib/pdfjs/cmaps/78-V.bcmap +0 -0
  66. package/lib/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
  67. package/lib/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
  68. package/lib/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
  69. package/lib/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
  70. package/lib/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
  71. package/lib/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
  72. package/lib/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
  73. package/lib/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
  74. package/lib/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
  75. package/lib/pdfjs/cmaps/Add-H.bcmap +0 -0
  76. package/lib/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
  77. package/lib/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
  78. package/lib/pdfjs/cmaps/Add-V.bcmap +0 -0
  79. package/lib/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
  80. package/lib/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
  81. package/lib/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
  82. package/lib/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
  83. package/lib/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
  84. package/lib/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
  85. package/lib/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
  86. package/lib/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
  87. package/lib/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
  88. package/lib/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
  89. package/lib/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
  90. package/lib/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
  91. package/lib/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
  92. package/lib/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
  93. package/lib/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
  94. package/lib/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
  95. package/lib/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
  96. package/lib/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
  97. package/lib/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
  98. package/lib/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
  99. package/lib/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
  100. package/lib/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
  101. package/lib/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
  102. package/lib/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
  103. package/lib/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
  104. package/lib/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
  105. package/lib/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
  106. package/lib/pdfjs/cmaps/B5-H.bcmap +0 -0
  107. package/lib/pdfjs/cmaps/B5-V.bcmap +0 -0
  108. package/lib/pdfjs/cmaps/B5pc-H.bcmap +0 -0
  109. package/lib/pdfjs/cmaps/B5pc-V.bcmap +0 -0
  110. package/lib/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
  111. package/lib/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
  112. package/lib/pdfjs/cmaps/CNS1-H.bcmap +0 -0
  113. package/lib/pdfjs/cmaps/CNS1-V.bcmap +0 -0
  114. package/lib/pdfjs/cmaps/CNS2-H.bcmap +0 -0
  115. package/lib/pdfjs/cmaps/CNS2-V.bcmap +0 -3
  116. package/lib/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
  117. package/lib/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
  118. package/lib/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
  119. package/lib/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
  120. package/lib/pdfjs/cmaps/ETenms-B5-H.bcmap +0 -3
  121. package/lib/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
  122. package/lib/pdfjs/cmaps/EUC-H.bcmap +0 -0
  123. package/lib/pdfjs/cmaps/EUC-V.bcmap +0 -0
  124. package/lib/pdfjs/cmaps/Ext-H.bcmap +0 -0
  125. package/lib/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
  126. package/lib/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
  127. package/lib/pdfjs/cmaps/Ext-V.bcmap +0 -0
  128. package/lib/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
  129. package/lib/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
  130. package/lib/pdfjs/cmaps/GB-H.bcmap +0 -4
  131. package/lib/pdfjs/cmaps/GB-V.bcmap +0 -0
  132. package/lib/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
  133. package/lib/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
  134. package/lib/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
  135. package/lib/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
  136. package/lib/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
  137. package/lib/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
  138. package/lib/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
  139. package/lib/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
  140. package/lib/pdfjs/cmaps/GBT-H.bcmap +0 -0
  141. package/lib/pdfjs/cmaps/GBT-V.bcmap +0 -0
  142. package/lib/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
  143. package/lib/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
  144. package/lib/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
  145. package/lib/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
  146. package/lib/pdfjs/cmaps/H.bcmap +0 -0
  147. package/lib/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
  148. package/lib/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
  149. package/lib/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
  150. package/lib/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
  151. package/lib/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
  152. package/lib/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
  153. package/lib/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
  154. package/lib/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
  155. package/lib/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
  156. package/lib/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
  157. package/lib/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
  158. package/lib/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
  159. package/lib/pdfjs/cmaps/Hankaku.bcmap +0 -0
  160. package/lib/pdfjs/cmaps/Hiragana.bcmap +0 -0
  161. package/lib/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
  162. package/lib/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
  163. package/lib/pdfjs/cmaps/KSC-H.bcmap +0 -0
  164. package/lib/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
  165. package/lib/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
  166. package/lib/pdfjs/cmaps/KSC-V.bcmap +0 -0
  167. package/lib/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
  168. package/lib/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
  169. package/lib/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
  170. package/lib/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
  171. package/lib/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
  172. package/lib/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
  173. package/lib/pdfjs/cmaps/Katakana.bcmap +0 -0
  174. package/lib/pdfjs/cmaps/LICENSE +0 -36
  175. package/lib/pdfjs/cmaps/NWP-H.bcmap +0 -0
  176. package/lib/pdfjs/cmaps/NWP-V.bcmap +0 -0
  177. package/lib/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
  178. package/lib/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
  179. package/lib/pdfjs/cmaps/Roman.bcmap +0 -0
  180. package/lib/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
  181. package/lib/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
  182. package/lib/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
  183. package/lib/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
  184. package/lib/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
  185. package/lib/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
  186. package/lib/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
  187. package/lib/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
  188. package/lib/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
  189. package/lib/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
  190. package/lib/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
  191. package/lib/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
  192. package/lib/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
  193. package/lib/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
  194. package/lib/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
  195. package/lib/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
  196. package/lib/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
  197. package/lib/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
  198. package/lib/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
  199. package/lib/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
  200. package/lib/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
  201. package/lib/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
  202. package/lib/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
  203. package/lib/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
  204. package/lib/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
  205. package/lib/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
  206. package/lib/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
  207. package/lib/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
  208. package/lib/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
  209. package/lib/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
  210. package/lib/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
  211. package/lib/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
  212. package/lib/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
  213. package/lib/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
  214. package/lib/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
  215. package/lib/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
  216. package/lib/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
  217. package/lib/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
  218. package/lib/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
  219. package/lib/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
  220. package/lib/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
  221. package/lib/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
  222. package/lib/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
  223. package/lib/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
  224. package/lib/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
  225. package/lib/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
  226. package/lib/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
  227. package/lib/pdfjs/cmaps/V.bcmap +0 -0
  228. package/lib/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
  229. package/lib/pdfjs/pdf.worker.min.mjs +0 -21
@@ -1,280 +0,0 @@
1
- import { defineComponent as U, ref as u, computed as S, onMounted as Y, onBeforeUnmount as _, watch as F, openBlock as s, createElementBlock as c, createElementVNode as p, normalizeStyle as E, renderSlot as B, normalizeClass as T, resolveComponent as ee, createVNode as W, unref as C, createBlock as R, resolveDynamicComponent as K, toDisplayString as D, Fragment as I, renderList as O, createCommentVNode as P, defineAsyncComponent as te, withCtx as N, Teleport as ne } from "vue";
2
- import { _ as A, F as le, C as oe, u as se, a as ae, d as H, j as ie, D as re, A as fe, R as ve } from "./index-CQFN4h-t.mjs";
3
- import { FileImage as de, FileText as ue, FileCode as pe, File as ce, ChevronRight as me, FolderOpen as he, Folder as we } from "lucide-vue-next";
4
- import { _ as ye } from "./RendererError.vue_vue_type_script_setup_true_lang-CbgZBSDr.mjs";
5
- const xe = { class: "vfp-flex-1 vfp-min-w-0 vfp-min-h-0 vfp-overflow-hidden" }, ge = /* @__PURE__ */ U({
6
- name: "ResizableSplit",
7
- __name: "ResizableSplit",
8
- props: {
9
- initialLeftWidth: { default: 280 },
10
- minLeftWidth: { default: 160 },
11
- maxLeftWidth: { default: 640 },
12
- minRightWidth: { default: 200 },
13
- storageKey: {},
14
- desktopMedia: { default: "(min-width: 768px)" }
15
- },
16
- setup(a) {
17
- const r = a, f = u(null), i = u(
18
- (() => {
19
- if (r.storageKey && typeof window < "u") {
20
- const t = Number(window.localStorage.getItem(r.storageKey));
21
- if (!isNaN(t) && t > 0) return t;
22
- }
23
- return r.initialLeftWidth;
24
- })()
25
- ), m = u(!1), b = u(!1);
26
- let h = null;
27
- const k = () => {
28
- h && (b.value = h.matches);
29
- }, w = S(
30
- () => b.value ? { width: `${i.value}px` } : void 0
31
- ), y = (t) => {
32
- if (!f.value) return;
33
- const v = f.value.getBoundingClientRect(), d = t.clientX - v.left, x = v.width - r.minRightWidth - 6, M = Math.min(r.maxLeftWidth, x);
34
- i.value = Math.max(
35
- r.minLeftWidth,
36
- Math.min(M, d)
37
- );
38
- }, o = () => {
39
- if (m.value && (m.value = !1, window.removeEventListener("mousemove", y), window.removeEventListener("mouseup", o), document.body.style.cursor = "", document.body.style.userSelect = "", r.storageKey))
40
- try {
41
- window.localStorage.setItem(r.storageKey, String(i.value));
42
- } catch {
43
- }
44
- }, n = (t) => {
45
- t.preventDefault(), m.value = !0, window.addEventListener("mousemove", y), window.addEventListener("mouseup", o), document.body.style.cursor = "col-resize", document.body.style.userSelect = "none";
46
- };
47
- return Y(() => {
48
- typeof window < "u" && (h = window.matchMedia(r.desktopMedia), k(), h.addEventListener("change", k));
49
- }), _(() => {
50
- h && h.removeEventListener("change", k), window.removeEventListener("mousemove", y), window.removeEventListener("mouseup", o), m.value && (document.body.style.cursor = "", document.body.style.userSelect = "");
51
- }), F(
52
- () => r.initialLeftWidth,
53
- (t) => {
54
- r.storageKey || (i.value = t);
55
- }
56
- ), (t, v) => (s(), c("div", {
57
- ref_key: "containerRef",
58
- ref: f,
59
- class: "vfp-w-full vfp-h-full vfp-flex vfp-flex-col md:vfp-flex-row vfp-min-h-0 vfp-min-w-0"
60
- }, [
61
- p("div", {
62
- class: "vfp-min-h-0 vfp-min-w-0 vfp-flex-shrink-0 vfp-w-full vfp-max-h-60 md:vfp-h-full md:vfp-max-h-none",
63
- style: E(w.value)
64
- }, [
65
- B(t.$slots, "left", {}, void 0, !0)
66
- ], 4),
67
- p("div", {
68
- role: "separator",
69
- "aria-orientation": "vertical",
70
- class: T(["split-divider vfp-hidden md:vfp-block vfp-relative vfp-w-1.5 vfp-flex-shrink-0 vfp-cursor-col-resize vfp-transition-colors", m.value ? "dragging" : ""]),
71
- onMousedown: n
72
- }, [...v[0] || (v[0] = [
73
- p("span", { class: "vfp-absolute vfp-inset-y-0 hit-area" }, null, -1)
74
- ])], 34),
75
- p("div", xe, [
76
- B(t.$slots, "right", {}, void 0, !0)
77
- ])
78
- ], 512));
79
- }
80
- }), be = /* @__PURE__ */ A(ge, [["__scopeId", "data-v-790c366f"]]), ke = { key: 0 }, Le = { class: "vfp-truncate vfp-flex-1 vfp-min-w-0" }, ze = { class: "vfp-flex-1 vfp-truncate vfp-min-w-0" }, Se = { class: "vfp-text-xs vfp-text-fg-disabled vfp-flex-shrink-0 vfp-ml-2" }, Ce = { name: "ZipTreeItem" }, Re = /* @__PURE__ */ U({
81
- ...Ce,
82
- props: {
83
- node: {},
84
- depth: {},
85
- selectedPath: {},
86
- expanded: {}
87
- },
88
- emits: ["toggle", "select", "hover", "leave"],
89
- setup(a, { emit: r }) {
90
- const f = a, i = r, m = S(() => ({ paddingLeft: `${f.depth * 14 + 10}px` })), b = S(() => f.expanded.has(f.node.path)), h = S(() => f.selectedPath === f.node.path), k = S(() => {
91
- const o = le({ name: f.node.name, type: "" });
92
- return o === "image" ? de : o === "text" || o === "markdown" || o === "json" || o === "csv" || o === "xml" || o === "subtitle" ? f.node.name.endsWith(".md") || f.node.name.endsWith(".markdown") ? ue : pe : ce;
93
- }), w = (o) => {
94
- const n = o.currentTarget.getBoundingClientRect();
95
- i("hover", f.node.name || "/", n);
96
- }, y = () => i("leave");
97
- return (o, n) => {
98
- const t = ee("ZipTreeItem");
99
- return a.node.isDir ? (s(), c("div", ke, [
100
- p("button", {
101
- type: "button",
102
- class: "tree-row dir-row",
103
- style: E(m.value),
104
- onClick: n[0] || (n[0] = (v) => i("toggle", a.node.path)),
105
- onMouseenter: w,
106
- onMouseleave: y
107
- }, [
108
- W(C(me), {
109
- class: T(["vfp-w-3.5 vfp-h-3.5 vfp-flex-shrink-0 vfp-transition-transform", { "vfp-rotate-90": b.value }])
110
- }, null, 8, ["class"]),
111
- (s(), R(K(b.value ? C(he) : C(we)), { class: "vfp-w-4 vfp-h-4 vfp-flex-shrink-0 vfp-text-amber-300/80" })),
112
- p("span", Le, D(a.node.name || "/"), 1)
113
- ], 36),
114
- b.value && a.node.children ? (s(!0), c(I, { key: 0 }, O(a.node.children, (v) => (s(), R(t, {
115
- key: v.path,
116
- node: v,
117
- depth: a.depth + 1,
118
- "selected-path": a.selectedPath,
119
- expanded: a.expanded,
120
- onToggle: n[1] || (n[1] = (d) => i("toggle", d)),
121
- onSelect: n[2] || (n[2] = (d) => i("select", d)),
122
- onHover: n[3] || (n[3] = (d, x) => i("hover", d, x)),
123
- onLeave: n[4] || (n[4] = (d) => i("leave"))
124
- }, null, 8, ["node", "depth", "selected-path", "expanded"]))), 128)) : P("", !0)
125
- ])) : (s(), c("button", {
126
- key: 1,
127
- type: "button",
128
- class: T(["tree-row file-row", { selected: h.value }]),
129
- style: E(m.value),
130
- onClick: n[5] || (n[5] = (v) => i("select", a.node)),
131
- onMouseenter: w,
132
- onMouseleave: y
133
- }, [
134
- n[6] || (n[6] = p("span", { class: "vfp-w-3.5 vfp-h-3.5 vfp-flex-shrink-0" }, null, -1)),
135
- (s(), R(K(k.value), { class: "vfp-w-4 vfp-h-4 vfp-flex-shrink-0 vfp-text-fg-tertiary" })),
136
- p("span", ze, D(a.node.name), 1),
137
- p("span", Se, D(C(oe)(a.node.size)), 1)
138
- ], 38));
139
- };
140
- }
141
- }), Me = /* @__PURE__ */ A(Re, [["__scopeId", "data-v-c8c0f0ee"]]), $e = {
142
- key: 0,
143
- class: "vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full"
144
- }, De = { class: "vfp-w-full vfp-h-full vfp-overflow-auto" }, Ee = { class: "vfp-w-full vfp-h-full vfp-flex vfp-flex-col" }, _e = {
145
- key: 0,
146
- class: "vfp-flex-1 vfp-flex vfp-items-center vfp-justify-center vfp-text-fg-muted vfp-text-sm vfp-p-6"
147
- }, Fe = {
148
- key: 1,
149
- class: "vfp-flex-1 vfp-flex vfp-items-center vfp-justify-center"
150
- }, Te = {
151
- key: 2,
152
- class: "vfp-flex-1 vfp-flex vfp-items-center vfp-justify-center vfp-text-fg-secondary"
153
- }, We = {
154
- key: 3,
155
- class: "vfp-flex-1 vfp-min-h-0 vfp-overflow-hidden vfp-flex vfp-relative vfp-z-0"
156
- }, Ke = /* @__PURE__ */ U({
157
- __name: "index",
158
- props: {
159
- url: {},
160
- nestingDepth: { default: 0 }
161
- },
162
- emits: ["statsChange"],
163
- setup(a, { emit: r }) {
164
- const f = te(
165
- () => import("./index-CQFN4h-t.mjs").then((e) => e.i)
166
- ), i = a, m = r, { t: b } = se(), h = ae(), k = u(null), w = u(null), y = u(!0), o = u(null), n = u(/* @__PURE__ */ new Set([""])), t = u(null), v = u(!1), d = u(null), x = u(null), M = () => {
167
- var e;
168
- (e = t.value) != null && e.blobUrl && URL.revokeObjectURL(t.value.blobUrl);
169
- }, V = async () => {
170
- M(), t.value = null, y.value = !0, o.value = null;
171
- try {
172
- const e = await h.value(i.url);
173
- if (!e.ok) throw new Error("加载失败");
174
- const l = await e.arrayBuffer(), g = await ie(l), L = re(g), z = fe(L);
175
- k.value = g, w.value = z;
176
- const $ = /* @__PURE__ */ new Set([""]);
177
- if (z.children)
178
- for (const j of z.children) j.isDir && $.add(j.path);
179
- n.value = $;
180
- } catch (e) {
181
- console.error(e), o.value = b.value("zip.load_failed");
182
- } finally {
183
- y.value = !1;
184
- }
185
- };
186
- F(() => i.url, (e) => {
187
- e && V();
188
- }, { immediate: !0 }), _(() => {
189
- M();
190
- });
191
- const Z = S(() => {
192
- if (!w.value) return null;
193
- let e = 0, l = 0, g = 0;
194
- const L = (z) => {
195
- var $;
196
- z.isDir ? (z.path && l++, ($ = z.children) == null || $.forEach(L)) : (e++, g += z.size);
197
- };
198
- return L(w.value), { files: e, dirs: l, size: g };
199
- });
200
- F(Z, (e) => m("statsChange", e), { immediate: !0 }), _(() => m("statsChange", null));
201
- const q = (e) => {
202
- const l = new Set(n.value);
203
- l.has(e) ? l.delete(e) : l.add(e), n.value = l;
204
- }, X = (e, l) => {
205
- x.value = { text: e, x: l.right + 8, y: l.top + l.height / 2 };
206
- }, G = () => {
207
- x.value = null;
208
- }, J = async (e) => {
209
- if (!(!k.value || e.isDir)) {
210
- M(), v.value = !0, d.value = null;
211
- try {
212
- const l = H(e.name), g = await ve(k.value, e.path, l !== "application/octet-stream" ? l : void 0), L = URL.createObjectURL(g);
213
- t.value = { path: e.path, name: e.name, size: e.size, blobUrl: L };
214
- } catch (l) {
215
- console.error(l), d.value = "条目读取失败";
216
- } finally {
217
- v.value = !1;
218
- }
219
- }
220
- }, Q = S(() => t.value ? [{ name: t.value.name, url: t.value.blobUrl, type: H(t.value.name) }] : []);
221
- return (e, l) => y.value ? (s(), c("div", $e, [...l[0] || (l[0] = [
222
- p("div", { class: "vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin" }, null, -1)
223
- ])])) : o.value || !w.value ? (s(), R(ye, {
224
- key: 1,
225
- message: o.value || C(b)("zip.parse_failed")
226
- }, null, 8, ["message"])) : (s(), c(I, { key: 2 }, [
227
- W(be, {
228
- "initial-left-width": 280,
229
- "min-left-width": 180,
230
- "max-left-width": 560,
231
- "storage-key": "vfp-zip-split-left"
232
- }, {
233
- left: N(() => [
234
- p("div", De, [
235
- (s(!0), c(I, null, O(w.value.children || [], (g) => {
236
- var L;
237
- return s(), R(Me, {
238
- key: g.path,
239
- node: g,
240
- depth: 0,
241
- "selected-path": ((L = t.value) == null ? void 0 : L.path) ?? null,
242
- expanded: n.value,
243
- onToggle: q,
244
- onSelect: J,
245
- onHover: X,
246
- onLeave: G
247
- }, null, 8, ["node", "selected-path", "expanded"]);
248
- }), 128))
249
- ])
250
- ]),
251
- right: N(() => [
252
- p("div", Ee, [
253
- t.value ? v.value ? (s(), c("div", Fe, [...l[1] || (l[1] = [
254
- p("div", { class: "vfp-w-8 vfp-h-8 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin" }, null, -1)
255
- ])])) : d.value ? (s(), c("div", Te, D(d.value), 1)) : (s(), c("div", We, [
256
- W(C(f), {
257
- mode: "embed",
258
- files: Q.value,
259
- "current-index": 0,
260
- "zip-nesting-depth": a.nestingDepth + 1
261
- }, null, 8, ["files", "zip-nesting-depth"])
262
- ])) : (s(), c("div", _e, " 从左侧选择一个文件以预览 "))
263
- ])
264
- ]),
265
- _: 1
266
- }),
267
- (s(), R(ne, { to: "body" }, [
268
- x.value ? (s(), c("div", {
269
- key: 0,
270
- class: "vfp-zip-tip",
271
- style: E({ left: x.value.x + "px", top: x.value.y + "px" })
272
- }, D(x.value.text), 5)) : P("", !0)
273
- ]))
274
- ], 64));
275
- }
276
- });
277
- export {
278
- Ke as default
279
- };
280
- //# sourceMappingURL=index-ijv9F2cZ.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-ijv9F2cZ.mjs","sources":["../../src/components/ResizableSplit.vue","../../src/renderers/Zip/TreeItem.vue","../../src/renderers/Zip/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, onBeforeUnmount, onMounted, watch } from 'vue';\n\ninterface Props {\n /** 左侧初始宽度(px);传入 storageKey 时会从 localStorage 读取 */\n initialLeftWidth?: number;\n /** 左侧最小宽度(px) */\n minLeftWidth?: number;\n /** 左侧最大宽度(px) */\n maxLeftWidth?: number;\n /** 右侧至少保留的宽度(px) */\n minRightWidth?: number;\n /** localStorage 持久化 key */\n storageKey?: string;\n /** 启用横向拖动的媒体查询 */\n desktopMedia?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n initialLeftWidth: 280,\n minLeftWidth: 160,\n maxLeftWidth: 640,\n minRightWidth: 200,\n desktopMedia: '(min-width: 768px)',\n});\n\ndefineOptions({ name: 'ResizableSplit' });\n\nconst containerRef = ref<HTMLDivElement | null>(null);\nconst leftWidth = ref<number>(\n (() => {\n if (props.storageKey && typeof window !== 'undefined') {\n const saved = Number(window.localStorage.getItem(props.storageKey));\n if (!isNaN(saved) && saved > 0) return saved;\n }\n return props.initialLeftWidth;\n })()\n);\nconst dragging = ref(false);\nconst isDesktop = ref(false);\n\nlet mq: MediaQueryList | null = null;\nconst mqHandler = () => {\n if (mq) isDesktop.value = mq.matches;\n};\n\nconst leftStyle = computed(() =>\n isDesktop.value ? { width: `${leftWidth.value}px` } : undefined\n);\n\nconst onMove = (e: MouseEvent) => {\n if (!containerRef.value) return;\n const rect = containerRef.value.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const cap = rect.width - props.minRightWidth - 6;\n const effectiveMax = Math.min(props.maxLeftWidth, cap);\n leftWidth.value = Math.max(\n props.minLeftWidth,\n Math.min(effectiveMax, x)\n );\n};\n\nconst onUp = () => {\n if (!dragging.value) return;\n dragging.value = false;\n window.removeEventListener('mousemove', onMove);\n window.removeEventListener('mouseup', onUp);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n if (props.storageKey) {\n try {\n window.localStorage.setItem(props.storageKey, String(leftWidth.value));\n } catch {\n // ignore\n }\n }\n};\n\nconst onDividerDown = (e: MouseEvent) => {\n e.preventDefault();\n dragging.value = true;\n window.addEventListener('mousemove', onMove);\n window.addEventListener('mouseup', onUp);\n document.body.style.cursor = 'col-resize';\n document.body.style.userSelect = 'none';\n};\n\nonMounted(() => {\n if (typeof window !== 'undefined') {\n mq = window.matchMedia(props.desktopMedia);\n mqHandler();\n mq.addEventListener('change', mqHandler);\n }\n});\n\nonBeforeUnmount(() => {\n if (mq) mq.removeEventListener('change', mqHandler);\n window.removeEventListener('mousemove', onMove);\n window.removeEventListener('mouseup', onUp);\n if (dragging.value) {\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n }\n});\n\nwatch(\n () => props.initialLeftWidth,\n (w) => {\n if (!props.storageKey) leftWidth.value = w;\n }\n);\n</script>\n\n<template>\n <div\n ref=\"containerRef\"\n class=\"vfp-w-full vfp-h-full vfp-flex vfp-flex-col md:vfp-flex-row vfp-min-h-0 vfp-min-w-0\"\n >\n <div\n class=\"vfp-min-h-0 vfp-min-w-0 vfp-flex-shrink-0 vfp-w-full vfp-max-h-60 md:vfp-h-full md:vfp-max-h-none\"\n :style=\"leftStyle\"\n >\n <slot name=\"left\" />\n </div>\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n class=\"split-divider vfp-hidden md:vfp-block vfp-relative vfp-w-1.5 vfp-flex-shrink-0 vfp-cursor-col-resize vfp-transition-colors\"\n :class=\"dragging ? 'dragging' : ''\"\n @mousedown=\"onDividerDown\"\n >\n <span class=\"vfp-absolute vfp-inset-y-0 hit-area\" />\n </div>\n <div class=\"vfp-flex-1 vfp-min-w-0 vfp-min-h-0 vfp-overflow-hidden\">\n <slot name=\"right\" />\n </div>\n </div>\n</template>\n\n<style scoped>\n.split-divider {\n background: rgba(255, 255, 255, 0.1);\n}\n.split-divider:hover {\n background: rgba(255, 255, 255, 0.3);\n}\n.split-divider.dragging {\n background: rgba(255, 255, 255, 0.4);\n}\n.hit-area {\n left: -4px;\n right: -4px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport {\n Folder,\n FolderOpen,\n FileText,\n FileImage,\n FileCode,\n File as FileIcon,\n ChevronRight,\n} from 'lucide-vue-next';\nimport { formatFileSize, getFileType, type ZipTreeNode } from '@eternalheart/file-preview-core';\n\nconst props = defineProps<{\n node: ZipTreeNode;\n depth: number;\n selectedPath: string | null;\n expanded: Set<string>;\n}>();\n\nconst emit = defineEmits<{\n (e: 'toggle', path: string): void;\n (e: 'select', node: ZipTreeNode): void;\n (e: 'hover', text: string, rect: DOMRect): void;\n (e: 'leave'): void;\n}>();\n\nconst padStyle = computed(() => ({ paddingLeft: `${props.depth * 14 + 10}px` }));\nconst isOpen = computed(() => props.expanded.has(props.node.path));\nconst isSelected = computed(() => props.selectedPath === props.node.path);\n\nconst fileIcon = computed(() => {\n const ft = getFileType({ id: '', name: props.node.name, url: '', type: '' });\n if (ft === 'image') return FileImage;\n if (ft === 'text' || ft === 'markdown' || ft === 'json' || ft === 'csv' || ft === 'xml' || ft === 'subtitle') {\n return (props.node.name.endsWith('.md') || props.node.name.endsWith('.markdown')) ? FileText : FileCode;\n }\n return FileIcon;\n});\n\nconst handleEnter = (e: MouseEvent) => {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n emit('hover', props.node.name || '/', rect);\n};\n\nconst handleLeave = () => emit('leave');\n</script>\n\n<template>\n <div v-if=\"node.isDir\">\n <button\n type=\"button\"\n class=\"tree-row dir-row\"\n :style=\"padStyle\"\n @click=\"emit('toggle', node.path)\"\n @mouseenter=\"handleEnter\"\n @mouseleave=\"handleLeave\"\n >\n <ChevronRight\n class=\"vfp-w-3.5 vfp-h-3.5 vfp-flex-shrink-0 vfp-transition-transform\"\n :class=\"{ 'vfp-rotate-90': isOpen }\"\n />\n <component\n :is=\"isOpen ? FolderOpen : Folder\"\n class=\"vfp-w-4 vfp-h-4 vfp-flex-shrink-0 vfp-text-amber-300/80\"\n />\n <span class=\"vfp-truncate vfp-flex-1 vfp-min-w-0\">{{ node.name || '/' }}</span>\n </button>\n <template v-if=\"isOpen && node.children\">\n <ZipTreeItem\n v-for=\"child in node.children\"\n :key=\"child.path\"\n :node=\"child\"\n :depth=\"depth + 1\"\n :selected-path=\"selectedPath\"\n :expanded=\"expanded\"\n @toggle=\"(p) => emit('toggle', p)\"\n @select=\"(n) => emit('select', n)\"\n @hover=\"(t, r) => emit('hover', t, r)\"\n @leave=\"emit('leave')\"\n />\n </template>\n </div>\n <button\n v-else\n type=\"button\"\n class=\"tree-row file-row\"\n :class=\"{ selected: isSelected }\"\n :style=\"padStyle\"\n @click=\"emit('select', node)\"\n @mouseenter=\"handleEnter\"\n @mouseleave=\"handleLeave\"\n >\n <span class=\"vfp-w-3.5 vfp-h-3.5 vfp-flex-shrink-0\" />\n <component :is=\"fileIcon\" class=\"vfp-w-4 vfp-h-4 vfp-flex-shrink-0 vfp-text-fg-tertiary\" />\n <span class=\"vfp-flex-1 vfp-truncate vfp-min-w-0\">{{ node.name }}</span>\n <span class=\"vfp-text-xs vfp-text-fg-disabled vfp-flex-shrink-0 vfp-ml-2\">{{ formatFileSize(node.size) }}</span>\n </button>\n</template>\n\n<script lang=\"ts\">\nexport default { name: 'ZipTreeItem' };\n</script>\n\n<style scoped>\n.tree-row {\n width: 100%;\n display: flex;\n align-items: center;\n gap: 0.375rem;\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n padding-right: 0.5rem;\n text-align: left;\n font-size: 0.875rem;\n background: transparent;\n border: 0;\n cursor: pointer;\n}\n.dir-row {\n color: var(--fp-fg-secondary);\n}\n.file-row {\n color: var(--fp-fg-secondary);\n}\n.tree-row:hover {\n background: var(--fp-surface-1);\n}\n.file-row.selected {\n background: var(--fp-line);\n color: #fff;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { ref, computed, watch, onBeforeUnmount, defineAsyncComponent } from 'vue';\nimport type JSZip from 'jszip';\nimport {\n loadZip,\n listZipEntries,\n buildZipTree,\n readZipEntryBlob,\n inferMimeType,\n type ZipTreeNode,\n} from '@eternalheart/file-preview-core';\nimport ResizableSplit from '../../components/ResizableSplit.vue';\nimport TreeItem from './TreeItem.vue';\nimport type { ZipToolbarStats } from './toolbar';\nimport { useTranslator } from '../../composables/useTranslator';\nimport { useFetcher } from '../../composables/useRequest';\nimport RendererError from '../RendererError.vue';\n\n// 懒加载 FilePreviewContent 以打破循环依赖\nconst LazyFilePreviewContent = defineAsyncComponent(\n () => import('../../FilePreviewContent.vue')\n);\n\nconst props = withDefaults(defineProps<{\n url: string;\n /** ZIP 嵌套深度(由 FilePreviewContent 传入) */\n nestingDepth?: number;\n}>(), {\n nestingDepth: 0,\n});\n\nconst emit = defineEmits<{\n (e: 'statsChange', stats: ZipToolbarStats | null): void;\n}>();\n\nconst { t } = useTranslator();\nconst fetcher = useFetcher();\n\ninterface SelectedPreview {\n path: string;\n name: string;\n size: number;\n blobUrl: string;\n}\n\ninterface HoverTipState {\n text: string;\n x: number;\n y: number;\n}\n\nconst zip = ref<JSZip | null>(null);\nconst tree = ref<ZipTreeNode | null>(null);\nconst loading = ref(true);\nconst error = ref<string | null>(null);\nconst expanded = ref<Set<string>>(new Set(['']));\nconst selected = ref<SelectedPreview | null>(null);\nconst previewLoading = ref(false);\nconst previewError = ref<string | null>(null);\nconst hoverTip = ref<HoverTipState | null>(null);\n\nconst revokeCurrent = () => {\n if (selected.value?.blobUrl) URL.revokeObjectURL(selected.value.blobUrl);\n};\n\nconst load = async () => {\n revokeCurrent();\n selected.value = null;\n loading.value = true;\n error.value = null;\n try {\n const res = await fetcher.value(props.url);\n if (!res.ok) throw new Error('加载失败');\n const buf = await res.arrayBuffer();\n const z = await loadZip(buf);\n const entries = listZipEntries(z);\n const root = buildZipTree(entries);\n zip.value = z;\n tree.value = root;\n const init = new Set<string>(['']);\n if (root.children) for (const c of root.children) if (c.isDir) init.add(c.path);\n expanded.value = init;\n } catch (err) {\n console.error(err);\n error.value = t.value('zip.load_failed');\n } finally {\n loading.value = false;\n }\n};\n\nwatch(() => props.url, (newUrl) => {\n // 只有 URL 有效时才加载(避免空字符串或已 revoke 的 blob URL)\n if (newUrl) load();\n}, { immediate: true });\nonBeforeUnmount(() => { revokeCurrent(); });\n\nconst totalStats = computed<ZipToolbarStats | null>(() => {\n if (!tree.value) return null;\n let files = 0, dirs = 0, size = 0;\n const walk = (n: ZipTreeNode) => {\n if (n.isDir) { if (n.path) dirs++; n.children?.forEach(walk); }\n else { files++; size += n.size; }\n };\n walk(tree.value);\n return { files, dirs, size };\n});\n\nwatch(totalStats, (s) => emit('statsChange', s), { immediate: true });\nonBeforeUnmount(() => emit('statsChange', null));\n\nconst handleToggle = (path: string) => {\n const next = new Set(expanded.value);\n if (next.has(path)) next.delete(path);\n else next.add(path);\n expanded.value = next;\n};\n\nconst handleHover = (text: string, rect: DOMRect) => {\n hoverTip.value = { text, x: rect.right + 8, y: rect.top + rect.height / 2 };\n};\nconst handleLeave = () => { hoverTip.value = null; };\n\nconst handleSelect = async (node: ZipTreeNode) => {\n if (!zip.value || node.isDir) return;\n revokeCurrent();\n previewLoading.value = true;\n previewError.value = null;\n\n try {\n const mime = inferMimeType(node.name);\n const blob = await readZipEntryBlob(zip.value, node.path, mime !== 'application/octet-stream' ? mime : undefined);\n const blobUrl = URL.createObjectURL(blob);\n selected.value = { path: node.path, name: node.name, size: node.size, blobUrl };\n } catch (err) {\n console.error(err);\n previewError.value = '条目读取失败';\n } finally {\n previewLoading.value = false;\n }\n};\n\n/** 为嵌入的 FilePreviewContent 构建 files 数组 */\nconst previewFiles = computed(() => {\n if (!selected.value) return [];\n return [{ name: selected.value.name, url: selected.value.blobUrl, type: inferMimeType(selected.value.name) }];\n});\n</script>\n\n<template>\n <div v-if=\"loading\" class=\"vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full\">\n <div class=\"vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin\" />\n </div>\n\n <RendererError v-else-if=\"error || !tree\" :message=\"error || t('zip.parse_failed')\" />\n\n <template v-else>\n <ResizableSplit\n :initial-left-width=\"280\"\n :min-left-width=\"180\"\n :max-left-width=\"560\"\n storage-key=\"vfp-zip-split-left\"\n >\n <template #left>\n <div class=\"vfp-w-full vfp-h-full vfp-overflow-auto\">\n <TreeItem\n v-for=\"child in tree.children || []\"\n :key=\"child.path\"\n :node=\"child\"\n :depth=\"0\"\n :selected-path=\"selected?.path ?? null\"\n :expanded=\"expanded\"\n @toggle=\"handleToggle\"\n @select=\"handleSelect\"\n @hover=\"handleHover\"\n @leave=\"handleLeave\"\n />\n </div>\n </template>\n\n <template #right>\n <div class=\"vfp-w-full vfp-h-full vfp-flex vfp-flex-col\">\n <div v-if=\"!selected\" class=\"vfp-flex-1 vfp-flex vfp-items-center vfp-justify-center vfp-text-fg-muted vfp-text-sm vfp-p-6\">\n 从左侧选择一个文件以预览\n </div>\n <div v-else-if=\"previewLoading\" class=\"vfp-flex-1 vfp-flex vfp-items-center vfp-justify-center\">\n <div class=\"vfp-w-8 vfp-h-8 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin\" />\n </div>\n <div v-else-if=\"previewError\" class=\"vfp-flex-1 vfp-flex vfp-items-center vfp-justify-center vfp-text-fg-secondary\">{{ previewError }}</div>\n <template v-else>\n <div class=\"vfp-flex-1 vfp-min-h-0 vfp-overflow-hidden vfp-flex vfp-relative vfp-z-0\">\n <LazyFilePreviewContent\n mode=\"embed\"\n :files=\"previewFiles\"\n :current-index=\"0\"\n :zip-nesting-depth=\"nestingDepth + 1\"\n />\n </div>\n </template>\n </div>\n </template>\n </ResizableSplit>\n\n <!-- 文件名 hover tooltip (teleport 到 body 避免被滚动区裁剪) -->\n <Teleport to=\"body\">\n <div\n v-if=\"hoverTip\"\n class=\"vfp-zip-tip\"\n :style=\"{ left: hoverTip.x + 'px', top: hoverTip.y + 'px' }\"\n >\n {{ hoverTip.text }}\n </div>\n </Teleport>\n </template>\n</template>\n\n<style>\n/* 全局 tooltip(不能 scoped,因 Teleport 到 body) */\n.vfp-zip-tip {\n position: fixed;\n z-index: 9999;\n pointer-events: none;\n transform: translateY(-50%);\n padding: 4px 8px;\n background: rgba(0, 0, 0, 0.85);\n color: #fff;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 4px;\n white-space: nowrap;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);\n}\n</style>\n"],"names":["props","__props","containerRef","ref","leftWidth","saved","dragging","isDesktop","mq","mqHandler","leftStyle","computed","onMove","e","rect","x","cap","effectiveMax","onUp","onDividerDown","onMounted","onBeforeUnmount","watch","w","_createElementBlock","_createElementVNode","_renderSlot","_ctx","_normalizeClass","_hoisted_1","__default__","emit","__emit","padStyle","isOpen","isSelected","fileIcon","ft","getFileType","FileImage","FileText","FileCode","FileIcon","handleEnter","handleLeave","_cache","$event","_createVNode","_unref","ChevronRight","_createBlock","_resolveDynamicComponent","FolderOpen","Folder","_hoisted_2","_toDisplayString","_openBlock","_Fragment","_renderList","child","_component_ZipTreeItem","p","n","t","r","_hoisted_3","_hoisted_4","LazyFilePreviewContent","defineAsyncComponent","useTranslator","fetcher","useFetcher","zip","tree","loading","error","expanded","selected","previewLoading","previewError","hoverTip","revokeCurrent","_a","load","res","buf","z","loadZip","entries","listZipEntries","root","buildZipTree","init","c","err","newUrl","totalStats","files","dirs","size","walk","s","handleToggle","path","next","handleHover","text","handleSelect","node","mime","inferMimeType","blob","readZipEntryBlob","blobUrl","previewFiles","RendererError","ResizableSplit","TreeItem","_hoisted_5","_hoisted_6","_hoisted_7","_Teleport"],"mappings":"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"}
@@ -1,234 +0,0 @@
1
- import { defineComponent as oe, ref as l, watch as $, onBeforeUnmount as X, onMounted as se, computed as V, openBlock as c, createElementBlock as _, normalizeStyle as K, createVNode as re, unref as q, createElementVNode as z, createTextVNode as ue, toDisplayString as M, createCommentVNode as g, createBlock as G, normalizeClass as ie } from "vue";
2
- import { Loader2 as ve } from "lucide-vue-next";
3
- import { u as fe, G as ce, q as de, C as pe } from "./index-CQFN4h-t.mjs";
4
- import { _ as F } from "./RendererError.vue_vue_type_script_setup_true_lang-CbgZBSDr.mjs";
5
- const he = {
6
- key: 0,
7
- class: "vfp-absolute vfp-inset-0 vfp-flex vfp-flex-col vfp-items-center vfp-justify-center vfp-bg-surface-1/80 vfp-z-10"
8
- }, me = { class: "vfp-mt-4 vfp-text-fg-secondary" }, ge = { key: 0 }, ye = {
9
- key: 2,
10
- class: "vfp-flex vfp-items-center vfp-justify-center"
11
- }, be = ["src"], xe = {
12
- key: 5,
13
- class: "vfp-absolute vfp-bottom-2 vfp-right-3 vfp-text-[10px] vfp-text-fg-disabled hover:vfp-text-fg-secondary vfp-transition-colors vfp-pointer-events-auto vfp-select-none vfp-cursor-default"
14
- }, we = {
15
- key: 6,
16
- class: "vfp-absolute vfp-bottom-2 vfp-left-1/2 -vfp-translate-x-1/2 vfp-flex vfp-items-center vfp-gap-2 vfp-px-3 vfp-py-1.5 vfp-bg-surface-toolbar vfp-border vfp-border-line vfp-rounded-lg vfp-text-sm vfp-text-fg-primary vfp-shadow-md"
17
- }, _e = ["disabled"], ke = { class: "vfp-text-fg-secondary vfp-tabular-nums" }, Ce = ["disabled"], ze = /* @__PURE__ */ oe({
18
- __name: "index",
19
- props: {
20
- url: {},
21
- zoom: {},
22
- rotation: {},
23
- resetKey: {},
24
- fileSize: {},
25
- file: {}
26
- },
27
- emits: ["zoomChange", "naturalWidthChange", "naturalHeightChange"],
28
- setup(Q, { emit: Z }) {
29
- const n = Q, E = Z, { t: D } = fe(), y = l(!1), d = l(null), r = l(!1), j = l(0), p = l(null), h = l(""), m = l(1), k = l(1), H = l(!1), u = l({ x: 0, y: 0 }), U = l(!1);
30
- let W = { x: 0, y: 0 };
31
- const b = l(1), x = l({ width: 0, height: 0 }), A = l(null), C = l(null);
32
- let R = null, B = null, S = null;
33
- const i = /* @__PURE__ */ new Map();
34
- $(
35
- () => [n.url, n.file],
36
- async () => {
37
- if (h.value = "", y.value = !1, d.value = null, r.value = !1, p.value = null, j.value = 0, u.value = { x: 0, y: 0 }, b.value = 1, m.value = 1, k.value = 1, H.value = !1, R && (URL.revokeObjectURL(R), R = null), i.forEach((e) => URL.revokeObjectURL(e)), i.clear(), B = null, S = null, !n.file) {
38
- h.value = n.url;
39
- return;
40
- }
41
- try {
42
- const e = await ce(n.file), t = await de(e);
43
- if (!t || !await t.needsDecode(e)) {
44
- h.value = n.url;
45
- return;
46
- }
47
- r.value = !0;
48
- let a;
49
- if (n.file instanceof Blob)
50
- a = n.file;
51
- else {
52
- const s = await fetch(n.url);
53
- if (!s.ok) throw new Error("Failed to fetch file");
54
- a = await s.blob();
55
- }
56
- if (B = a, S = t, e.startsWith("image/x-") && (H.value = !0), t.getMetadata)
57
- try {
58
- const s = await t.getMetadata(a);
59
- s.pageCount && s.pageCount > 1 && (k.value = s.pageCount);
60
- } catch {
61
- }
62
- const o = await t.decode(a, {
63
- page: 1,
64
- fullQuality: !1,
65
- onProgress: (s) => {
66
- j.value = s;
67
- }
68
- }), v = typeof o == "string" ? o : URL.createObjectURL(o);
69
- R = v, i.set(1, v), h.value = v, r.value = !1;
70
- } catch (e) {
71
- p.value = (e == null ? void 0 : e.message) || "解码失败", r.value = !1;
72
- }
73
- },
74
- { immediate: !0 }
75
- );
76
- const T = async (e) => {
77
- if (!B || !S || e < 1 || e > k.value) return;
78
- const t = i.get(e);
79
- if (t) {
80
- m.value = e, h.value = t;
81
- return;
82
- }
83
- r.value = !0;
84
- try {
85
- const a = await S.decode(B, { page: e }), f = typeof a == "string" ? a : URL.createObjectURL(a);
86
- if (i.size >= 10) {
87
- const o = i.keys().next().value;
88
- if (o !== void 0) {
89
- const v = i.get(o);
90
- v && URL.revokeObjectURL(v), i.delete(o);
91
- }
92
- }
93
- i.set(e, f), m.value = e, h.value = f, r.value = !1;
94
- } catch (a) {
95
- p.value = (a == null ? void 0 : a.message) || "翻页解码失败", r.value = !1;
96
- }
97
- };
98
- X(() => {
99
- R && URL.revokeObjectURL(R), i.forEach((t) => URL.revokeObjectURL(t)), i.clear();
100
- const e = C.value;
101
- e && e.removeEventListener("wheel", O);
102
- }), $(
103
- () => n.zoom,
104
- (e) => {
105
- b.value = e;
106
- }
107
- ), $(
108
- () => n.resetKey,
109
- () => {
110
- u.value = { x: 0, y: 0 };
111
- }
112
- );
113
- const Y = (e, t) => {
114
- const a = C.value;
115
- if (!a || x.value.width === 0) return e;
116
- const f = a.clientWidth, o = a.clientHeight, v = x.value.width * t, s = x.value.height * t, w = Math.min(80, f * 0.15, o * 0.15), L = (f + v) / 2 - w, P = (o + s) / 2 - w;
117
- return {
118
- x: L > 0 ? Math.max(-L, Math.min(L, e.x)) : 0,
119
- y: P > 0 ? Math.max(-P, Math.min(P, e.y)) : 0
120
- };
121
- }, I = (e) => {
122
- y.value = !0;
123
- const t = e.currentTarget;
124
- x.value = { width: t.naturalWidth, height: t.naturalHeight }, E("naturalWidthChange", t.naturalWidth), E("naturalHeightChange", t.naturalHeight);
125
- }, J = () => {
126
- d.value = D.value("image.load_failed"), y.value = !0;
127
- }, ee = () => {
128
- u.value = { x: 0, y: 0 }, b.value = 1, E("zoomChange", 1);
129
- }, O = (e) => {
130
- e.preventDefault(), e.stopPropagation();
131
- const t = C.value;
132
- if (!t) return;
133
- const a = t.getBoundingClientRect(), f = e.clientX - a.left - a.width / 2, o = e.clientY - a.top - a.height / 2, v = e.deltaY > 0 ? -0.05 : 0.05, s = b.value, w = Math.max(0.01, Math.min(10, s + v)), L = w / s;
134
- u.value = Y(
135
- {
136
- x: f - L * (f - u.value.x),
137
- y: o - L * (o - u.value.y)
138
- },
139
- w
140
- ), b.value = w, E("zoomChange", w);
141
- };
142
- se(() => {
143
- const e = C.value;
144
- e && e.addEventListener("wheel", O, { passive: !1 });
145
- }), X(() => {
146
- const e = C.value;
147
- e && e.removeEventListener("wheel", O);
148
- });
149
- const te = (e) => {
150
- e.button === 0 && (U.value = !0, W = {
151
- x: e.clientX - u.value.x,
152
- y: e.clientY - u.value.y
153
- });
154
- }, ae = (e) => {
155
- U.value && (u.value = Y(
156
- {
157
- x: e.clientX - W.x,
158
- y: e.clientY - W.y
159
- },
160
- b.value
161
- ));
162
- }, N = () => {
163
- U.value = !1;
164
- }, le = V(() => ({
165
- transform: `translate(${u.value.x}px, ${u.value.y}px) scale(${b.value}) rotate(${n.rotation}deg)`,
166
- transformOrigin: "center",
167
- transition: U.value ? "none" : "transform 0.3s ease-out",
168
- opacity: y.value && !d.value && !p.value ? 1 : 0
169
- })), ne = V(() => n.fileSize == null ? "" : ` · ${pe(n.fileSize)}`);
170
- return (e, t) => (c(), _("div", {
171
- ref_key: "containerRef",
172
- ref: C,
173
- class: "vfp-relative vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full vfp-overflow-hidden",
174
- style: K({ cursor: U.value ? "grabbing" : "grab" }),
175
- onMousedown: te,
176
- onMousemove: ae,
177
- onMouseup: N,
178
- onMouseleave: N
179
- }, [
180
- r.value ? (c(), _("div", he, [
181
- re(q(ve), { class: "vfp-w-12 vfp-h-12 vfp-text-fg-primary vfp-animate-spin" }),
182
- z("p", me, [
183
- t[2] || (t[2] = ue(" 正在解码... ", -1)),
184
- j.value > 0 ? (c(), _("span", ge, M(Math.round(j.value)) + "%", 1)) : g("", !0)
185
- ])
186
- ])) : g("", !0),
187
- p.value ? (c(), G(F, {
188
- key: 1,
189
- message: q(D)("image.decode_failed"),
190
- detail: p.value
191
- }, null, 8, ["message", "detail"])) : g("", !0),
192
- !y.value && !d.value && !r.value && !p.value ? (c(), _("div", ye, [...t[3] || (t[3] = [
193
- z("div", { class: "vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin" }, null, -1)
194
- ])])) : g("", !0),
195
- d.value ? (c(), G(F, {
196
- key: 3,
197
- message: d.value
198
- }, null, 8, ["message"])) : g("", !0),
199
- h.value ? (c(), _("img", {
200
- key: 4,
201
- ref_key: "imgRef",
202
- ref: A,
203
- src: h.value,
204
- alt: "Preview",
205
- class: ie(["vfp-max-w-none vfp-select-none", (!y.value || d.value || p.value) && "vfp-hidden"]),
206
- style: K(le.value),
207
- draggable: !1,
208
- onLoad: I,
209
- onError: J,
210
- onDblclick: ee
211
- }, null, 46, be)) : g("", !0),
212
- y.value && !d.value && x.value.width > 0 ? (c(), _("div", xe, M(x.value.width) + " × " + M(x.value.height) + M(ne.value), 1)) : g("", !0),
213
- k.value > 1 ? (c(), _("div", we, [
214
- z("button", {
215
- type: "button",
216
- disabled: m.value <= 1 || r.value,
217
- class: "vfp-px-2 vfp-py-0.5 vfp-rounded hover:vfp-bg-surface-nav-hover disabled:vfp-opacity-40 disabled:vfp-cursor-not-allowed",
218
- onClick: t[0] || (t[0] = (a) => T(m.value - 1))
219
- }, " 上一页 ", 8, _e),
220
- z("span", ke, M(m.value) + " / " + M(k.value), 1),
221
- z("button", {
222
- type: "button",
223
- disabled: m.value >= k.value || r.value,
224
- class: "vfp-px-2 vfp-py-0.5 vfp-rounded hover:vfp-bg-surface-nav-hover disabled:vfp-opacity-40 disabled:vfp-cursor-not-allowed",
225
- onClick: t[1] || (t[1] = (a) => T(m.value + 1))
226
- }, " 下一页 ", 8, Ce)
227
- ])) : g("", !0)
228
- ], 36));
229
- }
230
- });
231
- export {
232
- ze as default
233
- };
234
- //# sourceMappingURL=index-y7gaKu36.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-y7gaKu36.mjs","sources":["../../src/renderers/Image/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, watch, onMounted, onBeforeUnmount, computed } from 'vue';\nimport { Loader2 } from 'lucide-vue-next';\nimport { formatFileSize, detectImageFormat, getLoaderForMimeType } from '@eternalheart/file-preview-core';\nimport type { PreviewFile } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../composables/useTranslator';\nimport RendererError from '../RendererError.vue';\n\nconst props = defineProps<{\n url: string;\n zoom: number;\n rotation: number;\n resetKey?: number;\n fileSize?: number;\n file?: PreviewFile | File;\n}>();\n\nconst emit = defineEmits<{\n (e: 'zoomChange', zoom: number): void;\n (e: 'naturalWidthChange', width: number): void;\n (e: 'naturalHeightChange', height: number): void;\n}>();\n\nconst { t } = useTranslator();\n\nconst loaded = ref(false);\nconst error = ref<string | null>(null);\nconst decoding = ref(false);\nconst decodeProgress = ref(0);\nconst decodeError = ref<string | null>(null);\nconst imageSrc = ref<string>('');\nconst currentPage = ref(1);\nconst totalPages = ref(1);\nconst isRawThumbnail = ref(false);\nconst position = ref({ x: 0, y: 0 });\nconst isDragging = ref(false);\nlet dragStart = { x: 0, y: 0 };\nconst internalZoom = ref(1);\nconst naturalSize = ref({ width: 0, height: 0 });\n\nconst imgRef = ref<HTMLImageElement | null>(null);\nconst containerRef = ref<HTMLDivElement | null>(null);\nlet blobUrl: string | null = null;\nlet fileBlobCache: Blob | null = null;\nlet loaderCache: any = null;\nconst pageCache = new Map<number, string>();\n\n// 解码逻辑\nwatch(\n () => [props.url, props.file] as const,\n async () => {\n // 重置状态:清空 src 以避免上一张图片的 onLoad/onError 误触发到新文件\n imageSrc.value = '';\n loaded.value = false;\n error.value = null;\n decoding.value = false;\n decodeError.value = null;\n decodeProgress.value = 0;\n position.value = { x: 0, y: 0 };\n internalZoom.value = 1;\n currentPage.value = 1;\n totalPages.value = 1;\n isRawThumbnail.value = false;\n\n // 清理旧的 blob URL 与缓存\n if (blobUrl) {\n URL.revokeObjectURL(blobUrl);\n blobUrl = null;\n }\n pageCache.forEach((url) => URL.revokeObjectURL(url));\n pageCache.clear();\n fileBlobCache = null;\n loaderCache = null;\n\n // 如果没有 file 对象,直接使用 url\n if (!props.file) {\n imageSrc.value = props.url;\n return;\n }\n\n try {\n // 检测图片格式\n const mimeType = await detectImageFormat(props.file);\n const loader = await getLoaderForMimeType(mimeType);\n\n // 如果不需要解码,直接使用原 URL\n if (!loader || !(await loader.needsDecode(mimeType))) {\n imageSrc.value = props.url;\n return;\n }\n\n // 需要解码\n decoding.value = true;\n\n // 获取文件 Blob\n let fileBlob: Blob;\n if (props.file instanceof Blob) {\n fileBlob = props.file;\n } else {\n const response = await fetch(props.url);\n if (!response.ok) throw new Error('Failed to fetch file');\n fileBlob = await response.blob();\n }\n\n // 缓存 Blob 与 loader\n fileBlobCache = fileBlob;\n loaderCache = loader;\n\n // 标记 RAW 缩略图模式\n const isRaw = mimeType.startsWith('image/x-');\n if (isRaw) {\n isRawThumbnail.value = true;\n }\n\n // 获取元数据(用于检测多页 TIFF)\n if (loader.getMetadata) {\n try {\n const metadata = await loader.getMetadata(fileBlob);\n if (metadata.pageCount && metadata.pageCount > 1) {\n totalPages.value = 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 decodeProgress.value = percent;\n },\n });\n\n // 生成 blob URL\n const url = typeof decodedBlob === 'string'\n ? decodedBlob\n : URL.createObjectURL(decodedBlob);\n\n blobUrl = url;\n pageCache.set(1, url);\n imageSrc.value = url;\n decoding.value = false;\n } catch (err: any) {\n decodeError.value = err?.message || '解码失败';\n decoding.value = false;\n }\n },\n { immediate: true }\n);\n\n// 多页 TIFF 翻页\nconst handlePageChange = async (page: number) => {\n if (!fileBlobCache || !loaderCache) return;\n if (page < 1 || page > totalPages.value) return;\n\n // 命中缓存:直接切换\n const cached = pageCache.get(page);\n if (cached) {\n currentPage.value = page;\n imageSrc.value = cached;\n return;\n }\n\n // 解码新页面\n decoding.value = true;\n try {\n const decodedBlob = await loaderCache.decode(fileBlobCache, { page });\n const url = typeof decodedBlob === 'string'\n ? decodedBlob\n : URL.createObjectURL(decodedBlob);\n\n // LRU:缓存超过 10 页时删除最早的\n if (pageCache.size >= 10) {\n const firstKey = pageCache.keys().next().value;\n if (firstKey !== undefined) {\n const oldUrl = pageCache.get(firstKey);\n if (oldUrl) URL.revokeObjectURL(oldUrl);\n pageCache.delete(firstKey);\n }\n }\n\n pageCache.set(page, url);\n currentPage.value = page;\n imageSrc.value = url;\n decoding.value = false;\n } catch (err: any) {\n decodeError.value = err?.message || '翻页解码失败';\n decoding.value = false;\n }\n};\n\n// Cleanup on unmount\nonBeforeUnmount(() => {\n if (blobUrl) {\n URL.revokeObjectURL(blobUrl);\n }\n pageCache.forEach((url) => URL.revokeObjectURL(url));\n pageCache.clear();\n const container = containerRef.value;\n if (container) {\n container.removeEventListener('wheel', handleWheelNative);\n }\n});\n\nwatch(\n () => props.zoom,\n (z) => {\n internalZoom.value = z;\n }\n);\n\nwatch(\n () => props.resetKey,\n () => {\n position.value = { x: 0, y: 0 };\n }\n);\n\nconst clampPosition = (pos: { x: number; y: number }, currentZoom: number) => {\n const container = containerRef.value;\n if (!container || naturalSize.value.width === 0) return pos;\n\n const containerW = container.clientWidth;\n const containerH = container.clientHeight;\n const imgW = naturalSize.value.width * currentZoom;\n const imgH = naturalSize.value.height * currentZoom;\n\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};\n\nconst handleLoad = (e: Event) => {\n loaded.value = true;\n const img = e.currentTarget as HTMLImageElement;\n naturalSize.value = { width: img.naturalWidth, height: img.naturalHeight };\n emit('naturalWidthChange', img.naturalWidth);\n emit('naturalHeightChange', img.naturalHeight);\n};\n\nconst handleError = () => {\n error.value = t.value('image.load_failed');\n loaded.value = true;\n};\n\nconst handleDoubleClick = () => {\n position.value = { x: 0, y: 0 };\n internalZoom.value = 1;\n emit('zoomChange', 1);\n};\n\n// 鼠标滚轮缩放\nconst handleWheelNative = (e: WheelEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const container = containerRef.value;\n if (!container) return;\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 const prev = internalZoom.value;\n const newZoom = Math.max(0.01, Math.min(10, prev + delta));\n const scale = newZoom / prev;\n\n position.value = clampPosition(\n {\n x: mouseX - scale * (mouseX - position.value.x),\n y: mouseY - scale * (mouseY - position.value.y),\n },\n newZoom\n );\n\n internalZoom.value = newZoom;\n emit('zoomChange', newZoom);\n};\n\nonMounted(() => {\n const container = containerRef.value;\n if (container) {\n container.addEventListener('wheel', handleWheelNative, { passive: false });\n }\n});\n\nonBeforeUnmount(() => {\n const container = containerRef.value;\n if (container) {\n container.removeEventListener('wheel', handleWheelNative);\n }\n});\n\nconst handleMouseDown = (e: MouseEvent) => {\n if (e.button !== 0) return;\n isDragging.value = true;\n dragStart = {\n x: e.clientX - position.value.x,\n y: e.clientY - position.value.y,\n };\n};\n\nconst handleMouseMove = (e: MouseEvent) => {\n if (!isDragging.value) return;\n position.value = clampPosition(\n {\n x: e.clientX - dragStart.x,\n y: e.clientY - dragStart.y,\n },\n internalZoom.value\n );\n};\n\nconst handleMouseUp = () => {\n isDragging.value = false;\n};\n\nconst transformStyle = computed(() => ({\n transform: `translate(${position.value.x}px, ${position.value.y}px) scale(${internalZoom.value}) rotate(${props.rotation}deg)`,\n transformOrigin: 'center',\n transition: isDragging.value ? 'none' : 'transform 0.3s ease-out',\n opacity: loaded.value && !error.value && !decodeError.value ? 1 : 0,\n}));\n\nconst sizeText = computed(() => {\n if (props.fileSize == null) return '';\n return ` · ${formatFileSize(props.fileSize)}`;\n});\n</script>\n\n<template>\n <div\n ref=\"containerRef\"\n class=\"vfp-relative vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full vfp-overflow-hidden\"\n :style=\"{ cursor: isDragging ? 'grabbing' : 'grab' }\"\n @mousedown=\"handleMouseDown\"\n @mousemove=\"handleMouseMove\"\n @mouseup=\"handleMouseUp\"\n @mouseleave=\"handleMouseUp\"\n >\n <!-- 解码中 -->\n <div\n v-if=\"decoding\"\n class=\"vfp-absolute vfp-inset-0 vfp-flex vfp-flex-col vfp-items-center vfp-justify-center vfp-bg-surface-1/80 vfp-z-10\"\n >\n <Loader2 class=\"vfp-w-12 vfp-h-12 vfp-text-fg-primary vfp-animate-spin\" />\n <p class=\"vfp-mt-4 vfp-text-fg-secondary\">\n 正在解码... <span v-if=\"decodeProgress > 0\">{{ Math.round(decodeProgress) }}%</span>\n </p>\n </div>\n\n <!-- 解码错误 -->\n <RendererError v-if=\"decodeError\" :message=\"t('image.decode_failed')\" :detail=\"decodeError\" />\n\n <div v-if=\"!loaded && !error && !decoding && !decodeError\" class=\"vfp-flex vfp-items-center vfp-justify-center\">\n <div\n class=\"vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin\"\n />\n </div>\n\n <RendererError v-if=\"error\" :message=\"error\" />\n\n <img\n v-if=\"imageSrc\"\n ref=\"imgRef\"\n :src=\"imageSrc\"\n alt=\"Preview\"\n :class=\"['vfp-max-w-none vfp-select-none', (!loaded || error || decodeError) && 'vfp-hidden']\"\n :style=\"transformStyle\"\n :draggable=\"false\"\n @load=\"handleLoad\"\n @error=\"handleError\"\n @dblclick=\"handleDoubleClick\"\n />\n\n <div\n v-if=\"loaded && !error && naturalSize.width > 0\"\n class=\"vfp-absolute vfp-bottom-2 vfp-right-3 vfp-text-[10px] vfp-text-fg-disabled hover:vfp-text-fg-secondary vfp-transition-colors vfp-pointer-events-auto vfp-select-none vfp-cursor-default\"\n >\n {{ naturalSize.width }} × {{ naturalSize.height }}{{ sizeText }}\n </div>\n\n <!-- 多页 TIFF 翻页器 -->\n <div\n v-if=\"totalPages > 1\"\n class=\"vfp-absolute vfp-bottom-2 vfp-left-1/2 -vfp-translate-x-1/2 vfp-flex vfp-items-center vfp-gap-2 vfp-px-3 vfp-py-1.5 vfp-bg-surface-toolbar vfp-border vfp-border-line vfp-rounded-lg vfp-text-sm vfp-text-fg-primary vfp-shadow-md\"\n >\n <button\n type=\"button\"\n :disabled=\"currentPage <= 1 || decoding\"\n class=\"vfp-px-2 vfp-py-0.5 vfp-rounded hover:vfp-bg-surface-nav-hover disabled:vfp-opacity-40 disabled:vfp-cursor-not-allowed\"\n @click=\"handlePageChange(currentPage - 1)\"\n >\n 上一页\n </button>\n <span class=\"vfp-text-fg-secondary vfp-tabular-nums\">\n {{ currentPage }} / {{ totalPages }}\n </span>\n <button\n type=\"button\"\n :disabled=\"currentPage >= totalPages || decoding\"\n class=\"vfp-px-2 vfp-py-0.5 vfp-rounded hover:vfp-bg-surface-nav-hover disabled:vfp-opacity-40 disabled:vfp-cursor-not-allowed\"\n @click=\"handlePageChange(currentPage + 1)\"\n >\n 下一页\n </button>\n </div>\n </div>\n</template>\n"],"names":["props","__props","emit","__emit","t","useTranslator","loaded","ref","error","decoding","decodeProgress","decodeError","imageSrc","currentPage","totalPages","isRawThumbnail","position","isDragging","dragStart","internalZoom","naturalSize","imgRef","containerRef","blobUrl","fileBlobCache","loaderCache","pageCache","watch","url","mimeType","detectImageFormat","loader","getLoaderForMimeType","fileBlob","response","metadata","decodedBlob","percent","err","handlePageChange","page","cached","firstKey","oldUrl","onBeforeUnmount","container","handleWheelNative","z","clampPosition","pos","currentZoom","containerW","containerH","imgW","imgH","margin","rangeX","rangeY","handleLoad","img","handleError","handleDoubleClick","rect","mouseX","mouseY","delta","prev","newZoom","scale","onMounted","handleMouseDown","handleMouseMove","handleMouseUp","transformStyle","computed","sizeText","formatFileSize","_createElementBlock","_openBlock","_hoisted_1","_createVNode","_unref","Loader2","_createElementVNode","_hoisted_2","_createBlock","RendererError","_hoisted_4","_cache","_normalizeClass","_hoisted_6","_toDisplayString","_hoisted_7","$event","_hoisted_8","_hoisted_9","_hoisted_10"],"mappings":"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"}
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file