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
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
type DefaultEventMap = Record<string, unknown>;
|
|
2
|
-
type Listener<T> = T extends void ? () => void : (data: T) => void;
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Generic typed event emitter. The `TEvents` parameter is constrained
|
|
6
|
-
* via the self-referential `Record<keyof TEvents, unknown>` so concrete
|
|
7
|
-
* event maps (like `PlayerEventMap`) can be used directly without
|
|
8
|
-
* adding a noisy `[key: string]: unknown` index signature, which would
|
|
9
|
-
* defeat the typo-protection that strongly typed event maps provide.
|
|
10
|
-
*/
|
|
11
|
-
export class EventEmitter<TEvents extends Record<keyof TEvents, unknown> = DefaultEventMap> {
|
|
12
|
-
private events: Partial<Record<keyof TEvents, Array<(...args: unknown[]) => void>>> = {};
|
|
13
|
-
|
|
14
|
-
on<K extends keyof TEvents>(event: K, listener: Listener<TEvents[K]>): this {
|
|
15
|
-
const listeners = this.events[event] ?? [];
|
|
16
|
-
listeners.push(listener as (...args: unknown[]) => void);
|
|
17
|
-
this.events[event] = listeners;
|
|
18
|
-
return this;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
once<K extends keyof TEvents>(event: K, listener: Listener<TEvents[K]>): this {
|
|
22
|
-
const onceListener = ((...args: unknown[]) => {
|
|
23
|
-
(listener as (...a: unknown[]) => void)(...args);
|
|
24
|
-
this.off(event, onceListener as Listener<TEvents[K]>);
|
|
25
|
-
}) as unknown as Listener<TEvents[K]>;
|
|
26
|
-
return this.on(event, onceListener);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
off<K extends keyof TEvents>(event: K, listener?: Listener<TEvents[K]>): this {
|
|
30
|
-
const listeners = this.events[event];
|
|
31
|
-
if (!listeners) return this;
|
|
32
|
-
|
|
33
|
-
if (!listener) {
|
|
34
|
-
delete this.events[event];
|
|
35
|
-
} else {
|
|
36
|
-
this.events[event] = listeners.filter(
|
|
37
|
-
l => l !== (listener as unknown)
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return this;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
emit<K extends keyof TEvents>(event: K, ...args: unknown[]): this {
|
|
45
|
-
const listeners = this.events[event];
|
|
46
|
-
if (!listeners) return this;
|
|
47
|
-
|
|
48
|
-
listeners.forEach(listener => {
|
|
49
|
-
listener(...args);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
return this;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
removeAllListeners(): this {
|
|
56
|
-
this.events = {};
|
|
57
|
-
return this;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
1
|
+
type DefaultEventMap = Record<string, unknown>;
|
|
2
|
+
type Listener<T> = T extends void ? () => void : (data: T) => void;
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generic typed event emitter. The `TEvents` parameter is constrained
|
|
6
|
+
* via the self-referential `Record<keyof TEvents, unknown>` so concrete
|
|
7
|
+
* event maps (like `PlayerEventMap`) can be used directly without
|
|
8
|
+
* adding a noisy `[key: string]: unknown` index signature, which would
|
|
9
|
+
* defeat the typo-protection that strongly typed event maps provide.
|
|
10
|
+
*/
|
|
11
|
+
export class EventEmitter<TEvents extends Record<keyof TEvents, unknown> = DefaultEventMap> {
|
|
12
|
+
private events: Partial<Record<keyof TEvents, Array<(...args: unknown[]) => void>>> = {};
|
|
13
|
+
|
|
14
|
+
on<K extends keyof TEvents>(event: K, listener: Listener<TEvents[K]>): this {
|
|
15
|
+
const listeners = this.events[event] ?? [];
|
|
16
|
+
listeners.push(listener as (...args: unknown[]) => void);
|
|
17
|
+
this.events[event] = listeners;
|
|
18
|
+
return this;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
once<K extends keyof TEvents>(event: K, listener: Listener<TEvents[K]>): this {
|
|
22
|
+
const onceListener = ((...args: unknown[]) => {
|
|
23
|
+
(listener as (...a: unknown[]) => void)(...args);
|
|
24
|
+
this.off(event, onceListener as Listener<TEvents[K]>);
|
|
25
|
+
}) as unknown as Listener<TEvents[K]>;
|
|
26
|
+
return this.on(event, onceListener);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
off<K extends keyof TEvents>(event: K, listener?: Listener<TEvents[K]>): this {
|
|
30
|
+
const listeners = this.events[event];
|
|
31
|
+
if (!listeners) return this;
|
|
32
|
+
|
|
33
|
+
if (!listener) {
|
|
34
|
+
delete this.events[event];
|
|
35
|
+
} else {
|
|
36
|
+
this.events[event] = listeners.filter(
|
|
37
|
+
l => l !== (listener as unknown)
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
emit<K extends keyof TEvents>(event: K, ...args: unknown[]): this {
|
|
45
|
+
const listeners = this.events[event];
|
|
46
|
+
if (!listeners) return this;
|
|
47
|
+
|
|
48
|
+
listeners.forEach(listener => {
|
|
49
|
+
listener(...args);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
return this;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
removeAllListeners(): this {
|
|
56
|
+
this.events = {};
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
}
|
package/src/utils/FormUtils.ts
CHANGED
|
@@ -1,95 +1,95 @@
|
|
|
1
|
-
import { DOMUtils } from './DOMUtils.js';
|
|
2
|
-
import { i18n } from '../i18n/i18n.js';
|
|
3
|
-
|
|
4
|
-
export interface SelectOption {
|
|
5
|
-
value: string;
|
|
6
|
-
text: string;
|
|
7
|
-
selected?: boolean;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface LabeledSelectOptions {
|
|
11
|
-
classPrefix: string;
|
|
12
|
-
labelClass: string;
|
|
13
|
-
selectClass: string;
|
|
14
|
-
labelText: string;
|
|
15
|
-
selectId: string;
|
|
16
|
-
hidden?: boolean;
|
|
17
|
-
onChange?: (e: Event) => void;
|
|
18
|
-
options?: SelectOption[];
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function createLabeledSelect({
|
|
22
|
-
classPrefix: _classPrefix,
|
|
23
|
-
labelClass,
|
|
24
|
-
selectClass,
|
|
25
|
-
labelText,
|
|
26
|
-
selectId,
|
|
27
|
-
hidden = false,
|
|
28
|
-
onChange = undefined,
|
|
29
|
-
options = []
|
|
30
|
-
}: LabeledSelectOptions): { label: HTMLLabelElement; select: HTMLSelectElement } {
|
|
31
|
-
const isI18nKey =
|
|
32
|
-
typeof labelText === 'string' &&
|
|
33
|
-
(labelText.startsWith('transcript.') ||
|
|
34
|
-
labelText.startsWith('player.') ||
|
|
35
|
-
labelText.startsWith('settings.') ||
|
|
36
|
-
labelText.startsWith('captions.'));
|
|
37
|
-
const labelTextContent = isI18nKey ? i18n.t(labelText) || labelText : labelText;
|
|
38
|
-
|
|
39
|
-
const label = DOMUtils.createElement('label', {
|
|
40
|
-
className: labelClass,
|
|
41
|
-
textContent: labelTextContent,
|
|
42
|
-
attributes: {
|
|
43
|
-
for: selectId,
|
|
44
|
-
style: hidden ? 'display: none;' : undefined
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
const select = DOMUtils.createElement('select', {
|
|
49
|
-
className: selectClass,
|
|
50
|
-
attributes: {
|
|
51
|
-
id: selectId,
|
|
52
|
-
style: hidden ? 'display: none;' : undefined
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
options.forEach(opt => {
|
|
57
|
-
const option = DOMUtils.createElement('option', {
|
|
58
|
-
textContent: opt.text,
|
|
59
|
-
attributes: {
|
|
60
|
-
value: opt.value,
|
|
61
|
-
selected: opt.selected ? 'selected' : undefined
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
select.appendChild(option);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
if (onChange) {
|
|
68
|
-
select.addEventListener('change', onChange);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return { label, select };
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export function toggleLabeledSelect(
|
|
75
|
-
label: HTMLElement | null,
|
|
76
|
-
select: HTMLElement | null,
|
|
77
|
-
show: boolean
|
|
78
|
-
): void {
|
|
79
|
-
if (label) {
|
|
80
|
-
label.style.display = show ? 'block' : 'none';
|
|
81
|
-
}
|
|
82
|
-
if (select) {
|
|
83
|
-
select.style.display = show ? 'block' : 'none';
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export function preventDragOnElement(element: HTMLElement | null): void {
|
|
88
|
-
if (!element) return;
|
|
89
|
-
|
|
90
|
-
(['pointerdown', 'mousedown', 'click'] as const).forEach(eventType => {
|
|
91
|
-
element.addEventListener(eventType, (e: Event) => {
|
|
92
|
-
e.stopPropagation();
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
}
|
|
1
|
+
import { DOMUtils } from './DOMUtils.js';
|
|
2
|
+
import { i18n } from '../i18n/i18n.js';
|
|
3
|
+
|
|
4
|
+
export interface SelectOption {
|
|
5
|
+
value: string;
|
|
6
|
+
text: string;
|
|
7
|
+
selected?: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface LabeledSelectOptions {
|
|
11
|
+
classPrefix: string;
|
|
12
|
+
labelClass: string;
|
|
13
|
+
selectClass: string;
|
|
14
|
+
labelText: string;
|
|
15
|
+
selectId: string;
|
|
16
|
+
hidden?: boolean;
|
|
17
|
+
onChange?: (e: Event) => void;
|
|
18
|
+
options?: SelectOption[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function createLabeledSelect({
|
|
22
|
+
classPrefix: _classPrefix,
|
|
23
|
+
labelClass,
|
|
24
|
+
selectClass,
|
|
25
|
+
labelText,
|
|
26
|
+
selectId,
|
|
27
|
+
hidden = false,
|
|
28
|
+
onChange = undefined,
|
|
29
|
+
options = []
|
|
30
|
+
}: LabeledSelectOptions): { label: HTMLLabelElement; select: HTMLSelectElement } {
|
|
31
|
+
const isI18nKey =
|
|
32
|
+
typeof labelText === 'string' &&
|
|
33
|
+
(labelText.startsWith('transcript.') ||
|
|
34
|
+
labelText.startsWith('player.') ||
|
|
35
|
+
labelText.startsWith('settings.') ||
|
|
36
|
+
labelText.startsWith('captions.'));
|
|
37
|
+
const labelTextContent = isI18nKey ? i18n.t(labelText) || labelText : labelText;
|
|
38
|
+
|
|
39
|
+
const label = DOMUtils.createElement('label', {
|
|
40
|
+
className: labelClass,
|
|
41
|
+
textContent: labelTextContent,
|
|
42
|
+
attributes: {
|
|
43
|
+
for: selectId,
|
|
44
|
+
style: hidden ? 'display: none;' : undefined
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const select = DOMUtils.createElement('select', {
|
|
49
|
+
className: selectClass,
|
|
50
|
+
attributes: {
|
|
51
|
+
id: selectId,
|
|
52
|
+
style: hidden ? 'display: none;' : undefined
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
options.forEach(opt => {
|
|
57
|
+
const option = DOMUtils.createElement('option', {
|
|
58
|
+
textContent: opt.text,
|
|
59
|
+
attributes: {
|
|
60
|
+
value: opt.value,
|
|
61
|
+
selected: opt.selected ? 'selected' : undefined
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
select.appendChild(option);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
if (onChange) {
|
|
68
|
+
select.addEventListener('change', onChange);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return { label, select };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function toggleLabeledSelect(
|
|
75
|
+
label: HTMLElement | null,
|
|
76
|
+
select: HTMLElement | null,
|
|
77
|
+
show: boolean
|
|
78
|
+
): void {
|
|
79
|
+
if (label) {
|
|
80
|
+
label.style.display = show ? 'block' : 'none';
|
|
81
|
+
}
|
|
82
|
+
if (select) {
|
|
83
|
+
select.style.display = show ? 'block' : 'none';
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function preventDragOnElement(element: HTMLElement | null): void {
|
|
88
|
+
if (!element) return;
|
|
89
|
+
|
|
90
|
+
(['pointerdown', 'mousedown', 'click'] as const).forEach(eventType => {
|
|
91
|
+
element.addEventListener(eventType, (e: Event) => {
|
|
92
|
+
e.stopPropagation();
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
}
|