PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 2.0.0
MxChat – AI Chatbot & Content Generation for WordPress v2.0.0
3.2.21 3.2.20 3.2.19 3.2.18 3.2.17 3.2.16 3.2.15 3.2.14 3.2.12 3.2.13 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 3.2.6 3.2.5 3.2.4 3.2.3 3.2.2 3.2.1 2.0.3 2.0.4 2.0.5 2.0.6 All 152 releases
← All changes | js/chat-script.js +46 -84 2.0.52.0.0 View file →
@@ -256,48 +256,24 @@
256 256 sendMessageToChatbot(question);
257 257 });
258 258
259 259
260 -// Add this new function to handle markdown headers
261 -function formatMarkdownHeaders(text) {
262 - // Handle h1 to h6 headers
263 - return text.replace(/^(#{1,6})\s(.+)$/gm, function(match, hashes, content) {
264 - const level = hashes.length;
265 - return `<h${level} class="chat-heading">${content}</h${level}>`;
266 - });
267 -}
268 -
269 -// Update the linkify function to handle both URLs and markdown
270 -// Modified linkify function that only processes URLs in user content
260 +// Use the linkTarget in your linkify function
271 261 function linkify(inputText) {
272 - if (!inputText) return '';
273 -
274 - // Process markdown headers
275 - let processedText = formatMarkdownHeaders(inputText);
276 -
277 - // Process markdown links
278 - const markdownLinkPattern = /\[([^\]]+)\]\((https?:\/\/[^\s]+)\)/g;
279 - processedText = processedText.replace(markdownLinkPattern, (match, text, url) => {
280 - const safeUrl = encodeURI(url);
281 - const safeText = sanitizeUserInput(text);
282 - return `<a href="${safeUrl}" target="${linkTarget}">${safeText}</a>`;
283 - });
262 + // Check for already linked URLs and skip them
263 + // We use negative lookaheads to skip anything already in an <a> tag
264 + var markdownLinkPattern = /\[([^\]]+)\]\((https?:\/\/[^\s]+)\)/g;
265 + var replacedText = inputText.replace(markdownLinkPattern, '<a href="$2" target="' + linkTarget + '">$1</a>');
284 266
285 - // Process standalone URLs
286 - const urlPattern = /(^|[^">])(https?:\/\/[^\s<]+)/gim;
287 - processedText = processedText.replace(urlPattern, (match, prefix, url) => {
288 - const safeUrl = encodeURI(url);
289 - return `${prefix}<a href="${safeUrl}" target="${linkTarget}">${url}</a>`;
290 - });
267 + // Replace standalone URLs not already in an <a> tag
268 + var urlPattern = /(^|[^">])(https?:\/\/[^\s<]+)/gim;
269 + replacedText = replacedText.replace(urlPattern, '$1<a href="$2" target="' + linkTarget + '">$2</a>');
291 270
292 - // Process www. URLs
293 - const wwwPattern = /(^|[^">])(www\.[\S]+(\b|$))(?![^<]*<\/a>)/gim;
294 - processedText = processedText.replace(wwwPattern, (match, prefix, url) => {
295 - const safeUrl = encodeURI(`http://${url}`);
296 - return `${prefix}<a href="${safeUrl}" target="${linkTarget}">${url}</a>`;
297 - });
271 + // Replace "www." prefixed URLs not already in an <a> tag
272 + var wwwPattern = /(^|[^">])(www\.[\S]+(\b|$))(?![^<]*<\/a>)/gim;
273 + replacedText = replacedText.replace(wwwPattern, '$1<a href="http://$2" target="' + linkTarget + '">$2</a>');
298 274
299 - return processedText;
275 + return replacedText;
300 276 }
301 277
302 278
303 279 function scrollElementToTop(element) {
@@ -403,10 +379,10 @@
403 379 if (response.data && response.data.filename) {
404 380 showActivePdf(response.data.filename);
405 381 activePdfFile = response.data.filename;
406 382 }
407 -
408 - // Add redirect check here
383 +
384 + // Add redirect check here
409 385 if (response.redirect_url) {
410 386 let responseText = response.text || '';
411 387 if (responseText) {
412 388 replaceLastMessage("bot", responseText);
@@ -416,9 +392,8 @@
416 392 }, 1500);
417 393 return;
418 394 }
419 395
420 -
421 396 // Check for live agent response
422 397 if (response.success && response.data && response.data.status === 'waiting_for_agent') {
423 398 updateChatModeIndicator('agent');
424 399 return;
@@ -467,17 +442,11 @@
467 442 }
468 443 });
469 444 }
470 445
471 -// Sanitize only user input
472 -function sanitizeUserInput(text) {
473 - const div = document.createElement('div');
474 - div.textContent = text;
475 - return div.innerHTML;
476 -}
446 +function appendMessage(sender, messageText = '', messageHtml = '', images = [], isTemporary = false) {
447 + //console.log("Appending message. Sender:", sender, "Content:", messageText);
477 448
478 -// Modified appendMessage function that only sanitizes user content
479 -function appendMessage(sender, messageText = '', messageHtml = '', images = [], isTemporary = false) {
480 449 try {
481 450 // Determine styles based on sender type
482 451 let messageClass, bgColor, fontColor;
483 452
@@ -484,52 +453,42 @@
484 453 if (sender === "user") {
485 454 messageClass = "user-message";
486 455 bgColor = userMessageBgColor;
487 456 fontColor = userMessageFontColor;
488 - // Only sanitize user input
489 - messageText = sanitizeUserInput(messageText);
490 - } else if (sender === "agent") {
491 - messageClass = "agent-message";
492 - bgColor = liveAgentMessageBgColor;
493 - fontColor = liveAgentMessageFontColor;
494 - } else {
457 + } else if (sender === "agent") {
458 + messageClass = "agent-message";
459 + bgColor = liveAgentMessageBgColor;
460 + fontColor = liveAgentMessageFontColor;
461 + } else {
495 462 messageClass = "bot-message";
496 463 bgColor = botMessageBgColor;
497 464 fontColor = botMessageFontColor;
498 465 }
499 466
500 - const messageDiv = $('<div>')
501 - .addClass(messageClass)
502 - .css({
503 - 'background': bgColor,
504 - 'color': fontColor,
505 - 'margin-bottom': '1em'
506 - });
467 + const messageDiv = $('<div>')
468 + .addClass(messageClass)
469 + .css({
470 + 'background': bgColor,
471 + 'color': fontColor,
472 + });
507 473
508 - // Process the message content based on sender
509 - let fullMessage;
510 - if (sender === "user") {
511 - // For user messages, apply linkify after sanitization
512 - fullMessage = linkify(formatBoldText(convertNewlinesToBreaks(formatCodeBlocks(messageText))));
513 - } else {
514 - // For bot/agent messages, preserve HTML
515 - fullMessage = messageText;
516 - }
474 + // Add CSS for paragraphs
475 + messageDiv.css({
476 + 'margin-bottom': '1em'
477 + });
517 478
479 + // Format and process the message content
480 + let fullMessage = linkify(formatBoldText(convertNewlinesToBreaks(formatCodeBlocks(messageText))));
481 +
518 482 // Add images if provided
519 483 if (images && images.length > 0) {
520 484 fullMessage += '<div class="image-gallery">';
521 485 images.forEach(img => {
522 - // Ensure image URLs and titles are properly escaped
523 - const safeTitle = sanitizeUserInput(img.title);
524 - const safeUrl = encodeURI(img.image_url);
525 - const safeThumbnail = encodeURI(img.thumbnail_url);
526 -
527 486 fullMessage += `
528 487 <div style="margin-bottom: 10px;">
529 - <strong>${safeTitle}</strong><br>
530 - <a href="${safeUrl}" target="_blank">
531 - <img src="${safeThumbnail}" alt="${safeTitle}" style="max-width: 100px; height: auto; margin: 5px;" />
488 + <strong>${img.title}</strong><br>
489 + <a href="${img.image_url}" target="_blank">
490 + <img src="${img.thumbnail_url}" alt="${img.title}" style="max-width: 100px; height: auto; margin: 5px;" />
532 491 </a>
533 492 </div>`;
534 493 });
535 494 fullMessage += '</div>';
@@ -535,20 +494,23 @@
535 494 fullMessage += '</div>';
536 495 }
537 496
538 497 // Append HTML content if provided
539 - if (messageHtml && sender !== "user") {
498 + if (messageHtml) {
540 499 fullMessage += '<br><br>' + messageHtml;
541 500 }
542 501
543 502 messageDiv.html(fullMessage);
544 503
504 + // Add a class for temporary messages if needed
545 505 if (isTemporary) {
546 506 messageDiv.addClass('temporary-message');
547 507 }
548 508
549 - messageDiv.hide().appendTo('#chat-box').fadeIn(300, function() {
509 + // Append the message to the chat box
510 + messageDiv.hide().appendTo('#chat-box').fadeIn(300, function () {
550 511 if (sender === "bot") {
512 + // After bot's message is displayed, scroll the last user message to the top
551 513 const lastUserMessage = $('#chat-box').find('.user-message').last();
552 514 if (lastUserMessage.length) {
553 515 scrollElementToTop(lastUserMessage);
554 516 }
@@ -555,13 +517,13 @@
555 517 }
556 518 });
557 519
558 520 if (messageText.id) {
559 - lastSeenMessageId = messageText.id;
560 - hideNotification();
561 - }
521 + lastSeenMessageId = messageText.id;
522 + hideNotification();
523 + }
562 524 } catch (error) {
563 - console.error("Error rendering message:", error);
525 + console.error("Error rendering message with images:", error);
564 526 }
565 527 }
566 528
567 529