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_time_range_exports = {}; __export(media_time_range_exports, { default: () => media_time_range_default }); module.exports = __toCommonJS(media_time_range_exports); var import_server_safe_globals = require("./utils/server-safe-globals.js"); var import_media_chrome_range = require("./media-chrome-range.js"); var import_media_preview_thumbnail = require("./media-preview-thumbnail.js"); var import_media_preview_time_display = require("./media-preview-time-display.js"); var import_media_preview_chapter_display = require("./media-preview-chapter-display.js"); var import_constants = require("./constants.js"); var import_labels = require("./labels/labels.js"); var import_utils = require("./utils/utils.js"); var import_time = require("./utils/time.js"); var import_element_utils = require("./utils/element-utils.js"); var import_range_animation = require("./utils/range-animation.js"); var import_element_utils2 = require("./utils/element-utils.js"); var _rootNode, _animation, _boxes, _previewTime, _previewBox, _currentBox, _boxPaddingLeft, _boxPaddingRight, _mediaChaptersCues, _toggleRangeAnimation, toggleRangeAnimation_fn, _shouldRangeAnimate, shouldRangeAnimate_fn, _updateRange, _getElementRects, getElementRects_fn, _getBoxPosition, getBoxPosition_fn, _getBoxShiftPosition, getBoxShiftPosition_fn, _handlePointerMove, handlePointerMove_fn, _previewRequest, previewRequest_fn, _seekRequest, seekRequest_fn; const DEFAULT_MISSING_TIME_PHRASE = "video not loaded, unknown time."; const updateAriaValueText = (el) => { const range = el.range; const currentTimePhrase = (0, import_time.formatAsTimePhrase)(+calcTimeFromRangeValue(el)); const totalTimePhrase = (0, import_time.formatAsTimePhrase)(+el.mediaSeekableEnd); const fullPhrase = !(currentTimePhrase && totalTimePhrase) ? DEFAULT_MISSING_TIME_PHRASE : `${currentTimePhrase} of ${totalTimePhrase}`; range.setAttribute("aria-valuetext", fullPhrase); }; const template = import_server_safe_globals.document.createElement("template"); template.innerHTML = /*html*/ `
${/* Example: add the current time w/ arrow to the playhead
*/ ""}
`; const calcRangeValueFromTime = (el, time = el.mediaCurrentTime) => { const startTime = Number.isFinite(el.mediaSeekableStart) ? el.mediaSeekableStart : 0; const endTime = Number.isFinite(el.mediaDuration) ? el.mediaDuration : el.mediaSeekableEnd; if (Number.isNaN(endTime)) return 0; const value = (time - startTime) / (endTime - startTime); return Math.max(0, Math.min(value, 1)); }; const calcTimeFromRangeValue = (el, value = el.range.valueAsNumber) => { const startTime = Number.isFinite(el.mediaSeekableStart) ? el.mediaSeekableStart : 0; const endTime = Number.isFinite(el.mediaDuration) ? el.mediaDuration : el.mediaSeekableEnd; if (Number.isNaN(endTime)) return 0; return value * (endTime - startTime) + startTime; }; class MediaTimeRange extends import_media_chrome_range.MediaChromeRange { constructor() { super(); __privateAdd(this, _toggleRangeAnimation); __privateAdd(this, _shouldRangeAnimate); __privateAdd(this, _getElementRects); /** * Get the position, max and min for the box in percentage. * It's important this is in percentage so when the player is resized * the box will move accordingly. */ __privateAdd(this, _getBoxPosition); __privateAdd(this, _getBoxShiftPosition); __privateAdd(this, _handlePointerMove); __privateAdd(this, _previewRequest); __privateAdd(this, _seekRequest); __privateAdd(this, _rootNode, void 0); __privateAdd(this, _animation, void 0); __privateAdd(this, _boxes, void 0); __privateAdd(this, _previewTime, void 0); __privateAdd(this, _previewBox, void 0); __privateAdd(this, _currentBox, void 0); __privateAdd(this, _boxPaddingLeft, void 0); __privateAdd(this, _boxPaddingRight, void 0); __privateAdd(this, _mediaChaptersCues, void 0); __privateAdd(this, _updateRange, (value) => { if (this.dragging) return; if ((0, import_utils.isValidNumber)(value)) { this.range.valueAsNumber = value; } this.updateBar(); }); this.container.appendChild(template.content.cloneNode(true)); const track = this.shadowRoot.querySelector("#track"); track.insertAdjacentHTML("afterbegin", '
'); __privateSet(this, _boxes, this.shadowRoot.querySelectorAll('[part~="box"]')); __privateSet(this, _previewBox, this.shadowRoot.querySelector('[part~="preview-box"]')); __privateSet(this, _currentBox, this.shadowRoot.querySelector('[part~="current-box"]')); const computedStyle = getComputedStyle(this); __privateSet(this, _boxPaddingLeft, parseInt( computedStyle.getPropertyValue("--media-box-padding-left") )); __privateSet(this, _boxPaddingRight, parseInt( computedStyle.getPropertyValue("--media-box-padding-right") )); __privateSet(this, _animation, new import_range_animation.RangeAnimation(this.range, __privateGet(this, _updateRange), 60)); } static get observedAttributes() { return [ ...super.observedAttributes, import_constants.MediaUIAttributes.MEDIA_PAUSED, import_constants.MediaUIAttributes.MEDIA_DURATION, import_constants.MediaUIAttributes.MEDIA_SEEKABLE, import_constants.MediaUIAttributes.MEDIA_CURRENT_TIME, import_constants.MediaUIAttributes.MEDIA_PREVIEW_IMAGE, import_constants.MediaUIAttributes.MEDIA_PREVIEW_TIME, import_constants.MediaUIAttributes.MEDIA_PREVIEW_CHAPTER, import_constants.MediaUIAttributes.MEDIA_BUFFERED, import_constants.MediaUIAttributes.MEDIA_PLAYBACK_RATE, import_constants.MediaUIAttributes.MEDIA_LOADING, import_constants.MediaUIAttributes.MEDIA_ENDED ]; } connectedCallback() { var _a; super.connectedCallback(); this.range.setAttribute("aria-label", import_labels.nouns.SEEK()); __privateMethod(this, _toggleRangeAnimation, toggleRangeAnimation_fn).call(this); __privateSet(this, _rootNode, this.getRootNode()); (_a = __privateGet(this, _rootNode)) == null ? void 0 : _a.addEventListener("transitionstart", this); } disconnectedCallback() { var _a; super.disconnectedCallback(); __privateMethod(this, _toggleRangeAnimation, toggleRangeAnimation_fn).call(this); (_a = __privateGet(this, _rootNode)) == null ? void 0 : _a.removeEventListener("transitionstart", this); __privateSet(this, _rootNode, null); } attributeChangedCallback(attrName, oldValue, newValue) { super.attributeChangedCallback(attrName, oldValue, newValue); if (oldValue == newValue) return; if (attrName === import_constants.MediaUIAttributes.MEDIA_CURRENT_TIME || attrName === import_constants.MediaUIAttributes.MEDIA_PAUSED || attrName === import_constants.MediaUIAttributes.MEDIA_ENDED || attrName === import_constants.MediaUIAttributes.MEDIA_LOADING || attrName === import_constants.MediaUIAttributes.MEDIA_DURATION || attrName === import_constants.MediaUIAttributes.MEDIA_SEEKABLE) { __privateGet(this, _animation).update({ start: calcRangeValueFromTime(this), duration: this.mediaSeekableEnd - this.mediaSeekableStart, playbackRate: this.mediaPlaybackRate }); __privateMethod(this, _toggleRangeAnimation, toggleRangeAnimation_fn).call(this); updateAriaValueText(this); } else if (attrName === import_constants.MediaUIAttributes.MEDIA_BUFFERED) { this.updateBufferedBar(); } if (attrName === import_constants.MediaUIAttributes.MEDIA_DURATION || attrName === import_constants.MediaUIAttributes.MEDIA_SEEKABLE) { this.mediaChaptersCues = __privateGet(this, _mediaChaptersCues); this.updateBar(); } } get mediaChaptersCues() { return __privateGet(this, _mediaChaptersCues); } set mediaChaptersCues(value) { var _a; __privateSet(this, _mediaChaptersCues, value); this.updateSegments( (_a = __privateGet(this, _mediaChaptersCues)) == null ? void 0 : _a.map((c) => ({ start: calcRangeValueFromTime(this, c.startTime), end: calcRangeValueFromTime(this, c.endTime) })) ); } /** * Is the media paused */ get mediaPaused() { return (0, import_element_utils2.getBooleanAttr)(this, import_constants.MediaUIAttributes.MEDIA_PAUSED); } set mediaPaused(value) { (0, import_element_utils2.setBooleanAttr)(this, import_constants.MediaUIAttributes.MEDIA_PAUSED, value); } /** * Is the media loading */ get mediaLoading() { return (0, import_element_utils2.getBooleanAttr)(this, import_constants.MediaUIAttributes.MEDIA_LOADING); } set mediaLoading(value) { (0, import_element_utils2.setBooleanAttr)(this, import_constants.MediaUIAttributes.MEDIA_LOADING, value); } /** * */ get mediaDuration() { return (0, import_element_utils2.getNumericAttr)(this, import_constants.MediaUIAttributes.MEDIA_DURATION); } set mediaDuration(value) { (0, import_element_utils2.setNumericAttr)(this, import_constants.MediaUIAttributes.MEDIA_DURATION, value); } /** * */ get mediaCurrentTime() { return (0, import_element_utils2.getNumericAttr)(this, import_constants.MediaUIAttributes.MEDIA_CURRENT_TIME); } set mediaCurrentTime(value) { (0, import_element_utils2.setNumericAttr)(this, import_constants.MediaUIAttributes.MEDIA_CURRENT_TIME, value); } /** * */ get mediaPlaybackRate() { return (0, import_element_utils2.getNumericAttr)(this, import_constants.MediaUIAttributes.MEDIA_PLAYBACK_RATE, 1); } set mediaPlaybackRate(value) { (0, import_element_utils2.setNumericAttr)(this, import_constants.MediaUIAttributes.MEDIA_PLAYBACK_RATE, value); } /** * An array of ranges, each range being an array of two numbers. * e.g. [[1, 2], [3, 4]] */ get mediaBuffered() { const buffered = this.getAttribute(import_constants.MediaUIAttributes.MEDIA_BUFFERED); if (!buffered) return []; return buffered.split(" ").map((timePair) => timePair.split(":").map((timeStr) => +timeStr)); } set mediaBuffered(list) { if (!list) { this.removeAttribute(import_constants.MediaUIAttributes.MEDIA_BUFFERED); return; } const strVal = list.map((tuple) => tuple.join(":")).join(" "); this.setAttribute(import_constants.MediaUIAttributes.MEDIA_BUFFERED, strVal); } /** * Range of values that can be seeked to * An array of two numbers [start, end] */ get mediaSeekable() { const seekable = this.getAttribute(import_constants.MediaUIAttributes.MEDIA_SEEKABLE); if (!seekable) return void 0; return seekable.split(":").map((time) => +time); } set mediaSeekable(range) { if (range == null) { this.removeAttribute(import_constants.MediaUIAttributes.MEDIA_SEEKABLE); return; } this.setAttribute(import_constants.MediaUIAttributes.MEDIA_SEEKABLE, range.join(":")); } /** * */ get mediaSeekableEnd() { var _a; const [, end = this.mediaDuration] = (_a = this.mediaSeekable) != null ? _a : []; return end; } get mediaSeekableStart() { var _a; const [start = 0] = (_a = this.mediaSeekable) != null ? _a : []; return start; } /** * The url of the preview image */ get mediaPreviewImage() { return (0, import_element_utils2.getStringAttr)(this, import_constants.MediaUIAttributes.MEDIA_PREVIEW_IMAGE); } set mediaPreviewImage(value) { (0, import_element_utils2.setStringAttr)(this, import_constants.MediaUIAttributes.MEDIA_PREVIEW_IMAGE, value); } /** * */ get mediaPreviewTime() { return (0, import_element_utils2.getNumericAttr)(this, import_constants.MediaUIAttributes.MEDIA_PREVIEW_TIME); } set mediaPreviewTime(value) { (0, import_element_utils2.setNumericAttr)(this, import_constants.MediaUIAttributes.MEDIA_PREVIEW_TIME, value); } /** * */ get mediaEnded() { return (0, import_element_utils2.getBooleanAttr)(this, import_constants.MediaUIAttributes.MEDIA_ENDED); } set mediaEnded(value) { (0, import_element_utils2.setBooleanAttr)(this, import_constants.MediaUIAttributes.MEDIA_ENDED, value); } /* Add a buffered progress bar */ updateBar() { super.updateBar(); this.updateBufferedBar(); this.updateCurrentBox(); } updateBufferedBar() { var _a; const buffered = this.mediaBuffered; if (!buffered.length) { return; } let relativeBufferedEnd; if (!this.mediaEnded) { const currentTime = this.mediaCurrentTime; const [, bufferedEnd = this.mediaSeekableStart] = (_a = buffered.find( ([start, end]) => start <= currentTime && currentTime <= end )) != null ? _a : []; relativeBufferedEnd = calcRangeValueFromTime(this, bufferedEnd); } else { relativeBufferedEnd = 1; } const { style } = (0, import_element_utils2.getOrInsertCSSRule)(this.shadowRoot, "#buffered"); style.setProperty("width", `${relativeBufferedEnd * 100}%`); } updateCurrentBox() { const currentSlot = this.shadowRoot.querySelector( 'slot[name="current"]' ); if (!currentSlot.assignedElements().length) return; const currentRailRule = (0, import_element_utils2.getOrInsertCSSRule)( this.shadowRoot, "#current-rail" ); const currentBoxRule = (0, import_element_utils2.getOrInsertCSSRule)( this.shadowRoot, '[part~="current-box"]' ); const rects = __privateMethod(this, _getElementRects, getElementRects_fn).call(this, __privateGet(this, _currentBox)); const boxPos = __privateMethod(this, _getBoxPosition, getBoxPosition_fn).call(this, rects, this.range.valueAsNumber); const boxShift = __privateMethod(this, _getBoxShiftPosition, getBoxShiftPosition_fn).call(this, rects, this.range.valueAsNumber); currentRailRule.style.transform = `translateX(${boxPos})`; currentRailRule.style.setProperty("--_range-width", `${rects.range.width}`); currentBoxRule.style.setProperty("--_box-shift", `${boxShift}`); currentBoxRule.style.setProperty("--_box-width", `${rects.box.width}px`); currentBoxRule.style.setProperty("visibility", "initial"); } handleEvent(evt) { super.handleEvent(evt); switch (evt.type) { case "input": __privateMethod(this, _seekRequest, seekRequest_fn).call(this); break; case "pointermove": __privateMethod(this, _handlePointerMove, handlePointerMove_fn).call(this, evt); break; case "pointerup": case "pointerleave": __privateMethod(this, _previewRequest, previewRequest_fn).call(this, null); break; case "transitionstart": if ((0, import_element_utils2.containsComposedNode)(evt.target, this)) { setTimeout(() => __privateMethod(this, _toggleRangeAnimation, toggleRangeAnimation_fn).call(this), 0); } break; } } } _rootNode = new WeakMap(); _animation = new WeakMap(); _boxes = new WeakMap(); _previewTime = new WeakMap(); _previewBox = new WeakMap(); _currentBox = new WeakMap(); _boxPaddingLeft = new WeakMap(); _boxPaddingRight = new WeakMap(); _mediaChaptersCues = new WeakMap(); _toggleRangeAnimation = new WeakSet(); toggleRangeAnimation_fn = function() { if (__privateMethod(this, _shouldRangeAnimate, shouldRangeAnimate_fn).call(this)) { __privateGet(this, _animation).start(); } else { __privateGet(this, _animation).stop(); } }; _shouldRangeAnimate = new WeakSet(); shouldRangeAnimate_fn = function() { return this.isConnected && !this.mediaPaused && !this.mediaLoading && !this.mediaEnded && this.mediaSeekableEnd > 0 && (0, import_element_utils.isElementVisible)(this); }; _updateRange = new WeakMap(); _getElementRects = new WeakSet(); getElementRects_fn = function(box) { var _a; const bounds = (_a = this.getAttribute("bounds") ? (0, import_element_utils2.closestComposedNode)(this, `#${this.getAttribute("bounds")}`) : this.parentElement) != null ? _a : this; const boundsRect = bounds.getBoundingClientRect(); const rangeRect = this.range.getBoundingClientRect(); const width = box.offsetWidth; const min = -(rangeRect.left - boundsRect.left - width / 2); const max = boundsRect.right - rangeRect.left - width / 2; return { box: { width, min, max }, bounds: boundsRect, range: rangeRect }; }; _getBoxPosition = new WeakSet(); getBoxPosition_fn = function(rects, ratio) { let position = `${ratio * 100}%`; const { width, min, max } = rects.box; if (!width) return position; if (!Number.isNaN(min)) { const pad = `var(--media-box-padding-left)`; const minPos = `calc(1 / var(--_range-width) * 100 * ${min}% + ${pad})`; position = `max(${minPos}, ${position})`; } if (!Number.isNaN(max)) { const pad = `var(--media-box-padding-right)`; const maxPos = `calc(1 / var(--_range-width) * 100 * ${max}% - ${pad})`; position = `min(${position}, ${maxPos})`; } return position; }; _getBoxShiftPosition = new WeakSet(); getBoxShiftPosition_fn = function(rects, ratio) { const { width, min, max } = rects.box; const pointerX = ratio * rects.range.width; if (pointerX < min + __privateGet(this, _boxPaddingLeft)) { const offset = rects.range.left - rects.bounds.left - __privateGet(this, _boxPaddingLeft); return `${pointerX - width / 2 + offset}px`; } if (pointerX > max - __privateGet(this, _boxPaddingRight)) { const offset = rects.bounds.right - rects.range.right - __privateGet(this, _boxPaddingRight); return `${pointerX + width / 2 - offset - rects.range.width}px`; } return 0; }; _handlePointerMove = new WeakSet(); handlePointerMove_fn = function(evt) { const isOverBoxes = [...__privateGet(this, _boxes)].some( (b) => evt.composedPath().includes(b) ); if (!this.dragging && (isOverBoxes || !evt.composedPath().includes(this))) { __privateMethod(this, _previewRequest, previewRequest_fn).call(this, null); return; } const duration = this.mediaSeekableEnd; if (!duration) return; const previewRailRule = (0, import_element_utils2.getOrInsertCSSRule)( this.shadowRoot, "#preview-rail" ); const previewBoxRule = (0, import_element_utils2.getOrInsertCSSRule)( this.shadowRoot, '[part~="preview-box"]' ); const rects = __privateMethod(this, _getElementRects, getElementRects_fn).call(this, __privateGet(this, _previewBox)); let pointerRatio = (evt.clientX - rects.range.left) / rects.range.width; pointerRatio = Math.max(0, Math.min(1, pointerRatio)); const boxPos = __privateMethod(this, _getBoxPosition, getBoxPosition_fn).call(this, rects, pointerRatio); const boxShift = __privateMethod(this, _getBoxShiftPosition, getBoxShiftPosition_fn).call(this, rects, pointerRatio); previewRailRule.style.transform = `translateX(${boxPos})`; previewRailRule.style.setProperty("--_range-width", `${rects.range.width}`); previewBoxRule.style.setProperty("--_box-shift", `${boxShift}`); previewBoxRule.style.setProperty("--_box-width", `${rects.box.width}px`); const diff = Math.round(__privateGet(this, _previewTime)) - Math.round(pointerRatio * duration); if (Math.abs(diff) < 1 && pointerRatio > 0.01 && pointerRatio < 0.99) return; __privateSet(this, _previewTime, pointerRatio * duration); __privateMethod(this, _previewRequest, previewRequest_fn).call(this, __privateGet(this, _previewTime)); }; _previewRequest = new WeakSet(); previewRequest_fn = function(detail) { this.dispatchEvent( new import_server_safe_globals.globalThis.CustomEvent(import_constants.MediaUIEvents.MEDIA_PREVIEW_REQUEST, { composed: true, bubbles: true, detail }) ); }; _seekRequest = new WeakSet(); seekRequest_fn = function() { __privateGet(this, _animation).stop(); const detail = calcTimeFromRangeValue(this); this.dispatchEvent( new import_server_safe_globals.globalThis.CustomEvent(import_constants.MediaUIEvents.MEDIA_SEEK_REQUEST, { composed: true, bubbles: true, detail }) ); }; if (!import_server_safe_globals.globalThis.customElements.get("media-time-range")) { import_server_safe_globals.globalThis.customElements.define("media-time-range", MediaTimeRange); } var media_time_range_default = MediaTimeRange;