PageSourceSearch

https://www.visitlenawee.com/includes/public/managed/v_a2e6ae52_3a…/common/virtuals/js/shared_footer.js

js visitlenawee.com collected 2026-10-04 16:28:03 UTC 9,375 bytes, 270 lines download raw bytes

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("qv-tripbuilder", handleTripbuilder);
21	uiEvents.on("quick-view", handleQuickview);
22
23	// tracking handlers
24	function handleTripbuilder(payload){
25		var event = payload.eventContext,
26		widget = payload.widgetContext;
27		let ga4Data = {
28			eventName: event?.value === "Add" ? "add_to_favorites" : undefined,
29			itemType: event?.itemType ?? (widget?.name === "Coupons" ? 'offers' : !["quickview", "quick view"].includes(widget?.name.toLowerCase()) ? widget?.name.toLowerCase() : undefined),
30			itemName: event.itemName ?? event.refTitle,
31			linkObject: event?.linkObject,
32			itemCategory: event?.crmc,
33			interactionSource: event?.interactionSource,
34			interactionText: event?.interactionText,
35			interactionUrl: event?.interactionUrl,
36			itemCity: event?.itemCity,
37			itemRegion: event?.itemRegion,
38			itemId: event?.itemId,
39			acctId: event?.acctId,
40			itemVariant: event?.itemVariant,
41			price: event?.price,
42			viatorEvent: event?.viatorEvent,
43			propertyId: event?.propertyId,
44			propertyType: event?.propertyType,
45			propertyName: event?.propertyName,
46			isFeatured: event?.isFeatured,
47		}
48		if (event?.crmsc) 
49			ga4Data.itemSubcategory = event?.crmsc;
50		if (ga4Data.eventName && ga4Data.itemType && ga4Data.itemName && ga4Data.linkObject)
51			gtm.sendEvents({ tClient_ga4: ga4Data });
52	}
53	
54	function handleQuickview(payload){
55		var event = payload.eventContext;
56		let ga4Data = {
57			eventName: event?.eventName,
58			itemType: event?.itemType,
59			itemName: event?.itemName ?? event?.refTitle,
60			linkObject: event?.linkObject,
61			itemCategory: event?.crmc,
62			interactionSource: event?.interactionSource,
63			interactionText: event?.interactionText,
64			interactionUrl: event?.interactionUrl,
65			itemCity: event?.itemCity,
66			itemRegion: event?.itemRegion,
67			itemId: event?.itemId,
68			acctId: event?.acctId,
69			itemVariant: event?.itemVariant,
70			price: event?.price,
71			referralType: event?.referralType,
72			viatorEvent: event?.viatorEvent,
73			propertyId: event?.propertyId,
74			propertyType: event?.propertyType,
75			propertyName: event?.propertyName,
76			isFeatured: event?.isFeatured,
77		}
78		if (event?.crmsc) 
79			ga4Data.itemSubcategory = event?.crmsc;
80		if (event?.eventName === 'partner_referral')
81			ga4Data.value = 5;
82		if (ga4Data.eventName && ga4Data.itemType && ga4Data.itemName && ga4Data.linkObject)
83			gtm.sendEvents({ tClient_ga4: ga4Data });
84	}
85
86	function handleScrollIntoView(payload){
87		var event = payload.eventContext,
88			widget = payload.widgetContext;
89		var data = {
90			eventCategory: widget.name,
91			eventAction: event.name,
92			eventLabel: "Widget - "+widget.name,
93			nonInteraction: true
94		}
95		if (data.eventCategory && data.eventAction && data.eventLabel)
96			gtm.sendEvents({tClient: data});
97	}
98
99	function handleShowMoreToggle(payload){
100		var event = payload.eventContext;
101		let ga4Data = {
102			eventName: "filter",
103			filterType: `${event?.refTitle} | ${event?.displayText}`,
104			itemType: event?.itemType,
105			interactionSource: event?.interactionSource,
106			interactionText: event?.interactionText,
107		}
108		if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType)
109			gtm.sendEvents({ tClient_ga4: ga4Data });
110	}
111
112	function handlePageChange(payload){
113		var event = payload.eventContext;
114		let ga4Data = {
115			eventName: "filter",
116			filterType: `${event?.refTitle} | ${event?.displayText}`,
117			itemType: event?.itemType,
118			interactionSource: event?.interactionSource,
119			interactionText: event?.interactionText,
120		}
121		if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType)
122			gtm.sendEvents({ tClient_ga4: ga4Data });
123	}
124
125	function handleItemClick(payload){
126		var event = payload.eventContext;
127		if (event?.name === "Quickview" || event?.name === "Quick View") {
128			var ga4Data = {
129				eventName: "filter",
130				filterType: "Open Quickview",
131				itemType: event?.itemType,
132				itemName: event?.itemName ?? event?.refTitle,
133				interactionSource: event?.interactionSource,
134				interactionText: event?.interactionText,
135				itemCategory: event?.crmc,
136				itemCity: event?.itemCity,
137				itemRegion: event?.itemRegion,
138				itemId: event?.itemId,
139				acctId: event?.acctId,
140				itemVariant: event?.itemVariant,
141				price: event?.price,
142				viatorEvent: event?.viatorEvent,
143				propertyId: event?.propertyId,
144				propertyType: event?.propertyType,
145				propertyName: event?.propertyName,
146				isFeatured: event?.isFeatured,
147			}
148			if (event?.crmsc)
149				ga4Data.itemSubcategory = event?.crmsc;
150			if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType)
151				gtm.sendEvents({tClient_ga4: ga4Data});
152		} else {
153			var ga4Data = {
154				eventName: event?.eventName,
155				widgetName: event?.widgetName,
156				itemType: event?.itemType,
157				itemName: event?.itemName ?? event?.refTitle,
158				linkObject: event?.linkObject,
159				itemCategory: event?.crmc,
160				interactionSource: event?.interactionSource,
161				interactionText: event?.interactionText,
162				interactionUrl: event?.interactionUrl,
163				itemCity: event?.itemCity,
164				itemRegion: event?.itemRegion,
165				itemId: event?.itemId,
166				acctId: event?.acctId,
167				itemVariant: event?.itemVariant,
168				price: event?.price,
169				referralType: event?.referralType,
170				viatorEvent: event?.viatorEvent,
171				propertyId: event?.propertyId,
172				propertyType: event?.propertyType,
173				propertyName: event?.propertyName,
174				isFeatured: event?.isFeatured,
175			}
176			if (event?.crmsc)
177				ga4Data.itemSubcategory = event?.crmsc;
178			if (event?.eventName === 'partner_referral')
179				ga4Data.value = 5;
180			if (ga4Data.eventName && ga4Data.itemType && ga4Data.itemName && ga4Data.linkObject)
181				gtm.sendEvents({tClient_ga4: ga4Data});
182		}
183	}
184
185	function handleMapPinClick(payload){
186		var event = payload.eventContext,
187			widget = payload.widgetContext;
188		var data = {
189			eventCategory: widget.name,
190			eventAction: event.name,
191			eventLabel: event.refTitle,
192			ot: event.type,
193			nonInteraction: false
194		}
195		if (data.eventCategory && data.eventAction && data.eventLabel)
196			gtm.sendEvents({tClient: data});
197	}
198 
199	function handleFilterChange (payload) {
200		var event = payload.eventContext;
201		let ga4Data = {
202			eventName: "filter",
203			filterType: `${event?.refTitle} | ${event?.displayText}`,
204			itemType: event?.itemType,
205			interactionSource: event?.interactionSource,
206			interactionText: event?.interactionText,
207		}
208		if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType)
209			gtm.sendEvents({ tClient_ga4: ga4Data });
210	}
211	// end SEM tracking
212});
213
214// Lazy-load FontAwesome
215(function() {
216	var css = document.createElement('link');
217	css.href = 'https://use.fontawesome.com/releases/v5.14.0/css/all.css';
218	css.rel = 'stylesheet';
219	css.type = 'text/css';
220	document.getElementsByTagName('head')[0].appendChild(css);
221})();
222
223// Lazy-load js for widgets that have the [data-js] attribute on their root node
224(function() {
225	function initDataJs(searchScope, selector = '[data-js]' ){
226		require(['plugins_common_custom_lazyload'], function(lazyload) {
227			var widgetsToLoad = [];
228			let scope = searchScope ? searchScope : document;
229			var els = scope.querySelectorAll(selector);
230
231			for (var i = 0; i < els.length; i++) {
232				widgetsToLoad.push(els[i]);
233			}
234			
235			lazyload.lazy(widgetsToLoad, function(entry, io) {
236				var target = entry.target;
237				var jsFile = target.dataset.js;
238				var guid = target.dataset.guid;
239
240				require([jsFile], function(widget) {
241					widget.init(guid);
242					io.unobserve(target);
243				});
244			});
245		});
246	};
247
248	initDataJs();
249
250	let eventToSelectorMap = {
251		// each event needs a slightly different selector
252		"dynamicContentLoaded": "[data-dynamic-chosen] > .contentRender > [data-js]",
253		"abContentLoaded": "[data-ab-chosen] > .contentRender > [data-js]"
254	}
255	
256	Object.entries(eventToSelectorMap).forEach( event => {
257		const [eventName, selector] = event;
258		window.addEventListener(eventName, e => {
259			const collections = document.querySelector(`[data-guid="${e}"]`);
260			initDataJs(collections, selector);
261		});
262	});
263})();
264
265// Remove critical styles from head after all CSS files have loaded
266// This prevents a situation where the critical styles cause an override of the CSS in files
267const criticalStyles = document.querySelector('[data-critical-styles]');
268if (criticalStyles) {
269	window.addEventListener('load', e => criticalStyles.remove());
270}

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.