1(function($, Granite) { 2 "use strict"; 3 4 const dialogContentSelector = ".cmp-teaser__editor"; 5 const actionsMultifieldSelector = ".cmp-teaser__editor-multifield_actions"; 6 const descriptionCheckboxSelector = 'coral-checkbox[name="./descriptionFromPage"]'; 7 const descriptionTextfieldSelector = '.cq-RichText-editable[name="./jcr:description"]'; 8 const titleCheckboxSelector = 'coral-checkbox[name="./titleFromPage"]'; 9 const titleTextfieldSelector = '.cq-RichText-editable[name="./jcr:title"]'; 10 const linkURLSelector = '[name="./linkURL"]'; 11 let CheckboxTextfieldTuple = window.CQ?.CoreComponents?.CheckboxTextfieldTuple?.v1; 12 let descriptionTuple, titleTuple; 13 let linkURL; 14 15 $(document).on("dialog-loaded", function(e) { 16 var $dialog = e.dialog; 17 var $dialogContent = $dialog.find(dialogContentSelector); 18 var dialogContent = $dialogContent.length > 0 ? $dialogContent[0] : undefined; 19 20 if (dialogContent) { 21 // Initialize description field 22 var $descriptionTextfield = $(descriptionTextfieldSelector); 23 if ($descriptionTextfield.length) { 24 if (!$descriptionTextfield[0].hasAttribute("aria-labelledby")) { 25 associateRichTextFieldWithLabel($descriptionTextfield[0]); 26 } 27 var rteInstance = $descriptionTextfield.data("rteinstance"); 28 if (rteInstance && rteInstance.isActive) { 29 init(e, $dialog, $dialogContent, dialogContent); 30 } else { 31 $descriptionTextfield.on("editing-start", function() { 32 init(e, $dialog, $dialogContent, dialogContent); 33 }); 34 } 35 } else { 36 init(e, $dialog, $dialogContent, dialogContent); 37 } 38 39 // Initialize title field 40 var $titleTextfield = $(titleTextfieldSelector); 41 if ($titleTextfield.length) { 42 if (!$titleTextfield[0].hasAttribute("aria-labelledby")) { 43 associateRichTextFieldWithLabel($titleTextfield[0]); 44 } 45 var rteTitleInstance = $titleTextfield.data("rteinstance"); 46 if (rteTitleInstance && rteTitleInstance.isActive) { 47 init(e, $dialog, $dialogContent, dialogContent); 48 } else { 49 $titleTextfield.on("editing-start", function() { 50 init(e, $dialog, $dialogContent, dialogContent); 51 }); 52 } 53 } 54 55 } 56 }); 57 58 function init(e, $dialog, $dialogContent, dialogContent) { 59 descriptionTuple = new CheckboxTextfieldTuple(dialogContent, descriptionCheckboxSelector, descriptionTextfieldSelector, true); 60 titleTuple = new CheckboxTextfieldTuple(dialogContent, titleCheckboxSelector, titleTextfieldSelector, true); 61 retrievePageInfo($dialogContent); 62 63 var $linkURLField = $dialogContent.find(linkURLSelector); 64 if ($linkURLField.length) { 65 linkURL = $linkURLField.adaptTo("foundation-field").getValue(); 66 $linkURLField.on("change", function() { 67 linkURL = $linkURLField.adaptTo("foundation-field").getValue(); 68 retrievePageInfo($dialogContent); 69 }); 70 } 71 72 var $actionsMultifield = $dialogContent.find(actionsMultifieldSelector); 73 $actionsMultifield.on("change", function(event) { 74 var $target = $(event.target); 75 if ($target.is("foundation-autocomplete")) { 76 updateText($target); 77 } else if ($target.is("coral-multifield")) { 78 var $first = $(event.target.items.first()); 79 if (event.target.items.length === 1 && $first.is("coral-multifield-item")) { 80 var $input = $first.find(".cmp-teaser__editor-actionField-linkUrl"); 81 if ($input.is("foundation-autocomplete")) { 82 var value = $linkURLField.adaptTo("foundation-field").getValue(); 83 if (!$input.val() && value) { 84 $input.val(value); 85 updateText($input); 86 } 87 } 88 } 89 } 90 retrievePageInfo($dialogContent); 91 }); 92 } 93 94 function retrievePageInfo(dialogContent) { 95 var url; 96 if (linkURL === undefined || linkURL === "") { 97 url = dialogContent.find('.cmp-teaser__editor-multifield_actions [data-cmp-teaser-v2-dialog-edit-hook="actionLink"]').val(); 98 } else { 99 url = linkURL; 100 } 101 if ((url === undefined || url === "") && (Granite.author && Granite.author.page)) { 102 url = Granite.author.page.path; 103 } 104 if (url && url.startsWith("/")) { 105 return $.ajax({ 106 url: url + "/_jcr_content.json" 107 }).done(function(data) { 108 if (data) { 109 descriptionTuple.seedTextValue(data["jcr:description"]); 110 titleTuple.seedTextValue(data["jcr:title"]);
111 descriptionTuple.update(); 112 titleTuple.update(); 113 } 114 }); 115 } else { 116 descriptionTuple.update(); 117 titleTuple.update(); 118 } 119 } 120 121 function updateText(target) { 122 var url = target.val(); 123 if (url && url.startsWith("/")) { 124 var textField = target.parents("coral-multifield-item").find('[data-cmp-teaser-v2-dialog-edit-hook="actionTitle"]'); 125 if (textField && !textField.val()) { 126 $.ajax({ 127 url: url + "/_jcr_content.json" 128 }).done(function(data) { 129 if (data) { 130 textField.val(data["jcr:title"]); 131 } 132 }); 133 } 134 } 135 } 136 137 function associateRichTextFieldWithLabel(textfieldElement) { 138 var richTextContainer = document.querySelector(".cq-RichText.richtext-container"); 139 if (richTextContainer) { 140 var richTextContainerParent = richTextContainer.parentNode; 141 var fieldLabel = richTextContainerParent.querySelector("label.coral-Form-fieldlabel"); 142 if (fieldLabel) { 143 textfieldElement.setAttribute("aria-labelledby", fieldLabel.id); 144 } 145 } 146 } 147})(jQuery, Granite); 148 149 150window.addEventListener("load", (event) => { 151 console.log('JavaScript loaded'); 152 153 const video = document.getElementById('myVideo'); 154 const playButton = document.getElementById('playButton'); 155 156 function hidePlayButtonIfPlaying() { 157 if (!video.paused && !video.ended) { 158 playButton.classList.add('hidden'); 159 console.log('Video started, play button hidden'); 160 } 161 } 162 163 video.addEventListener('canplay', function() { 164 console.log('Video can play'); 165 hidePlayButtonIfPlaying(); 166 }); 167 168 video.addEventListener('play', function() { 169 hidePlayButtonIfPlaying(); 170 }); 171 172 playButton.addEventListener('click', function() { 173 console.log('Play button clicked'); 174 video.play(); 175 playButton.classList.add('hidden'); 176 }); 177 178 video.addEventListener('pause', function() { 179 playButton.classList.remove('hidden'); 180 console.log('Video paused, play button shown'); 181 }); 182 183 video.addEventListener('ended', function() { 184 playButton.classList.remove('hidden'); 185 console.log('Video ended, play button shown'); 186 }); 187}); 188 189$(document).on("dialog-ready", function() { 190 191 // Get the image, video, and text (caption) fields 192 var imageField = $("[name='./posterImage']"); 193 var videoField = $("[name='./videoFile']"); 194 var captionField = $("[name='./captionFile']"); 195 var transcriptField = $("[name='./transcriptFile']"); 196 197 // Validate image formats (jpg, jpeg, png) 198 imageField.on("change", function() { 199 var imageValue = imageField.val(); 200 if (imageValue && !(/\.(jpg|jpeg|png)$/i).test(imageValue)) { 201 alert("Only JPG, JPEG, or PNG formats are allowed for images."); 202 imageField.val(""); // Clear the field 203 } 204 }); 205 206 // Validate video formats (mp4, webm, ogg) 207 videoField.on("change", function() { 208 var videoValue = videoField.val(); 209 if (videoValue && !(/\.(mp4|webm|ogg)$/i).test(videoValue)) { 210 alert("Only MP4, WebM, or OGG formats are allowed for videos."); 211 videoField.val(""); // Clear the field 212 } 213 }); 214 215 // Validate text file formats (vtt) 216 captionField.on("change", function() { 217 var captionValue = captionField.val(); 218 if (captionValue && !(/\.(vtt)$/i).test(captionValue)) { 219 alert("Only VTT format is allowed for captions."); 220 captionField.val(""); // Clear the field 221 } 222 }); 223 224 transcriptField.on("change", function () { 225 var transcriptValue = transcriptField.val(); 226 if (transcriptValue && !(/\.(vtt)$/i).test(transcriptValue)) { 227 alert("Only VTT format is allowed for transcript file."); 228 transcriptField.val(""); // Clear the field 229 } 230 }); 231}); 232// Video onclick Modal Play 233$(document).ready(function() { 234 let isFullscreen = false;
235 // modal video 236 $('.modal-video #playButton').click(function() { 237 if (!isFullscreen) { 238 $('.modal-video').addClass('fullscreen-video'); 239 let video = $('#myVideo')[0]; 240 video.muted = true; 241 video.currentTime = 0; 242 video.play(); 243 $('.close-fullscreen-video').fadeIn(); 244 isFullscreen = true; 245 } 246 }); 247 248 //Close Modal video 249 $('.close-fullscreen-video').click(function() { 250 $('.modal-video').removeClass('fullscreen-video'); 251 $('#myVideo')[0].pause(); 252 $('.close-fullscreen-video').fadeOut(); 253 isFullscreen = false; 254 }); 255}); 256// Video onclick Modal Play End 257// Video Transcript start. 258$(document).ready(function () { 259 // Get the transcript URL 260 const transcriptTrack = $('#transcriptTrack').attr('src'); 261 // Stop fetch(undefined) 262 if (!transcriptTrack || transcriptTrack === 'undefined') { 263 return; 264 } 265 266 fetch(transcriptTrack) 267 .then(response => { 268 if (!response.ok) { 269 throw new Error( 270 `Failed to load VTT file: ${response.status} ${response.statusText}` 271 ); 272 } 273 274 return response.text(); 275 }) 276 .then(parseVTT) 277 .then(transcript => { 278 279 const $content = $('#transcript-content'); 280 281 transcript.forEach(item => { 282 $content.append( 283 $('<p>') 284 .attr('data-time', item.start) 285 .text(item.text) 286 ); 287 }); 288 289 $('#myVideo').on('timeupdate', function () { 290 highlightTranscript(this.currentTime); 291 }); 292 293 function highlightTranscript(currentTime) { 294 295 transcript.forEach(function (item, index) { 296 297 const nextItemTime = 298 transcript[index + 1] 299 ? transcript[index + 1].start 300 : Number.MAX_SAFE_INTEGER; 301 302 if ( 303 currentTime >= item.start && 304 currentTime < nextItemTime 305 ) { 306 307 const $line = $content 308 .find('p[data-time="' + item.start + '"]'); 309 310 $content.find('p').removeClass('highlight'); 311 $line.addClass('highlight'); 312 313 const $window = $('#transcript-window'); 314 315 if ($line.length) { 316 $window.scrollTop( 317 $line.position().top + 318 $window.scrollTop() - 319 50 320 ); 321 } 322 } 323 }); 324 } 325 326 $content.on('click', 'p', function () { 327 const clickedTime = Number($(this).attr('data-time')); 328 $('#myVideo')[0].currentTime = clickedTime; 329 }); 330 }) 331 .catch(error => { 332 console.error('Transcript error:', error); 333 }); 334 335 336 // Parse VTT 337 function parseVTT(vttContent) { 338 339 const lines = vttContent.split(/\r?\n/); 340 const transcript = []; 341 342 let currentCue = null; 343 344 lines.forEach(function (line) { 345 346 line = line.trim(); 347 348 if (line === 'WEBVTT') { 349 return; 350 } 351 352 if (line.includes('-->')) { 353 354 const times = line.split('-->'); 355 356 currentCue = { 357 start: parseTime(times[0].trim()), 358 end: parseTime(times[1].trim()), 359 text: '' 360 }; 361 362 return; 363 } 364 365 if (line === '') { 366 367 if (currentCue && currentCue.text.trim()) { 368 transcript.push(currentCue); 369 } 370 371 currentCue = null; 372 return; 373 } 374 375 if (currentCue) { 376 currentCue.text += 377 (currentCue.text ? ' ' : '') + line; 378 } 379 }); 380 381 // Add last cue 382 if (currentCue && currentCue.text.trim()) { 383 transcript.push(currentCue); 384 } 385 386 return transcript; 387 } 388 389 390 function parseTime(timeString) { 391
392 const parts = timeString.split(':'); 393 394 if (parts.length === 3) { 395 return ( 396 parseFloat(parts[0]) * 3600 + 397 parseFloat(parts[1]) * 60 + 398 parseFloat(parts[2]) 399 ); 400 } 401 402 if (parts.length === 2) { 403 return ( 404 parseFloat(parts[0]) * 60 + 405 parseFloat(parts[1]) 406 ); 407 } 408 409 return parseFloat(timeString); 410 } 411 412 // Toggle transcript 413 $('#toggleTranscriptBtn').on('click', function () { 414 415 const $window = $('#transcript-window'); 416 417 if ($window.is(':visible')) { 418 $window.hide(); 419 $(this).text('Show Transcript'); 420 } else { 421 $window.show(); 422 $(this).text('Hide Transcript'); 423 } 424 }); 425 426}); 427(function (document, $) { 428 "use strict"; 429 430 const TOGGLE_ATTRIBUTE_PREFIX = "data-toggle-"; 431 const MASTER_ATTRIBUTE_SUFFIX = "_master"; 432 const SLAVE_ATTRIBUTE_SUFFIX = "_slave"; 433 const DIALOG_CONTENT_SELECTOR = ".cq-dialog-content"; 434 435 function getAttributes(toggleName) { 436 return { 437 master: TOGGLE_ATTRIBUTE_PREFIX + toggleName + MASTER_ATTRIBUTE_SUFFIX, 438 slave: TOGGLE_ATTRIBUTE_PREFIX + toggleName + SLAVE_ATTRIBUTE_SUFFIX 439 }; 440 } 441 function getSelectors(toggleName) { 442 let attributes = getAttributes(toggleName); 443 return { 444 master: "[" + attributes.master + "]", 445 slave: "[" + attributes.slave + "]" 446 }; 447 } 448 let toggle = { 449 name: "checkbox", 450 updateFunction: function (master, $slaves) { 451 let isChecked = master[0].checked; 452 $slaves.each(function () { 453 let $slave = $(this); 454 455 $slave.prop("disabled", isChecked.toString() === $slave.attr(getAttributes("checkbox").slave)); 456 457 if (isChecked) { 458 $slave.prop("checked", false); 459 } 460 }); 461 } 462 }; 463 464 let selectors = getSelectors(toggle.name); 465 466 $(document).on("foundation-contentloaded", function (e) { 467 468 let $dialog = $(e.target); 469 if ($dialog && $dialog.length === 1) { 470 471 let $master = $dialog.find(selectors.master); 472 if ($master) { 473 if ($master.length !== 1) { 474 console.error($master.length + " masters for toggle <" + toggle.name + ">"); 475 return; 476 } 477 478 let $slaves = $dialog.find(selectors.slave); 479 toggle.updateFunction($master, $slaves); 480 } 481 } 482 }); 483 484 $(document).on("change", function (e) { 485 486 let $master = $(e.target); 487 let $dialog = $master.parents(DIALOG_CONTENT_SELECTOR); 488 if ($master && $master.length === 1 && $master.is(selectors.master)) { 489 490 let $slaves = $dialog.find(selectors.slave); 491 toggle.updateFunction($master, $slaves); 492 } 493 }); 494 495})(document, Granite.$);
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.