PageSourceSearch

https://www.visitrochester.com/includes/public/managed/v_a2e6ae52_…/common/virtuals/js/shared_footer.js

js visitrochester.com collected 2026-10-02 04:30:21 UTC 8,924 bytes, 288 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("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.