PageSourceSearch

https://www.pcsclassical.org/wp-content/themes/salient-child/js/scripts.js?ver=1773685033

js pcsclassical.org collected 2026-10-02 19:10:20 UTC 9,621 bytes, 335 lines download raw bytes

1/*
2function adjustElementHeight() {
3	
4	// Query elements inside the function to ensure they exist
5	const $element = document.querySelector(".adjust-height-to-cta-buttons");
6	const $ctaButtons = document.querySelectorAll(".inquire-visit-apply-cta");
7
8	if (!$element || $ctaButtons.length === 0) {
9		return;
10	}
11
12	// Unset min-height and max-height with !important
13	$element.style.setProperty("min-height", "unset", "important");
14	$element.style.setProperty("max-height", "none", "important");
15
16	// Get screen height
17	const screenHeight = window.innerHeight;
18	const viewportWidth = window.innerWidth;
19	const isDesktop = viewportWidth >= 1024;
20
21	// Get header height for desktop
22	let headerHeight = 0;
23	if (isDesktop) {
24		const $header = document.querySelector("#header-outer");
25		if ($header) {
26			headerHeight = $header.offsetHeight;
27		}
28	}
29
30	// Get WordPress admin bar height (topbar) if user is logged in
31	let adminBarHeight = 0;
32	const $adminBar = document.querySelector("#wpadminbar");
33	if ($adminBar) {
34		adminBarHeight = $adminBar.offsetHeight;
35	}
36
37	// Get the actual rendered height of the button group
38	// Use getBoundingClientRect to get the actual height from first to last button
39	let totalButtonsHeight = 0;
40	if ($ctaButtons.length > 0) {
41		const firstButton = $ctaButtons[0];
42		const lastButton = $ctaButtons[$ctaButtons.length - 1];
43		const firstRect = firstButton.getBoundingClientRect();
44		const lastRect = lastButton.getBoundingClientRect();
45		// Height is from top of first button to bottom of last button
46		totalButtonsHeight = lastRect.bottom - firstRect.top;
47	}
48
49	// Calculate element height: screen height - button group height - header height (desktop only) - admin bar height
50	const elementHeight =
51		screenHeight - totalButtonsHeight - headerHeight - adminBarHeight;
52
53	console.log("Screen height:", screenHeight);
54	console.log("Viewport width:", viewportWidth);
55	console.log("Is desktop:", isDesktop);
56	console.log("Header height:", headerHeight);
57	console.log("Admin bar height:", adminBarHeight);
58	console.log("Button group height:", totalButtonsHeight);
59	console.log("Element height:", elementHeight);
60
61	// Set the height with !important to ensure it overrides any CSS
62	$element.style.setProperty("height", `${elementHeight}px`, "important");
63}
64
65// Debounce function to prevent excessive calls during resize
66let resizeTimeout;
67function debouncedAdjustHeight() {
68	clearTimeout(resizeTimeout);
69	resizeTimeout = setTimeout(adjustElementHeight, 100);
70}
71
72// Function to handle CTA fixed positioning on scroll
73function handleCTAFixedPosition() {
74	const $ctaButtons = document.querySelectorAll(".inquire-visit-apply-cta");
75	const $header = document.querySelector("#header-outer");
76
77	if ($ctaButtons.length === 0) {
78		return;
79	}
80
81	// Get the first CTA button to check its position
82	const firstCTA = $ctaButtons[0];
83
84	// Temporarily remove fixed class to get accurate viewport position
85	const wasFixed = firstCTA.classList.contains("cta-fixed");
86	if (wasFixed) {
87		firstCTA.classList.remove("cta-fixed");
88		firstCTA.style.removeProperty("top");
89	}
90
91	// Get CTA's current position in viewport
92	const ctaRect = firstCTA.getBoundingClientRect();
93	const ctaTop = ctaRect.top;
94
95	// Get header height
96	let headerHeight = 0;
97	if ($header) {
98		headerHeight = $header.offsetHeight;
99	}
100
101	// Get WordPress admin bar height if present
102	let adminBarHeight = 0;
103	const $adminBar = document.querySelector("#wpadminbar");
104	if ($adminBar) {
105		adminBarHeight = $adminBar.offsetHeight;
106	}
107
108	// Calculate the total offset from top (header + admin bar)
109	const totalOffsetFromTop = headerHeight + adminBarHeight;
110
111	// Check if CTA has touched or passed the header
112	// CTA should be fixed when its top edge reaches or passes the header bottom
113	const shouldBeFixed = ctaTop <= totalOffsetFromTop;
114
115	// Restore fixed state temporarily removed for measurement
116	if (wasFixed && shouldBeFixed) {
117		firstCTA.classList.add("cta-fixed");
118		firstCTA.style.setProperty("top", `${totalOffsetFromTop}px`, "important");
119	}
120
121	// Add or remove fixed class based on scroll position
122	for (const button of $ctaButtons) {
123		if (shouldBeFixed) {
124			button.classList.add("cta-fixed");
125			// Set top position to header height (plus admin bar if present)
126			button.style.setProperty("top", `${totalOffsetFromTop}px`, "important");
127		} else {
128			button.classList.remove("cta-fixed");
129			button.style.removeProperty("top");
130		}
131	}
132}
133
134// Debounce function for scroll events
135let scrollTimeout;
136function debouncedHandleCTAFixed() {
137	if (scrollTimeout) {
138		cancelAnimationFrame(scrollTimeout);
139	}
140	scrollTimeout = requestAnimationFrame(handleCTAFixedPosition);
141}
142
143// Ensure code runs only after page is fully loaded
144function initHeightAdjustment() {
145	// Use window.load for production reliability - ensures all resources are loaded
146	if (document.readyState === "complete") {
147		adjustElementHeight();
148		handleCTAFixedPosition();
149	} else {
150		window.addEventListener("load", () => {
151			adjustElementHeight();
152			handleCTAFixedPosition();
153		});
154	}
155
156	// Run on window resize with debouncing
157	window.addEventListener("resize", () => {
158		debouncedAdjustHeight();
159		debouncedHandleCTAFixed();
160	});
161
162	// Also run on orientation change (mobile/tablet)
163	window.addEventListener("orientationchange", () => {
164		setTimeout(() => {
165			adjustElementHeight();
166			handleCTAFixedPosition();
167		}, 200);
168	});
169
170	// Handle scroll events for CTA fixed positioning
171	window.addEventListener("scroll", debouncedHandleCTAFixed, { passive: true });
172}
173
174// Initialize when DOM is ready
175if (document.readyState === "loading") {
176	document.addEventListener("DOMContentLoaded", initHeightAdjustment);
177} else {
178	initHeightAdjustment();
179}
180*/
181
182(() => {
183	window.PCS_CTA_DEBUG = window.PCS_CTA_DEBUG || false;
184
185	function getFlipCardTargets() {
186		const targets = [];
187		const ctaTextBlocks = document.querySelectorAll(
188			".hp-age-and-stage .cta-text",
189		);
190
191		for (const ctaText of ctaTextBlocks) {
192			const card = ctaText.closest(".vc_column-inner");
193			if (card && targets.indexOf(card) === -1) {
194				targets.push(card);
195			}
196		}
197
198		return targets;
199	}
200
201	function setOriginalDisplay(element) {
202		if (!element.dataset.originalDisplay) {
203			element.dataset.originalDisplay =
204				window.getComputedStyle(element).display;
205		}
206	}
207
208	function setFlipState(card, shouldFlip) {
209		const hideSelectors = "h2, h3, h4, .divider-wrap";
210		const elementsToHide = card.querySelectorAll(hideSelectors);
211		const ctaText = card.querySelector(".cta-text");
212
213		for (const element of elementsToHide) {
214			setOriginalDisplay(element);
215			element.style.display = shouldFlip
216				? "none"
217				: element.dataset.originalDisplay;
218		}
219
220		if (ctaText) {
221			setOriginalDisplay(ctaText);
222			ctaText.style.display = shouldFlip ? "flex" : "none";
223			ctaText.classList.toggle("is-visible", shouldFlip);
224		}
225
226		card.classList.toggle("is-flipped", shouldFlip);
227		card.setAttribute("aria-pressed", shouldFlip ? "true" : "false");
228	}
229
230	function toggleFlipState(card) {
231		const shouldFlip = !card.classList.contains("is-flipped");
232		setFlipState(card, shouldFlip);
233	}
234
235	function logCtaMetrics(card, context) {
236		if (!window.PCS_CTA_DEBUG) {
237			return;
238		}
239
240		const ctaText = card.querySelector(".cta-text");
241		const wrapper = ctaText ? ctaText.querySelector(".wpb_wrapper") : null;
242
243		console.groupCollapsed(`[PCS CTA] ${context}`, card);
244		console.log("card.clientHeight", card.clientHeight);
245		console.log("card.scrollHeight", card.scrollHeight);
246		if (ctaText) {
247			console.log("ctaText.clientHeight", ctaText.clientHeight);
248			console.log("ctaText.scrollHeight", ctaText.scrollHeight);
249			console.log("ctaText.scrollTop", ctaText.scrollTop);
250			console.log(
251				"ctaText.alignItems",
252				window.getComputedStyle(ctaText).alignItems,
253			);
254			console.log(
255				"ctaText.justifyContent",
256				window.getComputedStyle(ctaText).justifyContent,
257			);
258		}
259		if (wrapper) {
260			console.log("wrapper.clientHeight", wrapper.clientHeight);
261			console.log("wrapper.scrollHeight", wrapper.scrollHeight);
262			console.log("wrapper.scrollTop", wrapper.scrollTop);
263		}
264		console.groupEnd();
265	}
266
267	function bindFlipCardEvents(card) {
268		card.setAttribute("role", "button");
269		card.setAttribute("tabindex", "0");
270		card.setAttribute("aria-pressed", "false");
271
272		card.addEventListener("mouseenter", () => {
273			setFlipState(card, true);
274			logCtaMetrics(card, "hover-in");
275		});
276
277		card.addEventListener("mouseleave", () => {
278			setFlipState(card, false);
279			logCtaMetrics(card, "hover-out");
280		});
281
282		card.addEventListener("focus", () => {
283			setFlipState(card, true);
284			logCtaMetrics(card, "focus");
285		});
286
287		card.addEventListener("blur", () => {
288			setFlipState(card, false);
289			logCtaMetrics(card, "blur");
290		});
291	}
292
293	function initCtaFlipCards() {
294		const cards = getFlipCardTargets();
295
296		for (const card of cards) {
297			setFlipState(card, false);
298			bindFlipCardEvents(card);
299			logCtaMetrics(card, "init");
300		}
301
302		if (window.PCS_CTA_DEBUG && !cards.length) {
303			console.warn(
304				"[PCS CTA] No cards found. Check selector:",
305				".hp-age-and-stage .cta-text",
306			);
307		}
308
309		window.addEventListener("resize", () => {
310			for (const card of cards) {
311				logCtaMetrics(card, "resize");
312			}
313		});
314	}
315
316	window.PCS_CTA_LOG = () => {
317		window.PCS_CTA_DEBUG = true;
318		const cards = getFlipCardTargets();
319		if (!cards.length) {
320			console.warn(
321				"[PCS CTA] No cards found. Check selector:",
322				".hp-age-and-stage .cta-text",
323			);
324		}
325		for (const card of cards) {
326			logCtaMetrics(card, "manual");
327		}
328	};
329
330	if (document.readyState === "loading") {
331		document.addEventListener("DOMContentLoaded", initCtaFlipCards);
332	} else {
333		initCtaFlipCards();
334	}
335})();

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.