PageSourceSearch

https://www.visa.co.jp/etc.clientlibs/cms-rest/clientlibs/modal.min.js

js visa.co.jp collected 2026-09-24 08:41:39 UTC 15,151 bytes, 409 lines download raw bytes

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.