UNPKG

@mux/mux-player

Version:

An open source Mux player web component that Just Worksâ„¢

1,429 lines (1,395 loc) • 447 kB
"use strict"; var mediaThemeMinimal = (() => { var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; 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 __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); // src/themes/minimal/index.ts var index_exports = {}; // ../../node_modules/media-chrome/dist/constants.js var MediaUIEvents = { MEDIA_PLAY_REQUEST: "mediaplayrequest", MEDIA_PAUSE_REQUEST: "mediapauserequest", MEDIA_MUTE_REQUEST: "mediamuterequest", MEDIA_UNMUTE_REQUEST: "mediaunmuterequest", MEDIA_VOLUME_REQUEST: "mediavolumerequest", MEDIA_SEEK_REQUEST: "mediaseekrequest", MEDIA_AIRPLAY_REQUEST: "mediaairplayrequest", MEDIA_ENTER_FULLSCREEN_REQUEST: "mediaenterfullscreenrequest", MEDIA_EXIT_FULLSCREEN_REQUEST: "mediaexitfullscreenrequest", MEDIA_PREVIEW_REQUEST: "mediapreviewrequest", MEDIA_ENTER_PIP_REQUEST: "mediaenterpiprequest", MEDIA_EXIT_PIP_REQUEST: "mediaexitpiprequest", MEDIA_ENTER_CAST_REQUEST: "mediaentercastrequest", MEDIA_EXIT_CAST_REQUEST: "mediaexitcastrequest", MEDIA_SHOW_TEXT_TRACKS_REQUEST: "mediashowtexttracksrequest", MEDIA_HIDE_TEXT_TRACKS_REQUEST: "mediahidetexttracksrequest", MEDIA_SHOW_SUBTITLES_REQUEST: "mediashowsubtitlesrequest", MEDIA_DISABLE_SUBTITLES_REQUEST: "mediadisablesubtitlesrequest", MEDIA_TOGGLE_SUBTITLES_REQUEST: "mediatogglesubtitlesrequest", MEDIA_PLAYBACK_RATE_REQUEST: "mediaplaybackraterequest", MEDIA_RENDITION_REQUEST: "mediarenditionrequest", MEDIA_AUDIO_TRACK_REQUEST: "mediaaudiotrackrequest", MEDIA_SEEK_TO_LIVE_REQUEST: "mediaseektoliverequest", REGISTER_MEDIA_STATE_RECEIVER: "registermediastatereceiver", UNREGISTER_MEDIA_STATE_RECEIVER: "unregistermediastatereceiver" }; var MediaStateReceiverAttributes = { MEDIA_CHROME_ATTRIBUTES: "mediachromeattributes", MEDIA_CONTROLLER: "mediacontroller" }; var MediaUIProps = { MEDIA_AIRPLAY_UNAVAILABLE: "mediaAirplayUnavailable", MEDIA_AUDIO_TRACK_ENABLED: "mediaAudioTrackEnabled", MEDIA_AUDIO_TRACK_LIST: "mediaAudioTrackList", MEDIA_AUDIO_TRACK_UNAVAILABLE: "mediaAudioTrackUnavailable", MEDIA_BUFFERED: "mediaBuffered", MEDIA_CAST_UNAVAILABLE: "mediaCastUnavailable", MEDIA_CHAPTERS_CUES: "mediaChaptersCues", MEDIA_CURRENT_TIME: "mediaCurrentTime", MEDIA_DURATION: "mediaDuration", MEDIA_ENDED: "mediaEnded", MEDIA_ERROR: "mediaError", MEDIA_ERROR_CODE: "mediaErrorCode", MEDIA_ERROR_MESSAGE: "mediaErrorMessage", MEDIA_FULLSCREEN_UNAVAILABLE: "mediaFullscreenUnavailable", MEDIA_HAS_PLAYED: "mediaHasPlayed", MEDIA_HEIGHT: "mediaHeight", MEDIA_IS_AIRPLAYING: "mediaIsAirplaying", MEDIA_IS_CASTING: "mediaIsCasting", MEDIA_IS_FULLSCREEN: "mediaIsFullscreen", MEDIA_IS_PIP: "mediaIsPip", MEDIA_LOADING: "mediaLoading", MEDIA_MUTED: "mediaMuted", MEDIA_PAUSED: "mediaPaused", MEDIA_PIP_UNAVAILABLE: "mediaPipUnavailable", MEDIA_PLAYBACK_RATE: "mediaPlaybackRate", MEDIA_PREVIEW_CHAPTER: "mediaPreviewChapter", MEDIA_PREVIEW_COORDS: "mediaPreviewCoords", MEDIA_PREVIEW_IMAGE: "mediaPreviewImage", MEDIA_PREVIEW_TIME: "mediaPreviewTime", MEDIA_RENDITION_LIST: "mediaRenditionList", MEDIA_RENDITION_SELECTED: "mediaRenditionSelected", MEDIA_RENDITION_UNAVAILABLE: "mediaRenditionUnavailable", MEDIA_SEEKABLE: "mediaSeekable", MEDIA_STREAM_TYPE: "mediaStreamType", MEDIA_SUBTITLES_LIST: "mediaSubtitlesList", MEDIA_SUBTITLES_SHOWING: "mediaSubtitlesShowing", MEDIA_TARGET_LIVE_WINDOW: "mediaTargetLiveWindow", MEDIA_TIME_IS_LIVE: "mediaTimeIsLive", MEDIA_VOLUME: "mediaVolume", MEDIA_VOLUME_LEVEL: "mediaVolumeLevel", MEDIA_VOLUME_UNAVAILABLE: "mediaVolumeUnavailable", MEDIA_WIDTH: "mediaWidth" }; var MediaUIPropsEntries = Object.entries( MediaUIProps ); var MediaUIAttributes = MediaUIPropsEntries.reduce( (dictObj, [key, propName]) => { dictObj[key] = propName.toLowerCase(); return dictObj; }, {} ); var AdditionalStateChangeEvents = { USER_INACTIVE_CHANGE: "userinactivechange", BREAKPOINTS_CHANGE: "breakpointchange", BREAKPOINTS_COMPUTED: "breakpointscomputed" }; var MediaStateChangeEvents = MediaUIPropsEntries.reduce( (dictObj, [key, propName]) => { dictObj[key] = propName.toLowerCase(); return dictObj; }, { ...AdditionalStateChangeEvents } ); var StateChangeEventToAttributeMap = Object.entries( MediaStateChangeEvents ).reduce( (mapObj, [key, eventType]) => { const attrName = MediaUIAttributes[key]; if (attrName) { mapObj[eventType] = attrName; } return mapObj; }, { userinactivechange: "userinactive" } ); var AttributeToStateChangeEventMap = Object.entries( MediaUIAttributes ).reduce( (mapObj, [key, attrName]) => { const evtType = MediaStateChangeEvents[key]; if (evtType) { mapObj[attrName] = evtType; } return mapObj; }, { userinactive: "userinactivechange" } ); var TextTrackKinds = { SUBTITLES: "subtitles", CAPTIONS: "captions", DESCRIPTIONS: "descriptions", CHAPTERS: "chapters", METADATA: "metadata" }; var TextTrackModes = { DISABLED: "disabled", HIDDEN: "hidden", SHOWING: "showing" }; var PointerTypes = { MOUSE: "mouse", PEN: "pen", TOUCH: "touch" }; var AvailabilityStates = { UNAVAILABLE: "unavailable", UNSUPPORTED: "unsupported" }; var StreamTypes = { LIVE: "live", ON_DEMAND: "on-demand", UNKNOWN: "unknown" }; var WebkitPresentationModes = { INLINE: "inline", FULLSCREEN: "fullscreen", PICTURE_IN_PICTURE: "picture-in-picture" }; // ../../node_modules/media-chrome/dist/utils/utils.js function stringifyRenditionList(renditions) { return renditions == null ? void 0 : renditions.map(stringifyRendition).join(" "); } function parseRenditionList(renditions) { return renditions == null ? void 0 : renditions.split(/\s+/).map(parseRendition); } function stringifyRendition(rendition) { if (rendition) { const { id, width, height } = rendition; return [id, width, height].filter((a) => a != null).join(":"); } } function parseRendition(rendition) { if (rendition) { const [id, width, height] = rendition.split(":"); return { id, width: +width, height: +height }; } } function stringifyAudioTrackList(audioTracks) { return audioTracks == null ? void 0 : audioTracks.map(stringifyAudioTrack).join(" "); } function parseAudioTrackList(audioTracks) { return audioTracks == null ? void 0 : audioTracks.split(/\s+/).map(parseAudioTrack); } function stringifyAudioTrack(audioTrack) { if (audioTrack) { const { id, kind, language, label } = audioTrack; return [id, kind, language, label].filter((a) => a != null).join(":"); } } function parseAudioTrack(audioTrack) { if (audioTrack) { const [id, kind, language, label] = audioTrack.split(":"); return { id, kind, language, label }; } } function camelCase(name) { return name.replace(/[-_]([a-z])/g, ($0, $1) => $1.toUpperCase()); } function isValidNumber(x) { return typeof x === "number" && !Number.isNaN(x) && Number.isFinite(x); } function isNumericString(str) { if (typeof str != "string") return false; return !isNaN(str) && !isNaN(parseFloat(str)); } var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); // ../../node_modules/media-chrome/dist/utils/time.js var UnitLabels = [ { singular: "hour", plural: "hours" }, { singular: "minute", plural: "minutes" }, { singular: "second", plural: "seconds" } ]; var toTimeUnitPhrase = (timeUnitValue, unitIndex) => { const unitLabel = timeUnitValue === 1 ? UnitLabels[unitIndex].singular : UnitLabels[unitIndex].plural; return `${timeUnitValue} ${unitLabel}`; }; var formatAsTimePhrase = (seconds) => { if (!isValidNumber(seconds)) return ""; const positiveSeconds = Math.abs(seconds); const negative = positiveSeconds !== seconds; const secondsDateTime = new Date(0, 0, 0, 0, 0, positiveSeconds, 0); const timeParts = [ secondsDateTime.getHours(), secondsDateTime.getMinutes(), secondsDateTime.getSeconds() ]; const timeString = timeParts.map( (timeUnitValue, index) => timeUnitValue && toTimeUnitPhrase(timeUnitValue, index) ).filter((x) => x).join(", "); const negativeSuffix = negative ? " remaining" : ""; return `${timeString}${negativeSuffix}`; }; function formatTime(seconds, guide) { let negative = false; if (seconds < 0) { negative = true; seconds = 0 - seconds; } seconds = seconds < 0 ? 0 : seconds; let s = Math.floor(seconds % 60); let m = Math.floor(seconds / 60 % 60); let h = Math.floor(seconds / 3600); const gm = Math.floor(guide / 60 % 60); const gh = Math.floor(guide / 3600); if (isNaN(seconds) || seconds === Infinity) { h = m = s = "0"; } h = h > 0 || gh > 0 ? h + ":" : ""; m = ((h || gm >= 10) && m < 10 ? "0" + m : m) + ":"; s = s < 10 ? "0" + s : s; return (negative ? "-" : "") + h + m + s; } var emptyTimeRanges = Object.freeze({ length: 0, start(index) { const unsignedIdx = index >>> 0; if (unsignedIdx >= this.length) { throw new DOMException( `Failed to execute 'start' on 'TimeRanges': The index provided (${unsignedIdx}) is greater than or equal to the maximum bound (${this.length}).` ); } return 0; }, end(index) { const unsignedIdx = index >>> 0; if (unsignedIdx >= this.length) { throw new DOMException( `Failed to execute 'end' on 'TimeRanges': The index provided (${unsignedIdx}) is greater than or equal to the maximum bound (${this.length}).` ); } return 0; } }); // ../../node_modules/media-chrome/dist/lang/en.js var En = { "Start airplay": "Start airplay", "Stop airplay": "Stop airplay", Audio: "Audio", Captions: "Captions", "Enable captions": "Enable captions", "Disable captions": "Disable captions", "Start casting": "Start casting", "Stop casting": "Stop casting", "Enter fullscreen mode": "Enter fullscreen mode", "Exit fullscreen mode": "Exit fullscreen mode", Mute: "Mute", Unmute: "Unmute", "Enter picture in picture mode": "Enter picture in picture mode", "Exit picture in picture mode": "Exit picture in picture mode", Play: "Play", Pause: "Pause", "Playback rate": "Playback rate", "Playback rate {playbackRate}": "Playback rate {playbackRate}", Quality: "Quality", "Seek backward": "Seek backward", "Seek forward": "Seek forward", Settings: "Settings", "audio player": "audio player", "video player": "video player", volume: "volume", seek: "seek", "closed captions": "closed captions", "current playback rate": "current playback rate", "playback time": "playback time", "media loading": "media loading", settings: "settings", "audio tracks": "audio tracks", quality: "quality", play: "play", pause: "pause", mute: "mute", unmute: "unmute", live: "live", "start airplay": "start airplay", "stop airplay": "stop airplay", "start casting": "start casting", "stop casting": "stop casting", "enter fullscreen mode": "enter fullscreen mode", "exit fullscreen mode": "exit fullscreen mode", "enter picture in picture mode": "enter picture in picture mode", "exit picture in picture mode": "exit picture in picture mode", "seek to live": "seek to live", "playing live": "playing live", "seek back {seekOffset} seconds": "seek back {seekOffset} seconds", "seek forward {seekOffset} seconds": "seek forward {seekOffset} seconds", "Network Error": "Network Error", "Decode Error": "Decode Error", "Source Not Supported": "Source Not Supported", "Encryption Error": "Encryption Error", "A network error caused the media download to fail.": "A network error caused the media download to fail.", "A media error caused playback to be aborted. The media could be corrupt or your browser does not support this format.": "A media error caused playback to be aborted. The media could be corrupt or your browser does not support this format.", "An unsupported error occurred. The server or network failed, or your browser does not support this format.": "An unsupported error occurred. The server or network failed, or your browser does not support this format.", "The media is encrypted and there are no keys to decrypt it.": "The media is encrypted and there are no keys to decrypt it." }; // ../../node_modules/media-chrome/dist/utils/i18n.js var _a; var translationsLanguages = { en: En }; var currentLanguage = ((_a = globalThis.navigator) == null ? void 0 : _a.language.split("-")[0]) || "en"; var setLanguage = (langCode) => { currentLanguage = langCode; }; var t = (key, variables = {}) => { var _a22; const result = ((_a22 = translationsLanguages[currentLanguage]) == null ? void 0 : _a22[key]) || En[key]; return result.replace( /\{(\w+)\}/g, (_, varName) => variables[varName] !== void 0 ? String(variables[varName]) : `{${varName}}` ); }; // ../../node_modules/media-chrome/dist/utils/server-safe-globals.js var EventTarget = class { addEventListener() { } removeEventListener() { } dispatchEvent() { return true; } }; var Node = class extends EventTarget { }; var Element = class extends Node { constructor() { super(...arguments); this.role = null; } }; var ResizeObserver = class { observe() { } unobserve() { } disconnect() { } }; var documentShim = { createElement: function() { return new globalThisShim.HTMLElement(); }, createElementNS: function() { return new globalThisShim.HTMLElement(); }, addEventListener() { }, removeEventListener() { }, dispatchEvent(_event) { return false; } }; var globalThisShim = { ResizeObserver, document: documentShim, Node, Element, HTMLElement: class HTMLElement extends Element { constructor() { super(...arguments); this.innerHTML = ""; } get content() { return new globalThisShim.DocumentFragment(); } }, DocumentFragment: class DocumentFragment extends EventTarget { }, customElements: { get: function() { }, define: function() { }, whenDefined: function() { } }, localStorage: { getItem(_key) { return null; }, setItem(_key, _value2) { }, removeItem(_key) { } }, CustomEvent: function CustomEvent2() { }, getComputedStyle: function() { }, navigator: { languages: [], get userAgent() { return ""; } }, matchMedia(media) { return { matches: false, media }; } }; var isServer = typeof window === "undefined" || typeof window.customElements === "undefined"; var isShimmed = Object.keys(globalThisShim).every((key) => key in globalThis); var GlobalThis = isServer && !isShimmed ? globalThisShim : globalThis; var Document2 = isServer && !isShimmed ? documentShim : globalThis.document; // ../../node_modules/media-chrome/dist/utils/resize-observer.js var callbacksMap = /* @__PURE__ */ new WeakMap(); var getCallbacks = (element) => { let callbacks = callbacksMap.get(element); if (!callbacks) callbacksMap.set(element, callbacks = /* @__PURE__ */ new Set()); return callbacks; }; var observer = new GlobalThis.ResizeObserver( (entries) => { for (const entry of entries) { for (const callback of getCallbacks(entry.target)) { callback(entry); } } } ); function observeResize(element, callback) { getCallbacks(element).add(callback); observer.observe(element); } function unobserveResize(element, callback) { const callbacks = getCallbacks(element); callbacks.delete(callback); if (!callbacks.size) { observer.unobserve(element); } } // ../../node_modules/media-chrome/dist/utils/element-utils.js function namedNodeMapToObject(namedNodeMap) { const obj = {}; for (const attr of namedNodeMap) { obj[attr.name] = attr.value; } return obj; } function getMediaController(host) { var _a4; return (_a4 = getAttributeMediaController(host)) != null ? _a4 : closestComposedNode(host, "media-controller"); } function getAttributeMediaController(host) { var _a4; const { MEDIA_CONTROLLER } = MediaStateReceiverAttributes; const mediaControllerId = host.getAttribute(MEDIA_CONTROLLER); if (mediaControllerId) { return (_a4 = getDocumentOrShadowRoot(host)) == null ? void 0 : _a4.getElementById( mediaControllerId ); } } var updateIconText = (svg, value, selector = ".value") => { const node = svg.querySelector(selector); if (!node) return; node.textContent = value; }; var getAllSlotted = (el, name) => { const slotSelector = `slot[name="${name}"]`; const slot = el.shadowRoot.querySelector(slotSelector); if (!slot) return []; return slot.children; }; var getSlotted = (el, name) => getAllSlotted(el, name)[0]; var containsComposedNode = (rootNode, childNode) => { if (!rootNode || !childNode) return false; if (rootNode == null ? void 0 : rootNode.contains(childNode)) return true; return containsComposedNode( rootNode, childNode.getRootNode().host ); }; var closestComposedNode = (childNode, selector) => { if (!childNode) return null; const closest = childNode.closest(selector); if (closest) return closest; return closestComposedNode( childNode.getRootNode().host, selector ); }; function getActiveElement(root = document) { var _a4; const activeEl = root == null ? void 0 : root.activeElement; if (!activeEl) return null; return (_a4 = getActiveElement(activeEl.shadowRoot)) != null ? _a4 : activeEl; } function getDocumentOrShadowRoot(node) { var _a4; const rootNode = (_a4 = node == null ? void 0 : node.getRootNode) == null ? void 0 : _a4.call(node); if (rootNode instanceof ShadowRoot || rootNode instanceof Document) { return rootNode; } return null; } function isElementVisible(element, { depth = 3, checkOpacity = true, checkVisibilityCSS = true } = {}) { if (element.checkVisibility) { return element.checkVisibility({ checkOpacity, checkVisibilityCSS }); } let el = element; while (el && depth > 0) { const style = getComputedStyle(el); if (checkOpacity && style.opacity === "0" || checkVisibilityCSS && style.visibility === "hidden" || style.display === "none") { return false; } el = el.parentElement; depth--; } return true; } function getPointProgressOnLine(x, y, p1, p2) { const dx = p2.x - p1.x; const dy = p2.y - p1.y; const lengthSquared = dx * dx + dy * dy; if (lengthSquared === 0) return 0; const projection = ((x - p1.x) * dx + (y - p1.y) * dy) / lengthSquared; return Math.max(0, Math.min(1, projection)); } function getOrInsertCSSRule(styleParent, selectorText) { const cssRule = getCSSRule(styleParent, (st) => st === selectorText); if (cssRule) return cssRule; return insertCSSRule(styleParent, selectorText); } function getCSSRule(styleParent, predicate) { var _a4, _b2; let style; for (style of (_a4 = styleParent.querySelectorAll("style:not([media])")) != null ? _a4 : []) { let cssRules; try { cssRules = (_b2 = style.sheet) == null ? void 0 : _b2.cssRules; } catch { continue; } for (const rule of cssRules != null ? cssRules : []) { if (predicate(rule.selectorText)) return rule; } } } function insertCSSRule(styleParent, selectorText) { var _a4, _b2; const styles = (_a4 = styleParent.querySelectorAll("style:not([media])")) != null ? _a4 : []; const style = styles == null ? void 0 : styles[styles.length - 1]; if (!(style == null ? void 0 : style.sheet)) { console.warn( "Media Chrome: No style sheet found on style tag of", styleParent ); return { // @ts-ignore style: { setProperty: () => { }, removeProperty: () => "", getPropertyValue: () => "" } }; } style == null ? void 0 : style.sheet.insertRule(`${selectorText}{}`, style.sheet.cssRules.length); return ( /** @type {CSSStyleRule} */ (_b2 = style.sheet.cssRules) == null ? void 0 : _b2[style.sheet.cssRules.length - 1] ); } function getNumericAttr(el, attrName, defaultValue = Number.NaN) { const attrVal = el.getAttribute(attrName); return attrVal != null ? +attrVal : defaultValue; } function setNumericAttr(el, attrName, value) { const nextNumericValue = +value; if (value == null || Number.isNaN(nextNumericValue)) { if (el.hasAttribute(attrName)) { el.removeAttribute(attrName); } return; } if (getNumericAttr(el, attrName, void 0) === nextNumericValue) return; el.setAttribute(attrName, `${nextNumericValue}`); } function getBooleanAttr(el, attrName) { return el.hasAttribute(attrName); } function setBooleanAttr(el, attrName, value) { if (value == null) { if (el.hasAttribute(attrName)) { el.removeAttribute(attrName); } return; } if (getBooleanAttr(el, attrName) == value) return; el.toggleAttribute(attrName, value); } function getStringAttr(el, attrName, defaultValue = null) { var _a4; return (_a4 = el.getAttribute(attrName)) != null ? _a4 : defaultValue; } function setStringAttr(el, attrName, value) { if (value == null) { if (el.hasAttribute(attrName)) { el.removeAttribute(attrName); } return; } const nextValue = `${value}`; if (getStringAttr(el, attrName, void 0) === nextValue) return; el.setAttribute(attrName, nextValue); } // ../../node_modules/media-chrome/dist/media-gesture-receiver.js var __accessCheck = (obj, member, msg) => { if (!member.has(obj)) throw TypeError("Cannot " + msg); }; var __privateGet = (obj, member, getter) => { __accessCheck(obj, member, "read from private field"); return getter ? getter.call(obj) : member.get(obj); }; var __privateAdd = (obj, member, value) => { if (member.has(obj)) throw TypeError("Cannot add the same private member more than once"); member instanceof WeakSet ? member.add(obj) : member.set(obj, value); }; var __privateSet = (obj, member, value, setter) => { __accessCheck(obj, member, "write to private field"); setter ? setter.call(obj, value) : member.set(obj, value); return value; }; var _mediaController; var template = Document2.createElement("template"); template.innerHTML = /*html*/ ` <style> :host { display: var(--media-control-display, var(--media-gesture-receiver-display, inline-block)); box-sizing: border-box; } </style> `; var MediaGestureReceiver = class extends GlobalThis.HTMLElement { constructor(options = {}) { super(); __privateAdd(this, _mediaController, void 0); if (!this.shadowRoot) { const shadow = this.attachShadow({ mode: "open" }); const buttonHTML = template.content.cloneNode(true); this.nativeEl = buttonHTML; let slotTemplate17 = options.slotTemplate; if (!slotTemplate17) { slotTemplate17 = Document2.createElement("template"); slotTemplate17.innerHTML = `<slot>${options.defaultContent || ""}</slot>`; } this.nativeEl.appendChild(slotTemplate17.content.cloneNode(true)); shadow.appendChild(buttonHTML); } } // NOTE: Currently "baking in" actions + attrs until we come up with // a more robust architecture (CJP) static get observedAttributes() { return [ MediaStateReceiverAttributes.MEDIA_CONTROLLER, MediaUIAttributes.MEDIA_PAUSED ]; } attributeChangedCallback(attrName, oldValue, newValue) { var _a4, _b2, _c, _d, _e; if (attrName === MediaStateReceiverAttributes.MEDIA_CONTROLLER) { if (oldValue) { (_b2 = (_a4 = __privateGet(this, _mediaController)) == null ? void 0 : _a4.unassociateElement) == null ? void 0 : _b2.call(_a4, this); __privateSet(this, _mediaController, null); } if (newValue && this.isConnected) { __privateSet(this, _mediaController, (_c = this.getRootNode()) == null ? void 0 : _c.getElementById(newValue)); (_e = (_d = __privateGet(this, _mediaController)) == null ? void 0 : _d.associateElement) == null ? void 0 : _e.call(_d, this); } } } connectedCallback() { var _a4, _b2, _c, _d; this.tabIndex = -1; this.setAttribute("aria-hidden", "true"); __privateSet(this, _mediaController, getMediaControllerEl(this)); if (this.getAttribute(MediaStateReceiverAttributes.MEDIA_CONTROLLER)) { (_b2 = (_a4 = __privateGet(this, _mediaController)) == null ? void 0 : _a4.associateElement) == null ? void 0 : _b2.call(_a4, this); } (_c = __privateGet(this, _mediaController)) == null ? void 0 : _c.addEventListener("pointerdown", this); (_d = __privateGet(this, _mediaController)) == null ? void 0 : _d.addEventListener("click", this); } disconnectedCallback() { var _a4, _b2, _c, _d; if (this.getAttribute(MediaStateReceiverAttributes.MEDIA_CONTROLLER)) { (_b2 = (_a4 = __privateGet(this, _mediaController)) == null ? void 0 : _a4.unassociateElement) == null ? void 0 : _b2.call(_a4, this); } (_c = __privateGet(this, _mediaController)) == null ? void 0 : _c.removeEventListener("pointerdown", this); (_d = __privateGet(this, _mediaController)) == null ? void 0 : _d.removeEventListener("click", this); __privateSet(this, _mediaController, null); } handleEvent(event) { var _a4; const composedTarget = (_a4 = event.composedPath()) == null ? void 0 : _a4[0]; const allowList = ["video", "media-controller"]; if (!allowList.includes(composedTarget == null ? void 0 : composedTarget.localName)) return; if (event.type === "pointerdown") { this._pointerType = event.pointerType; } else if (event.type === "click") { const { clientX, clientY } = event; const { left, top, width, height } = this.getBoundingClientRect(); const x = clientX - left; const y = clientY - top; if (x < 0 || y < 0 || x > width || y > height || // In case this element has no dimensions (or display: none) return. width === 0 && height === 0) { return; } const { pointerType = this._pointerType } = event; this._pointerType = void 0; if (pointerType === PointerTypes.TOUCH) { this.handleTap(event); return; } else if (pointerType === PointerTypes.MOUSE) { this.handleMouseClick(event); return; } } } /** * @type {boolean} Is the media paused */ get mediaPaused() { return getBooleanAttr(this, MediaUIAttributes.MEDIA_PAUSED); } set mediaPaused(value) { setBooleanAttr(this, MediaUIAttributes.MEDIA_PAUSED, value); } // NOTE: Currently "baking in" actions + attrs until we come up with // a more robust architecture (CJP) /** * @abstract * @argument {Event} e */ handleTap(e) { } // eslint-disable-line // eslint-disable-next-line handleMouseClick(e) { const eventName = this.mediaPaused ? MediaUIEvents.MEDIA_PLAY_REQUEST : MediaUIEvents.MEDIA_PAUSE_REQUEST; this.dispatchEvent( new GlobalThis.CustomEvent(eventName, { composed: true, bubbles: true }) ); } }; _mediaController = /* @__PURE__ */ new WeakMap(); function getMediaControllerEl(controlEl) { var _a4; const mediaControllerId = controlEl.getAttribute( MediaStateReceiverAttributes.MEDIA_CONTROLLER ); if (mediaControllerId) { return (_a4 = controlEl.getRootNode()) == null ? void 0 : _a4.getElementById(mediaControllerId); } return closestComposedNode(controlEl, "media-controller"); } if (!GlobalThis.customElements.get("media-gesture-receiver")) { GlobalThis.customElements.define( "media-gesture-receiver", MediaGestureReceiver ); } // ../../node_modules/media-chrome/dist/media-container.js var __accessCheck2 = (obj, member, msg) => { if (!member.has(obj)) throw TypeError("Cannot " + msg); }; var __privateGet2 = (obj, member, getter) => { __accessCheck2(obj, member, "read from private field"); return getter ? getter.call(obj) : member.get(obj); }; var __privateAdd2 = (obj, member, value) => { if (member.has(obj)) throw TypeError("Cannot add the same private member more than once"); member instanceof WeakSet ? member.add(obj) : member.set(obj, value); }; var __privateSet2 = (obj, member, value, setter) => { __accessCheck2(obj, member, "write to private field"); setter ? setter.call(obj, value) : member.set(obj, value); return value; }; var __privateMethod = (obj, member, method) => { __accessCheck2(obj, member, "access private method"); return method; }; var _pointerDownTimeStamp; var _currentMedia; var _inactiveTimeout; var _autohide; var _mutationObserver; var _handleMutation; var handleMutation_fn; var _isResizePending; var _handleResize; var _handlePointerMove; var handlePointerMove_fn; var _handlePointerUp; var handlePointerUp_fn; var _setInactive; var setInactive_fn; var _setActive; var setActive_fn; var _scheduleInactive; var scheduleInactive_fn; var Attributes = { AUDIO: "audio", AUTOHIDE: "autohide", BREAKPOINTS: "breakpoints", GESTURES_DISABLED: "gesturesdisabled", KEYBOARD_CONTROL: "keyboardcontrol", NO_AUTOHIDE: "noautohide", USER_INACTIVE: "userinactive", AUTOHIDE_OVER_CONTROLS: "autohideovercontrols" }; var template2 = Document2.createElement("template"); template2.innerHTML = /*html*/ ` <style> ${/* * outline on media is turned off because it is allowed to get focus to faciliate hotkeys. * However, on keyboard interactions, the focus outline is shown, * which is particularly noticeable when going fullscreen via hotkeys. */ ""} :host([${MediaUIAttributes.MEDIA_IS_FULLSCREEN}]) ::slotted([slot=media]) { outline: none; } :host { box-sizing: border-box; position: relative; display: inline-block; line-height: 0; background-color: var(--media-background-color, #000); } :host(:not([${Attributes.AUDIO}])) [part~=layer]:not([part~=media-layer]) { position: absolute; top: 0; left: 0; bottom: 0; right: 0; display: flex; flex-flow: column nowrap; align-items: start; pointer-events: none; background: none; } slot[name=media] { display: var(--media-slot-display, contents); } ${/* * when in audio mode, hide the slotted media element by default */ ""} :host([${Attributes.AUDIO}]) slot[name=media] { display: var(--media-slot-display, none); } ${/* * when in audio mode, hide the gesture-layer which causes media-controller to be taller than the control bar */ ""} :host([${Attributes.AUDIO}]) [part~=layer][part~=gesture-layer] { height: 0; display: block; } ${/* * if gestures are disabled, don't accept pointer-events */ ""} :host(:not([${Attributes.AUDIO}])[${Attributes.GESTURES_DISABLED}]) ::slotted([slot=gestures-chrome]), :host(:not([${Attributes.AUDIO}])[${Attributes.GESTURES_DISABLED}]) media-gesture-receiver[slot=gestures-chrome] { display: none; } ${/* * any slotted element that isn't a poster or media slot should be pointer-events auto * we'll want to add here any slotted elements that shouldn't get pointer-events by default when slotted */ ""} ::slotted(:not([slot=media]):not([slot=poster]):not(media-loading-indicator):not([role=dialog]):not([hidden])) { pointer-events: auto; } :host(:not([${Attributes.AUDIO}])) *[part~=layer][part~=centered-layer] { align-items: center; justify-content: center; } :host(:not([${Attributes.AUDIO}])) ::slotted(media-gesture-receiver[slot=gestures-chrome]), :host(:not([${Attributes.AUDIO}])) media-gesture-receiver[slot=gestures-chrome] { align-self: stretch; flex-grow: 1; } slot[name=middle-chrome] { display: inline; flex-grow: 1; pointer-events: none; background: none; } ${/* Position the media and poster elements to fill the container */ ""} ::slotted([slot=media]), ::slotted([slot=poster]) { width: 100%; height: 100%; } ${/* Video specific styles */ ""} :host(:not([${Attributes.AUDIO}])) .spacer { flex-grow: 1; } ${/* Safari needs this to actually make the element fill the window */ ""} :host(:-webkit-full-screen) { ${/* Needs to use !important otherwise easy to break */ ""} width: 100% !important; height: 100% !important; } ${/* Only add these if auto hide is not disabled */ ""} ::slotted(:not([slot=media]):not([slot=poster]):not([${Attributes.NO_AUTOHIDE}]):not([hidden]):not([role=dialog])) { opacity: 1; transition: var(--media-control-transition-in, opacity 0.25s); } ${/* Hide controls when inactive, not paused, not audio and auto hide not disabled */ ""} :host([${Attributes.USER_INACTIVE}]:not([${MediaUIAttributes.MEDIA_PAUSED}]):not([${MediaUIAttributes.MEDIA_IS_AIRPLAYING}]):not([${MediaUIAttributes.MEDIA_IS_CASTING}]):not([${Attributes.AUDIO}])) ::slotted(:not([slot=media]):not([slot=poster]):not([${Attributes.NO_AUTOHIDE}]):not([role=dialog])) { opacity: 0; transition: var(--media-control-transition-out, opacity 1s); } :host([${Attributes.USER_INACTIVE}]:not([${Attributes.NO_AUTOHIDE}]):not([${MediaUIAttributes.MEDIA_PAUSED}]):not([${MediaUIAttributes.MEDIA_IS_CASTING}]):not([${Attributes.AUDIO}])) ::slotted([slot=media]) { cursor: none; } :host([${Attributes.USER_INACTIVE}][${Attributes.AUTOHIDE_OVER_CONTROLS}]:not([${Attributes.NO_AUTOHIDE}]):not([${MediaUIAttributes.MEDIA_PAUSED}]):not([${MediaUIAttributes.MEDIA_IS_CASTING}]):not([${Attributes.AUDIO}])) * { --media-cursor: none; cursor: none; } ::slotted(media-control-bar) { align-self: stretch; } ${/* ::slotted([slot=poster]) doesn't work for slot fallback content so hide parent slot instead */ ""} :host(:not([${Attributes.AUDIO}])[${MediaUIAttributes.MEDIA_HAS_PLAYED}]) slot[name=poster] { display: none; } ::slotted([role=dialog]) { width: 100%; height: 100%; align-self: center; } ::slotted([role=menu]) { align-self: end; } </style> <slot name="media" part="layer media-layer"></slot> <slot name="poster" part="layer poster-layer"></slot> <slot name="gestures-chrome" part="layer gesture-layer"> <media-gesture-receiver slot="gestures-chrome"></media-gesture-receiver> </slot> <span part="layer vertical-layer"> <slot name="top-chrome" part="top chrome"></slot> <slot name="middle-chrome" part="middle chrome"></slot> <slot name="centered-chrome" part="layer centered-layer center centered chrome"></slot> ${/* default, effectively "bottom-chrome" */ ""} <slot part="bottom chrome"></slot> </span> <slot name="dialog" part="layer dialog-layer"></slot> `; var MEDIA_UI_ATTRIBUTE_NAMES = Object.values(MediaUIAttributes); var defaultBreakpoints = "sm:384 md:576 lg:768 xl:960"; function resizeCallback(entry) { setBreakpoints(entry.target, entry.contentRect.width); } function setBreakpoints(container, width) { var _a4; if (!container.isConnected) return; const breakpoints = (_a4 = container.getAttribute(Attributes.BREAKPOINTS)) != null ? _a4 : defaultBreakpoints; const ranges = createBreakpointMap(breakpoints); const activeBreakpoints = getBreakpoints(ranges, width); let changed = false; Object.keys(ranges).forEach((name) => { if (activeBreakpoints.includes(name)) { if (!container.hasAttribute(`breakpoint${name}`)) { container.setAttribute(`breakpoint${name}`, ""); changed = true; } return; } if (container.hasAttribute(`breakpoint${name}`)) { container.removeAttribute(`breakpoint${name}`); changed = true; } }); if (changed) { const evt = new CustomEvent(MediaStateChangeEvents.BREAKPOINTS_CHANGE, { detail: activeBreakpoints }); container.dispatchEvent(evt); } if (!container.breakpointsComputed) { container.breakpointsComputed = true; container.dispatchEvent( new CustomEvent(MediaStateChangeEvents.BREAKPOINTS_COMPUTED, { bubbles: true, composed: true }) ); } } function createBreakpointMap(breakpoints) { const pairs = breakpoints.split(/\s+/); return Object.fromEntries(pairs.map((pair) => pair.split(":"))); } function getBreakpoints(breakpoints, width) { return Object.keys(breakpoints).filter((name) => { return width >= parseInt(breakpoints[name]); }); } var MediaContainer = class extends GlobalThis.HTMLElement { constructor() { super(); __privateAdd2(this, _handleMutation); __privateAdd2(this, _handlePointerMove); __privateAdd2(this, _handlePointerUp); __privateAdd2(this, _setInactive); __privateAdd2(this, _setActive); __privateAdd2(this, _scheduleInactive); __privateAdd2(this, _pointerDownTimeStamp, 0); __privateAdd2(this, _currentMedia, null); __privateAdd2(this, _inactiveTimeout, null); __privateAdd2(this, _autohide, void 0); this.breakpointsComputed = false; __privateAdd2(this, _mutationObserver, new MutationObserver(__privateMethod(this, _handleMutation, handleMutation_fn).bind(this))); __privateAdd2(this, _isResizePending, false); __privateAdd2(this, _handleResize, (entry) => { if (__privateGet2(this, _isResizePending)) return; setTimeout(() => { resizeCallback(entry); __privateSet2(this, _isResizePending, false); }, 0); __privateSet2(this, _isResizePending, true); }); if (!this.shadowRoot) { this.attachShadow({ mode: "open" }); this.shadowRoot.appendChild(template2.content.cloneNode(true)); } const chainedSlot = this.querySelector( ":scope > slot[slot=media]" ); if (chainedSlot) { chainedSlot.addEventListener("slotchange", () => { const slotEls = chainedSlot.assignedElements({ flatten: true }); if (!slotEls.length) { if (__privateGet2(this, _currentMedia)) { this.mediaUnsetCallback(__privateGet2(this, _currentMedia)); } return; } this.handleMediaUpdated(this.media); }); } } static get observedAttributes() { return [Attributes.AUTOHIDE, Attributes.GESTURES_DISABLED].concat(MEDIA_UI_ATTRIBUTE_NAMES).filter( (name) => ![ MediaUIAttributes.MEDIA_RENDITION_LIST, MediaUIAttributes.MEDIA_AUDIO_TRACK_LIST, MediaUIAttributes.MEDIA_CHAPTERS_CUES, MediaUIAttributes.MEDIA_WIDTH, MediaUIAttributes.MEDIA_HEIGHT, MediaUIAttributes.MEDIA_ERROR, MediaUIAttributes.MEDIA_ERROR_MESSAGE ].includes(name) ); } // Could share this code with media-chrome-html-element instead attributeChangedCallback(attrName, _oldValue, newValue) { if (attrName.toLowerCase() == Attributes.AUTOHIDE) { this.autohide = newValue; } } // First direct child with slot=media, or null get media() { let media = this.querySelector(":scope > [slot=media]"); if ((media == null ? void 0 : media.nodeName) == "SLOT") media = media.assignedElements({ flatten: true })[0]; return media; } async handleMediaUpdated(media) { if (!media) return; __privateSet2(this, _currentMedia, media); if (media.localName.includes("-")) { await GlobalThis.customElements.whenDefined(media.localName); } this.mediaSetCallback(media); } connectedCallback() { var _a4; __privateGet2(this, _mutationObserver).observe(this, { childList: true, subtree: true }); observeResize(this, __privateGet2(this, _handleResize)); const isAudioChrome = this.getAttribute(Attributes.AUDIO) != null; const label = isAudioChrome ? t("audio player") : t("video player"); this.setAttribute("role", "region"); this.setAttribute("aria-label", label); this.handleMediaUpdated(this.media); this.setAttribute(Attributes.USER_INACTIVE, ""); setBreakpoints(this, this.getBoundingClientRect().width); this.addEventListener("pointerdown", this); this.addEventListener("pointermove", this); this.addEventListener("pointerup", this); this.addEventListener("mouseleave", this); this.addEventListener("keyup", this); (_a4 = GlobalThis.window) == null ? void 0 : _a4.addEventListener("mouseup", this); } disconnectedCallback() { var _a4; __privateGet2(this, _mutationObserver).disconnect(); unobserveResize(this, __privateGet2(this, _handleResize)); if (this.media) { this.mediaUnsetCallback(this.media); } (_a4 = GlobalThis.window) == null ? void 0 : _a4.removeEventListener("mouseup", this); } /** * @abstract */ mediaSetCallback(_media) { } mediaUnsetCallback(_media) { __privateSet2(this, _currentMedia, null); } handleEvent(event) { switch (event.type) { case "pointerdown": __privateSet2(this, _pointerDownTimeStamp, event.timeStamp); break; case "pointermove": __privateMethod(this, _handlePointerMove, handlePointerMove_fn).call(this, event); break; case "pointerup": __privateMethod(this, _handlePointerUp, handlePointerUp_fn).call(this, event); break; case "mouseleave": __privateMethod(this, _setInactive, setInactive_fn).call(this); break; case "mouseup": this.removeAttribute(Attributes.KEYBOARD_CONTROL); break; case "keyup": __privateMethod(this, _scheduleInactive, scheduleInactive_fn).call(this); this.setAttribute(Attributes.KEYBOARD_CONTROL, ""); break; } } set autohide(seconds) { const parsedSeconds = Number(seconds); __privateSet2(this, _autohide, isNaN(parsedSeconds) ? 0 : parsedSeconds); } get autohide() { return (__privateGet2(this, _autohide) === void 0 ? 2 : __privateGet2(this, _autohide)).toString(); } get breakpoints() { return getStringAttr(this, Attributes.BREAKPOINTS); } set breakpoints(value) { setStringAttr(this, Attributes.BREAKPOINTS, value); } get audio() { return getBooleanAttr(this, Attributes.AUDIO); } set audio(value) { setBooleanAttr(this, Attributes.AUDIO, value); } get gesturesDisabled() { return getBooleanAttr(this, Attributes.GESTURES_DISABLED); } set gesturesDisabled(value) { setBooleanAttr(this, Attributes.GESTURES_DISABLED, value); } get keyboardControl() { return getBooleanAttr(this, Attributes.KEYBOARD_CONTROL); } set keyboardControl(value) { setBooleanAttr(this, Attributes.KEYBOARD_CONTROL, value); } get noAutohide() { return getBooleanAttr(this, Attributes.NO_AUTOHIDE); } set noAutohide(value) { setBooleanAttr(this, Attributes.NO_AUTOHIDE, value); } get autohideOverControls() { return getBooleanAttr(this, Attributes.AUTOHIDE_OVER_CONTROLS); } set autohideOverControls(value) { setBooleanAttr(this, Attributes.AUTOHIDE_OVER_CONTROLS, value); } get userInteractive() { return getBooleanAttr(this, Attributes.USER_INACTIVE); } set userInteractive(value) { setBooleanAttr(this, Attributes.USER_INACTIVE, value); } }; _pointerDownTimeStamp = /* @__PURE__ */ new WeakMap(); _currentMedia = /* @__PURE__ */ new WeakMap(); _inactiveTimeout = /* @__PURE__ */ new WeakMap(); _autohide = /* @__PURE__ */ new WeakMap(); _mutationObserver = /* @__PURE__ */ new WeakMap(); _handleMutation = /* @__PURE__ */ new WeakSet(); handleMutation_fn = function(mutationsList) { const media = this.media; for (const mutation of mutationsList) { if (mutation.type !== "childList") continue; const removedNodes = mutation.removedNodes; for (const node of removedNodes) { if (node.slot != "media" || mutation.target != this) continue; let previousSibling = mutation.previousSibling && mutation.previousSibling.previousElementSibling; if (!previousSibling || !media) { this.mediaUnsetCallback(node); } else { let wasFirst = previousSibling.slot !== "media"; while ((previousSibling = previousSibling.previousSibling) !== null) { if (previousSibling.slot == "media") wasFirst = false; } if (wasFirst) this.mediaUnsetCallback(node); } } if (media) { for (const node of mutation.addedNodes) { if (node === media) this.handleMediaUpdated(media); } } } }; _isResizePending = /* @__PURE__ */ new WeakMap(); _handleResize = /* @__PURE__ */ new WeakMap(); _handlePointerMove = /* @__PURE__ */ new WeakSet(); handlePointerMove_fn = function(event) { if (event.pointerType !== "mouse") { const MAX_TAP_DURATION = 250; if (event.timeStamp - __privateGet2(this, _pointerDownTimeStamp) < MAX_TAP_DURATION) return; } __privateMethod(this, _setActive, setActive_fn).call(this); clearTimeout(__privateGet2(this, _inactiveTimeout)); const autohideOverControls = this.hasAttribute( Attributes.AUTOHIDE_OVER_CONTROLS ); if ([this, this.media].includes(event.target) || autohideOverControls) { __privateMethod(this, _scheduleInactive, scheduleInactive_fn).call(this); } }; _handlePointerUp = /* @__PURE__ */ new WeakSet(); handlePointerUp_fn = function(event) { if (event.pointerType === "touch") { const controlsVisible = !this.hasAttribute(Attributes.USER_INACTIVE); if ([this, this.media].includes(event.target) && controlsVisible) { __privateMethod(this, _setInactive, setInactive_fn).call(this); } else { __privateMethod(this, _scheduleInactive, scheduleInactive_fn).call(this); } } else if (event.composedPath().some( (el) => ["media-play-button", "media-fullscreen-button"].includes( el == null ? void 0 : el.localName ) )) { __privateMethod(this, _scheduleInactive, scheduleInactive_fn).call(this); } }; _setInactive = /* @__PURE__ */ new WeakSet(); setInactive_fn = function() { if (__privateGet2(this, _autohide) < 0) return; if (this.hasAttribute(Attributes.USER_INACTIVE)) return; this.setAttribute(Attributes.USER_INACTIVE, ""); const evt = new GlobalThis.CustomEvent( MediaStateChangeEvents.USER_INACTIVE_CHANGE, { composed: true, bubbles: true, detail: true } ); this.dispatchEvent(evt); }; _setActive = /* @__PURE__ */ new WeakSet(); setActive_fn = function() { if (!this.hasAttribute(Attributes.USER_INACTIVE)) return; this.removeAttribute(Attributes.USER_INACTIVE); const evt = new GlobalThis.CustomEvent( MediaStateChangeEvents.USER_INACTIVE_CHANGE, { composed: true, bubbles: true, detail: false } ); this.dispatchEvent(evt); }; _scheduleInactive = /* @__PURE__ */ new WeakSet(); scheduleInactiv