« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/content
diff options
context:
space:
mode:
Diffstat (limited to 'src/content')
-rw-r--r--src/content/dependencies/linkExternal.js69
1 files changed, 51 insertions, 18 deletions
diff --git a/src/content/dependencies/linkExternal.js b/src/content/dependencies/linkExternal.js
index 188c1f0d..39a593b2 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');
     }