@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,9 +1,14 @@
|
|
|
1
1
|
import { t as listen } from "./listen-w-Aun0yN.js";
|
|
2
|
-
import { a as ContextRequestEvent, n as mediaContext, r as playerContext, t as containerContext } from "./context-
|
|
3
|
-
import { t as anyAbortSignal } from "./abort-
|
|
4
|
-
import { t as shallowEqual } from "./shallow-equal-
|
|
2
|
+
import { a as ContextRequestEvent, n as mediaContext, r as playerContext, t as containerContext } from "./context-CvJ83xGk.js";
|
|
3
|
+
import { t as anyAbortSignal } from "./abort-BL-SGV3o.js";
|
|
4
|
+
import { t as shallowEqual } from "./shallow-equal-Ca0qjpLJ.js";
|
|
5
5
|
|
|
6
6
|
//#region ../utils/dist/dom/event.js
|
|
7
|
+
/** Resolve the deepest event target, preferring composedPath for shadow DOM. */
|
|
8
|
+
function resolveEventTarget(event) {
|
|
9
|
+
const path = event.composedPath();
|
|
10
|
+
return path.length > 0 ? path[0] : event.target;
|
|
11
|
+
}
|
|
7
12
|
function onEvent(target, type, options) {
|
|
8
13
|
return new Promise((resolve, reject) => {
|
|
9
14
|
const handleAbort = () => {
|
|
@@ -25,64 +30,35 @@ function onEvent(target, type, options) {
|
|
|
25
30
|
}
|
|
26
31
|
|
|
27
32
|
//#endregion
|
|
28
|
-
//#region ../utils/dist/dom/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
//#endregion
|
|
47
|
-
//#region ../utils/dist/string/casing.js
|
|
48
|
-
function kebabCase(str) {
|
|
49
|
-
return str.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
|
|
33
|
+
//#region ../utils/dist/dom/predicates.js
|
|
34
|
+
const EDITABLE_INPUT_TYPES = new Set([
|
|
35
|
+
"text",
|
|
36
|
+
"search",
|
|
37
|
+
"url",
|
|
38
|
+
"tel",
|
|
39
|
+
"email",
|
|
40
|
+
"password",
|
|
41
|
+
"number"
|
|
42
|
+
]);
|
|
43
|
+
function isEditableElement(el) {
|
|
44
|
+
if (el instanceof HTMLTextAreaElement) return true;
|
|
45
|
+
if (el instanceof HTMLSelectElement) return true;
|
|
46
|
+
if (el instanceof HTMLInputElement) return EDITABLE_INPUT_TYPES.has(el.type.toLowerCase());
|
|
47
|
+
if (!(el instanceof HTMLElement)) return false;
|
|
48
|
+
const editable = el.getAttribute("contenteditable");
|
|
49
|
+
return editable !== null && editable !== "false";
|
|
50
50
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
for (const [prop, value] of Object.entries(styles)) if (typeof value === "string") {
|
|
56
|
-
const key = prop.startsWith("--") ? prop : kebabCase(prop);
|
|
57
|
-
element.style.setProperty(key, value);
|
|
58
|
-
}
|
|
51
|
+
/** Whether the keyboard event target is an editable element (input, textarea, etc). */
|
|
52
|
+
function isEditableTarget(event) {
|
|
53
|
+
const target = resolveEventTarget(event);
|
|
54
|
+
return target instanceof Element && isEditableElement(target);
|
|
59
55
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
if (
|
|
65
|
-
|
|
66
|
-
const doc = el.ownerDocument;
|
|
67
|
-
const root = doc?.documentElement;
|
|
68
|
-
if (trimmed.endsWith("rem")) return parsed * (root ? Number.parseFloat(getComputedStyle(root).fontSize) || 16 : 16);
|
|
69
|
-
if (trimmed.endsWith("em")) return parsed * (el instanceof HTMLElement ? Number.parseFloat(getComputedStyle(el).fontSize) || 16 : 16);
|
|
70
|
-
if (!doc) return parsed;
|
|
71
|
-
const measurementEl = doc.createElement("div");
|
|
72
|
-
measurementEl.style.position = "absolute";
|
|
73
|
-
measurementEl.style.visibility = "hidden";
|
|
74
|
-
measurementEl.style.pointerEvents = "none";
|
|
75
|
-
measurementEl.style.inlineSize = trimmed;
|
|
76
|
-
measurementEl.style.blockSize = "0";
|
|
77
|
-
measurementEl.style.padding = "0";
|
|
78
|
-
measurementEl.style.border = "0";
|
|
79
|
-
measurementEl.style.inset = "0";
|
|
80
|
-
const parent = doc.body ?? doc.documentElement;
|
|
81
|
-
if (!parent) return parsed;
|
|
82
|
-
parent.appendChild(measurementEl);
|
|
83
|
-
const pixels = measurementEl.getBoundingClientRect().width;
|
|
84
|
-
measurementEl.remove();
|
|
85
|
-
return Number.isFinite(pixels) ? pixels : parsed;
|
|
56
|
+
const INTERACTIVE_SELECTOR = "button, input, select, textarea, [role=\"button\"], [role=\"slider\"]";
|
|
57
|
+
/** Whether the event originated from an interactive control (button, slider, etc). */
|
|
58
|
+
function isInteractiveTarget(event) {
|
|
59
|
+
const target = resolveEventTarget(event);
|
|
60
|
+
if (!(target instanceof Element)) return false;
|
|
61
|
+
return target.closest(INTERACTIVE_SELECTOR) !== null;
|
|
86
62
|
}
|
|
87
63
|
|
|
88
64
|
//#endregion
|
|
@@ -97,7 +73,7 @@ function getTextTrackList(media, filterPred) {
|
|
|
97
73
|
return Array.from(media.textTracks).filter(filterPred).sort(sortByTextTrackKind);
|
|
98
74
|
}
|
|
99
75
|
function sortByTextTrackKind(a, b) {
|
|
100
|
-
return a.kind
|
|
76
|
+
return a.kind > b.kind ? 1 : a.kind < b.kind ? -1 : 0;
|
|
101
77
|
}
|
|
102
78
|
|
|
103
79
|
//#endregion
|
|
@@ -468,190 +444,398 @@ function resolve(ctor) {
|
|
|
468
444
|
}
|
|
469
445
|
|
|
470
446
|
//#endregion
|
|
471
|
-
//#region
|
|
472
|
-
function isNumber(value) {
|
|
473
|
-
return typeof value === "number";
|
|
474
|
-
}
|
|
475
|
-
function isFunction(value) {
|
|
476
|
-
return typeof value === "function";
|
|
477
|
-
}
|
|
478
|
-
function isNull(value) {
|
|
479
|
-
return value === null;
|
|
480
|
-
}
|
|
481
|
-
function isUndefined(value) {
|
|
482
|
-
return typeof value === "undefined";
|
|
483
|
-
}
|
|
447
|
+
//#region ../../node_modules/.pnpm/@lit+context@1.1.6/node_modules/@lit/context/development/lib/controllers/context-consumer.js
|
|
484
448
|
/**
|
|
485
|
-
*
|
|
449
|
+
* @license
|
|
450
|
+
* Copyright 2021 Google LLC
|
|
451
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
486
452
|
*/
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
453
|
+
/**
|
|
454
|
+
* A ReactiveController which adds context consuming behavior to a custom
|
|
455
|
+
* element by dispatching `context-request` events.
|
|
456
|
+
*
|
|
457
|
+
* When the host element is connected to the document it will emit a
|
|
458
|
+
* `context-request` event with its context key. When the context request
|
|
459
|
+
* is satisfied the controller will invoke the callback, if present, and
|
|
460
|
+
* trigger a host update so it can respond to the new value.
|
|
461
|
+
*
|
|
462
|
+
* It will also call the dispose method given by the provider when the
|
|
463
|
+
* host element is disconnected.
|
|
464
|
+
*/
|
|
465
|
+
var ContextConsumer = class {
|
|
466
|
+
constructor(host, contextOrOptions, callback, subscribe) {
|
|
467
|
+
this.subscribe = false;
|
|
468
|
+
this.provided = false;
|
|
469
|
+
this.value = void 0;
|
|
470
|
+
this._callback = (value, unsubscribe) => {
|
|
471
|
+
if (this.unsubscribe) {
|
|
472
|
+
if (this.unsubscribe !== unsubscribe) {
|
|
473
|
+
this.provided = false;
|
|
474
|
+
this.unsubscribe();
|
|
475
|
+
}
|
|
476
|
+
if (!this.subscribe) this.unsubscribe();
|
|
477
|
+
}
|
|
478
|
+
this.value = value;
|
|
479
|
+
this.host.requestUpdate();
|
|
480
|
+
if (!this.provided || this.subscribe) {
|
|
481
|
+
this.provided = true;
|
|
482
|
+
if (this.callback) this.callback(value, unsubscribe);
|
|
483
|
+
}
|
|
484
|
+
this.unsubscribe = unsubscribe;
|
|
485
|
+
};
|
|
486
|
+
this.host = host;
|
|
487
|
+
if (contextOrOptions.context !== void 0) {
|
|
488
|
+
const options = contextOrOptions;
|
|
489
|
+
this.context = options.context;
|
|
490
|
+
this.callback = options.callback;
|
|
491
|
+
this.subscribe = options.subscribe ?? false;
|
|
492
|
+
} else {
|
|
493
|
+
this.context = contextOrOptions;
|
|
494
|
+
this.callback = callback;
|
|
495
|
+
this.subscribe = subscribe ?? false;
|
|
496
|
+
}
|
|
497
|
+
this.host.addController(this);
|
|
499
498
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
for (const controller of this.#keys.values()) controller.abort();
|
|
503
|
-
this.#keys.clear();
|
|
499
|
+
hostConnected() {
|
|
500
|
+
this.dispatchRequest();
|
|
504
501
|
}
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
502
|
+
hostDisconnected() {
|
|
503
|
+
if (this.unsubscribe) {
|
|
504
|
+
this.unsubscribe();
|
|
505
|
+
this.unsubscribe = void 0;
|
|
506
|
+
}
|
|
510
507
|
}
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
this.#keys.get(key)?.abort();
|
|
514
|
-
const controller = new AbortController();
|
|
515
|
-
this.#keys.set(key, controller);
|
|
516
|
-
return anyAbortSignal([this.#base.signal, controller.signal]);
|
|
508
|
+
dispatchRequest() {
|
|
509
|
+
this.host.dispatchEvent(new ContextRequestEvent(this.context, this.host, this._callback, this.subscribe));
|
|
517
510
|
}
|
|
518
511
|
};
|
|
519
512
|
|
|
520
513
|
//#endregion
|
|
521
|
-
//#region
|
|
514
|
+
//#region ../../node_modules/.pnpm/@lit+context@1.1.6/node_modules/@lit/context/development/lib/value-notifier.js
|
|
522
515
|
/**
|
|
523
|
-
*
|
|
516
|
+
* @license
|
|
517
|
+
* Copyright 2021 Google LLC
|
|
518
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
519
|
+
*/
|
|
520
|
+
/**
|
|
521
|
+
* A simple class which stores a value, and triggers registered callbacks when
|
|
522
|
+
* the value is changed via its setter.
|
|
524
523
|
*
|
|
525
|
-
*
|
|
526
|
-
*
|
|
524
|
+
* An implementor might use other observable patterns such as MobX or Redux to
|
|
525
|
+
* get behavior like this. But this is a pretty minimal approach that will
|
|
526
|
+
* likely work for a number of use cases.
|
|
527
527
|
*/
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
528
|
+
var ValueNotifier = class {
|
|
529
|
+
get value() {
|
|
530
|
+
return this._value;
|
|
531
|
+
}
|
|
532
|
+
set value(v) {
|
|
533
|
+
this.setValue(v);
|
|
534
|
+
}
|
|
535
|
+
setValue(v, force = false) {
|
|
536
|
+
const update = force || !Object.is(v, this._value);
|
|
537
|
+
this._value = v;
|
|
538
|
+
if (update) this.updateObservers();
|
|
539
|
+
}
|
|
540
|
+
constructor(defaultValue) {
|
|
541
|
+
this.subscriptions = /* @__PURE__ */ new Map();
|
|
542
|
+
this.updateObservers = () => {
|
|
543
|
+
for (const [callback, { disposer }] of this.subscriptions) callback(this._value, disposer);
|
|
544
|
+
};
|
|
545
|
+
if (defaultValue !== void 0) this.value = defaultValue;
|
|
546
|
+
}
|
|
547
|
+
addCallback(callback, consumerHost, subscribe) {
|
|
548
|
+
if (!subscribe) {
|
|
549
|
+
callback(this.value);
|
|
550
|
+
return;
|
|
540
551
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
this.
|
|
552
|
-
this.code = code;
|
|
553
|
-
this.cause = options?.cause;
|
|
552
|
+
if (!this.subscriptions.has(callback)) this.subscriptions.set(callback, {
|
|
553
|
+
disposer: () => {
|
|
554
|
+
this.subscriptions.delete(callback);
|
|
555
|
+
},
|
|
556
|
+
consumerHost
|
|
557
|
+
});
|
|
558
|
+
const { disposer } = this.subscriptions.get(callback);
|
|
559
|
+
callback(this.value, disposer);
|
|
560
|
+
}
|
|
561
|
+
clearCallbacks() {
|
|
562
|
+
this.subscriptions.clear();
|
|
554
563
|
}
|
|
555
564
|
};
|
|
556
|
-
function throwNoTargetError() {
|
|
557
|
-
throw new StoreError("NO_TARGET");
|
|
558
|
-
}
|
|
559
|
-
function throwDestroyedError() {
|
|
560
|
-
throw new StoreError("DESTROYED");
|
|
561
|
-
}
|
|
562
565
|
|
|
563
566
|
//#endregion
|
|
564
|
-
//#region
|
|
567
|
+
//#region ../../node_modules/.pnpm/@lit+context@1.1.6/node_modules/@lit/context/development/lib/controllers/context-provider.js
|
|
565
568
|
/**
|
|
566
|
-
*
|
|
567
|
-
*
|
|
568
|
-
*
|
|
569
|
-
* const obj = { a: 1, b: 2, c: 3 };
|
|
570
|
-
* pick(obj, ['a', 'c']); // { a: 1, c: 3 }
|
|
569
|
+
* @license
|
|
570
|
+
* Copyright 2021 Google LLC
|
|
571
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
571
572
|
*/
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
573
|
+
var ContextProviderEvent = class extends Event {
|
|
574
|
+
/**
|
|
575
|
+
*
|
|
576
|
+
* @param context the context which this provider can provide
|
|
577
|
+
* @param contextTarget the original context target of the provider
|
|
578
|
+
*/
|
|
579
|
+
constructor(context, contextTarget) {
|
|
580
|
+
super("context-provider", {
|
|
581
|
+
bubbles: true,
|
|
582
|
+
composed: true
|
|
583
|
+
});
|
|
584
|
+
this.context = context;
|
|
585
|
+
this.contextTarget = contextTarget;
|
|
586
|
+
}
|
|
584
587
|
};
|
|
585
588
|
/**
|
|
586
|
-
*
|
|
587
|
-
*
|
|
588
|
-
* The selector returns the slice's state, or `undefined` if the slice
|
|
589
|
-
* is not configured in the store.
|
|
589
|
+
* A ReactiveController which adds context provider behavior to a
|
|
590
|
+
* custom element.
|
|
590
591
|
*
|
|
591
|
-
*
|
|
592
|
-
*
|
|
593
|
-
*
|
|
594
|
-
* selectPlayback(store.state); // { paused, play, pause, ... } | undefined
|
|
595
|
-
* selectPlayback.displayName; // 'playback' (from slice name)
|
|
596
|
-
* ```
|
|
592
|
+
* This controller simply listens to the `context-request` event when
|
|
593
|
+
* the host is connected to the DOM and registers the received callbacks
|
|
594
|
+
* against its observable Context implementation.
|
|
597
595
|
*
|
|
598
|
-
*
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
const keys = Object.keys(initialState);
|
|
603
|
-
const firstKey = keys[0];
|
|
604
|
-
if (!firstKey) return Object.assign(() => void 0, { displayName: slice.name });
|
|
605
|
-
return Object.assign((state) => {
|
|
606
|
-
if (!(firstKey in state)) return void 0;
|
|
607
|
-
return pick(state, keys);
|
|
608
|
-
}, { displayName: slice.name });
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
//#endregion
|
|
612
|
-
//#region ../store/dist/dev/core/slice.js
|
|
613
|
-
function defineSlice() {
|
|
614
|
-
return (config) => config;
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
//#endregion
|
|
618
|
-
//#region ../utils/dist/function/noop.js
|
|
619
|
-
function noop(..._args) {}
|
|
620
|
-
|
|
621
|
-
//#endregion
|
|
622
|
-
//#region ../utils/dist/function/throttle.js
|
|
623
|
-
/**
|
|
624
|
-
* Trailing-edge throttle: the first call schedules a timer; subsequent calls
|
|
625
|
-
* within the window update the arguments. The function fires once per `ms`
|
|
626
|
-
* window with the latest arguments.
|
|
596
|
+
* The controller may also be attached to any HTML element in which case it's
|
|
597
|
+
* up to the user to call hostConnected() when attached to the DOM. This is
|
|
598
|
+
* done automatically for any custom elements implementing
|
|
599
|
+
* ReactiveControllerHost.
|
|
627
600
|
*/
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
601
|
+
var ContextProvider = class extends ValueNotifier {
|
|
602
|
+
constructor(host, contextOrOptions, initialValue) {
|
|
603
|
+
super(contextOrOptions.context !== void 0 ? contextOrOptions.initialValue : initialValue);
|
|
604
|
+
this.onContextRequest = (ev) => {
|
|
605
|
+
if (ev.context !== this.context) return;
|
|
606
|
+
const consumerHost = ev.contextTarget ?? ev.composedPath()[0];
|
|
607
|
+
if (consumerHost === this.host) return;
|
|
608
|
+
ev.stopPropagation();
|
|
609
|
+
this.addCallback(ev.callback, consumerHost, ev.subscribe);
|
|
610
|
+
};
|
|
611
|
+
/**
|
|
612
|
+
* When we get a provider request event, that means a child of this element
|
|
613
|
+
* has just woken up. If it's a provider of our context, then we may need to
|
|
614
|
+
* re-parent our subscriptions, because is a more specific provider than us
|
|
615
|
+
* for its subtree.
|
|
616
|
+
*/
|
|
617
|
+
this.onProviderRequest = (ev) => {
|
|
618
|
+
if (ev.context !== this.context) return;
|
|
619
|
+
if ((ev.contextTarget ?? ev.composedPath()[0]) === this.host) return;
|
|
620
|
+
const seen = /* @__PURE__ */ new Set();
|
|
621
|
+
for (const [callback, { consumerHost }] of this.subscriptions) {
|
|
622
|
+
if (seen.has(callback)) continue;
|
|
623
|
+
seen.add(callback);
|
|
624
|
+
consumerHost.dispatchEvent(new ContextRequestEvent(this.context, consumerHost, callback, true));
|
|
625
|
+
}
|
|
626
|
+
ev.stopPropagation();
|
|
627
|
+
};
|
|
628
|
+
this.host = host;
|
|
629
|
+
if (contextOrOptions.context !== void 0) this.context = contextOrOptions.context;
|
|
630
|
+
else this.context = contextOrOptions;
|
|
631
|
+
this.attachListeners();
|
|
632
|
+
this.host.addController?.(this);
|
|
633
|
+
}
|
|
634
|
+
attachListeners() {
|
|
635
|
+
this.host.addEventListener("context-request", this.onContextRequest);
|
|
636
|
+
this.host.addEventListener("context-provider", this.onProviderRequest);
|
|
637
|
+
}
|
|
638
|
+
hostConnected() {
|
|
639
|
+
this.host.dispatchEvent(new ContextProviderEvent(this.context, this.host));
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
|
|
643
|
+
//#endregion
|
|
644
|
+
//#region src/store/container-mixin.ts
|
|
645
|
+
/**
|
|
646
|
+
* Create a mixin that consumes player context and registers itself as the
|
|
647
|
+
* container element with the provider via `containerContext`.
|
|
648
|
+
*
|
|
649
|
+
* @param config - Container configuration with player and container contexts.
|
|
650
|
+
*/
|
|
651
|
+
function createContainerMixin(config) {
|
|
652
|
+
return (BaseClass) => {
|
|
653
|
+
class PlayerContainerElement extends BaseClass {
|
|
654
|
+
#contextStore = null;
|
|
655
|
+
#setContainer = null;
|
|
656
|
+
constructor(...args) {
|
|
657
|
+
super(...args);
|
|
658
|
+
new ContextConsumer(this, {
|
|
659
|
+
context: config.playerContext,
|
|
660
|
+
callback: (value) => {
|
|
661
|
+
this.#contextStore = value ?? null;
|
|
662
|
+
},
|
|
663
|
+
subscribe: true
|
|
664
|
+
});
|
|
665
|
+
new ContextConsumer(this, {
|
|
666
|
+
context: config.containerContext,
|
|
667
|
+
callback: (value) => {
|
|
668
|
+
this.#setContainer = value?.setContainer ?? null;
|
|
669
|
+
if (this.isConnected) this.#setContainer?.(this);
|
|
670
|
+
},
|
|
671
|
+
subscribe: true
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
get store() {
|
|
675
|
+
return this.#contextStore;
|
|
676
|
+
}
|
|
677
|
+
connectedCallback() {
|
|
678
|
+
super.connectedCallback();
|
|
679
|
+
this.#setContainer?.(this);
|
|
680
|
+
}
|
|
681
|
+
disconnectedCallback() {
|
|
682
|
+
super.disconnectedCallback();
|
|
683
|
+
this.#setContainer?.(null);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
return PlayerContainerElement;
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
//#endregion
|
|
691
|
+
//#region src/ui/media-element.ts
|
|
692
|
+
/** Base class for interactive media UI elements. */
|
|
693
|
+
var MediaElement = class extends DestroyMixin(ReactiveElement) {};
|
|
694
|
+
|
|
695
|
+
//#endregion
|
|
696
|
+
//#region src/media/container-element.ts
|
|
697
|
+
const ContainerMixin = createContainerMixin({
|
|
698
|
+
playerContext,
|
|
699
|
+
containerContext
|
|
700
|
+
});
|
|
701
|
+
var MediaContainerElement = class extends ContainerMixin(MediaElement) {
|
|
702
|
+
static {
|
|
703
|
+
this.tagName = "media-container";
|
|
704
|
+
}
|
|
705
|
+
#disconnect = null;
|
|
706
|
+
connectedCallback() {
|
|
707
|
+
super.connectedCallback();
|
|
708
|
+
if (!this.hasAttribute("tabindex")) this.setAttribute("tabindex", "0");
|
|
709
|
+
this.#disconnect = new AbortController();
|
|
710
|
+
listen(this, "pointerup", this.#onPointerUp, { signal: this.#disconnect.signal });
|
|
711
|
+
}
|
|
712
|
+
disconnectedCallback() {
|
|
713
|
+
super.disconnectedCallback();
|
|
714
|
+
this.#disconnect?.abort();
|
|
715
|
+
this.#disconnect = null;
|
|
716
|
+
}
|
|
717
|
+
#onPointerUp = () => {
|
|
718
|
+
if (!this.contains(document.activeElement) || document.activeElement === document.body) this.focus({ preventScroll: true });
|
|
719
|
+
};
|
|
720
|
+
};
|
|
721
|
+
|
|
722
|
+
//#endregion
|
|
723
|
+
//#region ../utils/dist/predicate/predicate.js
|
|
724
|
+
function isNumber(value) {
|
|
725
|
+
return typeof value === "number";
|
|
726
|
+
}
|
|
727
|
+
function isFunction(value) {
|
|
728
|
+
return typeof value === "function";
|
|
729
|
+
}
|
|
730
|
+
function isNull(value) {
|
|
731
|
+
return value === null;
|
|
732
|
+
}
|
|
733
|
+
function isUndefined(value) {
|
|
734
|
+
return typeof value === "undefined";
|
|
735
|
+
}
|
|
736
|
+
/**
|
|
737
|
+
* Check if a value is an object, excluding null.
|
|
738
|
+
*/
|
|
739
|
+
function isObject(value) {
|
|
740
|
+
return value !== null && typeof value === "object";
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
//#endregion
|
|
744
|
+
//#region ../store/dist/dev/core/abort-controller-registry.js
|
|
745
|
+
var AbortControllerRegistry = class {
|
|
746
|
+
#base = new AbortController();
|
|
747
|
+
#keys = /* @__PURE__ */ new Map();
|
|
748
|
+
/** The attach-scoped signal. Aborts on detach or reattach. */
|
|
749
|
+
get base() {
|
|
750
|
+
return this.#base.signal;
|
|
751
|
+
}
|
|
752
|
+
/** Clears all keyed signals, leaving base intact. */
|
|
753
|
+
clear() {
|
|
754
|
+
for (const controller of this.#keys.values()) controller.abort();
|
|
755
|
+
this.#keys.clear();
|
|
756
|
+
}
|
|
757
|
+
/** Resets base and clears all keyed signals. */
|
|
758
|
+
reset() {
|
|
759
|
+
this.clear();
|
|
760
|
+
this.#base.abort();
|
|
761
|
+
this.#base = new AbortController();
|
|
762
|
+
}
|
|
763
|
+
/** Creates a new signal for the key, superseding any previous signal. */
|
|
764
|
+
supersede(key) {
|
|
765
|
+
this.#keys.get(key)?.abort();
|
|
766
|
+
const controller = new AbortController();
|
|
767
|
+
this.#keys.set(key, controller);
|
|
768
|
+
return anyAbortSignal([this.#base.signal, controller.signal]);
|
|
769
|
+
}
|
|
770
|
+
};
|
|
771
|
+
|
|
772
|
+
//#endregion
|
|
773
|
+
//#region ../store/dist/dev/core/combine.js
|
|
774
|
+
/**
|
|
775
|
+
* Combines multiple slices into a single slice.
|
|
776
|
+
*
|
|
777
|
+
* @param slices - The slices to combine.
|
|
778
|
+
* @returns A new slice that represents the combination of the input slices.
|
|
779
|
+
*/
|
|
780
|
+
function combine(...slices) {
|
|
781
|
+
return {
|
|
782
|
+
state: (ctx) => {
|
|
783
|
+
const states = slices.map((slice) => slice.state(ctx));
|
|
784
|
+
{
|
|
785
|
+
const seen = /* @__PURE__ */ new Set();
|
|
786
|
+
for (const state of states) for (const key of Object.keys(state)) {
|
|
787
|
+
if (seen.has(key)) console.warn(`[vjs-store] combine(): duplicate state key "${key}" — later slice overwrites earlier one`);
|
|
788
|
+
seen.add(key);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
return Object.assign({}, ...states);
|
|
792
|
+
},
|
|
793
|
+
attach: (ctx) => {
|
|
794
|
+
for (const slice of slices) try {
|
|
795
|
+
slice.attach?.(ctx);
|
|
796
|
+
} catch (err) {
|
|
797
|
+
ctx.reportError(err);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
//#endregion
|
|
804
|
+
//#region ../store/dist/dev/core/errors.js
|
|
805
|
+
var StoreError = class extends Error {
|
|
806
|
+
code;
|
|
807
|
+
cause;
|
|
808
|
+
constructor(code, options) {
|
|
809
|
+
super(options?.message ?? code);
|
|
810
|
+
this.name = "StoreError";
|
|
811
|
+
this.code = code;
|
|
812
|
+
this.cause = options?.cause;
|
|
813
|
+
}
|
|
814
|
+
};
|
|
815
|
+
function throwNoTargetError() {
|
|
816
|
+
throw new StoreError("NO_TARGET");
|
|
817
|
+
}
|
|
818
|
+
function throwDestroyedError() {
|
|
819
|
+
throw new StoreError("DESTROYED");
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
//#endregion
|
|
823
|
+
//#region ../store/dist/dev/core/slice.js
|
|
824
|
+
function defineSlice() {
|
|
825
|
+
return (config) => config;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
//#endregion
|
|
829
|
+
//#region ../utils/dist/function/noop.js
|
|
830
|
+
function noop(..._args) {}
|
|
831
|
+
|
|
832
|
+
//#endregion
|
|
833
|
+
//#region ../store/dist/dev/core/state.js
|
|
834
|
+
let isFlushScheduled = false;
|
|
835
|
+
function scheduleFlush() {
|
|
836
|
+
if (isFlushScheduled) return;
|
|
837
|
+
isFlushScheduled = true;
|
|
838
|
+
queueMicrotask(flush);
|
|
655
839
|
}
|
|
656
840
|
const pendingContainers = /* @__PURE__ */ new Set();
|
|
657
841
|
function flush() {
|
|
@@ -733,6 +917,7 @@ function createStore() {
|
|
|
733
917
|
return target;
|
|
734
918
|
},
|
|
735
919
|
signals,
|
|
920
|
+
get: () => state.current,
|
|
736
921
|
set: (partial) => state.patch(partial)
|
|
737
922
|
});
|
|
738
923
|
state = createState(initialState);
|
|
@@ -852,15 +1037,152 @@ const bufferFeature = definePlayerFeature({
|
|
|
852
1037
|
}
|
|
853
1038
|
});
|
|
854
1039
|
|
|
1040
|
+
//#endregion
|
|
1041
|
+
//#region ../core/dist/dev/dom/gesture/region.js
|
|
1042
|
+
/**
|
|
1043
|
+
* Determine which named region a pointer position falls into.
|
|
1044
|
+
*
|
|
1045
|
+
* Regions divide the container width equally based on how many are active:
|
|
1046
|
+
* - `left` + `right` → halves (50% / 50%)
|
|
1047
|
+
* - `left` + `center` + `right` → thirds (33% / 34% / 33%)
|
|
1048
|
+
*
|
|
1049
|
+
* Single region: `left` covers the left half, `right` the right half,
|
|
1050
|
+
* and `center` covers the full surface. Partial two-region combos
|
|
1051
|
+
* (e.g. `left` + `center`) use the same natural zones — positions outside
|
|
1052
|
+
* all active zones return `null` so full-surface gestures can handle them.
|
|
1053
|
+
*/
|
|
1054
|
+
function resolveRegion(clientX, containerRect, activeRegions) {
|
|
1055
|
+
if (activeRegions.size === 0) return null;
|
|
1056
|
+
const relativeX = clientX - containerRect.left;
|
|
1057
|
+
const width = containerRect.width;
|
|
1058
|
+
if (width === 0) return null;
|
|
1059
|
+
const ratio = relativeX / width;
|
|
1060
|
+
if (activeRegions.size === 2 && activeRegions.has("left") && activeRegions.has("right")) return ratio < .5 ? "left" : "right";
|
|
1061
|
+
if (activeRegions.size === 3) {
|
|
1062
|
+
if (ratio < 1 / 3) return "left";
|
|
1063
|
+
if (ratio < 2 / 3) return "center";
|
|
1064
|
+
return "right";
|
|
1065
|
+
}
|
|
1066
|
+
if (activeRegions.has("left") && ratio < .5) return "left";
|
|
1067
|
+
if (activeRegions.has("right") && ratio >= .5) return "right";
|
|
1068
|
+
if (activeRegions.has("center")) {
|
|
1069
|
+
if (activeRegions.size === 1) return "center";
|
|
1070
|
+
if (ratio >= 1 / 3 && ratio < 2 / 3) return "center";
|
|
1071
|
+
}
|
|
1072
|
+
return null;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
//#endregion
|
|
1076
|
+
//#region ../core/dist/dev/dom/gesture/coordinator.js
|
|
1077
|
+
const TAP_THRESHOLD$1 = 250;
|
|
1078
|
+
var GestureCoordinator = class {
|
|
1079
|
+
#target;
|
|
1080
|
+
#bindings = [];
|
|
1081
|
+
#recognizers = /* @__PURE__ */ new Set();
|
|
1082
|
+
#disconnect = null;
|
|
1083
|
+
constructor(target) {
|
|
1084
|
+
this.#target = target;
|
|
1085
|
+
}
|
|
1086
|
+
get bindings() {
|
|
1087
|
+
return this.#bindings;
|
|
1088
|
+
}
|
|
1089
|
+
add(binding) {
|
|
1090
|
+
this.#bindings.push(binding);
|
|
1091
|
+
this.#recognizers.add(binding.recognizer);
|
|
1092
|
+
this.#connect();
|
|
1093
|
+
let removed = false;
|
|
1094
|
+
return () => {
|
|
1095
|
+
if (removed) return;
|
|
1096
|
+
removed = true;
|
|
1097
|
+
const idx = this.#bindings.indexOf(binding);
|
|
1098
|
+
if (idx !== -1) this.#bindings.splice(idx, 1);
|
|
1099
|
+
this.#maybeDisconnect();
|
|
1100
|
+
};
|
|
1101
|
+
}
|
|
1102
|
+
#connect() {
|
|
1103
|
+
if (this.#disconnect) return;
|
|
1104
|
+
this.#disconnect = new AbortController();
|
|
1105
|
+
const { signal } = this.#disconnect;
|
|
1106
|
+
let pointerDownTime = 0;
|
|
1107
|
+
listen(this.#target, "pointerdown", () => {
|
|
1108
|
+
pointerDownTime = Date.now();
|
|
1109
|
+
}, { signal });
|
|
1110
|
+
listen(this.#target, "pointerup", (event) => {
|
|
1111
|
+
if (Date.now() - pointerDownTime > TAP_THRESHOLD$1) return;
|
|
1112
|
+
if (isInteractiveTarget(event)) return;
|
|
1113
|
+
const pointerType = event.pointerType;
|
|
1114
|
+
const clientX = event.clientX;
|
|
1115
|
+
const target = this.#target;
|
|
1116
|
+
const bindings = this.#bindings;
|
|
1117
|
+
const matches = { resolve: (type) => matchBindings(bindings, type, pointerType, clientX, target) };
|
|
1118
|
+
for (const recognizer of this.#recognizers) recognizer.handleUp(matches, event);
|
|
1119
|
+
}, { signal });
|
|
1120
|
+
}
|
|
1121
|
+
#maybeDisconnect() {
|
|
1122
|
+
if (this.#bindings.length > 0) return;
|
|
1123
|
+
for (const recognizer of this.#recognizers) recognizer.reset();
|
|
1124
|
+
this.#recognizers.clear();
|
|
1125
|
+
this.#disconnect?.abort();
|
|
1126
|
+
this.#disconnect = null;
|
|
1127
|
+
}
|
|
1128
|
+
};
|
|
1129
|
+
const coordinators = /* @__PURE__ */ new WeakMap();
|
|
1130
|
+
/** Look up the gesture coordinator for a target element, if one exists. */
|
|
1131
|
+
function findGestureCoordinator(target) {
|
|
1132
|
+
return coordinators.get(target);
|
|
1133
|
+
}
|
|
1134
|
+
function getGestureCoordinator(target) {
|
|
1135
|
+
let coordinator = coordinators.get(target);
|
|
1136
|
+
if (!coordinator) {
|
|
1137
|
+
coordinator = new GestureCoordinator(target);
|
|
1138
|
+
coordinators.set(target, coordinator);
|
|
1139
|
+
}
|
|
1140
|
+
return coordinator;
|
|
1141
|
+
}
|
|
1142
|
+
function matchBindings(bindings, type, pointerType, clientX, target) {
|
|
1143
|
+
const rect = target.getBoundingClientRect();
|
|
1144
|
+
const activeRegions = getActiveRegions(bindings, type, pointerType);
|
|
1145
|
+
const region = activeRegions.size > 0 ? resolveRegion(clientX, rect, activeRegions) : null;
|
|
1146
|
+
const matches = [];
|
|
1147
|
+
for (const binding of bindings) {
|
|
1148
|
+
if (binding.disabled) continue;
|
|
1149
|
+
if (binding.type !== type) continue;
|
|
1150
|
+
if (binding.pointer && binding.pointer !== pointerType) continue;
|
|
1151
|
+
if (binding.region) {
|
|
1152
|
+
if (binding.region !== region) continue;
|
|
1153
|
+
} else if (region !== null) continue;
|
|
1154
|
+
matches.push(binding);
|
|
1155
|
+
}
|
|
1156
|
+
return matches;
|
|
1157
|
+
}
|
|
1158
|
+
function getActiveRegions(bindings, type, pointerType) {
|
|
1159
|
+
const regions = /* @__PURE__ */ new Set();
|
|
1160
|
+
for (const binding of bindings) {
|
|
1161
|
+
if (binding.disabled) continue;
|
|
1162
|
+
if (binding.type !== type) continue;
|
|
1163
|
+
if (binding.pointer && binding.pointer !== pointerType) continue;
|
|
1164
|
+
if (binding.region) regions.add(binding.region);
|
|
1165
|
+
}
|
|
1166
|
+
return regions;
|
|
1167
|
+
}
|
|
1168
|
+
|
|
855
1169
|
//#endregion
|
|
856
1170
|
//#region ../core/dist/dev/dom/store/features/controls.js
|
|
857
1171
|
const IDLE_DELAY = 2e3;
|
|
858
1172
|
const TAP_THRESHOLD = 250;
|
|
859
1173
|
const controlsFeature = definePlayerFeature({
|
|
860
1174
|
name: "controls",
|
|
861
|
-
state: () => ({
|
|
1175
|
+
state: ({ get, set }) => ({
|
|
862
1176
|
userActive: true,
|
|
863
|
-
controlsVisible: true
|
|
1177
|
+
controlsVisible: true,
|
|
1178
|
+
toggleControls() {
|
|
1179
|
+
const next = !get().userActive;
|
|
1180
|
+
set({
|
|
1181
|
+
userActive: next,
|
|
1182
|
+
controlsVisible: next
|
|
1183
|
+
});
|
|
1184
|
+
return next;
|
|
1185
|
+
}
|
|
864
1186
|
}),
|
|
865
1187
|
attach({ target, signal, get, set }) {
|
|
866
1188
|
const { media, container } = target;
|
|
@@ -894,12 +1216,18 @@ const controlsFeature = definePlayerFeature({
|
|
|
894
1216
|
controlsVisible: computeVisible(false)
|
|
895
1217
|
});
|
|
896
1218
|
}
|
|
1219
|
+
set({ toggleControls() {
|
|
1220
|
+
if (get().controlsVisible) setInactive();
|
|
1221
|
+
else setActive();
|
|
1222
|
+
return get().controlsVisible;
|
|
1223
|
+
} });
|
|
897
1224
|
let pointerDownTime = 0;
|
|
898
1225
|
function onPointerDown() {
|
|
899
1226
|
pointerDownTime = Date.now();
|
|
900
1227
|
}
|
|
901
1228
|
function onPointerUp(event) {
|
|
902
1229
|
if (event.pointerType === "touch" && Date.now() - pointerDownTime < TAP_THRESHOLD) {
|
|
1230
|
+
if (findGestureCoordinator(container)?.bindings.some((b) => b.type === "tap" && b.action === "toggleControls" && (!b.pointer || b.pointer === "touch"))) return;
|
|
903
1231
|
const isMediaOrContainer = [media, container].includes(event.target);
|
|
904
1232
|
if (get().controlsVisible && isMediaOrContainer) setInactive();
|
|
905
1233
|
else setActive();
|
|
@@ -1083,6 +1411,12 @@ const fullscreenFeature = definePlayerFeature({
|
|
|
1083
1411
|
async exitFullscreen() {
|
|
1084
1412
|
const { media } = target();
|
|
1085
1413
|
return exitFullscreen(media);
|
|
1414
|
+
},
|
|
1415
|
+
async toggleFullscreen() {
|
|
1416
|
+
const { media, container } = target();
|
|
1417
|
+
if (isFullscreenElement(container, media)) return exitFullscreen(media);
|
|
1418
|
+
if (isPictureInPictureElement(media)) await exitPictureInPicture(media);
|
|
1419
|
+
return requestFullscreen(container, media);
|
|
1086
1420
|
}
|
|
1087
1421
|
}),
|
|
1088
1422
|
attach({ target, signal, set }) {
|
|
@@ -1111,6 +1445,12 @@ const pipFeature = definePlayerFeature({
|
|
|
1111
1445
|
async exitPictureInPicture() {
|
|
1112
1446
|
const { media } = target();
|
|
1113
1447
|
return exitPictureInPicture(media);
|
|
1448
|
+
},
|
|
1449
|
+
async togglePictureInPicture() {
|
|
1450
|
+
const { media, container } = target();
|
|
1451
|
+
if (isPictureInPictureElement(media)) return exitPictureInPicture(media);
|
|
1452
|
+
if (isFullscreenElement(container, media)) await exitFullscreen();
|
|
1453
|
+
return requestPictureInPicture(media);
|
|
1114
1454
|
}
|
|
1115
1455
|
}),
|
|
1116
1456
|
attach({ target, signal, set }) {
|
|
@@ -1138,6 +1478,15 @@ const playbackFeature = definePlayerFeature({
|
|
|
1138
1478
|
},
|
|
1139
1479
|
pause() {
|
|
1140
1480
|
target().media.pause();
|
|
1481
|
+
},
|
|
1482
|
+
togglePaused() {
|
|
1483
|
+
const media = target().media;
|
|
1484
|
+
if (media.paused) {
|
|
1485
|
+
media.play();
|
|
1486
|
+
return true;
|
|
1487
|
+
}
|
|
1488
|
+
media.pause();
|
|
1489
|
+
return false;
|
|
1141
1490
|
}
|
|
1142
1491
|
}),
|
|
1143
1492
|
attach({ target, signal, set }) {
|
|
@@ -1162,6 +1511,9 @@ const playbackFeature = definePlayerFeature({
|
|
|
1162
1511
|
//#endregion
|
|
1163
1512
|
//#region ../core/dist/dev/dom/store/features/playback-rate.js
|
|
1164
1513
|
const DEFAULT_RATES = [
|
|
1514
|
+
.2,
|
|
1515
|
+
.5,
|
|
1516
|
+
.7,
|
|
1165
1517
|
1,
|
|
1166
1518
|
1.2,
|
|
1167
1519
|
1.5,
|
|
@@ -1312,15 +1664,19 @@ const timeFeature = definePlayerFeature({
|
|
|
1312
1664
|
return media.currentTime;
|
|
1313
1665
|
}
|
|
1314
1666
|
}),
|
|
1315
|
-
attach({ target, signal, set }) {
|
|
1667
|
+
attach({ target, signal, set, get }) {
|
|
1316
1668
|
const { media } = target;
|
|
1317
1669
|
const sync = () => set({
|
|
1318
1670
|
currentTime: media.currentTime,
|
|
1319
1671
|
duration: Number.isFinite(media.duration) ? media.duration : 0,
|
|
1320
1672
|
seeking: media.seeking
|
|
1321
1673
|
});
|
|
1674
|
+
const onTimeUpdate = () => {
|
|
1675
|
+
if (get().seeking) return;
|
|
1676
|
+
sync();
|
|
1677
|
+
};
|
|
1322
1678
|
sync();
|
|
1323
|
-
listen(media, "timeupdate",
|
|
1679
|
+
listen(media, "timeupdate", onTimeUpdate, { signal });
|
|
1324
1680
|
listen(media, "durationchange", sync, { signal });
|
|
1325
1681
|
listen(media, "seeking", sync, { signal });
|
|
1326
1682
|
listen(media, "seeked", sync, { signal });
|
|
@@ -1404,1535 +1760,231 @@ const audioFeatures = [
|
|
|
1404
1760
|
const backgroundFeatures = [];
|
|
1405
1761
|
|
|
1406
1762
|
//#endregion
|
|
1407
|
-
//#region ../
|
|
1408
|
-
/**
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
//#endregion
|
|
1432
|
-
//#region ../core/dist/dev/dom/ui/dismiss-layer.js
|
|
1433
|
-
function createDismissLayer(options) {
|
|
1434
|
-
const { transition } = options;
|
|
1435
|
-
const state = transition.state;
|
|
1436
|
-
const abort = new AbortController();
|
|
1437
|
-
let docAbort = null;
|
|
1438
|
-
function open() {
|
|
1439
|
-
if (abort.signal.aborted) return null;
|
|
1440
|
-
const { active, status } = state.current;
|
|
1441
|
-
if (active && status !== "ending") return null;
|
|
1442
|
-
if (status === "ending") transition.cancel();
|
|
1443
|
-
return transition.open();
|
|
1444
|
-
}
|
|
1445
|
-
function close(element) {
|
|
1446
|
-
const { active, status } = state.current;
|
|
1447
|
-
if (abort.signal.aborted || !active || status === "ending") return null;
|
|
1448
|
-
return transition.close(element);
|
|
1449
|
-
}
|
|
1450
|
-
function setupDocumentListeners() {
|
|
1451
|
-
cleanupDocumentListeners();
|
|
1452
|
-
if (typeof document === "undefined") return;
|
|
1453
|
-
docAbort = new AbortController();
|
|
1454
|
-
const { signal } = docAbort;
|
|
1455
|
-
listen(document, "keydown", handleKeydown, { signal });
|
|
1456
|
-
options.onDocumentActive?.(signal);
|
|
1457
|
-
}
|
|
1458
|
-
function cleanupDocumentListeners() {
|
|
1459
|
-
docAbort?.abort();
|
|
1460
|
-
docAbort = null;
|
|
1461
|
-
}
|
|
1462
|
-
function handleKeydown(event) {
|
|
1463
|
-
if (event.key !== "Escape") return;
|
|
1464
|
-
if (!state.current.active) return;
|
|
1465
|
-
if (!(options.closeOnEscape?.() ?? true)) return;
|
|
1466
|
-
options.onEscapeDismiss(event);
|
|
1467
|
-
}
|
|
1468
|
-
const unsubscribe = state.subscribe(() => {
|
|
1469
|
-
if (state.current.active) setupDocumentListeners();
|
|
1470
|
-
else cleanupDocumentListeners();
|
|
1471
|
-
});
|
|
1472
|
-
abort.signal.addEventListener("abort", () => {
|
|
1473
|
-
unsubscribe();
|
|
1474
|
-
transition.destroy();
|
|
1475
|
-
cleanupDocumentListeners();
|
|
1476
|
-
});
|
|
1477
|
-
function destroy() {
|
|
1478
|
-
if (abort.signal.aborted) return;
|
|
1479
|
-
abort.abort();
|
|
1480
|
-
}
|
|
1481
|
-
return {
|
|
1482
|
-
input: state,
|
|
1483
|
-
open,
|
|
1484
|
-
close,
|
|
1485
|
-
signal: abort.signal,
|
|
1486
|
-
destroy
|
|
1487
|
-
};
|
|
1488
|
-
}
|
|
1489
|
-
|
|
1490
|
-
//#endregion
|
|
1491
|
-
//#region ../core/dist/dev/dom/ui/alert-dialog.js
|
|
1492
|
-
function createAlertDialog(options) {
|
|
1493
|
-
const { onOpenChange } = options;
|
|
1494
|
-
let element = null;
|
|
1495
|
-
let previousFocus = null;
|
|
1496
|
-
let elementAbort = null;
|
|
1497
|
-
const layer = createDismissLayer({
|
|
1498
|
-
transition: options.transition,
|
|
1499
|
-
closeOnEscape: options.closeOnEscape,
|
|
1500
|
-
onEscapeDismiss(event) {
|
|
1501
|
-
event.stopPropagation();
|
|
1502
|
-
applyClose();
|
|
1503
|
-
}
|
|
1504
|
-
});
|
|
1505
|
-
const state = layer.input;
|
|
1506
|
-
function applyOpen() {
|
|
1507
|
-
previousFocus = document.activeElement;
|
|
1508
|
-
const opening = layer.open();
|
|
1509
|
-
if (!opening) return;
|
|
1510
|
-
onOpenChange(true);
|
|
1511
|
-
requestAnimationFrame(() => {
|
|
1512
|
-
if (layer.signal.aborted || !state.current.active) return;
|
|
1513
|
-
element?.focus();
|
|
1514
|
-
});
|
|
1515
|
-
opening.then(() => {
|
|
1516
|
-
if (layer.signal.aborted || !state.current.active) return;
|
|
1517
|
-
options.onOpenChangeComplete?.(true);
|
|
1518
|
-
});
|
|
1519
|
-
}
|
|
1520
|
-
function applyClose() {
|
|
1521
|
-
const closing = layer.close(element);
|
|
1522
|
-
if (!closing) return;
|
|
1523
|
-
onOpenChange(false);
|
|
1524
|
-
closing.then(() => {
|
|
1525
|
-
if (layer.signal.aborted) return;
|
|
1526
|
-
if (previousFocus) {
|
|
1527
|
-
previousFocus.focus();
|
|
1528
|
-
previousFocus = null;
|
|
1529
|
-
}
|
|
1530
|
-
options.onOpenChangeComplete?.(false);
|
|
1531
|
-
});
|
|
1763
|
+
//#region ../store/dist/dev/html/controllers/snapshot-controller.js
|
|
1764
|
+
/**
|
|
1765
|
+
* Subscribe to a `State<T>` container with optional selector.
|
|
1766
|
+
*
|
|
1767
|
+
* Without selector: returns full state, re-renders on any state change.
|
|
1768
|
+
* With selector: returns selected slice, re-renders only when the slice changes (shallowEqual).
|
|
1769
|
+
*
|
|
1770
|
+
* @example
|
|
1771
|
+
* ```ts
|
|
1772
|
+
* #state = new SnapshotController(this, sliderState, (s) => s.value);
|
|
1773
|
+
* ```
|
|
1774
|
+
*/
|
|
1775
|
+
var SnapshotController = class {
|
|
1776
|
+
#host;
|
|
1777
|
+
#selector;
|
|
1778
|
+
#state;
|
|
1779
|
+
#cached;
|
|
1780
|
+
#unsubscribe = noop;
|
|
1781
|
+
constructor(host, state, selector) {
|
|
1782
|
+
this.#host = host;
|
|
1783
|
+
this.#state = state;
|
|
1784
|
+
this.#selector = selector;
|
|
1785
|
+
host.addController(this);
|
|
1532
1786
|
}
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
const { signal } = elementAbort;
|
|
1538
|
-
listen(element, "click", handleElementClick, { signal });
|
|
1787
|
+
get value() {
|
|
1788
|
+
if (!this.#selector) return this.#state.current;
|
|
1789
|
+
this.#cached ??= this.#selector(this.#state.current);
|
|
1790
|
+
return this.#cached;
|
|
1539
1791
|
}
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1792
|
+
/** Switch to tracking a different state container. */
|
|
1793
|
+
track(state) {
|
|
1794
|
+
this.#state = state;
|
|
1795
|
+
this.#subscribe();
|
|
1543
1796
|
}
|
|
1544
|
-
|
|
1545
|
-
|
|
1797
|
+
hostConnected() {
|
|
1798
|
+
this.#subscribe();
|
|
1546
1799
|
}
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1800
|
+
hostDisconnected() {
|
|
1801
|
+
this.#unsubscribe();
|
|
1802
|
+
this.#unsubscribe = noop;
|
|
1803
|
+
this.#cached = void 0;
|
|
1550
1804
|
}
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
return {
|
|
1557
|
-
input: state,
|
|
1558
|
-
open: applyOpen,
|
|
1559
|
-
close: applyClose,
|
|
1560
|
-
setElement,
|
|
1561
|
-
destroy: layer.destroy
|
|
1562
|
-
};
|
|
1563
|
-
}
|
|
1564
|
-
|
|
1565
|
-
//#endregion
|
|
1566
|
-
//#region ../core/dist/dev/dom/ui/button.js
|
|
1567
|
-
function createButton(options) {
|
|
1568
|
-
const { onActivate, isDisabled } = options;
|
|
1569
|
-
return {
|
|
1570
|
-
role: "button",
|
|
1571
|
-
tabIndex: 0,
|
|
1572
|
-
onClick(event) {
|
|
1573
|
-
if (isDisabled()) {
|
|
1574
|
-
event.preventDefault();
|
|
1575
|
-
return;
|
|
1576
|
-
}
|
|
1577
|
-
onActivate();
|
|
1578
|
-
},
|
|
1579
|
-
onPointerDown(event) {
|
|
1580
|
-
if (isDisabled()) event.preventDefault();
|
|
1581
|
-
},
|
|
1582
|
-
onMouseDown(event) {
|
|
1583
|
-
if (isDisabled()) event.preventDefault();
|
|
1584
|
-
},
|
|
1585
|
-
onKeyDown(event) {
|
|
1586
|
-
if (event.target !== event.currentTarget) return;
|
|
1587
|
-
if (isDisabled()) {
|
|
1588
|
-
if (event.key !== "Tab") event.preventDefault();
|
|
1589
|
-
return;
|
|
1590
|
-
}
|
|
1591
|
-
if (event.key === "Enter") {
|
|
1592
|
-
event.preventDefault();
|
|
1593
|
-
onActivate();
|
|
1594
|
-
} else if (event.key === " ") event.preventDefault();
|
|
1595
|
-
},
|
|
1596
|
-
onKeyUp(event) {
|
|
1597
|
-
if (event.target !== event.currentTarget) return;
|
|
1598
|
-
if (isDisabled()) return;
|
|
1599
|
-
if (event.key === " ") onActivate();
|
|
1805
|
+
#subscribe() {
|
|
1806
|
+
this.#unsubscribe();
|
|
1807
|
+
if (!this.#selector) {
|
|
1808
|
+
this.#unsubscribe = this.#state.subscribe(() => this.#host.requestUpdate());
|
|
1809
|
+
return;
|
|
1600
1810
|
}
|
|
1601
|
-
|
|
1602
|
-
|
|
1811
|
+
const selector = this.#selector;
|
|
1812
|
+
this.#cached = selector(this.#state.current);
|
|
1813
|
+
this.#unsubscribe = this.#state.subscribe(() => {
|
|
1814
|
+
const next = selector(this.#state.current);
|
|
1815
|
+
if (!shallowEqual(this.#cached, next)) {
|
|
1816
|
+
this.#cached = next;
|
|
1817
|
+
this.#host.requestUpdate();
|
|
1818
|
+
}
|
|
1819
|
+
});
|
|
1820
|
+
}
|
|
1821
|
+
};
|
|
1603
1822
|
|
|
1604
1823
|
//#endregion
|
|
1605
|
-
//#region ../
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1824
|
+
//#region ../store/dist/dev/html/store-accessor.js
|
|
1825
|
+
/**
|
|
1826
|
+
* Resolves a store from either a direct instance or context.
|
|
1827
|
+
*
|
|
1828
|
+
* When given a direct store, provides immediate access.
|
|
1829
|
+
* When given a context, sets up a ContextConsumer to receive the store.
|
|
1830
|
+
*
|
|
1831
|
+
* @example Direct store
|
|
1832
|
+
* ```ts
|
|
1833
|
+
* const accessor = new StoreAccessor(host, store, (s) => console.log('available', s));
|
|
1834
|
+
* accessor.value; // Store (immediately available)
|
|
1835
|
+
* ```
|
|
1836
|
+
*
|
|
1837
|
+
* @example Context source
|
|
1838
|
+
* ```ts
|
|
1839
|
+
* const accessor = new StoreAccessor(host, context, (s) => console.log('available', s));
|
|
1840
|
+
* accessor.value; // null until context provides store
|
|
1841
|
+
* ```
|
|
1842
|
+
*/
|
|
1843
|
+
var StoreAccessor = class {
|
|
1844
|
+
#onAvailable;
|
|
1845
|
+
#consumer;
|
|
1846
|
+
#directStore;
|
|
1847
|
+
constructor(host, source, onAvailable) {
|
|
1848
|
+
this.#onAvailable = onAvailable ?? noop;
|
|
1849
|
+
if (isStore(source)) {
|
|
1850
|
+
this.#directStore = source;
|
|
1851
|
+
this.#consumer = null;
|
|
1852
|
+
} else {
|
|
1853
|
+
this.#directStore = null;
|
|
1854
|
+
this.#consumer = new ContextConsumer(host, {
|
|
1855
|
+
context: source,
|
|
1856
|
+
callback: (store) => this.#onAvailable(store),
|
|
1857
|
+
subscribe: false
|
|
1623
1858
|
});
|
|
1624
1859
|
}
|
|
1625
|
-
|
|
1626
|
-
const state = layer.input;
|
|
1627
|
-
function clearHoverTimeout() {
|
|
1628
|
-
if (hoverTimeout !== null) {
|
|
1629
|
-
clearTimeout(hoverTimeout);
|
|
1630
|
-
hoverTimeout = null;
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
function canHover() {
|
|
1634
|
-
return globalThis.matchMedia?.("(hover: hover)")?.matches ?? false;
|
|
1635
|
-
}
|
|
1636
|
-
function canOpenOnFocus() {
|
|
1637
|
-
if (!canHover()) return false;
|
|
1638
|
-
return globalThis.matchMedia?.("(pointer: fine)")?.matches ?? false;
|
|
1639
|
-
}
|
|
1640
|
-
function canToggleOnClick() {
|
|
1641
|
-
if (!options.openOnHover?.()) return true;
|
|
1642
|
-
return canHover();
|
|
1643
|
-
}
|
|
1644
|
-
/**
|
|
1645
|
-
* The transition handler manages animation lifecycle via `createState`:
|
|
1646
|
-
*
|
|
1647
|
-
* **Open:** `transition.open()` patches `{ active: true, status: 'starting' }`.
|
|
1648
|
-
* After one RAF it patches `{ status: 'idle' }` and the promise resolves.
|
|
1649
|
-
* Frameworks render `data-starting-style` / `data-ending-style` via
|
|
1650
|
-
* `getPopupAttrs(state)` — no imperative DOM mutation needed.
|
|
1651
|
-
*
|
|
1652
|
-
* **Close:** `transition.close(el)` patches `{ status: 'ending' }` (keeping
|
|
1653
|
-
* `active: true` so the element stays mounted). After a double-RAF it waits
|
|
1654
|
-
* for `getAnimations()` to settle, then patches `{ active: false, status: 'idle' }`.
|
|
1655
|
-
*
|
|
1656
|
-
* `onOpenChange` fires immediately (before animations).
|
|
1657
|
-
* `onOpenChangeComplete` fires after animations finish.
|
|
1658
|
-
*/
|
|
1659
|
-
function applyOpen(reason, event) {
|
|
1660
|
-
const opening = layer.open();
|
|
1661
|
-
if (!opening) return;
|
|
1662
|
-
onOpenChange(true, event ? {
|
|
1663
|
-
reason,
|
|
1664
|
-
event
|
|
1665
|
-
} : { reason });
|
|
1666
|
-
opening.then(() => {
|
|
1667
|
-
if (layer.signal.aborted || !state.current.active) return;
|
|
1668
|
-
options.onOpenChangeComplete?.(true);
|
|
1669
|
-
});
|
|
1670
|
-
}
|
|
1671
|
-
function applyClose(reason, event) {
|
|
1672
|
-
const closing = layer.close(popupEl);
|
|
1673
|
-
if (!closing) return;
|
|
1674
|
-
onOpenChange(false, event ? {
|
|
1675
|
-
reason,
|
|
1676
|
-
event
|
|
1677
|
-
} : { reason });
|
|
1678
|
-
closing.then(() => {
|
|
1679
|
-
if (layer.signal.aborted) return;
|
|
1680
|
-
tryHidePopover(popupEl);
|
|
1681
|
-
options.onOpenChangeComplete?.(false);
|
|
1682
|
-
});
|
|
1683
|
-
}
|
|
1684
|
-
function open(reason = "click") {
|
|
1685
|
-
applyOpen(reason);
|
|
1686
|
-
}
|
|
1687
|
-
function close(reason = "click") {
|
|
1688
|
-
applyClose(reason);
|
|
1860
|
+
host.addController(this);
|
|
1689
1861
|
}
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
applyClose("outside-click", event);
|
|
1862
|
+
/** Returns the store, or null if not yet available from context. */
|
|
1863
|
+
get value() {
|
|
1864
|
+
if (this.#consumer) return this.#consumer.value ?? null;
|
|
1865
|
+
return this.#directStore;
|
|
1695
1866
|
}
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
capturedPointers.clear();
|
|
1699
|
-
triggerEl = null;
|
|
1700
|
-
popupEl = null;
|
|
1701
|
-
});
|
|
1702
|
-
const triggerProps = {
|
|
1703
|
-
onClick(event) {
|
|
1704
|
-
if (!canToggleOnClick()) return;
|
|
1705
|
-
if (state.current.active && state.current.status !== "ending") applyClose("click", event);
|
|
1706
|
-
else applyOpen("click", event);
|
|
1707
|
-
},
|
|
1708
|
-
onPointerEnter(_event) {
|
|
1709
|
-
if (!options.openOnHover?.()) return;
|
|
1710
|
-
if (!canHover()) return;
|
|
1711
|
-
clearHoverTimeout();
|
|
1712
|
-
if (state.current.active) return;
|
|
1713
|
-
const delay = options.delay?.() ?? 300;
|
|
1714
|
-
hoverTimeout = setTimeout(() => applyOpen("hover"), delay);
|
|
1715
|
-
},
|
|
1716
|
-
onPointerLeave(_event) {
|
|
1717
|
-
if (!options.openOnHover?.()) return;
|
|
1718
|
-
if (!canHover()) return;
|
|
1719
|
-
clearHoverTimeout();
|
|
1720
|
-
if (!state.current.active) return;
|
|
1721
|
-
const closeDelay = options.closeDelay?.() ?? 0;
|
|
1722
|
-
hoverTimeout = setTimeout(() => applyClose("hover"), closeDelay);
|
|
1723
|
-
},
|
|
1724
|
-
onFocusIn(_event) {
|
|
1725
|
-
if (options.openOnHover?.()) {
|
|
1726
|
-
if (!canOpenOnFocus()) return;
|
|
1727
|
-
applyOpen("focus");
|
|
1728
|
-
}
|
|
1729
|
-
},
|
|
1730
|
-
onFocusOut(event) {
|
|
1731
|
-
const relatedTarget = event.relatedTarget;
|
|
1732
|
-
if (relatedTarget && (triggerEl?.contains(relatedTarget) || popupEl?.contains(relatedTarget))) return;
|
|
1733
|
-
if (options.openOnHover?.()) applyClose("blur");
|
|
1734
|
-
}
|
|
1735
|
-
};
|
|
1736
|
-
const popupProps = {
|
|
1737
|
-
onPointerEnter(_event) {
|
|
1738
|
-
if (!options.openOnHover?.()) return;
|
|
1739
|
-
clearHoverTimeout();
|
|
1740
|
-
},
|
|
1741
|
-
onPointerLeave(_event) {
|
|
1742
|
-
if (!options.openOnHover?.()) return;
|
|
1743
|
-
if (capturedPointers.size > 0) return;
|
|
1744
|
-
clearHoverTimeout();
|
|
1745
|
-
if (!state.current.active) return;
|
|
1746
|
-
const closeDelay = options.closeDelay?.() ?? 0;
|
|
1747
|
-
hoverTimeout = setTimeout(() => applyClose("hover"), closeDelay);
|
|
1748
|
-
},
|
|
1749
|
-
onGotPointerCapture(event) {
|
|
1750
|
-
capturedPointers.add(event.pointerId);
|
|
1751
|
-
},
|
|
1752
|
-
onLostPointerCapture(event) {
|
|
1753
|
-
capturedPointers.delete(event.pointerId);
|
|
1754
|
-
},
|
|
1755
|
-
onFocusOut(event) {
|
|
1756
|
-
const relatedTarget = event.relatedTarget;
|
|
1757
|
-
if (relatedTarget && (triggerEl?.contains(relatedTarget) || popupEl?.contains(relatedTarget))) return;
|
|
1758
|
-
applyClose("blur");
|
|
1759
|
-
}
|
|
1760
|
-
};
|
|
1761
|
-
function setTriggerElement(el) {
|
|
1762
|
-
triggerEl = el;
|
|
1763
|
-
}
|
|
1764
|
-
function setPopupElement(el) {
|
|
1765
|
-
if (!el && popupEl && state.current.active) tryHidePopover(popupEl);
|
|
1766
|
-
popupEl = el;
|
|
1767
|
-
if (el) {
|
|
1768
|
-
if (state.current.active) tryShowPopover(el);
|
|
1769
|
-
}
|
|
1867
|
+
hostConnected() {
|
|
1868
|
+
if (this.#directStore) this.#onAvailable(this.#directStore);
|
|
1770
1869
|
}
|
|
1771
|
-
return {
|
|
1772
|
-
input: state,
|
|
1773
|
-
triggerProps,
|
|
1774
|
-
popupProps,
|
|
1775
|
-
get triggerElement() {
|
|
1776
|
-
return triggerEl;
|
|
1777
|
-
},
|
|
1778
|
-
setTriggerElement,
|
|
1779
|
-
setPopupElement,
|
|
1780
|
-
open,
|
|
1781
|
-
close,
|
|
1782
|
-
destroy: layer.destroy
|
|
1783
|
-
};
|
|
1784
|
-
}
|
|
1785
|
-
|
|
1786
|
-
//#endregion
|
|
1787
|
-
//#region ../core/dist/dev/core/ui/popover/popover-css-vars.js
|
|
1788
|
-
const PopoverCSSVars = {
|
|
1789
|
-
sideOffset: "--media-popover-side-offset",
|
|
1790
|
-
alignOffset: "--media-popover-align-offset",
|
|
1791
|
-
anchorWidth: "--media-popover-anchor-width",
|
|
1792
|
-
anchorHeight: "--media-popover-anchor-height",
|
|
1793
|
-
availableWidth: "--media-popover-available-width",
|
|
1794
|
-
availableHeight: "--media-popover-available-height"
|
|
1795
1870
|
};
|
|
1796
1871
|
|
|
1797
1872
|
//#endregion
|
|
1798
|
-
//#region ../
|
|
1799
|
-
const OPPOSITE_SIDE = {
|
|
1800
|
-
top: "bottom",
|
|
1801
|
-
bottom: "top",
|
|
1802
|
-
left: "right",
|
|
1803
|
-
right: "left"
|
|
1804
|
-
};
|
|
1873
|
+
//#region ../store/dist/dev/html/controllers/store-controller.js
|
|
1805
1874
|
/**
|
|
1806
|
-
*
|
|
1875
|
+
* Access store state and actions.
|
|
1876
|
+
*
|
|
1877
|
+
* Without selector: Returns the store, does NOT subscribe to changes.
|
|
1878
|
+
* With selector: Returns selected state, triggers update when selected state changes (shallowEqual).
|
|
1879
|
+
*
|
|
1880
|
+
* @example
|
|
1881
|
+
* ```ts
|
|
1882
|
+
* // Store access (no subscription) - access actions
|
|
1883
|
+
* class Controls extends LitElement {
|
|
1884
|
+
* #store = new StoreController(this, storeSource);
|
|
1807
1885
|
*
|
|
1808
|
-
*
|
|
1809
|
-
*
|
|
1810
|
-
*
|
|
1886
|
+
* handleClick() {
|
|
1887
|
+
* this.#store.value.setVolume(0.5);
|
|
1888
|
+
* }
|
|
1889
|
+
* }
|
|
1811
1890
|
*
|
|
1812
|
-
*
|
|
1813
|
-
*
|
|
1814
|
-
*
|
|
1891
|
+
* // Selector-based subscription - re-renders when playback changes
|
|
1892
|
+
* class PlayButton extends LitElement {
|
|
1893
|
+
* #playback = new StoreController(this, storeSource, selectPlayback);
|
|
1815
1894
|
*
|
|
1816
|
-
*
|
|
1817
|
-
*
|
|
1818
|
-
*
|
|
1895
|
+
* render() {
|
|
1896
|
+
* const playback = this.#playback.value;
|
|
1897
|
+
* if (!playback) return nothing;
|
|
1898
|
+
* return html`<button @click=${playback.toggle}>
|
|
1899
|
+
* ${playback.paused ? 'Play' : 'Pause'}
|
|
1900
|
+
* </button>`;
|
|
1901
|
+
* }
|
|
1902
|
+
* }
|
|
1903
|
+
* ```
|
|
1819
1904
|
*/
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
margin: "0"
|
|
1831
|
-
};
|
|
1832
|
-
return {};
|
|
1833
|
-
}
|
|
1834
|
-
/** Generate style to set on the trigger for CSS Anchor Positioning. */
|
|
1835
|
-
function getAnchorNameStyle(anchorName) {
|
|
1836
|
-
if (!supportsAnchorPositioning()) return {};
|
|
1837
|
-
return { anchorName: `--${anchorName}` };
|
|
1838
|
-
}
|
|
1839
|
-
function getAnchorPositionCSS(anchorName, opts, cssVars = PopoverCSSVars) {
|
|
1840
|
-
const SIDE_OFFSET_VAR = `var(${cssVars.sideOffset}, 0px)`;
|
|
1841
|
-
const ALIGN_OFFSET_VAR = `var(${cssVars.alignOffset}, 0px)`;
|
|
1842
|
-
const { side, align } = opts;
|
|
1843
|
-
const style = {
|
|
1844
|
-
positionAnchor: `--${anchorName}`,
|
|
1845
|
-
position: "fixed",
|
|
1846
|
-
inset: "auto",
|
|
1847
|
-
margin: "0",
|
|
1848
|
-
justifySelf: "normal",
|
|
1849
|
-
alignSelf: "normal",
|
|
1850
|
-
marginInlineStart: "0",
|
|
1851
|
-
marginBlockStart: "0"
|
|
1852
|
-
};
|
|
1853
|
-
const insetProp = OPPOSITE_SIDE[side];
|
|
1854
|
-
if (side === "top" || side === "bottom") {
|
|
1855
|
-
style[insetProp] = `calc(anchor(${side}) + ${SIDE_OFFSET_VAR})`;
|
|
1856
|
-
if (align === "start") style.left = `calc(anchor(left) + ${ALIGN_OFFSET_VAR})`;
|
|
1857
|
-
else if (align === "end") style.right = `calc(anchor(right) + ${ALIGN_OFFSET_VAR})`;
|
|
1858
|
-
else {
|
|
1859
|
-
style.justifySelf = "anchor-center";
|
|
1860
|
-
style.marginInlineStart = ALIGN_OFFSET_VAR;
|
|
1861
|
-
}
|
|
1862
|
-
} else {
|
|
1863
|
-
style[insetProp] = `calc(anchor(${side}) + ${SIDE_OFFSET_VAR})`;
|
|
1864
|
-
if (align === "start") style.top = `calc(anchor(top) + ${ALIGN_OFFSET_VAR})`;
|
|
1865
|
-
else if (align === "end") style.bottom = `calc(anchor(bottom) + ${ALIGN_OFFSET_VAR})`;
|
|
1866
|
-
else {
|
|
1867
|
-
style.alignSelf = "anchor-center";
|
|
1868
|
-
style.marginBlockStart = ALIGN_OFFSET_VAR;
|
|
1869
|
-
}
|
|
1905
|
+
var StoreController = class {
|
|
1906
|
+
#host;
|
|
1907
|
+
#selector;
|
|
1908
|
+
#accessor;
|
|
1909
|
+
#snapshot = null;
|
|
1910
|
+
constructor(host, source, selector) {
|
|
1911
|
+
this.#host = host;
|
|
1912
|
+
this.#selector = selector;
|
|
1913
|
+
this.#accessor = new StoreAccessor(host, source, (store) => this.#connect(store));
|
|
1914
|
+
host.addController(this);
|
|
1870
1915
|
}
|
|
1871
|
-
|
|
1872
|
-
|
|
1916
|
+
get value() {
|
|
1917
|
+
const store = this.#accessor.value;
|
|
1918
|
+
if (isNull(store)) throw new Error("Store not available");
|
|
1919
|
+
if (isUndefined(this.#selector)) return store;
|
|
1920
|
+
return this.#snapshot.value;
|
|
1921
|
+
}
|
|
1922
|
+
hostConnected() {}
|
|
1923
|
+
#connect(store) {
|
|
1924
|
+
if (isUndefined(this.#selector)) return;
|
|
1925
|
+
if (!this.#snapshot) this.#snapshot = new SnapshotController(this.#host, store.$state, this.#selector);
|
|
1926
|
+
else this.#snapshot.track(store.$state);
|
|
1927
|
+
}
|
|
1928
|
+
};
|
|
1929
|
+
|
|
1930
|
+
//#endregion
|
|
1931
|
+
//#region src/player/player-controller.ts
|
|
1873
1932
|
/**
|
|
1874
|
-
*
|
|
1933
|
+
* Reactive controller for accessing player store state.
|
|
1875
1934
|
*
|
|
1876
|
-
*
|
|
1877
|
-
*
|
|
1878
|
-
*/
|
|
1879
|
-
function getPositioningCSSVars(triggerRect, boundaryRect, side, cssVars = PopoverCSSVars) {
|
|
1880
|
-
const vars = {};
|
|
1881
|
-
vars[cssVars.anchorWidth] = `${triggerRect.width}px`;
|
|
1882
|
-
vars[cssVars.anchorHeight] = `${triggerRect.height}px`;
|
|
1883
|
-
if (side === "top" || side === "bottom") {
|
|
1884
|
-
vars[cssVars.availableHeight] = side === "top" ? `${triggerRect.top - boundaryRect.top}px` : `${boundaryRect.bottom - triggerRect.bottom}px`;
|
|
1885
|
-
vars[cssVars.availableWidth] = `${boundaryRect.width}px`;
|
|
1886
|
-
} else {
|
|
1887
|
-
vars[cssVars.availableWidth] = side === "left" ? `${triggerRect.left - boundaryRect.left}px` : `${boundaryRect.right - triggerRect.right}px`;
|
|
1888
|
-
vars[cssVars.availableHeight] = `${boundaryRect.height}px`;
|
|
1889
|
-
}
|
|
1890
|
-
return vars;
|
|
1891
|
-
}
|
|
1892
|
-
/**
|
|
1893
|
-
* Compute manual positioning when CSS Anchor Positioning is not supported.
|
|
1935
|
+
* Without selector: Returns the store, does NOT subscribe to changes.
|
|
1936
|
+
* With selector: Returns selected state, subscribes with shallowEqual comparison.
|
|
1894
1937
|
*
|
|
1895
|
-
*
|
|
1896
|
-
*
|
|
1897
|
-
*
|
|
1938
|
+
* @example
|
|
1939
|
+
* ```ts
|
|
1940
|
+
* // Store access (no subscription)
|
|
1941
|
+
* class Controls extends MediaElement {
|
|
1942
|
+
* #player = new PlayerController(this, playerContext);
|
|
1898
1943
|
*
|
|
1899
|
-
*
|
|
1900
|
-
*
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
sideOffset: 0,
|
|
1904
|
-
alignOffset: 0
|
|
1905
|
-
}) {
|
|
1906
|
-
const { side, align } = opts;
|
|
1907
|
-
const { sideOffset, alignOffset } = offsets;
|
|
1908
|
-
let top = 0;
|
|
1909
|
-
let left = 0;
|
|
1910
|
-
if (side === "top") top = triggerRect.top - popupRect.height - sideOffset;
|
|
1911
|
-
else if (side === "bottom") top = triggerRect.bottom + sideOffset;
|
|
1912
|
-
else if (side === "left") left = triggerRect.left - popupRect.width - sideOffset;
|
|
1913
|
-
else left = triggerRect.right + sideOffset;
|
|
1914
|
-
if (side === "top" || side === "bottom") if (align === "start") left = triggerRect.left + alignOffset;
|
|
1915
|
-
else if (align === "end") left = triggerRect.right - popupRect.width + alignOffset;
|
|
1916
|
-
else left = triggerRect.left + (triggerRect.width - popupRect.width) / 2 + alignOffset;
|
|
1917
|
-
else if (align === "start") top = triggerRect.top + alignOffset;
|
|
1918
|
-
else if (align === "end") top = triggerRect.bottom - popupRect.height + alignOffset;
|
|
1919
|
-
else top = triggerRect.top + (triggerRect.height - popupRect.height) / 2 + alignOffset;
|
|
1920
|
-
return {
|
|
1921
|
-
top: `${top}px`,
|
|
1922
|
-
left: `${left}px`
|
|
1923
|
-
};
|
|
1924
|
-
}
|
|
1925
|
-
/**
|
|
1926
|
-
* Read side-offset and align-offset CSS custom properties from the
|
|
1927
|
-
* popup element's computed style, returning numeric pixel values.
|
|
1928
|
-
*/
|
|
1929
|
-
function resolveOffsets(el, cssVars = PopoverCSSVars) {
|
|
1930
|
-
const computed = getComputedStyle(el);
|
|
1931
|
-
return {
|
|
1932
|
-
sideOffset: resolveCSSLength(el, computed.getPropertyValue(cssVars.sideOffset)),
|
|
1933
|
-
alignOffset: resolveCSSLength(el, computed.getPropertyValue(cssVars.alignOffset))
|
|
1934
|
-
};
|
|
1935
|
-
}
|
|
1936
|
-
/**
|
|
1937
|
-
* Measure the popup's layout box for positioning.
|
|
1944
|
+
* handleClick() {
|
|
1945
|
+
* this.#player.value.setVolume(0.5);
|
|
1946
|
+
* }
|
|
1947
|
+
* }
|
|
1938
1948
|
*
|
|
1939
|
-
*
|
|
1940
|
-
*
|
|
1941
|
-
*
|
|
1942
|
-
|
|
1943
|
-
function getPopupPositionRect(el) {
|
|
1944
|
-
const rect = el.getBoundingClientRect();
|
|
1945
|
-
const width = el.offsetWidth || rect.width;
|
|
1946
|
-
const height = el.offsetHeight || rect.height;
|
|
1947
|
-
const adjustedRect = {
|
|
1948
|
-
...rect,
|
|
1949
|
-
width,
|
|
1950
|
-
height,
|
|
1951
|
-
right: rect.left + width,
|
|
1952
|
-
bottom: rect.top + height
|
|
1953
|
-
};
|
|
1954
|
-
return {
|
|
1955
|
-
...adjustedRect,
|
|
1956
|
-
toJSON: () => adjustedRect
|
|
1957
|
-
};
|
|
1958
|
-
}
|
|
1959
|
-
|
|
1960
|
-
//#endregion
|
|
1961
|
-
//#region ../utils/dist/number/number.js
|
|
1962
|
-
/** Clamp a value between min and max (inclusive). */
|
|
1963
|
-
function clamp(value, min, max) {
|
|
1964
|
-
return Math.max(min, Math.min(max, value));
|
|
1965
|
-
}
|
|
1966
|
-
/** Snap a value to the nearest step, offset from min. */
|
|
1967
|
-
function roundToStep(value, step, min) {
|
|
1968
|
-
const nearest = Math.round((value - min) / step) * step + min;
|
|
1969
|
-
const dot = `${step}`.indexOf(".");
|
|
1970
|
-
return dot === -1 ? nearest : Number(nearest.toFixed(`${step}`.length - dot - 1));
|
|
1971
|
-
}
|
|
1972
|
-
|
|
1973
|
-
//#endregion
|
|
1974
|
-
//#region ../core/dist/dev/dom/utils/pointer.js
|
|
1975
|
-
/** Convert a pointer event position to a 0–100 percent along an element's rect. */
|
|
1976
|
-
function getPercentFromPointerEvent(event, rect, orientation, isRTL) {
|
|
1977
|
-
let ratio;
|
|
1978
|
-
if (orientation === "vertical") ratio = 1 - (event.clientY - rect.top) / rect.height;
|
|
1979
|
-
else if (isRTL) ratio = (rect.right - event.clientX) / rect.width;
|
|
1980
|
-
else ratio = (event.clientX - rect.left) / rect.width;
|
|
1981
|
-
if (!Number.isFinite(ratio)) return 0;
|
|
1982
|
-
return clamp(ratio * 100, 0, 100);
|
|
1983
|
-
}
|
|
1984
|
-
|
|
1985
|
-
//#endregion
|
|
1986
|
-
//#region ../core/dist/dev/dom/ui/slider.js
|
|
1987
|
-
/** Intentional drag threshold — number of pointermove events before drag starts. */
|
|
1988
|
-
const DRAG_THRESHOLD = 2;
|
|
1989
|
-
function createSlider(options) {
|
|
1990
|
-
const input = createState({
|
|
1991
|
-
pointerPercent: 0,
|
|
1992
|
-
dragPercent: 0,
|
|
1993
|
-
dragging: false,
|
|
1994
|
-
pointing: false,
|
|
1995
|
-
focused: false
|
|
1996
|
-
});
|
|
1997
|
-
const abort = new AbortController();
|
|
1998
|
-
const commitThrottleMs = options.commitThrottle ?? 0;
|
|
1999
|
-
let isDragging = false, moveCount = 0, cachedRTL = false, cachedRect = null, capturedPointerId = null;
|
|
2000
|
-
const throttledCommit = commitThrottleMs > 0 ? throttle((percent) => options.onValueCommit?.(percent), commitThrottleMs) : null;
|
|
2001
|
-
function releaseCapture() {
|
|
2002
|
-
if (isNull(capturedPointerId)) return;
|
|
2003
|
-
const id = capturedPointerId;
|
|
2004
|
-
capturedPointerId = null;
|
|
2005
|
-
try {
|
|
2006
|
-
options.getElement().releasePointerCapture(id);
|
|
2007
|
-
} catch {}
|
|
2008
|
-
}
|
|
2009
|
-
function endDrag() {
|
|
2010
|
-
if (!isDragging) input.patch({ pointing: false });
|
|
2011
|
-
else {
|
|
2012
|
-
isDragging = false;
|
|
2013
|
-
input.patch({
|
|
2014
|
-
dragging: false,
|
|
2015
|
-
pointing: false
|
|
2016
|
-
});
|
|
2017
|
-
options.onDragEnd?.();
|
|
2018
|
-
}
|
|
2019
|
-
cleanup();
|
|
2020
|
-
}
|
|
2021
|
-
function cleanup() {
|
|
2022
|
-
throttledCommit?.cancel();
|
|
2023
|
-
capturedPointerId = null;
|
|
2024
|
-
cachedRect = null;
|
|
2025
|
-
}
|
|
2026
|
-
const rootProps = {
|
|
2027
|
-
onPointerDown(event) {
|
|
2028
|
-
if (options.isDisabled()) return;
|
|
2029
|
-
event.preventDefault();
|
|
2030
|
-
const el = options.getElement();
|
|
2031
|
-
cachedRect = el.getBoundingClientRect();
|
|
2032
|
-
cachedRTL = options.isRTL();
|
|
2033
|
-
moveCount = 0;
|
|
2034
|
-
releaseCapture();
|
|
2035
|
-
capturedPointerId = event.pointerId;
|
|
2036
|
-
el.setPointerCapture(event.pointerId);
|
|
2037
|
-
const percent = getPercentFromPointerEvent(event, cachedRect, options.getOrientation(), cachedRTL);
|
|
2038
|
-
input.patch({
|
|
2039
|
-
pointing: true,
|
|
2040
|
-
pointerPercent: percent,
|
|
2041
|
-
dragPercent: percent
|
|
2042
|
-
});
|
|
2043
|
-
options.onValueChange?.(percent);
|
|
2044
|
-
options.getThumbElement?.()?.focus({
|
|
2045
|
-
preventScroll: true,
|
|
2046
|
-
focusVisible: false
|
|
2047
|
-
});
|
|
2048
|
-
},
|
|
2049
|
-
onPointerMove(event) {
|
|
2050
|
-
if (options.isDisabled()) return;
|
|
2051
|
-
if (!isNull(capturedPointerId)) {
|
|
2052
|
-
if (event.pointerType !== "touch" && event.buttons === 0) {
|
|
2053
|
-
endDrag();
|
|
2054
|
-
return;
|
|
2055
|
-
}
|
|
2056
|
-
moveCount++;
|
|
2057
|
-
const percent = getPercentFromPointerEvent(event, cachedRect, options.getOrientation(), cachedRTL);
|
|
2058
|
-
if (!isDragging && moveCount >= DRAG_THRESHOLD) {
|
|
2059
|
-
isDragging = true;
|
|
2060
|
-
input.patch({
|
|
2061
|
-
dragging: true,
|
|
2062
|
-
dragPercent: percent,
|
|
2063
|
-
pointerPercent: percent
|
|
2064
|
-
});
|
|
2065
|
-
options.onDragStart?.();
|
|
2066
|
-
options.onValueChange?.(percent);
|
|
2067
|
-
throttledCommit?.(percent);
|
|
2068
|
-
} else if (isDragging) {
|
|
2069
|
-
input.patch({
|
|
2070
|
-
dragPercent: percent,
|
|
2071
|
-
pointerPercent: percent
|
|
2072
|
-
});
|
|
2073
|
-
options.onValueChange?.(percent);
|
|
2074
|
-
throttledCommit?.(percent);
|
|
2075
|
-
} else input.patch({ pointerPercent: percent });
|
|
2076
|
-
return;
|
|
2077
|
-
}
|
|
2078
|
-
const percent = getPercentFromPointerEvent(event, options.getElement().getBoundingClientRect(), options.getOrientation(), options.isRTL());
|
|
2079
|
-
input.patch({
|
|
2080
|
-
pointing: true,
|
|
2081
|
-
pointerPercent: percent
|
|
2082
|
-
});
|
|
2083
|
-
},
|
|
2084
|
-
onPointerUp(event) {
|
|
2085
|
-
if (isNull(capturedPointerId)) return;
|
|
2086
|
-
const percent = getPercentFromPointerEvent(event, cachedRect, options.getOrientation(), cachedRTL);
|
|
2087
|
-
throttledCommit?.cancel();
|
|
2088
|
-
options.onValueCommit?.(percent);
|
|
2089
|
-
},
|
|
2090
|
-
onPointerLeave() {
|
|
2091
|
-
if (!isNull(capturedPointerId)) return;
|
|
2092
|
-
input.patch({ pointing: false });
|
|
2093
|
-
},
|
|
2094
|
-
onLostPointerCapture() {
|
|
2095
|
-
endDrag();
|
|
2096
|
-
}
|
|
2097
|
-
};
|
|
2098
|
-
const thumbProps = {
|
|
2099
|
-
onKeyDown(event) {
|
|
2100
|
-
if (options.isDisabled()) {
|
|
2101
|
-
if (event.key !== "Tab") event.preventDefault();
|
|
2102
|
-
return;
|
|
2103
|
-
}
|
|
2104
|
-
const stepPercent = options.getStepPercent();
|
|
2105
|
-
const largeStepPercent = options.getLargeStepPercent();
|
|
2106
|
-
const rounded = roundToStep(options.getPercent(), stepPercent, 0);
|
|
2107
|
-
const horizontalSign = options.isRTL() ? -1 : 1;
|
|
2108
|
-
const step = event.shiftKey ? largeStepPercent : stepPercent;
|
|
2109
|
-
let newPercent = null;
|
|
2110
|
-
switch (event.key) {
|
|
2111
|
-
case "ArrowRight":
|
|
2112
|
-
newPercent = rounded + step * horizontalSign;
|
|
2113
|
-
break;
|
|
2114
|
-
case "ArrowLeft":
|
|
2115
|
-
newPercent = rounded - step * horizontalSign;
|
|
2116
|
-
break;
|
|
2117
|
-
case "ArrowUp":
|
|
2118
|
-
newPercent = rounded + step;
|
|
2119
|
-
break;
|
|
2120
|
-
case "ArrowDown":
|
|
2121
|
-
newPercent = rounded - step;
|
|
2122
|
-
break;
|
|
2123
|
-
case "PageUp":
|
|
2124
|
-
newPercent = rounded + largeStepPercent;
|
|
2125
|
-
break;
|
|
2126
|
-
case "PageDown":
|
|
2127
|
-
newPercent = rounded - largeStepPercent;
|
|
2128
|
-
break;
|
|
2129
|
-
case "Home":
|
|
2130
|
-
newPercent = 0;
|
|
2131
|
-
break;
|
|
2132
|
-
case "End":
|
|
2133
|
-
newPercent = 100;
|
|
2134
|
-
break;
|
|
2135
|
-
default:
|
|
2136
|
-
if (!event.metaKey && !event.ctrlKey && !event.altKey && event.key >= "0" && event.key <= "9") newPercent = Number(event.key) * 10;
|
|
2137
|
-
break;
|
|
2138
|
-
}
|
|
2139
|
-
if (newPercent !== null) {
|
|
2140
|
-
event.preventDefault();
|
|
2141
|
-
newPercent = clamp(newPercent, 0, 100);
|
|
2142
|
-
input.patch({
|
|
2143
|
-
pointerPercent: newPercent,
|
|
2144
|
-
dragPercent: newPercent
|
|
2145
|
-
});
|
|
2146
|
-
options.onValueChange?.(newPercent);
|
|
2147
|
-
options.onValueCommit?.(newPercent);
|
|
2148
|
-
}
|
|
2149
|
-
},
|
|
2150
|
-
onFocus() {
|
|
2151
|
-
input.patch({ focused: true });
|
|
2152
|
-
},
|
|
2153
|
-
onBlur() {
|
|
2154
|
-
input.patch({ focused: false });
|
|
2155
|
-
}
|
|
2156
|
-
};
|
|
2157
|
-
function adjustForAlignment(state) {
|
|
2158
|
-
if (!options.adjustPercent || state.thumbAlignment !== "edge") return state;
|
|
2159
|
-
const rootEl = options.getElement();
|
|
2160
|
-
const thumbEl = options.getThumbElement?.();
|
|
2161
|
-
if (!thumbEl) return state;
|
|
2162
|
-
const isHorizontal = state.orientation === "horizontal";
|
|
2163
|
-
const thumbSize = isHorizontal ? thumbEl.offsetWidth : thumbEl.offsetHeight;
|
|
2164
|
-
const trackSize = isHorizontal ? rootEl.offsetWidth : rootEl.offsetHeight;
|
|
2165
|
-
return {
|
|
2166
|
-
...state,
|
|
2167
|
-
fillPercent: options.adjustPercent(state.fillPercent, thumbSize, trackSize),
|
|
2168
|
-
pointerPercent: options.adjustPercent(state.pointerPercent, thumbSize, trackSize)
|
|
2169
|
-
};
|
|
2170
|
-
}
|
|
2171
|
-
let resizeObserver = null;
|
|
2172
|
-
if (options.onResize) {
|
|
2173
|
-
resizeObserver = new ResizeObserver(() => options.onResize());
|
|
2174
|
-
resizeObserver.observe(options.getElement());
|
|
2175
|
-
}
|
|
2176
|
-
return {
|
|
2177
|
-
input,
|
|
2178
|
-
rootProps,
|
|
2179
|
-
rootStyle: {
|
|
2180
|
-
touchAction: "none",
|
|
2181
|
-
userSelect: "none"
|
|
2182
|
-
},
|
|
2183
|
-
thumbProps,
|
|
2184
|
-
adjustForAlignment,
|
|
2185
|
-
destroy() {
|
|
2186
|
-
if (abort.signal.aborted) return;
|
|
2187
|
-
abort.abort();
|
|
2188
|
-
resizeObserver?.disconnect();
|
|
2189
|
-
releaseCapture();
|
|
2190
|
-
cleanup();
|
|
2191
|
-
}
|
|
2192
|
-
};
|
|
2193
|
-
}
|
|
2194
|
-
|
|
2195
|
-
//#endregion
|
|
2196
|
-
//#region ../core/dist/dev/core/ui/slider/slider-css-vars.js
|
|
2197
|
-
/** CSS custom property names for slider visual state. */
|
|
2198
|
-
const SliderCSSVars = {
|
|
2199
|
-
fill: "--media-slider-fill",
|
|
2200
|
-
pointer: "--media-slider-pointer",
|
|
2201
|
-
buffer: "--media-slider-buffer"
|
|
2202
|
-
};
|
|
2203
|
-
|
|
2204
|
-
//#endregion
|
|
2205
|
-
//#region ../core/dist/dev/dom/ui/slider-css-vars.js
|
|
2206
|
-
function getSliderCSSVars(state) {
|
|
2207
|
-
return {
|
|
2208
|
-
[SliderCSSVars.fill]: `${state.fillPercent.toFixed(3)}%`,
|
|
2209
|
-
[SliderCSSVars.pointer]: `${state.pointerPercent.toFixed(3)}%`
|
|
2210
|
-
};
|
|
2211
|
-
}
|
|
2212
|
-
function getTimeSliderCSSVars(state) {
|
|
2213
|
-
return {
|
|
2214
|
-
...getSliderCSSVars(state),
|
|
2215
|
-
[SliderCSSVars.buffer]: `${state.bufferPercent.toFixed(3)}%`
|
|
2216
|
-
};
|
|
2217
|
-
}
|
|
2218
|
-
/** Compute structural positioning styles for a slider preview element. */
|
|
2219
|
-
function getSliderPreviewStyle(width, overflow) {
|
|
2220
|
-
const halfWidth = width / 2;
|
|
2221
|
-
return {
|
|
2222
|
-
position: "absolute",
|
|
2223
|
-
left: overflow === "visible" ? `calc(var(${SliderCSSVars.pointer}) - ${halfWidth}px)` : `min(max(0px, calc(var(${SliderCSSVars.pointer}) - ${halfWidth}px)), calc(100% - ${width}px))`,
|
|
2224
|
-
width: "max-content",
|
|
2225
|
-
pointerEvents: "none"
|
|
2226
|
-
};
|
|
2227
|
-
}
|
|
2228
|
-
|
|
2229
|
-
//#endregion
|
|
2230
|
-
//#region ../core/dist/dev/core/ui/thumbnail/thumbnail-core.js
|
|
2231
|
-
var ThumbnailCore = class {
|
|
2232
|
-
findActiveThumbnail(thumbnails, time) {
|
|
2233
|
-
if (thumbnails.length === 0) return void 0;
|
|
2234
|
-
let low = 0;
|
|
2235
|
-
let high = thumbnails.length - 1;
|
|
2236
|
-
let result;
|
|
2237
|
-
while (low <= high) {
|
|
2238
|
-
const mid = low + high >>> 1;
|
|
2239
|
-
const image = thumbnails[mid];
|
|
2240
|
-
if (time >= image.startTime) {
|
|
2241
|
-
result = image;
|
|
2242
|
-
low = mid + 1;
|
|
2243
|
-
} else high = mid - 1;
|
|
2244
|
-
}
|
|
2245
|
-
return result;
|
|
2246
|
-
}
|
|
2247
|
-
/**
|
|
2248
|
-
* Parse CSS constraint strings into numeric `ThumbnailConstraints`.
|
|
2249
|
-
*
|
|
2250
|
-
* Accepts any object with string `minWidth`/`maxWidth`/`minHeight`/`maxHeight`
|
|
2251
|
-
* properties — `CSSStyleDeclaration` satisfies this structurally.
|
|
2252
|
-
*/
|
|
2253
|
-
parseConstraints(raw) {
|
|
2254
|
-
const minW = parseFloat(raw.minWidth);
|
|
2255
|
-
const maxW = parseFloat(raw.maxWidth);
|
|
2256
|
-
const minH = parseFloat(raw.minHeight);
|
|
2257
|
-
const maxH = parseFloat(raw.maxHeight);
|
|
2258
|
-
return {
|
|
2259
|
-
minWidth: Number.isFinite(minW) ? minW : 0,
|
|
2260
|
-
maxWidth: Number.isFinite(maxW) ? maxW : Infinity,
|
|
2261
|
-
minHeight: Number.isFinite(minH) ? minH : 0,
|
|
2262
|
-
maxHeight: Number.isFinite(maxH) ? maxH : Infinity
|
|
2263
|
-
};
|
|
2264
|
-
}
|
|
2265
|
-
/**
|
|
2266
|
-
* Calculate a uniform scale factor that fits `tileWidth × tileHeight` within the
|
|
2267
|
-
* given CSS min/max constraints while preserving aspect ratio.
|
|
2268
|
-
*
|
|
2269
|
-
* - Scales down when the tile exceeds max constraints.
|
|
2270
|
-
* - Scales up when the tile is smaller than min constraints.
|
|
2271
|
-
* - Returns `1` when no scaling is needed.
|
|
2272
|
-
*/
|
|
2273
|
-
calculateScale(tileWidth, tileHeight, constraints) {
|
|
2274
|
-
const { minWidth, maxWidth, minHeight, maxHeight } = constraints;
|
|
2275
|
-
const maxRatio = Math.min(maxWidth / tileWidth, maxHeight / tileHeight);
|
|
2276
|
-
const minRatio = Math.max(minWidth / tileWidth, minHeight / tileHeight);
|
|
2277
|
-
if (Number.isFinite(maxRatio) && maxRatio < 1) return maxRatio;
|
|
2278
|
-
if (Number.isFinite(minRatio) && minRatio > 1) return minRatio;
|
|
2279
|
-
return 1;
|
|
2280
|
-
}
|
|
2281
|
-
/**
|
|
2282
|
-
* Compute container and image dimensions for the current thumbnail, scaled to
|
|
2283
|
-
* fit within the element's CSS min/max constraints.
|
|
2284
|
-
*
|
|
2285
|
-
* The container clips the sprite sheet via `overflow: hidden`, and the image is
|
|
2286
|
-
* positioned with `transform: translate()` to show the correct tile.
|
|
2287
|
-
*/
|
|
2288
|
-
resize(thumbnail, imgNaturalWidth, imgNaturalHeight, constraints) {
|
|
2289
|
-
const tileWidth = thumbnail.width ?? imgNaturalWidth;
|
|
2290
|
-
const tileHeight = thumbnail.height ?? imgNaturalHeight;
|
|
2291
|
-
if (!tileWidth || !tileHeight) return void 0;
|
|
2292
|
-
const scale = this.calculateScale(tileWidth, tileHeight, constraints);
|
|
2293
|
-
const coordX = thumbnail.coords?.x ?? 0;
|
|
2294
|
-
const coordY = thumbnail.coords?.y ?? 0;
|
|
2295
|
-
const inset = scale !== 1 ? 1 : 0;
|
|
2296
|
-
return {
|
|
2297
|
-
scale,
|
|
2298
|
-
containerWidth: Math.max(0, Math.floor(tileWidth * scale) - inset * 2),
|
|
2299
|
-
containerHeight: Math.max(0, Math.floor(tileHeight * scale) - inset * 2),
|
|
2300
|
-
imageWidth: Math.ceil(imgNaturalWidth * scale),
|
|
2301
|
-
imageHeight: Math.ceil(imgNaturalHeight * scale),
|
|
2302
|
-
offsetX: Math.ceil(coordX * scale) + inset,
|
|
2303
|
-
offsetY: Math.ceil(coordY * scale) + inset
|
|
2304
|
-
};
|
|
2305
|
-
}
|
|
2306
|
-
getState(loading, error, thumbnail) {
|
|
2307
|
-
return {
|
|
2308
|
-
loading,
|
|
2309
|
-
error,
|
|
2310
|
-
hidden: !loading && !thumbnail
|
|
2311
|
-
};
|
|
2312
|
-
}
|
|
2313
|
-
getAttrs(_state) {
|
|
2314
|
-
return {
|
|
2315
|
-
role: "img",
|
|
2316
|
-
"aria-hidden": "true"
|
|
2317
|
-
};
|
|
2318
|
-
}
|
|
2319
|
-
};
|
|
2320
|
-
|
|
2321
|
-
//#endregion
|
|
2322
|
-
//#region ../core/dist/dev/dom/ui/thumbnail.js
|
|
2323
|
-
function createThumbnail(options) {
|
|
2324
|
-
const { getContainer, getImg, onStateChange } = options;
|
|
2325
|
-
const core = new ThumbnailCore();
|
|
2326
|
-
const abort = new AbortController();
|
|
2327
|
-
const signal = abort.signal;
|
|
2328
|
-
let loading = false;
|
|
2329
|
-
let error = false;
|
|
2330
|
-
let naturalWidth = 0;
|
|
2331
|
-
let naturalHeight = 0;
|
|
2332
|
-
let lastSrc = "";
|
|
2333
|
-
let imgBound = false;
|
|
2334
|
-
let resizeObserver = null;
|
|
2335
|
-
function onImgLoad() {
|
|
2336
|
-
const img = getImg();
|
|
2337
|
-
if (img) {
|
|
2338
|
-
naturalWidth = img.naturalWidth;
|
|
2339
|
-
naturalHeight = img.naturalHeight;
|
|
2340
|
-
}
|
|
2341
|
-
loading = false;
|
|
2342
|
-
error = false;
|
|
2343
|
-
onStateChange();
|
|
2344
|
-
}
|
|
2345
|
-
function onImgError() {
|
|
2346
|
-
loading = false;
|
|
2347
|
-
error = true;
|
|
2348
|
-
onStateChange();
|
|
2349
|
-
}
|
|
2350
|
-
function bindImg(img) {
|
|
2351
|
-
listen(img, "load", onImgLoad, { signal });
|
|
2352
|
-
listen(img, "error", onImgError, { signal });
|
|
2353
|
-
}
|
|
2354
|
-
function ensureBindings() {
|
|
2355
|
-
if (!imgBound) {
|
|
2356
|
-
const img = getImg();
|
|
2357
|
-
if (img) {
|
|
2358
|
-
bindImg(img);
|
|
2359
|
-
imgBound = true;
|
|
2360
|
-
}
|
|
2361
|
-
}
|
|
2362
|
-
if (!resizeObserver) {
|
|
2363
|
-
const container = getContainer();
|
|
2364
|
-
if (container) {
|
|
2365
|
-
resizeObserver = new ResizeObserver(onStateChange);
|
|
2366
|
-
resizeObserver.observe(container);
|
|
2367
|
-
}
|
|
2368
|
-
}
|
|
2369
|
-
}
|
|
2370
|
-
function updateSrc(url) {
|
|
2371
|
-
ensureBindings();
|
|
2372
|
-
const src = url ?? "";
|
|
2373
|
-
if (src === lastSrc) return;
|
|
2374
|
-
lastSrc = src;
|
|
2375
|
-
if (src) {
|
|
2376
|
-
loading = true;
|
|
2377
|
-
error = false;
|
|
2378
|
-
} else {
|
|
2379
|
-
loading = false;
|
|
2380
|
-
error = false;
|
|
2381
|
-
naturalWidth = 0;
|
|
2382
|
-
naturalHeight = 0;
|
|
2383
|
-
}
|
|
2384
|
-
}
|
|
2385
|
-
function connect() {
|
|
2386
|
-
ensureBindings();
|
|
2387
|
-
const img = getImg();
|
|
2388
|
-
if (img?.complete && lastSrc) {
|
|
2389
|
-
if (img.naturalWidth > 0) {
|
|
2390
|
-
naturalWidth = img.naturalWidth;
|
|
2391
|
-
naturalHeight = img.naturalHeight;
|
|
2392
|
-
loading = false;
|
|
2393
|
-
error = false;
|
|
2394
|
-
} else {
|
|
2395
|
-
loading = false;
|
|
2396
|
-
error = true;
|
|
2397
|
-
}
|
|
2398
|
-
onStateChange();
|
|
2399
|
-
}
|
|
2400
|
-
}
|
|
2401
|
-
function destroy() {
|
|
2402
|
-
abort.abort();
|
|
2403
|
-
resizeObserver?.disconnect();
|
|
2404
|
-
resizeObserver = null;
|
|
2405
|
-
}
|
|
2406
|
-
return {
|
|
2407
|
-
get loading() {
|
|
2408
|
-
return loading;
|
|
2409
|
-
},
|
|
2410
|
-
get error() {
|
|
2411
|
-
return error;
|
|
2412
|
-
},
|
|
2413
|
-
get naturalWidth() {
|
|
2414
|
-
return naturalWidth;
|
|
2415
|
-
},
|
|
2416
|
-
get naturalHeight() {
|
|
2417
|
-
return naturalHeight;
|
|
2418
|
-
},
|
|
2419
|
-
readConstraints() {
|
|
2420
|
-
const el = getContainer();
|
|
2421
|
-
if (!el) return {
|
|
2422
|
-
minWidth: 0,
|
|
2423
|
-
maxWidth: Infinity,
|
|
2424
|
-
minHeight: 0,
|
|
2425
|
-
maxHeight: Infinity
|
|
2426
|
-
};
|
|
2427
|
-
return core.parseConstraints(getComputedStyle(el));
|
|
2428
|
-
},
|
|
2429
|
-
updateSrc,
|
|
2430
|
-
connect,
|
|
2431
|
-
destroy
|
|
2432
|
-
};
|
|
2433
|
-
}
|
|
2434
|
-
|
|
2435
|
-
//#endregion
|
|
2436
|
-
//#region ../core/dist/dev/dom/ui/tooltip/tooltip.js
|
|
2437
|
-
/** Map popover reasons to tooltip reasons, filtering out click/outside-click. */
|
|
2438
|
-
const REASON_MAP = {
|
|
2439
|
-
hover: "hover",
|
|
2440
|
-
focus: "focus",
|
|
2441
|
-
escape: "escape",
|
|
2442
|
-
blur: "blur"
|
|
2443
|
-
};
|
|
2444
|
-
function createTooltip(options) {
|
|
2445
|
-
const popoverOpts = {
|
|
2446
|
-
transition: options.transition,
|
|
2447
|
-
onOpenChange(open, details) {
|
|
2448
|
-
const reason = REASON_MAP[details.reason];
|
|
2449
|
-
if (!reason) return;
|
|
2450
|
-
const group = options.group?.();
|
|
2451
|
-
if (open) group?.notifyOpen();
|
|
2452
|
-
else group?.notifyClose();
|
|
2453
|
-
const tooltipDetails = details.event ? {
|
|
2454
|
-
reason,
|
|
2455
|
-
event: details.event
|
|
2456
|
-
} : { reason };
|
|
2457
|
-
options.onOpenChange(open, tooltipDetails);
|
|
2458
|
-
},
|
|
2459
|
-
closeOnEscape: () => true,
|
|
2460
|
-
closeOnOutsideClick: () => false,
|
|
2461
|
-
openOnHover: () => true,
|
|
2462
|
-
delay: () => {
|
|
2463
|
-
const group = options.group?.();
|
|
2464
|
-
if (group?.shouldSkipDelay()) return 0;
|
|
2465
|
-
return options.delay?.() ?? group?.delay ?? 600;
|
|
2466
|
-
},
|
|
2467
|
-
closeDelay: () => {
|
|
2468
|
-
const group = options.group?.();
|
|
2469
|
-
return options.closeDelay?.() ?? group?.closeDelay ?? 0;
|
|
2470
|
-
}
|
|
2471
|
-
};
|
|
2472
|
-
if (options.onOpenChangeComplete) popoverOpts.onOpenChangeComplete = options.onOpenChangeComplete;
|
|
2473
|
-
const popover = createPopover(popoverOpts);
|
|
2474
|
-
let isPointerDown = false;
|
|
2475
|
-
const { onClick: _, ...baseTriggerProps } = popover.triggerProps;
|
|
2476
|
-
const triggerProps = {
|
|
2477
|
-
...baseTriggerProps,
|
|
2478
|
-
onPointerDown() {
|
|
2479
|
-
isPointerDown = true;
|
|
2480
|
-
},
|
|
2481
|
-
onPointerEnter(event) {
|
|
2482
|
-
if (options.disabled?.()) return;
|
|
2483
|
-
if (event.pointerType === "touch") return;
|
|
2484
|
-
baseTriggerProps.onPointerEnter(event);
|
|
2485
|
-
},
|
|
2486
|
-
onFocusIn(event) {
|
|
2487
|
-
if (options.disabled?.()) return;
|
|
2488
|
-
if (isPointerDown) {
|
|
2489
|
-
isPointerDown = false;
|
|
2490
|
-
return;
|
|
2491
|
-
}
|
|
2492
|
-
baseTriggerProps.onFocusIn(event);
|
|
2493
|
-
}
|
|
2494
|
-
};
|
|
2495
|
-
const popupProps = {
|
|
2496
|
-
...popover.popupProps,
|
|
2497
|
-
onPointerEnter(event) {
|
|
2498
|
-
if (options.disableHoverablePopup?.()) return;
|
|
2499
|
-
popover.popupProps.onPointerEnter(event);
|
|
2500
|
-
}
|
|
2501
|
-
};
|
|
2502
|
-
return {
|
|
2503
|
-
...popover,
|
|
2504
|
-
triggerProps,
|
|
2505
|
-
popupProps,
|
|
2506
|
-
get triggerElement() {
|
|
2507
|
-
return popover.triggerElement;
|
|
2508
|
-
},
|
|
2509
|
-
open: () => popover.open("hover"),
|
|
2510
|
-
close: () => popover.close("hover")
|
|
2511
|
-
};
|
|
2512
|
-
}
|
|
2513
|
-
|
|
2514
|
-
//#endregion
|
|
2515
|
-
//#region ../core/dist/dev/dom/ui/transition.js
|
|
2516
|
-
/**
|
|
2517
|
-
* Manages open/close transition lifecycle via `createState`.
|
|
2518
|
-
*
|
|
2519
|
-
* **Open:** patches `{ active: true, status: 'starting' }`, then after a
|
|
2520
|
-
* double-RAF patches `{ status: 'idle' }` so the browser paints the
|
|
2521
|
-
* initial ("from") state before transitioning.
|
|
2522
|
-
*
|
|
2523
|
-
* **Close:** patches `{ status: 'ending' }` (keeping `active: true` so the
|
|
2524
|
-
* element stays mounted), then after a double-RAF waits for
|
|
2525
|
-
* `getAnimations()` to settle before patching `{ active: false, status: 'idle' }`.
|
|
2526
|
-
*/
|
|
2527
|
-
function createTransition() {
|
|
2528
|
-
const state = createState({
|
|
2529
|
-
active: false,
|
|
2530
|
-
status: "idle"
|
|
2531
|
-
});
|
|
2532
|
-
let destroyed = false;
|
|
2533
|
-
let rafId1 = 0;
|
|
2534
|
-
let rafId2 = 0;
|
|
2535
|
-
function open() {
|
|
2536
|
-
cancelAnimationFrame(rafId1);
|
|
2537
|
-
cancelAnimationFrame(rafId2);
|
|
2538
|
-
rafId1 = 0;
|
|
2539
|
-
rafId2 = 0;
|
|
2540
|
-
state.patch({
|
|
2541
|
-
active: true,
|
|
2542
|
-
status: "starting"
|
|
2543
|
-
});
|
|
2544
|
-
return new Promise((resolve) => {
|
|
2545
|
-
rafId1 = requestAnimationFrame(() => {
|
|
2546
|
-
rafId1 = 0;
|
|
2547
|
-
rafId2 = requestAnimationFrame(() => {
|
|
2548
|
-
rafId2 = 0;
|
|
2549
|
-
if (destroyed || !state.current.active) return resolve();
|
|
2550
|
-
state.patch({ status: "idle" });
|
|
2551
|
-
resolve();
|
|
2552
|
-
});
|
|
2553
|
-
});
|
|
2554
|
-
});
|
|
2555
|
-
}
|
|
2556
|
-
function close(el) {
|
|
2557
|
-
cancelAnimationFrame(rafId1);
|
|
2558
|
-
cancelAnimationFrame(rafId2);
|
|
2559
|
-
rafId1 = 0;
|
|
2560
|
-
rafId2 = 0;
|
|
2561
|
-
state.patch({ status: "ending" });
|
|
2562
|
-
return new Promise((resolve) => {
|
|
2563
|
-
rafId1 = requestAnimationFrame(() => {
|
|
2564
|
-
rafId1 = 0;
|
|
2565
|
-
rafId2 = requestAnimationFrame(() => {
|
|
2566
|
-
rafId2 = 0;
|
|
2567
|
-
if (destroyed) return resolve();
|
|
2568
|
-
waitForAnimations(el).finally(() => {
|
|
2569
|
-
if (destroyed || state.current.status !== "ending") return resolve();
|
|
2570
|
-
state.patch({
|
|
2571
|
-
active: false,
|
|
2572
|
-
status: "idle"
|
|
2573
|
-
});
|
|
2574
|
-
resolve();
|
|
2575
|
-
});
|
|
2576
|
-
});
|
|
2577
|
-
});
|
|
2578
|
-
});
|
|
2579
|
-
}
|
|
2580
|
-
function cancel() {
|
|
2581
|
-
cancelAnimationFrame(rafId1);
|
|
2582
|
-
cancelAnimationFrame(rafId2);
|
|
2583
|
-
rafId1 = 0;
|
|
2584
|
-
rafId2 = 0;
|
|
2585
|
-
if (state.current.status !== "idle") state.patch({ status: "idle" });
|
|
2586
|
-
}
|
|
2587
|
-
return {
|
|
2588
|
-
state,
|
|
2589
|
-
open,
|
|
2590
|
-
close,
|
|
2591
|
-
cancel,
|
|
2592
|
-
destroy() {
|
|
2593
|
-
if (destroyed) return;
|
|
2594
|
-
destroyed = true;
|
|
2595
|
-
cancel();
|
|
2596
|
-
}
|
|
2597
|
-
};
|
|
2598
|
-
}
|
|
2599
|
-
function waitForAnimations(el) {
|
|
2600
|
-
if (!el) return Promise.resolve();
|
|
2601
|
-
const animations = el.getAnimations?.() ?? [];
|
|
2602
|
-
if (animations.length === 0) return Promise.resolve();
|
|
2603
|
-
return Promise.all(animations.map((a) => a.finished)).then(noop, noop);
|
|
2604
|
-
}
|
|
2605
|
-
|
|
2606
|
-
//#endregion
|
|
2607
|
-
//#region ../core/dist/dev/dom/ui/wheel-step.js
|
|
2608
|
-
function createWheelStep(options) {
|
|
2609
|
-
return { onWheel(event) {
|
|
2610
|
-
if (options.isDisabled()) return;
|
|
2611
|
-
const direction = Math.sign(event.deltaY);
|
|
2612
|
-
if (direction === 0) return;
|
|
2613
|
-
event.preventDefault();
|
|
2614
|
-
const stepPercent = options.getStepPercent();
|
|
2615
|
-
const newPercent = clamp(options.getPercent() - direction * stepPercent, 0, 100);
|
|
2616
|
-
options.onValueChange?.(newPercent);
|
|
2617
|
-
} };
|
|
2618
|
-
}
|
|
2619
|
-
|
|
2620
|
-
//#endregion
|
|
2621
|
-
//#region ../core/dist/dev/dom/utils/element-props.js
|
|
2622
|
-
/**
|
|
2623
|
-
* Apply props to a DOM element.
|
|
2624
|
-
*
|
|
2625
|
-
* Handles both attributes and event listeners:
|
|
2626
|
-
* - Event props (onClick, onKeyDown, etc.) are attached as listeners
|
|
2627
|
-
* - Boolean props: `true` sets empty attribute, `false` removes
|
|
2628
|
-
* - `undefined` removes the attribute
|
|
2629
|
-
* - Other props are set as string attributes
|
|
2630
|
-
*/
|
|
2631
|
-
function applyElementProps(element, props, options) {
|
|
2632
|
-
const signal = options?.signal;
|
|
2633
|
-
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);
|
|
2634
|
-
else if (isUndefined(value) || value === false) element.removeAttribute(key);
|
|
2635
|
-
else if (value === true) element.setAttribute(key, "");
|
|
2636
|
-
else element.setAttribute(key, String(value));
|
|
2637
|
-
}
|
|
2638
|
-
|
|
2639
|
-
//#endregion
|
|
2640
|
-
//#region ../core/dist/dev/dom/utils/log.js
|
|
2641
|
-
const warned = /* @__PURE__ */ new Set();
|
|
2642
|
-
function logMissingFeature(displayName, featureName) {
|
|
2643
|
-
const key = `${displayName}:${featureName}`;
|
|
2644
|
-
if (warned.has(key)) return;
|
|
2645
|
-
warned.add(key);
|
|
2646
|
-
console.warn(`${displayName} requires ${featureName} feature`);
|
|
2647
|
-
}
|
|
2648
|
-
|
|
2649
|
-
//#endregion
|
|
2650
|
-
//#region ../core/dist/dev/dom/utils/state-data-attrs.js
|
|
2651
|
-
/**
|
|
2652
|
-
* Apply state as data attributes to an element.
|
|
2653
|
-
*
|
|
2654
|
-
* - `true` → sets `data-keyname=""`
|
|
2655
|
-
* - truthy string/number → sets `data-keyname="value"`
|
|
2656
|
-
* - falsy → removes the attribute
|
|
2657
|
-
*
|
|
2658
|
-
* @example
|
|
2659
|
-
* ```ts
|
|
2660
|
-
* const state = { paused: true, ended: false };
|
|
2661
|
-
* applyStateDataAttrs(element, state);
|
|
2662
|
-
* // element has data-paused="", data-ended is removed
|
|
1949
|
+
* // Selector-based subscription
|
|
1950
|
+
* class PlayButton extends MediaElement {
|
|
1951
|
+
* #playback = new PlayerController(this, playerContext, selectPlayback);
|
|
1952
|
+
* }
|
|
2663
1953
|
* ```
|
|
2664
1954
|
*/
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
constructor(host, contextOrOptions, callback, subscribe) {
|
|
2699
|
-
this.subscribe = false;
|
|
2700
|
-
this.provided = false;
|
|
2701
|
-
this.value = void 0;
|
|
2702
|
-
this._callback = (value, unsubscribe) => {
|
|
2703
|
-
if (this.unsubscribe) {
|
|
2704
|
-
if (this.unsubscribe !== unsubscribe) {
|
|
2705
|
-
this.provided = false;
|
|
2706
|
-
this.unsubscribe();
|
|
2707
|
-
}
|
|
2708
|
-
if (!this.subscribe) this.unsubscribe();
|
|
2709
|
-
}
|
|
2710
|
-
this.value = value;
|
|
2711
|
-
this.host.requestUpdate();
|
|
2712
|
-
if (!this.provided || this.subscribe) {
|
|
2713
|
-
this.provided = true;
|
|
2714
|
-
if (this.callback) this.callback(value, unsubscribe);
|
|
2715
|
-
}
|
|
2716
|
-
this.unsubscribe = unsubscribe;
|
|
2717
|
-
};
|
|
2718
|
-
this.host = host;
|
|
2719
|
-
if (contextOrOptions.context !== void 0) {
|
|
2720
|
-
const options = contextOrOptions;
|
|
2721
|
-
this.context = options.context;
|
|
2722
|
-
this.callback = options.callback;
|
|
2723
|
-
this.subscribe = options.subscribe ?? false;
|
|
2724
|
-
} else {
|
|
2725
|
-
this.context = contextOrOptions;
|
|
2726
|
-
this.callback = callback;
|
|
2727
|
-
this.subscribe = subscribe ?? false;
|
|
2728
|
-
}
|
|
2729
|
-
this.host.addController(this);
|
|
2730
|
-
}
|
|
2731
|
-
hostConnected() {
|
|
2732
|
-
this.dispatchRequest();
|
|
2733
|
-
}
|
|
2734
|
-
hostDisconnected() {
|
|
2735
|
-
if (this.unsubscribe) {
|
|
2736
|
-
this.unsubscribe();
|
|
2737
|
-
this.unsubscribe = void 0;
|
|
2738
|
-
}
|
|
2739
|
-
}
|
|
2740
|
-
dispatchRequest() {
|
|
2741
|
-
this.host.dispatchEvent(new ContextRequestEvent(this.context, this.host, this._callback, this.subscribe));
|
|
2742
|
-
}
|
|
2743
|
-
};
|
|
2744
|
-
|
|
2745
|
-
//#endregion
|
|
2746
|
-
//#region ../../node_modules/.pnpm/@lit+context@1.1.6/node_modules/@lit/context/development/lib/value-notifier.js
|
|
2747
|
-
/**
|
|
2748
|
-
* @license
|
|
2749
|
-
* Copyright 2021 Google LLC
|
|
2750
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
2751
|
-
*/
|
|
2752
|
-
/**
|
|
2753
|
-
* A simple class which stores a value, and triggers registered callbacks when
|
|
2754
|
-
* the value is changed via its setter.
|
|
2755
|
-
*
|
|
2756
|
-
* An implementor might use other observable patterns such as MobX or Redux to
|
|
2757
|
-
* get behavior like this. But this is a pretty minimal approach that will
|
|
2758
|
-
* likely work for a number of use cases.
|
|
2759
|
-
*/
|
|
2760
|
-
var ValueNotifier = class {
|
|
2761
|
-
get value() {
|
|
2762
|
-
return this._value;
|
|
2763
|
-
}
|
|
2764
|
-
set value(v) {
|
|
2765
|
-
this.setValue(v);
|
|
2766
|
-
}
|
|
2767
|
-
setValue(v, force = false) {
|
|
2768
|
-
const update = force || !Object.is(v, this._value);
|
|
2769
|
-
this._value = v;
|
|
2770
|
-
if (update) this.updateObservers();
|
|
2771
|
-
}
|
|
2772
|
-
constructor(defaultValue) {
|
|
2773
|
-
this.subscriptions = /* @__PURE__ */ new Map();
|
|
2774
|
-
this.updateObservers = () => {
|
|
2775
|
-
for (const [callback, { disposer }] of this.subscriptions) callback(this._value, disposer);
|
|
2776
|
-
};
|
|
2777
|
-
if (defaultValue !== void 0) this.value = defaultValue;
|
|
2778
|
-
}
|
|
2779
|
-
addCallback(callback, consumerHost, subscribe) {
|
|
2780
|
-
if (!subscribe) {
|
|
2781
|
-
callback(this.value);
|
|
2782
|
-
return;
|
|
2783
|
-
}
|
|
2784
|
-
if (!this.subscriptions.has(callback)) this.subscriptions.set(callback, {
|
|
2785
|
-
disposer: () => {
|
|
2786
|
-
this.subscriptions.delete(callback);
|
|
2787
|
-
},
|
|
2788
|
-
consumerHost
|
|
2789
|
-
});
|
|
2790
|
-
const { disposer } = this.subscriptions.get(callback);
|
|
2791
|
-
callback(this.value, disposer);
|
|
2792
|
-
}
|
|
2793
|
-
clearCallbacks() {
|
|
2794
|
-
this.subscriptions.clear();
|
|
2795
|
-
}
|
|
2796
|
-
};
|
|
2797
|
-
|
|
2798
|
-
//#endregion
|
|
2799
|
-
//#region ../../node_modules/.pnpm/@lit+context@1.1.6/node_modules/@lit/context/development/lib/controllers/context-provider.js
|
|
2800
|
-
/**
|
|
2801
|
-
* @license
|
|
2802
|
-
* Copyright 2021 Google LLC
|
|
2803
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
2804
|
-
*/
|
|
2805
|
-
var ContextProviderEvent = class extends Event {
|
|
2806
|
-
/**
|
|
2807
|
-
*
|
|
2808
|
-
* @param context the context which this provider can provide
|
|
2809
|
-
* @param contextTarget the original context target of the provider
|
|
2810
|
-
*/
|
|
2811
|
-
constructor(context, contextTarget) {
|
|
2812
|
-
super("context-provider", {
|
|
2813
|
-
bubbles: true,
|
|
2814
|
-
composed: true
|
|
2815
|
-
});
|
|
2816
|
-
this.context = context;
|
|
2817
|
-
this.contextTarget = contextTarget;
|
|
2818
|
-
}
|
|
2819
|
-
};
|
|
2820
|
-
/**
|
|
2821
|
-
* A ReactiveController which adds context provider behavior to a
|
|
2822
|
-
* custom element.
|
|
2823
|
-
*
|
|
2824
|
-
* This controller simply listens to the `context-request` event when
|
|
2825
|
-
* the host is connected to the DOM and registers the received callbacks
|
|
2826
|
-
* against its observable Context implementation.
|
|
2827
|
-
*
|
|
2828
|
-
* The controller may also be attached to any HTML element in which case it's
|
|
2829
|
-
* up to the user to call hostConnected() when attached to the DOM. This is
|
|
2830
|
-
* done automatically for any custom elements implementing
|
|
2831
|
-
* ReactiveControllerHost.
|
|
2832
|
-
*/
|
|
2833
|
-
var ContextProvider = class extends ValueNotifier {
|
|
2834
|
-
constructor(host, contextOrOptions, initialValue) {
|
|
2835
|
-
super(contextOrOptions.context !== void 0 ? contextOrOptions.initialValue : initialValue);
|
|
2836
|
-
this.onContextRequest = (ev) => {
|
|
2837
|
-
if (ev.context !== this.context) return;
|
|
2838
|
-
const consumerHost = ev.contextTarget ?? ev.composedPath()[0];
|
|
2839
|
-
if (consumerHost === this.host) return;
|
|
2840
|
-
ev.stopPropagation();
|
|
2841
|
-
this.addCallback(ev.callback, consumerHost, ev.subscribe);
|
|
2842
|
-
};
|
|
2843
|
-
/**
|
|
2844
|
-
* When we get a provider request event, that means a child of this element
|
|
2845
|
-
* has just woken up. If it's a provider of our context, then we may need to
|
|
2846
|
-
* re-parent our subscriptions, because is a more specific provider than us
|
|
2847
|
-
* for its subtree.
|
|
2848
|
-
*/
|
|
2849
|
-
this.onProviderRequest = (ev) => {
|
|
2850
|
-
if (ev.context !== this.context) return;
|
|
2851
|
-
if ((ev.contextTarget ?? ev.composedPath()[0]) === this.host) return;
|
|
2852
|
-
const seen = /* @__PURE__ */ new Set();
|
|
2853
|
-
for (const [callback, { consumerHost }] of this.subscriptions) {
|
|
2854
|
-
if (seen.has(callback)) continue;
|
|
2855
|
-
seen.add(callback);
|
|
2856
|
-
consumerHost.dispatchEvent(new ContextRequestEvent(this.context, consumerHost, callback, true));
|
|
2857
|
-
}
|
|
2858
|
-
ev.stopPropagation();
|
|
2859
|
-
};
|
|
2860
|
-
this.host = host;
|
|
2861
|
-
if (contextOrOptions.context !== void 0) this.context = contextOrOptions.context;
|
|
2862
|
-
else this.context = contextOrOptions;
|
|
2863
|
-
this.attachListeners();
|
|
2864
|
-
this.host.addController?.(this);
|
|
2865
|
-
}
|
|
2866
|
-
attachListeners() {
|
|
2867
|
-
this.host.addEventListener("context-request", this.onContextRequest);
|
|
2868
|
-
this.host.addEventListener("context-provider", this.onProviderRequest);
|
|
2869
|
-
}
|
|
2870
|
-
hostConnected() {
|
|
2871
|
-
this.host.dispatchEvent(new ContextProviderEvent(this.context, this.host));
|
|
2872
|
-
}
|
|
2873
|
-
};
|
|
2874
|
-
|
|
2875
|
-
//#endregion
|
|
2876
|
-
//#region src/store/container-mixin.ts
|
|
2877
|
-
/**
|
|
2878
|
-
* Create a mixin that consumes player context and registers itself as the
|
|
2879
|
-
* container element with the provider via `containerContext`.
|
|
2880
|
-
*
|
|
2881
|
-
* @param config - Container configuration with player and container contexts.
|
|
2882
|
-
*/
|
|
2883
|
-
function createContainerMixin(config) {
|
|
2884
|
-
return (BaseClass) => {
|
|
2885
|
-
class PlayerContainerElement extends BaseClass {
|
|
2886
|
-
#contextStore = null;
|
|
2887
|
-
#setContainer = null;
|
|
2888
|
-
constructor(...args) {
|
|
2889
|
-
super(...args);
|
|
2890
|
-
new ContextConsumer(this, {
|
|
2891
|
-
context: config.playerContext,
|
|
2892
|
-
callback: (value) => {
|
|
2893
|
-
this.#contextStore = value ?? null;
|
|
2894
|
-
},
|
|
2895
|
-
subscribe: true
|
|
2896
|
-
});
|
|
2897
|
-
new ContextConsumer(this, {
|
|
2898
|
-
context: config.containerContext,
|
|
2899
|
-
callback: (value) => {
|
|
2900
|
-
this.#setContainer = value?.setContainer ?? null;
|
|
2901
|
-
if (this.isConnected) this.#setContainer?.(this);
|
|
2902
|
-
},
|
|
2903
|
-
subscribe: true
|
|
2904
|
-
});
|
|
2905
|
-
}
|
|
2906
|
-
get store() {
|
|
2907
|
-
return this.#contextStore;
|
|
2908
|
-
}
|
|
2909
|
-
connectedCallback() {
|
|
2910
|
-
super.connectedCallback();
|
|
2911
|
-
this.#setContainer?.(this);
|
|
2912
|
-
}
|
|
2913
|
-
disconnectedCallback() {
|
|
2914
|
-
super.disconnectedCallback();
|
|
2915
|
-
this.#setContainer?.(null);
|
|
2916
|
-
}
|
|
2917
|
-
}
|
|
2918
|
-
return PlayerContainerElement;
|
|
2919
|
-
};
|
|
2920
|
-
}
|
|
2921
|
-
|
|
2922
|
-
//#endregion
|
|
2923
|
-
//#region src/ui/media-element.ts
|
|
2924
|
-
/** Base class for interactive media UI elements. */
|
|
2925
|
-
var MediaElement = class extends DestroyMixin(ReactiveElement) {};
|
|
2926
|
-
|
|
2927
|
-
//#endregion
|
|
2928
|
-
//#region src/media/container-element.ts
|
|
2929
|
-
const ContainerMixin = createContainerMixin({
|
|
2930
|
-
playerContext,
|
|
2931
|
-
containerContext
|
|
2932
|
-
});
|
|
2933
|
-
var MediaContainerElement = class extends ContainerMixin(MediaElement) {
|
|
2934
|
-
static {
|
|
2935
|
-
this.tagName = "media-container";
|
|
1955
|
+
var PlayerController = class {
|
|
1956
|
+
#host;
|
|
1957
|
+
#selector;
|
|
1958
|
+
#consumer;
|
|
1959
|
+
#store = null;
|
|
1960
|
+
constructor(host, context, selector) {
|
|
1961
|
+
this.#host = host;
|
|
1962
|
+
this.#selector = selector;
|
|
1963
|
+
this.#consumer = new ContextConsumer(host, {
|
|
1964
|
+
context,
|
|
1965
|
+
callback: (ctx) => this.#connect(ctx),
|
|
1966
|
+
subscribe: true
|
|
1967
|
+
});
|
|
1968
|
+
host.addController(this);
|
|
1969
|
+
}
|
|
1970
|
+
get value() {
|
|
1971
|
+
const store = this.#consumer.value;
|
|
1972
|
+
if (!store) return void 0;
|
|
1973
|
+
if (!this.#selector) return store;
|
|
1974
|
+
return this.#store?.value;
|
|
1975
|
+
}
|
|
1976
|
+
get displayName() {
|
|
1977
|
+
return this.#selector?.displayName;
|
|
1978
|
+
}
|
|
1979
|
+
hostConnected() {
|
|
1980
|
+
const store = this.#consumer.value;
|
|
1981
|
+
if (store) this.#connect(store);
|
|
1982
|
+
}
|
|
1983
|
+
hostDisconnected() {
|
|
1984
|
+
this.#store = null;
|
|
1985
|
+
}
|
|
1986
|
+
#connect(store) {
|
|
1987
|
+
if (!this.#store && this.#selector) this.#store = new StoreController(this.#host, store, this.#selector);
|
|
2936
1988
|
}
|
|
2937
1989
|
};
|
|
2938
1990
|
|
|
@@ -3060,235 +2112,6 @@ function createProviderMixin(config) {
|
|
|
3060
2112
|
};
|
|
3061
2113
|
}
|
|
3062
2114
|
|
|
3063
|
-
//#endregion
|
|
3064
|
-
//#region ../store/dist/dev/html/controllers/snapshot-controller.js
|
|
3065
|
-
/**
|
|
3066
|
-
* Subscribe to a `State<T>` container with optional selector.
|
|
3067
|
-
*
|
|
3068
|
-
* Without selector: returns full state, re-renders on any state change.
|
|
3069
|
-
* With selector: returns selected slice, re-renders only when the slice changes (shallowEqual).
|
|
3070
|
-
*
|
|
3071
|
-
* @example
|
|
3072
|
-
* ```ts
|
|
3073
|
-
* #state = new SnapshotController(this, sliderState, (s) => s.value);
|
|
3074
|
-
* ```
|
|
3075
|
-
*/
|
|
3076
|
-
var SnapshotController = class {
|
|
3077
|
-
#host;
|
|
3078
|
-
#selector;
|
|
3079
|
-
#state;
|
|
3080
|
-
#cached;
|
|
3081
|
-
#unsubscribe = noop;
|
|
3082
|
-
constructor(host, state, selector) {
|
|
3083
|
-
this.#host = host;
|
|
3084
|
-
this.#state = state;
|
|
3085
|
-
this.#selector = selector;
|
|
3086
|
-
host.addController(this);
|
|
3087
|
-
}
|
|
3088
|
-
get value() {
|
|
3089
|
-
if (!this.#selector) return this.#state.current;
|
|
3090
|
-
this.#cached ??= this.#selector(this.#state.current);
|
|
3091
|
-
return this.#cached;
|
|
3092
|
-
}
|
|
3093
|
-
/** Switch to tracking a different state container. */
|
|
3094
|
-
track(state) {
|
|
3095
|
-
this.#state = state;
|
|
3096
|
-
this.#subscribe();
|
|
3097
|
-
}
|
|
3098
|
-
hostConnected() {
|
|
3099
|
-
this.#subscribe();
|
|
3100
|
-
}
|
|
3101
|
-
hostDisconnected() {
|
|
3102
|
-
this.#unsubscribe();
|
|
3103
|
-
this.#unsubscribe = noop;
|
|
3104
|
-
this.#cached = void 0;
|
|
3105
|
-
}
|
|
3106
|
-
#subscribe() {
|
|
3107
|
-
this.#unsubscribe();
|
|
3108
|
-
if (!this.#selector) {
|
|
3109
|
-
this.#unsubscribe = this.#state.subscribe(() => this.#host.requestUpdate());
|
|
3110
|
-
return;
|
|
3111
|
-
}
|
|
3112
|
-
const selector = this.#selector;
|
|
3113
|
-
this.#cached = selector(this.#state.current);
|
|
3114
|
-
this.#unsubscribe = this.#state.subscribe(() => {
|
|
3115
|
-
const next = selector(this.#state.current);
|
|
3116
|
-
if (!shallowEqual(this.#cached, next)) {
|
|
3117
|
-
this.#cached = next;
|
|
3118
|
-
this.#host.requestUpdate();
|
|
3119
|
-
}
|
|
3120
|
-
});
|
|
3121
|
-
}
|
|
3122
|
-
};
|
|
3123
|
-
|
|
3124
|
-
//#endregion
|
|
3125
|
-
//#region ../store/dist/dev/html/store-accessor.js
|
|
3126
|
-
/**
|
|
3127
|
-
* Resolves a store from either a direct instance or context.
|
|
3128
|
-
*
|
|
3129
|
-
* When given a direct store, provides immediate access.
|
|
3130
|
-
* When given a context, sets up a ContextConsumer to receive the store.
|
|
3131
|
-
*
|
|
3132
|
-
* @example Direct store
|
|
3133
|
-
* ```ts
|
|
3134
|
-
* const accessor = new StoreAccessor(host, store, (s) => console.log('available', s));
|
|
3135
|
-
* accessor.value; // Store (immediately available)
|
|
3136
|
-
* ```
|
|
3137
|
-
*
|
|
3138
|
-
* @example Context source
|
|
3139
|
-
* ```ts
|
|
3140
|
-
* const accessor = new StoreAccessor(host, context, (s) => console.log('available', s));
|
|
3141
|
-
* accessor.value; // null until context provides store
|
|
3142
|
-
* ```
|
|
3143
|
-
*/
|
|
3144
|
-
var StoreAccessor = class {
|
|
3145
|
-
#onAvailable;
|
|
3146
|
-
#consumer;
|
|
3147
|
-
#directStore;
|
|
3148
|
-
constructor(host, source, onAvailable) {
|
|
3149
|
-
this.#onAvailable = onAvailable ?? noop;
|
|
3150
|
-
if (isStore(source)) {
|
|
3151
|
-
this.#directStore = source;
|
|
3152
|
-
this.#consumer = null;
|
|
3153
|
-
} else {
|
|
3154
|
-
this.#directStore = null;
|
|
3155
|
-
this.#consumer = new ContextConsumer(host, {
|
|
3156
|
-
context: source,
|
|
3157
|
-
callback: (store) => this.#onAvailable(store),
|
|
3158
|
-
subscribe: false
|
|
3159
|
-
});
|
|
3160
|
-
}
|
|
3161
|
-
host.addController(this);
|
|
3162
|
-
}
|
|
3163
|
-
/** Returns the store, or null if not yet available from context. */
|
|
3164
|
-
get value() {
|
|
3165
|
-
if (this.#consumer) return this.#consumer.value ?? null;
|
|
3166
|
-
return this.#directStore;
|
|
3167
|
-
}
|
|
3168
|
-
hostConnected() {
|
|
3169
|
-
if (this.#directStore) this.#onAvailable(this.#directStore);
|
|
3170
|
-
}
|
|
3171
|
-
};
|
|
3172
|
-
|
|
3173
|
-
//#endregion
|
|
3174
|
-
//#region ../store/dist/dev/html/controllers/store-controller.js
|
|
3175
|
-
/**
|
|
3176
|
-
* Access store state and actions.
|
|
3177
|
-
*
|
|
3178
|
-
* Without selector: Returns the store, does NOT subscribe to changes.
|
|
3179
|
-
* With selector: Returns selected state, triggers update when selected state changes (shallowEqual).
|
|
3180
|
-
*
|
|
3181
|
-
* @example
|
|
3182
|
-
* ```ts
|
|
3183
|
-
* // Store access (no subscription) - access actions
|
|
3184
|
-
* class Controls extends LitElement {
|
|
3185
|
-
* #store = new StoreController(this, storeSource);
|
|
3186
|
-
*
|
|
3187
|
-
* handleClick() {
|
|
3188
|
-
* this.#store.value.setVolume(0.5);
|
|
3189
|
-
* }
|
|
3190
|
-
* }
|
|
3191
|
-
*
|
|
3192
|
-
* // Selector-based subscription - re-renders when playback changes
|
|
3193
|
-
* class PlayButton extends LitElement {
|
|
3194
|
-
* #playback = new StoreController(this, storeSource, selectPlayback);
|
|
3195
|
-
*
|
|
3196
|
-
* render() {
|
|
3197
|
-
* const playback = this.#playback.value;
|
|
3198
|
-
* if (!playback) return nothing;
|
|
3199
|
-
* return html`<button @click=${playback.toggle}>
|
|
3200
|
-
* ${playback.paused ? 'Play' : 'Pause'}
|
|
3201
|
-
* </button>`;
|
|
3202
|
-
* }
|
|
3203
|
-
* }
|
|
3204
|
-
* ```
|
|
3205
|
-
*/
|
|
3206
|
-
var StoreController = class {
|
|
3207
|
-
#host;
|
|
3208
|
-
#selector;
|
|
3209
|
-
#accessor;
|
|
3210
|
-
#snapshot = null;
|
|
3211
|
-
constructor(host, source, selector) {
|
|
3212
|
-
this.#host = host;
|
|
3213
|
-
this.#selector = selector;
|
|
3214
|
-
this.#accessor = new StoreAccessor(host, source, (store) => this.#connect(store));
|
|
3215
|
-
host.addController(this);
|
|
3216
|
-
}
|
|
3217
|
-
get value() {
|
|
3218
|
-
const store = this.#accessor.value;
|
|
3219
|
-
if (isNull(store)) throw new Error("Store not available");
|
|
3220
|
-
if (isUndefined(this.#selector)) return store;
|
|
3221
|
-
return this.#snapshot.value;
|
|
3222
|
-
}
|
|
3223
|
-
hostConnected() {}
|
|
3224
|
-
#connect(store) {
|
|
3225
|
-
if (isUndefined(this.#selector)) return;
|
|
3226
|
-
if (!this.#snapshot) this.#snapshot = new SnapshotController(this.#host, store.$state, this.#selector);
|
|
3227
|
-
else this.#snapshot.track(store.$state);
|
|
3228
|
-
}
|
|
3229
|
-
};
|
|
3230
|
-
|
|
3231
|
-
//#endregion
|
|
3232
|
-
//#region src/player/player-controller.ts
|
|
3233
|
-
/**
|
|
3234
|
-
* Reactive controller for accessing player store state.
|
|
3235
|
-
*
|
|
3236
|
-
* Without selector: Returns the store, does NOT subscribe to changes.
|
|
3237
|
-
* With selector: Returns selected state, subscribes with shallowEqual comparison.
|
|
3238
|
-
*
|
|
3239
|
-
* @example
|
|
3240
|
-
* ```ts
|
|
3241
|
-
* // Store access (no subscription)
|
|
3242
|
-
* class Controls extends MediaElement {
|
|
3243
|
-
* #player = new PlayerController(this, playerContext);
|
|
3244
|
-
*
|
|
3245
|
-
* handleClick() {
|
|
3246
|
-
* this.#player.value.setVolume(0.5);
|
|
3247
|
-
* }
|
|
3248
|
-
* }
|
|
3249
|
-
*
|
|
3250
|
-
* // Selector-based subscription
|
|
3251
|
-
* class PlayButton extends MediaElement {
|
|
3252
|
-
* #playback = new PlayerController(this, playerContext, selectPlayback);
|
|
3253
|
-
* }
|
|
3254
|
-
* ```
|
|
3255
|
-
*/
|
|
3256
|
-
var PlayerController = class {
|
|
3257
|
-
#host;
|
|
3258
|
-
#selector;
|
|
3259
|
-
#consumer;
|
|
3260
|
-
#store = null;
|
|
3261
|
-
constructor(host, context, selector) {
|
|
3262
|
-
this.#host = host;
|
|
3263
|
-
this.#selector = selector;
|
|
3264
|
-
this.#consumer = new ContextConsumer(host, {
|
|
3265
|
-
context,
|
|
3266
|
-
callback: (ctx) => this.#connect(ctx),
|
|
3267
|
-
subscribe: true
|
|
3268
|
-
});
|
|
3269
|
-
host.addController(this);
|
|
3270
|
-
}
|
|
3271
|
-
get value() {
|
|
3272
|
-
const store = this.#consumer.value;
|
|
3273
|
-
if (!store) return void 0;
|
|
3274
|
-
if (!this.#selector) return store;
|
|
3275
|
-
return this.#store?.value;
|
|
3276
|
-
}
|
|
3277
|
-
get displayName() {
|
|
3278
|
-
return this.#selector?.displayName;
|
|
3279
|
-
}
|
|
3280
|
-
hostConnected() {
|
|
3281
|
-
const store = this.#consumer.value;
|
|
3282
|
-
if (store) this.#connect(store);
|
|
3283
|
-
}
|
|
3284
|
-
hostDisconnected() {
|
|
3285
|
-
this.#store = null;
|
|
3286
|
-
}
|
|
3287
|
-
#connect(store) {
|
|
3288
|
-
if (!this.#store && this.#selector) this.#store = new StoreController(this.#host, store, this.#selector);
|
|
3289
|
-
}
|
|
3290
|
-
};
|
|
3291
|
-
|
|
3292
2115
|
//#endregion
|
|
3293
2116
|
//#region src/player/create-player.ts
|
|
3294
2117
|
function createPlayer(config) {
|
|
@@ -3314,5 +2137,5 @@ function createPlayer(config) {
|
|
|
3314
2137
|
}
|
|
3315
2138
|
|
|
3316
2139
|
//#endregion
|
|
3317
|
-
export {
|
|
3318
|
-
//# sourceMappingURL=create-player-
|
|
2140
|
+
export { ContextConsumer as A, isFunction as C, MediaContainerElement as D, isUndefined as E, isEditableTarget as M, resolveEventTarget as N, MediaElement as O, AbortControllerRegistry as S, isNumber as T, getGestureCoordinator as _, backgroundFeatures as a, noop as b, timeFeature as c, playbackRateFeature as d, playbackFeature as f, controlsFeature as g, errorFeature as h, audioFeatures as i, ReactiveElement as j, ContextProvider as k, textTrackFeature as l, fullscreenFeature as m, PlayerController as n, videoFeatures as o, pipFeature as p, SnapshotController as r, volumeFeature as s, createPlayer as t, sourceFeature as u, bufferFeature as v, isNull as w, throwNoTargetError as x, createState as y };
|
|
2141
|
+
//# sourceMappingURL=create-player-CyG77t-m.js.map
|