diff --git a/src/components/graph/widgets/TextPreviewWidget.vue b/src/components/graph/widgets/TextPreviewWidget.vue index 33ab748748..68c2c09550 100644 --- a/src/components/graph/widgets/TextPreviewWidget.vue +++ b/src/components/graph/widgets/TextPreviewWidget.vue @@ -27,7 +27,33 @@ const props = defineProps<{ const executionStore = useExecutionStore() const isParentNodeExecuting = ref(true) -const formattedText = computed(() => nl2br(linkifyHtml(modelValue.value))) +const formattedText = computed(() => { + const src = modelValue.value + // Turn [[label|url]] into placeholders to avoid interfering with linkifyHtml + const tokens: { label: string; url: string }[] = [] + const holed = src.replace( + /\[\[([^|\]]+)\|([^\]]+)\]\]/g, + (_m, label, url) => { + tokens.push({ label: String(label), url: String(url) }) + return `__LNK${tokens.length - 1}__` + } + ) + + // Keep current behavior (auto-link bare URLs + \n ->
) + let html = nl2br(linkifyHtml(holed)) + + // Restore placeholders as ... (minimal escaping + http default) + html = html.replace(/__LNK(\d+)__/g, (_m, i) => { + const { label, url } = tokens[+i] + const safeHref = url.replace(/"/g, '"') + const safeLabel = label.replace(//g, '>') + return /^https?:\/\//i.test(url) + ? `${safeLabel}` + : safeLabel + }) + + return html +}) let parentNodeId: NodeId | null = null onMounted(() => {