@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.
- package/cdn/{abort-CzqmAxxH.js → abort-BL-SGV3o.js} +1 -1
- package/cdn/{abort-CzqmAxxH.js.map → abort-BL-SGV3o.js.map} +1 -1
- package/cdn/{abort-KaHR4JO1.js → abort-DGNIECLn.js} +1 -1
- package/cdn/{abort-KaHR4JO1.js.map → abort-DGNIECLn.js.map} +1 -1
- package/cdn/audio-minimal-ui.dev.js +4 -5
- package/cdn/audio-minimal-ui.js +1 -1
- package/cdn/audio-minimal.dev.js +7 -8
- package/cdn/audio-minimal.dev.js.map +1 -1
- package/cdn/audio-minimal.js +1 -1
- package/cdn/audio-minimal.js.map +1 -1
- package/cdn/audio-ui.dev.js +4 -5
- package/cdn/audio-ui.js +1 -1
- package/cdn/audio.dev.js +22 -7
- package/cdn/audio.dev.js.map +1 -1
- package/cdn/audio.js +1 -1
- package/cdn/audio.js.map +1 -1
- package/cdn/background.dev.js +3 -3
- package/cdn/background.js +1 -1
- package/cdn/background.js.map +1 -1
- package/cdn/compounds-Df_1JbZD.js +8 -0
- package/cdn/compounds-Df_1JbZD.js.map +1 -0
- package/cdn/{volume-slider-Co5X4Z1t.js → compounds-VFPcCeRV.js} +2439 -946
- package/cdn/compounds-VFPcCeRV.js.map +1 -0
- package/cdn/context-C-IpVHEt.js +14 -0
- package/cdn/context-C-IpVHEt.js.map +1 -0
- package/cdn/{context-BjrbhiSk.js → context-CvJ83xGk.js} +2 -83
- package/cdn/context-CvJ83xGk.js.map +1 -0
- package/cdn/{create-player-p9xCO0yC.js → create-player-CyG77t-m.js} +778 -1955
- package/cdn/create-player-CyG77t-m.js.map +1 -0
- package/cdn/create-player-Gom2ZZe3.js +7 -0
- package/cdn/create-player-Gom2ZZe3.js.map +1 -0
- package/cdn/{hls-26YJVjvD.js → hls-BAbdl84H.js} +3 -3
- package/cdn/{hls-26YJVjvD.js.map → hls-BAbdl84H.js.map} +1 -1
- package/cdn/{hls-BriQI4q1.js → hls-BrzPpueW.js} +9 -12
- package/cdn/{hls-BriQI4q1.js.map → hls-BrzPpueW.js.map} +1 -1
- package/cdn/hotkey-element-DR3ZAqKa.js +2 -0
- package/cdn/hotkey-element-DR3ZAqKa.js.map +1 -0
- package/cdn/hotkey-element-Dlta37Be.js +369 -0
- package/cdn/hotkey-element-Dlta37Be.js.map +1 -0
- package/cdn/media/dash-video.dev.js +3 -4
- package/cdn/media/dash-video.dev.js.map +1 -1
- package/cdn/media/dash-video.js +2 -2
- package/cdn/media/hls-video.dev.js +4 -5
- package/cdn/media/hls-video.dev.js.map +1 -1
- package/cdn/media/hls-video.js +1 -1
- package/cdn/media/hls-video.js.map +1 -1
- package/cdn/media/mux-audio.dev.d.ts +1 -0
- package/cdn/media/mux-audio.dev.js +29 -0
- package/cdn/media/mux-audio.dev.js.map +1 -0
- package/cdn/media/mux-audio.js +2 -0
- package/cdn/media/mux-audio.js.map +1 -0
- package/cdn/media/mux-video.dev.js +5 -3099
- package/cdn/media/mux-video.dev.js.map +1 -1
- package/cdn/media/mux-video.js +1 -24
- package/cdn/media/mux-video.js.map +1 -1
- package/cdn/media/native-hls-video.dev.js +4 -4
- package/cdn/media/native-hls-video.js +1 -1
- package/cdn/media/simple-hls-video.dev.js +966 -681
- package/cdn/media/simple-hls-video.dev.js.map +1 -1
- package/cdn/media/simple-hls-video.js +6 -6
- package/cdn/media/simple-hls-video.js.map +1 -1
- package/cdn/{media-attach-mixin-DfKkofgF.js → media-attach-mixin-CMH1ziXP.js} +2 -2
- package/cdn/{media-attach-mixin-DfKkofgF.js.map → media-attach-mixin-CMH1ziXP.js.map} +1 -1
- package/cdn/{media-attach-mixin-Dv2D43tb.js → media-attach-mixin-DUzmXEJ3.js} +2 -2
- package/cdn/{media-attach-mixin-Dv2D43tb.js.map → media-attach-mixin-DUzmXEJ3.js.map} +1 -1
- package/cdn/{media-props-mixin-Dc5dpCV4.js → media-props-mixin-hheRmkup.js} +92 -8
- package/cdn/media-props-mixin-hheRmkup.js.map +1 -0
- package/cdn/media-props-mixin-yRWj8yXF.js +47 -0
- package/cdn/media-props-mixin-yRWj8yXF.js.map +1 -0
- package/cdn/{minimal-BUUGNZK7.js → minimal-D9Dw-L2P.js} +1 -1
- package/cdn/{minimal-BUUGNZK7.js.map → minimal-D9Dw-L2P.js.map} +1 -1
- package/cdn/{minimal-CJGOJ6pE.js → minimal-Dc5nNl_-.js} +1 -1
- package/cdn/{minimal-CJGOJ6pE.js.map → minimal-Dc5nNl_-.js.map} +1 -1
- package/cdn/minimal-ui-B3BBK5nX.js +2 -0
- package/cdn/minimal-ui-B3BBK5nX.js.map +1 -0
- package/cdn/minimal-ui-CPRSYky_.js +28 -0
- package/cdn/minimal-ui-CPRSYky_.js.map +1 -0
- package/cdn/minimal-ui-Cnaig4X6.js +22 -0
- package/cdn/minimal-ui-Cnaig4X6.js.map +1 -0
- package/cdn/minimal-ui-DOePmQfq.js +2 -0
- package/cdn/minimal-ui-DOePmQfq.js.map +1 -0
- package/cdn/mux-DGgCyz_A.js +3102 -0
- package/cdn/mux-DGgCyz_A.js.map +1 -0
- package/cdn/mux-fYfPUpq3.js +25 -0
- package/cdn/mux-fYfPUpq3.js.map +1 -0
- package/cdn/{native-hls-D2rfyyyW.js → native-hls-BuCYu7Rd.js} +2 -3
- package/cdn/{native-hls-D2rfyyyW.js.map → native-hls-BuCYu7Rd.js.map} +1 -1
- package/cdn/native-hls-DnqJ-0zL.js +2 -0
- package/cdn/{native-hls-CjRvSXAJ.js.map → native-hls-DnqJ-0zL.js.map} +1 -1
- package/cdn/player-Cu5_r0Gk.js +2 -0
- package/cdn/{player-Cz9-_j7J.js.map → player-Cu5_r0Gk.js.map} +1 -1
- package/cdn/player-DIOgBqQf.js +382 -0
- package/cdn/player-DIOgBqQf.js.map +1 -0
- package/cdn/{player-D0bhjT8X.js → player-DxBoqZVw.js} +4 -3
- package/cdn/{player-D0bhjT8X.js.map → player-DxBoqZVw.js.map} +1 -1
- package/cdn/player-eEH-XjnF.js +2 -0
- package/cdn/player-eEH-XjnF.js.map +1 -0
- package/cdn/{shallow-equal-uPuCQhnd.js → shallow-equal-1KBb-lrM.js} +1 -1
- package/cdn/{shallow-equal-uPuCQhnd.js.map → shallow-equal-1KBb-lrM.js.map} +1 -1
- package/cdn/{shallow-equal-C8Fs4TTE.js → shallow-equal-Ca0qjpLJ.js} +1 -1
- package/cdn/{shallow-equal-C8Fs4TTE.js.map → shallow-equal-Ca0qjpLJ.js.map} +1 -1
- package/cdn/{skin-element-zakTHELS.js → skin-element-BTPr5DoY.js} +2 -2
- package/cdn/{skin-element-zakTHELS.js.map → skin-element-BTPr5DoY.js.map} +1 -1
- package/cdn/{skin-element-DB-cKAAx.js → skin-element-u6pdmSSs.js} +2 -2
- package/cdn/{skin-element-DB-cKAAx.js.map → skin-element-u6pdmSSs.js.map} +1 -1
- package/cdn/ui-34pkHFdT.js +25 -0
- package/cdn/ui-34pkHFdT.js.map +1 -0
- package/cdn/ui-DWoV_Da1.js +2 -0
- package/cdn/ui-DWoV_Da1.js.map +1 -0
- package/cdn/ui-DXtTKomo.js +2 -0
- package/cdn/ui-DXtTKomo.js.map +1 -0
- package/cdn/ui-X5WOdCCw.js +31 -0
- package/cdn/ui-X5WOdCCw.js.map +1 -0
- package/cdn/video-minimal-ui.dev.js +4 -5
- package/cdn/video-minimal-ui.js +1 -1
- package/cdn/video-minimal.dev.js +7 -8
- package/cdn/video-minimal.dev.js.map +1 -1
- package/cdn/video-minimal.js +1 -1
- package/cdn/video-minimal.js.map +1 -1
- package/cdn/video-ui.dev.js +4 -5
- package/cdn/video-ui.js +1 -1
- package/cdn/video.dev.js +32 -7
- package/cdn/video.dev.js.map +1 -1
- package/cdn/video.js +1 -1
- package/cdn/video.js.map +1 -1
- package/dist/default/_virtual/inline-css_src/define/audio/minimal-skin.js +1 -1
- package/dist/default/_virtual/inline-css_src/define/audio/minimal-skin.js.map +1 -1
- package/dist/default/_virtual/inline-css_src/define/audio/skin.js +1 -1
- package/dist/default/_virtual/inline-css_src/define/audio/skin.js.map +1 -1
- package/dist/default/_virtual/inline-css_src/define/video/minimal-skin.js +1 -1
- package/dist/default/_virtual/inline-css_src/define/video/minimal-skin.js.map +1 -1
- package/dist/default/_virtual/inline-css_src/define/video/skin.js +1 -1
- package/dist/default/_virtual/inline-css_src/define/video/skin.js.map +1 -1
- package/dist/default/define/audio/minimal-skin.css +23 -0
- package/dist/default/define/audio/minimal-ui.js +28 -12
- package/dist/default/define/audio/minimal-ui.js.map +1 -0
- package/dist/default/define/audio/skin.css +23 -0
- package/dist/default/define/audio/skin.js +1 -1
- package/dist/default/define/audio/skin.js.map +1 -1
- package/dist/default/define/audio/ui.js +32 -12
- package/dist/default/define/audio/ui.js.map +1 -0
- package/dist/default/define/background/skin.js +1 -1
- package/dist/default/define/media/mux-audio.js +13 -0
- package/dist/default/define/media/mux-audio.js.map +1 -0
- package/dist/default/define/skin-element.js +1 -1
- package/dist/default/define/ui/compounds.js +62 -0
- package/dist/default/define/ui/compounds.js.map +1 -0
- package/dist/default/define/ui/controls.js +2 -5
- package/dist/default/define/ui/controls.js.map +1 -1
- package/dist/default/define/ui/error-dialog.js +2 -9
- package/dist/default/define/ui/error-dialog.js.map +1 -1
- package/dist/default/define/ui/hotkey.js +7 -0
- package/dist/default/define/ui/hotkey.js.map +1 -0
- package/dist/default/define/ui/slider.js +2 -13
- package/dist/default/define/ui/slider.js.map +1 -1
- package/dist/default/define/ui/time-slider.js +2 -17
- package/dist/default/define/ui/time-slider.js.map +1 -1
- package/dist/default/define/ui/time.js +2 -7
- package/dist/default/define/ui/time.js.map +1 -1
- package/dist/default/define/ui/volume-slider.js +2 -13
- package/dist/default/define/ui/volume-slider.js.map +1 -1
- package/dist/default/define/video/minimal-skin.css +23 -0
- package/dist/default/define/video/minimal-ui.js +39 -18
- package/dist/default/define/video/minimal-ui.js.map +1 -0
- package/dist/default/define/video/skin.css +23 -0
- package/dist/default/define/video/skin.js +1 -1
- package/dist/default/define/video/skin.js.map +1 -1
- package/dist/default/define/video/ui.js +43 -18
- package/dist/default/define/video/ui.js.map +1 -0
- package/dist/default/index.js +6 -1
- package/dist/default/media/container-element.js +16 -0
- package/dist/default/media/container-element.js.map +1 -1
- package/dist/default/media/mux-audio/index.js +18 -0
- package/dist/default/media/mux-audio/index.js.map +1 -0
- package/dist/default/player/context.js.map +1 -1
- package/dist/default/ui/alert-dialog/alert-dialog-element.js +1 -0
- package/dist/default/ui/alert-dialog/alert-dialog-element.js.map +1 -1
- package/dist/default/ui/buffering-indicator/buffering-indicator-element.js +1 -0
- package/dist/default/ui/buffering-indicator/buffering-indicator-element.js.map +1 -1
- package/dist/default/ui/captions-button/captions-button-element.js +1 -0
- package/dist/default/ui/captions-button/captions-button-element.js.map +1 -1
- package/dist/default/ui/error-dialog/error-dialog-element.js +1 -0
- package/dist/default/ui/error-dialog/error-dialog-element.js.map +1 -1
- package/dist/default/ui/fullscreen-button/fullscreen-button-element.js +1 -0
- package/dist/default/ui/fullscreen-button/fullscreen-button-element.js.map +1 -1
- package/dist/default/ui/gesture/gesture-element.js +84 -0
- package/dist/default/ui/gesture/gesture-element.js.map +1 -0
- package/dist/default/ui/hotkey/aria-key-shortcuts-controller.js +28 -0
- package/dist/default/ui/hotkey/aria-key-shortcuts-controller.js.map +1 -0
- package/dist/default/ui/hotkey/hotkey-element.js +81 -0
- package/dist/default/ui/hotkey/hotkey-element.js.map +1 -0
- package/dist/default/ui/media-button-element.js +9 -1
- package/dist/default/ui/media-button-element.js.map +1 -1
- package/dist/default/ui/mute-button/mute-button-element.js +1 -0
- package/dist/default/ui/mute-button/mute-button-element.js.map +1 -1
- package/dist/default/ui/pip-button/pip-button-element.js +1 -0
- package/dist/default/ui/pip-button/pip-button-element.js.map +1 -1
- package/dist/default/ui/play-button/play-button-element.js +1 -0
- package/dist/default/ui/play-button/play-button-element.js.map +1 -1
- package/dist/default/ui/popover/popover-element.js +7 -55
- package/dist/default/ui/popover/popover-element.js.map +1 -1
- package/dist/default/ui/position-controller.js +76 -0
- package/dist/default/ui/position-controller.js.map +1 -0
- package/dist/default/ui/slider/slider-element.js +1 -1
- package/dist/default/ui/slider/slider-preview-element.js +1 -1
- package/dist/default/ui/time-slider/time-slider-element.js +5 -5
- package/dist/default/ui/time-slider/time-slider-element.js.map +1 -1
- package/dist/default/ui/tooltip/tooltip-element.js +8 -54
- package/dist/default/ui/tooltip/tooltip-element.js.map +1 -1
- package/dist/default/ui/volume-slider/volume-slider-element.js +1 -1
- package/dist/dev/_virtual/inline-css_src/define/audio/minimal-skin.js +1 -1
- package/dist/dev/_virtual/inline-css_src/define/audio/minimal-skin.js.map +1 -1
- package/dist/dev/_virtual/inline-css_src/define/audio/skin.js +1 -1
- package/dist/dev/_virtual/inline-css_src/define/audio/skin.js.map +1 -1
- package/dist/dev/_virtual/inline-css_src/define/video/minimal-skin.js +1 -1
- package/dist/dev/_virtual/inline-css_src/define/video/minimal-skin.js.map +1 -1
- package/dist/dev/_virtual/inline-css_src/define/video/skin.js +1 -1
- package/dist/dev/_virtual/inline-css_src/define/video/skin.js.map +1 -1
- package/dist/dev/define/audio/minimal-skin.css +23 -0
- package/dist/dev/define/audio/minimal-ui.js +28 -12
- package/dist/dev/define/audio/minimal-ui.js.map +1 -0
- package/dist/dev/define/audio/skin.css +23 -0
- package/dist/dev/define/audio/skin.d.ts.map +1 -1
- package/dist/dev/define/audio/skin.js +16 -0
- package/dist/dev/define/audio/skin.js.map +1 -1
- package/dist/dev/define/audio/ui.js +32 -12
- package/dist/dev/define/audio/ui.js.map +1 -0
- package/dist/dev/define/background/skin.js +1 -1
- package/dist/dev/define/media/mux-audio.d.ts +14 -0
- package/dist/dev/define/media/mux-audio.d.ts.map +1 -0
- package/dist/dev/define/media/mux-audio.js +13 -0
- package/dist/dev/define/media/mux-audio.js.map +1 -0
- package/dist/dev/define/skin-element.d.ts +1 -1
- package/dist/dev/define/skin-element.js +1 -1
- package/dist/dev/define/ui/compounds.d.ts +12 -0
- package/dist/dev/define/ui/compounds.d.ts.map +1 -0
- package/dist/dev/define/ui/compounds.js +62 -0
- package/dist/dev/define/ui/compounds.js.map +1 -0
- package/dist/dev/define/ui/controls.d.ts +2 -0
- package/dist/dev/define/ui/controls.d.ts.map +1 -1
- package/dist/dev/define/ui/controls.js +2 -5
- package/dist/dev/define/ui/controls.js.map +1 -1
- package/dist/dev/define/ui/error-dialog.d.ts +6 -0
- package/dist/dev/define/ui/error-dialog.d.ts.map +1 -1
- package/dist/dev/define/ui/error-dialog.js +2 -9
- package/dist/dev/define/ui/error-dialog.js.map +1 -1
- package/dist/dev/define/ui/hotkey.d.ts +9 -0
- package/dist/dev/define/ui/hotkey.d.ts.map +1 -0
- package/dist/dev/define/ui/hotkey.js +7 -0
- package/dist/dev/define/ui/hotkey.js.map +1 -0
- package/dist/dev/define/ui/slider.d.ts +10 -0
- package/dist/dev/define/ui/slider.d.ts.map +1 -1
- package/dist/dev/define/ui/slider.js +2 -13
- package/dist/dev/define/ui/slider.js.map +1 -1
- package/dist/dev/define/ui/time-slider.d.ts +14 -0
- package/dist/dev/define/ui/time-slider.d.ts.map +1 -1
- package/dist/dev/define/ui/time-slider.js +2 -17
- package/dist/dev/define/ui/time-slider.js.map +1 -1
- package/dist/dev/define/ui/time.d.ts +4 -0
- package/dist/dev/define/ui/time.d.ts.map +1 -1
- package/dist/dev/define/ui/time.js +2 -7
- package/dist/dev/define/ui/time.js.map +1 -1
- package/dist/dev/define/ui/volume-slider.d.ts +10 -0
- package/dist/dev/define/ui/volume-slider.d.ts.map +1 -1
- package/dist/dev/define/ui/volume-slider.js +2 -13
- package/dist/dev/define/ui/volume-slider.js.map +1 -1
- package/dist/dev/define/video/minimal-skin.css +23 -0
- package/dist/dev/define/video/minimal-ui.js +39 -18
- package/dist/dev/define/video/minimal-ui.js.map +1 -0
- package/dist/dev/define/video/skin.css +23 -0
- package/dist/dev/define/video/skin.d.ts.map +1 -1
- package/dist/dev/define/video/skin.js +26 -0
- package/dist/dev/define/video/skin.js.map +1 -1
- package/dist/dev/define/video/ui.js +43 -18
- package/dist/dev/define/video/ui.js.map +1 -0
- package/dist/dev/index.d.ts +7 -2
- package/dist/dev/index.js +6 -1
- package/dist/dev/media/container-element.d.ts +3 -0
- package/dist/dev/media/container-element.d.ts.map +1 -1
- package/dist/dev/media/container-element.js +16 -0
- package/dist/dev/media/container-element.js.map +1 -1
- package/dist/dev/media/mux-audio/index.d.ts +11 -0
- package/dist/dev/media/mux-audio/index.d.ts.map +1 -0
- package/dist/dev/media/mux-audio/index.js +18 -0
- package/dist/dev/media/mux-audio/index.js.map +1 -0
- package/dist/dev/player/context.d.ts +4 -2
- package/dist/dev/player/context.d.ts.map +1 -1
- package/dist/dev/player/context.js.map +1 -1
- package/dist/dev/ui/alert-dialog/alert-dialog-element.d.ts.map +1 -1
- package/dist/dev/ui/alert-dialog/alert-dialog-element.js +1 -0
- package/dist/dev/ui/alert-dialog/alert-dialog-element.js.map +1 -1
- package/dist/dev/ui/buffering-indicator/buffering-indicator-element.d.ts.map +1 -1
- package/dist/dev/ui/buffering-indicator/buffering-indicator-element.js +1 -0
- package/dist/dev/ui/buffering-indicator/buffering-indicator-element.js.map +1 -1
- package/dist/dev/ui/captions-button/captions-button-element.d.ts +1 -0
- package/dist/dev/ui/captions-button/captions-button-element.d.ts.map +1 -1
- package/dist/dev/ui/captions-button/captions-button-element.js +1 -0
- package/dist/dev/ui/captions-button/captions-button-element.js.map +1 -1
- package/dist/dev/ui/context-part-element.d.ts +1 -1
- package/dist/dev/ui/error-dialog/error-dialog-element.d.ts.map +1 -1
- package/dist/dev/ui/error-dialog/error-dialog-element.js +1 -0
- package/dist/dev/ui/error-dialog/error-dialog-element.js.map +1 -1
- package/dist/dev/ui/fullscreen-button/fullscreen-button-element.d.ts +1 -0
- package/dist/dev/ui/fullscreen-button/fullscreen-button-element.d.ts.map +1 -1
- package/dist/dev/ui/fullscreen-button/fullscreen-button-element.js +1 -0
- package/dist/dev/ui/fullscreen-button/fullscreen-button-element.js.map +1 -1
- package/dist/dev/ui/gesture/gesture-element.d.ts +22 -0
- package/dist/dev/ui/gesture/gesture-element.d.ts.map +1 -0
- package/dist/dev/ui/gesture/gesture-element.js +84 -0
- package/dist/dev/ui/gesture/gesture-element.js.map +1 -0
- package/dist/dev/ui/hotkey/aria-key-shortcuts-controller.d.ts +15 -0
- package/dist/dev/ui/hotkey/aria-key-shortcuts-controller.d.ts.map +1 -0
- package/dist/dev/ui/hotkey/aria-key-shortcuts-controller.js +28 -0
- package/dist/dev/ui/hotkey/aria-key-shortcuts-controller.js.map +1 -0
- package/dist/dev/ui/hotkey/hotkey-element.d.ts +21 -0
- package/dist/dev/ui/hotkey/hotkey-element.d.ts.map +1 -0
- package/dist/dev/ui/hotkey/hotkey-element.js +81 -0
- package/dist/dev/ui/hotkey/hotkey-element.js.map +1 -0
- package/dist/dev/ui/media-button-element.d.ts +2 -0
- package/dist/dev/ui/media-button-element.d.ts.map +1 -1
- package/dist/dev/ui/media-button-element.js +9 -1
- package/dist/dev/ui/media-button-element.js.map +1 -1
- package/dist/dev/ui/mute-button/mute-button-element.d.ts +1 -0
- package/dist/dev/ui/mute-button/mute-button-element.d.ts.map +1 -1
- package/dist/dev/ui/mute-button/mute-button-element.js +1 -0
- package/dist/dev/ui/mute-button/mute-button-element.js.map +1 -1
- package/dist/dev/ui/pip-button/pip-button-element.d.ts +1 -0
- package/dist/dev/ui/pip-button/pip-button-element.d.ts.map +1 -1
- package/dist/dev/ui/pip-button/pip-button-element.js +1 -0
- package/dist/dev/ui/pip-button/pip-button-element.js.map +1 -1
- package/dist/dev/ui/play-button/play-button-element.d.ts +1 -0
- package/dist/dev/ui/play-button/play-button-element.d.ts.map +1 -1
- package/dist/dev/ui/play-button/play-button-element.js +1 -0
- package/dist/dev/ui/play-button/play-button-element.js.map +1 -1
- package/dist/dev/ui/popover/popover-element.d.ts.map +1 -1
- package/dist/dev/ui/popover/popover-element.js +7 -55
- package/dist/dev/ui/popover/popover-element.js.map +1 -1
- package/dist/dev/ui/position-controller.js +76 -0
- package/dist/dev/ui/position-controller.js.map +1 -0
- package/dist/dev/ui/slider/slider-element.js +1 -1
- package/dist/dev/ui/slider/slider-preview-element.d.ts +21 -0
- package/dist/dev/ui/slider/slider-preview-element.d.ts.map +1 -0
- package/dist/dev/ui/slider/slider-preview-element.js +1 -1
- package/dist/dev/ui/time-slider/time-slider-element.d.ts +2 -2
- package/dist/dev/ui/time-slider/time-slider-element.js +5 -5
- package/dist/dev/ui/time-slider/time-slider-element.js.map +1 -1
- package/dist/dev/ui/tooltip/tooltip-element.d.ts.map +1 -1
- package/dist/dev/ui/tooltip/tooltip-element.js +8 -54
- package/dist/dev/ui/tooltip/tooltip-element.js.map +1 -1
- package/dist/dev/ui/volume-slider/volume-slider-element.js +1 -1
- package/package.json +8 -8
- package/cdn/context-BjrbhiSk.js.map +0 -1
- package/cdn/context-CdkhXQEw.js +0 -14
- package/cdn/context-CdkhXQEw.js.map +0 -1
- package/cdn/create-player-BqU8r8H4.js +0 -7
- package/cdn/create-player-BqU8r8H4.js.map +0 -1
- package/cdn/create-player-p9xCO0yC.js.map +0 -1
- package/cdn/delegate-B626t_Va.js +0 -2
- package/cdn/delegate-B626t_Va.js.map +0 -1
- package/cdn/delegate-BCw-LjP_.js +0 -56
- package/cdn/delegate-BCw-LjP_.js.map +0 -1
- package/cdn/media-props-mixin-Bd_N2HWy.js +0 -47
- package/cdn/media-props-mixin-Bd_N2HWy.js.map +0 -1
- package/cdn/media-props-mixin-Dc5dpCV4.js.map +0 -1
- package/cdn/minimal-ui-BL9eBXck.js +0 -0
- package/cdn/minimal-ui-a1UOKF79.js +0 -0
- package/cdn/native-hls-CjRvSXAJ.js +0 -2
- package/cdn/player-Cz9-_j7J.js +0 -2
- package/cdn/poster-2FPYTjyv.js +0 -2
- package/cdn/poster-2FPYTjyv.js.map +0 -1
- package/cdn/poster-gVT-J1-z.js +0 -215
- package/cdn/poster-gVT-J1-z.js.map +0 -1
- package/cdn/ui-CFIgmrlA.js +0 -0
- package/cdn/ui-Ccp_LyCf.js +0 -0
- package/cdn/volume-slider-Co5X4Z1t.js.map +0 -1
- package/cdn/volume-slider-D18sXnIA.js +0 -8
- package/cdn/volume-slider-D18sXnIA.js.map +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { A as ContextConsumer, C as isFunction, E as isUndefined, M as isEditableTarget, N as resolveEventTarget, O as MediaElement, S as AbortControllerRegistry, T as isNumber, b as noop, c as timeFeature, d as playbackRateFeature, f as playbackFeature, g as controlsFeature, h as errorFeature, k as ContextProvider, l as textTrackFeature, m as fullscreenFeature, n as PlayerController, p as pipFeature, r as SnapshotController, s as volumeFeature, u as sourceFeature, v as bufferFeature, w as isNull, x as throwNoTargetError, y as createState } from "./create-player-CyG77t-m.js";
|
|
2
|
+
import { t as listen } from "./listen-w-Aun0yN.js";
|
|
3
|
+
import { i as createContext, o as safeDefine, r as playerContext, t as containerContext } from "./context-CvJ83xGk.js";
|
|
3
4
|
|
|
4
5
|
//#region ../utils/dist/dom/direction.js
|
|
5
6
|
/** Check whether an element's text direction is right-to-left. */
|
|
@@ -10,21 +11,70 @@ function isRTL(element) {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
//#endregion
|
|
13
|
-
//#region ../utils/dist/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
14
|
+
//#region ../utils/dist/dom/supports.js
|
|
15
|
+
function supportsAnchorPositioning() {
|
|
16
|
+
return typeof CSS !== "undefined" && CSS.supports("anchor-name: --a");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region ../utils/dist/dom/platform.js
|
|
21
|
+
function isMacOS() {
|
|
22
|
+
return typeof navigator !== "undefined" && /mac/i.test(navigator.userAgent);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region ../utils/dist/dom/popover.js
|
|
27
|
+
function tryShowPopover(el) {
|
|
28
|
+
try {
|
|
29
|
+
el?.showPopover?.();
|
|
30
|
+
} catch {}
|
|
31
|
+
}
|
|
32
|
+
function tryHidePopover(el) {
|
|
33
|
+
try {
|
|
34
|
+
el?.hidePopover?.();
|
|
35
|
+
} catch {}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region ../utils/dist/string/casing.js
|
|
40
|
+
function kebabCase(str) {
|
|
41
|
+
return str.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region ../utils/dist/dom/style.js
|
|
46
|
+
function applyStyles(element, styles) {
|
|
47
|
+
for (const [prop, value] of Object.entries(styles)) if (typeof value === "string") {
|
|
48
|
+
const key = prop.startsWith("--") ? prop : kebabCase(prop);
|
|
49
|
+
element.style.setProperty(key, value);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function resolveCSSLength(el, value) {
|
|
53
|
+
const trimmed = value.trim();
|
|
54
|
+
if (!trimmed) return 0;
|
|
55
|
+
const parsed = Number.parseFloat(trimmed);
|
|
56
|
+
if (Number.isNaN(parsed)) return 0;
|
|
57
|
+
if (/^-?\d*\.?\d+$/.test(trimmed) || trimmed.endsWith("px")) return parsed;
|
|
58
|
+
const doc = el.ownerDocument;
|
|
59
|
+
const root = doc?.documentElement;
|
|
60
|
+
if (trimmed.endsWith("rem")) return parsed * (root ? Number.parseFloat(getComputedStyle(root).fontSize) || 16 : 16);
|
|
61
|
+
if (trimmed.endsWith("em")) return parsed * (el instanceof HTMLElement ? Number.parseFloat(getComputedStyle(el).fontSize) || 16 : 16);
|
|
62
|
+
if (!doc) return parsed;
|
|
63
|
+
const measurementEl = doc.createElement("div");
|
|
64
|
+
measurementEl.style.position = "absolute";
|
|
65
|
+
measurementEl.style.visibility = "hidden";
|
|
66
|
+
measurementEl.style.pointerEvents = "none";
|
|
67
|
+
measurementEl.style.inlineSize = trimmed;
|
|
68
|
+
measurementEl.style.blockSize = "0";
|
|
69
|
+
measurementEl.style.padding = "0";
|
|
70
|
+
measurementEl.style.border = "0";
|
|
71
|
+
measurementEl.style.inset = "0";
|
|
72
|
+
const parent = doc.body ?? doc.documentElement;
|
|
73
|
+
if (!parent) return parsed;
|
|
74
|
+
parent.appendChild(measurementEl);
|
|
75
|
+
const pixels = measurementEl.getBoundingClientRect().width;
|
|
76
|
+
measurementEl.remove();
|
|
77
|
+
return Number.isFinite(pixels) ? pixels : parsed;
|
|
28
78
|
}
|
|
29
79
|
|
|
30
80
|
//#endregion
|
|
@@ -86,100 +136,122 @@ const AlertDialogDataAttrs = {
|
|
|
86
136
|
};
|
|
87
137
|
|
|
88
138
|
//#endregion
|
|
89
|
-
//#region ../
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
this.state.patch({ visible: true });
|
|
106
|
-
}, this.#props.delay);
|
|
107
|
-
else if (!buffering) {
|
|
108
|
-
this.#clearTimer();
|
|
109
|
-
this.state.patch({ visible: false });
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
#clearTimer() {
|
|
113
|
-
if (this.#timer !== null) {
|
|
114
|
-
clearTimeout(this.#timer);
|
|
115
|
-
this.#timer = null;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
};
|
|
139
|
+
//#region ../utils/dist/object/defaults.js
|
|
140
|
+
/**
|
|
141
|
+
* Creates a new object with default values filled in for undefined properties.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```ts
|
|
145
|
+
* const props = { label: undefined, disabled: true };
|
|
146
|
+
* const defaultProps = { label: '', disabled: false };
|
|
147
|
+
* defaults(props, defaultProps); // { label: '', disabled: true }
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
function defaults(object, defaultValues) {
|
|
151
|
+
const result = { ...defaultValues };
|
|
152
|
+
for (const key in object) if (!isUndefined(object[key])) result[key] = object[key];
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
119
155
|
|
|
120
156
|
//#endregion
|
|
121
|
-
//#region ../
|
|
122
|
-
|
|
157
|
+
//#region ../utils/dist/object/pick.js
|
|
158
|
+
/**
|
|
159
|
+
* Creates a new object with only the specified keys.
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* const obj = { a: 1, b: 2, c: 3 };
|
|
163
|
+
* pick(obj, ['a', 'c']); // { a: 1, c: 3 }
|
|
164
|
+
*/
|
|
165
|
+
function pick(obj, keys) {
|
|
166
|
+
const result = {};
|
|
167
|
+
for (const key of keys) result[key] = obj[key];
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
123
170
|
|
|
124
171
|
//#endregion
|
|
125
|
-
//#region ../
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
state = createState({
|
|
132
|
-
subtitlesShowing: false,
|
|
133
|
-
availability: "unavailable",
|
|
134
|
-
label: ""
|
|
135
|
-
});
|
|
136
|
-
#props = { ...CaptionsButtonCore.defaultProps };
|
|
137
|
-
#media = null;
|
|
138
|
-
constructor(props) {
|
|
139
|
-
if (props) this.setProps(props);
|
|
140
|
-
}
|
|
141
|
-
setProps(props) {
|
|
142
|
-
this.#props = defaults(props, CaptionsButtonCore.defaultProps);
|
|
143
|
-
}
|
|
144
|
-
getLabel(state) {
|
|
145
|
-
const { label } = this.#props;
|
|
146
|
-
if (isFunction(label)) {
|
|
147
|
-
const customLabel = label(state);
|
|
148
|
-
if (customLabel) return customLabel;
|
|
149
|
-
} else if (label) return label;
|
|
150
|
-
return state.subtitlesShowing ? "Disable captions" : "Enable captions";
|
|
151
|
-
}
|
|
152
|
-
getAttrs(state) {
|
|
153
|
-
return {
|
|
154
|
-
"aria-label": this.getLabel(state),
|
|
155
|
-
"aria-disabled": this.#props.disabled ? "true" : void 0
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
setMedia(media) {
|
|
159
|
-
this.#media = media;
|
|
160
|
-
}
|
|
161
|
-
getState() {
|
|
162
|
-
const media = this.#media;
|
|
163
|
-
const availability = media.textTrackList.some((t) => t.kind === "captions" || t.kind === "subtitles") ? "available" : "unavailable";
|
|
164
|
-
this.state.patch({
|
|
165
|
-
subtitlesShowing: media.subtitlesShowing,
|
|
166
|
-
availability
|
|
167
|
-
});
|
|
168
|
-
this.state.patch({ label: this.getLabel(this.state.current) });
|
|
169
|
-
return this.state.current;
|
|
170
|
-
}
|
|
171
|
-
toggle(media) {
|
|
172
|
-
if (this.#props.disabled) return;
|
|
173
|
-
media.toggleSubtitles();
|
|
174
|
-
}
|
|
172
|
+
//#region ../store/dist/dev/core/selector.js
|
|
173
|
+
const stateContext = {
|
|
174
|
+
target: throwNoTargetError,
|
|
175
|
+
signals: new AbortControllerRegistry(),
|
|
176
|
+
get: throwNoTargetError,
|
|
177
|
+
set: throwNoTargetError
|
|
175
178
|
};
|
|
179
|
+
/**
|
|
180
|
+
* Create a type-safe selector for a slice's state.
|
|
181
|
+
*
|
|
182
|
+
* The selector returns the slice's state, or `undefined` if the slice
|
|
183
|
+
* is not configured in the store.
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```ts
|
|
187
|
+
* const selectPlayback = createSelector(playbackSlice);
|
|
188
|
+
* selectPlayback(store.state); // { paused, play, pause, ... } | undefined
|
|
189
|
+
* selectPlayback.displayName; // 'playback' (from slice name)
|
|
190
|
+
* ```
|
|
191
|
+
*
|
|
192
|
+
* @param slice - The slice to create a selector for.
|
|
193
|
+
*/
|
|
194
|
+
function createSelector(slice) {
|
|
195
|
+
const initialState = slice.state(stateContext);
|
|
196
|
+
const keys = Object.keys(initialState);
|
|
197
|
+
const firstKey = keys[0];
|
|
198
|
+
if (!firstKey) return Object.assign(() => void 0, { displayName: slice.name });
|
|
199
|
+
return Object.assign((state) => {
|
|
200
|
+
if (!(firstKey in state)) return void 0;
|
|
201
|
+
return pick(state, keys);
|
|
202
|
+
}, { displayName: slice.name });
|
|
203
|
+
}
|
|
176
204
|
|
|
177
205
|
//#endregion
|
|
178
|
-
//#region ../
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
206
|
+
//#region ../utils/dist/function/throttle.js
|
|
207
|
+
/**
|
|
208
|
+
* Throttle: limits `fn` to at most once per `ms` window.
|
|
209
|
+
*
|
|
210
|
+
* - Default (no options): trailing-edge only — the first call schedules a
|
|
211
|
+
* timer; subsequent calls within the window update the arguments. The
|
|
212
|
+
* function fires once per window with the latest arguments.
|
|
213
|
+
* - `{ leading: true }`: leading + trailing — the first call invokes
|
|
214
|
+
* immediately and opens a cooldown window. Subsequent calls within the
|
|
215
|
+
* window are coalesced to a single trailing-edge invocation.
|
|
216
|
+
*/
|
|
217
|
+
function throttle(fn, ms, options) {
|
|
218
|
+
const leading = options?.leading ?? false;
|
|
219
|
+
let timerId = null;
|
|
220
|
+
let latestArgs;
|
|
221
|
+
let hasPending = false;
|
|
222
|
+
function startCooldown() {
|
|
223
|
+
timerId = setTimeout(() => {
|
|
224
|
+
timerId = null;
|
|
225
|
+
if (hasPending) {
|
|
226
|
+
hasPending = false;
|
|
227
|
+
fn(...latestArgs);
|
|
228
|
+
startCooldown();
|
|
229
|
+
}
|
|
230
|
+
}, ms);
|
|
231
|
+
}
|
|
232
|
+
const throttled = (...args) => {
|
|
233
|
+
latestArgs = args;
|
|
234
|
+
if (leading) if (timerId === null) {
|
|
235
|
+
fn(...latestArgs);
|
|
236
|
+
startCooldown();
|
|
237
|
+
} else hasPending = true;
|
|
238
|
+
else {
|
|
239
|
+
if (timerId !== null) return;
|
|
240
|
+
timerId = setTimeout(() => {
|
|
241
|
+
timerId = null;
|
|
242
|
+
fn(...latestArgs);
|
|
243
|
+
}, ms);
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
throttled.cancel = () => {
|
|
247
|
+
if (timerId !== null) {
|
|
248
|
+
clearTimeout(timerId);
|
|
249
|
+
timerId = null;
|
|
250
|
+
}
|
|
251
|
+
hasPending = false;
|
|
252
|
+
};
|
|
253
|
+
return throttled;
|
|
254
|
+
}
|
|
183
255
|
|
|
184
256
|
//#endregion
|
|
185
257
|
//#region ../core/dist/dev/core/ui/controls/controls-core.js
|
|
@@ -211,69 +283,6 @@ var ErrorDialogCore = class extends AlertDialogCore {
|
|
|
211
283
|
setProps() {}
|
|
212
284
|
};
|
|
213
285
|
|
|
214
|
-
//#endregion
|
|
215
|
-
//#region ../core/dist/dev/core/ui/fullscreen-button/fullscreen-button-core.js
|
|
216
|
-
var FullscreenButtonCore = class FullscreenButtonCore {
|
|
217
|
-
static defaultProps = {
|
|
218
|
-
label: "",
|
|
219
|
-
disabled: false
|
|
220
|
-
};
|
|
221
|
-
state = createState({
|
|
222
|
-
fullscreen: false,
|
|
223
|
-
availability: "available",
|
|
224
|
-
label: ""
|
|
225
|
-
});
|
|
226
|
-
#props = { ...FullscreenButtonCore.defaultProps };
|
|
227
|
-
#media = null;
|
|
228
|
-
constructor(props) {
|
|
229
|
-
if (props) this.setProps(props);
|
|
230
|
-
}
|
|
231
|
-
setProps(props) {
|
|
232
|
-
this.#props = defaults(props, FullscreenButtonCore.defaultProps);
|
|
233
|
-
}
|
|
234
|
-
getLabel(state) {
|
|
235
|
-
const { label } = this.#props;
|
|
236
|
-
if (isFunction(label)) {
|
|
237
|
-
const customLabel = label(state);
|
|
238
|
-
if (customLabel) return customLabel;
|
|
239
|
-
} else if (label) return label;
|
|
240
|
-
return state.fullscreen ? "Exit fullscreen" : "Enter fullscreen";
|
|
241
|
-
}
|
|
242
|
-
getAttrs(state) {
|
|
243
|
-
return {
|
|
244
|
-
"aria-label": this.getLabel(state),
|
|
245
|
-
"aria-disabled": this.#props.disabled ? "true" : void 0
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
setMedia(media) {
|
|
249
|
-
this.#media = media;
|
|
250
|
-
}
|
|
251
|
-
getState() {
|
|
252
|
-
const media = this.#media;
|
|
253
|
-
this.state.patch({
|
|
254
|
-
fullscreen: media.fullscreen,
|
|
255
|
-
availability: media.fullscreenAvailability
|
|
256
|
-
});
|
|
257
|
-
this.state.patch({ label: this.getLabel(this.state.current) });
|
|
258
|
-
return this.state.current;
|
|
259
|
-
}
|
|
260
|
-
async toggle(media) {
|
|
261
|
-
if (this.#props.disabled) return;
|
|
262
|
-
if (media.fullscreenAvailability !== "available") return;
|
|
263
|
-
try {
|
|
264
|
-
if (media.fullscreen) await media.exitFullscreen();
|
|
265
|
-
else await media.requestFullscreen();
|
|
266
|
-
} catch {}
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
//#endregion
|
|
271
|
-
//#region ../core/dist/dev/core/ui/fullscreen-button/fullscreen-button-data-attrs.js
|
|
272
|
-
const FullscreenButtonDataAttrs = {
|
|
273
|
-
fullscreen: "data-fullscreen",
|
|
274
|
-
availability: "data-availability"
|
|
275
|
-
};
|
|
276
|
-
|
|
277
286
|
//#endregion
|
|
278
287
|
//#region ../core/dist/dev/core/ui/mute-button/mute-button-core.js
|
|
279
288
|
var MuteButtonCore = class MuteButtonCore {
|
|
@@ -339,69 +348,6 @@ const MuteButtonDataAttrs = {
|
|
|
339
348
|
volumeLevel: "data-volume-level"
|
|
340
349
|
};
|
|
341
350
|
|
|
342
|
-
//#endregion
|
|
343
|
-
//#region ../core/dist/dev/core/ui/pip-button/pip-button-core.js
|
|
344
|
-
var PiPButtonCore = class PiPButtonCore {
|
|
345
|
-
static defaultProps = {
|
|
346
|
-
label: "",
|
|
347
|
-
disabled: false
|
|
348
|
-
};
|
|
349
|
-
state = createState({
|
|
350
|
-
pip: false,
|
|
351
|
-
availability: "available",
|
|
352
|
-
label: ""
|
|
353
|
-
});
|
|
354
|
-
#props = { ...PiPButtonCore.defaultProps };
|
|
355
|
-
#media = null;
|
|
356
|
-
constructor(props) {
|
|
357
|
-
if (props) this.setProps(props);
|
|
358
|
-
}
|
|
359
|
-
setProps(props) {
|
|
360
|
-
this.#props = defaults(props, PiPButtonCore.defaultProps);
|
|
361
|
-
}
|
|
362
|
-
getLabel(state) {
|
|
363
|
-
const { label } = this.#props;
|
|
364
|
-
if (isFunction(label)) {
|
|
365
|
-
const customLabel = label(state);
|
|
366
|
-
if (customLabel) return customLabel;
|
|
367
|
-
} else if (label) return label;
|
|
368
|
-
return state.pip ? "Exit picture-in-picture" : "Enter picture-in-picture";
|
|
369
|
-
}
|
|
370
|
-
getAttrs(state) {
|
|
371
|
-
return {
|
|
372
|
-
"aria-label": this.getLabel(state),
|
|
373
|
-
"aria-disabled": this.#props.disabled ? "true" : void 0
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
setMedia(media) {
|
|
377
|
-
this.#media = media;
|
|
378
|
-
}
|
|
379
|
-
getState() {
|
|
380
|
-
const media = this.#media;
|
|
381
|
-
this.state.patch({
|
|
382
|
-
pip: media.pip,
|
|
383
|
-
availability: media.pipAvailability
|
|
384
|
-
});
|
|
385
|
-
this.state.patch({ label: this.getLabel(this.state.current) });
|
|
386
|
-
return this.state.current;
|
|
387
|
-
}
|
|
388
|
-
async toggle(media) {
|
|
389
|
-
if (this.#props.disabled) return;
|
|
390
|
-
if (media.pipAvailability !== "available") return;
|
|
391
|
-
try {
|
|
392
|
-
if (media.pip) await media.exitPictureInPicture();
|
|
393
|
-
else await media.requestPictureInPicture();
|
|
394
|
-
} catch {}
|
|
395
|
-
}
|
|
396
|
-
};
|
|
397
|
-
|
|
398
|
-
//#endregion
|
|
399
|
-
//#region ../core/dist/dev/core/ui/pip-button/pip-button-data-attrs.js
|
|
400
|
-
const PiPButtonDataAttrs = {
|
|
401
|
-
pip: "data-pip",
|
|
402
|
-
availability: "data-availability"
|
|
403
|
-
};
|
|
404
|
-
|
|
405
351
|
//#endregion
|
|
406
352
|
//#region ../core/dist/dev/core/ui/play-button/play-button-core.js
|
|
407
353
|
var PlayButtonCore = class PlayButtonCore {
|
|
@@ -575,6 +521,17 @@ var PopoverCore = class PopoverCore {
|
|
|
575
521
|
}
|
|
576
522
|
};
|
|
577
523
|
|
|
524
|
+
//#endregion
|
|
525
|
+
//#region ../core/dist/dev/core/ui/popover/popover-css-vars.js
|
|
526
|
+
const PopoverCSSVars = {
|
|
527
|
+
sideOffset: "--media-popover-side-offset",
|
|
528
|
+
alignOffset: "--media-popover-align-offset",
|
|
529
|
+
anchorWidth: "--media-popover-anchor-width",
|
|
530
|
+
anchorHeight: "--media-popover-anchor-height",
|
|
531
|
+
availableWidth: "--media-popover-available-width",
|
|
532
|
+
availableHeight: "--media-popover-available-height"
|
|
533
|
+
};
|
|
534
|
+
|
|
578
535
|
//#endregion
|
|
579
536
|
//#region ../core/dist/dev/core/ui/popover/popover-data-attrs.js
|
|
580
537
|
const PopoverDataAttrs = {
|
|
@@ -585,22 +542,6 @@ const PopoverDataAttrs = {
|
|
|
585
542
|
transitionEnding: "data-ending-style"
|
|
586
543
|
};
|
|
587
544
|
|
|
588
|
-
//#endregion
|
|
589
|
-
//#region ../core/dist/dev/core/ui/poster/poster-core.js
|
|
590
|
-
var PosterCore = class {
|
|
591
|
-
#media = null;
|
|
592
|
-
setMedia(media) {
|
|
593
|
-
this.#media = media;
|
|
594
|
-
}
|
|
595
|
-
getState() {
|
|
596
|
-
return { visible: !this.#media.started };
|
|
597
|
-
}
|
|
598
|
-
};
|
|
599
|
-
|
|
600
|
-
//#endregion
|
|
601
|
-
//#region ../core/dist/dev/core/ui/poster/poster-data-attrs.js
|
|
602
|
-
const PosterDataAttrs = { visible: "data-visible" };
|
|
603
|
-
|
|
604
545
|
//#endregion
|
|
605
546
|
//#region ../core/dist/dev/core/ui/seek-button/seek-button-core.js
|
|
606
547
|
var SeekButtonCore = class SeekButtonCore {
|
|
@@ -663,6 +604,19 @@ const SeekButtonDataAttrs = {
|
|
|
663
604
|
direction: "data-direction"
|
|
664
605
|
};
|
|
665
606
|
|
|
607
|
+
//#endregion
|
|
608
|
+
//#region ../utils/dist/number/number.js
|
|
609
|
+
/** Clamp a value between min and max (inclusive). */
|
|
610
|
+
function clamp(value, min, max) {
|
|
611
|
+
return Math.max(min, Math.min(max, value));
|
|
612
|
+
}
|
|
613
|
+
/** Snap a value to the nearest step, offset from min. */
|
|
614
|
+
function roundToStep(value, step, min) {
|
|
615
|
+
const nearest = Math.round((value - min) / step) * step + min;
|
|
616
|
+
const dot = `${step}`.indexOf(".");
|
|
617
|
+
return dot === -1 ? nearest : Number(nearest.toFixed(`${step}`.length - dot - 1));
|
|
618
|
+
}
|
|
619
|
+
|
|
666
620
|
//#endregion
|
|
667
621
|
//#region ../core/dist/dev/core/ui/slider/slider-core.js
|
|
668
622
|
/** Base slider logic: value mapping, ARIA attrs, and step calculations. */
|
|
@@ -773,6 +727,15 @@ var SliderCore = class SliderCore {
|
|
|
773
727
|
}
|
|
774
728
|
};
|
|
775
729
|
|
|
730
|
+
//#endregion
|
|
731
|
+
//#region ../core/dist/dev/core/ui/slider/slider-css-vars.js
|
|
732
|
+
/** CSS custom property names for slider visual state. */
|
|
733
|
+
const SliderCSSVars = {
|
|
734
|
+
fill: "--media-slider-fill",
|
|
735
|
+
pointer: "--media-slider-pointer",
|
|
736
|
+
buffer: "--media-slider-buffer"
|
|
737
|
+
};
|
|
738
|
+
|
|
776
739
|
//#endregion
|
|
777
740
|
//#region ../core/dist/dev/core/ui/slider/slider-data-attrs.js
|
|
778
741
|
const SliderDataAttrs = {
|
|
@@ -784,25 +747,117 @@ const SliderDataAttrs = {
|
|
|
784
747
|
};
|
|
785
748
|
|
|
786
749
|
//#endregion
|
|
787
|
-
//#region ../core/dist/dev/core/ui/thumbnail/thumbnail-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
750
|
+
//#region ../core/dist/dev/core/ui/thumbnail/thumbnail-core.js
|
|
751
|
+
var ThumbnailCore = class {
|
|
752
|
+
findActiveThumbnail(thumbnails, time) {
|
|
753
|
+
if (thumbnails.length === 0) return void 0;
|
|
754
|
+
let low = 0;
|
|
755
|
+
let high = thumbnails.length - 1;
|
|
756
|
+
let result;
|
|
757
|
+
while (low <= high) {
|
|
758
|
+
const mid = low + high >>> 1;
|
|
759
|
+
const image = thumbnails[mid];
|
|
760
|
+
if (time >= image.startTime) {
|
|
761
|
+
result = image;
|
|
762
|
+
low = mid + 1;
|
|
763
|
+
} else high = mid - 1;
|
|
764
|
+
}
|
|
765
|
+
return result;
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Parse CSS constraint strings into numeric `ThumbnailConstraints`.
|
|
769
|
+
*
|
|
770
|
+
* Accepts any object with string `minWidth`/`maxWidth`/`minHeight`/`maxHeight`
|
|
771
|
+
* properties — `CSSStyleDeclaration` satisfies this structurally.
|
|
772
|
+
*/
|
|
773
|
+
parseConstraints(raw) {
|
|
774
|
+
const minW = parseFloat(raw.minWidth);
|
|
775
|
+
const maxW = parseFloat(raw.maxWidth);
|
|
776
|
+
const minH = parseFloat(raw.minHeight);
|
|
777
|
+
const maxH = parseFloat(raw.maxHeight);
|
|
778
|
+
return {
|
|
779
|
+
minWidth: Number.isFinite(minW) ? minW : 0,
|
|
780
|
+
maxWidth: Number.isFinite(maxW) ? maxW : Infinity,
|
|
781
|
+
minHeight: Number.isFinite(minH) ? minH : 0,
|
|
782
|
+
maxHeight: Number.isFinite(maxH) ? maxH : Infinity
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
/**
|
|
786
|
+
* Calculate a uniform scale factor that fits `tileWidth × tileHeight` within the
|
|
787
|
+
* given CSS min/max constraints while preserving aspect ratio.
|
|
788
|
+
*
|
|
789
|
+
* - Scales down when the tile exceeds max constraints.
|
|
790
|
+
* - Scales up when the tile is smaller than min constraints.
|
|
791
|
+
* - Returns `1` when no scaling is needed.
|
|
792
|
+
*/
|
|
793
|
+
calculateScale(tileWidth, tileHeight, constraints) {
|
|
794
|
+
const { minWidth, maxWidth, minHeight, maxHeight } = constraints;
|
|
795
|
+
const maxRatio = Math.min(maxWidth / tileWidth, maxHeight / tileHeight);
|
|
796
|
+
const minRatio = Math.max(minWidth / tileWidth, minHeight / tileHeight);
|
|
797
|
+
if (Number.isFinite(maxRatio) && maxRatio < 1) return maxRatio;
|
|
798
|
+
if (Number.isFinite(minRatio) && minRatio > 1) return minRatio;
|
|
799
|
+
return 1;
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Compute container and image dimensions for the current thumbnail, scaled to
|
|
803
|
+
* fit within the element's CSS min/max constraints.
|
|
804
|
+
*
|
|
805
|
+
* The container clips the sprite sheet via `overflow: hidden`, and the image is
|
|
806
|
+
* positioned with `transform: translate()` to show the correct tile.
|
|
807
|
+
*/
|
|
808
|
+
resize(thumbnail, imgNaturalWidth, imgNaturalHeight, constraints) {
|
|
809
|
+
const tileWidth = thumbnail.width ?? imgNaturalWidth;
|
|
810
|
+
const tileHeight = thumbnail.height ?? imgNaturalHeight;
|
|
811
|
+
if (!tileWidth || !tileHeight) return void 0;
|
|
812
|
+
const scale = this.calculateScale(tileWidth, tileHeight, constraints);
|
|
813
|
+
const coordX = thumbnail.coords?.x ?? 0;
|
|
814
|
+
const coordY = thumbnail.coords?.y ?? 0;
|
|
815
|
+
const inset = scale !== 1 ? 1 : 0;
|
|
816
|
+
return {
|
|
817
|
+
scale,
|
|
818
|
+
containerWidth: Math.max(0, Math.floor(tileWidth * scale) - inset * 2),
|
|
819
|
+
containerHeight: Math.max(0, Math.floor(tileHeight * scale) - inset * 2),
|
|
820
|
+
imageWidth: Math.ceil(imgNaturalWidth * scale),
|
|
821
|
+
imageHeight: Math.ceil(imgNaturalHeight * scale),
|
|
822
|
+
offsetX: Math.ceil(coordX * scale) + inset,
|
|
823
|
+
offsetY: Math.ceil(coordY * scale) + inset
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
getState(loading, error, thumbnail) {
|
|
827
|
+
return {
|
|
828
|
+
loading,
|
|
829
|
+
error,
|
|
830
|
+
hidden: !loading && !thumbnail
|
|
831
|
+
};
|
|
832
|
+
}
|
|
833
|
+
getAttrs(_state) {
|
|
834
|
+
return {
|
|
835
|
+
role: "img",
|
|
836
|
+
"aria-hidden": "true"
|
|
837
|
+
};
|
|
838
|
+
}
|
|
839
|
+
};
|
|
840
|
+
|
|
841
|
+
//#endregion
|
|
842
|
+
//#region ../core/dist/dev/core/ui/thumbnail/thumbnail-data-attrs.js
|
|
843
|
+
const ThumbnailDataAttrs = {
|
|
844
|
+
loading: "data-loading",
|
|
845
|
+
error: "data-error",
|
|
846
|
+
hidden: "data-hidden"
|
|
847
|
+
};
|
|
848
|
+
|
|
849
|
+
//#endregion
|
|
850
|
+
//#region ../core/dist/dev/core/ui/thumbnail/thumbnail-media-fragment.js
|
|
851
|
+
/** Parse `url#xywh=x,y,w,h` into a URL and optional sprite coordinates. */
|
|
852
|
+
function parseMediaFragment(text, baseURL) {
|
|
853
|
+
const parts = text.trim().split("#");
|
|
854
|
+
const rawURL = parts[0] ?? "";
|
|
855
|
+
const hash = parts[1];
|
|
856
|
+
const url = baseURL ? new URL(rawURL, baseURL).href : rawURL;
|
|
857
|
+
if (!hash) return { url };
|
|
858
|
+
const eqIndex = hash.indexOf("=");
|
|
859
|
+
if (eqIndex === -1) return { url };
|
|
860
|
+
const keys = hash.slice(0, eqIndex);
|
|
806
861
|
const values = hash.slice(eqIndex + 1).split(",").map(Number);
|
|
807
862
|
const data = {};
|
|
808
863
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -1028,7 +1083,7 @@ var TimeSliderCore = class TimeSliderCore extends SliderCore {
|
|
|
1028
1083
|
static defaultProps = {
|
|
1029
1084
|
...SliderCore.defaultProps,
|
|
1030
1085
|
label: "Seek",
|
|
1031
|
-
|
|
1086
|
+
changeThrottle: 100
|
|
1032
1087
|
};
|
|
1033
1088
|
#props = { ...TimeSliderCore.defaultProps };
|
|
1034
1089
|
#media = null;
|
|
@@ -1048,14 +1103,12 @@ var TimeSliderCore = class TimeSliderCore extends SliderCore {
|
|
|
1048
1103
|
}
|
|
1049
1104
|
getState() {
|
|
1050
1105
|
const { duration, currentTime, seeking, buffered } = this.#media;
|
|
1051
|
-
const { dragging, dragPercent } = this.input;
|
|
1052
1106
|
super.setProps({
|
|
1053
1107
|
...this.#props,
|
|
1054
1108
|
min: 0,
|
|
1055
1109
|
max: duration
|
|
1056
1110
|
});
|
|
1057
|
-
const
|
|
1058
|
-
const base = super.getSliderState(value);
|
|
1111
|
+
const base = super.getSliderState(currentTime);
|
|
1059
1112
|
const bufferedEnd = buffered.length > 0 ? buffered[buffered.length - 1][1] : 0;
|
|
1060
1113
|
const bufferPercent = duration > 0 ? bufferedEnd / duration * 100 : 0;
|
|
1061
1114
|
return {
|
|
@@ -1071,11 +1124,13 @@ var TimeSliderCore = class TimeSliderCore extends SliderCore {
|
|
|
1071
1124
|
}
|
|
1072
1125
|
getAttrs(state) {
|
|
1073
1126
|
const base = super.getAttrs(state);
|
|
1074
|
-
const
|
|
1127
|
+
const announceValue = state.dragging ? this.rawValueFromPercent(state.pointerPercent) : state.value;
|
|
1128
|
+
const currentPhrase = formatTimeAsPhrase(announceValue);
|
|
1075
1129
|
const durationPhrase = formatTimeAsPhrase(state.duration);
|
|
1076
1130
|
const valuetext = durationPhrase ? `${currentPhrase} of ${durationPhrase}` : currentPhrase;
|
|
1077
1131
|
return {
|
|
1078
1132
|
...base,
|
|
1133
|
+
"aria-valuenow": announceValue,
|
|
1079
1134
|
"aria-valuetext": valuetext
|
|
1080
1135
|
};
|
|
1081
1136
|
}
|
|
@@ -1250,238 +1305,1490 @@ const VolumeSliderDataAttrs = {
|
|
|
1250
1305
|
};
|
|
1251
1306
|
|
|
1252
1307
|
//#endregion
|
|
1253
|
-
//#region
|
|
1254
|
-
/**
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1308
|
+
//#region ../core/dist/dev/dom/store/selectors.js
|
|
1309
|
+
/** Select the buffer state (buffered ranges, percent buffered). */
|
|
1310
|
+
const selectBuffer = createSelector(bufferFeature);
|
|
1311
|
+
/** Select the controls state (controls visible, user-active). */
|
|
1312
|
+
const selectControls = createSelector(controlsFeature);
|
|
1313
|
+
/** Select the error state (error, dismissed, dismissError). */
|
|
1314
|
+
const selectError = createSelector(errorFeature);
|
|
1315
|
+
/** Select the fullscreen state (fullscreen active, availability). */
|
|
1316
|
+
const selectFullscreen = createSelector(fullscreenFeature);
|
|
1317
|
+
/** Select the PiP state (picture-in-picture active, availability). */
|
|
1318
|
+
const selectPiP = createSelector(pipFeature);
|
|
1319
|
+
/** Select the playback state (paused, ended, play, pause, toggle). */
|
|
1320
|
+
const selectPlayback = createSelector(playbackFeature);
|
|
1321
|
+
/** Select the playback rate state (playbackRate, playbackRates, setPlaybackRate). */
|
|
1322
|
+
const selectPlaybackRate = createSelector(playbackRateFeature);
|
|
1323
|
+
/** Select the source state (src, type). */
|
|
1324
|
+
const selectSource = createSelector(sourceFeature);
|
|
1325
|
+
/** Select the text track state (chapters cues, thumbnail cues). */
|
|
1326
|
+
const selectTextTrack = createSelector(textTrackFeature);
|
|
1327
|
+
/** Select the time state (currentTime, duration, seek). */
|
|
1328
|
+
const selectTime = createSelector(timeFeature);
|
|
1329
|
+
/** Select the volume state (volume, muted, setVolume, setMuted). */
|
|
1330
|
+
const selectVolume = createSelector(volumeFeature);
|
|
1331
|
+
|
|
1332
|
+
//#endregion
|
|
1333
|
+
//#region ../core/dist/dev/dom/hotkey/aria.js
|
|
1334
|
+
const ARIA_MODIFIER_MAP = {
|
|
1335
|
+
shift: "Shift",
|
|
1336
|
+
ctrl: "Control",
|
|
1337
|
+
alt: "Alt",
|
|
1338
|
+
meta: "Meta"
|
|
1339
|
+
};
|
|
1340
|
+
const MODIFIER_ORDER = [
|
|
1341
|
+
"ctrl",
|
|
1342
|
+
"shift",
|
|
1343
|
+
"alt",
|
|
1344
|
+
"meta"
|
|
1345
|
+
];
|
|
1346
|
+
/**
|
|
1347
|
+
* Convert parsed key bindings to a WAI-ARIA `aria-keyshortcuts` formatted string.
|
|
1348
|
+
*
|
|
1349
|
+
* @example
|
|
1350
|
+
* ```ts
|
|
1351
|
+
* toAriaKeyShortcut(parseHotkeyPattern('Ctrl+Shift+f'));
|
|
1352
|
+
* // "Control+Shift+f"
|
|
1353
|
+
*
|
|
1354
|
+
* toAriaKeyShortcut([...parseHotkeyPattern('k'), ...parseHotkeyPattern('Space')]);
|
|
1355
|
+
* // "k Space"
|
|
1356
|
+
* ```
|
|
1357
|
+
*/
|
|
1358
|
+
function toAriaKeyShortcut(bindings) {
|
|
1359
|
+
return bindings.map((b) => {
|
|
1360
|
+
const parts = [];
|
|
1361
|
+
for (const mod of MODIFIER_ORDER) if (b.modifiers.has(mod)) parts.push(ARIA_MODIFIER_MAP[mod]);
|
|
1362
|
+
parts.push(b.originalKey);
|
|
1363
|
+
return parts.join("+");
|
|
1364
|
+
}).join(" ");
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
//#endregion
|
|
1368
|
+
//#region ../core/dist/dev/dom/hotkey/coordinator.js
|
|
1369
|
+
const ACTIVATION_KEYS = new Set([" ", "Enter"]);
|
|
1370
|
+
/** Whether the event is an activation key on an interactive element (button, slider). */
|
|
1371
|
+
function isInteractiveActivation(event) {
|
|
1372
|
+
if (!ACTIVATION_KEYS.has(event.key)) return false;
|
|
1373
|
+
const target = resolveEventTarget(event);
|
|
1374
|
+
if (!(target instanceof HTMLElement)) return false;
|
|
1375
|
+
if (target instanceof HTMLButtonElement) return true;
|
|
1376
|
+
const role = target.getAttribute("role");
|
|
1377
|
+
return role === "button" || role === "slider";
|
|
1378
|
+
}
|
|
1379
|
+
var HotkeyCoordinator = class {
|
|
1380
|
+
#target;
|
|
1381
|
+
#bindings = [];
|
|
1382
|
+
#nextId = 0;
|
|
1383
|
+
#disconnect = null;
|
|
1384
|
+
#docDisconnect = null;
|
|
1385
|
+
/** Action name → bound keys. Controls query this to set `aria-keyshortcuts`. */
|
|
1386
|
+
#ariaRegistry = /* @__PURE__ */ new Map();
|
|
1387
|
+
#destroyed = false;
|
|
1388
|
+
constructor(target) {
|
|
1389
|
+
this.#target = target;
|
|
1390
|
+
}
|
|
1391
|
+
add(options) {
|
|
1392
|
+
const parsed = parseHotkeyPattern(options.keys);
|
|
1393
|
+
const binding = {
|
|
1394
|
+
parsed,
|
|
1395
|
+
options,
|
|
1396
|
+
id: this.#nextId++
|
|
1397
|
+
};
|
|
1398
|
+
this.#bindings.push(binding);
|
|
1399
|
+
this.#sortBindings();
|
|
1400
|
+
if (options.action) this.#addToAriaRegistry(options.action, parsed);
|
|
1401
|
+
if (options.target === "document") this.#connectDocument();
|
|
1402
|
+
else this.#connect();
|
|
1403
|
+
let removed = false;
|
|
1404
|
+
return () => {
|
|
1405
|
+
if (removed) return;
|
|
1406
|
+
removed = true;
|
|
1407
|
+
const idx = this.#bindings.indexOf(binding);
|
|
1408
|
+
if (idx !== -1) this.#bindings.splice(idx, 1);
|
|
1409
|
+
if (options.action) this.#removeFromAriaRegistry(options.action, parsed);
|
|
1410
|
+
this.#maybeDisconnect();
|
|
1265
1411
|
};
|
|
1266
1412
|
}
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
connectedCallback() {
|
|
1272
|
-
super.connectedCallback();
|
|
1273
|
-
this.#disconnect = new AbortController();
|
|
1274
|
-
const buttonProps = createButton({
|
|
1275
|
-
onActivate: () => this.activate(this.mediaState.value),
|
|
1276
|
-
isDisabled: () => this.disabled || !this.mediaState.value
|
|
1277
|
-
});
|
|
1278
|
-
applyElementProps(this, buttonProps, { signal: this.#disconnect.signal });
|
|
1279
|
-
if (!this.mediaState.value && this.mediaState.displayName) logMissingFeature(this.localName, this.mediaState.displayName);
|
|
1413
|
+
getAriaKeys(action) {
|
|
1414
|
+
const bindings = this.#ariaRegistry.get(action);
|
|
1415
|
+
if (!bindings?.length) return void 0;
|
|
1416
|
+
return toAriaKeyShortcut(bindings);
|
|
1280
1417
|
}
|
|
1281
|
-
|
|
1282
|
-
|
|
1418
|
+
destroy() {
|
|
1419
|
+
if (this.#destroyed) return;
|
|
1420
|
+
this.#destroyed = true;
|
|
1283
1421
|
this.#disconnect?.abort();
|
|
1284
1422
|
this.#disconnect = null;
|
|
1423
|
+
this.#docDisconnect?.abort();
|
|
1424
|
+
this.#docDisconnect = null;
|
|
1425
|
+
this.#bindings = [];
|
|
1426
|
+
this.#ariaRegistry.clear();
|
|
1427
|
+
}
|
|
1428
|
+
#sortBindings() {
|
|
1429
|
+
this.#bindings.sort((a, b) => {
|
|
1430
|
+
const specDiff = b.parsed[0].modifiers.size - a.parsed[0].modifiers.size;
|
|
1431
|
+
if (specDiff !== 0) return specDiff;
|
|
1432
|
+
return a.id - b.id;
|
|
1433
|
+
});
|
|
1285
1434
|
}
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1435
|
+
#connect() {
|
|
1436
|
+
if (this.#disconnect) return;
|
|
1437
|
+
this.#disconnect = new AbortController();
|
|
1438
|
+
listen(this.#target, "keydown", this.#handleEvent, { signal: this.#disconnect.signal });
|
|
1439
|
+
}
|
|
1440
|
+
#connectDocument() {
|
|
1441
|
+
if (this.#docDisconnect) return;
|
|
1442
|
+
this.#docDisconnect = new AbortController();
|
|
1443
|
+
listen(document, "keydown", this.#handleEvent, { signal: this.#docDisconnect.signal });
|
|
1444
|
+
}
|
|
1445
|
+
#maybeDisconnect() {
|
|
1446
|
+
const hasPlayer = this.#bindings.some((b) => b.options.target !== "document");
|
|
1447
|
+
const hasDoc = this.#bindings.some((b) => b.options.target === "document");
|
|
1448
|
+
if (!hasPlayer) {
|
|
1449
|
+
this.#disconnect?.abort();
|
|
1450
|
+
this.#disconnect = null;
|
|
1451
|
+
}
|
|
1452
|
+
if (!hasDoc) {
|
|
1453
|
+
this.#docDisconnect?.abort();
|
|
1454
|
+
this.#docDisconnect = null;
|
|
1455
|
+
}
|
|
1289
1456
|
}
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1457
|
+
#handleEvent = (event) => {
|
|
1458
|
+
if (event.key === "Unidentified") return;
|
|
1459
|
+
if (isInteractiveActivation(event)) return;
|
|
1460
|
+
const editable = isEditableTarget(event);
|
|
1461
|
+
for (const binding of this.#bindings) {
|
|
1462
|
+
const { options, parsed } = binding;
|
|
1463
|
+
if (options.disabled) continue;
|
|
1464
|
+
if (event.repeat && options.repeatable === false) continue;
|
|
1465
|
+
if (options.target === "document" !== (event.currentTarget === document)) continue;
|
|
1466
|
+
for (const p of parsed) {
|
|
1467
|
+
if (!matchesHotkeyEvent(p, event)) continue;
|
|
1468
|
+
if (editable && p.modifiers.size === 0) continue;
|
|
1469
|
+
event.preventDefault();
|
|
1470
|
+
options.onActivate(event, p.originalKey);
|
|
1471
|
+
return;
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
};
|
|
1475
|
+
#addToAriaRegistry(action, bindings) {
|
|
1476
|
+
let existing = this.#ariaRegistry.get(action);
|
|
1477
|
+
if (!existing) {
|
|
1478
|
+
existing = [];
|
|
1479
|
+
this.#ariaRegistry.set(action, existing);
|
|
1480
|
+
}
|
|
1481
|
+
existing.push(...bindings);
|
|
1293
1482
|
}
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
this.
|
|
1299
|
-
|
|
1300
|
-
applyElementProps(this, this.core.getAttrs?.(state) ?? {});
|
|
1301
|
-
applyStateDataAttrs(this, state, this.stateAttrMap);
|
|
1483
|
+
#removeFromAriaRegistry(action, bindings) {
|
|
1484
|
+
const existing = this.#ariaRegistry.get(action);
|
|
1485
|
+
if (!existing) return;
|
|
1486
|
+
const filtered = existing.filter((b) => !bindings.includes(b));
|
|
1487
|
+
if (filtered.length === 0) this.#ariaRegistry.delete(action);
|
|
1488
|
+
else this.#ariaRegistry.set(action, filtered);
|
|
1302
1489
|
}
|
|
1303
1490
|
};
|
|
1304
1491
|
|
|
1305
1492
|
//#endregion
|
|
1306
|
-
//#region
|
|
1493
|
+
//#region ../core/dist/dev/dom/hotkey/hotkey.js
|
|
1494
|
+
const MODIFIER_KEYS = new Set([
|
|
1495
|
+
"shift",
|
|
1496
|
+
"ctrl",
|
|
1497
|
+
"alt",
|
|
1498
|
+
"meta"
|
|
1499
|
+
]);
|
|
1307
1500
|
/**
|
|
1308
|
-
*
|
|
1309
|
-
* context and apply data attributes from `ctx.state` + `ctx.stateAttrMap`.
|
|
1310
|
-
*
|
|
1311
|
-
* Subclasses only need to declare the `consumer` property:
|
|
1501
|
+
* Parse a key pattern string into one or more bindings.
|
|
1312
1502
|
*
|
|
1503
|
+
* @example
|
|
1313
1504
|
* ```ts
|
|
1314
|
-
*
|
|
1315
|
-
*
|
|
1316
|
-
*
|
|
1317
|
-
*
|
|
1505
|
+
* parseHotkeyPattern('>');
|
|
1506
|
+
* // [{ modifiers: Set(), key: '>', originalKey: '>' }]
|
|
1507
|
+
*
|
|
1508
|
+
* parseHotkeyPattern('0-9');
|
|
1509
|
+
* // 10 bindings, one per digit
|
|
1318
1510
|
* ```
|
|
1319
1511
|
*/
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1512
|
+
function parseHotkeyPattern(pattern) {
|
|
1513
|
+
if (pattern === "0-9") return Array.from({ length: 10 }, (_, i) => ({
|
|
1514
|
+
modifiers: /* @__PURE__ */ new Set(),
|
|
1515
|
+
key: String(i),
|
|
1516
|
+
originalKey: String(i)
|
|
1517
|
+
}));
|
|
1518
|
+
const segments = pattern.split("+");
|
|
1519
|
+
const rawKey = segments.pop();
|
|
1520
|
+
const modifiers = /* @__PURE__ */ new Set();
|
|
1521
|
+
for (const seg of segments) {
|
|
1522
|
+
const lower = seg.toLowerCase();
|
|
1523
|
+
if (lower === "mod") modifiers.add(isMacOS() ? "meta" : "ctrl");
|
|
1524
|
+
else if (MODIFIER_KEYS.has(lower)) modifiers.add(lower);
|
|
1525
|
+
else console.warn(`[vjs-hotkey] Unknown modifier: "${seg}" in pattern "${pattern}"`);
|
|
1526
|
+
}
|
|
1527
|
+
return [{
|
|
1528
|
+
modifiers,
|
|
1529
|
+
key: rawKey === "Space" ? " " : rawKey.toLowerCase(),
|
|
1530
|
+
originalKey: rawKey
|
|
1531
|
+
}];
|
|
1532
|
+
}
|
|
1533
|
+
/**
|
|
1534
|
+
* Single non-letter character — layout-dependent modifiers (Shift, Alt/Option)
|
|
1535
|
+
* were used to produce the character itself, not as deliberate modifiers
|
|
1536
|
+
* (e.g. Shift+. → ">", Option+Shift → ">" on some Mac layouts).
|
|
1537
|
+
* Letters excluded because Shift changes case intentionally (k vs K).
|
|
1538
|
+
* Named keys excluded because event.key.length > 1 (ArrowLeft, Tab, etc.).
|
|
1539
|
+
*/
|
|
1540
|
+
function isImplicitModifierKey(key) {
|
|
1541
|
+
return key.length === 1 && !/[a-z]/i.test(key);
|
|
1542
|
+
}
|
|
1543
|
+
/** Whether a parsed binding matches a keyboard event. */
|
|
1544
|
+
function matchesHotkeyEvent(binding, event) {
|
|
1545
|
+
if (event.key === "Unidentified") return false;
|
|
1546
|
+
if (event.key.toLowerCase() !== binding.key) return false;
|
|
1547
|
+
const implicit = isImplicitModifierKey(event.key);
|
|
1548
|
+
const shiftKey = implicit ? event.shiftKey && binding.modifiers.has("shift") : event.shiftKey;
|
|
1549
|
+
const altKey = implicit ? event.altKey && binding.modifiers.has("alt") : event.altKey;
|
|
1550
|
+
if (shiftKey !== binding.modifiers.has("shift")) return false;
|
|
1551
|
+
if (event.ctrlKey !== binding.modifiers.has("ctrl")) return false;
|
|
1552
|
+
if (altKey !== binding.modifiers.has("alt")) return false;
|
|
1553
|
+
if (event.metaKey !== binding.modifiers.has("meta")) return false;
|
|
1554
|
+
return true;
|
|
1555
|
+
}
|
|
1556
|
+
const coordinators = /* @__PURE__ */ new WeakMap();
|
|
1557
|
+
/** Look up the coordinator for a target element, if one exists. */
|
|
1558
|
+
function findHotkeyCoordinator(target) {
|
|
1559
|
+
return coordinators.get(target);
|
|
1560
|
+
}
|
|
1561
|
+
function getCoordinator(target) {
|
|
1562
|
+
let coordinator = coordinators.get(target);
|
|
1563
|
+
if (!coordinator) {
|
|
1564
|
+
coordinator = new HotkeyCoordinator(target);
|
|
1565
|
+
coordinators.set(target, coordinator);
|
|
1325
1566
|
}
|
|
1326
|
-
|
|
1567
|
+
return coordinator;
|
|
1568
|
+
}
|
|
1569
|
+
/**
|
|
1570
|
+
* Register a hotkey binding on a target element.
|
|
1571
|
+
*
|
|
1572
|
+
* @example
|
|
1573
|
+
* ```ts
|
|
1574
|
+
* const cleanup = createHotkey(container, {
|
|
1575
|
+
* keys: 'k',
|
|
1576
|
+
* onActivate: () => store.paused ? store.play() : store.pause(),
|
|
1577
|
+
* });
|
|
1578
|
+
*
|
|
1579
|
+
* // Later: remove the binding
|
|
1580
|
+
* cleanup();
|
|
1581
|
+
* ```
|
|
1582
|
+
*
|
|
1583
|
+
* @returns A cleanup function that removes the binding.
|
|
1584
|
+
*/
|
|
1585
|
+
function createHotkey(target, options) {
|
|
1586
|
+
return getCoordinator(target).add(options);
|
|
1587
|
+
}
|
|
1327
1588
|
|
|
1328
1589
|
//#endregion
|
|
1329
|
-
//#region
|
|
1330
|
-
|
|
1331
|
-
const
|
|
1590
|
+
//#region ../core/dist/dev/dom/ui/dismiss-layer.js
|
|
1591
|
+
function createDismissLayer(options) {
|
|
1592
|
+
const { transition } = options;
|
|
1593
|
+
const state = transition.state;
|
|
1594
|
+
const abort = new AbortController();
|
|
1595
|
+
let docAbort = null;
|
|
1596
|
+
function open() {
|
|
1597
|
+
if (abort.signal.aborted) return null;
|
|
1598
|
+
const { active, status } = state.current;
|
|
1599
|
+
if (active && status !== "ending") return null;
|
|
1600
|
+
if (status === "ending") transition.cancel();
|
|
1601
|
+
return transition.open();
|
|
1602
|
+
}
|
|
1603
|
+
function close(element) {
|
|
1604
|
+
const { active, status } = state.current;
|
|
1605
|
+
if (abort.signal.aborted || !active || status === "ending") return null;
|
|
1606
|
+
return transition.close(element);
|
|
1607
|
+
}
|
|
1608
|
+
function setupDocumentListeners() {
|
|
1609
|
+
cleanupDocumentListeners();
|
|
1610
|
+
if (typeof document === "undefined") return;
|
|
1611
|
+
docAbort = new AbortController();
|
|
1612
|
+
const { signal } = docAbort;
|
|
1613
|
+
listen(document, "keydown", handleKeydown, { signal });
|
|
1614
|
+
options.onDocumentActive?.(signal);
|
|
1615
|
+
}
|
|
1616
|
+
function cleanupDocumentListeners() {
|
|
1617
|
+
docAbort?.abort();
|
|
1618
|
+
docAbort = null;
|
|
1619
|
+
}
|
|
1620
|
+
function handleKeydown(event) {
|
|
1621
|
+
if (event.key !== "Escape") return;
|
|
1622
|
+
if (!state.current.active) return;
|
|
1623
|
+
if (!(options.closeOnEscape?.() ?? true)) return;
|
|
1624
|
+
options.onEscapeDismiss(event);
|
|
1625
|
+
}
|
|
1626
|
+
const unsubscribe = state.subscribe(() => {
|
|
1627
|
+
if (state.current.active) setupDocumentListeners();
|
|
1628
|
+
else cleanupDocumentListeners();
|
|
1629
|
+
});
|
|
1630
|
+
abort.signal.addEventListener("abort", () => {
|
|
1631
|
+
unsubscribe();
|
|
1632
|
+
transition.destroy();
|
|
1633
|
+
cleanupDocumentListeners();
|
|
1634
|
+
});
|
|
1635
|
+
function destroy() {
|
|
1636
|
+
if (abort.signal.aborted) return;
|
|
1637
|
+
abort.abort();
|
|
1638
|
+
}
|
|
1639
|
+
return {
|
|
1640
|
+
input: state,
|
|
1641
|
+
open,
|
|
1642
|
+
close,
|
|
1643
|
+
signal: abort.signal,
|
|
1644
|
+
destroy
|
|
1645
|
+
};
|
|
1646
|
+
}
|
|
1332
1647
|
|
|
1333
1648
|
//#endregion
|
|
1334
|
-
//#region
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1649
|
+
//#region ../core/dist/dev/dom/ui/alert-dialog.js
|
|
1650
|
+
function createAlertDialog(options) {
|
|
1651
|
+
const { onOpenChange } = options;
|
|
1652
|
+
let element = null;
|
|
1653
|
+
let previousFocus = null;
|
|
1654
|
+
let elementAbort = null;
|
|
1655
|
+
const layer = createDismissLayer({
|
|
1656
|
+
transition: options.transition,
|
|
1657
|
+
closeOnEscape: options.closeOnEscape,
|
|
1658
|
+
onEscapeDismiss(event) {
|
|
1659
|
+
event.stopPropagation();
|
|
1660
|
+
applyClose();
|
|
1661
|
+
}
|
|
1662
|
+
});
|
|
1663
|
+
const state = layer.input;
|
|
1664
|
+
function applyOpen() {
|
|
1665
|
+
previousFocus = document.activeElement;
|
|
1666
|
+
const opening = layer.open();
|
|
1667
|
+
if (!opening) return;
|
|
1668
|
+
onOpenChange(true);
|
|
1669
|
+
requestAnimationFrame(() => {
|
|
1670
|
+
if (layer.signal.aborted || !state.current.active) return;
|
|
1671
|
+
element?.focus();
|
|
1672
|
+
});
|
|
1673
|
+
opening.then(() => {
|
|
1674
|
+
if (layer.signal.aborted || !state.current.active) return;
|
|
1675
|
+
options.onOpenChangeComplete?.(true);
|
|
1676
|
+
});
|
|
1339
1677
|
}
|
|
1340
|
-
|
|
1341
|
-
|
|
1678
|
+
function applyClose() {
|
|
1679
|
+
const closing = layer.close(element);
|
|
1680
|
+
if (!closing) return;
|
|
1681
|
+
onOpenChange(false);
|
|
1682
|
+
closing.then(() => {
|
|
1683
|
+
if (layer.signal.aborted) return;
|
|
1684
|
+
if (previousFocus) {
|
|
1685
|
+
previousFocus.focus();
|
|
1686
|
+
previousFocus = null;
|
|
1687
|
+
}
|
|
1688
|
+
options.onOpenChangeComplete?.(false);
|
|
1689
|
+
});
|
|
1342
1690
|
}
|
|
1343
|
-
|
|
1344
|
-
|
|
1691
|
+
function setupElementListeners() {
|
|
1692
|
+
cleanupElementListeners();
|
|
1693
|
+
if (!element) return;
|
|
1694
|
+
elementAbort = new AbortController();
|
|
1695
|
+
const { signal } = elementAbort;
|
|
1696
|
+
listen(element, "click", handleElementClick, { signal });
|
|
1345
1697
|
}
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
});
|
|
1350
|
-
#disconnect = null;
|
|
1351
|
-
connectedCallback() {
|
|
1352
|
-
super.connectedCallback();
|
|
1353
|
-
this.#disconnect = new AbortController();
|
|
1354
|
-
const buttonProps = createButton({
|
|
1355
|
-
onActivate: () => this.#ctx.value?.close(),
|
|
1356
|
-
isDisabled: () => this.disabled
|
|
1357
|
-
});
|
|
1358
|
-
applyElementProps(this, buttonProps, { signal: this.#disconnect.signal });
|
|
1698
|
+
function cleanupElementListeners() {
|
|
1699
|
+
elementAbort?.abort();
|
|
1700
|
+
elementAbort = null;
|
|
1359
1701
|
}
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
this.#disconnect?.abort();
|
|
1363
|
-
this.#disconnect = null;
|
|
1702
|
+
function handleElementClick(event) {
|
|
1703
|
+
if (event.target instanceof HTMLButtonElement) applyClose();
|
|
1364
1704
|
}
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
if (ctx) applyStateDataAttrs(this, ctx.state, ctx.stateAttrMap);
|
|
1705
|
+
function setElement(el) {
|
|
1706
|
+
element = el;
|
|
1707
|
+
setupElementListeners();
|
|
1369
1708
|
}
|
|
1370
|
-
|
|
1709
|
+
layer.signal.addEventListener("abort", () => {
|
|
1710
|
+
cleanupElementListeners();
|
|
1711
|
+
element = null;
|
|
1712
|
+
previousFocus = null;
|
|
1713
|
+
});
|
|
1714
|
+
return {
|
|
1715
|
+
input: state,
|
|
1716
|
+
open: applyOpen,
|
|
1717
|
+
close: applyClose,
|
|
1718
|
+
setElement,
|
|
1719
|
+
destroy: layer.destroy
|
|
1720
|
+
};
|
|
1721
|
+
}
|
|
1371
1722
|
|
|
1372
1723
|
//#endregion
|
|
1373
|
-
//#region
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1724
|
+
//#region ../core/dist/dev/dom/ui/button.js
|
|
1725
|
+
function createButton(options) {
|
|
1726
|
+
const { onActivate, isDisabled } = options;
|
|
1727
|
+
return {
|
|
1728
|
+
role: "button",
|
|
1729
|
+
tabIndex: 0,
|
|
1730
|
+
onClick(event) {
|
|
1731
|
+
if (isDisabled()) {
|
|
1732
|
+
event.preventDefault();
|
|
1733
|
+
return;
|
|
1734
|
+
}
|
|
1735
|
+
onActivate();
|
|
1736
|
+
},
|
|
1737
|
+
onPointerDown(event) {
|
|
1738
|
+
if (isDisabled()) event.preventDefault();
|
|
1739
|
+
},
|
|
1740
|
+
onMouseDown(event) {
|
|
1741
|
+
if (isDisabled()) event.preventDefault();
|
|
1742
|
+
},
|
|
1743
|
+
onKeyDown(event) {
|
|
1744
|
+
if (event.target !== event.currentTarget) return;
|
|
1745
|
+
if (isDisabled()) {
|
|
1746
|
+
if (event.key !== "Tab") event.preventDefault();
|
|
1747
|
+
return;
|
|
1748
|
+
}
|
|
1749
|
+
if (event.key === "Enter") {
|
|
1750
|
+
event.preventDefault();
|
|
1751
|
+
onActivate();
|
|
1752
|
+
} else if (event.key === " ") event.preventDefault();
|
|
1753
|
+
},
|
|
1754
|
+
onKeyUp(event) {
|
|
1755
|
+
if (event.target !== event.currentTarget) return;
|
|
1756
|
+
if (isDisabled()) return;
|
|
1757
|
+
if (event.key === " ") onActivate();
|
|
1758
|
+
}
|
|
1759
|
+
};
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
//#endregion
|
|
1763
|
+
//#region ../core/dist/dev/dom/ui/popover/popover.js
|
|
1764
|
+
function createPopover(options) {
|
|
1765
|
+
const { onOpenChange, closeOnOutsideClick } = options;
|
|
1766
|
+
let triggerEl = null;
|
|
1767
|
+
let popupEl = null;
|
|
1768
|
+
let hoverTimeout = null;
|
|
1769
|
+
const capturedPointers = /* @__PURE__ */ new Set();
|
|
1770
|
+
const layer = createDismissLayer({
|
|
1771
|
+
transition: options.transition,
|
|
1772
|
+
closeOnEscape: options.closeOnEscape,
|
|
1773
|
+
onEscapeDismiss(event) {
|
|
1774
|
+
event.preventDefault();
|
|
1775
|
+
applyClose("escape", event);
|
|
1776
|
+
},
|
|
1777
|
+
onDocumentActive(signal) {
|
|
1778
|
+
listen(document, "pointerdown", handleDocumentPointerdown, {
|
|
1779
|
+
capture: true,
|
|
1780
|
+
signal
|
|
1781
|
+
});
|
|
1782
|
+
}
|
|
1783
|
+
});
|
|
1784
|
+
const state = layer.input;
|
|
1785
|
+
function clearHoverTimeout() {
|
|
1786
|
+
if (hoverTimeout !== null) {
|
|
1787
|
+
clearTimeout(hoverTimeout);
|
|
1788
|
+
hoverTimeout = null;
|
|
1789
|
+
}
|
|
1381
1790
|
}
|
|
1382
|
-
|
|
1383
|
-
|
|
1791
|
+
function canHover() {
|
|
1792
|
+
return globalThis.matchMedia?.("(hover: hover)")?.matches ?? false;
|
|
1384
1793
|
}
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
if (descriptionId) this.id = descriptionId;
|
|
1794
|
+
function canOpenOnFocus() {
|
|
1795
|
+
if (!canHover()) return false;
|
|
1796
|
+
return globalThis.matchMedia?.("(pointer: fine)")?.matches ?? false;
|
|
1389
1797
|
}
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1798
|
+
function canToggleOnClick() {
|
|
1799
|
+
if (!options.openOnHover?.()) return true;
|
|
1800
|
+
return canHover();
|
|
1801
|
+
}
|
|
1802
|
+
/**
|
|
1803
|
+
* The transition handler manages animation lifecycle via `createState`:
|
|
1804
|
+
*
|
|
1805
|
+
* **Open:** `transition.open()` patches `{ active: true, status: 'starting' }`.
|
|
1806
|
+
* After one RAF it patches `{ status: 'idle' }` and the promise resolves.
|
|
1807
|
+
* Frameworks render `data-starting-style` / `data-ending-style` via
|
|
1808
|
+
* `getPopupAttrs(state)` — no imperative DOM mutation needed.
|
|
1809
|
+
*
|
|
1810
|
+
* **Close:** `transition.close(el)` patches `{ status: 'ending' }` (keeping
|
|
1811
|
+
* `active: true` so the element stays mounted). After a double-RAF it waits
|
|
1812
|
+
* for `getAnimations()` to settle, then patches `{ active: false, status: 'idle' }`.
|
|
1813
|
+
*
|
|
1814
|
+
* `onOpenChange` fires immediately (before animations).
|
|
1815
|
+
* `onOpenChangeComplete` fires after animations finish.
|
|
1816
|
+
*/
|
|
1817
|
+
function applyOpen(reason, event) {
|
|
1818
|
+
const opening = layer.open();
|
|
1819
|
+
if (!opening) return;
|
|
1820
|
+
onOpenChange(true, event ? {
|
|
1821
|
+
reason,
|
|
1822
|
+
event
|
|
1823
|
+
} : { reason });
|
|
1824
|
+
opening.then(() => {
|
|
1825
|
+
if (layer.signal.aborted || !state.current.active) return;
|
|
1826
|
+
options.onOpenChangeComplete?.(true);
|
|
1400
1827
|
});
|
|
1401
1828
|
}
|
|
1402
|
-
|
|
1403
|
-
|
|
1829
|
+
function applyClose(reason, event) {
|
|
1830
|
+
const closing = layer.close(popupEl);
|
|
1831
|
+
if (!closing) return;
|
|
1832
|
+
onOpenChange(false, event ? {
|
|
1833
|
+
reason,
|
|
1834
|
+
event
|
|
1835
|
+
} : { reason });
|
|
1836
|
+
closing.then(() => {
|
|
1837
|
+
if (layer.signal.aborted) return;
|
|
1838
|
+
tryHidePopover(popupEl);
|
|
1839
|
+
options.onOpenChangeComplete?.(false);
|
|
1840
|
+
});
|
|
1404
1841
|
}
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
const titleId = this.consumer.value?.state.titleId;
|
|
1408
|
-
if (titleId) this.id = titleId;
|
|
1842
|
+
function open(reason = "click") {
|
|
1843
|
+
applyOpen(reason);
|
|
1409
1844
|
}
|
|
1410
|
-
|
|
1845
|
+
function close(reason = "click") {
|
|
1846
|
+
applyClose(reason);
|
|
1847
|
+
}
|
|
1848
|
+
function handleDocumentPointerdown(event) {
|
|
1849
|
+
if (!closeOnOutsideClick() || !state.current.active) return;
|
|
1850
|
+
const path = event.composedPath();
|
|
1851
|
+
if (triggerEl && path.includes(triggerEl) || popupEl && path.includes(popupEl)) return;
|
|
1852
|
+
applyClose("outside-click", event);
|
|
1853
|
+
}
|
|
1854
|
+
layer.signal.addEventListener("abort", () => {
|
|
1855
|
+
clearHoverTimeout();
|
|
1856
|
+
capturedPointers.clear();
|
|
1857
|
+
triggerEl = null;
|
|
1858
|
+
popupEl = null;
|
|
1859
|
+
});
|
|
1860
|
+
const triggerProps = {
|
|
1861
|
+
onClick(event) {
|
|
1862
|
+
if (!canToggleOnClick()) return;
|
|
1863
|
+
if (state.current.active && state.current.status !== "ending") applyClose("click", event);
|
|
1864
|
+
else applyOpen("click", event);
|
|
1865
|
+
},
|
|
1866
|
+
onPointerEnter(_event) {
|
|
1867
|
+
if (!options.openOnHover?.()) return;
|
|
1868
|
+
if (!canHover()) return;
|
|
1869
|
+
clearHoverTimeout();
|
|
1870
|
+
if (state.current.active) return;
|
|
1871
|
+
const delay = options.delay?.() ?? 300;
|
|
1872
|
+
hoverTimeout = setTimeout(() => applyOpen("hover"), delay);
|
|
1873
|
+
},
|
|
1874
|
+
onPointerLeave(_event) {
|
|
1875
|
+
if (!options.openOnHover?.()) return;
|
|
1876
|
+
if (!canHover()) return;
|
|
1877
|
+
clearHoverTimeout();
|
|
1878
|
+
if (!state.current.active) return;
|
|
1879
|
+
const closeDelay = options.closeDelay?.() ?? 0;
|
|
1880
|
+
hoverTimeout = setTimeout(() => applyClose("hover"), closeDelay);
|
|
1881
|
+
},
|
|
1882
|
+
onFocusIn(_event) {
|
|
1883
|
+
if (options.openOnHover?.()) {
|
|
1884
|
+
if (!canOpenOnFocus()) return;
|
|
1885
|
+
applyOpen("focus");
|
|
1886
|
+
}
|
|
1887
|
+
},
|
|
1888
|
+
onFocusOut(event) {
|
|
1889
|
+
const relatedTarget = event.relatedTarget;
|
|
1890
|
+
if (relatedTarget && (triggerEl?.contains(relatedTarget) || popupEl?.contains(relatedTarget))) return;
|
|
1891
|
+
if (options.openOnHover?.()) applyClose("blur");
|
|
1892
|
+
}
|
|
1893
|
+
};
|
|
1894
|
+
const popupProps = {
|
|
1895
|
+
onPointerEnter(_event) {
|
|
1896
|
+
if (!options.openOnHover?.()) return;
|
|
1897
|
+
clearHoverTimeout();
|
|
1898
|
+
},
|
|
1899
|
+
onPointerLeave(_event) {
|
|
1900
|
+
if (!options.openOnHover?.()) return;
|
|
1901
|
+
if (capturedPointers.size > 0) return;
|
|
1902
|
+
clearHoverTimeout();
|
|
1903
|
+
if (!state.current.active) return;
|
|
1904
|
+
const closeDelay = options.closeDelay?.() ?? 0;
|
|
1905
|
+
hoverTimeout = setTimeout(() => applyClose("hover"), closeDelay);
|
|
1906
|
+
},
|
|
1907
|
+
onGotPointerCapture(event) {
|
|
1908
|
+
capturedPointers.add(event.pointerId);
|
|
1909
|
+
},
|
|
1910
|
+
onLostPointerCapture(event) {
|
|
1911
|
+
capturedPointers.delete(event.pointerId);
|
|
1912
|
+
},
|
|
1913
|
+
onFocusOut(event) {
|
|
1914
|
+
const relatedTarget = event.relatedTarget;
|
|
1915
|
+
if (relatedTarget && (triggerEl?.contains(relatedTarget) || popupEl?.contains(relatedTarget))) return;
|
|
1916
|
+
applyClose("blur");
|
|
1917
|
+
}
|
|
1918
|
+
};
|
|
1919
|
+
function setTriggerElement(el) {
|
|
1920
|
+
triggerEl = el;
|
|
1921
|
+
}
|
|
1922
|
+
function setPopupElement(el) {
|
|
1923
|
+
if (!el && popupEl && state.current.active) tryHidePopover(popupEl);
|
|
1924
|
+
popupEl = el;
|
|
1925
|
+
if (el) {
|
|
1926
|
+
if (state.current.active) tryShowPopover(el);
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
return {
|
|
1930
|
+
input: state,
|
|
1931
|
+
triggerProps,
|
|
1932
|
+
popupProps,
|
|
1933
|
+
get triggerElement() {
|
|
1934
|
+
return triggerEl;
|
|
1935
|
+
},
|
|
1936
|
+
setTriggerElement,
|
|
1937
|
+
setPopupElement,
|
|
1938
|
+
open,
|
|
1939
|
+
close,
|
|
1940
|
+
destroy: layer.destroy
|
|
1941
|
+
};
|
|
1942
|
+
}
|
|
1411
1943
|
|
|
1412
1944
|
//#endregion
|
|
1413
|
-
//#region
|
|
1414
|
-
const
|
|
1415
|
-
|
|
1416
|
-
|
|
1945
|
+
//#region ../core/dist/dev/dom/ui/popover/popover-positioning.js
|
|
1946
|
+
const OPPOSITE_SIDE = {
|
|
1947
|
+
top: "bottom",
|
|
1948
|
+
bottom: "top",
|
|
1949
|
+
left: "right",
|
|
1950
|
+
right: "left"
|
|
1951
|
+
};
|
|
1952
|
+
/**
|
|
1953
|
+
* Get positioning styles for the popup element.
|
|
1954
|
+
*
|
|
1955
|
+
* When the browser supports CSS Anchor Positioning, returns native CSS properties
|
|
1956
|
+
* that reference the provided CSS var names for side/align offsets — no JS offset
|
|
1957
|
+
* values needed.
|
|
1958
|
+
*
|
|
1959
|
+
* When rects are provided and anchor positioning is unsupported, falls back to
|
|
1960
|
+
* manual JS-computed positioning. The caller must resolve offset CSS vars via
|
|
1961
|
+
* `getComputedStyle` and pass them as `offsets`.
|
|
1962
|
+
*
|
|
1963
|
+
* Returns camelCase keys for standard CSS properties and `--*` keys for
|
|
1964
|
+
* custom properties — compatible with both React's `style` prop and
|
|
1965
|
+
* `applyStyles()` from `@videojs/utils/dom`.
|
|
1966
|
+
*/
|
|
1967
|
+
function getAnchorPositionStyle(anchorName, opts, triggerRect, popupRect, boundaryRect, offsets, cssVars = PopoverCSSVars) {
|
|
1968
|
+
if (supportsAnchorPositioning()) return getAnchorPositionCSS(anchorName, opts, cssVars);
|
|
1969
|
+
if (triggerRect && popupRect) return {
|
|
1970
|
+
...getManualPositionStyle(triggerRect, popupRect, opts, offsets ?? {
|
|
1971
|
+
sideOffset: 0,
|
|
1972
|
+
alignOffset: 0
|
|
1973
|
+
}),
|
|
1974
|
+
...boundaryRect ? getPositioningCSSVars(triggerRect, boundaryRect, opts.side, cssVars) : {},
|
|
1975
|
+
position: "fixed",
|
|
1976
|
+
inset: "auto",
|
|
1977
|
+
margin: "0"
|
|
1978
|
+
};
|
|
1979
|
+
return {};
|
|
1980
|
+
}
|
|
1981
|
+
/** Generate style to set on the trigger for CSS Anchor Positioning. */
|
|
1982
|
+
function getAnchorNameStyle(anchorName) {
|
|
1983
|
+
if (!supportsAnchorPositioning()) return {};
|
|
1984
|
+
return { anchorName: `--${anchorName}` };
|
|
1985
|
+
}
|
|
1986
|
+
function getAnchorPositionCSS(anchorName, opts, cssVars = PopoverCSSVars) {
|
|
1987
|
+
const SIDE_OFFSET_VAR = `var(${cssVars.sideOffset}, 0px)`;
|
|
1988
|
+
const ALIGN_OFFSET_VAR = `var(${cssVars.alignOffset}, 0px)`;
|
|
1989
|
+
const { side, align } = opts;
|
|
1990
|
+
const style = {
|
|
1991
|
+
positionAnchor: `--${anchorName}`,
|
|
1992
|
+
position: "fixed",
|
|
1993
|
+
inset: "auto",
|
|
1994
|
+
margin: "0",
|
|
1995
|
+
justifySelf: "normal",
|
|
1996
|
+
alignSelf: "normal",
|
|
1997
|
+
marginInlineStart: "0",
|
|
1998
|
+
marginBlockStart: "0"
|
|
1999
|
+
};
|
|
2000
|
+
const insetProp = OPPOSITE_SIDE[side];
|
|
2001
|
+
if (side === "top" || side === "bottom") {
|
|
2002
|
+
style[insetProp] = `calc(anchor(${side}) + ${SIDE_OFFSET_VAR})`;
|
|
2003
|
+
if (align === "start") style.left = `calc(anchor(left) + ${ALIGN_OFFSET_VAR})`;
|
|
2004
|
+
else if (align === "end") style.right = `calc(anchor(right) + ${ALIGN_OFFSET_VAR})`;
|
|
2005
|
+
else {
|
|
2006
|
+
style.justifySelf = "anchor-center";
|
|
2007
|
+
style.marginInlineStart = ALIGN_OFFSET_VAR;
|
|
2008
|
+
}
|
|
2009
|
+
} else {
|
|
2010
|
+
style[insetProp] = `calc(anchor(${side}) + ${SIDE_OFFSET_VAR})`;
|
|
2011
|
+
if (align === "start") style.top = `calc(anchor(top) + ${ALIGN_OFFSET_VAR})`;
|
|
2012
|
+
else if (align === "end") style.bottom = `calc(anchor(bottom) + ${ALIGN_OFFSET_VAR})`;
|
|
2013
|
+
else {
|
|
2014
|
+
style.alignSelf = "anchor-center";
|
|
2015
|
+
style.marginBlockStart = ALIGN_OFFSET_VAR;
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
return style;
|
|
2019
|
+
}
|
|
2020
|
+
/**
|
|
2021
|
+
* Compute CSS variables for sizing constraints relative to the anchor/boundary.
|
|
2022
|
+
*
|
|
2023
|
+
* Accepts a `cssVars` map so the same logic works for both popover
|
|
2024
|
+
* (`--media-popover-*`) and tooltip (`--media-tooltip-*`) namespaces.
|
|
2025
|
+
*/
|
|
2026
|
+
function getPositioningCSSVars(triggerRect, boundaryRect, side, cssVars = PopoverCSSVars) {
|
|
2027
|
+
const vars = {};
|
|
2028
|
+
vars[cssVars.anchorWidth] = `${triggerRect.width}px`;
|
|
2029
|
+
vars[cssVars.anchorHeight] = `${triggerRect.height}px`;
|
|
2030
|
+
if (side === "top" || side === "bottom") {
|
|
2031
|
+
vars[cssVars.availableHeight] = side === "top" ? `${triggerRect.top - boundaryRect.top}px` : `${boundaryRect.bottom - triggerRect.bottom}px`;
|
|
2032
|
+
vars[cssVars.availableWidth] = `${boundaryRect.width}px`;
|
|
2033
|
+
} else {
|
|
2034
|
+
vars[cssVars.availableWidth] = side === "left" ? `${triggerRect.left - boundaryRect.left}px` : `${boundaryRect.right - triggerRect.right}px`;
|
|
2035
|
+
vars[cssVars.availableHeight] = `${boundaryRect.height}px`;
|
|
2036
|
+
}
|
|
2037
|
+
return vars;
|
|
2038
|
+
}
|
|
2039
|
+
/**
|
|
2040
|
+
* Compute manual positioning when CSS Anchor Positioning is not supported.
|
|
2041
|
+
*
|
|
2042
|
+
* Returns inline `top`/`left` styles in **viewport coordinates** for use
|
|
2043
|
+
* with `position: fixed` (the popup is in the top layer). All rects from
|
|
2044
|
+
* `getBoundingClientRect()` are already viewport-relative.
|
|
2045
|
+
*
|
|
2046
|
+
* Offsets are resolved by the caller from CSS custom properties via
|
|
2047
|
+
* `getComputedStyle()` and passed as `offsets`.
|
|
2048
|
+
*/
|
|
2049
|
+
function getManualPositionStyle(triggerRect, popupRect, opts, offsets = {
|
|
2050
|
+
sideOffset: 0,
|
|
2051
|
+
alignOffset: 0
|
|
2052
|
+
}) {
|
|
2053
|
+
const { side, align } = opts;
|
|
2054
|
+
const { sideOffset, alignOffset } = offsets;
|
|
2055
|
+
let top = 0;
|
|
2056
|
+
let left = 0;
|
|
2057
|
+
if (side === "top") top = triggerRect.top - popupRect.height - sideOffset;
|
|
2058
|
+
else if (side === "bottom") top = triggerRect.bottom + sideOffset;
|
|
2059
|
+
else if (side === "left") left = triggerRect.left - popupRect.width - sideOffset;
|
|
2060
|
+
else left = triggerRect.right + sideOffset;
|
|
2061
|
+
if (side === "top" || side === "bottom") if (align === "start") left = triggerRect.left + alignOffset;
|
|
2062
|
+
else if (align === "end") left = triggerRect.right - popupRect.width + alignOffset;
|
|
2063
|
+
else left = triggerRect.left + (triggerRect.width - popupRect.width) / 2 + alignOffset;
|
|
2064
|
+
else if (align === "start") top = triggerRect.top + alignOffset;
|
|
2065
|
+
else if (align === "end") top = triggerRect.bottom - popupRect.height + alignOffset;
|
|
2066
|
+
else top = triggerRect.top + (triggerRect.height - popupRect.height) / 2 + alignOffset;
|
|
2067
|
+
return {
|
|
2068
|
+
top: `${top}px`,
|
|
2069
|
+
left: `${left}px`
|
|
2070
|
+
};
|
|
2071
|
+
}
|
|
2072
|
+
/**
|
|
2073
|
+
* Read side-offset and align-offset CSS custom properties from the
|
|
2074
|
+
* popup element's computed style, returning numeric pixel values.
|
|
2075
|
+
*/
|
|
2076
|
+
function resolveOffsets(el, cssVars = PopoverCSSVars) {
|
|
2077
|
+
const computed = getComputedStyle(el);
|
|
2078
|
+
return {
|
|
2079
|
+
sideOffset: resolveCSSLength(el, computed.getPropertyValue(cssVars.sideOffset)),
|
|
2080
|
+
alignOffset: resolveCSSLength(el, computed.getPropertyValue(cssVars.alignOffset))
|
|
2081
|
+
};
|
|
2082
|
+
}
|
|
2083
|
+
/**
|
|
2084
|
+
* Measure the popup's layout box for positioning.
|
|
2085
|
+
*
|
|
2086
|
+
* `getBoundingClientRect()` includes active transforms, which causes the
|
|
2087
|
+
* fallback position to drift while opening/closing animations scale the popup.
|
|
2088
|
+
* Using `offsetWidth`/`offsetHeight` preserves the untransformed size.
|
|
2089
|
+
*/
|
|
2090
|
+
function getPopupPositionRect(el) {
|
|
2091
|
+
const rect = el.getBoundingClientRect();
|
|
2092
|
+
const width = el.offsetWidth || rect.width;
|
|
2093
|
+
const height = el.offsetHeight || rect.height;
|
|
2094
|
+
const adjustedRect = {
|
|
2095
|
+
...rect,
|
|
2096
|
+
width,
|
|
2097
|
+
height,
|
|
2098
|
+
right: rect.left + width,
|
|
2099
|
+
bottom: rect.top + height
|
|
2100
|
+
};
|
|
2101
|
+
return {
|
|
2102
|
+
...adjustedRect,
|
|
2103
|
+
toJSON: () => adjustedRect
|
|
2104
|
+
};
|
|
2105
|
+
}
|
|
2106
|
+
|
|
2107
|
+
//#endregion
|
|
2108
|
+
//#region ../core/dist/dev/dom/utils/pointer.js
|
|
2109
|
+
/** Convert a pointer event position to a 0–100 percent along an element's rect. */
|
|
2110
|
+
function getPercentFromPointerEvent(event, rect, orientation, isRTL) {
|
|
2111
|
+
let ratio;
|
|
2112
|
+
if (orientation === "vertical") ratio = 1 - (event.clientY - rect.top) / rect.height;
|
|
2113
|
+
else if (isRTL) ratio = (rect.right - event.clientX) / rect.width;
|
|
2114
|
+
else ratio = (event.clientX - rect.left) / rect.width;
|
|
2115
|
+
if (!Number.isFinite(ratio)) return 0;
|
|
2116
|
+
return clamp(ratio * 100, 0, 100);
|
|
2117
|
+
}
|
|
2118
|
+
|
|
2119
|
+
//#endregion
|
|
2120
|
+
//#region ../core/dist/dev/dom/ui/slider.js
|
|
2121
|
+
function createSlider(options) {
|
|
2122
|
+
const input = createState({
|
|
2123
|
+
pointerPercent: 0,
|
|
2124
|
+
dragPercent: 0,
|
|
2125
|
+
dragging: false,
|
|
2126
|
+
pointing: false,
|
|
2127
|
+
focused: false
|
|
2128
|
+
});
|
|
2129
|
+
const abort = new AbortController();
|
|
2130
|
+
const changeThrottleMs = options.changeThrottle ?? 0;
|
|
2131
|
+
let isDragging = false, cachedRTL = false, cachedRect = null, capturedPointerId = null, lastDragPercent = 0, committedOnRelease = false;
|
|
2132
|
+
const throttledChange = changeThrottleMs > 0 ? throttle((percent) => options.onValueChange?.(percent), changeThrottleMs, { leading: true }) : null;
|
|
2133
|
+
/** Fire `onValueChange` — throttled during drag when `changeThrottle > 0`. */
|
|
2134
|
+
function fireChange(percent, duringDrag) {
|
|
2135
|
+
if (duringDrag && throttledChange) throttledChange(percent);
|
|
2136
|
+
else options.onValueChange?.(percent);
|
|
2137
|
+
}
|
|
2138
|
+
function releaseCapture() {
|
|
2139
|
+
if (isNull(capturedPointerId)) return;
|
|
2140
|
+
const id = capturedPointerId;
|
|
2141
|
+
capturedPointerId = null;
|
|
2142
|
+
try {
|
|
2143
|
+
options.getElement().releasePointerCapture(id);
|
|
2144
|
+
} catch {}
|
|
2145
|
+
}
|
|
2146
|
+
function endDrag() {
|
|
2147
|
+
if (!isDragging) input.patch({ pointing: false });
|
|
2148
|
+
else {
|
|
2149
|
+
if (!committedOnRelease) options.onValueCommit?.(lastDragPercent);
|
|
2150
|
+
isDragging = false;
|
|
2151
|
+
input.patch({
|
|
2152
|
+
dragging: false,
|
|
2153
|
+
pointing: false
|
|
2154
|
+
});
|
|
2155
|
+
options.onDragEnd?.();
|
|
2156
|
+
}
|
|
2157
|
+
committedOnRelease = false;
|
|
2158
|
+
cleanup();
|
|
2159
|
+
}
|
|
2160
|
+
function cleanup() {
|
|
2161
|
+
throttledChange?.cancel();
|
|
2162
|
+
capturedPointerId = null;
|
|
2163
|
+
cachedRect = null;
|
|
2164
|
+
}
|
|
2165
|
+
const rootProps = {
|
|
2166
|
+
onPointerDown(event) {
|
|
2167
|
+
if (options.isDisabled()) return;
|
|
2168
|
+
event.preventDefault();
|
|
2169
|
+
const el = options.getElement();
|
|
2170
|
+
cachedRect = el.getBoundingClientRect();
|
|
2171
|
+
cachedRTL = options.isRTL();
|
|
2172
|
+
committedOnRelease = false;
|
|
2173
|
+
releaseCapture();
|
|
2174
|
+
capturedPointerId = event.pointerId;
|
|
2175
|
+
el.setPointerCapture(event.pointerId);
|
|
2176
|
+
const percent = getPercentFromPointerEvent(event, cachedRect, options.getOrientation(), cachedRTL);
|
|
2177
|
+
isDragging = true;
|
|
2178
|
+
lastDragPercent = percent;
|
|
2179
|
+
input.patch({
|
|
2180
|
+
pointing: true,
|
|
2181
|
+
dragging: true,
|
|
2182
|
+
pointerPercent: percent,
|
|
2183
|
+
dragPercent: percent
|
|
2184
|
+
});
|
|
2185
|
+
options.onDragStart?.();
|
|
2186
|
+
options.onValueChange?.(percent);
|
|
2187
|
+
options.getThumbElement?.()?.focus({
|
|
2188
|
+
preventScroll: true,
|
|
2189
|
+
focusVisible: false
|
|
2190
|
+
});
|
|
2191
|
+
},
|
|
2192
|
+
onPointerMove(event) {
|
|
2193
|
+
if (options.isDisabled()) return;
|
|
2194
|
+
if (!isNull(capturedPointerId)) {
|
|
2195
|
+
if (event.pointerType !== "touch" && event.buttons === 0) {
|
|
2196
|
+
endDrag();
|
|
2197
|
+
return;
|
|
2198
|
+
}
|
|
2199
|
+
const percent = getPercentFromPointerEvent(event, cachedRect, options.getOrientation(), cachedRTL);
|
|
2200
|
+
lastDragPercent = percent;
|
|
2201
|
+
input.patch({
|
|
2202
|
+
dragPercent: percent,
|
|
2203
|
+
pointerPercent: percent
|
|
2204
|
+
});
|
|
2205
|
+
fireChange(percent, true);
|
|
2206
|
+
return;
|
|
2207
|
+
}
|
|
2208
|
+
const percent = getPercentFromPointerEvent(event, options.getElement().getBoundingClientRect(), options.getOrientation(), options.isRTL());
|
|
2209
|
+
input.patch({
|
|
2210
|
+
pointing: true,
|
|
2211
|
+
pointerPercent: percent
|
|
2212
|
+
});
|
|
2213
|
+
},
|
|
2214
|
+
onPointerUp(event) {
|
|
2215
|
+
if (isNull(capturedPointerId)) return;
|
|
2216
|
+
const percent = getPercentFromPointerEvent(event, cachedRect, options.getOrientation(), cachedRTL);
|
|
2217
|
+
throttledChange?.cancel();
|
|
2218
|
+
options.onValueChange?.(percent);
|
|
2219
|
+
options.onValueCommit?.(percent);
|
|
2220
|
+
committedOnRelease = true;
|
|
2221
|
+
},
|
|
2222
|
+
onPointerLeave() {
|
|
2223
|
+
if (!isNull(capturedPointerId)) return;
|
|
2224
|
+
input.patch({ pointing: false });
|
|
2225
|
+
},
|
|
2226
|
+
onLostPointerCapture() {
|
|
2227
|
+
endDrag();
|
|
2228
|
+
}
|
|
2229
|
+
};
|
|
2230
|
+
const thumbProps = {
|
|
2231
|
+
onKeyDown(event) {
|
|
2232
|
+
if (options.isDisabled()) {
|
|
2233
|
+
if (event.key !== "Tab") event.preventDefault();
|
|
2234
|
+
return;
|
|
2235
|
+
}
|
|
2236
|
+
const stepPercent = options.getStepPercent();
|
|
2237
|
+
const largeStepPercent = options.getLargeStepPercent();
|
|
2238
|
+
const rounded = roundToStep(options.getPercent(), stepPercent, 0);
|
|
2239
|
+
const horizontalSign = options.isRTL() ? -1 : 1;
|
|
2240
|
+
const step = event.shiftKey ? largeStepPercent : stepPercent;
|
|
2241
|
+
let newPercent = null;
|
|
2242
|
+
switch (event.key) {
|
|
2243
|
+
case "ArrowRight":
|
|
2244
|
+
newPercent = rounded + step * horizontalSign;
|
|
2245
|
+
break;
|
|
2246
|
+
case "ArrowLeft":
|
|
2247
|
+
newPercent = rounded - step * horizontalSign;
|
|
2248
|
+
break;
|
|
2249
|
+
case "ArrowUp":
|
|
2250
|
+
newPercent = rounded + step;
|
|
2251
|
+
break;
|
|
2252
|
+
case "ArrowDown":
|
|
2253
|
+
newPercent = rounded - step;
|
|
2254
|
+
break;
|
|
2255
|
+
case "PageUp":
|
|
2256
|
+
newPercent = rounded + largeStepPercent;
|
|
2257
|
+
break;
|
|
2258
|
+
case "PageDown":
|
|
2259
|
+
newPercent = rounded - largeStepPercent;
|
|
2260
|
+
break;
|
|
2261
|
+
case "Home":
|
|
2262
|
+
newPercent = 0;
|
|
2263
|
+
break;
|
|
2264
|
+
case "End":
|
|
2265
|
+
newPercent = 100;
|
|
2266
|
+
break;
|
|
2267
|
+
default:
|
|
2268
|
+
if (!event.metaKey && !event.ctrlKey && !event.altKey && event.key >= "0" && event.key <= "9") newPercent = Number(event.key) * 10;
|
|
2269
|
+
break;
|
|
2270
|
+
}
|
|
2271
|
+
if (newPercent !== null) {
|
|
2272
|
+
event.preventDefault();
|
|
2273
|
+
newPercent = clamp(newPercent, 0, 100);
|
|
2274
|
+
input.patch({
|
|
2275
|
+
pointerPercent: newPercent,
|
|
2276
|
+
dragPercent: newPercent
|
|
2277
|
+
});
|
|
2278
|
+
options.onValueChange?.(newPercent);
|
|
2279
|
+
options.onValueCommit?.(newPercent);
|
|
2280
|
+
}
|
|
2281
|
+
},
|
|
2282
|
+
onFocus() {
|
|
2283
|
+
input.patch({ focused: true });
|
|
2284
|
+
},
|
|
2285
|
+
onBlur() {
|
|
2286
|
+
input.patch({ focused: false });
|
|
2287
|
+
}
|
|
2288
|
+
};
|
|
2289
|
+
function adjustForAlignment(state) {
|
|
2290
|
+
if (!options.adjustPercent || state.thumbAlignment !== "edge") return state;
|
|
2291
|
+
const rootEl = options.getElement();
|
|
2292
|
+
const thumbEl = options.getThumbElement?.();
|
|
2293
|
+
if (!thumbEl) return state;
|
|
2294
|
+
const isHorizontal = state.orientation === "horizontal";
|
|
2295
|
+
const thumbSize = isHorizontal ? thumbEl.offsetWidth : thumbEl.offsetHeight;
|
|
2296
|
+
const trackSize = isHorizontal ? rootEl.offsetWidth : rootEl.offsetHeight;
|
|
2297
|
+
return {
|
|
2298
|
+
...state,
|
|
2299
|
+
fillPercent: options.adjustPercent(state.fillPercent, thumbSize, trackSize),
|
|
2300
|
+
pointerPercent: options.adjustPercent(state.pointerPercent, thumbSize, trackSize)
|
|
2301
|
+
};
|
|
2302
|
+
}
|
|
2303
|
+
let resizeObserver = null;
|
|
2304
|
+
if (options.onResize) {
|
|
2305
|
+
resizeObserver = new ResizeObserver(() => options.onResize());
|
|
2306
|
+
resizeObserver.observe(options.getElement());
|
|
2307
|
+
}
|
|
2308
|
+
return {
|
|
2309
|
+
input,
|
|
2310
|
+
rootProps,
|
|
2311
|
+
rootStyle: {
|
|
2312
|
+
touchAction: "none",
|
|
2313
|
+
userSelect: "none"
|
|
2314
|
+
},
|
|
2315
|
+
thumbProps,
|
|
2316
|
+
adjustForAlignment,
|
|
2317
|
+
destroy() {
|
|
2318
|
+
if (abort.signal.aborted) return;
|
|
2319
|
+
abort.abort();
|
|
2320
|
+
resizeObserver?.disconnect();
|
|
2321
|
+
releaseCapture();
|
|
2322
|
+
cleanup();
|
|
2323
|
+
}
|
|
2324
|
+
};
|
|
2325
|
+
}
|
|
2326
|
+
|
|
2327
|
+
//#endregion
|
|
2328
|
+
//#region ../core/dist/dev/dom/ui/slider-css-vars.js
|
|
2329
|
+
function getSliderCSSVars(state) {
|
|
2330
|
+
return {
|
|
2331
|
+
[SliderCSSVars.fill]: `${state.fillPercent.toFixed(3)}%`,
|
|
2332
|
+
[SliderCSSVars.pointer]: `${state.pointerPercent.toFixed(3)}%`
|
|
2333
|
+
};
|
|
2334
|
+
}
|
|
2335
|
+
function getTimeSliderCSSVars(state) {
|
|
2336
|
+
return {
|
|
2337
|
+
...getSliderCSSVars(state),
|
|
2338
|
+
[SliderCSSVars.buffer]: `${state.bufferPercent.toFixed(3)}%`
|
|
2339
|
+
};
|
|
2340
|
+
}
|
|
2341
|
+
/** Compute structural positioning styles for a slider preview element. */
|
|
2342
|
+
function getSliderPreviewStyle(width, overflow) {
|
|
2343
|
+
const halfWidth = width / 2;
|
|
2344
|
+
return {
|
|
2345
|
+
position: "absolute",
|
|
2346
|
+
left: overflow === "visible" ? `calc(var(${SliderCSSVars.pointer}) - ${halfWidth}px)` : `min(max(0px, calc(var(${SliderCSSVars.pointer}) - ${halfWidth}px)), calc(100% - ${width}px))`,
|
|
2347
|
+
width: "max-content",
|
|
2348
|
+
pointerEvents: "none"
|
|
2349
|
+
};
|
|
2350
|
+
}
|
|
2351
|
+
|
|
2352
|
+
//#endregion
|
|
2353
|
+
//#region ../core/dist/dev/dom/ui/thumbnail.js
|
|
2354
|
+
function createThumbnail(options) {
|
|
2355
|
+
const { getContainer, getImg, onStateChange } = options;
|
|
2356
|
+
const core = new ThumbnailCore();
|
|
2357
|
+
const abort = new AbortController();
|
|
2358
|
+
const signal = abort.signal;
|
|
2359
|
+
let loading = false;
|
|
2360
|
+
let error = false;
|
|
2361
|
+
let naturalWidth = 0;
|
|
2362
|
+
let naturalHeight = 0;
|
|
2363
|
+
let lastSrc = "";
|
|
2364
|
+
let imgBound = false;
|
|
2365
|
+
let resizeObserver = null;
|
|
2366
|
+
function onImgLoad() {
|
|
2367
|
+
const img = getImg();
|
|
2368
|
+
if (img) {
|
|
2369
|
+
naturalWidth = img.naturalWidth;
|
|
2370
|
+
naturalHeight = img.naturalHeight;
|
|
2371
|
+
}
|
|
2372
|
+
loading = false;
|
|
2373
|
+
error = false;
|
|
2374
|
+
onStateChange();
|
|
2375
|
+
}
|
|
2376
|
+
function onImgError() {
|
|
2377
|
+
loading = false;
|
|
2378
|
+
error = true;
|
|
2379
|
+
onStateChange();
|
|
2380
|
+
}
|
|
2381
|
+
function bindImg(img) {
|
|
2382
|
+
listen(img, "load", onImgLoad, { signal });
|
|
2383
|
+
listen(img, "error", onImgError, { signal });
|
|
2384
|
+
}
|
|
2385
|
+
function ensureBindings() {
|
|
2386
|
+
if (!imgBound) {
|
|
2387
|
+
const img = getImg();
|
|
2388
|
+
if (img) {
|
|
2389
|
+
bindImg(img);
|
|
2390
|
+
imgBound = true;
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
if (!resizeObserver) {
|
|
2394
|
+
const container = getContainer();
|
|
2395
|
+
if (container) {
|
|
2396
|
+
resizeObserver = new ResizeObserver(onStateChange);
|
|
2397
|
+
resizeObserver.observe(container);
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
function updateSrc(url) {
|
|
2402
|
+
ensureBindings();
|
|
2403
|
+
const src = url ?? "";
|
|
2404
|
+
if (src === lastSrc) return;
|
|
2405
|
+
lastSrc = src;
|
|
2406
|
+
if (src) {
|
|
2407
|
+
loading = true;
|
|
2408
|
+
error = false;
|
|
2409
|
+
} else {
|
|
2410
|
+
loading = false;
|
|
2411
|
+
error = false;
|
|
2412
|
+
naturalWidth = 0;
|
|
2413
|
+
naturalHeight = 0;
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
function connect() {
|
|
2417
|
+
ensureBindings();
|
|
2418
|
+
const img = getImg();
|
|
2419
|
+
if (img?.complete && lastSrc) {
|
|
2420
|
+
if (img.naturalWidth > 0) {
|
|
2421
|
+
naturalWidth = img.naturalWidth;
|
|
2422
|
+
naturalHeight = img.naturalHeight;
|
|
2423
|
+
loading = false;
|
|
2424
|
+
error = false;
|
|
2425
|
+
} else {
|
|
2426
|
+
loading = false;
|
|
2427
|
+
error = true;
|
|
2428
|
+
}
|
|
2429
|
+
onStateChange();
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
function destroy() {
|
|
2433
|
+
abort.abort();
|
|
2434
|
+
resizeObserver?.disconnect();
|
|
2435
|
+
resizeObserver = null;
|
|
2436
|
+
}
|
|
2437
|
+
return {
|
|
2438
|
+
get loading() {
|
|
2439
|
+
return loading;
|
|
2440
|
+
},
|
|
2441
|
+
get error() {
|
|
2442
|
+
return error;
|
|
2443
|
+
},
|
|
2444
|
+
get naturalWidth() {
|
|
2445
|
+
return naturalWidth;
|
|
2446
|
+
},
|
|
2447
|
+
get naturalHeight() {
|
|
2448
|
+
return naturalHeight;
|
|
2449
|
+
},
|
|
2450
|
+
readConstraints() {
|
|
2451
|
+
const el = getContainer();
|
|
2452
|
+
if (!el) return {
|
|
2453
|
+
minWidth: 0,
|
|
2454
|
+
maxWidth: Infinity,
|
|
2455
|
+
minHeight: 0,
|
|
2456
|
+
maxHeight: Infinity
|
|
2457
|
+
};
|
|
2458
|
+
return core.parseConstraints(getComputedStyle(el));
|
|
2459
|
+
},
|
|
2460
|
+
updateSrc,
|
|
2461
|
+
connect,
|
|
2462
|
+
destroy
|
|
2463
|
+
};
|
|
2464
|
+
}
|
|
2465
|
+
|
|
2466
|
+
//#endregion
|
|
2467
|
+
//#region ../core/dist/dev/dom/ui/tooltip/tooltip.js
|
|
2468
|
+
/** Map popover reasons to tooltip reasons, filtering out click/outside-click. */
|
|
2469
|
+
const REASON_MAP = {
|
|
2470
|
+
hover: "hover",
|
|
2471
|
+
focus: "focus",
|
|
2472
|
+
escape: "escape",
|
|
2473
|
+
blur: "blur"
|
|
2474
|
+
};
|
|
2475
|
+
function createTooltip(options) {
|
|
2476
|
+
const popoverOpts = {
|
|
2477
|
+
transition: options.transition,
|
|
2478
|
+
onOpenChange(open, details) {
|
|
2479
|
+
const reason = REASON_MAP[details.reason];
|
|
2480
|
+
if (!reason) return;
|
|
2481
|
+
const group = options.group?.();
|
|
2482
|
+
if (open) group?.notifyOpen();
|
|
2483
|
+
else group?.notifyClose();
|
|
2484
|
+
const tooltipDetails = details.event ? {
|
|
2485
|
+
reason,
|
|
2486
|
+
event: details.event
|
|
2487
|
+
} : { reason };
|
|
2488
|
+
options.onOpenChange(open, tooltipDetails);
|
|
2489
|
+
},
|
|
2490
|
+
closeOnEscape: () => true,
|
|
2491
|
+
closeOnOutsideClick: () => false,
|
|
2492
|
+
openOnHover: () => true,
|
|
2493
|
+
delay: () => {
|
|
2494
|
+
const group = options.group?.();
|
|
2495
|
+
if (group?.shouldSkipDelay()) return 0;
|
|
2496
|
+
return options.delay?.() ?? group?.delay ?? 600;
|
|
2497
|
+
},
|
|
2498
|
+
closeDelay: () => {
|
|
2499
|
+
const group = options.group?.();
|
|
2500
|
+
return options.closeDelay?.() ?? group?.closeDelay ?? 0;
|
|
2501
|
+
}
|
|
2502
|
+
};
|
|
2503
|
+
if (options.onOpenChangeComplete) popoverOpts.onOpenChangeComplete = options.onOpenChangeComplete;
|
|
2504
|
+
const popover = createPopover(popoverOpts);
|
|
2505
|
+
let isPointerDown = false;
|
|
2506
|
+
const { onClick: _, ...baseTriggerProps } = popover.triggerProps;
|
|
2507
|
+
const triggerProps = {
|
|
2508
|
+
...baseTriggerProps,
|
|
2509
|
+
onPointerDown() {
|
|
2510
|
+
isPointerDown = true;
|
|
2511
|
+
},
|
|
2512
|
+
onPointerEnter(event) {
|
|
2513
|
+
if (options.disabled?.()) return;
|
|
2514
|
+
if (event.pointerType === "touch") return;
|
|
2515
|
+
baseTriggerProps.onPointerEnter(event);
|
|
2516
|
+
},
|
|
2517
|
+
onFocusIn(event) {
|
|
2518
|
+
if (options.disabled?.()) return;
|
|
2519
|
+
if (isPointerDown) {
|
|
2520
|
+
isPointerDown = false;
|
|
2521
|
+
return;
|
|
2522
|
+
}
|
|
2523
|
+
baseTriggerProps.onFocusIn(event);
|
|
2524
|
+
}
|
|
2525
|
+
};
|
|
2526
|
+
const popupProps = {
|
|
2527
|
+
...popover.popupProps,
|
|
2528
|
+
onPointerEnter(event) {
|
|
2529
|
+
if (options.disableHoverablePopup?.()) return;
|
|
2530
|
+
popover.popupProps.onPointerEnter(event);
|
|
2531
|
+
}
|
|
2532
|
+
};
|
|
2533
|
+
return {
|
|
2534
|
+
...popover,
|
|
2535
|
+
triggerProps,
|
|
2536
|
+
popupProps,
|
|
2537
|
+
get triggerElement() {
|
|
2538
|
+
return popover.triggerElement;
|
|
2539
|
+
},
|
|
2540
|
+
open: () => popover.open("hover"),
|
|
2541
|
+
close: () => popover.close("hover")
|
|
2542
|
+
};
|
|
2543
|
+
}
|
|
2544
|
+
|
|
2545
|
+
//#endregion
|
|
2546
|
+
//#region ../core/dist/dev/dom/ui/transition.js
|
|
2547
|
+
/**
|
|
2548
|
+
* Manages open/close transition lifecycle via `createState`.
|
|
2549
|
+
*
|
|
2550
|
+
* **Open:** patches `{ active: true, status: 'starting' }`, then after a
|
|
2551
|
+
* double-RAF patches `{ status: 'idle' }` so the browser paints the
|
|
2552
|
+
* initial ("from") state before transitioning.
|
|
2553
|
+
*
|
|
2554
|
+
* **Close:** patches `{ status: 'ending' }` (keeping `active: true` so the
|
|
2555
|
+
* element stays mounted), then after a double-RAF waits for
|
|
2556
|
+
* `getAnimations()` to settle before patching `{ active: false, status: 'idle' }`.
|
|
2557
|
+
*/
|
|
2558
|
+
function createTransition() {
|
|
2559
|
+
const state = createState({
|
|
2560
|
+
active: false,
|
|
2561
|
+
status: "idle"
|
|
2562
|
+
});
|
|
2563
|
+
let destroyed = false;
|
|
2564
|
+
let rafId1 = 0;
|
|
2565
|
+
let rafId2 = 0;
|
|
2566
|
+
function open() {
|
|
2567
|
+
cancelAnimationFrame(rafId1);
|
|
2568
|
+
cancelAnimationFrame(rafId2);
|
|
2569
|
+
rafId1 = 0;
|
|
2570
|
+
rafId2 = 0;
|
|
2571
|
+
state.patch({
|
|
2572
|
+
active: true,
|
|
2573
|
+
status: "starting"
|
|
2574
|
+
});
|
|
2575
|
+
return new Promise((resolve) => {
|
|
2576
|
+
rafId1 = requestAnimationFrame(() => {
|
|
2577
|
+
rafId1 = 0;
|
|
2578
|
+
rafId2 = requestAnimationFrame(() => {
|
|
2579
|
+
rafId2 = 0;
|
|
2580
|
+
if (destroyed || !state.current.active) return resolve();
|
|
2581
|
+
state.patch({ status: "idle" });
|
|
2582
|
+
resolve();
|
|
2583
|
+
});
|
|
2584
|
+
});
|
|
2585
|
+
});
|
|
2586
|
+
}
|
|
2587
|
+
function close(el) {
|
|
2588
|
+
cancelAnimationFrame(rafId1);
|
|
2589
|
+
cancelAnimationFrame(rafId2);
|
|
2590
|
+
rafId1 = 0;
|
|
2591
|
+
rafId2 = 0;
|
|
2592
|
+
state.patch({ status: "ending" });
|
|
2593
|
+
return new Promise((resolve) => {
|
|
2594
|
+
rafId1 = requestAnimationFrame(() => {
|
|
2595
|
+
rafId1 = 0;
|
|
2596
|
+
rafId2 = requestAnimationFrame(() => {
|
|
2597
|
+
rafId2 = 0;
|
|
2598
|
+
if (destroyed) return resolve();
|
|
2599
|
+
waitForAnimations(el).finally(() => {
|
|
2600
|
+
if (destroyed || state.current.status !== "ending") return resolve();
|
|
2601
|
+
state.patch({
|
|
2602
|
+
active: false,
|
|
2603
|
+
status: "idle"
|
|
2604
|
+
});
|
|
2605
|
+
resolve();
|
|
2606
|
+
});
|
|
2607
|
+
});
|
|
2608
|
+
});
|
|
2609
|
+
});
|
|
2610
|
+
}
|
|
2611
|
+
function cancel() {
|
|
2612
|
+
cancelAnimationFrame(rafId1);
|
|
2613
|
+
cancelAnimationFrame(rafId2);
|
|
2614
|
+
rafId1 = 0;
|
|
2615
|
+
rafId2 = 0;
|
|
2616
|
+
if (state.current.status !== "idle") state.patch({ status: "idle" });
|
|
2617
|
+
}
|
|
2618
|
+
return {
|
|
2619
|
+
state,
|
|
2620
|
+
open,
|
|
2621
|
+
close,
|
|
2622
|
+
cancel,
|
|
2623
|
+
destroy() {
|
|
2624
|
+
if (destroyed) return;
|
|
2625
|
+
destroyed = true;
|
|
2626
|
+
cancel();
|
|
2627
|
+
}
|
|
2628
|
+
};
|
|
2629
|
+
}
|
|
2630
|
+
function waitForAnimations(el) {
|
|
2631
|
+
if (!el) return Promise.resolve();
|
|
2632
|
+
const animations = el.getAnimations?.() ?? [];
|
|
2633
|
+
if (animations.length === 0) return Promise.resolve();
|
|
2634
|
+
return Promise.all(animations.map((a) => a.finished)).then(noop, noop);
|
|
2635
|
+
}
|
|
2636
|
+
|
|
2637
|
+
//#endregion
|
|
2638
|
+
//#region ../core/dist/dev/dom/ui/wheel-step.js
|
|
2639
|
+
function createWheelStep(options) {
|
|
2640
|
+
return { onWheel(event) {
|
|
2641
|
+
if (options.isDisabled()) return;
|
|
2642
|
+
const direction = Math.sign(event.deltaY);
|
|
2643
|
+
if (direction === 0) return;
|
|
2644
|
+
event.preventDefault();
|
|
2645
|
+
const stepPercent = options.getStepPercent();
|
|
2646
|
+
const newPercent = clamp(options.getPercent() - direction * stepPercent, 0, 100);
|
|
2647
|
+
options.onValueChange?.(newPercent);
|
|
2648
|
+
} };
|
|
2649
|
+
}
|
|
2650
|
+
|
|
2651
|
+
//#endregion
|
|
2652
|
+
//#region ../core/dist/dev/dom/utils/element-props.js
|
|
2653
|
+
/**
|
|
2654
|
+
* Apply props to a DOM element.
|
|
2655
|
+
*
|
|
2656
|
+
* Handles both attributes and event listeners:
|
|
2657
|
+
* - Event props (onClick, onKeyDown, etc.) are attached as listeners
|
|
2658
|
+
* - Boolean props: `true` sets empty attribute, `false` removes
|
|
2659
|
+
* - `undefined` removes the attribute
|
|
2660
|
+
* - Other props are set as string attributes
|
|
2661
|
+
*/
|
|
2662
|
+
function applyElementProps(element, props, options) {
|
|
2663
|
+
const signal = options?.signal;
|
|
2664
|
+
for (const [key, value] of Object.entries(props)) if (isFunction(value) && key.startsWith("on")) listen(element, key.slice(2).toLowerCase(), value, signal ? { signal } : void 0);
|
|
2665
|
+
else if (isUndefined(value) || value === false) element.removeAttribute(key);
|
|
2666
|
+
else if (value === true) element.setAttribute(key, "");
|
|
2667
|
+
else element.setAttribute(key, String(value));
|
|
2668
|
+
}
|
|
2669
|
+
|
|
2670
|
+
//#endregion
|
|
2671
|
+
//#region ../core/dist/dev/dom/utils/log.js
|
|
2672
|
+
const warned = /* @__PURE__ */ new Set();
|
|
2673
|
+
function logMissingFeature(displayName, featureName) {
|
|
2674
|
+
const key = `${displayName}:${featureName}`;
|
|
2675
|
+
if (warned.has(key)) return;
|
|
2676
|
+
warned.add(key);
|
|
2677
|
+
console.warn(`${displayName} requires ${featureName} feature`);
|
|
2678
|
+
}
|
|
2679
|
+
|
|
2680
|
+
//#endregion
|
|
2681
|
+
//#region ../core/dist/dev/dom/utils/state-data-attrs.js
|
|
2682
|
+
/**
|
|
2683
|
+
* Apply state as data attributes to an element.
|
|
2684
|
+
*
|
|
2685
|
+
* - `true` → sets `data-keyname=""`
|
|
2686
|
+
* - truthy string/number → sets `data-keyname="value"`
|
|
2687
|
+
* - falsy → removes the attribute
|
|
2688
|
+
*
|
|
2689
|
+
* @example
|
|
2690
|
+
* ```ts
|
|
2691
|
+
* const state = { paused: true, ended: false };
|
|
2692
|
+
* applyStateDataAttrs(element, state);
|
|
2693
|
+
* // element has data-paused="", data-ended is removed
|
|
2694
|
+
* ```
|
|
2695
|
+
*/
|
|
2696
|
+
function applyStateDataAttrs(element, state, map) {
|
|
2697
|
+
for (const key in state) {
|
|
2698
|
+
if (map && !(key in map)) continue;
|
|
2699
|
+
const name = map?.[key] ?? toDataAttrName(key), value = state[key];
|
|
2700
|
+
if (value === true) element.setAttribute(name, "");
|
|
2701
|
+
else if (value) element.setAttribute(name, String(value));
|
|
2702
|
+
else element.removeAttribute(name);
|
|
2703
|
+
}
|
|
2704
|
+
}
|
|
2705
|
+
function toDataAttrName(key) {
|
|
2706
|
+
return `data-${key.toLowerCase()}`;
|
|
2707
|
+
}
|
|
2708
|
+
|
|
2709
|
+
//#endregion
|
|
2710
|
+
//#region src/ui/hotkey/aria-key-shortcuts-controller.ts
|
|
2711
|
+
/** Provides `aria-keyshortcuts` for a given hotkey action name. */
|
|
2712
|
+
var AriaKeyShortcutsController = class {
|
|
2713
|
+
#action;
|
|
2714
|
+
#container;
|
|
2715
|
+
constructor(host, action) {
|
|
2716
|
+
this.#action = action;
|
|
2717
|
+
this.#container = new ContextConsumer(host, {
|
|
2718
|
+
context: containerContext,
|
|
2719
|
+
subscribe: true
|
|
2720
|
+
});
|
|
2721
|
+
host.addController(this);
|
|
2722
|
+
}
|
|
2723
|
+
get value() {
|
|
2724
|
+
const container = this.#container.value?.container;
|
|
2725
|
+
if (!container) return void 0;
|
|
2726
|
+
return findHotkeyCoordinator(container)?.getAriaKeys(this.#action);
|
|
2727
|
+
}
|
|
2728
|
+
hostConnected() {}
|
|
2729
|
+
hostDisconnected() {}
|
|
2730
|
+
};
|
|
2731
|
+
|
|
2732
|
+
//#endregion
|
|
2733
|
+
//#region src/ui/media-button-element.ts
|
|
2734
|
+
/** Abstract base for HTML custom elements that render a media-control button. */
|
|
2735
|
+
var MediaButtonElement = class extends MediaElement {
|
|
2736
|
+
constructor(..._args) {
|
|
2737
|
+
super(..._args);
|
|
2738
|
+
this.disabled = false;
|
|
2739
|
+
this.label = "";
|
|
2740
|
+
this.hotkeyAction = void 0;
|
|
2741
|
+
}
|
|
1417
2742
|
static {
|
|
1418
|
-
this.
|
|
2743
|
+
this.properties = {
|
|
2744
|
+
label: { type: String },
|
|
2745
|
+
disabled: { type: Boolean }
|
|
2746
|
+
};
|
|
1419
2747
|
}
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
#titleId = `vjs-error-dialog-title-${idCounter++}`;
|
|
1423
|
-
#descriptionId = `vjs-error-dialog-desc-${idCounter++}`;
|
|
1424
|
-
#errorState = new PlayerController(this, playerContext, selectError);
|
|
1425
|
-
#dialog = null;
|
|
1426
|
-
#snapshot = null;
|
|
1427
|
-
#lastErrorMessage = null;
|
|
1428
|
-
constructor() {
|
|
1429
|
-
super();
|
|
1430
|
-
this.#core.setTitleId(this.#titleId);
|
|
1431
|
-
this.#core.setDescriptionId(this.#descriptionId);
|
|
2748
|
+
get $state() {
|
|
2749
|
+
return this.core.state;
|
|
1432
2750
|
}
|
|
2751
|
+
#disconnect = null;
|
|
2752
|
+
#hotkeyRegistry = null;
|
|
1433
2753
|
connectedCallback() {
|
|
1434
2754
|
super.connectedCallback();
|
|
1435
|
-
this
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
2755
|
+
if (this.destroyed) return;
|
|
2756
|
+
if (this.hotkeyAction && !this.#hotkeyRegistry) this.#hotkeyRegistry = new AriaKeyShortcutsController(this, this.hotkeyAction);
|
|
2757
|
+
this.#disconnect = new AbortController();
|
|
2758
|
+
const buttonProps = createButton({
|
|
2759
|
+
onActivate: () => this.activate(this.mediaState.value),
|
|
2760
|
+
isDisabled: () => this.disabled || !this.mediaState.value
|
|
1440
2761
|
});
|
|
1441
|
-
this.#
|
|
1442
|
-
if (this
|
|
1443
|
-
else this.#snapshot = new SnapshotController(this, this.#dialog.input);
|
|
2762
|
+
applyElementProps(this, buttonProps, { signal: this.#disconnect.signal });
|
|
2763
|
+
if (!this.mediaState.value && this.mediaState.displayName) logMissingFeature(this.localName, this.mediaState.displayName);
|
|
1444
2764
|
}
|
|
1445
2765
|
disconnectedCallback() {
|
|
1446
2766
|
super.disconnectedCallback();
|
|
1447
|
-
this.#
|
|
1448
|
-
this.#
|
|
2767
|
+
this.#disconnect?.abort();
|
|
2768
|
+
this.#disconnect = null;
|
|
1449
2769
|
}
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
const errorState = this.#errorState.value;
|
|
1454
|
-
const hasError = Boolean(errorState?.error);
|
|
1455
|
-
const { active: isOpen } = this.#dialog.input.current;
|
|
1456
|
-
if (errorState?.error) this.#lastErrorMessage = errorState.error.message?.trim() || null;
|
|
1457
|
-
const desc = this.querySelector("media-alert-dialog-description");
|
|
1458
|
-
if (desc) desc.textContent = this.#lastErrorMessage ?? FALLBACK_MESSAGE;
|
|
1459
|
-
if (hasError && !isOpen) this.#dialog.open();
|
|
1460
|
-
else if (!hasError && isOpen) this.#dialog.close();
|
|
2770
|
+
/** Returns the button's current label derived from media state. */
|
|
2771
|
+
getLabel() {
|
|
2772
|
+
return this.core.state.current.label || void 0;
|
|
1461
2773
|
}
|
|
1462
|
-
|
|
1463
|
-
super.
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
this
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
2774
|
+
willUpdate(changed) {
|
|
2775
|
+
super.willUpdate(changed);
|
|
2776
|
+
this.core.setProps?.(this);
|
|
2777
|
+
}
|
|
2778
|
+
update(changed) {
|
|
2779
|
+
super.update(changed);
|
|
2780
|
+
const media = this.mediaState.value;
|
|
2781
|
+
if (!media) return;
|
|
2782
|
+
this.core.setMedia(media);
|
|
2783
|
+
const state = this.core.getState();
|
|
2784
|
+
applyElementProps(this, {
|
|
2785
|
+
...this.core.getAttrs?.(state),
|
|
2786
|
+
"aria-keyshortcuts": this.#hotkeyRegistry?.value
|
|
1474
2787
|
});
|
|
2788
|
+
applyStateDataAttrs(this, state, this.stateAttrMap);
|
|
1475
2789
|
}
|
|
1476
2790
|
};
|
|
1477
2791
|
|
|
1478
|
-
//#endregion
|
|
1479
|
-
//#region src/define/ui/error-dialog.ts
|
|
1480
|
-
safeDefine(ErrorDialogElement);
|
|
1481
|
-
safeDefine(AlertDialogCloseElement);
|
|
1482
|
-
safeDefine(AlertDialogDescriptionElement);
|
|
1483
|
-
safeDefine(AlertDialogTitleElement);
|
|
1484
|
-
|
|
1485
2792
|
//#endregion
|
|
1486
2793
|
//#region src/ui/mute-button/mute-button-element.ts
|
|
1487
2794
|
var MuteButtonElement = class extends MediaButtonElement {
|
|
@@ -1490,6 +2797,7 @@ var MuteButtonElement = class extends MediaButtonElement {
|
|
|
1490
2797
|
this.core = new MuteButtonCore();
|
|
1491
2798
|
this.stateAttrMap = MuteButtonDataAttrs;
|
|
1492
2799
|
this.mediaState = new PlayerController(this, playerContext, selectVolume);
|
|
2800
|
+
this.hotkeyAction = "toggleMuted";
|
|
1493
2801
|
}
|
|
1494
2802
|
static {
|
|
1495
2803
|
this.tagName = "media-mute-button";
|
|
@@ -1499,10 +2807,6 @@ var MuteButtonElement = class extends MediaButtonElement {
|
|
|
1499
2807
|
}
|
|
1500
2808
|
};
|
|
1501
2809
|
|
|
1502
|
-
//#endregion
|
|
1503
|
-
//#region src/define/ui/mute-button.ts
|
|
1504
|
-
safeDefine(MuteButtonElement);
|
|
1505
|
-
|
|
1506
2810
|
//#endregion
|
|
1507
2811
|
//#region src/ui/play-button/play-button-element.ts
|
|
1508
2812
|
var PlayButtonElement = class extends MediaButtonElement {
|
|
@@ -1511,6 +2815,7 @@ var PlayButtonElement = class extends MediaButtonElement {
|
|
|
1511
2815
|
this.core = new PlayButtonCore();
|
|
1512
2816
|
this.stateAttrMap = PlayButtonDataAttrs;
|
|
1513
2817
|
this.mediaState = new PlayerController(this, playerContext, selectPlayback);
|
|
2818
|
+
this.hotkeyAction = "togglePaused";
|
|
1514
2819
|
}
|
|
1515
2820
|
static {
|
|
1516
2821
|
this.tagName = "media-play-button";
|
|
@@ -1520,49 +2825,306 @@ var PlayButtonElement = class extends MediaButtonElement {
|
|
|
1520
2825
|
}
|
|
1521
2826
|
};
|
|
1522
2827
|
|
|
1523
|
-
//#endregion
|
|
1524
|
-
//#region src/define/ui/play-button.ts
|
|
1525
|
-
safeDefine(PlayButtonElement);
|
|
1526
|
-
|
|
1527
2828
|
//#endregion
|
|
1528
2829
|
//#region src/ui/playback-rate-button/playback-rate-button-element.ts
|
|
1529
2830
|
var PlaybackRateButtonElement = class extends MediaButtonElement {
|
|
1530
2831
|
constructor(..._args) {
|
|
1531
2832
|
super(..._args);
|
|
1532
|
-
this.core = new PlaybackRateButtonCore();
|
|
1533
|
-
this.stateAttrMap = PlaybackRateButtonDataAttrs;
|
|
1534
|
-
this.mediaState = new PlayerController(this, playerContext, selectPlaybackRate);
|
|
2833
|
+
this.core = new PlaybackRateButtonCore();
|
|
2834
|
+
this.stateAttrMap = PlaybackRateButtonDataAttrs;
|
|
2835
|
+
this.mediaState = new PlayerController(this, playerContext, selectPlaybackRate);
|
|
2836
|
+
}
|
|
2837
|
+
static {
|
|
2838
|
+
this.tagName = "media-playback-rate-button";
|
|
2839
|
+
}
|
|
2840
|
+
activate(state) {
|
|
2841
|
+
this.core.cycle(state);
|
|
2842
|
+
}
|
|
2843
|
+
};
|
|
2844
|
+
|
|
2845
|
+
//#endregion
|
|
2846
|
+
//#region src/ui/position-controller.ts
|
|
2847
|
+
/**
|
|
2848
|
+
* Reactive controller that manages JS-fallback positioning for floating
|
|
2849
|
+
* popup elements (tooltips, popovers). Tracks scroll, resize, and
|
|
2850
|
+
* ResizeObserver events to keep the popup aligned with its trigger.
|
|
2851
|
+
*
|
|
2852
|
+
* When native CSS Anchor Positioning is supported, `sync()` is a no-op.
|
|
2853
|
+
*/
|
|
2854
|
+
var PositionController = class {
|
|
2855
|
+
#host;
|
|
2856
|
+
#abort = null;
|
|
2857
|
+
#frame = 0;
|
|
2858
|
+
#resizeObserver = null;
|
|
2859
|
+
#trigger = null;
|
|
2860
|
+
constructor(host) {
|
|
2861
|
+
this.#host = host;
|
|
2862
|
+
host.addController(this);
|
|
2863
|
+
}
|
|
2864
|
+
/** Discover a trigger element linked via `commandfor` attribute. */
|
|
2865
|
+
findTrigger() {
|
|
2866
|
+
if (!this.#host.id) return null;
|
|
2867
|
+
return this.#host.getRootNode().querySelector(`[commandfor="${this.#host.id}"]`);
|
|
2868
|
+
}
|
|
2869
|
+
/** Start or update position tracking for the given trigger. */
|
|
2870
|
+
sync(trigger) {
|
|
2871
|
+
if (supportsAnchorPositioning()) return;
|
|
2872
|
+
if (!trigger) return;
|
|
2873
|
+
if (this.#abort && this.#trigger === trigger) return;
|
|
2874
|
+
this.cleanup();
|
|
2875
|
+
this.#abort = new AbortController();
|
|
2876
|
+
this.#trigger = trigger;
|
|
2877
|
+
const { signal } = this.#abort;
|
|
2878
|
+
const reposition = () => {
|
|
2879
|
+
cancelAnimationFrame(this.#frame);
|
|
2880
|
+
this.#frame = requestAnimationFrame(() => {
|
|
2881
|
+
if (signal.aborted) return;
|
|
2882
|
+
this.#host.requestUpdate();
|
|
2883
|
+
});
|
|
2884
|
+
};
|
|
2885
|
+
window.addEventListener("scroll", reposition, {
|
|
2886
|
+
capture: true,
|
|
2887
|
+
passive: true,
|
|
2888
|
+
signal
|
|
2889
|
+
});
|
|
2890
|
+
window.addEventListener("resize", reposition, { signal });
|
|
2891
|
+
if (typeof ResizeObserver === "function") {
|
|
2892
|
+
this.#resizeObserver = new ResizeObserver(() => {
|
|
2893
|
+
reposition();
|
|
2894
|
+
});
|
|
2895
|
+
this.#resizeObserver.observe(trigger);
|
|
2896
|
+
this.#resizeObserver.observe(this.#host);
|
|
2897
|
+
}
|
|
2898
|
+
reposition();
|
|
2899
|
+
}
|
|
2900
|
+
/** Stop all position tracking. */
|
|
2901
|
+
cleanup() {
|
|
2902
|
+
this.#abort?.abort();
|
|
2903
|
+
this.#abort = null;
|
|
2904
|
+
this.#trigger = null;
|
|
2905
|
+
cancelAnimationFrame(this.#frame);
|
|
2906
|
+
this.#frame = 0;
|
|
2907
|
+
this.#resizeObserver?.disconnect();
|
|
2908
|
+
this.#resizeObserver = null;
|
|
2909
|
+
}
|
|
2910
|
+
hostDisconnected() {
|
|
2911
|
+
this.cleanup();
|
|
2912
|
+
}
|
|
2913
|
+
hostDestroyed() {
|
|
2914
|
+
this.cleanup();
|
|
2915
|
+
}
|
|
2916
|
+
};
|
|
2917
|
+
|
|
2918
|
+
//#endregion
|
|
2919
|
+
//#region src/ui/popover/popover-element.ts
|
|
2920
|
+
var PopoverElement = class extends MediaElement {
|
|
2921
|
+
constructor(..._args) {
|
|
2922
|
+
super(..._args);
|
|
2923
|
+
this.open = PopoverCore.defaultProps.open;
|
|
2924
|
+
this.defaultOpen = PopoverCore.defaultProps.defaultOpen;
|
|
2925
|
+
this.side = PopoverCore.defaultProps.side;
|
|
2926
|
+
this.align = PopoverCore.defaultProps.align;
|
|
2927
|
+
this.modal = PopoverCore.defaultProps.modal;
|
|
2928
|
+
this.closeOnEscape = PopoverCore.defaultProps.closeOnEscape;
|
|
2929
|
+
this.closeOnOutsideClick = PopoverCore.defaultProps.closeOnOutsideClick;
|
|
2930
|
+
this.openOnHover = PopoverCore.defaultProps.openOnHover;
|
|
2931
|
+
this.delay = PopoverCore.defaultProps.delay;
|
|
2932
|
+
this.closeDelay = PopoverCore.defaultProps.closeDelay;
|
|
2933
|
+
}
|
|
2934
|
+
static {
|
|
2935
|
+
this.tagName = "media-popover";
|
|
2936
|
+
}
|
|
2937
|
+
static {
|
|
2938
|
+
this.properties = {
|
|
2939
|
+
open: { type: Boolean },
|
|
2940
|
+
defaultOpen: {
|
|
2941
|
+
type: Boolean,
|
|
2942
|
+
attribute: "default-open"
|
|
2943
|
+
},
|
|
2944
|
+
side: { type: String },
|
|
2945
|
+
align: { type: String },
|
|
2946
|
+
modal: { type: Boolean },
|
|
2947
|
+
closeOnEscape: {
|
|
2948
|
+
type: Boolean,
|
|
2949
|
+
attribute: "close-on-escape"
|
|
2950
|
+
},
|
|
2951
|
+
closeOnOutsideClick: {
|
|
2952
|
+
type: Boolean,
|
|
2953
|
+
attribute: "close-on-outside-click"
|
|
2954
|
+
},
|
|
2955
|
+
openOnHover: {
|
|
2956
|
+
type: Boolean,
|
|
2957
|
+
attribute: "open-on-hover"
|
|
2958
|
+
},
|
|
2959
|
+
delay: { type: Number },
|
|
2960
|
+
closeDelay: {
|
|
2961
|
+
type: Number,
|
|
2962
|
+
attribute: "close-delay"
|
|
2963
|
+
}
|
|
2964
|
+
};
|
|
2965
|
+
}
|
|
2966
|
+
#core = new PopoverCore();
|
|
2967
|
+
#position = new PositionController(this);
|
|
2968
|
+
#popover = null;
|
|
2969
|
+
#snapshot = null;
|
|
2970
|
+
#disconnect = null;
|
|
2971
|
+
#triggerAbort = null;
|
|
2972
|
+
#currentTrigger = null;
|
|
2973
|
+
connectedCallback() {
|
|
2974
|
+
super.connectedCallback();
|
|
2975
|
+
if (this.destroyed) return;
|
|
2976
|
+
this.#disconnect = new AbortController();
|
|
2977
|
+
this.#popover = createPopover({
|
|
2978
|
+
transition: createTransition(),
|
|
2979
|
+
onOpenChange: (nextOpen, details) => {
|
|
2980
|
+
this.open = nextOpen;
|
|
2981
|
+
this.dispatchEvent(new CustomEvent("open-change", { detail: {
|
|
2982
|
+
open: nextOpen,
|
|
2983
|
+
...details
|
|
2984
|
+
} }));
|
|
2985
|
+
},
|
|
2986
|
+
closeOnEscape: () => this.closeOnEscape,
|
|
2987
|
+
closeOnOutsideClick: () => this.closeOnOutsideClick,
|
|
2988
|
+
openOnHover: () => this.openOnHover,
|
|
2989
|
+
delay: () => this.delay,
|
|
2990
|
+
closeDelay: () => this.closeDelay
|
|
2991
|
+
});
|
|
2992
|
+
this.#popover.setPopupElement(this);
|
|
2993
|
+
applyElementProps(this, this.#popover.popupProps, { signal: this.#disconnect.signal });
|
|
2994
|
+
if (this.#snapshot) this.#snapshot.track(this.#popover.input);
|
|
2995
|
+
else this.#snapshot = new SnapshotController(this, this.#popover.input);
|
|
2996
|
+
}
|
|
2997
|
+
firstUpdated(changed) {
|
|
2998
|
+
super.firstUpdated(changed);
|
|
2999
|
+
if (this.defaultOpen && !this.open) this.#popover?.open();
|
|
3000
|
+
}
|
|
3001
|
+
disconnectedCallback() {
|
|
3002
|
+
super.disconnectedCallback();
|
|
3003
|
+
this.#disconnect?.abort();
|
|
3004
|
+
this.#disconnect = null;
|
|
3005
|
+
}
|
|
3006
|
+
destroyCallback() {
|
|
3007
|
+
this.#cleanupTrigger();
|
|
3008
|
+
this.#popover?.destroy();
|
|
3009
|
+
super.destroyCallback();
|
|
3010
|
+
}
|
|
3011
|
+
willUpdate(changed) {
|
|
3012
|
+
super.willUpdate(changed);
|
|
3013
|
+
this.#core.setProps(this);
|
|
3014
|
+
if (this.#popover && changed.has("open")) {
|
|
3015
|
+
const { active: interactionOpen } = this.#popover.input.current;
|
|
3016
|
+
if (this.open !== interactionOpen) if (this.open) this.#popover.open();
|
|
3017
|
+
else this.#popover.close();
|
|
3018
|
+
}
|
|
3019
|
+
}
|
|
3020
|
+
update(_changed) {
|
|
3021
|
+
super.update(_changed);
|
|
3022
|
+
if (!this.#popover) return;
|
|
3023
|
+
const triggerEl = this.#position.findTrigger();
|
|
3024
|
+
this.#syncTrigger(triggerEl);
|
|
3025
|
+
const input = this.#popover.input.current;
|
|
3026
|
+
this.#core.setInput(input);
|
|
3027
|
+
const state = this.#core.getState();
|
|
3028
|
+
applyElementProps(this, this.#core.getPopupAttrs(state));
|
|
3029
|
+
applyStateDataAttrs(this, state, PopoverDataAttrs);
|
|
3030
|
+
if (state.open) tryShowPopover(this);
|
|
3031
|
+
else tryHidePopover(this);
|
|
3032
|
+
if (this.#currentTrigger) {
|
|
3033
|
+
applyElementProps(this.#currentTrigger, this.#core.getTriggerAttrs(state, this.id));
|
|
3034
|
+
applyStyles(this.#currentTrigger, getAnchorNameStyle(this.id));
|
|
3035
|
+
}
|
|
3036
|
+
if (!state.open) {
|
|
3037
|
+
this.#position.cleanup();
|
|
3038
|
+
return;
|
|
3039
|
+
}
|
|
3040
|
+
const posOpts = {
|
|
3041
|
+
side: state.side,
|
|
3042
|
+
align: state.align
|
|
3043
|
+
};
|
|
3044
|
+
if (supportsAnchorPositioning()) applyStyles(this, getAnchorPositionStyle(this.id, posOpts));
|
|
3045
|
+
else {
|
|
3046
|
+
const triggerRect = this.#currentTrigger?.getBoundingClientRect();
|
|
3047
|
+
const selfRect = getPopupPositionRect(this);
|
|
3048
|
+
const boundaryRect = document.documentElement.getBoundingClientRect();
|
|
3049
|
+
const offsets = resolveOffsets(this);
|
|
3050
|
+
applyStyles(this, getAnchorPositionStyle(this.id, posOpts, triggerRect, selfRect, boundaryRect, offsets));
|
|
3051
|
+
}
|
|
3052
|
+
this.#position.sync(this.#currentTrigger);
|
|
3053
|
+
}
|
|
3054
|
+
#syncTrigger(triggerEl) {
|
|
3055
|
+
if (triggerEl === this.#currentTrigger) return;
|
|
3056
|
+
this.#position.cleanup();
|
|
3057
|
+
this.#cleanupTrigger();
|
|
3058
|
+
this.#currentTrigger = triggerEl;
|
|
3059
|
+
this.#popover?.setTriggerElement(triggerEl);
|
|
3060
|
+
if (triggerEl && this.#popover) {
|
|
3061
|
+
this.#triggerAbort = new AbortController();
|
|
3062
|
+
applyElementProps(triggerEl, this.#popover.triggerProps, { signal: this.#triggerAbort.signal });
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
3065
|
+
#cleanupTrigger() {
|
|
3066
|
+
if (this.#currentTrigger) {
|
|
3067
|
+
applyElementProps(this.#currentTrigger, {
|
|
3068
|
+
"aria-expanded": void 0,
|
|
3069
|
+
"aria-haspopup": void 0,
|
|
3070
|
+
"aria-controls": void 0
|
|
3071
|
+
});
|
|
3072
|
+
this.#currentTrigger.style.removeProperty("anchor-name");
|
|
3073
|
+
}
|
|
3074
|
+
this.#triggerAbort?.abort();
|
|
3075
|
+
this.#triggerAbort = null;
|
|
3076
|
+
this.#currentTrigger = null;
|
|
3077
|
+
}
|
|
3078
|
+
};
|
|
3079
|
+
|
|
3080
|
+
//#endregion
|
|
3081
|
+
//#region src/ui/seek-button/seek-button-element.ts
|
|
3082
|
+
var SeekButtonElement = class extends MediaButtonElement {
|
|
3083
|
+
constructor(..._args) {
|
|
3084
|
+
super(..._args);
|
|
3085
|
+
this.seconds = SeekButtonCore.defaultProps.seconds;
|
|
3086
|
+
this.core = new SeekButtonCore();
|
|
3087
|
+
this.stateAttrMap = SeekButtonDataAttrs;
|
|
3088
|
+
this.mediaState = new PlayerController(this, playerContext, selectTime);
|
|
1535
3089
|
}
|
|
1536
3090
|
static {
|
|
1537
|
-
this.tagName = "media-
|
|
3091
|
+
this.tagName = "media-seek-button";
|
|
3092
|
+
}
|
|
3093
|
+
static {
|
|
3094
|
+
this.properties = {
|
|
3095
|
+
...MediaButtonElement.properties,
|
|
3096
|
+
seconds: { type: Number }
|
|
3097
|
+
};
|
|
1538
3098
|
}
|
|
1539
3099
|
activate(state) {
|
|
1540
|
-
this.core.
|
|
3100
|
+
this.core.seek(state);
|
|
1541
3101
|
}
|
|
1542
3102
|
};
|
|
1543
3103
|
|
|
1544
3104
|
//#endregion
|
|
1545
|
-
//#region src/
|
|
1546
|
-
|
|
3105
|
+
//#region src/ui/tooltip/context.ts
|
|
3106
|
+
const TOOLTIP_GROUP_CONTEXT_KEY = Symbol("@videojs/tooltip-group");
|
|
3107
|
+
const tooltipGroupContext = createContext(TOOLTIP_GROUP_CONTEXT_KEY);
|
|
1547
3108
|
|
|
1548
3109
|
//#endregion
|
|
1549
|
-
//#region src/ui/
|
|
1550
|
-
|
|
3110
|
+
//#region src/ui/tooltip/tooltip-element.ts
|
|
3111
|
+
function isLabelTrigger(el) {
|
|
3112
|
+
return "$state" in el;
|
|
3113
|
+
}
|
|
3114
|
+
var TooltipElement = class extends MediaElement {
|
|
1551
3115
|
constructor(..._args) {
|
|
1552
3116
|
super(..._args);
|
|
1553
|
-
this.open =
|
|
1554
|
-
this.defaultOpen =
|
|
1555
|
-
this.side =
|
|
1556
|
-
this.align =
|
|
1557
|
-
this.
|
|
1558
|
-
this.
|
|
1559
|
-
this.
|
|
1560
|
-
this.
|
|
1561
|
-
this.delay = PopoverCore.defaultProps.delay;
|
|
1562
|
-
this.closeDelay = PopoverCore.defaultProps.closeDelay;
|
|
3117
|
+
this.open = TooltipCore.defaultProps.open;
|
|
3118
|
+
this.defaultOpen = TooltipCore.defaultProps.defaultOpen;
|
|
3119
|
+
this.side = TooltipCore.defaultProps.side;
|
|
3120
|
+
this.align = TooltipCore.defaultProps.align;
|
|
3121
|
+
this.delay = TooltipCore.defaultProps.delay;
|
|
3122
|
+
this.closeDelay = TooltipCore.defaultProps.closeDelay;
|
|
3123
|
+
this.disableHoverablePopup = TooltipCore.defaultProps.disableHoverablePopup;
|
|
3124
|
+
this.disabled = TooltipCore.defaultProps.disabled;
|
|
1563
3125
|
}
|
|
1564
3126
|
static {
|
|
1565
|
-
this.tagName = "media-
|
|
3127
|
+
this.tagName = "media-tooltip";
|
|
1566
3128
|
}
|
|
1567
3129
|
static {
|
|
1568
3130
|
this.properties = {
|
|
@@ -1573,41 +3135,31 @@ var PopoverElement = class extends MediaElement {
|
|
|
1573
3135
|
},
|
|
1574
3136
|
side: { type: String },
|
|
1575
3137
|
align: { type: String },
|
|
1576
|
-
modal: { type: Boolean },
|
|
1577
|
-
closeOnEscape: {
|
|
1578
|
-
type: Boolean,
|
|
1579
|
-
attribute: "close-on-escape"
|
|
1580
|
-
},
|
|
1581
|
-
closeOnOutsideClick: {
|
|
1582
|
-
type: Boolean,
|
|
1583
|
-
attribute: "close-on-outside-click"
|
|
1584
|
-
},
|
|
1585
|
-
openOnHover: {
|
|
1586
|
-
type: Boolean,
|
|
1587
|
-
attribute: "open-on-hover"
|
|
1588
|
-
},
|
|
1589
3138
|
delay: { type: Number },
|
|
1590
3139
|
closeDelay: {
|
|
1591
3140
|
type: Number,
|
|
1592
3141
|
attribute: "close-delay"
|
|
1593
|
-
}
|
|
3142
|
+
},
|
|
3143
|
+
disableHoverablePopup: {
|
|
3144
|
+
type: Boolean,
|
|
3145
|
+
attribute: "disable-hoverable-popup"
|
|
3146
|
+
},
|
|
3147
|
+
disabled: { type: Boolean }
|
|
1594
3148
|
};
|
|
1595
3149
|
}
|
|
1596
|
-
#core = new
|
|
1597
|
-
#
|
|
3150
|
+
#core = new TooltipCore();
|
|
3151
|
+
#groupConsumer = new ContextConsumer(this, { context: tooltipGroupContext });
|
|
3152
|
+
#position = new PositionController(this);
|
|
3153
|
+
#tooltip = null;
|
|
1598
3154
|
#snapshot = null;
|
|
1599
3155
|
#disconnect = null;
|
|
1600
3156
|
#triggerAbort = null;
|
|
1601
3157
|
#currentTrigger = null;
|
|
1602
|
-
#positionAbort = null;
|
|
1603
|
-
#positionFrame = 0;
|
|
1604
|
-
#resizeObserver = null;
|
|
1605
|
-
#positionTrigger = null;
|
|
1606
3158
|
connectedCallback() {
|
|
1607
3159
|
super.connectedCallback();
|
|
1608
3160
|
if (this.destroyed) return;
|
|
1609
3161
|
this.#disconnect = new AbortController();
|
|
1610
|
-
this.#
|
|
3162
|
+
this.#tooltip = createTooltip({
|
|
1611
3163
|
transition: createTransition(),
|
|
1612
3164
|
onOpenChange: (nextOpen, details) => {
|
|
1613
3165
|
this.open = nextOpen;
|
|
@@ -1616,259 +3168,354 @@ var PopoverElement = class extends MediaElement {
|
|
|
1616
3168
|
...details
|
|
1617
3169
|
} }));
|
|
1618
3170
|
},
|
|
1619
|
-
closeOnEscape: () => this.closeOnEscape,
|
|
1620
|
-
closeOnOutsideClick: () => this.closeOnOutsideClick,
|
|
1621
|
-
openOnHover: () => this.openOnHover,
|
|
1622
3171
|
delay: () => this.delay,
|
|
1623
|
-
closeDelay: () => this.closeDelay
|
|
3172
|
+
closeDelay: () => this.closeDelay,
|
|
3173
|
+
disableHoverablePopup: () => this.disableHoverablePopup,
|
|
3174
|
+
disabled: () => this.disabled,
|
|
3175
|
+
group: () => this.#groupConsumer.value
|
|
1624
3176
|
});
|
|
1625
|
-
this.#
|
|
1626
|
-
applyElementProps(this, this.#
|
|
1627
|
-
if (this.#snapshot) this.#snapshot.track(this.#
|
|
1628
|
-
else this.#snapshot = new SnapshotController(this, this.#
|
|
3177
|
+
this.#tooltip.setPopupElement(this);
|
|
3178
|
+
applyElementProps(this, this.#tooltip.popupProps, { signal: this.#disconnect.signal });
|
|
3179
|
+
if (this.#snapshot) this.#snapshot.track(this.#tooltip.input);
|
|
3180
|
+
else this.#snapshot = new SnapshotController(this, this.#tooltip.input);
|
|
1629
3181
|
}
|
|
1630
3182
|
firstUpdated(changed) {
|
|
1631
3183
|
super.firstUpdated(changed);
|
|
1632
|
-
if (this.defaultOpen && !this.open) this.#
|
|
3184
|
+
if (this.defaultOpen && !this.open) this.#tooltip?.open();
|
|
1633
3185
|
}
|
|
1634
3186
|
disconnectedCallback() {
|
|
1635
3187
|
super.disconnectedCallback();
|
|
1636
|
-
this.#
|
|
3188
|
+
this.#cleanupTrigger();
|
|
3189
|
+
this.#tooltip?.destroy();
|
|
3190
|
+
this.#tooltip = null;
|
|
1637
3191
|
this.#disconnect?.abort();
|
|
1638
3192
|
this.#disconnect = null;
|
|
1639
3193
|
}
|
|
1640
|
-
destroyCallback() {
|
|
1641
|
-
this.#cleanupPositioning();
|
|
1642
|
-
this.#cleanupTrigger();
|
|
1643
|
-
this.#popover?.destroy();
|
|
1644
|
-
super.destroyCallback();
|
|
1645
|
-
}
|
|
1646
3194
|
willUpdate(changed) {
|
|
1647
3195
|
super.willUpdate(changed);
|
|
1648
3196
|
this.#core.setProps(this);
|
|
1649
|
-
if (this.#
|
|
1650
|
-
const { active: interactionOpen } = this.#
|
|
1651
|
-
if (this.open !== interactionOpen) if (this.open) this.#
|
|
1652
|
-
else this.#
|
|
3197
|
+
if (this.#tooltip && changed.has("open")) {
|
|
3198
|
+
const { active: interactionOpen } = this.#tooltip.input.current;
|
|
3199
|
+
if (this.open !== interactionOpen) if (this.open) this.#tooltip.open();
|
|
3200
|
+
else this.#tooltip.close();
|
|
1653
3201
|
}
|
|
1654
3202
|
}
|
|
1655
3203
|
update(_changed) {
|
|
1656
3204
|
super.update(_changed);
|
|
1657
|
-
if (!this.#
|
|
1658
|
-
const triggerEl = this.#findTrigger();
|
|
3205
|
+
if (!this.#tooltip) return;
|
|
3206
|
+
const triggerEl = this.#position.findTrigger();
|
|
1659
3207
|
this.#syncTrigger(triggerEl);
|
|
1660
|
-
const input = this.#
|
|
3208
|
+
const input = this.#tooltip.input.current;
|
|
1661
3209
|
this.#core.setInput(input);
|
|
1662
3210
|
const state = this.#core.getState();
|
|
1663
3211
|
applyElementProps(this, this.#core.getPopupAttrs(state));
|
|
1664
|
-
applyStateDataAttrs(this, state,
|
|
3212
|
+
applyStateDataAttrs(this, state, TooltipDataAttrs);
|
|
1665
3213
|
if (state.open) tryShowPopover(this);
|
|
1666
3214
|
else tryHidePopover(this);
|
|
1667
|
-
if (this.#currentTrigger)
|
|
1668
|
-
applyElementProps(this.#currentTrigger, this.#core.getTriggerAttrs(state, this.id));
|
|
1669
|
-
applyStyles(this.#currentTrigger, getAnchorNameStyle(this.id));
|
|
1670
|
-
}
|
|
3215
|
+
if (this.#currentTrigger) applyStyles(this.#currentTrigger, getAnchorNameStyle(this.id));
|
|
1671
3216
|
if (!state.open) {
|
|
1672
|
-
this.#
|
|
3217
|
+
this.#position.cleanup();
|
|
1673
3218
|
return;
|
|
1674
3219
|
}
|
|
1675
3220
|
const posOpts = {
|
|
1676
3221
|
side: state.side,
|
|
1677
3222
|
align: state.align
|
|
1678
3223
|
};
|
|
1679
|
-
if (supportsAnchorPositioning()) applyStyles(this, getAnchorPositionStyle(this.id, posOpts));
|
|
3224
|
+
if (supportsAnchorPositioning()) applyStyles(this, getAnchorPositionStyle(this.id, posOpts, void 0, void 0, void 0, void 0, TooltipCSSVars));
|
|
1680
3225
|
else {
|
|
1681
3226
|
const triggerRect = this.#currentTrigger?.getBoundingClientRect();
|
|
1682
3227
|
const selfRect = getPopupPositionRect(this);
|
|
1683
3228
|
const boundaryRect = document.documentElement.getBoundingClientRect();
|
|
1684
|
-
const offsets = resolveOffsets(this);
|
|
1685
|
-
applyStyles(this, getAnchorPositionStyle(this.id, posOpts, triggerRect, selfRect, boundaryRect, offsets));
|
|
3229
|
+
const offsets = resolveOffsets(this, TooltipCSSVars);
|
|
3230
|
+
applyStyles(this, getAnchorPositionStyle(this.id, posOpts, triggerRect, selfRect, boundaryRect, offsets, TooltipCSSVars));
|
|
1686
3231
|
}
|
|
1687
|
-
this.#
|
|
1688
|
-
}
|
|
1689
|
-
#findTrigger() {
|
|
1690
|
-
if (!this.id) return null;
|
|
1691
|
-
return this.getRootNode().querySelector(`[commandfor="${this.id}"]`);
|
|
3232
|
+
this.#position.sync(this.#currentTrigger);
|
|
1692
3233
|
}
|
|
1693
3234
|
#syncTrigger(triggerEl) {
|
|
1694
3235
|
if (triggerEl === this.#currentTrigger) return;
|
|
1695
|
-
this.#
|
|
3236
|
+
this.#position.cleanup();
|
|
1696
3237
|
this.#cleanupTrigger();
|
|
1697
3238
|
this.#currentTrigger = triggerEl;
|
|
1698
|
-
this.#
|
|
1699
|
-
if (triggerEl && this.#
|
|
3239
|
+
this.#tooltip?.setTriggerElement(triggerEl);
|
|
3240
|
+
if (triggerEl && this.#tooltip) {
|
|
1700
3241
|
this.#triggerAbort = new AbortController();
|
|
1701
|
-
applyElementProps(triggerEl, this.#
|
|
3242
|
+
applyElementProps(triggerEl, this.#tooltip.triggerProps, { signal: this.#triggerAbort.signal });
|
|
3243
|
+
if (isLabelTrigger(triggerEl)) {
|
|
3244
|
+
this.#syncContent(triggerEl);
|
|
3245
|
+
triggerEl.$state.subscribe(() => this.#syncContent(triggerEl), { signal: this.#triggerAbort.signal });
|
|
3246
|
+
}
|
|
1702
3247
|
}
|
|
1703
3248
|
}
|
|
3249
|
+
#syncContent(triggerEl) {
|
|
3250
|
+
this.textContent = triggerEl.getLabel() ?? "";
|
|
3251
|
+
}
|
|
1704
3252
|
#cleanupTrigger() {
|
|
1705
|
-
if (this.#currentTrigger)
|
|
1706
|
-
applyElementProps(this.#currentTrigger, {
|
|
1707
|
-
"aria-expanded": void 0,
|
|
1708
|
-
"aria-haspopup": void 0,
|
|
1709
|
-
"aria-controls": void 0
|
|
1710
|
-
});
|
|
1711
|
-
this.#currentTrigger.style.removeProperty("anchor-name");
|
|
1712
|
-
}
|
|
3253
|
+
if (this.#currentTrigger) this.#currentTrigger.style.removeProperty("anchor-name");
|
|
1713
3254
|
this.#triggerAbort?.abort();
|
|
1714
3255
|
this.#triggerAbort = null;
|
|
1715
3256
|
this.#currentTrigger = null;
|
|
1716
3257
|
}
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
this
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
3258
|
+
};
|
|
3259
|
+
|
|
3260
|
+
//#endregion
|
|
3261
|
+
//#region src/ui/tooltip/tooltip-group-element.ts
|
|
3262
|
+
var TooltipGroupElement = class extends MediaElement {
|
|
3263
|
+
constructor(..._args) {
|
|
3264
|
+
super(..._args);
|
|
3265
|
+
this.delay = TooltipGroupCore.defaultProps.delay;
|
|
3266
|
+
this.closeDelay = TooltipGroupCore.defaultProps.closeDelay;
|
|
3267
|
+
this.timeout = TooltipGroupCore.defaultProps.timeout;
|
|
3268
|
+
}
|
|
3269
|
+
static {
|
|
3270
|
+
this.tagName = "media-tooltip-group";
|
|
3271
|
+
}
|
|
3272
|
+
static {
|
|
3273
|
+
this.properties = {
|
|
3274
|
+
delay: { type: Number },
|
|
3275
|
+
closeDelay: {
|
|
3276
|
+
type: Number,
|
|
3277
|
+
attribute: "close-delay"
|
|
3278
|
+
},
|
|
3279
|
+
timeout: { type: Number }
|
|
1732
3280
|
};
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
3281
|
+
}
|
|
3282
|
+
#core = new TooltipGroupCore();
|
|
3283
|
+
#provider = new ContextProvider(this, {
|
|
3284
|
+
context: tooltipGroupContext,
|
|
3285
|
+
initialValue: this.#core
|
|
3286
|
+
});
|
|
3287
|
+
update(_changed) {
|
|
3288
|
+
super.update(_changed);
|
|
3289
|
+
this.#core.setProps(this);
|
|
3290
|
+
this.#provider.setValue(this.#core);
|
|
3291
|
+
}
|
|
3292
|
+
};
|
|
3293
|
+
|
|
3294
|
+
//#endregion
|
|
3295
|
+
//#region src/ui/alert-dialog/context.ts
|
|
3296
|
+
const ALERT_DIALOG_CONTEXT_KEY = Symbol("@videojs/alert-dialog");
|
|
3297
|
+
const alertDialogContext = createContext(ALERT_DIALOG_CONTEXT_KEY);
|
|
3298
|
+
|
|
3299
|
+
//#endregion
|
|
3300
|
+
//#region src/ui/alert-dialog/alert-dialog-close-element.ts
|
|
3301
|
+
var AlertDialogCloseElement = class extends MediaElement {
|
|
3302
|
+
constructor(..._args) {
|
|
3303
|
+
super(..._args);
|
|
3304
|
+
this.disabled = false;
|
|
3305
|
+
}
|
|
3306
|
+
static {
|
|
3307
|
+
this.tagName = "media-alert-dialog-close";
|
|
3308
|
+
}
|
|
3309
|
+
static {
|
|
3310
|
+
this.properties = { disabled: { type: Boolean } };
|
|
3311
|
+
}
|
|
3312
|
+
#ctx = new ContextConsumer(this, {
|
|
3313
|
+
context: alertDialogContext,
|
|
3314
|
+
subscribe: true
|
|
3315
|
+
});
|
|
3316
|
+
#disconnect = null;
|
|
3317
|
+
connectedCallback() {
|
|
3318
|
+
super.connectedCallback();
|
|
3319
|
+
this.#disconnect = new AbortController();
|
|
3320
|
+
const buttonProps = createButton({
|
|
3321
|
+
onActivate: () => this.#ctx.value?.close(),
|
|
3322
|
+
isDisabled: () => this.disabled
|
|
1737
3323
|
});
|
|
1738
|
-
|
|
1739
|
-
if (typeof ResizeObserver === "function") {
|
|
1740
|
-
this.#resizeObserver = new ResizeObserver(() => {
|
|
1741
|
-
reposition();
|
|
1742
|
-
});
|
|
1743
|
-
this.#resizeObserver.observe(triggerEl);
|
|
1744
|
-
this.#resizeObserver.observe(this);
|
|
1745
|
-
}
|
|
1746
|
-
reposition();
|
|
3324
|
+
applyElementProps(this, buttonProps, { signal: this.#disconnect.signal });
|
|
1747
3325
|
}
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
this.#
|
|
1751
|
-
this.#
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
3326
|
+
disconnectedCallback() {
|
|
3327
|
+
super.disconnectedCallback();
|
|
3328
|
+
this.#disconnect?.abort();
|
|
3329
|
+
this.#disconnect = null;
|
|
3330
|
+
}
|
|
3331
|
+
update(_changed) {
|
|
3332
|
+
super.update(_changed);
|
|
3333
|
+
const ctx = this.#ctx.value;
|
|
3334
|
+
if (ctx) applyStateDataAttrs(this, ctx.state, ctx.stateAttrMap);
|
|
3335
|
+
}
|
|
3336
|
+
};
|
|
3337
|
+
|
|
3338
|
+
//#endregion
|
|
3339
|
+
//#region src/ui/context-part-element.ts
|
|
3340
|
+
/**
|
|
3341
|
+
* Abstract base for compound-component part elements that consume a parent
|
|
3342
|
+
* context and apply data attributes from `ctx.state` + `ctx.stateAttrMap`.
|
|
3343
|
+
*
|
|
3344
|
+
* Subclasses only need to declare the `consumer` property:
|
|
3345
|
+
*
|
|
3346
|
+
* ```ts
|
|
3347
|
+
* export class SliderTrackElement extends ContextPartElement<SliderState> {
|
|
3348
|
+
* static readonly tagName = 'media-slider-track';
|
|
3349
|
+
* protected readonly consumer = new ContextConsumer(this, { context: sliderContext, subscribe: true });
|
|
3350
|
+
* }
|
|
3351
|
+
* ```
|
|
3352
|
+
*/
|
|
3353
|
+
var ContextPartElement = class extends MediaElement {
|
|
3354
|
+
update(_changed) {
|
|
3355
|
+
super.update(_changed);
|
|
3356
|
+
const ctx = this.consumer.value;
|
|
3357
|
+
if (ctx) applyStateDataAttrs(this, ctx.state, ctx.stateAttrMap);
|
|
1756
3358
|
}
|
|
1757
3359
|
};
|
|
1758
3360
|
|
|
1759
3361
|
//#endregion
|
|
1760
|
-
//#region src/
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
//#endregion
|
|
1764
|
-
//#region src/ui/seek-button/seek-button-element.ts
|
|
1765
|
-
var SeekButtonElement = class extends MediaButtonElement {
|
|
3362
|
+
//#region src/ui/alert-dialog/alert-dialog-description-element.ts
|
|
3363
|
+
var AlertDialogDescriptionElement = class extends ContextPartElement {
|
|
1766
3364
|
constructor(..._args) {
|
|
1767
3365
|
super(..._args);
|
|
1768
|
-
this.
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
}
|
|
1773
|
-
static {
|
|
1774
|
-
this.tagName = "media-seek-button";
|
|
3366
|
+
this.consumer = new ContextConsumer(this, {
|
|
3367
|
+
context: alertDialogContext,
|
|
3368
|
+
subscribe: true
|
|
3369
|
+
});
|
|
1775
3370
|
}
|
|
1776
3371
|
static {
|
|
1777
|
-
this.
|
|
1778
|
-
...MediaButtonElement.properties,
|
|
1779
|
-
seconds: { type: Number }
|
|
1780
|
-
};
|
|
3372
|
+
this.tagName = "media-alert-dialog-description";
|
|
1781
3373
|
}
|
|
1782
|
-
|
|
1783
|
-
|
|
3374
|
+
update(changed) {
|
|
3375
|
+
super.update(changed);
|
|
3376
|
+
const descriptionId = this.consumer.value?.state.descriptionId;
|
|
3377
|
+
if (descriptionId) this.id = descriptionId;
|
|
1784
3378
|
}
|
|
1785
3379
|
};
|
|
1786
3380
|
|
|
1787
3381
|
//#endregion
|
|
1788
|
-
//#region src/
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
//#endregion
|
|
1792
|
-
//#region src/ui/time/time-element.ts
|
|
1793
|
-
var TimeElement = class extends MediaElement {
|
|
3382
|
+
//#region src/ui/alert-dialog/alert-dialog-title-element.ts
|
|
3383
|
+
var AlertDialogTitleElement = class extends ContextPartElement {
|
|
1794
3384
|
constructor(..._args) {
|
|
1795
3385
|
super(..._args);
|
|
1796
|
-
this.
|
|
1797
|
-
|
|
1798
|
-
|
|
3386
|
+
this.consumer = new ContextConsumer(this, {
|
|
3387
|
+
context: alertDialogContext,
|
|
3388
|
+
subscribe: true
|
|
3389
|
+
});
|
|
1799
3390
|
}
|
|
1800
3391
|
static {
|
|
1801
|
-
this.tagName = "media-
|
|
3392
|
+
this.tagName = "media-alert-dialog-title";
|
|
3393
|
+
}
|
|
3394
|
+
update(changed) {
|
|
3395
|
+
super.update(changed);
|
|
3396
|
+
const titleId = this.consumer.value?.state.titleId;
|
|
3397
|
+
if (titleId) this.id = titleId;
|
|
1802
3398
|
}
|
|
3399
|
+
};
|
|
3400
|
+
|
|
3401
|
+
//#endregion
|
|
3402
|
+
//#region src/ui/controls/context.ts
|
|
3403
|
+
const CONTROLS_CONTEXT_KEY = Symbol("@videojs/controls");
|
|
3404
|
+
const controlsContext = createContext(CONTROLS_CONTEXT_KEY);
|
|
3405
|
+
|
|
3406
|
+
//#endregion
|
|
3407
|
+
//#region src/ui/controls/controls-element.ts
|
|
3408
|
+
var ControlsElement = class extends MediaElement {
|
|
1803
3409
|
static {
|
|
1804
|
-
this.
|
|
1805
|
-
type: { type: String },
|
|
1806
|
-
negativeSign: {
|
|
1807
|
-
type: String,
|
|
1808
|
-
attribute: "negative-sign"
|
|
1809
|
-
},
|
|
1810
|
-
label: { type: String }
|
|
1811
|
-
};
|
|
3410
|
+
this.tagName = "media-controls";
|
|
1812
3411
|
}
|
|
1813
|
-
#core = new
|
|
1814
|
-
#
|
|
1815
|
-
#
|
|
1816
|
-
#textNode = document.createTextNode("");
|
|
3412
|
+
#core = new ControlsCore();
|
|
3413
|
+
#mediaState = new PlayerController(this, playerContext, selectControls);
|
|
3414
|
+
#provider = new ContextProvider(this, { context: controlsContext });
|
|
1817
3415
|
connectedCallback() {
|
|
1818
3416
|
super.connectedCallback();
|
|
1819
|
-
if (!this.#
|
|
1820
|
-
this.#signSpan.setAttribute("aria-hidden", "true");
|
|
1821
|
-
this.#signSpan.hidden = true;
|
|
1822
|
-
this.appendChild(this.#signSpan);
|
|
1823
|
-
this.appendChild(this.#textNode);
|
|
1824
|
-
}
|
|
1825
|
-
if (!this.#state.value) logMissingFeature(this.localName, this.#state.displayName);
|
|
1826
|
-
}
|
|
1827
|
-
willUpdate(changed) {
|
|
1828
|
-
super.willUpdate(changed);
|
|
1829
|
-
this.#core.setProps(this);
|
|
3417
|
+
if (!this.#mediaState.value && this.#mediaState.displayName) logMissingFeature(this.localName, this.#mediaState.displayName);
|
|
1830
3418
|
}
|
|
1831
|
-
update(
|
|
1832
|
-
super.update(
|
|
1833
|
-
const media = this.#
|
|
3419
|
+
update(_changed) {
|
|
3420
|
+
super.update(_changed);
|
|
3421
|
+
const media = this.#mediaState.value;
|
|
1834
3422
|
if (!media) return;
|
|
1835
3423
|
this.#core.setMedia(media);
|
|
1836
3424
|
const state = this.#core.getState();
|
|
1837
|
-
this
|
|
1838
|
-
this.#
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
3425
|
+
applyStateDataAttrs(this, state, ControlsDataAttrs);
|
|
3426
|
+
this.#provider.setValue({
|
|
3427
|
+
state,
|
|
3428
|
+
stateAttrMap: ControlsDataAttrs
|
|
3429
|
+
});
|
|
1842
3430
|
}
|
|
1843
3431
|
};
|
|
1844
3432
|
|
|
1845
3433
|
//#endregion
|
|
1846
|
-
//#region src/ui/
|
|
1847
|
-
var
|
|
3434
|
+
//#region src/ui/controls/controls-group-element.ts
|
|
3435
|
+
var ControlsGroupElement = class extends ContextPartElement {
|
|
3436
|
+
constructor(..._args) {
|
|
3437
|
+
super(..._args);
|
|
3438
|
+
this.consumer = new ContextConsumer(this, {
|
|
3439
|
+
context: controlsContext,
|
|
3440
|
+
subscribe: true
|
|
3441
|
+
});
|
|
3442
|
+
}
|
|
1848
3443
|
static {
|
|
1849
|
-
this.tagName = "media-
|
|
3444
|
+
this.tagName = "media-controls-group";
|
|
3445
|
+
}
|
|
3446
|
+
connectedCallback() {
|
|
3447
|
+
super.connectedCallback();
|
|
3448
|
+
if (this.hasAttribute("aria-label") || this.hasAttribute("aria-labelledby")) this.setAttribute("role", "group");
|
|
1850
3449
|
}
|
|
1851
3450
|
};
|
|
1852
3451
|
|
|
1853
3452
|
//#endregion
|
|
1854
|
-
//#region src/ui/
|
|
1855
|
-
|
|
3453
|
+
//#region src/ui/error-dialog/error-dialog-element.ts
|
|
3454
|
+
const FALLBACK_MESSAGE = "An error occurred. Please try again.";
|
|
3455
|
+
let idCounter = 0;
|
|
3456
|
+
var ErrorDialogElement = class extends MediaElement {
|
|
1856
3457
|
static {
|
|
1857
|
-
this.tagName = "media-
|
|
3458
|
+
this.tagName = "media-error-dialog";
|
|
3459
|
+
}
|
|
3460
|
+
#core = new ErrorDialogCore();
|
|
3461
|
+
#provider = new ContextProvider(this, { context: alertDialogContext });
|
|
3462
|
+
#titleId = `vjs-error-dialog-title-${idCounter++}`;
|
|
3463
|
+
#descriptionId = `vjs-error-dialog-desc-${idCounter++}`;
|
|
3464
|
+
#errorState = new PlayerController(this, playerContext, selectError);
|
|
3465
|
+
#dialog = null;
|
|
3466
|
+
#snapshot = null;
|
|
3467
|
+
#lastErrorMessage = null;
|
|
3468
|
+
constructor() {
|
|
3469
|
+
super();
|
|
3470
|
+
this.#core.setTitleId(this.#titleId);
|
|
3471
|
+
this.#core.setDescriptionId(this.#descriptionId);
|
|
1858
3472
|
}
|
|
1859
3473
|
connectedCallback() {
|
|
1860
3474
|
super.connectedCallback();
|
|
1861
|
-
this.
|
|
1862
|
-
|
|
3475
|
+
if (this.destroyed) return;
|
|
3476
|
+
this.#dialog = createAlertDialog({
|
|
3477
|
+
transition: createTransition(),
|
|
3478
|
+
onOpenChange: (nextOpen) => {
|
|
3479
|
+
if (!nextOpen) this.#errorState.value?.dismissError();
|
|
3480
|
+
}
|
|
3481
|
+
});
|
|
3482
|
+
this.#dialog.setElement(this);
|
|
3483
|
+
if (this.#snapshot) this.#snapshot.track(this.#dialog.input);
|
|
3484
|
+
else this.#snapshot = new SnapshotController(this, this.#dialog.input);
|
|
3485
|
+
}
|
|
3486
|
+
disconnectedCallback() {
|
|
3487
|
+
super.disconnectedCallback();
|
|
3488
|
+
this.#dialog?.destroy();
|
|
3489
|
+
this.#dialog = null;
|
|
3490
|
+
}
|
|
3491
|
+
willUpdate(_changed) {
|
|
3492
|
+
super.willUpdate(_changed);
|
|
3493
|
+
if (!this.#dialog) return;
|
|
3494
|
+
const errorState = this.#errorState.value;
|
|
3495
|
+
const hasError = Boolean(errorState?.error);
|
|
3496
|
+
const { active: isOpen } = this.#dialog.input.current;
|
|
3497
|
+
if (errorState?.error) this.#lastErrorMessage = errorState.error.message?.trim() || null;
|
|
3498
|
+
const desc = this.querySelector("media-alert-dialog-description");
|
|
3499
|
+
if (desc) desc.textContent = this.#lastErrorMessage ?? FALLBACK_MESSAGE;
|
|
3500
|
+
if (hasError && !isOpen) this.#dialog.open();
|
|
3501
|
+
else if (!hasError && isOpen) this.#dialog.close();
|
|
3502
|
+
}
|
|
3503
|
+
update(_changed) {
|
|
3504
|
+
super.update(_changed);
|
|
3505
|
+
if (!this.#dialog) return;
|
|
3506
|
+
const input = this.#dialog.input.current;
|
|
3507
|
+
this.#core.setInput(input);
|
|
3508
|
+
const state = this.#core.getState();
|
|
3509
|
+
applyElementProps(this, this.#core.getAttrs(state));
|
|
3510
|
+
applyStateDataAttrs(this, state, AlertDialogDataAttrs);
|
|
3511
|
+
this.#provider.setValue({
|
|
3512
|
+
state,
|
|
3513
|
+
stateAttrMap: AlertDialogDataAttrs,
|
|
3514
|
+
close: () => this.#dialog?.close()
|
|
3515
|
+
});
|
|
1863
3516
|
}
|
|
1864
3517
|
};
|
|
1865
3518
|
|
|
1866
|
-
//#endregion
|
|
1867
|
-
//#region src/define/ui/time.ts
|
|
1868
|
-
safeDefine(TimeElement);
|
|
1869
|
-
safeDefine(TimeGroupElement);
|
|
1870
|
-
safeDefine(TimeSeparatorElement);
|
|
1871
|
-
|
|
1872
3519
|
//#endregion
|
|
1873
3520
|
//#region src/ui/slider/context.ts
|
|
1874
3521
|
const SLIDER_CONTEXT_KEY = Symbol("@videojs/slider");
|
|
@@ -2147,33 +3794,108 @@ var SliderTrackElement = class extends ContextPartElement {
|
|
|
2147
3794
|
};
|
|
2148
3795
|
|
|
2149
3796
|
//#endregion
|
|
2150
|
-
//#region src/ui/slider/slider-value-element.ts
|
|
2151
|
-
var SliderValueElement = class extends MediaElement {
|
|
2152
|
-
constructor(..._args) {
|
|
2153
|
-
super(..._args);
|
|
2154
|
-
this.type = "current";
|
|
2155
|
-
}
|
|
3797
|
+
//#region src/ui/slider/slider-value-element.ts
|
|
3798
|
+
var SliderValueElement = class extends MediaElement {
|
|
3799
|
+
constructor(..._args) {
|
|
3800
|
+
super(..._args);
|
|
3801
|
+
this.type = "current";
|
|
3802
|
+
}
|
|
3803
|
+
static {
|
|
3804
|
+
this.tagName = "media-slider-value";
|
|
3805
|
+
}
|
|
3806
|
+
static {
|
|
3807
|
+
this.properties = { type: { type: String } };
|
|
3808
|
+
}
|
|
3809
|
+
#ctx = new ContextConsumer(this, {
|
|
3810
|
+
context: sliderContext,
|
|
3811
|
+
subscribe: true
|
|
3812
|
+
});
|
|
3813
|
+
connectedCallback() {
|
|
3814
|
+
super.connectedCallback();
|
|
3815
|
+
this.setAttribute("aria-live", "off");
|
|
3816
|
+
}
|
|
3817
|
+
update(_changed) {
|
|
3818
|
+
super.update(_changed);
|
|
3819
|
+
const ctx = this.#ctx.value;
|
|
3820
|
+
if (!ctx) return;
|
|
3821
|
+
const value = this.type === "pointer" ? ctx.pointerValue : ctx.state.value;
|
|
3822
|
+
this.textContent = ctx.formatValue ? ctx.formatValue(value, this.type) : String(Math.round(value));
|
|
3823
|
+
applyStateDataAttrs(this, ctx.state, ctx.stateAttrMap);
|
|
3824
|
+
}
|
|
3825
|
+
};
|
|
3826
|
+
|
|
3827
|
+
//#endregion
|
|
3828
|
+
//#region src/ui/time/time-element.ts
|
|
3829
|
+
var TimeElement = class extends MediaElement {
|
|
3830
|
+
constructor(..._args) {
|
|
3831
|
+
super(..._args);
|
|
3832
|
+
this.type = TimeCore.defaultProps.type;
|
|
3833
|
+
this.negativeSign = TimeCore.defaultProps.negativeSign;
|
|
3834
|
+
this.label = TimeCore.defaultProps.label;
|
|
3835
|
+
}
|
|
3836
|
+
static {
|
|
3837
|
+
this.tagName = "media-time";
|
|
3838
|
+
}
|
|
3839
|
+
static {
|
|
3840
|
+
this.properties = {
|
|
3841
|
+
type: { type: String },
|
|
3842
|
+
negativeSign: {
|
|
3843
|
+
type: String,
|
|
3844
|
+
attribute: "negative-sign"
|
|
3845
|
+
},
|
|
3846
|
+
label: { type: String }
|
|
3847
|
+
};
|
|
3848
|
+
}
|
|
3849
|
+
#core = new TimeCore();
|
|
3850
|
+
#state = new PlayerController(this, playerContext, selectTime);
|
|
3851
|
+
#signSpan = document.createElement("span");
|
|
3852
|
+
#textNode = document.createTextNode("");
|
|
3853
|
+
connectedCallback() {
|
|
3854
|
+
super.connectedCallback();
|
|
3855
|
+
if (!this.#signSpan.parentNode) {
|
|
3856
|
+
this.#signSpan.setAttribute("aria-hidden", "true");
|
|
3857
|
+
this.#signSpan.hidden = true;
|
|
3858
|
+
this.appendChild(this.#signSpan);
|
|
3859
|
+
this.appendChild(this.#textNode);
|
|
3860
|
+
}
|
|
3861
|
+
if (!this.#state.value) logMissingFeature(this.localName, this.#state.displayName);
|
|
3862
|
+
}
|
|
3863
|
+
willUpdate(changed) {
|
|
3864
|
+
super.willUpdate(changed);
|
|
3865
|
+
this.#core.setProps(this);
|
|
3866
|
+
}
|
|
3867
|
+
update(changed) {
|
|
3868
|
+
super.update(changed);
|
|
3869
|
+
const media = this.#state.value;
|
|
3870
|
+
if (!media) return;
|
|
3871
|
+
this.#core.setMedia(media);
|
|
3872
|
+
const state = this.#core.getState();
|
|
3873
|
+
this.#signSpan.hidden = !state.negative;
|
|
3874
|
+
this.#signSpan.textContent = state.negative ? this.negativeSign : "";
|
|
3875
|
+
this.#textNode.textContent = state.text;
|
|
3876
|
+
applyElementProps(this, this.#core.getAttrs(state));
|
|
3877
|
+
applyStateDataAttrs(this, state, TimeDataAttrs);
|
|
3878
|
+
}
|
|
3879
|
+
};
|
|
3880
|
+
|
|
3881
|
+
//#endregion
|
|
3882
|
+
//#region src/ui/time/time-group-element.ts
|
|
3883
|
+
var TimeGroupElement = class extends MediaElement {
|
|
2156
3884
|
static {
|
|
2157
|
-
this.tagName = "media-
|
|
3885
|
+
this.tagName = "media-time-group";
|
|
2158
3886
|
}
|
|
3887
|
+
};
|
|
3888
|
+
|
|
3889
|
+
//#endregion
|
|
3890
|
+
//#region src/ui/time/time-separator-element.ts
|
|
3891
|
+
var TimeSeparatorElement = class extends MediaElement {
|
|
2159
3892
|
static {
|
|
2160
|
-
this.
|
|
3893
|
+
this.tagName = "media-time-separator";
|
|
2161
3894
|
}
|
|
2162
|
-
#ctx = new ContextConsumer(this, {
|
|
2163
|
-
context: sliderContext,
|
|
2164
|
-
subscribe: true
|
|
2165
|
-
});
|
|
2166
3895
|
connectedCallback() {
|
|
2167
3896
|
super.connectedCallback();
|
|
2168
|
-
this.setAttribute("aria-
|
|
2169
|
-
|
|
2170
|
-
update(_changed) {
|
|
2171
|
-
super.update(_changed);
|
|
2172
|
-
const ctx = this.#ctx.value;
|
|
2173
|
-
if (!ctx) return;
|
|
2174
|
-
const value = this.type === "pointer" ? ctx.pointerValue : ctx.state.value;
|
|
2175
|
-
this.textContent = ctx.formatValue ? ctx.formatValue(value, this.type) : String(Math.round(value));
|
|
2176
|
-
applyStateDataAttrs(this, ctx.state, ctx.stateAttrMap);
|
|
3897
|
+
this.setAttribute("aria-hidden", "true");
|
|
3898
|
+
if (!this.textContent?.trim()) this.textContent = "/";
|
|
2177
3899
|
}
|
|
2178
3900
|
};
|
|
2179
3901
|
|
|
@@ -2183,7 +3905,7 @@ var TimeSliderElement = class extends MediaElement {
|
|
|
2183
3905
|
constructor(..._args) {
|
|
2184
3906
|
super(..._args);
|
|
2185
3907
|
this.label = TimeSliderCore.defaultProps.label;
|
|
2186
|
-
this.
|
|
3908
|
+
this.changeThrottle = TimeSliderCore.defaultProps.changeThrottle;
|
|
2187
3909
|
this.step = TimeSliderCore.defaultProps.step;
|
|
2188
3910
|
this.largeStep = TimeSliderCore.defaultProps.largeStep;
|
|
2189
3911
|
this.orientation = TimeSliderCore.defaultProps.orientation;
|
|
@@ -2196,9 +3918,9 @@ var TimeSliderElement = class extends MediaElement {
|
|
|
2196
3918
|
static {
|
|
2197
3919
|
this.properties = {
|
|
2198
3920
|
label: { type: String },
|
|
2199
|
-
|
|
3921
|
+
changeThrottle: {
|
|
2200
3922
|
type: Number,
|
|
2201
|
-
attribute: "
|
|
3923
|
+
attribute: "change-throttle"
|
|
2202
3924
|
},
|
|
2203
3925
|
step: { type: Number },
|
|
2204
3926
|
largeStep: {
|
|
@@ -2241,7 +3963,7 @@ var TimeSliderElement = class extends MediaElement {
|
|
|
2241
3963
|
const media = this.#timeState.value;
|
|
2242
3964
|
if (media) media.seek(this.#core.rawValueFromPercent(percent));
|
|
2243
3965
|
},
|
|
2244
|
-
|
|
3966
|
+
changeThrottle: this.changeThrottle,
|
|
2245
3967
|
onDragStart: () => {
|
|
2246
3968
|
this.dispatchEvent(new CustomEvent("drag-start", { bubbles: true }));
|
|
2247
3969
|
},
|
|
@@ -2299,262 +4021,6 @@ var TimeSliderElement = class extends MediaElement {
|
|
|
2299
4021
|
}
|
|
2300
4022
|
};
|
|
2301
4023
|
|
|
2302
|
-
//#endregion
|
|
2303
|
-
//#region src/define/ui/time-slider.ts
|
|
2304
|
-
safeDefine(TimeSliderElement);
|
|
2305
|
-
safeDefine(SliderBufferElement);
|
|
2306
|
-
safeDefine(SliderFillElement);
|
|
2307
|
-
safeDefine(SliderPreviewElement);
|
|
2308
|
-
safeDefine(SliderThumbElement);
|
|
2309
|
-
safeDefine(SliderThumbnailElement);
|
|
2310
|
-
safeDefine(SliderTrackElement);
|
|
2311
|
-
safeDefine(SliderValueElement);
|
|
2312
|
-
|
|
2313
|
-
//#endregion
|
|
2314
|
-
//#region src/ui/tooltip/context.ts
|
|
2315
|
-
const TOOLTIP_GROUP_CONTEXT_KEY = Symbol("@videojs/tooltip-group");
|
|
2316
|
-
const tooltipGroupContext = createContext(TOOLTIP_GROUP_CONTEXT_KEY);
|
|
2317
|
-
|
|
2318
|
-
//#endregion
|
|
2319
|
-
//#region src/ui/tooltip/tooltip-element.ts
|
|
2320
|
-
function isLabelTrigger(el) {
|
|
2321
|
-
return "$state" in el;
|
|
2322
|
-
}
|
|
2323
|
-
var TooltipElement = class extends MediaElement {
|
|
2324
|
-
constructor(..._args) {
|
|
2325
|
-
super(..._args);
|
|
2326
|
-
this.open = TooltipCore.defaultProps.open;
|
|
2327
|
-
this.defaultOpen = TooltipCore.defaultProps.defaultOpen;
|
|
2328
|
-
this.side = TooltipCore.defaultProps.side;
|
|
2329
|
-
this.align = TooltipCore.defaultProps.align;
|
|
2330
|
-
this.delay = TooltipCore.defaultProps.delay;
|
|
2331
|
-
this.closeDelay = TooltipCore.defaultProps.closeDelay;
|
|
2332
|
-
this.disableHoverablePopup = TooltipCore.defaultProps.disableHoverablePopup;
|
|
2333
|
-
this.disabled = TooltipCore.defaultProps.disabled;
|
|
2334
|
-
}
|
|
2335
|
-
static {
|
|
2336
|
-
this.tagName = "media-tooltip";
|
|
2337
|
-
}
|
|
2338
|
-
static {
|
|
2339
|
-
this.properties = {
|
|
2340
|
-
open: { type: Boolean },
|
|
2341
|
-
defaultOpen: {
|
|
2342
|
-
type: Boolean,
|
|
2343
|
-
attribute: "default-open"
|
|
2344
|
-
},
|
|
2345
|
-
side: { type: String },
|
|
2346
|
-
align: { type: String },
|
|
2347
|
-
delay: { type: Number },
|
|
2348
|
-
closeDelay: {
|
|
2349
|
-
type: Number,
|
|
2350
|
-
attribute: "close-delay"
|
|
2351
|
-
},
|
|
2352
|
-
disableHoverablePopup: {
|
|
2353
|
-
type: Boolean,
|
|
2354
|
-
attribute: "disable-hoverable-popup"
|
|
2355
|
-
},
|
|
2356
|
-
disabled: { type: Boolean }
|
|
2357
|
-
};
|
|
2358
|
-
}
|
|
2359
|
-
#core = new TooltipCore();
|
|
2360
|
-
#groupConsumer = new ContextConsumer(this, { context: tooltipGroupContext });
|
|
2361
|
-
#tooltip = null;
|
|
2362
|
-
#snapshot = null;
|
|
2363
|
-
#disconnect = null;
|
|
2364
|
-
#triggerAbort = null;
|
|
2365
|
-
#currentTrigger = null;
|
|
2366
|
-
#positionAbort = null;
|
|
2367
|
-
#positionFrame = 0;
|
|
2368
|
-
#resizeObserver = null;
|
|
2369
|
-
#positionTrigger = null;
|
|
2370
|
-
connectedCallback() {
|
|
2371
|
-
super.connectedCallback();
|
|
2372
|
-
this.#disconnect = new AbortController();
|
|
2373
|
-
this.#tooltip = createTooltip({
|
|
2374
|
-
transition: createTransition(),
|
|
2375
|
-
onOpenChange: (nextOpen, details) => {
|
|
2376
|
-
this.open = nextOpen;
|
|
2377
|
-
this.dispatchEvent(new CustomEvent("open-change", { detail: {
|
|
2378
|
-
open: nextOpen,
|
|
2379
|
-
...details
|
|
2380
|
-
} }));
|
|
2381
|
-
},
|
|
2382
|
-
delay: () => this.delay,
|
|
2383
|
-
closeDelay: () => this.closeDelay,
|
|
2384
|
-
disableHoverablePopup: () => this.disableHoverablePopup,
|
|
2385
|
-
disabled: () => this.disabled,
|
|
2386
|
-
group: () => this.#groupConsumer.value
|
|
2387
|
-
});
|
|
2388
|
-
this.#tooltip.setPopupElement(this);
|
|
2389
|
-
applyElementProps(this, this.#tooltip.popupProps, { signal: this.#disconnect.signal });
|
|
2390
|
-
if (this.#snapshot) this.#snapshot.track(this.#tooltip.input);
|
|
2391
|
-
else this.#snapshot = new SnapshotController(this, this.#tooltip.input);
|
|
2392
|
-
}
|
|
2393
|
-
firstUpdated(changed) {
|
|
2394
|
-
super.firstUpdated(changed);
|
|
2395
|
-
if (this.defaultOpen && !this.open) this.#tooltip?.open();
|
|
2396
|
-
}
|
|
2397
|
-
disconnectedCallback() {
|
|
2398
|
-
super.disconnectedCallback();
|
|
2399
|
-
this.#cleanupPositioning();
|
|
2400
|
-
this.#cleanupTrigger();
|
|
2401
|
-
this.#tooltip?.destroy();
|
|
2402
|
-
this.#tooltip = null;
|
|
2403
|
-
this.#disconnect?.abort();
|
|
2404
|
-
this.#disconnect = null;
|
|
2405
|
-
}
|
|
2406
|
-
willUpdate(changed) {
|
|
2407
|
-
super.willUpdate(changed);
|
|
2408
|
-
this.#core.setProps(this);
|
|
2409
|
-
if (this.#tooltip && changed.has("open")) {
|
|
2410
|
-
const { active: interactionOpen } = this.#tooltip.input.current;
|
|
2411
|
-
if (this.open !== interactionOpen) if (this.open) this.#tooltip.open();
|
|
2412
|
-
else this.#tooltip.close();
|
|
2413
|
-
}
|
|
2414
|
-
}
|
|
2415
|
-
update(_changed) {
|
|
2416
|
-
super.update(_changed);
|
|
2417
|
-
if (!this.#tooltip) return;
|
|
2418
|
-
const triggerEl = this.#findTrigger();
|
|
2419
|
-
this.#syncTrigger(triggerEl);
|
|
2420
|
-
const input = this.#tooltip.input.current;
|
|
2421
|
-
this.#core.setInput(input);
|
|
2422
|
-
const state = this.#core.getState();
|
|
2423
|
-
applyElementProps(this, this.#core.getPopupAttrs(state));
|
|
2424
|
-
applyStateDataAttrs(this, state, TooltipDataAttrs);
|
|
2425
|
-
if (state.open) tryShowPopover(this);
|
|
2426
|
-
else tryHidePopover(this);
|
|
2427
|
-
if (this.#currentTrigger) applyStyles(this.#currentTrigger, getAnchorNameStyle(this.id));
|
|
2428
|
-
if (!state.open) {
|
|
2429
|
-
this.#cleanupPositioning();
|
|
2430
|
-
return;
|
|
2431
|
-
}
|
|
2432
|
-
const posOpts = {
|
|
2433
|
-
side: state.side,
|
|
2434
|
-
align: state.align
|
|
2435
|
-
};
|
|
2436
|
-
if (supportsAnchorPositioning()) applyStyles(this, getAnchorPositionStyle(this.id, posOpts, void 0, void 0, void 0, void 0, TooltipCSSVars));
|
|
2437
|
-
else {
|
|
2438
|
-
const triggerRect = this.#currentTrigger?.getBoundingClientRect();
|
|
2439
|
-
const selfRect = getPopupPositionRect(this);
|
|
2440
|
-
const boundaryRect = document.documentElement.getBoundingClientRect();
|
|
2441
|
-
const offsets = resolveOffsets(this, TooltipCSSVars);
|
|
2442
|
-
applyStyles(this, getAnchorPositionStyle(this.id, posOpts, triggerRect, selfRect, boundaryRect, offsets, TooltipCSSVars));
|
|
2443
|
-
}
|
|
2444
|
-
this.#syncPositioning();
|
|
2445
|
-
}
|
|
2446
|
-
#findTrigger() {
|
|
2447
|
-
if (!this.id) return null;
|
|
2448
|
-
return this.getRootNode().querySelector(`[commandfor="${this.id}"]`);
|
|
2449
|
-
}
|
|
2450
|
-
#syncTrigger(triggerEl) {
|
|
2451
|
-
if (triggerEl === this.#currentTrigger) return;
|
|
2452
|
-
this.#cleanupPositioning();
|
|
2453
|
-
this.#cleanupTrigger();
|
|
2454
|
-
this.#currentTrigger = triggerEl;
|
|
2455
|
-
this.#tooltip?.setTriggerElement(triggerEl);
|
|
2456
|
-
if (triggerEl && this.#tooltip) {
|
|
2457
|
-
this.#triggerAbort = new AbortController();
|
|
2458
|
-
applyElementProps(triggerEl, this.#tooltip.triggerProps, { signal: this.#triggerAbort.signal });
|
|
2459
|
-
if (isLabelTrigger(triggerEl)) {
|
|
2460
|
-
this.#syncContent(triggerEl);
|
|
2461
|
-
triggerEl.$state.subscribe(() => this.#syncContent(triggerEl), { signal: this.#triggerAbort.signal });
|
|
2462
|
-
}
|
|
2463
|
-
}
|
|
2464
|
-
}
|
|
2465
|
-
#syncContent(triggerEl) {
|
|
2466
|
-
this.textContent = triggerEl.getLabel() ?? "";
|
|
2467
|
-
}
|
|
2468
|
-
#cleanupTrigger() {
|
|
2469
|
-
if (this.#currentTrigger) this.#currentTrigger.style.removeProperty("anchor-name");
|
|
2470
|
-
this.#triggerAbort?.abort();
|
|
2471
|
-
this.#triggerAbort = null;
|
|
2472
|
-
this.#currentTrigger = null;
|
|
2473
|
-
}
|
|
2474
|
-
#syncPositioning() {
|
|
2475
|
-
if (supportsAnchorPositioning()) return;
|
|
2476
|
-
const triggerEl = this.#currentTrigger;
|
|
2477
|
-
if (!triggerEl) return;
|
|
2478
|
-
if (this.#positionAbort && this.#positionTrigger === triggerEl) return;
|
|
2479
|
-
this.#cleanupPositioning();
|
|
2480
|
-
this.#positionAbort = new AbortController();
|
|
2481
|
-
this.#positionTrigger = triggerEl;
|
|
2482
|
-
const { signal } = this.#positionAbort;
|
|
2483
|
-
const reposition = () => {
|
|
2484
|
-
cancelAnimationFrame(this.#positionFrame);
|
|
2485
|
-
this.#positionFrame = requestAnimationFrame(() => {
|
|
2486
|
-
if (signal.aborted) return;
|
|
2487
|
-
this.requestUpdate();
|
|
2488
|
-
});
|
|
2489
|
-
};
|
|
2490
|
-
window.addEventListener("scroll", reposition, {
|
|
2491
|
-
capture: true,
|
|
2492
|
-
passive: true,
|
|
2493
|
-
signal
|
|
2494
|
-
});
|
|
2495
|
-
window.addEventListener("resize", reposition, { signal });
|
|
2496
|
-
if (typeof ResizeObserver === "function") {
|
|
2497
|
-
this.#resizeObserver = new ResizeObserver(() => {
|
|
2498
|
-
reposition();
|
|
2499
|
-
});
|
|
2500
|
-
this.#resizeObserver.observe(triggerEl);
|
|
2501
|
-
this.#resizeObserver.observe(this);
|
|
2502
|
-
}
|
|
2503
|
-
reposition();
|
|
2504
|
-
}
|
|
2505
|
-
#cleanupPositioning() {
|
|
2506
|
-
this.#positionAbort?.abort();
|
|
2507
|
-
this.#positionAbort = null;
|
|
2508
|
-
this.#positionTrigger = null;
|
|
2509
|
-
cancelAnimationFrame(this.#positionFrame);
|
|
2510
|
-
this.#positionFrame = 0;
|
|
2511
|
-
this.#resizeObserver?.disconnect();
|
|
2512
|
-
this.#resizeObserver = null;
|
|
2513
|
-
}
|
|
2514
|
-
};
|
|
2515
|
-
|
|
2516
|
-
//#endregion
|
|
2517
|
-
//#region src/define/ui/tooltip.ts
|
|
2518
|
-
safeDefine(TooltipElement);
|
|
2519
|
-
|
|
2520
|
-
//#endregion
|
|
2521
|
-
//#region src/ui/tooltip/tooltip-group-element.ts
|
|
2522
|
-
var TooltipGroupElement = class extends MediaElement {
|
|
2523
|
-
constructor(..._args) {
|
|
2524
|
-
super(..._args);
|
|
2525
|
-
this.delay = TooltipGroupCore.defaultProps.delay;
|
|
2526
|
-
this.closeDelay = TooltipGroupCore.defaultProps.closeDelay;
|
|
2527
|
-
this.timeout = TooltipGroupCore.defaultProps.timeout;
|
|
2528
|
-
}
|
|
2529
|
-
static {
|
|
2530
|
-
this.tagName = "media-tooltip-group";
|
|
2531
|
-
}
|
|
2532
|
-
static {
|
|
2533
|
-
this.properties = {
|
|
2534
|
-
delay: { type: Number },
|
|
2535
|
-
closeDelay: {
|
|
2536
|
-
type: Number,
|
|
2537
|
-
attribute: "close-delay"
|
|
2538
|
-
},
|
|
2539
|
-
timeout: { type: Number }
|
|
2540
|
-
};
|
|
2541
|
-
}
|
|
2542
|
-
#core = new TooltipGroupCore();
|
|
2543
|
-
#provider = new ContextProvider(this, {
|
|
2544
|
-
context: tooltipGroupContext,
|
|
2545
|
-
initialValue: this.#core
|
|
2546
|
-
});
|
|
2547
|
-
update(_changed) {
|
|
2548
|
-
super.update(_changed);
|
|
2549
|
-
this.#core.setProps(this);
|
|
2550
|
-
this.#provider.setValue(this.#core);
|
|
2551
|
-
}
|
|
2552
|
-
};
|
|
2553
|
-
|
|
2554
|
-
//#endregion
|
|
2555
|
-
//#region src/define/ui/tooltip-group.ts
|
|
2556
|
-
safeDefine(TooltipGroupElement);
|
|
2557
|
-
|
|
2558
4024
|
//#endregion
|
|
2559
4025
|
//#region src/ui/volume-slider/volume-slider-element.ts
|
|
2560
4026
|
var VolumeSliderElement = class extends MediaElement {
|
|
@@ -2676,14 +4142,41 @@ var VolumeSliderElement = class extends MediaElement {
|
|
|
2676
4142
|
};
|
|
2677
4143
|
|
|
2678
4144
|
//#endregion
|
|
2679
|
-
//#region src/define/ui/
|
|
2680
|
-
|
|
2681
|
-
safeDefine(
|
|
2682
|
-
safeDefine(
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
safeDefine(
|
|
4145
|
+
//#region src/define/ui/compounds.ts
|
|
4146
|
+
function defineControls() {
|
|
4147
|
+
safeDefine(ControlsElement);
|
|
4148
|
+
safeDefine(ControlsGroupElement);
|
|
4149
|
+
}
|
|
4150
|
+
function defineErrorDialog() {
|
|
4151
|
+
safeDefine(ErrorDialogElement);
|
|
4152
|
+
safeDefine(AlertDialogCloseElement);
|
|
4153
|
+
safeDefine(AlertDialogDescriptionElement);
|
|
4154
|
+
safeDefine(AlertDialogTitleElement);
|
|
4155
|
+
}
|
|
4156
|
+
/** Shared slider sub-elements used by all slider types. */
|
|
4157
|
+
function defineSliderParts() {
|
|
4158
|
+
safeDefine(SliderFillElement);
|
|
4159
|
+
safeDefine(SliderPreviewElement);
|
|
4160
|
+
safeDefine(SliderThumbElement);
|
|
4161
|
+
safeDefine(SliderTrackElement);
|
|
4162
|
+
safeDefine(SliderValueElement);
|
|
4163
|
+
}
|
|
4164
|
+
function defineTime() {
|
|
4165
|
+
safeDefine(TimeElement);
|
|
4166
|
+
safeDefine(TimeGroupElement);
|
|
4167
|
+
safeDefine(TimeSeparatorElement);
|
|
4168
|
+
}
|
|
4169
|
+
function defineTimeSlider() {
|
|
4170
|
+
safeDefine(TimeSliderElement);
|
|
4171
|
+
defineSliderParts();
|
|
4172
|
+
safeDefine(SliderBufferElement);
|
|
4173
|
+
safeDefine(SliderThumbnailElement);
|
|
4174
|
+
}
|
|
4175
|
+
function defineVolumeSlider() {
|
|
4176
|
+
safeDefine(VolumeSliderElement);
|
|
4177
|
+
defineSliderParts();
|
|
4178
|
+
}
|
|
2686
4179
|
|
|
2687
4180
|
//#endregion
|
|
2688
|
-
export {
|
|
2689
|
-
//# sourceMappingURL=
|
|
4181
|
+
export { selectVolume as C, selectTime as S, selectFullscreen as _, defineVolumeSlider as a, selectPlaybackRate as b, SeekButtonElement as c, PlayButtonElement as d, MuteButtonElement as f, createHotkey as g, logMissingFeature as h, defineTimeSlider as i, PopoverElement as l, applyStateDataAttrs as m, defineErrorDialog as n, TooltipGroupElement as o, MediaButtonElement as p, defineTime as r, TooltipElement as s, defineControls as t, PlaybackRateButtonElement as u, selectPiP as v, defaults as w, selectTextTrack as x, selectPlayback as y };
|
|
4182
|
+
//# sourceMappingURL=compounds-VFPcCeRV.js.map
|