@hanifhan1f/vidstack 1.12.26 → 1.12.27

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.
Files changed (76) hide show
  1. package/cdn/chunks/vidstack-Bpnl-N6k.js +1 -0
  2. package/cdn/chunks/vidstack-CqzAnF2W.js +16 -0
  3. package/cdn/vidstack.js +1 -1
  4. package/cdn/with-layouts/chunks/vidstack-BD5YoTt5.js +937 -0
  5. package/cdn/with-layouts/chunks/vidstack-DCaNJN4T.js +1 -0
  6. package/cdn/with-layouts/vidstack.js +1 -1
  7. package/dev/chunks/vidstack--aukHYxl.js +1520 -0
  8. package/dev/chunks/vidstack-B__DfQsT.js +1621 -0
  9. package/dev/chunks/vidstack-BoLIUOyq.js +204 -0
  10. package/dev/chunks/vidstack-Crz0ROkT.js +3009 -0
  11. package/dev/chunks/vidstack-D-sqb6YI.js +308 -0
  12. package/dev/chunks/vidstack-Dco6kA4h.js +104 -0
  13. package/dev/chunks/vidstack-DpS0Kt4b.js +297 -0
  14. package/dev/chunks/vidstack-zJT-7ncH.js +5182 -0
  15. package/dev/define/plyr-layout.js +3 -4
  16. package/dev/define/templates/vidstack-audio-layout.js +4 -4
  17. package/dev/define/templates/vidstack-video-layout.js +4 -4
  18. package/dev/define/vidstack-player-default-layout.js +4 -4
  19. package/dev/define/vidstack-player-layouts.js +4 -4
  20. package/dev/define/vidstack-player-ui.js +5 -6
  21. package/dev/define/vidstack-player.js +3 -4
  22. package/dev/global/plyr.js +5 -6
  23. package/dev/global/vidstack-player.js +3 -4
  24. package/dev/providers/vidstack-dash.js +1 -2
  25. package/dev/providers/vidstack-hls.js +1 -2
  26. package/dev/providers/vidstack-video.js +1 -2
  27. package/dev/providers/vidstack-vimeo.js +1 -2
  28. package/dev/vidstack-elements.js +8 -9
  29. package/dev/vidstack.js +6 -7
  30. package/package.json +2 -1
  31. package/prod/chunks/vidstack-BVSJtdRd.js +297 -0
  32. package/prod/chunks/vidstack-BnEo_Sla.js +1621 -0
  33. package/prod/chunks/vidstack-CLTPjjXX.js +4772 -0
  34. package/prod/chunks/vidstack-CSHHV2zO.js +201 -0
  35. package/prod/chunks/vidstack-Eo46ZHu7.js +2999 -0
  36. package/prod/chunks/vidstack-sP7TQMB1.js +300 -0
  37. package/prod/chunks/vidstack-uVm3xX8H.js +104 -0
  38. package/prod/chunks/vidstack-zknLxihl.js +1520 -0
  39. package/prod/define/plyr-layout.js +3 -4
  40. package/prod/define/templates/vidstack-audio-layout.js +4 -4
  41. package/prod/define/templates/vidstack-video-layout.js +4 -4
  42. package/prod/define/vidstack-player-default-layout.js +4 -4
  43. package/prod/define/vidstack-player-layouts.js +4 -4
  44. package/prod/define/vidstack-player-ui.js +5 -6
  45. package/prod/define/vidstack-player.js +3 -4
  46. package/prod/global/plyr.js +5 -6
  47. package/prod/global/vidstack-player.js +3 -4
  48. package/prod/providers/vidstack-dash.js +1 -2
  49. package/prod/providers/vidstack-hls.js +1 -2
  50. package/prod/providers/vidstack-video.js +1 -2
  51. package/prod/providers/vidstack-vimeo.js +1 -2
  52. package/prod/vidstack-elements.js +8 -9
  53. package/prod/vidstack.js +6 -7
  54. package/server/chunks/vidstack-B3eA67nX.js +205 -0
  55. package/server/chunks/vidstack-BK4xGWUK.js +207 -0
  56. package/server/chunks/vidstack-BaXvZgx2.js +141 -0
  57. package/server/chunks/vidstack-BlvJg_5A.js +4636 -0
  58. package/server/chunks/vidstack-CBhikwSz.js +67 -0
  59. package/server/chunks/vidstack-COczNXom.js +3059 -0
  60. package/server/chunks/vidstack-CyZPtpwO.js +1503 -0
  61. package/server/chunks/vidstack-Dh1ZDEI-.js +29 -0
  62. package/server/chunks/vidstack-Dm-ETAZh.js +295 -0
  63. package/server/chunks/vidstack-NpAD9hfP.js +620 -0
  64. package/server/chunks/vidstack-O4BgIcQI.js +104 -0
  65. package/server/chunks/vidstack-n4zAyLEV.js +2139 -0
  66. package/server/chunks/vidstack-za5Yh5DQ.js +566 -0
  67. package/server/chunks/vidstack-zoXyfYxa.js +107 -0
  68. package/server/define/plyr-layout.js +7 -7
  69. package/server/define/vidstack-player-default-layout.js +3 -3
  70. package/server/define/vidstack-player-layouts.js +5 -5
  71. package/server/define/vidstack-player-ui.js +6 -6
  72. package/server/define/vidstack-player.js +4 -4
  73. package/server/global/plyr.js +9 -9
  74. package/server/global/vidstack-player.js +4 -4
  75. package/server/vidstack-elements.js +13 -13
  76. package/server/vidstack.js +8 -8
@@ -0,0 +1,308 @@
1
+ import { listenEvent, scoped, isString, getScope, EventsTarget, DOMEvent, isArray, isNumber } from './vidstack-C1PwJD_4.js';
2
+ import { getRequestCredentials } from './vidstack-DdTXMZro.js';
3
+
4
+ const CROSS_ORIGIN = Symbol("TEXT_TRACK_CROSS_ORIGIN" ), READY_STATE = Symbol("TEXT_TRACK_READY_STATE" ), UPDATE_ACTIVE_CUES = Symbol("TEXT_TRACK_UPDATE_ACTIVE_CUES" ), CAN_LOAD = Symbol("TEXT_TRACK_CAN_LOAD" ), ON_MODE_CHANGE = Symbol("TEXT_TRACK_ON_MODE_CHANGE" ), NATIVE = Symbol("TEXT_TRACK_NATIVE" ), NATIVE_HLS = Symbol("TEXT_TRACK_NATIVE_HLS" );
5
+ const TextTrackSymbol = {
6
+ crossOrigin: CROSS_ORIGIN,
7
+ readyState: READY_STATE,
8
+ updateActiveCues: UPDATE_ACTIVE_CUES,
9
+ canLoad: CAN_LOAD,
10
+ onModeChange: ON_MODE_CHANGE,
11
+ native: NATIVE,
12
+ nativeHLS: NATIVE_HLS
13
+ };
14
+
15
+ function findActiveCue(cues, time) {
16
+ for (let i = 0, len = cues.length; i < len; i++) {
17
+ if (isCueActive(cues[i], time)) return cues[i];
18
+ }
19
+ return null;
20
+ }
21
+ function isCueActive(cue, time) {
22
+ return time >= cue.startTime && time < cue.endTime;
23
+ }
24
+ function watchActiveTextTrack(tracks, kind, onChange) {
25
+ let currentTrack = null, scope = getScope();
26
+ function onModeChange() {
27
+ const kinds = isString(kind) ? [kind] : kind, track = tracks.toArray().find((track2) => kinds.includes(track2.kind) && track2.mode === "showing");
28
+ if (track === currentTrack) return;
29
+ if (!track) {
30
+ onChange(null);
31
+ currentTrack = null;
32
+ return;
33
+ }
34
+ if (track.readyState == 2) {
35
+ onChange(track);
36
+ } else {
37
+ onChange(null);
38
+ scoped(() => {
39
+ const off = listenEvent(
40
+ track,
41
+ "load",
42
+ () => {
43
+ onChange(track);
44
+ off();
45
+ },
46
+ { once: true }
47
+ );
48
+ }, scope);
49
+ }
50
+ currentTrack = track;
51
+ }
52
+ onModeChange();
53
+ return listenEvent(tracks, "mode-change", onModeChange);
54
+ }
55
+ function watchCueTextChange(tracks, kind, callback) {
56
+ watchActiveTextTrack(tracks, kind, (track) => {
57
+ if (!track) {
58
+ callback("");
59
+ return;
60
+ }
61
+ const onCueChange = () => {
62
+ const activeCue = track?.activeCues[0];
63
+ callback(activeCue?.text || "");
64
+ };
65
+ onCueChange();
66
+ listenEvent(track, "cue-change", onCueChange);
67
+ });
68
+ }
69
+
70
+ class TextTrack extends EventsTarget {
71
+ static createId(track) {
72
+ return `vds-${track.type}-${track.kind}-${track.src ?? track.label ?? "?"}`;
73
+ }
74
+ src;
75
+ content;
76
+ type;
77
+ encoding;
78
+ id = "";
79
+ label = "";
80
+ language = "";
81
+ kind;
82
+ default = false;
83
+ #canLoad = false;
84
+ #currentTime = 0;
85
+ #mode = "disabled";
86
+ #metadata = {};
87
+ #regions = [];
88
+ #cues = [];
89
+ #activeCues = [];
90
+ #cueIds = /* @__PURE__ */ new Set();
91
+ /** @internal */
92
+ [TextTrackSymbol.readyState] = 0;
93
+ /** @internal */
94
+ [TextTrackSymbol.crossOrigin];
95
+ /** @internal */
96
+ [TextTrackSymbol.onModeChange] = null;
97
+ /** @internal */
98
+ [TextTrackSymbol.native] = null;
99
+ get metadata() {
100
+ return this.#metadata;
101
+ }
102
+ get regions() {
103
+ return this.#regions;
104
+ }
105
+ get cues() {
106
+ return this.#cues;
107
+ }
108
+ get activeCues() {
109
+ return this.#activeCues;
110
+ }
111
+ /**
112
+ * - 0: Not Loading
113
+ * - 1: Loading
114
+ * - 2: Ready
115
+ * - 3: Error
116
+ */
117
+ get readyState() {
118
+ return this[TextTrackSymbol.readyState];
119
+ }
120
+ get mode() {
121
+ return this.#mode;
122
+ }
123
+ set mode(mode) {
124
+ this.setMode(mode);
125
+ }
126
+ constructor(init) {
127
+ super();
128
+ for (const prop of Object.keys(init)) this[prop] = init[prop];
129
+ if (!this.type) this.type = "vtt";
130
+ if (init.content) {
131
+ this.#parseContent(init);
132
+ } else if (!init.src) {
133
+ this[TextTrackSymbol.readyState] = 2;
134
+ }
135
+ if (isTrackCaptionKind(this) && !this.label) {
136
+ console.warn(`[vidstack] captions text track created without label: \`${this.src}\``);
137
+ }
138
+ }
139
+ addCue(cue, trigger) {
140
+ if (cue.id) {
141
+ if (this.#cueIds.has(cue.id)) return;
142
+ this.#cueIds.add(cue.id);
143
+ }
144
+ let i = 0, length = this.#cues.length;
145
+ for (i = 0; i < length; i++) if (cue.endTime <= this.#cues[i].startTime) break;
146
+ if (i === length) this.#cues.push(cue);
147
+ else this.#cues.splice(i, 0, cue);
148
+ if (!(cue instanceof TextTrackCue)) {
149
+ this[TextTrackSymbol.native]?.track.addCue(cue);
150
+ }
151
+ this.dispatchEvent(new DOMEvent("add-cue", { detail: cue, trigger }));
152
+ if (isCueActive(cue, this.#currentTime)) {
153
+ this[TextTrackSymbol.updateActiveCues](this.#currentTime, trigger);
154
+ }
155
+ }
156
+ removeCue(cue, trigger) {
157
+ const index = this.#cues.indexOf(cue);
158
+ if (index >= 0) {
159
+ const isActive = this.#activeCues.includes(cue);
160
+ if (cue.id) this.#cueIds.delete(cue.id);
161
+ this.#cues.splice(index, 1);
162
+ this[TextTrackSymbol.native]?.track.removeCue(cue);
163
+ this.dispatchEvent(new DOMEvent("remove-cue", { detail: cue, trigger }));
164
+ if (isActive) {
165
+ this[TextTrackSymbol.updateActiveCues](this.#currentTime, trigger);
166
+ }
167
+ }
168
+ }
169
+ setMode(mode, trigger) {
170
+ if (this.#mode === mode) return;
171
+ this.#mode = mode;
172
+ if (mode === "disabled") {
173
+ this.#activeCues = [];
174
+ this.#activeCuesChanged();
175
+ } else if (this.readyState === 2) {
176
+ this[TextTrackSymbol.updateActiveCues](this.#currentTime, trigger);
177
+ } else {
178
+ this.#load();
179
+ }
180
+ this.dispatchEvent(new DOMEvent("mode-change", { detail: this, trigger }));
181
+ this[TextTrackSymbol.onModeChange]?.();
182
+ }
183
+ /** @internal */
184
+ [TextTrackSymbol.updateActiveCues](currentTime, trigger) {
185
+ this.#currentTime = currentTime;
186
+ if (this.mode === "disabled" || !this.#cues.length) return;
187
+ const activeCues = [];
188
+ for (let i = 0, length = this.#cues.length; i < length; i++) {
189
+ const cue = this.#cues[i];
190
+ if (isCueActive(cue, currentTime)) activeCues.push(cue);
191
+ }
192
+ let changed = activeCues.length !== this.#activeCues.length;
193
+ if (!changed) {
194
+ for (let i = 0; i < activeCues.length; i++) {
195
+ if (!this.#activeCues.includes(activeCues[i])) {
196
+ changed = true;
197
+ break;
198
+ }
199
+ }
200
+ }
201
+ this.#activeCues = activeCues;
202
+ if (changed) this.#activeCuesChanged(trigger);
203
+ }
204
+ /** @internal */
205
+ [TextTrackSymbol.canLoad]() {
206
+ this.#canLoad = true;
207
+ if (this.#mode !== "disabled") this.#load();
208
+ }
209
+ #parseContent(init) {
210
+ import('media-captions').then(({ parseText, VTTCue, VTTRegion }) => {
211
+ if (!isString(init.content) || init.type === "json") {
212
+ this.#parseJSON(init.content, VTTCue, VTTRegion);
213
+ if (this.readyState !== 3) this.#ready();
214
+ } else {
215
+ const content = init.content.split("\n").map((line) => line.trim()).join("\n").trim();
216
+ parseText(content, { type: init.type }).then(({ cues, regions }) => {
217
+ this.#cues = cues;
218
+ this.#regions = regions;
219
+ this.#ready();
220
+ });
221
+ }
222
+ });
223
+ }
224
+ async #load() {
225
+ if (!this.#canLoad || this[TextTrackSymbol.readyState] > 0) return;
226
+ this[TextTrackSymbol.readyState] = 1;
227
+ this.dispatchEvent(new DOMEvent("load-start"));
228
+ if (!this.src) {
229
+ this.#ready();
230
+ return;
231
+ }
232
+ try {
233
+ const { parseResponse, VTTCue, VTTRegion } = await import('media-captions'), crossOrigin = this[TextTrackSymbol.crossOrigin]?.();
234
+ const response = fetch(this.src, {
235
+ headers: this.type === "json" ? { "Content-Type": "application/json" } : void 0,
236
+ credentials: getRequestCredentials(crossOrigin)
237
+ });
238
+ if (this.type === "json") {
239
+ this.#parseJSON(await (await response).text(), VTTCue, VTTRegion);
240
+ } else {
241
+ const { errors, metadata, regions, cues } = await parseResponse(response, {
242
+ type: this.type,
243
+ encoding: this.encoding
244
+ });
245
+ if (errors[0]?.code === 0) {
246
+ throw errors[0];
247
+ } else {
248
+ this.#metadata = metadata;
249
+ this.#regions = regions;
250
+ this.#cues = cues;
251
+ }
252
+ }
253
+ this.#ready();
254
+ } catch (error) {
255
+ this.#error(error);
256
+ }
257
+ }
258
+ #ready() {
259
+ this[TextTrackSymbol.readyState] = 2;
260
+ if (!this.src || this.type !== "vtt") {
261
+ const native = this[TextTrackSymbol.native];
262
+ if (native && !native.managed) {
263
+ for (const cue of this.#cues) native.track.addCue(cue);
264
+ }
265
+ }
266
+ const loadEvent = new DOMEvent("load");
267
+ this[TextTrackSymbol.updateActiveCues](this.#currentTime, loadEvent);
268
+ this.dispatchEvent(loadEvent);
269
+ }
270
+ #error(error) {
271
+ this[TextTrackSymbol.readyState] = 3;
272
+ this.dispatchEvent(new DOMEvent("error", { detail: error }));
273
+ }
274
+ #parseJSON(json, VTTCue, VTTRegion) {
275
+ try {
276
+ const { regions, cues } = parseJSONCaptionsFile(json, VTTCue, VTTRegion);
277
+ this.#regions = regions;
278
+ this.#cues = cues;
279
+ } catch (error) {
280
+ {
281
+ console.error(`[vidstack] failed to parse JSON captions at: \`${this.src}\`
282
+
283
+ `, error);
284
+ }
285
+ this.#error(error);
286
+ }
287
+ }
288
+ #activeCuesChanged(trigger) {
289
+ this.dispatchEvent(new DOMEvent("cue-change", { trigger }));
290
+ }
291
+ }
292
+ const captionRE = /captions|subtitles/;
293
+ function isTrackCaptionKind(track) {
294
+ return captionRE.test(track.kind);
295
+ }
296
+ function parseJSONCaptionsFile(json, Cue, Region) {
297
+ const content = isString(json) ? JSON.parse(json) : json;
298
+ let regions = [], cues = [];
299
+ if (content.regions && Region) {
300
+ regions = content.regions.map((region) => Object.assign(new Region(), region));
301
+ }
302
+ if (content.cues || isArray(content)) {
303
+ cues = (isArray(content) ? content : content.cues).filter((content2) => isNumber(content2.startTime) && isNumber(content2.endTime)).map((cue) => Object.assign(new Cue(0, 0, ""), cue));
304
+ }
305
+ return { regions, cues };
306
+ }
307
+
308
+ export { TextTrack, TextTrackSymbol, findActiveCue, isCueActive, isTrackCaptionKind, parseJSONCaptionsFile, watchActiveTextTrack, watchCueTextChange };
@@ -0,0 +1,104 @@
1
+ import { Host, effect, setAttribute, computed } from './vidstack-C1PwJD_4.js';
2
+ import { MediaProvider, MediaPlayer } from './vidstack-zJT-7ncH.js';
3
+ import { useMediaContext } from './vidstack-BjxlZzGu.js';
4
+
5
+ class MediaProviderElement extends Host(HTMLElement, MediaProvider) {
6
+ static tagName = "media-provider";
7
+ #media;
8
+ #target = null;
9
+ #blocker = null;
10
+ onSetup() {
11
+ this.#media = useMediaContext();
12
+ this.setAttribute("keep-alive", "");
13
+ }
14
+ onDestroy() {
15
+ this.#blocker?.remove();
16
+ this.#blocker = null;
17
+ this.#target?.remove();
18
+ this.#target = null;
19
+ }
20
+ onConnect() {
21
+ effect(() => {
22
+ const loader = this.$state.loader(), isYouTubeEmbed = loader?.name === "youtube", isVimeoEmbed = loader?.name === "vimeo", isEmbed = isYouTubeEmbed || isVimeoEmbed, isGoogleCast = loader?.name === "google-cast";
23
+ const target = loader ? isGoogleCast ? this.#createGoogleCastContainer() : isEmbed ? this.#createIFrame() : loader.mediaType() === "audio" ? this.#createAudio() : this.#createVideo() : null;
24
+ if (this.#target !== target) {
25
+ const parent = this.#target?.parentElement ?? this;
26
+ this.#target?.remove();
27
+ this.#target = target;
28
+ if (target) parent.prepend(target);
29
+ if (isEmbed && target) {
30
+ effect(() => {
31
+ const { nativeControls, viewType } = this.#media.$state, showNativeControls = nativeControls(), isAudioView = viewType() === "audio", showBlocker = !showNativeControls && !isAudioView;
32
+ if (showBlocker) {
33
+ this.#blocker = this.querySelector(".vds-blocker");
34
+ if (!this.#blocker) {
35
+ this.#blocker = document.createElement("div");
36
+ this.#blocker.classList.add("vds-blocker");
37
+ target.after(this.#blocker);
38
+ }
39
+ } else {
40
+ this.#blocker?.remove();
41
+ this.#blocker = null;
42
+ }
43
+ setAttribute(target, "data-no-controls", !showNativeControls);
44
+ });
45
+ }
46
+ }
47
+ if (isYouTubeEmbed) target?.classList.add("vds-youtube");
48
+ else if (isVimeoEmbed) target?.classList.add("vds-vimeo");
49
+ if (!isEmbed) {
50
+ this.#blocker?.remove();
51
+ this.#blocker = null;
52
+ }
53
+ this.load(target);
54
+ });
55
+ }
56
+ #createAudio() {
57
+ const audio = this.#target instanceof HTMLAudioElement ? this.#target : document.createElement("audio");
58
+ const { controls, crossOrigin } = this.#media.$state;
59
+ effect(() => {
60
+ setAttribute(audio, "controls", controls());
61
+ setAttribute(audio, "crossorigin", crossOrigin());
62
+ });
63
+ return audio;
64
+ }
65
+ #createVideo() {
66
+ const video = this.#target instanceof HTMLVideoElement ? this.#target : document.createElement("video");
67
+ const { crossOrigin, poster, nativeControls } = this.#media.$state, $controls = computed(() => nativeControls() ? "true" : null), $poster = computed(() => poster() && nativeControls() ? poster() : null);
68
+ effect(() => {
69
+ setAttribute(video, "controls", $controls());
70
+ setAttribute(video, "crossorigin", crossOrigin());
71
+ setAttribute(video, "poster", $poster());
72
+ });
73
+ return video;
74
+ }
75
+ #createIFrame() {
76
+ const iframe = this.#target instanceof HTMLIFrameElement ? this.#target : document.createElement("iframe"), { nativeControls } = this.#media.$state;
77
+ effect(() => setAttribute(iframe, "tabindex", !nativeControls() ? -1 : null));
78
+ return iframe;
79
+ }
80
+ #createGoogleCastContainer() {
81
+ if (this.#target?.classList.contains("vds-google-cast")) {
82
+ return this.#target;
83
+ }
84
+ const container = document.createElement("div");
85
+ container.classList.add("vds-google-cast");
86
+ import('./vidstack-Bf6x4gWe.js').then(({ insertContent }) => {
87
+ insertContent(container, this.#media.$state);
88
+ });
89
+ return container;
90
+ }
91
+ }
92
+
93
+ class MediaPlayerElement extends Host(HTMLElement, MediaPlayer) {
94
+ static tagName = "media-player";
95
+ static attrs = {
96
+ autoPlay: "autoplay",
97
+ crossOrigin: "crossorigin",
98
+ playsInline: "playsinline",
99
+ preferNativeHLS: "prefer-native-hls",
100
+ minLiveDVRWindow: "min-live-dvr-window"
101
+ };
102
+ }
103
+
104
+ export { MediaPlayerElement, MediaProviderElement };
@@ -0,0 +1,297 @@
1
+ import { Host, effect, Component, signal, setAttribute, isBoolean, computed, isString, useState } from './vidstack-C1PwJD_4.js';
2
+ import { Captions, Gesture, MediaAnnouncer, Controls, ControlsGroup, GoogleCastButton, ToggleButton, Tooltip, TooltipTrigger, TooltipContent, ChaptersRadioGroup, AudioGainRadioGroup, RadioGroup, SliderVideo, AudioGainSlider, SpeedSlider, QualitySlider, SliderChapters } from './vidstack--aukHYxl.js';
3
+ import { useMediaContext } from './vidstack-BjxlZzGu.js';
4
+ import { watchCueTextChange } from './vidstack-D-sqb6YI.js';
5
+ import { html } from 'lit-html';
6
+ import { requestScopedAnimationFrame, isHTMLElement, cloneTemplateContent, createTemplate, cloneTemplate } from './vidstack-C0SWkbs7.js';
7
+ import { LitElement } from './vidstack-CwTj4H1w.js';
8
+ import { MenuPortal, Slider, sliderState } from './vidstack-Crz0ROkT.js';
9
+ import { renderMenuItemsTemplate } from './vidstack-BoLIUOyq.js';
10
+
11
+ class MediaCaptionsElement extends Host(HTMLElement, Captions) {
12
+ static tagName = "media-captions";
13
+ }
14
+
15
+ class MediaGestureElement extends Host(HTMLElement, Gesture) {
16
+ static tagName = "media-gesture";
17
+ }
18
+
19
+ class MediaAnnouncerElement extends Host(HTMLElement, MediaAnnouncer) {
20
+ static tagName = "media-announcer";
21
+ }
22
+
23
+ class MediaControlsElement extends Host(HTMLElement, Controls) {
24
+ static tagName = "media-controls";
25
+ }
26
+
27
+ class MediaControlsGroupElement extends Host(HTMLElement, ControlsGroup) {
28
+ static tagName = "media-controls-group";
29
+ }
30
+
31
+ class Title extends Component {
32
+ }
33
+ class MediaTitleElement extends Host(HTMLElement, Title) {
34
+ static tagName = "media-title";
35
+ #media;
36
+ onSetup() {
37
+ this.#media = useMediaContext();
38
+ }
39
+ onConnect() {
40
+ effect(this.#watchTitle.bind(this));
41
+ }
42
+ #watchTitle() {
43
+ const { title } = this.#media.$state;
44
+ this.textContent = title();
45
+ }
46
+ }
47
+
48
+ class ChapterTitle extends Component {
49
+ static props = {
50
+ defaultText: ""
51
+ };
52
+ }
53
+ class MediaChapterTitleElement extends Host(HTMLElement, ChapterTitle) {
54
+ static tagName = "media-chapter-title";
55
+ #media;
56
+ #chapterTitle;
57
+ onSetup() {
58
+ this.#media = useMediaContext();
59
+ this.#chapterTitle = signal("");
60
+ }
61
+ onConnect() {
62
+ const tracks = this.#media.textTracks;
63
+ watchCueTextChange(tracks, "chapters", this.#chapterTitle.set);
64
+ effect(this.#watchChapterTitle.bind(this));
65
+ }
66
+ #watchChapterTitle() {
67
+ const { defaultText } = this.$props;
68
+ this.textContent = this.#chapterTitle() || defaultText();
69
+ }
70
+ }
71
+
72
+ class Spinner extends Component {
73
+ static props = {
74
+ size: 96,
75
+ trackWidth: 8,
76
+ fillPercent: 50
77
+ };
78
+ onConnect(el) {
79
+ requestScopedAnimationFrame(() => {
80
+ if (!this.connectScope) return;
81
+ const root = el.querySelector("svg"), track = root.firstElementChild, trackFill = track.nextElementSibling;
82
+ effect(this.#update.bind(this, root, track, trackFill));
83
+ });
84
+ }
85
+ #update(root, track, trackFill) {
86
+ const { size, trackWidth, fillPercent } = this.$props;
87
+ setAttribute(root, "width", size());
88
+ setAttribute(root, "height", size());
89
+ setAttribute(track, "stroke-width", trackWidth());
90
+ setAttribute(trackFill, "stroke-width", trackWidth());
91
+ setAttribute(trackFill, "stroke-dashoffset", 100 - fillPercent());
92
+ }
93
+ }
94
+ class MediaSpinnerElement extends Host(LitElement, Spinner) {
95
+ static tagName = "media-spinner";
96
+ render() {
97
+ return html`
98
+ <svg fill="none" viewBox="0 0 120 120" aria-hidden="true" data-part="root">
99
+ <circle cx="60" cy="60" r="54" stroke="currentColor" data-part="track"></circle>
100
+ <circle
101
+ cx="60"
102
+ cy="60"
103
+ r="54"
104
+ stroke="currentColor"
105
+ pathLength="100"
106
+ stroke-dasharray="100"
107
+ data-part="track-fill"
108
+ ></circle>
109
+ </svg>
110
+ `;
111
+ }
112
+ }
113
+
114
+ class MediaLayout extends Component {
115
+ static props = {
116
+ when: false
117
+ };
118
+ }
119
+ class MediaLayoutElement extends Host(HTMLElement, MediaLayout) {
120
+ static tagName = "media-layout";
121
+ #media;
122
+ onSetup() {
123
+ this.#media = useMediaContext();
124
+ }
125
+ onConnect() {
126
+ effect(this.#watchWhen.bind(this));
127
+ }
128
+ #watchWhen() {
129
+ const root = this.firstElementChild, isTemplate = root?.localName === "template", when = this.$props.when(), matches = isBoolean(when) ? when : computed(() => when(this.#media.player.state))();
130
+ if (!matches) {
131
+ if (isTemplate) {
132
+ this.textContent = "";
133
+ this.appendChild(root);
134
+ } else if (isHTMLElement(root)) {
135
+ root.style.display = "none";
136
+ }
137
+ return;
138
+ }
139
+ if (isTemplate) {
140
+ this.append(root.content.cloneNode(true));
141
+ } else if (isHTMLElement(root)) {
142
+ root.style.display = "";
143
+ }
144
+ }
145
+ }
146
+
147
+ class MediaGoogleCastButtonElement extends Host(HTMLElement, GoogleCastButton) {
148
+ static tagName = "media-google-cast-button";
149
+ }
150
+
151
+ class MediaToggleButtonElement extends Host(HTMLElement, ToggleButton) {
152
+ static tagName = "media-toggle-button";
153
+ }
154
+
155
+ class MediaTooltipElement extends Host(HTMLElement, Tooltip) {
156
+ static tagName = "media-tooltip";
157
+ }
158
+
159
+ class MediaTooltipTriggerElement extends Host(HTMLElement, TooltipTrigger) {
160
+ static tagName = "media-tooltip-trigger";
161
+ onConnect() {
162
+ this.style.display = "contents";
163
+ }
164
+ }
165
+
166
+ class MediaTooltipContentElement extends Host(HTMLElement, TooltipContent) {
167
+ static tagName = "media-tooltip-content";
168
+ }
169
+
170
+ class MediaMenuPortalElement extends Host(HTMLElement, MenuPortal) {
171
+ static tagName = "media-menu-portal";
172
+ static attrs = {
173
+ disabled: {
174
+ converter(value) {
175
+ if (isString(value)) return value;
176
+ return value !== null;
177
+ }
178
+ }
179
+ };
180
+ }
181
+
182
+ class MediaChaptersRadioGroupElement extends Host(HTMLElement, ChaptersRadioGroup) {
183
+ static tagName = "media-chapters-radio-group";
184
+ onConnect() {
185
+ renderMenuItemsTemplate(this, (el, option) => {
186
+ const { cue, startTime, duration } = option, thumbnailEl = el.querySelector(".vds-thumbnail,media-thumbnail"), startEl = el.querySelector('[data-part="start-time"]'), durationEl = el.querySelector('[data-part="duration"]');
187
+ if (startEl) startEl.textContent = startTime;
188
+ if (durationEl) durationEl.textContent = duration;
189
+ if (thumbnailEl) {
190
+ thumbnailEl.setAttribute("time", cue.startTime + "");
191
+ effect(() => {
192
+ const thumbnails = this.$props.thumbnails();
193
+ if ("src" in thumbnailEl) {
194
+ thumbnailEl.src = thumbnails;
195
+ } else if (isString(thumbnails)) {
196
+ thumbnailEl.setAttribute("src", thumbnails);
197
+ }
198
+ });
199
+ }
200
+ });
201
+ }
202
+ }
203
+
204
+ class MediaAudioGainRadioGroupElement extends Host(HTMLElement, AudioGainRadioGroup) {
205
+ static tagName = "media-audio-gain-radio-group";
206
+ onConnect() {
207
+ renderMenuItemsTemplate(this);
208
+ }
209
+ }
210
+
211
+ class MediaRadioGroupElement extends Host(HTMLElement, RadioGroup) {
212
+ static tagName = "media-radio-group";
213
+ }
214
+
215
+ class MediaSliderElement extends Host(HTMLElement, Slider) {
216
+ static tagName = "media-slider";
217
+ }
218
+
219
+ const videoTemplate = /* @__PURE__ */ createTemplate(
220
+ `<video muted playsinline preload="none" style="max-width: unset;"></video>`
221
+ );
222
+ class MediaSliderVideoElement extends Host(HTMLElement, SliderVideo) {
223
+ static tagName = "media-slider-video";
224
+ #media;
225
+ #video = this.#createVideo();
226
+ onSetup() {
227
+ this.#media = useMediaContext();
228
+ this.$state.video.set(this.#video);
229
+ }
230
+ onConnect() {
231
+ const { canLoad } = this.#media.$state, { src, crossOrigin } = this.$state;
232
+ if (this.#video.parentNode !== this) {
233
+ this.prepend(this.#video);
234
+ }
235
+ effect(() => {
236
+ setAttribute(this.#video, "crossorigin", crossOrigin());
237
+ setAttribute(this.#video, "preload", canLoad() ? "auto" : "none");
238
+ setAttribute(this.#video, "src", src());
239
+ });
240
+ }
241
+ #createVideo() {
242
+ return cloneTemplateContent(videoTemplate);
243
+ }
244
+ }
245
+
246
+ class MediaAudioGainSliderElement extends Host(HTMLElement, AudioGainSlider) {
247
+ static tagName = "media-audio-gain-slider";
248
+ }
249
+
250
+ class MediaSpeedSliderElement extends Host(HTMLElement, SpeedSlider) {
251
+ static tagName = "media-speed-slider";
252
+ }
253
+
254
+ class MediaQualitySliderElement extends Host(HTMLElement, QualitySlider) {
255
+ static tagName = "media-quality-slider";
256
+ }
257
+
258
+ class MediaSliderChaptersElement extends Host(HTMLElement, SliderChapters) {
259
+ static tagName = "media-slider-chapters";
260
+ #template = null;
261
+ onConnect() {
262
+ requestScopedAnimationFrame(() => {
263
+ if (!this.connectScope) return;
264
+ const template = this.querySelector("template");
265
+ if (template) {
266
+ this.#template = template;
267
+ effect(this.#renderTemplate.bind(this));
268
+ }
269
+ });
270
+ }
271
+ #renderTemplate() {
272
+ if (!this.#template) return;
273
+ const elements = cloneTemplate(this.#template, this.cues.length || 1);
274
+ this.setRefs(elements);
275
+ }
276
+ }
277
+
278
+ class SliderSteps extends Component {
279
+ }
280
+ class MediaSliderStepsElement extends Host(HTMLElement, SliderSteps) {
281
+ static tagName = "media-slider-steps";
282
+ #template = null;
283
+ onConnect(el) {
284
+ requestScopedAnimationFrame(() => {
285
+ if (!this.connectScope) return;
286
+ this.#template = el.querySelector("template");
287
+ if (this.#template) effect(this.#render.bind(this));
288
+ });
289
+ }
290
+ #render() {
291
+ if (!this.#template) return;
292
+ const { min, max, step } = useState(sliderState), steps = (max() - min()) / step();
293
+ cloneTemplate(this.#template, Math.floor(steps) + 1);
294
+ }
295
+ }
296
+
297
+ export { MediaAnnouncerElement, MediaAudioGainRadioGroupElement, MediaAudioGainSliderElement, MediaCaptionsElement, MediaChapterTitleElement, MediaChaptersRadioGroupElement, MediaControlsElement, MediaControlsGroupElement, MediaGestureElement, MediaGoogleCastButtonElement, MediaLayoutElement, MediaMenuPortalElement, MediaQualitySliderElement, MediaRadioGroupElement, MediaSliderChaptersElement, MediaSliderElement, MediaSliderStepsElement, MediaSliderVideoElement, MediaSpeedSliderElement, MediaSpinnerElement, MediaTitleElement, MediaToggleButtonElement, MediaTooltipContentElement, MediaTooltipElement, MediaTooltipTriggerElement };