« get me outta code hell

content: linkExternal: return placeholder on invalid URL - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2024-03-01 09:05:07 -0400
committer(quasar) nebula <qznebula@protonmail.com>2024-03-31 19:19:45 -0300
commit0c607b69c344e6cd71c2b9a63f3cd0feddca1063 (patch)
tree94d749637b8a445e57474f6213854f3490f81f32 /src
parent49240a57e063844387831336908111c0229f5ec0 (diff)
content: linkExternal: return placeholder on invalid URL
Diffstat (limited to 'src')
-rw-r--r--src/content/dependencies/linkExternal.js69
-rw-r--r--src/strings-default.yaml7
2 files changed, 56 insertions, 20 deletions
diff --git a/src/content/dependencies/linkExternal.js b/src/content/dependencies/linkExternal.js
index 188c1f0..39a593b 100644
--- a/src/content/dependencies/linkExternal.js
+++ b/src/content/dependencies/linkExternal.js
@@ -36,31 +36,64 @@ export default {
   },
 
   generate(data, slots, {html, language}) {
-    let formattedLink =
-      language.formatExternalLink(data.url, {
-        style: slots.style,
-        context: slots.context,
-      });
-
-    // Fall back to platform if nothing matched the desired style.
-    if (html.isBlank(formattedLink) && slots.style !== 'platform') {
+    let urlIsValid;
+    try {
+      new URL(data.url);
+      urlIsValid = true;
+    } catch (error) {
+      urlIsValid = false;
+    }
+
+    let formattedLink;
+    if (urlIsValid) {
       formattedLink =
         language.formatExternalLink(data.url, {
-          style: 'platform',
+          style: slots.style,
           context: slots.context,
         });
+
+      // Fall back to platform if nothing matched the desired style.
+      if (html.isBlank(formattedLink) && slots.style !== 'platform') {
+        formattedLink =
+          language.formatExternalLink(data.url, {
+            style: 'platform',
+            context: slots.context,
+          });
+      }
+    } else {
+      formattedLink = null;
     }
 
-    const linkAttributes = html.attributes();
-    const linkContent =
-      (html.isBlank(slots.content)
-        ? formattedLink
-        : slots.content);
+    const linkAttributes = html.attributes({
+      class: 'external-link',
+    });
 
-    linkAttributes.set('class', 'external-link');
-    linkAttributes.set('href', data.url);
+    let linkContent;
+    if (urlIsValid) {
+      linkAttributes.set('href', data.url);
+
+      if (html.isBlank(slots.content)) {
+        linkContent = formattedLink;
+      } else {
+        linkContent = slots.content;
+      }
+    } else {
+      if (html.isBlank(slots.content)) {
+        linkContent =
+          html.tag('i',
+            language.$('misc.external.invalidURL.annotation'));
+      } else {
+        linkContent =
+          language.$('misc.external.invalidURL', {
+            link: slots.content,
+            annotation:
+              html.tag('i',
+                language.$('misc.external.invalidURL.annotation')),
+          });
+      }
+    }
 
-    if (slots.indicateExternal) {
+    if (urlIsValid && slots.indicateExternal) {
       linkAttributes.add('class', 'indicate-external');
 
       let titleText;
@@ -85,7 +118,7 @@ export default {
       }
     }
 
-    if (slots.tab === 'separate') {
+    if (urlIsValid && slots.tab === 'separate') {
       linkAttributes.set('target', '_blank');
     }
 
diff --git a/src/strings-default.yaml b/src/strings-default.yaml
index 46aeee8..9b82d1d 100644
--- a/src/strings-default.yaml
+++ b/src/strings-default.yaml
@@ -506,8 +506,11 @@ misc:
 
     opensInNewTab:
       _: "{LINK} ({ANNOTATION})"
-      annotation:
-        "opens in new tab"
+      annotation: "opens in new tab"
+
+    invalidURL:
+      _: "{LINK} ({ANNOTATION})"
+      annotation: "invalid URL"
 
     appleMusic: "Apple Music"
     artstation: "ArtStation"