node_modules ignore

This commit is contained in:
2025-05-08 23:43:47 +02:00
parent e19d52f172
commit 4574544c9f
65041 changed files with 10593536 additions and 0 deletions

View File

@@ -0,0 +1,296 @@
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var media_store_exports = {};
__export(media_store_exports, {
default: () => media_store_default
});
module.exports = __toCommonJS(media_store_exports);
var import_state_mediator = require("./state-mediator.js");
var import_util = require("./util.js");
var import_request_map = require("./request-map.js");
const createMediaStore = ({
media,
fullscreenElement,
documentElement,
stateMediator = import_state_mediator.stateMediator,
requestMap = import_request_map.requestMap,
options = {},
monitorStateOwnersOnlyWithSubscriptions = true
}) => {
const callbacks = [];
const stateOwners = {
// Spreading options here since folks should not rely on holding onto references
// for any app-level logic wrt options.
options: { ...options }
};
let state = Object.freeze({
mediaPreviewTime: void 0,
mediaPreviewImage: void 0,
mediaPreviewCoords: void 0,
mediaPreviewChapter: void 0
});
const updateState = (nextStateDelta) => {
if (nextStateDelta == void 0)
return;
if ((0, import_util.areValuesEq)(nextStateDelta, state)) {
return;
}
state = Object.freeze({
...state,
...nextStateDelta
});
callbacks.forEach((cb) => cb(state));
};
const updateStateFromFacade = () => {
const nextState = Object.entries(stateMediator).reduce(
(nextState2, [stateName, { get }]) => {
nextState2[stateName] = get(stateOwners);
return nextState2;
},
{}
);
updateState(nextState);
};
const stateUpdateHandlers = {};
let nextStateOwners = void 0;
const updateStateOwners = async (nextStateOwnersDelta, nextSubscriberCount) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
const pendingUpdate = !!nextStateOwners;
nextStateOwners = {
...stateOwners,
...nextStateOwners != null ? nextStateOwners : {},
...nextStateOwnersDelta
};
if (pendingUpdate)
return;
await (0, import_state_mediator.prepareStateOwners)(...Object.values(nextStateOwnersDelta));
const shouldTeardownFromSubscriberCount = callbacks.length > 0 && nextSubscriberCount === 0 && monitorStateOwnersOnlyWithSubscriptions;
const mediaChanged = stateOwners.media !== nextStateOwners.media;
const textTracksChanged = ((_a = stateOwners.media) == null ? void 0 : _a.textTracks) !== ((_b = nextStateOwners.media) == null ? void 0 : _b.textTracks);
const videoRenditionsChanged = ((_c = stateOwners.media) == null ? void 0 : _c.videoRenditions) !== ((_d = nextStateOwners.media) == null ? void 0 : _d.videoRenditions);
const audioTracksChanged = ((_e = stateOwners.media) == null ? void 0 : _e.audioTracks) !== ((_f = nextStateOwners.media) == null ? void 0 : _f.audioTracks);
const remoteChanged = ((_g = stateOwners.media) == null ? void 0 : _g.remote) !== ((_h = nextStateOwners.media) == null ? void 0 : _h.remote);
const rootNodeChanged = stateOwners.documentElement !== nextStateOwners.documentElement;
const teardownMedia = !!stateOwners.media && (mediaChanged || shouldTeardownFromSubscriberCount);
const teardownTextTracks = !!((_i = stateOwners.media) == null ? void 0 : _i.textTracks) && (textTracksChanged || shouldTeardownFromSubscriberCount);
const teardownVideoRenditions = !!((_j = stateOwners.media) == null ? void 0 : _j.videoRenditions) && (videoRenditionsChanged || shouldTeardownFromSubscriberCount);
const teardownAudioTracks = !!((_k = stateOwners.media) == null ? void 0 : _k.audioTracks) && (audioTracksChanged || shouldTeardownFromSubscriberCount);
const teardownRemote = !!((_l = stateOwners.media) == null ? void 0 : _l.remote) && (remoteChanged || shouldTeardownFromSubscriberCount);
const teardownRootNode = !!stateOwners.documentElement && (rootNodeChanged || shouldTeardownFromSubscriberCount);
const teardownSomething = teardownMedia || teardownTextTracks || teardownVideoRenditions || teardownAudioTracks || teardownRemote || teardownRootNode;
const shouldSetupFromSubscriberCount = callbacks.length === 0 && nextSubscriberCount === 1 && monitorStateOwnersOnlyWithSubscriptions;
const setupMedia = !!nextStateOwners.media && (mediaChanged || shouldSetupFromSubscriberCount);
const setupTextTracks = !!((_m = nextStateOwners.media) == null ? void 0 : _m.textTracks) && (textTracksChanged || shouldSetupFromSubscriberCount);
const setupVideoRenditions = !!((_n = nextStateOwners.media) == null ? void 0 : _n.videoRenditions) && (videoRenditionsChanged || shouldSetupFromSubscriberCount);
const setupAudioTracks = !!((_o = nextStateOwners.media) == null ? void 0 : _o.audioTracks) && (audioTracksChanged || shouldSetupFromSubscriberCount);
const setupRemote = !!((_p = nextStateOwners.media) == null ? void 0 : _p.remote) && (remoteChanged || shouldSetupFromSubscriberCount);
const setupRootNode = !!nextStateOwners.documentElement && (rootNodeChanged || shouldSetupFromSubscriberCount);
const setupSomething = setupMedia || setupTextTracks || setupVideoRenditions || setupAudioTracks || setupRemote || setupRootNode;
const somethingToDo = teardownSomething || setupSomething;
if (!somethingToDo) {
Object.entries(nextStateOwners).forEach(
([stateOwnerName, stateOwner]) => {
stateOwners[stateOwnerName] = stateOwner;
}
);
updateStateFromFacade();
nextStateOwners = void 0;
return;
}
Object.entries(stateMediator).forEach(
([
stateName,
{
get,
mediaEvents = [],
textTracksEvents = [],
videoRenditionsEvents = [],
audioTracksEvents = [],
remoteEvents = [],
rootEvents = [],
stateOwnersUpdateHandlers = []
}
]) => {
if (!stateUpdateHandlers[stateName]) {
stateUpdateHandlers[stateName] = {};
}
const handler = (event) => {
const nextValue = get(stateOwners, event);
updateState({ [stateName]: nextValue });
};
let prevHandler;
prevHandler = stateUpdateHandlers[stateName].mediaEvents;
mediaEvents.forEach((eventType) => {
if (prevHandler && teardownMedia) {
stateOwners.media.removeEventListener(eventType, prevHandler);
stateUpdateHandlers[stateName].mediaEvents = void 0;
}
if (setupMedia) {
nextStateOwners.media.addEventListener(eventType, handler);
stateUpdateHandlers[stateName].mediaEvents = handler;
}
});
prevHandler = stateUpdateHandlers[stateName].textTracksEvents;
textTracksEvents.forEach((eventType) => {
var _a2, _b2;
if (prevHandler && teardownTextTracks) {
(_a2 = stateOwners.media.textTracks) == null ? void 0 : _a2.removeEventListener(
eventType,
prevHandler
);
stateUpdateHandlers[stateName].textTracksEvents = void 0;
}
if (setupTextTracks) {
(_b2 = nextStateOwners.media.textTracks) == null ? void 0 : _b2.addEventListener(
eventType,
handler
);
stateUpdateHandlers[stateName].textTracksEvents = handler;
}
});
prevHandler = stateUpdateHandlers[stateName].videoRenditionsEvents;
videoRenditionsEvents.forEach((eventType) => {
var _a2, _b2;
if (prevHandler && teardownVideoRenditions) {
(_a2 = stateOwners.media.videoRenditions) == null ? void 0 : _a2.removeEventListener(
eventType,
prevHandler
);
stateUpdateHandlers[stateName].videoRenditionsEvents = void 0;
}
if (setupVideoRenditions) {
(_b2 = nextStateOwners.media.videoRenditions) == null ? void 0 : _b2.addEventListener(
eventType,
handler
);
stateUpdateHandlers[stateName].videoRenditionsEvents = handler;
}
});
prevHandler = stateUpdateHandlers[stateName].audioTracksEvents;
audioTracksEvents.forEach((eventType) => {
var _a2, _b2;
if (prevHandler && teardownAudioTracks) {
(_a2 = stateOwners.media.audioTracks) == null ? void 0 : _a2.removeEventListener(
eventType,
prevHandler
);
stateUpdateHandlers[stateName].audioTracksEvents = void 0;
}
if (setupAudioTracks) {
(_b2 = nextStateOwners.media.audioTracks) == null ? void 0 : _b2.addEventListener(
eventType,
handler
);
stateUpdateHandlers[stateName].audioTracksEvents = handler;
}
});
prevHandler = stateUpdateHandlers[stateName].remoteEvents;
remoteEvents.forEach((eventType) => {
var _a2, _b2;
if (prevHandler && teardownRemote) {
(_a2 = stateOwners.media.remote) == null ? void 0 : _a2.removeEventListener(
eventType,
prevHandler
);
stateUpdateHandlers[stateName].remoteEvents = void 0;
}
if (setupRemote) {
(_b2 = nextStateOwners.media.remote) == null ? void 0 : _b2.addEventListener(eventType, handler);
stateUpdateHandlers[stateName].remoteEvents = handler;
}
});
prevHandler = stateUpdateHandlers[stateName].rootEvents;
rootEvents.forEach((eventType) => {
if (prevHandler && teardownRootNode) {
stateOwners.documentElement.removeEventListener(
eventType,
prevHandler
);
stateUpdateHandlers[stateName].rootEvents = void 0;
}
if (setupRootNode) {
nextStateOwners.documentElement.addEventListener(
eventType,
handler
);
stateUpdateHandlers[stateName].rootEvents = handler;
}
});
const prevHandlerTeardown = stateUpdateHandlers[stateName].stateOwnersUpdateHandlers;
stateOwnersUpdateHandlers.forEach((fn) => {
if (prevHandlerTeardown && teardownSomething) {
prevHandlerTeardown();
}
if (setupSomething) {
stateUpdateHandlers[stateName].stateOwnersUpdateHandlers = fn(
handler,
nextStateOwners
);
}
});
}
);
Object.entries(nextStateOwners).forEach(([stateOwnerName, stateOwner]) => {
stateOwners[stateOwnerName] = stateOwner;
});
updateStateFromFacade();
nextStateOwners = void 0;
};
updateStateOwners({ media, fullscreenElement, documentElement, options });
return {
// note that none of these cases directly interact with the media element, root node, full screen element, etc.
// note these "actions" could just be the events if we wanted, especially if we normalize on "detail" for
// any payload-relevant values
// This is roughly equivalent to our used to be in our state requests dictionary object, though much of the
// "heavy lifting" is now moved into the facade `set()`
dispatch(action) {
const { type, detail } = action;
if (requestMap[type]) {
updateState(requestMap[type](stateMediator, stateOwners, action));
return;
}
if (type === "mediaelementchangerequest") {
updateStateOwners({ media: detail });
} else if (type === "fullscreenelementchangerequest") {
updateStateOwners({ fullscreenElement: detail });
} else if (type === "documentelementchangerequest") {
updateStateOwners({ documentElement: detail });
} else if (type === "optionschangerequest") {
Object.entries(detail != null ? detail : {}).forEach(([optionName, optionValue]) => {
stateOwners.options[optionName] = optionValue;
});
}
},
getState() {
return state;
},
subscribe(callback) {
updateStateOwners({}, callbacks.length + 1);
callbacks.push(callback);
callback(state);
return () => {
const idx = callbacks.indexOf(callback);
if (idx >= 0) {
updateStateOwners({}, callbacks.length - 1);
callbacks.splice(idx, 1);
}
};
}
};
};
var media_store_default = createMediaStore;

View File

@@ -0,0 +1,214 @@
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var request_map_exports = {};
__export(request_map_exports, {
requestMap: () => requestMap
});
module.exports = __toCommonJS(request_map_exports);
var import_server_safe_globals = require("../utils/server-safe-globals.js");
var import_constants = require("../constants.js");
var import_captions = require("../utils/captions.js");
var import_util = require("./util.js");
const requestMap = {
/**
* @TODO Consider adding state to `StateMediator` for e.g. `mediaThumbnailCues` and use that for derived state here (CJP)
*/
[import_constants.MediaUIEvents.MEDIA_PREVIEW_REQUEST](stateMediator, stateOwners, { detail }) {
var _a, _b, _c;
const { media } = stateOwners;
const mediaPreviewTime = detail != null ? detail : void 0;
let mediaPreviewImage = void 0;
let mediaPreviewCoords = void 0;
if (media && mediaPreviewTime != null) {
const [track] = (0, import_captions.getTextTracksList)(media, {
kind: import_constants.TextTrackKinds.METADATA,
label: "thumbnails"
});
const cue = Array.prototype.find.call((_a = track == null ? void 0 : track.cues) != null ? _a : [], (c, i, cs) => {
if (i === 0)
return c.endTime > mediaPreviewTime;
if (i === cs.length - 1)
return c.startTime <= mediaPreviewTime;
return c.startTime <= mediaPreviewTime && c.endTime > mediaPreviewTime;
});
if (cue) {
const base = !/'^(?:[a-z]+:)?\/\//i.test(cue.text) ? (_b = media == null ? void 0 : media.querySelector(
'track[label="thumbnails"]'
)) == null ? void 0 : _b.src : void 0;
const url = new URL(cue.text, base);
const previewCoordsStr = new URLSearchParams(url.hash).get("#xywh");
mediaPreviewCoords = previewCoordsStr.split(",").map((numStr) => +numStr);
mediaPreviewImage = url.href;
}
}
const mediaDuration = stateMediator.mediaDuration.get(stateOwners);
const mediaChaptersCues = stateMediator.mediaChaptersCues.get(stateOwners);
let mediaPreviewChapter = (_c = mediaChaptersCues.find((c, i, cs) => {
if (i === cs.length - 1 && mediaDuration === c.endTime) {
return c.startTime <= mediaPreviewTime && c.endTime >= mediaPreviewTime;
}
return c.startTime <= mediaPreviewTime && c.endTime > mediaPreviewTime;
})) == null ? void 0 : _c.text;
if (detail != null && mediaPreviewChapter == null) {
mediaPreviewChapter = "";
}
return {
mediaPreviewTime,
mediaPreviewImage,
mediaPreviewCoords,
mediaPreviewChapter
};
},
[import_constants.MediaUIEvents.MEDIA_PAUSE_REQUEST](stateMediator, stateOwners) {
const key = "mediaPaused";
const value = true;
stateMediator[key].set(value, stateOwners);
},
[import_constants.MediaUIEvents.MEDIA_PLAY_REQUEST](stateMediator, stateOwners) {
var _a;
const key = "mediaPaused";
const value = false;
const live = stateMediator.mediaStreamType.get(stateOwners) === import_constants.StreamTypes.LIVE;
if (live) {
const notDvr = !(stateMediator.mediaTargetLiveWindow.get(stateOwners) > 0);
const liveEdgeTime = (_a = stateMediator.mediaSeekable.get(stateOwners)) == null ? void 0 : _a[1];
if (notDvr && liveEdgeTime) {
stateMediator.mediaCurrentTime.set(liveEdgeTime, stateOwners);
}
}
stateMediator[key].set(value, stateOwners);
},
[import_constants.MediaUIEvents.MEDIA_PLAYBACK_RATE_REQUEST](stateMediator, stateOwners, { detail }) {
const key = "mediaPlaybackRate";
const value = detail;
stateMediator[key].set(value, stateOwners);
},
[import_constants.MediaUIEvents.MEDIA_MUTE_REQUEST](stateMediator, stateOwners) {
const key = "mediaMuted";
const value = true;
stateMediator[key].set(value, stateOwners);
},
[import_constants.MediaUIEvents.MEDIA_UNMUTE_REQUEST](stateMediator, stateOwners) {
const key = "mediaMuted";
const value = false;
if (!stateMediator.mediaVolume.get(stateOwners)) {
stateMediator.mediaVolume.set(0.25, stateOwners);
}
stateMediator[key].set(value, stateOwners);
},
[import_constants.MediaUIEvents.MEDIA_VOLUME_REQUEST](stateMediator, stateOwners, { detail }) {
const key = "mediaVolume";
const value = detail;
if (value && stateMediator.mediaMuted.get(stateOwners)) {
stateMediator.mediaMuted.set(false, stateOwners);
}
stateMediator[key].set(value, stateOwners);
},
[import_constants.MediaUIEvents.MEDIA_SEEK_REQUEST](stateMediator, stateOwners, { detail }) {
const key = "mediaCurrentTime";
const value = detail;
stateMediator[key].set(value, stateOwners);
},
[import_constants.MediaUIEvents.MEDIA_SEEK_TO_LIVE_REQUEST](stateMediator, stateOwners) {
var _a;
const key = "mediaCurrentTime";
const value = (_a = stateMediator.mediaSeekable.get(stateOwners)) == null ? void 0 : _a[1];
if (Number.isNaN(Number(value)))
return;
stateMediator[key].set(value, stateOwners);
},
// Text Tracks state change requests
[import_constants.MediaUIEvents.MEDIA_SHOW_SUBTITLES_REQUEST](_stateMediator, stateOwners, { detail }) {
var _a;
const { options } = stateOwners;
const tracks = (0, import_util.getSubtitleTracks)(stateOwners);
const tracksToUpdate = (0, import_captions.parseTracks)(detail);
const preferredLanguage = (_a = tracksToUpdate[0]) == null ? void 0 : _a.language;
if (preferredLanguage && !options.noSubtitlesLangPref) {
import_server_safe_globals.globalThis.localStorage.setItem(
"media-chrome-pref-subtitles-lang",
preferredLanguage
);
}
(0, import_captions.updateTracksModeTo)(import_constants.TextTrackModes.SHOWING, tracks, tracksToUpdate);
},
[import_constants.MediaUIEvents.MEDIA_DISABLE_SUBTITLES_REQUEST](_stateMediator, stateOwners, { detail }) {
const tracks = (0, import_util.getSubtitleTracks)(stateOwners);
const tracksToUpdate = detail != null ? detail : [];
(0, import_captions.updateTracksModeTo)(import_constants.TextTrackModes.DISABLED, tracks, tracksToUpdate);
},
[import_constants.MediaUIEvents.MEDIA_TOGGLE_SUBTITLES_REQUEST](_stateMediator, stateOwners, { detail }) {
(0, import_util.toggleSubtitleTracks)(stateOwners, detail);
},
// Renditions/Tracks state change requests
[import_constants.MediaUIEvents.MEDIA_RENDITION_REQUEST](stateMediator, stateOwners, { detail }) {
const key = "mediaRenditionSelected";
const value = detail;
stateMediator[key].set(value, stateOwners);
},
[import_constants.MediaUIEvents.MEDIA_AUDIO_TRACK_REQUEST](stateMediator, stateOwners, { detail }) {
const key = "mediaAudioTrackEnabled";
const value = detail;
stateMediator[key].set(value, stateOwners);
},
// State change requests dependent on root node
[import_constants.MediaUIEvents.MEDIA_ENTER_PIP_REQUEST](stateMediator, stateOwners) {
const key = "mediaIsPip";
const value = true;
if (stateMediator.mediaIsFullscreen.get(stateOwners)) {
stateMediator.mediaIsFullscreen.set(false, stateOwners);
}
stateMediator[key].set(value, stateOwners);
},
[import_constants.MediaUIEvents.MEDIA_EXIT_PIP_REQUEST](stateMediator, stateOwners) {
const key = "mediaIsPip";
const value = false;
stateMediator[key].set(value, stateOwners);
},
[import_constants.MediaUIEvents.MEDIA_ENTER_FULLSCREEN_REQUEST](stateMediator, stateOwners) {
const key = "mediaIsFullscreen";
const value = true;
if (stateMediator.mediaIsPip.get(stateOwners)) {
stateMediator.mediaIsPip.set(false, stateOwners);
}
stateMediator[key].set(value, stateOwners);
},
[import_constants.MediaUIEvents.MEDIA_EXIT_FULLSCREEN_REQUEST](stateMediator, stateOwners) {
const key = "mediaIsFullscreen";
const value = false;
stateMediator[key].set(value, stateOwners);
},
[import_constants.MediaUIEvents.MEDIA_ENTER_CAST_REQUEST](stateMediator, stateOwners) {
const key = "mediaIsCasting";
const value = true;
if (stateMediator.mediaIsFullscreen.get(stateOwners)) {
stateMediator.mediaIsFullscreen.set(false, stateOwners);
}
stateMediator[key].set(value, stateOwners);
},
[import_constants.MediaUIEvents.MEDIA_EXIT_CAST_REQUEST](stateMediator, stateOwners) {
const key = "mediaIsCasting";
const value = false;
stateMediator[key].set(value, stateOwners);
},
[import_constants.MediaUIEvents.MEDIA_AIRPLAY_REQUEST](stateMediator, stateOwners) {
const key = "mediaIsAirplaying";
const value = true;
stateMediator[key].set(value, stateOwners);
}
};

View File

@@ -0,0 +1,811 @@
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var state_mediator_exports = {};
__export(state_mediator_exports, {
prepareStateOwners: () => prepareStateOwners,
stateMediator: () => stateMediator,
volumeSupportPromise: () => volumeSupportPromise
});
module.exports = __toCommonJS(state_mediator_exports);
var import_server_safe_globals = require("../utils/server-safe-globals.js");
var import_constants = require("../constants.js");
var import_element_utils = require("../utils/element-utils.js");
var import_fullscreen_api = require("../utils/fullscreen-api.js");
var import_platform_tests = require("../utils/platform-tests.js");
var import_util = require("./util.js");
var import_captions = require("../utils/captions.js");
var import_utils = require("../utils/utils.js");
const StreamTypeValues = Object.values(import_constants.StreamTypes);
let volumeSupported;
const volumeSupportPromise = (0, import_platform_tests.hasVolumeSupportAsync)().then((supported) => {
volumeSupported = supported;
return volumeSupported;
});
const prepareStateOwners = async (...stateOwners) => {
await Promise.all(
stateOwners.filter((x) => x).map(async (stateOwner) => {
if (!("localName" in stateOwner && stateOwner instanceof import_server_safe_globals.globalThis.HTMLElement)) {
return;
}
const name = stateOwner.localName;
if (!name.includes("-"))
return;
const classDef = import_server_safe_globals.globalThis.customElements.get(name);
if (classDef && stateOwner instanceof classDef)
return;
await import_server_safe_globals.globalThis.customElements.whenDefined(name);
import_server_safe_globals.globalThis.customElements.upgrade(stateOwner);
})
);
};
const stateMediator = {
mediaWidth: {
get(stateOwners) {
var _a;
const { media } = stateOwners;
return (_a = media == null ? void 0 : media.videoWidth) != null ? _a : 0;
},
mediaEvents: ["resize"]
},
mediaHeight: {
get(stateOwners) {
var _a;
const { media } = stateOwners;
return (_a = media == null ? void 0 : media.videoHeight) != null ? _a : 0;
},
mediaEvents: ["resize"]
},
mediaPaused: {
get(stateOwners) {
var _a;
const { media } = stateOwners;
return (_a = media == null ? void 0 : media.paused) != null ? _a : true;
},
set(value, stateOwners) {
var _a;
const { media } = stateOwners;
if (!media)
return;
if (value) {
media.pause();
} else {
(_a = media.play()) == null ? void 0 : _a.catch(() => {
});
}
},
mediaEvents: ["play", "playing", "pause", "emptied"]
},
mediaHasPlayed: {
// We want to let the user know that the media started playing at any point (`media-has-played`).
// Since these propagators are all called when boostrapping state, let's verify this is
// a real playing event by checking that 1) there's media and 2) it isn't currently paused.
get(stateOwners, event) {
const { media } = stateOwners;
if (!media)
return false;
if (!event)
return !media.paused;
return event.type === "playing";
},
mediaEvents: ["playing", "emptied"]
},
mediaEnded: {
get(stateOwners) {
var _a;
const { media } = stateOwners;
return (_a = media == null ? void 0 : media.ended) != null ? _a : false;
},
mediaEvents: ["seeked", "ended", "emptied"]
},
mediaPlaybackRate: {
get(stateOwners) {
var _a;
const { media } = stateOwners;
return (_a = media == null ? void 0 : media.playbackRate) != null ? _a : 1;
},
set(value, stateOwners) {
const { media } = stateOwners;
if (!media)
return;
if (!Number.isFinite(+value))
return;
media.playbackRate = +value;
},
mediaEvents: ["ratechange", "loadstart"]
},
mediaMuted: {
get(stateOwners) {
var _a;
const { media } = stateOwners;
return (_a = media == null ? void 0 : media.muted) != null ? _a : false;
},
set(value, stateOwners) {
const { media } = stateOwners;
if (!media)
return;
media.muted = value;
},
mediaEvents: ["volumechange"]
},
mediaVolume: {
get(stateOwners) {
var _a;
const { media } = stateOwners;
return (_a = media == null ? void 0 : media.volume) != null ? _a : 1;
},
set(value, stateOwners) {
const { media } = stateOwners;
if (!media)
return;
try {
if (value == null) {
import_server_safe_globals.globalThis.localStorage.removeItem("media-chrome-pref-volume");
} else {
import_server_safe_globals.globalThis.localStorage.setItem(
"media-chrome-pref-volume",
value.toString()
);
}
} catch (err) {
}
if (!Number.isFinite(+value))
return;
media.volume = +value;
},
mediaEvents: ["volumechange"],
stateOwnersUpdateHandlers: [
(handler, stateOwners) => {
const {
options: { noVolumePref }
} = stateOwners;
if (noVolumePref)
return;
try {
const volumePref = import_server_safe_globals.globalThis.localStorage.getItem(
"media-chrome-pref-volume"
);
if (volumePref == null)
return;
stateMediator.mediaVolume.set(+volumePref, stateOwners);
handler(+volumePref);
} catch (e) {
console.debug("Error getting volume pref", e);
}
}
]
},
// NOTE: Keeping this roughly equivalent to prior impl to reduce number of changes,
// however we may want to model "derived" state differently from "primary" state
// (in this case, derived === mediaVolumeLevel, primary === mediaMuted, mediaVolume) (CJP)
mediaVolumeLevel: {
get(stateOwners) {
const { media } = stateOwners;
if (typeof (media == null ? void 0 : media.volume) == "undefined")
return "high";
if (media.muted || media.volume === 0)
return "off";
if (media.volume < 0.5)
return "low";
if (media.volume < 0.75)
return "medium";
return "high";
},
mediaEvents: ["volumechange"]
},
mediaCurrentTime: {
get(stateOwners) {
var _a;
const { media } = stateOwners;
return (_a = media == null ? void 0 : media.currentTime) != null ? _a : 0;
},
set(value, stateOwners) {
const { media } = stateOwners;
if (!media || !(0, import_utils.isValidNumber)(value))
return;
media.currentTime = value;
},
mediaEvents: ["timeupdate", "loadedmetadata"]
},
mediaDuration: {
get(stateOwners) {
const { media, options: { defaultDuration } = {} } = stateOwners;
if (defaultDuration && (!media || !media.duration || Number.isNaN(media.duration) || !Number.isFinite(media.duration))) {
return defaultDuration;
}
return Number.isFinite(media == null ? void 0 : media.duration) ? media.duration : Number.NaN;
},
mediaEvents: ["durationchange", "loadedmetadata", "emptied"]
},
mediaLoading: {
get(stateOwners) {
const { media } = stateOwners;
return (media == null ? void 0 : media.readyState) < 3;
},
mediaEvents: ["waiting", "playing", "emptied"]
},
mediaSeekable: {
get(stateOwners) {
var _a;
const { media } = stateOwners;
if (!((_a = media == null ? void 0 : media.seekable) == null ? void 0 : _a.length))
return void 0;
const start = media.seekable.start(0);
const end = media.seekable.end(media.seekable.length - 1);
if (!start && !end)
return void 0;
return [Number(start.toFixed(3)), Number(end.toFixed(3))];
},
mediaEvents: ["loadedmetadata", "emptied", "progress", "seekablechange"]
},
mediaBuffered: {
get(stateOwners) {
var _a;
const { media } = stateOwners;
const timeRanges = (_a = media == null ? void 0 : media.buffered) != null ? _a : [];
return Array.from(timeRanges).map((_, i) => [
Number(timeRanges.start(i).toFixed(3)),
Number(timeRanges.end(i).toFixed(3))
]);
},
mediaEvents: ["progress", "emptied"]
},
mediaStreamType: {
get(stateOwners) {
const { media, options: { defaultStreamType } = {} } = stateOwners;
const usedDefaultStreamType = [
import_constants.StreamTypes.LIVE,
import_constants.StreamTypes.ON_DEMAND
].includes(defaultStreamType) ? defaultStreamType : void 0;
if (!media)
return usedDefaultStreamType;
const { streamType } = media;
if (StreamTypeValues.includes(streamType)) {
if (streamType === import_constants.StreamTypes.UNKNOWN) {
return usedDefaultStreamType;
}
return streamType;
}
const duration = media.duration;
if (duration === Infinity) {
return import_constants.StreamTypes.LIVE;
} else if (Number.isFinite(duration)) {
return import_constants.StreamTypes.ON_DEMAND;
}
return usedDefaultStreamType;
},
mediaEvents: [
"emptied",
"durationchange",
"loadedmetadata",
"streamtypechange"
]
},
mediaTargetLiveWindow: {
get(stateOwners) {
const { media } = stateOwners;
if (!media)
return Number.NaN;
const { targetLiveWindow } = media;
const streamType = stateMediator.mediaStreamType.get(stateOwners);
if ((targetLiveWindow == null || Number.isNaN(targetLiveWindow)) && streamType === import_constants.StreamTypes.LIVE) {
return 0;
}
return targetLiveWindow;
},
mediaEvents: [
"emptied",
"durationchange",
"loadedmetadata",
"streamtypechange",
"targetlivewindowchange"
]
},
mediaTimeIsLive: {
get(stateOwners) {
const {
media,
// Default to 10 seconds
options: { liveEdgeOffset = 10 } = {}
} = stateOwners;
if (!media)
return false;
if (typeof media.liveEdgeStart === "number") {
if (Number.isNaN(media.liveEdgeStart))
return false;
return media.currentTime >= media.liveEdgeStart;
}
const live = stateMediator.mediaStreamType.get(stateOwners) === import_constants.StreamTypes.LIVE;
if (!live)
return false;
const seekable = media.seekable;
if (!seekable)
return true;
if (!seekable.length)
return false;
const liveEdgeStart = seekable.end(seekable.length - 1) - liveEdgeOffset;
return media.currentTime >= liveEdgeStart;
},
mediaEvents: ["playing", "timeupdate", "progress", "waiting", "emptied"]
},
// Text Tracks modeling
mediaSubtitlesList: {
get(stateOwners) {
return (0, import_util.getSubtitleTracks)(stateOwners).map(
({ kind, label, language }) => ({ kind, label, language })
);
},
mediaEvents: ["loadstart"],
textTracksEvents: ["addtrack", "removetrack"]
},
mediaSubtitlesShowing: {
get(stateOwners) {
return (0, import_util.getShowingSubtitleTracks)(stateOwners).map(
({ kind, label, language }) => ({ kind, label, language })
);
},
mediaEvents: ["loadstart"],
textTracksEvents: ["addtrack", "removetrack", "change"],
stateOwnersUpdateHandlers: [
(_handler, stateOwners) => {
var _a, _b;
const { media, options } = stateOwners;
if (!media)
return;
const updateDefaultSubtitlesCallback = (event) => {
var _a2;
if (!options.defaultSubtitles)
return;
const nonSubsEvent = event && ![import_constants.TextTrackKinds.CAPTIONS, import_constants.TextTrackKinds.SUBTITLES].includes(
// @ts-ignore
(_a2 = event == null ? void 0 : event.track) == null ? void 0 : _a2.kind
);
if (nonSubsEvent)
return;
(0, import_util.toggleSubtitleTracks)(stateOwners, true);
};
(_a = media.textTracks) == null ? void 0 : _a.addEventListener(
"addtrack",
updateDefaultSubtitlesCallback
);
(_b = media.textTracks) == null ? void 0 : _b.addEventListener(
"removetrack",
updateDefaultSubtitlesCallback
);
updateDefaultSubtitlesCallback();
return () => {
var _a2, _b2;
(_a2 = media.textTracks) == null ? void 0 : _a2.removeEventListener(
"addtrack",
updateDefaultSubtitlesCallback
);
(_b2 = media.textTracks) == null ? void 0 : _b2.removeEventListener(
"removetrack",
updateDefaultSubtitlesCallback
);
};
}
]
},
mediaChaptersCues: {
get(stateOwners) {
var _a;
const { media } = stateOwners;
if (!media)
return [];
const [chaptersTrack] = (0, import_captions.getTextTracksList)(media, {
kind: import_constants.TextTrackKinds.CHAPTERS
});
return Array.from((_a = chaptersTrack == null ? void 0 : chaptersTrack.cues) != null ? _a : []).map(
({ text, startTime, endTime }) => ({
text,
startTime,
endTime
})
);
},
mediaEvents: ["loadstart", "loadedmetadata"],
textTracksEvents: ["addtrack", "removetrack", "change"],
stateOwnersUpdateHandlers: [
(handler, stateOwners) => {
var _a;
const { media } = stateOwners;
if (!media)
return;
const chaptersTrack = media.querySelector(
'track[kind="chapters"][default][src]'
);
const shadowChaptersTrack = (_a = media.shadowRoot) == null ? void 0 : _a.querySelector(
':is(video,audio) > track[kind="chapters"][default][src]'
);
chaptersTrack == null ? void 0 : chaptersTrack.addEventListener("load", handler);
shadowChaptersTrack == null ? void 0 : shadowChaptersTrack.addEventListener("load", handler);
return () => {
chaptersTrack == null ? void 0 : chaptersTrack.removeEventListener("load", handler);
shadowChaptersTrack == null ? void 0 : shadowChaptersTrack.removeEventListener("load", handler);
};
}
]
},
// Modeling state tied to root node
mediaIsPip: {
get(stateOwners) {
var _a, _b;
const { media, documentElement } = stateOwners;
if (!media || !documentElement)
return false;
if (!documentElement.pictureInPictureElement)
return false;
if (documentElement.pictureInPictureElement === media)
return true;
if (documentElement.pictureInPictureElement instanceof HTMLMediaElement) {
if (!((_a = media.localName) == null ? void 0 : _a.includes("-")))
return false;
return (0, import_element_utils.containsComposedNode)(
media,
documentElement.pictureInPictureElement
);
}
if (documentElement.pictureInPictureElement.localName.includes("-")) {
let currentRoot = documentElement.pictureInPictureElement.shadowRoot;
while (currentRoot == null ? void 0 : currentRoot.pictureInPictureElement) {
if (currentRoot.pictureInPictureElement === media)
return true;
currentRoot = (_b = currentRoot.pictureInPictureElement) == null ? void 0 : _b.shadowRoot;
}
}
return false;
},
set(value, stateOwners) {
const { media } = stateOwners;
if (!media)
return;
if (value) {
if (!import_server_safe_globals.document.pictureInPictureEnabled) {
console.warn("MediaChrome: Picture-in-picture is not enabled");
return;
}
if (!media.requestPictureInPicture) {
console.warn(
"MediaChrome: The current media does not support picture-in-picture"
);
return;
}
const warnNotReady = () => {
console.warn(
"MediaChrome: The media is not ready for picture-in-picture. It must have a readyState > 0."
);
};
media.requestPictureInPicture().catch((err) => {
if (err.code === 11) {
if (!media.src) {
console.warn(
"MediaChrome: The media is not ready for picture-in-picture. It must have a src set."
);
return;
}
if (media.readyState === 0 && media.preload === "none") {
const cleanup = () => {
media.removeEventListener("loadedmetadata", tryPip);
media.preload = "none";
};
const tryPip = () => {
media.requestPictureInPicture().catch(warnNotReady);
cleanup();
};
media.addEventListener("loadedmetadata", tryPip);
media.preload = "metadata";
setTimeout(() => {
if (media.readyState === 0)
warnNotReady();
cleanup();
}, 1e3);
} else {
throw err;
}
} else {
throw err;
}
});
} else if (import_server_safe_globals.document.pictureInPictureElement) {
import_server_safe_globals.document.exitPictureInPicture();
}
},
mediaEvents: ["enterpictureinpicture", "leavepictureinpicture"]
},
mediaRenditionList: {
get(stateOwners) {
var _a;
const { media } = stateOwners;
return [...(_a = media == null ? void 0 : media.videoRenditions) != null ? _a : []].map((videoRendition) => ({
...videoRendition
}));
},
mediaEvents: ["emptied", "loadstart"],
videoRenditionsEvents: ["addrendition", "removerendition"]
},
/** @TODO Model this as a derived value? (CJP) */
mediaRenditionSelected: {
get(stateOwners) {
var _a, _b, _c;
const { media } = stateOwners;
return (_c = (_b = media == null ? void 0 : media.videoRenditions) == null ? void 0 : _b[(_a = media.videoRenditions) == null ? void 0 : _a.selectedIndex]) == null ? void 0 : _c.id;
},
set(value, stateOwners) {
const { media } = stateOwners;
if (!(media == null ? void 0 : media.videoRenditions)) {
console.warn(
"MediaController: Rendition selection not supported by this media."
);
return;
}
const renditionId = value;
const index = Array.prototype.findIndex.call(
media.videoRenditions,
(r) => r.id == renditionId
);
if (media.videoRenditions.selectedIndex != index) {
media.videoRenditions.selectedIndex = index;
}
},
mediaEvents: ["emptied"],
videoRenditionsEvents: ["addrendition", "removerendition", "change"]
},
mediaAudioTrackList: {
get(stateOwners) {
var _a;
const { media } = stateOwners;
return [...(_a = media == null ? void 0 : media.audioTracks) != null ? _a : []];
},
mediaEvents: ["emptied", "loadstart"],
audioTracksEvents: ["addtrack", "removetrack"]
},
mediaAudioTrackEnabled: {
get(stateOwners) {
var _a, _b;
const { media } = stateOwners;
return (_b = [...(_a = media == null ? void 0 : media.audioTracks) != null ? _a : []].find(
(audioTrack) => audioTrack.enabled
)) == null ? void 0 : _b.id;
},
set(value, stateOwners) {
const { media } = stateOwners;
if (!(media == null ? void 0 : media.audioTracks)) {
console.warn(
"MediaChrome: Audio track selection not supported by this media."
);
return;
}
const audioTrackId = value;
for (const track of media.audioTracks) {
track.enabled = audioTrackId == track.id;
}
},
mediaEvents: ["emptied"],
audioTracksEvents: ["addtrack", "removetrack", "change"]
},
mediaIsFullscreen: {
get(stateOwners) {
return (0, import_fullscreen_api.isFullscreen)(stateOwners);
},
set(value, stateOwners) {
if (!value) {
(0, import_fullscreen_api.exitFullscreen)(stateOwners);
} else {
(0, import_fullscreen_api.enterFullscreen)(stateOwners);
}
},
// older Safari version may require webkit-specific events
rootEvents: ["fullscreenchange", "webkitfullscreenchange"],
// iOS requires webkit-specific events on the video.
mediaEvents: ["webkitbeginfullscreen", "webkitendfullscreen", "webkitpresentationmodechanged"]
},
mediaIsCasting: {
// Note this relies on a customized castable-video element.
get(stateOwners) {
var _a;
const { media } = stateOwners;
if (!(media == null ? void 0 : media.remote) || ((_a = media.remote) == null ? void 0 : _a.state) === "disconnected")
return false;
return !!media.remote.state;
},
set(value, stateOwners) {
var _a, _b;
const { media } = stateOwners;
if (!media)
return;
if (value && ((_a = media.remote) == null ? void 0 : _a.state) !== "disconnected")
return;
if (!value && ((_b = media.remote) == null ? void 0 : _b.state) !== "connected")
return;
if (typeof media.remote.prompt !== "function") {
console.warn(
"MediaChrome: Casting is not supported in this environment"
);
return;
}
media.remote.prompt().catch(() => {
});
},
remoteEvents: ["connect", "connecting", "disconnect"]
},
// NOTE: Newly added state for tracking airplaying
mediaIsAirplaying: {
// NOTE: Cannot know if airplaying since Safari doesn't fully support HTMLMediaElement::remote yet (e.g. remote::state) (CJP)
get() {
return false;
},
set(_value, stateOwners) {
const { media } = stateOwners;
if (!media)
return;
if (!(media.webkitShowPlaybackTargetPicker && import_server_safe_globals.globalThis.WebKitPlaybackTargetAvailabilityEvent)) {
console.warn(
"MediaChrome: received a request to select AirPlay but AirPlay is not supported in this environment"
);
return;
}
media.webkitShowPlaybackTargetPicker();
},
mediaEvents: ["webkitcurrentplaybacktargetiswirelesschanged"]
},
mediaFullscreenUnavailable: {
get(stateOwners) {
const { media } = stateOwners;
if (!import_platform_tests.fullscreenSupported || !(0, import_platform_tests.hasFullscreenSupport)(media))
return import_constants.AvailabilityStates.UNSUPPORTED;
return void 0;
}
},
mediaPipUnavailable: {
get(stateOwners) {
const { media } = stateOwners;
if (!import_platform_tests.pipSupported || !(0, import_platform_tests.hasPipSupport)(media))
return import_constants.AvailabilityStates.UNSUPPORTED;
}
},
mediaVolumeUnavailable: {
get(stateOwners) {
const { media } = stateOwners;
if (volumeSupported === false || (media == null ? void 0 : media.volume) == void 0) {
return import_constants.AvailabilityStates.UNSUPPORTED;
}
return void 0;
},
// NOTE: Slightly different impl here. Added generic support for
// "stateOwnersUpdateHandlers" since the original impl had to hack around
// race conditions. (CJP)
stateOwnersUpdateHandlers: [
(handler) => {
if (volumeSupported == null) {
volumeSupportPromise.then(
(supported) => handler(supported ? void 0 : import_constants.AvailabilityStates.UNSUPPORTED)
);
}
}
]
},
mediaCastUnavailable: {
// @ts-ignore
get(stateOwners, { availability = "not-available" } = {}) {
var _a;
const { media } = stateOwners;
if (!import_platform_tests.castSupported || !((_a = media == null ? void 0 : media.remote) == null ? void 0 : _a.state)) {
return import_constants.AvailabilityStates.UNSUPPORTED;
}
if (availability == null || availability === "available")
return void 0;
return import_constants.AvailabilityStates.UNAVAILABLE;
},
stateOwnersUpdateHandlers: [
(handler, stateOwners) => {
var _a;
const { media } = stateOwners;
if (!media)
return;
const remotePlaybackDisabled = media.disableRemotePlayback || media.hasAttribute("disableremoteplayback");
if (!remotePlaybackDisabled) {
(_a = media == null ? void 0 : media.remote) == null ? void 0 : _a.watchAvailability((availabilityBool) => {
const availability = availabilityBool ? "available" : "not-available";
handler({ availability });
}).catch((error) => {
if (error.name === "NotSupportedError") {
handler({ availability: null });
} else {
handler({ availability: "not-available" });
}
});
}
return () => {
var _a2;
(_a2 = media == null ? void 0 : media.remote) == null ? void 0 : _a2.cancelWatchAvailability().catch(() => {
});
};
}
]
},
mediaAirplayUnavailable: {
get(_stateOwners, event) {
if (!import_platform_tests.airplaySupported)
return import_constants.AvailabilityStates.UNSUPPORTED;
if ((event == null ? void 0 : event.availability) === "not-available") {
return import_constants.AvailabilityStates.UNAVAILABLE;
}
return void 0;
},
// NOTE: Keeping this event, as it's still the documented way of monitoring
// for AirPlay availability from Apple.
// See: https://developer.apple.com/documentation/webkitjs/adding_an_airplay_button_to_your_safari_media_controls#2940021 (CJP)
mediaEvents: ["webkitplaybacktargetavailabilitychanged"],
stateOwnersUpdateHandlers: [
(handler, stateOwners) => {
var _a;
const { media } = stateOwners;
if (!media)
return;
const remotePlaybackDisabled = media.disableRemotePlayback || media.hasAttribute("disableremoteplayback");
if (!remotePlaybackDisabled) {
(_a = media == null ? void 0 : media.remote) == null ? void 0 : _a.watchAvailability((availabilityBool) => {
const availability = availabilityBool ? "available" : "not-available";
handler({ availability });
}).catch((error) => {
if (error.name === "NotSupportedError") {
handler({ availability: null });
} else {
handler({ availability: "not-available" });
}
});
}
return () => {
var _a2;
(_a2 = media == null ? void 0 : media.remote) == null ? void 0 : _a2.cancelWatchAvailability().catch(() => {
});
};
}
]
},
mediaRenditionUnavailable: {
get(stateOwners) {
var _a;
const { media } = stateOwners;
if (!(media == null ? void 0 : media.videoRenditions)) {
return import_constants.AvailabilityStates.UNSUPPORTED;
}
if (!((_a = media.videoRenditions) == null ? void 0 : _a.length)) {
return import_constants.AvailabilityStates.UNAVAILABLE;
}
return void 0;
},
mediaEvents: ["emptied", "loadstart"],
videoRenditionsEvents: ["addrendition", "removerendition"]
},
mediaAudioTrackUnavailable: {
get(stateOwners) {
var _a, _b;
const { media } = stateOwners;
if (!(media == null ? void 0 : media.audioTracks)) {
return import_constants.AvailabilityStates.UNSUPPORTED;
}
if (((_b = (_a = media.audioTracks) == null ? void 0 : _a.length) != null ? _b : 0) <= 1) {
return import_constants.AvailabilityStates.UNAVAILABLE;
}
return void 0;
},
mediaEvents: ["emptied", "loadstart"],
audioTracksEvents: ["addtrack", "removetrack"]
}
};

View File

@@ -0,0 +1,109 @@
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var util_exports = {};
__export(util_exports, {
areArraysEq: () => areArraysEq,
areValuesEq: () => areValuesEq,
getShowingSubtitleTracks: () => getShowingSubtitleTracks,
getSubtitleTracks: () => getSubtitleTracks,
toggleSubtitleTracks: () => toggleSubtitleTracks
});
module.exports = __toCommonJS(util_exports);
var import_constants = require("../constants.js");
var import_captions = require("../utils/captions.js");
const getSubtitleTracks = (stateOwners) => {
return (0, import_captions.getTextTracksList)(stateOwners.media, (textTrack) => {
return [import_constants.TextTrackKinds.SUBTITLES, import_constants.TextTrackKinds.CAPTIONS].includes(
textTrack.kind
);
}).sort((a, b) => a.kind >= b.kind ? 1 : -1);
};
const getShowingSubtitleTracks = (stateOwners) => {
return (0, import_captions.getTextTracksList)(stateOwners.media, (textTrack) => {
return textTrack.mode === import_constants.TextTrackModes.SHOWING && [import_constants.TextTrackKinds.SUBTITLES, import_constants.TextTrackKinds.CAPTIONS].includes(
textTrack.kind
);
});
};
const toggleSubtitleTracks = (stateOwners, force) => {
const tracks = getSubtitleTracks(stateOwners);
const showingSubitleTracks = getShowingSubtitleTracks(stateOwners);
const subtitlesShowing = !!showingSubitleTracks.length;
if (!tracks.length)
return;
if (force === false || subtitlesShowing && force !== true) {
(0, import_captions.updateTracksModeTo)(import_constants.TextTrackModes.DISABLED, tracks, showingSubitleTracks);
} else if (force === true || !subtitlesShowing && force !== false) {
let subTrack = tracks[0];
const { options } = stateOwners;
if (!(options == null ? void 0 : options.noSubtitlesLangPref)) {
const subtitlesPref = globalThis.localStorage.getItem(
"media-chrome-pref-subtitles-lang"
);
const userLangPrefs = subtitlesPref ? [subtitlesPref, ...globalThis.navigator.languages] : globalThis.navigator.languages;
const preferredAvailableSubs = tracks.filter((textTrack) => {
return userLangPrefs.some(
(lang) => textTrack.language.toLowerCase().startsWith(lang.split("-")[0])
);
}).sort((textTrackA, textTrackB) => {
const idxA = userLangPrefs.findIndex(
(lang) => textTrackA.language.toLowerCase().startsWith(lang.split("-")[0])
);
const idxB = userLangPrefs.findIndex(
(lang) => textTrackB.language.toLowerCase().startsWith(lang.split("-")[0])
);
return idxA - idxB;
});
if (preferredAvailableSubs[0]) {
subTrack = preferredAvailableSubs[0];
}
}
const { language, label, kind } = subTrack;
(0, import_captions.updateTracksModeTo)(import_constants.TextTrackModes.DISABLED, tracks, showingSubitleTracks);
(0, import_captions.updateTracksModeTo)(import_constants.TextTrackModes.SHOWING, tracks, [
{ language, label, kind }
]);
}
};
const areValuesEq = (x, y) => {
if (x === y)
return true;
if (typeof x !== typeof y)
return false;
if (typeof x === "number" && Number.isNaN(x) && Number.isNaN(y))
return true;
if (typeof x !== "object")
return false;
if (Array.isArray(x))
return areArraysEq(x, y);
return Object.entries(x).every(
// NOTE: Checking key in y to disambiguate between between missing keys and keys whose value are undefined (CJP)
([key, value]) => key in y && areValuesEq(value, y[key])
);
};
const areArraysEq = (xs, ys) => {
const xIsArray = Array.isArray(xs);
const yIsArray = Array.isArray(ys);
if (xIsArray !== yIsArray)
return false;
if (!(xIsArray || yIsArray))
return true;
if (xs.length !== ys.length)
return false;
return xs.every((x, i) => areValuesEq(x, ys[i]));
};