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;