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", "plugins_common_custom_ui_watcher", "sv_load!plugins_dynamic_content", "domReady!"], function($, gtm, UIWatcher, dynamic) { 7 gtm.update(); 8 9 // SEM tracking 10 var uiEvents = new UIWatcher({}, $, document); 11 uiEvents.on("change-page", handlePageChange); 12 uiEvents.on("view-change", handleFilterChange); 13 uiEvents.on("sort-change", handleFilterChange); 14 uiEvents.on("value-change", handleFilterChange); 15 uiEvents.on("toggle-show-more", handleShowMoreToggle); 16 uiEvents.on("scroll-into-view", handleScrollIntoView); 17 uiEvents.on("item-click", handleItemClick); 18 uiEvents.on("map-pin-click", handleMapPinClick); 19 uiEvents.on("tripbuilder", handleTripbuilder); 20 uiEvents.on("quick-view", handleQuickview); 21 22 // tracking handlers 23 function handleTripbuilder(payload){ 24 var event = payload.eventContext, 25 widget = payload.widgetContext; 26 var data = { 27 eventCategory: widget.name, 28 eventAction: event.name +" - "+ event.value, 29 eventLabel: event.refTitle, 30 ot: event.type, 31 ltxt: event.displayText, 32 nonInteraction: false 33 } 34 if (data.eventCategory && data.eventAction && data.eventLabel) 35 gtm.sendEvents({tClient: data}); 36 } 37 38 function handleQuickview(payload){ 39 var event = payload.eventContext, 40 widget = payload.widgetContext; 41 var eventCatName = widget.name; 42 switch(event.detailType) { 43 case "listings": 44 eventCatName = "Listings"; 45 break; 46 case "events": 47 eventCatName = "Events"; 48 break; 49 case "offers": 50 eventCatName = "Coupons"; 51 break; 52 default: 53 eventCatName = widget.name; 54 } 55 var data = { 56 eventCategory: eventCatName, 57 eventAction: event.linkTo, 58 eventLabel: event.refTitle, 59 ot: event.type, 60 ltxt: event.displayText, 61 nonInteraction: false 62 } 63 if (data.eventCategory && data.eventAction && data.eventLabel) 64 gtm.sendEvents({tClient: data}); 65 } 66 67 function handleScrollIntoView(payload){ 68 var event = payload.eventContext, 69 widget = payload.widgetContext; 70 var data = { 71 eventCategory: widget.name, 72 eventAction: event.name, 73 eventLabel: "Widget - "+widget.name, 74 nonInteraction: true 75 } 76 if (data.eventCategory && data.eventAction && data.eventLabel) 77 gtm.sendEvents({tClient: data}); 78 } 79 80 function handleShowMoreToggle(payload){ 81 var event = payload.eventContext, 82 widget = payload.widgetContext; 83 var data = { 84 eventCategory: widget.name, 85 eventAction: event.name, 86 eventLabel: event.displayText+" | "+event.refTitle, 87 nonInteraction: false 88 } 89 let ga4Data = { 90 eventName: "filter", 91 filterType: `${event.refTitle} | ${event.displayText}`, 92 itemType: event.itemType 93 } 94 if (data.eventCategory && data.eventAction && data.eventLabel) 95 gtm.sendEvents({tClient: data}); 96 if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType) 97 gtm.sendEvents({ tClient_ga4: ga4Data }); 98 } 99 100 function handlePageChange(payload){ 101 var event = payload.eventContext, 102 widget = payload.widgetContext; 103 var data = { 104 eventCategory: widget.name, 105 eventAction: event.name, 106 eventLabel: event.refTitle+" | "+event.displayText, 107 nonInteraction: false 108 } 109 let ga4Data = { 110 eventName: "filter", 111 filterType: `${event.refTitle} | ${event.displayText}`, 112 itemType: event.itemType 113 } 114 if (data.eventCategory && data.eventAction && data.eventLabel) 115 gtm.sendEvents({tClient: data}); 116 if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType) 117 gtm.sendEvents({ tClient_ga4: ga4Data }); 118 } 119 120 function handleItemClick(payload){ 121 var event = payload.eventContext, 122 widget = payload.widgetContext; 123 var data = { 124 eventCategory: widget.name, 125 eventAction: event.linkTo, 126 eventLabel: event.refTitle, 127 ot: event.type, 128 ltxt: event.displayText, 129 nonInteraction: false 130 } 131 /* alter action for once there */ 132 if (event.recId !== undefined && event.recId.toString().indexOf("ot") > -1) { 133 data.eventAction = "OnceThere"; 134 } 135 if (data.eventCategory && data.eventAction && data.eventLabel) 136 gtm.sendEvents({tClient: data}); 137 138 let crmCatSubcat = event?.crmc; 139 if (event?.v_crmc) { 140 crmCatSubcat = event.v_crmc; 141 } else if (crmCatSubcat && event.crmsc) { 142 crmCatSubcat += " | " + event.crmsc; 143 } 144 if (event?.name === "Quick View") { 145 var ga4Data = { 146 eventName: "filter", 147 filterType: "Open Quick View", 148 itemType: event.itemType, 149 itemName: event.itemName ?? event.refTitle, 150 } 151 if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType) 152 gtm.sendEvents({ tClient_ga4: ga4Data }); 153 } else { 154 var ga4Data = { 155 eventName: event.eventName, 156 itemType: event.itemType, 157 itemName: event.itemName ?? event.refTitle, 158 linkObject: event.linkObject, 159 crmCatSubcat: crmCatSubcat 160 } 161 if (ga4Data.eventName && ga4Data.itemType && ga4Data.itemName && ga4Data.linkObject) 162 gtm.sendEvents({ tClient_ga4: ga4Data }); 163 } 164 } 165 166 function handleMapPinClick(payload){ 167 var event = payload.eventContext, 168 widget = payload.widgetContext; 169 var data = { 170 eventCategory: widget.name, 171 eventAction: event.name, 172 eventLabel: event.refTitle, 173 ot: event.type, 174 nonInteraction: false 175 } 176 if (data.eventCategory && data.eventAction && data.eventLabel) 177 gtm.sendEvents({tClient: data}); 178 } 179
180 function handleFilterChange (payload) { 181 var event = payload.eventContext, 182 widget = payload.widgetContext; 183 var data = { 184 eventCategory: widget.name, 185 eventAction: "Filter Change", 186 eventLabel: event.refTitle+" | "+event.displayText, 187 nonInteraction: false 188 } 189 let ga4Data = { 190 eventName: "filter", 191 filterType: `${event.refTitle} | ${event.displayText}`, 192 itemType: event.itemType 193 } 194 if (data.eventCategory && data.eventAction && data.eventLabel) 195 gtm.sendEvents({tClient: data}); 196 if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType) 197 gtm.sendEvents({ tClient_ga4: ga4Data }); 198 } 199 // end SEM tracking 200 201 202 // accessiBe script 203 (function(document, tag) { 204 var script = document.createElement(tag); 205 var element = document.getElementsByTagName('body')[0]; 206 script.src = 'https://acsbap.com/api/app/assets/js/acsb.js'; 207 script.async = true; 208 script.defer = true; 209 (typeof element === 'undefined' ? document.getElementsByTagName('html')[0] : element).appendChild(script); 210 script.onload = function() { 211 acsbJS.init({ 212 statementLink: '', 213 feedbackLink: '', 214 footerHtml: '', 215 hideMobile: false, 216 hideTrigger: false, 217 language: 'en', 218 position: 'right', 219 leadColor: '#146FF8', 220 triggerColor: '#146FF8', 221 triggerRadius: '50%', 222 triggerPositionX: 'right', 223 triggerPositionY: 'bottom', 224 triggerIcon: 'default', 225 triggerSize: 'medium', 226 triggerOffsetX: 20, 227 triggerOffsetY: 20, 228 mobile: { 229 triggerSize: 'small', 230 triggerPositionX: 'right', 231 triggerPositionY: 'bottom', 232 triggerOffsetX: 0, 233 triggerOffsetY: 0, 234 triggerRadius: '0' 235 } 236 }); 237 }; 238 }(document, 'script')); 239}); 240 241// Lazy-load js for widgets that have the [data-js] attribute on their root node 242(function() { 243 function initDataJs(searchScope, selector = '[data-js]' ){ 244 require(['plugins_common_custom_lazyload'], function(lazyload) { 245 var widgetsToLoad = []; 246 let scope = searchScope ? searchScope : document; 247 var els = scope.querySelectorAll(selector); 248 249 for (var i = 0; i < els.length; i++) { 250 widgetsToLoad.push(els[i]); 251 } 252 253 lazyload.lazy(widgetsToLoad, function(entry, io) { 254 var target = entry.target; 255 var jsFile = target.dataset.js; 256 var guid = target.dataset.guid; 257 258 require([jsFile], function(widget) { 259 widget.init(guid); 260 io.unobserve(target); 261 }); 262 }); 263 }); 264 }; 265 266 initDataJs(); 267 268 let eventToSelectorMap = { 269 // each event needs a slightly different selector 270 "dynamicContentLoaded": "[data-dynamic-chosen] > .contentRender > [data-js]", 271 "abContentLoaded": "[data-ab-chosen] > .contentRender > [data-js]" 272 } 273 274 Object.entries(eventToSelectorMap).forEach( event => { 275 const [eventName, selector] = event; 276 window.addEventListener(eventName, e => { 277 const collections = document.querySelector(`[data-guid="${e}"]`); 278 initDataJs(collections, selector); 279 }); 280 }); 281})(); 282 283// Remove critical styles from head after all CSS files have loaded 284// This prevents a situation where the critical styles cause an override of the CSS in files 285const criticalStyles = document.querySelector('[data-critical-styles]'); 286if (criticalStyles) { 287 window.addEventListener('load', e =>
287 criticalStyles.remove()); 288}
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.