PageSourceSearch

https://www.rsatidewater.org/assets/js/utils.js?v=1.20

js rsatidewater.org collected 2026-10-02 01:07:26 UTC 9,878 bytes, 287 lines download raw bytes

1function defTxtCkFocus(field) {
2	var tmpAttr = field.hasAttribute('defValue')?field.getAttribute('defValue'):field.id;
3	if (field.value == tmpAttr) {
4		field.className = '';
5		field.value = '';
6		if (tmpAttr == 'Password') field.type = 'password';
7	}
8}
9function defTxtCkBlur(field) {
10	var tmpAttr = field.hasAttribute('defValue')?field.getAttribute('defValue'):field.id;
11	if (field.value == tmpAttr || field.value == '') {
12		field.className = 'txtFieldDef';
13		field.value = tmpAttr;
14		if (tmpAttr == 'Password') field.type = 'text';
15	} else {
16		field.className = '';
17	}
18}
19
20function copy2clip(obj2copy) {
21	if ($(obj2copy).data("link")) {
22		var textToCopy = $(obj2copy).data("link");
23	} else if ($(obj2copy).is(':input')) {
24		var textToCopy = $(obj2copy).val();
25	} else {
26		var textToCopy = $(obj2copy).text();
27	}
28	navigator.clipboard.writeText(textToCopy);	//there's a known bug with this if the browser does not accept the security cert/thinks connection is insecure
29	if ($(obj2copy).data("copysuccessmsg")) {
30		const oldTxt = $(obj2copy).text();
31		$(obj2copy).text($(obj2copy).data("copysuccessmsg"));
32		setTimeout(function() {
33			$(obj2copy).text(oldTxt);
34		}, 2000);
35	}
36}
37
38// Custom slide/fade out animation
39function slideFadeOut($el, duration = 250, callback) {
40	$el.animate(
41		{ height: 0, opacity: 0, paddingTop: 0, paddingBottom: 0, marginTop: 0, marginBottom: 0 },
42		duration,
43		function () {
44			if (callback) callback();
45		}
46	);
47}
48
49function slideFadeIn($el, duration = 250, callback) {
50    $el.css({ height: 0, opacity: 0, paddingTop: '', paddingBottom: '', marginTop: '', marginBottom: '' });
51    $el.animate(
52        { height: $el.get(0).scrollHeight, opacity: 1 },
53        duration,
54        function () {
55            $el.css({ height: '' }); // Clear the height to allow for dynamic content
56            if (callback) callback();
57        }
58    );
59}
60
61function hasScrollableParent(el) {
62    while (el && el !== document.body) {
63        const style = window.getComputedStyle(el);
64        const overflowY = style.overflowY;
65
66        const isScrollable =
67            (overflowY === "auto" || overflowY === "scroll") &&
68            el.scrollHeight > el.clientHeight;
69
70        if (isScrollable) return true;
71
72        el = el.parentElement;
73    }
74
75    return false;
76}
77
78
79function initStdPopup() {
80	var popup = document.createElement("div");
81	popup.className = "infoStdPopup";
82	popup.style.display = "none";
83	popup.style.zIndex = "9999";
84	popup.style.position = "absolute";
85	popup.style.background = "#fff";
86	popup.style.border = "1px solid #ccc";
87	popup.style.padding = "10px";
88	popup.style.boxShadow = "0 4px 8px rgba(0, 0, 0, 0.2)";
89	document.body.appendChild(popup);
90
91	document.addEventListener("click", function(event) {
92		var offsetX = 10;
93		var offsetY = 10;
94		var popupData = event.target.getAttribute("data-popupData");
95		var popupTitle = event.target.getAttribute("data-popupTitle");
96		if (popupData && popupTitle) {
97			popup.innerHTML = "<h4>" + popupTitle + "</h4>" + "<i class='fa-regular fa-rectangle-xmark'></i>" + "<div class='popup-content'>" + popupData + "</div>";
98			popup.querySelector("div").setAttribute("style", "display:flex; flex-direction:column;");
99			popup.style.border = "1px dashed rgb(153,153,153)";
100			popup.style.background = "rgb(246,246,246)";
101			popup.querySelector("i").setAttribute("style", "position:absolute; top:5px; right:5px; cursor:pointer;");
102			event.stopPropagation();
103			popup.querySelector("h4").setAttribute("style", "width:90%; margin-bottom:0px; margin-top:0px; margin-right:15px;");
104
105			setTimeout(function() {
106				const popupWidth = event.target.getAttribute("data-popupWidth");
107				const popupMaxWidth = event.target.getAttribute("data-popupMaxWidth");
108				const popupHeight = event.target.getAttribute("data-popupHeight");
109				const popupMaxHeight = event.target.getAttribute("data-popupMaxHeight");
110				if (popupWidth !== "auto") {
111					popup.style.width = popupWidth + "px";
112				} else {
113					popup.style.width = "auto"; // Default width for auto
114				}
115				if (window.innerWidth >= 900) {
116					popup.style.maxWidth = popupMaxWidth + "px";
117				} else if (popupMaxWidth !== "none" && 500 < window.innerWidth < 900) {
118					popup.style.maxWidth = "500px"; // Default max width for smaller screens
119				} else {
120					popup.style.maxWidth = "300px";
121				}
122				if (popupHeight !== "auto") {
123					popup.style.height = popupHeight + "px";
124				} else {
125					popup.style.height = "auto";
126				}
127				if (popupMaxHeight !== "none") {
128					popup.style.maxHeight = popupMaxHeight + "px";
129				} else {
130					popup.style.maxHeight = "none";
131				}
132				if (window.innerWidth >= 900) {
133					popup.style.left = (event.pageX - offsetX) + "px";
134				} else {
135					popup.style.left = "10px";
136				}
137				popup.style.top = (event.pageY + offsetY) + "px";
138				popup.style.display = "block";
139			}, 0);
140		}
141	});
142
143	document.addEventListener("click", function(event) {
144		var isPopup = popup.contains(event.target);
145		var isIcon = event.target.id.includes("popIcon");
146		var isClose = event.target.classList.contains("fa-rectangle-xmark");
147		if ((!isPopup && !isIcon) || isClose) {
148			popup.style.display = "none";
149		}
150	});
151}
152
153function initListPopup() {
154	var popup = document.createElement("div");
155	popup.className = "infoPopup";
156	popup.style.display = "none";
157	popup.style.zIndex = "9999";
158	popup.style.position = "absolute";
159	popup.style.background = "#fff";
160	popup.style.border = "1px solid #ccc";
161	popup.style.padding = "10px";
162	popup.style.boxShadow = "0 4px 8px rgba(0, 0, 0, 0.2)";
163	document.body.appendChild(popup);
164
165	document.addEventListener("click", function(event) {
166		var offsetX = 10;
167		var offsetY = 10;
168		var listHTML = event.target.getAttribute("data-listHTML");
169		var listTitle = event.target.getAttribute("data-listTitle");
170		if (listHTML && listTitle) {
171			popup.innerHTML = "<h4>" + listTitle + "</h4>" + "<i class='fa-regular fa-rectangle-xmark'></i>" + "<div class='popup-content'>" + listHTML + "</div>";
172			popup.querySelector("div").setAttribute("style", "display:flex;");
173			popup.style.border = "1px dashed rgb(153,153,153)";
174			popup.style.background = "rgb(246,246,246)";
175			popup.querySelector("i").setAttribute("style", "position:absolute; top:5px; right:5px; cursor:pointer;");
176			event.stopPropagation();
177			popup.querySelectorAll("ul").forEach(function(ul) {
178				ul.style.paddingLeft = "15px";
179				ul.style.paddingRight = "10px";
180			});
181			popup.querySelector("h4").setAttribute("style", "width:90%; margin-bottom:0px; margin-top:0px;");
182
183			setTimeout(function() {
184				const numCols = popup.querySelectorAll(".popup-content > ul").length;
185				const baseWidth = 150;
186				const extraWidthPerCol = 20;
187				const calcWidth = baseWidth + (extraWidthPerCol * (numCols - 1));
188				popup.style.width = calcWidth + "px";
189				if (window.innerWidth/2 > event.pageX) {
190					popup.style.left = (event.pageX + offsetX) + "px";
191				} else {
192					popup.style.left = (event.pageX - calcWidth) + "px";
193				}
194				popup.style.top = (event.pageY + offsetY) + "px";
195				popup.style.display = "block";
196			}, 0);
197		}
198	});
199
200	document.addEventListener("click", function(event) {
201		var isPopup = popup.contains(event.target);
202		var isIcon = event.target.id.includes("popIcon");
203		var isClose = event.target.classList.contains("fa-rectangle-xmark");
204		if ((!isPopup && !isIcon) || isClose) {
205			popup.style.display = "none";
206		}
207	});
208}
209
210/* ~~~ PWA AJAX JS ~~~ */
211//This function causes a file download on Android and brings up a window with preview/download options on iOS safari for the PWA
212async function downloadFile(url, preventDefault = true, fileName = "downloaded-file") {
213	if (preventDefault) {
214		event.preventDefault();
215	}
216
217	const response = await fetch(url);
218
219	const contentDisposition = response.headers.get("Content-Disposition");
220
221	if (contentDisposition) {
222		const filenameMatch = 
223		contentDisposition.match(/filename\*=(?:UTF-8'')?(.+?)(?:;|$)/) ||
224		contentDisposition.match(/filename="(.+?)"/);
225		if (filenameMatch && filenameMatch.length > 1) {
226			fileName = decodeURIComponent(filenameMatch[1].replace(/"/g, ""));
227		}
228	}
229
230	const blob = await response.blob();
231	const downloadUrl = URL.createObjectURL(blob);
232
233	const anchorElement = document.createElement("a");
234	anchorElement.href = downloadUrl;
235	anchorElement.setAttribute("data-spa-no-ajax", "");
236	anchorElement.download = fileName || "downloaded-file";
237	document.body.appendChild(anchorElement);
238	anchorElement.click();
239	document.body.removeChild(anchorElement);
240	URL.revokeObjectURL(downloadUrl);
241}
242
243function pwaSubmitFormAndDownload(form) {
244	const $form = $(form);
245
246	const action = $form.attr("action");
247	const method = ($form.attr("method") || "POST").toUpperCase();
248
249	return $.ajax({
250		url: action,
251		method,
252		data: new FormData($form[0]),
253		processData: false,
254		contentType: false,
255		headers: { "X-PWA-Request": "true" },
256		xhrFields: {
257			withCredentials: true
258		}
259	}).then(async function (result) {
260
261		if (!result.success || !result.downloadURL) {
262			throw new Error("No download URL returned");
263		}
264
265		// Trigger the actual download
266		await downloadFile(result.downloadURL, false, result.fileName);
267
268		return result;
269	});
270}
271
272// Change the color of the notch area
273function setThemeColor(color) {
274	let meta = document.querySelector('meta[name="theme-color"]');
275	if (meta) {
276		meta.setAttribute('content', color);
277	} else {
278		meta = document.createElement('meta');
279		meta.setAttribute('name', 'theme-color');
280		meta.setAttribute('content', color);
281		document.head.appendChild(meta);
282	}
283}
284
285// To trigger PWA content loading via AJAX in JS on click events
286
287/* ~~~ END PWA AJAX JS ~~~ */

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.