vidply 1.2.0 → 1.2.1
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/README.md +946 -946
- package/dist/dev/{vidply.AudioDescriptionManager-R47Q4YR4.js → vidply.AudioDescriptionManager-6RFVF27Z.js} +275 -19
- package/dist/dev/vidply.AudioDescriptionManager-6RFVF27Z.js.map +7 -0
- package/dist/dev/{vidply.CaptionStyleMenu-7XHRBWUM.js → vidply.CaptionStyleMenu-R2SCQ6VP.js} +4 -4
- package/dist/dev/{vidply.DASHRenderer-PWEMC3BT.js → vidply.DASHRenderer-EOVEW73H.js} +3 -3
- package/dist/dev/vidply.DASHRenderer-EOVEW73H.js.map +7 -0
- package/dist/dev/{vidply.FloatingPlayerManager-PKNNNAS2.js → vidply.FloatingPlayerManager-V5XQWS75.js} +5 -5
- package/dist/dev/vidply.FloatingPlayerManager-V5XQWS75.js.map +7 -0
- package/dist/dev/{vidply.HLSRenderer-E7RQ74HI.js → vidply.HLSRenderer-ZBEFVH5W.js} +4 -4
- package/dist/dev/vidply.HLSRenderer-ZBEFVH5W.js.map +7 -0
- package/dist/dev/vidply.HTML5Renderer-P7ICKYU4.js +12 -0
- package/dist/dev/{vidply.SignLanguageManager-FET5FQZ7.js → vidply.SignLanguageManager-7IAJOVF6.js} +8 -8
- package/dist/dev/vidply.SignLanguageManager-7IAJOVF6.js.map +7 -0
- package/dist/dev/{vidply.SoundCloudRenderer-RVSJZODO.js → vidply.SoundCloudRenderer-OA7QQYGN.js} +3 -3
- package/dist/dev/vidply.SoundCloudRenderer-OA7QQYGN.js.map +7 -0
- package/dist/dev/{vidply.TranscriptManager-5GXOQCLX.js → vidply.TranscriptManager-BPM3T23L.js} +10 -10
- package/dist/dev/vidply.TranscriptManager-BPM3T23L.js.map +7 -0
- package/dist/dev/{vidply.VimeoRenderer-ER2LSBBW.js → vidply.VimeoRenderer-BRHFYPNJ.js} +3 -3
- package/dist/dev/vidply.VimeoRenderer-BRHFYPNJ.js.map +7 -0
- package/dist/dev/{vidply.YouTubeRenderer-NFTOWJAB.js → vidply.YouTubeRenderer-HRTN4EJ5.js} +3 -3
- package/dist/dev/vidply.YouTubeRenderer-HRTN4EJ5.js.map +7 -0
- package/dist/dev/{vidply.chunk-6RQA4ROD.js → vidply.chunk-5IK3IC5V.js} +2 -2
- package/dist/dev/{vidply.chunk-JJ47NO24.js → vidply.chunk-C55OBT5H.js} +2 -2
- package/dist/dev/vidply.chunk-C55OBT5H.js.map +7 -0
- package/dist/dev/{vidply.chunk-DZSDO3B7.js → vidply.chunk-HOYEMJSD.js} +2 -2
- package/dist/dev/{vidply.chunk-VMSQAZM7.js → vidply.chunk-JAKZNGOR.js} +2 -2
- package/dist/dev/{vidply.chunk-64WXMTGL.js → vidply.chunk-LDVFAFGC.js} +5 -5
- package/dist/dev/vidply.chunk-LDVFAFGC.js.map +7 -0
- package/dist/dev/{vidply.chunk-RZWZGDV7.js → vidply.chunk-NSMAZCMB.js} +6 -6
- package/dist/dev/vidply.chunk-NSMAZCMB.js.map +7 -0
- package/dist/dev/{vidply.chunk-KI7C3QVL.js → vidply.chunk-RQG3MA7W.js} +2 -2
- package/dist/dev/vidply.chunk-RQG3MA7W.js.map +7 -0
- package/dist/dev/{vidply.chunk-BNFIUL2Z.js → vidply.chunk-UHMVDBDB.js} +3 -3
- package/dist/dev/vidply.chunk-UHMVDBDB.js.map +7 -0
- package/dist/dev/{vidply.chunk-NQPURMQY.js → vidply.chunk-W5BR65JY.js} +6 -6
- package/dist/dev/vidply.chunk-W5BR65JY.js.map +7 -0
- package/dist/dev/{vidply.chunk-W25HUCHS.js → vidply.chunk-XAK3DPTO.js} +2 -2
- package/dist/dev/vidply.chunk-XAK3DPTO.js.map +7 -0
- package/dist/dev/{vidply.chunk-SK4V2DAU.js → vidply.chunk-YVCYQZJI.js} +3 -3
- package/dist/dev/{vidply.de-4YAT7FFM.js → vidply.de-5W5LBFSJ.js} +2 -2
- package/dist/dev/vidply.de-5W5LBFSJ.js.map +7 -0
- package/dist/dev/{vidply.es-LEWIRUBH.js → vidply.es-SHDAT6L6.js} +2 -2
- package/dist/dev/vidply.es-SHDAT6L6.js.map +7 -0
- package/dist/dev/vidply.esm.js +73 -34
- package/dist/dev/vidply.esm.js.map +2 -2
- package/dist/dev/{vidply.fr-Q4GV2NOE.js → vidply.fr-2JANOMNB.js} +2 -2
- package/dist/dev/vidply.fr-2JANOMNB.js.map +7 -0
- package/dist/dev/{vidply.ja-S6ITA6WU.js → vidply.ja-WWMSTEJH.js} +2 -2
- package/dist/dev/vidply.ja-WWMSTEJH.js.map +7 -0
- package/dist/legacy/vidply.js +345 -32
- package/dist/legacy/vidply.js.map +3 -3
- package/dist/legacy/vidply.min.js +2 -2
- package/dist/legacy/vidply.min.meta.json +66 -47
- package/dist/prod/vidply.AudioDescriptionManager-YTDVDQBO.min.js +6 -0
- package/dist/prod/{vidply.CaptionStyleMenu-M3KVQWB5.min.js → vidply.CaptionStyleMenu-2AFF3HF2.min.js} +2 -2
- package/dist/prod/{vidply.DASHRenderer-DN3S27AV.min.js → vidply.DASHRenderer-URDOTOKS.min.js} +2 -2
- package/dist/prod/{vidply.FloatingPlayerManager-SKAZ4J43.min.js → vidply.FloatingPlayerManager-QUBFK7CQ.min.js} +2 -2
- package/dist/prod/{vidply.HLSRenderer-62HH4YTK.min.js → vidply.HLSRenderer-46KNUVAB.min.js} +2 -2
- package/dist/prod/vidply.HTML5Renderer-7TQDMIGY.min.js +6 -0
- package/dist/prod/{vidply.SignLanguageManager-V3OBTSSF.min.js → vidply.SignLanguageManager-H4C36EVL.min.js} +2 -2
- package/dist/prod/{vidply.SoundCloudRenderer-CXRVZIAJ.min.js → vidply.SoundCloudRenderer-OYSWMW7D.min.js} +2 -2
- package/dist/prod/{vidply.TranscriptManager-SYM3DFUY.min.js → vidply.TranscriptManager-BA3DAS63.min.js} +2 -2
- package/dist/prod/{vidply.VimeoRenderer-72TWRYFQ.min.js → vidply.VimeoRenderer-NF3COTHU.min.js} +2 -2
- package/dist/prod/{vidply.YouTubeRenderer-UMHEV3KD.min.js → vidply.YouTubeRenderer-UCQKYIJ4.min.js} +2 -2
- package/dist/prod/{vidply.chunk-Z3YDSA7O.min.js → vidply.chunk-2HNCP64N.min.js} +1 -1
- package/dist/prod/{vidply.chunk-EKEYJWMG.min.js → vidply.chunk-6ECBIYVI.min.js} +2 -2
- package/dist/prod/{vidply.chunk-YEENJS3Q.min.js → vidply.chunk-7S5AFTST.min.js} +2 -2
- package/dist/prod/{vidply.chunk-P4UXOHWA.min.js → vidply.chunk-EUOA2DJK.min.js} +1 -1
- package/dist/prod/{vidply.chunk-2TB6MUHO.min.js → vidply.chunk-G6KGXNEW.min.js} +1 -1
- package/dist/prod/{vidply.chunk-ABPXVDLZ.min.js → vidply.chunk-JPMAK3NS.min.js} +1 -1
- package/dist/prod/{vidply.chunk-P3PQBY7N.min.js → vidply.chunk-L4O44K63.min.js} +1 -1
- package/dist/prod/{vidply.chunk-WX3MVEAL.min.js → vidply.chunk-M76ABMKB.min.js} +1 -1
- package/dist/prod/{vidply.chunk-TM6AXJVD.min.js → vidply.chunk-WRVDVD33.min.js} +2 -2
- package/dist/prod/{vidply.chunk-RI3X7WHK.min.js → vidply.chunk-X2FQEQYR.min.js} +2 -2
- package/dist/prod/{vidply.chunk-UK7YGOB5.min.js → vidply.chunk-XXUH7ADU.min.js} +2 -2
- package/dist/prod/{vidply.de-BCHXRQ53.min.js → vidply.de-JMCATTKZ.min.js} +1 -1
- package/dist/prod/{vidply.es-PICAKMZD.min.js → vidply.es-YVG37V7Z.min.js} +1 -1
- package/dist/prod/vidply.esm.min.js +2 -2
- package/dist/prod/{vidply.fr-ZILI7CDR.min.js → vidply.fr-OGKGN2R4.min.js} +1 -1
- package/dist/prod/{vidply.ja-5WQ4OK4J.min.js → vidply.ja-Z6DS7QLS.min.js} +1 -1
- package/dist/vidply.css +5796 -5796
- package/dist/vidply.esm.min.meta.json +148 -135
- package/package.json +7 -7
- package/src/controls/CaptionManager.ts +598 -598
- package/src/controls/ControlBar.ts +4159 -4159
- package/src/controls/KeyboardManager.ts +383 -383
- package/src/controls/SettingsDialog.ts +488 -488
- package/src/controls/TranscriptManager.ts +2426 -2426
- package/src/core/AudioDescriptionManager.ts +863 -774
- package/src/core/DescriptionSpeechManager.ts +232 -0
- package/src/core/FloatingPlayerManager.ts +674 -674
- package/src/core/LazyInit.ts +80 -80
- package/src/core/MetadataAlertsManager.ts +514 -514
- package/src/core/Player.ts +2915 -2872
- package/src/core/PosterManager.ts +169 -169
- package/src/core/PseudoFullscreen.ts +179 -179
- package/src/core/ResponsiveManager.ts +231 -231
- package/src/core/ResumeManager.ts +236 -236
- package/src/core/SignLanguageManager.ts +1308 -1308
- package/src/core/ThemeManager.ts +157 -157
- package/src/features/PlaylistManager.ts +1838 -1827
- package/src/i18n/i18n.ts +223 -223
- package/src/i18n/languages/de.ts +217 -217
- package/src/i18n/languages/en.ts +218 -218
- package/src/i18n/languages/es.ts +214 -214
- package/src/i18n/languages/fr.ts +214 -214
- package/src/i18n/languages/ja.ts +214 -214
- package/src/icons/Icons.ts +167 -167
- package/src/index.ts +196 -193
- package/src/renderers/DASHRenderer.ts +1077 -1077
- package/src/renderers/HLSRenderer.ts +944 -944
- package/src/renderers/HTML5Renderer.ts +389 -389
- package/src/renderers/SoundCloudRenderer.ts +437 -437
- package/src/renderers/VimeoRenderer.ts +298 -298
- package/src/renderers/YouTubeRenderer.ts +290 -290
- package/src/styles/vidply.css +5796 -5796
- package/src/types/events.ts +124 -122
- package/src/types/globals.d.ts +313 -313
- package/src/types/options.ts +185 -182
- package/src/types/renderer.ts +58 -58
- package/src/utils/DOMUtils.ts +281 -281
- package/src/utils/DownloadInfo.ts +171 -171
- package/src/utils/DraggablePanel.ts +539 -539
- package/src/utils/DraggablePanelMenu.ts +195 -195
- package/src/utils/DraggableResizable.ts +997 -997
- package/src/utils/EventEmitter.ts +59 -59
- package/src/utils/FormUtils.ts +95 -95
- package/src/utils/MenuFactory.ts +483 -483
- package/src/utils/Sanitize.ts +70 -70
- package/src/utils/SettingsMenuFactory.ts +289 -289
- package/src/utils/StorageManager.ts +287 -287
- package/src/utils/TrackLabelUtils.ts +52 -52
- package/src/utils/UrlSafe.ts +69 -69
- package/src/utils/VideoFrameCapture.ts +114 -114
- package/src/utils/WindowComponents.ts +250 -250
- package/dist/dev/vidply.AudioDescriptionManager-R47Q4YR4.js.map +0 -7
- package/dist/dev/vidply.DASHRenderer-PWEMC3BT.js.map +0 -7
- package/dist/dev/vidply.FloatingPlayerManager-PKNNNAS2.js.map +0 -7
- package/dist/dev/vidply.HLSRenderer-E7RQ74HI.js.map +0 -7
- package/dist/dev/vidply.HTML5Renderer-BU4QJJJY.js +0 -12
- package/dist/dev/vidply.SignLanguageManager-FET5FQZ7.js.map +0 -7
- package/dist/dev/vidply.SoundCloudRenderer-RVSJZODO.js.map +0 -7
- package/dist/dev/vidply.TranscriptManager-5GXOQCLX.js.map +0 -7
- package/dist/dev/vidply.VimeoRenderer-ER2LSBBW.js.map +0 -7
- package/dist/dev/vidply.YouTubeRenderer-NFTOWJAB.js.map +0 -7
- package/dist/dev/vidply.chunk-64WXMTGL.js.map +0 -7
- package/dist/dev/vidply.chunk-BNFIUL2Z.js.map +0 -7
- package/dist/dev/vidply.chunk-JJ47NO24.js.map +0 -7
- package/dist/dev/vidply.chunk-KI7C3QVL.js.map +0 -7
- package/dist/dev/vidply.chunk-NQPURMQY.js.map +0 -7
- package/dist/dev/vidply.chunk-RZWZGDV7.js.map +0 -7
- package/dist/dev/vidply.chunk-W25HUCHS.js.map +0 -7
- package/dist/dev/vidply.de-4YAT7FFM.js.map +0 -7
- package/dist/dev/vidply.es-LEWIRUBH.js.map +0 -7
- package/dist/dev/vidply.fr-Q4GV2NOE.js.map +0 -7
- package/dist/dev/vidply.ja-S6ITA6WU.js.map +0 -7
- package/dist/prod/vidply.AudioDescriptionManager-RHLIJW5C.min.js +0 -6
- package/dist/prod/vidply.HTML5Renderer-IU5T3WEW.min.js +0 -6
- /package/dist/dev/{vidply.CaptionStyleMenu-7XHRBWUM.js.map → vidply.CaptionStyleMenu-R2SCQ6VP.js.map} +0 -0
- /package/dist/dev/{vidply.HTML5Renderer-BU4QJJJY.js.map → vidply.HTML5Renderer-P7ICKYU4.js.map} +0 -0
- /package/dist/dev/{vidply.chunk-6RQA4ROD.js.map → vidply.chunk-5IK3IC5V.js.map} +0 -0
- /package/dist/dev/{vidply.chunk-DZSDO3B7.js.map → vidply.chunk-HOYEMJSD.js.map} +0 -0
- /package/dist/dev/{vidply.chunk-VMSQAZM7.js.map → vidply.chunk-JAKZNGOR.js.map} +0 -0
- /package/dist/dev/{vidply.chunk-SK4V2DAU.js.map → vidply.chunk-YVCYQZJI.js.map} +0 -0
package/src/icons/Icons.ts
CHANGED
|
@@ -1,167 +1,167 @@
|
|
|
1
|
-
const iconPaths: Record<string, string> = {
|
|
2
|
-
play: `<path d="M8 5v14l11-7z"/>`,
|
|
3
|
-
pause: `<path d="M6 4h4v16H6V4zm8 0h4v16h-4V4z"/>`,
|
|
4
|
-
stop: `<rect x="6" y="6" width="12" height="12"/>`,
|
|
5
|
-
rewind: `<path d="M11 18V6l-8.5 6 8.5 6zm.5-6l8.5 6V6l-8.5 6z"/>`,
|
|
6
|
-
forward: `<path d="M4 18l8.5-6L4 6v12zm9-12v12l8.5-6L13 6z"/>`,
|
|
7
|
-
skipPrevious: `<path d="M6 6h2v12H6V6zm3 6l8.5 6V6L9 12z"/>`,
|
|
8
|
-
skipNext: `<path d="M16 6h2v12h-2V6zM6 6l8.5 6L6 18V6z"/>`,
|
|
9
|
-
restart: `<path d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z"/>`,
|
|
10
|
-
volumeHigh: `<path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/>`,
|
|
11
|
-
volumeMedium: `<path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/>`,
|
|
12
|
-
volumeLow: `<path d="M7 9v6h4l5 5V4l-5 5H7z"/>`,
|
|
13
|
-
volumeMuted: `<path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/>`,
|
|
14
|
-
fullscreen: `<path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/>`,
|
|
15
|
-
fullscreenExit: `<path d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"/>`,
|
|
16
|
-
settings: `<path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94L14.4 2.81c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/>`,
|
|
17
|
-
captions: `<path d="M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1c0 .55-.45 1-1 1h-3c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1z"/>`,
|
|
18
|
-
captionsOff: `<path d="M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1c0 .55-.45 1-1 1h-3c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1z"/><path d="M0 0h24v24H0z" fill="none"/>`,
|
|
19
|
-
pip: `<path d="M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98V5c0-1.1-.9-2-2-2zm0 16.01H3V4.98h18v14.03z"/>`,
|
|
20
|
-
speed: `<path d="M20.38 8.57l-1.23 1.85a8 8 0 0 1-.22 7.58H5.07A8 8 0 0 1 15.58 6.85l1.85-1.23A10 10 0 0 0 3.35 19a2 2 0 0 0 1.72 1h13.85a2 2 0 0 0 1.74-1 10 10 0 0 0-.27-10.44z"/><path d="M10.59 15.41a2 2 0 0 0 2.83 0l5.66-8.49-8.49 5.66a2 2 0 0 0 0 2.83z"/>`,
|
|
21
|
-
close: `<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>`,
|
|
22
|
-
check: `<path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>`,
|
|
23
|
-
loading: `<path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"/>`,
|
|
24
|
-
error: `<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>`,
|
|
25
|
-
playlist: `<path d="M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18c-.31-.11-.65-.18-1-.18-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z"/>`,
|
|
26
|
-
hd: `<path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-8 12H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm7-1c0 .55-.45 1-1 1h-.75v1.5h-1.5V15H14c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v4zm-3.5-.5h2v-3h-2v3z"/>`,
|
|
27
|
-
transcript: `<path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z"/>`,
|
|
28
|
-
chapters: `<path d="M3 5h2v2H3V5zm0 4h2v2H3V9zm0 4h2v2H3v-2zm0 4h2v2H3v-2zM7 5h14v2H7V5zm0 4h14v2H7V9zm0 4h14v2H7v-2zm0 4h14v2H7v-2z"/>`,
|
|
29
|
-
audioDescription: `<rect x="2" y="5" width="20" height="14" rx="2" fill="none" stroke="currentColor" stroke-width="1.5"/><text x="12" y="14.5" text-anchor="middle" font-size="8" font-weight="bold" font-family="Arial, sans-serif" fill="currentColor">AD</text>`,
|
|
30
|
-
audioDescriptionOn: `<rect x="2" y="5" width="20" height="14" rx="2" fill="currentColor"/><text x="12" y="14.5" text-anchor="middle" font-size="8" font-weight="bold" font-family="Arial, sans-serif" class="vidply-icon-ad-fg">AD</text>`,
|
|
31
|
-
signLanguage: `<g transform="scale(1.5)"><path d="M16 11.3c-.1-.9-4.8 1.3-5.4 1.1-2.6-1 5.8-1.3 5.1-2.9s-5.1 1.5-6 1.4C6.5 9.4 16.5 9.1 13.5 8c-1.9-.6-8.8 2.9-6.8.4.7-.6.7-1.9-.7-1.7-9.7 7.2-.7 12.2 8.8 7 0-1.3-3.5.4-4.1.4-2.6 0 5.6-2 5.4-3ZM3.9 7.8c3.2-4.2 3.7 1.2 6 .1s.2-.2.2-.3c.7-2.7 2.5-7.5-1.5-1.3-1.6 0 1.1-4 1-4.6C8.9-1 7.3 4.4 7.2 4.9c-1.6.7-.9-1.4-.7-1.5 3-6-.6-3.1-.9.4-2.5 1.8 0-2.8 0-3.5C2.8-.9 4 9.4 1.1 4.9S.1 4.6 0 5c-.4 2.7 2.6 7.2 3.9 2.8Z"/></g>`,
|
|
32
|
-
signLanguageOn: `<g transform="scale(1.5)"><path d="M16 11.3c-.1-.9-4.8 1.3-5.4 1.1-2.6-1 5.8-1.3 5.1-2.9s-5.1 1.5-6 1.4C6.5 9.4 16.5 9.1 13.5 8c-1.9-.6-8.8 2.9-6.8.4.7-.6.7-1.9-.7-1.7-9.7 7.2-.7 12.2 8.8 7 0-1.3-3.5.4-4.1.4-2.6 0 5.6-2 5.4-3ZM3.9 7.8c3.2-4.2 3.7 1.2 6 .1s.2-.2.2-.3c.7-2.7 2.5-7.5-1.5-1.3-1.6 0 1.1-4 1-4.6C8.9-1 7.3 4.4 7.2 4.9c-1.6.7-.9-1.4-.7-1.5 3-6-.6-3.1-.9.4-2.5 1.8 0-2.8 0-3.5C2.8-.9 4 9.4 1.1 4.9S.1 4.6 0 5c-.4 2.7 2.6 7.2 3.9 2.8Z"/></g>`,
|
|
33
|
-
signLanguagePip: `<g transform="scale(1.2) translate(1, 1)"><path d="M16 11.3c-.1-.9-4.8 1.3-5.4 1.1-2.6-1 5.8-1.3 5.1-2.9s-5.1 1.5-6 1.4C6.5 9.4 16.5 9.1 13.5 8c-1.9-.6-8.8 2.9-6.8.4.7-.6.7-1.9-.7-1.7-9.7 7.2-.7 12.2 8.8 7 0-1.3-3.5.4-4.1.4-2.6 0 5.6-2 5.4-3ZM3.9 7.8c3.2-4.2 3.7 1.2 6 .1s.2-.2.2-.3c.7-2.7 2.5-7.5-1.5-1.3-1.6 0 1.1-4 1-4.6C8.9-1 7.3 4.4 7.2 4.9c-1.6.7-.9-1.4-.7-1.5 3-6-.6-3.1-.9.4-2.5 1.8 0-2.8 0-3.5C2.8-.9 4 9.4 1.1 4.9S.1 4.6 0 5c-.4 2.7 2.6 7.2 3.9 2.8Z"/></g><polygon points="14,23 23,14 23,23" fill="currentColor"/>`,
|
|
34
|
-
signLanguagePipOn: `<g transform="scale(1.2) translate(1, 1)"><path d="M16 11.3c-.1-.9-4.8 1.3-5.4 1.1-2.6-1 5.8-1.3 5.1-2.9s-5.1 1.5-6 1.4C6.5 9.4 16.5 9.1 13.5 8c-1.9-.6-8.8 2.9-6.8.4.7-.6.7-1.9-.7-1.7-9.7 7.2-.7 12.2 8.8 7 0-1.3-3.5.4-4.1.4-2.6 0 5.6-2 5.4-3ZM3.9 7.8c3.2-4.2 3.7 1.2 6 .1s.2-.2.2-.3c.7-2.7 2.5-7.5-1.5-1.3-1.6 0 1.1-4 1-4.6C8.9-1 7.3 4.4 7.2 4.9c-1.6.7-.9-1.4-.7-1.5 3-6-.6-3.1-.9.4-2.5 1.8 0-2.8 0-3.5C2.8-.9 4 9.4 1.1 4.9S.1 4.6 0 5c-.4 2.7 2.6 7.2 3.9 2.8Z"/></g><polygon points="14,23 23,14 23,23" fill="currentColor"/>`,
|
|
35
|
-
music: `<path d="M12 3v9.28c-.47-.17-.97-.28-1.5-.28C8.01 12 6 14.01 6 16.5S8.01 21 10.5 21c2.31 0 4.2-1.75 4.45-4H15V6h4V3h-7zm-1.5 16c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/>`,
|
|
36
|
-
moreVertical: `<path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/>`,
|
|
37
|
-
move: `<path d="M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z"/>`,
|
|
38
|
-
resize: `<path d="M21.71 11.29l-9-9c-.39-.39-1.02-.39-1.41 0l-9 9c-.39.39-.39 1.02 0 1.41l9 9c.39.39 1.02.39 1.41 0l9-9c.39-.38.39-1.01 0-1.41zM14 14.5V12h-4v2.5L7 11l3-3.5V10h4V7.5l3 3.5-3 3.5z"/>`,
|
|
39
|
-
clock: `<path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/><path d="M12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z"/>`,
|
|
40
|
-
download: `<path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/>`
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// The `xmlns` declaration is mandatory for `DOMParser.parseFromString`
|
|
44
|
-
// with `image/svg+xml`: without it, XML parsing leaves the child
|
|
45
|
-
// elements (`<path>`, `<rect>`, `<g>`, `<text>`, `<polygon>`) in the
|
|
46
|
-
// null namespace, so the browser can't render them as SVG shapes.
|
|
47
|
-
// The old `innerHTML`-based path worked by accident because the HTML
|
|
48
|
-
// parser treats `<svg>` as a special token and places its descendants
|
|
49
|
-
// in the SVG namespace automatically.
|
|
50
|
-
const svgWrapper = (paths: string) =>
|
|
51
|
-
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">${paths}</svg>`;
|
|
52
|
-
|
|
53
|
-
export const Icons: Record<string, string> = Object.fromEntries(
|
|
54
|
-
Object.entries(iconPaths).map(([key, value]) => [key, svgWrapper(value)])
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
export function getIcon(name: string): string {
|
|
58
|
-
return Icons[name] || Icons.play || '';
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Parse every icon once at module load into an SVG template element and
|
|
63
|
-
* clone it per call. This replaces the previous `wrapper.innerHTML = …`
|
|
64
|
-
* approach: `innerHTML` is disallowed by strict CSP (`require-trusted-types-for`)
|
|
65
|
-
* and is slower because the browser has to re-tokenise the same string on
|
|
66
|
-
* every icon render.
|
|
67
|
-
*
|
|
68
|
-
* The icon SVG strings are trusted constants defined in this module, so
|
|
69
|
-
* parsing via `DOMParser` is safe.
|
|
70
|
-
*/
|
|
71
|
-
const iconTemplates: Record<string, SVGSVGElement> = (() => {
|
|
72
|
-
const parser = new DOMParser();
|
|
73
|
-
const templates: Record<string, SVGSVGElement> = {};
|
|
74
|
-
for (const [key, paths] of Object.entries(iconPaths)) {
|
|
75
|
-
const doc = parser.parseFromString(svgWrapper(paths), 'image/svg+xml');
|
|
76
|
-
const root = doc.documentElement;
|
|
77
|
-
// A parse failure produces a `<parsererror>` element as the
|
|
78
|
-
// document root; reject that and skip the entry rather than
|
|
79
|
-
// storing a broken template that would render as nothing.
|
|
80
|
-
if (
|
|
81
|
-
root &&
|
|
82
|
-
root.nodeName.toLowerCase() === 'svg' &&
|
|
83
|
-
!root.querySelector('parsererror')
|
|
84
|
-
) {
|
|
85
|
-
templates[key] = root as unknown as SVGSVGElement;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return templates;
|
|
89
|
-
})();
|
|
90
|
-
|
|
91
|
-
export function createIconElement(name: string, className = ''): HTMLElement {
|
|
92
|
-
const wrapper = document.createElement('span');
|
|
93
|
-
wrapper.className = `vidply-icon ${className}`.trim();
|
|
94
|
-
wrapper.setAttribute('aria-hidden', 'true');
|
|
95
|
-
|
|
96
|
-
const template = iconTemplates[name] || iconTemplates.play;
|
|
97
|
-
if (template) {
|
|
98
|
-
wrapper.appendChild(template.cloneNode(true));
|
|
99
|
-
}
|
|
100
|
-
return wrapper;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export function createPlayOverlay(): SVGSVGElement {
|
|
104
|
-
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
105
|
-
svg.setAttribute('class', 'vidply-play-overlay');
|
|
106
|
-
svg.setAttribute('viewBox', '0 0 80 80');
|
|
107
|
-
svg.setAttribute('width', '80');
|
|
108
|
-
svg.setAttribute('height', '80');
|
|
109
|
-
svg.setAttribute('aria-hidden', 'true');
|
|
110
|
-
svg.setAttribute('role', 'presentation');
|
|
111
|
-
svg.style.cursor = 'pointer';
|
|
112
|
-
|
|
113
|
-
const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
|
|
114
|
-
const filterId = `vidply-play-shadow-${Math.random().toString(36).slice(2, 11)}`;
|
|
115
|
-
const filter = document.createElementNS('http://www.w3.org/2000/svg', 'filter');
|
|
116
|
-
filter.setAttribute('id', filterId);
|
|
117
|
-
filter.setAttribute('x', '-50%');
|
|
118
|
-
filter.setAttribute('y', '-50%');
|
|
119
|
-
filter.setAttribute('width', '200%');
|
|
120
|
-
filter.setAttribute('height', '200%');
|
|
121
|
-
|
|
122
|
-
const feGaussianBlur = document.createElementNS('http://www.w3.org/2000/svg', 'feGaussianBlur');
|
|
123
|
-
feGaussianBlur.setAttribute('in', 'SourceAlpha');
|
|
124
|
-
feGaussianBlur.setAttribute('stdDeviation', '3');
|
|
125
|
-
|
|
126
|
-
const feOffset = document.createElementNS('http://www.w3.org/2000/svg', 'feOffset');
|
|
127
|
-
feOffset.setAttribute('dx', '0');
|
|
128
|
-
feOffset.setAttribute('dy', '2');
|
|
129
|
-
feOffset.setAttribute('result', 'offsetblur');
|
|
130
|
-
|
|
131
|
-
const feComponentTransfer = document.createElementNS('http://www.w3.org/2000/svg', 'feComponentTransfer');
|
|
132
|
-
const feFuncA = document.createElementNS('http://www.w3.org/2000/svg', 'feFuncA');
|
|
133
|
-
feFuncA.setAttribute('type', 'linear');
|
|
134
|
-
feFuncA.setAttribute('slope', '0.3');
|
|
135
|
-
feComponentTransfer.appendChild(feFuncA);
|
|
136
|
-
|
|
137
|
-
const feMerge = document.createElementNS('http://www.w3.org/2000/svg', 'feMerge');
|
|
138
|
-
const feMergeNode1 = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');
|
|
139
|
-
const feMergeNode2 = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');
|
|
140
|
-
feMergeNode2.setAttribute('in', 'SourceGraphic');
|
|
141
|
-
feMerge.appendChild(feMergeNode1);
|
|
142
|
-
feMerge.appendChild(feMergeNode2);
|
|
143
|
-
|
|
144
|
-
filter.appendChild(feGaussianBlur);
|
|
145
|
-
filter.appendChild(feOffset);
|
|
146
|
-
filter.appendChild(feComponentTransfer);
|
|
147
|
-
filter.appendChild(feMerge);
|
|
148
|
-
defs.appendChild(filter);
|
|
149
|
-
svg.appendChild(defs);
|
|
150
|
-
|
|
151
|
-
const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
|
|
152
|
-
circle.setAttribute('cx', '40');
|
|
153
|
-
circle.setAttribute('cy', '40');
|
|
154
|
-
circle.setAttribute('r', '40');
|
|
155
|
-
circle.setAttribute('fill', 'rgba(255, 255, 255, 0.95)');
|
|
156
|
-
circle.setAttribute('filter', `url(#${filterId})`);
|
|
157
|
-
circle.setAttribute('class', 'vidply-play-overlay-bg');
|
|
158
|
-
svg.appendChild(circle);
|
|
159
|
-
|
|
160
|
-
const playTriangle = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
|
|
161
|
-
playTriangle.setAttribute('points', '32,28 32,52 54,40');
|
|
162
|
-
playTriangle.setAttribute('fill', '#0a406e');
|
|
163
|
-
playTriangle.setAttribute('class', 'vidply-play-overlay-icon');
|
|
164
|
-
svg.appendChild(playTriangle);
|
|
165
|
-
|
|
166
|
-
return svg;
|
|
167
|
-
}
|
|
1
|
+
const iconPaths: Record<string, string> = {
|
|
2
|
+
play: `<path d="M8 5v14l11-7z"/>`,
|
|
3
|
+
pause: `<path d="M6 4h4v16H6V4zm8 0h4v16h-4V4z"/>`,
|
|
4
|
+
stop: `<rect x="6" y="6" width="12" height="12"/>`,
|
|
5
|
+
rewind: `<path d="M11 18V6l-8.5 6 8.5 6zm.5-6l8.5 6V6l-8.5 6z"/>`,
|
|
6
|
+
forward: `<path d="M4 18l8.5-6L4 6v12zm9-12v12l8.5-6L13 6z"/>`,
|
|
7
|
+
skipPrevious: `<path d="M6 6h2v12H6V6zm3 6l8.5 6V6L9 12z"/>`,
|
|
8
|
+
skipNext: `<path d="M16 6h2v12h-2V6zM6 6l8.5 6L6 18V6z"/>`,
|
|
9
|
+
restart: `<path d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z"/>`,
|
|
10
|
+
volumeHigh: `<path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/>`,
|
|
11
|
+
volumeMedium: `<path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/>`,
|
|
12
|
+
volumeLow: `<path d="M7 9v6h4l5 5V4l-5 5H7z"/>`,
|
|
13
|
+
volumeMuted: `<path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/>`,
|
|
14
|
+
fullscreen: `<path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/>`,
|
|
15
|
+
fullscreenExit: `<path d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"/>`,
|
|
16
|
+
settings: `<path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94L14.4 2.81c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/>`,
|
|
17
|
+
captions: `<path d="M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1c0 .55-.45 1-1 1h-3c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1z"/>`,
|
|
18
|
+
captionsOff: `<path d="M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1c0 .55-.45 1-1 1h-3c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1z"/><path d="M0 0h24v24H0z" fill="none"/>`,
|
|
19
|
+
pip: `<path d="M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98V5c0-1.1-.9-2-2-2zm0 16.01H3V4.98h18v14.03z"/>`,
|
|
20
|
+
speed: `<path d="M20.38 8.57l-1.23 1.85a8 8 0 0 1-.22 7.58H5.07A8 8 0 0 1 15.58 6.85l1.85-1.23A10 10 0 0 0 3.35 19a2 2 0 0 0 1.72 1h13.85a2 2 0 0 0 1.74-1 10 10 0 0 0-.27-10.44z"/><path d="M10.59 15.41a2 2 0 0 0 2.83 0l5.66-8.49-8.49 5.66a2 2 0 0 0 0 2.83z"/>`,
|
|
21
|
+
close: `<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>`,
|
|
22
|
+
check: `<path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>`,
|
|
23
|
+
loading: `<path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"/>`,
|
|
24
|
+
error: `<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>`,
|
|
25
|
+
playlist: `<path d="M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18c-.31-.11-.65-.18-1-.18-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z"/>`,
|
|
26
|
+
hd: `<path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-8 12H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm7-1c0 .55-.45 1-1 1h-.75v1.5h-1.5V15H14c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v4zm-3.5-.5h2v-3h-2v3z"/>`,
|
|
27
|
+
transcript: `<path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z"/>`,
|
|
28
|
+
chapters: `<path d="M3 5h2v2H3V5zm0 4h2v2H3V9zm0 4h2v2H3v-2zm0 4h2v2H3v-2zM7 5h14v2H7V5zm0 4h14v2H7V9zm0 4h14v2H7v-2zm0 4h14v2H7v-2z"/>`,
|
|
29
|
+
audioDescription: `<rect x="2" y="5" width="20" height="14" rx="2" fill="none" stroke="currentColor" stroke-width="1.5"/><text x="12" y="14.5" text-anchor="middle" font-size="8" font-weight="bold" font-family="Arial, sans-serif" fill="currentColor">AD</text>`,
|
|
30
|
+
audioDescriptionOn: `<rect x="2" y="5" width="20" height="14" rx="2" fill="currentColor"/><text x="12" y="14.5" text-anchor="middle" font-size="8" font-weight="bold" font-family="Arial, sans-serif" class="vidply-icon-ad-fg">AD</text>`,
|
|
31
|
+
signLanguage: `<g transform="scale(1.5)"><path d="M16 11.3c-.1-.9-4.8 1.3-5.4 1.1-2.6-1 5.8-1.3 5.1-2.9s-5.1 1.5-6 1.4C6.5 9.4 16.5 9.1 13.5 8c-1.9-.6-8.8 2.9-6.8.4.7-.6.7-1.9-.7-1.7-9.7 7.2-.7 12.2 8.8 7 0-1.3-3.5.4-4.1.4-2.6 0 5.6-2 5.4-3ZM3.9 7.8c3.2-4.2 3.7 1.2 6 .1s.2-.2.2-.3c.7-2.7 2.5-7.5-1.5-1.3-1.6 0 1.1-4 1-4.6C8.9-1 7.3 4.4 7.2 4.9c-1.6.7-.9-1.4-.7-1.5 3-6-.6-3.1-.9.4-2.5 1.8 0-2.8 0-3.5C2.8-.9 4 9.4 1.1 4.9S.1 4.6 0 5c-.4 2.7 2.6 7.2 3.9 2.8Z"/></g>`,
|
|
32
|
+
signLanguageOn: `<g transform="scale(1.5)"><path d="M16 11.3c-.1-.9-4.8 1.3-5.4 1.1-2.6-1 5.8-1.3 5.1-2.9s-5.1 1.5-6 1.4C6.5 9.4 16.5 9.1 13.5 8c-1.9-.6-8.8 2.9-6.8.4.7-.6.7-1.9-.7-1.7-9.7 7.2-.7 12.2 8.8 7 0-1.3-3.5.4-4.1.4-2.6 0 5.6-2 5.4-3ZM3.9 7.8c3.2-4.2 3.7 1.2 6 .1s.2-.2.2-.3c.7-2.7 2.5-7.5-1.5-1.3-1.6 0 1.1-4 1-4.6C8.9-1 7.3 4.4 7.2 4.9c-1.6.7-.9-1.4-.7-1.5 3-6-.6-3.1-.9.4-2.5 1.8 0-2.8 0-3.5C2.8-.9 4 9.4 1.1 4.9S.1 4.6 0 5c-.4 2.7 2.6 7.2 3.9 2.8Z"/></g>`,
|
|
33
|
+
signLanguagePip: `<g transform="scale(1.2) translate(1, 1)"><path d="M16 11.3c-.1-.9-4.8 1.3-5.4 1.1-2.6-1 5.8-1.3 5.1-2.9s-5.1 1.5-6 1.4C6.5 9.4 16.5 9.1 13.5 8c-1.9-.6-8.8 2.9-6.8.4.7-.6.7-1.9-.7-1.7-9.7 7.2-.7 12.2 8.8 7 0-1.3-3.5.4-4.1.4-2.6 0 5.6-2 5.4-3ZM3.9 7.8c3.2-4.2 3.7 1.2 6 .1s.2-.2.2-.3c.7-2.7 2.5-7.5-1.5-1.3-1.6 0 1.1-4 1-4.6C8.9-1 7.3 4.4 7.2 4.9c-1.6.7-.9-1.4-.7-1.5 3-6-.6-3.1-.9.4-2.5 1.8 0-2.8 0-3.5C2.8-.9 4 9.4 1.1 4.9S.1 4.6 0 5c-.4 2.7 2.6 7.2 3.9 2.8Z"/></g><polygon points="14,23 23,14 23,23" fill="currentColor"/>`,
|
|
34
|
+
signLanguagePipOn: `<g transform="scale(1.2) translate(1, 1)"><path d="M16 11.3c-.1-.9-4.8 1.3-5.4 1.1-2.6-1 5.8-1.3 5.1-2.9s-5.1 1.5-6 1.4C6.5 9.4 16.5 9.1 13.5 8c-1.9-.6-8.8 2.9-6.8.4.7-.6.7-1.9-.7-1.7-9.7 7.2-.7 12.2 8.8 7 0-1.3-3.5.4-4.1.4-2.6 0 5.6-2 5.4-3ZM3.9 7.8c3.2-4.2 3.7 1.2 6 .1s.2-.2.2-.3c.7-2.7 2.5-7.5-1.5-1.3-1.6 0 1.1-4 1-4.6C8.9-1 7.3 4.4 7.2 4.9c-1.6.7-.9-1.4-.7-1.5 3-6-.6-3.1-.9.4-2.5 1.8 0-2.8 0-3.5C2.8-.9 4 9.4 1.1 4.9S.1 4.6 0 5c-.4 2.7 2.6 7.2 3.9 2.8Z"/></g><polygon points="14,23 23,14 23,23" fill="currentColor"/>`,
|
|
35
|
+
music: `<path d="M12 3v9.28c-.47-.17-.97-.28-1.5-.28C8.01 12 6 14.01 6 16.5S8.01 21 10.5 21c2.31 0 4.2-1.75 4.45-4H15V6h4V3h-7zm-1.5 16c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/>`,
|
|
36
|
+
moreVertical: `<path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/>`,
|
|
37
|
+
move: `<path d="M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z"/>`,
|
|
38
|
+
resize: `<path d="M21.71 11.29l-9-9c-.39-.39-1.02-.39-1.41 0l-9 9c-.39.39-.39 1.02 0 1.41l9 9c.39.39 1.02.39 1.41 0l9-9c.39-.38.39-1.01 0-1.41zM14 14.5V12h-4v2.5L7 11l3-3.5V10h4V7.5l3 3.5-3 3.5z"/>`,
|
|
39
|
+
clock: `<path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/><path d="M12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z"/>`,
|
|
40
|
+
download: `<path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/>`
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// The `xmlns` declaration is mandatory for `DOMParser.parseFromString`
|
|
44
|
+
// with `image/svg+xml`: without it, XML parsing leaves the child
|
|
45
|
+
// elements (`<path>`, `<rect>`, `<g>`, `<text>`, `<polygon>`) in the
|
|
46
|
+
// null namespace, so the browser can't render them as SVG shapes.
|
|
47
|
+
// The old `innerHTML`-based path worked by accident because the HTML
|
|
48
|
+
// parser treats `<svg>` as a special token and places its descendants
|
|
49
|
+
// in the SVG namespace automatically.
|
|
50
|
+
const svgWrapper = (paths: string) =>
|
|
51
|
+
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">${paths}</svg>`;
|
|
52
|
+
|
|
53
|
+
export const Icons: Record<string, string> = Object.fromEntries(
|
|
54
|
+
Object.entries(iconPaths).map(([key, value]) => [key, svgWrapper(value)])
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
export function getIcon(name: string): string {
|
|
58
|
+
return Icons[name] || Icons.play || '';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Parse every icon once at module load into an SVG template element and
|
|
63
|
+
* clone it per call. This replaces the previous `wrapper.innerHTML = …`
|
|
64
|
+
* approach: `innerHTML` is disallowed by strict CSP (`require-trusted-types-for`)
|
|
65
|
+
* and is slower because the browser has to re-tokenise the same string on
|
|
66
|
+
* every icon render.
|
|
67
|
+
*
|
|
68
|
+
* The icon SVG strings are trusted constants defined in this module, so
|
|
69
|
+
* parsing via `DOMParser` is safe.
|
|
70
|
+
*/
|
|
71
|
+
const iconTemplates: Record<string, SVGSVGElement> = (() => {
|
|
72
|
+
const parser = new DOMParser();
|
|
73
|
+
const templates: Record<string, SVGSVGElement> = {};
|
|
74
|
+
for (const [key, paths] of Object.entries(iconPaths)) {
|
|
75
|
+
const doc = parser.parseFromString(svgWrapper(paths), 'image/svg+xml');
|
|
76
|
+
const root = doc.documentElement;
|
|
77
|
+
// A parse failure produces a `<parsererror>` element as the
|
|
78
|
+
// document root; reject that and skip the entry rather than
|
|
79
|
+
// storing a broken template that would render as nothing.
|
|
80
|
+
if (
|
|
81
|
+
root &&
|
|
82
|
+
root.nodeName.toLowerCase() === 'svg' &&
|
|
83
|
+
!root.querySelector('parsererror')
|
|
84
|
+
) {
|
|
85
|
+
templates[key] = root as unknown as SVGSVGElement;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return templates;
|
|
89
|
+
})();
|
|
90
|
+
|
|
91
|
+
export function createIconElement(name: string, className = ''): HTMLElement {
|
|
92
|
+
const wrapper = document.createElement('span');
|
|
93
|
+
wrapper.className = `vidply-icon ${className}`.trim();
|
|
94
|
+
wrapper.setAttribute('aria-hidden', 'true');
|
|
95
|
+
|
|
96
|
+
const template = iconTemplates[name] || iconTemplates.play;
|
|
97
|
+
if (template) {
|
|
98
|
+
wrapper.appendChild(template.cloneNode(true));
|
|
99
|
+
}
|
|
100
|
+
return wrapper;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function createPlayOverlay(): SVGSVGElement {
|
|
104
|
+
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
105
|
+
svg.setAttribute('class', 'vidply-play-overlay');
|
|
106
|
+
svg.setAttribute('viewBox', '0 0 80 80');
|
|
107
|
+
svg.setAttribute('width', '80');
|
|
108
|
+
svg.setAttribute('height', '80');
|
|
109
|
+
svg.setAttribute('aria-hidden', 'true');
|
|
110
|
+
svg.setAttribute('role', 'presentation');
|
|
111
|
+
svg.style.cursor = 'pointer';
|
|
112
|
+
|
|
113
|
+
const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
|
|
114
|
+
const filterId = `vidply-play-shadow-${Math.random().toString(36).slice(2, 11)}`;
|
|
115
|
+
const filter = document.createElementNS('http://www.w3.org/2000/svg', 'filter');
|
|
116
|
+
filter.setAttribute('id', filterId);
|
|
117
|
+
filter.setAttribute('x', '-50%');
|
|
118
|
+
filter.setAttribute('y', '-50%');
|
|
119
|
+
filter.setAttribute('width', '200%');
|
|
120
|
+
filter.setAttribute('height', '200%');
|
|
121
|
+
|
|
122
|
+
const feGaussianBlur = document.createElementNS('http://www.w3.org/2000/svg', 'feGaussianBlur');
|
|
123
|
+
feGaussianBlur.setAttribute('in', 'SourceAlpha');
|
|
124
|
+
feGaussianBlur.setAttribute('stdDeviation', '3');
|
|
125
|
+
|
|
126
|
+
const feOffset = document.createElementNS('http://www.w3.org/2000/svg', 'feOffset');
|
|
127
|
+
feOffset.setAttribute('dx', '0');
|
|
128
|
+
feOffset.setAttribute('dy', '2');
|
|
129
|
+
feOffset.setAttribute('result', 'offsetblur');
|
|
130
|
+
|
|
131
|
+
const feComponentTransfer = document.createElementNS('http://www.w3.org/2000/svg', 'feComponentTransfer');
|
|
132
|
+
const feFuncA = document.createElementNS('http://www.w3.org/2000/svg', 'feFuncA');
|
|
133
|
+
feFuncA.setAttribute('type', 'linear');
|
|
134
|
+
feFuncA.setAttribute('slope', '0.3');
|
|
135
|
+
feComponentTransfer.appendChild(feFuncA);
|
|
136
|
+
|
|
137
|
+
const feMerge = document.createElementNS('http://www.w3.org/2000/svg', 'feMerge');
|
|
138
|
+
const feMergeNode1 = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');
|
|
139
|
+
const feMergeNode2 = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');
|
|
140
|
+
feMergeNode2.setAttribute('in', 'SourceGraphic');
|
|
141
|
+
feMerge.appendChild(feMergeNode1);
|
|
142
|
+
feMerge.appendChild(feMergeNode2);
|
|
143
|
+
|
|
144
|
+
filter.appendChild(feGaussianBlur);
|
|
145
|
+
filter.appendChild(feOffset);
|
|
146
|
+
filter.appendChild(feComponentTransfer);
|
|
147
|
+
filter.appendChild(feMerge);
|
|
148
|
+
defs.appendChild(filter);
|
|
149
|
+
svg.appendChild(defs);
|
|
150
|
+
|
|
151
|
+
const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
|
|
152
|
+
circle.setAttribute('cx', '40');
|
|
153
|
+
circle.setAttribute('cy', '40');
|
|
154
|
+
circle.setAttribute('r', '40');
|
|
155
|
+
circle.setAttribute('fill', 'rgba(255, 255, 255, 0.95)');
|
|
156
|
+
circle.setAttribute('filter', `url(#${filterId})`);
|
|
157
|
+
circle.setAttribute('class', 'vidply-play-overlay-bg');
|
|
158
|
+
svg.appendChild(circle);
|
|
159
|
+
|
|
160
|
+
const playTriangle = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
|
|
161
|
+
playTriangle.setAttribute('points', '32,28 32,52 54,40');
|
|
162
|
+
playTriangle.setAttribute('fill', '#0a406e');
|
|
163
|
+
playTriangle.setAttribute('class', 'vidply-play-overlay-icon');
|
|
164
|
+
svg.appendChild(playTriangle);
|
|
165
|
+
|
|
166
|
+
return svg;
|
|
167
|
+
}
|