PageSourceSearch

https://www.visa.com.ph/etc/ui/headless-ui/scripts/core/analytics.js

js visa.com.ph collected 2026-10-03 22:56:41 UTC 16,347 bytes, 337 lines download raw bytes

1let config = `{       
2    "clickElements":[".vs-btn",".btn-xs",".vs-link-cta",".vs-link-cta-ga4",".link-cta",".new-window-link",".modal__show",".slide-cta-button",".vs-share-anchor",".vs-nav-logo",".vs-ct-image",".vs-social-anchor",".vs-sct",".vs-d-inline",".visa-icon-close",".vs-video-play-button",".vs-share-modal-btn",".overflower-item selected",".vs-sticky-button","div.vs-chat-box-element div",".vs-circle-icon",".visa-document-button",".vs-prev",".vs-next",".vs-minimize-icon",".vs-bot-response a",".end-chat-history a"],
3    "filterElements":[".vs-filter-tracker",".vs-tab-filter-btn"],
4    "selectFilterElements":[".vs-grid-sort-select"],
5    "shadowRootRef":[],
6    "hoverElements":[],
7    "selectElements":[],
8    "eventObject":{
9        "clickText":"getClickText(this)",
10            "clickUrl":"this.attributes?.href?.value ? this.attributes?.href?.value : (this.firstChild?.attributes?.href?.value ? this.firstChild?.attributes?.href?.value : this.parentElement?.attributes?.href?.value)",
11        "eventAction":"getClickTrack(this)",
12        "componentType":{
13            "selectors":{
14                "'Header'":"$(this).closest('header')",
15                "'Footer'":"$(this).closest('footer')",
16                "'Button'":"$(this).closest('button').length > 0 ? $(this).closest('button') : $(this).closest('.vs-btn').length > 0 ? $(this).closest('.vs-btn') : $(this).closest('div[role=button]').length > 0 ? $(this).closest('div[role=button]') : $(this).closest('.vs-sticky-button').length>0 ? $(this).closest('.vs-sticky-button') : $(this).closest('.vs-video-play-button')",
17                "'Link'":"$(this).closest('.vs-link-cta').length > 0 ? $(this).closest('.vs-link-cta') : $(this).closest('.vs-link-cta-ga4').length > 0 ? $(this).closest('.vs-link-cta-ga4') : $(this).closest('.link-cta').length > 0 ? $(this).closest('.link-cta') : $(this).closest('.new-window-link')",
18                "'Offers'":"$(this).closest('vs-offers')",
19                "'Rich text'":"$(this).closest('.rich-text-content')",
20                "'Model'":"$(this).closest('.vs-modal-parent')",
21               	"'Image'":"$(this).closest('.vs-sct')",
22                "'Dropdown'":"$(this).closest('select')",
23                "'Text'":"$(this).closest('body')"
24            }
25        },
26            "siteSection":"window.location.pathname === '/' ? 'home' :'others'",
27        "imageLabel":"$(this).find('img').length > 0 ? $(this).find('img')[0].getAttribute('alt'): 'NAA'",
28        "component":{
29            "selectors":{
30                "'Hero Marquee'":"$(this).closest('.heromarquee-item')",
31                "'Fullbleed Marquee'":"$(this).closest('visa-marquee')",
32                "'Sub Marquee'":"$(this).closest('visa-submarquee')",
33                "'Fullbleed Marquee Slide'":"$(this).closest('.slide visa-marquee')",
34                "'Sub Marquee Slide'":"$(this).closest('.slide visa-submarquee')",
35                "'Marquee Legacy'":"$(this).closest('.visa-marquee')",
36                "'Marquee Slide Legacy'":"$(this).closest('.visa-marquee-slide')",
37                "'Tile Container'":"$(this).closest('tile-container')",
38                "'Filmstrip'":"$(this).closest('vs-filmstrip')",
39                "'Interrupter Container'":"$(this).closest('.ContainerInterrupter')",
40                "'Accordion Container'":"$(this).closest('.containerAccordion').length > 0 ? $(this).closest('.containerAccordion') : ($(this).closest('.containerAccordionNew').length > 0 ? $(this).closest('.containerAccordionNew') :$(this).closest('.drawercomponent'))",
41                "'Brand Blade Container'":"$(this).closest('.brand-blade-container')",
42                "'Card Stack'":"$(this).closest('.cardStack')",
43                "'Content Card'":"$(this).closest('.contentCard-Medium')",
44                "'Content Bundle'":"$(this).closest('vs-content-bundle')",
45                "'Anchor Navigation'":"$(this).closest('.navanchor .vs-anchor-base')",
46                "'Secondary Navigation'":"$(this).closest('.vs-ribbon-nav .vs-ribbon-nav-list')",
47                "'Audience Navigation'":"$(this).closest('.visa-horizontal-nav-audience')",
48                "'Grid'":"$(this).closest('vs-grid')",
49                "'Navigation'":"$(this).closest('nav')",
50                "'Quotes'":"$(this).closest('.vs-quote-section')",
51                "'Related Link'":"$(this).closest('.vs-related-links')",
52                "'Social Share'":"$(this).closest('vs-social-share-container')",
53                "'Rich Text Editor'":"$(this).closest('.rich-text-content') || $(this).closest('.vs-link-submenu')",
54                "'Offers+Perks'":"$(this).closest('vs-global-offers')",
55                "'Exchange Rate Calculator'": "$(this).closest('.vs-calculator')",
56                "'Carousel'": "$(this).closest('.vs-carousel-content')",
57                "'Button'":"$(this).closest('.buttonComp')",
58                "'Model Text'":"$(this).closest('.vs-modal-parent')",
59                "'Table'":"$(this).closest('vs-table')",
60                "'Chat Assistant'":"$(this).closest('.vs-chat-main-container')",
61                "'Feature Container'":"$(this).closest('.vs-featured-container')",
62
63                "$(this).closest('.section')?.classList? $(this).closest('.section')?.classList[0] : ''":"$(this).closest('.section')"
64            }
65        },
66        "clickCategory1":{
67            "selectors":{
68                "$($(this).closest('vs-content-bundle').find('.vs-content-bundle-header')[0]).text()":"$($(this).closest('vs-content-bundle').find('.vs-content-bundle-header')[0]).text()",
69                "$($(this).closest('vs-table').find('caption')).text()":"$($(this).closest('vs-table').find('caption')).text()",
70                "$($(this).closest('.vs-submenu')).siblings('.vs-mainmenu-item')[0]?.text" : "$($(this).closest('.vs-submenu')).siblings('.vs-mainmenu-item')[0]?.text",
71                "$(this.parentNode)?.find('.vs-lead').text().trim()":"$(this.parentNode)?.find('.vs-lead').text().trim()",
72                "$(this.parentElement?.parentNode)?.find('.vs-lead').text().trim()":"$(this.parentElement?.parentNode)?.find('.vs-lead').text().trim()",
73                "$(this.parentElement?.parentElement?.parentNode)?.find('.vs-lead').text().trim()":"$(this.parentElement?.parentElement?.parentNode)?.find('.vs-lead').text().trim()",
74                "$(this.parentElement?.parentElement?.parentNode)?.find('.vs-interrupter-title').text().trim()":"$(this.parentElement?.parentElement?.parentNode)?.find('.vs-interrupter-title').text().trim()",
75                "$(this).closest('.vs-bot-response').find('p').text().trim()":"$(this).closest('.vs-bot-response').find('p').text().trim()",
76                "getClickCategoryModel(this)":"getClickCategoryModel(this)"
77            }
78        },
79        "clickCategory2":{
80            "selectors":{
81             "$($(this).closest('vs-content-bundle').find('.vs-content-bundle-body')[0]).text()":"$($(this).closest('vs-content-bundle').find('.vs-content-bundle-body')[0]).text()",
82              "$(this.parentElement?.parentElement?.parentNode)?.find('.vs-lead-submenu').text().trim()" : "$(this.parentElement?.parentElement?.parentNode)?.find('.vs-lead-submenu').text().trim()"
83            }
84        }
85    }
86    
87}`;
88let clickElements = JSON.parse(config)?.clickElements;
89let shadowRoots = JSON.parse(config)?.shadowRootRef;
90
91// START GENAI@GHCOPILOT
92let filterElements = JSON.parse(config)?.filterElements;
93let selectFilterElements = JSON.parse(config)?.selectFilterElements;
94
95filterElements?.forEach((elem) => {
96    $(document).on('click', elem, function (event) {
97        let eventObj = JSON.parse(config)?.eventObject;
98        iterate.call(this, eventObj);
99        simplify.call(this, eventObj);
100        let filter_event = new CustomEvent('filters_tracking', {
101            detail: {
102                ...eventObj,
103                eventAction: getFilterType(this),
104                filterDetails: getFilterInfo(this),
105            },
106        });
107        document.dispatchEvent(filter_event);
108    });
109});
110
111// START GENAI@CHATGPT4
112//let eventObj = JSON.parse(config)?.eventObject;
113selectFilterElements?.forEach((elem) => {
114    $(document).on('change', elem, function (event) {
115        let eventObj = JSON.parse(config)?.eventObject;
116        iterate.call(this, eventObj);
117        simplify.call(this, eventObj);
118        let filter_event = new CustomEvent('filters_tracking', {
119            detail: {
120                ...eventObj,
121                eventAction: getFilterType(this),
122                filterDetails: getFilterInfo(this),
123            },
124        });
125        document.dispatchEvent(filter_event);
126    });
127});
128// END GENAI@CHATGPT4
129
130
131const getFilterInfo = (element) => {
132    let filterInfo = 'sortBy: text';
133    if ($(element).hasClass('vs-col-header')) {
134        filterInfo = $(element).data('sort-info');
135    } else if ($(element).hasClass('vs-grid-sort-select') || $(element).hasClass('vs-tab-filter-selected')) {
136        filterInfo = 'sortBy:' + element.value;
137    }
138    return filterInfo;
139};
140
141const getFilterType = (element) => {
142    let filterType = 'dropdown_selected';
143    if ($(element).hasClass('vs-col-header')) {
144        filterType = 'table_sorted';
145    } else if ($(element).hasClass('vs-grid-sort-select') || $(element).hasClass('vs-tab-filter-selected')) {
146        filterType = 'filter_selected';
147    }
148    return filterType;
149};
150
151// END GENAI@GHCOPILOT
152
153function getClickTrack(element) {
154    var clickType = 'NAA';
155    if ($(element).hasClass('vs-accordion-button')) {
156        let expanded = $(element).attr('aria-expanded');
157        
158        if (expanded === 'true') {
159            clickType = 'expand';
160        } else {
161            clickType = 'collapse';
162        }
163    } else if ($(element).hasClass('vs-link-open')) {
164        clickType = 'expand';
165    } else if ($(element).hasClass('vs-link-close')) {
166        clickType = 'collapse';
167    } else if (
168        $(element).hasClass('modal__show') ||
169        $(element).hasClass('vs-video-play-button') ||
170        $(element).hasClass('vs-share-modal-btn')
171    ) {
172        clickType = 'modal open';
173    } else if ($(element).hasClass('visa-icon-close')) {
174        clickType = 'modal close';
175    } else if ($(element).hasClass('vs-sticky-button')) {
176        clickType = 'start chat';
177    } else if ($(element).hasClass('line')) {
178        clickType = 'chat preconfigured options';
179    }
180    else if ($(element).hasClass('visa-document-button')) {
181        clickType = 'chat suggested help questions';
182    }
183    else if ($(element).hasClass('vs-minimize-icon') && $(element).closest('.vs-chat-box-element').length > 0) {
184        clickType = 'minimize chat';
185    }
186    else if ($(element).closest('.vs-bot-response').length > 0) {
187        clickType = 'chat link clicks';
188    }
189    else if ($(element).hasClass('vs-prev') || $(element).hasClass('vs-next')) {
190        clickType = 'carousel navigation';
191    }
192    else if (
193        $(element).hasClass('vs-btn') ||
194        $(element).hasClass('vs-link-cta') ||
195        $(element).hasClass('vs-sct') ||
196        $(element).hasClass('vs-share-anchor') ||
197        $(element).hasClass('slide-cta-button') ||
198        $(element).hasClass('btn-xs') ||
199        $(element).hasClass('link-cta') ||
200        $(element).hasClass('vs-d-inline') ||
201        $(element).hasClass('overflower-item selected') ||
202        $(element).hasClass('vs-link-cta-ga4')
203    ) {
204        clickType = 'link_click';
205    }
206
207    return clickType;
208}
209
210function getClickCategoryModel(element) {
211    var clickType = '';
212    if ($(element).hasClass('visa-icon-close')) {
213        var vsmodel = $(element)
214            .closest('.vs-modal-parent')
215            .find('div[data-gtm-component-title]');
216        var vsmodelVideo = $(element)
217            .closest('.vs-modal-container')
218            .find('.vs-modal-header');
219        if (vsmodel && vsmodel.length > 0) {
220            clickType = $(vsmodel[0]).attr('data-gtm-component-title');
221        } else if (vsmodelVideo && vsmodelVideo.length > 0) {
222            clickType = vsmodelVideo.text().trim();
223        }
224    }
225    return clickType;
226}
227
228function getClickText(elem) {
229    let clickText = '';
230
231    if (elem.nodeName === 'SELECT') {
232        clickText = elem.value;
233    } else if (elem.textContent?.length > 0) {
234        clickText = elem.textContent?.trim();
235    } else if (elem.ariaLabel?.length > 0) {
236        clickText = elem.ariaLabel?.trim();
237    } else if ($(elem).hasClass('visa-icon-thumbs-up-reverse')) {
238        clickText = 'like';
239    } else if ($(elem).hasClass('visa-icon-thumbs-down-reverse')) {
240        clickText = 'dislike';
241    }
242    
243    if (clickText.toLocaleLowerCase().startsWith("ongoing chat")) {
244        clickText = 'ongoing chat';
245    }
246    
247    return clickText;
248}
249
250clickElements.forEach((elem) => {
251    $(document).on('click', elem, function (event) {
252        // Special handling for accordion buttons - delay the analytics to allow DOM update
253        if ($(this).hasClass('vs-accordion-button')) {
254            setTimeout(() => {
255                let eventObj = JSON.parse(config)?.eventObject;
256                iterate.call(this, eventObj);
257                simplify.call(this, eventObj);
258                let click_event = new CustomEvent('click_tracking', { detail: eventObj });
259                if (eventObj.component === 'Chat Assistant' && elem != ".vs-link-cta") {
260                    click_event = new CustomEvent('chat_tracking', { detail: eventObj });
261                }
262                if(!$(event.target).hasClass("chat-end-btn")){
263                    document.dispatchEvent(click_event);
264                }
265            }, 100); // 100ms delay to allow accordion to update
266        } else {
267            // Normal processing for non-accordion elements
268            let eventObj = JSON.parse(config)?.eventObject;
269            iterate.call(this, eventObj);
270            simplify.call(this, eventObj);
271            let click_event = new CustomEvent('click_tracking', { detail: eventObj });
272            if (eventObj.component === 'Chat Assistant' && elem != ".vs-link-cta") {
273                click_event = new CustomEvent('chat_tracking', { detail: eventObj });
274            }
275            if(!$(event.target).hasClass("chat-end-btn")){
276                document.dispatchEvent(click_event);
277            }
278        }
279    });
280});
281
282shadowRoots.forEach((shadowRoot) => {
283    clickElements.forEach((elem) => {
284        $(shadowRoot)[0]
285            ?.shadowRoot.querySelectorAll(elem)
286            .forEach((item) => {
287                item.addEventListener('click', function (item) {
288                    let eventObj = JSON.parse(config)?.eventObject;
289                    iterate.call(this, eventObj);
290                    simplify.call(this, eventObj);
291                    let click_event = new CustomEvent('click_tracking', {
292                        detail: eventObj,
293                    });
294                    document.dispatchEvent(click_event);
295                });
296            });
297    });
298});
299
300document.addEventListener("chat_tracking_internal", (e) => {
301    document.dispatchEvent(new CustomEvent("chat_tracking", { detail: e.detail }));
302});
303
304iterate = function (obj) {
305    Object.keys(obj).forEach((key) => {
306        if (eval(obj[key])?.length <= 0) {
307            delete obj[key];
308        } else if (typeof obj[key] === 'object' && obj[key] !== null) {
309            iterate.call(this, obj[key]);
310        } else {
311            obj[key] = eval(obj[key]);
312        }
313    });
314};
315simplify = function (obj) {
316    Object.keys(obj).forEach((key) => {
317        if (obj[key] && obj[key]['selectors']) {
318            let firstKey = Object.keys(obj[key]['selectors'])[0];
319            let objectKeyValue = eval(firstKey);
320            if (objectKeyValue) {
321                obj[key] = objectKeyValue;
322            } else if (Object.keys(obj[key]['selectors'])[1]) {
323                let secondkey = Object.keys(obj[key]['selectors'])[1];
324                let objectSecondKeyValue = eval(secondkey);
325                if (objectSecondKeyValue) {
326                    obj[key] = objectSecondKeyValue;
327                }
328            } else {
329                obj[key] = '';
330            }
331        } else if (typeof obj[key] === 'object' && obj[key] !== null) {
332            simplify(this, obj[key]);
333        } else if (typeof obj[key] === 'undefined' || obj[key] === 'NAA') {
334            obj[key] = '';
335        }
336    });
337};

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.