From d1af24deb8ad344994c0a06b909b7a6f4bac4c94 Mon Sep 17 00:00:00 2001 From: Agando Date: Thu, 28 May 2026 06:02:08 +0200 Subject: auto: 2026-05-28_06:02 changes --- modules/core/terminal.js | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'modules/core') diff --git a/modules/core/terminal.js b/modules/core/terminal.js index 2617f79..309e477 100644 --- a/modules/core/terminal.js +++ b/modules/core/terminal.js @@ -377,7 +377,57 @@ this.scrollToBottom(); this._trimOutput(); } + _renderHTMLPreview(content) { + // AI returns raw HTML. We must HTML-escape for the srcdoc attribute + // so the parser treats it as attribute content, not tags. + // srcdoc decodes entities back to actual HTML inside the iframe. + const hasOwnStyle = /body{background:#000;color:#0f0;margin:16px;font-family:monospace;}${content}`; + const safeSrcdoc = themedContent + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/`/g, '`'); + return `
`; + } + _renderHTMLBlock(text) { + const renderRegex = /:::render-html\r?\n([\s\S]*?)\r?\n:::/g; + let match; + let lastIndex = 0; + const fragments = []; + while ((match = renderRegex.exec(text)) !== null) { + // Text before this block + const before = text.slice(lastIndex, match.index); + if (before.trim()) { + const safeBefore = before.replace(//g, ">"); + fragments.push({ type: 'text', html: `
${safeBefore}
` }); + } + fragments.push({ type: 'render', html: this._renderHTMLPreview(match[1].trim()) }); + lastIndex = match.index + match[0].length; + } + const after = text.slice(lastIndex); + if (after.trim()) { + const safeAfter = after.replace(//g, ">"); + fragments.push({ type: 'text', html: `
${safeAfter}
` }); + } + return fragments.length > 0 ? fragments : null; + } printAIResponse(text) { + const fragments = this._renderHTMLBlock(text); + if (fragments) { + for (const frag of fragments) { + const wrapper = document.createElement('div'); + wrapper.className = 'output-line' + (frag.type === 'text' ? ' ollama' : ''); + wrapper.innerHTML = frag.html; + this.outputContainer.appendChild(wrapper); + } + this.scrollToBottom(); + this._trimOutput(); + return; + } const wrapper = document.createElement('div'); wrapper.className = 'output-line ollama'; const safeText = text.replace(//g, ">"); -- cgit v1.2.3