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 __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 __privateMethod = (obj, member, method) => { __accessCheck(obj, member, "access private method"); return method; }; var media_container_exports = {}; __export(media_container_exports, { Attributes: () => Attributes, MediaContainer: () => MediaContainer, default: () => media_container_default }); module.exports = __toCommonJS(media_container_exports); var import_server_safe_globals = require("./utils/server-safe-globals.js"); var import_constants = require("./constants.js"); var import_labels = require("./labels/labels.js"); var import_resize_observer = require("./utils/resize-observer.js"); var import_media_gesture_receiver = require("./media-gesture-receiver.js"); var _pointerDownTimeStamp, _currentMedia, _inactiveTimeout, _autohide, _handlePointerMove, handlePointerMove_fn, _handlePointerUp, handlePointerUp_fn, _setInactive, setInactive_fn, _setActive, setActive_fn, _scheduleInactive, scheduleInactive_fn; const Attributes = { AUDIO: "audio", AUTOHIDE: "autohide", BREAKPOINTS: "breakpoints", GESTURES_DISABLED: "gesturesdisabled", KEYBOARD_CONTROL: "keyboardcontrol", NO_AUTOHIDE: "noautohide", USER_INACTIVE: "userinactive" }; const template = import_server_safe_globals.document.createElement("template"); template.innerHTML = /*html*/ ` ${/* default, effectively "bottom-chrome" */ ""} `; const MEDIA_UI_ATTRIBUTE_NAMES = Object.values(import_constants.MediaUIAttributes); const defaultBreakpoints = "sm:384 md:576 lg:768 xl:960"; function resizeCallback(entry) { setBreakpoints(entry.target, entry.contentRect.width); } function setBreakpoints(container, width) { var _a; if (!container.isConnected) return; const breakpoints = (_a = container.getAttribute(Attributes.BREAKPOINTS)) != null ? _a : 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(import_constants.MediaStateChangeEvents.BREAKPOINTS_CHANGE, { detail: activeBreakpoints }); container.dispatchEvent(evt); } } 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]); }); } class MediaContainer extends import_server_safe_globals.globalThis.HTMLElement { constructor() { super(); __privateAdd(this, _handlePointerMove); __privateAdd(this, _handlePointerUp); __privateAdd(this, _setInactive); __privateAdd(this, _setActive); __privateAdd(this, _scheduleInactive); __privateAdd(this, _pointerDownTimeStamp, 0); __privateAdd(this, _currentMedia, null); __privateAdd(this, _inactiveTimeout, null); __privateAdd(this, _autohide, void 0); this.breakpointsComputed = false; if (!this.shadowRoot) { this.attachShadow({ mode: "open" }); this.shadowRoot.appendChild(template.content.cloneNode(true)); } const mutationCallback = (mutationsList) => { const media = this.media; for (const mutation of mutationsList) { if (mutation.type === "childList") { mutation.removedNodes.forEach((node) => { if (node.slot == "media" && mutation.target == this) { 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) { mutation.addedNodes.forEach((node) => { if (node === media) { this.handleMediaUpdated(media); } }); } } } }; const mutationObserver = new MutationObserver(mutationCallback); mutationObserver.observe(this, { childList: true, subtree: true }); let pendingResizeCb = false; const deferResizeCallback = (entry) => { if (pendingResizeCb) return; setTimeout(() => { resizeCallback(entry); pendingResizeCb = false; if (!this.breakpointsComputed) { this.breakpointsComputed = true; this.dispatchEvent( new CustomEvent(import_constants.MediaStateChangeEvents.BREAKPOINTS_COMPUTED, { bubbles: true, composed: true }) ); } }, 0); pendingResizeCb = true; }; (0, import_resize_observer.observeResize)(this, deferResizeCallback); const chainedSlot = this.querySelector( ":scope > slot[slot=media]" ); if (chainedSlot) { chainedSlot.addEventListener("slotchange", () => { const slotEls = chainedSlot.assignedElements({ flatten: true }); if (!slotEls.length) { if (__privateGet(this, _currentMedia)) { this.mediaUnsetCallback(__privateGet(this, _currentMedia)); } return; } this.handleMediaUpdated(this.media); }); } } static get observedAttributes() { return [Attributes.AUTOHIDE, Attributes.GESTURES_DISABLED].concat(MEDIA_UI_ATTRIBUTE_NAMES).filter( (name) => ![ import_constants.MediaUIAttributes.MEDIA_RENDITION_LIST, import_constants.MediaUIAttributes.MEDIA_AUDIO_TRACK_LIST, import_constants.MediaUIAttributes.MEDIA_CHAPTERS_CUES, import_constants.MediaUIAttributes.MEDIA_WIDTH, import_constants.MediaUIAttributes.MEDIA_HEIGHT ].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 /** * @returns {HTMLVideoElement & * {buffered, * webkitEnterFullscreen?, * webkitExitFullscreen?, * requestCast?, * webkitShowPlaybackTargetPicker?, * videoTracks?, * }} */ 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; } /** * @param {HTMLMediaElement} media */ async handleMediaUpdated(media) { if (!media) return; __privateSet(this, _currentMedia, media); if (media.localName.includes("-")) { await import_server_safe_globals.globalThis.customElements.whenDefined(media.localName); } this.mediaSetCallback(media); } connectedCallback() { var _a; const isAudioChrome = this.getAttribute(Attributes.AUDIO) != null; const label = isAudioChrome ? import_labels.nouns.AUDIO_PLAYER() : import_labels.nouns.VIDEO_PLAYER(); this.setAttribute("role", "region"); this.setAttribute("aria-label", label); this.handleMediaUpdated(this.media); this.setAttribute(Attributes.USER_INACTIVE, ""); this.addEventListener("pointerdown", this); this.addEventListener("pointermove", this); this.addEventListener("pointerup", this); this.addEventListener("mouseleave", this); this.addEventListener("keyup", this); (_a = import_server_safe_globals.globalThis.window) == null ? void 0 : _a.addEventListener("mouseup", this); } disconnectedCallback() { var _a; if (this.media) { this.mediaUnsetCallback(this.media); } (_a = import_server_safe_globals.globalThis.window) == null ? void 0 : _a.removeEventListener("mouseup", this); } /** * @abstract * @param {HTMLMediaElement} media */ mediaSetCallback(media) { } // eslint-disable-line /** * @param {HTMLMediaElement} media */ mediaUnsetCallback(media) { __privateSet(this, _currentMedia, null); } handleEvent(event) { switch (event.type) { case "pointerdown": __privateSet(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); __privateSet(this, _autohide, isNaN(parsedSeconds) ? 0 : parsedSeconds); } get autohide() { return (__privateGet(this, _autohide) === void 0 ? 2 : __privateGet(this, _autohide)).toString(); } } _pointerDownTimeStamp = new WeakMap(); _currentMedia = new WeakMap(); _inactiveTimeout = new WeakMap(); _autohide = new WeakMap(); _handlePointerMove = new WeakSet(); handlePointerMove_fn = function(event) { if (event.pointerType !== "mouse") { const MAX_TAP_DURATION = 250; if (event.timeStamp - __privateGet(this, _pointerDownTimeStamp) < MAX_TAP_DURATION) return; } __privateMethod(this, _setActive, setActive_fn).call(this); clearTimeout(__privateGet(this, _inactiveTimeout)); if ([this, this.media].includes(event.target)) { __privateMethod(this, _scheduleInactive, scheduleInactive_fn).call(this); } }; _handlePointerUp = 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 = new WeakSet(); setInactive_fn = function() { if (__privateGet(this, _autohide) < 0) return; if (this.hasAttribute(Attributes.USER_INACTIVE)) return; this.setAttribute(Attributes.USER_INACTIVE, ""); const evt = new import_server_safe_globals.globalThis.CustomEvent( import_constants.MediaStateChangeEvents.USER_INACTIVE, { composed: true, bubbles: true, detail: true } ); this.dispatchEvent(evt); }; _setActive = new WeakSet(); setActive_fn = function() { if (!this.hasAttribute(Attributes.USER_INACTIVE)) return; this.removeAttribute(Attributes.USER_INACTIVE); const evt = new import_server_safe_globals.globalThis.CustomEvent( import_constants.MediaStateChangeEvents.USER_INACTIVE, { composed: true, bubbles: true, detail: false } ); this.dispatchEvent(evt); }; _scheduleInactive = new WeakSet(); scheduleInactive_fn = function() { __privateMethod(this, _setActive, setActive_fn).call(this); clearTimeout(__privateGet(this, _inactiveTimeout)); const autohide = parseInt(this.autohide); if (autohide < 0) return; __privateSet(this, _inactiveTimeout, setTimeout(() => { __privateMethod(this, _setInactive, setInactive_fn).call(this); }, autohide * 1e3)); }; if (!import_server_safe_globals.globalThis.customElements.get("media-container")) { import_server_safe_globals.globalThis.customElements.define("media-container", MediaContainer); } var media_container_default = MediaContainer;