PageSourceSearch

https://www.visit-dorset.com/includes/public/managed/v_a2e6ae52_a5…/common/virtuals/js/shared_footer.js

js visit-dorset.com collected 2026-10-01 11:29:56 UTC 8,687 bytes, 254 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?.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		}
43		if (event?.crmsc) 
44			ga4Data.itemSubcategory = event?.crmsc;
45		if (ga4Data.eventName && ga4Data.itemType && ga4Data.itemName && ga4Data.linkObject)
46			gtm.sendEvents({ tClient_ga4: ga4Data });
47	}
48	
49	function handleQuickview(payload){
50		var event = payload.eventContext;
51		let ga4Data = {
52			eventName: event?.eventName,
53			itemType: event?.itemType,
54			itemName: event?.itemName ?? event?.refTitle,
55			linkObject: event?.linkObject,
56			itemCategory: event?.crmc,
57			interactionSource: event?.interactionSource,
58			interactionText: event?.interactionText,
59			interactionUrl: event?.interactionUrl,
60			itemCity: event?.itemCity,
61			itemRegion: event?.itemRegion,
62			itemId: event?.itemId,
63			acctId: event?.acctId,
64			itemVariant: event?.itemVariant,
65			price: event?.price,
66			referralType: event?.referralType,
67		}
68		if (event?.crmsc) 
69			ga4Data.itemSubcategory = event?.crmsc;
70		if (event?.eventName === 'partner_referral')
71			ga4Data.value = 5;
72		if (ga4Data.eventName && ga4Data.itemType && ga4Data.itemName && ga4Data.linkObject)
73			gtm.sendEvents({ tClient_ga4: ga4Data });
74	}
75
76	function handleScrollIntoView(payload){
77		var event = payload.eventContext,
78			widget = payload.widgetContext;
79		var data = {
80			eventCategory: widget.name,
81			eventAction: event.name,
82			eventLabel: "Widget - "+widget.name,
83			nonInteraction: true
84		}
85		if (data.eventCategory && data.eventAction && data.eventLabel)
86			gtm.sendEvents({tClient: data});
87	}
88
89	function handleShowMoreToggle(payload){
90		var event = payload.eventContext;
91		let ga4Data = {
92			eventName: "filter",
93			filterType: `${event?.refTitle} | ${event?.displayText}`,
94			itemType: event?.itemType,
95			interactionSource: event?.interactionSource,
96			interactionText: event?.interactionText,
97		}
98		if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType)
99			gtm.sendEvents({ tClient_ga4: ga4Data });
100	}
101
102	function handlePageChange(payload){
103		var event = payload.eventContext;
104		let ga4Data = {
105			eventName: "filter",
106			filterType: `${event?.refTitle} | ${event?.displayText}`,
107			itemType: event?.itemType,
108			interactionSource: event?.interactionSource,
109			interactionText: event?.interactionText,
110		}
111		if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType)
112			gtm.sendEvents({ tClient_ga4: ga4Data });
113	}
114
115	function handleItemClick(payload){
116		var event = payload.eventContext;
117		if (event?.name === "Quickview") {
118			var ga4Data = {
119				eventName: "filter",
120				filterType: "Open Quickview",
121				itemType: event?.itemType,
122				itemName: event?.itemName ?? event?.refTitle,
123				interactionSource: event?.interactionSource,
124				interactionText: event?.interactionText,
125				itemCategory: event?.crmc,
126				itemCity: event?.itemCity,
127				itemRegion: event?.itemRegion,
128				itemId: event?.itemId,
129				acctId: event?.acctId,
130				itemVariant: event?.itemVariant,
131				price: event?.price,
132			}
133			if (event?.crmsc)
134				ga4Data.itemSubcategory = event?.crmsc;
135			if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType)
136				gtm.sendEvents({tClient_ga4: ga4Data});
137		}
138		else {
139			var ga4Data = {
140				eventName: event?.eventName,
141				itemType: event?.itemType,
142				itemName: event?.itemName ?? event?.refTitle,
143				linkObject: event?.linkObject,
144				itemCategory: event?.crmc,
145				interactionSource: event?.interactionSource,
146				interactionText: event?.interactionText,
147				interactionUrl: event?.interactionUrl,
148				itemCity: event?.itemCity,
149				itemRegion: event?.itemRegion,
150				itemId: event?.itemId,
151				acctId: event?.acctId,
152				itemVariant: event?.itemVariant,
153				price: event?.price,
154				referralType: event?.referralType,
155			}
156			if (event?.crmsc)
157				ga4Data.itemSubcategory = event?.crmsc;
158			if (event?.eventName === 'partner_referral')
159				ga4Data.value = 5;
160			if (ga4Data.eventName && ga4Data.itemType && ga4Data.itemName && ga4Data.linkObject)
161				gtm.sendEvents({tClient_ga4: ga4Data});
162		}
163	}
164
165	function handleMapPinClick(payload){
166		var event = payload.eventContext,
167			widget = payload.widgetContext;
168		var data = {
169			eventCategory: widget.name,
170			eventAction: event.name,
171			eventLabel: event.refTitle,
172			ot: event.type,
173			nonInteraction: false
174		}
175		if (data.eventCategory && data.eventAction && data.eventLabel)
176			gtm.sendEvents({tClient: data});
177	}
178
179	function handleFilterChange (payload) {
180		var event = payload.eventContext;
181		let ga4Data = {
182			eventName: "filter",
183			filterType: `${event?.refTitle} | ${event?.displayText}`,
184			itemType: event?.itemType,
185			interactionSource: event?.interactionSource,
186			interactionText: event?.interactionText,
187		}
188		if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType)
189			gtm.sendEvents({ tClient_ga4: ga4Data });
190	}
191	// end SEM tracking
192});
193
194// Lazy-load js for widgets that have the [data-js] attribute on their root node
195(function() {
196	function initDataJs(searchScope, selector = '[data-js]' ){
197		require(['plugins_common_custom_lazyload'], function(lazyload) {
198			var widgetsToLoad = [];
199			let scope = searchScope ? searchScope : document;
200			var els = scope.querySelectorAll(selector);
201
202			for (var i = 0; i < els.length; i++) {
203				var jsFile = els[i].dataset.js || '';
204
205				// Collection modules establish their layout and reveal the widget.
206				// Waiting for intersection can permanently skip a collection when
207				// earlier widgets initialise and shift it across the viewport.
208				if (jsFile.indexOf('plugins_collections_') === 0) {
209					loadWidget(els[i]);
210				} else {
211					widgetsToLoad.push(els[i]);
212				}
213			}
214			
215			lazyload.lazy(widgetsToLoad, function(entry, io) {
216				loadWidget(entry.target, io);
217			});
218
219			function loadWidget(target, io) {
220				var jsFile = target.dataset.js;
221				var guid = target.dataset.guid;
222
223				require([jsFile], function(widget) {
224					widget.init(guid);
225
226					if (io) io.unobserve(target);
227				});
228			}
229		});
230	};
231
232	initDataJs();
233
234	let eventToSelectorMap = {
235		// each event needs a slightly different selector
236		"dynamicContentLoaded": "[data-dynamic-chosen] > .contentRender > [data-js]",
237		"abContentLoaded": "[data-ab-chosen] > .contentRender > [data-js]"
238	}
239	
240	Object.entries(eventToSelectorMap).forEach( event => {
241		const [eventName, selector] = event;
242		window.addEventListener(eventName, e => {
243			const collections = document.querySelector(`[data-guid="${e}"]`);
244			initDataJs(collections, selector);
245		});
246	});
247})();
248
249// Remove critical styles from head after all CSS files have loaded
250// This prevents a situation where the critical styles cause an override of the CSS in files
251const criticalStyles = document.querySelector('[data-critical-styles]');
252if (criticalStyles) {
253	window.addEventListener('load', e => criticalStyles.remove());
254}

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.