PageSourceSearch

https://gfny.com/wp-content/themes/yootheme-gfny/js/help-desk.js?t=1

js gfny.com collected 2026-10-01 12:15:16 UTC 6,938 bytes, 232 lines download raw bytes

1const createCSS = (query) => {
2	let css = "";
3	query
4		.trim()
5		.split(" ")
6		.filter((part) => part.length > 0)
7		.reverse()
8		.slice(0, 3)
9		.forEach((word) => {
10			css += `
11		[data-category*="${word}"], 
12		[data-subcategory*="${word}"],
13		[data-title*="${word}"] {
14			display: flex!important;
15		}
16		[data-category*="${word}"] ~ .no-results, 
17		[data-subcategory*="${word}"] ~ .no-results,
18		[data-title*="${word}"] ~ .no-results{
19			display: none!important;
20		}
21		.no-results span::before{
22			content: "${searchField.value}";
23		}
24	`;
25		});
26
27	return css;
28};
29
30const focusFirst = (el) => {
31	el.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])')[0]?.focus();
32}
33
34const scrollToWithOffset = (el, callback, offset = -180) => {
35
36	const target = el.getBoundingClientRect().top + window.pageYOffset + offset;
37	const step = (x) => x / 50 < 0.5 ? 1 - Math.pow(-2 * x / 50 + 2, 3) / 2 : 4 * x / 50 * x / 50 * x / 50;
38	let i = 0;
39
40	const interval = setInterval((
41	) => {
42		i++;
43		if (window.pageYOffset + step(i) < target) {
44			window.scroll(
45				0, window.pageYOffset + step(i)
46			);
47		} else {
48			clearInterval(interval)
49			callback && callback();
50		}
51	}, 10)
52
53};
54
55// search
56
57const searchWrap = document.querySelector(".help-desk__search-wrap");
58const searchField = document.querySelector(".help-desk__search-field");
59const searchResults = document.querySelector(".help-desk__search-wrap ul");
60const styleTag = document.head.appendChild(document.createElement("style"));
61
62const clearSearchBtn = document.querySelector(".help-desk__search-clear");
63
64const states = ["focus", "hasquery", "hasresults", "noresults"];
65
66const updateState = () => {
67	searchWrap.classList[searchField.value == "" ? "remove" : "add"](
68		"help-desk__search-wrap--hasquery"
69	);
70};
71
72searchField.addEventListener("input", () => {
73	styleTag.innerHTML = createCSS(searchField.value.trim());
74	updateState();
75});
76
77const clearSearch = () => {
78	searchField.value = "";
79	searchField.dispatchEvent(new Event("input"));
80	searchField.focus();
81};
82
83const handleSearchKeyDown = (e) => {
84	if (e.key === 'ArrowDown') {
85		e.preventDefault();
86		searchResults.firstElementChild.firstElementChild?.focus();
87	}
88};
89
90const handleOptionKeyDown = (e) => {
91	if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
92		e.preventDefault();
93
94		const nextElementToFocus = (e.target).parentElement[
95			`${e.key === 'ArrowDown' ? 'next' : 'previous'}ElementSibling`
96		]?.firstElementChild;
97
98		if (nextElementToFocus && nextElementToFocus.clientHeight > 10) {
99			nextElementToFocus.focus();
100		} else {
101			searchField.focus();
102		}
103	}
104};
105
106searchField.addEventListener("keydown", handleSearchKeyDown);
107searchResults.querySelectorAll("li a").forEach((el) => {
108	el.addEventListener("keydown", handleOptionKeyDown);
109});
110
111clearSearchBtn.addEventListener("click", clearSearch);
112
113// anchors
114
115const accordionAnchors = document.querySelectorAll(
116	".help-desk__search-wrap a:not([target='_blank'])"
117);
118const anchorBlocks = document.querySelectorAll(".help-desk__category-anchor");
119
120[...anchorBlocks, ...accordionAnchors].forEach((anchorBlock) => {
121	anchorBlock.addEventListener("click", (e) => {
122		e.preventDefault();
123		const el = e.target.closest("a");
124		const isBlockAnchor = el?.classList.contains("help-desk__category-anchor");
125
126		if (!isBlockAnchor) {
127			clearSearch();
128			document.querySelectorAll(".details[open]").forEach(detail => detail.removeAttribute("open"))
129		}
130		const target = document.getElementById(el.getAttribute("href").slice(1));
131		scrollToWithOffset(target, () => {
132			focusFirst(target)
133			const firstButton = target.querySelector("button");
134			const isOpen = firstButton?.parentElement?.getAttribute("open") !== null;
135			!isOpen && firstButton?.click();
136		}
137		);
138	})
139});
140
141// modal
142
143const modal = document.createElement("dialog");
144
145const openModal = () => {
146	modal.setAttribute("open", "");
147	document.querySelector("html").style = "overflow:hidden";
148	const firstInput = modal.querySelector("select, input:not([type='hidden'])");
149	firstInput?.focus();
150};
151
152const closeModal = () => {
153	document.querySelector("html").style = "overflow:auto";
154	modal.removeAttribute("open");
155};
156
157document.addEventListener("DOMContentLoaded", () => {
158	const openBtns = document.querySelectorAll(".js-open-modal-form");
159	const close = document.createElement("button");
160	close.classList.add("help-desk__form-modal-close-btn");
161	modal.classList.add("help-desk__form-modal");
162
163	const form =
164		document.querySelector(".wpcf7");
165
166	const thankYouTemplate = `
167    	<h2>Thank you for your message!</h2>
168    	<p>We will get back to you as soon as possible.</p>
169    	<button type="button" class="thank-you-close">Close</button>
170    `;
171
172	const thankYouElement = document.createElement("div");
173
174	thankYouElement.classList.add("help-desk__form-thank-you")
175	thankYouElement.innerHTML = thankYouTemplate;
176
177	thankYouElement.querySelector("button").addEventListener("click", closeModal)
178
179	form.querySelector("form").appendChild(thankYouElement);
180
181	const errorOutput = document.querySelector(".wpcf7-response-output");
182	form.parentElement.removeChild(form);
183	form.prepend(close);
184
185	errorOutput.parentElement.removeChild(errorOutput);
186	form.querySelector("#contactus-form").appendChild(errorOutput);
187
188	modal.appendChild(form);
189	document.querySelector("body").appendChild(modal);
190
191	if (window.location.search.includes("contact")) {
192		openModal();
193	}
194
195	[...openBtns].forEach((openBtn) =>
196		openBtn.addEventListener("click", openModal)
197	);
198
199	const whatsAppForm = document.querySelector(".help-desk__form-modal-whatsapp-form");
200
201	if (whatsAppForm) {
202		whatsAppForm.parentNode.removeChild(whatsAppForm);
203		const newForm = document.createElement("form");
204		newForm.append(...whatsAppForm.childNodes)
205		Object.entries(whatsAppForm.attributes).map(([_, attributes]) => [attributes.name, attributes.value]).forEach(([name, value]) => newForm.setAttribute(name, value))
206		form.append(newForm);
207	}
208
209	document.querySelectorAll(".help-desk__form-modal-whatsapp-switcher button").forEach(btn => {
210		btn.addEventListener("click", (e) => {
211			e.target.parentElement.querySelector("button[active]").removeAttribute("active");
212			e.target.setAttribute("active", "");
213			modal.classList[e.target.classList.contains("whatsapp") ? "add" : "remove"]("whatsapp");
214		})
215	})
216
217	close.addEventListener("click", closeModal);
218
219	modal.addEventListener("click", (e) => {
220		if (e.target.classList.contains("help-desk__form-modal")) {
221			closeModal();
222		}
223	});
224
225	window.addEventListener("keydown", (e) => {
226		if (e.key === "Escape") {
227			closeModal();
228		}
229	});
230});
231
232document.querySelectorAll(".details__summary").forEach(el => el.addEventListener("click", () => el.parentElement.toggleAttribute("open")))

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.