From 944ca18baaa8bed9dc14a77a6e5d1385803499da Mon Sep 17 00:00:00 2001 From: Rob Gordon Date: Mon, 27 Jan 2025 17:09:11 -0500 Subject: [PATCH] Auto-link url labels --- app/src/components/Graph.tsx | 12 ++++++++---- app/src/lib/helpers.ts | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/app/src/components/Graph.tsx b/app/src/components/Graph.tsx index 0aa5b38c..d14eb3fe 100644 --- a/app/src/components/Graph.tsx +++ b/app/src/components/Graph.tsx @@ -16,7 +16,7 @@ import { monacoMarkerErrorSeverity } from "../lib/constants"; import { cytoscape } from "../lib/cytoscape"; import { getElements } from "../lib/getElements"; import { DEFAULT_GRAPH_PADDING } from "../lib/graphOptions"; -import { isError } from "../lib/helpers"; +import { isError, isUrl } from "../lib/helpers"; import { useCanEdit } from "../lib/hooks"; import { preprocessStyle, @@ -224,9 +224,13 @@ function initializeGraph({ }); // on node tap, if has a href, open it cyCurrent.on("tap", "node", function handleTap(this: NodeSingular) { - const { href } = this.data(); - if (href) { - window.open(href, "_blank"); + const { href, label } = this.data(); + const url = + href || (typeof label === "string" && isUrl(label) ? label : null); + if (url) { + // Add https:// if no protocol is specified + const fullUrl = url.startsWith("http") ? url : `https://${url}`; + window.open(fullUrl, "_blank"); } }); diff --git a/app/src/lib/helpers.ts b/app/src/lib/helpers.ts index 00c5c1ce..a72e5308 100644 --- a/app/src/lib/helpers.ts +++ b/app/src/lib/helpers.ts @@ -70,3 +70,19 @@ export function hasOwnProperty< // eslint-disable-next-line no-prototype-builtins return obj.hasOwnProperty(prop); } + +export function isUrl(str: string): boolean { + try { + // Check if it starts with a protocol + if (str.startsWith("http://") || str.startsWith("https://")) { + return true; + } + // Check if it looks like a domain (e.g., example.com, www.example.com) + if (/^(www\.)?[a-zA-Z0-9-]+\.[a-zA-Z]{2,}/.test(str)) { + return true; + } + return false; + } catch { + return false; + } +}