1String.prototype.replaceAll = function (find, replace) { 2 const str = this; 3 //return str.replace(new RegExp(find, 'g'), replace); 4 return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace); 5}; 6 7let YoutubeGalleryPlayerObjects = []; 8 9function YoutubeGalleryPlayersSetAPILoaded() { 10 for (let i = 0; i < YoutubeGalleryPlayerObjects.length; i++) { 11 YoutubeGalleryPlayerObjects[i].iframeAPIloaded = true; 12 } 13} 14 15const YoutubeGalleryPlayerObject = class { 16 constructor(width_, height_, playerapiid_, initial_volume_, mute_on_play_, auto_play_, allowplaylist_) { 17 this.WebsiteRoot = ""; 18 19 this.iframeAPIloaded = false; 20 this.iframeAPIloadedCheckCount = 0; 21 this.videorecords = []; 22 this.videolistid = null; 23 this.themeid = null; 24 this.playerapiid = playerapiid_; 25 26 this.PlayList = []; 27 this.CurrentVideoID = ""; 28 this.IframeApiReady = false; 29 this.youtubeplayer_options = null;//options_; 30 this.ApiStart = null;//this.options.start; 31 this.ApiEnd = null;//this.options.end; 32 this.width = width_; 33 this.height = height_; 34 this.api_player = null; 35 this.APIPlayerBodyPartLoaded = false; 36 this.initial_volume = initial_volume_;//-1 is default 37 this.mute_on_play = mute_on_play_; 38 this.auto_play = auto_play_; 39 this.allowplaylist = allowplaylist_; 40 this.VideoSources = []; 41 this.Player = []; 42 this.openinnewwindow = 0; 43 } 44 45 youtube_SetPlayer_(videoid) { 46 this.youtubeplayer_options.start = this.ApiStart; 47 this.youtubeplayer_options.end = this.ApiEnd; 48 this.youtubeplayer_options.mute = 1;//for autoplay: https://stackoverflow.com/questions/54944500/problems-with-youtube-iframe-api-to-start-playing-video-on-chrome 49 50 this.CurrentVideoID = videoid; 51 const playerid = this.playerapiid + "api"; 52 document.getElementById(playerid).innerHTML = ''; 53 54 const initial_volume = this.initial_volume; 55 const mute_on_play = this.mute_on_play; 56 const auto_play = this.auto_play; 57 const allowplaylist = this.allowplaylist; 58 const PlayList = this.PlayList; 59 const classname = "youtubeplayer" + this.videolistid; 60 const func = classname + '.FindNextVideo();'; 61 62 this.api_player = new YT.Player(playerid, { 63 width: this.width, 64 id: playerid, 65 height: this.height, 66 host: 'https://www.youtube.com', 67 mute: 1, 68 allow: "autoplay", 69 autoplay: 0, 70 playerVars: this.youtubeplayer_options, 71 videoId: videoid, 72 origin: 'https://joomlaboat.com/', 73 74 events: { 75 "onReady": function (event) { 76 if (initial_volume !== -1) 77 event.target.setVolume(initial_volume); 78 79 if (mute_on_play) 80 event.target.mute(); 81 82 if (auto_play) 83 event.target.playVideo(); 84 85 if (!mute_on_play) { 86 setTimeout(function () { 87 event.target.unMute(); 88 89 if (auto_play) 90 event.target.playVideo(); //try to play video after unmuting 91 92 }, 500); 93 } 94 }, 95 "onStateChange": function (event) { 96 if (PlayList.length !== 0 && allowplaylist) { 97 if (event.data === YT.PlayerState.ENDED) { 98 setTimeout(eval(func), 500); 99 } 100 } 101 } 102 } 103 }); 104 // 105 } 106 107 vimeo_SetPlayer_(videoid) { 108 this.vimeoplayer_options.start = this.ApiStart; 109 this.vimeoplayer_options.end = this.ApiEnd; 110 111 this.CurrentVideoID = videoid; 112 const playerid = this.playerapiid + "api"; 113 document.getElementById(playerid).innerHTML = ''; 114 115 const classname = "youtubeplayer" + this.videolistid; 116 const func = classname + '.FindNextVideo();'; 117 const player_options = { 118 id: videoid, 119 width: this.width, 120 height: this.height, 121 autoplay: !!+this.auto_play, 122 background: !!+this.vimeoplayer_options.background, 123 loop: !!+this.vimeoplayer_options.loop, 124 muted: !!+this.mute_on_play 125 }; 126 127 this.api_player = new Vimeo.Player(playerid, player_options); 128 129 if (this.initial_volume !== -1) 130 this.api_player.setVolume(this.initial_volume / 100);//Vimeo player volume is from 0 to 1 131 132 this.api_player.on('play', function () { 133 //alert('Played the first video'); 134 }); 135 136 this.api_player.on('ended', function () { 137 138 alert("eval138"); 139 setTimeout(eval(func), 500); 140 }); 141 } 142 143 144 FindNextVideo() { 145 if (this.PlayList.length === 1 && this.PlayList[0] === '') { 146 //Video not found 147 return; 148 } 149 150 if (!this.iframeAPIloaded) { 151 //iframe API not loaded 152 this.iframeAPIloadedCheckCount++; 153 154 if (this.iframeAPIloadedCheckCount < 5) { 155 setTimeout(this.FindNextVideo(), 500); 156 } 157 return false;
158 } 159 160 if (this.PlayList.length === 0) { 161 alert("FindNextVideo:Video records not loaded yet"); 162 setTimeout(this.FindNextVideo(), 500); 163 return false; 164 } 165 166 let d = 0; 167 const v = this.CurrentVideoID; 168 const l = this.PlayList.length; 169 170 let g = null; 171 for (let i = 0; i < l; i++) { 172 g = this.PlayList[i].split("*"); 173 if (g[0] === v)//0 - id 174 { 175 //if current video is the last in the list play the first video 176 d = i + 1; 177 if (d === l) 178 d = 0; 179 180 break; 181 } 182 } 183 g = this.PlayList[d].split("*"); 184 185 const videoid = g[0]; 186 const objectid = g[1]; 187 const videosource = g[2]; 188 189 this.HotVideoSwitch(this.videolistid, videoid, videosource, objectid); 190 } 191 192 FindCurrentVideo() { 193 if (!this.iframeAPIloaded) { 194 if (this.iframeAPIloadedCheckCount < 5) 195 setTimeout(this.FindCurrentVideo(), 500); 196 197 this.iframeAPIloadedCheckCount++; 198 return false; 199 } 200 201 if (this.PlayList.length === 0) { 202 setTimeout(this.FindCurrentVideo(), 500); 203 return false; 204 } 205 206 const l = this.PlayList.length; 207 for (let i = 0; i < l; i++) { 208 const g = this.PlayList[i].split("*"); 209 if (g[0] === this.CurrentVideoID) { 210 const videoid = g[0]; 211 const objectid = g[1]; 212 const videosource = g[2]; 213 this.HotVideoSwitch(this.videolistid, videoid, videosource, objectid); 214 break; 215 } 216 } 217 } 218 219 loadVideoRecords(ygstart) { 220 const xmlHttp = new XMLHttpRequest(); 221 let url = this.WebsiteRoot + '/index.php?option=com_youtubegallery&view=youtubegallery&yg_api=1&listid=' + this.videolistid + '&themeid=' + this.themeid + '&ygstart=' + ygstart; 222 xmlHttp.open("GET", url, false); 223 xmlHttp.send(null); 224 const r = xmlHttp.responseText; 225 226 this.videorecords = JSON && JSON.parse(r) || $.parseJSON(r); 227 } 228 229 findVideoRecordByID(videoid) { 230 for (let i = 0; i < this.videorecords.length; i++) { 231 const rec = this.videorecords[i]; 232 233 if (rec.es_videoid === videoid) 234 return rec; 235 } 236 return null; 237 } 238 239 element_addClass(objname, classname) { 240 const obj = document.getElementById(objname); 241 if (obj) { 242 const classes = obj.className.split(" "); 243 let found = false; 244 for (let i = 0; i < classes.length; i++) { 245 if (classes[i] === classname) 246 found = true; 247 } 248 249 if (!found) { 250 classes.push(classname); 251 obj.className = classes.join(" "); 252 } 253 } 254 } 255 256 element_removeClass(objname, classname) { 257 const obj = document.getElementById(objname); 258 if (obj) { 259 const classes = obj.className.split(" "); 260 const new_classes = []; 261 262 for (let i = 0; i < classes.length; i++) { 263 if (classes[i] !== classname) 264 new_classes.push(classes[i]); 265 } 266 267 obj.className = new_classes.join(" "); 268 } 269 } 270 271 thumb_addClass(id, classname) { 272 const objname = "youtubegallery_thumbnail_box_" + this.videolistid + "_" + id; 273 this.element_addClass(objname, classname) 274 } 275 276 thumb_removeClass(id, classname) { 277 const objname = "youtubegallery_thumbnail_box_" + this.videolistid + "_" + id; 278 this.element_removeClass(objname, classname) 279 } 280 281 highlightCurrentThumb(id) { 282 for (let i = 0; i < this.videorecords.length; i++) { 283 const rec = this.videorecords[i]; 284 this.thumb_removeClass(rec.id, "ygThumb-active"); 285 this.thumb_addClass(rec.id, "ygThumb-inactive"); 286 } 287 288 this.thumb_removeClass(id, "ygThumb-inactive"); 289 this.thumb_addClass(id, "ygThumb-active"); 290 } 291 292 HotVideoSwitch(videolistid, videoid, videosource, id) { 293 294 let i = this.VideoSources.indexOf(videosource); 295 let playercode = ""; 296 if (i !== -1) 297 playercode = this.Player[i]; 298 299 playercode = playercode.replace("****youtubegallery-video-id****", videoid); 300 const rec = this.findVideoRecordByID(videoid); 301 302 if (rec == null) 303 return; 304 305 if (rec.es_customimageurl !== null && rec.es_customimageurl !== "" && rec.es_customimageurl.indexOf("#") === -1) { 306 const customimage = rec.es_customimageurl; 307 const n = customimage.indexOf("_small"); 308 if (n === -1) { 309 playercode = playercode.replace("****youtubegallery-video-customimage****", customimage); 310 for (i = 0; i < 2; i++) { 311 playercode = playercode.replace("***code_begin***", ""); 312 playercode = playercode.replace("***code_end***", ""); 313 } 314 } else 315 playercode = YoutubeGalleryCleanCode(playercode); 316 } else 317 playercode = YoutubeGalleryCleanCode(playercode); 318 319 playercode = playercode.replace("****youtubegallery-video-link****", rec.es_link); 320 playercode = playercode.replace("****youtubegallery-video-startsecond****", rec.es_startsecond); 321 playercode = playercode.replace("****youtubegallery-video-endsecond****", rec.es_endsecond); 322 playercode = playercode.replace("autoplay=0", "autoplay=1"); 323 playercode = playercode.replace("****scriptbegin****", "<script "); 324 playercode = playercode.replace("****scriptend****", "</script>"); 325 326 const ygsc = document.getElementById("YoutubeGallerySecondaryContainer" + this.videolistid + ""); 327 ygsc.innerHTML = playercode; 328 ygsc.style.display = "block"; 329 330 if (playercode.indexOf('data-marker="DYNAMIC PLAYER"') !== -1) { 331 this.ApiStart = rec.es_startsecond; 332 this.ApiEnd = rec.es_endsecond; 333 334 if (videosource === "youtube") { 335 this.youtube_SetPlayer_(videoid); 336 } else if (videosource === "vimeo") { 337 this.vimeo_SetPlayer_(videoid); 338 339 } else { 340 alert("eval340"); 341 eval("this.youtubegallery_updateplayer_" + videosource + "(videoid,true)"); 342 } 343 } 344 345 const title_obj_name = "YoutubeGalleryVideoTitle" + this.videolistid + ""; 346 const tObj = document.getElementById(title_obj_name); 347 const description_obj_name = "YoutubeGalleryVideoDescription" + this.videolistid + ""; 348 const dObj = document.getElementById(description_obj_name); 349 const t = this; 350 351 if (tObj) { 352 this.element_removeClass(title_obj_name, "ygTitle-visible"); 353 this.element_addClass(title_obj_name, "ygTitle-hidden"); 354 355 let title = rec.es_title; 356 if (title === null) 357 title = ""; 358 359 tObj.innerHTML = title.replaceAll('_quote_', '"'); 360 361 setTimeout(function () { 362 t.element_removeClass(title_obj_name, "ygTitle-hidden"); 363 t.element_addClass(title_obj_name, "ygTitle-visible"); 364 }, 200); 365 } 366 367 if (dObj) { 368 this.element_removeClass(description_obj_name, "ygDescription-visible"); 369 this.element_addClass(description_obj_name, "ygDescription-hidden"); 370 let desc = rec.es_description; 371 372 desc = desc.replaceAll('_thelinebreak_', '<br />'); 373 desc = desc.replaceAll('_quote_', '"'); 374 desc = desc.replaceAll('_email_', '@'); 375 376 dObj.innerHTML = desc; 377 378 setTimeout(function () { 379 t.element_removeClass(description_obj_name, "ygDescription-hidden"); 380 t.element_addClass(description_obj_name, "ygDescription-visible"); 381 }, 200); 382 } 383 384 if (this.openinnewwindow === 5) { 385 //Jump to the player anchor:"youtubegallery" 386 window.location.hash = "youtubegallery"; 387 } 388 389 this.highlightCurrentThumb(id); 390 } 391}; 392 393function YoutubeGalleryCleanCode(playercode) { 394 do { 395 const b = playercode.indexOf("***code_begin***"); 396 const e = playercode.indexOf("***code_end***"); 397 if (b !== -1 && e !== -1) 398 playercode = playercode.substr(0, b) + playercode.substr(e + 14); 399 400 if (b === -1 || e === -1) 401 break; 402 403 } while (1); 404 return playercode; 405}
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.