PageSourceSearch

https://www.shakespeares-england.co.uk/includes/public/managed/v_c…/common/virtuals/js/shared_footer.js

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

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.