@tencentcloud/ai-desk-customer-uniapp
Version:
uni-app Vue2/Vue3 UIKit for AI Desk
65 lines (58 loc) • 2.1 kB
text/typescript
import { marked } from '../../../../../../utils/lib-marked';
import DOMPurify from "dompurify";
import { isH5 } from "../../../../../../utils/env";
import { getStyledATagFromText } from "../../../../../../utils/utils";
const rendererMD = new marked.Renderer();
rendererMD.image = (href, title, text) => {
return `
<img src="${href}" alt="${text}" style="max-width: 100%;">
`;
}
rendererMD.link = (href, title, text) => {
if (href) {
return getStyledATagFromText(href, 'message-marked_link', undefined, title);
}
return text;
}
rendererMD.paragraph = (text: string) => {
if (text.startsWith('<video')) {
const videoSrc = extractVideoSrc(text) || '';
if (videoSrc) {
return `<video src="${videoSrc}" preload="auto" controls/>`;
}
}
return `<p>${text}</p>`;
}
marked.setOptions({
gfm: false,
breaks: true,
pedantic: false,
sanitize: false,
smartLists: true,
smartypants: false,
});
export const extractVideoSrc = (text: string) => {
const videoSrcRegex = /<video[^>]*src=["']([^"']*)["'][^>]*>/gi;
const result = videoSrcRegex.exec(text);
return result ? result[1] : null;
}
// uni-app 的 jscore 版本比较低,不支持 Unicode 属性
// marked 库v4.0起使用了 /\p{L}\p{N}/gu 等 Unicode 属性正则表达式,这些特性在 ES2018 引入,低版本 jscore 不支持,会报错
// 使用传统的正则代替,以规避问题
// uni-app android 不支持 marked v7.0.5 或更高版本(会白屏,uni-app ios 可以用,为了更好的兼容性,目前都用 marked v4.0)
export const parseMarkdown = (text: string) => {
// 不要手动替换,如把 \n\n 替换成 p 或者 <br/>,否则可能会导致Markdown结构被破坏,进而导致 bad case
let ret = marked.parse(text, { renderer: rendererMD });
if (typeof ret === 'string') {
if (isH5) {
return DOMPurify.sanitize(ret,{
USE_PROFILES: { html: true,},
ADD_ATTR: ['onclick'],
FORBID_TAGS: ['style']
});
}
// 小程序和 app 环境不要用 DOMPurify,不支持
return ret;
}
return '';
};