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.