/** * This file is part of Radicale Server - Calendar Server * Copyright © 2017-2024 Unrud * Copyright © 2023-2024 Matthew Hana * Copyright © 2024-2025 Peter Bieringer * Copyright © 2026-2026 Max Berger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /** * Escape string for usage in XML * @param {string} s * @return {string} */ export function escape_xml(s) { return (s .replace(/&/g, "&") .replace(/"/g, """) .replace(/'/g, "'") .replace(//g, ">")); } /** * @return {string} */ export function random_uuid() { return random_hex(8) + "-" + random_hex(4) + "-" + random_hex(4) + "-" + random_hex(4) + "-" + random_hex(12); } /** * Generate random hex number. * @param {number} length * @return {string} */ export function random_hex(length) { let bytes = new Uint8Array(Math.ceil(length / 2)); window.crypto.getRandomValues(bytes); // Fallback for compatibility with older browsers which may not have padStart return bytes.reduce((s, b) => { let hex = b.toString(16); return s + (String.prototype["padStart"] ? hex["padStart"](2, "0") : ("0" + hex).slice(-2)); }, "").substring(0, length); } /** * Removed invalid HREF characters for a collection HREF. * @param {HTMLInputElement} href_form A valid Input element or an onchange Event of an Input element. */ export function cleanHREFinput(href_form) { let currentTxtVal = href_form.value.trim().toLowerCase(); //Clean the HREF to remove not permitted chars currentTxtVal = currentTxtVal.replace(/(?![0-9a-z\-\_\.])./g, ''); //Clean the HREF to remove leading . (would result in hidden directory) currentTxtVal = currentTxtVal.replace(/^\./, ''); href_form.value = currentTxtVal; } /** * Event listener for cleaning HREF input. * @param {Event} event */ export function onCleanHREFinput(event) { if (event.target instanceof HTMLInputElement) { cleanHREFinput(event.target); } } /** * Checks if a proposed HREF for a collection has a valid format and syntax. * @param {string} href String of the proposed HREF. * @return Boolean results if the HREF is valid. */ export function isValidHREF(href) { if (href.length < 1) { return false; } if (href.indexOf("/") != -1) { return false; } return true; } /** * Format bytes to human-readable text. * @param {number} bytes Number of bytes. * @return Formatted string. */ export function bytesToHumanReadable(bytes) { if (isNaN(bytes - 0)) { return ""; } const units = ['b', 'kb', 'mb', 'gb', 'tb']; let i = bytes == 0 ? 0 : Math.floor(Math.log(bytes) / Math.log(1024)); i = Math.min(i, units.length - 1); return Math.round((bytes / Math.pow(1024, i)) * 100) / 100 + ' ' + units[i]; } /** * Add selection handler for input fields with 'selectall' class. */ export function setupSelectAll() { document.addEventListener("focusin", (event) => { if (event.target instanceof HTMLInputElement && event.target.classList.contains("selectall")) { event.target.setSelectionRange(0, 99999); } }); }