| /* | |
| * Licensed to the Apache Software Foundation (ASF) under one or more | |
| * contributor license agreements. The ASF licenses this file to You | |
| * under the Apache License, Version 2.0 (the "License"); you may not | |
| * use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. For additional information regarding | |
| * copyright in this work, please see the NOTICE file in the top level | |
| * directory of this distribution. | |
| */ | |
| /* This function is used to set cookies */ | |
| function setCookie(name, value, expires, path, domain, secure=true, sameSite=true) { | |
| document.cookie = name + "=" + escape (value) + | |
| ((expires) ? "; expires=" + expires.toGMTString() : "") + | |
| ((path) ? "; path=" + path : "") + | |
| ((domain) ? "; domain=" + domain : "") + ((secure) ? "; secure" : "") + | |
| ((sameSite) ? "; SameSite=Strict" : ""); | |
| } | |
| /* This function is used to get cookies */ | |
| function getCookie(name) { | |
| var prefix = name + "="; | |
| var start = document.cookie.indexOf(prefix); | |
| if (start===-1) { | |
| return null; | |
| } | |
| var end = document.cookie.indexOf(";", start+prefix.length); | |
| if (end===-1) { | |
| end=document.cookie.length; | |
| } | |
| var value=document.cookie.substring(start+prefix.length, end); | |
| return unescape(value); | |
| } | |
| /* This function is used to delete cookies */ | |
| function deleteCookie(name,path,domain) { | |
| if (getCookie(name)) { | |
| document.cookie = name + "=" + | |
| ((path) ? "; path=" + path : "") + | |
| ((domain) ? "; domain=" + domain : "") + | |
| "; expires=Thu, 01-Jan-70 00:00:01 GMT"; | |
| } | |
| } | |
| function rememberUser(theForm) { | |
| var expires = new Date(); | |
| expires.setTime(expires.getTime() + 24 * 365 * 60 * 60 * 1000); // sets it for approx 365 days. | |
| // sets it for entire domain, so freeroller will remember for all users | |
| setCookie("commentAuthor",theForm.name.value,expires,"/"); | |
| setCookie("commentEmail",theForm.email.value,expires,"/"); | |
| setCookie("commentUrl",theForm.url.value,expires,"/"); | |
| } | |
| function forgetUser(theForm) { | |
| deleteCookie("commentAuthor","/"); | |
| deleteCookie("commentEmail","/"); | |
| deleteCookie("commentUrl","/"); | |
| } | |
| /* This function is used to show/hide elements with a display:none style attribute */ | |
| function toggle(targetId) { | |
| if (document.getElementById) { | |
| target = document.getElementById(targetId); | |
| if (target.style.display === "none") { | |
| target.style.display = ""; | |
| } else { | |
| target.style.display = "none"; | |
| } | |
| } | |
| } | |
| /* The toggleFolder and togglePlusMinus functions are for expanding/contracting folders */ | |
| function toggleFolder(targetId) { | |
| var expanded; | |
| if (document.getElementById) { | |
| target = document.getElementById(targetId); | |
| if (target.style.display === "none") { | |
| target.style.display = ""; | |
| expanded = true; | |
| } else { | |
| target.style.display = "none"; | |
| expanded = false; | |
| } | |
| togglePlusMinus("i" + targetId); | |
| // set a cookie to remember this preference | |
| var expires = new Date(); | |
| expires.setTime(expires.getTime() + 24 * 365 * 60 * 60 * 1000); // sets it for approx 365 days. | |
| setCookie("rfolder-"+targetId,expanded,expires,"/"); | |
| } | |
| } | |
| function togglePlusMinus(targetId) { | |
| if (document.getElementById) { | |
| target = document.getElementById(targetId); | |
| if (target.innerHTML === "+") { | |
| target.innerHTML = "-"; | |
| } else { | |
| target.innerHTML = "+"; | |
| } | |
| } | |
| } | |
| /* This function is to set folders to expand/contract based on a user's preference */ | |
| function folderPreference(folderId) { | |
| var folderCookie = getCookie("rfolder-"+folderId); | |
| if (folderCookie != null) { // we have user's last setting | |
| var folder = document.getElementById(folderId); | |
| var plusMinus = document.getElementById("i"+folderId); | |
| if (folderCookie === "true") { // show | |
| folder.style.display = ""; | |
| plusMinus.innerHTML = "-"; | |
| } else { // hide | |
| folder.style.display = "none"; | |
| plusMinus.innerHTML = "+"; | |
| } | |
| } | |
| } | |
| function toggleNextRow(e) { | |
| var checked; | |
| if (e.type === "checkbox") { | |
| checked = e.checked; | |
| } else if (e.type === "radio") { | |
| var v = e.value; | |
| checked = (v === "1" || v === "y" || v === "true"); | |
| } | |
| // var nextRow = e.parentNode.parentNode.nextSibling; | |
| // the above doesn't work on Mozilla since it treats white space as nodes | |
| var thisRow = e.parentNode.parentNode; | |
| var tableBody = thisRow.parentNode; | |
| var nextRow = tableBody.getElementsByTagName("tr")[thisRow.rowIndex+1]; | |
| if (checked === true) { | |
| nextRow.style.display = ""; | |
| } else { | |
| nextRow.style.display = "none"; | |
| } | |
| } | |
| function toggleControl(toggleId, targetId) { | |
| var expanded; | |
| if (document.getElementById) { | |
| target = document.getElementById(targetId); | |
| toggle = document.getElementById(toggleId); | |
| if (target.style.display === "none") { | |
| target.style.display = ""; | |
| expanded = true; | |
| } else { | |
| target.style.display = "none"; | |
| expanded = false; | |
| } | |
| togglePlusMinus("i" + targetId); | |
| // set a cookie to remember this preference | |
| var expires = new Date(); | |
| expires.setTime(expires.getTime() + 24 * 365 * 60 * 60 * 1000); // sets it for approx 365 days. | |
| setCookie("control_"+targetId,expanded,expires,"/"); | |
| } | |
| } | |
| function isblank(s) { | |
| for (var i=0; i<s.length; s++) { | |
| var c = s.charAt(i); | |
| if ((c!==' ') && (c!=='\n') && (c!=='')) return false; | |
| } | |
| return true; | |
| } | |
| // Show the document's title on the status bar | |
| window.defaultStatus=document.title; | |
| // Toggle check boxes | |
| function toggleFunctionAll(toggleValue) { | |
| var inputs = document.getElementsByTagName('input'); | |
| for(var i = 0; i < inputs.length ; i++) { | |
| if(inputs[i].name !== "control" && inputs[i].type === 'checkbox' && inputs[i].disabled === false ) { | |
| if (inputs[i].checked === true){ | |
| inputs[i].checked = !inputs[i].checked; | |
| } else{ | |
| inputs[i].checked = toggleValue; | |
| } | |
| } | |
| } | |
| } | |
| function toggleFunction(toggleValue,name) { | |
| var inputs = document.getElementsByName(name); | |
| for(var i = 0; i < inputs.length ; i++) { | |
| if(inputs[i].type === 'checkbox' && inputs[i].disabled === false) { | |
| inputs[i].checked = toggleValue; | |
| } | |
| } | |
| } | |
| function isValidUrl(url) { | |
| return /^(http|https|ftp):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/i.test(url); | |
| } | |
| function validateEmail(email) { | |
| var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; | |
| return re.test(email); | |
| } | |
| /* | |
| * A salt can be used only once. After a form is posted with AJAX, copy the | |
| * salt issued with the response into the forms on this page, so the next post | |
| * from this page is accepted. | |
| */ | |
| function refreshSalt(html) { | |
| var issued = new DOMParser().parseFromString(html, "text/html") | |
| .querySelector("meta[name='roller-salt']"); | |
| var salt = issued ? issued.getAttribute("content") : ""; | |
| if (salt) { | |
| document.querySelectorAll("input[name='salt']").forEach(function (field) { | |
| field.value = salt; | |
| }); | |
| } | |
| } | |
| /* Returns the action error messages in a page returned to an AJAX post. */ | |
| function actionErrors(html) { | |
| var errors = new DOMParser().parseFromString(html, "text/html") | |
| .querySelectorAll("#errors li"); | |
| return Array.prototype.map.call(errors, function (error) { | |
| return error.textContent.trim(); | |
| }); | |
| } | |
| // weblog pages include this script with their comment form, and most themes | |
| // do not load jQuery, so validation only runs where jQuery Validation is loaded | |
| window.jQuery && jQuery.validator && jQuery(function () { | |
| jQuery("form.validate-form").validate(); | |
| // Added method to check valid email address and add a custom error message | |
| jQuery.validator.addMethod( | |
| "regex", | |
| function(value, element, regexp) { | |
| if (regexp && regexp.constructor != RegExp) { | |
| regexp = new RegExp(regexp); | |
| } else if (regexp.global) { | |
| regexp.lastIndex = 0; | |
| } | |
| return this.optional(element) || regexp.test(value); | |
| } | |
| ); | |
| // Applied email rules to field with class name validate-email | |
| jQuery( ".validate-email" ).rules( "add", { | |
| minlength: 3, | |
| maxlength: 255, | |
| email: true, | |
| regex: /^\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b$/i | |
| }); | |
| }); | |
| // Bootstrap 5 tooltips are opt-in; field hints come from the form theme. | |
| // Titles may contain markup, hence html: true. | |
| document.addEventListener('DOMContentLoaded', function () { | |
| if (typeof bootstrap === 'undefined' || !bootstrap.Tooltip) { | |
| return; | |
| } | |
| document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(function (el) { | |
| new bootstrap.Tooltip(el, {html: true, placement: 'right'}); | |
| }); | |
| }); |