diff --git a/VERSION b/VERSION index 202f5cc..3534bef 100755 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.6.1-develop14 +4.6.1-develop15 diff --git a/web-ui/css/components/_log-viewer.css b/web-ui/css/components/_log-viewer.css index 74892cb..91348f8 100644 --- a/web-ui/css/components/_log-viewer.css +++ b/web-ui/css/components/_log-viewer.css @@ -152,6 +152,31 @@ overflow: visible; /* Allow content to overflow */ } +/* Clickable links in log messages */ +.log-link { + color: var(--link-color, #007bff); + text-decoration: underline; + text-decoration-color: var(--link-color, #007bff); + text-decoration-thickness: 1px; + text-underline-offset: 2px; + transition: color 0.2s ease, text-decoration-color 0.2s ease; +} + +.log-link:hover { + color: var(--link-hover-color, #0056b3); + text-decoration-color: var(--link-hover-color, #0056b3); +} + +.log-link:visited { + color: var(--link-visited-color, #6c757d); + text-decoration-color: var(--link-visited-color, #6c757d); +} + +.log-link:focus { + outline: 2px solid var(--focus-color, #007bff); + outline-offset: 2px; +} + .log-source { flex-shrink: 0; margin-left: var(--spacing-sm); diff --git a/web-ui/js/components/log-viewer.js b/web-ui/js/components/log-viewer.js index 81cc8fb..5e4dfe2 100755 --- a/web-ui/js/components/log-viewer.js +++ b/web-ui/js/components/log-viewer.js @@ -294,10 +294,10 @@ class LogViewer { let html = ''; this.filteredLogs.forEach((log, index) => { - // Logs are now raw strings, display them directly + // Logs are now raw strings, display them directly with clickable links html += `
- ${this.escapeHtml(log)} + ${this.makeLinksClickable(log)}
`; }); @@ -312,6 +312,24 @@ class LogViewer { return div.innerHTML; } + /** + * Converts URLs in text to clickable links while escaping the rest + * @param {string} text - The text to process + * @returns {string} - HTML with clickable links + */ + makeLinksClickable(text) { + // URL regex pattern that matches http:// and https:// URLs + const urlRegex = /(https?:\/\/[^\s]+)/g; + + // Escape the entire text first for security + const escapedText = this.escapeHtml(text); + + // Replace URLs with clickable links + return escapedText.replace(urlRegex, (url) => { + return `${url}`; + }); + } + scrollToTop() { const logViewerContent = this.container.querySelector('.log-viewer-content'); if (logViewerContent) {