From b72a7b04dc1beee12e51907e5d5e2932e7589c62 Mon Sep 17 00:00:00 2001
From: Timm Fitschen <t.fitschen@indiscale.com>
Date: Tue, 14 Sep 2021 15:23:50 +0200
Subject: [PATCH] Add more tests and complete implementation of
 ext_cosmetics.linkify

---
 src/core/js/ext_cosmetics.js             | 27 +++++++++----
 test/core/js/modules/ext_cosmetics.js.js | 51 ++++++++++++++++++++++--
 2 files changed, 67 insertions(+), 11 deletions(-)

diff --git a/src/core/js/ext_cosmetics.js b/src/core/js/ext_cosmetics.js
index a8ccc5d8..f4f28112 100644
--- a/src/core/js/ext_cosmetics.js
+++ b/src/core/js/ext_cosmetics.js
@@ -28,22 +28,33 @@
  */
 var cosmetics = new function () {
 
+    /**
+     * Cut-off length of links. When linkify processes the links any href
+     * longer than this will be cut off at character 25 and "[...]" will be
+     * appended for the link text.
+     */
+    var _link_cut_off_length = 40;
+
     var _linkify = function () {
         $('.caosdb-f-property-text-value').each(function (index) {
-            // TODO also extract and convert links surrounded by other text
-            if (/^https?:\/\//.test(this.innerText)) {
-                var uri = this.innerText;
-                var text = uri
+            if (/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 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>`;
+                });
 
-                $(this).parent().css("overflow", "hidden");
-                $(this).parent().css("text-overflow", "ellipsis");
-                $(this).html(`<a class="caosdb-v-property-href-value" href="${uri}">${text} <i class="bi bi-box-arrow-up-right"></i></a>`);
+                $(this).html(result);
             }
         });
     }
 
     /**
-     * Convert any text-value beginning with 'http(s)://' into a link.
+     * Convert any substring of a text-value beginning with 'http(s)://' into a
+     * link.
      *
      * A listener detects edit-mode changes and previews
      */
diff --git a/test/core/js/modules/ext_cosmetics.js.js b/test/core/js/modules/ext_cosmetics.js.js
index b54d183f..d5d4df7f 100644
--- a/test/core/js/modules/ext_cosmetics.js.js
+++ b/test/core/js/modules/ext_cosmetics.js.js
@@ -22,7 +22,7 @@
 
 QUnit.module("ext_cosmetics.js", {
     before: function (assert) {
-      cosmetics.init();
+        cosmetics.init();
         // setup before module
     },
     beforeEach: function (assert) {
@@ -36,7 +36,52 @@ QUnit.module("ext_cosmetics.js", {
     }
 });
 
-QUnit.test("linkify", function(assert) {
-  assert.ok(cosmetics.linkify, "linkify available");
+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],
+    ];
+    for (let test_case of test_cases) {
+        var text_value = $(`<div class="caosdb-f-property-text-value">${test_case[0]}</div>`);
+        $(document.body).append(text_value);
+        assert.equal($(text_value).find("a[href='https://link']").length, 0, "no link present");
+        cosmetics.linkify();
+        assert.equal($(text_value).find("a[href='https://link']").length, test_case[1], "link is present");
+        text_value.remove();
+    }
+});
+
+QUnit.test("linkify - http", function (assert) {
+    var test_cases = [
+        ["http://link", 1],
+        ["this is other text http://link", 1],
+        ["http://link this is other text", 1],
+        ["this is other text http://link and this as well", 1],
+        ["this is other text http://link", 1],
+        ["this is other text http://link and here comes another link http://link and more text", 2],
+    ];
+    for (let test_case of test_cases) {
+        var text_value = $(`<div class="caosdb-f-property-text-value">${test_case[0]}</div>`);
+        $(document.body).append(text_value);
+        assert.equal($(text_value).find("a[href='http://link']").length, 0, "no link present");
+        cosmetics.linkify();
+        assert.equal($(text_value).find("a[href='http://link']").length, test_case[1], "link is present");
+        text_value.remove();
+    }
 });
 
+QUnit.test("linkify cut-off (40)", function (assert) {
+    var test_case = "here is some text https://this.is.a.link/with/more/than/40/characters/ this is more text";
+    var text_value = $(`<div class="caosdb-f-property-text-value">${test_case}</div>`);
+    $(document.body).append(text_value);
+    assert.equal($(text_value).find("a").length, 0, "no link present");
+    cosmetics.linkify();
+    assert.equal($(text_value).find("a").length, 1, "link is present");
+    assert.equal($(text_value).find("a").text(), "https://this.is.a.link/with/more/th[...] ", "link text has been cut off");
+    text_value.remove();
+});
\ No newline at end of file
-- 
GitLab