vistaview 1.0.5 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (342) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +18 -65
  3. package/{dist/lib/extensions/dailymotion-video.d.ts → extensions/dailymotion-video/dist/main.d.ts} +3 -3
  4. package/extensions/dailymotion-video/dist/main.d.ts.map +1 -0
  5. package/extensions/dailymotion-video/dist/main.js +72 -0
  6. package/extensions/dailymotion-video/dist/main.js.map +1 -0
  7. package/extensions/dailymotion-video/dist/main.test.d.ts +2 -0
  8. package/extensions/dailymotion-video/dist/main.test.d.ts.map +1 -0
  9. package/extensions/dailymotion-video/dist/main.umd.cjs +2 -0
  10. package/extensions/dailymotion-video/dist/main.umd.cjs.map +1 -0
  11. package/extensions/download/dist/main.d.ts +4 -0
  12. package/extensions/download/dist/main.d.ts.map +1 -0
  13. package/extensions/download/dist/main.js +42 -0
  14. package/extensions/download/dist/main.js.map +1 -0
  15. package/extensions/download/dist/main.test.d.ts +2 -0
  16. package/extensions/download/dist/main.test.d.ts.map +1 -0
  17. package/extensions/download/dist/main.umd.cjs +2 -0
  18. package/extensions/download/dist/main.umd.cjs.map +1 -0
  19. package/{dist/lib/extensions/google-maps.d.ts → extensions/google-maps/dist/main.d.ts} +3 -3
  20. package/extensions/google-maps/dist/main.d.ts.map +1 -0
  21. package/extensions/google-maps/dist/main.js +96 -0
  22. package/extensions/google-maps/dist/main.js.map +1 -0
  23. package/extensions/google-maps/dist/main.test.d.ts +2 -0
  24. package/extensions/google-maps/dist/main.test.d.ts.map +1 -0
  25. package/extensions/google-maps/dist/main.umd.cjs +2 -0
  26. package/extensions/google-maps/dist/main.umd.cjs.map +1 -0
  27. package/extensions/image-story/dist/main.d.ts +16 -0
  28. package/extensions/image-story/dist/main.d.ts.map +1 -0
  29. package/extensions/image-story/dist/main.js +600 -0
  30. package/extensions/image-story/dist/main.js.map +1 -0
  31. package/extensions/image-story/dist/main.test.d.ts +2 -0
  32. package/extensions/image-story/dist/main.test.d.ts.map +1 -0
  33. package/extensions/image-story/dist/main.umd.cjs +3 -0
  34. package/extensions/image-story/dist/main.umd.cjs.map +1 -0
  35. package/extensions/image-story/dist/style.css +1 -0
  36. package/extensions/logger/dist/main.d.ts +3 -0
  37. package/extensions/logger/dist/main.d.ts.map +1 -0
  38. package/extensions/logger/dist/main.js +23 -0
  39. package/extensions/logger/dist/main.js.map +1 -0
  40. package/extensions/logger/dist/main.test.d.ts +2 -0
  41. package/extensions/logger/dist/main.test.d.ts.map +1 -0
  42. package/extensions/logger/dist/main.umd.cjs +2 -0
  43. package/extensions/logger/dist/main.umd.cjs.map +1 -0
  44. package/{dist/lib/extensions/mapbox.d.ts → extensions/mapbox/dist/main.d.ts} +3 -3
  45. package/extensions/mapbox/dist/main.d.ts.map +1 -0
  46. package/extensions/mapbox/dist/main.js +114 -0
  47. package/extensions/mapbox/dist/main.js.map +1 -0
  48. package/extensions/mapbox/dist/main.test.d.ts +2 -0
  49. package/extensions/mapbox/dist/main.test.d.ts.map +1 -0
  50. package/extensions/mapbox/dist/main.umd.cjs +2 -0
  51. package/extensions/mapbox/dist/main.umd.cjs.map +1 -0
  52. package/{dist/lib/extensions/openstreetmap.d.ts → extensions/openstreetmap/dist/main.d.ts} +3 -3
  53. package/extensions/openstreetmap/dist/main.d.ts.map +1 -0
  54. package/extensions/openstreetmap/dist/main.js +114 -0
  55. package/extensions/openstreetmap/dist/main.js.map +1 -0
  56. package/extensions/openstreetmap/dist/main.test.d.ts +2 -0
  57. package/extensions/openstreetmap/dist/main.test.d.ts.map +1 -0
  58. package/extensions/openstreetmap/dist/main.umd.cjs +2 -0
  59. package/extensions/openstreetmap/dist/main.umd.cjs.map +1 -0
  60. package/{dist/lib/extensions/select-box.d.ts → extensions/select-box/dist/main.d.ts} +2 -2
  61. package/extensions/select-box/dist/main.d.ts.map +1 -0
  62. package/extensions/select-box/dist/main.js +25 -0
  63. package/extensions/select-box/dist/main.js.map +1 -0
  64. package/extensions/select-box/dist/main.umd.cjs +2 -0
  65. package/extensions/select-box/dist/main.umd.cjs.map +1 -0
  66. package/{dist/lib/extensions/streamable-video.d.ts → extensions/streamable-video/dist/main.d.ts} +3 -3
  67. package/extensions/streamable-video/dist/main.d.ts.map +1 -0
  68. package/extensions/streamable-video/dist/main.js +68 -0
  69. package/extensions/streamable-video/dist/main.js.map +1 -0
  70. package/extensions/streamable-video/dist/main.test.d.ts +2 -0
  71. package/extensions/streamable-video/dist/main.test.d.ts.map +1 -0
  72. package/extensions/streamable-video/dist/main.umd.cjs +2 -0
  73. package/extensions/streamable-video/dist/main.umd.cjs.map +1 -0
  74. package/{dist/lib/extensions/twitch-video.d.ts → extensions/twitch-video/dist/main.d.ts} +3 -3
  75. package/extensions/twitch-video/dist/main.d.ts.map +1 -0
  76. package/extensions/twitch-video/dist/main.js +81 -0
  77. package/extensions/twitch-video/dist/main.js.map +1 -0
  78. package/extensions/twitch-video/dist/main.umd.cjs +2 -0
  79. package/extensions/twitch-video/dist/main.umd.cjs.map +1 -0
  80. package/{dist/lib/extensions/vidyard-video.d.ts → extensions/vidyard-video/dist/main.d.ts} +3 -3
  81. package/extensions/vidyard-video/dist/main.d.ts.map +1 -0
  82. package/extensions/vidyard-video/dist/main.js +72 -0
  83. package/extensions/vidyard-video/dist/main.js.map +1 -0
  84. package/extensions/vidyard-video/dist/main.test.d.ts +2 -0
  85. package/extensions/vidyard-video/dist/main.test.d.ts.map +1 -0
  86. package/extensions/vidyard-video/dist/main.umd.cjs +2 -0
  87. package/extensions/vidyard-video/dist/main.umd.cjs.map +1 -0
  88. package/{dist/lib/extensions/vimeo-video.d.ts → extensions/vimeo-video/dist/main.d.ts} +3 -3
  89. package/extensions/vimeo-video/dist/main.d.ts.map +1 -0
  90. package/extensions/vimeo-video/dist/main.js +68 -0
  91. package/extensions/vimeo-video/dist/main.js.map +1 -0
  92. package/extensions/vimeo-video/dist/main.test.d.ts +2 -0
  93. package/extensions/vimeo-video/dist/main.test.d.ts.map +1 -0
  94. package/extensions/vimeo-video/dist/main.umd.cjs +2 -0
  95. package/extensions/vimeo-video/dist/main.umd.cjs.map +1 -0
  96. package/{dist/lib/extensions/wistia-video.d.ts → extensions/wistia-video/dist/main.d.ts} +3 -3
  97. package/extensions/wistia-video/dist/main.d.ts.map +1 -0
  98. package/extensions/wistia-video/dist/main.js +72 -0
  99. package/extensions/wistia-video/dist/main.js.map +1 -0
  100. package/extensions/wistia-video/dist/main.test.d.ts +2 -0
  101. package/extensions/wistia-video/dist/main.test.d.ts.map +1 -0
  102. package/extensions/wistia-video/dist/main.umd.cjs +2 -0
  103. package/extensions/wistia-video/dist/main.umd.cjs.map +1 -0
  104. package/{dist/lib/extensions/youtube-video.d.ts → extensions/youtube-video/dist/main.d.ts} +3 -3
  105. package/extensions/youtube-video/dist/main.d.ts.map +1 -0
  106. package/extensions/youtube-video/dist/main.js +80 -0
  107. package/extensions/youtube-video/dist/main.js.map +1 -0
  108. package/extensions/youtube-video/dist/main.test.d.ts +2 -0
  109. package/extensions/youtube-video/dist/main.test.d.ts.map +1 -0
  110. package/extensions/youtube-video/dist/main.umd.cjs +2 -0
  111. package/extensions/youtube-video/dist/main.umd.cjs.map +1 -0
  112. package/frameworks/react/dist/main.d.ts +3 -0
  113. package/frameworks/react/dist/main.es.js +51 -0
  114. package/frameworks/react/dist/main.es.js.map +1 -0
  115. package/frameworks/react/dist/test-setup.d.ts +1 -0
  116. package/frameworks/react/dist/use-vistaview.d.ts +2 -0
  117. package/frameworks/react/dist/vistaview.d.ts +13 -0
  118. package/frameworks/solid/dist/dev.js +77 -0
  119. package/frameworks/solid/dist/dev.jsx +72 -0
  120. package/frameworks/solid/dist/index.d.ts +18 -0
  121. package/frameworks/solid/dist/index.js +76 -0
  122. package/frameworks/solid/dist/index.jsx +71 -0
  123. package/frameworks/svelte/dist/VistaView.svelte +65 -0
  124. package/frameworks/svelte/dist/VistaView.svelte.d.ts +46 -0
  125. package/frameworks/svelte/dist/index.d.ts +3 -0
  126. package/frameworks/svelte/dist/index.js +2 -0
  127. package/frameworks/svelte/dist/types.d.ts +14 -0
  128. package/frameworks/svelte/dist/types.js +1 -0
  129. package/frameworks/svelte/dist/use-vistaview.d.ts +2 -0
  130. package/frameworks/svelte/dist/use-vistaview.js +24 -0
  131. package/frameworks/svelte/dist/use-vistaview.test.d.ts +1 -0
  132. package/frameworks/svelte/dist/use-vistaview.test.js +115 -0
  133. package/frameworks/vue/dist/main.es.js +95 -0
  134. package/frameworks/vue/dist/main.es.js.map +1 -0
  135. package/{dist → main/dist}/lib/components.d.ts +1 -2
  136. package/main/dist/lib/components.js +107 -0
  137. package/main/dist/lib/defaults/close.d.ts +2 -0
  138. package/main/dist/lib/defaults/close.js +4 -0
  139. package/main/dist/lib/defaults/image-setup.d.ts +3 -0
  140. package/main/dist/lib/defaults/image-setup.js +4 -0
  141. package/main/dist/lib/defaults/init.d.ts +2 -0
  142. package/main/dist/lib/defaults/init.js +97 -0
  143. package/main/dist/lib/defaults/open.d.ts +2 -0
  144. package/main/dist/lib/defaults/open.js +8 -0
  145. package/main/dist/lib/defaults/options.d.ts +2 -0
  146. package/main/dist/lib/defaults/options.js +15 -0
  147. package/{dist → main/dist}/lib/defaults/transition.d.ts +2 -3
  148. package/main/dist/lib/defaults/transition.js +40 -0
  149. package/{dist → main/dist}/lib/main.d.ts +1 -2
  150. package/main/dist/lib/main.js +66 -0
  151. package/{dist → main/dist}/lib/throttle.d.ts +0 -1
  152. package/main/dist/lib/throttle.js +21 -0
  153. package/{dist → main/dist}/lib/types.d.ts +4 -5
  154. package/main/dist/lib/types.js +1 -0
  155. package/{dist → main/dist}/lib/utils/get-fitted-size.d.ts +0 -1
  156. package/main/dist/lib/utils/get-fitted-size.js +53 -0
  157. package/{dist → main/dist}/lib/utils/get-full-size-dim.d.ts +0 -1
  158. package/main/dist/lib/utils/get-full-size-dim.js +35 -0
  159. package/{dist → main/dist}/lib/utils/get-style.d.ts +0 -1
  160. package/main/dist/lib/utils/get-style.js +19 -0
  161. package/{dist → main/dist}/lib/utils/index.d.ts +0 -1
  162. package/main/dist/lib/utils/index.js +7 -0
  163. package/{dist → main/dist}/lib/utils/is-not-zero-css.d.ts +0 -1
  164. package/main/dist/lib/utils/is-not-zero-css.js +3 -0
  165. package/{dist → main/dist}/lib/utils/parse-element.d.ts +1 -2
  166. package/main/dist/lib/utils/parse-element.js +67 -0
  167. package/{dist → main/dist}/lib/vista-box.d.ts +3 -4
  168. package/main/dist/lib/vista-box.js +466 -0
  169. package/{dist → main/dist}/lib/vista-hires-transition.d.ts +2 -3
  170. package/main/dist/lib/vista-hires-transition.js +108 -0
  171. package/{dist → main/dist}/lib/vista-image-event.d.ts +2 -3
  172. package/main/dist/lib/vista-image-event.js +166 -0
  173. package/{dist → main/dist}/lib/vista-image.d.ts +2 -3
  174. package/main/dist/lib/vista-image.js +274 -0
  175. package/{dist → main/dist}/lib/vista-pointers.d.ts +1 -2
  176. package/main/dist/lib/vista-pointers.js +163 -0
  177. package/{dist → main/dist}/lib/vista-state.d.ts +2 -3
  178. package/main/dist/lib/vista-state.js +15 -0
  179. package/{dist → main/dist}/lib/vista-view.d.ts +2 -3
  180. package/main/dist/lib/vista-view.js +576 -0
  181. package/main/dist/style.css +1 -0
  182. package/main/dist/styles/autumn-amber.css +1 -0
  183. package/main/dist/styles/cotton-candy.css +1 -0
  184. package/main/dist/styles/dark-rounded.css +1 -0
  185. package/main/dist/styles/ember-glow.css +1 -0
  186. package/main/dist/styles/forest-moss.css +1 -0
  187. package/main/dist/styles/green-lake.css +1 -0
  188. package/main/dist/styles/ice-crystal.css +1 -0
  189. package/main/dist/styles/lavender-fields.css +1 -0
  190. package/main/dist/styles/midnight-gold.css +1 -0
  191. package/main/dist/styles/midnight-ocean.css +1 -0
  192. package/main/dist/styles/mint-chocolate.css +1 -0
  193. package/main/dist/styles/neon-nights.css +1 -0
  194. package/main/dist/styles/paper-light.css +1 -0
  195. package/main/dist/styles/retro-arcade.css +1 -0
  196. package/main/dist/styles/soft-neutral.css +1 -0
  197. package/main/dist/styles/stark-minimal.css +1 -0
  198. package/main/dist/styles/strawberry.css +1 -0
  199. package/{dist → main/dist}/vistaview.d.ts +0 -1
  200. package/main/dist/vistaview.js +14 -0
  201. package/main/dist/vistaview.umd.js +18 -0
  202. package/package.json +122 -67
  203. package/dist/extensions/dailymotion-video.d.ts +0 -2
  204. package/dist/extensions/dailymotion-video.js +0 -80
  205. package/dist/extensions/dailymotion-video.umd.js +0 -1
  206. package/dist/extensions/download.d.ts +0 -2
  207. package/dist/extensions/download.js +0 -35
  208. package/dist/extensions/download.umd.js +0 -1
  209. package/dist/extensions/google-maps.d.ts +0 -2
  210. package/dist/extensions/google-maps.js +0 -96
  211. package/dist/extensions/google-maps.umd.js +0 -1
  212. package/dist/extensions/image-story.d.ts +0 -2
  213. package/dist/extensions/image-story.js +0 -621
  214. package/dist/extensions/image-story.umd.js +0 -2
  215. package/dist/extensions/logger.d.ts +0 -2
  216. package/dist/extensions/logger.js +0 -23
  217. package/dist/extensions/logger.umd.js +0 -1
  218. package/dist/extensions/mapbox.d.ts +0 -2
  219. package/dist/extensions/mapbox.js +0 -124
  220. package/dist/extensions/mapbox.umd.js +0 -1
  221. package/dist/extensions/openstreetmap.d.ts +0 -2
  222. package/dist/extensions/openstreetmap.js +0 -125
  223. package/dist/extensions/openstreetmap.umd.js +0 -1
  224. package/dist/extensions/select-box.d.ts +0 -2
  225. package/dist/extensions/select-box.js +0 -29
  226. package/dist/extensions/select-box.umd.js +0 -1
  227. package/dist/extensions/streamable-video.d.ts +0 -2
  228. package/dist/extensions/streamable-video.js +0 -76
  229. package/dist/extensions/streamable-video.umd.js +0 -1
  230. package/dist/extensions/twitch-video.d.ts +0 -2
  231. package/dist/extensions/twitch-video.js +0 -79
  232. package/dist/extensions/vidyard-video.d.ts +0 -2
  233. package/dist/extensions/vidyard-video.js +0 -80
  234. package/dist/extensions/vidyard-video.umd.js +0 -1
  235. package/dist/extensions/vimeo-video.d.ts +0 -2
  236. package/dist/extensions/vimeo-video.js +0 -76
  237. package/dist/extensions/vimeo-video.umd.js +0 -1
  238. package/dist/extensions/wistia-video.d.ts +0 -2
  239. package/dist/extensions/wistia-video.js +0 -85
  240. package/dist/extensions/wistia-video.umd.js +0 -1
  241. package/dist/extensions/youtube-video.d.ts +0 -2
  242. package/dist/extensions/youtube-video.js +0 -88
  243. package/dist/extensions/youtube-video.umd.js +0 -1
  244. package/dist/lib/components.d.ts.map +0 -1
  245. package/dist/lib/defaults/close.d.ts +0 -3
  246. package/dist/lib/defaults/close.d.ts.map +0 -1
  247. package/dist/lib/defaults/image-setup.d.ts +0 -4
  248. package/dist/lib/defaults/image-setup.d.ts.map +0 -1
  249. package/dist/lib/defaults/init.d.ts +0 -3
  250. package/dist/lib/defaults/init.d.ts.map +0 -1
  251. package/dist/lib/defaults/open.d.ts +0 -3
  252. package/dist/lib/defaults/open.d.ts.map +0 -1
  253. package/dist/lib/defaults/options.d.ts +0 -3
  254. package/dist/lib/defaults/options.d.ts.map +0 -1
  255. package/dist/lib/defaults/transition.d.ts.map +0 -1
  256. package/dist/lib/extensions/dailymotion-video.d.ts.map +0 -1
  257. package/dist/lib/extensions/download.d.ts +0 -3
  258. package/dist/lib/extensions/download.d.ts.map +0 -1
  259. package/dist/lib/extensions/google-maps.d.ts.map +0 -1
  260. package/dist/lib/extensions/image-story.d.ts +0 -12
  261. package/dist/lib/extensions/image-story.d.ts.map +0 -1
  262. package/dist/lib/extensions/logger.d.ts +0 -3
  263. package/dist/lib/extensions/logger.d.ts.map +0 -1
  264. package/dist/lib/extensions/mapbox.d.ts.map +0 -1
  265. package/dist/lib/extensions/openstreetmap.d.ts.map +0 -1
  266. package/dist/lib/extensions/select-box.d.ts.map +0 -1
  267. package/dist/lib/extensions/streamable-video.d.ts.map +0 -1
  268. package/dist/lib/extensions/twitch-video.d.ts.map +0 -1
  269. package/dist/lib/extensions/vidyard-video.d.ts.map +0 -1
  270. package/dist/lib/extensions/vimeo-video.d.ts.map +0 -1
  271. package/dist/lib/extensions/wistia-video.d.ts.map +0 -1
  272. package/dist/lib/extensions/youtube-video.d.ts.map +0 -1
  273. package/dist/lib/main.d.ts.map +0 -1
  274. package/dist/lib/throttle.d.ts.map +0 -1
  275. package/dist/lib/types.d.ts.map +0 -1
  276. package/dist/lib/utils/get-fitted-size.d.ts.map +0 -1
  277. package/dist/lib/utils/get-full-size-dim.d.ts.map +0 -1
  278. package/dist/lib/utils/get-style.d.ts.map +0 -1
  279. package/dist/lib/utils/index.d.ts.map +0 -1
  280. package/dist/lib/utils/is-not-zero-css.d.ts.map +0 -1
  281. package/dist/lib/utils/parse-element.d.ts.map +0 -1
  282. package/dist/lib/vista-box.d.ts.map +0 -1
  283. package/dist/lib/vista-hires-transition.d.ts.map +0 -1
  284. package/dist/lib/vista-image-event.d.ts.map +0 -1
  285. package/dist/lib/vista-image.d.ts.map +0 -1
  286. package/dist/lib/vista-pointers.d.ts.map +0 -1
  287. package/dist/lib/vista-state.d.ts.map +0 -1
  288. package/dist/lib/vista-view.d.ts.map +0 -1
  289. package/dist/react.d.ts +0 -11
  290. package/dist/react.d.ts.map +0 -1
  291. package/dist/react.js +0 -69
  292. package/dist/solid.d.ts +0 -3
  293. package/dist/solid.d.ts.map +0 -1
  294. package/dist/solid.js +0 -24
  295. package/dist/style.css +0 -1
  296. package/dist/style.d.ts +0 -1
  297. package/dist/styles/autumn-amber.css +0 -1
  298. package/dist/styles/autumn-amber.d.ts +0 -1
  299. package/dist/styles/cotton-candy.css +0 -1
  300. package/dist/styles/cotton-candy.d.ts +0 -1
  301. package/dist/styles/dark-rounded.css +0 -1
  302. package/dist/styles/dark-rounded.d.ts +0 -1
  303. package/dist/styles/ember-glow.css +0 -1
  304. package/dist/styles/ember-glow.d.ts +0 -1
  305. package/dist/styles/extensions/image-story.css +0 -1
  306. package/dist/styles/extensions/image-story.d.ts +0 -1
  307. package/dist/styles/forest-moss.css +0 -1
  308. package/dist/styles/forest-moss.d.ts +0 -1
  309. package/dist/styles/green-lake.css +0 -1
  310. package/dist/styles/green-lake.d.ts +0 -1
  311. package/dist/styles/ice-crystal.css +0 -1
  312. package/dist/styles/ice-crystal.d.ts +0 -1
  313. package/dist/styles/lavender-fields.css +0 -1
  314. package/dist/styles/lavender-fields.d.ts +0 -1
  315. package/dist/styles/midnight-gold.css +0 -1
  316. package/dist/styles/midnight-gold.d.ts +0 -1
  317. package/dist/styles/midnight-ocean.css +0 -1
  318. package/dist/styles/midnight-ocean.d.ts +0 -1
  319. package/dist/styles/mint-chocolate.css +0 -1
  320. package/dist/styles/mint-chocolate.d.ts +0 -1
  321. package/dist/styles/neon-nights.css +0 -1
  322. package/dist/styles/neon-nights.d.ts +0 -1
  323. package/dist/styles/paper-light.css +0 -1
  324. package/dist/styles/paper-light.d.ts +0 -1
  325. package/dist/styles/retro-arcade.css +0 -1
  326. package/dist/styles/retro-arcade.d.ts +0 -1
  327. package/dist/styles/soft-neutral.css +0 -1
  328. package/dist/styles/soft-neutral.d.ts +0 -1
  329. package/dist/styles/stark-minimal.css +0 -1
  330. package/dist/styles/stark-minimal.d.ts +0 -1
  331. package/dist/styles/strawberry.css +0 -1
  332. package/dist/styles/strawberry.d.ts +0 -1
  333. package/dist/svelte.d.ts +0 -3
  334. package/dist/svelte.d.ts.map +0 -1
  335. package/dist/svelte.js +0 -22
  336. package/dist/vista-box-zG6ZgBcI.js +0 -334
  337. package/dist/vistaview.d.ts.map +0 -1
  338. package/dist/vistaview.js +0 -1013
  339. package/dist/vistaview.umd.js +0 -18
  340. package/dist/vue.d.ts +0 -25
  341. package/dist/vue.d.ts.map +0 -1
  342. package/dist/vue.js +0 -79
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MotionRail
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,81 +1,34 @@
1
1
  # VistaView
2
2
 
3
- A lightweight, modern image lightbox library for the web. Zero dependencies, framework-agnostic, and highly customizable.
3
+ A lightweight, zero-dependency image lightbox library with smooth animations and touch support.
4
4
 
5
- For full documentation, visit [https://vistaview.jujiplay.com/](https://vistaview.jujiplay.com/)
5
+ ## Packages
6
6
 
7
- ## Features
7
+ | Path | Description |
8
+ |------|-------------|
9
+ | `main/` | Core library |
10
+ | `frameworks/` | React, Vue, Svelte, Solid bindings |
11
+ | `extensions/` | Optional plugins (video, maps, UI) |
12
+ | `doc/` | Documentation site (Astro + Starlight) |
8
13
 
9
- - 🪶 **Lightweight** — ~42KB ESM (~10KB gzip), minimal footprint
10
- - 📱 **Touch-first** — Swipe gestures for navigation and closing, pinch-to-zoom support
11
- - 🎨 **Customizable** — Configurable controls, animations, and styling via CSS variables
12
- - ♿ **Accessible** — Keyboard navigation, ARIA labels, reduced motion support
13
- - 🔧 **Framework-agnostic** — Works with vanilla JS, React, Vue, Svelte, Solid, or any framework
14
- - 🖼️ **Progressive loading** — Low-res thumbnails → high-res images with smooth transitions
15
- - 🔍 **Smart zoom** — Pan and zoom with momentum physics, respects actual image resolution
16
- - 🎯 **Pointer-aware** — Advanced multi-touch tracking with context menu prevention
17
- - 🎬 **Video embeds** — Support for YouTube, Vimeo, Dailymotion, Wistia, Vidyard, Streamable
18
- - 🗺️ **Map embeds** — Support for Google Maps, Mapbox, OpenStreetMap with interactive controls
14
+ ## Extensions
19
15
 
20
- ## Installation
21
-
22
- ```bash
23
- npm install vistaview
24
- ```
25
-
26
- ### Using CDN (UMD)
27
-
28
- For quick prototyping or non-bundler environments, use the UMD build via CDN:
29
-
30
- ```html
31
- <!-- unpkg -->
32
- <link rel="stylesheet" href="https://unpkg.com/vistaview/dist/style.css" />
33
- <script src="https://unpkg.com/vistaview/dist/vistaview.umd.js"></script>
34
-
35
- <!-- or jsDelivr -->
36
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vistaview/dist/style.css" />
37
- <script src="https://cdn.jsdelivr.net/npm/vistaview/dist/vistaview.umd.js"></script>
38
-
39
- <script>
40
- // VistaView is available globally
41
- VistaView.vistaView({
42
- elements: '#gallery a',
43
- });
44
- </script>
45
- ```
16
+ Public extensions are documented at [opencode.ai](https://opencode.ai). Some extensions exist in the repo but are **not publicly documented** — they are available for use but don't appear in the sidebar or have dedicated doc pages (`select-box`, `twitch-video`).
46
17
 
47
18
  ## Quick Start
48
19
 
49
- ### Using anchor elements (recommended)
50
-
51
- ```html
52
- <div id="gallery">
53
- <a href="/images/photo1-full.jpg">
54
- <img src="/images/photo1-thumb.jpg" alt="Photo 1" />
55
- </a>
56
- <a href="/images/photo2-full.jpg">
57
- <img src="/images/photo2-thumb.jpg" alt="Photo 2" />
58
- </a>
59
- </div>
60
-
61
- <script type="module">
62
- import { vistaView } from 'vistaview';
63
- import 'vistaview/style.css';
64
-
65
- vistaView({
66
- elements: '#gallery a',
67
- });
68
- </script>
20
+ ```bash
21
+ pnpm install
22
+ pnpm dev
69
23
  ```
70
24
 
71
- ## Documentation
25
+ ## Test
72
26
 
73
- For full documentation, visit [https://vistaview.jujiplay.com/](https://vistaview.jujiplay.com/)
27
+ ```bash
28
+ pnpm test:core # Core library (170 tests)
29
+ pnpm test # All workspace packages with test scripts
30
+ ```
74
31
 
75
32
  ## License
76
33
 
77
34
  MIT
78
-
79
- ---
80
-
81
- [![Sponsor juji](https://img.shields.io/badge/sponsor-juji-ea4aaa?style=for-the-badge&logo=github)](https://github.com/sponsors/juji)
@@ -1,5 +1,5 @@
1
- import { VistaExtension, VistaImageParams } from '../types';
2
- import { VistaBox } from '../vista-box';
1
+ import type { VistaExtension, VistaImageParams } from 'vistaview';
2
+ import { VistaBox } from 'vistaview';
3
3
  /**
4
4
  * Parse Dailymotion URL and extract video ID
5
5
  * Supports various Dailymotion URL formats:
@@ -31,4 +31,4 @@ export declare class VistaDailymotionVideo extends VistaBox {
31
31
  } | undefined;
32
32
  }
33
33
  export declare function dailymotionVideo(): VistaExtension;
34
- //# sourceMappingURL=dailymotion-video.d.ts.map
34
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,cAAc,EAAE,gBAAgB,EAAa,MAAM,WAAW,CAAC;AACxF,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkBlE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQhE;AAED,qBAAa,qBAAsB,SAAQ,QAAQ;IACjD,OAAO,EAAE,cAAc,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;gBAEA,GAAG,EAAE,gBAAgB;IA0DjC,SAAS,CAAC,cAAc,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAU7D,iBAAiB;;;;CAGlB;AAED,wBAAgB,gBAAgB,IAAI,cAAc,CAiBjD"}
@@ -0,0 +1,72 @@
1
+ import { VistaBox } from "vistaview";
2
+ function parseDailymotionVideoId(e) {
3
+ if (!e) return null;
4
+ for (let t of [
5
+ /dailymotion\.com\/video\/([a-zA-Z0-9]+)/,
6
+ /dai\.ly\/([a-zA-Z0-9]+)/,
7
+ /dailymotion\.com\/embed\/video\/([a-zA-Z0-9]+)/
8
+ ]) {
9
+ let n = e.match(t);
10
+ if (n && n[1]) return n[1];
11
+ }
12
+ return null;
13
+ }
14
+ function getDailymotionThumbnail(e) {
15
+ let n = parseDailymotionVideoId(e);
16
+ if (!n) throw Error("Invalid Dailymotion video URL");
17
+ return `https://www.dailymotion.com/thumbnail/video/${n}`;
18
+ }
19
+ var VistaDailymotionVideo = class extends VistaBox {
20
+ element;
21
+ url;
22
+ constructor(e) {
23
+ super(e);
24
+ let r = e.elm.config.src;
25
+ this.url = r;
26
+ let i = document.createElement("div");
27
+ i.style.position = "relative";
28
+ let a = document.createElement("img");
29
+ i.appendChild(a), a.src = this.origin?.image.src || getDailymotionThumbnail(r), a.style.width = "100%", a.style.height = "100%", a.style.objectFit = "cover", a.classList.add("vvw--pulsing"), this.element = i, this.element.classList.add("vvw-img-hi");
30
+ let { width: o, height: s } = this.getFullSizeDim();
31
+ if (this.fullH = s, this.fullW = o, this.minW = this.fullW * .5, this.maxW = this.fullW, this.element.style.width = `${o}px`, this.element.style.height = `${s}px`, this.setSizes({
32
+ stableSize: !1,
33
+ initDimension: !0
34
+ }), this.pos === 0) {
35
+ let e = document.createElement("iframe");
36
+ e.frameBorder = "0", e.allow = "autoplay; fullscreen; picture-in-picture", e.allowFullscreen = !0, e.width = "100%", e.height = "100%", e.style.position = "absolute", e.style.top = "0", e.style.left = "0", e.style.opacity = "0", e.style.transition = "opacity 333ms ease", e.src = `https://www.dailymotion.com/embed/video/${parseDailymotionVideoId(r)}?autoplay=1`, i.appendChild(e), e.onload = () => {
37
+ e.style.opacity = "1", a.classList.remove("vvw--pulsing");
38
+ };
39
+ }
40
+ this.isLoadedResolved(!0);
41
+ }
42
+ getFullSizeDim() {
43
+ let e = Math.min(window.innerWidth, 800);
44
+ return {
45
+ width: e,
46
+ height: e * 9 / 16
47
+ };
48
+ }
49
+ setFinalTransform() {
50
+ return super.setFinalTransform({ propagateEvent: !1 });
51
+ }
52
+ };
53
+ function dailymotionVideo() {
54
+ return {
55
+ name: "dailymotionVideo",
56
+ onInitializeImage: (e) => {
57
+ let n = e.elm.config.src;
58
+ if (parseDailymotionVideoId(n)) return new VistaDailymotionVideo(e);
59
+ },
60
+ onImageView: async (e, t) => {
61
+ let n = e.images.to[Math.floor(e.images.to.length / 2)];
62
+ n instanceof VistaDailymotionVideo && t.deactivateUi([
63
+ "download",
64
+ "zoomIn",
65
+ "zoomOut"
66
+ ], n);
67
+ }
68
+ };
69
+ }
70
+ export { VistaDailymotionVideo, dailymotionVideo, getDailymotionThumbnail, parseDailymotionVideoId };
71
+
72
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","names":[],"sources":["../src/main.ts"],"sourcesContent":["import type { VistaData, VistaExtension, VistaImageParams, VistaView } from 'vistaview';\nimport { VistaBox } from 'vistaview';\n\n/**\n * Parse Dailymotion URL and extract video ID\n * Supports various Dailymotion URL formats:\n * - https://www.dailymotion.com/video/VIDEO_ID\n * - https://dai.ly/VIDEO_ID\n * - https://www.dailymotion.com/embed/video/VIDEO_ID\n * @param url - Dailymotion video URL\n * @returns Video ID or null if not found\n */\nexport function parseDailymotionVideoId(url: string): string | null {\n if (!url) return null;\n\n // Try different Dailymotion URL patterns\n const patterns = [\n /dailymotion\\.com\\/video\\/([a-zA-Z0-9]+)/,\n /dai\\.ly\\/([a-zA-Z0-9]+)/,\n /dailymotion\\.com\\/embed\\/video\\/([a-zA-Z0-9]+)/,\n ];\n\n for (const pattern of patterns) {\n const match = url.match(pattern);\n if (match && match[1]) {\n return match[1];\n }\n }\n\n return null;\n}\n\n/**\n * Get Dailymotion video thumbnail URL\n * @param videoUrl - Dailymotion video URL\n * @param quality - Thumbnail quality: 'large' | 'medium' | 'small'\n * @returns Thumbnail URL\n */\nexport function getDailymotionThumbnail(videoUrl: string): string {\n const videoId = parseDailymotionVideoId(videoUrl);\n if (!videoId) {\n throw new Error('Invalid Dailymotion video URL');\n }\n\n // Dailymotion thumbnail URL pattern\n return `https://www.dailymotion.com/thumbnail/video/${videoId}`;\n}\n\nexport class VistaDailymotionVideo extends VistaBox {\n element: HTMLDivElement;\n url: string;\n\n constructor(par: VistaImageParams) {\n super(par);\n\n const url = par.elm.config.src;\n this.url = url;\n\n const div = document.createElement('div');\n div.style.position = 'relative';\n const image = document.createElement('img');\n div.appendChild(image);\n image.src = this.origin?.image.src || getDailymotionThumbnail(url);\n image.style.width = '100%';\n image.style.height = '100%';\n image.style.objectFit = 'cover';\n image.classList.add('vvw--pulsing');\n\n this.element = div;\n\n this.element.classList.add('vvw-img-hi');\n\n // set sizes\n const { width: fullWidth, height: fullHeight } = this.getFullSizeDim();\n this.fullH = fullHeight;\n this.fullW = fullWidth;\n this.minW = this.fullW * 0.5;\n this.maxW = this.fullW; // no scaling\n this.element.style.width = `${fullWidth}px`;\n this.element.style.height = `${fullHeight}px`;\n\n // trigger setSizes to setup thumb and iframe initial style\n this.setSizes({ stableSize: false, initDimension: true });\n\n if (this.pos === 0) {\n const iframe = document.createElement('iframe');\n iframe.frameBorder = '0';\n iframe.allow = 'autoplay; fullscreen; picture-in-picture';\n iframe.allowFullscreen = true;\n iframe.width = '100%';\n iframe.height = '100%';\n iframe.style.position = 'absolute';\n iframe.style.top = '0';\n iframe.style.left = '0';\n iframe.style.opacity = '0';\n iframe.style.transition = 'opacity 333ms ease';\n iframe.src = `https://www.dailymotion.com/embed/video/${parseDailymotionVideoId(url)}?autoplay=1`;\n div.appendChild(iframe);\n\n iframe.onload = () => {\n iframe.style.opacity = '1';\n image.classList.remove('vvw--pulsing');\n };\n }\n\n this.isLoadedResolved!(true);\n }\n\n // the default full size is the scaled thumbnail size\n // so we change it to 16:9 full window width size (or max 800px)\n protected getFullSizeDim(): { width: number; height: number } {\n const maxWidth = Math.min(window.innerWidth, 800);\n return {\n width: maxWidth,\n height: (maxWidth * 9) / 16,\n };\n }\n\n // override to avoid propagating content change event\n // (because no change will happen on iframe)\n setFinalTransform() {\n return super.setFinalTransform({ propagateEvent: false });\n }\n}\n\nexport function dailymotionVideo(): VistaExtension {\n return {\n name: 'dailymotionVideo',\n onInitializeImage: (params: VistaImageParams) => {\n const url = params.elm.config.src;\n const videoId = parseDailymotionVideoId(url);\n if (!videoId) return;\n\n return new VistaDailymotionVideo(params);\n },\n onImageView: async (data: VistaData, v: VistaView) => {\n const mainData = data.images.to![Math.floor(data.images.to!.length / 2)];\n if (mainData instanceof VistaDailymotionVideo) {\n v.deactivateUi(['download', 'zoomIn', 'zoomOut'], mainData);\n }\n },\n };\n}\n"],"mappings":";AAYA,SAAgB,wBAAwB,GAA4B;AAClE,KAAI,CAAC,EAAK,QAAO;AASjB,MAAK,IAAM,KANM;EACf;EACA;EACA;EACD,EAE+B;EAC9B,IAAM,IAAQ,EAAI,MAAM,EAAQ;AAChC,MAAI,KAAS,EAAM,GACjB,QAAO,EAAM;;AAIjB,QAAO;;AAST,SAAgB,wBAAwB,GAA0B;CAChE,IAAM,IAAU,wBAAwB,EAAS;AACjD,KAAI,CAAC,EACH,OAAU,MAAM,gCAAgC;AAIlD,QAAO,+CAA+C;;AAGxD,IAAa,wBAAb,cAA2C,SAAS;CAClD;CACA;CAEA,YAAY,GAAuB;AACjC,QAAM,EAAI;EAEV,IAAM,IAAM,EAAI,IAAI,OAAO;AAC3B,OAAK,MAAM;EAEX,IAAM,IAAM,SAAS,cAAc,MAAM;AACzC,IAAI,MAAM,WAAW;EACrB,IAAM,IAAQ,SAAS,cAAc,MAAM;AAU3C,EATA,EAAI,YAAY,EAAM,EACtB,EAAM,MAAM,KAAK,QAAQ,MAAM,OAAO,wBAAwB,EAAI,EAClE,EAAM,MAAM,QAAQ,QACpB,EAAM,MAAM,SAAS,QACrB,EAAM,MAAM,YAAY,SACxB,EAAM,UAAU,IAAI,eAAe,EAEnC,KAAK,UAAU,GAEf,KAAK,QAAQ,UAAU,IAAI,aAAa;EAGxC,IAAM,EAAE,OAAO,GAAW,QAAQ,MAAe,KAAK,gBAAgB;AAWtE,MAVA,KAAK,QAAQ,GACb,KAAK,QAAQ,GACb,KAAK,OAAO,KAAK,QAAQ,IACzB,KAAK,OAAO,KAAK,OACjB,KAAK,QAAQ,MAAM,QAAQ,GAAG,EAAU,KACxC,KAAK,QAAQ,MAAM,SAAS,GAAG,EAAW,KAG1C,KAAK,SAAS;GAAE,YAAY;GAAO,eAAe;GAAM,CAAC,EAErD,KAAK,QAAQ,GAAG;GAClB,IAAM,IAAS,SAAS,cAAc,SAAS;AAc/C,GAbA,EAAO,cAAc,KACrB,EAAO,QAAQ,4CACf,EAAO,kBAAkB,IACzB,EAAO,QAAQ,QACf,EAAO,SAAS,QAChB,EAAO,MAAM,WAAW,YACxB,EAAO,MAAM,MAAM,KACnB,EAAO,MAAM,OAAO,KACpB,EAAO,MAAM,UAAU,KACvB,EAAO,MAAM,aAAa,sBAC1B,EAAO,MAAM,2CAA2C,wBAAwB,EAAI,CAAC,cACrF,EAAI,YAAY,EAAO,EAEvB,EAAO,eAAe;AAEpB,IADA,EAAO,MAAM,UAAU,KACvB,EAAM,UAAU,OAAO,eAAe;;;AAI1C,OAAK,iBAAkB,GAAK;;CAK9B,iBAA8D;EAC5D,IAAM,IAAW,KAAK,IAAI,OAAO,YAAY,IAAI;AACjD,SAAO;GACL,OAAO;GACP,QAAS,IAAW,IAAK;GAC1B;;CAKH,oBAAoB;AAClB,SAAO,MAAM,kBAAkB,EAAE,gBAAgB,IAAO,CAAC;;;AAI7D,SAAgB,mBAAmC;AACjD,QAAO;EACL,MAAM;EACN,oBAAoB,MAA6B;GAC/C,IAAM,IAAM,EAAO,IAAI,OAAO;AACd,+BAAwB,EAAI,CAG5C,QAAO,IAAI,sBAAsB,EAAO;;EAE1C,aAAa,OAAO,GAAiB,MAAiB;GACpD,IAAM,IAAW,EAAK,OAAO,GAAI,KAAK,MAAM,EAAK,OAAO,GAAI,SAAS,EAAE;AACvE,GAAI,aAAoB,yBACtB,EAAE,aAAa;IAAC;IAAY;IAAU;IAAU,EAAE,EAAS;;EAGhE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=main.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.test.d.ts","sourceRoot":"","sources":["../src/main.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`vistaview`)):typeof define==`function`&&define.amd?define([`exports`,`vistaview`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.VistaView=e.VistaView||{},e.VistaView))})(this,function(e,t){function n(e){if(!e)return null;for(let t of[/dailymotion\.com\/video\/([a-zA-Z0-9]+)/,/dai\.ly\/([a-zA-Z0-9]+)/,/dailymotion\.com\/embed\/video\/([a-zA-Z0-9]+)/]){let n=e.match(t);if(n&&n[1])return n[1]}return null}function r(e){let t=n(e);if(!t)throw Error(`Invalid Dailymotion video URL`);return`https://www.dailymotion.com/thumbnail/video/${t}`}var i=class extends t.VistaBox{element;url;constructor(e){super(e);let t=e.elm.config.src;this.url=t;let i=document.createElement(`div`);i.style.position=`relative`;let a=document.createElement(`img`);i.appendChild(a),a.src=this.origin?.image.src||r(t),a.style.width=`100%`,a.style.height=`100%`,a.style.objectFit=`cover`,a.classList.add(`vvw--pulsing`),this.element=i,this.element.classList.add(`vvw-img-hi`);let{width:o,height:s}=this.getFullSizeDim();if(this.fullH=s,this.fullW=o,this.minW=this.fullW*.5,this.maxW=this.fullW,this.element.style.width=`${o}px`,this.element.style.height=`${s}px`,this.setSizes({stableSize:!1,initDimension:!0}),this.pos===0){let e=document.createElement(`iframe`);e.frameBorder=`0`,e.allow=`autoplay; fullscreen; picture-in-picture`,e.allowFullscreen=!0,e.width=`100%`,e.height=`100%`,e.style.position=`absolute`,e.style.top=`0`,e.style.left=`0`,e.style.opacity=`0`,e.style.transition=`opacity 333ms ease`,e.src=`https://www.dailymotion.com/embed/video/${n(t)}?autoplay=1`,i.appendChild(e),e.onload=()=>{e.style.opacity=`1`,a.classList.remove(`vvw--pulsing`)}}this.isLoadedResolved(!0)}getFullSizeDim(){let e=Math.min(window.innerWidth,800);return{width:e,height:e*9/16}}setFinalTransform(){return super.setFinalTransform({propagateEvent:!1})}};function a(){return{name:`dailymotionVideo`,onInitializeImage:e=>{let t=e.elm.config.src;if(n(t))return new i(e)},onImageView:async(e,t)=>{let n=e.images.to[Math.floor(e.images.to.length/2)];n instanceof i&&t.deactivateUi([`download`,`zoomIn`,`zoomOut`],n)}}}e.VistaDailymotionVideo=i,e.dailymotionVideo=a,e.getDailymotionThumbnail=r,e.parseDailymotionVideoId=n});
2
+ //# sourceMappingURL=main.umd.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.umd.cjs","names":[],"sources":["../src/main.ts"],"sourcesContent":["import type { VistaData, VistaExtension, VistaImageParams, VistaView } from 'vistaview';\nimport { VistaBox } from 'vistaview';\n\n/**\n * Parse Dailymotion URL and extract video ID\n * Supports various Dailymotion URL formats:\n * - https://www.dailymotion.com/video/VIDEO_ID\n * - https://dai.ly/VIDEO_ID\n * - https://www.dailymotion.com/embed/video/VIDEO_ID\n * @param url - Dailymotion video URL\n * @returns Video ID or null if not found\n */\nexport function parseDailymotionVideoId(url: string): string | null {\n if (!url) return null;\n\n // Try different Dailymotion URL patterns\n const patterns = [\n /dailymotion\\.com\\/video\\/([a-zA-Z0-9]+)/,\n /dai\\.ly\\/([a-zA-Z0-9]+)/,\n /dailymotion\\.com\\/embed\\/video\\/([a-zA-Z0-9]+)/,\n ];\n\n for (const pattern of patterns) {\n const match = url.match(pattern);\n if (match && match[1]) {\n return match[1];\n }\n }\n\n return null;\n}\n\n/**\n * Get Dailymotion video thumbnail URL\n * @param videoUrl - Dailymotion video URL\n * @param quality - Thumbnail quality: 'large' | 'medium' | 'small'\n * @returns Thumbnail URL\n */\nexport function getDailymotionThumbnail(videoUrl: string): string {\n const videoId = parseDailymotionVideoId(videoUrl);\n if (!videoId) {\n throw new Error('Invalid Dailymotion video URL');\n }\n\n // Dailymotion thumbnail URL pattern\n return `https://www.dailymotion.com/thumbnail/video/${videoId}`;\n}\n\nexport class VistaDailymotionVideo extends VistaBox {\n element: HTMLDivElement;\n url: string;\n\n constructor(par: VistaImageParams) {\n super(par);\n\n const url = par.elm.config.src;\n this.url = url;\n\n const div = document.createElement('div');\n div.style.position = 'relative';\n const image = document.createElement('img');\n div.appendChild(image);\n image.src = this.origin?.image.src || getDailymotionThumbnail(url);\n image.style.width = '100%';\n image.style.height = '100%';\n image.style.objectFit = 'cover';\n image.classList.add('vvw--pulsing');\n\n this.element = div;\n\n this.element.classList.add('vvw-img-hi');\n\n // set sizes\n const { width: fullWidth, height: fullHeight } = this.getFullSizeDim();\n this.fullH = fullHeight;\n this.fullW = fullWidth;\n this.minW = this.fullW * 0.5;\n this.maxW = this.fullW; // no scaling\n this.element.style.width = `${fullWidth}px`;\n this.element.style.height = `${fullHeight}px`;\n\n // trigger setSizes to setup thumb and iframe initial style\n this.setSizes({ stableSize: false, initDimension: true });\n\n if (this.pos === 0) {\n const iframe = document.createElement('iframe');\n iframe.frameBorder = '0';\n iframe.allow = 'autoplay; fullscreen; picture-in-picture';\n iframe.allowFullscreen = true;\n iframe.width = '100%';\n iframe.height = '100%';\n iframe.style.position = 'absolute';\n iframe.style.top = '0';\n iframe.style.left = '0';\n iframe.style.opacity = '0';\n iframe.style.transition = 'opacity 333ms ease';\n iframe.src = `https://www.dailymotion.com/embed/video/${parseDailymotionVideoId(url)}?autoplay=1`;\n div.appendChild(iframe);\n\n iframe.onload = () => {\n iframe.style.opacity = '1';\n image.classList.remove('vvw--pulsing');\n };\n }\n\n this.isLoadedResolved!(true);\n }\n\n // the default full size is the scaled thumbnail size\n // so we change it to 16:9 full window width size (or max 800px)\n protected getFullSizeDim(): { width: number; height: number } {\n const maxWidth = Math.min(window.innerWidth, 800);\n return {\n width: maxWidth,\n height: (maxWidth * 9) / 16,\n };\n }\n\n // override to avoid propagating content change event\n // (because no change will happen on iframe)\n setFinalTransform() {\n return super.setFinalTransform({ propagateEvent: false });\n }\n}\n\nexport function dailymotionVideo(): VistaExtension {\n return {\n name: 'dailymotionVideo',\n onInitializeImage: (params: VistaImageParams) => {\n const url = params.elm.config.src;\n const videoId = parseDailymotionVideoId(url);\n if (!videoId) return;\n\n return new VistaDailymotionVideo(params);\n },\n onImageView: async (data: VistaData, v: VistaView) => {\n const mainData = data.images.to![Math.floor(data.images.to!.length / 2)];\n if (mainData instanceof VistaDailymotionVideo) {\n v.deactivateUi(['download', 'zoomIn', 'zoomOut'], mainData);\n }\n },\n };\n}\n"],"mappings":"gRAYA,SAAgB,EAAwB,EAA4B,CAClE,GAAI,CAAC,EAAK,OAAO,KASjB,IAAK,IAAM,IANM,CACf,0CACA,0BACA,iDACD,CAE+B,CAC9B,IAAM,EAAQ,EAAI,MAAM,EAAQ,CAChC,GAAI,GAAS,EAAM,GACjB,OAAO,EAAM,GAIjB,OAAO,KAST,SAAgB,EAAwB,EAA0B,CAChE,IAAM,EAAU,EAAwB,EAAS,CACjD,GAAI,CAAC,EACH,MAAU,MAAM,gCAAgC,CAIlD,MAAO,+CAA+C,IAGxD,IAAa,EAAb,cAA2C,EAAA,QAAS,CAClD,QACA,IAEA,YAAY,EAAuB,CACjC,MAAM,EAAI,CAEV,IAAM,EAAM,EAAI,IAAI,OAAO,IAC3B,KAAK,IAAM,EAEX,IAAM,EAAM,SAAS,cAAc,MAAM,CACzC,EAAI,MAAM,SAAW,WACrB,IAAM,EAAQ,SAAS,cAAc,MAAM,CAC3C,EAAI,YAAY,EAAM,CACtB,EAAM,IAAM,KAAK,QAAQ,MAAM,KAAO,EAAwB,EAAI,CAClE,EAAM,MAAM,MAAQ,OACpB,EAAM,MAAM,OAAS,OACrB,EAAM,MAAM,UAAY,QACxB,EAAM,UAAU,IAAI,eAAe,CAEnC,KAAK,QAAU,EAEf,KAAK,QAAQ,UAAU,IAAI,aAAa,CAGxC,GAAM,CAAE,MAAO,EAAW,OAAQ,GAAe,KAAK,gBAAgB,CAWtE,GAVA,KAAK,MAAQ,EACb,KAAK,MAAQ,EACb,KAAK,KAAO,KAAK,MAAQ,GACzB,KAAK,KAAO,KAAK,MACjB,KAAK,QAAQ,MAAM,MAAQ,GAAG,EAAU,IACxC,KAAK,QAAQ,MAAM,OAAS,GAAG,EAAW,IAG1C,KAAK,SAAS,CAAE,WAAY,GAAO,cAAe,GAAM,CAAC,CAErD,KAAK,MAAQ,EAAG,CAClB,IAAM,EAAS,SAAS,cAAc,SAAS,CAC/C,EAAO,YAAc,IACrB,EAAO,MAAQ,2CACf,EAAO,gBAAkB,GACzB,EAAO,MAAQ,OACf,EAAO,OAAS,OAChB,EAAO,MAAM,SAAW,WACxB,EAAO,MAAM,IAAM,IACnB,EAAO,MAAM,KAAO,IACpB,EAAO,MAAM,QAAU,IACvB,EAAO,MAAM,WAAa,qBAC1B,EAAO,IAAM,2CAA2C,EAAwB,EAAI,CAAC,aACrF,EAAI,YAAY,EAAO,CAEvB,EAAO,WAAe,CACpB,EAAO,MAAM,QAAU,IACvB,EAAM,UAAU,OAAO,eAAe,EAI1C,KAAK,iBAAkB,GAAK,CAK9B,gBAA8D,CAC5D,IAAM,EAAW,KAAK,IAAI,OAAO,WAAY,IAAI,CACjD,MAAO,CACL,MAAO,EACP,OAAS,EAAW,EAAK,GAC1B,CAKH,mBAAoB,CAClB,OAAO,MAAM,kBAAkB,CAAE,eAAgB,GAAO,CAAC,GAI7D,SAAgB,GAAmC,CACjD,MAAO,CACL,KAAM,mBACN,kBAAoB,GAA6B,CAC/C,IAAM,EAAM,EAAO,IAAI,OAAO,IACd,KAAwB,EAAI,CAG5C,OAAO,IAAI,EAAsB,EAAO,EAE1C,YAAa,MAAO,EAAiB,IAAiB,CACpD,IAAM,EAAW,EAAK,OAAO,GAAI,KAAK,MAAM,EAAK,OAAO,GAAI,OAAS,EAAE,EACnE,aAAoB,GACtB,EAAE,aAAa,CAAC,WAAY,SAAU,UAAU,CAAE,EAAS,EAGhE"}
@@ -0,0 +1,4 @@
1
+ import type { VistaExtension } from 'vistaview';
2
+ export declare function getDownloadFileName(url: string, alt?: string | null): string;
3
+ export declare function download(): VistaExtension;
4
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,cAAc,EAAa,MAAM,WAAW,CAAC;AAMtE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAW5E;AAED,wBAAgB,QAAQ,IAAI,cAAc,CAuEzC"}
@@ -0,0 +1,42 @@
1
+ var downloadIcon = "<svg viewBox=\"0 0 24 24\"><path d=\"M12 15V3\"/><path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><path d=\"m7 10 5 5 5-5\"/></svg>";
2
+ function getDownloadFileName(e, t) {
3
+ let n = e.split("?")[0].split("#")[0].split("/").pop() || "", r = n.lastIndexOf(".");
4
+ if (r > -1) {
5
+ let e = n.slice(r + 1);
6
+ return t ? `${t}.${e}` : n;
7
+ }
8
+ return t || n || "download";
9
+ }
10
+ function download() {
11
+ let n = null, r = null, i = null;
12
+ return {
13
+ name: "download",
14
+ control: () => (i = document.createElement("button"), i.setAttribute("aria-label", "Download"), i.innerHTML = downloadIcon, i.addEventListener("click", async () => {
15
+ if (!n || i?.classList.contains("vvw--pulsing")) return;
16
+ i?.classList.add("vvw--pulsing");
17
+ let e = await fetch(n), a = await e.blob(), o = e.url, s = getDownloadFileName(o, r), c = document.createElement("a");
18
+ c.href = URL.createObjectURL(a), c.download = s, document.body.appendChild(c), c.click(), document.body.removeChild(c), a = null, e = null, i?.classList.remove("vvw--pulsing");
19
+ }), i),
20
+ onImageView: (e, t) => {
21
+ let i = e.images.to ? e.images.to[Math.floor(e.images.to.length / 2)] : null;
22
+ if (!i) {
23
+ n = null, r = null;
24
+ return;
25
+ }
26
+ let { parsedSrcSet: a, config: o } = i;
27
+ n = a && a.length > 0 ? a[a.length - 1].src : o.src || null, r = o.alt || null;
28
+ },
29
+ onDeactivateUi: (e, t, n) => {
30
+ e.includes("download") && i && i.setAttribute("disabled", "true");
31
+ },
32
+ onReactivateUi: (e, t, n) => {
33
+ e.includes("download") && i && i.removeAttribute("disabled");
34
+ },
35
+ onClose: (e) => {
36
+ i?.remove(), i = null, n = null, r = null;
37
+ }
38
+ };
39
+ }
40
+ export { download, getDownloadFileName };
41
+
42
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","names":["currentImage: string | null","currentAlt: string | null","button: HTMLButtonElement | null","response: Response | null","blob: Blob | null"],"sources":["../src/main.ts"],"sourcesContent":["import type { VistaData, VistaExtension, VistaView } from 'vistaview';\nimport type { VistaBox } from 'vistaview';\n\n// okayy\nconst downloadIcon = `<svg viewBox=\"0 0 24 24\"><path d=\"M12 15V3\"/><path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><path d=\"m7 10 5 5 5-5\"/></svg>`;\n\nexport function getDownloadFileName(url: string, alt?: string | null): string {\n const clean = url.split('?')[0].split('#')[0];\n const lastSegment = clean.split('/').pop() || '';\n const dotIndex = lastSegment.lastIndexOf('.');\n if (dotIndex > -1) {\n const ext = lastSegment.slice(dotIndex + 1);\n if (alt) return `${alt}.${ext}`;\n return lastSegment;\n }\n if (alt) return alt;\n return lastSegment || 'download';\n}\n\nexport function download(): VistaExtension {\n let currentImage: string | null = null;\n let currentAlt: string | null = null;\n let button: HTMLButtonElement | null = null;\n\n return {\n name: 'download',\n control: () => {\n button = document.createElement('button');\n button.setAttribute('aria-label', 'Download');\n button.innerHTML = downloadIcon;\n button.addEventListener('click', async () => {\n if (!currentImage) return;\n if (button?.classList.contains('vvw--pulsing')) return; // prevent multiple clicks\n button?.classList.add('vvw--pulsing');\n\n let response: Response | null = await fetch(currentImage);\n let blob: Blob | null = await response.blob();\n const finalUrl = response.url; // This is the redirected URL\n\n const fileName = getDownloadFileName(finalUrl, currentAlt);\n\n const link = document.createElement('a');\n link.href = URL.createObjectURL(blob);\n link.download = fileName;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n blob = null;\n response = null;\n button?.classList.remove('vvw--pulsing');\n });\n return button;\n },\n onImageView: (vistaData: VistaData, _v: VistaView) => {\n const centerImage = vistaData.images.to\n ? vistaData.images.to[Math.floor(vistaData.images.to.length / 2)]\n : null;\n\n if (!centerImage) {\n currentImage = null;\n currentAlt = null;\n return;\n }\n const { parsedSrcSet, config } = centerImage;\n\n // get the biggest image || the current image\n currentImage =\n parsedSrcSet && parsedSrcSet.length > 0\n ? parsedSrcSet[parsedSrcSet.length - 1].src\n : config.src || null;\n\n currentAlt = config.alt || null;\n },\n onDeactivateUi: (names: string[], _requestBy: VistaBox | null, _v: VistaView) => {\n if (names.includes('download') && button) {\n button.setAttribute('disabled', 'true');\n }\n },\n onReactivateUi: (names: string[], _requestBy: VistaBox | null, _v: VistaView) => {\n if (names.includes('download') && button) {\n button.removeAttribute('disabled');\n }\n },\n onClose: (_vistaView: VistaView) => {\n button?.remove();\n button = null;\n currentImage = null;\n currentAlt = null;\n },\n };\n}\n"],"mappings":"AAIA,IAAM,eAAe;AAErB,SAAgB,oBAAoB,GAAa,GAA6B;CAE5E,IAAM,IADQ,EAAI,MAAM,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,GACjB,MAAM,IAAI,CAAC,KAAK,IAAI,IACxC,IAAW,EAAY,YAAY,IAAI;AAC7C,KAAI,IAAW,IAAI;EACjB,IAAM,IAAM,EAAY,MAAM,IAAW,EAAE;AAE3C,SADI,IAAY,GAAG,EAAI,GAAG,MACnB;;AAGT,QADI,KACG,KAAe;;AAGxB,SAAgB,WAA2B;CACzC,IAAIA,IAA8B,MAC9BC,IAA4B,MAC5BC,IAAmC;AAEvC,QAAO;EACL,MAAM;EACN,gBACE,IAAS,SAAS,cAAc,SAAS,EACzC,EAAO,aAAa,cAAc,WAAW,EAC7C,EAAO,YAAY,cACnB,EAAO,iBAAiB,SAAS,YAAY;AAE3C,OADI,CAAC,KACD,GAAQ,UAAU,SAAS,eAAe,CAAE;AAChD,MAAQ,UAAU,IAAI,eAAe;GAErC,IAAIC,IAA4B,MAAM,MAAM,EAAa,EACrDC,IAAoB,MAAM,EAAS,MAAM,EACvC,IAAW,EAAS,KAEpB,IAAW,oBAAoB,GAAU,EAAW,EAEpD,IAAO,SAAS,cAAc,IAAI;AAQxC,GAPA,EAAK,OAAO,IAAI,gBAAgB,EAAK,EACrC,EAAK,WAAW,GAChB,SAAS,KAAK,YAAY,EAAK,EAC/B,EAAK,OAAO,EACZ,SAAS,KAAK,YAAY,EAAK,EAC/B,IAAO,MACP,IAAW,MACX,GAAQ,UAAU,OAAO,eAAe;IACxC,EACK;EAET,cAAc,GAAsB,MAAkB;GACpD,IAAM,IAAc,EAAU,OAAO,KACjC,EAAU,OAAO,GAAG,KAAK,MAAM,EAAU,OAAO,GAAG,SAAS,EAAE,IAC9D;AAEJ,OAAI,CAAC,GAAa;AAEhB,IADA,IAAe,MACf,IAAa;AACb;;GAEF,IAAM,EAAE,iBAAc,cAAW;AAQjC,GALA,IACE,KAAgB,EAAa,SAAS,IAClC,EAAa,EAAa,SAAS,GAAG,MACtC,EAAO,OAAO,MAEpB,IAAa,EAAO,OAAO;;EAE7B,iBAAiB,GAAiB,GAA6B,MAAkB;AAC/E,GAAI,EAAM,SAAS,WAAW,IAAI,KAChC,EAAO,aAAa,YAAY,OAAO;;EAG3C,iBAAiB,GAAiB,GAA6B,MAAkB;AAC/E,GAAI,EAAM,SAAS,WAAW,IAAI,KAChC,EAAO,gBAAgB,WAAW;;EAGtC,UAAU,MAA0B;AAIlC,GAHA,GAAQ,QAAQ,EAChB,IAAS,MACT,IAAe,MACf,IAAa;;EAEhB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=main.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.test.d.ts","sourceRoot":"","sources":["../src/main.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.VistaView=e.VistaView||{}))})(this,function(e){var t=`<svg viewBox="0 0 24 24"><path d="M12 15V3"/><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m7 10 5 5 5-5"/></svg>`;function n(e,t){let n=e.split(`?`)[0].split(`#`)[0].split(`/`).pop()||``,r=n.lastIndexOf(`.`);if(r>-1){let e=n.slice(r+1);return t?`${t}.${e}`:n}return t||n||`download`}function r(){let e=null,r=null,i=null;return{name:`download`,control:()=>(i=document.createElement(`button`),i.setAttribute(`aria-label`,`Download`),i.innerHTML=t,i.addEventListener(`click`,async()=>{if(!e||i?.classList.contains(`vvw--pulsing`))return;i?.classList.add(`vvw--pulsing`);let t=await fetch(e),a=await t.blob(),o=t.url,s=n(o,r),c=document.createElement(`a`);c.href=URL.createObjectURL(a),c.download=s,document.body.appendChild(c),c.click(),document.body.removeChild(c),a=null,t=null,i?.classList.remove(`vvw--pulsing`)}),i),onImageView:(t,n)=>{let i=t.images.to?t.images.to[Math.floor(t.images.to.length/2)]:null;if(!i){e=null,r=null;return}let{parsedSrcSet:a,config:o}=i;e=a&&a.length>0?a[a.length-1].src:o.src||null,r=o.alt||null},onDeactivateUi:(e,t,n)=>{e.includes(`download`)&&i&&i.setAttribute(`disabled`,`true`)},onReactivateUi:(e,t,n)=>{e.includes(`download`)&&i&&i.removeAttribute(`disabled`)},onClose:t=>{i?.remove(),i=null,e=null,r=null}}}e.download=r,e.getDownloadFileName=n});
2
+ //# sourceMappingURL=main.umd.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.umd.cjs","names":["currentImage: string | null","currentAlt: string | null","button: HTMLButtonElement | null","response: Response | null","blob: Blob | null"],"sources":["../src/main.ts"],"sourcesContent":["import type { VistaData, VistaExtension, VistaView } from 'vistaview';\nimport type { VistaBox } from 'vistaview';\n\n// okayy\nconst downloadIcon = `<svg viewBox=\"0 0 24 24\"><path d=\"M12 15V3\"/><path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><path d=\"m7 10 5 5 5-5\"/></svg>`;\n\nexport function getDownloadFileName(url: string, alt?: string | null): string {\n const clean = url.split('?')[0].split('#')[0];\n const lastSegment = clean.split('/').pop() || '';\n const dotIndex = lastSegment.lastIndexOf('.');\n if (dotIndex > -1) {\n const ext = lastSegment.slice(dotIndex + 1);\n if (alt) return `${alt}.${ext}`;\n return lastSegment;\n }\n if (alt) return alt;\n return lastSegment || 'download';\n}\n\nexport function download(): VistaExtension {\n let currentImage: string | null = null;\n let currentAlt: string | null = null;\n let button: HTMLButtonElement | null = null;\n\n return {\n name: 'download',\n control: () => {\n button = document.createElement('button');\n button.setAttribute('aria-label', 'Download');\n button.innerHTML = downloadIcon;\n button.addEventListener('click', async () => {\n if (!currentImage) return;\n if (button?.classList.contains('vvw--pulsing')) return; // prevent multiple clicks\n button?.classList.add('vvw--pulsing');\n\n let response: Response | null = await fetch(currentImage);\n let blob: Blob | null = await response.blob();\n const finalUrl = response.url; // This is the redirected URL\n\n const fileName = getDownloadFileName(finalUrl, currentAlt);\n\n const link = document.createElement('a');\n link.href = URL.createObjectURL(blob);\n link.download = fileName;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n blob = null;\n response = null;\n button?.classList.remove('vvw--pulsing');\n });\n return button;\n },\n onImageView: (vistaData: VistaData, _v: VistaView) => {\n const centerImage = vistaData.images.to\n ? vistaData.images.to[Math.floor(vistaData.images.to.length / 2)]\n : null;\n\n if (!centerImage) {\n currentImage = null;\n currentAlt = null;\n return;\n }\n const { parsedSrcSet, config } = centerImage;\n\n // get the biggest image || the current image\n currentImage =\n parsedSrcSet && parsedSrcSet.length > 0\n ? parsedSrcSet[parsedSrcSet.length - 1].src\n : config.src || null;\n\n currentAlt = config.alt || null;\n },\n onDeactivateUi: (names: string[], _requestBy: VistaBox | null, _v: VistaView) => {\n if (names.includes('download') && button) {\n button.setAttribute('disabled', 'true');\n }\n },\n onReactivateUi: (names: string[], _requestBy: VistaBox | null, _v: VistaView) => {\n if (names.includes('download') && button) {\n button.removeAttribute('disabled');\n }\n },\n onClose: (_vistaView: VistaView) => {\n button?.remove();\n button = null;\n currentImage = null;\n currentAlt = null;\n },\n };\n}\n"],"mappings":"iOAIA,IAAM,EAAe,oIAErB,SAAgB,EAAoB,EAAa,EAA6B,CAE5E,IAAM,EADQ,EAAI,MAAM,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,GACjB,MAAM,IAAI,CAAC,KAAK,EAAI,GACxC,EAAW,EAAY,YAAY,IAAI,CAC7C,GAAI,EAAW,GAAI,CACjB,IAAM,EAAM,EAAY,MAAM,EAAW,EAAE,CAE3C,OADI,EAAY,GAAG,EAAI,GAAG,IACnB,EAGT,OADI,GACG,GAAe,WAGxB,SAAgB,GAA2B,CACzC,IAAIA,EAA8B,KAC9BC,EAA4B,KAC5BC,EAAmC,KAEvC,MAAO,CACL,KAAM,WACN,aACE,EAAS,SAAS,cAAc,SAAS,CACzC,EAAO,aAAa,aAAc,WAAW,CAC7C,EAAO,UAAY,EACnB,EAAO,iBAAiB,QAAS,SAAY,CAE3C,GADI,CAAC,GACD,GAAQ,UAAU,SAAS,eAAe,CAAE,OAChD,GAAQ,UAAU,IAAI,eAAe,CAErC,IAAIC,EAA4B,MAAM,MAAM,EAAa,CACrDC,EAAoB,MAAM,EAAS,MAAM,CACvC,EAAW,EAAS,IAEpB,EAAW,EAAoB,EAAU,EAAW,CAEpD,EAAO,SAAS,cAAc,IAAI,CACxC,EAAK,KAAO,IAAI,gBAAgB,EAAK,CACrC,EAAK,SAAW,EAChB,SAAS,KAAK,YAAY,EAAK,CAC/B,EAAK,OAAO,CACZ,SAAS,KAAK,YAAY,EAAK,CAC/B,EAAO,KACP,EAAW,KACX,GAAQ,UAAU,OAAO,eAAe,EACxC,CACK,GAET,aAAc,EAAsB,IAAkB,CACpD,IAAM,EAAc,EAAU,OAAO,GACjC,EAAU,OAAO,GAAG,KAAK,MAAM,EAAU,OAAO,GAAG,OAAS,EAAE,EAC9D,KAEJ,GAAI,CAAC,EAAa,CAChB,EAAe,KACf,EAAa,KACb,OAEF,GAAM,CAAE,eAAc,UAAW,EAGjC,EACE,GAAgB,EAAa,OAAS,EAClC,EAAa,EAAa,OAAS,GAAG,IACtC,EAAO,KAAO,KAEpB,EAAa,EAAO,KAAO,MAE7B,gBAAiB,EAAiB,EAA6B,IAAkB,CAC3E,EAAM,SAAS,WAAW,EAAI,GAChC,EAAO,aAAa,WAAY,OAAO,EAG3C,gBAAiB,EAAiB,EAA6B,IAAkB,CAC3E,EAAM,SAAS,WAAW,EAAI,GAChC,EAAO,gBAAgB,WAAW,EAGtC,QAAU,GAA0B,CAClC,GAAQ,QAAQ,CAChB,EAAS,KACT,EAAe,KACf,EAAa,MAEhB"}
@@ -1,5 +1,5 @@
1
- import { VistaExtension, VistaImageParams } from '../types';
2
- import { VistaBox } from '../vista-box';
1
+ import type { VistaExtension, VistaImageParams } from 'vistaview';
2
+ import { VistaBox } from 'vistaview';
3
3
  export interface GoogleMapsConfig {
4
4
  apiKey?: string;
5
5
  zoom?: number;
@@ -46,4 +46,4 @@ export declare class VistaGoogleMaps extends VistaBox {
46
46
  } | undefined;
47
47
  }
48
48
  export declare function googleMaps(config?: GoogleMapsConfig): VistaExtension;
49
- //# sourceMappingURL=google-maps.d.ts.map
49
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,cAAc,EAAE,gBAAgB,EAAa,MAAM,WAAW,CAAC;AACxF,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;CAC1D;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CA4C9E;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,kBAAkB,EAC5B,MAAM,EAAE,gBAAgB,GACvB,MAAM,CAcR;AAED,qBAAa,eAAgB,SAAQ,QAAQ;IAC3C,OAAO,EAAE,cAAc,CAAC;IACxB,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,QAAQ,CAAqB;gBAEzB,GAAG,EAAE,gBAAgB,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,CAAC,EAAE,gBAAgB;IAmE1F,SAAS,CAAC,cAAc,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAS7D,iBAAiB;;;;CAGlB;AAED,wBAAgB,UAAU,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG,cAAc,CAiBpE"}
@@ -0,0 +1,96 @@
1
+ import { VistaBox } from "vistaview";
2
+ function parseGoogleMapsLocation(e) {
3
+ if (!e) return null;
4
+ try {
5
+ let t = new URL(e), n = e.match(/@(-?\d+\.?\d*),(-?\d+\.?\d*),?(\d+\.?\d*)?z?/);
6
+ if (n) return {
7
+ lat: parseFloat(n[1]),
8
+ lng: parseFloat(n[2]),
9
+ zoom: n[3] ? parseFloat(n[3]) : void 0
10
+ };
11
+ let r = t.searchParams.get("q");
12
+ if (r) {
13
+ let e = r.match(/(-?\d+\.?\d*),\s*(-?\d+\.?\d*)/);
14
+ return e ? {
15
+ lat: parseFloat(e[1]),
16
+ lng: parseFloat(e[2]),
17
+ query: r
18
+ } : {
19
+ lat: 0,
20
+ lng: 0,
21
+ query: r
22
+ };
23
+ }
24
+ let i = t.searchParams.get("ll");
25
+ if (i) {
26
+ let [e, t] = i.split(",").map(parseFloat);
27
+ if (!isNaN(e) && !isNaN(t)) return {
28
+ lat: e,
29
+ lng: t
30
+ };
31
+ }
32
+ } catch (e) {
33
+ console.error("Failed to parse Google Maps URL:", e);
34
+ }
35
+ return null;
36
+ }
37
+ function getGoogleMapsStaticImage(e, t) {
38
+ if (!t.apiKey) throw Error("Google Maps API key is required");
39
+ let n = e.zoom || t.zoom || 15, r = t.width || 800, i = t.height || 600, a = t.mapType || "roadmap", o = e.query || `${e.lat},${e.lng}`, s = e.query ? "" : `&markers=color:red|${e.lat},${e.lng}`;
40
+ return `https://maps.googleapis.com/maps/api/staticmap?center=${encodeURIComponent(o)}&zoom=${n}&size=${r}x${i}&maptype=${a}${s}&key=${t.apiKey}`;
41
+ }
42
+ var VistaGoogleMaps = class extends VistaBox {
43
+ element;
44
+ mapsConfig;
45
+ location;
46
+ constructor(e, t, r) {
47
+ super(e), this.mapsConfig = r || {}, this.location = t;
48
+ let i = document.createElement("div");
49
+ i.style.position = "relative";
50
+ let a = document.createElement("img");
51
+ i.appendChild(a), a.src = this.origin?.image.src || (r && r.apiKey ? getGoogleMapsStaticImage(t, r) : ""), a.style.width = "100%", a.style.height = "100%", a.style.objectFit = "cover", a.classList.add("vvw--pulsing"), this.element = i, this.element.classList.add("vvw-img-hi");
52
+ let { width: o, height: s } = this.getFullSizeDim();
53
+ if (this.fullH = s, this.fullW = o, this.minW = this.fullW * .5, this.maxW = this.fullW, this.element.style.width = `${o}px`, this.element.style.height = `${s}px`, this.setSizes({
54
+ stableSize: !1,
55
+ initDimension: !0
56
+ }), this.pos === 0) {
57
+ let e = document.createElement("iframe");
58
+ e.frameBorder = "0", e.allow = "geolocation", e.allowFullscreen = !0, e.width = "100%", e.height = "100%", e.style.position = "absolute", e.style.top = "0", e.style.left = "0", e.style.opacity = "0", e.style.transition = "opacity 1s ease";
59
+ let t;
60
+ t = this.location.query ? `https://www.google.com/maps?q=${encodeURIComponent(this.location.query)}&output=embed` : `https://www.google.com/maps?q=${this.location.lat},${this.location.lng}&output=embed`, e.src = t, i.appendChild(e), e.onload = () => {
61
+ e.style.opacity = "1", a.classList.remove("vvw--pulsing");
62
+ };
63
+ }
64
+ this.isLoadedResolved(!0);
65
+ }
66
+ getFullSizeDim() {
67
+ let e = Math.min(window.innerWidth, this.mapsConfig.width || 800);
68
+ return {
69
+ width: e,
70
+ height: e * 9 / 16
71
+ };
72
+ }
73
+ setFinalTransform() {
74
+ return super.setFinalTransform({ propagateEvent: !1 });
75
+ }
76
+ };
77
+ function googleMaps(e) {
78
+ return {
79
+ name: "googleMaps",
80
+ onInitializeImage: (n) => {
81
+ let i = n.elm.config.src, a = parseGoogleMapsLocation(i);
82
+ if (a) return new VistaGoogleMaps(n, a, e);
83
+ },
84
+ onImageView: async (e, t) => {
85
+ let n = e.images.to[Math.floor(e.images.to.length / 2)];
86
+ n instanceof VistaGoogleMaps && t.deactivateUi([
87
+ "download",
88
+ "zoomIn",
89
+ "zoomOut"
90
+ ], n);
91
+ }
92
+ };
93
+ }
94
+ export { VistaGoogleMaps, getGoogleMapsStaticImage, googleMaps, parseGoogleMapsLocation };
95
+
96
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","names":["embedUrl: string"],"sources":["../src/main.ts"],"sourcesContent":["import type { VistaData, VistaExtension, VistaImageParams, VistaView } from 'vistaview';\nimport { VistaBox } from 'vistaview';\n\nexport interface GoogleMapsConfig {\n apiKey?: string;\n zoom?: number; // Default zoom level (1-20)\n width?: number; // Map width in pixels\n height?: number; // Map height in pixels\n mapType?: 'roadmap' | 'satellite' | 'hybrid' | 'terrain';\n}\n\nexport interface GoogleMapsLocation {\n lat: number;\n lng: number;\n zoom?: number;\n query?: string;\n}\n\n/**\n * Parse Google Maps URL and extract location data\n * Supports various Google Maps URL formats:\n * - https://www.google.com/maps?q=40.7128,-74.0060\n * - https://www.google.com/maps/@40.7128,-74.0060,15z\n * - https://maps.google.com?q=40.7128,-74.0060\n * - https://goo.gl/maps/...\n * @param url - Google Maps URL\n * @returns Location data or null if not found\n */\nexport function parseGoogleMapsLocation(url: string): GoogleMapsLocation | null {\n if (!url) return null;\n\n try {\n const urlObj = new URL(url);\n\n // Check for @lat,lng,zoom format\n const atMatch = url.match(/@(-?\\d+\\.?\\d*),(-?\\d+\\.?\\d*),?(\\d+\\.?\\d*)?z?/);\n if (atMatch) {\n return {\n lat: parseFloat(atMatch[1]),\n lng: parseFloat(atMatch[2]),\n zoom: atMatch[3] ? parseFloat(atMatch[3]) : undefined,\n };\n }\n\n // Check for q=lat,lng format\n const qParam = urlObj.searchParams.get('q');\n if (qParam) {\n const coordMatch = qParam.match(/(-?\\d+\\.?\\d*),\\s*(-?\\d+\\.?\\d*)/);\n if (coordMatch) {\n return {\n lat: parseFloat(coordMatch[1]),\n lng: parseFloat(coordMatch[2]),\n query: qParam,\n };\n }\n // If q param doesn't contain coordinates, store it as a query\n return { lat: 0, lng: 0, query: qParam };\n }\n\n // Check for ll= parameter (lat,lng)\n const llParam = urlObj.searchParams.get('ll');\n if (llParam) {\n const [lat, lng] = llParam.split(',').map(parseFloat);\n if (!isNaN(lat) && !isNaN(lng)) {\n return { lat, lng };\n }\n }\n } catch (error) {\n console.error('Failed to parse Google Maps URL:', error);\n }\n\n return null;\n}\n\n/**\n * Get Google Maps static image URL\n * @param location - Location data\n * @param config - Google Maps configuration\n * @returns Static map image URL\n */\nexport function getGoogleMapsStaticImage(\n location: GoogleMapsLocation,\n config: GoogleMapsConfig\n): string {\n if (!config.apiKey) {\n throw new Error('Google Maps API key is required');\n }\n\n const zoom = location.zoom || config.zoom || 15;\n const width = config.width || 800;\n const height = config.height || 600;\n const mapType = config.mapType || 'roadmap';\n\n const center = location.query || `${location.lat},${location.lng}`;\n const marker = location.query ? '' : `&markers=color:red|${location.lat},${location.lng}`;\n\n return `https://maps.googleapis.com/maps/api/staticmap?center=${encodeURIComponent(center)}&zoom=${zoom}&size=${width}x${height}&maptype=${mapType}${marker}&key=${config.apiKey}`;\n}\n\nexport class VistaGoogleMaps extends VistaBox {\n element: HTMLDivElement;\n private mapsConfig: GoogleMapsConfig;\n private location: GoogleMapsLocation;\n\n constructor(par: VistaImageParams, location: GoogleMapsLocation, config?: GoogleMapsConfig) {\n super(par);\n\n this.mapsConfig = config || {};\n this.location = location;\n\n const div = document.createElement('div');\n div.style.position = 'relative';\n const image = document.createElement('img');\n div.appendChild(image);\n image.src =\n this.origin?.image.src ||\n (config && config.apiKey ? getGoogleMapsStaticImage(location, config) : '');\n image.style.width = '100%';\n image.style.height = '100%';\n image.style.objectFit = 'cover';\n image.classList.add('vvw--pulsing');\n\n this.element = div;\n\n this.element.classList.add('vvw-img-hi');\n\n // Set sizes\n const { width: fullWidth, height: fullHeight } = this.getFullSizeDim();\n this.fullH = fullHeight;\n this.fullW = fullWidth;\n this.minW = this.fullW * 0.5;\n this.maxW = this.fullW; // no scaling\n this.element.style.width = `${fullWidth}px`;\n this.element.style.height = `${fullHeight}px`;\n\n // Trigger setSizes to setup thumb and iframe initial style\n this.setSizes({ stableSize: false, initDimension: true });\n\n if (this.pos === 0) {\n const iframe = document.createElement('iframe');\n iframe.frameBorder = '0';\n iframe.allow = 'geolocation';\n iframe.allowFullscreen = true;\n iframe.width = '100%';\n iframe.height = '100%';\n iframe.style.position = 'absolute';\n iframe.style.top = '0';\n iframe.style.left = '0';\n iframe.style.opacity = '0';\n iframe.style.transition = 'opacity 1s ease';\n\n // Use standard Google Maps iframe embed\n let embedUrl: string;\n if (this.location.query) {\n embedUrl = `https://www.google.com/maps?q=${encodeURIComponent(this.location.query)}&output=embed`;\n } else {\n embedUrl = `https://www.google.com/maps?q=${this.location.lat},${this.location.lng}&output=embed`;\n }\n iframe.src = embedUrl;\n div.appendChild(iframe);\n\n iframe.onload = () => {\n iframe.style.opacity = '1';\n image.classList.remove('vvw--pulsing');\n };\n }\n\n this.isLoadedResolved!(true);\n }\n\n // Use 16:9 aspect ratio with max 800px width\n protected getFullSizeDim(): { width: number; height: number } {\n const maxWidth = Math.min(window.innerWidth, this.mapsConfig.width || 800);\n return {\n width: maxWidth,\n height: (maxWidth * 9) / 16,\n };\n }\n\n // Override to avoid propagating content change event\n setFinalTransform() {\n return super.setFinalTransform({ propagateEvent: false });\n }\n}\n\nexport function googleMaps(config?: GoogleMapsConfig): VistaExtension {\n return {\n name: 'googleMaps',\n onInitializeImage: (params: VistaImageParams) => {\n const url = params.elm.config.src;\n const location = parseGoogleMapsLocation(url);\n if (!location) return;\n\n return new VistaGoogleMaps(params, location, config);\n },\n onImageView: async (data: VistaData, v: VistaView) => {\n const mainData = data.images.to![Math.floor(data.images.to!.length / 2)];\n if (mainData instanceof VistaGoogleMaps) {\n v.deactivateUi(['download', 'zoomIn', 'zoomOut'], mainData);\n }\n },\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=main.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.test.d.ts","sourceRoot":"","sources":["../src/main.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`vistaview`)):typeof define==`function`&&define.amd?define([`exports`,`vistaview`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.VistaView=e.VistaView||{},e.VistaView))})(this,function(e,t){function n(e){if(!e)return null;try{let t=new URL(e),n=e.match(/@(-?\d+\.?\d*),(-?\d+\.?\d*),?(\d+\.?\d*)?z?/);if(n)return{lat:parseFloat(n[1]),lng:parseFloat(n[2]),zoom:n[3]?parseFloat(n[3]):void 0};let r=t.searchParams.get(`q`);if(r){let e=r.match(/(-?\d+\.?\d*),\s*(-?\d+\.?\d*)/);return e?{lat:parseFloat(e[1]),lng:parseFloat(e[2]),query:r}:{lat:0,lng:0,query:r}}let i=t.searchParams.get(`ll`);if(i){let[e,t]=i.split(`,`).map(parseFloat);if(!isNaN(e)&&!isNaN(t))return{lat:e,lng:t}}}catch(e){console.error(`Failed to parse Google Maps URL:`,e)}return null}function r(e,t){if(!t.apiKey)throw Error(`Google Maps API key is required`);let n=e.zoom||t.zoom||15,r=t.width||800,i=t.height||600,a=t.mapType||`roadmap`,o=e.query||`${e.lat},${e.lng}`,s=e.query?``:`&markers=color:red|${e.lat},${e.lng}`;return`https://maps.googleapis.com/maps/api/staticmap?center=${encodeURIComponent(o)}&zoom=${n}&size=${r}x${i}&maptype=${a}${s}&key=${t.apiKey}`}var i=class extends t.VistaBox{element;mapsConfig;location;constructor(e,t,n){super(e),this.mapsConfig=n||{},this.location=t;let i=document.createElement(`div`);i.style.position=`relative`;let a=document.createElement(`img`);i.appendChild(a),a.src=this.origin?.image.src||(n&&n.apiKey?r(t,n):``),a.style.width=`100%`,a.style.height=`100%`,a.style.objectFit=`cover`,a.classList.add(`vvw--pulsing`),this.element=i,this.element.classList.add(`vvw-img-hi`);let{width:o,height:s}=this.getFullSizeDim();if(this.fullH=s,this.fullW=o,this.minW=this.fullW*.5,this.maxW=this.fullW,this.element.style.width=`${o}px`,this.element.style.height=`${s}px`,this.setSizes({stableSize:!1,initDimension:!0}),this.pos===0){let e=document.createElement(`iframe`);e.frameBorder=`0`,e.allow=`geolocation`,e.allowFullscreen=!0,e.width=`100%`,e.height=`100%`,e.style.position=`absolute`,e.style.top=`0`,e.style.left=`0`,e.style.opacity=`0`,e.style.transition=`opacity 1s ease`;let t;t=this.location.query?`https://www.google.com/maps?q=${encodeURIComponent(this.location.query)}&output=embed`:`https://www.google.com/maps?q=${this.location.lat},${this.location.lng}&output=embed`,e.src=t,i.appendChild(e),e.onload=()=>{e.style.opacity=`1`,a.classList.remove(`vvw--pulsing`)}}this.isLoadedResolved(!0)}getFullSizeDim(){let e=Math.min(window.innerWidth,this.mapsConfig.width||800);return{width:e,height:e*9/16}}setFinalTransform(){return super.setFinalTransform({propagateEvent:!1})}};function a(e){return{name:`googleMaps`,onInitializeImage:t=>{let r=t.elm.config.src,a=n(r);if(a)return new i(t,a,e)},onImageView:async(e,t)=>{let n=e.images.to[Math.floor(e.images.to.length/2)];n instanceof i&&t.deactivateUi([`download`,`zoomIn`,`zoomOut`],n)}}}e.VistaGoogleMaps=i,e.getGoogleMapsStaticImage=r,e.googleMaps=a,e.parseGoogleMapsLocation=n});
2
+ //# sourceMappingURL=main.umd.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.umd.cjs","names":["embedUrl: string"],"sources":["../src/main.ts"],"sourcesContent":["import type { VistaData, VistaExtension, VistaImageParams, VistaView } from 'vistaview';\nimport { VistaBox } from 'vistaview';\n\nexport interface GoogleMapsConfig {\n apiKey?: string;\n zoom?: number; // Default zoom level (1-20)\n width?: number; // Map width in pixels\n height?: number; // Map height in pixels\n mapType?: 'roadmap' | 'satellite' | 'hybrid' | 'terrain';\n}\n\nexport interface GoogleMapsLocation {\n lat: number;\n lng: number;\n zoom?: number;\n query?: string;\n}\n\n/**\n * Parse Google Maps URL and extract location data\n * Supports various Google Maps URL formats:\n * - https://www.google.com/maps?q=40.7128,-74.0060\n * - https://www.google.com/maps/@40.7128,-74.0060,15z\n * - https://maps.google.com?q=40.7128,-74.0060\n * - https://goo.gl/maps/...\n * @param url - Google Maps URL\n * @returns Location data or null if not found\n */\nexport function parseGoogleMapsLocation(url: string): GoogleMapsLocation | null {\n if (!url) return null;\n\n try {\n const urlObj = new URL(url);\n\n // Check for @lat,lng,zoom format\n const atMatch = url.match(/@(-?\\d+\\.?\\d*),(-?\\d+\\.?\\d*),?(\\d+\\.?\\d*)?z?/);\n if (atMatch) {\n return {\n lat: parseFloat(atMatch[1]),\n lng: parseFloat(atMatch[2]),\n zoom: atMatch[3] ? parseFloat(atMatch[3]) : undefined,\n };\n }\n\n // Check for q=lat,lng format\n const qParam = urlObj.searchParams.get('q');\n if (qParam) {\n const coordMatch = qParam.match(/(-?\\d+\\.?\\d*),\\s*(-?\\d+\\.?\\d*)/);\n if (coordMatch) {\n return {\n lat: parseFloat(coordMatch[1]),\n lng: parseFloat(coordMatch[2]),\n query: qParam,\n };\n }\n // If q param doesn't contain coordinates, store it as a query\n return { lat: 0, lng: 0, query: qParam };\n }\n\n // Check for ll= parameter (lat,lng)\n const llParam = urlObj.searchParams.get('ll');\n if (llParam) {\n const [lat, lng] = llParam.split(',').map(parseFloat);\n if (!isNaN(lat) && !isNaN(lng)) {\n return { lat, lng };\n }\n }\n } catch (error) {\n console.error('Failed to parse Google Maps URL:', error);\n }\n\n return null;\n}\n\n/**\n * Get Google Maps static image URL\n * @param location - Location data\n * @param config - Google Maps configuration\n * @returns Static map image URL\n */\nexport function getGoogleMapsStaticImage(\n location: GoogleMapsLocation,\n config: GoogleMapsConfig\n): string {\n if (!config.apiKey) {\n throw new Error('Google Maps API key is required');\n }\n\n const zoom = location.zoom || config.zoom || 15;\n const width = config.width || 800;\n const height = config.height || 600;\n const mapType = config.mapType || 'roadmap';\n\n const center = location.query || `${location.lat},${location.lng}`;\n const marker = location.query ? '' : `&markers=color:red|${location.lat},${location.lng}`;\n\n return `https://maps.googleapis.com/maps/api/staticmap?center=${encodeURIComponent(center)}&zoom=${zoom}&size=${width}x${height}&maptype=${mapType}${marker}&key=${config.apiKey}`;\n}\n\nexport class VistaGoogleMaps extends VistaBox {\n element: HTMLDivElement;\n private mapsConfig: GoogleMapsConfig;\n private location: GoogleMapsLocation;\n\n constructor(par: VistaImageParams, location: GoogleMapsLocation, config?: GoogleMapsConfig) {\n super(par);\n\n this.mapsConfig = config || {};\n this.location = location;\n\n const div = document.createElement('div');\n div.style.position = 'relative';\n const image = document.createElement('img');\n div.appendChild(image);\n image.src =\n this.origin?.image.src ||\n (config && config.apiKey ? getGoogleMapsStaticImage(location, config) : '');\n image.style.width = '100%';\n image.style.height = '100%';\n image.style.objectFit = 'cover';\n image.classList.add('vvw--pulsing');\n\n this.element = div;\n\n this.element.classList.add('vvw-img-hi');\n\n // Set sizes\n const { width: fullWidth, height: fullHeight } = this.getFullSizeDim();\n this.fullH = fullHeight;\n this.fullW = fullWidth;\n this.minW = this.fullW * 0.5;\n this.maxW = this.fullW; // no scaling\n this.element.style.width = `${fullWidth}px`;\n this.element.style.height = `${fullHeight}px`;\n\n // Trigger setSizes to setup thumb and iframe initial style\n this.setSizes({ stableSize: false, initDimension: true });\n\n if (this.pos === 0) {\n const iframe = document.createElement('iframe');\n iframe.frameBorder = '0';\n iframe.allow = 'geolocation';\n iframe.allowFullscreen = true;\n iframe.width = '100%';\n iframe.height = '100%';\n iframe.style.position = 'absolute';\n iframe.style.top = '0';\n iframe.style.left = '0';\n iframe.style.opacity = '0';\n iframe.style.transition = 'opacity 1s ease';\n\n // Use standard Google Maps iframe embed\n let embedUrl: string;\n if (this.location.query) {\n embedUrl = `https://www.google.com/maps?q=${encodeURIComponent(this.location.query)}&output=embed`;\n } else {\n embedUrl = `https://www.google.com/maps?q=${this.location.lat},${this.location.lng}&output=embed`;\n }\n iframe.src = embedUrl;\n div.appendChild(iframe);\n\n iframe.onload = () => {\n iframe.style.opacity = '1';\n image.classList.remove('vvw--pulsing');\n };\n }\n\n this.isLoadedResolved!(true);\n }\n\n // Use 16:9 aspect ratio with max 800px width\n protected getFullSizeDim(): { width: number; height: number } {\n const maxWidth = Math.min(window.innerWidth, this.mapsConfig.width || 800);\n return {\n width: maxWidth,\n height: (maxWidth * 9) / 16,\n };\n }\n\n // Override to avoid propagating content change event\n setFinalTransform() {\n return super.setFinalTransform({ propagateEvent: false });\n }\n}\n\nexport function googleMaps(config?: GoogleMapsConfig): VistaExtension {\n return {\n name: 'googleMaps',\n onInitializeImage: (params: VistaImageParams) => {\n const url = params.elm.config.src;\n const location = parseGoogleMapsLocation(url);\n if (!location) return;\n\n return new VistaGoogleMaps(params, location, config);\n },\n onImageView: async (data: VistaData, v: VistaView) => {\n const mainData = data.images.to![Math.floor(data.images.to!.length / 2)];\n if (mainData instanceof VistaGoogleMaps) {\n v.deactivateUi(['download', 'zoomIn', 'zoomOut'], mainData);\n }\n },\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { VistaExtension } from 'vistaview';
2
+ type VistaGetStoryResult = {
3
+ content: string;
4
+ onLoad?: () => void;
5
+ onUnload?: () => void;
6
+ };
7
+ export declare function removeStory(currentIndex: string, storyCache: {
8
+ [key: string]: VistaGetStoryResult;
9
+ }, maxStoryCache: number): void;
10
+ export declare function imageStory({ getStory, maxStoryCache, sanitize, }: {
11
+ getStory: (imageIndex: number) => Promise<VistaGetStoryResult>;
12
+ maxStoryCache?: number;
13
+ sanitize?: (content: string) => string;
14
+ }): VistaExtension;
15
+ export {};
16
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,cAAc,EAAa,MAAM,WAAW,CAAC;AAKtE,KAAK,mBAAmB,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB,CAAC;AAEF,wBAAgB,WAAW,CACzB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,CAAA;CAAE,EAClD,aAAa,EAAE,MAAM,QA4BtB;AAED,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,aAAiB,EACjB,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC/D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;CACxC,GAAG,cAAc,CAyFjB"}