|
@@ -56,26 +56,19 @@ export const formatMdToHtml = (exist_metrics, md) => {
|
|
|
|
|
|
|
|
const placeholderText = '请输入特别提示词,以此统一文本结构、规范输出样式';
|
|
const placeholderText = '请输入特别提示词,以此统一文本结构、规范输出样式';
|
|
|
|
|
|
|
|
- // 直接在 markdown 解析前处理特殊标签,使用 HTML 注释作为占位符
|
|
|
|
|
- // 这样 markdown 解析器会保留注释,不会把 (special) 当成链接
|
|
|
|
|
- let specialCounter = 0;
|
|
|
|
|
- const specialInputs = [];
|
|
|
|
|
-
|
|
|
|
|
- // 使用 HTML 注释作为占位符,避免被 markdown 解析器处理
|
|
|
|
|
|
|
+ // 直接在 markdown 解析前将 (special)...(/special) 替换为 input 元素
|
|
|
|
|
+ // 使用 DOMParser 确保 HTML 转义正确
|
|
|
md = md.replace(/\(special\)([\s\S]*?)\(\/special\)/gi, (match, content) => {
|
|
md = md.replace(/\(special\)([\s\S]*?)\(\/special\)/gi, (match, content) => {
|
|
|
- const inputHtml = `<input type="text" data-special="true" autocomplete="off" value="${content.trim()}" placeholder="${placeholderText}" contenteditable="false" style="background-color: #fff3cd; border: 1px solid #ffeeba; border-radius: 4px; padding: 2px 8px; color: #856404; font-weight: 500; min-width: 360px; display: inline-block; outline: none; font-size: inherit; font-family: inherit; vertical-align: middle; box-sizing: border-box; margin-left:5px;"/>`;
|
|
|
|
|
- specialInputs.push(inputHtml);
|
|
|
|
|
- return `<!--SPECIAL_INPUT_${specialCounter}-->`;
|
|
|
|
|
|
|
+ // 使用 DOMParser 转义内容,防止 XSS 和 HTML 解析问题
|
|
|
|
|
+ const doc = new DOMParser().parseFromString(`<div>${content.trim()}</div>`, 'text/html');
|
|
|
|
|
+ const escapedValue = doc.querySelector('div').textContent;
|
|
|
|
|
+
|
|
|
|
|
+ return `<input type="text" data-special="true" autocomplete="off" value="${escapedValue}" placeholder="${placeholderText}" contenteditable="false" style="background-color: #fff3cd; border: 1px solid #ffeeba; border-radius: 4px; padding: 2px 8px; color: #856404; font-weight: 500; min-width: 360px; display: inline-block; outline: none; font-size: inherit; font-family: inherit; vertical-align: middle; box-sizing: border-box; margin:0 5px;"/>`;
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- // 再解析 markdown 为 html
|
|
|
|
|
|
|
+ // 解析 markdown 为 html
|
|
|
let html = marked.parse(md);
|
|
let html = marked.parse(md);
|
|
|
|
|
|
|
|
- // 将 HTML 注释替换为实际的 input 元素
|
|
|
|
|
- for (let i = 0; i < specialInputs.length; i++) {
|
|
|
|
|
- html = html.replace(`<!--SPECIAL_INPUT_${i}-->`, specialInputs[i]);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
// 只转换存在的指标
|
|
// 只转换存在的指标
|
|
|
html = html.replace(/\[\[([^_]+?)_([^\]]+?)\]\]/g, (match, text, uid) => {
|
|
html = html.replace(/\[\[([^_]+?)_([^\]]+?)\]\]/g, (match, text, uid) => {
|
|
|
// 检查指标名称是否存在
|
|
// 检查指标名称是否存在
|