@videojs/html 10.0.0-beta.15 → 10.0.0-beta.17

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 (377) hide show
  1. package/cdn/{abort-CzqmAxxH.js → abort-BL-SGV3o.js} +1 -1
  2. package/cdn/{abort-CzqmAxxH.js.map → abort-BL-SGV3o.js.map} +1 -1
  3. package/cdn/{abort-KaHR4JO1.js → abort-DGNIECLn.js} +1 -1
  4. package/cdn/{abort-KaHR4JO1.js.map → abort-DGNIECLn.js.map} +1 -1
  5. package/cdn/audio-minimal-ui.dev.js +4 -5
  6. package/cdn/audio-minimal-ui.js +1 -1
  7. package/cdn/audio-minimal.dev.js +7 -8
  8. package/cdn/audio-minimal.dev.js.map +1 -1
  9. package/cdn/audio-minimal.js +1 -1
  10. package/cdn/audio-minimal.js.map +1 -1
  11. package/cdn/audio-ui.dev.js +4 -5
  12. package/cdn/audio-ui.js +1 -1
  13. package/cdn/audio.dev.js +22 -7
  14. package/cdn/audio.dev.js.map +1 -1
  15. package/cdn/audio.js +1 -1
  16. package/cdn/audio.js.map +1 -1
  17. package/cdn/background.dev.js +3 -3
  18. package/cdn/background.js +1 -1
  19. package/cdn/background.js.map +1 -1
  20. package/cdn/compounds-Df_1JbZD.js +8 -0
  21. package/cdn/compounds-Df_1JbZD.js.map +1 -0
  22. package/cdn/{volume-slider-Co5X4Z1t.js → compounds-VFPcCeRV.js} +2439 -946
  23. package/cdn/compounds-VFPcCeRV.js.map +1 -0
  24. package/cdn/context-C-IpVHEt.js +14 -0
  25. package/cdn/context-C-IpVHEt.js.map +1 -0
  26. package/cdn/{context-BjrbhiSk.js → context-CvJ83xGk.js} +2 -83
  27. package/cdn/context-CvJ83xGk.js.map +1 -0
  28. package/cdn/{create-player-p9xCO0yC.js → create-player-CyG77t-m.js} +778 -1955
  29. package/cdn/create-player-CyG77t-m.js.map +1 -0
  30. package/cdn/create-player-Gom2ZZe3.js +7 -0
  31. package/cdn/create-player-Gom2ZZe3.js.map +1 -0
  32. package/cdn/{hls-26YJVjvD.js → hls-BAbdl84H.js} +3 -3
  33. package/cdn/{hls-26YJVjvD.js.map → hls-BAbdl84H.js.map} +1 -1
  34. package/cdn/{hls-BriQI4q1.js → hls-BrzPpueW.js} +9 -12
  35. package/cdn/{hls-BriQI4q1.js.map → hls-BrzPpueW.js.map} +1 -1
  36. package/cdn/hotkey-element-DR3ZAqKa.js +2 -0
  37. package/cdn/hotkey-element-DR3ZAqKa.js.map +1 -0
  38. package/cdn/hotkey-element-Dlta37Be.js +369 -0
  39. package/cdn/hotkey-element-Dlta37Be.js.map +1 -0
  40. package/cdn/media/dash-video.dev.js +3 -4
  41. package/cdn/media/dash-video.dev.js.map +1 -1
  42. package/cdn/media/dash-video.js +2 -2
  43. package/cdn/media/hls-video.dev.js +4 -5
  44. package/cdn/media/hls-video.dev.js.map +1 -1
  45. package/cdn/media/hls-video.js +1 -1
  46. package/cdn/media/hls-video.js.map +1 -1
  47. package/cdn/media/mux-audio.dev.d.ts +1 -0
  48. package/cdn/media/mux-audio.dev.js +29 -0
  49. package/cdn/media/mux-audio.dev.js.map +1 -0
  50. package/cdn/media/mux-audio.js +2 -0
  51. package/cdn/media/mux-audio.js.map +1 -0
  52. package/cdn/media/mux-video.dev.js +5 -3099
  53. package/cdn/media/mux-video.dev.js.map +1 -1
  54. package/cdn/media/mux-video.js +1 -24
  55. package/cdn/media/mux-video.js.map +1 -1
  56. package/cdn/media/native-hls-video.dev.js +4 -4
  57. package/cdn/media/native-hls-video.js +1 -1
  58. package/cdn/media/simple-hls-video.dev.js +966 -681
  59. package/cdn/media/simple-hls-video.dev.js.map +1 -1
  60. package/cdn/media/simple-hls-video.js +6 -6
  61. package/cdn/media/simple-hls-video.js.map +1 -1
  62. package/cdn/{media-attach-mixin-DfKkofgF.js → media-attach-mixin-CMH1ziXP.js} +2 -2
  63. package/cdn/{media-attach-mixin-DfKkofgF.js.map → media-attach-mixin-CMH1ziXP.js.map} +1 -1
  64. package/cdn/{media-attach-mixin-Dv2D43tb.js → media-attach-mixin-DUzmXEJ3.js} +2 -2
  65. package/cdn/{media-attach-mixin-Dv2D43tb.js.map → media-attach-mixin-DUzmXEJ3.js.map} +1 -1
  66. package/cdn/{media-props-mixin-Dc5dpCV4.js → media-props-mixin-hheRmkup.js} +92 -8
  67. package/cdn/media-props-mixin-hheRmkup.js.map +1 -0
  68. package/cdn/media-props-mixin-yRWj8yXF.js +47 -0
  69. package/cdn/media-props-mixin-yRWj8yXF.js.map +1 -0
  70. package/cdn/{minimal-BUUGNZK7.js → minimal-D9Dw-L2P.js} +1 -1
  71. package/cdn/{minimal-BUUGNZK7.js.map → minimal-D9Dw-L2P.js.map} +1 -1
  72. package/cdn/{minimal-CJGOJ6pE.js → minimal-Dc5nNl_-.js} +1 -1
  73. package/cdn/{minimal-CJGOJ6pE.js.map → minimal-Dc5nNl_-.js.map} +1 -1
  74. package/cdn/minimal-ui-B3BBK5nX.js +2 -0
  75. package/cdn/minimal-ui-B3BBK5nX.js.map +1 -0
  76. package/cdn/minimal-ui-CPRSYky_.js +28 -0
  77. package/cdn/minimal-ui-CPRSYky_.js.map +1 -0
  78. package/cdn/minimal-ui-Cnaig4X6.js +22 -0
  79. package/cdn/minimal-ui-Cnaig4X6.js.map +1 -0
  80. package/cdn/minimal-ui-DOePmQfq.js +2 -0
  81. package/cdn/minimal-ui-DOePmQfq.js.map +1 -0
  82. package/cdn/mux-DGgCyz_A.js +3102 -0
  83. package/cdn/mux-DGgCyz_A.js.map +1 -0
  84. package/cdn/mux-fYfPUpq3.js +25 -0
  85. package/cdn/mux-fYfPUpq3.js.map +1 -0
  86. package/cdn/{native-hls-D2rfyyyW.js → native-hls-BuCYu7Rd.js} +2 -3
  87. package/cdn/{native-hls-D2rfyyyW.js.map → native-hls-BuCYu7Rd.js.map} +1 -1
  88. package/cdn/native-hls-DnqJ-0zL.js +2 -0
  89. package/cdn/{native-hls-CjRvSXAJ.js.map → native-hls-DnqJ-0zL.js.map} +1 -1
  90. package/cdn/player-Cu5_r0Gk.js +2 -0
  91. package/cdn/{player-Cz9-_j7J.js.map → player-Cu5_r0Gk.js.map} +1 -1
  92. package/cdn/player-DIOgBqQf.js +382 -0
  93. package/cdn/player-DIOgBqQf.js.map +1 -0
  94. package/cdn/{player-D0bhjT8X.js → player-DxBoqZVw.js} +4 -3
  95. package/cdn/{player-D0bhjT8X.js.map → player-DxBoqZVw.js.map} +1 -1
  96. package/cdn/player-eEH-XjnF.js +2 -0
  97. package/cdn/player-eEH-XjnF.js.map +1 -0
  98. package/cdn/{shallow-equal-uPuCQhnd.js → shallow-equal-1KBb-lrM.js} +1 -1
  99. package/cdn/{shallow-equal-uPuCQhnd.js.map → shallow-equal-1KBb-lrM.js.map} +1 -1
  100. package/cdn/{shallow-equal-C8Fs4TTE.js → shallow-equal-Ca0qjpLJ.js} +1 -1
  101. package/cdn/{shallow-equal-C8Fs4TTE.js.map → shallow-equal-Ca0qjpLJ.js.map} +1 -1
  102. package/cdn/{skin-element-zakTHELS.js → skin-element-BTPr5DoY.js} +2 -2
  103. package/cdn/{skin-element-zakTHELS.js.map → skin-element-BTPr5DoY.js.map} +1 -1
  104. package/cdn/{skin-element-DB-cKAAx.js → skin-element-u6pdmSSs.js} +2 -2
  105. package/cdn/{skin-element-DB-cKAAx.js.map → skin-element-u6pdmSSs.js.map} +1 -1
  106. package/cdn/ui-34pkHFdT.js +25 -0
  107. package/cdn/ui-34pkHFdT.js.map +1 -0
  108. package/cdn/ui-DWoV_Da1.js +2 -0
  109. package/cdn/ui-DWoV_Da1.js.map +1 -0
  110. package/cdn/ui-DXtTKomo.js +2 -0
  111. package/cdn/ui-DXtTKomo.js.map +1 -0
  112. package/cdn/ui-X5WOdCCw.js +31 -0
  113. package/cdn/ui-X5WOdCCw.js.map +1 -0
  114. package/cdn/video-minimal-ui.dev.js +4 -5
  115. package/cdn/video-minimal-ui.js +1 -1
  116. package/cdn/video-minimal.dev.js +7 -8
  117. package/cdn/video-minimal.dev.js.map +1 -1
  118. package/cdn/video-minimal.js +1 -1
  119. package/cdn/video-minimal.js.map +1 -1
  120. package/cdn/video-ui.dev.js +4 -5
  121. package/cdn/video-ui.js +1 -1
  122. package/cdn/video.dev.js +32 -7
  123. package/cdn/video.dev.js.map +1 -1
  124. package/cdn/video.js +1 -1
  125. package/cdn/video.js.map +1 -1
  126. package/dist/default/_virtual/inline-css_src/define/audio/minimal-skin.js +1 -1
  127. package/dist/default/_virtual/inline-css_src/define/audio/minimal-skin.js.map +1 -1
  128. package/dist/default/_virtual/inline-css_src/define/audio/skin.js +1 -1
  129. package/dist/default/_virtual/inline-css_src/define/audio/skin.js.map +1 -1
  130. package/dist/default/_virtual/inline-css_src/define/video/minimal-skin.js +1 -1
  131. package/dist/default/_virtual/inline-css_src/define/video/minimal-skin.js.map +1 -1
  132. package/dist/default/_virtual/inline-css_src/define/video/skin.js +1 -1
  133. package/dist/default/_virtual/inline-css_src/define/video/skin.js.map +1 -1
  134. package/dist/default/define/audio/minimal-skin.css +23 -0
  135. package/dist/default/define/audio/minimal-ui.js +28 -12
  136. package/dist/default/define/audio/minimal-ui.js.map +1 -0
  137. package/dist/default/define/audio/skin.css +23 -0
  138. package/dist/default/define/audio/skin.js +1 -1
  139. package/dist/default/define/audio/skin.js.map +1 -1
  140. package/dist/default/define/audio/ui.js +32 -12
  141. package/dist/default/define/audio/ui.js.map +1 -0
  142. package/dist/default/define/background/skin.js +1 -1
  143. package/dist/default/define/media/mux-audio.js +13 -0
  144. package/dist/default/define/media/mux-audio.js.map +1 -0
  145. package/dist/default/define/skin-element.js +1 -1
  146. package/dist/default/define/ui/compounds.js +62 -0
  147. package/dist/default/define/ui/compounds.js.map +1 -0
  148. package/dist/default/define/ui/controls.js +2 -5
  149. package/dist/default/define/ui/controls.js.map +1 -1
  150. package/dist/default/define/ui/error-dialog.js +2 -9
  151. package/dist/default/define/ui/error-dialog.js.map +1 -1
  152. package/dist/default/define/ui/hotkey.js +7 -0
  153. package/dist/default/define/ui/hotkey.js.map +1 -0
  154. package/dist/default/define/ui/slider.js +2 -13
  155. package/dist/default/define/ui/slider.js.map +1 -1
  156. package/dist/default/define/ui/time-slider.js +2 -17
  157. package/dist/default/define/ui/time-slider.js.map +1 -1
  158. package/dist/default/define/ui/time.js +2 -7
  159. package/dist/default/define/ui/time.js.map +1 -1
  160. package/dist/default/define/ui/volume-slider.js +2 -13
  161. package/dist/default/define/ui/volume-slider.js.map +1 -1
  162. package/dist/default/define/video/minimal-skin.css +23 -0
  163. package/dist/default/define/video/minimal-ui.js +39 -18
  164. package/dist/default/define/video/minimal-ui.js.map +1 -0
  165. package/dist/default/define/video/skin.css +23 -0
  166. package/dist/default/define/video/skin.js +1 -1
  167. package/dist/default/define/video/skin.js.map +1 -1
  168. package/dist/default/define/video/ui.js +43 -18
  169. package/dist/default/define/video/ui.js.map +1 -0
  170. package/dist/default/index.js +6 -1
  171. package/dist/default/media/container-element.js +16 -0
  172. package/dist/default/media/container-element.js.map +1 -1
  173. package/dist/default/media/mux-audio/index.js +18 -0
  174. package/dist/default/media/mux-audio/index.js.map +1 -0
  175. package/dist/default/player/context.js.map +1 -1
  176. package/dist/default/ui/alert-dialog/alert-dialog-element.js +1 -0
  177. package/dist/default/ui/alert-dialog/alert-dialog-element.js.map +1 -1
  178. package/dist/default/ui/buffering-indicator/buffering-indicator-element.js +1 -0
  179. package/dist/default/ui/buffering-indicator/buffering-indicator-element.js.map +1 -1
  180. package/dist/default/ui/captions-button/captions-button-element.js +1 -0
  181. package/dist/default/ui/captions-button/captions-button-element.js.map +1 -1
  182. package/dist/default/ui/error-dialog/error-dialog-element.js +1 -0
  183. package/dist/default/ui/error-dialog/error-dialog-element.js.map +1 -1
  184. package/dist/default/ui/fullscreen-button/fullscreen-button-element.js +1 -0
  185. package/dist/default/ui/fullscreen-button/fullscreen-button-element.js.map +1 -1
  186. package/dist/default/ui/gesture/gesture-element.js +84 -0
  187. package/dist/default/ui/gesture/gesture-element.js.map +1 -0
  188. package/dist/default/ui/hotkey/aria-key-shortcuts-controller.js +28 -0
  189. package/dist/default/ui/hotkey/aria-key-shortcuts-controller.js.map +1 -0
  190. package/dist/default/ui/hotkey/hotkey-element.js +81 -0
  191. package/dist/default/ui/hotkey/hotkey-element.js.map +1 -0
  192. package/dist/default/ui/media-button-element.js +9 -1
  193. package/dist/default/ui/media-button-element.js.map +1 -1
  194. package/dist/default/ui/mute-button/mute-button-element.js +1 -0
  195. package/dist/default/ui/mute-button/mute-button-element.js.map +1 -1
  196. package/dist/default/ui/pip-button/pip-button-element.js +1 -0
  197. package/dist/default/ui/pip-button/pip-button-element.js.map +1 -1
  198. package/dist/default/ui/play-button/play-button-element.js +1 -0
  199. package/dist/default/ui/play-button/play-button-element.js.map +1 -1
  200. package/dist/default/ui/popover/popover-element.js +7 -55
  201. package/dist/default/ui/popover/popover-element.js.map +1 -1
  202. package/dist/default/ui/position-controller.js +76 -0
  203. package/dist/default/ui/position-controller.js.map +1 -0
  204. package/dist/default/ui/slider/slider-element.js +1 -1
  205. package/dist/default/ui/slider/slider-preview-element.js +1 -1
  206. package/dist/default/ui/time-slider/time-slider-element.js +5 -5
  207. package/dist/default/ui/time-slider/time-slider-element.js.map +1 -1
  208. package/dist/default/ui/tooltip/tooltip-element.js +8 -54
  209. package/dist/default/ui/tooltip/tooltip-element.js.map +1 -1
  210. package/dist/default/ui/volume-slider/volume-slider-element.js +1 -1
  211. package/dist/dev/_virtual/inline-css_src/define/audio/minimal-skin.js +1 -1
  212. package/dist/dev/_virtual/inline-css_src/define/audio/minimal-skin.js.map +1 -1
  213. package/dist/dev/_virtual/inline-css_src/define/audio/skin.js +1 -1
  214. package/dist/dev/_virtual/inline-css_src/define/audio/skin.js.map +1 -1
  215. package/dist/dev/_virtual/inline-css_src/define/video/minimal-skin.js +1 -1
  216. package/dist/dev/_virtual/inline-css_src/define/video/minimal-skin.js.map +1 -1
  217. package/dist/dev/_virtual/inline-css_src/define/video/skin.js +1 -1
  218. package/dist/dev/_virtual/inline-css_src/define/video/skin.js.map +1 -1
  219. package/dist/dev/define/audio/minimal-skin.css +23 -0
  220. package/dist/dev/define/audio/minimal-ui.js +28 -12
  221. package/dist/dev/define/audio/minimal-ui.js.map +1 -0
  222. package/dist/dev/define/audio/skin.css +23 -0
  223. package/dist/dev/define/audio/skin.d.ts.map +1 -1
  224. package/dist/dev/define/audio/skin.js +16 -0
  225. package/dist/dev/define/audio/skin.js.map +1 -1
  226. package/dist/dev/define/audio/ui.js +32 -12
  227. package/dist/dev/define/audio/ui.js.map +1 -0
  228. package/dist/dev/define/background/skin.js +1 -1
  229. package/dist/dev/define/media/mux-audio.d.ts +14 -0
  230. package/dist/dev/define/media/mux-audio.d.ts.map +1 -0
  231. package/dist/dev/define/media/mux-audio.js +13 -0
  232. package/dist/dev/define/media/mux-audio.js.map +1 -0
  233. package/dist/dev/define/skin-element.d.ts +1 -1
  234. package/dist/dev/define/skin-element.js +1 -1
  235. package/dist/dev/define/ui/compounds.d.ts +12 -0
  236. package/dist/dev/define/ui/compounds.d.ts.map +1 -0
  237. package/dist/dev/define/ui/compounds.js +62 -0
  238. package/dist/dev/define/ui/compounds.js.map +1 -0
  239. package/dist/dev/define/ui/controls.d.ts +2 -0
  240. package/dist/dev/define/ui/controls.d.ts.map +1 -1
  241. package/dist/dev/define/ui/controls.js +2 -5
  242. package/dist/dev/define/ui/controls.js.map +1 -1
  243. package/dist/dev/define/ui/error-dialog.d.ts +6 -0
  244. package/dist/dev/define/ui/error-dialog.d.ts.map +1 -1
  245. package/dist/dev/define/ui/error-dialog.js +2 -9
  246. package/dist/dev/define/ui/error-dialog.js.map +1 -1
  247. package/dist/dev/define/ui/hotkey.d.ts +9 -0
  248. package/dist/dev/define/ui/hotkey.d.ts.map +1 -0
  249. package/dist/dev/define/ui/hotkey.js +7 -0
  250. package/dist/dev/define/ui/hotkey.js.map +1 -0
  251. package/dist/dev/define/ui/slider.d.ts +10 -0
  252. package/dist/dev/define/ui/slider.d.ts.map +1 -1
  253. package/dist/dev/define/ui/slider.js +2 -13
  254. package/dist/dev/define/ui/slider.js.map +1 -1
  255. package/dist/dev/define/ui/time-slider.d.ts +14 -0
  256. package/dist/dev/define/ui/time-slider.d.ts.map +1 -1
  257. package/dist/dev/define/ui/time-slider.js +2 -17
  258. package/dist/dev/define/ui/time-slider.js.map +1 -1
  259. package/dist/dev/define/ui/time.d.ts +4 -0
  260. package/dist/dev/define/ui/time.d.ts.map +1 -1
  261. package/dist/dev/define/ui/time.js +2 -7
  262. package/dist/dev/define/ui/time.js.map +1 -1
  263. package/dist/dev/define/ui/volume-slider.d.ts +10 -0
  264. package/dist/dev/define/ui/volume-slider.d.ts.map +1 -1
  265. package/dist/dev/define/ui/volume-slider.js +2 -13
  266. package/dist/dev/define/ui/volume-slider.js.map +1 -1
  267. package/dist/dev/define/video/minimal-skin.css +23 -0
  268. package/dist/dev/define/video/minimal-ui.js +39 -18
  269. package/dist/dev/define/video/minimal-ui.js.map +1 -0
  270. package/dist/dev/define/video/skin.css +23 -0
  271. package/dist/dev/define/video/skin.d.ts.map +1 -1
  272. package/dist/dev/define/video/skin.js +26 -0
  273. package/dist/dev/define/video/skin.js.map +1 -1
  274. package/dist/dev/define/video/ui.js +43 -18
  275. package/dist/dev/define/video/ui.js.map +1 -0
  276. package/dist/dev/index.d.ts +7 -2
  277. package/dist/dev/index.js +6 -1
  278. package/dist/dev/media/container-element.d.ts +3 -0
  279. package/dist/dev/media/container-element.d.ts.map +1 -1
  280. package/dist/dev/media/container-element.js +16 -0
  281. package/dist/dev/media/container-element.js.map +1 -1
  282. package/dist/dev/media/mux-audio/index.d.ts +11 -0
  283. package/dist/dev/media/mux-audio/index.d.ts.map +1 -0
  284. package/dist/dev/media/mux-audio/index.js +18 -0
  285. package/dist/dev/media/mux-audio/index.js.map +1 -0
  286. package/dist/dev/player/context.d.ts +4 -2
  287. package/dist/dev/player/context.d.ts.map +1 -1
  288. package/dist/dev/player/context.js.map +1 -1
  289. package/dist/dev/ui/alert-dialog/alert-dialog-element.d.ts.map +1 -1
  290. package/dist/dev/ui/alert-dialog/alert-dialog-element.js +1 -0
  291. package/dist/dev/ui/alert-dialog/alert-dialog-element.js.map +1 -1
  292. package/dist/dev/ui/buffering-indicator/buffering-indicator-element.d.ts.map +1 -1
  293. package/dist/dev/ui/buffering-indicator/buffering-indicator-element.js +1 -0
  294. package/dist/dev/ui/buffering-indicator/buffering-indicator-element.js.map +1 -1
  295. package/dist/dev/ui/captions-button/captions-button-element.d.ts +1 -0
  296. package/dist/dev/ui/captions-button/captions-button-element.d.ts.map +1 -1
  297. package/dist/dev/ui/captions-button/captions-button-element.js +1 -0
  298. package/dist/dev/ui/captions-button/captions-button-element.js.map +1 -1
  299. package/dist/dev/ui/context-part-element.d.ts +1 -1
  300. package/dist/dev/ui/error-dialog/error-dialog-element.d.ts.map +1 -1
  301. package/dist/dev/ui/error-dialog/error-dialog-element.js +1 -0
  302. package/dist/dev/ui/error-dialog/error-dialog-element.js.map +1 -1
  303. package/dist/dev/ui/fullscreen-button/fullscreen-button-element.d.ts +1 -0
  304. package/dist/dev/ui/fullscreen-button/fullscreen-button-element.d.ts.map +1 -1
  305. package/dist/dev/ui/fullscreen-button/fullscreen-button-element.js +1 -0
  306. package/dist/dev/ui/fullscreen-button/fullscreen-button-element.js.map +1 -1
  307. package/dist/dev/ui/gesture/gesture-element.d.ts +22 -0
  308. package/dist/dev/ui/gesture/gesture-element.d.ts.map +1 -0
  309. package/dist/dev/ui/gesture/gesture-element.js +84 -0
  310. package/dist/dev/ui/gesture/gesture-element.js.map +1 -0
  311. package/dist/dev/ui/hotkey/aria-key-shortcuts-controller.d.ts +15 -0
  312. package/dist/dev/ui/hotkey/aria-key-shortcuts-controller.d.ts.map +1 -0
  313. package/dist/dev/ui/hotkey/aria-key-shortcuts-controller.js +28 -0
  314. package/dist/dev/ui/hotkey/aria-key-shortcuts-controller.js.map +1 -0
  315. package/dist/dev/ui/hotkey/hotkey-element.d.ts +21 -0
  316. package/dist/dev/ui/hotkey/hotkey-element.d.ts.map +1 -0
  317. package/dist/dev/ui/hotkey/hotkey-element.js +81 -0
  318. package/dist/dev/ui/hotkey/hotkey-element.js.map +1 -0
  319. package/dist/dev/ui/media-button-element.d.ts +2 -0
  320. package/dist/dev/ui/media-button-element.d.ts.map +1 -1
  321. package/dist/dev/ui/media-button-element.js +9 -1
  322. package/dist/dev/ui/media-button-element.js.map +1 -1
  323. package/dist/dev/ui/mute-button/mute-button-element.d.ts +1 -0
  324. package/dist/dev/ui/mute-button/mute-button-element.d.ts.map +1 -1
  325. package/dist/dev/ui/mute-button/mute-button-element.js +1 -0
  326. package/dist/dev/ui/mute-button/mute-button-element.js.map +1 -1
  327. package/dist/dev/ui/pip-button/pip-button-element.d.ts +1 -0
  328. package/dist/dev/ui/pip-button/pip-button-element.d.ts.map +1 -1
  329. package/dist/dev/ui/pip-button/pip-button-element.js +1 -0
  330. package/dist/dev/ui/pip-button/pip-button-element.js.map +1 -1
  331. package/dist/dev/ui/play-button/play-button-element.d.ts +1 -0
  332. package/dist/dev/ui/play-button/play-button-element.d.ts.map +1 -1
  333. package/dist/dev/ui/play-button/play-button-element.js +1 -0
  334. package/dist/dev/ui/play-button/play-button-element.js.map +1 -1
  335. package/dist/dev/ui/popover/popover-element.d.ts.map +1 -1
  336. package/dist/dev/ui/popover/popover-element.js +7 -55
  337. package/dist/dev/ui/popover/popover-element.js.map +1 -1
  338. package/dist/dev/ui/position-controller.js +76 -0
  339. package/dist/dev/ui/position-controller.js.map +1 -0
  340. package/dist/dev/ui/slider/slider-element.js +1 -1
  341. package/dist/dev/ui/slider/slider-preview-element.d.ts +21 -0
  342. package/dist/dev/ui/slider/slider-preview-element.d.ts.map +1 -0
  343. package/dist/dev/ui/slider/slider-preview-element.js +1 -1
  344. package/dist/dev/ui/time-slider/time-slider-element.d.ts +2 -2
  345. package/dist/dev/ui/time-slider/time-slider-element.js +5 -5
  346. package/dist/dev/ui/time-slider/time-slider-element.js.map +1 -1
  347. package/dist/dev/ui/tooltip/tooltip-element.d.ts.map +1 -1
  348. package/dist/dev/ui/tooltip/tooltip-element.js +8 -54
  349. package/dist/dev/ui/tooltip/tooltip-element.js.map +1 -1
  350. package/dist/dev/ui/volume-slider/volume-slider-element.js +1 -1
  351. package/package.json +8 -8
  352. package/cdn/context-BjrbhiSk.js.map +0 -1
  353. package/cdn/context-CdkhXQEw.js +0 -14
  354. package/cdn/context-CdkhXQEw.js.map +0 -1
  355. package/cdn/create-player-BqU8r8H4.js +0 -7
  356. package/cdn/create-player-BqU8r8H4.js.map +0 -1
  357. package/cdn/create-player-p9xCO0yC.js.map +0 -1
  358. package/cdn/delegate-B626t_Va.js +0 -2
  359. package/cdn/delegate-B626t_Va.js.map +0 -1
  360. package/cdn/delegate-BCw-LjP_.js +0 -56
  361. package/cdn/delegate-BCw-LjP_.js.map +0 -1
  362. package/cdn/media-props-mixin-Bd_N2HWy.js +0 -47
  363. package/cdn/media-props-mixin-Bd_N2HWy.js.map +0 -1
  364. package/cdn/media-props-mixin-Dc5dpCV4.js.map +0 -1
  365. package/cdn/minimal-ui-BL9eBXck.js +0 -0
  366. package/cdn/minimal-ui-a1UOKF79.js +0 -0
  367. package/cdn/native-hls-CjRvSXAJ.js +0 -2
  368. package/cdn/player-Cz9-_j7J.js +0 -2
  369. package/cdn/poster-2FPYTjyv.js +0 -2
  370. package/cdn/poster-2FPYTjyv.js.map +0 -1
  371. package/cdn/poster-gVT-J1-z.js +0 -215
  372. package/cdn/poster-gVT-J1-z.js.map +0 -1
  373. package/cdn/ui-CFIgmrlA.js +0 -0
  374. package/cdn/ui-Ccp_LyCf.js +0 -0
  375. package/cdn/volume-slider-Co5X4Z1t.js.map +0 -1
  376. package/cdn/volume-slider-D18sXnIA.js +0 -8
  377. package/cdn/volume-slider-D18sXnIA.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"error-dialog-element.js","names":["#core","#provider","#titleId","#descriptionId","#errorState","#dialog","#snapshot","#lastErrorMessage"],"sources":["../../../../src/ui/error-dialog/error-dialog-element.ts"],"sourcesContent":["import { AlertDialogDataAttrs, type AlertDialogInput, ErrorDialogCore } from '@videojs/core';\nimport {\n type AlertDialogApi,\n applyElementProps,\n applyStateDataAttrs,\n createAlertDialog,\n createTransition,\n selectError,\n} from '@videojs/core/dom';\nimport type { PropertyValues } from '@videojs/element';\nimport { ContextProvider } from '@videojs/element/context';\nimport { SnapshotController } from '@videojs/store/html';\n\nimport { playerContext } from '../../player/context';\nimport { PlayerController } from '../../player/player-controller';\nimport { alertDialogContext } from '../alert-dialog/context';\nimport { MediaElement } from '../media-element';\n\nconst FALLBACK_MESSAGE = 'An error occurred. Please try again.';\n\nlet idCounter = 0;\n\nexport class ErrorDialogElement extends MediaElement {\n static readonly tagName = 'media-error-dialog';\n\n readonly #core = new ErrorDialogCore();\n readonly #provider = new ContextProvider(this, { context: alertDialogContext });\n readonly #titleId = `vjs-error-dialog-title-${idCounter++}`;\n readonly #descriptionId = `vjs-error-dialog-desc-${idCounter++}`;\n readonly #errorState = new PlayerController(this, playerContext, selectError);\n\n #dialog: AlertDialogApi | null = null;\n #snapshot: SnapshotController<AlertDialogInput> | null = null;\n #lastErrorMessage: string | null = null;\n\n constructor() {\n super();\n this.#core.setTitleId(this.#titleId);\n this.#core.setDescriptionId(this.#descriptionId);\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n\n this.#dialog = createAlertDialog({\n transition: createTransition(),\n onOpenChange: (nextOpen: boolean) => {\n if (!nextOpen) {\n this.#errorState.value?.dismissError();\n }\n },\n });\n\n this.#dialog.setElement(this);\n\n if (this.#snapshot) {\n this.#snapshot.track(this.#dialog.input);\n } else {\n this.#snapshot = new SnapshotController(this, this.#dialog.input);\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#dialog?.destroy();\n this.#dialog = null;\n }\n\n protected override willUpdate(_changed: PropertyValues): void {\n super.willUpdate(_changed);\n if (!this.#dialog) return;\n\n const errorState = this.#errorState.value;\n const hasError = Boolean(errorState?.error);\n const { active: isOpen } = this.#dialog.input.current;\n\n if (errorState?.error) {\n const message = errorState.error.message?.trim();\n this.#lastErrorMessage = message || null;\n }\n\n // Set description text before opening so content is ready for the transition.\n const desc = this.querySelector('media-alert-dialog-description');\n if (desc) {\n desc.textContent = this.#lastErrorMessage ?? FALLBACK_MESSAGE;\n }\n\n if (hasError && !isOpen) {\n this.#dialog.open();\n } else if (!hasError && isOpen) {\n this.#dialog.close();\n }\n }\n\n protected override update(_changed: PropertyValues): void {\n super.update(_changed);\n if (!this.#dialog) return;\n\n const input = this.#dialog.input.current;\n this.#core.setInput(input);\n const state = this.#core.getState();\n\n applyElementProps(this, this.#core.getAttrs(state));\n applyStateDataAttrs(this, state, AlertDialogDataAttrs);\n\n this.#provider.setValue({\n state,\n stateAttrMap: AlertDialogDataAttrs,\n close: () => this.#dialog?.close(),\n });\n }\n}\n"],"mappings":";;;;;;;;;AAkBA,MAAM,mBAAmB;AAEzB,IAAI,YAAY;AAEhB,IAAa,qBAAb,cAAwC,aAAa;;iBACzB;;CAE1B,QAAiB,IAAI,iBAAiB;CACtC,YAAqB,IAAI,gBAAgB,MAAM,EAAE,SAAS,oBAAoB,CAAC;CAC/E,WAAoB,0BAA0B;CAC9C,iBAA0B,yBAAyB;CACnD,cAAuB,IAAI,iBAAiB,MAAM,eAAe,YAAY;CAE7E,UAAiC;CACjC,YAAyD;CACzD,oBAAmC;CAEnC,cAAc;AACZ,SAAO;AACP,QAAA,KAAW,WAAW,MAAA,QAAc;AACpC,QAAA,KAAW,iBAAiB,MAAA,cAAoB;;CAGlD,oBAAmC;AACjC,QAAM,mBAAmB;AAEzB,QAAA,SAAe,kBAAkB;GAC/B,YAAY,kBAAkB;GAC9B,eAAe,aAAsB;AACnC,QAAI,CAAC,SACH,OAAA,WAAiB,OAAO,cAAc;;GAG3C,CAAC;AAEF,QAAA,OAAa,WAAW,KAAK;AAE7B,MAAI,MAAA,SACF,OAAA,SAAe,MAAM,MAAA,OAAa,MAAM;MAExC,OAAA,WAAiB,IAAI,mBAAmB,MAAM,MAAA,OAAa,MAAM;;CAIrE,uBAAsC;AACpC,QAAM,sBAAsB;AAC5B,QAAA,QAAc,SAAS;AACvB,QAAA,SAAe;;CAGjB,WAA8B,UAAgC;AAC5D,QAAM,WAAW,SAAS;AAC1B,MAAI,CAAC,MAAA,OAAc;EAEnB,MAAM,aAAa,MAAA,WAAiB;EACpC,MAAM,WAAW,QAAQ,YAAY,MAAM;EAC3C,MAAM,EAAE,QAAQ,WAAW,MAAA,OAAa,MAAM;AAE9C,MAAI,YAAY,MAEd,OAAA,mBADgB,WAAW,MAAM,SAAS,MAAM,IACZ;EAItC,MAAM,OAAO,KAAK,cAAc,iCAAiC;AACjE,MAAI,KACF,MAAK,cAAc,MAAA,oBAA0B;AAG/C,MAAI,YAAY,CAAC,OACf,OAAA,OAAa,MAAM;WACV,CAAC,YAAY,OACtB,OAAA,OAAa,OAAO;;CAIxB,OAA0B,UAAgC;AACxD,QAAM,OAAO,SAAS;AACtB,MAAI,CAAC,MAAA,OAAc;EAEnB,MAAM,QAAQ,MAAA,OAAa,MAAM;AACjC,QAAA,KAAW,SAAS,MAAM;EAC1B,MAAM,QAAQ,MAAA,KAAW,UAAU;AAEnC,oBAAkB,MAAM,MAAA,KAAW,SAAS,MAAM,CAAC;AACnD,sBAAoB,MAAM,OAAO,qBAAqB;AAEtD,QAAA,SAAe,SAAS;GACtB;GACA,cAAc;GACd,aAAa,MAAA,QAAc,OAAO;GACnC,CAAC"}
1
+ {"version":3,"file":"error-dialog-element.js","names":["#core","#provider","#titleId","#descriptionId","#errorState","#dialog","#snapshot","#lastErrorMessage"],"sources":["../../../../src/ui/error-dialog/error-dialog-element.ts"],"sourcesContent":["import { AlertDialogDataAttrs, type AlertDialogInput, ErrorDialogCore } from '@videojs/core';\nimport {\n type AlertDialogApi,\n applyElementProps,\n applyStateDataAttrs,\n createAlertDialog,\n createTransition,\n selectError,\n} from '@videojs/core/dom';\nimport type { PropertyValues } from '@videojs/element';\nimport { ContextProvider } from '@videojs/element/context';\nimport { SnapshotController } from '@videojs/store/html';\n\nimport { playerContext } from '../../player/context';\nimport { PlayerController } from '../../player/player-controller';\nimport { alertDialogContext } from '../alert-dialog/context';\nimport { MediaElement } from '../media-element';\n\nconst FALLBACK_MESSAGE = 'An error occurred. Please try again.';\n\nlet idCounter = 0;\n\nexport class ErrorDialogElement extends MediaElement {\n static readonly tagName = 'media-error-dialog';\n\n readonly #core = new ErrorDialogCore();\n readonly #provider = new ContextProvider(this, { context: alertDialogContext });\n readonly #titleId = `vjs-error-dialog-title-${idCounter++}`;\n readonly #descriptionId = `vjs-error-dialog-desc-${idCounter++}`;\n readonly #errorState = new PlayerController(this, playerContext, selectError);\n\n #dialog: AlertDialogApi | null = null;\n #snapshot: SnapshotController<AlertDialogInput> | null = null;\n #lastErrorMessage: string | null = null;\n\n constructor() {\n super();\n this.#core.setTitleId(this.#titleId);\n this.#core.setDescriptionId(this.#descriptionId);\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (this.destroyed) return;\n\n this.#dialog = createAlertDialog({\n transition: createTransition(),\n onOpenChange: (nextOpen: boolean) => {\n if (!nextOpen) {\n this.#errorState.value?.dismissError();\n }\n },\n });\n\n this.#dialog.setElement(this);\n\n if (this.#snapshot) {\n this.#snapshot.track(this.#dialog.input);\n } else {\n this.#snapshot = new SnapshotController(this, this.#dialog.input);\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#dialog?.destroy();\n this.#dialog = null;\n }\n\n protected override willUpdate(_changed: PropertyValues): void {\n super.willUpdate(_changed);\n if (!this.#dialog) return;\n\n const errorState = this.#errorState.value;\n const hasError = Boolean(errorState?.error);\n const { active: isOpen } = this.#dialog.input.current;\n\n if (errorState?.error) {\n const message = errorState.error.message?.trim();\n this.#lastErrorMessage = message || null;\n }\n\n // Set description text before opening so content is ready for the transition.\n const desc = this.querySelector('media-alert-dialog-description');\n if (desc) {\n desc.textContent = this.#lastErrorMessage ?? FALLBACK_MESSAGE;\n }\n\n if (hasError && !isOpen) {\n this.#dialog.open();\n } else if (!hasError && isOpen) {\n this.#dialog.close();\n }\n }\n\n protected override update(_changed: PropertyValues): void {\n super.update(_changed);\n if (!this.#dialog) return;\n\n const input = this.#dialog.input.current;\n this.#core.setInput(input);\n const state = this.#core.getState();\n\n applyElementProps(this, this.#core.getAttrs(state));\n applyStateDataAttrs(this, state, AlertDialogDataAttrs);\n\n this.#provider.setValue({\n state,\n stateAttrMap: AlertDialogDataAttrs,\n close: () => this.#dialog?.close(),\n });\n }\n}\n"],"mappings":";;;;;;;;;AAkBA,MAAM,mBAAmB;AAEzB,IAAI,YAAY;AAEhB,IAAa,qBAAb,cAAwC,aAAa;;iBACzB;;CAE1B,QAAiB,IAAI,iBAAiB;CACtC,YAAqB,IAAI,gBAAgB,MAAM,EAAE,SAAS,oBAAoB,CAAC;CAC/E,WAAoB,0BAA0B;CAC9C,iBAA0B,yBAAyB;CACnD,cAAuB,IAAI,iBAAiB,MAAM,eAAe,YAAY;CAE7E,UAAiC;CACjC,YAAyD;CACzD,oBAAmC;CAEnC,cAAc;AACZ,SAAO;AACP,QAAA,KAAW,WAAW,MAAA,QAAc;AACpC,QAAA,KAAW,iBAAiB,MAAA,cAAoB;;CAGlD,oBAAmC;AACjC,QAAM,mBAAmB;AACzB,MAAI,KAAK,UAAW;AAEpB,QAAA,SAAe,kBAAkB;GAC/B,YAAY,kBAAkB;GAC9B,eAAe,aAAsB;AACnC,QAAI,CAAC,SACH,OAAA,WAAiB,OAAO,cAAc;;GAG3C,CAAC;AAEF,QAAA,OAAa,WAAW,KAAK;AAE7B,MAAI,MAAA,SACF,OAAA,SAAe,MAAM,MAAA,OAAa,MAAM;MAExC,OAAA,WAAiB,IAAI,mBAAmB,MAAM,MAAA,OAAa,MAAM;;CAIrE,uBAAsC;AACpC,QAAM,sBAAsB;AAC5B,QAAA,QAAc,SAAS;AACvB,QAAA,SAAe;;CAGjB,WAA8B,UAAgC;AAC5D,QAAM,WAAW,SAAS;AAC1B,MAAI,CAAC,MAAA,OAAc;EAEnB,MAAM,aAAa,MAAA,WAAiB;EACpC,MAAM,WAAW,QAAQ,YAAY,MAAM;EAC3C,MAAM,EAAE,QAAQ,WAAW,MAAA,OAAa,MAAM;AAE9C,MAAI,YAAY,MAEd,OAAA,mBADgB,WAAW,MAAM,SAAS,MAAM,IACZ;EAItC,MAAM,OAAO,KAAK,cAAc,iCAAiC;AACjE,MAAI,KACF,MAAK,cAAc,MAAA,oBAA0B;AAG/C,MAAI,YAAY,CAAC,OACf,OAAA,OAAa,MAAM;WACV,CAAC,YAAY,OACtB,OAAA,OAAa,OAAO;;CAIxB,OAA0B,UAAgC;AACxD,QAAM,OAAO,SAAS;AACtB,MAAI,CAAC,MAAA,OAAc;EAEnB,MAAM,QAAQ,MAAA,OAAa,MAAM;AACjC,QAAA,KAAW,SAAS,MAAM;EAC1B,MAAM,QAAQ,MAAA,KAAW,UAAU;AAEnC,oBAAkB,MAAM,MAAA,KAAW,SAAS,MAAM,CAAC;AACnD,sBAAoB,MAAM,OAAO,qBAAqB;AAEtD,QAAA,SAAe,SAAS;GACtB;GACA,cAAc;GACd,aAAa,MAAA,QAAc,OAAO;GACnC,CAAC"}
@@ -10,6 +10,7 @@ var FullscreenButtonElement = class extends MediaButtonElement {
10
10
  this.core = new FullscreenButtonCore();
11
11
  this.stateAttrMap = FullscreenButtonDataAttrs;
12
12
  this.mediaState = new PlayerController(this, playerContext, selectFullscreen);
13
+ this.hotkeyAction = "toggleFullscreen";
13
14
  }
14
15
  static {
15
16
  this.tagName = "media-fullscreen-button";
@@ -1 +1 @@
1
- {"version":3,"file":"fullscreen-button-element.js","names":[],"sources":["../../../../src/ui/fullscreen-button/fullscreen-button-element.ts"],"sourcesContent":["import { FullscreenButtonCore, FullscreenButtonDataAttrs, type MediaFullscreenState } from '@videojs/core';\nimport { selectFullscreen } from '@videojs/core/dom';\n\nimport { playerContext } from '../../player/context';\nimport { PlayerController } from '../../player/player-controller';\nimport { MediaButtonElement } from '../media-button-element';\n\nexport class FullscreenButtonElement extends MediaButtonElement<FullscreenButtonCore> {\n static readonly tagName = 'media-fullscreen-button';\n\n protected readonly core = new FullscreenButtonCore();\n protected readonly stateAttrMap = FullscreenButtonDataAttrs;\n protected readonly mediaState = new PlayerController(this, playerContext, selectFullscreen);\n\n protected activate(state: MediaFullscreenState): void {\n this.core.toggle(state);\n }\n}\n"],"mappings":";;;;;;AAOA,IAAa,0BAAb,cAA6C,mBAAyC;;;cAG1D,IAAI,sBAAsB;sBAClB;oBACF,IAAI,iBAAiB,MAAM,eAAe,iBAAiB;;;iBAJjE;;CAM1B,SAAmB,OAAmC;AACpD,OAAK,KAAK,OAAO,MAAM"}
1
+ {"version":3,"file":"fullscreen-button-element.js","names":[],"sources":["../../../../src/ui/fullscreen-button/fullscreen-button-element.ts"],"sourcesContent":["import { FullscreenButtonCore, FullscreenButtonDataAttrs, type MediaFullscreenState } from '@videojs/core';\nimport { selectFullscreen } from '@videojs/core/dom';\n\nimport { playerContext } from '../../player/context';\nimport { PlayerController } from '../../player/player-controller';\nimport { MediaButtonElement } from '../media-button-element';\n\nexport class FullscreenButtonElement extends MediaButtonElement<FullscreenButtonCore> {\n static readonly tagName = 'media-fullscreen-button';\n\n protected readonly core = new FullscreenButtonCore();\n protected readonly stateAttrMap = FullscreenButtonDataAttrs;\n protected readonly mediaState = new PlayerController(this, playerContext, selectFullscreen);\n protected override readonly hotkeyAction = 'toggleFullscreen';\n\n protected activate(state: MediaFullscreenState): void {\n this.core.toggle(state);\n }\n}\n"],"mappings":";;;;;;AAOA,IAAa,0BAAb,cAA6C,mBAAyC;;;cAG1D,IAAI,sBAAsB;sBAClB;oBACF,IAAI,iBAAiB,MAAM,eAAe,iBAAiB;sBAChD;;;iBALjB;;CAO1B,SAAmB,OAAmC;AACpD,OAAK,KAAK,OAAO,MAAM"}
@@ -0,0 +1,84 @@
1
+ import { containerContext, playerContext } from "../../player/context.js";
2
+ import { MediaElement } from "../media-element.js";
3
+ import { PlayerController } from "../../player/player-controller.js";
4
+ import { createDoubleTapGesture, createTapGesture, resolveGestureAction } from "@videojs/core/dom";
5
+ import { ContextConsumer } from "@videojs/element/context";
6
+ //#region src/ui/gesture/gesture-element.ts
7
+ var GestureElement = class extends MediaElement {
8
+ constructor(..._args) {
9
+ super(..._args);
10
+ this.type = "";
11
+ this.action = "";
12
+ this.value = void 0;
13
+ this.pointer = void 0;
14
+ this.region = void 0;
15
+ this.disabled = false;
16
+ }
17
+ static {
18
+ this.tagName = "media-gesture";
19
+ }
20
+ static {
21
+ this.properties = {
22
+ type: { type: String },
23
+ action: { type: String },
24
+ value: { type: Number },
25
+ pointer: { type: String },
26
+ region: { type: String },
27
+ disabled: { type: Boolean }
28
+ };
29
+ }
30
+ #player = new PlayerController(this, playerContext);
31
+ #container = new ContextConsumer(this, {
32
+ context: containerContext,
33
+ callback: () => this.requestUpdate(),
34
+ subscribe: true
35
+ });
36
+ #cleanup = null;
37
+ connectedCallback() {
38
+ super.connectedCallback();
39
+ this.style.display = "none";
40
+ this.#register();
41
+ }
42
+ disconnectedCallback() {
43
+ super.disconnectedCallback();
44
+ this.#unregister();
45
+ }
46
+ update(changed) {
47
+ super.update(changed);
48
+ if (this.isConnected) {
49
+ this.#unregister();
50
+ this.#register();
51
+ }
52
+ }
53
+ #register() {
54
+ const store = this.#player.value;
55
+ const container = this.#container.value?.container;
56
+ if (!this.type || !this.action || !store || !container) return;
57
+ const resolver = resolveGestureAction(this.action);
58
+ if (!resolver) return;
59
+ const { value } = this;
60
+ const onActivate = (event) => {
61
+ resolver({
62
+ store,
63
+ value,
64
+ event
65
+ });
66
+ };
67
+ const options = {
68
+ pointer: this.pointer,
69
+ region: this.region,
70
+ disabled: this.disabled,
71
+ action: this.action
72
+ };
73
+ if (this.type === "doubletap") this.#cleanup = createDoubleTapGesture(container, onActivate, options);
74
+ else this.#cleanup = createTapGesture(container, onActivate, options);
75
+ }
76
+ #unregister() {
77
+ this.#cleanup?.();
78
+ this.#cleanup = null;
79
+ }
80
+ };
81
+ //#endregion
82
+ export { GestureElement };
83
+
84
+ //# sourceMappingURL=gesture-element.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gesture-element.js","names":["#player","#container","#register","#unregister","#cleanup"],"sources":["../../../../src/ui/gesture/gesture-element.ts"],"sourcesContent":["import {\n createDoubleTapGesture,\n createTapGesture,\n type GestureActionName,\n type GesturePointerType,\n type GestureRegion,\n resolveGestureAction,\n} from '@videojs/core/dom';\nimport type { PropertyDeclarationMap, PropertyValues } from '@videojs/element';\nimport { ContextConsumer } from '@videojs/element/context';\n\nimport { containerContext, playerContext } from '../../player/context';\nimport { PlayerController } from '../../player/player-controller';\nimport { MediaElement } from '../media-element';\n\nexport class GestureElement extends MediaElement {\n static readonly tagName = 'media-gesture';\n\n static override properties: PropertyDeclarationMap = {\n type: { type: String },\n action: { type: String },\n value: { type: Number },\n pointer: { type: String },\n region: { type: String },\n disabled: { type: Boolean },\n };\n\n type: 'tap' | 'doubletap' | (string & {}) = '';\n action: GestureActionName | (string & {}) = '';\n value: number | undefined = undefined;\n pointer: GesturePointerType | undefined = undefined;\n region: GestureRegion | undefined = undefined;\n disabled = false;\n\n readonly #player = new PlayerController(this, playerContext);\n readonly #container = new ContextConsumer(this, {\n context: containerContext,\n callback: () => this.requestUpdate(),\n subscribe: true,\n });\n #cleanup: (() => void) | null = null;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.style.display = 'none';\n this.#register();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#unregister();\n }\n\n protected override update(changed: PropertyValues): void {\n super.update(changed);\n\n // Re-register when attributes change.\n if (this.isConnected) {\n this.#unregister();\n this.#register();\n }\n }\n\n #register(): void {\n const store = this.#player.value;\n const container = this.#container.value?.container;\n if (!this.type || !this.action || !store || !container) return;\n\n const resolver = resolveGestureAction(this.action);\n if (!resolver) return;\n\n const { value } = this;\n\n const onActivate = (event: PointerEvent) => {\n resolver({ store, value, event });\n };\n\n const options = {\n pointer: this.pointer,\n region: this.region,\n disabled: this.disabled,\n action: this.action,\n };\n\n if (this.type === 'doubletap') {\n this.#cleanup = createDoubleTapGesture(container, onActivate, options);\n } else {\n this.#cleanup = createTapGesture(container, onActivate, options);\n }\n }\n\n #unregister(): void {\n this.#cleanup?.();\n this.#cleanup = null;\n }\n}\n"],"mappings":";;;;;;AAeA,IAAa,iBAAb,cAAoC,aAAa;;;cAYH;gBACA;eAChB,KAAA;iBACc,KAAA;gBACN,KAAA;kBACzB;;;iBAhBe;;;oBAE2B;GACnD,MAAM,EAAE,MAAM,QAAQ;GACtB,QAAQ,EAAE,MAAM,QAAQ;GACxB,OAAO,EAAE,MAAM,QAAQ;GACvB,SAAS,EAAE,MAAM,QAAQ;GACzB,QAAQ,EAAE,MAAM,QAAQ;GACxB,UAAU,EAAE,MAAM,SAAS;GAC5B;;CASD,UAAmB,IAAI,iBAAiB,MAAM,cAAc;CAC5D,aAAsB,IAAI,gBAAgB,MAAM;EAC9C,SAAS;EACT,gBAAgB,KAAK,eAAe;EACpC,WAAW;EACZ,CAAC;CACF,WAAgC;CAEhC,oBAAmC;AACjC,QAAM,mBAAmB;AACzB,OAAK,MAAM,UAAU;AACrB,QAAA,UAAgB;;CAGlB,uBAAsC;AACpC,QAAM,sBAAsB;AAC5B,QAAA,YAAkB;;CAGpB,OAA0B,SAA+B;AACvD,QAAM,OAAO,QAAQ;AAGrB,MAAI,KAAK,aAAa;AACpB,SAAA,YAAkB;AAClB,SAAA,UAAgB;;;CAIpB,YAAkB;EAChB,MAAM,QAAQ,MAAA,OAAa;EAC3B,MAAM,YAAY,MAAA,UAAgB,OAAO;AACzC,MAAI,CAAC,KAAK,QAAQ,CAAC,KAAK,UAAU,CAAC,SAAS,CAAC,UAAW;EAExD,MAAM,WAAW,qBAAqB,KAAK,OAAO;AAClD,MAAI,CAAC,SAAU;EAEf,MAAM,EAAE,UAAU;EAElB,MAAM,cAAc,UAAwB;AAC1C,YAAS;IAAE;IAAO;IAAO;IAAO,CAAC;;EAGnC,MAAM,UAAU;GACd,SAAS,KAAK;GACd,QAAQ,KAAK;GACb,UAAU,KAAK;GACf,QAAQ,KAAK;GACd;AAED,MAAI,KAAK,SAAS,YAChB,OAAA,UAAgB,uBAAuB,WAAW,YAAY,QAAQ;MAEtE,OAAA,UAAgB,iBAAiB,WAAW,YAAY,QAAQ;;CAIpE,cAAoB;AAClB,QAAA,WAAiB;AACjB,QAAA,UAAgB"}
@@ -0,0 +1,28 @@
1
+ import { containerContext } from "../../player/context.js";
2
+ import { findHotkeyCoordinator } from "@videojs/core/dom";
3
+ import { ContextConsumer } from "@videojs/element/context";
4
+ //#region src/ui/hotkey/aria-key-shortcuts-controller.ts
5
+ /** Provides `aria-keyshortcuts` for a given hotkey action name. */
6
+ var AriaKeyShortcutsController = class {
7
+ #action;
8
+ #container;
9
+ constructor(host, action) {
10
+ this.#action = action;
11
+ this.#container = new ContextConsumer(host, {
12
+ context: containerContext,
13
+ subscribe: true
14
+ });
15
+ host.addController(this);
16
+ }
17
+ get value() {
18
+ const container = this.#container.value?.container;
19
+ if (!container) return void 0;
20
+ return findHotkeyCoordinator(container)?.getAriaKeys(this.#action);
21
+ }
22
+ hostConnected() {}
23
+ hostDisconnected() {}
24
+ };
25
+ //#endregion
26
+ export { AriaKeyShortcutsController };
27
+
28
+ //# sourceMappingURL=aria-key-shortcuts-controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aria-key-shortcuts-controller.js","names":["#action","#container"],"sources":["../../../../src/ui/hotkey/aria-key-shortcuts-controller.ts"],"sourcesContent":["import { findHotkeyCoordinator } from '@videojs/core/dom';\nimport type { ReactiveController } from '@videojs/element';\nimport { ContextConsumer } from '@videojs/element/context';\n\nimport type { ContainerContextConsumer } from '../../player/context';\nimport { containerContext } from '../../player/context';\nimport type { PlayerControllerHost } from '../../player/player-controller';\n\n/** Provides `aria-keyshortcuts` for a given hotkey action name. */\nexport class AriaKeyShortcutsController implements ReactiveController {\n #action: string;\n #container: ContainerContextConsumer;\n\n constructor(host: PlayerControllerHost, action: string) {\n this.#action = action;\n this.#container = new ContextConsumer(host, { context: containerContext, subscribe: true });\n host.addController(this);\n }\n\n get value(): string | undefined {\n const container = this.#container.value?.container;\n if (!container) return undefined;\n return findHotkeyCoordinator(container)?.getAriaKeys(this.#action);\n }\n\n hostConnected(): void {}\n hostDisconnected(): void {}\n}\n"],"mappings":";;;;;AASA,IAAa,6BAAb,MAAsE;CACpE;CACA;CAEA,YAAY,MAA4B,QAAgB;AACtD,QAAA,SAAe;AACf,QAAA,YAAkB,IAAI,gBAAgB,MAAM;GAAE,SAAS;GAAkB,WAAW;GAAM,CAAC;AAC3F,OAAK,cAAc,KAAK;;CAG1B,IAAI,QAA4B;EAC9B,MAAM,YAAY,MAAA,UAAgB,OAAO;AACzC,MAAI,CAAC,UAAW,QAAO,KAAA;AACvB,SAAO,sBAAsB,UAAU,EAAE,YAAY,MAAA,OAAa;;CAGpE,gBAAsB;CACtB,mBAAyB"}
@@ -0,0 +1,81 @@
1
+ import { containerContext, playerContext } from "../../player/context.js";
2
+ import { MediaElement } from "../media-element.js";
3
+ import { PlayerController } from "../../player/player-controller.js";
4
+ import { createHotkey, isHotkeyToggleAction, resolveHotkeyAction } from "@videojs/core/dom";
5
+ import { ContextConsumer } from "@videojs/element/context";
6
+ //#region src/ui/hotkey/hotkey-element.ts
7
+ var HotkeyElement = class extends MediaElement {
8
+ constructor(..._args) {
9
+ super(..._args);
10
+ this.keys = "";
11
+ this.action = "";
12
+ this.value = void 0;
13
+ this.disabled = false;
14
+ this.target = "player";
15
+ }
16
+ static {
17
+ this.tagName = "media-hotkey";
18
+ }
19
+ static {
20
+ this.properties = {
21
+ keys: { type: String },
22
+ action: { type: String },
23
+ value: { type: Number },
24
+ disabled: { type: Boolean },
25
+ target: { type: String }
26
+ };
27
+ }
28
+ #player = new PlayerController(this, playerContext);
29
+ #container = new ContextConsumer(this, {
30
+ context: containerContext,
31
+ callback: () => this.requestUpdate(),
32
+ subscribe: true
33
+ });
34
+ #cleanup = null;
35
+ connectedCallback() {
36
+ super.connectedCallback();
37
+ this.style.display = "none";
38
+ this.#register();
39
+ }
40
+ disconnectedCallback() {
41
+ super.disconnectedCallback();
42
+ this.#unregister();
43
+ }
44
+ update(changed) {
45
+ super.update(changed);
46
+ if (this.isConnected) {
47
+ this.#unregister();
48
+ this.#register();
49
+ }
50
+ }
51
+ #register() {
52
+ const store = this.#player.value;
53
+ const container = this.#container.value?.container;
54
+ if (!this.keys || !this.action || !store || !container) return;
55
+ const resolver = resolveHotkeyAction(this.action);
56
+ if (!resolver) return;
57
+ const { value, action } = this;
58
+ this.#cleanup = createHotkey(container, {
59
+ keys: this.keys,
60
+ action,
61
+ target: this.target,
62
+ disabled: this.disabled,
63
+ repeatable: !isHotkeyToggleAction(action),
64
+ onActivate: (_event, key) => {
65
+ resolver({
66
+ store,
67
+ key,
68
+ value
69
+ });
70
+ }
71
+ });
72
+ }
73
+ #unregister() {
74
+ this.#cleanup?.();
75
+ this.#cleanup = null;
76
+ }
77
+ };
78
+ //#endregion
79
+ export { HotkeyElement };
80
+
81
+ //# sourceMappingURL=hotkey-element.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hotkey-element.js","names":["#player","#container","#register","#unregister","#cleanup"],"sources":["../../../../src/ui/hotkey/hotkey-element.ts"],"sourcesContent":["import { createHotkey, type HotkeyActionName, isHotkeyToggleAction, resolveHotkeyAction } from '@videojs/core/dom';\nimport type { PropertyDeclarationMap, PropertyValues } from '@videojs/element';\nimport { ContextConsumer } from '@videojs/element/context';\n\nimport { containerContext, playerContext } from '../../player/context';\nimport { PlayerController } from '../../player/player-controller';\nimport { MediaElement } from '../media-element';\n\nexport class HotkeyElement extends MediaElement {\n static readonly tagName = 'media-hotkey';\n\n static override properties: PropertyDeclarationMap = {\n keys: { type: String },\n action: { type: String },\n value: { type: Number },\n disabled: { type: Boolean },\n target: { type: String },\n };\n\n keys = '';\n action: HotkeyActionName | (string & {}) = '';\n value: number | undefined = undefined;\n disabled = false;\n target: 'player' | 'document' = 'player';\n\n readonly #player = new PlayerController(this, playerContext);\n readonly #container = new ContextConsumer(this, {\n context: containerContext,\n callback: () => this.requestUpdate(),\n subscribe: true,\n });\n #cleanup: (() => void) | null = null;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.style.display = 'none';\n this.#register();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#unregister();\n }\n\n protected override update(changed: PropertyValues): void {\n super.update(changed);\n\n // Re-register when attributes change.\n if (this.isConnected) {\n this.#unregister();\n this.#register();\n }\n }\n\n #register(): void {\n const store = this.#player.value;\n const container = this.#container.value?.container;\n if (!this.keys || !this.action || !store || !container) return;\n\n const resolver = resolveHotkeyAction(this.action);\n if (!resolver) return;\n\n const { value, action } = this;\n\n this.#cleanup = createHotkey(container, {\n keys: this.keys,\n action,\n target: this.target,\n disabled: this.disabled,\n repeatable: !isHotkeyToggleAction(action),\n onActivate: (_event, key) => {\n resolver({ store, key, value });\n },\n });\n }\n\n #unregister(): void {\n this.#cleanup?.();\n this.#cleanup = null;\n }\n}\n"],"mappings":";;;;;;AAQA,IAAa,gBAAb,cAAmC,aAAa;;;cAWvC;gBACoC;eACf,KAAA;kBACjB;gBACqB;;;iBAdN;;;oBAE2B;GACnD,MAAM,EAAE,MAAM,QAAQ;GACtB,QAAQ,EAAE,MAAM,QAAQ;GACxB,OAAO,EAAE,MAAM,QAAQ;GACvB,UAAU,EAAE,MAAM,SAAS;GAC3B,QAAQ,EAAE,MAAM,QAAQ;GACzB;;CAQD,UAAmB,IAAI,iBAAiB,MAAM,cAAc;CAC5D,aAAsB,IAAI,gBAAgB,MAAM;EAC9C,SAAS;EACT,gBAAgB,KAAK,eAAe;EACpC,WAAW;EACZ,CAAC;CACF,WAAgC;CAEhC,oBAAmC;AACjC,QAAM,mBAAmB;AACzB,OAAK,MAAM,UAAU;AACrB,QAAA,UAAgB;;CAGlB,uBAAsC;AACpC,QAAM,sBAAsB;AAC5B,QAAA,YAAkB;;CAGpB,OAA0B,SAA+B;AACvD,QAAM,OAAO,QAAQ;AAGrB,MAAI,KAAK,aAAa;AACpB,SAAA,YAAkB;AAClB,SAAA,UAAgB;;;CAIpB,YAAkB;EAChB,MAAM,QAAQ,MAAA,OAAa;EAC3B,MAAM,YAAY,MAAA,UAAgB,OAAO;AACzC,MAAI,CAAC,KAAK,QAAQ,CAAC,KAAK,UAAU,CAAC,SAAS,CAAC,UAAW;EAExD,MAAM,WAAW,oBAAoB,KAAK,OAAO;AACjD,MAAI,CAAC,SAAU;EAEf,MAAM,EAAE,OAAO,WAAW;AAE1B,QAAA,UAAgB,aAAa,WAAW;GACtC,MAAM,KAAK;GACX;GACA,QAAQ,KAAK;GACb,UAAU,KAAK;GACf,YAAY,CAAC,qBAAqB,OAAO;GACzC,aAAa,QAAQ,QAAQ;AAC3B,aAAS;KAAE;KAAO;KAAK;KAAO,CAAC;;GAElC,CAAC;;CAGJ,cAAoB;AAClB,QAAA,WAAiB;AACjB,QAAA,UAAgB"}
@@ -1,4 +1,5 @@
1
1
  import { MediaElement } from "./media-element.js";
2
+ import { AriaKeyShortcutsController } from "./hotkey/aria-key-shortcuts-controller.js";
2
3
  import { applyElementProps, applyStateDataAttrs, createButton } from "@videojs/core/dom";
3
4
  //#region src/ui/media-button-element.ts
4
5
  /** Abstract base for HTML custom elements that render a media-control button. */
@@ -7,6 +8,7 @@ var MediaButtonElement = class extends MediaElement {
7
8
  super(..._args);
8
9
  this.disabled = false;
9
10
  this.label = "";
11
+ this.hotkeyAction = void 0;
10
12
  }
11
13
  static {
12
14
  this.properties = {
@@ -18,8 +20,11 @@ var MediaButtonElement = class extends MediaElement {
18
20
  return this.core.state;
19
21
  }
20
22
  #disconnect = null;
23
+ #hotkeyRegistry = null;
21
24
  connectedCallback() {
22
25
  super.connectedCallback();
26
+ if (this.destroyed) return;
27
+ if (this.hotkeyAction && !this.#hotkeyRegistry) this.#hotkeyRegistry = new AriaKeyShortcutsController(this, this.hotkeyAction);
23
28
  this.#disconnect = new AbortController();
24
29
  const buttonProps = createButton({
25
30
  onActivate: () => this.activate(this.mediaState.value),
@@ -46,7 +51,10 @@ var MediaButtonElement = class extends MediaElement {
46
51
  if (!media) return;
47
52
  this.core.setMedia(media);
48
53
  const state = this.core.getState();
49
- applyElementProps(this, this.core.getAttrs?.(state) ?? {});
54
+ applyElementProps(this, {
55
+ ...this.core.getAttrs?.(state),
56
+ "aria-keyshortcuts": this.#hotkeyRegistry?.value
57
+ });
50
58
  applyStateDataAttrs(this, state, this.stateAttrMap);
51
59
  }
52
60
  };
@@ -1 +1 @@
1
- {"version":3,"file":"media-button-element.js","names":["#disconnect"],"sources":["../../../src/ui/media-button-element.ts"],"sourcesContent":["import type {\n ButtonState,\n InferComponentState,\n InferMediaState,\n MediaButtonComponent,\n StateAttrMap,\n} from '@videojs/core';\nimport { applyElementProps, applyStateDataAttrs, createButton, logMissingFeature } from '@videojs/core/dom';\nimport type { PropertyDeclarationMap, PropertyValues } from '@videojs/element';\nimport type { State } from '@videojs/store';\n\nimport type { PlayerController } from '../player/player-controller';\nimport { MediaElement } from './media-element';\n\n/** Abstract base for HTML custom elements that render a media-control button. */\nexport abstract class MediaButtonElement<Core extends MediaButtonComponent> extends MediaElement {\n static override properties: PropertyDeclarationMap = {\n label: { type: String },\n disabled: { type: Boolean },\n };\n\n disabled = false;\n label = '';\n\n protected abstract readonly core: Core;\n protected abstract readonly stateAttrMap: StateAttrMap<InferComponentState<Core>>;\n protected abstract readonly mediaState: PlayerController<any, InferMediaState<Core> | undefined>;\n\n protected abstract activate(state: InferMediaState<Core>): void;\n\n get $state(): State<ButtonState> {\n return this.core.state;\n }\n\n #disconnect: AbortController | null = null;\n\n override connectedCallback(): void {\n super.connectedCallback();\n\n this.#disconnect = new AbortController();\n\n const buttonProps = createButton({\n onActivate: () => this.activate(this.mediaState.value!),\n isDisabled: () => this.disabled || !this.mediaState.value,\n });\n\n applyElementProps(this, buttonProps, { signal: this.#disconnect.signal });\n\n if (__DEV__ && !this.mediaState.value && this.mediaState.displayName) {\n logMissingFeature(this.localName, this.mediaState.displayName);\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#disconnect?.abort();\n this.#disconnect = null;\n }\n\n /** Returns the button's current label derived from media state. */\n getLabel(): string | undefined {\n return this.core.state.current.label || undefined;\n }\n\n protected override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n this.core.setProps?.(this);\n }\n\n protected override update(changed: PropertyValues): void {\n super.update(changed);\n\n const media = this.mediaState.value;\n\n if (!media) return;\n\n this.core.setMedia(media);\n const state = this.core.getState();\n applyElementProps(this, this.core.getAttrs?.(state) ?? {});\n applyStateDataAttrs(this, state, this.stateAttrMap);\n }\n}\n"],"mappings":";;;;AAeA,IAAsB,qBAAtB,cAAoF,aAAa;;;kBAMpF;eACH;;;oBAN6C;GACnD,OAAO,EAAE,MAAM,QAAQ;GACvB,UAAU,EAAE,MAAM,SAAS;GAC5B;;CAWD,IAAI,SAA6B;AAC/B,SAAO,KAAK,KAAK;;CAGnB,cAAsC;CAEtC,oBAAmC;AACjC,QAAM,mBAAmB;AAEzB,QAAA,aAAmB,IAAI,iBAAiB;EAExC,MAAM,cAAc,aAAa;GAC/B,kBAAkB,KAAK,SAAS,KAAK,WAAW,MAAO;GACvD,kBAAkB,KAAK,YAAY,CAAC,KAAK,WAAW;GACrD,CAAC;AAEF,oBAAkB,MAAM,aAAa,EAAE,QAAQ,MAAA,WAAiB,QAAQ,CAAC;;CAO3E,uBAAsC;AACpC,QAAM,sBAAsB;AAC5B,QAAA,YAAkB,OAAO;AACzB,QAAA,aAAmB;;;CAIrB,WAA+B;AAC7B,SAAO,KAAK,KAAK,MAAM,QAAQ,SAAS,KAAA;;CAG1C,WAA8B,SAA+B;AAC3D,QAAM,WAAW,QAAQ;AACzB,OAAK,KAAK,WAAW,KAAK;;CAG5B,OAA0B,SAA+B;AACvD,QAAM,OAAO,QAAQ;EAErB,MAAM,QAAQ,KAAK,WAAW;AAE9B,MAAI,CAAC,MAAO;AAEZ,OAAK,KAAK,SAAS,MAAM;EACzB,MAAM,QAAQ,KAAK,KAAK,UAAU;AAClC,oBAAkB,MAAM,KAAK,KAAK,WAAW,MAAM,IAAI,EAAE,CAAC;AAC1D,sBAAoB,MAAM,OAAO,KAAK,aAAa"}
1
+ {"version":3,"file":"media-button-element.js","names":["#hotkeyRegistry","#disconnect"],"sources":["../../../src/ui/media-button-element.ts"],"sourcesContent":["import type {\n ButtonState,\n InferComponentState,\n InferMediaState,\n MediaButtonComponent,\n StateAttrMap,\n} from '@videojs/core';\nimport { applyElementProps, applyStateDataAttrs, createButton, logMissingFeature } from '@videojs/core/dom';\nimport type { PropertyDeclarationMap, PropertyValues } from '@videojs/element';\nimport type { State } from '@videojs/store';\n\nimport type { PlayerController } from '../player/player-controller';\nimport { AriaKeyShortcutsController } from './hotkey/aria-key-shortcuts-controller';\nimport { MediaElement } from './media-element';\n\n/** Abstract base for HTML custom elements that render a media-control button. */\nexport abstract class MediaButtonElement<Core extends MediaButtonComponent> extends MediaElement {\n static override properties: PropertyDeclarationMap = {\n label: { type: String },\n disabled: { type: Boolean },\n };\n\n disabled = false;\n label = '';\n\n protected abstract readonly core: Core;\n protected abstract readonly stateAttrMap: StateAttrMap<InferComponentState<Core>>;\n protected abstract readonly mediaState: PlayerController<any, InferMediaState<Core> | undefined>;\n\n protected abstract activate(state: InferMediaState<Core>): void;\n\n /** Override to set the hotkey action name for `aria-keyshortcuts`. */\n protected readonly hotkeyAction: string | undefined = undefined;\n\n get $state(): State<ButtonState> {\n return this.core.state;\n }\n\n #disconnect: AbortController | null = null;\n #hotkeyRegistry: AriaKeyShortcutsController | null = null;\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (this.destroyed) return;\n\n if (this.hotkeyAction && !this.#hotkeyRegistry) {\n this.#hotkeyRegistry = new AriaKeyShortcutsController(this, this.hotkeyAction);\n }\n\n this.#disconnect = new AbortController();\n\n const buttonProps = createButton({\n onActivate: () => this.activate(this.mediaState.value!),\n isDisabled: () => this.disabled || !this.mediaState.value,\n });\n\n applyElementProps(this, buttonProps, { signal: this.#disconnect.signal });\n\n if (__DEV__ && !this.mediaState.value && this.mediaState.displayName) {\n logMissingFeature(this.localName, this.mediaState.displayName);\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#disconnect?.abort();\n this.#disconnect = null;\n }\n\n /** Returns the button's current label derived from media state. */\n getLabel(): string | undefined {\n return this.core.state.current.label || undefined;\n }\n\n protected override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n this.core.setProps?.(this);\n }\n\n protected override update(changed: PropertyValues): void {\n super.update(changed);\n\n const media = this.mediaState.value;\n\n if (!media) return;\n\n this.core.setMedia(media);\n const state = this.core.getState();\n applyElementProps(this, {\n ...this.core.getAttrs?.(state),\n 'aria-keyshortcuts': this.#hotkeyRegistry?.value,\n });\n applyStateDataAttrs(this, state, this.stateAttrMap);\n }\n}\n"],"mappings":";;;;;AAgBA,IAAsB,qBAAtB,cAAoF,aAAa;;;kBAMpF;eACH;sBAS8C,KAAA;;;oBAfD;GACnD,OAAO,EAAE,MAAM,QAAQ;GACvB,UAAU,EAAE,MAAM,SAAS;GAC5B;;CAcD,IAAI,SAA6B;AAC/B,SAAO,KAAK,KAAK;;CAGnB,cAAsC;CACtC,kBAAqD;CAErD,oBAAmC;AACjC,QAAM,mBAAmB;AACzB,MAAI,KAAK,UAAW;AAEpB,MAAI,KAAK,gBAAgB,CAAC,MAAA,eACxB,OAAA,iBAAuB,IAAI,2BAA2B,MAAM,KAAK,aAAa;AAGhF,QAAA,aAAmB,IAAI,iBAAiB;EAExC,MAAM,cAAc,aAAa;GAC/B,kBAAkB,KAAK,SAAS,KAAK,WAAW,MAAO;GACvD,kBAAkB,KAAK,YAAY,CAAC,KAAK,WAAW;GACrD,CAAC;AAEF,oBAAkB,MAAM,aAAa,EAAE,QAAQ,MAAA,WAAiB,QAAQ,CAAC;;CAO3E,uBAAsC;AACpC,QAAM,sBAAsB;AAC5B,QAAA,YAAkB,OAAO;AACzB,QAAA,aAAmB;;;CAIrB,WAA+B;AAC7B,SAAO,KAAK,KAAK,MAAM,QAAQ,SAAS,KAAA;;CAG1C,WAA8B,SAA+B;AAC3D,QAAM,WAAW,QAAQ;AACzB,OAAK,KAAK,WAAW,KAAK;;CAG5B,OAA0B,SAA+B;AACvD,QAAM,OAAO,QAAQ;EAErB,MAAM,QAAQ,KAAK,WAAW;AAE9B,MAAI,CAAC,MAAO;AAEZ,OAAK,KAAK,SAAS,MAAM;EACzB,MAAM,QAAQ,KAAK,KAAK,UAAU;AAClC,oBAAkB,MAAM;GACtB,GAAG,KAAK,KAAK,WAAW,MAAM;GAC9B,qBAAqB,MAAA,gBAAsB;GAC5C,CAAC;AACF,sBAAoB,MAAM,OAAO,KAAK,aAAa"}
@@ -10,6 +10,7 @@ var MuteButtonElement = class extends MediaButtonElement {
10
10
  this.core = new MuteButtonCore();
11
11
  this.stateAttrMap = MuteButtonDataAttrs;
12
12
  this.mediaState = new PlayerController(this, playerContext, selectVolume);
13
+ this.hotkeyAction = "toggleMuted";
13
14
  }
14
15
  static {
15
16
  this.tagName = "media-mute-button";
@@ -1 +1 @@
1
- {"version":3,"file":"mute-button-element.js","names":[],"sources":["../../../../src/ui/mute-button/mute-button-element.ts"],"sourcesContent":["import { type MediaVolumeState, MuteButtonCore, MuteButtonDataAttrs } from '@videojs/core';\nimport { selectVolume } from '@videojs/core/dom';\n\nimport { playerContext } from '../../player/context';\nimport { PlayerController } from '../../player/player-controller';\nimport { MediaButtonElement } from '../media-button-element';\n\nexport class MuteButtonElement extends MediaButtonElement<MuteButtonCore> {\n static readonly tagName = 'media-mute-button';\n\n protected readonly core = new MuteButtonCore();\n protected readonly stateAttrMap = MuteButtonDataAttrs;\n protected readonly mediaState = new PlayerController(this, playerContext, selectVolume);\n\n protected activate(state: MediaVolumeState): void {\n this.core.toggle(state);\n }\n}\n"],"mappings":";;;;;;AAOA,IAAa,oBAAb,cAAuC,mBAAmC;;;cAG9C,IAAI,gBAAgB;sBACZ;oBACF,IAAI,iBAAiB,MAAM,eAAe,aAAa;;;iBAJ7D;;CAM1B,SAAmB,OAA+B;AAChD,OAAK,KAAK,OAAO,MAAM"}
1
+ {"version":3,"file":"mute-button-element.js","names":[],"sources":["../../../../src/ui/mute-button/mute-button-element.ts"],"sourcesContent":["import { type MediaVolumeState, MuteButtonCore, MuteButtonDataAttrs } from '@videojs/core';\nimport { selectVolume } from '@videojs/core/dom';\n\nimport { playerContext } from '../../player/context';\nimport { PlayerController } from '../../player/player-controller';\nimport { MediaButtonElement } from '../media-button-element';\n\nexport class MuteButtonElement extends MediaButtonElement<MuteButtonCore> {\n static readonly tagName = 'media-mute-button';\n\n protected readonly core = new MuteButtonCore();\n protected readonly stateAttrMap = MuteButtonDataAttrs;\n protected readonly mediaState = new PlayerController(this, playerContext, selectVolume);\n protected override readonly hotkeyAction = 'toggleMuted';\n\n protected activate(state: MediaVolumeState): void {\n this.core.toggle(state);\n }\n}\n"],"mappings":";;;;;;AAOA,IAAa,oBAAb,cAAuC,mBAAmC;;;cAG9C,IAAI,gBAAgB;sBACZ;oBACF,IAAI,iBAAiB,MAAM,eAAe,aAAa;sBAC5C;;;iBALjB;;CAO1B,SAAmB,OAA+B;AAChD,OAAK,KAAK,OAAO,MAAM"}
@@ -10,6 +10,7 @@ var PiPButtonElement = class extends MediaButtonElement {
10
10
  this.core = new PiPButtonCore();
11
11
  this.stateAttrMap = PiPButtonDataAttrs;
12
12
  this.mediaState = new PlayerController(this, playerContext, selectPiP);
13
+ this.hotkeyAction = "togglePictureInPicture";
13
14
  }
14
15
  static {
15
16
  this.tagName = "media-pip-button";
@@ -1 +1 @@
1
- {"version":3,"file":"pip-button-element.js","names":[],"sources":["../../../../src/ui/pip-button/pip-button-element.ts"],"sourcesContent":["import { type MediaPictureInPictureState, PiPButtonCore, PiPButtonDataAttrs } from '@videojs/core';\nimport { selectPiP } from '@videojs/core/dom';\n\nimport { playerContext } from '../../player/context';\nimport { PlayerController } from '../../player/player-controller';\nimport { MediaButtonElement } from '../media-button-element';\n\nexport class PiPButtonElement extends MediaButtonElement<PiPButtonCore> {\n static readonly tagName = 'media-pip-button';\n\n protected readonly core = new PiPButtonCore();\n protected readonly stateAttrMap = PiPButtonDataAttrs;\n protected readonly mediaState = new PlayerController(this, playerContext, selectPiP);\n\n protected activate(state: MediaPictureInPictureState): void {\n this.core.toggle(state);\n }\n}\n"],"mappings":";;;;;;AAOA,IAAa,mBAAb,cAAsC,mBAAkC;;;cAG5C,IAAI,eAAe;sBACX;oBACF,IAAI,iBAAiB,MAAM,eAAe,UAAU;;;iBAJ1D;;CAM1B,SAAmB,OAAyC;AAC1D,OAAK,KAAK,OAAO,MAAM"}
1
+ {"version":3,"file":"pip-button-element.js","names":[],"sources":["../../../../src/ui/pip-button/pip-button-element.ts"],"sourcesContent":["import { type MediaPictureInPictureState, PiPButtonCore, PiPButtonDataAttrs } from '@videojs/core';\nimport { selectPiP } from '@videojs/core/dom';\n\nimport { playerContext } from '../../player/context';\nimport { PlayerController } from '../../player/player-controller';\nimport { MediaButtonElement } from '../media-button-element';\n\nexport class PiPButtonElement extends MediaButtonElement<PiPButtonCore> {\n static readonly tagName = 'media-pip-button';\n\n protected readonly core = new PiPButtonCore();\n protected readonly stateAttrMap = PiPButtonDataAttrs;\n protected readonly mediaState = new PlayerController(this, playerContext, selectPiP);\n protected override readonly hotkeyAction = 'togglePictureInPicture';\n\n protected activate(state: MediaPictureInPictureState): void {\n this.core.toggle(state);\n }\n}\n"],"mappings":";;;;;;AAOA,IAAa,mBAAb,cAAsC,mBAAkC;;;cAG5C,IAAI,eAAe;sBACX;oBACF,IAAI,iBAAiB,MAAM,eAAe,UAAU;sBACzC;;;iBALjB;;CAO1B,SAAmB,OAAyC;AAC1D,OAAK,KAAK,OAAO,MAAM"}
@@ -10,6 +10,7 @@ var PlayButtonElement = class extends MediaButtonElement {
10
10
  this.core = new PlayButtonCore();
11
11
  this.stateAttrMap = PlayButtonDataAttrs;
12
12
  this.mediaState = new PlayerController(this, playerContext, selectPlayback);
13
+ this.hotkeyAction = "togglePaused";
13
14
  }
14
15
  static {
15
16
  this.tagName = "media-play-button";
@@ -1 +1 @@
1
- {"version":3,"file":"play-button-element.js","names":[],"sources":["../../../../src/ui/play-button/play-button-element.ts"],"sourcesContent":["import { type MediaPlaybackState, PlayButtonCore, PlayButtonDataAttrs } from '@videojs/core';\nimport { selectPlayback } from '@videojs/core/dom';\n\nimport { playerContext } from '../../player/context';\nimport { PlayerController } from '../../player/player-controller';\nimport { MediaButtonElement } from '../media-button-element';\n\nexport class PlayButtonElement extends MediaButtonElement<PlayButtonCore> {\n static readonly tagName = 'media-play-button';\n\n protected readonly core = new PlayButtonCore();\n protected readonly stateAttrMap = PlayButtonDataAttrs;\n protected readonly mediaState = new PlayerController(this, playerContext, selectPlayback);\n\n protected activate(state: MediaPlaybackState): void {\n this.core.toggle(state);\n }\n}\n"],"mappings":";;;;;;AAOA,IAAa,oBAAb,cAAuC,mBAAmC;;;cAG9C,IAAI,gBAAgB;sBACZ;oBACF,IAAI,iBAAiB,MAAM,eAAe,eAAe;;;iBAJ/D;;CAM1B,SAAmB,OAAiC;AAClD,OAAK,KAAK,OAAO,MAAM"}
1
+ {"version":3,"file":"play-button-element.js","names":[],"sources":["../../../../src/ui/play-button/play-button-element.ts"],"sourcesContent":["import { type MediaPlaybackState, PlayButtonCore, PlayButtonDataAttrs } from '@videojs/core';\nimport { selectPlayback } from '@videojs/core/dom';\n\nimport { playerContext } from '../../player/context';\nimport { PlayerController } from '../../player/player-controller';\nimport { MediaButtonElement } from '../media-button-element';\n\nexport class PlayButtonElement extends MediaButtonElement<PlayButtonCore> {\n static readonly tagName = 'media-play-button';\n\n protected readonly core = new PlayButtonCore();\n protected readonly stateAttrMap = PlayButtonDataAttrs;\n protected readonly mediaState = new PlayerController(this, playerContext, selectPlayback);\n protected override readonly hotkeyAction = 'togglePaused';\n\n protected activate(state: MediaPlaybackState): void {\n this.core.toggle(state);\n }\n}\n"],"mappings":";;;;;;AAOA,IAAa,oBAAb,cAAuC,mBAAmC;;;cAG9C,IAAI,gBAAgB;sBACZ;oBACF,IAAI,iBAAiB,MAAM,eAAe,eAAe;sBAC9C;;;iBALjB;;CAO1B,SAAmB,OAAiC;AAClD,OAAK,KAAK,OAAO,MAAM"}
@@ -1,8 +1,9 @@
1
1
  import { MediaElement } from "../media-element.js";
2
+ import { PositionController } from "../position-controller.js";
2
3
  import { PopoverCore, PopoverDataAttrs } from "@videojs/core";
3
4
  import { applyElementProps, applyStateDataAttrs, createPopover, createTransition, getAnchorNameStyle, getAnchorPositionStyle, getPopupPositionRect, resolveOffsets } from "@videojs/core/dom";
4
- import { SnapshotController } from "@videojs/store/html";
5
5
  import { applyStyles, supportsAnchorPositioning, tryHidePopover, tryShowPopover } from "@videojs/utils/dom";
6
+ import { SnapshotController } from "@videojs/store/html";
6
7
  //#region src/ui/popover/popover-element.ts
7
8
  var PopoverElement = class extends MediaElement {
8
9
  constructor(..._args) {
@@ -51,15 +52,12 @@ var PopoverElement = class extends MediaElement {
51
52
  };
52
53
  }
53
54
  #core = new PopoverCore();
55
+ #position = new PositionController(this);
54
56
  #popover = null;
55
57
  #snapshot = null;
56
58
  #disconnect = null;
57
59
  #triggerAbort = null;
58
60
  #currentTrigger = null;
59
- #positionAbort = null;
60
- #positionFrame = 0;
61
- #resizeObserver = null;
62
- #positionTrigger = null;
63
61
  connectedCallback() {
64
62
  super.connectedCallback();
65
63
  if (this.destroyed) return;
@@ -90,12 +88,10 @@ var PopoverElement = class extends MediaElement {
90
88
  }
91
89
  disconnectedCallback() {
92
90
  super.disconnectedCallback();
93
- this.#cleanupPositioning();
94
91
  this.#disconnect?.abort();
95
92
  this.#disconnect = null;
96
93
  }
97
94
  destroyCallback() {
98
- this.#cleanupPositioning();
99
95
  this.#cleanupTrigger();
100
96
  this.#popover?.destroy();
101
97
  super.destroyCallback();
@@ -112,7 +108,7 @@ var PopoverElement = class extends MediaElement {
112
108
  update(_changed) {
113
109
  super.update(_changed);
114
110
  if (!this.#popover) return;
115
- const triggerEl = this.#findTrigger();
111
+ const triggerEl = this.#position.findTrigger();
116
112
  this.#syncTrigger(triggerEl);
117
113
  const input = this.#popover.input.current;
118
114
  this.#core.setInput(input);
@@ -126,7 +122,7 @@ var PopoverElement = class extends MediaElement {
126
122
  applyStyles(this.#currentTrigger, getAnchorNameStyle(this.id));
127
123
  }
128
124
  if (!state.open) {
129
- this.#cleanupPositioning();
125
+ this.#position.cleanup();
130
126
  return;
131
127
  }
132
128
  const posOpts = {
@@ -141,15 +137,11 @@ var PopoverElement = class extends MediaElement {
141
137
  const offsets = resolveOffsets(this);
142
138
  applyStyles(this, getAnchorPositionStyle(this.id, posOpts, triggerRect, selfRect, boundaryRect, offsets));
143
139
  }
144
- this.#syncPositioning();
145
- }
146
- #findTrigger() {
147
- if (!this.id) return null;
148
- return this.getRootNode().querySelector(`[commandfor="${this.id}"]`);
140
+ this.#position.sync(this.#currentTrigger);
149
141
  }
150
142
  #syncTrigger(triggerEl) {
151
143
  if (triggerEl === this.#currentTrigger) return;
152
- this.#cleanupPositioning();
144
+ this.#position.cleanup();
153
145
  this.#cleanupTrigger();
154
146
  this.#currentTrigger = triggerEl;
155
147
  this.#popover?.setTriggerElement(triggerEl);
@@ -171,46 +163,6 @@ var PopoverElement = class extends MediaElement {
171
163
  this.#triggerAbort = null;
172
164
  this.#currentTrigger = null;
173
165
  }
174
- #syncPositioning() {
175
- if (supportsAnchorPositioning()) return;
176
- const triggerEl = this.#currentTrigger;
177
- if (!triggerEl) return;
178
- if (this.#positionAbort && this.#positionTrigger === triggerEl) return;
179
- this.#cleanupPositioning();
180
- this.#positionAbort = new AbortController();
181
- this.#positionTrigger = triggerEl;
182
- const { signal } = this.#positionAbort;
183
- const reposition = () => {
184
- cancelAnimationFrame(this.#positionFrame);
185
- this.#positionFrame = requestAnimationFrame(() => {
186
- if (signal.aborted) return;
187
- this.requestUpdate();
188
- });
189
- };
190
- window.addEventListener("scroll", reposition, {
191
- capture: true,
192
- passive: true,
193
- signal
194
- });
195
- window.addEventListener("resize", reposition, { signal });
196
- if (typeof ResizeObserver === "function") {
197
- this.#resizeObserver = new ResizeObserver(() => {
198
- reposition();
199
- });
200
- this.#resizeObserver.observe(triggerEl);
201
- this.#resizeObserver.observe(this);
202
- }
203
- reposition();
204
- }
205
- #cleanupPositioning() {
206
- this.#positionAbort?.abort();
207
- this.#positionAbort = null;
208
- this.#positionTrigger = null;
209
- cancelAnimationFrame(this.#positionFrame);
210
- this.#positionFrame = 0;
211
- this.#resizeObserver?.disconnect();
212
- this.#resizeObserver = null;
213
- }
214
166
  };
215
167
  //#endregion
216
168
  export { PopoverElement };
@@ -1 +1 @@
1
- {"version":3,"file":"popover-element.js","names":["#core","#disconnect","#popover","#snapshot","#cleanupPositioning","#cleanupTrigger","#findTrigger","#syncTrigger","#currentTrigger","#syncPositioning","#triggerAbort","#positionAbort","#positionTrigger","#positionFrame","#resizeObserver"],"sources":["../../../../src/ui/popover/popover-element.ts"],"sourcesContent":["import { PopoverCore, PopoverDataAttrs, type PopoverInput, type PopoverProps } from '@videojs/core';\nimport {\n applyElementProps,\n applyStateDataAttrs,\n createPopover,\n createTransition,\n getAnchorNameStyle,\n getAnchorPositionStyle,\n getPopupPositionRect,\n type PopoverApi,\n type PopoverChangeDetails,\n resolveOffsets,\n} from '@videojs/core/dom';\nimport type { PropertyDeclarationMap, PropertyValues } from '@videojs/element';\nimport { SnapshotController } from '@videojs/store/html';\nimport { applyStyles, supportsAnchorPositioning, tryHidePopover, tryShowPopover } from '@videojs/utils/dom';\n\nimport { MediaElement } from '../media-element';\n\nexport class PopoverElement extends MediaElement {\n static readonly tagName = 'media-popover';\n\n static override properties = {\n open: { type: Boolean },\n defaultOpen: { type: Boolean, attribute: 'default-open' },\n side: { type: String },\n align: { type: String },\n modal: { type: Boolean },\n closeOnEscape: { type: Boolean, attribute: 'close-on-escape' },\n closeOnOutsideClick: { type: Boolean, attribute: 'close-on-outside-click' },\n openOnHover: { type: Boolean, attribute: 'open-on-hover' },\n delay: { type: Number },\n closeDelay: { type: Number, attribute: 'close-delay' },\n } satisfies PropertyDeclarationMap<keyof PopoverCore.Props>;\n\n open = PopoverCore.defaultProps.open;\n defaultOpen = PopoverCore.defaultProps.defaultOpen;\n side = PopoverCore.defaultProps.side;\n align = PopoverCore.defaultProps.align;\n modal: PopoverProps['modal'] = PopoverCore.defaultProps.modal;\n closeOnEscape = PopoverCore.defaultProps.closeOnEscape;\n closeOnOutsideClick = PopoverCore.defaultProps.closeOnOutsideClick;\n openOnHover = PopoverCore.defaultProps.openOnHover;\n delay = PopoverCore.defaultProps.delay;\n closeDelay = PopoverCore.defaultProps.closeDelay;\n\n readonly #core = new PopoverCore();\n #popover: PopoverApi | null = null;\n #snapshot: SnapshotController<PopoverInput> | null = null;\n\n // Cleanup controllers\n #disconnect: AbortController | null = null;\n #triggerAbort: AbortController | null = null;\n #currentTrigger: HTMLElement | null = null;\n #positionAbort: AbortController | null = null;\n #positionFrame = 0;\n #resizeObserver: ResizeObserver | null = null;\n #positionTrigger: HTMLElement | null = null;\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (this.destroyed) return;\n\n this.#disconnect = new AbortController();\n\n this.#popover = createPopover({\n transition: createTransition(),\n onOpenChange: (nextOpen: boolean, details: PopoverChangeDetails) => {\n this.open = nextOpen;\n this.dispatchEvent(new CustomEvent('open-change', { detail: { open: nextOpen, ...details } }));\n },\n closeOnEscape: () => this.closeOnEscape,\n closeOnOutsideClick: () => this.closeOnOutsideClick,\n openOnHover: () => this.openOnHover,\n delay: () => this.delay,\n closeDelay: () => this.closeDelay,\n });\n\n // Register self as the popup element — the element IS the popup.\n this.#popover.setPopupElement(this);\n\n // Apply popup event handlers (pointerenter/leave, focusout) to self.\n applyElementProps(this, this.#popover.popupProps, { signal: this.#disconnect.signal });\n\n // Subscribe to interaction state for reactive updates.\n // Reuse the controller across connect/disconnect cycles to avoid\n // leaking stale controllers in the host's controller set.\n if (this.#snapshot) {\n this.#snapshot.track(this.#popover.input);\n } else {\n this.#snapshot = new SnapshotController(this, this.#popover.input);\n }\n }\n\n protected override firstUpdated(changed: PropertyValues): void {\n super.firstUpdated(changed);\n\n // Uncontrolled mode: open if `defaultOpen` is set. Controlled `open`\n // is already synced by `willUpdate` on the first render cycle.\n if (this.defaultOpen && !this.open) {\n this.#popover?.open();\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#cleanupPositioning();\n this.#disconnect?.abort();\n this.#disconnect = null;\n }\n\n override destroyCallback(): void {\n this.#cleanupPositioning();\n this.#cleanupTrigger();\n this.#popover?.destroy();\n super.destroyCallback();\n }\n\n protected override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n this.#core.setProps(this);\n\n // Sync controlled open state\n if (this.#popover && changed.has('open')) {\n const { active: interactionOpen } = this.#popover.input.current;\n if (this.open !== interactionOpen) {\n if (this.open) {\n this.#popover.open();\n } else {\n this.#popover.close();\n }\n }\n }\n }\n\n protected override update(_changed: PropertyValues): void {\n super.update(_changed);\n if (!this.#popover) return;\n\n // Discover trigger via commandfor linkage.\n const triggerEl = this.#findTrigger();\n this.#syncTrigger(triggerEl);\n\n // Derive state from core + input.\n const input = this.#popover.input.current;\n this.#core.setInput(input);\n const state = this.#core.getState();\n\n // Apply popup ARIA and data attributes to self.\n applyElementProps(this, this.#core.getPopupAttrs(state));\n applyStateDataAttrs(this, state, PopoverDataAttrs);\n\n // Show/hide via Popover API AFTER data attributes are applied so\n // `data-starting-style` is present before the first visible frame.\n if (state.open) {\n tryShowPopover(this);\n } else {\n tryHidePopover(this);\n }\n\n // Apply trigger ARIA and anchor-name to the discovered trigger.\n if (this.#currentTrigger) {\n applyElementProps(this.#currentTrigger, this.#core.getTriggerAttrs(state, this.id));\n applyStyles(this.#currentTrigger, getAnchorNameStyle(this.id));\n }\n\n // Skip positioning when closed — no rects to measure.\n if (!state.open) {\n this.#cleanupPositioning();\n return;\n }\n\n // Apply positioning styles to self.\n const posOpts = { side: state.side, align: state.align };\n\n if (supportsAnchorPositioning()) {\n // Native CSS Anchor Positioning — no JS rect measurements needed.\n applyStyles(this, getAnchorPositionStyle(this.id, posOpts));\n } else {\n // JS fallback: measure rects and resolve CSS var offsets.\n const triggerRect = this.#currentTrigger?.getBoundingClientRect();\n const selfRect = getPopupPositionRect(this);\n const boundaryRect = document.documentElement.getBoundingClientRect();\n const offsets = resolveOffsets(this);\n applyStyles(this, getAnchorPositionStyle(this.id, posOpts, triggerRect, selfRect, boundaryRect, offsets));\n }\n\n this.#syncPositioning();\n }\n\n // --- Trigger discovery ---\n\n #findTrigger(): HTMLElement | null {\n if (!this.id) return null;\n const root = this.getRootNode() as Document | ShadowRoot;\n return root.querySelector<HTMLElement>(`[commandfor=\"${this.id}\"]`);\n }\n\n #syncTrigger(triggerEl: HTMLElement | null): void {\n if (triggerEl === this.#currentTrigger) return;\n\n this.#cleanupPositioning();\n this.#cleanupTrigger();\n this.#currentTrigger = triggerEl;\n this.#popover?.setTriggerElement(triggerEl);\n\n if (triggerEl && this.#popover) {\n this.#triggerAbort = new AbortController();\n applyElementProps(triggerEl, this.#popover.triggerProps, { signal: this.#triggerAbort.signal });\n }\n }\n\n #cleanupTrigger(): void {\n if (this.#currentTrigger) {\n // Remove ARIA attributes and anchor-name style from the old trigger.\n applyElementProps(this.#currentTrigger, {\n 'aria-expanded': undefined,\n 'aria-haspopup': undefined,\n 'aria-controls': undefined,\n });\n this.#currentTrigger.style.removeProperty('anchor-name');\n }\n\n this.#triggerAbort?.abort();\n this.#triggerAbort = null;\n this.#currentTrigger = null;\n }\n\n #syncPositioning(): void {\n if (supportsAnchorPositioning()) return;\n\n const triggerEl = this.#currentTrigger;\n\n if (!triggerEl) return;\n if (this.#positionAbort && this.#positionTrigger === triggerEl) return;\n\n this.#cleanupPositioning();\n this.#positionAbort = new AbortController();\n this.#positionTrigger = triggerEl;\n const { signal } = this.#positionAbort;\n\n const reposition = () => {\n cancelAnimationFrame(this.#positionFrame);\n this.#positionFrame = requestAnimationFrame(() => {\n if (signal.aborted) return;\n this.requestUpdate();\n });\n };\n\n window.addEventListener('scroll', reposition, { capture: true, passive: true, signal });\n window.addEventListener('resize', reposition, { signal });\n\n if (typeof ResizeObserver === 'function') {\n this.#resizeObserver = new ResizeObserver(() => {\n reposition();\n });\n this.#resizeObserver.observe(triggerEl);\n this.#resizeObserver.observe(this);\n }\n\n reposition();\n }\n\n #cleanupPositioning(): void {\n this.#positionAbort?.abort();\n this.#positionAbort = null;\n this.#positionTrigger = null;\n cancelAnimationFrame(this.#positionFrame);\n this.#positionFrame = 0;\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = null;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"popover-element.js","names":["#core","#position","#disconnect","#popover","#snapshot","#cleanupTrigger","#syncTrigger","#currentTrigger","#triggerAbort"],"sources":["../../../../src/ui/popover/popover-element.ts"],"sourcesContent":["import { PopoverCore, PopoverDataAttrs, type PopoverInput, type PopoverProps } from '@videojs/core';\nimport {\n applyElementProps,\n applyStateDataAttrs,\n createPopover,\n createTransition,\n getAnchorNameStyle,\n getAnchorPositionStyle,\n getPopupPositionRect,\n type PopoverApi,\n type PopoverChangeDetails,\n resolveOffsets,\n} from '@videojs/core/dom';\nimport type { PropertyDeclarationMap, PropertyValues } from '@videojs/element';\nimport { SnapshotController } from '@videojs/store/html';\nimport { applyStyles, supportsAnchorPositioning, tryHidePopover, tryShowPopover } from '@videojs/utils/dom';\n\nimport { MediaElement } from '../media-element';\nimport { PositionController } from '../position-controller';\n\nexport class PopoverElement extends MediaElement {\n static readonly tagName = 'media-popover';\n\n static override properties = {\n open: { type: Boolean },\n defaultOpen: { type: Boolean, attribute: 'default-open' },\n side: { type: String },\n align: { type: String },\n modal: { type: Boolean },\n closeOnEscape: { type: Boolean, attribute: 'close-on-escape' },\n closeOnOutsideClick: { type: Boolean, attribute: 'close-on-outside-click' },\n openOnHover: { type: Boolean, attribute: 'open-on-hover' },\n delay: { type: Number },\n closeDelay: { type: Number, attribute: 'close-delay' },\n } satisfies PropertyDeclarationMap<keyof PopoverCore.Props>;\n\n open = PopoverCore.defaultProps.open;\n defaultOpen = PopoverCore.defaultProps.defaultOpen;\n side = PopoverCore.defaultProps.side;\n align = PopoverCore.defaultProps.align;\n modal: PopoverProps['modal'] = PopoverCore.defaultProps.modal;\n closeOnEscape = PopoverCore.defaultProps.closeOnEscape;\n closeOnOutsideClick = PopoverCore.defaultProps.closeOnOutsideClick;\n openOnHover = PopoverCore.defaultProps.openOnHover;\n delay = PopoverCore.defaultProps.delay;\n closeDelay = PopoverCore.defaultProps.closeDelay;\n\n readonly #core = new PopoverCore();\n readonly #position = new PositionController(this);\n #popover: PopoverApi | null = null;\n #snapshot: SnapshotController<PopoverInput> | null = null;\n\n // Cleanup controllers\n #disconnect: AbortController | null = null;\n #triggerAbort: AbortController | null = null;\n #currentTrigger: HTMLElement | null = null;\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (this.destroyed) return;\n\n this.#disconnect = new AbortController();\n\n this.#popover = createPopover({\n transition: createTransition(),\n onOpenChange: (nextOpen: boolean, details: PopoverChangeDetails) => {\n this.open = nextOpen;\n this.dispatchEvent(new CustomEvent('open-change', { detail: { open: nextOpen, ...details } }));\n },\n closeOnEscape: () => this.closeOnEscape,\n closeOnOutsideClick: () => this.closeOnOutsideClick,\n openOnHover: () => this.openOnHover,\n delay: () => this.delay,\n closeDelay: () => this.closeDelay,\n });\n\n // Register self as the popup element — the element IS the popup.\n this.#popover.setPopupElement(this);\n\n // Apply popup event handlers (pointerenter/leave, focusout) to self.\n applyElementProps(this, this.#popover.popupProps, { signal: this.#disconnect.signal });\n\n // Subscribe to interaction state for reactive updates.\n // Reuse the controller across connect/disconnect cycles to avoid\n // leaking stale controllers in the host's controller set.\n if (this.#snapshot) {\n this.#snapshot.track(this.#popover.input);\n } else {\n this.#snapshot = new SnapshotController(this, this.#popover.input);\n }\n }\n\n protected override firstUpdated(changed: PropertyValues): void {\n super.firstUpdated(changed);\n\n // Uncontrolled mode: open if `defaultOpen` is set. Controlled `open`\n // is already synced by `willUpdate` on the first render cycle.\n if (this.defaultOpen && !this.open) {\n this.#popover?.open();\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#disconnect?.abort();\n this.#disconnect = null;\n }\n\n override destroyCallback(): void {\n this.#cleanupTrigger();\n this.#popover?.destroy();\n super.destroyCallback();\n }\n\n protected override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n this.#core.setProps(this);\n\n // Sync controlled open state\n if (this.#popover && changed.has('open')) {\n const { active: interactionOpen } = this.#popover.input.current;\n if (this.open !== interactionOpen) {\n if (this.open) {\n this.#popover.open();\n } else {\n this.#popover.close();\n }\n }\n }\n }\n\n protected override update(_changed: PropertyValues): void {\n super.update(_changed);\n if (!this.#popover) return;\n\n // Discover trigger via commandfor linkage.\n const triggerEl = this.#position.findTrigger();\n this.#syncTrigger(triggerEl);\n\n // Derive state from core + input.\n const input = this.#popover.input.current;\n this.#core.setInput(input);\n const state = this.#core.getState();\n\n // Apply popup ARIA and data attributes to self.\n applyElementProps(this, this.#core.getPopupAttrs(state));\n applyStateDataAttrs(this, state, PopoverDataAttrs);\n\n // Show/hide via Popover API AFTER data attributes are applied so\n // `data-starting-style` is present before the first visible frame.\n if (state.open) {\n tryShowPopover(this);\n } else {\n tryHidePopover(this);\n }\n\n // Apply trigger ARIA and anchor-name to the discovered trigger.\n if (this.#currentTrigger) {\n applyElementProps(this.#currentTrigger, this.#core.getTriggerAttrs(state, this.id));\n applyStyles(this.#currentTrigger, getAnchorNameStyle(this.id));\n }\n\n // Skip positioning when closed — no rects to measure.\n if (!state.open) {\n this.#position.cleanup();\n return;\n }\n\n // Apply positioning styles to self.\n const posOpts = { side: state.side, align: state.align };\n\n if (supportsAnchorPositioning()) {\n // Native CSS Anchor Positioning — no JS rect measurements needed.\n applyStyles(this, getAnchorPositionStyle(this.id, posOpts));\n } else {\n // JS fallback: measure rects and resolve CSS var offsets.\n const triggerRect = this.#currentTrigger?.getBoundingClientRect();\n const selfRect = getPopupPositionRect(this);\n const boundaryRect = document.documentElement.getBoundingClientRect();\n const offsets = resolveOffsets(this);\n applyStyles(this, getAnchorPositionStyle(this.id, posOpts, triggerRect, selfRect, boundaryRect, offsets));\n }\n\n this.#position.sync(this.#currentTrigger);\n }\n\n // --- Trigger management ---\n\n #syncTrigger(triggerEl: HTMLElement | null): void {\n if (triggerEl === this.#currentTrigger) return;\n\n this.#position.cleanup();\n this.#cleanupTrigger();\n this.#currentTrigger = triggerEl;\n this.#popover?.setTriggerElement(triggerEl);\n\n if (triggerEl && this.#popover) {\n this.#triggerAbort = new AbortController();\n applyElementProps(triggerEl, this.#popover.triggerProps, { signal: this.#triggerAbort.signal });\n }\n }\n\n #cleanupTrigger(): void {\n if (this.#currentTrigger) {\n // Remove ARIA attributes and anchor-name style from the old trigger.\n applyElementProps(this.#currentTrigger, {\n 'aria-expanded': undefined,\n 'aria-haspopup': undefined,\n 'aria-controls': undefined,\n });\n this.#currentTrigger.style.removeProperty('anchor-name');\n }\n\n this.#triggerAbort?.abort();\n this.#triggerAbort = null;\n this.#currentTrigger = null;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ import { supportsAnchorPositioning } from "@videojs/utils/dom";
2
+ //#region src/ui/position-controller.ts
3
+ /**
4
+ * Reactive controller that manages JS-fallback positioning for floating
5
+ * popup elements (tooltips, popovers). Tracks scroll, resize, and
6
+ * ResizeObserver events to keep the popup aligned with its trigger.
7
+ *
8
+ * When native CSS Anchor Positioning is supported, `sync()` is a no-op.
9
+ */
10
+ var PositionController = class {
11
+ #host;
12
+ #abort = null;
13
+ #frame = 0;
14
+ #resizeObserver = null;
15
+ #trigger = null;
16
+ constructor(host) {
17
+ this.#host = host;
18
+ host.addController(this);
19
+ }
20
+ /** Discover a trigger element linked via `commandfor` attribute. */
21
+ findTrigger() {
22
+ if (!this.#host.id) return null;
23
+ return this.#host.getRootNode().querySelector(`[commandfor="${this.#host.id}"]`);
24
+ }
25
+ /** Start or update position tracking for the given trigger. */
26
+ sync(trigger) {
27
+ if (supportsAnchorPositioning()) return;
28
+ if (!trigger) return;
29
+ if (this.#abort && this.#trigger === trigger) return;
30
+ this.cleanup();
31
+ this.#abort = new AbortController();
32
+ this.#trigger = trigger;
33
+ const { signal } = this.#abort;
34
+ const reposition = () => {
35
+ cancelAnimationFrame(this.#frame);
36
+ this.#frame = requestAnimationFrame(() => {
37
+ if (signal.aborted) return;
38
+ this.#host.requestUpdate();
39
+ });
40
+ };
41
+ window.addEventListener("scroll", reposition, {
42
+ capture: true,
43
+ passive: true,
44
+ signal
45
+ });
46
+ window.addEventListener("resize", reposition, { signal });
47
+ if (typeof ResizeObserver === "function") {
48
+ this.#resizeObserver = new ResizeObserver(() => {
49
+ reposition();
50
+ });
51
+ this.#resizeObserver.observe(trigger);
52
+ this.#resizeObserver.observe(this.#host);
53
+ }
54
+ reposition();
55
+ }
56
+ /** Stop all position tracking. */
57
+ cleanup() {
58
+ this.#abort?.abort();
59
+ this.#abort = null;
60
+ this.#trigger = null;
61
+ cancelAnimationFrame(this.#frame);
62
+ this.#frame = 0;
63
+ this.#resizeObserver?.disconnect();
64
+ this.#resizeObserver = null;
65
+ }
66
+ hostDisconnected() {
67
+ this.cleanup();
68
+ }
69
+ hostDestroyed() {
70
+ this.cleanup();
71
+ }
72
+ };
73
+ //#endregion
74
+ export { PositionController };
75
+
76
+ //# sourceMappingURL=position-controller.js.map