| @@ -767,37 +767,29 @@ | ||
| 767 | 767 | return textArea.value; |
| 768 | 768 | } |
| 769 | 769 | |
| 770 | 770 | |
| 771 | -// Update formatCodeBlocks function | |
| 772 | 771 | function formatCodeBlocks(text) { |
| 773 | - // First handle raw PHP tags | |
| 774 | - text = text.replace(/(<\?php[\s\S]*?\?>)/g, (match) => { | |
| 775 | - return `<pre><code class="language-php">${escapeHtml(match)}</code></pre>`; | |
| 776 | - }); | |
| 772 | + // Ensure the input is a string; otherwise, convert or return empty | |
| 773 | + if (typeof text !== 'string') { | |
| 774 | + console.error("formatCodeBlocks: Input is not a string:", text); | |
| 775 | + return typeof text === 'object' && text.text ? text.text : ""; // Use .text if available, else empty | |
| 776 | + } | |
| 777 | 777 | |
| 778 | - // Then handle code blocks with backticks | |
| 779 | - text = text.replace(/```php5?\n([\s\S]+?)```/gi, (match, code) => { | |
| 780 | - return `<pre><code class="language-php">${escapeHtml(code)}</code></pre>`; | |
| 778 | + const codeBlockPattern = /```(\w+)?\n?([\s\S]+?)```/g; | |
| 779 | + | |
| 780 | + return text.replace(codeBlockPattern, (_, language, codeContent) => { | |
| 781 | + language = language || 'plaintext'; | |
| 782 | + | |
| 783 | + return ` | |
| 784 | + <div class="mxchat-code-block-container"> | |
| 785 | + <button class="mxchat-copy-button" aria-label="Copy to clipboard">Copy</button> | |
| 786 | + <pre class="mxchat-code-block"><code class="mxchat-language-${language}">${escapeHtml(codeContent)}</code></pre> | |
| 787 | + </div>`; | |
| 781 | 788 | }); |
| 789 | +} | |
| 782 | 790 | |
| 783 | - return text; | |
| 784 | -} | |
| 785 | 791 | |
| 786 | -// Update escapeHtml function to preserve existing code blocks | |
| 787 | -function escapeHtml(unsafe) { | |
| 788 | - // First check if it's already a code block | |
| 789 | - if (unsafe.includes('<pre><code') || unsafe.includes('</code></pre>')) { | |
| 790 | - return unsafe; | |
| 791 | - } | |
| 792 | - | |
| 793 | - return unsafe | |
| 794 | - .replace(/&/g, "&") | |
| 795 | - .replace(/</g, "<") | |
| 796 | - .replace(/>/g, ">") | |
| 797 | - .replace(/"/g, """) | |
| 798 | - .replace(/'/g, "'"); | |
| 799 | -} | |
| 800 | 792 | // Utility function to escape HTML |
| 801 | 793 | function escapeHtml(unsafe) { |
| 802 | 794 | return unsafe |
| 803 | 795 | .replace(/&/g, "&") |
| @@ -811,14 +803,13 @@ | ||
| 811 | 803 | |
| 812 | 804 | |
| 813 | 805 | // Function to convert newlines, skipping preformatted text |
| 814 | 806 | function convertNewlinesToBreaks(text) { |
| 815 | - // Split while preserving code blocks | |
| 816 | - return text.split(/(<pre\b[^>]*>[\s\S]*?<\/pre>)/g).map(part => { | |
| 817 | - if (part.startsWith('<pre')) return part; | |
| 818 | - return part.replace(/(^|[^>])\n/g, '$1<br>'); | |
| 819 | - }).join(''); | |
| 807 | + // Regex to exclude <pre> and <code> tags from adding <br> tags | |
| 808 | + return text.replace(/(^|[^>])\n/g, '$1<br>'); | |
| 820 | 809 | } |
| 810 | + | |
| 811 | + | |
| 821 | 812 | |
| 822 | 813 | |
| 823 | 814 | |
| 824 | 815 | |