@videojs/html 10.1.0 → 10.3.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 (355) hide show
  1. package/dist/default/define/audio/compat-skin.css +116 -65
  2. package/dist/default/define/audio/compat-skin2.js +1 -1
  3. package/dist/default/define/audio/neutral-skin.css +25 -16
  4. package/dist/default/define/audio/neutral-skin2.js +1 -1
  5. package/dist/default/define/audio/scaffold-skin.css +93 -51
  6. package/dist/default/define/audio/scaffold-skin2.js +1 -1
  7. package/dist/default/define/audio/skin.css +21 -6
  8. package/dist/default/define/audio/skin2.js +1 -1
  9. package/dist/default/define/extensions/google-analytics.js +6 -0
  10. package/dist/default/define/live-audio/compat-skin.css +98 -65
  11. package/dist/default/define/live-audio/compat-skin2.js +1 -1
  12. package/dist/default/define/live-audio/neutral-skin.css +8 -5
  13. package/dist/default/define/live-audio/neutral-skin2.js +1 -1
  14. package/dist/default/define/live-audio/scaffold-skin.css +75 -51
  15. package/dist/default/define/live-audio/scaffold-skin2.js +1 -1
  16. package/dist/default/define/live-audio/skin.css +6 -5
  17. package/dist/default/define/live-audio/skin2.js +1 -1
  18. package/dist/default/define/live-video/compat-skin.css +123 -21
  19. package/dist/default/define/live-video/compat-skin2.js +1 -1
  20. package/dist/default/define/live-video/neutral-skin.css +82 -14
  21. package/dist/default/define/live-video/neutral-skin2.js +1 -1
  22. package/dist/default/define/live-video/scaffold-skin.css +107 -26
  23. package/dist/default/define/live-video/scaffold-skin2.js +1 -1
  24. package/dist/default/define/live-video/skin.css +96 -16
  25. package/dist/default/define/live-video/skin2.js +1 -1
  26. package/dist/default/define/media/dailymotion-video.js +11 -0
  27. package/dist/default/define/media/mixcloud-audio.js +11 -0
  28. package/dist/default/define/media/soundcloud-audio.js +11 -0
  29. package/dist/default/define/video/compat-skin.css +123 -21
  30. package/dist/default/define/video/compat-skin2.js +1 -1
  31. package/dist/default/define/video/neutral-skin.css +85 -24
  32. package/dist/default/define/video/neutral-skin2.js +1 -1
  33. package/dist/default/define/video/scaffold-skin.css +107 -26
  34. package/dist/default/define/video/scaffold-skin2.js +1 -1
  35. package/dist/default/define/video/skin.css +94 -16
  36. package/dist/default/define/video/skin2.js +1 -1
  37. package/dist/default/extensions/google-analytics/extension.js +75 -0
  38. package/dist/default/extensions/mux-data/extension.js +7 -2
  39. package/dist/default/internal/skins/compat-audio/register.js +0 -10
  40. package/dist/default/internal/skins/compat-audio/skin.css +116 -65
  41. package/dist/default/internal/skins/compat-audio/template.js +15 -39
  42. package/dist/default/internal/skins/compat-live-audio/register.js +0 -10
  43. package/dist/default/internal/skins/compat-live-audio/skin.css +98 -65
  44. package/dist/default/internal/skins/compat-live-audio/template.js +2 -26
  45. package/dist/default/internal/skins/compat-live-video/skin.css +123 -21
  46. package/dist/default/internal/skins/compat-video/skin.css +123 -21
  47. package/dist/default/internal/skins/default-audio/skin.css +21 -6
  48. package/dist/default/internal/skins/default-live-audio/skin.css +6 -5
  49. package/dist/default/internal/skins/default-live-video/skin.css +96 -16
  50. package/dist/default/internal/skins/default-video/skin.css +94 -16
  51. package/dist/default/internal/skins/neutral-audio/skin.css +25 -16
  52. package/dist/default/internal/skins/neutral-audio/template.js +1 -1
  53. package/dist/default/internal/skins/neutral-live-audio/skin.css +8 -5
  54. package/dist/default/internal/skins/neutral-live-video/skin.css +82 -14
  55. package/dist/default/internal/skins/neutral-video/skin.css +85 -24
  56. package/dist/default/internal/skins/neutral-video/template.js +1 -1
  57. package/dist/default/internal/skins/scaffold-audio/register.js +0 -10
  58. package/dist/default/internal/skins/scaffold-audio/skin.css +93 -51
  59. package/dist/default/internal/skins/scaffold-audio/template.js +15 -39
  60. package/dist/default/internal/skins/scaffold-live-audio/register.js +0 -10
  61. package/dist/default/internal/skins/scaffold-live-audio/skin.css +75 -51
  62. package/dist/default/internal/skins/scaffold-live-audio/template.js +2 -26
  63. package/dist/default/internal/skins/scaffold-live-video/skin.css +107 -26
  64. package/dist/default/internal/skins/scaffold-video/skin.css +107 -26
  65. package/dist/default/media/dailymotion-video/adapter.js +31 -0
  66. package/dist/default/media/hls-audio/adapter.js +1 -1
  67. package/dist/default/media/hls-background-video/adapter.js +8 -1
  68. package/dist/default/media/hls-video/adapter.js +1 -1
  69. package/dist/default/media/mixcloud-audio/adapter.js +16 -0
  70. package/dist/default/media/soundcloud-audio/adapter.js +16 -0
  71. package/dist/default/player/element.js +1 -5
  72. package/dist/default/presets/background/skin.js +2 -2
  73. package/dist/default/presets/skin.js +4 -3
  74. package/dist/default/ui/dialog/element.js +13 -1
  75. package/dist/default/ui/gesture/element.js +3 -0
  76. package/dist/default/ui/media-button-element.js +10 -1
  77. package/dist/default/ui/playback-rate-button/element.js +7 -2
  78. package/dist/default/ui/playback-rate-radio-group/element.js +10 -3
  79. package/dist/default/ui/radio-options/controller.js +18 -5
  80. package/dist/default/ui/slider/element.js +3 -1
  81. package/dist/default/ui/time-slider/element.js +19 -7
  82. package/dist/default/ui/volume-slider/element.js +3 -1
  83. package/dist/default/version.js +1 -1
  84. package/dist/dev/define/audio/compat-skin.css +116 -65
  85. package/dist/dev/define/audio/compat-skin2.js +1 -1
  86. package/dist/dev/define/audio/compat-skin2.js.map +1 -1
  87. package/dist/dev/define/audio/neutral-skin.css +25 -16
  88. package/dist/dev/define/audio/neutral-skin2.js +1 -1
  89. package/dist/dev/define/audio/neutral-skin2.js.map +1 -1
  90. package/dist/dev/define/audio/scaffold-skin.css +93 -51
  91. package/dist/dev/define/audio/scaffold-skin2.js +1 -1
  92. package/dist/dev/define/audio/scaffold-skin2.js.map +1 -1
  93. package/dist/dev/define/audio/skin.css +21 -6
  94. package/dist/dev/define/audio/skin2.js +1 -1
  95. package/dist/dev/define/audio/skin2.js.map +1 -1
  96. package/dist/dev/define/extensions/google-analytics.d.ts +11 -0
  97. package/dist/dev/define/extensions/google-analytics.js +8 -0
  98. package/dist/dev/define/extensions/google-analytics.js.map +1 -0
  99. package/dist/dev/define/live-audio/compat-skin.css +98 -65
  100. package/dist/dev/define/live-audio/compat-skin2.js +1 -1
  101. package/dist/dev/define/live-audio/compat-skin2.js.map +1 -1
  102. package/dist/dev/define/live-audio/neutral-skin.css +8 -5
  103. package/dist/dev/define/live-audio/neutral-skin2.js +1 -1
  104. package/dist/dev/define/live-audio/neutral-skin2.js.map +1 -1
  105. package/dist/dev/define/live-audio/scaffold-skin.css +75 -51
  106. package/dist/dev/define/live-audio/scaffold-skin2.js +1 -1
  107. package/dist/dev/define/live-audio/scaffold-skin2.js.map +1 -1
  108. package/dist/dev/define/live-audio/skin.css +6 -5
  109. package/dist/dev/define/live-audio/skin2.js +1 -1
  110. package/dist/dev/define/live-audio/skin2.js.map +1 -1
  111. package/dist/dev/define/live-video/compat-skin.css +123 -21
  112. package/dist/dev/define/live-video/compat-skin2.js +1 -1
  113. package/dist/dev/define/live-video/compat-skin2.js.map +1 -1
  114. package/dist/dev/define/live-video/neutral-skin.css +82 -14
  115. package/dist/dev/define/live-video/neutral-skin2.js +1 -1
  116. package/dist/dev/define/live-video/neutral-skin2.js.map +1 -1
  117. package/dist/dev/define/live-video/scaffold-skin.css +107 -26
  118. package/dist/dev/define/live-video/scaffold-skin2.js +1 -1
  119. package/dist/dev/define/live-video/scaffold-skin2.js.map +1 -1
  120. package/dist/dev/define/live-video/skin.css +96 -16
  121. package/dist/dev/define/live-video/skin2.js +1 -1
  122. package/dist/dev/define/live-video/skin2.js.map +1 -1
  123. package/dist/dev/define/media/dailymotion-video.d.ts +15 -0
  124. package/dist/dev/define/media/dailymotion-video.js +13 -0
  125. package/dist/dev/define/media/dailymotion-video.js.map +1 -0
  126. package/dist/dev/define/media/mixcloud-audio.d.ts +15 -0
  127. package/dist/dev/define/media/mixcloud-audio.js +13 -0
  128. package/dist/dev/define/media/mixcloud-audio.js.map +1 -0
  129. package/dist/dev/define/media/soundcloud-audio.d.ts +15 -0
  130. package/dist/dev/define/media/soundcloud-audio.js +13 -0
  131. package/dist/dev/define/media/soundcloud-audio.js.map +1 -0
  132. package/dist/dev/define/video/compat-skin.css +123 -21
  133. package/dist/dev/define/video/compat-skin2.js +1 -1
  134. package/dist/dev/define/video/compat-skin2.js.map +1 -1
  135. package/dist/dev/define/video/neutral-skin.css +85 -24
  136. package/dist/dev/define/video/neutral-skin2.js +1 -1
  137. package/dist/dev/define/video/neutral-skin2.js.map +1 -1
  138. package/dist/dev/define/video/scaffold-skin.css +107 -26
  139. package/dist/dev/define/video/scaffold-skin2.js +1 -1
  140. package/dist/dev/define/video/scaffold-skin2.js.map +1 -1
  141. package/dist/dev/define/video/skin.css +94 -16
  142. package/dist/dev/define/video/skin2.js +1 -1
  143. package/dist/dev/define/video/skin2.js.map +1 -1
  144. package/dist/dev/extensions/google-analytics/extension.d.ts +52 -0
  145. package/dist/dev/extensions/google-analytics/extension.js +77 -0
  146. package/dist/dev/extensions/google-analytics/extension.js.map +1 -0
  147. package/dist/dev/extensions/google-analytics/index.d.ts +2 -0
  148. package/dist/dev/extensions/mux-data/extension.d.ts +4 -1
  149. package/dist/dev/extensions/mux-data/extension.js +7 -2
  150. package/dist/dev/extensions/mux-data/extension.js.map +1 -1
  151. package/dist/dev/index.d.ts +3 -3
  152. package/dist/dev/internal/skins/compat-audio/register.d.ts +3 -5
  153. package/dist/dev/internal/skins/compat-audio/register.js +0 -10
  154. package/dist/dev/internal/skins/compat-audio/register.js.map +1 -1
  155. package/dist/dev/internal/skins/compat-audio/skin.css +116 -65
  156. package/dist/dev/internal/skins/compat-audio/template.js +15 -39
  157. package/dist/dev/internal/skins/compat-audio/template.js.map +1 -1
  158. package/dist/dev/internal/skins/compat-live-audio/register.d.ts +0 -2
  159. package/dist/dev/internal/skins/compat-live-audio/register.js +0 -10
  160. package/dist/dev/internal/skins/compat-live-audio/register.js.map +1 -1
  161. package/dist/dev/internal/skins/compat-live-audio/skin.css +98 -65
  162. package/dist/dev/internal/skins/compat-live-audio/template.js +2 -26
  163. package/dist/dev/internal/skins/compat-live-audio/template.js.map +1 -1
  164. package/dist/dev/internal/skins/compat-live-video/register.d.ts +2 -2
  165. package/dist/dev/internal/skins/compat-live-video/skin.css +123 -21
  166. package/dist/dev/internal/skins/compat-video/register.d.ts +5 -5
  167. package/dist/dev/internal/skins/compat-video/skin.css +123 -21
  168. package/dist/dev/internal/skins/default-audio/register.d.ts +1 -1
  169. package/dist/dev/internal/skins/default-audio/skin.css +21 -6
  170. package/dist/dev/internal/skins/default-live-audio/skin.css +6 -5
  171. package/dist/dev/internal/skins/default-live-video/register.d.ts +2 -2
  172. package/dist/dev/internal/skins/default-live-video/skin.css +96 -16
  173. package/dist/dev/internal/skins/default-video/register.d.ts +3 -3
  174. package/dist/dev/internal/skins/default-video/skin.css +94 -16
  175. package/dist/dev/internal/skins/neutral-audio/register.d.ts +3 -3
  176. package/dist/dev/internal/skins/neutral-audio/skin.css +25 -16
  177. package/dist/dev/internal/skins/neutral-audio/template.js +1 -1
  178. package/dist/dev/internal/skins/neutral-audio/template.js.map +1 -1
  179. package/dist/dev/internal/skins/neutral-live-audio/skin.css +8 -5
  180. package/dist/dev/internal/skins/neutral-live-video/register.d.ts +2 -2
  181. package/dist/dev/internal/skins/neutral-live-video/skin.css +82 -14
  182. package/dist/dev/internal/skins/neutral-video/register.d.ts +5 -5
  183. package/dist/dev/internal/skins/neutral-video/skin.css +85 -24
  184. package/dist/dev/internal/skins/neutral-video/template.js +1 -1
  185. package/dist/dev/internal/skins/neutral-video/template.js.map +1 -1
  186. package/dist/dev/internal/skins/scaffold-audio/register.d.ts +3 -5
  187. package/dist/dev/internal/skins/scaffold-audio/register.js +0 -10
  188. package/dist/dev/internal/skins/scaffold-audio/register.js.map +1 -1
  189. package/dist/dev/internal/skins/scaffold-audio/skin.css +93 -51
  190. package/dist/dev/internal/skins/scaffold-audio/template.js +15 -39
  191. package/dist/dev/internal/skins/scaffold-audio/template.js.map +1 -1
  192. package/dist/dev/internal/skins/scaffold-live-audio/register.d.ts +0 -2
  193. package/dist/dev/internal/skins/scaffold-live-audio/register.js +0 -10
  194. package/dist/dev/internal/skins/scaffold-live-audio/register.js.map +1 -1
  195. package/dist/dev/internal/skins/scaffold-live-audio/skin.css +75 -51
  196. package/dist/dev/internal/skins/scaffold-live-audio/template.js +2 -26
  197. package/dist/dev/internal/skins/scaffold-live-audio/template.js.map +1 -1
  198. package/dist/dev/internal/skins/scaffold-live-video/register.d.ts +2 -2
  199. package/dist/dev/internal/skins/scaffold-live-video/skin.css +107 -26
  200. package/dist/dev/internal/skins/scaffold-video/register.d.ts +5 -5
  201. package/dist/dev/internal/skins/scaffold-video/skin.css +107 -26
  202. package/dist/dev/media/dailymotion-video/adapter.d.ts +17 -0
  203. package/dist/dev/media/dailymotion-video/adapter.js +47 -0
  204. package/dist/dev/media/dailymotion-video/adapter.js.map +1 -0
  205. package/dist/dev/media/dailymotion-video/index.d.ts +2 -0
  206. package/dist/dev/media/hls-audio/adapter.d.ts +1 -1
  207. package/dist/dev/media/hls-audio/adapter.js +1 -1
  208. package/dist/dev/media/hls-audio/adapter.js.map +1 -1
  209. package/dist/dev/media/hls-background-video/adapter.d.ts +6 -1
  210. package/dist/dev/media/hls-background-video/adapter.js +8 -1
  211. package/dist/dev/media/hls-background-video/adapter.js.map +1 -1
  212. package/dist/dev/media/hls-video/adapter.d.ts +1 -1
  213. package/dist/dev/media/hls-video/adapter.js +1 -1
  214. package/dist/dev/media/hls-video/adapter.js.map +1 -1
  215. package/dist/dev/media/mixcloud-audio/adapter.d.ts +11 -0
  216. package/dist/dev/media/mixcloud-audio/adapter.js +52 -0
  217. package/dist/dev/media/mixcloud-audio/adapter.js.map +1 -0
  218. package/dist/dev/media/mixcloud-audio/index.d.ts +2 -0
  219. package/dist/dev/media/soundcloud-audio/adapter.d.ts +11 -0
  220. package/dist/dev/media/soundcloud-audio/adapter.js +53 -0
  221. package/dist/dev/media/soundcloud-audio/adapter.js.map +1 -0
  222. package/dist/dev/media/soundcloud-audio/index.d.ts +2 -0
  223. package/dist/dev/player/element.js +1 -5
  224. package/dist/dev/player/element.js.map +1 -1
  225. package/dist/dev/presets/background/skin.d.ts +2 -1
  226. package/dist/dev/presets/background/skin.js +2 -2
  227. package/dist/dev/presets/background/skin.js.map +1 -1
  228. package/dist/dev/presets/skin.d.ts +4 -3
  229. package/dist/dev/presets/skin.js +4 -3
  230. package/dist/dev/presets/skin.js.map +1 -1
  231. package/dist/dev/ui/dialog/element.js +13 -1
  232. package/dist/dev/ui/dialog/element.js.map +1 -1
  233. package/dist/dev/ui/gesture/element.js +3 -0
  234. package/dist/dev/ui/gesture/element.js.map +1 -1
  235. package/dist/dev/ui/media-button-element.d.ts +9 -0
  236. package/dist/dev/ui/media-button-element.js +10 -1
  237. package/dist/dev/ui/media-button-element.js.map +1 -1
  238. package/dist/dev/ui/play-button/element.d.ts +2 -0
  239. package/dist/dev/ui/playback-rate-button/element.d.ts +9 -1
  240. package/dist/dev/ui/playback-rate-button/element.js +7 -2
  241. package/dist/dev/ui/playback-rate-button/element.js.map +1 -1
  242. package/dist/dev/ui/playback-rate-radio-group/element.d.ts +4 -0
  243. package/dist/dev/ui/playback-rate-radio-group/element.js +10 -3
  244. package/dist/dev/ui/playback-rate-radio-group/element.js.map +1 -1
  245. package/dist/dev/ui/radio-options/controller.js +18 -5
  246. package/dist/dev/ui/radio-options/controller.js.map +1 -1
  247. package/dist/dev/ui/slider/element.js +3 -1
  248. package/dist/dev/ui/slider/element.js.map +1 -1
  249. package/dist/dev/ui/time-slider/element.js +19 -7
  250. package/dist/dev/ui/time-slider/element.js.map +1 -1
  251. package/dist/dev/ui/volume-slider/element.js +3 -1
  252. package/dist/dev/ui/volume-slider/element.js.map +1 -1
  253. package/dist/dev/version.js +1 -1
  254. package/docs/README.md +1 -1
  255. package/docs/guides/autoplay.md +1 -1
  256. package/docs/guides/browser-support.md +13 -11
  257. package/docs/guides/build-your-own-skin.md +383 -0
  258. package/docs/guides/cdn.md +10 -9
  259. package/docs/guides/content-security-policy.md +3 -0
  260. package/docs/guides/customize-skins.md +6 -3
  261. package/docs/guides/features.md +1 -1
  262. package/docs/guides/google-analytics.md +199 -0
  263. package/docs/guides/installation-cdn.md +4 -4
  264. package/docs/guides/installation-shadcn.md +3 -3
  265. package/docs/guides/installation-svelte.md +4 -4
  266. package/docs/guides/installation-vue.md +4 -4
  267. package/docs/guides/installation.md +4 -4
  268. package/docs/guides/internationalization.md +5 -5
  269. package/docs/guides/keyboard-shortcuts.md +1 -1
  270. package/docs/guides/llms.txt +3 -1
  271. package/docs/guides/media-sources.md +3 -0
  272. package/docs/guides/migrate-from-media-chrome.md +4 -4
  273. package/docs/guides/migrate-from-mux-player.md +9 -9
  274. package/docs/guides/migrate-from-plyr.md +8 -8
  275. package/docs/guides/migrate-from-video-js-8.md +9 -10
  276. package/docs/guides/migrate-from-vidstack.md +9 -9
  277. package/docs/guides/mux-data.md +22 -0
  278. package/docs/guides/presets.md +1 -1
  279. package/docs/guides/self-hosting.md +9 -6
  280. package/docs/guides/skins.md +17 -1
  281. package/docs/guides/ui-components.md +1 -1
  282. package/docs/llms.txt +12 -6
  283. package/docs/reference/api/feature-playback-rate.md +54 -3
  284. package/docs/reference/api/feature-playback.md +5 -1
  285. package/docs/reference/api/html-create-player.md +2 -2
  286. package/docs/reference/api/llms.txt +1 -1
  287. package/docs/reference/api/media-capabilities.md +1 -1
  288. package/docs/reference/api/player-store.md +6 -3
  289. package/docs/reference/api/preset-audio.md +13 -5
  290. package/docs/reference/api/preset-background.md +2 -2
  291. package/docs/reference/api/preset-live-audio.md +13 -5
  292. package/docs/reference/api/preset-live-video.md +13 -5
  293. package/docs/reference/api/preset-video.md +13 -5
  294. package/docs/reference/api/resolve-adapter-type.md +4 -1
  295. package/docs/reference/api/ui-element.md +2 -2
  296. package/docs/reference/components/alert-dialog.md +21 -16
  297. package/docs/reference/components/audio-compat-skin.md +8 -2
  298. package/docs/reference/components/audio-neutral-skin.md +2 -2
  299. package/docs/reference/components/audio-scaffold-skin.md +2 -2
  300. package/docs/reference/components/audio-skin.md +2 -2
  301. package/docs/reference/components/audio-track-radio-group.md +2 -2
  302. package/docs/reference/components/background-video-skin.md +1 -1
  303. package/docs/reference/components/background-video.md +1 -1
  304. package/docs/reference/components/buffering-indicator.md +2 -2
  305. package/docs/reference/components/captions-radio-group.md +2 -2
  306. package/docs/reference/components/cloudflare-video.md +1 -1
  307. package/docs/reference/components/dailymotion-video.md +192 -0
  308. package/docs/reference/components/dash-video.md +2 -1
  309. package/docs/reference/components/dialog.md +49 -22
  310. package/docs/reference/components/error-dialog.md +13 -10
  311. package/docs/reference/components/gesture.md +2 -2
  312. package/docs/reference/components/google-analytics.md +51 -0
  313. package/docs/reference/components/google-cast.md +1 -1
  314. package/docs/reference/components/hls-audio.md +2 -48
  315. package/docs/reference/components/hls-background-video.md +4 -1
  316. package/docs/reference/components/hls-video.md +2 -66
  317. package/docs/reference/components/hlsjs-video.md +3 -1
  318. package/docs/reference/components/hotkey.md +2 -2
  319. package/docs/reference/components/live-audio-compat-skin.md +8 -2
  320. package/docs/reference/components/live-audio-neutral-skin.md +2 -2
  321. package/docs/reference/components/live-audio-scaffold-skin.md +2 -2
  322. package/docs/reference/components/live-audio-skin.md +2 -2
  323. package/docs/reference/components/live-video-compat-skin.md +8 -2
  324. package/docs/reference/components/live-video-neutral-skin.md +2 -2
  325. package/docs/reference/components/live-video-scaffold-skin.md +2 -2
  326. package/docs/reference/components/live-video-skin.md +2 -2
  327. package/docs/reference/components/llms.txt +9 -5
  328. package/docs/reference/components/mixcloud-audio.md +203 -0
  329. package/docs/reference/components/mux-audio.md +3 -1
  330. package/docs/reference/components/mux-background-video.md +1 -1
  331. package/docs/reference/components/mux-data.md +22 -2
  332. package/docs/reference/components/mux-video.md +3 -1
  333. package/docs/reference/components/native-hls-video.md +2 -1
  334. package/docs/reference/components/play-button.md +7 -5
  335. package/docs/reference/components/playback-rate-button.md +26 -7
  336. package/docs/reference/components/playback-rate-radio-group.md +7 -4
  337. package/docs/reference/components/player.md +3 -3
  338. package/docs/reference/components/playerjs-video.md +1 -1
  339. package/docs/reference/components/quality-radio-group.md +2 -2
  340. package/docs/reference/components/shaka-video.md +2 -1
  341. package/docs/reference/components/slider.md +2 -0
  342. package/docs/reference/components/soundcloud-audio.md +227 -0
  343. package/docs/reference/components/spotify-audio.md +2 -2
  344. package/docs/reference/components/tiktok-video.md +2 -2
  345. package/docs/reference/components/time-slider.md +7 -5
  346. package/docs/reference/components/twitch-video.md +2 -3
  347. package/docs/reference/components/video-compat-skin.md +8 -2
  348. package/docs/reference/components/video-neutral-skin.md +2 -2
  349. package/docs/reference/components/video-scaffold-skin.md +2 -2
  350. package/docs/reference/components/video-skin.md +2 -2
  351. package/docs/reference/components/vimeo-video.md +2 -1
  352. package/docs/reference/components/volume-slider.md +8 -6
  353. package/docs/reference/components/wistia-video.md +1 -1
  354. package/docs/reference/components/youtube-video.md +2 -1
  355. package/package.json +62 -43
@@ -223,6 +223,10 @@
223
223
  display: none;
224
224
  }
225
225
 
226
+ :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-dialog-backdrop[data-scope="document"] {
227
+ position: fixed;
228
+ }
229
+
226
230
  :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-dialog-close {
227
231
  height: calc(var(--media-spacing) * 8);
228
232
  width: auto;
@@ -240,8 +244,8 @@
240
244
 
241
245
  :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-dialog-popup {
242
246
  z-index: 50;
243
- width: calc(100% - 2rem);
244
- max-height: calc(100% - 2rem);
247
+ max-height: calc(100% - var(--media-spacing) * 8);
248
+ width: calc(100% - var(--media-spacing) * 8);
245
249
  max-width: calc(var(--media-spacing) * 80);
246
250
  gap: calc(var(--media-spacing) * 3);
247
251
  background-color: var(--media-popover);
@@ -268,6 +272,11 @@
268
272
  outline-color: var(--media-ring);
269
273
  }
270
274
 
275
+ :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-dialog-popup[data-scope="document"] {
276
+ max-height: calc(100dvh - var(--media-spacing) * 8);
277
+ position: fixed;
278
+ }
279
+
271
280
  @media (forced-colors: active) {
272
281
  :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-dialog-popup {
273
282
  border: 1px solid canvastext;
@@ -281,8 +290,8 @@
281
290
  }
282
291
 
283
292
  :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-dialog-title {
284
- font-size: 1.125rem;
285
- line-height: 1.55556;
293
+ font-size: calc(var(--media-spacing) * 4.5);
294
+ line-height: calc(var(--media-spacing) * 7);
286
295
  }
287
296
 
288
297
  :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-indicator {
@@ -431,6 +440,18 @@
431
440
  overflow: hidden;
432
441
  }
433
442
 
443
+ .media-poster > slot::slotted(img) {
444
+ object-fit: var(--media-object-fit, contain);
445
+ object-position: var(--media-object-position, center);
446
+ width: 100%;
447
+ display: block;
448
+ height: 100% !important;
449
+ }
450
+
451
+ .media-poster > slot::slotted(img:not([src]):not([srcset])) {
452
+ visibility: hidden;
453
+ }
454
+
434
455
  :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-poster {
435
456
  width: 100%;
436
457
  height: 100%;
@@ -602,8 +623,13 @@
602
623
  }
603
624
 
604
625
  :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-tooltip-shortcut {
626
+ text-align: center;
627
+ min-width: 1.5em;
605
628
  font-family: inherit;
606
629
  font-size: calc(var(--media-spacing) * 2.75);
630
+ background-color: oklab(100% 0 5.96046e-8 / .1);
631
+ padding: .1em;
632
+ line-height: 1.25;
607
633
  }
608
634
 
609
635
  :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-button-icon {
@@ -676,6 +702,10 @@
676
702
  outline: 2px solid;
677
703
  }
678
704
 
705
+ :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-menu-radio-item[data-custom] {
706
+ font-style: italic;
707
+ }
708
+
679
709
  :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-menu-radio-item[data-highlighted] {
680
710
  background-color: var(--media-button-highlight);
681
711
  }
@@ -1201,14 +1231,6 @@
1201
1231
  display: block;
1202
1232
  }
1203
1233
 
1204
- :where(.media-skin[data-theme="scaffold"][data-preset="video"]) :where(.media-airplay-button)[data-airplay-state="connected"] .media-airplay-button-enter-icon, :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-airplay-button-exit-icon {
1205
- display: none;
1206
- }
1207
-
1208
- :where(:where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-airplay-button)[data-airplay-state="connected"] .media-airplay-button-exit-icon {
1209
- display: block;
1210
- }
1211
-
1212
1234
  :where(.media-skin[data-theme="scaffold"][data-preset="video"]) :where(.media-captions-button)[data-active] .media-captions-button-off-icon, :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-captions-button-on-icon {
1213
1235
  display: none;
1214
1236
  }
@@ -1699,6 +1721,14 @@
1699
1721
  inset: auto !important;
1700
1722
  }
1701
1723
 
1724
+ :where(.media-skin[data-theme="scaffold"][data-preset="video"]) :where(.media-airplay-button)[data-airplay-state="connected"] .media-airplay-button-enter-icon, :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-airplay-button-exit-icon {
1725
+ display: none;
1726
+ }
1727
+
1728
+ :where(:where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-airplay-button)[data-airplay-state="connected"] .media-airplay-button-exit-icon {
1729
+ display: block;
1730
+ }
1731
+
1702
1732
  :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-tooltip-screen-popup {
1703
1733
  --media-tooltip-side-offset: calc(var(--media-spacing) * 3) !important;
1704
1734
  }
@@ -1768,7 +1798,7 @@
1768
1798
 
1769
1799
  :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .video-controls-backdrop {
1770
1800
  pointer-events: none;
1771
- background-color: #0006;
1801
+ background-image: linear-gradient(to top, #00000080, #0000 40% 60%, #0006);
1772
1802
  position: absolute;
1773
1803
  inset: 0;
1774
1804
  }
@@ -1803,6 +1833,9 @@
1803
1833
  :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-container, :where(.media-skin[data-theme="scaffold"][data-preset="video"]).media-container {
1804
1834
  border-radius: var(--media-video-border-radius);
1805
1835
  width: 100%;
1836
+ min-width: 0;
1837
+ height: 100%;
1838
+ min-height: 0;
1806
1839
  font-family: var(--media-font-family, inherit);
1807
1840
  font-size: calc(var(--media-spacing) * 3.25);
1808
1841
  color: var(--media-foreground);
@@ -1822,9 +1855,19 @@
1822
1855
  }
1823
1856
 
1824
1857
  :where(.media-skin[data-theme="scaffold"][data-preset="video"]) .media-video, :where(.media-skin[data-theme="scaffold"][data-preset="video"]).media-video {
1825
- aspect-ratio: 16 / 9;
1826
1858
  background-color: #000;
1827
1859
  }
1860
+
1861
+ .media-container > slot::slotted(video), :scope.media-container > slot::slotted(video) {
1862
+ border-radius: inherit;
1863
+ object-fit: var(--media-object-fit, contain);
1864
+ object-position: var(--media-object-position, center);
1865
+ width: 100%;
1866
+ max-width: 100%;
1867
+ margin: 0;
1868
+ display: block;
1869
+ height: 100% !important;
1870
+ }
1828
1871
  }
1829
1872
 
1830
1873
  @layer utilities;
@@ -1842,7 +1885,7 @@
1842
1885
  --media-accent: var(--media-accent-color, color-mix(in oklab, var(--media-default-accent-color) 10%, transparent));
1843
1886
  --media-accent-foreground: var(--media-accent-text-color, currentColor);
1844
1887
  --media-muted: oklch(100% 0 0 / .15);
1845
- --media-muted-foreground: oklch(100% 0 0 / .65);
1888
+ --media-muted-foreground: color-mix(in oklab, var(--media-foreground) 65%, transparent);
1846
1889
  --media-border: oklch(0% 0 0 / .1);
1847
1890
  --media-ring: oklch(100% 0 0);
1848
1891
  --media-backdrop: oklch(0% 0 0);
@@ -1855,9 +1898,9 @@
1855
1898
  --media-shadow-current-color: oklch(from currentColor 0 0 0 / clamp(0, calc((l - .5) * .5), .15));
1856
1899
  --media-shadow-subtle-current-color: color-mix(in oklab, var(--media-shadow-current-color) 40%, transparent);
1857
1900
  --media-text-shadow-dialog: 0 1px 0 #00000040;
1858
- --media-backdrop-filter-surface: blur(16px) saturate(110%);
1901
+ --media-backdrop-filter-surface: blur(16px) saturate(125%);
1859
1902
  --media-backdrop-filter-indicator: blur(8px);
1860
- --media-backdrop-filter-dialog: blur(16px) saturate(110%);
1903
+ --media-backdrop-filter-dialog: blur(16px) saturate(125%);
1861
1904
  --media-control-corner-shape: round;
1862
1905
  --media-control-radius: 99px;
1863
1906
  --media-control-size: calc(var(--media-spacing) * 9);
@@ -1957,10 +2000,20 @@
1957
2000
  @layer base.preset {
1958
2001
  .media-skin:is([data-preset="video"], [data-preset="live-video"]) {
1959
2002
  --media-frame-border: var(--media-border-color, #0000001a);
2003
+ --media-controls-gradient-height: max(40%, calc(var(--media-spacing) * 40));
2004
+ --media-controls-bottom-gradient-height: max(50%, calc(var(--media-spacing) * 60));
1960
2005
  --media-controls-gradient: linear-gradient(to top,
1961
- color-mix(in oklab, var(--media-backdrop) 40%, transparent),
1962
- color-mix(in oklab, var(--media-backdrop) 20%, transparent),
1963
- color-mix(in oklab, var(--media-backdrop) 50%, transparent));
2006
+ color-mix(in oklab, var(--media-backdrop) 60%, transparent),
2007
+ color-mix(in oklab, var(--media-backdrop) 50.7%, transparent) 25%,
2008
+ color-mix(in oklab, var(--media-backdrop) 30%, transparent) 50%,
2009
+ color-mix(in oklab, var(--media-backdrop) 9.3%, transparent) 75%,
2010
+ transparent);
2011
+ --media-controls-top-gradient: linear-gradient(to bottom,
2012
+ color-mix(in oklab, var(--media-backdrop) 55%, transparent),
2013
+ color-mix(in oklab, var(--media-backdrop) 46.48%, transparent) 25%,
2014
+ color-mix(in oklab, var(--media-backdrop) 27.5%, transparent) 50%,
2015
+ color-mix(in oklab, var(--media-backdrop) 8.53%, transparent) 75%,
2016
+ transparent);
1964
2017
  --media-caption-controls-y: calc(var(--media-spacing) * -16);
1965
2018
  --media-slider-preview-offset: calc(var(--media-spacing) * 9);
1966
2019
  --media-thumbnail-gradient: linear-gradient(to top,
@@ -1972,9 +2025,17 @@
1972
2025
  @supports (color: oklch(from red l c h)) and (background-image: linear-gradient(in oklab, red, red)) {
1973
2026
  .media-skin:is([data-preset="video"], [data-preset="live-video"]) {
1974
2027
  --media-controls-gradient: linear-gradient(to top in oklab,
1975
- oklch(from var(--media-backdrop) l c h / .4),
1976
- oklch(from var(--media-backdrop) l c h / .2),
1977
- oklch(from var(--media-backdrop) l c h / .5));
2028
+ oklch(from var(--media-backdrop) l c h / .6),
2029
+ oklch(from var(--media-backdrop) l c h / .507) 25%,
2030
+ oklch(from var(--media-backdrop) l c h / .3) 50%,
2031
+ oklch(from var(--media-backdrop) l c h / .093) 75%,
2032
+ transparent);
2033
+ --media-controls-top-gradient: linear-gradient(to bottom in oklab,
2034
+ oklch(from var(--media-backdrop) l c h / .55),
2035
+ oklch(from var(--media-backdrop) l c h / .4647) 25%,
2036
+ oklch(from var(--media-backdrop) l c h / .275) 50%,
2037
+ oklch(from var(--media-backdrop) l c h / .0853) 75%,
2038
+ transparent);
1978
2039
  }
1979
2040
  }
1980
2041
 
@@ -1989,9 +2050,20 @@
1989
2050
 
1990
2051
  .media-skin:is([data-preset="video"], [data-preset="live-video"])[data-theme="neutral"] {
1991
2052
  --media-frame-border: var(--media-border-color, #00000026);
2053
+ --media-controls-gradient-height: 40%;
2054
+ --media-controls-bottom-gradient-height: 40%;
1992
2055
  --media-controls-gradient: linear-gradient(to top,
1993
2056
  color-mix(in oklab, var(--media-backdrop) 50%, transparent),
1994
- color-mix(in oklab, var(--media-backdrop) 20%, transparent));
2057
+ color-mix(in oklab, var(--media-backdrop) 42.2%, transparent) 25%,
2058
+ color-mix(in oklab, var(--media-backdrop) 25%, transparent) 50%,
2059
+ color-mix(in oklab, var(--media-backdrop) 7.8%, transparent) 75%,
2060
+ transparent);
2061
+ --media-controls-top-gradient: linear-gradient(to bottom,
2062
+ color-mix(in oklab, var(--media-backdrop) 50%, transparent),
2063
+ color-mix(in oklab, var(--media-backdrop) 42.2%, transparent) 25%,
2064
+ color-mix(in oklab, var(--media-backdrop) 25%, transparent) 50%,
2065
+ color-mix(in oklab, var(--media-backdrop) 7.8%, transparent) 75%,
2066
+ transparent);
1995
2067
  --media-indicator-gradient: linear-gradient(to bottom,
1996
2068
  color-mix(in oklab, var(--media-backdrop) 35%, transparent),
1997
2069
  color-mix(in oklab, var(--media-backdrop) 20%, transparent) calc(var(--media-spacing) * 12),
@@ -2001,6 +2073,7 @@
2001
2073
  }
2002
2074
 
2003
2075
  .media-skin:is([data-preset="video"], [data-preset="live-video"])[data-theme="compat"] {
2076
+ --media-controls-gradient: linear-gradient(to top, #00000080, transparent 40% 60%, #0006);
2004
2077
  --media-caption-controls-y: calc(var(--media-spacing) * -18);
2005
2078
  }
2006
2079
 
@@ -2012,7 +2085,16 @@
2012
2085
  .media-skin:is([data-preset="video"], [data-preset="live-video"])[data-theme="neutral"] {
2013
2086
  --media-controls-gradient: linear-gradient(to top in oklab,
2014
2087
  oklch(from var(--media-backdrop) l c h / .5),
2015
- oklch(from var(--media-backdrop) l c h / .2));
2088
+ oklch(from var(--media-backdrop) l c h / .422) 25%,
2089
+ oklch(from var(--media-backdrop) l c h / .25) 50%,
2090
+ oklch(from var(--media-backdrop) l c h / .078) 75%,
2091
+ transparent);
2092
+ --media-controls-top-gradient: linear-gradient(to bottom in oklab,
2093
+ oklch(from var(--media-backdrop) l c h / .5),
2094
+ oklch(from var(--media-backdrop) l c h / .422) 25%,
2095
+ oklch(from var(--media-backdrop) l c h / .25) 50%,
2096
+ oklch(from var(--media-backdrop) l c h / .078) 75%,
2097
+ transparent);
2016
2098
  }
2017
2099
  }
2018
2100
 
@@ -2036,7 +2118,6 @@
2036
2118
  }
2037
2119
 
2038
2120
  .media-skin[data-theme="scaffold"] {
2039
- --media-spacing: calc(var(--media-scale-unit, 16px) / 4);
2040
2121
  --media-background: transparent;
2041
2122
  --media-foreground: white;
2042
2123
  --media-accent: var(--media-accent-color, var(--media-default-accent-color));
@@ -0,0 +1,31 @@
1
+ import { MediaAttachMixin } from "../../store/media-attach-mixin.js";
2
+ import { CustomMediaElement } from "@videojs/media/dom";
3
+ import { DailymotionAdapter } from "@videojs/dailymotion-video";
4
+ //#region src/media/dailymotion-video/adapter.ts
5
+ var DailymotionCustomMediaElement = class extends CustomMediaElement("iframe", DailymotionAdapter) {
6
+ static {
7
+ this.getTemplateHTML = () => `<style> :host { display: inline-block; min-width: 300px; min-height: 150px; position: relative; } ::slotted([slot=media]) { position: absolute; inset: 0; } </style><slot name="media"></slot>`;
8
+ }
9
+ };
10
+ var DailymotionVideo = class extends MediaAttachMixin(DailymotionCustomMediaElement) {
11
+ constructor() {
12
+ super();
13
+ this.adapter.addEventListener("volumechange", () => {
14
+ const { muted } = this.adapter;
15
+ if (this.hasAttribute("muted") !== muted) this.toggleAttribute("muted", muted);
16
+ });
17
+ }
18
+ connectedCallback() {
19
+ super.connectedCallback?.();
20
+ const existing = this.querySelector(":scope > [slot=media]");
21
+ if (existing) {
22
+ if (this.adapter.src && !existing.hasChildNodes() && !this.adapter.error) this.adapter.load();
23
+ return;
24
+ }
25
+ const container = document.createElement("div");
26
+ container.slot = "media";
27
+ this.append(container);
28
+ }
29
+ };
30
+ //#endregion
31
+ export { DailymotionVideo };
@@ -1,6 +1,6 @@
1
1
  import { MediaAttachMixin } from "../../store/media-attach-mixin.js";
2
2
  import { CustomMediaElement } from "@videojs/media/dom";
3
- import { HlsAudioAdapter } from "@videojs/spf/hls-audio";
3
+ import { HlsAudioAdapter } from "@videojs/spf/adapters/hls-audio";
4
4
  //#region src/media/hls-audio/adapter.ts
5
5
  var HlsAudio = class extends MediaAttachMixin(CustomMediaElement("audio", HlsAudioAdapter)) {};
6
6
  //#endregion
@@ -1,7 +1,7 @@
1
1
  import { MediaAttachMixin } from "../../store/media-attach-mixin.js";
2
2
  import { getTemplateHTML } from "../background-video/template.js";
3
3
  import { namedNodeMapToObject } from "@videojs/utils/dom";
4
- import { HlsBackgroundVideoAdapter } from "@videojs/spf/hls-background-video";
4
+ import { HlsBackgroundVideoAdapter } from "@videojs/spf/adapters/hls-background-video";
5
5
  //#region src/media/hls-background-video/adapter.ts
6
6
  const HTMLElementBase = globalThis.HTMLElement ?? class {};
7
7
  const HlsBackgroundVideoBase = MediaAttachMixin(HTMLElementBase);
@@ -73,6 +73,13 @@ var HlsBackgroundVideo = class extends HlsBackgroundVideoBase {
73
73
  getMediaTarget() {
74
74
  return this.#media;
75
75
  }
76
+ /**
77
+ * The Media driving the inner `<video>`, matching `adapter` on `CustomMediaElement`. Call `adapter.destroy()` to
78
+ * release the engine after `keep-alive` kept it running past removal.
79
+ */
80
+ get adapter() {
81
+ return this.#media;
82
+ }
76
83
  disconnectedCallback() {
77
84
  super.disconnectedCallback?.();
78
85
  if (this.hasAttribute("keep-alive")) return;
@@ -1,6 +1,6 @@
1
1
  import { MediaAttachMixin } from "../../store/media-attach-mixin.js";
2
2
  import { CustomMediaElement } from "@videojs/media/dom";
3
- import { HlsVideoAdapter } from "@videojs/spf/hls-video";
3
+ import { HlsVideoAdapter } from "@videojs/spf/adapters/hls-video";
4
4
  //#region src/media/hls-video/adapter.ts
5
5
  var HlsVideo = class extends MediaAttachMixin(CustomMediaElement("video", HlsVideoAdapter)) {};
6
6
  //#endregion
@@ -0,0 +1,16 @@
1
+ import { MediaAttachMixin } from "../../store/media-attach-mixin.js";
2
+ import { CustomMediaElement } from "@videojs/media/dom";
3
+ import { escapeHtml } from "@videojs/utils/string";
4
+ import { MixcloudAdapter, buildMixcloudIframeSrc } from "@videojs/mixcloud-audio";
5
+ //#region src/media/mixcloud-audio/adapter.ts
6
+ var MixcloudCustomMediaElement = class extends CustomMediaElement("iframe", MixcloudAdapter) {
7
+ static {
8
+ this.getTemplateHTML = (attrs) => {
9
+ const initialSrc = buildMixcloudIframeSrc(attrs.src ?? "");
10
+ return `<style> :host { display: block; position: relative; height: 120px; } iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; } /* * The widget is Mixcloud's own chrome, so without controls it is a * transport and nothing else. Hidden rather than merely inert, and * important so a consumer's own display rule cannot put it back on * screen. An iframe in a hidden subtree still loads and plays its src. */ :host(:not([controls])) { display: none !important; } </style><iframe part="iframe" title="Mixcloud audio player" ${initialSrc ? ` src="${escapeHtml(initialSrc)}"` : ""} allow="autoplay; encrypted-media" frameborder="0" width="100%" height="100%" referrerpolicy="${escapeHtml(attrs.referrerpolicy ?? "")}" ></iframe>`;
11
+ };
12
+ }
13
+ };
14
+ var MixcloudAudio = class extends MediaAttachMixin(MixcloudCustomMediaElement) {};
15
+ //#endregion
16
+ export { MixcloudAudio };
@@ -0,0 +1,16 @@
1
+ import { MediaAttachMixin } from "../../store/media-attach-mixin.js";
2
+ import { CustomMediaElement } from "@videojs/media/dom";
3
+ import { escapeHtml } from "@videojs/utils/string";
4
+ import { SoundCloudAdapter, buildSoundCloudIframeSrc } from "@videojs/soundcloud-audio";
5
+ //#region src/media/soundcloud-audio/adapter.ts
6
+ var SoundCloudCustomMediaElement = class extends CustomMediaElement("iframe", SoundCloudAdapter) {
7
+ static {
8
+ this.getTemplateHTML = (attrs) => {
9
+ const initialSrc = buildSoundCloudIframeSrc(attrs.src ?? "");
10
+ return `<style> :host { display: block; position: relative; height: 166px; } iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; } /* * The widget is SoundCloud's own chrome, so without controls it is a * transport and nothing else. Hidden rather than merely inert, and * important so a consumer's own display rule cannot put it back on * screen. An iframe in a hidden subtree still loads and plays its src. */ :host(:not([controls])) { display: none !important; } </style><iframe part="iframe" title="SoundCloud audio player" ${initialSrc ? ` src="${escapeHtml(initialSrc)}"` : ""} allow="autoplay; encrypted-media" scrolling="no" frameborder="0" width="100%" height="100%" referrerpolicy="${escapeHtml(attrs.referrerpolicy ?? "")}" ></iframe>`;
11
+ };
12
+ }
13
+ };
14
+ var SoundCloudAudio = class extends MediaAttachMixin(SoundCloudCustomMediaElement) {};
15
+ //#endregion
16
+ export { SoundCloudAudio };
@@ -1,6 +1,6 @@
1
1
  import { UIElement } from "../ui/ui-element.js";
2
2
  import { PlayerExtensionCoordinator, setPlayerConfigValue } from "@videojs/core/dom";
3
- import { ContextProvider, ContextRoot } from "@videojs/element/context";
3
+ import { ContextProvider } from "@videojs/element/context";
4
4
  import { camelCase, kebabCase } from "@videojs/utils/string";
5
5
  import { isNull } from "@videojs/utils/predicate";
6
6
  //#region src/player/element.ts
@@ -27,7 +27,6 @@ function createPlayerElement(options) {
27
27
  };
28
28
  }
29
29
  #store = options.factory();
30
- #contextRoot = new ContextRoot();
31
30
  #configuredStore = null;
32
31
  #detach = null;
33
32
  #connected = false;
@@ -94,7 +93,6 @@ function createPlayerElement(options) {
94
93
  }
95
94
  connectedCallback() {
96
95
  this.#connected = true;
97
- this.#contextRoot.attach(this);
98
96
  super.connectedCallback();
99
97
  this.#syncInitialConfig();
100
98
  this.#playerProvider.setValue(this.store);
@@ -111,13 +109,11 @@ function createPlayerElement(options) {
111
109
  }
112
110
  disconnectedCallback() {
113
111
  this.#connected = false;
114
- this.#contextRoot.detach(this);
115
112
  this.#observer.disconnect();
116
113
  this.#detachStore();
117
114
  super.disconnectedCallback();
118
115
  }
119
116
  destroyCallback() {
120
- this.#contextRoot.detach(this);
121
117
  this.#observer.disconnect();
122
118
  this.#detachStore();
123
119
  this.#extensions.destroy();
@@ -1,5 +1,5 @@
1
1
  import skin_default from "../../define/background/skin2.js";
2
- import { ReactiveElement } from "@videojs/element";
2
+ import { DestroyMixin, ReactiveElement } from "@videojs/element";
3
3
  import { ensureGlobalStyle } from "@videojs/utils/dom";
4
4
  //#region src/presets/background/skin.ts
5
5
  const STYLES_ID = "__media-background-styles";
@@ -12,7 +12,7 @@ function getTemplateHTML() {
12
12
  </media-container>
13
13
  `;
14
14
  }
15
- var BackgroundVideoSkinElement = class BackgroundVideoSkinElement extends ReactiveElement {
15
+ var BackgroundVideoSkinElement = class BackgroundVideoSkinElement extends DestroyMixin(ReactiveElement) {
16
16
  static {
17
17
  this.tagName = "background-video-skin";
18
18
  }
@@ -1,15 +1,16 @@
1
+ import { UIElement } from "../ui/ui-element.js";
1
2
  import global_default from "../define/global.js";
2
3
  import shadow_default from "../define/shadow.js";
3
- import { ReactiveElement } from "@videojs/element";
4
4
  import { applyShadowStyles, createShadowStyle, ensureGlobalStyle, renderTemplate } from "@videojs/utils/dom";
5
5
  //#region src/presets/skin.ts
6
6
  const STYLES_ID = "__media-styles";
7
7
  const shadowSheet = createShadowStyle(shadow_default);
8
8
  /**
9
9
  * Base element for skin definitions. Attaches a shadow root, clones `static template` into it, and applies shared +
10
- * per-skin styles via `adoptedStyleSheets` (or `<style>` fallback).
10
+ * per-skin styles via `adoptedStyleSheets` (or `<style>` fallback). Destroying it also destroys the controls in its
11
+ * shadow root.
11
12
  */
12
- var SkinElement = class extends ReactiveElement {
13
+ var SkinElement = class extends UIElement {
13
14
  static {
14
15
  this.shadowRootOptions = { mode: "open" };
15
16
  }
@@ -1,9 +1,10 @@
1
+ import { containerContext } from "../../player/context.js";
1
2
  import { UIElement } from "../ui-element.js";
2
3
  import { PositionController } from "../position-controller.js";
3
4
  import { dialogContext } from "./context.js";
4
5
  import { DialogCore, DialogDataAttrs } from "@videojs/core";
5
6
  import { applyElementProps, applyStateDataAttrs, createDialog, createTransition } from "@videojs/core/dom";
6
- import { ContextProvider } from "@videojs/element/context";
7
+ import { ContextConsumer, ContextProvider } from "@videojs/element/context";
7
8
  import { SnapshotController } from "@videojs/store/html";
8
9
  //#region src/ui/dialog/element.ts
9
10
  let idCounter = 0;
@@ -25,12 +26,14 @@ var DialogElementBase = class extends UIElement {
25
26
  #stateAttrMap;
26
27
  #provider;
27
28
  #position;
29
+ #container;
28
30
  #popupId;
29
31
  #titleId;
30
32
  #descriptionId;
31
33
  #bindTrigger;
32
34
  #dialog;
33
35
  #snapshot;
36
+ #modalitySnapshot;
34
37
  #triggerAbort;
35
38
  #triggerElement;
36
39
  constructor({ core = new DialogCore(), stateAttrMap = DialogDataAttrs, idPrefix = "dialog", bindTrigger = true } = {}) {
@@ -40,8 +43,13 @@ var DialogElementBase = class extends UIElement {
40
43
  this.closeOnEscape = DialogCore.defaultProps.closeOnEscape;
41
44
  this.#provider = new ContextProvider(this, { context: dialogContext });
42
45
  this.#position = new PositionController(this);
46
+ this.#container = new ContextConsumer(this, {
47
+ context: containerContext,
48
+ subscribe: true
49
+ });
43
50
  this.#dialog = null;
44
51
  this.#snapshot = null;
52
+ this.#modalitySnapshot = null;
45
53
  this.#triggerAbort = null;
46
54
  this.#triggerElement = null;
47
55
  this.#core = core;
@@ -69,6 +77,8 @@ var DialogElementBase = class extends UIElement {
69
77
  });
70
78
  if (this.#snapshot) this.#snapshot.track(this.#dialog.input);
71
79
  else this.#snapshot = new SnapshotController(this, this.#dialog.input);
80
+ if (this.#modalitySnapshot) this.#modalitySnapshot.track(this.#dialog.modality);
81
+ else this.#modalitySnapshot = new SnapshotController(this, this.#dialog.modality);
72
82
  }
73
83
  firstUpdated(changed) {
74
84
  super.firstUpdated(changed);
@@ -86,6 +96,7 @@ var DialogElementBase = class extends UIElement {
86
96
  willUpdate(changed) {
87
97
  super.willUpdate(changed);
88
98
  this.#core.setProps(this);
99
+ this.#dialog?.setInteractionRoot(this.#container.value?.container ?? null);
89
100
  if (this.#dialog && changed.has("open")) {
90
101
  const { active: inputOpen } = this.#dialog.input.current;
91
102
  if (this.open !== inputOpen) {
@@ -101,6 +112,7 @@ var DialogElementBase = class extends UIElement {
101
112
  this.#syncTrigger(triggerElement);
102
113
  const input = this.#dialog.input.current;
103
114
  this.#core.setInput(input);
115
+ this.#core.setDocumentModal(this.#dialog.modality.current.documentModal);
104
116
  const state = this.#core.getState();
105
117
  applyStateDataAttrs(this, state, this.#stateAttrMap);
106
118
  if (this.#triggerElement) applyElementProps(this.#triggerElement, this.#core.getTriggerAttrs(state, this.#popupId));
@@ -61,14 +61,17 @@ var GestureElement = class extends UIElement {
61
61
  if (!resolver) return;
62
62
  const { value, region } = this;
63
63
  const actionValue = getGestureActionValue(this.action, region, value);
64
+ let state;
64
65
  const onActivate = (event) => {
65
66
  resolver({
66
67
  store,
68
+ state,
67
69
  value: actionValue,
68
70
  event
69
71
  });
70
72
  };
71
73
  const options = {
74
+ onPointerDown: () => state = store.state,
72
75
  pointer: this.pointer,
73
76
  region,
74
77
  disabled: this.disabled,
@@ -71,6 +71,7 @@ var MediaButtonElement = class extends UIElement {
71
71
  if (!media) return void 0;
72
72
  this.core.setMedia(media);
73
73
  const state = this.core.getState();
74
+ if (this.core.getTooltipLabel) return translateText(this.core.getTooltipLabel(state), this.#i18n.value);
74
75
  return translateText(this.core.getLabel(state), this.#i18n.value, this.core.getLabelParams?.(state));
75
76
  }
76
77
  willUpdate(changed) {
@@ -89,9 +90,17 @@ var MediaButtonElement = class extends UIElement {
89
90
  applyElementProps(this, {
90
91
  ...attrs,
91
92
  "aria-keyshortcuts": this.#hotkeyRegistry?.aria,
92
- ...isHideable(state) && { hidden: state.hidden ? "" : void 0 }
93
+ ...isHideable(state) && this.reflectsHidden() && { hidden: state.hidden ? "" : void 0 }
93
94
  });
94
95
  applyStateDataAttrs(this, state, this.stateAttrMap);
96
+ for (const [name, value] of Object.entries(this.core.getCSSVars?.(state) ?? {})) this.style.setProperty(name, value);
97
+ }
98
+ /**
99
+ * Whether this button writes its core's `hidden` state to the `hidden` attribute. A subclass returns `false` while
100
+ * another owner, such as a linked menu, manages its visibility.
101
+ */
102
+ reflectsHidden() {
103
+ return true;
95
104
  }
96
105
  #syncHotkeyShortcut() {
97
106
  const shortcut = this.getShortcut();
@@ -8,6 +8,7 @@ var PlaybackRateButtonElement = class extends MediaButtonElement {
8
8
  constructor(..._args) {
9
9
  super(..._args);
10
10
  this.commandfor = void 0;
11
+ this.rates = void 0;
11
12
  this.core = new PlaybackRateButtonCore();
12
13
  this.stateAttrMap = PlaybackRateButtonDataAttrs;
13
14
  this.mediaState = new PlayerController(this, playerContext, selectPlaybackRate);
@@ -20,7 +21,8 @@ var PlaybackRateButtonElement = class extends MediaButtonElement {
20
21
  this.properties = {
21
22
  label: { type: String },
22
23
  disabled: { type: Boolean },
23
- commandfor: { type: String }
24
+ commandfor: { type: String },
25
+ rates: { type: String }
24
26
  };
25
27
  }
26
28
  activate(state, event) {
@@ -33,9 +35,12 @@ var PlaybackRateButtonElement = class extends MediaButtonElement {
33
35
  getIsButtonDisabled() {
34
36
  const media = this.mediaState.value;
35
37
  if (super.getIsButtonDisabled()) return true;
36
- if (this.commandfor && media && media.playbackRates.length === 0) return true;
38
+ if (this.commandfor && media && this.core.getRates(media).length === 0) return true;
37
39
  return false;
38
40
  }
41
+ reflectsHidden() {
42
+ return !this.commandfor;
43
+ }
39
44
  willUpdate(changed) {
40
45
  super.willUpdate(changed);
41
46
  if (changed.has("commandfor")) {
@@ -17,12 +17,17 @@ var PlaybackRateRadioGroupElement = class extends MenuRadioGroupElement {
17
17
  constructor(..._args) {
18
18
  super(..._args);
19
19
  this.disabled = false;
20
+ this.rates = void 0;
20
21
  this.formatRate = PlaybackRateRadioGroupCore.defaultProps.formatRate;
21
22
  this.#core = new PlaybackRateRadioGroupCore();
22
23
  this.#i18n = new I18nController(this, i18nContext);
23
24
  this.#mediaState = new PlayerController(this, playerContext, selectPlaybackRate);
24
25
  this.#options = new RadioOptionsController(this, {
25
- setItemAttributes: (item, option) => item.setAttribute("data-rate", option.value),
26
+ setItemAttributes: (item, option) => {
27
+ item.setAttribute("data-rate", option.value);
28
+ item.toggleAttribute("data-custom", option.custom);
29
+ },
30
+ getOptionCacheKey: (option) => option.custom ? "custom" : "",
26
31
  onValueChange: (value) => {
27
32
  const media = this.#mediaState.value;
28
33
  if (media) this.#core.selectValue(media, value);
@@ -35,7 +40,8 @@ var PlaybackRateRadioGroupElement = class extends MenuRadioGroupElement {
35
40
  static {
36
41
  this.properties = {
37
42
  ...MenuRadioGroupElement.properties,
38
- disabled: { type: Boolean }
43
+ disabled: { type: Boolean },
44
+ rates: { type: String }
39
45
  };
40
46
  }
41
47
  #core;
@@ -52,7 +58,8 @@ var PlaybackRateRadioGroupElement = class extends MenuRadioGroupElement {
52
58
  if (media) {
53
59
  this.#core.setProps({
54
60
  formatRate: this.formatRate,
55
- disabled: this.disabled
61
+ disabled: this.disabled,
62
+ rates: this.rates
56
63
  });
57
64
  this.#core.setMedia(media);
58
65
  state = this.#core.getState();