1var showModalBody = false; 2 3$(document).ready(function () { 4 5 $(document).on('click', '.modal__show', function (e) { 6 var videoModal = $(this).data("modaltype") === 'video' ? true : false; 7 if (!videoModal) { 8 e.preventDefault(); 9 var url = $(this).attr('href') ? encodeURI($(this).attr('href')) : encodeURI($(this).closest('a').attr('href')); 10 showHideModal(url); 11 } 12 }); 13 14 // START GENAI@CHATGPT4 15 // Handle modal close using the specific button ID 16 $(document).on('click', '#modal_close_btn', function() { 17 // Remove the ID 18 $('[id="modal-title"]').removeAttr('id'); 19 }); 20 21 // Handle ESC key press to remove modal-title ID 22 $(document).on('keydown', function(e) { 23 if (e.key === 'Escape' || e.key === 'Esc') { 24 // Remove the ID 25 $('[id="modal-title"]').removeAttr('id'); 26 } 27 }); 28 // END GENAI@CHATGPT4 29 30 function showHideModal(url) { 31 $(".modal--body").load(url, hideElements); 32 } 33 34 function hideElements() { 35 $(this).find('script[src*="promotion-offer"]').remove(); 36 $(this).find(".main_nav_component").addClass("vs-d-none"); 37 $(this).find("#vs-navigation-header").addClass("vs-d-none"); 38 // START GENAI@GHCOPILOT 39 $(this).find("#vs-navigation-footer").remove(); 40 // END GENAI@GHCOPILOT 41 $(this).find(".globalAlert").addClass("vs-d-none"); 42 $(this).find(".footer").addClass("vs-d-none"); 43 44 // START GENAI@CHATGPT4 45 var modalTitle = $(this).find('h1').first(); 46 if (modalTitle.length) { 47 // Add id="modal-title" to the first heading 48 modalTitle.attr('id', 'modal-title'); 49 50 // Continue with existing heading level adjustments 51 for (let headingLevel = 6; headingLevel >= 1; headingLevel--) { 52 let headings = $('.modal--body h' + headingLevel); 53 if (headings.length) { 54 headings.each(function () { 55 // START GENAI@CHATGPT4 56 let classes = $(this).attr('class') || ''; // Get the classes or set an empty string if none exist 57 classes = classes.replace('vs-h' + headingLevel, ''); 58 // END GENAI@CHATGPT4 59 // START GENAI@CHATGPT4 60 let sanitizedTitle = sanitize_html($(this).html(), DefaultWhitelist, null); 61 $(this).replaceWith('<h' + (headingLevel + 1) + ' class="' + classes + ' vs-h' + (headingLevel + 1) + '"' + 62 ($(this).is(modalTitle) ? ' id="modal-title"' : '') + 63 '>' + sanitizedTitle + '</h' + (headingLevel + 1) + '>'); 64 // END GENAI@CHATGPT4 65 }); 66 } 67 } 68 } 69 // END GENAI@CHATGPT4 70 71 showModalBody = true; 72 closeButton = $(this).parent().next(); 73 firstFocusableElement =$(this).find('button, a, input:visible:not([type=hidden]), select').first(); 74 $(this).find('button, a, input:visible:not([type=hidden]), select').first().focus(); 75 76 // START GENAI@CHATGPT4 77 document.addEventListener('keyup', function (e) { 78 if (e.key !== 'Tab') return; 79 80 var activeElement = document.activeElement; 81 var isInsideModal = activeElement.closest('.vs-generic-modal'); 82 83 if ((e.shiftKey && !isInsideModal) || (!e.shiftKey && activeElement.classList.contains('vs-generic-modal'))) { 84 e.preventDefault(); 85 if(firstFocusableElement.length > 0){ 86 firstFocusableElement.focus(); 87 }else{ 88 closeButton.focus(); 89 } 90 } 91 }); 92 // END GENAI@CHATGPT4 93 } 94 95}); 96 97/* 98 99Copyright (C) 2015, Visa 100Description - youTube returns only 1 callback when the iframe api is returned and does 101 not play well with the widget facory. jQuery widget factory applies the functionality to
102 each of the class it was applied to, overwiting the youTube api. Therefor custom js 103 is needed to listen for the single youTube api event callback, then pass it all of the 104 of the video players. 105@author - Razorfish Dev Team 106@version - 1.0 107 108*/ 109var VisaApp = VisaApp || {}; 110var pauseFlag = false; 111var player, timer; 112var modalClosed = false; 113 114 115// Kick it off 116$(document).ready(function () { 117 $(document).on('click', '.modal__show', function () { 118 setTimeout(function () { 119 if ($('.vs-video-player').length > 0) { 120 if (typeof (YT) == 'undefined' || typeof (YT.Player) == 'undefined' || typeof (VisaApp.VideoPlayer) == 'undefined') { 121 loadPlayer(); 122 } 123 VisaApp.VideoPlayer.init(0); 124 const closeButtonSelector = document.getElementById('modal_close_btn') 125 closeButtonSelector.focus({preventScroll:true}); 126 127 } 128 }, 2000); 129 }); 130 $(document).on('click', 'button.visa-icon-close', function () { 131 if ($('.vs-video-player').length > 0) { 132 stopVideo(); 133 } 134 135 }); 136 137 $(document).keydown(function (e) { 138 if (e.key === "Escape") { 139 if ($('.vs-video-player').length > 0) { 140 stopVideo(); 141 } 142 } 143 }); 144 145 function stopVideo() { 146 if (VisaApp.VideoPlayer._player[VisaApp.VideoPlayer.playerIndex]) { 147 VisaApp.VideoPlayer._player[VisaApp.VideoPlayer.playerIndex].destroy(); 148 VisaApp.VideoPlayer._player[VisaApp.VideoPlayer.playerIndex] = null; 149 } 150 } 151 152 function playStateChange(event) { 153 curID = event.target.getVideoData().video_id; 154 if(event.target.getVideoData()) 155 { 156 curTitle = event.target.getVideoData().title; 157 } 158 159 //Code for DataLayer implementation for Youtube Video 160 if (event.data === 1) { // Started playing 161 var timerDict = {} 162 timer = setInterval(showPercentage, 500); 163 } else { 164 clearInterval(timer); 165 } 166 167 function showPercentage() { 168 169 var percent = 0; 170 percent = event.target.getCurrentTime(); 171 var duration = event.target.getDuration(); 172 percent = Math.round(percent / duration * 100); 173 174 switch (percent) { 175 case 10: 176 showPer(10); 177 break; 178 case 20: 179 showPer(20); 180 break; 181 case 30: 182 showPer(30); 183 break; 184 case 40: 185 showPer(40); 186 break; 187 case 50: 188 showPer(50); 189 break; 190 case 60: 191 showPer(60); 192 break; 193 case 70: 194 showPer(70); 195 break; 196 case 80: 197 showPer(80); 198 break; 199 case 90: 200 showPer(90); 201 202 } 203 function showPer(timer) { 204 if (timerDict[timer] != 1) { 205 timerDict[timer] = 1; 206 window.dataLayer.push({ event: 'youtube-event', videoAction: 'progress' + timer + '%', videoId: curID, videoTitle: curTitle }); 207 var video_progress_event = new CustomEvent("track_video_progress", { 208 detail: { 209 'event': 'video-event', 210 'videoAction': 'progress' + timer + '%', 211 'videoId': curID, 212 'videoTitle': curTitle 213 214 } 215 }); 216 document.dispatchEvent(video_progress_event); 217 218 } 219 } 220 } 221 //Code for DataLayer implementation for Youtube Video - Play , Pause and End 222 switch(event.data) { 223 case 0: { 224 window.dataLayer.push({ event: 'youtube-event', videoAction: 'end', videoId: curID, videoTitle: curTitle }); 225 var video_finish_event = new CustomEvent("track_video_finish",{ 226 detail: { 227 'event': 'video-event', 228 'videoAction': 'finish', 229 'videoId': curID, 230 'videoTitle': curTitle 231 232 } 233 }); 234 document.dispatchEvent(video_finish_event); 235 break; 236 } 237 case 1: 238 window.dataLayer.push({ event: 'youtube-event', videoAction: 'play', videoId: curID, videoTitle: curTitle }); 239 var video_play_event = new CustomEvent("track_video_play",{ 240 detail: { 241 'event': 'video-event', 242 'videoAction': 'play', 243 'videoId': curID, 244 'videoTitle': curTitle 245 246 } 247 }); 248 document.dispatchEvent(video_play_event); 249 break; 250 case 2: 251 window.dataLayer.push({ event: 'youtube-event', videoAction: 'pause', videoId: curID, videoTitle: curTitle }); 252 var video_pause_event = new CustomEvent("track_video_pause",{ 253 detail: { 254 'event': 'video-event', 255 'videoAction': 'pause', 256 'videoId': curID, 257 'videoTitle': curTitle 258 259 } 260 }); 261 document.dispatchEvent(video_pause_event); 262 263 } 264 265 if(event.data === 1) { 266 $(".modal").focus(); 267 var playerContainer = $(event.target.i.closest(".content-video-player")); 268 playerContainer.find('.cover').fadeOut(); 269 playerContainer.find('.topics').fadeOut(); 270 } 271 if(event.data === 0) { 272 //this.showTopics(); 273 } 274 if(event.data === 2) { 275 $(".modal").focus(); 276 } 277 } 278 279 function loadPlayer() { 280 281 VisaApp.VideoPlayer = { 282 283 options: { 284 autoplay: 1 285 }, 286 287 //_cover: null, 288 _video: null, 289 element: null, 290 playerIndex: null, 291 _player: {}, 292 currentPlayer: null, 293 294 init: function (playerIndex) { 295 if (!modalClosed) { 296 if (!this._player[playerIndex]) { 297 var tag = document.createElement('script'); 298 var firstScriptTag = document.getElementsByTagName('script')[0]; 299 this.element = $('.vs-player-container.youTube'); 300 this.element.addClass('vs-video-player'); 301 this._video = this.element.data("video"); 302 tag.src = "https://www.youtube.com/iframe_api"; 303 tag.classList.add('youtube-api'); 304 if ($('script.youtube-api').length === 0) { 305 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 306 } 307 } 308 this.playerIndex = playerIndex; 309 if (typeof (YT) == 'undefined' || typeof (YT.Player) == 'undefined') { 310 window.onYouTubeIframeAPIReady = this._onYouTubeIframeAPIReady.bind(this); 311 this.additionalEvents.bind(this); 312 if (typeof this.additionalEvents() !== 'undefined') { 313 this.additionalEvents(); 314 } 315 } else { 316 this._onYouTubeIframeAPIReady.bind(this); 317 if (typeof this._onYouTubeIframeAPIReady() !== 'undefined') { 318 this._onYouTubeIframeAPIReady(); 319 } 320 } 321 } 322 323 }, 324 325 additionalEvents: function () { 326 var gScope = this; 327 $('.vs-player-container.youTube').each(function (i) { 328 // For each player, assign click functions 329 var _this = $(this); 330 _this.find('iframe.vs-embed-responsive-item').hide(); 331 _this.find('iframe.vs-embed-responsive-item').show(); 332 gScope._playClickHandler(gScope._player[i]); 333 334 }); 335 }, 336 337 _onYouTubeIframeAPIReady: function () { 338 var gScope = this; 339 if (!this._player[gScope.playerIndex]) { 340 var data = {}; 341 var playerContainer = $($('.vs-player-container.youTube')[this.playerIndex]); 342 videoId = playerContainer.data("video"); 343 data.element = playerContainer.find("#player-" + videoId)[0]; 344 data.id = 'player-' + videoId; 345 data.videoId = videoId; 346 347 var player = this._createPlayer(data); 348 this._player[gScope.playerIndex] = player; 349 } else { 350 this._replayClickHandler(this._player[gScope.playerIndex]); 351 } 352 }, 353 354 // Create each player and return it 355 _createPlayer: function (playerInfo) { 356 player = new YT.Player(playerInfo.element, { 357 videoId: playerInfo.videoId, 358 events: { 359 'onReady': this.playerReady, 360 'onStateChange': this._onPlayerStateChange.bind(this) 361 }, 362 playerVars: { 363 'autohide': 1, 364 'autoplay': 1, 365 'color': 'black', 366 'modestbranding': 1, 367 'origin': 'visa.com', 368 'rel': 0, 369 'showinfo': 0, 370 'start': 0, 371 'theme': 'light', 372 'wmode': 'opaque' 373 } 374 }); 375 this.element.find('iframe').removeAttr('frameborder'); 376 this.element.find('iframe').addClass('vs-embed-responsive-item'); 377 return player; 378 379 }, 380 _onPlayerStateChange: playStateChange, 381 382 _playClickHandler: function (player) { 383 if (player) { 384 this.playVideo(player); 385 } else { 386 return null; 387 } 388 }, 389 390 _replayClickHandler: function (player) { 391 this.playVideo(player); 392 }, 393 394 playerReady: function (event) { 395 event.target.playVideo(); 396 }, 397 398 playVideo: function (player) { 399 this.element.find('iframe')?.access(); 400 return this; 401 } 402 } 403 404 } 405 406 407 408}); 409
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.