@videojs/html 10.0.0-beta.16 → 10.0.0-beta.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cdn/{abort-CzqmAxxH.js → abort-BL-SGV3o.js} +1 -1
- package/cdn/{abort-CzqmAxxH.js.map → abort-BL-SGV3o.js.map} +1 -1
- package/cdn/{abort-KaHR4JO1.js → abort-DGNIECLn.js} +1 -1
- package/cdn/{abort-KaHR4JO1.js.map → abort-DGNIECLn.js.map} +1 -1
- package/cdn/audio-minimal-ui.dev.js +3 -3
- package/cdn/audio-minimal-ui.js +1 -1
- package/cdn/audio-minimal.dev.js +4 -4
- package/cdn/audio-minimal.js +1 -1
- package/cdn/audio-minimal.js.map +1 -1
- package/cdn/audio-ui.dev.js +3 -4
- package/cdn/audio-ui.js +1 -1
- package/cdn/audio.dev.js +4 -5
- package/cdn/audio.dev.js.map +1 -1
- package/cdn/audio.js +1 -1
- package/cdn/audio.js.map +1 -1
- package/cdn/background.dev.js +1 -1
- package/cdn/background.js +1 -1
- package/cdn/compounds-Df_1JbZD.js +8 -0
- package/cdn/compounds-Df_1JbZD.js.map +1 -0
- package/cdn/{volume-slider-C6ek7oC9.js → compounds-VFPcCeRV.js} +2784 -2760
- package/cdn/compounds-VFPcCeRV.js.map +1 -0
- package/cdn/{create-player-DckZq-sE.js → create-player-CyG77t-m.js} +1336 -1153
- package/cdn/create-player-CyG77t-m.js.map +1 -0
- package/cdn/create-player-Gom2ZZe3.js +7 -0
- package/cdn/create-player-Gom2ZZe3.js.map +1 -0
- package/cdn/{hls-lPH0rWmB.js → hls-BAbdl84H.js} +3 -3
- package/cdn/{hls-lPH0rWmB.js.map → hls-BAbdl84H.js.map} +1 -1
- package/cdn/{hls-CJCXZSGG.js → hls-BrzPpueW.js} +4 -4
- package/cdn/{hls-CJCXZSGG.js.map → hls-BrzPpueW.js.map} +1 -1
- package/cdn/hotkey-element-DR3ZAqKa.js +2 -0
- package/cdn/hotkey-element-DR3ZAqKa.js.map +1 -0
- package/cdn/hotkey-element-Dlta37Be.js +369 -0
- package/cdn/hotkey-element-Dlta37Be.js.map +1 -0
- package/cdn/media/dash-video.dev.js +1 -1
- package/cdn/media/dash-video.js +1 -1
- package/cdn/media/hls-video.dev.js +2 -2
- package/cdn/media/hls-video.js +1 -1
- package/cdn/media/mux-audio.dev.js +3 -3
- package/cdn/media/mux-audio.js +1 -1
- package/cdn/media/mux-video.dev.js +3 -3
- package/cdn/media/mux-video.js +1 -1
- package/cdn/media/native-hls-video.dev.js +2 -2
- package/cdn/media/native-hls-video.js +1 -1
- package/cdn/media/simple-hls-video.dev.js +2 -2
- package/cdn/media/simple-hls-video.js +2 -2
- package/cdn/media/simple-hls-video.js.map +1 -1
- package/cdn/{media-props-mixin-CZLZIhGT.js → media-props-mixin-hheRmkup.js} +9 -9
- package/cdn/{media-props-mixin-CZLZIhGT.js.map → media-props-mixin-hheRmkup.js.map} +1 -1
- package/cdn/{media-props-mixin-DrjlZybt.js → media-props-mixin-yRWj8yXF.js} +3 -3
- package/cdn/{media-props-mixin-DrjlZybt.js.map → media-props-mixin-yRWj8yXF.js.map} +1 -1
- package/cdn/minimal-ui-B3BBK5nX.js +2 -0
- package/cdn/minimal-ui-B3BBK5nX.js.map +1 -0
- package/cdn/minimal-ui-CPRSYky_.js +28 -0
- package/cdn/minimal-ui-CPRSYky_.js.map +1 -0
- package/cdn/minimal-ui-Cnaig4X6.js +22 -0
- package/cdn/minimal-ui-Cnaig4X6.js.map +1 -0
- package/cdn/minimal-ui-DOePmQfq.js +2 -0
- package/cdn/minimal-ui-DOePmQfq.js.map +1 -0
- package/cdn/{mux-CBXn2z5k.js → mux-DGgCyz_A.js} +4 -4
- package/cdn/{mux-CBXn2z5k.js.map → mux-DGgCyz_A.js.map} +1 -1
- package/cdn/{mux-DmGzBNIq.js → mux-fYfPUpq3.js} +2 -2
- package/cdn/{mux-DmGzBNIq.js.map → mux-fYfPUpq3.js.map} +1 -1
- package/cdn/{native-hls-BCOLtRUl.js → native-hls-BuCYu7Rd.js} +2 -2
- package/cdn/{native-hls-BCOLtRUl.js.map → native-hls-BuCYu7Rd.js.map} +1 -1
- package/cdn/{native-hls-BU8--1Kg.js → native-hls-DnqJ-0zL.js} +2 -2
- package/cdn/{native-hls-BU8--1Kg.js.map → native-hls-DnqJ-0zL.js.map} +1 -1
- package/cdn/player-Cu5_r0Gk.js +2 -0
- package/cdn/{player-DAmuLGE1.js.map → player-Cu5_r0Gk.js.map} +1 -1
- package/cdn/{poster-qAhnKWea.js → player-DIOgBqQf.js} +15 -113
- package/cdn/player-DIOgBqQf.js.map +1 -0
- package/cdn/{player-Dbl1MUJ2.js → player-DxBoqZVw.js} +3 -2
- package/cdn/{player-Dbl1MUJ2.js.map → player-DxBoqZVw.js.map} +1 -1
- package/cdn/player-eEH-XjnF.js +2 -0
- package/cdn/player-eEH-XjnF.js.map +1 -0
- package/cdn/{shallow-equal-uPuCQhnd.js → shallow-equal-1KBb-lrM.js} +1 -1
- package/cdn/{shallow-equal-uPuCQhnd.js.map → shallow-equal-1KBb-lrM.js.map} +1 -1
- package/cdn/{shallow-equal-C8Fs4TTE.js → shallow-equal-Ca0qjpLJ.js} +1 -1
- package/cdn/{shallow-equal-C8Fs4TTE.js.map → shallow-equal-Ca0qjpLJ.js.map} +1 -1
- package/cdn/{skin-element-ih3VrnYx.js → skin-element-BTPr5DoY.js} +2 -2
- package/cdn/{skin-element-ih3VrnYx.js.map → skin-element-BTPr5DoY.js.map} +1 -1
- package/cdn/{skin-element-DbmY-ske.js → skin-element-u6pdmSSs.js} +2 -2
- package/cdn/{skin-element-DbmY-ske.js.map → skin-element-u6pdmSSs.js.map} +1 -1
- package/cdn/ui-34pkHFdT.js +25 -0
- package/cdn/ui-34pkHFdT.js.map +1 -0
- package/cdn/ui-DWoV_Da1.js +2 -0
- package/cdn/ui-DWoV_Da1.js.map +1 -0
- package/cdn/ui-DXtTKomo.js +2 -0
- package/cdn/ui-DXtTKomo.js.map +1 -0
- package/cdn/ui-X5WOdCCw.js +31 -0
- package/cdn/ui-X5WOdCCw.js.map +1 -0
- package/cdn/video-minimal-ui.dev.js +3 -3
- package/cdn/video-minimal-ui.js +1 -1
- package/cdn/video-minimal.dev.js +4 -4
- package/cdn/video-minimal.js +1 -1
- package/cdn/video-minimal.js.map +1 -1
- package/cdn/video-ui.dev.js +3 -4
- package/cdn/video-ui.js +1 -1
- package/cdn/video.dev.js +12 -6
- package/cdn/video.dev.js.map +1 -1
- package/cdn/video.js +1 -1
- package/cdn/video.js.map +1 -1
- package/dist/default/define/audio/minimal-ui.js +28 -12
- package/dist/default/define/audio/minimal-ui.js.map +1 -0
- package/dist/default/define/audio/ui.js +32 -13
- package/dist/default/define/audio/ui.js.map +1 -0
- package/dist/default/define/ui/compounds.js +62 -0
- package/dist/default/define/ui/compounds.js.map +1 -0
- package/dist/default/define/ui/controls.js +2 -5
- package/dist/default/define/ui/controls.js.map +1 -1
- package/dist/default/define/ui/error-dialog.js +2 -9
- package/dist/default/define/ui/error-dialog.js.map +1 -1
- package/dist/default/define/ui/slider.js +2 -13
- package/dist/default/define/ui/slider.js.map +1 -1
- package/dist/default/define/ui/time-slider.js +2 -17
- package/dist/default/define/ui/time-slider.js.map +1 -1
- package/dist/default/define/ui/time.js +2 -7
- package/dist/default/define/ui/time.js.map +1 -1
- package/dist/default/define/ui/volume-slider.js +2 -13
- package/dist/default/define/ui/volume-slider.js.map +1 -1
- package/dist/default/define/video/minimal-ui.js +39 -18
- package/dist/default/define/video/minimal-ui.js.map +1 -0
- package/dist/default/define/video/skin.js +1 -1
- package/dist/default/define/video/skin.js.map +1 -1
- package/dist/default/define/video/ui.js +43 -19
- package/dist/default/define/video/ui.js.map +1 -0
- package/dist/default/index.js +2 -1
- package/dist/default/ui/gesture/gesture-element.js +84 -0
- package/dist/default/ui/gesture/gesture-element.js.map +1 -0
- package/dist/default/ui/pip-button/pip-button-element.js +1 -1
- package/dist/default/ui/pip-button/pip-button-element.js.map +1 -1
- package/dist/dev/define/audio/minimal-ui.js +28 -12
- package/dist/dev/define/audio/minimal-ui.js.map +1 -0
- package/dist/dev/define/audio/ui.js +32 -13
- package/dist/dev/define/audio/ui.js.map +1 -0
- package/dist/dev/define/ui/compounds.d.ts +12 -0
- package/dist/dev/define/ui/compounds.d.ts.map +1 -0
- package/dist/dev/define/ui/compounds.js +62 -0
- package/dist/dev/define/ui/compounds.js.map +1 -0
- package/dist/dev/define/ui/controls.d.ts +2 -0
- package/dist/dev/define/ui/controls.d.ts.map +1 -1
- package/dist/dev/define/ui/controls.js +2 -5
- package/dist/dev/define/ui/controls.js.map +1 -1
- package/dist/dev/define/ui/error-dialog.d.ts +6 -0
- package/dist/dev/define/ui/error-dialog.d.ts.map +1 -1
- package/dist/dev/define/ui/error-dialog.js +2 -9
- package/dist/dev/define/ui/error-dialog.js.map +1 -1
- package/dist/dev/define/ui/slider.d.ts +10 -0
- package/dist/dev/define/ui/slider.d.ts.map +1 -1
- package/dist/dev/define/ui/slider.js +2 -13
- package/dist/dev/define/ui/slider.js.map +1 -1
- package/dist/dev/define/ui/time-slider.d.ts +14 -0
- package/dist/dev/define/ui/time-slider.d.ts.map +1 -1
- package/dist/dev/define/ui/time-slider.js +2 -17
- package/dist/dev/define/ui/time-slider.js.map +1 -1
- package/dist/dev/define/ui/time.d.ts +4 -0
- package/dist/dev/define/ui/time.d.ts.map +1 -1
- package/dist/dev/define/ui/time.js +2 -7
- package/dist/dev/define/ui/time.js.map +1 -1
- package/dist/dev/define/ui/volume-slider.d.ts +10 -0
- package/dist/dev/define/ui/volume-slider.d.ts.map +1 -1
- package/dist/dev/define/ui/volume-slider.js +2 -13
- package/dist/dev/define/ui/volume-slider.js.map +1 -1
- package/dist/dev/define/video/minimal-ui.js +39 -18
- package/dist/dev/define/video/minimal-ui.js.map +1 -0
- package/dist/dev/define/video/skin.d.ts.map +1 -1
- package/dist/dev/define/video/skin.js +8 -1
- package/dist/dev/define/video/skin.js.map +1 -1
- package/dist/dev/define/video/ui.js +43 -19
- package/dist/dev/define/video/ui.js.map +1 -0
- package/dist/dev/index.d.ts +2 -1
- package/dist/dev/index.js +2 -1
- package/dist/dev/ui/gesture/gesture-element.d.ts +22 -0
- package/dist/dev/ui/gesture/gesture-element.d.ts.map +1 -0
- package/dist/dev/ui/gesture/gesture-element.js +84 -0
- package/dist/dev/ui/gesture/gesture-element.js.map +1 -0
- package/dist/dev/ui/pip-button/pip-button-element.d.ts +1 -1
- package/dist/dev/ui/pip-button/pip-button-element.js +1 -1
- package/dist/dev/ui/pip-button/pip-button-element.js.map +1 -1
- package/package.json +8 -8
- package/cdn/create-player-B_oNyyb5.js +0 -7
- package/cdn/create-player-B_oNyyb5.js.map +0 -1
- package/cdn/create-player-DckZq-sE.js.map +0 -1
- package/cdn/hotkey-B7OaweHa.js +0 -154
- package/cdn/hotkey-B7OaweHa.js.map +0 -1
- package/cdn/hotkey-BLEt77Z0.js +0 -2
- package/cdn/hotkey-BLEt77Z0.js.map +0 -1
- package/cdn/minimal-ui-DXFwjywa.js +0 -0
- package/cdn/minimal-ui-jrmrxIOn.js +0 -0
- package/cdn/player-DAmuLGE1.js +0 -2
- package/cdn/poster-B9COb7AR.js +0 -2
- package/cdn/poster-B9COb7AR.js.map +0 -1
- package/cdn/poster-qAhnKWea.js.map +0 -1
- package/cdn/ui-18UYtw8D.js +0 -0
- package/cdn/ui-8HVY3XSt.js +0 -0
- package/cdn/volume-slider-BbIc1N4U.js +0 -8
- package/cdn/volume-slider-BbIc1N4U.js.map +0 -1
- package/cdn/volume-slider-C6ek7oC9.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as listen } from "./listen-w-Aun0yN.js";
|
|
2
2
|
import { a as ContextRequestEvent, n as mediaContext, r as playerContext, t as containerContext } from "./context-CvJ83xGk.js";
|
|
3
|
-
import { t as anyAbortSignal } from "./abort-
|
|
4
|
-
import { t as shallowEqual } from "./shallow-equal-
|
|
3
|
+
import { t as anyAbortSignal } from "./abort-BL-SGV3o.js";
|
|
4
|
+
import { t as shallowEqual } from "./shallow-equal-Ca0qjpLJ.js";
|
|
5
5
|
|
|
6
6
|
//#region ../utils/dist/dom/event.js
|
|
7
7
|
/** Resolve the deepest event target, preferring composedPath for shadow DOM. */
|
|
@@ -29,6 +29,38 @@ function onEvent(target, type, options) {
|
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region ../utils/dist/dom/predicates.js
|
|
34
|
+
const EDITABLE_INPUT_TYPES = new Set([
|
|
35
|
+
"text",
|
|
36
|
+
"search",
|
|
37
|
+
"url",
|
|
38
|
+
"tel",
|
|
39
|
+
"email",
|
|
40
|
+
"password",
|
|
41
|
+
"number"
|
|
42
|
+
]);
|
|
43
|
+
function isEditableElement(el) {
|
|
44
|
+
if (el instanceof HTMLTextAreaElement) return true;
|
|
45
|
+
if (el instanceof HTMLSelectElement) return true;
|
|
46
|
+
if (el instanceof HTMLInputElement) return EDITABLE_INPUT_TYPES.has(el.type.toLowerCase());
|
|
47
|
+
if (!(el instanceof HTMLElement)) return false;
|
|
48
|
+
const editable = el.getAttribute("contenteditable");
|
|
49
|
+
return editable !== null && editable !== "false";
|
|
50
|
+
}
|
|
51
|
+
/** Whether the keyboard event target is an editable element (input, textarea, etc). */
|
|
52
|
+
function isEditableTarget(event) {
|
|
53
|
+
const target = resolveEventTarget(event);
|
|
54
|
+
return target instanceof Element && isEditableElement(target);
|
|
55
|
+
}
|
|
56
|
+
const INTERACTIVE_SELECTOR = "button, input, select, textarea, [role=\"button\"], [role=\"slider\"]";
|
|
57
|
+
/** Whether the event originated from an interactive control (button, slider, etc). */
|
|
58
|
+
function isInteractiveTarget(event) {
|
|
59
|
+
const target = resolveEventTarget(event);
|
|
60
|
+
if (!(target instanceof Element)) return false;
|
|
61
|
+
return target.closest(INTERACTIVE_SELECTOR) !== null;
|
|
62
|
+
}
|
|
63
|
+
|
|
32
64
|
//#endregion
|
|
33
65
|
//#region ../utils/dist/dom/text-track.js
|
|
34
66
|
/** Find the `<track>` element that owns the given `TextTrack`. */
|
|
@@ -412,1294 +444,1321 @@ function resolve(ctor) {
|
|
|
412
444
|
}
|
|
413
445
|
|
|
414
446
|
//#endregion
|
|
415
|
-
//#region
|
|
416
|
-
function isNumber(value) {
|
|
417
|
-
return typeof value === "number";
|
|
418
|
-
}
|
|
419
|
-
function isFunction(value) {
|
|
420
|
-
return typeof value === "function";
|
|
421
|
-
}
|
|
422
|
-
function isNull(value) {
|
|
423
|
-
return value === null;
|
|
424
|
-
}
|
|
425
|
-
function isUndefined(value) {
|
|
426
|
-
return typeof value === "undefined";
|
|
427
|
-
}
|
|
447
|
+
//#region ../../node_modules/.pnpm/@lit+context@1.1.6/node_modules/@lit/context/development/lib/controllers/context-consumer.js
|
|
428
448
|
/**
|
|
429
|
-
*
|
|
449
|
+
* @license
|
|
450
|
+
* Copyright 2021 Google LLC
|
|
451
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
430
452
|
*/
|
|
431
|
-
function isObject(value) {
|
|
432
|
-
return value !== null && typeof value === "object";
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
//#endregion
|
|
436
|
-
//#region ../store/dist/dev/core/abort-controller-registry.js
|
|
437
|
-
var AbortControllerRegistry = class {
|
|
438
|
-
#base = new AbortController();
|
|
439
|
-
#keys = /* @__PURE__ */ new Map();
|
|
440
|
-
/** The attach-scoped signal. Aborts on detach or reattach. */
|
|
441
|
-
get base() {
|
|
442
|
-
return this.#base.signal;
|
|
443
|
-
}
|
|
444
|
-
/** Clears all keyed signals, leaving base intact. */
|
|
445
|
-
clear() {
|
|
446
|
-
for (const controller of this.#keys.values()) controller.abort();
|
|
447
|
-
this.#keys.clear();
|
|
448
|
-
}
|
|
449
|
-
/** Resets base and clears all keyed signals. */
|
|
450
|
-
reset() {
|
|
451
|
-
this.clear();
|
|
452
|
-
this.#base.abort();
|
|
453
|
-
this.#base = new AbortController();
|
|
454
|
-
}
|
|
455
|
-
/** Creates a new signal for the key, superseding any previous signal. */
|
|
456
|
-
supersede(key) {
|
|
457
|
-
this.#keys.get(key)?.abort();
|
|
458
|
-
const controller = new AbortController();
|
|
459
|
-
this.#keys.set(key, controller);
|
|
460
|
-
return anyAbortSignal([this.#base.signal, controller.signal]);
|
|
461
|
-
}
|
|
462
|
-
};
|
|
463
|
-
|
|
464
|
-
//#endregion
|
|
465
|
-
//#region ../store/dist/dev/core/combine.js
|
|
466
453
|
/**
|
|
467
|
-
*
|
|
454
|
+
* A ReactiveController which adds context consuming behavior to a custom
|
|
455
|
+
* element by dispatching `context-request` events.
|
|
468
456
|
*
|
|
469
|
-
*
|
|
470
|
-
*
|
|
457
|
+
* When the host element is connected to the document it will emit a
|
|
458
|
+
* `context-request` event with its context key. When the context request
|
|
459
|
+
* is satisfied the controller will invoke the callback, if present, and
|
|
460
|
+
* trigger a host update so it can respond to the new value.
|
|
461
|
+
*
|
|
462
|
+
* It will also call the dispose method given by the provider when the
|
|
463
|
+
* host element is disconnected.
|
|
471
464
|
*/
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
465
|
+
var ContextConsumer = class {
|
|
466
|
+
constructor(host, contextOrOptions, callback, subscribe) {
|
|
467
|
+
this.subscribe = false;
|
|
468
|
+
this.provided = false;
|
|
469
|
+
this.value = void 0;
|
|
470
|
+
this._callback = (value, unsubscribe) => {
|
|
471
|
+
if (this.unsubscribe) {
|
|
472
|
+
if (this.unsubscribe !== unsubscribe) {
|
|
473
|
+
this.provided = false;
|
|
474
|
+
this.unsubscribe();
|
|
481
475
|
}
|
|
476
|
+
if (!this.subscribe) this.unsubscribe();
|
|
482
477
|
}
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
} catch (err) {
|
|
489
|
-
ctx.reportError(err);
|
|
478
|
+
this.value = value;
|
|
479
|
+
this.host.requestUpdate();
|
|
480
|
+
if (!this.provided || this.subscribe) {
|
|
481
|
+
this.provided = true;
|
|
482
|
+
if (this.callback) this.callback(value, unsubscribe);
|
|
490
483
|
}
|
|
484
|
+
this.unsubscribe = unsubscribe;
|
|
485
|
+
};
|
|
486
|
+
this.host = host;
|
|
487
|
+
if (contextOrOptions.context !== void 0) {
|
|
488
|
+
const options = contextOrOptions;
|
|
489
|
+
this.context = options.context;
|
|
490
|
+
this.callback = options.callback;
|
|
491
|
+
this.subscribe = options.subscribe ?? false;
|
|
492
|
+
} else {
|
|
493
|
+
this.context = contextOrOptions;
|
|
494
|
+
this.callback = callback;
|
|
495
|
+
this.subscribe = subscribe ?? false;
|
|
491
496
|
}
|
|
492
|
-
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
this.
|
|
497
|
+
this.host.addController(this);
|
|
498
|
+
}
|
|
499
|
+
hostConnected() {
|
|
500
|
+
this.dispatchRequest();
|
|
501
|
+
}
|
|
502
|
+
hostDisconnected() {
|
|
503
|
+
if (this.unsubscribe) {
|
|
504
|
+
this.unsubscribe();
|
|
505
|
+
this.unsubscribe = void 0;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
dispatchRequest() {
|
|
509
|
+
this.host.dispatchEvent(new ContextRequestEvent(this.context, this.host, this._callback, this.subscribe));
|
|
505
510
|
}
|
|
506
511
|
};
|
|
507
|
-
function throwNoTargetError() {
|
|
508
|
-
throw new StoreError("NO_TARGET");
|
|
509
|
-
}
|
|
510
|
-
function throwDestroyedError() {
|
|
511
|
-
throw new StoreError("DESTROYED");
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
//#endregion
|
|
515
|
-
//#region ../store/dist/dev/core/slice.js
|
|
516
|
-
function defineSlice() {
|
|
517
|
-
return (config) => config;
|
|
518
|
-
}
|
|
519
512
|
|
|
520
513
|
//#endregion
|
|
521
|
-
//#region
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
const hasOwnProp = Object.prototype.hasOwnProperty;
|
|
539
|
-
var StateContainer = class {
|
|
540
|
-
#current;
|
|
541
|
-
#listeners = /* @__PURE__ */ new Set();
|
|
542
|
-
#pending = false;
|
|
543
|
-
constructor(initial) {
|
|
544
|
-
this.#current = Object.freeze({ ...initial });
|
|
514
|
+
//#region ../../node_modules/.pnpm/@lit+context@1.1.6/node_modules/@lit/context/development/lib/value-notifier.js
|
|
515
|
+
/**
|
|
516
|
+
* @license
|
|
517
|
+
* Copyright 2021 Google LLC
|
|
518
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
519
|
+
*/
|
|
520
|
+
/**
|
|
521
|
+
* A simple class which stores a value, and triggers registered callbacks when
|
|
522
|
+
* the value is changed via its setter.
|
|
523
|
+
*
|
|
524
|
+
* An implementor might use other observable patterns such as MobX or Redux to
|
|
525
|
+
* get behavior like this. But this is a pretty minimal approach that will
|
|
526
|
+
* likely work for a number of use cases.
|
|
527
|
+
*/
|
|
528
|
+
var ValueNotifier = class {
|
|
529
|
+
get value() {
|
|
530
|
+
return this._value;
|
|
545
531
|
}
|
|
546
|
-
|
|
547
|
-
|
|
532
|
+
set value(v) {
|
|
533
|
+
this.setValue(v);
|
|
548
534
|
}
|
|
549
|
-
|
|
550
|
-
const
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
if (!hasOwnProp.call(partial, key)) continue;
|
|
554
|
-
const value = partial[key];
|
|
555
|
-
if (!Object.is(this.#current[key], value)) {
|
|
556
|
-
next[key] = value;
|
|
557
|
-
changed = true;
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
if (changed) {
|
|
561
|
-
this.#current = Object.freeze(next);
|
|
562
|
-
this.#markPending();
|
|
563
|
-
}
|
|
535
|
+
setValue(v, force = false) {
|
|
536
|
+
const update = force || !Object.is(v, this._value);
|
|
537
|
+
this._value = v;
|
|
538
|
+
if (update) this.updateObservers();
|
|
564
539
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
if (!signal) return () => this.#listeners.delete(callback);
|
|
570
|
-
const onAbort = () => this.#listeners.delete(callback);
|
|
571
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
572
|
-
return () => {
|
|
573
|
-
signal.removeEventListener("abort", onAbort);
|
|
574
|
-
this.#listeners.delete(callback);
|
|
540
|
+
constructor(defaultValue) {
|
|
541
|
+
this.subscriptions = /* @__PURE__ */ new Map();
|
|
542
|
+
this.updateObservers = () => {
|
|
543
|
+
for (const [callback, { disposer }] of this.subscriptions) callback(this._value, disposer);
|
|
575
544
|
};
|
|
545
|
+
if (defaultValue !== void 0) this.value = defaultValue;
|
|
576
546
|
}
|
|
577
|
-
|
|
578
|
-
if (!
|
|
579
|
-
|
|
580
|
-
|
|
547
|
+
addCallback(callback, consumerHost, subscribe) {
|
|
548
|
+
if (!subscribe) {
|
|
549
|
+
callback(this.value);
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
if (!this.subscriptions.has(callback)) this.subscriptions.set(callback, {
|
|
553
|
+
disposer: () => {
|
|
554
|
+
this.subscriptions.delete(callback);
|
|
555
|
+
},
|
|
556
|
+
consumerHost
|
|
557
|
+
});
|
|
558
|
+
const { disposer } = this.subscriptions.get(callback);
|
|
559
|
+
callback(this.value, disposer);
|
|
581
560
|
}
|
|
582
|
-
|
|
583
|
-
this
|
|
584
|
-
pendingContainers.add(this);
|
|
585
|
-
scheduleFlush();
|
|
561
|
+
clearCallbacks() {
|
|
562
|
+
this.subscriptions.clear();
|
|
586
563
|
}
|
|
587
564
|
};
|
|
588
|
-
function createState(initial) {
|
|
589
|
-
return new StateContainer(initial);
|
|
590
|
-
}
|
|
591
565
|
|
|
592
566
|
//#endregion
|
|
593
|
-
//#region
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
return target;
|
|
610
|
-
},
|
|
611
|
-
signals,
|
|
612
|
-
get: () => state.current,
|
|
613
|
-
set: (partial) => state.patch(partial)
|
|
567
|
+
//#region ../../node_modules/.pnpm/@lit+context@1.1.6/node_modules/@lit/context/development/lib/controllers/context-provider.js
|
|
568
|
+
/**
|
|
569
|
+
* @license
|
|
570
|
+
* Copyright 2021 Google LLC
|
|
571
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
572
|
+
*/
|
|
573
|
+
var ContextProviderEvent = class extends Event {
|
|
574
|
+
/**
|
|
575
|
+
*
|
|
576
|
+
* @param context the context which this provider can provide
|
|
577
|
+
* @param contextTarget the original context target of the provider
|
|
578
|
+
*/
|
|
579
|
+
constructor(context, contextTarget) {
|
|
580
|
+
super("context-provider", {
|
|
581
|
+
bubbles: true,
|
|
582
|
+
composed: true
|
|
614
583
|
});
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
584
|
+
this.context = context;
|
|
585
|
+
this.contextTarget = contextTarget;
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
/**
|
|
589
|
+
* A ReactiveController which adds context provider behavior to a
|
|
590
|
+
* custom element.
|
|
591
|
+
*
|
|
592
|
+
* This controller simply listens to the `context-request` event when
|
|
593
|
+
* the host is connected to the DOM and registers the received callbacks
|
|
594
|
+
* against its observable Context implementation.
|
|
595
|
+
*
|
|
596
|
+
* The controller may also be attached to any HTML element in which case it's
|
|
597
|
+
* up to the user to call hostConnected() when attached to the DOM. This is
|
|
598
|
+
* done automatically for any custom elements implementing
|
|
599
|
+
* ReactiveControllerHost.
|
|
600
|
+
*/
|
|
601
|
+
var ContextProvider = class extends ValueNotifier {
|
|
602
|
+
constructor(host, contextOrOptions, initialValue) {
|
|
603
|
+
super(contextOrOptions.context !== void 0 ? contextOrOptions.initialValue : initialValue);
|
|
604
|
+
this.onContextRequest = (ev) => {
|
|
605
|
+
if (ev.context !== this.context) return;
|
|
606
|
+
const consumerHost = ev.contextTarget ?? ev.composedPath()[0];
|
|
607
|
+
if (consumerHost === this.host) return;
|
|
608
|
+
ev.stopPropagation();
|
|
609
|
+
this.addCallback(ev.callback, consumerHost, ev.subscribe);
|
|
633
610
|
};
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
if (destroyed) throwDestroyedError();
|
|
649
|
-
signals.reset();
|
|
650
|
-
target = newTarget;
|
|
651
|
-
const attachContext = {
|
|
652
|
-
target: newTarget,
|
|
653
|
-
signal: signals.base,
|
|
654
|
-
get: () => state.current,
|
|
655
|
-
set: (partial) => state.patch(partial),
|
|
656
|
-
reportError,
|
|
657
|
-
store: {
|
|
658
|
-
get state() {
|
|
659
|
-
return state.current;
|
|
660
|
-
},
|
|
661
|
-
subscribe
|
|
662
|
-
}
|
|
663
|
-
};
|
|
664
|
-
try {
|
|
665
|
-
slice.attach?.(attachContext);
|
|
666
|
-
} catch (error) {
|
|
667
|
-
reportError(error);
|
|
611
|
+
/**
|
|
612
|
+
* When we get a provider request event, that means a child of this element
|
|
613
|
+
* has just woken up. If it's a provider of our context, then we may need to
|
|
614
|
+
* re-parent our subscriptions, because is a more specific provider than us
|
|
615
|
+
* for its subtree.
|
|
616
|
+
*/
|
|
617
|
+
this.onProviderRequest = (ev) => {
|
|
618
|
+
if (ev.context !== this.context) return;
|
|
619
|
+
if ((ev.contextTarget ?? ev.composedPath()[0]) === this.host) return;
|
|
620
|
+
const seen = /* @__PURE__ */ new Set();
|
|
621
|
+
for (const [callback, { consumerHost }] of this.subscriptions) {
|
|
622
|
+
if (seen.has(callback)) continue;
|
|
623
|
+
seen.add(callback);
|
|
624
|
+
consumerHost.dispatchEvent(new ContextRequestEvent(this.context, consumerHost, callback, true));
|
|
668
625
|
}
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
626
|
+
ev.stopPropagation();
|
|
627
|
+
};
|
|
628
|
+
this.host = host;
|
|
629
|
+
if (contextOrOptions.context !== void 0) this.context = contextOrOptions.context;
|
|
630
|
+
else this.context = contextOrOptions;
|
|
631
|
+
this.attachListeners();
|
|
632
|
+
this.host.addController?.(this);
|
|
633
|
+
}
|
|
634
|
+
attachListeners() {
|
|
635
|
+
this.host.addEventListener("context-request", this.onContextRequest);
|
|
636
|
+
this.host.addEventListener("context-provider", this.onProviderRequest);
|
|
637
|
+
}
|
|
638
|
+
hostConnected() {
|
|
639
|
+
this.host.dispatchEvent(new ContextProviderEvent(this.context, this.host));
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
|
|
643
|
+
//#endregion
|
|
644
|
+
//#region src/store/container-mixin.ts
|
|
645
|
+
/**
|
|
646
|
+
* Create a mixin that consumes player context and registers itself as the
|
|
647
|
+
* container element with the provider via `containerContext`.
|
|
648
|
+
*
|
|
649
|
+
* @param config - Container configuration with player and container contexts.
|
|
650
|
+
*/
|
|
651
|
+
function createContainerMixin(config) {
|
|
652
|
+
return (BaseClass) => {
|
|
653
|
+
class PlayerContainerElement extends BaseClass {
|
|
654
|
+
#contextStore = null;
|
|
655
|
+
#setContainer = null;
|
|
656
|
+
constructor(...args) {
|
|
657
|
+
super(...args);
|
|
658
|
+
new ContextConsumer(this, {
|
|
659
|
+
context: config.playerContext,
|
|
660
|
+
callback: (value) => {
|
|
661
|
+
this.#contextStore = value ?? null;
|
|
662
|
+
},
|
|
663
|
+
subscribe: true
|
|
664
|
+
});
|
|
665
|
+
new ContextConsumer(this, {
|
|
666
|
+
context: config.containerContext,
|
|
667
|
+
callback: (value) => {
|
|
668
|
+
this.#setContainer = value?.setContainer ?? null;
|
|
669
|
+
if (this.isConnected) this.#setContainer?.(this);
|
|
670
|
+
},
|
|
671
|
+
subscribe: true
|
|
674
672
|
});
|
|
675
|
-
} catch (error) {
|
|
676
|
-
reportError(error);
|
|
677
673
|
}
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
detach();
|
|
690
|
-
setupAbort.abort();
|
|
691
|
-
}
|
|
692
|
-
function subscribe(callback, options) {
|
|
693
|
-
return state.subscribe(callback, options);
|
|
694
|
-
}
|
|
695
|
-
function reportError(error) {
|
|
696
|
-
if (options.onError) options.onError({
|
|
697
|
-
store,
|
|
698
|
-
error
|
|
699
|
-
});
|
|
700
|
-
else console.error("[vjs-store]", error);
|
|
674
|
+
get store() {
|
|
675
|
+
return this.#contextStore;
|
|
676
|
+
}
|
|
677
|
+
connectedCallback() {
|
|
678
|
+
super.connectedCallback();
|
|
679
|
+
this.#setContainer?.(this);
|
|
680
|
+
}
|
|
681
|
+
disconnectedCallback() {
|
|
682
|
+
super.disconnectedCallback();
|
|
683
|
+
this.#setContainer?.(null);
|
|
684
|
+
}
|
|
701
685
|
}
|
|
686
|
+
return PlayerContainerElement;
|
|
702
687
|
};
|
|
703
688
|
}
|
|
704
|
-
function isStore(value) {
|
|
705
|
-
return isObject(value) && STORE_SYMBOL in value;
|
|
706
|
-
}
|
|
707
689
|
|
|
708
690
|
//#endregion
|
|
709
|
-
//#region
|
|
710
|
-
|
|
691
|
+
//#region src/ui/media-element.ts
|
|
692
|
+
/** Base class for interactive media UI elements. */
|
|
693
|
+
var MediaElement = class extends DestroyMixin(ReactiveElement) {};
|
|
711
694
|
|
|
712
695
|
//#endregion
|
|
713
|
-
//#region
|
|
714
|
-
const
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
buffered: [],
|
|
718
|
-
seekable: []
|
|
719
|
-
}),
|
|
720
|
-
attach({ target, signal, set }) {
|
|
721
|
-
const { media } = target;
|
|
722
|
-
const sync = () => set({
|
|
723
|
-
buffered: serializeTimeRanges(media.buffered),
|
|
724
|
-
seekable: serializeTimeRanges(media.seekable)
|
|
725
|
-
});
|
|
726
|
-
sync();
|
|
727
|
-
listen(media, "progress", sync, { signal });
|
|
728
|
-
listen(media, "emptied", sync, { signal });
|
|
729
|
-
}
|
|
696
|
+
//#region src/media/container-element.ts
|
|
697
|
+
const ContainerMixin = createContainerMixin({
|
|
698
|
+
playerContext,
|
|
699
|
+
containerContext
|
|
730
700
|
});
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
const IDLE_DELAY = 2e3;
|
|
735
|
-
const TAP_THRESHOLD = 250;
|
|
736
|
-
const controlsFeature = definePlayerFeature({
|
|
737
|
-
name: "controls",
|
|
738
|
-
state: ({ get, set }) => ({
|
|
739
|
-
userActive: true,
|
|
740
|
-
controlsVisible: true,
|
|
741
|
-
toggleControls() {
|
|
742
|
-
const next = !get().userActive;
|
|
743
|
-
set({
|
|
744
|
-
userActive: next,
|
|
745
|
-
controlsVisible: next
|
|
746
|
-
});
|
|
747
|
-
return next;
|
|
748
|
-
}
|
|
749
|
-
}),
|
|
750
|
-
attach({ target, signal, get, set }) {
|
|
751
|
-
const { media, container } = target;
|
|
752
|
-
if (isNull(container)) {
|
|
753
|
-
console.warn("[vjs] controlsFeature requires a container element for activity tracking.");
|
|
754
|
-
return;
|
|
755
|
-
}
|
|
756
|
-
function computeVisible(userActive) {
|
|
757
|
-
return userActive || media.paused;
|
|
758
|
-
}
|
|
759
|
-
let idleTimer;
|
|
760
|
-
function clearIdle() {
|
|
761
|
-
clearTimeout(idleTimer);
|
|
762
|
-
idleTimer = void 0;
|
|
763
|
-
}
|
|
764
|
-
function scheduleIdle() {
|
|
765
|
-
clearIdle();
|
|
766
|
-
idleTimer = setTimeout(setInactive, IDLE_DELAY);
|
|
767
|
-
}
|
|
768
|
-
function setActive() {
|
|
769
|
-
if (!get().userActive) set({
|
|
770
|
-
userActive: true,
|
|
771
|
-
controlsVisible: true
|
|
772
|
-
});
|
|
773
|
-
scheduleIdle();
|
|
774
|
-
}
|
|
775
|
-
function setInactive() {
|
|
776
|
-
clearIdle();
|
|
777
|
-
set({
|
|
778
|
-
userActive: false,
|
|
779
|
-
controlsVisible: computeVisible(false)
|
|
780
|
-
});
|
|
781
|
-
}
|
|
782
|
-
set({ toggleControls() {
|
|
783
|
-
if (get().controlsVisible) setInactive();
|
|
784
|
-
else setActive();
|
|
785
|
-
return get().controlsVisible;
|
|
786
|
-
} });
|
|
787
|
-
let pointerDownTime = 0;
|
|
788
|
-
function onPointerDown() {
|
|
789
|
-
pointerDownTime = Date.now();
|
|
790
|
-
}
|
|
791
|
-
function onPointerUp(event) {
|
|
792
|
-
if (event.pointerType === "touch" && Date.now() - pointerDownTime < TAP_THRESHOLD) {
|
|
793
|
-
const isMediaOrContainer = [media, container].includes(event.target);
|
|
794
|
-
if (get().controlsVisible && isMediaOrContainer) setInactive();
|
|
795
|
-
else setActive();
|
|
796
|
-
} else setActive();
|
|
797
|
-
}
|
|
798
|
-
function onPlaybackChange() {
|
|
799
|
-
const { userActive } = get();
|
|
800
|
-
set({ controlsVisible: computeVisible(userActive) });
|
|
801
|
-
if (!media.paused && userActive) scheduleIdle();
|
|
802
|
-
}
|
|
803
|
-
listen(container, "pointermove", setActive, { signal });
|
|
804
|
-
listen(container, "pointerdown", onPointerDown, { signal });
|
|
805
|
-
listen(container, "pointerup", onPointerUp, { signal });
|
|
806
|
-
listen(container, "keyup", setActive, { signal });
|
|
807
|
-
listen(container, "focusin", setActive, { signal });
|
|
808
|
-
listen(container, "mouseleave", setInactive, { signal });
|
|
809
|
-
listen(media, "play", onPlaybackChange, { signal });
|
|
810
|
-
listen(media, "pause", onPlaybackChange, { signal });
|
|
811
|
-
listen(media, "ended", onPlaybackChange, { signal });
|
|
812
|
-
signal.addEventListener("abort", clearIdle, { once: true });
|
|
813
|
-
scheduleIdle();
|
|
701
|
+
var MediaContainerElement = class extends ContainerMixin(MediaElement) {
|
|
702
|
+
static {
|
|
703
|
+
this.tagName = "media-container";
|
|
814
704
|
}
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
state: ({ set }) => ({
|
|
822
|
-
error: null,
|
|
823
|
-
dismissError() {
|
|
824
|
-
set({ error: null });
|
|
825
|
-
}
|
|
826
|
-
}),
|
|
827
|
-
attach({ target, signal, set }) {
|
|
828
|
-
const { media } = target;
|
|
829
|
-
const syncError = () => set({ error: media.error });
|
|
830
|
-
listen(media, "error", syncError, { signal });
|
|
831
|
-
listen(media, "emptied", () => set({ error: null }), { signal });
|
|
705
|
+
#disconnect = null;
|
|
706
|
+
connectedCallback() {
|
|
707
|
+
super.connectedCallback();
|
|
708
|
+
if (!this.hasAttribute("tabindex")) this.setAttribute("tabindex", "0");
|
|
709
|
+
this.#disconnect = new AbortController();
|
|
710
|
+
listen(this, "pointerup", this.#onPointerUp, { signal: this.#disconnect.signal });
|
|
832
711
|
}
|
|
833
|
-
|
|
712
|
+
disconnectedCallback() {
|
|
713
|
+
super.disconnectedCallback();
|
|
714
|
+
this.#disconnect?.abort();
|
|
715
|
+
this.#disconnect = null;
|
|
716
|
+
}
|
|
717
|
+
#onPointerUp = () => {
|
|
718
|
+
if (!this.contains(document.activeElement) || document.activeElement === document.body) this.focus({ preventScroll: true });
|
|
719
|
+
};
|
|
720
|
+
};
|
|
834
721
|
|
|
835
722
|
//#endregion
|
|
836
|
-
//#region ../
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
const doc = document;
|
|
840
|
-
if (doc.fullscreenEnabled || doc.webkitFullscreenEnabled) return true;
|
|
841
|
-
return isFunction(document.createElement("video").webkitEnterFullscreen);
|
|
723
|
+
//#region ../utils/dist/predicate/predicate.js
|
|
724
|
+
function isNumber(value) {
|
|
725
|
+
return typeof value === "number";
|
|
842
726
|
}
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
const doc = document;
|
|
846
|
-
return doc.fullscreenElement ?? doc.webkitFullscreenElement ?? null;
|
|
727
|
+
function isFunction(value) {
|
|
728
|
+
return typeof value === "function";
|
|
847
729
|
}
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
function isFullscreenElement(container, media) {
|
|
854
|
-
const video = media;
|
|
855
|
-
if (video.webkitDisplayingFullscreen && video.webkitPresentationMode === "fullscreen") return true;
|
|
856
|
-
const target = container ?? media;
|
|
857
|
-
if (getFullscreenElement() === target) return true;
|
|
858
|
-
try {
|
|
859
|
-
return target.matches(":fullscreen");
|
|
860
|
-
} catch {
|
|
861
|
-
return false;
|
|
862
|
-
}
|
|
730
|
+
function isNull(value) {
|
|
731
|
+
return value === null;
|
|
732
|
+
}
|
|
733
|
+
function isUndefined(value) {
|
|
734
|
+
return typeof value === "undefined";
|
|
863
735
|
}
|
|
864
736
|
/**
|
|
865
|
-
*
|
|
866
|
-
*
|
|
867
|
-
* Tries container first (to show custom UI), falls back to media element
|
|
868
|
-
* for platforms that only support video fullscreen (iOS Safari).
|
|
737
|
+
* Check if a value is an object, excluding null.
|
|
869
738
|
*/
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
const video = media;
|
|
873
|
-
if (container && (doc.fullscreenEnabled || doc.webkitFullscreenEnabled)) {
|
|
874
|
-
const el = container;
|
|
875
|
-
if (isFunction(el.requestFullscreen)) return el.requestFullscreen();
|
|
876
|
-
if (isFunction(el.webkitRequestFullscreen)) return el.webkitRequestFullscreen();
|
|
877
|
-
}
|
|
878
|
-
if (isFunction(video.webkitEnterFullscreen)) {
|
|
879
|
-
video.webkitEnterFullscreen();
|
|
880
|
-
return;
|
|
881
|
-
}
|
|
882
|
-
if (isFunction(media.requestFullscreen)) return media.requestFullscreen();
|
|
883
|
-
throw new DOMException("Fullscreen not supported", "NotSupportedError");
|
|
884
|
-
}
|
|
885
|
-
/** Exit fullscreen mode. */
|
|
886
|
-
async function exitFullscreen(media) {
|
|
887
|
-
const doc = document;
|
|
888
|
-
if (media) {
|
|
889
|
-
const video = media;
|
|
890
|
-
if (isFunction(video.webkitExitFullscreen) && video.webkitDisplayingFullscreen) {
|
|
891
|
-
video.webkitExitFullscreen();
|
|
892
|
-
return;
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
if (isFunction(doc.exitFullscreen)) return doc.exitFullscreen();
|
|
896
|
-
if (isFunction(doc.webkitExitFullscreen)) return doc.webkitExitFullscreen();
|
|
739
|
+
function isObject(value) {
|
|
740
|
+
return value !== null && typeof value === "object";
|
|
897
741
|
}
|
|
898
742
|
|
|
899
743
|
//#endregion
|
|
900
|
-
//#region ../
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
*
|
|
908
|
-
* Note: Safari PWAs don't support PiP even though the API exists.
|
|
909
|
-
*/
|
|
910
|
-
function isPictureInPictureEnabled() {
|
|
911
|
-
if (document.pictureInPictureEnabled) {
|
|
912
|
-
const isSafari = /.*Version\/.*Safari\/.*/.test(navigator.userAgent);
|
|
913
|
-
const isPWA = typeof matchMedia === "function" && matchMedia("(display-mode: standalone)").matches;
|
|
914
|
-
return !isSafari || !isPWA;
|
|
744
|
+
//#region ../store/dist/dev/core/abort-controller-registry.js
|
|
745
|
+
var AbortControllerRegistry = class {
|
|
746
|
+
#base = new AbortController();
|
|
747
|
+
#keys = /* @__PURE__ */ new Map();
|
|
748
|
+
/** The attach-scoped signal. Aborts on detach or reattach. */
|
|
749
|
+
get base() {
|
|
750
|
+
return this.#base.signal;
|
|
915
751
|
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
*/
|
|
921
|
-
function isPictureInPictureElement(media) {
|
|
922
|
-
const target = resolveMediaTarget(media);
|
|
923
|
-
if (document.pictureInPictureElement === target) return true;
|
|
924
|
-
return target.webkitPresentationMode === "picture-in-picture";
|
|
925
|
-
}
|
|
926
|
-
/**
|
|
927
|
-
* Request Picture-in-Picture mode.
|
|
928
|
-
*
|
|
929
|
-
* Uses standard API where available, falls back to iOS Safari's
|
|
930
|
-
* WebKit presentation mode.
|
|
931
|
-
*/
|
|
932
|
-
async function requestPictureInPicture(media) {
|
|
933
|
-
const video = resolveMediaTarget(media);
|
|
934
|
-
if (isFunction(video.webkitSetPresentationMode)) {
|
|
935
|
-
video.webkitSetPresentationMode("picture-in-picture");
|
|
936
|
-
return;
|
|
752
|
+
/** Clears all keyed signals, leaving base intact. */
|
|
753
|
+
clear() {
|
|
754
|
+
for (const controller of this.#keys.values()) controller.abort();
|
|
755
|
+
this.#keys.clear();
|
|
937
756
|
}
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
757
|
+
/** Resets base and clears all keyed signals. */
|
|
758
|
+
reset() {
|
|
759
|
+
this.clear();
|
|
760
|
+
this.#base.abort();
|
|
761
|
+
this.#base = new AbortController();
|
|
941
762
|
}
|
|
942
|
-
|
|
943
|
-
|
|
763
|
+
/** Creates a new signal for the key, superseding any previous signal. */
|
|
764
|
+
supersede(key) {
|
|
765
|
+
this.#keys.get(key)?.abort();
|
|
766
|
+
const controller = new AbortController();
|
|
767
|
+
this.#keys.set(key, controller);
|
|
768
|
+
return anyAbortSignal([this.#base.signal, controller.signal]);
|
|
769
|
+
}
|
|
770
|
+
};
|
|
771
|
+
|
|
772
|
+
//#endregion
|
|
773
|
+
//#region ../store/dist/dev/core/combine.js
|
|
944
774
|
/**
|
|
945
|
-
*
|
|
775
|
+
* Combines multiple slices into a single slice.
|
|
946
776
|
*
|
|
947
|
-
*
|
|
948
|
-
*
|
|
777
|
+
* @param slices - The slices to combine.
|
|
778
|
+
* @returns A new slice that represents the combination of the input slices.
|
|
949
779
|
*/
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
780
|
+
function combine(...slices) {
|
|
781
|
+
return {
|
|
782
|
+
state: (ctx) => {
|
|
783
|
+
const states = slices.map((slice) => slice.state(ctx));
|
|
784
|
+
{
|
|
785
|
+
const seen = /* @__PURE__ */ new Set();
|
|
786
|
+
for (const state of states) for (const key of Object.keys(state)) {
|
|
787
|
+
if (seen.has(key)) console.warn(`[vjs-store] combine(): duplicate state key "${key}" — later slice overwrites earlier one`);
|
|
788
|
+
seen.add(key);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
return Object.assign({}, ...states);
|
|
792
|
+
},
|
|
793
|
+
attach: (ctx) => {
|
|
794
|
+
for (const slice of slices) try {
|
|
795
|
+
slice.attach?.(ctx);
|
|
796
|
+
} catch (err) {
|
|
797
|
+
ctx.reportError(err);
|
|
798
|
+
}
|
|
956
799
|
}
|
|
957
|
-
}
|
|
958
|
-
if (isFunction(document.exitPictureInPicture)) return document.exitPictureInPicture();
|
|
800
|
+
};
|
|
959
801
|
}
|
|
960
802
|
|
|
961
803
|
//#endregion
|
|
962
|
-
//#region ../
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
return requestFullscreen(container, media);
|
|
972
|
-
},
|
|
973
|
-
async exitFullscreen() {
|
|
974
|
-
const { media } = target();
|
|
975
|
-
return exitFullscreen(media);
|
|
976
|
-
}
|
|
977
|
-
}),
|
|
978
|
-
attach({ target, signal, set }) {
|
|
979
|
-
const { media, container } = target;
|
|
980
|
-
set({ fullscreenAvailability: isFullscreenEnabled() ? "available" : "unsupported" });
|
|
981
|
-
const sync = () => set({ fullscreen: isFullscreenElement(container, media) });
|
|
982
|
-
sync();
|
|
983
|
-
listen(document, "fullscreenchange", sync, { signal });
|
|
984
|
-
listen(document, "webkitfullscreenchange", sync, { signal });
|
|
985
|
-
if ("webkitPresentationMode" in media) listen(media, "webkitpresentationmodechanged", sync, { signal });
|
|
804
|
+
//#region ../store/dist/dev/core/errors.js
|
|
805
|
+
var StoreError = class extends Error {
|
|
806
|
+
code;
|
|
807
|
+
cause;
|
|
808
|
+
constructor(code, options) {
|
|
809
|
+
super(options?.message ?? code);
|
|
810
|
+
this.name = "StoreError";
|
|
811
|
+
this.code = code;
|
|
812
|
+
this.cause = options?.cause;
|
|
986
813
|
}
|
|
987
|
-
}
|
|
814
|
+
};
|
|
815
|
+
function throwNoTargetError() {
|
|
816
|
+
throw new StoreError("NO_TARGET");
|
|
817
|
+
}
|
|
818
|
+
function throwDestroyedError() {
|
|
819
|
+
throw new StoreError("DESTROYED");
|
|
820
|
+
}
|
|
988
821
|
|
|
989
822
|
//#endregion
|
|
990
|
-
//#region ../
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
pip: false,
|
|
995
|
-
pipAvailability: "unavailable",
|
|
996
|
-
async requestPictureInPicture() {
|
|
997
|
-
const { media, container } = target();
|
|
998
|
-
if (isFullscreenElement(container, media)) await exitFullscreen();
|
|
999
|
-
return requestPictureInPicture(media);
|
|
1000
|
-
},
|
|
1001
|
-
async exitPictureInPicture() {
|
|
1002
|
-
const { media } = target();
|
|
1003
|
-
return exitPictureInPicture(media);
|
|
1004
|
-
}
|
|
1005
|
-
}),
|
|
1006
|
-
attach({ target, signal, set }) {
|
|
1007
|
-
const { media } = target;
|
|
1008
|
-
set({ pipAvailability: isPictureInPictureEnabled() ? "available" : "unsupported" });
|
|
1009
|
-
const sync = () => set({ pip: isPictureInPictureElement(media) });
|
|
1010
|
-
sync();
|
|
1011
|
-
listen(media, "enterpictureinpicture", sync, { signal });
|
|
1012
|
-
listen(media, "leavepictureinpicture", sync, { signal });
|
|
1013
|
-
if ("webkitPresentationMode" in media) listen(media, "webkitpresentationmodechanged", sync, { signal });
|
|
1014
|
-
}
|
|
1015
|
-
});
|
|
823
|
+
//#region ../store/dist/dev/core/slice.js
|
|
824
|
+
function defineSlice() {
|
|
825
|
+
return (config) => config;
|
|
826
|
+
}
|
|
1016
827
|
|
|
1017
828
|
//#endregion
|
|
1018
|
-
//#region ../
|
|
1019
|
-
|
|
1020
|
-
name: "playback",
|
|
1021
|
-
state: ({ target }) => ({
|
|
1022
|
-
paused: true,
|
|
1023
|
-
ended: false,
|
|
1024
|
-
started: false,
|
|
1025
|
-
waiting: false,
|
|
1026
|
-
play() {
|
|
1027
|
-
return target().media.play();
|
|
1028
|
-
},
|
|
1029
|
-
pause() {
|
|
1030
|
-
target().media.pause();
|
|
1031
|
-
}
|
|
1032
|
-
}),
|
|
1033
|
-
attach({ target, signal, set }) {
|
|
1034
|
-
const { media } = target;
|
|
1035
|
-
const sync = () => set({
|
|
1036
|
-
paused: media.paused,
|
|
1037
|
-
ended: media.ended,
|
|
1038
|
-
started: !media.paused || media.currentTime > 0,
|
|
1039
|
-
waiting: media.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !media.paused
|
|
1040
|
-
});
|
|
1041
|
-
sync();
|
|
1042
|
-
listen(media, "emptied", sync, { signal });
|
|
1043
|
-
listen(media, "play", sync, { signal });
|
|
1044
|
-
listen(media, "pause", sync, { signal });
|
|
1045
|
-
listen(media, "ended", sync, { signal });
|
|
1046
|
-
listen(media, "playing", sync, { signal });
|
|
1047
|
-
listen(media, "waiting", sync, { signal });
|
|
1048
|
-
listen(media, "seeked", sync, { signal });
|
|
1049
|
-
}
|
|
1050
|
-
});
|
|
829
|
+
//#region ../utils/dist/function/noop.js
|
|
830
|
+
function noop(..._args) {}
|
|
1051
831
|
|
|
1052
832
|
//#endregion
|
|
1053
|
-
//#region ../
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
attach({ target, signal, set }) {
|
|
1074
|
-
const { media } = target;
|
|
1075
|
-
const sync = () => set({ playbackRate: media.playbackRate });
|
|
1076
|
-
sync();
|
|
1077
|
-
listen(media, "ratechange", sync, { signal });
|
|
833
|
+
//#region ../store/dist/dev/core/state.js
|
|
834
|
+
let isFlushScheduled = false;
|
|
835
|
+
function scheduleFlush() {
|
|
836
|
+
if (isFlushScheduled) return;
|
|
837
|
+
isFlushScheduled = true;
|
|
838
|
+
queueMicrotask(flush);
|
|
839
|
+
}
|
|
840
|
+
const pendingContainers = /* @__PURE__ */ new Set();
|
|
841
|
+
function flush() {
|
|
842
|
+
isFlushScheduled = false;
|
|
843
|
+
for (const container of pendingContainers) container.flush();
|
|
844
|
+
pendingContainers.clear();
|
|
845
|
+
}
|
|
846
|
+
const hasOwnProp = Object.prototype.hasOwnProperty;
|
|
847
|
+
var StateContainer = class {
|
|
848
|
+
#current;
|
|
849
|
+
#listeners = /* @__PURE__ */ new Set();
|
|
850
|
+
#pending = false;
|
|
851
|
+
constructor(initial) {
|
|
852
|
+
this.#current = Object.freeze({ ...initial });
|
|
1078
853
|
}
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
const
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
854
|
+
get current() {
|
|
855
|
+
return this.#current;
|
|
856
|
+
}
|
|
857
|
+
patch(partial) {
|
|
858
|
+
const next = { ...this.#current };
|
|
859
|
+
let changed = false;
|
|
860
|
+
for (const key in partial) {
|
|
861
|
+
if (!hasOwnProp.call(partial, key)) continue;
|
|
862
|
+
const value = partial[key];
|
|
863
|
+
if (!Object.is(this.#current[key], value)) {
|
|
864
|
+
next[key] = value;
|
|
865
|
+
changed = true;
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
if (changed) {
|
|
869
|
+
this.#current = Object.freeze(next);
|
|
870
|
+
this.#markPending();
|
|
1094
871
|
}
|
|
1095
|
-
}),
|
|
1096
|
-
attach({ target, signal, set }) {
|
|
1097
|
-
const { media } = target;
|
|
1098
|
-
const sync = () => set({
|
|
1099
|
-
source: media.currentSrc || media.src || null,
|
|
1100
|
-
canPlay: media.readyState >= HTMLMediaElement.HAVE_ENOUGH_DATA
|
|
1101
|
-
});
|
|
1102
|
-
sync();
|
|
1103
|
-
listen(media, "canplay", sync, { signal });
|
|
1104
|
-
listen(media, "canplaythrough", sync, { signal });
|
|
1105
|
-
listen(media, "loadstart", sync, { signal });
|
|
1106
|
-
listen(media, "emptied", sync, { signal });
|
|
1107
872
|
}
|
|
1108
|
-
|
|
873
|
+
subscribe(callback, options) {
|
|
874
|
+
const signal = options?.signal;
|
|
875
|
+
if (signal?.aborted) return noop;
|
|
876
|
+
this.#listeners.add(callback);
|
|
877
|
+
if (!signal) return () => this.#listeners.delete(callback);
|
|
878
|
+
const onAbort = () => this.#listeners.delete(callback);
|
|
879
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
880
|
+
return () => {
|
|
881
|
+
signal.removeEventListener("abort", onAbort);
|
|
882
|
+
this.#listeners.delete(callback);
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
flush() {
|
|
886
|
+
if (!this.#pending) return;
|
|
887
|
+
this.#pending = false;
|
|
888
|
+
for (const fn of this.#listeners) fn();
|
|
889
|
+
}
|
|
890
|
+
#markPending() {
|
|
891
|
+
this.#pending = true;
|
|
892
|
+
pendingContainers.add(this);
|
|
893
|
+
scheduleFlush();
|
|
894
|
+
}
|
|
895
|
+
};
|
|
896
|
+
function createState(initial) {
|
|
897
|
+
return new StateContainer(initial);
|
|
898
|
+
}
|
|
1109
899
|
|
|
1110
900
|
//#endregion
|
|
1111
|
-
//#region ../
|
|
1112
|
-
const
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
if (!
|
|
1123
|
-
const showing = subtitlesTracks.some((track) => track.mode === "showing");
|
|
1124
|
-
const nextShowing = forceShow ?? !showing;
|
|
1125
|
-
for (const track of subtitlesTracks) track.mode = nextShowing ? "showing" : "disabled";
|
|
1126
|
-
return nextShowing;
|
|
901
|
+
//#region ../store/dist/dev/core/store.js
|
|
902
|
+
const STORE_SYMBOL = Symbol("@videojs/store");
|
|
903
|
+
function createStore() {
|
|
904
|
+
return (slice, options = {}) => {
|
|
905
|
+
let target = null;
|
|
906
|
+
let destroyed = false;
|
|
907
|
+
const setupAbort = new AbortController();
|
|
908
|
+
const signals = new AbortControllerRegistry();
|
|
909
|
+
let state;
|
|
910
|
+
function validate() {
|
|
911
|
+
if (destroyed) throwDestroyedError();
|
|
912
|
+
if (!target) throwNoTargetError();
|
|
1127
913
|
}
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
914
|
+
const initialState = slice.state({
|
|
915
|
+
target: () => {
|
|
916
|
+
validate();
|
|
917
|
+
return target;
|
|
918
|
+
},
|
|
919
|
+
signals,
|
|
920
|
+
get: () => state.current,
|
|
921
|
+
set: (partial) => state.patch(partial)
|
|
922
|
+
});
|
|
923
|
+
state = createState(initialState);
|
|
924
|
+
const store = {
|
|
925
|
+
[STORE_SYMBOL]: true,
|
|
926
|
+
get $state() {
|
|
927
|
+
return state;
|
|
928
|
+
},
|
|
929
|
+
get target() {
|
|
930
|
+
return target;
|
|
931
|
+
},
|
|
932
|
+
get destroyed() {
|
|
933
|
+
return destroyed;
|
|
934
|
+
},
|
|
935
|
+
get state() {
|
|
936
|
+
return state.current;
|
|
937
|
+
},
|
|
938
|
+
attach,
|
|
939
|
+
destroy,
|
|
940
|
+
subscribe
|
|
941
|
+
};
|
|
942
|
+
for (const key of Object.keys(initialState)) Object.defineProperty(store, key, {
|
|
943
|
+
get: () => state.current[key],
|
|
944
|
+
enumerable: true
|
|
945
|
+
});
|
|
946
|
+
try {
|
|
947
|
+
options.onSetup?.({
|
|
948
|
+
store,
|
|
949
|
+
signal: setupAbort.signal
|
|
950
|
+
});
|
|
951
|
+
} catch (error) {
|
|
952
|
+
reportError(error);
|
|
953
|
+
}
|
|
954
|
+
return store;
|
|
955
|
+
function attach(newTarget) {
|
|
956
|
+
if (destroyed) throwDestroyedError();
|
|
957
|
+
signals.reset();
|
|
958
|
+
target = newTarget;
|
|
959
|
+
const attachContext = {
|
|
960
|
+
target: newTarget,
|
|
961
|
+
signal: signals.base,
|
|
962
|
+
get: () => state.current,
|
|
963
|
+
set: (partial) => state.patch(partial),
|
|
964
|
+
reportError,
|
|
965
|
+
store: {
|
|
966
|
+
get state() {
|
|
967
|
+
return state.current;
|
|
968
|
+
},
|
|
969
|
+
subscribe
|
|
970
|
+
}
|
|
971
|
+
};
|
|
972
|
+
try {
|
|
973
|
+
slice.attach?.(attachContext);
|
|
974
|
+
} catch (error) {
|
|
975
|
+
reportError(error);
|
|
976
|
+
}
|
|
977
|
+
try {
|
|
978
|
+
options.onAttach?.({
|
|
979
|
+
store,
|
|
980
|
+
target: newTarget,
|
|
981
|
+
signal: signals.base
|
|
1148
982
|
});
|
|
1149
|
-
|
|
983
|
+
} catch (error) {
|
|
984
|
+
reportError(error);
|
|
1150
985
|
}
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
if (
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
986
|
+
return detach;
|
|
987
|
+
}
|
|
988
|
+
function detach() {
|
|
989
|
+
if (isNull(target)) return;
|
|
990
|
+
signals.reset();
|
|
991
|
+
target = null;
|
|
992
|
+
state.patch(initialState);
|
|
993
|
+
}
|
|
994
|
+
function destroy() {
|
|
995
|
+
if (destroyed) return;
|
|
996
|
+
destroyed = true;
|
|
997
|
+
detach();
|
|
998
|
+
setupAbort.abort();
|
|
999
|
+
}
|
|
1000
|
+
function subscribe(callback, options) {
|
|
1001
|
+
return state.subscribe(callback, options);
|
|
1002
|
+
}
|
|
1003
|
+
function reportError(error) {
|
|
1004
|
+
if (options.onError) options.onError({
|
|
1005
|
+
store,
|
|
1006
|
+
error
|
|
1164
1007
|
});
|
|
1008
|
+
else console.error("[vjs-store]", error);
|
|
1165
1009
|
}
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
listen(media, "loadstart", sync, { signal });
|
|
1171
|
-
signal.addEventListener("abort", () => trackCleanup?.abort(), { once: true });
|
|
1172
|
-
}
|
|
1173
|
-
});
|
|
1174
|
-
|
|
1175
|
-
//#endregion
|
|
1176
|
-
//#region ../core/dist/dev/dom/media/predicate.js
|
|
1177
|
-
function hasMetadata(media) {
|
|
1178
|
-
return media.readyState >= HTMLMediaElement.HAVE_METADATA;
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
function isStore(value) {
|
|
1013
|
+
return isObject(value) && STORE_SYMBOL in value;
|
|
1179
1014
|
}
|
|
1180
1015
|
|
|
1181
1016
|
//#endregion
|
|
1182
|
-
//#region ../core/dist/dev/dom/
|
|
1183
|
-
const
|
|
1017
|
+
//#region ../core/dist/dev/dom/feature.js
|
|
1018
|
+
const definePlayerFeature = defineSlice();
|
|
1184
1019
|
|
|
1185
1020
|
//#endregion
|
|
1186
|
-
//#region ../core/dist/dev/dom/store/features/
|
|
1187
|
-
const
|
|
1188
|
-
name: "
|
|
1189
|
-
state: (
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
seeking: false,
|
|
1193
|
-
async seek(time) {
|
|
1194
|
-
const { media } = target(), signal = signals.supersede(signalKeys.seek);
|
|
1195
|
-
if (!hasMetadata(media)) {
|
|
1196
|
-
if (!await onEvent(media, "loadedmetadata", { signal }).catch(() => false)) return media.currentTime;
|
|
1197
|
-
}
|
|
1198
|
-
const clampedTime = Math.max(0, Math.min(time, media.duration || Infinity));
|
|
1199
|
-
set({
|
|
1200
|
-
currentTime: clampedTime,
|
|
1201
|
-
seeking: true
|
|
1202
|
-
});
|
|
1203
|
-
media.currentTime = clampedTime;
|
|
1204
|
-
await onEvent(media, "seeked", { signal }).catch(noop);
|
|
1205
|
-
return media.currentTime;
|
|
1206
|
-
}
|
|
1021
|
+
//#region ../core/dist/dev/dom/store/features/buffer.js
|
|
1022
|
+
const bufferFeature = definePlayerFeature({
|
|
1023
|
+
name: "buffer",
|
|
1024
|
+
state: () => ({
|
|
1025
|
+
buffered: [],
|
|
1026
|
+
seekable: []
|
|
1207
1027
|
}),
|
|
1208
|
-
attach({ target, signal, set
|
|
1028
|
+
attach({ target, signal, set }) {
|
|
1209
1029
|
const { media } = target;
|
|
1210
1030
|
const sync = () => set({
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
seeking: media.seeking
|
|
1031
|
+
buffered: serializeTimeRanges(media.buffered),
|
|
1032
|
+
seekable: serializeTimeRanges(media.seekable)
|
|
1214
1033
|
});
|
|
1215
|
-
const onTimeUpdate = () => {
|
|
1216
|
-
if (get().seeking) return;
|
|
1217
|
-
sync();
|
|
1218
|
-
};
|
|
1219
1034
|
sync();
|
|
1220
|
-
listen(media, "
|
|
1221
|
-
listen(media, "durationchange", sync, { signal });
|
|
1222
|
-
listen(media, "seeking", sync, { signal });
|
|
1223
|
-
listen(media, "seeked", sync, { signal });
|
|
1224
|
-
listen(media, "loadedmetadata", sync, { signal });
|
|
1035
|
+
listen(media, "progress", sync, { signal });
|
|
1225
1036
|
listen(media, "emptied", sync, { signal });
|
|
1226
1037
|
}
|
|
1227
1038
|
});
|
|
1228
1039
|
|
|
1229
1040
|
//#endregion
|
|
1230
|
-
//#region ../core/dist/dev/dom/
|
|
1231
|
-
/**
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
}
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
muted: media.muted
|
|
1261
|
-
});
|
|
1262
|
-
sync();
|
|
1263
|
-
listen(media, "volumechange", sync, { signal });
|
|
1264
|
-
}
|
|
1265
|
-
});
|
|
1266
|
-
/** Check if volume can be programmatically set (fails on iOS Safari). */
|
|
1267
|
-
function canSetVolume() {
|
|
1268
|
-
const video = document.createElement("video");
|
|
1269
|
-
try {
|
|
1270
|
-
video.volume = .5;
|
|
1271
|
-
return video.volume === .5 ? "available" : "unsupported";
|
|
1272
|
-
} catch {
|
|
1273
|
-
return "unsupported";
|
|
1041
|
+
//#region ../core/dist/dev/dom/gesture/region.js
|
|
1042
|
+
/**
|
|
1043
|
+
* Determine which named region a pointer position falls into.
|
|
1044
|
+
*
|
|
1045
|
+
* Regions divide the container width equally based on how many are active:
|
|
1046
|
+
* - `left` + `right` → halves (50% / 50%)
|
|
1047
|
+
* - `left` + `center` + `right` → thirds (33% / 34% / 33%)
|
|
1048
|
+
*
|
|
1049
|
+
* Single region: `left` covers the left half, `right` the right half,
|
|
1050
|
+
* and `center` covers the full surface. Partial two-region combos
|
|
1051
|
+
* (e.g. `left` + `center`) use the same natural zones — positions outside
|
|
1052
|
+
* all active zones return `null` so full-surface gestures can handle them.
|
|
1053
|
+
*/
|
|
1054
|
+
function resolveRegion(clientX, containerRect, activeRegions) {
|
|
1055
|
+
if (activeRegions.size === 0) return null;
|
|
1056
|
+
const relativeX = clientX - containerRect.left;
|
|
1057
|
+
const width = containerRect.width;
|
|
1058
|
+
if (width === 0) return null;
|
|
1059
|
+
const ratio = relativeX / width;
|
|
1060
|
+
if (activeRegions.size === 2 && activeRegions.has("left") && activeRegions.has("right")) return ratio < .5 ? "left" : "right";
|
|
1061
|
+
if (activeRegions.size === 3) {
|
|
1062
|
+
if (ratio < 1 / 3) return "left";
|
|
1063
|
+
if (ratio < 2 / 3) return "center";
|
|
1064
|
+
return "right";
|
|
1065
|
+
}
|
|
1066
|
+
if (activeRegions.has("left") && ratio < .5) return "left";
|
|
1067
|
+
if (activeRegions.has("right") && ratio >= .5) return "right";
|
|
1068
|
+
if (activeRegions.has("center")) {
|
|
1069
|
+
if (activeRegions.size === 1) return "center";
|
|
1070
|
+
if (ratio >= 1 / 3 && ratio < 2 / 3) return "center";
|
|
1274
1071
|
}
|
|
1072
|
+
return null;
|
|
1275
1073
|
}
|
|
1276
1074
|
|
|
1277
1075
|
//#endregion
|
|
1278
|
-
//#region ../core/dist/dev/dom/
|
|
1279
|
-
const
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
//#endregion
|
|
1304
|
-
//#region ../../node_modules/.pnpm/@lit+context@1.1.6/node_modules/@lit/context/development/lib/controllers/context-consumer.js
|
|
1305
|
-
/**
|
|
1306
|
-
* @license
|
|
1307
|
-
* Copyright 2021 Google LLC
|
|
1308
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
1309
|
-
*/
|
|
1310
|
-
/**
|
|
1311
|
-
* A ReactiveController which adds context consuming behavior to a custom
|
|
1312
|
-
* element by dispatching `context-request` events.
|
|
1313
|
-
*
|
|
1314
|
-
* When the host element is connected to the document it will emit a
|
|
1315
|
-
* `context-request` event with its context key. When the context request
|
|
1316
|
-
* is satisfied the controller will invoke the callback, if present, and
|
|
1317
|
-
* trigger a host update so it can respond to the new value.
|
|
1318
|
-
*
|
|
1319
|
-
* It will also call the dispose method given by the provider when the
|
|
1320
|
-
* host element is disconnected.
|
|
1321
|
-
*/
|
|
1322
|
-
var ContextConsumer = class {
|
|
1323
|
-
constructor(host, contextOrOptions, callback, subscribe) {
|
|
1324
|
-
this.subscribe = false;
|
|
1325
|
-
this.provided = false;
|
|
1326
|
-
this.value = void 0;
|
|
1327
|
-
this._callback = (value, unsubscribe) => {
|
|
1328
|
-
if (this.unsubscribe) {
|
|
1329
|
-
if (this.unsubscribe !== unsubscribe) {
|
|
1330
|
-
this.provided = false;
|
|
1331
|
-
this.unsubscribe();
|
|
1332
|
-
}
|
|
1333
|
-
if (!this.subscribe) this.unsubscribe();
|
|
1334
|
-
}
|
|
1335
|
-
this.value = value;
|
|
1336
|
-
this.host.requestUpdate();
|
|
1337
|
-
if (!this.provided || this.subscribe) {
|
|
1338
|
-
this.provided = true;
|
|
1339
|
-
if (this.callback) this.callback(value, unsubscribe);
|
|
1340
|
-
}
|
|
1341
|
-
this.unsubscribe = unsubscribe;
|
|
1076
|
+
//#region ../core/dist/dev/dom/gesture/coordinator.js
|
|
1077
|
+
const TAP_THRESHOLD$1 = 250;
|
|
1078
|
+
var GestureCoordinator = class {
|
|
1079
|
+
#target;
|
|
1080
|
+
#bindings = [];
|
|
1081
|
+
#recognizers = /* @__PURE__ */ new Set();
|
|
1082
|
+
#disconnect = null;
|
|
1083
|
+
constructor(target) {
|
|
1084
|
+
this.#target = target;
|
|
1085
|
+
}
|
|
1086
|
+
get bindings() {
|
|
1087
|
+
return this.#bindings;
|
|
1088
|
+
}
|
|
1089
|
+
add(binding) {
|
|
1090
|
+
this.#bindings.push(binding);
|
|
1091
|
+
this.#recognizers.add(binding.recognizer);
|
|
1092
|
+
this.#connect();
|
|
1093
|
+
let removed = false;
|
|
1094
|
+
return () => {
|
|
1095
|
+
if (removed) return;
|
|
1096
|
+
removed = true;
|
|
1097
|
+
const idx = this.#bindings.indexOf(binding);
|
|
1098
|
+
if (idx !== -1) this.#bindings.splice(idx, 1);
|
|
1099
|
+
this.#maybeDisconnect();
|
|
1342
1100
|
};
|
|
1343
|
-
this.host = host;
|
|
1344
|
-
if (contextOrOptions.context !== void 0) {
|
|
1345
|
-
const options = contextOrOptions;
|
|
1346
|
-
this.context = options.context;
|
|
1347
|
-
this.callback = options.callback;
|
|
1348
|
-
this.subscribe = options.subscribe ?? false;
|
|
1349
|
-
} else {
|
|
1350
|
-
this.context = contextOrOptions;
|
|
1351
|
-
this.callback = callback;
|
|
1352
|
-
this.subscribe = subscribe ?? false;
|
|
1353
|
-
}
|
|
1354
|
-
this.host.addController(this);
|
|
1355
1101
|
}
|
|
1356
|
-
|
|
1357
|
-
this
|
|
1102
|
+
#connect() {
|
|
1103
|
+
if (this.#disconnect) return;
|
|
1104
|
+
this.#disconnect = new AbortController();
|
|
1105
|
+
const { signal } = this.#disconnect;
|
|
1106
|
+
let pointerDownTime = 0;
|
|
1107
|
+
listen(this.#target, "pointerdown", () => {
|
|
1108
|
+
pointerDownTime = Date.now();
|
|
1109
|
+
}, { signal });
|
|
1110
|
+
listen(this.#target, "pointerup", (event) => {
|
|
1111
|
+
if (Date.now() - pointerDownTime > TAP_THRESHOLD$1) return;
|
|
1112
|
+
if (isInteractiveTarget(event)) return;
|
|
1113
|
+
const pointerType = event.pointerType;
|
|
1114
|
+
const clientX = event.clientX;
|
|
1115
|
+
const target = this.#target;
|
|
1116
|
+
const bindings = this.#bindings;
|
|
1117
|
+
const matches = { resolve: (type) => matchBindings(bindings, type, pointerType, clientX, target) };
|
|
1118
|
+
for (const recognizer of this.#recognizers) recognizer.handleUp(matches, event);
|
|
1119
|
+
}, { signal });
|
|
1120
|
+
}
|
|
1121
|
+
#maybeDisconnect() {
|
|
1122
|
+
if (this.#bindings.length > 0) return;
|
|
1123
|
+
for (const recognizer of this.#recognizers) recognizer.reset();
|
|
1124
|
+
this.#recognizers.clear();
|
|
1125
|
+
this.#disconnect?.abort();
|
|
1126
|
+
this.#disconnect = null;
|
|
1358
1127
|
}
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1128
|
+
};
|
|
1129
|
+
const coordinators = /* @__PURE__ */ new WeakMap();
|
|
1130
|
+
/** Look up the gesture coordinator for a target element, if one exists. */
|
|
1131
|
+
function findGestureCoordinator(target) {
|
|
1132
|
+
return coordinators.get(target);
|
|
1133
|
+
}
|
|
1134
|
+
function getGestureCoordinator(target) {
|
|
1135
|
+
let coordinator = coordinators.get(target);
|
|
1136
|
+
if (!coordinator) {
|
|
1137
|
+
coordinator = new GestureCoordinator(target);
|
|
1138
|
+
coordinators.set(target, coordinator);
|
|
1139
|
+
}
|
|
1140
|
+
return coordinator;
|
|
1141
|
+
}
|
|
1142
|
+
function matchBindings(bindings, type, pointerType, clientX, target) {
|
|
1143
|
+
const rect = target.getBoundingClientRect();
|
|
1144
|
+
const activeRegions = getActiveRegions(bindings, type, pointerType);
|
|
1145
|
+
const region = activeRegions.size > 0 ? resolveRegion(clientX, rect, activeRegions) : null;
|
|
1146
|
+
const matches = [];
|
|
1147
|
+
for (const binding of bindings) {
|
|
1148
|
+
if (binding.disabled) continue;
|
|
1149
|
+
if (binding.type !== type) continue;
|
|
1150
|
+
if (binding.pointer && binding.pointer !== pointerType) continue;
|
|
1151
|
+
if (binding.region) {
|
|
1152
|
+
if (binding.region !== region) continue;
|
|
1153
|
+
} else if (region !== null) continue;
|
|
1154
|
+
matches.push(binding);
|
|
1155
|
+
}
|
|
1156
|
+
return matches;
|
|
1157
|
+
}
|
|
1158
|
+
function getActiveRegions(bindings, type, pointerType) {
|
|
1159
|
+
const regions = /* @__PURE__ */ new Set();
|
|
1160
|
+
for (const binding of bindings) {
|
|
1161
|
+
if (binding.disabled) continue;
|
|
1162
|
+
if (binding.type !== type) continue;
|
|
1163
|
+
if (binding.pointer && binding.pointer !== pointerType) continue;
|
|
1164
|
+
if (binding.region) regions.add(binding.region);
|
|
1165
|
+
}
|
|
1166
|
+
return regions;
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
//#endregion
|
|
1170
|
+
//#region ../core/dist/dev/dom/store/features/controls.js
|
|
1171
|
+
const IDLE_DELAY = 2e3;
|
|
1172
|
+
const TAP_THRESHOLD = 250;
|
|
1173
|
+
const controlsFeature = definePlayerFeature({
|
|
1174
|
+
name: "controls",
|
|
1175
|
+
state: ({ get, set }) => ({
|
|
1176
|
+
userActive: true,
|
|
1177
|
+
controlsVisible: true,
|
|
1178
|
+
toggleControls() {
|
|
1179
|
+
const next = !get().userActive;
|
|
1180
|
+
set({
|
|
1181
|
+
userActive: next,
|
|
1182
|
+
controlsVisible: next
|
|
1183
|
+
});
|
|
1184
|
+
return next;
|
|
1185
|
+
}
|
|
1186
|
+
}),
|
|
1187
|
+
attach({ target, signal, get, set }) {
|
|
1188
|
+
const { media, container } = target;
|
|
1189
|
+
if (isNull(container)) {
|
|
1190
|
+
console.warn("[vjs] controlsFeature requires a container element for activity tracking.");
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1193
|
+
function computeVisible(userActive) {
|
|
1194
|
+
return userActive || media.paused;
|
|
1195
|
+
}
|
|
1196
|
+
let idleTimer;
|
|
1197
|
+
function clearIdle() {
|
|
1198
|
+
clearTimeout(idleTimer);
|
|
1199
|
+
idleTimer = void 0;
|
|
1200
|
+
}
|
|
1201
|
+
function scheduleIdle() {
|
|
1202
|
+
clearIdle();
|
|
1203
|
+
idleTimer = setTimeout(setInactive, IDLE_DELAY);
|
|
1204
|
+
}
|
|
1205
|
+
function setActive() {
|
|
1206
|
+
if (!get().userActive) set({
|
|
1207
|
+
userActive: true,
|
|
1208
|
+
controlsVisible: true
|
|
1209
|
+
});
|
|
1210
|
+
scheduleIdle();
|
|
1211
|
+
}
|
|
1212
|
+
function setInactive() {
|
|
1213
|
+
clearIdle();
|
|
1214
|
+
set({
|
|
1215
|
+
userActive: false,
|
|
1216
|
+
controlsVisible: computeVisible(false)
|
|
1217
|
+
});
|
|
1218
|
+
}
|
|
1219
|
+
set({ toggleControls() {
|
|
1220
|
+
if (get().controlsVisible) setInactive();
|
|
1221
|
+
else setActive();
|
|
1222
|
+
return get().controlsVisible;
|
|
1223
|
+
} });
|
|
1224
|
+
let pointerDownTime = 0;
|
|
1225
|
+
function onPointerDown() {
|
|
1226
|
+
pointerDownTime = Date.now();
|
|
1227
|
+
}
|
|
1228
|
+
function onPointerUp(event) {
|
|
1229
|
+
if (event.pointerType === "touch" && Date.now() - pointerDownTime < TAP_THRESHOLD) {
|
|
1230
|
+
if (findGestureCoordinator(container)?.bindings.some((b) => b.type === "tap" && b.action === "toggleControls" && (!b.pointer || b.pointer === "touch"))) return;
|
|
1231
|
+
const isMediaOrContainer = [media, container].includes(event.target);
|
|
1232
|
+
if (get().controlsVisible && isMediaOrContainer) setInactive();
|
|
1233
|
+
else setActive();
|
|
1234
|
+
} else setActive();
|
|
1235
|
+
}
|
|
1236
|
+
function onPlaybackChange() {
|
|
1237
|
+
const { userActive } = get();
|
|
1238
|
+
set({ controlsVisible: computeVisible(userActive) });
|
|
1239
|
+
if (!media.paused && userActive) scheduleIdle();
|
|
1363
1240
|
}
|
|
1241
|
+
listen(container, "pointermove", setActive, { signal });
|
|
1242
|
+
listen(container, "pointerdown", onPointerDown, { signal });
|
|
1243
|
+
listen(container, "pointerup", onPointerUp, { signal });
|
|
1244
|
+
listen(container, "keyup", setActive, { signal });
|
|
1245
|
+
listen(container, "focusin", setActive, { signal });
|
|
1246
|
+
listen(container, "mouseleave", setInactive, { signal });
|
|
1247
|
+
listen(media, "play", onPlaybackChange, { signal });
|
|
1248
|
+
listen(media, "pause", onPlaybackChange, { signal });
|
|
1249
|
+
listen(media, "ended", onPlaybackChange, { signal });
|
|
1250
|
+
signal.addEventListener("abort", clearIdle, { once: true });
|
|
1251
|
+
scheduleIdle();
|
|
1364
1252
|
}
|
|
1365
|
-
|
|
1366
|
-
|
|
1253
|
+
});
|
|
1254
|
+
|
|
1255
|
+
//#endregion
|
|
1256
|
+
//#region ../core/dist/dev/dom/store/features/error.js
|
|
1257
|
+
const errorFeature = definePlayerFeature({
|
|
1258
|
+
name: "error",
|
|
1259
|
+
state: ({ set }) => ({
|
|
1260
|
+
error: null,
|
|
1261
|
+
dismissError() {
|
|
1262
|
+
set({ error: null });
|
|
1263
|
+
}
|
|
1264
|
+
}),
|
|
1265
|
+
attach({ target, signal, set }) {
|
|
1266
|
+
const { media } = target;
|
|
1267
|
+
const syncError = () => set({ error: media.error });
|
|
1268
|
+
listen(media, "error", syncError, { signal });
|
|
1269
|
+
listen(media, "emptied", () => set({ error: null }), { signal });
|
|
1367
1270
|
}
|
|
1368
|
-
};
|
|
1271
|
+
});
|
|
1369
1272
|
|
|
1370
1273
|
//#endregion
|
|
1371
|
-
//#region
|
|
1274
|
+
//#region ../core/dist/dev/dom/presentation/fullscreen.js
|
|
1275
|
+
/** Check if the Fullscreen API is supported on this platform. */
|
|
1276
|
+
function isFullscreenEnabled() {
|
|
1277
|
+
const doc = document;
|
|
1278
|
+
if (doc.fullscreenEnabled || doc.webkitFullscreenEnabled) return true;
|
|
1279
|
+
return isFunction(document.createElement("video").webkitEnterFullscreen);
|
|
1280
|
+
}
|
|
1281
|
+
/** Get the current fullscreen element from the document. */
|
|
1282
|
+
function getFullscreenElement() {
|
|
1283
|
+
const doc = document;
|
|
1284
|
+
return doc.fullscreenElement ?? doc.webkitFullscreenElement ?? null;
|
|
1285
|
+
}
|
|
1372
1286
|
/**
|
|
1373
|
-
*
|
|
1374
|
-
*
|
|
1375
|
-
*
|
|
1287
|
+
* Check if a specific element (or its media) is currently in fullscreen.
|
|
1288
|
+
*
|
|
1289
|
+
* Uses `:fullscreen` pseudo-class which works across Shadow DOM boundaries.
|
|
1376
1290
|
*/
|
|
1291
|
+
function isFullscreenElement(container, media) {
|
|
1292
|
+
const video = media;
|
|
1293
|
+
if (video.webkitDisplayingFullscreen && video.webkitPresentationMode === "fullscreen") return true;
|
|
1294
|
+
const target = container ?? media;
|
|
1295
|
+
if (getFullscreenElement() === target) return true;
|
|
1296
|
+
try {
|
|
1297
|
+
return target.matches(":fullscreen");
|
|
1298
|
+
} catch {
|
|
1299
|
+
return false;
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1377
1302
|
/**
|
|
1378
|
-
*
|
|
1379
|
-
* the value is changed via its setter.
|
|
1303
|
+
* Request fullscreen mode.
|
|
1380
1304
|
*
|
|
1381
|
-
*
|
|
1382
|
-
*
|
|
1383
|
-
* likely work for a number of use cases.
|
|
1305
|
+
* Tries container first (to show custom UI), falls back to media element
|
|
1306
|
+
* for platforms that only support video fullscreen (iOS Safari).
|
|
1384
1307
|
*/
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1308
|
+
async function requestFullscreen(container, media) {
|
|
1309
|
+
const doc = document;
|
|
1310
|
+
const video = media;
|
|
1311
|
+
if (container && (doc.fullscreenEnabled || doc.webkitFullscreenEnabled)) {
|
|
1312
|
+
const el = container;
|
|
1313
|
+
if (isFunction(el.requestFullscreen)) return el.requestFullscreen();
|
|
1314
|
+
if (isFunction(el.webkitRequestFullscreen)) return el.webkitRequestFullscreen();
|
|
1388
1315
|
}
|
|
1389
|
-
|
|
1390
|
-
|
|
1316
|
+
if (isFunction(video.webkitEnterFullscreen)) {
|
|
1317
|
+
video.webkitEnterFullscreen();
|
|
1318
|
+
return;
|
|
1391
1319
|
}
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
if (defaultValue !== void 0) this.value = defaultValue;
|
|
1403
|
-
}
|
|
1404
|
-
addCallback(callback, consumerHost, subscribe) {
|
|
1405
|
-
if (!subscribe) {
|
|
1406
|
-
callback(this.value);
|
|
1320
|
+
if (isFunction(media.requestFullscreen)) return media.requestFullscreen();
|
|
1321
|
+
throw new DOMException("Fullscreen not supported", "NotSupportedError");
|
|
1322
|
+
}
|
|
1323
|
+
/** Exit fullscreen mode. */
|
|
1324
|
+
async function exitFullscreen(media) {
|
|
1325
|
+
const doc = document;
|
|
1326
|
+
if (media) {
|
|
1327
|
+
const video = media;
|
|
1328
|
+
if (isFunction(video.webkitExitFullscreen) && video.webkitDisplayingFullscreen) {
|
|
1329
|
+
video.webkitExitFullscreen();
|
|
1407
1330
|
return;
|
|
1408
1331
|
}
|
|
1409
|
-
if (!this.subscriptions.has(callback)) this.subscriptions.set(callback, {
|
|
1410
|
-
disposer: () => {
|
|
1411
|
-
this.subscriptions.delete(callback);
|
|
1412
|
-
},
|
|
1413
|
-
consumerHost
|
|
1414
|
-
});
|
|
1415
|
-
const { disposer } = this.subscriptions.get(callback);
|
|
1416
|
-
callback(this.value, disposer);
|
|
1417
|
-
}
|
|
1418
|
-
clearCallbacks() {
|
|
1419
|
-
this.subscriptions.clear();
|
|
1420
1332
|
}
|
|
1421
|
-
|
|
1333
|
+
if (isFunction(doc.exitFullscreen)) return doc.exitFullscreen();
|
|
1334
|
+
if (isFunction(doc.webkitExitFullscreen)) return doc.webkitExitFullscreen();
|
|
1335
|
+
}
|
|
1422
1336
|
|
|
1423
1337
|
//#endregion
|
|
1424
|
-
//#region
|
|
1338
|
+
//#region ../core/dist/dev/dom/presentation/pip.js
|
|
1339
|
+
function resolveMediaTarget(media) {
|
|
1340
|
+
const target = media.target;
|
|
1341
|
+
return target instanceof HTMLMediaElement ? target : media;
|
|
1342
|
+
}
|
|
1425
1343
|
/**
|
|
1426
|
-
*
|
|
1427
|
-
*
|
|
1428
|
-
*
|
|
1344
|
+
* Check if Picture-in-Picture is supported on this platform.
|
|
1345
|
+
*
|
|
1346
|
+
* Note: Safari PWAs don't support PiP even though the API exists.
|
|
1429
1347
|
*/
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
*/
|
|
1436
|
-
constructor(context, contextTarget) {
|
|
1437
|
-
super("context-provider", {
|
|
1438
|
-
bubbles: true,
|
|
1439
|
-
composed: true
|
|
1440
|
-
});
|
|
1441
|
-
this.context = context;
|
|
1442
|
-
this.contextTarget = contextTarget;
|
|
1348
|
+
function isPictureInPictureEnabled() {
|
|
1349
|
+
if (document.pictureInPictureEnabled) {
|
|
1350
|
+
const isSafari = /.*Version\/.*Safari\/.*/.test(navigator.userAgent);
|
|
1351
|
+
const isPWA = typeof matchMedia === "function" && matchMedia("(display-mode: standalone)").matches;
|
|
1352
|
+
return !isSafari || !isPWA;
|
|
1443
1353
|
}
|
|
1444
|
-
|
|
1354
|
+
return isFunction(document.createElement("video").webkitSetPresentationMode);
|
|
1355
|
+
}
|
|
1445
1356
|
/**
|
|
1446
|
-
*
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1357
|
+
* Check if Picture-in-Picture is currently active for a media element.
|
|
1358
|
+
*/
|
|
1359
|
+
function isPictureInPictureElement(media) {
|
|
1360
|
+
const target = resolveMediaTarget(media);
|
|
1361
|
+
if (document.pictureInPictureElement === target) return true;
|
|
1362
|
+
return target.webkitPresentationMode === "picture-in-picture";
|
|
1363
|
+
}
|
|
1364
|
+
/**
|
|
1365
|
+
* Request Picture-in-Picture mode.
|
|
1452
1366
|
*
|
|
1453
|
-
*
|
|
1454
|
-
*
|
|
1455
|
-
* done automatically for any custom elements implementing
|
|
1456
|
-
* ReactiveControllerHost.
|
|
1367
|
+
* Uses standard API where available, falls back to iOS Safari's
|
|
1368
|
+
* WebKit presentation mode.
|
|
1457
1369
|
*/
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
const consumerHost = ev.contextTarget ?? ev.composedPath()[0];
|
|
1464
|
-
if (consumerHost === this.host) return;
|
|
1465
|
-
ev.stopPropagation();
|
|
1466
|
-
this.addCallback(ev.callback, consumerHost, ev.subscribe);
|
|
1467
|
-
};
|
|
1468
|
-
/**
|
|
1469
|
-
* When we get a provider request event, that means a child of this element
|
|
1470
|
-
* has just woken up. If it's a provider of our context, then we may need to
|
|
1471
|
-
* re-parent our subscriptions, because is a more specific provider than us
|
|
1472
|
-
* for its subtree.
|
|
1473
|
-
*/
|
|
1474
|
-
this.onProviderRequest = (ev) => {
|
|
1475
|
-
if (ev.context !== this.context) return;
|
|
1476
|
-
if ((ev.contextTarget ?? ev.composedPath()[0]) === this.host) return;
|
|
1477
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1478
|
-
for (const [callback, { consumerHost }] of this.subscriptions) {
|
|
1479
|
-
if (seen.has(callback)) continue;
|
|
1480
|
-
seen.add(callback);
|
|
1481
|
-
consumerHost.dispatchEvent(new ContextRequestEvent(this.context, consumerHost, callback, true));
|
|
1482
|
-
}
|
|
1483
|
-
ev.stopPropagation();
|
|
1484
|
-
};
|
|
1485
|
-
this.host = host;
|
|
1486
|
-
if (contextOrOptions.context !== void 0) this.context = contextOrOptions.context;
|
|
1487
|
-
else this.context = contextOrOptions;
|
|
1488
|
-
this.attachListeners();
|
|
1489
|
-
this.host.addController?.(this);
|
|
1490
|
-
}
|
|
1491
|
-
attachListeners() {
|
|
1492
|
-
this.host.addEventListener("context-request", this.onContextRequest);
|
|
1493
|
-
this.host.addEventListener("context-provider", this.onProviderRequest);
|
|
1370
|
+
async function requestPictureInPicture(media) {
|
|
1371
|
+
const video = resolveMediaTarget(media);
|
|
1372
|
+
if (isFunction(video.webkitSetPresentationMode)) {
|
|
1373
|
+
video.webkitSetPresentationMode("picture-in-picture");
|
|
1374
|
+
return;
|
|
1494
1375
|
}
|
|
1495
|
-
|
|
1496
|
-
|
|
1376
|
+
if (isFunction(video.requestPictureInPicture)) {
|
|
1377
|
+
await video.requestPictureInPicture();
|
|
1378
|
+
return;
|
|
1497
1379
|
}
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
//#endregion
|
|
1501
|
-
//#region src/store/container-mixin.ts
|
|
1380
|
+
throw new DOMException("Picture-in-Picture not supported", "NotSupportedError");
|
|
1381
|
+
}
|
|
1502
1382
|
/**
|
|
1503
|
-
*
|
|
1504
|
-
* container element with the provider via `containerContext`.
|
|
1383
|
+
* Exit Picture-in-Picture mode.
|
|
1505
1384
|
*
|
|
1506
|
-
*
|
|
1385
|
+
* Uses standard API where available, falls back to iOS Safari's
|
|
1386
|
+
* WebKit presentation mode.
|
|
1507
1387
|
*/
|
|
1508
|
-
function
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
super(...args);
|
|
1515
|
-
new ContextConsumer(this, {
|
|
1516
|
-
context: config.playerContext,
|
|
1517
|
-
callback: (value) => {
|
|
1518
|
-
this.#contextStore = value ?? null;
|
|
1519
|
-
},
|
|
1520
|
-
subscribe: true
|
|
1521
|
-
});
|
|
1522
|
-
new ContextConsumer(this, {
|
|
1523
|
-
context: config.containerContext,
|
|
1524
|
-
callback: (value) => {
|
|
1525
|
-
this.#setContainer = value?.setContainer ?? null;
|
|
1526
|
-
if (this.isConnected) this.#setContainer?.(this);
|
|
1527
|
-
},
|
|
1528
|
-
subscribe: true
|
|
1529
|
-
});
|
|
1530
|
-
}
|
|
1531
|
-
get store() {
|
|
1532
|
-
return this.#contextStore;
|
|
1533
|
-
}
|
|
1534
|
-
connectedCallback() {
|
|
1535
|
-
super.connectedCallback();
|
|
1536
|
-
this.#setContainer?.(this);
|
|
1537
|
-
}
|
|
1538
|
-
disconnectedCallback() {
|
|
1539
|
-
super.disconnectedCallback();
|
|
1540
|
-
this.#setContainer?.(null);
|
|
1541
|
-
}
|
|
1388
|
+
async function exitPictureInPicture(media) {
|
|
1389
|
+
if (media) {
|
|
1390
|
+
const video = resolveMediaTarget(media);
|
|
1391
|
+
if (isFunction(video.webkitSetPresentationMode) && video.webkitPresentationMode === "picture-in-picture") {
|
|
1392
|
+
video.webkitSetPresentationMode("inline");
|
|
1393
|
+
return;
|
|
1542
1394
|
}
|
|
1543
|
-
|
|
1544
|
-
|
|
1395
|
+
}
|
|
1396
|
+
if (isFunction(document.exitPictureInPicture)) return document.exitPictureInPicture();
|
|
1545
1397
|
}
|
|
1546
1398
|
|
|
1547
1399
|
//#endregion
|
|
1548
|
-
//#region
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1400
|
+
//#region ../core/dist/dev/dom/store/features/fullscreen.js
|
|
1401
|
+
const fullscreenFeature = definePlayerFeature({
|
|
1402
|
+
name: "fullscreen",
|
|
1403
|
+
state: ({ target }) => ({
|
|
1404
|
+
fullscreen: false,
|
|
1405
|
+
fullscreenAvailability: "unavailable",
|
|
1406
|
+
async requestFullscreen() {
|
|
1407
|
+
const { media, container } = target();
|
|
1408
|
+
if (isPictureInPictureElement(media)) await exitPictureInPicture(media);
|
|
1409
|
+
return requestFullscreen(container, media);
|
|
1410
|
+
},
|
|
1411
|
+
async exitFullscreen() {
|
|
1412
|
+
const { media } = target();
|
|
1413
|
+
return exitFullscreen(media);
|
|
1414
|
+
},
|
|
1415
|
+
async toggleFullscreen() {
|
|
1416
|
+
const { media, container } = target();
|
|
1417
|
+
if (isFullscreenElement(container, media)) return exitFullscreen(media);
|
|
1418
|
+
if (isPictureInPictureElement(media)) await exitPictureInPicture(media);
|
|
1419
|
+
return requestFullscreen(container, media);
|
|
1420
|
+
}
|
|
1421
|
+
}),
|
|
1422
|
+
attach({ target, signal, set }) {
|
|
1423
|
+
const { media, container } = target;
|
|
1424
|
+
set({ fullscreenAvailability: isFullscreenEnabled() ? "available" : "unsupported" });
|
|
1425
|
+
const sync = () => set({ fullscreen: isFullscreenElement(container, media) });
|
|
1426
|
+
sync();
|
|
1427
|
+
listen(document, "fullscreenchange", sync, { signal });
|
|
1428
|
+
listen(document, "webkitfullscreenchange", sync, { signal });
|
|
1429
|
+
if ("webkitPresentationMode" in media) listen(media, "webkitpresentationmodechanged", sync, { signal });
|
|
1573
1430
|
}
|
|
1574
|
-
|
|
1575
|
-
if (!this.contains(document.activeElement) || document.activeElement === document.body) this.focus({ preventScroll: true });
|
|
1576
|
-
};
|
|
1577
|
-
};
|
|
1431
|
+
});
|
|
1578
1432
|
|
|
1579
1433
|
//#endregion
|
|
1580
|
-
//#region
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
initialValue: {
|
|
1634
|
-
container: this.#container,
|
|
1635
|
-
setContainer: this.#setContainer
|
|
1636
|
-
}
|
|
1637
|
-
});
|
|
1638
|
-
get store() {
|
|
1639
|
-
if (isNull(this.#store)) this.#store = config.factory();
|
|
1640
|
-
return this.#store;
|
|
1434
|
+
//#region ../core/dist/dev/dom/store/features/pip.js
|
|
1435
|
+
const pipFeature = definePlayerFeature({
|
|
1436
|
+
name: "pip",
|
|
1437
|
+
state: ({ target }) => ({
|
|
1438
|
+
pip: false,
|
|
1439
|
+
pipAvailability: "unavailable",
|
|
1440
|
+
async requestPictureInPicture() {
|
|
1441
|
+
const { media, container } = target();
|
|
1442
|
+
if (isFullscreenElement(container, media)) await exitFullscreen();
|
|
1443
|
+
return requestPictureInPicture(media);
|
|
1444
|
+
},
|
|
1445
|
+
async exitPictureInPicture() {
|
|
1446
|
+
const { media } = target();
|
|
1447
|
+
return exitPictureInPicture(media);
|
|
1448
|
+
},
|
|
1449
|
+
async togglePictureInPicture() {
|
|
1450
|
+
const { media, container } = target();
|
|
1451
|
+
if (isPictureInPictureElement(media)) return exitPictureInPicture(media);
|
|
1452
|
+
if (isFullscreenElement(container, media)) await exitFullscreen();
|
|
1453
|
+
return requestPictureInPicture(media);
|
|
1454
|
+
}
|
|
1455
|
+
}),
|
|
1456
|
+
attach({ target, signal, set }) {
|
|
1457
|
+
const { media } = target;
|
|
1458
|
+
set({ pipAvailability: isPictureInPictureEnabled() ? "available" : "unsupported" });
|
|
1459
|
+
const sync = () => set({ pip: isPictureInPictureElement(media) });
|
|
1460
|
+
sync();
|
|
1461
|
+
listen(media, "enterpictureinpicture", sync, { signal });
|
|
1462
|
+
listen(media, "leavepictureinpicture", sync, { signal });
|
|
1463
|
+
if ("webkitPresentationMode" in media) listen(media, "webkitpresentationmodechanged", sync, { signal });
|
|
1464
|
+
}
|
|
1465
|
+
});
|
|
1466
|
+
|
|
1467
|
+
//#endregion
|
|
1468
|
+
//#region ../core/dist/dev/dom/store/features/playback.js
|
|
1469
|
+
const playbackFeature = definePlayerFeature({
|
|
1470
|
+
name: "playback",
|
|
1471
|
+
state: ({ target }) => ({
|
|
1472
|
+
paused: true,
|
|
1473
|
+
ended: false,
|
|
1474
|
+
started: false,
|
|
1475
|
+
waiting: false,
|
|
1476
|
+
play() {
|
|
1477
|
+
return target().media.play();
|
|
1478
|
+
},
|
|
1479
|
+
pause() {
|
|
1480
|
+
target().media.pause();
|
|
1481
|
+
},
|
|
1482
|
+
togglePaused() {
|
|
1483
|
+
const media = target().media;
|
|
1484
|
+
if (media.paused) {
|
|
1485
|
+
media.play();
|
|
1486
|
+
return true;
|
|
1641
1487
|
}
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1488
|
+
media.pause();
|
|
1489
|
+
return false;
|
|
1490
|
+
}
|
|
1491
|
+
}),
|
|
1492
|
+
attach({ target, signal, set }) {
|
|
1493
|
+
const { media } = target;
|
|
1494
|
+
const sync = () => set({
|
|
1495
|
+
paused: media.paused,
|
|
1496
|
+
ended: media.ended,
|
|
1497
|
+
started: !media.paused || media.currentTime > 0,
|
|
1498
|
+
waiting: media.readyState < HTMLMediaElement.HAVE_FUTURE_DATA && !media.paused
|
|
1499
|
+
});
|
|
1500
|
+
sync();
|
|
1501
|
+
listen(media, "emptied", sync, { signal });
|
|
1502
|
+
listen(media, "play", sync, { signal });
|
|
1503
|
+
listen(media, "pause", sync, { signal });
|
|
1504
|
+
listen(media, "ended", sync, { signal });
|
|
1505
|
+
listen(media, "playing", sync, { signal });
|
|
1506
|
+
listen(media, "waiting", sync, { signal });
|
|
1507
|
+
listen(media, "seeked", sync, { signal });
|
|
1508
|
+
}
|
|
1509
|
+
});
|
|
1510
|
+
|
|
1511
|
+
//#endregion
|
|
1512
|
+
//#region ../core/dist/dev/dom/store/features/playback-rate.js
|
|
1513
|
+
const DEFAULT_RATES = [
|
|
1514
|
+
.2,
|
|
1515
|
+
.5,
|
|
1516
|
+
.7,
|
|
1517
|
+
1,
|
|
1518
|
+
1.2,
|
|
1519
|
+
1.5,
|
|
1520
|
+
1.7,
|
|
1521
|
+
2
|
|
1522
|
+
];
|
|
1523
|
+
const playbackRateFeature = definePlayerFeature({
|
|
1524
|
+
name: "playbackRate",
|
|
1525
|
+
state: ({ target }) => ({
|
|
1526
|
+
playbackRates: DEFAULT_RATES,
|
|
1527
|
+
playbackRate: 1,
|
|
1528
|
+
setPlaybackRate(rate) {
|
|
1529
|
+
target().media.playbackRate = rate;
|
|
1530
|
+
}
|
|
1531
|
+
}),
|
|
1532
|
+
attach({ target, signal, set }) {
|
|
1533
|
+
const { media } = target;
|
|
1534
|
+
const sync = () => set({ playbackRate: media.playbackRate });
|
|
1535
|
+
sync();
|
|
1536
|
+
listen(media, "ratechange", sync, { signal });
|
|
1537
|
+
}
|
|
1538
|
+
});
|
|
1539
|
+
|
|
1540
|
+
//#endregion
|
|
1541
|
+
//#region ../core/dist/dev/dom/store/features/source.js
|
|
1542
|
+
const sourceFeature = definePlayerFeature({
|
|
1543
|
+
name: "source",
|
|
1544
|
+
state: ({ target, signals }) => ({
|
|
1545
|
+
source: null,
|
|
1546
|
+
canPlay: false,
|
|
1547
|
+
loadSource(src) {
|
|
1548
|
+
signals.clear();
|
|
1549
|
+
const { media } = target();
|
|
1550
|
+
media.src = src;
|
|
1551
|
+
media.load();
|
|
1552
|
+
return src;
|
|
1553
|
+
}
|
|
1554
|
+
}),
|
|
1555
|
+
attach({ target, signal, set }) {
|
|
1556
|
+
const { media } = target;
|
|
1557
|
+
const sync = () => set({
|
|
1558
|
+
source: media.currentSrc || media.src || null,
|
|
1559
|
+
canPlay: media.readyState >= HTMLMediaElement.HAVE_ENOUGH_DATA
|
|
1560
|
+
});
|
|
1561
|
+
sync();
|
|
1562
|
+
listen(media, "canplay", sync, { signal });
|
|
1563
|
+
listen(media, "canplaythrough", sync, { signal });
|
|
1564
|
+
listen(media, "loadstart", sync, { signal });
|
|
1565
|
+
listen(media, "emptied", sync, { signal });
|
|
1566
|
+
}
|
|
1567
|
+
});
|
|
1568
|
+
|
|
1569
|
+
//#endregion
|
|
1570
|
+
//#region ../core/dist/dev/dom/store/features/text-track.js
|
|
1571
|
+
const textTrackFeature = definePlayerFeature({
|
|
1572
|
+
name: "textTrack",
|
|
1573
|
+
state: ({ target }) => ({
|
|
1574
|
+
chaptersCues: [],
|
|
1575
|
+
thumbnailCues: [],
|
|
1576
|
+
thumbnailTrackSrc: null,
|
|
1577
|
+
textTrackList: [],
|
|
1578
|
+
subtitlesShowing: false,
|
|
1579
|
+
toggleSubtitles(forceShow) {
|
|
1580
|
+
const subtitlesTracks = getTextTrackList(target().media, (track) => track.kind === "subtitles" || track.kind === "captions");
|
|
1581
|
+
if (!subtitlesTracks.length) return false;
|
|
1582
|
+
const showing = subtitlesTracks.some((track) => track.mode === "showing");
|
|
1583
|
+
const nextShowing = forceShow ?? !showing;
|
|
1584
|
+
for (const track of subtitlesTracks) track.mode = nextShowing ? "showing" : "disabled";
|
|
1585
|
+
return nextShowing;
|
|
1586
|
+
}
|
|
1587
|
+
}),
|
|
1588
|
+
attach({ target, signal, set }) {
|
|
1589
|
+
const { media } = target;
|
|
1590
|
+
let trackCleanup = null;
|
|
1591
|
+
function sync() {
|
|
1592
|
+
trackCleanup?.abort();
|
|
1593
|
+
trackCleanup = new AbortController();
|
|
1594
|
+
let chaptersTrack = null;
|
|
1595
|
+
let thumbnailTrack = null;
|
|
1596
|
+
const textTrackList = [];
|
|
1597
|
+
let subtitlesShowing = false;
|
|
1598
|
+
for (let i = 0; i < media.textTracks.length; i++) {
|
|
1599
|
+
const track = media.textTracks[i];
|
|
1600
|
+
if (!chaptersTrack && track.kind === "chapters") chaptersTrack = track;
|
|
1601
|
+
if (!thumbnailTrack && track.kind === "metadata" && track.label === "thumbnails") thumbnailTrack = track;
|
|
1602
|
+
textTrackList.push({
|
|
1603
|
+
kind: track.kind,
|
|
1604
|
+
label: track.label,
|
|
1605
|
+
language: track.language,
|
|
1606
|
+
mode: track.mode
|
|
1652
1607
|
});
|
|
1653
|
-
|
|
1654
|
-
this.#queueFallbackDiscovery();
|
|
1655
|
-
}
|
|
1656
|
-
disconnectedCallback() {
|
|
1657
|
-
super.disconnectedCallback();
|
|
1658
|
-
this.#detachStore();
|
|
1659
|
-
}
|
|
1660
|
-
destroyCallback() {
|
|
1661
|
-
this.#detachStore();
|
|
1662
|
-
this.#store?.destroy();
|
|
1663
|
-
this.#store = null;
|
|
1664
|
-
super.destroyCallback();
|
|
1665
|
-
}
|
|
1666
|
-
#tryAttach() {
|
|
1667
|
-
const store = this.#store;
|
|
1668
|
-
if (!store) return;
|
|
1669
|
-
if (!this.#media) {
|
|
1670
|
-
this.#detachStore();
|
|
1671
|
-
return;
|
|
1672
|
-
}
|
|
1673
|
-
const target = {
|
|
1674
|
-
media: this.#media,
|
|
1675
|
-
container: this.#container
|
|
1676
|
-
};
|
|
1677
|
-
const hasMediaChanged = store.target?.media !== target.media;
|
|
1678
|
-
const hasContainerChanged = store.target?.container !== target.container;
|
|
1679
|
-
if (hasMediaChanged || hasContainerChanged) {
|
|
1680
|
-
this.#detachStore();
|
|
1681
|
-
this.#detach = store.attach(target);
|
|
1682
|
-
}
|
|
1683
|
-
}
|
|
1684
|
-
#detachStore() {
|
|
1685
|
-
this.#detach?.();
|
|
1686
|
-
this.#detach = null;
|
|
1608
|
+
if ((track.kind === "captions" || track.kind === "subtitles") && track.mode === "showing") subtitlesShowing = true;
|
|
1687
1609
|
}
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1610
|
+
const chaptersCues = chaptersTrack?.cues ? Array.from(chaptersTrack.cues) : [];
|
|
1611
|
+
const thumbnailCues = thumbnailTrack?.cues ? Array.from(thumbnailTrack.cues) : [];
|
|
1612
|
+
let thumbnailTrackSrc = null;
|
|
1613
|
+
if (thumbnailTrack) thumbnailTrackSrc = findTrackElement(media, thumbnailTrack)?.src ?? null;
|
|
1614
|
+
const tracks = media.querySelectorAll?.("track") ?? [];
|
|
1615
|
+
const shadowTracks = media.shadowRoot?.querySelectorAll?.("track") ?? [];
|
|
1616
|
+
for (const trackEl of [...tracks, ...shadowTracks]) if (!trackEl.track?.cues?.length) listen(trackEl, "load", sync, { signal: trackCleanup.signal });
|
|
1617
|
+
set({
|
|
1618
|
+
chaptersCues,
|
|
1619
|
+
thumbnailCues,
|
|
1620
|
+
thumbnailTrackSrc,
|
|
1621
|
+
textTrackList,
|
|
1622
|
+
subtitlesShowing
|
|
1623
|
+
});
|
|
1624
|
+
}
|
|
1625
|
+
sync();
|
|
1626
|
+
listen(media.textTracks, "addtrack", sync, { signal });
|
|
1627
|
+
listen(media.textTracks, "removetrack", sync, { signal });
|
|
1628
|
+
listen(media.textTracks, "change", sync, { signal });
|
|
1629
|
+
listen(media, "loadstart", sync, { signal });
|
|
1630
|
+
signal.addEventListener("abort", () => trackCleanup?.abort(), { once: true });
|
|
1631
|
+
}
|
|
1632
|
+
});
|
|
1633
|
+
|
|
1634
|
+
//#endregion
|
|
1635
|
+
//#region ../core/dist/dev/dom/media/predicate.js
|
|
1636
|
+
function hasMetadata(media) {
|
|
1637
|
+
return media.readyState >= HTMLMediaElement.HAVE_METADATA;
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1640
|
+
//#endregion
|
|
1641
|
+
//#region ../core/dist/dev/dom/store/signal-keys.js
|
|
1642
|
+
const signalKeys = { seek: Symbol.for("@videojs/seek") };
|
|
1643
|
+
|
|
1644
|
+
//#endregion
|
|
1645
|
+
//#region ../core/dist/dev/dom/store/features/time.js
|
|
1646
|
+
const timeFeature = definePlayerFeature({
|
|
1647
|
+
name: "time",
|
|
1648
|
+
state: ({ target, signals, set }) => ({
|
|
1649
|
+
currentTime: 0,
|
|
1650
|
+
duration: 0,
|
|
1651
|
+
seeking: false,
|
|
1652
|
+
async seek(time) {
|
|
1653
|
+
const { media } = target(), signal = signals.supersede(signalKeys.seek);
|
|
1654
|
+
if (!hasMetadata(media)) {
|
|
1655
|
+
if (!await onEvent(media, "loadedmetadata", { signal }).catch(() => false)) return media.currentTime;
|
|
1697
1656
|
}
|
|
1657
|
+
const clampedTime = Math.max(0, Math.min(time, media.duration || Infinity));
|
|
1658
|
+
set({
|
|
1659
|
+
currentTime: clampedTime,
|
|
1660
|
+
seeking: true
|
|
1661
|
+
});
|
|
1662
|
+
media.currentTime = clampedTime;
|
|
1663
|
+
await onEvent(media, "seeked", { signal }).catch(noop);
|
|
1664
|
+
return media.currentTime;
|
|
1698
1665
|
}
|
|
1699
|
-
|
|
1700
|
-
}
|
|
1666
|
+
}),
|
|
1667
|
+
attach({ target, signal, set, get }) {
|
|
1668
|
+
const { media } = target;
|
|
1669
|
+
const sync = () => set({
|
|
1670
|
+
currentTime: media.currentTime,
|
|
1671
|
+
duration: Number.isFinite(media.duration) ? media.duration : 0,
|
|
1672
|
+
seeking: media.seeking
|
|
1673
|
+
});
|
|
1674
|
+
const onTimeUpdate = () => {
|
|
1675
|
+
if (get().seeking) return;
|
|
1676
|
+
sync();
|
|
1677
|
+
};
|
|
1678
|
+
sync();
|
|
1679
|
+
listen(media, "timeupdate", onTimeUpdate, { signal });
|
|
1680
|
+
listen(media, "durationchange", sync, { signal });
|
|
1681
|
+
listen(media, "seeking", sync, { signal });
|
|
1682
|
+
listen(media, "seeked", sync, { signal });
|
|
1683
|
+
listen(media, "loadedmetadata", sync, { signal });
|
|
1684
|
+
listen(media, "emptied", sync, { signal });
|
|
1685
|
+
}
|
|
1686
|
+
});
|
|
1687
|
+
|
|
1688
|
+
//#endregion
|
|
1689
|
+
//#region ../core/dist/dev/dom/store/features/volume.js
|
|
1690
|
+
/** Volume to restore when unmuting at zero. */
|
|
1691
|
+
const UNMUTE_VOLUME = .25;
|
|
1692
|
+
const volumeFeature = definePlayerFeature({
|
|
1693
|
+
name: "volume",
|
|
1694
|
+
state: ({ target }) => ({
|
|
1695
|
+
volume: 1,
|
|
1696
|
+
muted: false,
|
|
1697
|
+
volumeAvailability: "unavailable",
|
|
1698
|
+
setVolume(volume) {
|
|
1699
|
+
const { media } = target();
|
|
1700
|
+
const clamped = Math.max(0, Math.min(1, volume));
|
|
1701
|
+
if (clamped > 0 && media.muted) media.muted = false;
|
|
1702
|
+
media.volume = clamped;
|
|
1703
|
+
return media.volume;
|
|
1704
|
+
},
|
|
1705
|
+
toggleMuted() {
|
|
1706
|
+
const { media } = target();
|
|
1707
|
+
if (media.muted || media.volume === 0) {
|
|
1708
|
+
media.muted = false;
|
|
1709
|
+
if (media.volume === 0) media.volume = UNMUTE_VOLUME;
|
|
1710
|
+
} else media.muted = true;
|
|
1711
|
+
return media.muted;
|
|
1712
|
+
}
|
|
1713
|
+
}),
|
|
1714
|
+
attach({ target, signal, set }) {
|
|
1715
|
+
const { media } = target;
|
|
1716
|
+
set({ volumeAvailability: canSetVolume() });
|
|
1717
|
+
const sync = () => set({
|
|
1718
|
+
volume: media.volume,
|
|
1719
|
+
muted: media.muted
|
|
1720
|
+
});
|
|
1721
|
+
sync();
|
|
1722
|
+
listen(media, "volumechange", sync, { signal });
|
|
1723
|
+
}
|
|
1724
|
+
});
|
|
1725
|
+
/** Check if volume can be programmatically set (fails on iOS Safari). */
|
|
1726
|
+
function canSetVolume() {
|
|
1727
|
+
const video = document.createElement("video");
|
|
1728
|
+
try {
|
|
1729
|
+
video.volume = .5;
|
|
1730
|
+
return video.volume === .5 ? "available" : "unsupported";
|
|
1731
|
+
} catch {
|
|
1732
|
+
return "unsupported";
|
|
1733
|
+
}
|
|
1701
1734
|
}
|
|
1702
1735
|
|
|
1736
|
+
//#endregion
|
|
1737
|
+
//#region ../core/dist/dev/dom/store/features/presets.js
|
|
1738
|
+
const videoFeatures = [
|
|
1739
|
+
playbackFeature,
|
|
1740
|
+
playbackRateFeature,
|
|
1741
|
+
volumeFeature,
|
|
1742
|
+
timeFeature,
|
|
1743
|
+
sourceFeature,
|
|
1744
|
+
bufferFeature,
|
|
1745
|
+
fullscreenFeature,
|
|
1746
|
+
pipFeature,
|
|
1747
|
+
controlsFeature,
|
|
1748
|
+
textTrackFeature,
|
|
1749
|
+
errorFeature
|
|
1750
|
+
];
|
|
1751
|
+
const audioFeatures = [
|
|
1752
|
+
playbackFeature,
|
|
1753
|
+
playbackRateFeature,
|
|
1754
|
+
volumeFeature,
|
|
1755
|
+
timeFeature,
|
|
1756
|
+
sourceFeature,
|
|
1757
|
+
bufferFeature,
|
|
1758
|
+
errorFeature
|
|
1759
|
+
];
|
|
1760
|
+
const backgroundFeatures = [];
|
|
1761
|
+
|
|
1703
1762
|
//#endregion
|
|
1704
1763
|
//#region ../store/dist/dev/html/controllers/snapshot-controller.js
|
|
1705
1764
|
/**
|
|
@@ -1929,6 +1988,130 @@ var PlayerController = class {
|
|
|
1929
1988
|
}
|
|
1930
1989
|
};
|
|
1931
1990
|
|
|
1991
|
+
//#endregion
|
|
1992
|
+
//#region src/store/provider-mixin.ts
|
|
1993
|
+
/**
|
|
1994
|
+
* Create a mixin that provides player context to descendant elements and
|
|
1995
|
+
* owns the `store.attach()` lifecycle.
|
|
1996
|
+
*
|
|
1997
|
+
* Media and container elements register themselves via media/container
|
|
1998
|
+
* contexts that carry both the current value and a setter. When a media
|
|
1999
|
+
* element is available, the provider calls `store.attach({ media, container })`.
|
|
2000
|
+
*
|
|
2001
|
+
* As a fallback for plain `<video>`/`<audio>` that can't consume context,
|
|
2002
|
+
* the provider queries its subtree after a microtask.
|
|
2003
|
+
*
|
|
2004
|
+
* @param config - Provider configuration with contexts and store factory.
|
|
2005
|
+
*/
|
|
2006
|
+
function createProviderMixin(config) {
|
|
2007
|
+
return (BaseClass) => {
|
|
2008
|
+
class PlayerProviderElement extends BaseClass {
|
|
2009
|
+
#store = config.factory();
|
|
2010
|
+
#detach = null;
|
|
2011
|
+
#media = null;
|
|
2012
|
+
#container = null;
|
|
2013
|
+
#fallbackQueued = false;
|
|
2014
|
+
#setMedia = (media) => {
|
|
2015
|
+
if (this.#media === media) return;
|
|
2016
|
+
this.#media = media;
|
|
2017
|
+
this.#mediaProvider.setValue({
|
|
2018
|
+
media,
|
|
2019
|
+
setMedia: this.#setMedia
|
|
2020
|
+
});
|
|
2021
|
+
this.#tryAttach();
|
|
2022
|
+
};
|
|
2023
|
+
#setContainer = (container) => {
|
|
2024
|
+
if (this.#container === container) return;
|
|
2025
|
+
this.#container = container;
|
|
2026
|
+
this.#containerProvider.setValue({
|
|
2027
|
+
container,
|
|
2028
|
+
setContainer: this.#setContainer
|
|
2029
|
+
});
|
|
2030
|
+
this.#tryAttach();
|
|
2031
|
+
};
|
|
2032
|
+
#playerProvider = new ContextProvider(this, {
|
|
2033
|
+
context: config.playerContext,
|
|
2034
|
+
initialValue: this.store
|
|
2035
|
+
});
|
|
2036
|
+
#mediaProvider = new ContextProvider(this, {
|
|
2037
|
+
context: config.mediaContext,
|
|
2038
|
+
initialValue: {
|
|
2039
|
+
media: this.#media,
|
|
2040
|
+
setMedia: this.#setMedia
|
|
2041
|
+
}
|
|
2042
|
+
});
|
|
2043
|
+
#containerProvider = new ContextProvider(this, {
|
|
2044
|
+
context: config.containerContext,
|
|
2045
|
+
initialValue: {
|
|
2046
|
+
container: this.#container,
|
|
2047
|
+
setContainer: this.#setContainer
|
|
2048
|
+
}
|
|
2049
|
+
});
|
|
2050
|
+
get store() {
|
|
2051
|
+
if (isNull(this.#store)) this.#store = config.factory();
|
|
2052
|
+
return this.#store;
|
|
2053
|
+
}
|
|
2054
|
+
connectedCallback() {
|
|
2055
|
+
super.connectedCallback();
|
|
2056
|
+
this.#playerProvider.setValue(this.store);
|
|
2057
|
+
this.#mediaProvider.setValue({
|
|
2058
|
+
media: this.#media,
|
|
2059
|
+
setMedia: this.#setMedia
|
|
2060
|
+
});
|
|
2061
|
+
this.#containerProvider.setValue({
|
|
2062
|
+
container: this.#container,
|
|
2063
|
+
setContainer: this.#setContainer
|
|
2064
|
+
});
|
|
2065
|
+
this.#tryAttach();
|
|
2066
|
+
this.#queueFallbackDiscovery();
|
|
2067
|
+
}
|
|
2068
|
+
disconnectedCallback() {
|
|
2069
|
+
super.disconnectedCallback();
|
|
2070
|
+
this.#detachStore();
|
|
2071
|
+
}
|
|
2072
|
+
destroyCallback() {
|
|
2073
|
+
this.#detachStore();
|
|
2074
|
+
this.#store?.destroy();
|
|
2075
|
+
this.#store = null;
|
|
2076
|
+
super.destroyCallback();
|
|
2077
|
+
}
|
|
2078
|
+
#tryAttach() {
|
|
2079
|
+
const store = this.#store;
|
|
2080
|
+
if (!store) return;
|
|
2081
|
+
if (!this.#media) {
|
|
2082
|
+
this.#detachStore();
|
|
2083
|
+
return;
|
|
2084
|
+
}
|
|
2085
|
+
const target = {
|
|
2086
|
+
media: this.#media,
|
|
2087
|
+
container: this.#container
|
|
2088
|
+
};
|
|
2089
|
+
const hasMediaChanged = store.target?.media !== target.media;
|
|
2090
|
+
const hasContainerChanged = store.target?.container !== target.container;
|
|
2091
|
+
if (hasMediaChanged || hasContainerChanged) {
|
|
2092
|
+
this.#detachStore();
|
|
2093
|
+
this.#detach = store.attach(target);
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
#detachStore() {
|
|
2097
|
+
this.#detach?.();
|
|
2098
|
+
this.#detach = null;
|
|
2099
|
+
}
|
|
2100
|
+
#queueFallbackDiscovery() {
|
|
2101
|
+
if (this.#media || this.#fallbackQueued) return;
|
|
2102
|
+
this.#fallbackQueued = true;
|
|
2103
|
+
queueMicrotask(() => {
|
|
2104
|
+
this.#fallbackQueued = false;
|
|
2105
|
+
if (this.#media) return;
|
|
2106
|
+
const media = this.querySelector("video, audio");
|
|
2107
|
+
if (media) this.#setMedia(media);
|
|
2108
|
+
});
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
return PlayerProviderElement;
|
|
2112
|
+
};
|
|
2113
|
+
}
|
|
2114
|
+
|
|
1932
2115
|
//#endregion
|
|
1933
2116
|
//#region src/player/create-player.ts
|
|
1934
2117
|
function createPlayer(config) {
|
|
@@ -1954,5 +2137,5 @@ function createPlayer(config) {
|
|
|
1954
2137
|
}
|
|
1955
2138
|
|
|
1956
2139
|
//#endregion
|
|
1957
|
-
export {
|
|
1958
|
-
//# sourceMappingURL=create-player-
|
|
2140
|
+
export { ContextConsumer as A, isFunction as C, MediaContainerElement as D, isUndefined as E, isEditableTarget as M, resolveEventTarget as N, MediaElement as O, AbortControllerRegistry as S, isNumber as T, getGestureCoordinator as _, backgroundFeatures as a, noop as b, timeFeature as c, playbackRateFeature as d, playbackFeature as f, controlsFeature as g, errorFeature as h, audioFeatures as i, ReactiveElement as j, ContextProvider as k, textTrackFeature as l, fullscreenFeature as m, PlayerController as n, videoFeatures as o, pipFeature as p, SnapshotController as r, volumeFeature as s, createPlayer as t, sourceFeature as u, bufferFeature as v, isNull as w, throwNoTargetError as x, createState as y };
|
|
2141
|
+
//# sourceMappingURL=create-player-CyG77t-m.js.map
|