1(function () { 2 'use strict'; 3 4 var CONFIG = window.VidinoConfig || {}; 5 6 var DEFAULTS = { 7 selector: 'video.wp-video-shortcode, .wp-block-video video, .wp-video video, video.vidino-target', 8 seekStep: 10, 9 volumeStep: 0.1, 10 autoHide: 3000, 11 lazyInit: true, 12 pauseOthers: true, 13 playbackRates: [0.5, 0.75, 1, 1.25, 1.5, 2, 4], 14 i18n: {} 15 }; 16 17 var OPTS = Object.assign({}, DEFAULTS, CONFIG); 18 OPTS.i18n = Object.assign( 19 { 20 play: 'Play', 21 pause: 'Pause', 22 mute: 'Mute', 23 unmute: 'Unmute', 24 volume: 'Volume', 25 seek: 'Seek', 26 fullscreen: 'Fullscreen', 27 pip: 'Picture in Picture', 28 speed: 'Playback speed', 29 currentTime: 'Current time', 30 duration: 'Duration', 31 loading: 'Loading' 32 }, 33 CONFIG.i18n || {} 34 ); 35 36 var SVG_OPEN = '<svg viewBox="0 0 24 24" fill="none" aria-hidden="true" focusable="false">'; 37 var ICONS = { 38 play: SVG_OPEN + 39 '<path fill="currentColor" d="M7.87 21.28C7.08 21.28 6.33 21.09 5.67 20.71C4.11 19.81 3.25 17.98 3.25 15.57V8.43999C3.25 6.01999 4.11 4.19999 5.67 3.29999C7.23 2.39999 9.24 2.56999 11.34 3.77999L17.51 7.33999C19.6 8.54999 20.76 10.21 20.76 12.01C20.76 13.81 19.61 15.47 17.51 16.68L11.34 20.24C10.13 20.93 8.95 21.28 7.87 21.28ZM7.87 4.21999C7.33 4.21999 6.85 4.33999 6.42 4.58999C5.34 5.20999 4.75 6.57999 4.75 8.43999V15.56C4.75 17.42 5.34 18.78 6.42 19.41C7.5 20.04 8.98 19.86 10.59 18.93L16.76 15.37C18.37 14.44 19.26 13.25 19.26 12C19.26 10.75 18.37 9.55999 16.76 8.62999L10.59 5.06999C9.61 4.50999 8.69 4.21999 7.87 4.21999Z"/></svg>', 40 pause: SVG_OPEN + 41 '<path fill="currentColor" d="M8.64 21.75H5.01C3.15 21.75 2.25 20.89 2.25 19.11V4.89C2.25 3.11 3.15 2.25 5.01 2.25H8.64C10.5 2.25 11.4 3.11 11.4 4.89V19.11C11.4 20.89 10.5 21.75 8.64 21.75ZM5.01 3.75C3.93 3.75 3.75 4.02 3.75 4.89V19.11C3.75 19.98 3.92 20.25 5.01 20.25H8.64C9.72 20.25 9.9 19.98 9.9 19.11V4.89C9.9 4.02 9.73 3.75 8.64 3.75H5.01Z"/>' + 42 '<path fill="currentColor" d="M18.9896 21.75H15.3596C13.4996 21.75 12.5996 20.89 12.5996 19.11V4.89C12.5996 3.11 13.4996 2.25 15.3596 2.25H18.9896C20.8496 2.25 21.7496 3.11 21.7496 4.89V19.11C21.7496 20.89 20.8496 21.75 18.9896 21.75ZM15.3596 3.75C14.2796 3.75 14.0996 4.02 14.0996 4.89V19.11C14.0996 19.98 14.2696 20.25 15.3596 20.25H18.9896C20.0696 20.25 20.2496 19.98 20.2496 19.11V4.89C20.2496 4.02 20.0796 3.75 18.9896 3.75H15.3596Z"/></svg>', 43 volume: SVG_OPEN + 44 '<path fill="currentColor" d="M12.55 20.5901C11.76 20.5901 10.89 20.3101 10.02 19.7601L7.1 17.9301C6.9 17.8101 6.67 17.7401 6.44 17.7401H5C2.58 17.7401 1.25 16.4101 1.25 13.9901V9.99011C1.25 7.57011 2.58 6.24011 5 6.24011H6.43C6.66 6.24011 6.89 6.17011 7.09 6.05011L10.01 4.22011C11.47 3.31011 12.89 3.14011 14.01 3.76011C15.13 4.38011 15.74 5.67011 15.74 7.40011V16.5701C15.74 18.2901 15.12 19.5901 14.01 20.2101C13.57 20.4701 13.07 20.5901 12.55 20.5901ZM5 7.75011C3.42 7.75011 2.75 8.42011 2.75 10.0001V14.0001C2.75 15.5801 3.42 16.2501 5 16.2501H6.43C6.95 16.2501 7.45 16.3901 7.89 16.6701L10.81 18.5001C11.77 19.1001 12.68 19.2601 13.29 18.9201C13.9 18.5801 14.25 17.7301 14.25 16.6001V7.41011C14.25 6.27011 13.9 5.42011 13.29 5.09011C12.68 4.75011 11.77 4.90011 10.81 5.51011L7.88 7.33011C7.45 7.61011 6.94 7.75011 6.43 7.75011H5Z"/>' + 45 '<path fill="currentColor" d="M18.0003 16.7498C17.8403 16.7498 17.6903 16.6998 17.5503 16.5998C17.2203 16.3498 17.1503 15.8798 17.4003 15.5498C18.9703 13.4598 18.9703 10.5398 17.4003 8.44978C17.1503 8.11978 17.2203 7.64978 17.5503 7.39978C17.8803 7.14978 18.3503 7.21978 18.6003 7.54978C20.5603 10.1698 20.5603 13.8298 18.6003 16.4498C18.4503 16.6498 18.2303 16.7498 18.0003 16.7498Z"/>' + 46 '<path fill="currentColor" d="M19.8304 19.2498C19.6704 19.2498 19.5204 19.1998 19.3804 19.0998C19.0504 18.8498 18.9804 18.3798 19.2304 18.0498C21.9004 14.4898 21.9004 9.50978 19.2304 5.94978C18.9804 5.61978 19.0504 5.14978 19.3804 4.89978C19.7104 4.64978 20.1804 4.71978 20.4304 5.04978C23.5004 9.13978 23.5004 14.8598 20.4304 18.9498C20.2904 19.1498 20.0604 19.2498 19.8304 19.2498Z"/></svg>', 47 muted: SVG_OPEN + 48 '<path fill="currentColor" d="M7 17.7499H5C2.58 17.7499 1.25 16.4199 1.25 13.9999V9.99987C1.25 7.57987 2.58 6.24987 5 6.24987H6.43C6.66 6.24987 6.89 6.17987 7.09 6.05987L10.01 4.22987C11.47 3.31987 12.89 3.14987 14.01 3.76987C15.13 4.38987 15.74 5.67987 15.74 7.40987V8.36987C15.74 8.77987 15.4 9.11987 14.99 9.11987C14.58 9.11987 14.24 8.77987 14.24 8.36987V7.40987C14.24 6.26987 13.89 5.41987 13.28 5.08987C12.67 4.74987 11.77 4.89987 10.8 5.50987L7.88 7.32987C7.45 7.60987 6.94 7.74987 6.43 7.74987H5C3.42 7.74987 2.75 8.41987 2.75 9.99987V13.9999C2.75 15.5799 3.42 16.2499 5 16.2499H7C7.41 16.2499 7.75 16.5899 7.75 16.9999C7.75 17.4099 7.41 17.7499 7 17.7499Z"/>' +
49 '<path fill="currentColor" d="M12.5496 20.5902C11.7596 20.5902 10.8896 20.3102 10.0196 19.7602C9.6696 19.5402 9.5596 19.0802 9.7796 18.7302C9.9996 18.3802 10.4596 18.2702 10.8096 18.4902C11.7796 19.0902 12.6796 19.2502 13.2896 18.9102C13.8996 18.5702 14.2496 17.7202 14.2496 16.5902V12.9502C14.2496 12.5402 14.5896 12.2002 14.9996 12.2002C15.4096 12.2002 15.7496 12.5402 15.7496 12.9502V16.5902C15.7496 18.3102 15.1296 19.6102 14.0196 20.2302C13.5696 20.4702 13.0696 20.5902 12.5496 20.5902Z"/>' + 50 '<path fill="currentColor" d="M18.0003 16.7498C17.8403 16.7498 17.6903 16.6998 17.5503 16.5998C17.2203 16.3498 17.1503 15.8798 17.4003 15.5498C18.6603 13.8698 18.9303 11.6398 18.1203 9.70983C17.9603 9.32983 18.1403 8.88983 18.5203 8.72983C18.9003 8.56983 19.3403 8.74983 19.5003 9.12983C20.5203 11.5498 20.1703 14.3598 18.6003 16.4598C18.4503 16.6498 18.2303 16.7498 18.0003 16.7498Z"/>' + 51 '<path fill="currentColor" d="M19.8304 19.2502C19.6704 19.2502 19.5204 19.2002 19.3804 19.1002C19.0504 18.8502 18.9804 18.3802 19.2304 18.0502C21.3704 15.2002 21.8404 11.3802 20.4604 8.0902C20.3004 7.7102 20.4804 7.2702 20.8604 7.1102C21.2504 6.9502 21.6804 7.1302 21.8404 7.5102C23.4304 11.2902 22.8904 15.6702 20.4304 18.9502C20.2904 19.1502 20.0604 19.2502 19.8304 19.2502Z"/>' + 52 '<path fill="currentColor" d="M1.99945 22.7499C1.80945 22.7499 1.61945 22.6799 1.46945 22.5299C1.17945 22.2399 1.17945 21.7599 1.46945 21.4699L21.4695 1.46994C21.7595 1.17994 22.2395 1.17994 22.5295 1.46994C22.8195 1.75994 22.8195 2.23994 22.5295 2.52994L2.52945 22.5299C2.37945 22.6799 2.18945 22.7499 1.99945 22.7499Z"/></svg>', 53 enterfs: SVG_OPEN + 54 '<path fill="currentColor" d="M2 9.75C1.59 9.75 1.25 9.41 1.25 9V6.5C1.25 3.61 3.61 1.25 6.5 1.25H9C9.41 1.25 9.75 1.59 9.75 2C9.75 2.41 9.41 2.75 9 2.75H6.5C4.43 2.75 2.75 4.43 2.75 6.5V9C2.75 9.41 2.41 9.75 2 9.75Z"/>' + 55 '<path fill="currentColor" d="M22 9.75C21.59 9.75 21.25 9.41 21.25 9V6.5C21.25 4.43 19.57 2.75 17.5 2.75H15C14.59 2.75 14.25 2.41 14.25 2C14.25 1.59 14.59 1.25 15 1.25H17.5C20.39 1.25 22.75 3.61 22.75 6.5V9C22.75 9.41 22.41 9.75 22 9.75Z"/>' + 56 '<path fill="currentColor" d="M17.5 22.75H16C15.59 22.75 15.25 22.41 15.25 22C15.25 21.59 15.59 21.25 16 21.25H17.5C19.57 21.25 21.25 19.57 21.25 17.5V16C21.25 15.59 21.59 15.25 22 15.25C22.41 15.25 22.75 15.59 22.75 16V17.5C22.75 20.39 20.39 22.75 17.5 22.75Z"/>' + 57 '<path fill="currentColor" d="M9 22.75H6.5C3.61 22.75 1.25 20.39 1.25 17.5V15C1.25 14.59 1.59 14.25 2 14.25C2.41 14.25 2.75 14.59 2.75 15V17.5C2.75 19.57 4.43 21.25 6.5 21.25H9C9.41 21.25 9.75 21.59 9.75 22C9.75 22.41 9.41 22.75 9 22.75Z"/></svg>', 58 exitfs: SVG_OPEN + 59 '<g transform="matrix(-1 0 0 -1 12 12)"><path fill="currentColor" d="M2 9.75C1.59 9.75 1.25 9.41 1.25 9V6.5C1.25 3.61 3.61 1.25 6.5 1.25H9C9.41 1.25 9.75 1.59 9.75 2C9.75 2.41 9.41 2.75 9 2.75H6.5C4.43 2.75 2.75 4.43 2.75 6.5V9C2.75 9.41 2.41 9.75 2 9.75Z"/></g>' + 60 '<g transform="matrix(-1 0 0 -1 36 12)"><path fill="currentColor" d="M22 9.75C21.59 9.75 21.25 9.41 21.25 9V6.5C21.25 4.43 19.57 2.75 17.5 2.75H15C14.59 2.75 14.25 2.41 14.25 2C14.25 1.59 14.59 1.25 15 1.25H17.5C20.39 1.25 22.75 3.61 22.75 6.5V9C22.75 9.41 22.41 9.75 22 9.75Z"/></g>' + 61 '<g transform="matrix(-1 0 0 -1 36 36)"><path fill="currentColor" d="M17.5 22.75H16C15.59 22.75 15.25 22.41 15.25 22C15.25 21.59 15.59 21.25 16 21.25H17.5C19.57 21.25 21.25 19.57 21.25 17.5V16C21.25 15.59 21.59 15.25 22 15.25C22.41 15.25 22.75 15.59 22.75 16V17.5C22.75 20.39 20.39 22.75 17.5 22.75Z"/></g>' + 62 '<g transform="matrix(-1 0 0 -1 12 36)"><path fill="currentColor" d="M9 22.75H6.5C3.61 22.75 1.25 20.39 1.25 17.5V15C1.25 14.59 1.59 14.25 2 14.25C2.41 14.25 2.75 14.59 2.75 15V17.5C2.75 19.57 4.43 21.25 6.5 21.25H9C9.41 21.25 9.75 21.59 9.75 22C9.75 22.41 9.41 22.75 9 22.75Z"/></g></svg>', 63 pip: SVG_OPEN + 64 '<path fill="currentColor" d="M15 22.75H9C3.57 22.75 1.25 20.43 1.25 15V9C1.25 3.57 3.57 1.25 9 1.25H15C20.43 1.25 22.75 3.57 22.75 9V15C22.75 20.43 20.43 22.75 15 22.75ZM9 2.75C4.39 2.75 2.75 4.39 2.75 9V15C2.75 19.61 4.39 21.25 9 21.25H15C19.61 21.25 21.25 19.61 21.25 15V9C21.25 4.39 19.61 2.75 15 2.75H9Z"/>' +
65 '<path fill="currentColor" d="M16.4 19.25H12.6C10.68 19.25 9.75 18.32 9.75 16.4V14.6C9.75 12.68 10.68 11.75 12.6 11.75H16.4C18.32 11.75 19.25 12.68 19.25 14.6V16.4C19.25 18.32 18.32 19.25 16.4 19.25ZM12.6 13.25C11.52 13.25 11.25 13.52 11.25 14.6V16.4C11.25 17.48 11.52 17.75 12.6 17.75H16.4C17.48 17.75 17.75 17.48 17.75 16.4V14.6C17.75 13.52 17.48 13.25 16.4 13.25H12.6Z"/></svg>' 66 }; 67 68 function formatTime(secs) { 69 if (!isFinite(secs) || secs < 0) { 70 secs = 0; 71 } 72 secs = Math.floor(secs); 73 var h = Math.floor(secs / 3600); 74 var m = Math.floor((secs % 3600) / 60); 75 var s = secs % 60; 76 var pad = function (n) { 77 return n < 10 ? '0' + n : '' + n; 78 }; 79 return h > 0 ? h + ':' + pad(m) + ':' + pad(s) : m + ':' + pad(s); 80 } 81 82 function el(tag, attr, html) { 83 var node = document.createElement(tag); 84 if (attr) { 85 Object.keys(attr).forEach(function (key) { 86 node.setAttribute(key, attr[key]); 87 }); 88 } 89 if (html) { 90 node.innerHTML = html; 91 } 92 return node; 93 } 94 95 var VidinoPlayer = (function () { 96 function VidinoPlayer(video) { 97 this.video = video; 98 this.container = null; 99 this.controls = null; 100 this.hideTimer = null; 101 this.destroyed = false; 102 this.resizeObserver = null; 103 this._events = []; 104 this.init(); 105 } 106 107 VidinoPlayer.prototype._on = function (target, type, handler, opts) { 108 target.addEventListener(type, handler, opts || false); 109 this._events.push([target, type, handler, opts || false]); 110 }; 111 112 VidinoPlayer.prototype.init = function () { 113 var video = this.video; 114 if (video.dataset.vidino === 'ready') { 115 return; 116 } 117 video.dataset.vidino = 'ready'; 118 119 video.controls = false; 120 video.setAttribute('playsinline', ''); 121 122 this._unwrapMediaElement(); 123 this._fixWrapperWidth(); 124 125 var container = el('div', { class: 'vidino', tabindex: '-1' }); 126 video.parentNode.insertBefore(container, video); 127 container.appendChild(video); 128 this.container = container; 129 130 this._buildUI(); 131 this._bind(); 132 this._observeResize(); 133 this._syncMuted(); 134 this._ensurePoster(); 135 }; 136 137 VidinoPlayer.prototype._ensurePoster = function () { 138 var video = this.video; 139 if (video.getAttribute('poster')) { 140 return; 141 } 142 143 var capture = function () { 144 var w = video.videoWidth; 145 var h = video.videoHeight; 146 if (!w || !h) { 147 return; 148 } 149 try { 150 var canvas = document.createElement('canvas'); 151 canvas.width = w; 152 canvas.height = h; 153 canvas.getContext('2d').drawImage(video, 0, 0, w, h); 154 video.poster = canvas.toDataURL('image/jpeg', 0.72); 155 } catch (e) { 156 } 157 }; 158 159 var restore = function () { 160 capture(); 161 if (video.currentTime !== 0) { 162 video.currentTime = 0; 163 } 164 }; 165 166 var seekForFrame = function () { 167 if (!isFinite(video.duration) || video.duration <= 0) { 168 return; 169 } 170 this._on(video, 'seeked', restore, { once: true }); 171 try { 172 video.currentTime = Math.min(0.1, video.duration / 2); 173 } catch (e) {} 174 }.bind(this); 175 176 if (video.readyState >= 1) { 177 seekForFrame(); 178 } else { 179 this._on(video, 'loadedmetadata', seekForFrame, { once: true }); 180 } 181 }; 182 183 VidinoPlayer.prototype._unwrapMediaElement = function () { 184 var video = this.video; 185 var mejs = video.closest ? video.closest('.mejs-container') : null; 186 if (!mejs || !mejs.parentNode) { 187 return; 188 } 189 190 mejs.parentNode.insertBefore(video, mejs); 191 mejs.parentNode.removeChild(mejs); 192 193 if (video.id && /_html5$/.test(video.id)) { 194 video.id = video.id.replace(/_html5$/, ''); 195 } 196 197 if (video.style) { 198 video.style.width = ''; 199 video.style.height = ''; 200 } 201 }; 202 203 VidinoPlayer.prototype._fixWrapperWidth = function () { 204 var wrap = this.video.closest('.wp-video, .wp-video-shortcode, .wp-block-video'); 205 if (wrap && wrap.style && wrap.style.width) { 206 wrap.style.width = ''; 207 wrap.style.maxWidth = ''; 208 } 209 if (this.video.style && this.video.style.width) { 210 this.video.style.width = ''; 211 } 212 }; 213 214 VidinoPlayer.prototype._buildUI = function () { 215 var t = OPTS.i18n; 216 var container = this.container; 217 218 this.bigPlay = el('button', { class: 'vidino__bigplay', type: 'button', 'aria-label': t.play }, ICONS.play); 219 container.appendChild(this.bigPlay); 220 221 this.spinner = el('div', { class: 'vidino__spinner', role: 'status', 'aria-label': t.loading }); 222 container.appendChild(this.spinner); 223 224 var controls = el('div', { class: 'vidino__controls', role: 'group', 'aria-label': 'Video controls' }); 225 226 var left = el('div', { class: 'vidino__panel' }); 227 this.playBtn = el('button', { class: 'vidino__btn vidino__play', type: 'button', 'aria-label': t.play }, 228 '<span class="vidino-icon vidino-icon--main">' + ICONS.play + '</span>' + 229 '<span class="vidino-icon vidino-icon--alt">' + ICONS.pause + '</span>'); 230 left.appendChild(this.playBtn); 231 232 var volume = el('div', { class: 'vidino__volume' }); 233 this.muteBtn = el('button', { class: 'vidino__btn vidino__mute', type: 'button', 'aria-label': t.mute }, 234 '<span class="vidino-icon vidino-icon--main">
234' + ICONS.volume + '</span>' + 235 '<span class="vidino-icon vidino-icon--alt">' + ICONS.muted + '</span>'); 236 this.volSlider = el('div', { 237 class: 'vidino__volume-slider', role: 'slider', tabindex: '0', 238 'aria-label': t.volume, 'aria-valuemin': '0', 'aria-valuemax': '100', 'aria-valuenow': '100' 239 }); 240 this.volLevel = el('div', { class: 'vidino__volume-level' }); 241 this.volSlider.appendChild(this.volLevel); 242 volume.appendChild(this.muteBtn); 243 volume.appendChild(this.volSlider); 244 left.appendChild(volume); 245 controls.appendChild(left); 246 247 var center = el('div', { class: 'vidino__panel vidino__panel--grow' }); 248 this.curTime = el('span', { class: 'vidino__time vidino__time--current', 'aria-label': t.currentTime }, '0:00'); 249 this.progress = el('div', { 250 class: 'vidino__progress', role: 'slider', tabindex: '0', 251 'aria-label': t.seek, 'aria-valuemin': '0', 'aria-valuemax': '100', 'aria-valuenow': '0' 252 }); 253 var track = el('div', { class: 'vidino__progress-track' }); 254 this.buffer = el('div', { class: 'vidino__progress-buffer' }); 255 this.played = el('div', { class: 'vidino__progress-played' }); 256 this.thumb = el('div', { class: 'vidino__progress-thumb' }); 257 track.appendChild(this.buffer); 258 track.appendChild(this.played); 259 track.appendChild(this.thumb); 260 this.progress.appendChild(track); 261 this.durTime = el('span', { class: 'vidino__time vidino__time--duration', 'aria-label': t.duration }, '0:00'); 262 center.appendChild(this.curTime); 263 center.appendChild(this.progress); 264 center.appendChild(this.durTime); 265 controls.appendChild(center); 266 267 var right = el('div', { class: 'vidino__panel' }); 268 right.appendChild(this._buildSpeed()); 269 270 if (document.pictureInPictureEnabled && !this.video.disablePictureInPicture) { 271 this.pipBtn = el('button', { class: 'vidino__btn vidino__pip', type: 'button', 'aria-label': t.pip }, ICONS.pip); 272 right.appendChild(this.pipBtn); 273 } 274 275 this.fsBtn = el('button', { class: 'vidino__btn vidino__fs', type: 'button', 'aria-label': t.fullscreen }, 276 '<span class="vidino-icon vidino-icon--main">' + ICONS.enterfs + '</span>' + 277 '<span class="vidino-icon vidino-icon--alt">' + ICONS.exitfs + '</span>'); 278 right.appendChild(this.fsBtn); 279 controls.appendChild(right); 280 281 container.appendChild(controls); 282 this.controls = controls; 283 }; 284 285 VidinoPlayer.prototype._buildSpeed = function () { 286 var self = this; 287 var wrap = el('div', { class: 'vidino__speed' }); 288 this.speedBtn = el('button', { 289 class: 'vidino__btn vidino__speed-btn', type: 'button', 290 'aria-label': OPTS.i18n.speed, 'aria-haspopup': 'true', 'aria-expanded': 'false' 291 }, '1×'); 292 var menu = el('div', { class: 'vidino__speed-menu', role: 'menu' }); 293 294 (OPTS.playbackRates || []).forEach(function (rate) { 295 var opt = el('button', { 296 class: 'vidino__speed-option', type: 'button', role: 'menuitemradio', 297 'aria-checked': rate === 1 ? 'true' : 'false', 'data-rate': String(rate) 298 }, rate + '×'); 299 self._on(opt, 'click', function () { 300 self.setRate(rate); 301 }); 302 menu.appendChild(opt); 303 }); 304 305 this.speedMenu = menu; 306 this._on(this.speedBtn, 'click', function (e) { 307 e.stopPropagation(); 308 wrap.classList.toggle('is-open'); 309 self.speedBtn.setAttribute('aria-expanded', wrap.classList.contains('is-open') ? 'true' : 'false'); 310 }); 311 this._on(document, 'click', function () { 312 wrap.classList.remove('is-open'); 313 self.speedBtn.setAttribute('aria-expanded', 'false'); 314 }); 315 316 this.speedWrap = wrap; 317 wrap.appendChild(this.speedBtn); 318 wrap.appendChild(menu); 319 return wrap; 320 }; 321 322 VidinoPlayer.prototype._bind = function () { 323 var self = this; 324 var v = this.video; 325 var c = this.container; 326 327 this._on(this.bigPlay, 'click', function () { self.toggle(); }); 328 this._on(this.playBtn, 'click', function () { self.toggle(); }); 329 this._on(this.muteBtn, 'click', function () { self.toggleMute(); }); 330 this._on(this.fsBtn, 'click', function () { self.toggleFullscreen(); }); 331 if (this.pipBtn) { 332 this._on(this.pipBtn, 'click', function () { self.togglePip(); }); 333 } 334 335 this._on(v, 'click', function () { 336 clearTimeout(self._clickTimer);
337 self._clickTimer = setTimeout(function () { self.toggle(); }, 220); 338 }); 339 this._on(v, 'dblclick', function () { 340 clearTimeout(self._clickTimer); 341 self.toggleFullscreen(); 342 }); 343 344 this._on(v, 'play', function () { self._onPlay(); }); 345 this._on(v, 'pause', function () { c.classList.remove('is-playing'); self._syncPlayLabels(); }); 346 this._on(v, 'waiting', function () { c.classList.add('is-waiting'); }); 347 this._on(v, 'playing', function () { c.classList.remove('is-waiting'); }); 348 this._on(v, 'canplay', function () { c.classList.remove('is-waiting'); }); 349 this._on(v, 'timeupdate', function () { self._renderProgress(); }); 350 this._on(v, 'progress', function () { self._renderBuffer(); }); 351 this._on(v, 'loadedmetadata', function () { self._renderProgress(); self._renderBuffer(); }); 352 this._on(v, 'volumechange', function () { self._syncMuted(); }); 353 this._on(v, 'ratechange', function () { self._syncRate(); }); 354 this._on(v, 'ended', function () { c.classList.remove('is-playing'); self._showControls(); }); 355 356 this._on(document, 'fullscreenchange', function () { self._syncFullscreen(); }); 357 358 this._bindSlider(this.progress, function (ratio) { self.seekRatio(ratio); }); 359 this._bindSlider(this.volSlider, function (ratio) { self.setVolume(ratio); }); 360 361 c.setAttribute('tabindex', '0'); 362 this._on(c, 'keydown', function (e) { self._onKey(e); }); 363 364 this._on(c, 'mousemove', function () { self._showControls(); }); 365 this._on(c, 'mouseleave', function () { if (!v.paused) { self._hideControls(); } }); 366 this._on(c, 'touchstart', function () { self._showControls(); }, { passive: true }); 367 }; 368 369 VidinoPlayer.prototype._bindSlider = function (node, onSet) { 370 var self = this; 371 var dragging = false; 372 373 var ratioFromEvent = function (e) { 374 var rect = node.getBoundingClientRect(); 375 var x = (e.touches ? e.touches[0].clientX : e.clientX) - rect.left; 376 return Math.min(1, Math.max(0, x / rect.width)); 377 }; 378 379 this._on(node, 'pointerdown', function (e) { 380 dragging = true; 381 node.setPointerCapture && node.setPointerCapture(e.pointerId); 382 onSet(ratioFromEvent(e)); 383 }); 384 this._on(node, 'pointermove', function (e) { 385 if (dragging) { onSet(ratioFromEvent(e)); } 386 }); 387 this._on(node, 'pointerup', function () { dragging = false; }); 388 this._on(node, 'pointercancel', function () { dragging = false; }); 389 390 this._on(node, 'keydown', function (e) { 391 var current = parseFloat(node.getAttribute('aria-valuenow')) || 0; 392 if (e.key === 'ArrowRight' || e.key === 'ArrowUp') { 393 e.preventDefault(); 394 onSet(Math.min(1, current / 100 + 0.05)); 395 } else if (e.key === 'ArrowLeft' || e.key === 'ArrowDown') { 396 e.preventDefault(); 397 onSet(Math.max(0, current / 100 - 0.05)); 398 } 399 }); 400 }; 401 402 VidinoPlayer.prototype.play = function () { 403 var p = this.video.play(); 404 if (p && p.catch) { p.catch(function () {}); } 405 }; 406 407 VidinoPlayer.prototype.pause = function () { this.video.pause(); }; 408 409 VidinoPlayer.prototype.toggle = function () { 410 if (this.video.paused) { this.play(); } else { this.pause(); } 411 }; 412 413 VidinoPlayer.prototype.seekRatio = function (ratio) { 414 if (isFinite(this.video.duration)) { 415 this.video.currentTime = ratio * this.video.duration; 416 } 417 }; 418 419 VidinoPlayer.prototype.skip = function (delta) { 420 this.video.currentTime = Math.min( 421 this.video.duration || 0, 422 Math.max(0, this.video.currentTime + delta) 423 ); 424 }; 425 426 VidinoPlayer.prototype.setVolume = function (ratio) { 427 this.video.volume = Math.min(1, Math.max(0, ratio)); 428 this.video.muted = this.video.volume === 0; 429 }; 430 431 VidinoPlayer.prototype.toggleMute = function () { 432 this.video.muted = !this.video.muted; 433 }; 434 435 VidinoPlayer.prototype.setRate = function (rate) { 436 this.video.playbackRate = rate; 437 }; 438 439 VidinoPlayer.prototype.toggleFullscreen = function () { 440 if (document.fullscreenElement) { 441 document.exitFullscreen(); 442 } else if (this.container.requestFullscreen) { 443 this.container.requestFullscreen(); 444 } else if (this.video.webkitEnterFullscreen) { 445 this.video.webkitEnterFullscreen(); 446 } 447 }; 448 449 VidinoPlayer.prototype.togglePip = function () { 450 if (document.pictureInPictureElement) { 451 document.exitPictureInPicture(); 452 } else if (this.video.requestPictureInPicture) { 453 this.video.requestPictureInPicture().catch(function () {}); 454 } 455 }; 456 457 VidinoPlayer.prototype._onPlay = function () { 458 this.container.classList.add('is-playing'); 459 this._syncPlayLabels(); 460 if (OPTS.pauseOthers) { 461 VidinoManager.pauseOthers(this); 462 } 463 this._hideControls(); 464 }; 465 466 VidinoPlayer.prototype._syncPlayLabels = function () { 467 var label = this.video.paused ? OPTS.i18n.play : OPTS.i18n.pause; 468 this.playBtn.setAttribute('aria-label', label); 469 this.bigPlay.setAttribute('aria-label', label); 470 }; 471 472 VidinoPlayer.prototype._renderProgress = function () { 473 var v = this.video; 474 var d = v.duration || 0; 475 var pct = d ? (v.currentTime / d) * 100 : 0; 476 this.played.style.width = pct + '%'; 477 this.thumb.style.insetInlineStart = pct + '%'; 478 this.thumb.style.left = pct + '%'; 479 this.curTime.textContent = formatTime(v.currentTime);
480 this.durTime.textContent = formatTime(d); 481 this.progress.setAttribute('aria-valuenow', Math.round(pct)); 482 this.progress.setAttribute('aria-valuetext', formatTime(v.currentTime) + ' / ' + formatTime(d)); 483 }; 484 485 VidinoPlayer.prototype._renderBuffer = function () { 486 var v = this.video; 487 if (v.buffered && v.buffered.length && v.duration) { 488 var end = v.buffered.end(v.buffered.length - 1); 489 this.buffer.style.width = (end / v.duration) * 100 + '%'; 490 } 491 }; 492 493 VidinoPlayer.prototype._syncMuted = function () { 494 var v = this.video; 495 var muted = v.muted || v.volume === 0; 496 this.container.classList.toggle('is-muted', muted); 497 this.muteBtn.setAttribute('aria-label', muted ? OPTS.i18n.unmute : OPTS.i18n.mute); 498 var level = muted ? 0 : v.volume * 100; 499 this.volLevel.style.width = level + '%'; 500 this.volSlider.setAttribute('aria-valuenow', Math.round(level)); 501 }; 502 503 VidinoPlayer.prototype._syncRate = function () { 504 var rate = this.video.playbackRate; 505 this.speedBtn.innerHTML = rate + '×'; 506 var opts = this.speedMenu.querySelectorAll('.vidino__speed-option'); 507 Array.prototype.forEach.call(opts, function (opt) { 508 opt.setAttribute('aria-checked', parseFloat(opt.dataset.rate) === rate ? 'true' : 'false'); 509 }); 510 }; 511 512 VidinoPlayer.prototype._syncFullscreen = function () { 513 var active = document.fullscreenElement === this.container; 514 this.container.classList.toggle('is-fullscreen', active); 515 this.fsBtn.setAttribute('aria-label', OPTS.i18n.fullscreen); 516 }; 517 518 VidinoPlayer.prototype._showControls = function () { 519 var self = this; 520 this.container.classList.remove('is-hidden'); 521 clearTimeout(this.hideTimer); 522 if (OPTS.autoHide > 0) { 523 this.hideTimer = setTimeout(function () { 524 if (!self.video.paused) { self._hideControls(); } 525 }, OPTS.autoHide); 526 } 527 }; 528 529 VidinoPlayer.prototype._hideControls = function () { 530 if (this.speedWrap && this.speedWrap.classList.contains('is-open')) { 531 return; 532 } 533 this.container.classList.add('is-hidden'); 534 }; 535 536 VidinoPlayer.prototype._onKey = function (e) { 537 var tag = (e.target.getAttribute && e.target.getAttribute('role')) || ''; 538 var isSlider = tag === 'slider'; 539 540 switch (e.key) { 541 case ' ': 542 case 'k': 543 e.preventDefault(); 544 this.toggle(); 545 break; 546 case 'ArrowLeft': 547 if (!isSlider) { e.preventDefault(); this.skip(-OPTS.seekStep); } 548 break; 549 case 'ArrowRight': 550 if (!isSlider) { e.preventDefault(); this.skip(OPTS.seekStep); } 551 break; 552 case 'ArrowUp': 553 if (!isSlider) { e.preventDefault(); this.setVolume(this.video.volume + OPTS.volumeStep); } 554 break; 555 case 'ArrowDown': 556 if (!isSlider) { e.preventDefault(); this.setVolume(this.video.volume - OPTS.volumeStep); } 557 break; 558 case 'm': 559 case 'M': 560 this.toggleMute(); 561 break; 562 case 'f': 563 case 'F': 564 this.toggleFullscreen(); 565 break; 566 default: 567 return; 568 } 569 this._showControls(); 570 }; 571 572 VidinoPlayer.prototype._observeResize = function () { 573 if (typeof ResizeObserver === 'undefined') { 574 return; 575 } 576 var self = this; 577 this.resizeObserver = new ResizeObserver(function () { 578 self._fixWrapperWidth(); 579 }); 580 this.resizeObserver.observe(this.container); 581 }; 582 583 VidinoPlayer.prototype.refresh = function () { 584 this._renderProgress(); 585 this._renderBuffer(); 586 this._syncMuted(); 587 this._syncRate(); 588 }; 589 590 VidinoPlayer.prototype.destroy = function () { 591 if (this.destroyed) { 592 return; 593 } 594 this.destroyed = true; 595 clearTimeout(this.hideTimer); 596 clearTimeout(this._clickTimer); 597 598 this._events.forEach(function (rec) { 599 rec[0].removeEventListener(rec[1], rec[2], rec[3]); 600 }); 601 this._events = []; 602 603 if (this.resizeObserver) { 604 this.resizeObserver.disconnect(); 605 } 606 607 var video = this.video; 608 video.controls = true; 609 delete video.dataset.vidino; 610 611 if (this.container && this.container.parentNode) { 612 this.container.parentNode.insertBefore(video, this.container); 613 this.container.parentNode.removeChild(this.container); 614 } 615 }; 616 617 return VidinoPlayer; 618 })(); 619 620 var VidinoManager = (function () { 621 var players = []; 622 var intersectionObserver = null; 623 var mutationObserver = null; 624 var started = false;
625 626 function pauseOthers(active) { 627 players.forEach(function (p) { 628 if (p !== active && !p.video.paused) { 629 p.video.pause(); 630 } 631 }); 632 } 633 634 function enhance(video) { 635 if (!video || video.dataset.vidino) { 636 return null; 637 } 638 var player = new VidinoPlayer(video); 639 players.push(player); 640 641 video.dispatchEvent(new CustomEvent('vidino:enhanced', { 642 bubbles: true, 643 detail: { player: player } 644 })); 645 return player; 646 } 647 648 function getIntersectionObserver() { 649 if (intersectionObserver || typeof IntersectionObserver === 'undefined') { 650 return intersectionObserver; 651 } 652 intersectionObserver = new IntersectionObserver(function (entries) { 653 entries.forEach(function (entry) { 654 if (entry.isIntersecting) { 655 enhance(entry.target); 656 intersectionObserver.unobserve(entry.target); 657 } 658 }); 659 }, { rootMargin: '150px 0px' }); 660 return intersectionObserver; 661 } 662 663 function observe(video) { 664 if (video.dataset.vidino) { 665 return; 666 } 667 var io = OPTS.lazyInit ? getIntersectionObserver() : null; 668 if (io) { 669 io.observe(video); 670 } else { 671 enhance(video); 672 } 673 } 674 675 function scan(root) { 676 root = root || document; 677 var nodes = root.querySelectorAll(OPTS.selector); 678 Array.prototype.forEach.call(nodes, observe); 679 } 680 681 function watch() { 682 if (mutationObserver || typeof MutationObserver === 'undefined') { 683 return; 684 } 685 mutationObserver = new MutationObserver(function (mutations) { 686 mutations.forEach(function (m) { 687 Array.prototype.forEach.call(m.addedNodes, function (node) { 688 if (node.nodeType !== 1) { 689 return; 690 } 691 if (node.matches && node.matches(OPTS.selector)) { 692 observe(node); 693 } 694 if (node.querySelectorAll) { 695 scan(node); 696 } 697 }); 698 }); 699 }); 700 mutationObserver.observe(document.body, { childList: true, subtree: true }); 701 } 702 703 function init() { 704 if (started) { 705 scan(document); 706 return; 707 } 708 started = true; 709 scan(document); 710 watch(); 711 } 712 713 function refresh() { 714 scan(document); 715 players.forEach(function (p) { 716 if (!p.destroyed) { 717 p.refresh(); 718 } 719 }); 720 } 721 722 function destroy() { 723 players.forEach(function (p) { p.destroy(); }); 724 players = []; 725 if (intersectionObserver) { intersectionObserver.disconnect(); intersectionObserver = null; } 726 if (mutationObserver) { mutationObserver.disconnect(); mutationObserver = null; } 727 started = false; 728 } 729 730 return { 731 init: init, 732 refresh: refresh, 733 destroy: destroy, 734 observe: observe, 735 scan: scan, 736 enhance: enhance, 737 pauseOthers: pauseOthers, 738 players: function () { return players.slice(); } 739 }; 740 })(); 741 742 window.Vidino = { 743 Player: VidinoPlayer, 744 manager: VidinoManager, 745 init: VidinoManager.init, 746 refresh: VidinoManager.refresh, 747 destroy: VidinoManager.destroy, 748 options: OPTS 749 }; 750 751 if (document.readyState === 'loading') { 752 document.addEventListener('DOMContentLoaded', VidinoManager.init); 753 } else { 754 VidinoManager.init(); 755 } 756})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.