1// This file will be run in the footer on every page. 2// It should be used for content that relates 3// to your site as a whole, it should not be used for 4// plugin-specific js 5 6require(["jquery", "site_gtm", "sv_load!plugins_dynamic_content", "plugins_common_custom_ui_watcher", "sv_siteFoundation", "domReady!"], function($, gtm, dynamic, UIWatcher) { 7 $(document).foundation(); 8 gtm.update(); 9 10// Lazy-load FontAwesome 11(function() { 12 var css = document.createElement('link'); 13 css.href = 'https://use.fontawesome.com/releases/v5.10.2/css/all.css'; 14 css.rel = 'stylesheet'; 15 css.type = 'text/css'; 16 document.getElementsByTagName('head')[0].appendChild(css); 17})(); 18 19 // SEM tracking 20 var uiEvents = new UIWatcher({}, $, document); 21 uiEvents.on("change-page", handlePageChange); 22 uiEvents.on("view-change", handleFilterChange); 23 uiEvents.on("sort-change", handleFilterChange); 24 uiEvents.on("value-change", handleFilterChange); 25 uiEvents.on("toggle-show-more", handleShowMoreToggle); 26 uiEvents.on("scroll-into-view", handleScrollIntoView); 27 uiEvents.on("item-click", handleItemClick); 28 uiEvents.on("map-pin-click", handleMapPinClick); 29 uiEvents.on("tripbuilder", handleTripbuilder); 30 31 // tracking handlers 32 function handleTripbuilder(payload){ 33 var event = payload.eventContext, 34 widget = payload.widgetContext; 35 let ga4Data = { 36 eventName: event?.value === "Add" ? "add_to_favorites" : undefined, 37 itemType: event?.itemType ?? (widget?.name === "Coupons" ? 'offers' : !["quickview", "quick view"].includes(widget?.name.toLowerCase()) ? widget?.name.toLowerCase() : undefined), 38 itemName: event.itemName ?? event.refTitle, 39 linkObject: event?.linkObject, 40 itemCategory: event?.crmc, 41 interactionSource: event?.interactionSource, 42 interactionText: event?.interactionText, 43 interactionUrl: event?.interactionUrl, 44 itemCity: event?.itemCity, 45 itemRegion: event?.itemRegion, 46 itemId: event?.itemId, 47 acctId: event?.acctId, 48 itemVariant: event?.itemVariant, 49 price: event?.price, 50 } 51 if (event?.crmsc) 52 ga4Data.itemSubcategory = event?.crmsc; 53 if (ga4Data.eventName && ga4Data.itemType && ga4Data.itemName && ga4Data.linkObject) 54 gtm.sendEvents({ tClient_ga4: ga4Data }); 55 } 56 57 function handleScrollIntoView(payload){ 58 var event = payload.eventContext, 59 widget = payload.widgetContext; 60 } 61 62 function handleShowMoreToggle(payload){ 63 var event = payload.eventContext; 64 let ga4Data = { 65 eventName: "filter", 66 filterType: `${event?.refTitle} | ${event?.displayText}`, 67 itemType: event?.itemType, 68 interactionSource: event?.interactionSource, 69 interactionText: event?.interactionText, 70 } 71 if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType) 72 gtm.sendEvents({ tClient_ga4: ga4Data }); 73 } 74 75 function handlePageChange(payload){ 76 var event = payload.eventContext; 77 let ga4Data = { 78 eventName: "filter", 79 filterType: `${event?.refTitle} | ${event?.displayText}`, 80 itemType: event?.itemType, 81 interactionSource: event?.interactionSource, 82 interactionText: event?.interactionText, 83 } 84 if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType) 85 gtm.sendEvents({ tClient_ga4: ga4Data }); 86 } 87 88 function handleItemClick(payload){ 89 var event = payload.eventContext; 90 if (event?.name === "Quickview" || event?.name === "Quick View") { 91 var ga4Data = { 92 eventName: "filter", 93 filterType: "Open Quickview", 94 itemType: event?.itemType, 95 itemName: event?.itemName ?? event?.refTitle, 96 interactionSource: event?.interactionSource, 97 interactionText: event?.interactionText, 98 itemCategory: event?.crmc, 99 itemCity: event?.itemCity, 100 itemRegion: event?.itemRegion, 101 itemId: event?.itemId, 102 acctId: event?.acctId, 103 itemVariant: event?.itemVariant, 104 price: event?.price, 105 } 106 if (event?.crmsc) 107 ga4Data.itemSubcategory = event?.crmsc; 108 if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType) 109 gtm.sendEvents({tClient_ga4: ga4Data}); 110 } else { 111 var ga4Data = { 112 eventName: event?.eventName, 113 itemType: event?.itemType, 114 itemName: event?.itemName ?? event?.refTitle, 115 linkObject: event?.linkObject, 116 itemCategory: event?.crmc, 117 interactionSource: event?.interactionSource, 118 interactionText: event?.interactionText, 119 interactionUrl: event?.interactionUrl, 120 itemCity: event?.itemCity, 121 itemRegion: event?.itemRegion, 122 itemId: event?.itemId, 123 acctId: event?.acctId, 124 itemVariant: event?.itemVariant, 125 price: event?.price, 126 referralType: event?.referralType, 127 } 128 if (event?.crmsc) 129 ga4Data.itemSubcategory = event?.crmsc; 130 if (event?.eventName === 'partner_referral') 131 ga4Data.value = 5; 132 if (ga4Data.eventName && ga4Data.itemType && ga4Data.itemName && ga4Data.linkObject) 133 gtm.sendEvents({tClient_ga4: ga4Data}); 134 } 135 } 136 137 function handleMapPinClick(payload){ 138 var event = payload.eventContext, 139 widget = payload.widgetContext; 140 } 141 142 function handleFilterChange (payload) { 143 var event = payload.eventContext; 144 let ga4Data = { 145 eventName: "filter", 146 filterType: `${event?.refTitle} | ${event?.displayText}`, 147 itemType: event?.itemType, 148 interactionSource: event?.interactionSource, 149 interactionText: event?.interactionText, 150 } 151 if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType) 152 gtm.sendEvents({ tClient_ga4: ga4Data }); 153 } 154}); 155 156// Lazy-load js for widgets that have the [data-js] attribute on their root node 157(function() { 158 function initDataJs(searchScope, selector = '[data-js]' ){ 159 require(['plugins_common_custom_lazyload'], function(lazyload) { 160 var widgetsToLoad = []; 161 let scope = searchScope ? searchScope : document; 162 var els = scope.querySelectorAll(selector); 163 164 for (var i = 0; i < els.length; i++) { 165 widgetsToLoad.push(els[i]); 166 } 167 168 lazyload.lazy(widgetsToLoad, function(entry, io) { 169 var target = entry.target; 170 var jsFile = target.dataset.js; 171 var guid = target.dataset.guid; 172 173 require([jsFile], function(widget) { 174 widget.init(guid); 175 io.unobserve(target); 176 }); 177 }); 178 }); 179 }; 180 181 initDataJs(); 182})();
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.