diff --git a/frontend/src/preferences/PromptsModal.tsx b/frontend/src/preferences/PromptsModal.tsx index f6d938dc..7f6593c4 100644 --- a/frontend/src/preferences/PromptsModal.tsx +++ b/frontend/src/preferences/PromptsModal.tsx @@ -14,38 +14,35 @@ import { UserToolType } from '../settings/types'; const variablePattern = /(\{\{\s*[^{}]+\s*\}\}|\{(?!\{)[^{}]+\})/g; -const escapeHtml = (value: string) => - value - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, '''); - -const highlightPromptVariables = (text: string) => { +const highlightPromptVariables = (text: string): React.ReactNode[] => { if (!text) { - return '​'; + return ['\u200B']; } variablePattern.lastIndex = 0; - let result = ''; + const parts: React.ReactNode[] = []; let lastIndex = 0; let match: RegExpExecArray | null; + let key = 0; while ((match = variablePattern.exec(text)) !== null) { const precedingText = text.slice(lastIndex, match.index); if (precedingText) { - result += escapeHtml(precedingText); + parts.push(precedingText); } - result += `${escapeHtml(match[0])}`; + parts.push( + + {match[0]} + , + ); lastIndex = match.index + match[0].length; } const remainingText = text.slice(lastIndex); if (remainingText) { - result += escapeHtml(remainingText); + parts.push(remainingText); } - return result || '​'; + return parts.length > 0 ? parts : ['\u200B']; }; const systemVariableOptionDefinitions = [ @@ -131,8 +128,9 @@ function PromptTextarea({ style={{ transform: `translate(${-scrollOffsets.left}px, ${-scrollOffsets.top}px)`, }} - dangerouslySetInnerHTML={{ __html: highlightedValue }} - /> + > + {highlightedValue} +