From c7d825bddb55f2f72058afb98ab5993f34ebcd70 Mon Sep 17 00:00:00 2001 From: Debanjum Singh Solanky Date: Fri, 14 Jun 2024 11:52:23 +0530 Subject: [PATCH] Sanitize markdown in Obsidian after conversion to HTML too - Create and use a function to convert markdown to sanitized html - Remove unused Latex delimiter handling as Katex isn't used in Khoj chat on Obsidian --- src/interface/obsidian/src/chat_view.ts | 38 ++++++++++++------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/interface/obsidian/src/chat_view.ts b/src/interface/obsidian/src/chat_view.ts index 73236b1d..b175ad11 100644 --- a/src/interface/obsidian/src/chat_view.ts +++ b/src/interface/obsidian/src/chat_view.ts @@ -295,28 +295,16 @@ export class KhojChatView extends KhojPaneView { } formatHTMLMessage(message: string, raw = false, willReplace = true) { - let rendered_msg = message; + // Remove any text between [INST] and tags. These are spurious instructions for some AI chat model. + message = message.replace(/\[INST\].+(<\/s>)?/g, ''); - // Replace LaTeX delimiters with placeholders - rendered_msg = rendered_msg.replace(/\\\(/g, 'LEFTPAREN').replace(/\\\)/g, 'RIGHTPAREN') - .replace(/\\\[/g, 'LEFTBRACKET').replace(/\\\]/g, 'RIGHTBRACKET'); - - // Remove any text between [INST] and tags. These are spurious instructions for the AI chat model. - rendered_msg = rendered_msg.replace(/\[INST\].+(<\/s>)?/g, ''); - - // Sanitize the markdown to render + // Sanitize the markdown message message = DOMPurify.sanitize(message); - // Render markdow to HTML DOM element + // Convert the message to html, sanitize the message html and render it to the real DOM let chat_message_body_text_el = this.contentEl.createDiv(); chat_message_body_text_el.className = "chat-message-text-response"; - // @ts-ignore - MarkdownRenderer.renderMarkdown(message, chat_message_body_text_el, '', null); - - // Replace placeholders with LaTeX delimiters - rendered_msg = chat_message_body_text_el.innerHTML; - chat_message_body_text_el.innerHTML = rendered_msg.replace(/LEFTPAREN/g, '\\(').replace(/RIGHTPAREN/g, '\\)') - .replace(/LEFTBRACKET/g, '\\[').replace(/RIGHTBRACKET/g, '\\]'); + chat_message_body_text_el.innerHTML = this.markdownTextToSanitizedHtml(message); // Add a copy button to each chat message, if it doesn't already exist if (willReplace === true) { @@ -326,6 +314,18 @@ export class KhojChatView extends KhojPaneView { return chat_message_body_text_el; } + markdownTextToSanitizedHtml(markdownText: string): string { + // Render markdown to an unlinked DOM element + let virtualChatMessageBodyTextEl = document.createElement("div"); + + // Convert the message to html + // @ts-ignore + MarkdownRenderer.renderMarkdown(markdownText, virtualChatMessageBodyTextEl, '', null); + + // Sanitize the markdown text rendered as HTML + return DOMPurify.sanitize(virtualChatMessageBodyTextEl.innerHTML); + } + renderMessageWithReferences( chatEl: Element, message: string, @@ -401,7 +401,7 @@ export class KhojChatView extends KhojPaneView { chat_message_body_text_el.innerHTML = message; } else { // @ts-ignore - MarkdownRenderer.renderMarkdown(message, chat_message_body_text_el, '', null); + chat_message_body_text_el.innerHTML = this.markdownTextToSanitizedHtml(message); } // Add action buttons to each chat message element @@ -447,7 +447,7 @@ export class KhojChatView extends KhojPaneView { // Sanitize the markdown to render this.result = DOMPurify.sanitize(this.result); // @ts-ignore - await MarkdownRenderer.renderMarkdown(this.result, htmlElement, '', null); + htmlElement.innerHTML = this.markdownTextToSanitizedHtml(this.result); // Render action buttons for the message this.renderActionButtons(this.result, htmlElement); // Scroll to bottom of modal, till the send message input box