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
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/FormUtils.ts", "../../src/utils/MenuUtils.ts", "../../src/utils/DraggablePanelMenu.ts", "../../src/utils/DraggablePanel.ts"],
|
|
4
|
+
"sourcesContent": ["import { DOMUtils } from './DOMUtils.js';\nimport { i18n } from '../i18n/i18n.js';\n\nexport interface SelectOption {\n value: string;\n text: string;\n selected?: boolean;\n}\n\nexport interface LabeledSelectOptions {\n classPrefix: string;\n labelClass: string;\n selectClass: string;\n labelText: string;\n selectId: string;\n hidden?: boolean;\n onChange?: (e: Event) => void;\n options?: SelectOption[];\n}\n\nexport function createLabeledSelect({\n classPrefix: _classPrefix,\n labelClass,\n selectClass,\n labelText,\n selectId,\n hidden = false,\n onChange = undefined,\n options = []\n}: LabeledSelectOptions): { label: HTMLLabelElement; select: HTMLSelectElement } {\n const isI18nKey =\n typeof labelText === 'string' &&\n (labelText.startsWith('transcript.') ||\n labelText.startsWith('player.') ||\n labelText.startsWith('settings.') ||\n labelText.startsWith('captions.'));\n const labelTextContent = isI18nKey ? i18n.t(labelText) || labelText : labelText;\n\n const label = DOMUtils.createElement('label', {\n className: labelClass,\n textContent: labelTextContent,\n attributes: {\n for: selectId,\n style: hidden ? 'display: none;' : undefined\n }\n });\n\n const select = DOMUtils.createElement('select', {\n className: selectClass,\n attributes: {\n id: selectId,\n style: hidden ? 'display: none;' : undefined\n }\n });\n\n options.forEach(opt => {\n const option = DOMUtils.createElement('option', {\n textContent: opt.text,\n attributes: {\n value: opt.value,\n selected: opt.selected ? 'selected' : undefined\n }\n });\n select.appendChild(option);\n });\n\n if (onChange) {\n select.addEventListener('change', onChange);\n }\n\n return { label, select };\n}\n\nexport function toggleLabeledSelect(\n label: HTMLElement | null,\n select: HTMLElement | null,\n show: boolean\n): void {\n if (label) {\n label.style.display = show ? 'block' : 'none';\n }\n if (select) {\n select.style.display = show ? 'block' : 'none';\n }\n}\n\nexport function preventDragOnElement(element: HTMLElement | null): void {\n if (!element) return;\n\n (['pointerdown', 'mousedown', 'click'] as const).forEach(eventType => {\n element.addEventListener(eventType, (e: Event) => {\n e.stopPropagation();\n });\n });\n}\n", "import { DOMUtils } from './DOMUtils.js';\nimport { createIconElement } from '../icons/Icons.js';\nimport { i18n } from '../i18n/i18n.js';\nimport { focusElement } from './FocusUtils.js';\nimport { reducedMotionScrollOptions } from './PerformanceUtils.js';\n\nexport interface MenuItemOptions {\n classPrefix: string;\n itemClass: string;\n icon?: string;\n label: string;\n ariaLabel?: string;\n onClick?: (e: Event) => void;\n hasTextClass?: boolean;\n}\n\nexport function createMenuItem({\n classPrefix,\n itemClass,\n icon,\n label,\n ariaLabel,\n onClick,\n hasTextClass = false\n}: MenuItemOptions): HTMLElement {\n const isI18nKeyForAria =\n typeof label === 'string' &&\n (label.startsWith('transcript.') || label.startsWith('player.') || label.startsWith('settings.'));\n const ariaLabelText = ariaLabel || (isI18nKeyForAria ? i18n.t(label) || label : label);\n\n const button = DOMUtils.createElement('button', {\n className: itemClass,\n attributes: {\n type: 'button',\n 'aria-label': ariaLabelText,\n tabindex: '-1'\n }\n });\n\n if (icon) {\n button.appendChild(createIconElement(icon));\n }\n\n const isI18nKey =\n typeof label === 'string' &&\n (label.startsWith('transcript.') || label.startsWith('player.') || label.startsWith('settings.'));\n const textContent = isI18nKey ? i18n.t(label) || label : label;\n\n const text = DOMUtils.createElement('span', {\n textContent,\n className: hasTextClass ? `${classPrefix}-settings-text` : undefined,\n attributes: { 'aria-hidden': 'true' }\n });\n button.appendChild(text);\n\n if (onClick) {\n button.addEventListener('click', onClick);\n }\n\n return button;\n}\n\nexport function attachMenuKeyboardNavigation(\n menu: HTMLElement | null,\n button: HTMLElement | null,\n itemSelector: string,\n onClose?: () => void\n): ((e: KeyboardEvent) => void) | undefined {\n if (!menu) return undefined;\n\n // Only enabled items participate in roving navigation. aria-disabled\n // empty-state entries must never receive focus (WCAG 2.1.1, 4.1.2).\n const menuItems = Array.from(menu.querySelectorAll<HTMLElement>(itemSelector))\n .filter((item) => item.getAttribute('aria-disabled') !== 'true');\n if (menuItems.length === 0) return undefined;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n const currentIndex = menuItems.indexOf(document.activeElement as HTMLElement);\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault();\n e.stopPropagation();\n const nextIndex = (currentIndex + 1) % menuItems.length;\n menuItems.forEach((item, idx) => {\n item.setAttribute('tabindex', idx === nextIndex ? '0' : '-1');\n });\n const next = menuItems[nextIndex];\n if (next) {\n next.focus({ preventScroll: false });\n next.scrollIntoView(reducedMotionScrollOptions('nearest'));\n }\n break;\n }\n\n case 'ArrowUp': {\n e.preventDefault();\n e.stopPropagation();\n const prevIndex = (currentIndex - 1 + menuItems.length) % menuItems.length;\n menuItems.forEach((item, idx) => {\n item.setAttribute('tabindex', idx === prevIndex ? '0' : '-1');\n });\n const prev = menuItems[prevIndex];\n if (prev) {\n prev.focus({ preventScroll: false });\n prev.scrollIntoView(reducedMotionScrollOptions('nearest'));\n }\n break;\n }\n\n case 'Home': {\n e.preventDefault();\n e.stopPropagation();\n menuItems.forEach((item, idx) => {\n item.setAttribute('tabindex', idx === 0 ? '0' : '-1');\n });\n const firstItem = menuItems[0];\n if (firstItem) {\n firstItem.focus({ preventScroll: false });\n firstItem.scrollIntoView(reducedMotionScrollOptions('nearest'));\n }\n break;\n }\n\n case 'End': {\n e.preventDefault();\n e.stopPropagation();\n const lastIndex = menuItems.length - 1;\n menuItems.forEach((item, idx) => {\n item.setAttribute('tabindex', idx === lastIndex ? '0' : '-1');\n });\n const lastItem = menuItems[lastIndex];\n if (lastItem) {\n lastItem.focus({ preventScroll: false });\n lastItem.scrollIntoView(reducedMotionScrollOptions('nearest'));\n }\n break;\n }\n\n case 'Enter':\n case ' ': {\n e.preventDefault();\n e.stopPropagation();\n if (document.activeElement && menuItems.includes(document.activeElement as HTMLElement)) {\n (document.activeElement as HTMLElement).click();\n if (onClose) {\n setTimeout(() => {\n if (button && document.contains(button)) {\n button.focus();\n }\n }, 0);\n }\n }\n break;\n }\n\n case 'Escape':\n e.preventDefault();\n e.stopPropagation();\n if (onClose) {\n onClose();\n }\n break;\n }\n };\n\n menu.addEventListener('keydown', handleKeyDown as EventListener, true);\n return handleKeyDown;\n}\n\nexport function focusFirstMenuItem(\n menu: HTMLElement | null,\n itemSelector: string,\n delay = 0\n): void {\n if (!menu) return;\n\n setTimeout(() => {\n const menuItems = Array.from(menu.querySelectorAll<HTMLElement>(itemSelector))\n .filter((item) => item.getAttribute('aria-disabled') !== 'true');\n const firstItem = menuItems[0];\n if (firstItem) {\n menuItems.forEach((item, index) => {\n item.setAttribute('tabindex', index === 0 ? '0' : '-1');\n });\n focusElement(firstItem, { delay: 0 });\n firstItem.scrollIntoView(reducedMotionScrollOptions('nearest'));\n }\n }, delay);\n}\n", "/**\n * Shared helpers for the settings-menu items that toggle drag / resize\n * mode on a `DraggableResizable`-powered panel.\n *\n * Previously `SignLanguageManager` and `TranscriptManager` both carried\n * near-identical copies of:\n * - `updateDragOptionState` / `updateResizeOptionState`\n * (button `aria-checked` + label + i18n-driven text sync)\n * - `positionSettingsMenuImmediate`\n * (place the menu relative to the settings button, with above/below\n * flipping and viewport-edge clamping)\n *\n * This module owns those pieces so a future manager (or a refactor of\n * an existing one) doesn't have to re-derive the rules from scratch.\n *\n * NOTE: the full \"DraggablePanel\" abstraction that also owns the menu\n * *contents* (language selector, style dialog, pinned state, etc.) is\n * deliberately NOT attempted here — the per-manager specifics are\n * significant and an attempt to unify them would churn security-\n * sensitive code without meaningfully reducing LOC.\n */\n\n/** Visual state of a two-state (\"currently enabled / currently disabled\")\n * toggle menu item. */\nexport interface ToggleMenuItemState {\n /** Whether the underlying mode is currently active. */\n enabled: boolean;\n /** Label shown when the mode is active (i.e. the label invites the\n * user to disable it). */\n enabledText: string;\n /** Label shown when the mode is inactive. */\n disabledText: string;\n /** `aria-label` for screen readers when the mode is active. */\n enabledAria: string;\n /** `aria-label` for screen readers when the mode is inactive. */\n disabledAria: string;\n}\n\n/**\n * Sync a settings-menu toggle button's `aria-checked`, `aria-label`,\n * and visible text node with the current mode state. Both properties\n * are updated unconditionally so the element stays in sync even if a\n * previous render left them stale.\n *\n * The caller owns the DOM nodes; this helper only mutates known-safe\n * properties (no innerHTML), so a translated label with angle brackets\n * or ampersands is stored as text, not parsed as markup.\n */\nexport function updateToggleMenuItem(\n button: HTMLElement | null | undefined,\n textElement: Element | null | undefined,\n state: ToggleMenuItemState\n): void {\n if (!button) return;\n\n button.setAttribute('aria-checked', state.enabled ? 'true' : 'false');\n button.setAttribute('aria-label', state.enabled ? state.enabledAria : state.disabledAria);\n\n if (textElement) {\n // `textContent` exists on `Node`, so we can accept the broader\n // `Element` type here and let callers pass either an `HTMLElement`\n // (TranscriptManager keeps the tighter type for the sake of its\n // `.style` access elsewhere) or a plain `Element` returned by\n // `querySelector`.\n textElement.textContent = state.enabled ? state.enabledText : state.disabledText;\n }\n}\n\nexport interface PositionSettingsMenuOptions {\n /**\n * Horizontal anchoring:\n * - `'left'` : align the menu's left edge with the button's left edge\n * (the TranscriptManager convention — simple panels).\n * - `'center'` : centre the menu horizontally on the button, with\n * viewport-edge clamping (the SignLanguageManager\n * convention — small floating panel that can end up\n * near the viewport edges).\n */\n align?: 'left' | 'center';\n /** Vertical gap (px) between button and menu. */\n gap?: number;\n /** Extra breathing room (px) before we decide to flip above. */\n spaceReserve?: number;\n}\n\n/**\n * Position a settings menu relative to its button, using offsets that\n * are relative to the button's offset parent (so transforms on ancestor\n * elements don't throw the layout off).\n *\n * When there isn't enough room below the button but there is room\n * above, the menu flips upward and picks up a `vidply-menu-above` CSS\n * class so arrows / drop-shadows can be mirrored via stylesheet.\n */\nexport function positionSettingsMenu(\n menu: HTMLElement | null | undefined,\n button: HTMLElement | null | undefined,\n opts: PositionSettingsMenuOptions = {}\n): void {\n if (!menu || !button) return;\n const { align = 'left', gap = 4, spaceReserve = 20 } = opts;\n\n const parentContainer = button.parentElement;\n if (!parentContainer) return;\n\n const buttonRect = button.getBoundingClientRect();\n const parentRect = parentContainer.getBoundingClientRect();\n const menuRect = menu.getBoundingClientRect();\n const viewportHeight = window.innerHeight;\n const viewportWidth = window.innerWidth;\n\n const buttonBottom = buttonRect.bottom - parentRect.top;\n const buttonTop = buttonRect.top - parentRect.top;\n const buttonLeftOffset = buttonRect.left - parentRect.left;\n const buttonCenterX = buttonLeftOffset + buttonRect.width / 2;\n\n const spaceAbove = buttonRect.top;\n const spaceBelow = viewportHeight - buttonRect.bottom;\n\n // Vertical placement: default below, flip above when tight.\n let menuTop: number | null = buttonBottom + gap;\n let menuBottomPx: number | null = null;\n if (spaceBelow < menuRect.height + spaceReserve && spaceAbove > spaceBelow) {\n if (align === 'center') {\n // Measure from the bottom edge of the parent so the menu sits\n // directly above the button without being pushed off-screen.\n const parentHeight = parentRect.bottom - parentRect.top;\n menuBottomPx = parentHeight - buttonTop + gap;\n menuTop = null;\n } else {\n menuTop = buttonTop - menuRect.height - gap;\n }\n menu.classList.add('vidply-menu-above');\n } else {\n menu.classList.remove('vidply-menu-above');\n }\n\n // Horizontal placement: simple left-align vs viewport-clamped centre.\n let leftValue: string;\n let rightValue: string;\n let transform: string;\n\n if (align === 'center') {\n const menuLeftAbsolute = buttonRect.left + buttonRect.width / 2 - menuRect.width / 2;\n if (menuLeftAbsolute < 10) {\n leftValue = '0';\n rightValue = 'auto';\n transform = 'translateX(0)';\n } else if (menuLeftAbsolute + menuRect.width > viewportWidth - 10) {\n leftValue = 'auto';\n rightValue = '0';\n transform = 'translateX(0)';\n } else {\n leftValue = `${buttonCenterX}px`;\n rightValue = 'auto';\n transform = 'translateX(-50%)';\n }\n } else {\n leftValue = `${buttonLeftOffset}px`;\n rightValue = 'auto';\n transform = 'translateX(0)';\n }\n\n if (menuTop !== null) {\n menu.style.top = `${menuTop}px`;\n menu.style.bottom = 'auto';\n } else if (menuBottomPx !== null) {\n menu.style.top = 'auto';\n menu.style.bottom = `${menuBottomPx}px`;\n }\n\n menu.style.left = leftValue;\n menu.style.right = rightValue;\n menu.style.transform = transform;\n}\n\n/**\n * RAF-deferred wrapper around {@link positionSettingsMenu}. Some\n * callers need to re-position after layout has settled (e.g. when the\n * panel size just changed and `getBoundingClientRect` would still\n * return the pre-change measurements on this frame).\n */\nexport function positionSettingsMenuDeferred(\n menu: HTMLElement | null | undefined,\n button: HTMLElement | null | undefined,\n opts: PositionSettingsMenuOptions = {}\n): void {\n requestAnimationFrame(() => {\n // The extra setTimeout is intentional: older WebKit still reports\n // stale geometry during the first RAF callback following a DOM\n // mutation. A 10ms trailing microtask gives layout a chance to\n // settle without being user-perceptible.\n setTimeout(() => positionSettingsMenu(menu, button, opts), 10);\n });\n}\n", "/**\n * Owns the settings-menu lifecycle for a `DraggableResizable`-powered\n * floating panel: create, show, hide, outside-click dismissal, keyboard\n * navigation, viewport-aware positioning, and the drag-mode / resize-\n * mode toggle items.\n *\n * `SignLanguageManager` and `TranscriptManager` both present the same\n * pattern: a settings button that opens a menu containing a \"Keyboard\n * drag mode\" toggle, a \"Resize mode\" toggle, manager-specific extras,\n * and a close item. This class captures that pattern so each manager\n * only has to describe:\n * - how to resolve its `DraggableResizable` (for state readback),\n * - which i18n keys to use on the toggle items,\n * - where to place the menu in its own layout (via `getMenuParent`),\n * - how to toggle each mode (`onDragItemClick` / `onResizeItemClick`\n * run the manager's side effects — announcements, badges, focus),\n * - any extra menu items (`buildExtraItems`, e.g. style dialog,\n * timestamp toggle for TranscriptManager).\n *\n * The manager's own public API (`showSettingsMenu`, `toggleKeyboardDragMode`,\n * `hideSettingsMenu`, ...) is preserved by forwarding to this panel.\n * External code that reads `settingsMenuVisible` or the option-button\n * elements keeps working via getters on the manager that proxy the\n * panel's state.\n *\n * Event listeners attached to `document` are tied to the player's\n * `lifecycleSignal` so they are torn down automatically when the\n * player is destroyed.\n */\n\nimport { DOMUtils } from './DOMUtils.js';\nimport { i18n } from '../i18n/i18n.js';\nimport {\n attachMenuKeyboardNavigation,\n createMenuItem,\n focusFirstMenuItem,\n} from './MenuUtils.js';\nimport {\n positionSettingsMenu,\n positionSettingsMenuDeferred,\n updateToggleMenuItem,\n} from './DraggablePanelMenu.js';\n\nimport type { Player } from '../core/Player.js';\nimport type { DraggableResizable } from './DraggableResizable.js';\n\n/**\n * i18n keys used for the drag-mode and resize-mode toggle items and\n * the \"Close\" item. All values must be translation keys (passed\n * through `i18n.t()` by `createMenuItem`/`updateToggleMenuItem`).\n */\nexport interface DraggablePanelI18nKeys {\n enableDrag: string;\n disableDrag: string;\n enableDragAria: string;\n disableDragAria: string;\n enableResize: string;\n disableResize: string;\n enableResizeAria: string;\n disableResizeAria: string;\n closeMenu: string;\n}\n\nexport interface DraggablePanelExtrasContext {\n menu: HTMLElement;\n itemClass: string;\n classPrefix: string;\n /**\n * Strip the tooltip and duplicate `button-text` nodes from a menu\n * item. `createMenuItem` is shared with toolbar buttons that want a\n * hover tooltip; settings-menu rows already show the same text\n * inline, so the tooltip would cause screen readers to read the\n * label twice. Exposed here so manager-provided extras can reuse\n * the same stripping logic the panel applies to its own items.\n */\n stripInlineTooltip: (item: HTMLElement) => void;\n}\n\nexport interface DraggablePanelOptions {\n player: Player;\n /**\n * Namespace for CSS classes, e.g. `'sign-language'` or `'transcript'`.\n * The final menu class is `{classPrefix}-{namespace}-settings-menu`\n * and item class is `{classPrefix}-{namespace}-settings-item`.\n */\n namespace: string;\n /** The button that opens the menu. */\n settingsButton: HTMLElement;\n /** Lazy draggable lookup (it may be re-created by the manager). */\n getDraggable: () => DraggableResizable | null;\n i18nKeys: DraggablePanelI18nKeys;\n /**\n * Horizontal anchoring of the menu relative to the settings button.\n * - `'left'` : align left edge (Transcript — header-row button).\n * - `'center'` : centre horizontally with viewport clamping (Sign\n * language — floating near viewport edges).\n */\n menuAlign: 'left' | 'center';\n /** Where to attach the menu node when first created. */\n getMenuParent: () => HTMLElement | null;\n /**\n * Called when the drag-mode item is clicked. The manager is\n * expected to toggle drag mode and run any side effects\n * (announcements, badges, focus). After this runs the panel will\n * refresh menu item state.\n */\n onDragItemClick: (panel: DraggablePanel) => void;\n /** Same for the resize-mode item. */\n onResizeItemClick: (panel: DraggablePanel) => void;\n /**\n * Insert manager-specific items (style dialog, timestamps, ...)\n * between the resize item and the close item.\n */\n buildExtraItems?: (ctx: DraggablePanelExtrasContext) => void;\n /** Optional: vertical gap (px) between button and menu. */\n menuGap?: number;\n /** Optional: breathing room (px) before the menu flips above. */\n menuSpaceReserve?: number;\n /**\n * Where to attach the mode-feedback badge while keyboard drag /\n * pointer resize mode is active. If omitted, {@link DraggablePanel.showBadge}\n * is a no-op (the manager effectively opts out of the badge).\n */\n getBadgeHost?: () => HTMLElement | null;\n /**\n * CSS class for the badge element. Defaults to\n * `{classPrefix}-{namespace}-mode-badge`. Sign-language passes a\n * shorter class (`vidply-sign-mode-badge`) to preserve existing\n * CSS. Transcript uses the default.\n */\n badgeClass?: string;\n}\n\nexport class DraggablePanel {\n private readonly opts: DraggablePanelOptions;\n\n /** Populated lazily on first `show()`. */\n settingsMenu: HTMLElement | null = null;\n settingsMenuVisible = false;\n dragOptionButton: HTMLElement | null = null;\n dragOptionText: Element | null = null;\n resizeOptionButton: HTMLElement | null = null;\n resizeOptionText: Element | null = null;\n\n private _justOpened = false;\n private _justOpenedTimer: ReturnType<typeof setTimeout> | null = null;\n private _keyHandler: ((e: KeyboardEvent) => void) | null = null;\n private _documentClick: ((e: MouseEvent) => void) | null = null;\n private _documentClickAdded = false;\n private _modeBadge: HTMLElement | null = null;\n\n constructor(opts: DraggablePanelOptions) {\n this.opts = opts;\n }\n\n /** True while the just-opened debounce window (prevents the same\n * click that opened the menu from also closing it via document\n * `mousedown` / `click`). */\n get justOpened(): boolean {\n return this._justOpened;\n }\n\n get classPrefix(): string {\n return this.opts.player.options.classPrefix;\n }\n\n get menuClass(): string {\n return `${this.classPrefix}-${this.opts.namespace}-settings-menu`;\n }\n\n get itemClass(): string {\n return `${this.classPrefix}-${this.opts.namespace}-settings-item`;\n }\n\n /**\n * Show the menu. First call creates the DOM; subsequent calls reuse\n * it. Refreshes menu item state from the current draggable.\n */\n show(): void {\n this._markJustOpened(350);\n this._ensureDocumentClickHandler();\n\n if (this.settingsMenu) {\n this.settingsMenu.style.display = 'block';\n this.settingsMenuVisible = true;\n this.opts.settingsButton.setAttribute('aria-expanded', 'true');\n this._attachKeyboardNavigation();\n this._positionImmediate();\n this.refreshState();\n focusFirstMenuItem(this.settingsMenu, `.${this.itemClass}`);\n return;\n }\n\n this._createMenu();\n }\n\n /**\n * Hide the menu. By default returns focus to the settings button;\n * callers can opt out when the next interaction should land\n * elsewhere (e.g. on the wrapper after enabling drag mode).\n */\n hide({ focusButton = true }: { focusButton?: boolean } = {}): void {\n if (!this.settingsMenu) return;\n\n this.settingsMenu.style.display = 'none';\n this.settingsMenuVisible = false;\n this._clearJustOpened();\n\n if (this._keyHandler) {\n this.settingsMenu.removeEventListener('keydown', this._keyHandler, true);\n this._keyHandler = null;\n }\n\n const items = this.settingsMenu.querySelectorAll<HTMLElement>(`.${this.itemClass}`);\n items.forEach((item) => item.setAttribute('tabindex', '-1'));\n\n const { settingsButton } = this.opts;\n settingsButton.setAttribute('aria-expanded', 'false');\n if (focusButton) {\n settingsButton.focus({ preventScroll: true });\n }\n }\n\n toggle(): void {\n if (this.settingsMenuVisible) {\n this.hide();\n } else {\n this.show();\n }\n }\n\n /** Set a short \"just opened\" guard so the document-click handler\n * attached for outside-dismissal ignores the originating click. */\n markJustOpenedForClick(): void {\n if (this._documentClick) {\n this._markJustOpened(100);\n }\n }\n\n /** Refresh the drag and resize toggle item state from the draggable. */\n refreshState(): void {\n this.refreshDragState();\n this.refreshResizeState();\n }\n\n refreshDragState(): void {\n const draggable = this.opts.getDraggable();\n updateToggleMenuItem(this.dragOptionButton, this.dragOptionText, {\n enabled: Boolean(draggable?.keyboardDragMode),\n enabledText: i18n.t(this.opts.i18nKeys.disableDrag),\n disabledText: i18n.t(this.opts.i18nKeys.enableDrag),\n enabledAria: i18n.t(this.opts.i18nKeys.disableDragAria),\n disabledAria: i18n.t(this.opts.i18nKeys.enableDragAria),\n });\n }\n\n refreshResizeState(): void {\n const draggable = this.opts.getDraggable();\n updateToggleMenuItem(this.resizeOptionButton, this.resizeOptionText, {\n enabled: Boolean(draggable?.pointerResizeMode),\n enabledText: i18n.t(this.opts.i18nKeys.disableResize),\n disabledText: i18n.t(this.opts.i18nKeys.enableResize),\n enabledAria: i18n.t(this.opts.i18nKeys.disableResizeAria),\n disabledAria: i18n.t(this.opts.i18nKeys.enableResizeAria),\n });\n }\n\n /**\n * Show a persistent mode-feedback badge (e.g. \"Drag mode: arrow\n * keys to move, Esc to exit\") anchored to the host element\n * returned by `getBadgeHost`. Replaces any previous badge. The\n * badge is a real DOM element (not a CSS pseudo-element) so its\n * text is translatable, selectable, visible under high-contrast\n * themes, and reflected in browser translation overlays.\n *\n * Marked `aria-hidden` because the accompanying live-region\n * announcement (the manager's responsibility) already conveys the\n * state change to assistive tech.\n */\n showBadge(text: string): void {\n const host = this.opts.getBadgeHost?.();\n if (!host) return;\n this.hideBadge();\n\n const className =\n this.opts.badgeClass ??\n `${this.classPrefix}-${this.opts.namespace}-mode-badge`;\n const badge = DOMUtils.createElement('span', {\n className,\n textContent: text,\n attributes: { 'aria-hidden': 'true' },\n });\n host.appendChild(badge);\n this._modeBadge = badge;\n }\n\n /** Remove the mode-feedback badge if one is showing. */\n hideBadge(): void {\n if (this._modeBadge && this._modeBadge.parentNode) {\n this._modeBadge.remove();\n }\n this._modeBadge = null;\n }\n\n /** RAF-deferred reposition (e.g. after a panel resize). */\n reposition(): void {\n positionSettingsMenuDeferred(this.settingsMenu, this.opts.settingsButton, {\n align: this.opts.menuAlign,\n gap: this.opts.menuGap ?? 4,\n spaceReserve: this.opts.menuSpaceReserve ?? 20,\n });\n }\n\n /**\n * Tear down any DOM/listeners owned by this panel. Safe to call\n * multiple times. Callers must still drop their own references.\n */\n destroy(): void {\n if (this._justOpenedTimer) {\n clearTimeout(this._justOpenedTimer);\n this._justOpenedTimer = null;\n }\n this._justOpened = false;\n\n this.hideBadge();\n\n if (this.settingsMenu) {\n if (this._keyHandler) {\n this.settingsMenu.removeEventListener('keydown', this._keyHandler, true);\n }\n this.settingsMenu.remove();\n this.settingsMenu = null;\n }\n\n this._keyHandler = null;\n this.settingsMenuVisible = false;\n this.dragOptionButton = null;\n this.dragOptionText = null;\n this.resizeOptionButton = null;\n this.resizeOptionText = null;\n\n // The document-click listener was attached with the player's\n // lifecycleSignal, so it is cleaned up automatically. We clear\n // the local reference so a later show() re-installs.\n this._documentClick = null;\n this._documentClickAdded = false;\n }\n\n private _createMenu(): void {\n const { player, settingsButton, i18nKeys } = this.opts;\n\n const menu = DOMUtils.createElement('div', {\n className: this.menuClass,\n attributes: { role: 'menu' },\n });\n this.settingsMenu = menu;\n\n const dragOption = createMenuItem({\n classPrefix: this.classPrefix,\n itemClass: this.itemClass,\n icon: 'move',\n label: i18nKeys.enableDrag,\n hasTextClass: true,\n onClick: (event) => {\n event.preventDefault();\n event.stopPropagation();\n this.opts.onDragItemClick(this);\n this.refreshState();\n },\n });\n dragOption.setAttribute('role', 'switch');\n dragOption.setAttribute('aria-checked', 'false');\n dragOption.setAttribute('data-setting', 'keyboard-drag');\n this._stripInlineTooltip(dragOption);\n this.dragOptionButton = dragOption;\n this.dragOptionText = dragOption.querySelector(`.${this.classPrefix}-settings-text`);\n\n const resizeOption = createMenuItem({\n classPrefix: this.classPrefix,\n itemClass: this.itemClass,\n icon: 'resize',\n label: i18nKeys.enableResize,\n hasTextClass: true,\n onClick: (event) => {\n event.preventDefault();\n event.stopPropagation();\n this.opts.onResizeItemClick(this);\n this.refreshState();\n },\n });\n resizeOption.setAttribute('role', 'switch');\n resizeOption.setAttribute('aria-checked', 'false');\n this._stripInlineTooltip(resizeOption);\n this.resizeOptionButton = resizeOption;\n this.resizeOptionText = resizeOption.querySelector(`.${this.classPrefix}-settings-text`);\n\n menu.appendChild(dragOption);\n menu.appendChild(resizeOption);\n\n if (this.opts.buildExtraItems) {\n this.opts.buildExtraItems({\n menu,\n itemClass: this.itemClass,\n classPrefix: this.classPrefix,\n stripInlineTooltip: (item) => this._stripInlineTooltip(item),\n });\n }\n\n const closeOption = createMenuItem({\n classPrefix: this.classPrefix,\n itemClass: this.itemClass,\n icon: 'close',\n label: i18nKeys.closeMenu,\n onClick: () => this.hide(),\n });\n this._stripInlineTooltip(closeOption);\n menu.appendChild(closeOption);\n\n menu.style.visibility = 'hidden';\n menu.style.display = 'block';\n\n const parent = this.opts.getMenuParent();\n if (settingsButton.parentNode) {\n settingsButton.insertAdjacentElement('afterend', menu);\n } else if (parent) {\n parent.appendChild(menu);\n }\n\n this._positionImmediate();\n\n requestAnimationFrame(() => {\n if (this.settingsMenu) {\n this.settingsMenu.style.visibility = 'visible';\n }\n });\n\n this._attachKeyboardNavigation();\n\n this.settingsMenuVisible = true;\n settingsButton.setAttribute('aria-expanded', 'true');\n this.refreshState();\n\n focusFirstMenuItem(menu, `.${this.itemClass}`);\n\n // Don't reveal the fact that we created the menu to callers that\n // didn't trigger show() explicitly — but this is always driven\n // by a show() so the `player` reference is just for\n // documentation clarity here.\n void player;\n }\n\n private _attachKeyboardNavigation(): void {\n const menu = this.settingsMenu;\n if (!menu) return;\n if (this._keyHandler) {\n menu.removeEventListener('keydown', this._keyHandler, true);\n }\n const handler = attachMenuKeyboardNavigation(\n menu,\n this.opts.settingsButton,\n `.${this.itemClass}`,\n () => this.hide({ focusButton: true })\n );\n this._keyHandler = handler ?? null;\n }\n\n private _positionImmediate(): void {\n positionSettingsMenu(this.settingsMenu, this.opts.settingsButton, {\n align: this.opts.menuAlign,\n gap: this.opts.menuGap ?? 4,\n spaceReserve: this.opts.menuSpaceReserve ?? 20,\n });\n }\n\n /**\n * Remove tooltip and duplicate button-text nodes from a menu item.\n * `createMenuItem` is used both for toolbar buttons (which want a\n * tooltip) and for settings-menu rows (which show the same text\n * inline). This strips the duplicated pieces so screen readers\n * don't read the label twice.\n */\n private _stripInlineTooltip(item: HTMLElement): void {\n const tooltip = item.querySelector(`.${this.classPrefix}-tooltip`);\n if (tooltip) tooltip.remove();\n const buttonText = item.querySelector(`.${this.classPrefix}-button-text`);\n if (buttonText) buttonText.remove();\n }\n\n private _markJustOpened(durationMs: number): void {\n this._justOpened = true;\n if (this._justOpenedTimer) {\n clearTimeout(this._justOpenedTimer);\n }\n this._justOpenedTimer = setTimeout(() => {\n this._justOpened = false;\n this._justOpenedTimer = null;\n }, durationMs);\n }\n\n private _clearJustOpened(): void {\n this._justOpened = false;\n if (this._justOpenedTimer) {\n clearTimeout(this._justOpenedTimer);\n this._justOpenedTimer = null;\n }\n }\n\n private _ensureDocumentClickHandler(): void {\n if (this._documentClickAdded) return;\n\n this._documentClick = (event: MouseEvent) => {\n if (this._justOpened) return;\n const target = event.target as Node | null;\n const { settingsButton } = this.opts;\n\n if (settingsButton === target || (target && settingsButton.contains(target))) {\n return;\n }\n if (this.settingsMenu && target && this.settingsMenu.contains(target)) {\n return;\n }\n if (this.settingsMenuVisible) {\n this.hide();\n }\n };\n\n // Delay attach so the click that opened the menu doesn't instantly\n // close it even if the justOpened flag somehow races.\n setTimeout(() => {\n const handler = this._documentClick;\n if (!handler) return;\n document.addEventListener('mousedown', handler, {\n capture: true,\n signal: this.opts.player.lifecycleSignal,\n });\n this._documentClickAdded = true;\n }, 300);\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* VidPly v1.2.
|
|
2
|
+
* VidPly v1.2.1 - Universal, Accessible Video Player
|
|
3
3
|
* (c) 2026 Matthias Peltzer
|
|
4
4
|
* Released under GPL-2.0-or-later License
|
|
5
5
|
*/
|
|
@@ -297,4 +297,4 @@ var HTML5Renderer = class {
|
|
|
297
297
|
export {
|
|
298
298
|
HTML5Renderer
|
|
299
299
|
};
|
|
300
|
-
//# sourceMappingURL=vidply.chunk-
|
|
300
|
+
//# sourceMappingURL=vidply.chunk-XAK3DPTO.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/renderers/HTML5Renderer.ts"],
|
|
4
|
+
"sourcesContent": ["import type { Renderer } from '../types/renderer.js';\nimport type { Player } from '../core/Player.js';\n\nexport class HTML5Renderer implements Renderer {\n player: Player;\n media: HTMLMediaElement;\n _didDeferredLoad: boolean;\n // All media listeners are registered with this controller's signal so a\n // single abort() in destroy() detaches every one of them. Avoids the leak\n // of removeEventListener being called with fresh, non-matching callbacks.\n private _listenerController: AbortController;\n\n constructor(player: Player) {\n this.player = player;\n this.media = player.element;\n this._didDeferredLoad = false;\n this._listenerController = new AbortController();\n }\n\n async init() {\n // Hide native controls\n this.media.controls = false;\n this.media.removeAttribute('controls');\n \n this.attachEvents();\n \n // Set preload + optionally defer network loading until user play\n if (this.player.options.deferLoad) {\n // Allow metadata preload while still avoiding full media download.\n // Note: browsers may still fetch metadata automatically when preload=\"metadata\".\n this.media.preload = this.player.options.preload || 'none';\n \n // Firefox requires an explicit load() call to fetch metadata even with preload=\"metadata\".\n // Only call load() if preload is set to \"metadata\" to ensure duration is available.\n if (this.player.options.preload === 'metadata') {\n this.media.load();\n }\n } else {\n this.media.preload = this.player.options.preload;\n // Load media (eager)\n this.media.load();\n }\n \n // Show VidPly controls (remove external controls class if present)\n if (this.player.container) {\n this.player.container.classList.remove('vidply-external-controls');\n }\n }\n\n attachEvents() {\n const { signal } = this._listenerController;\n\n // Playback events\n this.media.addEventListener('loadedmetadata', () => {\n this.player.state.duration = this.media.duration;\n this.player.emit('loadedmetadata');\n \n // Auto-generate poster if none exists (for HTML5 video only)\n if (this.media.tagName === 'VIDEO') {\n this.player.autoGeneratePoster().catch((error: unknown) => {\n this.player.log('Failed to auto-generate poster:', error, 'warn');\n });\n }\n }, { signal });\n\n this.media.addEventListener('durationchange', () => {\n const duration = this.media.duration;\n if (duration && isFinite(duration) && duration > 0) {\n this.player.state.duration = duration;\n this.player.emit('durationchange', duration);\n }\n }, { signal });\n\n this.media.addEventListener('play', () => {\n this.player.state.playing = true;\n this.player.state.paused = false;\n this.player.state.ended = false;\n this.player.emit('play');\n \n if (this.player.options.onPlay) {\n this.player.options.onPlay.call(this.player);\n }\n \n // Pause other players if enabled\n if (this.player.options.pauseOthersOnPlay) {\n this.pauseOtherPlayers();\n }\n }, { signal });\n\n this.media.addEventListener('pause', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.emit('pause');\n \n if (this.player.options.onPause) {\n this.player.options.onPause.call(this.player);\n }\n }, { signal });\n\n this.media.addEventListener('ended', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.state.ended = true;\n this.player.emit('ended');\n \n if (this.player.options.onEnded) {\n this.player.options.onEnded.call(this.player);\n }\n \n // Handle loop\n if (this.player.options.loop) {\n this.player.seek(0);\n this.player.play();\n }\n }, { signal });\n\n this.media.addEventListener('timeupdate', () => {\n this.player.state.currentTime = this.media.currentTime;\n this.player.emit('timeupdate', this.media.currentTime);\n \n if (this.player.options.onTimeUpdate) {\n this.player.options.onTimeUpdate.call(this.player, this.media.currentTime);\n }\n }, { signal });\n\n this.media.addEventListener('volumechange', () => {\n this.player.state.volume = this.media.volume;\n this.player.state.muted = this.media.muted;\n this.player.emit('volumechange', this.media.volume);\n \n if (this.player.options.onVolumeChange) {\n this.player.options.onVolumeChange.call(this.player, this.media.volume);\n }\n }, { signal });\n\n this.media.addEventListener('seeking', () => {\n this.player.state.seeking = true;\n this.player.emit('seeking');\n }, { signal });\n\n this.media.addEventListener('seeked', () => {\n this.player.state.seeking = false;\n this.player.emit('seeked');\n }, { signal });\n\n this.media.addEventListener('waiting', () => {\n this.player.state.buffering = true;\n this.player.emit('waiting');\n }, { signal });\n\n this.media.addEventListener('canplay', () => {\n this.player.state.buffering = false;\n this.player.emit('canplay');\n }, { signal });\n\n this.media.addEventListener('progress', () => {\n if (this.media.buffered.length > 0) {\n const buffered = this.media.buffered.end(this.media.buffered.length - 1);\n this.player.emit('progress', buffered);\n }\n }, { signal });\n\n this.media.addEventListener('error', (_e: Event) => {\n this.player.handleError(this.media.error);\n }, { signal });\n\n this.media.addEventListener('ratechange', () => {\n this.player.state.playbackSpeed = this.media.playbackRate;\n this.player.emit('ratechange', this.media.playbackRate);\n }, { signal });\n }\n\n pauseOtherPlayers() {\n // Pause other VidPly instances\n const allPlayers = document.querySelectorAll('.vidply-player');\n allPlayers.forEach(playerEl => {\n if (playerEl !== this.player.container) {\n const video = playerEl.querySelector('video, audio') as HTMLMediaElement | null;\n if (video && !video.paused) {\n video.pause();\n }\n }\n });\n }\n\n play() {\n // Save scroll position to prevent browser from scrolling to video\n const scrollX = window.scrollX;\n const scrollY = window.scrollY;\n\n // If deferLoad is enabled, trigger load only on the first user play request.\n if (this.player.options.deferLoad && !this._didDeferredLoad) {\n try {\n // Only call load() if browser hasn't loaded anything yet.\n if (this.media.readyState === 0) {\n this.media.load();\n }\n } catch {\n // ignore\n }\n this._didDeferredLoad = true;\n }\n \n const promise = this.media.play();\n \n // Restore scroll position immediately to prevent auto-scroll\n window.scrollTo(scrollX, scrollY);\n \n if (promise !== undefined) {\n promise.catch(error => {\n this.player.log('Play failed:', error, 'warn');\n \n // If autoplay failed, try muted autoplay\n if (this.player.options.autoplay && !this.player.state.muted) {\n this.player.log('Retrying play with muted audio', 'info');\n this.media.muted = true;\n \n // Save scroll position again for retry\n const retryScrollX = window.scrollX;\n const retryScrollY = window.scrollY;\n this.media.play().then(() => {\n window.scrollTo(retryScrollX, retryScrollY);\n }).catch(err => {\n this.player.handleError(err);\n });\n }\n });\n return promise;\n }\n return Promise.resolve();\n }\n\n /**\n * Ensure the media element has been loaded at least once (metadata/initial state)\n * without starting playback. Useful for playlists to behave like single videos.\n */\n ensureLoaded() {\n if (!this.player.options.deferLoad || this._didDeferredLoad) {\n return;\n }\n\n try {\n if (this.media.readyState === 0) {\n this.media.load();\n }\n } catch {\n // ignore\n }\n this._didDeferredLoad = true;\n }\n\n pause() {\n this.media.pause();\n }\n\n seek(time: number) {\n this.media.currentTime = time;\n }\n\n setVolume(volume: number) {\n this.media.volume = volume;\n }\n\n setMuted(muted: boolean) {\n this.media.muted = muted;\n }\n\n setPlaybackSpeed(speed: number) {\n this.media.playbackRate = speed;\n }\n\n /**\n * Get available quality levels from source elements\n * @returns {Array} Array of quality objects with index, height, width, and src\n */\n getQualities() {\n const sources = Array.from(this.media.querySelectorAll('source'));\n \n if (sources.length <= 1) {\n return [];\n }\n\n return sources.map((source, index) => {\n // Extract quality from data-quality attribute (preferred, HTML5-valid)\n // Fallback to deprecated 'label' attribute for backward compatibility\n // Note: 'label' is not a valid HTML attribute on <source> elements\n const label = source.getAttribute('data-quality') || source.getAttribute('data-label') || source.getAttribute('label') || '';\n const height = source.getAttribute('data-height') || String(this.extractHeightFromLabel(label));\n const width = source.getAttribute('data-width') || '';\n \n return {\n index,\n height: height ? parseInt(height) : 0,\n width: width ? parseInt(width) : 0,\n src: source.src,\n type: source.type,\n name: label || (height ? `${height}p` : `Quality ${index + 1}`)\n };\n }).filter(q => q.height > 0); // Only return qualities with valid height\n }\n\n /**\n * Extract height from quality label (e.g., \"1080p\" -> 1080)\n * @param {string} label \n * @returns {number}\n */\n extractHeightFromLabel(label: string) {\n const match = label.match(/(\\d+)p/i);\n return match && match[1] ? parseInt(match[1], 10) : 0;\n }\n\n /**\n * Switch to a specific quality level\n * @param {number} qualityIndex - Index of the quality level (-1 for auto, not applicable for HTML5)\n */\n switchQuality(qualityIndex: number) {\n const qualities = this.getQualities();\n \n if (qualityIndex < 0 || qualityIndex >= qualities.length) {\n this.player.log('Invalid quality index', 'warn');\n return;\n }\n\n const quality = qualities[qualityIndex];\n if (!quality || !quality.src) {\n return;\n }\n const currentTime = this.media.currentTime;\n const wasPlaying = !this.media.paused;\n\n // Store the current source for comparison\n const currentSrc = this.media.currentSrc;\n \n // Don't switch if already at this quality\n if (currentSrc === quality.src) {\n this.player.log('Already at this quality level', 'info');\n return;\n }\n\n this.player.log(`Switching to quality: ${quality.name}`, 'info');\n\n // Update the src\n this.media.src = quality.src;\n \n // Wait for the new source to load, then restore playback state\n const onLoadedMetadata = () => {\n this.media.removeEventListener('loadedmetadata', onLoadedMetadata);\n \n // Restore playback position\n this.media.currentTime = currentTime;\n \n // Resume playback if it was playing\n if (wasPlaying) {\n this.media.play().catch(() => {\n this.player.log('Failed to resume playback after quality switch', 'warn');\n });\n }\n \n // Emit quality change event\n this.player.emit('qualitychange', { quality: quality.name, index: qualityIndex });\n };\n\n this.media.addEventListener('loadedmetadata', onLoadedMetadata);\n this.media.load();\n }\n\n /**\n * Get current quality index\n * @returns {number}\n */\n getCurrentQuality() {\n const qualities = this.getQualities();\n const currentSrc = this.media.currentSrc;\n \n for (let i = 0; i < qualities.length; i++) {\n if (qualities[i]?.src === currentSrc) {\n return i;\n }\n }\n \n return 0; // Default to first quality if not found\n }\n\n destroy() {\n // Detach every media listener registered in attachEvents() in one shot.\n this._listenerController.abort();\n }\n}\n\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* VidPly v1.2.
|
|
2
|
+
* VidPly v1.2.1 - Universal, Accessible Video Player
|
|
3
3
|
* (c) 2026 Matthias Peltzer
|
|
4
4
|
* Released under GPL-2.0-or-later License
|
|
5
5
|
*/
|
|
6
6
|
import {
|
|
7
7
|
i18n
|
|
8
|
-
} from "./vidply.chunk-
|
|
8
|
+
} from "./vidply.chunk-NSMAZCMB.js";
|
|
9
9
|
|
|
10
10
|
// src/utils/TimeUtils.ts
|
|
11
11
|
var TimeUtils = {
|
|
@@ -64,4 +64,4 @@ var TimeUtils = {
|
|
|
64
64
|
export {
|
|
65
65
|
TimeUtils
|
|
66
66
|
};
|
|
67
|
-
//# sourceMappingURL=vidply.chunk-
|
|
67
|
+
//# sourceMappingURL=vidply.chunk-YVCYQZJI.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* VidPly v1.2.
|
|
2
|
+
* VidPly v1.2.1 - Universal, Accessible Video Player
|
|
3
3
|
* (c) 2026 Matthias Peltzer
|
|
4
4
|
* Released under GPL-2.0-or-later License
|
|
5
5
|
*/
|
|
@@ -220,4 +220,4 @@ var de = {
|
|
|
220
220
|
export {
|
|
221
221
|
de
|
|
222
222
|
};
|
|
223
|
-
//# sourceMappingURL=vidply.de-
|
|
223
|
+
//# sourceMappingURL=vidply.de-5W5LBFSJ.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/i18n/languages/de.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * German translations for VidPly\n */\n\nexport const de = {\n player: {\n label: 'Videoplayer',\n play: 'Abspielen',\n pause: 'Pause',\n stop: 'Stopp',\n restart: 'Von vorne beginnen',\n rewind: 'Zurückspulen',\n forward: 'Vorspulen',\n rewindSeconds: '{seconds} Sekunden zurückspulen',\n forwardSeconds: '{seconds} Sekunden vorspulen',\n previous: 'Vorheriger Titel',\n next: 'Nächster Titel',\n playlist: 'Wiedergabeliste umschalten',\n volume: 'Lautstärke',\n mute: 'Stumm',\n unmute: 'Ton ein',\n fullscreen: 'Vollbild',\n exitFullscreen: 'Vollbild beenden',\n captions: 'Untertitel',\n chapters: 'Kapitel',\n quality: 'Qualität',\n captionStyling: 'Untertitel-Stil',\n transcript: 'Transkript umschalten',\n audioDescription: 'Audiodeskription',\n signLanguage: 'Gebärdensprache-Video',\n settings: 'Einstellungen',\n speed: 'Wiedergabegeschwindigkeit',\n pip: 'Bild-in-Bild',\n floatingPlayer: 'Schwebender Player',\n floatingPlayerClose: 'Schwebenden Player schlie\\u00dfen',\n floatingPlayerEnter: 'Video ausklappen',\n floatingPlayerExit: 'Video andocken',\n floatingPlayerDialog: 'Schwebender Videoplayer. D zum Verschieben, R zum Gr\\u00f6\\u00dfen\\u00e4ndern, Escape zum Schlie\\u00dfen.',\n download: 'Herunterladen',\n downloadWithFormat: 'Herunterladen {format}',\n downloadWithSize: 'Herunterladen ({size})',\n downloadWithFormatSize: 'Herunterladen {format} ({size})',\n currentTime: 'Aktuelle Zeit',\n duration: 'Dauer',\n progress: 'Fortschritt',\n seekForward: '{seconds} Sekunden vorspulen',\n seekBackward: '{seconds} Sekunden zurückspulen',\n volumeUp: 'Lauter',\n volumeDown: 'Leiser',\n loading: 'Lädt...',\n loadingChapters: 'Kapitel werden geladen...',\n error: 'Fehler beim Laden',\n buffering: 'Puffern...',\n signLanguageVideo: 'Gebärdensprache-Video',\n closeSignLanguage: 'Gebärdensprache-Video schließen',\n signLanguageSettings: 'Gebärdensprache-Einstellungen',\n startPlaybackFirst: 'Bitte starten Sie die Wiedergabe zuerst.',\n startPlaybackForAudioDescription: 'Bitte starten Sie die Wiedergabe zuerst, um die Audiodeskription zu nutzen.',\n startPlaybackForSignLanguage: 'Bitte starten Sie die Wiedergabe zuerst, um das Gebärdensprache-Video zu nutzen.',\n noChapters: 'Keine Kapitel verfügbar',\n noCaptions: 'Keine Untertitel verfügbar',\n auto: 'Automatisch',\n autoQuality: 'Automatisch (keine Qualitätsauswahl verfügbar)',\n noQuality: 'Qualitätsauswahl nicht verfügbar',\n signLanguageDragResize: 'Gebärdensprache-Video - Drücken Sie D zum Verschieben per Tastatur, R zum Ändern der Größe',\n signLanguageDragActive: 'Gebärdensprache-Video - Verschiebemodus aktiv. Pfeiltasten zum Bewegen, Escape zum Beenden.',\n signLanguageResizeActive: 'Gebärdensprache-Video - Größenänderungsmodus aktiv. Links-/Rechts-Pfeiltasten zum Ändern der Größe, Escape zum Beenden.',\n enableSignDragMode: 'Verschiebemodus aktivieren. Tastenkombination: D-Taste',\n disableSignDragMode: 'Verschiebemodus deaktivieren. Tastenkombination: D-Taste',\n enableSignDragModeAria: 'Tastatur-Verschiebemodus mit Pfeiltasten aktivieren. Tastenkombination: D-Taste',\n disableSignDragModeAria: 'Tastatur-Verschiebemodus mit Pfeiltasten deaktivieren. Tastenkombination: D-Taste',\n enableSignResizeMode: 'Größenänderungsmodus aktivieren. Tastenkombination: R-Taste',\n disableSignResizeMode: 'Größenänderungsmodus deaktivieren. Tastenkombination: R-Taste',\n enableSignResizeModeAria: 'Tastatur-Größenänderungsmodus mit Pfeiltasten aktivieren. Tastenkombination: R-Taste',\n disableSignResizeModeAria: 'Tastatur-Größenänderungsmodus mit Pfeiltasten deaktivieren. Tastenkombination: R-Taste',\n signDragModeHint: 'Verschiebemodus: Pfeiltasten zum Bewegen, Esc zum Beenden',\n signResizeModeHint: 'Größenänderungsmodus: Pfeiltasten zum Ändern, Esc zum Beenden',\n signDragModeDisabled: 'Verschiebemodus für Gebärdensprache-Video deaktiviert.',\n signResizeModeDisabled: 'Größenänderungsmodus für Gebärdensprache-Video deaktiviert.',\n resizeHandle: 'Größenänderung {direction}-Ecke',\n moreOptions: 'Weitere Optionen',\n noMoreOptions: 'Keine weiteren Optionen verfügbar',\n playing: 'Wird abgespielt',\n paused: 'Pausiert',\n muted: 'Stummgeschaltet',\n unmuted: 'Ton an',\n captionsOn: 'Untertitel an',\n captionsOff: 'Untertitel aus',\n volumePercent: 'Lautstärke {percent} Prozent',\n volumePercentMuted: 'Stummgeschaltet',\n speedRate: 'Geschwindigkeit {rate}x'\n },\n captions: {\n off: 'Aus',\n select: 'Untertitel auswählen',\n fontSize: 'Schriftgröße',\n fontFamily: 'Schriftart',\n color: 'Textfarbe',\n backgroundColor: 'Hintergrundfarbe',\n opacity: 'Deckkraft'\n },\n fontSizes: {\n small: 'Klein',\n normal: 'Normal',\n large: 'Groß',\n xlarge: 'Sehr groß'\n },\n fontFamilies: {\n sansSerif: 'Sans-serif',\n serif: 'Serif',\n monospace: 'Monospace'\n },\n styleLabels: {\n textColor: 'Textfarbe',\n background: 'Hintergrund',\n font: 'Schrift',\n fontSize: 'Schriftgröße',\n opacity: 'Deckkraft'\n },\n audioDescription: {\n enable: 'Audiodeskription aktivieren',\n disable: 'Audiodeskription deaktivieren'\n },\n signLanguage: {\n show: 'Gebärdensprache-Video anzeigen',\n hide: 'Gebärdensprache-Video ausblenden',\n showInMainView: 'Gebärdensprache im Hauptvideo anzeigen',\n hideInMainView: 'Gebärdensprache aus Hauptvideo entfernen'\n },\n transcript: {\n title: 'Transkript',\n ariaLabel: 'Video-Transkript',\n close: 'Transkript schließen',\n loading: 'Transkript wird geladen...',\n noTranscript: 'Kein Transkript für dieses Video verfügbar.',\n settings: 'Transkript-Einstellungen. Eingabetaste zum Öffnen des Menüs drücken oder D zum Aktivieren des Verschiebemodus',\n keyboardDragMode: 'Tastatur-Verschiebemodus mit Pfeiltasten umschalten. Tastenkombination: D-Taste',\n keyboardDragActive: '⌨️ Tastatur-Verschiebemodus aktiv (Pfeiltasten zum Bewegen, Umschalt+Pfeiltasten für große Schritte, D oder ESC zum Beenden)',\n dragResizePrompt: 'Drücken Sie D zum Verschieben oder R zur Größenänderung. Home setzt die Position zurück, Esc schließt.',\n dragModeEnabled: 'Tastatur-Verschiebemodus aktiviert. Pfeiltasten zum Bewegen, Umschalt+Pfeiltasten für größere Schritte. D oder Esc zum Beenden.',\n dragModeDisabled: 'Tastatur-Verschiebemodus deaktiviert.',\n enableDragMode: 'Verschiebemodus aktivieren. Tastenkombination: D-Taste',\n disableDragMode: 'Verschiebemodus deaktivieren. Tastenkombination: D-Taste',\n enableDragModeAria: 'Tastatur-Verschiebemodus mit Pfeiltasten aktivieren. Tastenkombination: D-Taste',\n disableDragModeAria: 'Tastatur-Verschiebemodus mit Pfeiltasten deaktivieren. Tastenkombination: D-Taste',\n resizeWindow: 'Fenster vergrößern/verkleinern',\n disableResizeWindow: 'Resize-Modus deaktivieren',\n enableResizeMode: 'Größenänderungsmodus aktivieren. Tastenkombination: R-Taste',\n disableResizeMode: 'Größenänderungsmodus deaktivieren. Tastenkombination: R-Taste',\n enableResizeModeAria: 'Tastatur-Größenänderungsmodus mit Pfeiltasten aktivieren. Tastenkombination: R-Taste',\n disableResizeModeAria: 'Tastatur-Größenänderungsmodus mit Pfeiltasten deaktivieren. Tastenkombination: R-Taste',\n resizeModeHint: 'Griffe aktiviert. Ziehen Sie Kanten oder Ecken zum Anpassen. Esc oder R zum Beenden.',\n resizeModeEnabled: 'Resize-Modus aktiviert. Kanten oder Ecken ziehen; Esc oder R beendet.',\n resizeModeDisabled: 'Resize-Modus deaktiviert.',\n dragModeBadge: 'Verschiebemodus: Pfeiltasten zum Bewegen, Esc zum Beenden',\n resizeModeBadge: 'Resize-Modus: Kanten oder Ecken ziehen, Esc zum Beenden',\n positionReset: 'Transkriptposition zurückgesetzt.',\n styleTranscript: 'Transkript-Stileinstellungen öffnen',\n closeMenu: 'Menü schließen',\n styleTitle: 'Transkript-Stil',\n autoscroll: 'Auto-Scroll',\n settingsMenu: 'Transkript-Dialog-Einstellungen',\n showTimestamps: 'Zeitstempel anzeigen',\n hideTimestamps: 'Zeitstempel ausblenden',\n showTimestampsAria: 'Zeitstempel im Transkript anzeigen',\n hideTimestampsAria: 'Zeitstempel im Transkript ausblenden',\n seekTo: 'Springe zu {time}'\n },\n settings: {\n title: 'Einstellungen',\n quality: 'Qualität',\n speed: 'Geschwindigkeit',\n captions: 'Untertitel',\n language: 'Sprache',\n reset: 'Zurücksetzen',\n close: 'Schließen'\n },\n speeds: {\n normal: 'Normal'\n },\n time: {\n display: 'Zeitanzeige',\n durationPrefix: 'Dauer: ',\n of: 'von',\n hour: '{count} Stunde',\n hours: '{count} Stunden',\n minute: '{count} Minute',\n minutes: '{count} Minuten',\n second: '{count} Sekunde',\n seconds: '{count} Sekunden'\n },\n resume: {\n prompt: 'Bei {time} fortsetzen?',\n resume: 'Fortsetzen',\n startOver: 'Von vorne'\n },\n playlist: {\n title: 'Wiedergabeliste',\n trackOf: 'Titel {current} von {total}',\n nowPlaying: 'Läuft gerade: Titel {current} von {total}. {title}{artist}',\n by: ' von ',\n untitled: 'Ohne Titel',\n trackUntitled: 'Titel {number}',\n currentlyPlaying: 'Wird gerade abgespielt',\n notPlaying: 'Nicht aktiv',\n pressEnterPlay: 'Eingabetaste zum Abspielen',\n pressEnterRestart: 'Eingabetaste zum Neustart',\n keyboardInstructions: 'Wiedergabelisten-Navigation: Verwenden Sie die Pfeiltasten nach oben und unten, um zwischen Titeln zu wechseln. Drücken Sie Bild auf oder Bild ab, um 5 Titel zu überspringen. Drücken Sie Pos1, um zum ersten Titel zu springen, Ende für den letzten Titel. Drücken Sie die Eingabetaste oder Leertaste, um den ausgewählten Titel abzuspielen.',\n endOfPlaylist: 'Ende der Wiedergabeliste. {current} von {total}.',\n beginningOfPlaylist: 'Anfang der Wiedergabeliste. 1 von {total}.',\n jumpedToLastTrack: 'Zum letzten Titel gesprungen. {current} von {total}.',\n jumpedToFirstTrack: 'Zum ersten Titel gesprungen. 1 von {total}.',\n firstTrack: 'Erster Titel. 1 von {total}.',\n lastTrack: 'Letzter Titel. {current} von {total}.'\n }\n};\n\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* VidPly v1.2.
|
|
2
|
+
* VidPly v1.2.1 - Universal, Accessible Video Player
|
|
3
3
|
* (c) 2026 Matthias Peltzer
|
|
4
4
|
* Released under GPL-2.0-or-later License
|
|
5
5
|
*/
|
|
@@ -217,4 +217,4 @@ var es = {
|
|
|
217
217
|
export {
|
|
218
218
|
es
|
|
219
219
|
};
|
|
220
|
-
//# sourceMappingURL=vidply.es-
|
|
220
|
+
//# sourceMappingURL=vidply.es-SHDAT6L6.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/i18n/languages/es.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Spanish translations for VidPly\n */\n\nexport const es = {\n player: {\n label: 'Reproductor de video',\n play: 'Reproducir',\n pause: 'Pausa',\n stop: 'Detener',\n restart: 'Reiniciar desde el principio',\n rewind: 'Retroceder',\n forward: 'Avanzar',\n rewindSeconds: 'Retroceder {seconds} segundos',\n forwardSeconds: 'Avanzar {seconds} segundos',\n previous: 'Pista anterior',\n next: 'Siguiente pista',\n playlist: 'Alternar lista de reproducción',\n volume: 'Volumen',\n mute: 'Silenciar',\n unmute: 'Activar sonido',\n fullscreen: 'Pantalla completa',\n exitFullscreen: 'Salir de pantalla completa',\n captions: 'Subtítulos',\n chapters: 'Capítulos',\n quality: 'Calidad',\n captionStyling: 'Estilo de subtítulos',\n transcript: 'Alternar transcripción',\n audioDescription: 'Audiodescripción',\n signLanguage: 'Video en lengua de señas',\n settings: 'Configuración',\n speed: 'Velocidad de reproducción',\n pip: 'Imagen en imagen',\n floatingPlayer: 'Reproductor flotante',\n floatingPlayerClose: 'Cerrar reproductor flotante',\n floatingPlayerEnter: 'Sacar el v\\u00eddeo',\n floatingPlayerExit: 'Anclar el v\\u00eddeo',\n floatingPlayerDialog: 'Reproductor de v\\u00eddeo flotante. Pulsa D para mover, R para redimensionar, Escape para cerrar.',\n download: 'Descargar',\n downloadWithFormat: 'Descargar {format}',\n downloadWithSize: 'Descargar ({size})',\n downloadWithFormatSize: 'Descargar {format} ({size})',\n currentTime: 'Tiempo actual',\n duration: 'Duración',\n progress: 'Progreso',\n seekForward: 'Avanzar {seconds} segundos',\n seekBackward: 'Retroceder {seconds} segundos',\n volumeUp: 'Subir volumen',\n volumeDown: 'Bajar volumen',\n loading: 'Cargando...',\n loadingChapters: 'Cargando capítulos...',\n error: 'Error al cargar',\n buffering: 'Almacenando en búfer...',\n signLanguageVideo: 'Video en Lengua de Señas',\n closeSignLanguage: 'Cerrar video en lengua de señas',\n signLanguageSettings: 'Configuración de lengua de señas',\n noChapters: 'No hay capítulos disponibles',\n noCaptions: 'No hay subtítulos disponibles',\n auto: 'Automático',\n autoQuality: 'Automático (selección de calidad no disponible)',\n noQuality: 'Selección de calidad no disponible',\n signLanguageDragResize: 'Video en Lengua de Señas - Presione D para arrastrar con el teclado, R para cambiar el tamaño',\n signLanguageDragActive: 'Video en Lengua de Señas - Modo de arrastre activo. Use las teclas de flecha para mover, Escape para salir.',\n signLanguageResizeActive: 'Video en Lengua de Señas - Modo de cambio de tamaño activo. Use las teclas de flecha izquierda/derecha para cambiar el tamaño, Escape para salir.',\n enableSignDragMode: 'Activar modo de arrastre. Atajo: tecla D',\n disableSignDragMode: 'Desactivar modo de arrastre. Atajo: tecla D',\n enableSignDragModeAria: 'Activar modo de arrastre con teclado usando teclas de flecha. Atajo: tecla D',\n disableSignDragModeAria: 'Desactivar modo de arrastre con teclado usando teclas de flecha. Atajo: tecla D',\n enableSignResizeMode: 'Activar modo de cambio de tamaño. Atajo: tecla R',\n disableSignResizeMode: 'Desactivar modo de cambio de tamaño. Atajo: tecla R',\n enableSignResizeModeAria: 'Activar modo de cambio de tamaño con teclado usando teclas de flecha. Atajo: tecla R',\n disableSignResizeModeAria: 'Desactivar modo de cambio de tamaño con teclado usando teclas de flecha. Atajo: tecla R',\n signDragModeHint: 'Modo de arrastre: flechas para mover, Esc para salir',\n signResizeModeHint: 'Modo de cambio de tamaño: flechas para redimensionar, Esc para salir',\n signDragModeDisabled: 'Modo de arrastre del video en lengua de señas desactivado.',\n signResizeModeDisabled: 'Modo de cambio de tamaño del video en lengua de señas desactivado.',\n resizeHandle: 'Cambiar tamaño esquina {direction}',\n moreOptions: 'Más opciones',\n noMoreOptions: 'No hay opciones adicionales disponibles',\n playing: 'Reproduciendo',\n paused: 'En pausa',\n muted: 'Silenciado',\n unmuted: 'Sonido activado',\n captionsOn: 'Subtítulos activados',\n captionsOff: 'Subtítulos desactivados',\n volumePercent: 'Volumen {percent} por ciento',\n volumePercentMuted: 'Silenciado',\n speedRate: 'Velocidad {rate}x'\n },\n captions: {\n off: 'Desactivado',\n select: 'Seleccionar subtítulos',\n fontSize: 'Tamaño de fuente',\n fontFamily: 'Familia de fuente',\n color: 'Color de texto',\n backgroundColor: 'Color de fondo',\n opacity: 'Opacidad'\n },\n fontSizes: {\n small: 'Pequeño',\n normal: 'Normal',\n large: 'Grande',\n xlarge: 'Muy grande'\n },\n fontFamilies: {\n sansSerif: 'Sans-serif',\n serif: 'Serif',\n monospace: 'Monospace'\n },\n styleLabels: {\n textColor: 'Color de texto',\n background: 'Fondo',\n font: 'Fuente',\n fontSize: 'Tamaño de fuente',\n opacity: 'Opacidad'\n },\n audioDescription: {\n enable: 'Activar audiodescripción',\n disable: 'Desactivar audiodescripción'\n },\n signLanguage: {\n show: 'Mostrar video en lengua de señas',\n hide: 'Ocultar video en lengua de señas',\n showInMainView: 'Mostrar lengua de señas en video principal',\n hideInMainView: 'Ocultar lengua de señas del video principal'\n },\n transcript: {\n title: 'Transcripción',\n ariaLabel: 'Transcripción de video',\n close: 'Cerrar transcripción',\n loading: 'Cargando transcripción...',\n noTranscript: 'No hay transcripción disponible para este video.',\n settings: 'Configuración de transcripción. Presione Enter para abrir el menú o D para activar el modo de arrastre',\n keyboardDragMode: 'Alternar modo de arrastre con teclado usando teclas de flecha. Atajo: tecla D',\n keyboardDragActive: '⌨️ Modo de Arrastre con Teclado Activo (Teclas de flecha para mover, Mayús+Flechas para pasos grandes, D o ESC para salir)',\n dragResizePrompt: 'Pulsa D para mover o R para cambiar el tamaño. Home restablece la posición; Esc cierra.',\n dragModeEnabled: 'Modo de arrastre con teclado activado. Usa flechas para mover, Mayús+Flechas para pasos grandes. Pulsa D o Esc para salir.',\n dragModeDisabled: 'Modo de arrastre con teclado desactivado.',\n enableDragMode: 'Activar modo de arrastre. Atajo: tecla D',\n disableDragMode: 'Desactivar modo de arrastre. Atajo: tecla D',\n enableDragModeAria: 'Activar modo de arrastre con teclado usando teclas de flecha. Atajo: tecla D',\n disableDragModeAria: 'Desactivar modo de arrastre con teclado usando teclas de flecha. Atajo: tecla D',\n resizeWindow: 'Cambiar tamaño de ventana',\n disableResizeWindow: 'Desactivar modo de cambio de tamaño',\n enableResizeMode: 'Activar modo de cambio de tamaño. Atajo: tecla R',\n disableResizeMode: 'Desactivar modo de cambio de tamaño. Atajo: tecla R',\n enableResizeModeAria: 'Activar modo de cambio de tamaño con teclado usando teclas de flecha. Atajo: tecla R',\n disableResizeModeAria: 'Desactivar modo de cambio de tamaño con teclado usando teclas de flecha. Atajo: tecla R',\n resizeModeHint: 'Controladores habilitados. Arrastra bordes o esquinas para ajustar. Pulsa Esc o R para salir.',\n resizeModeEnabled: 'Modo de cambio de tamaño activado. Arrastra bordes o esquinas. Pulsa Esc o R para salir.',\n resizeModeDisabled: 'Modo de cambio de tamaño desactivado.',\n dragModeBadge: 'Modo mover: flechas para mover, Esc para salir',\n resizeModeBadge: 'Modo redimensionar: arrastra bordes o esquinas, Esc para salir',\n positionReset: 'Posición de la transcripción restablecida.',\n styleTranscript: 'Abrir configuración de estilo de transcripción',\n closeMenu: 'Cerrar menú',\n styleTitle: 'Estilo de Transcripción',\n autoscroll: 'Desplazamiento automático',\n settingsMenu: 'Configuración del diálogo de transcripción',\n showTimestamps: 'Mostrar marcas de tiempo',\n hideTimestamps: 'Ocultar marcas de tiempo',\n showTimestampsAria: 'Mostrar marcas de tiempo en la transcripción',\n hideTimestampsAria: 'Ocultar marcas de tiempo en la transcripción',\n seekTo: 'Saltar a {time}'\n },\n settings: {\n title: 'Configuración',\n quality: 'Calidad',\n speed: 'Velocidad',\n captions: 'Subtítulos',\n language: 'Idioma',\n reset: 'Restablecer',\n close: 'Cerrar'\n },\n speeds: {\n normal: 'Normal'\n },\n time: {\n display: 'Visualización de tiempo',\n durationPrefix: 'Duración: ',\n of: 'de',\n hour: '{count} hora',\n hours: '{count} horas',\n minute: '{count} minuto',\n minutes: '{count} minutos',\n second: '{count} segundo',\n seconds: '{count} segundos'\n },\n resume: {\n prompt: '¿Continuar desde {time}?',\n resume: 'Continuar',\n startOver: 'Empezar de nuevo'\n },\n playlist: {\n title: 'Lista de reproducción',\n trackOf: 'Pista {current} de {total}',\n nowPlaying: 'Reproduciendo ahora: Pista {current} de {total}. {title}{artist}',\n by: ' por ',\n untitled: 'Sin título',\n trackUntitled: 'Pista {number}',\n currentlyPlaying: 'Reproduciendo actualmente',\n notPlaying: 'Sin reproducir',\n pressEnterPlay: 'Pulsa Enter para reproducir',\n pressEnterRestart: 'Pulsa Enter para reiniciar',\n keyboardInstructions: 'Navegación de lista de reproducción: Use las teclas de flecha arriba y abajo para moverse entre pistas. Pulse Retroceder página o Avanzar página para saltar 5 pistas. Pulse Inicio para ir a la primera pista, Fin para la última pista. Pulse Intro o Espacio para reproducir la pista seleccionada.',\n endOfPlaylist: 'Fin de la lista de reproducción. {current} de {total}.',\n beginningOfPlaylist: 'Inicio de la lista de reproducción. 1 de {total}.',\n jumpedToLastTrack: 'Saltó a la última pista. {current} de {total}.',\n jumpedToFirstTrack: 'Saltó a la primera pista. 1 de {total}.',\n firstTrack: 'Primera pista. 1 de {total}.',\n lastTrack: 'Última pista. {current} de {total}.'\n }\n};\n\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/dev/vidply.esm.js
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* VidPly v1.2.
|
|
2
|
+
* VidPly v1.2.1 - Universal, Accessible Video Player
|
|
3
3
|
* (c) 2026 Matthias Peltzer
|
|
4
4
|
* Released under GPL-2.0-or-later License
|
|
5
5
|
*/
|
|
6
6
|
import {
|
|
7
7
|
TimeUtils
|
|
8
|
-
} from "./vidply.chunk-
|
|
8
|
+
} from "./vidply.chunk-YVCYQZJI.js";
|
|
9
9
|
import {
|
|
10
10
|
createIconElement,
|
|
11
11
|
createPlayOverlay
|
|
12
|
-
} from "./vidply.chunk-
|
|
12
|
+
} from "./vidply.chunk-RQG3MA7W.js";
|
|
13
13
|
import {
|
|
14
14
|
focusElement
|
|
15
|
-
} from "./vidply.chunk-
|
|
15
|
+
} from "./vidply.chunk-JAKZNGOR.js";
|
|
16
16
|
import {
|
|
17
17
|
HTML5Renderer
|
|
18
|
-
} from "./vidply.chunk-
|
|
18
|
+
} from "./vidply.chunk-XAK3DPTO.js";
|
|
19
19
|
import {
|
|
20
20
|
CaptionManager
|
|
21
|
-
} from "./vidply.chunk-
|
|
21
|
+
} from "./vidply.chunk-LDVFAFGC.js";
|
|
22
22
|
import {
|
|
23
23
|
StorageManager
|
|
24
|
-
} from "./vidply.chunk-
|
|
24
|
+
} from "./vidply.chunk-UHMVDBDB.js";
|
|
25
25
|
import {
|
|
26
26
|
debounce,
|
|
27
27
|
isMobile,
|
|
28
28
|
rafWithTimeout,
|
|
29
29
|
reducedMotionScrollOptions,
|
|
30
30
|
throttle
|
|
31
|
-
} from "./vidply.chunk-
|
|
31
|
+
} from "./vidply.chunk-5IK3IC5V.js";
|
|
32
32
|
import {
|
|
33
33
|
DOMUtils,
|
|
34
34
|
i18n,
|
|
35
35
|
isForbiddenKey
|
|
36
|
-
} from "./vidply.chunk-
|
|
36
|
+
} from "./vidply.chunk-NSMAZCMB.js";
|
|
37
37
|
|
|
38
38
|
// src/utils/EventEmitter.ts
|
|
39
39
|
var EventEmitter = class {
|
|
@@ -2051,7 +2051,7 @@ var ControlBar = class {
|
|
|
2051
2051
|
return button;
|
|
2052
2052
|
}
|
|
2053
2053
|
showCaptionStyleMenu(button) {
|
|
2054
|
-
import("./vidply.CaptionStyleMenu-
|
|
2054
|
+
import("./vidply.CaptionStyleMenu-R2SCQ6VP.js").then(({ showCaptionStyleMenu }) => showCaptionStyleMenu(this, button)).catch((error) => this.player.log("Failed to load caption style menu:", error, "error"));
|
|
2055
2055
|
}
|
|
2056
2056
|
createSpeedButton() {
|
|
2057
2057
|
const button = DOMUtils.createElement("button", {
|
|
@@ -4700,21 +4700,21 @@ var SignLanguageManagerModule = null;
|
|
|
4700
4700
|
var FloatingPlayerManagerModule = null;
|
|
4701
4701
|
async function loadAudioDescriptionManager() {
|
|
4702
4702
|
if (!AudioDescriptionManagerModule) {
|
|
4703
|
-
const module = await import("./vidply.AudioDescriptionManager-
|
|
4703
|
+
const module = await import("./vidply.AudioDescriptionManager-6RFVF27Z.js");
|
|
4704
4704
|
AudioDescriptionManagerModule = module.AudioDescriptionManager;
|
|
4705
4705
|
}
|
|
4706
4706
|
return AudioDescriptionManagerModule;
|
|
4707
4707
|
}
|
|
4708
4708
|
async function loadSignLanguageManager() {
|
|
4709
4709
|
if (!SignLanguageManagerModule) {
|
|
4710
|
-
const module = await import("./vidply.SignLanguageManager-
|
|
4710
|
+
const module = await import("./vidply.SignLanguageManager-7IAJOVF6.js");
|
|
4711
4711
|
SignLanguageManagerModule = module.SignLanguageManager;
|
|
4712
4712
|
}
|
|
4713
4713
|
return SignLanguageManagerModule;
|
|
4714
4714
|
}
|
|
4715
4715
|
async function loadFloatingPlayerManager() {
|
|
4716
4716
|
if (!FloatingPlayerManagerModule) {
|
|
4717
|
-
const module = await import("./vidply.FloatingPlayerManager-
|
|
4717
|
+
const module = await import("./vidply.FloatingPlayerManager-V5XQWS75.js");
|
|
4718
4718
|
FloatingPlayerManagerModule = module.FloatingPlayerManager;
|
|
4719
4719
|
}
|
|
4720
4720
|
return FloatingPlayerManagerModule;
|
|
@@ -4967,6 +4967,9 @@ var Player = class _Player extends EventEmitter {
|
|
|
4967
4967
|
audioDescriptionSrc: null,
|
|
4968
4968
|
// URL to audio-described version
|
|
4969
4969
|
audioDescriptionButton: true,
|
|
4970
|
+
audioDescriptionMode: "auto",
|
|
4971
|
+
audioDescriptionSpeech: true,
|
|
4972
|
+
audioDescriptionExtended: true,
|
|
4970
4973
|
// Sign Language
|
|
4971
4974
|
signLanguage: true,
|
|
4972
4975
|
signLanguageSrc: null,
|
|
@@ -5364,7 +5367,7 @@ var Player = class _Player extends EventEmitter {
|
|
|
5364
5367
|
if (!this.options.transcript && !this.options.transcriptButton) {
|
|
5365
5368
|
return null;
|
|
5366
5369
|
}
|
|
5367
|
-
const module = await import("./vidply.TranscriptManager-
|
|
5370
|
+
const module = await import("./vidply.TranscriptManager-BPM3T23L.js");
|
|
5368
5371
|
const fallbackDefault = module.default;
|
|
5369
5372
|
const Manager = module.TranscriptManager || fallbackDefault;
|
|
5370
5373
|
if (!Manager) {
|
|
@@ -5392,15 +5395,33 @@ var Player = class _Player extends EventEmitter {
|
|
|
5392
5395
|
if (this.audioDescriptionManager) {
|
|
5393
5396
|
return this.audioDescriptionManager;
|
|
5394
5397
|
}
|
|
5395
|
-
|
|
5396
|
-
const hasAudioDescButton = this.options.audioDescriptionButton;
|
|
5397
|
-
if (!hasAudioDescSrc && !hasAudioDescButton) {
|
|
5398
|
+
if (!this.hasAudioDescriptionContent()) {
|
|
5398
5399
|
return null;
|
|
5399
5400
|
}
|
|
5400
5401
|
const AudioDescManager = await loadAudioDescriptionManager();
|
|
5401
5402
|
this.audioDescriptionManager = new AudioDescManager(this);
|
|
5402
5403
|
return this.audioDescriptionManager;
|
|
5403
5404
|
}
|
|
5405
|
+
/**
|
|
5406
|
+
* True when the current media actually exposes audio-description content:
|
|
5407
|
+
* an explicit described-audio source, `<source>` elements carrying
|
|
5408
|
+
* `data-desc-src` / `data-orig-src`, or a `descriptions` text track.
|
|
5409
|
+
* Mirrors `ControlBar.hasAudioDescription()` so the chunk load and the
|
|
5410
|
+
* button visibility stay in lock-step.
|
|
5411
|
+
*/
|
|
5412
|
+
hasAudioDescriptionContent() {
|
|
5413
|
+
if (this.options.audioDescriptionSrc || this.audioDescriptionSrc) {
|
|
5414
|
+
return true;
|
|
5415
|
+
}
|
|
5416
|
+
const hasSourceElementsWithDesc = this.sourceElements.some(
|
|
5417
|
+
(el) => el.getAttribute("data-desc-src") || el.getAttribute("data-orig-src")
|
|
5418
|
+
);
|
|
5419
|
+
if (hasSourceElementsWithDesc) {
|
|
5420
|
+
return true;
|
|
5421
|
+
}
|
|
5422
|
+
const textTracks = this.element ? Array.from(this.element.textTracks || []) : [];
|
|
5423
|
+
return textTracks.some((track) => track.kind === "descriptions");
|
|
5424
|
+
}
|
|
5404
5425
|
// ============================================
|
|
5405
5426
|
// Resume Playback Methods
|
|
5406
5427
|
// ============================================
|
|
@@ -5412,16 +5433,24 @@ var Player = class _Player extends EventEmitter {
|
|
|
5412
5433
|
if (this.signLanguageManager) {
|
|
5413
5434
|
return this.signLanguageManager;
|
|
5414
5435
|
}
|
|
5415
|
-
|
|
5416
|
-
const hasSignLangSources = this.options.signLanguageSources && Object.keys(this.options.signLanguageSources).length > 0;
|
|
5417
|
-
const hasSignLangButton = this.options.signLanguageButton;
|
|
5418
|
-
if (!hasSignLangSrc && !hasSignLangSources && !hasSignLangButton) {
|
|
5436
|
+
if (!this.hasSignLanguageContent()) {
|
|
5419
5437
|
return null;
|
|
5420
5438
|
}
|
|
5421
5439
|
const SignLangManager = await loadSignLanguageManager();
|
|
5422
5440
|
this.signLanguageManager = new SignLangManager(this);
|
|
5423
5441
|
return this.signLanguageManager;
|
|
5424
5442
|
}
|
|
5443
|
+
/**
|
|
5444
|
+
* True when a sign-language video source (single `signLanguageSrc` or a
|
|
5445
|
+
* `signLanguageSources` map) is configured. Mirrors
|
|
5446
|
+
* `ControlBar.hasSignLanguage()`.
|
|
5447
|
+
*/
|
|
5448
|
+
hasSignLanguageContent() {
|
|
5449
|
+
if (this.options.signLanguageSrc || this.signLanguageSrc) {
|
|
5450
|
+
return true;
|
|
5451
|
+
}
|
|
5452
|
+
return !!(this.options.signLanguageSources && Object.keys(this.options.signLanguageSources).length > 0);
|
|
5453
|
+
}
|
|
5425
5454
|
/**
|
|
5426
5455
|
* Lazy-load and instantiate the floating (in-page PiP) manager. Only
|
|
5427
5456
|
* created when `options.floating === true` and the media element is a
|
|
@@ -5446,13 +5475,10 @@ var Player = class _Player extends EventEmitter {
|
|
|
5446
5475
|
*/
|
|
5447
5476
|
async initFeatureManagers() {
|
|
5448
5477
|
const promises = [];
|
|
5449
|
-
|
|
5450
|
-
(el) => el.getAttribute("data-desc-src") || el.getAttribute("data-orig-src")
|
|
5451
|
-
);
|
|
5452
|
-
if (this.options.audioDescriptionButton || this.options.audioDescriptionSrc || this.audioDescriptionSrc || hasSourceElementsWithDesc) {
|
|
5478
|
+
if (this.hasAudioDescriptionContent()) {
|
|
5453
5479
|
promises.push(this.ensureAudioDescriptionManager());
|
|
5454
5480
|
}
|
|
5455
|
-
if (this.
|
|
5481
|
+
if (this.hasSignLanguageContent()) {
|
|
5456
5482
|
promises.push(this.ensureSignLanguageManager());
|
|
5457
5483
|
}
|
|
5458
5484
|
if (this.options.floating && this.element && this.element.tagName === "VIDEO") {
|
|
@@ -5782,6 +5808,9 @@ var Player = class _Player extends EventEmitter {
|
|
|
5782
5808
|
}
|
|
5783
5809
|
this.currentSource = src;
|
|
5784
5810
|
this._pendingSource = null;
|
|
5811
|
+
if (this.hasAudioDescriptionContent()) {
|
|
5812
|
+
await this.ensureAudioDescriptionManager();
|
|
5813
|
+
}
|
|
5785
5814
|
this.audioDescriptionManager?.initFromSourceElements(this.sourceElements, this.trackElements);
|
|
5786
5815
|
if (!this.originalSrc) {
|
|
5787
5816
|
this.originalSrc = src;
|
|
@@ -5807,19 +5836,19 @@ var Player = class _Player extends EventEmitter {
|
|
|
5807
5836
|
}
|
|
5808
5837
|
async _detectRendererClass(src) {
|
|
5809
5838
|
if (src.includes("youtube.com") || src.includes("youtu.be")) {
|
|
5810
|
-
const module = await import("./vidply.YouTubeRenderer-
|
|
5839
|
+
const module = await import("./vidply.YouTubeRenderer-HRTN4EJ5.js");
|
|
5811
5840
|
return module.YouTubeRenderer ?? module.default;
|
|
5812
5841
|
} else if (src.includes("vimeo.com")) {
|
|
5813
|
-
const module = await import("./vidply.VimeoRenderer-
|
|
5842
|
+
const module = await import("./vidply.VimeoRenderer-BRHFYPNJ.js");
|
|
5814
5843
|
return module.VimeoRenderer ?? module.default;
|
|
5815
5844
|
} else if (src.includes(".m3u8")) {
|
|
5816
|
-
const module = await import("./vidply.HLSRenderer-
|
|
5845
|
+
const module = await import("./vidply.HLSRenderer-ZBEFVH5W.js");
|
|
5817
5846
|
return module.HLSRenderer ?? module.default;
|
|
5818
5847
|
} else if (src.includes(".mpd")) {
|
|
5819
|
-
const module = await import("./vidply.DASHRenderer-
|
|
5848
|
+
const module = await import("./vidply.DASHRenderer-EOVEW73H.js");
|
|
5820
5849
|
return module.DASHRenderer ?? module.default;
|
|
5821
5850
|
} else if (src.includes("soundcloud.com") || src.includes("api.soundcloud.com")) {
|
|
5822
|
-
const module = await import("./vidply.SoundCloudRenderer-
|
|
5851
|
+
const module = await import("./vidply.SoundCloudRenderer-OA7QQYGN.js");
|
|
5823
5852
|
return module.SoundCloudRenderer ?? module.default;
|
|
5824
5853
|
}
|
|
5825
5854
|
return HTML5Renderer;
|
|
@@ -7285,12 +7314,19 @@ var PlaylistManager = class {
|
|
|
7285
7314
|
if (typeof this.player.invalidateTrackCache === "function") {
|
|
7286
7315
|
this.player.invalidateTrackCache();
|
|
7287
7316
|
}
|
|
7288
|
-
|
|
7317
|
+
const reinitAudioDescription = (adm) => {
|
|
7318
|
+
if (!adm || typeof adm.initFromSourceElements !== "function") return;
|
|
7289
7319
|
try {
|
|
7290
|
-
|
|
7291
|
-
|
|
7320
|
+
adm.captionTracks = [];
|
|
7321
|
+
adm.initFromSourceElements(this.player.sourceElements, this.player.trackElements);
|
|
7292
7322
|
} catch {
|
|
7293
7323
|
}
|
|
7324
|
+
};
|
|
7325
|
+
if (this.player.audioDescriptionManager) {
|
|
7326
|
+
reinitAudioDescription(this.player.audioDescriptionManager);
|
|
7327
|
+
} else if (this.player.hasAudioDescriptionContent?.()) {
|
|
7328
|
+
void this.player.ensureAudioDescriptionManager().then(reinitAudioDescription).catch(() => {
|
|
7329
|
+
});
|
|
7294
7330
|
}
|
|
7295
7331
|
if (this.player.captionManager && typeof this.player.captionManager.loadTracks === "function") {
|
|
7296
7332
|
try {
|
|
@@ -8152,6 +8188,9 @@ function parseDataAttributes(dataset) {
|
|
|
8152
8188
|
signLanguageDisplayMode: "signLanguageDisplayMode",
|
|
8153
8189
|
audioDescriptionSrc: "audioDescriptionSrc",
|
|
8154
8190
|
audioDescriptionButton: "audioDescriptionButton",
|
|
8191
|
+
audioDescriptionMode: "audioDescriptionMode",
|
|
8192
|
+
audioDescriptionSpeech: "audioDescriptionSpeech",
|
|
8193
|
+
audioDescriptionExtended: "audioDescriptionExtended",
|
|
8155
8194
|
autoplay: "autoplay",
|
|
8156
8195
|
loop: "loop",
|
|
8157
8196
|
muted: "muted",
|