Skip to content
Snippets Groups Projects
Commit 4f53c06e authored by Florian Spreckelsen's avatar Florian Spreckelsen
Browse files

Merge branch 'f-344-extern-linkify-absorbs-commas-etc-into-link-adress' into 'dev'

F 344 extern linkify absorbs commas etc into link adress

See merge request !128
parents cf481f99 143c4849
No related branches found
No related tags found
2 merge requests!131FIX: error in regexp to match URLs,!128F 344 extern linkify absorbs commas etc into link adress
Pipeline #47630 passed
......@@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed ###
* [#247](https://gitlab.com/linkahead/linkahead-webui/-/issues/247) Linkify absorbs commas
etc. (, . : ;) into link adress
* Query shortcuts are now displayed when using the new query panel.
* [249](https://gitlab.com/linkahead/linkahead-webui/-/issues/249) only the
first ≈100 options were shown in edit-mode reference dropdown menus in case
......
......@@ -31,5 +31,19 @@
editor plugins. Please refer to the `package.json` within
`libs/ckeditor...zip` for a full list of said plugins.
## For testing
## For unit testing
* qunit-2.9.2
### Debian 12 (also on WSL)
* unzip
* gettext
* firefox-esr
* xvfb
* libpci-dev
* libegl1
* imagemagick (to use `convert` on `screenshot.xwd`)
Install test dependencies on Debian
```bash
sudo apt install unzip gettext firefox-esr xvfb x11-apps libpci-dev libegl1 imagemagick
```
......@@ -63,10 +63,16 @@ See `build.properties.d/00_default.properties` for more information.
## Test
* See [DEPENDENCIES](DEPENDENCIES#for-unit-testing) for the requirements to run the unit tests.
* Run `make test` to compile/copy the web interface and the tests to a newly
created `public` folder.
* Run `make run-test-server` to start a python http server.
* The test suite can be started with `firefox http://localhost:8000/`.
* *On WSL (as of Feb 2024, WSL v2.0.14.0)*, port 8000 is sometimes not properly forwarded to the host
resulting in an unreachable test suite. Switching to a different port can be done easily
by using the `TEST_PORT` environment variable, e.g. with `TEST_PORT=8111 make
run-test-server`. Using the X11 `firefox` from within WSL always works.
* To run the test suite non-interactively (as in CI/CD) use `make -d run-qunit`
## Clean
......
/*
* This file is a part of the LinkAhead Project.
*
* Copyright (C) 2021-2023 IndiScale GmbH <info@indiscale.com>
* 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
......@@ -51,66 +52,81 @@ var cosmetics = new function () {
});
}
/**
* 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();
/**
* 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();
}
)
}
)
}
var _linkify = function () {
$('.caosdb-f-property-text-value').each(function (index) {
if (!($(this).hasClass("caosdb-v-property-linkified")) && (/https?:\/\//.test(this.innerText))) {
var result = this.innerText.replace(/https?:\/\/[^\s]*/g, function (href, index) {
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 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>`;
});
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(result);
$(this).after(linkified_text_value);
}
});
}
/**
* Customize datetime formatting.
* Convert any substring of a text-value beginning with 'http(s)://' into a
* link.
*
* A listener detects edit-mode changes and previews
*/
var custom_datetime = function () {
_custom_datetime();
var linkify = function () {
_linkify_all_text_values();
// 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);
// edit-mode-listener
document.body.addEventListener(edit_mode.end_edit.type, _linkify_all_text_values, true);
// preview listener
document.body.addEventListener(preview.previewReadyEvent.type, _custom_datetime, true);
document.body.addEventListener(preview.previewReadyEvent.type, _linkify_all_text_values, true);
}
/**
* Convert any substring of a text-value beginning with 'http(s)://' into a
* link.
* Customize datetime formatting.
*
* A listener detects edit-mode changes and previews
*/
var linkify = function () {
_linkify();
var custom_datetime = function () {
_custom_datetime();
// edit-mode-listener
document.body.addEventListener(edit_mode.end_edit.type, _linkify, true);
// 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, _linkify, true);
document.body.addEventListener(preview.previewReadyEvent.type, _custom_datetime, true);
}
this.init = function () {
......@@ -123,7 +139,6 @@ var cosmetics = new function () {
linkify();
}
}
}
......
/*
* This file is a part of the LinkAhead Project.
*
* Copyright (C) 2021-2023 IndiScale GmbH <info@indiscale.com>
* Copyright (C) 2021-2024 IndiScale GmbH <info@indiscale.com>
* Copyright (C) 2021 Timm Fitschen <t.fitschen@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
......@@ -51,12 +52,12 @@ QUnit.test("custom datetime", function (assert) {
const text_value = $(`<span class="caosdb-f-property-datetime-value">${test_case[0]}</span>`);
container.append(text_value);
assert.equal($(container).find(" ").length, 0, "Test original datetime.");
cosmetics.custom_datetime();
const newValueElement =
cosmetics.custom_datetime();
const newValueElement =
container[0].querySelector("span.caosdb-v-property-datetime-customized-newvalue");
assert.ok(newValueElement, "Datetime customization: Test if result exists.");
assert.equal(newValueElement.innerHTML, test_case[1],
"Datetime customization: compared result.");
assert.ok(newValueElement, "Datetime customization: Test if result exists.");
assert.equal(newValueElement.innerHTML, test_case[1],
"Datetime customization: compared result.");
container.remove();
}
});
......@@ -64,22 +65,22 @@ QUnit.test("custom datetime", function (assert) {
QUnit.test("linkify - https", function (assert) {
assert.ok(cosmetics.linkify, "linkify available");
var test_cases = [
["https://link", 1],
["this is other text https://link", 1],
["https://link this is other text", 1],
["this is other text https://link and this as well", 1],
["this is other text https://link", 1],
["this is other text https://link and here comes another link https://link and more text", 2],
["https://link", 1, "https://link",],
["this is other text https://link.com", 1, "https://link.com"],
["https://link; this is other text", 1, "https://link"],
["this is other text https://link.de and this as well", 1, "https://link.de"],
["this is other text https://link:3000", 1, "https://link:3000"],
["this is other text https://link.org/test, and here comes another link https://link.org/test and more text", 2, "https://link.org/test"],
];
for (let test_case of test_cases) {
const container = $('<div></div>');
var container = $('<div></div>');
$(document.body).append(container);
const text_value = $(`<div class="caosdb-f-property-text-value">${test_case[0]}</div>`);
container.append(text_value);
assert.equal($(container).find("a[href='https://link']").length, 0, "no link present");
assert.equal($(container).find(`a[href='${test_case[2]}']`).length, 0, "no link present");
cosmetics.linkify();
assert.equal($(container).find("a[href='https://link']").length, test_case[1], "link is present");
assert.equal($(container).find(`a[href='${test_case[2]}']`).length, test_case[1], `link is present: ${$(container)[0].outerHTML}`);
container.remove();
}
});
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment