/* * This file is a part of the LinkAhead Project. * * Copyright (C) 2021-2024 IndiScale GmbH <info@indiscale.com> * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com> * Copyright (C) 2023 Florian Spreckelsen <f.spreckelsen@indiscale.com> * Copyright (C) 2023 Daniel Hornung <d.hornung@indiscale.com> * Copyright (C) 2024 Joscha Schmiedt <joscha@schmiedt.dev> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ "use strict"; /** * Cosmetics module is a collection of small look-and-feel tweaks for the * LinkAhead webui. * * @author Timm Fitschen */ var cosmetics = new function () { /** * Cut-off length of links. When linkify processes the links any href * longer than this will be cut off at the end and "[...]" will be * appended for the link text. */ var _link_cut_off_length = 40; var _custom_datetime = function () { $('.caosdb-f-property-datetime-value').each(function (index) { if (!($(this).hasClass("caosdb-v-property-datetime-customized"))) { var result = this.innerText.replace(/T/, " ").replace(/\+.*/, ""); result = `<span class="caosdb-v-property-datetime-customized-newvalue">${result}</span>`; // add class to highlight that this has been customized already $(this).addClass("caosdb-v-property-datetime-customized") $(this).hide(); $(this).after(result); } }); } /** * Remove all the custom datetime elements again, for example when entering the edit mode. */ var _custom_datetime_clear = function () { $('.caosdb-v-property-datetime-customized-newvalue').each(function () { $(this).remove(); } ) } /** * Return a string with all occurences of a http(s) url in a given string replaced by <a> elements * @param {string} text - The text to be searched for URLs * @returns {string} text with <a> elements instead of raw links */ function linkify_string(text) { // const match_url_regex = /https?:\/\/[^\s]*/g // original // https://regexr.com helps you design regex const match_url_regex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.?[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g return text.replace(match_url_regex, function (href) { var link_text = href; if (_link_cut_off_length > 4 && link_text.length > _link_cut_off_length) { link_text = link_text.substring(0, _link_cut_off_length - 5) + "[...]"; } return `<a title="Open ${href} in a new tab." target="_blank" class="caosdb-v-property-href-value" href="${href}">${link_text} <i class="bi bi-box-arrow-up-right"></i></a>`; }); } /** * Turn all URLs in .caosdb-f-property-text-value DOM elements into actual links */ var _linkify_all_text_values = function () { $('.caosdb-f-property-text-value').each(function (index) { if (!($(this).hasClass("caosdb-v-property-linkified")) && (/https?:\/\//.test(this.innerText))) { var linkified_text_value = linkify_string(this.innerText); // add class to highlight that this has been linkified already // (see https://gitlab.com/caosdb/caosdb-webui/-/issues/199). $(this).addClass("caosdb-v-property-linkified") $(this).hide(); $(this).after(linkified_text_value); } }); } /** * Convert any substring of a text-value beginning with 'http(s)://' into a * link. * * A listener detects edit-mode changes and previews */ var linkify = function () { _linkify_all_text_values(); // edit-mode-listener document.body.addEventListener(edit_mode.end_edit.type, _linkify_all_text_values, true); // preview listener document.body.addEventListener(preview.previewReadyEvent.type, _linkify_all_text_values, true); } /** * Customize datetime formatting. * * A listener detects edit-mode changes and previews */ var custom_datetime = function () { _custom_datetime(); // edit-mode-listener to delete replacement document.body.addEventListener(edit_mode.start_edit.type, _custom_datetime_clear, true); // edit-mode-listener to recreate document.body.addEventListener(edit_mode.end_edit.type, _custom_datetime, true); // preview listener document.body.addEventListener(preview.previewReadyEvent.type, _custom_datetime, true); } /** * Prettify double values for display purposes. */ const prettify_double_values = () => { $('.caosdb-f-property-double-value').each(function (index) { if (!$(this).hasClass("caosdb-v-property-double-prettified")) { let value = parseFloat(this.innerText); let prettified_value = ""; if (Math.abs(value) > 1e6 || Math.abs(value) < 1e-6) { // Use scientific notation for very large or very small values prettified_value = value.toExponential(1); } else { // Otherwise, display with up to 12 significant digits prettified_value = value.toPrecision(12).replace(/\.?0+$/, ''); } $(this).addClass("caosdb-v-property-double-prettified"); $(this).hide(); $(this).after(`<span class="caosdb-v-property-double-prettified-newvalue">${prettified_value}</span>`); } }); }; this.init = function () { this.custom_datetime = custom_datetime; if ("${BUILD_MODULE_EXT_COSMETICS_CUSTOMDATETIME}" == "ENABLED") { custom_datetime(); } this.linkify = linkify; if ("${BUILD_MODULE_EXT_COSMETICS_LINKIFY}" == "ENABLED") { linkify(); } this.prettify_double_values = prettify_double_values; if ("${BUILD_MODULE_EXT_COSMETICS_PRETTIFY_DOUBLES}" === "ENABLED") { prettify_double_values(); } } } $(document).ready(function () { caosdb_modules.register(cosmetics); });