| @@ -265,10 +265,9 @@ | ||
| 265 | 265 | return `<h${level} class="chat-heading">${content}</h${level}>`; |
| 266 | 266 | }); |
| 267 | 267 | } |
| 268 | 268 | |
| 269 | -// Update the linkify function to handle both URLs and markdown | |
| 270 | -// Modified linkify function that only processes URLs in user content | |
| 269 | +// Update the linkify function to handle URLs, markdown, and phone numbers | |
| 271 | 270 | function linkify(inputText) { |
| 272 | 271 | if (!inputText) return ''; |
| 273 | 272 | |
| 274 | 273 | // Process markdown headers |
| @@ -281,8 +280,16 @@ | ||
| 281 | 280 | const safeText = sanitizeUserInput(text); |
| 282 | 281 | return `<a href="${safeUrl}" target="${linkTarget}">${safeText}</a>`; |
| 283 | 282 | }); |
| 284 | 283 | |
| 284 | + // Process phone numbers (tel:) | |
| 285 | + const phonePattern = /\[([^\]]+)\]\((tel:[\d+]+)\)/g; | |
| 286 | + processedText = processedText.replace(phonePattern, (match, text, phone) => { | |
| 287 | + const safePhone = encodeURI(phone); | |
| 288 | + const safeText = sanitizeUserInput(text); | |
| 289 | + return `<a href="${safePhone}">${safeText}</a>`; | |
| 290 | + }); | |
| 291 | + | |
| 285 | 292 | // Process standalone URLs |
| 286 | 293 | const urlPattern = /(^|[^">])(https?:\/\/[^\s<]+)/gim; |
| 287 | 294 | processedText = processedText.replace(urlPattern, (match, prefix, url) => { |
| 288 | 295 | const safeUrl = encodeURI(url); |
| @@ -298,9 +305,8 @@ | ||
| 298 | 305 | |
| 299 | 306 | return processedText; |
| 300 | 307 | } |
| 301 | 308 | |
| 302 | - | |
| 303 | 309 | function scrollElementToTop(element) { |
| 304 | 310 | var chatBox = $('#chat-box'); |
| 305 | 311 | var elementTop = element.position().top + chatBox.scrollTop(); |
| 306 | 312 | chatBox.animate({ scrollTop: elementTop }, 500); |
| @@ -1129,10 +1135,18 @@ | ||
| 1129 | 1135 | document.getElementById('word-upload').click(); |
| 1130 | 1136 | }); |
| 1131 | 1137 | } |
| 1132 | 1138 | |
| 1139 | +function addSafeEventListener(elementId, eventType, handler) { | |
| 1140 | + const element = document.getElementById(elementId); | |
| 1141 | + if (element) { | |
| 1142 | + element.addEventListener(eventType, handler); | |
| 1143 | + } | |
| 1144 | +} | |
| 1145 | + | |
| 1146 | + | |
| 1133 | 1147 | // PDF file input change handler |
| 1134 | -document.getElementById('pdf-upload').addEventListener('change', async function(e) { | |
| 1148 | +addSafeEventListener('pdf-upload', 'change', async function(e) { | |
| 1135 | 1149 | const file = e.target.files[0]; |
| 1136 | 1150 | |
| 1137 | 1151 | if (!file || file.type !== 'application/pdf') { |
| 1138 | 1152 | alert('Please select a valid PDF file.'); |
| @@ -1204,9 +1218,9 @@ | ||
| 1204 | 1218 | } |
| 1205 | 1219 | }); |
| 1206 | 1220 | |
| 1207 | 1221 | // Word file input change handler |
| 1208 | -document.getElementById('word-upload').addEventListener('change', async function(e) { | |
| 1222 | +addSafeEventListener('word-upload', 'change', async function(e) { | |
| 1209 | 1223 | const file = e.target.files[0]; |
| 1210 | 1224 | |
| 1211 | 1225 | if (!file || file.type !== 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') { |
| 1212 | 1226 | alert('Please select a valid Word document (.docx).'); |
| @@ -1439,21 +1453,24 @@ | ||
| 1439 | 1453 | document.addEventListener('DOMContentLoaded', function() { |
| 1440 | 1454 | checkInitialDocumentStatus(); |
| 1441 | 1455 | }); |
| 1442 | 1456 | |
| 1443 | -// Style all toolbar elements | |
| 1444 | 1457 | const toolbarElements = [ |
| 1445 | 1458 | '#mxchat-chatbot .toolbar-btn svg', |
| 1446 | 1459 | '#mxchat-chatbot .active-pdf-name', |
| 1447 | 1460 | '#mxchat-chatbot .active-word-name', |
| 1448 | 1461 | '#mxchat-chatbot .remove-pdf-btn svg', |
| 1449 | - '#mxchat-chatbot .remove-word-btn svg' | |
| 1462 | + '#mxchat-chatbot .remove-word-btn svg', | |
| 1463 | + '#mxchat-chatbot .toolbar-perplexity svg' | |
| 1450 | 1464 | ]; |
| 1451 | -$(toolbarElements.join(', ')).css({ | |
| 1452 | - 'fill': toolbarIconColor, | |
| 1453 | - 'color': toolbarIconColor | |
| 1465 | + | |
| 1466 | +toolbarElements.forEach(selector => { | |
| 1467 | + $(selector).css({ | |
| 1468 | + 'fill': toolbarIconColor, | |
| 1469 | + 'stroke': toolbarIconColor, | |
| 1470 | + 'color': toolbarIconColor | |
| 1471 | + }); | |
| 1454 | 1472 | }); |
| 1455 | - | |
| 1456 | 1473 | |
| 1457 | 1474 | |
| 1458 | 1475 | // Ensure essential elements are defined |
| 1459 | 1476 | const emailForm = document.getElementById('email-collection-form'); |