1// this file won't be updated, so you can write your own code here 2 3document.addEventListener('DOMContentLoaded', function () { 4 5 document.querySelectorAll('.ranx-yadisk-audio').forEach(function (wrapper) { 6 7 if (wrapper.dataset.audioInitialized === 'Y') { 8 return; 9 } 10 11 const source = wrapper.querySelector('.ranx-yadisk-audio__source'); 12 13 if (!source) { 14 return; 15 } 16 17 const publicUrl = source.getAttribute('href'); 18 const title = source.textContent.trim(); 19 20 if (!publicUrl) { 21 return; 22 } 23 24 25 /* 26 * Audio 27 */ 28 const audio = document.createElement('audio'); 29 30 audio.preload = 'metadata'; 31 audio.src = 32 '/local/ajax/yadisk-audio.php?url=' 33 + encodeURIComponent(publicUrl); 34 35 36 /* 37 * Player 38 */ 39 const player = document.createElement('div'); 40 player.className = 'ranx-audio-player'; 41 42 43 /* 44 * Play / Pause 45 */ 46 const playButton = document.createElement('button'); 47 48 playButton.type = 'button'; 49 playButton.className = 'ranx-audio-player__play'; 50 playButton.setAttribute('aria-label', 'ÐоÑпÑоизвеÑÑи'); 51 playButton.textContent = 'â¶'; 52 53 54 /* 55 * Content 56 */ 57 const content = document.createElement('div'); 58 content.className = 'ranx-audio-player__content'; 59 60 61 /* 62 * Title 63 */ 64 const titleElement = document.createElement('div'); 65 66 titleElement.className = 'ranx-audio-player__title'; 67 titleElement.textContent = title; 68 69 70 /* 71 * Waveform 72 */ 73 const waveform = document.createElement('div'); 74 75 waveform.className = 'ranx-audio-player__waveform'; 76 waveform.setAttribute('role', 'slider'); 77 waveform.setAttribute('aria-label', 'ÐеÑемоÑка аÑдио'); 78 waveform.setAttribute('aria-valuemin', '0'); 79 waveform.setAttribute('aria-valuemax', '100'); 80 waveform.setAttribute('aria-valuenow', '0'); 81 82 83 /* 84 * СоздаÑм seed из Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ð¸ ÑÑÑлки. 85 * Ðолна вÑглÑÐ´Ð¸Ñ ÑлÑÑайной, 86 * но оÑÑаÑÑÑÑ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ð¾Ð¹ поÑле пеÑезагÑÑзки. 87 */ 88 function createSeed(string) { 89 90 let seed = 0; 91 92 for (let i = 0; i < string.length; i++) { 93 94 seed = 95 ((seed << 5) - seed) 96 + string.charCodeAt(i); 97 98 seed |= 0; 99 } 100 101 return Math.abs(seed) || 1; 102 } 103 104 105 /* 106 * ÐÑевдоÑлÑÑайнÑй генеÑаÑÐ¾Ñ 107 */ 108 function seededRandom(seed) { 109 110 let value = seed % 2147483647; 111 112 if (value <= 0) { 113 value += 2147483646; 114 } 115 116 return function () { 117 118 value = 119 value * 16807 120 % 2147483647; 121 122 return (value - 1) / 2147483646; 123 }; 124 } 125 126 127 const random = seededRandom( 128 createSeed(title + publicUrl) 129 ); 130 131 132 /* 133 * ÐолиÑеÑÑво ÑÑолбиков 134 */ 135 const barsCount = 150; 136 137 138 /* 139 * ÐенеÑаÑÐ¸Ñ waveform 140 */ 141 for (let i = 0; i < barsCount; i++) { 142 143 const bar = document.createElement('span'); 144 145 bar.className = 'ranx-audio-player__bar'; 146 147 /* 148 * ÐÑÑоÑа Ð¾Ñ 22% до 100% 149 */ 150 const height = 151 22 + Math.floor(random() * 79); 152 153 bar.style.height = height + '%'; 154 155 waveform.appendChild(bar); 156 } 157 158 159 /* 160 * Time 161 */ 162 const time = document.createElement('div'); 163 164 time.className = 'ranx-audio-player__time'; 165 time.textContent = '0:00 / 0:00'; 166 167 168 /* 169 * Build player 170 */ 171 content.appendChild(titleElement); 172 content.appendChild(waveform); 173 content.appendChild(time); 174 175 player.appendChild(playButton); 176 player.appendChild(content); 177 player.appendChild(audio); 178 179 wrapper.innerHTML = ''; 180 wrapper.appendChild(player); 181 182 wrapper.dataset.audioInitialized = 'Y'; 183 184 185 /* 186 * Format seconds â 0:00 187 */ 188 function formatTime(seconds) { 189 190 if (!Number.isFinite(seconds)) { 191 return '0:00'; 192 } 193 194 const minutes = 195 Math.floor(seconds / 60); 196 197 const secs = 198 Math.floor(seconds % 60); 199 200 return ( 201 minutes 202 + ':' 203 + String(secs).padStart(2, '0') 204 ); 205 } 206 207 208 /* 209 * Update time 210 */ 211 function updateTime() { 212 213 time.textContent = 214 formatTime(audio.currentTime) 215 + ' / ' 216 + formatTime(audio.duration); 217 } 218 219 220 /* 221 * Update waveform progress 222 */ 223 function updateWaveform() { 224 225 if ( 226 !Number.isFinite(audio.duration) 227 || audio.duration <= 0 228 ) { 229 return; 230 } 231 232 const progress = 233 audio.currentTime 234 / audio.duration; 235 236 const bars = 237 waveform.querySelectorAll( 238 '.ranx-audio-player__bar' 239 ); 240
241 bars.forEach(function (bar, index) { 242 243 const barPosition = 244 (index + 1) 245 / bars.length; 246 247 bar.classList.toggle( 248 'is-played', 249 barPosition <= progress 250 ); 251 252 }); 253 254 waveform.setAttribute( 255 'aria-valuenow', 256 Math.round(progress * 100) 257 ); 258 } 259 260 261 /* 262 * Play / Pause 263 */ 264 playButton.addEventListener('click', function () { 265 266 if (audio.paused) { 267 268 /* 269 * ÐÑÑанавливаем дÑÑгие плееÑÑ 270 * на ÑекÑÑей ÑÑÑаниÑе. 271 */ 272 document 273 .querySelectorAll( 274 '.ranx-audio-player audio' 275 ) 276 .forEach(function (otherAudio) { 277 278 if ( 279 otherAudio !== audio 280 && !otherAudio.paused 281 ) { 282 otherAudio.pause(); 283 } 284 285 }); 286 287 288 audio.play().catch(function () { 289 290 /* 291 * Ðе ломаем ÑÑÑаниÑÑ 292 * пÑи оÑибке воÑпÑоизведениÑ. 293 */ 294 295 }); 296 297 } else { 298 299 audio.pause(); 300 301 } 302 303 }); 304 305 306 /* 307 * Click waveform â seek 308 */ 309 waveform.addEventListener('click', function (event) { 310 311 if ( 312 !Number.isFinite(audio.duration) 313 || audio.duration <= 0 314 ) { 315 return; 316 } 317 318 const rect = 319 waveform.getBoundingClientRect(); 320 321 const position = Math.max( 322 0, 323 Math.min( 324 1, 325 (event.clientX - rect.left) 326 / rect.width 327 ) 328 ); 329 330 audio.currentTime = 331 audio.duration * position; 332 333 updateTime(); 334 updateWaveform(); 335 336 }); 337 338 339 /* 340 * Audio events 341 */ 342 audio.addEventListener('play', function () { 343 344 playButton.textContent = 'ââ'; 345 346 playButton.setAttribute( 347 'aria-label', 348 'ÐаÑза' 349 ); 350 351 player.classList.add('is-playing'); 352 353 }); 354 355 356 audio.addEventListener('pause', function () { 357 358 playButton.textContent = 'â¶'; 359 360 playButton.setAttribute( 361 'aria-label', 362 'ÐоÑпÑоизвеÑÑи' 363 ); 364 365 player.classList.remove('is-playing'); 366 367 }); 368 369 370 audio.addEventListener('ended', function () { 371 372 audio.currentTime = 0; 373 374 updateTime(); 375 updateWaveform(); 376 377 }); 378 379 380 audio.addEventListener( 381 'loadedmetadata', 382 function () { 383 384 updateTime(); 385 updateWaveform(); 386 387 } 388 ); 389 390 391 audio.addEventListener( 392 'durationchange', 393 function () { 394 395 updateTime(); 396 updateWaveform(); 397 398 } 399 ); 400 401 402 audio.addEventListener( 403 'timeupdate', 404 function () { 405 406 updateTime(); 407 updateWaveform(); 408 409 } 410 ); 411 412 }); 413 414});
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.