UNPKG

tiny-essentials

Version:

Collection of small, essential scripts designed to be used across various projects. These simple utilities are crafted for speed, ease of use, and versatility.

168 lines (167 loc) 6.99 kB
import TinyHtmlMedia from '../TinyHtmlMedia.mjs'; /** * TinyVideo is a helper class for managing <video> elements. * It allows configuring all standard attributes such as src, poster, controls, * autoplay, loop, muted, playsinline, controlslist, crossorigin, preload, * disablepictureinpicture, disableremoteplayback, width, height, and volume, * with validation. * * @example * const video = new TinyHtmlVideo({ * src: 'video.mp4', * controls: true, * autoplay: false, * width: 640, * height: 360 * }); * * @extends TinyHtmlMedia<HTMLVideoElement> */ class TinyHtmlVideo extends TinyHtmlMedia { /** * Creates a new TinyVideo instance. * @param {Object} config * @param {string} [config.src=''] - The video file URL. * @param {string} [config.poster=''] - Image URL shown before playback starts. * @param {boolean} [config.controls=false] - Whether to show default controls. * @param {boolean} [config.autoplay=false] - Start playback automatically (muted may be required). * @param {boolean} [config.loop=false] - Replay automatically when finished. * @param {boolean} [config.muted=false] - Start playback muted. * @param {boolean} [config.playsinline=false] - Play inline instead of fullscreen (mobile devices). * @param {'nodownload'|'nofullscreen'|'noremoteplayback'|string} [config.controlslist] - Restrict controls visibility. * @param {'anonymous'|'use-credentials'} [config.crossorigin] - CORS setting for the video request. * @param {boolean} [config.disablepictureinpicture=false] - Disable Picture-in-Picture mode. * @param {boolean} [config.disableremoteplayback=false] - Disable casting / remote playback. * @param {'auto'|'metadata'|'none'} [config.preload] - Preload behavior suggestion. * @param {number} [config.width] - CSS pixel width of the video display. * @param {number} [config.height] - CSS pixel height of the video display. * @param {number} [config.volume] - Initial volume (0.0–1.0). * @param {string|string[]|Set<string>} [config.tags=[]] - Initial CSS classes. * @param {string} [config.mainClass=""] - Main CSS class applied. */ constructor({ src = '', poster = '', controls = false, autoplay = false, loop = false, muted = false, playsinline = false, controlslist, crossorigin, disablepictureinpicture = false, disableremoteplayback = false, preload, width, height, volume, tags = [], mainClass = '', } = {}) { super(document.createElement('video'), tags, mainClass); if (src) this.src = src; if (poster) this.poster = poster; if (preload) this.preload = preload; this.controls = controls; this.autoplay = autoplay; this.loop = loop; this.muted = muted; this.playsinline = playsinline; this.disablepictureinpicture = disablepictureinpicture; this.disableremoteplayback = disableremoteplayback; if (controlslist) this.controlslist = controlslist; if (crossorigin) this.crossorigin = crossorigin; if (typeof volume === 'number') this.volume = volume; if (width !== undefined) this.width = width; if (height !== undefined) this.height = height; } // ------------------------ // Attribute getters/setters // ------------------------ /** @param {string} src */ set src(src) { if (typeof src !== 'string') throw new TypeError('TinyVideo: "src" must be a string.'); this.setAttr('src', src); } /** @returns {string|null} */ get src() { return this.attrString('src'); } /** @param {string} poster */ set poster(poster) { if (typeof poster !== 'string') throw new TypeError('TinyVideo: "poster" must be a string.'); this.setAttr('poster', poster); } /** @returns {string|null} */ get poster() { return this.attrString('poster'); } /** @param {boolean} controls */ set controls(controls) { if (typeof controls !== 'boolean') throw new TypeError('"controls" must be a boolean.'); controls ? this.addProp('controls') : this.removeProp('controls'); } /** @returns {boolean} */ get controls() { return this.hasProp('controls'); } /** @param {boolean} playsinline */ set playsinline(playsinline) { if (typeof playsinline !== 'boolean') throw new TypeError('"playsinline" must be a boolean.'); playsinline ? this.addProp('playsinline') : this.removeProp('playsinline'); } /** @returns {boolean} */ get playsinline() { return this.hasProp('playsinline'); } /** @param {'nodownload'|'nofullscreen'|'noremoteplayback'|string} controlslist */ set controlslist(controlslist) { if (typeof controlslist !== 'string') throw new TypeError('TinyVideo: "controlslist" must be a string.'); this.setAttr('controlslist', controlslist); } /** @returns {string|null} */ get controlslist() { return this.attrString('controlslist'); } /** @param {'anonymous'|'use-credentials'} crossorigin */ set crossorigin(crossorigin) { if (!['anonymous', 'use-credentials'].includes(crossorigin)) throw new TypeError('TinyVideo: "crossorigin" must be "anonymous" or "use-credentials".'); this.setAttr('crossorigin', crossorigin); } /** @returns {string|null} */ get crossorigin() { return this.attrString('crossorigin'); } /** @param {boolean} disable */ set disablepictureinpicture(disable) { if (typeof disable !== 'boolean') throw new TypeError('"disablepictureinpicture" must be a boolean.'); disable ? this.addProp('disablepictureinpicture') : this.removeProp('disablepictureinpicture'); } /** @returns {boolean} */ get disablepictureinpicture() { return this.hasProp('disablepictureinpicture'); } /** @param {boolean} disable */ set disableremoteplayback(disable) { if (typeof disable !== 'boolean') throw new TypeError('"disableremoteplayback" must be a boolean.'); disable ? this.addProp('disableremoteplayback') : this.removeProp('disableremoteplayback'); } /** @returns {boolean} */ get disableremoteplayback() { return this.hasProp('disableremoteplayback'); } // ------------------------ // Fullscreen controls // ------------------------ /** @returns {Promise<void>|undefined} */ requestFullscreen() { return this.el.requestFullscreen(); } /** @returns {Promise<boolean>} */ async exitFullscreen() { if (document.fullscreenElement === this.el) { await document.exitFullscreen(); return true; } return false; } } export default TinyHtmlVideo;