12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- import React, { useMemo } from "react";
- import { IMAGE_SPLIT, REGEXP } from "../config/constant";
- import styles from "./ContentRender.less";
- import { htmlEncode, isUrl } from '../utils';
-
- export function renderContent(content: any) {
- let newContent = content;
- if (newContent.indexOf(IMAGE_SPLIT) !== -1) {
- newContent = newContent.split(IMAGE_SPLIT);
- newContent.pop();
- newContent = newContent.join("");
- }
- // 不包含在标签内的链接
- const innerUrl = /((http(s)?:)?\/\/)?(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[com|net|org|cn|edu|top|gov]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&//=]*)(?![^<>]*>|[^"]*?<\/a)/g;
- const data = htmlEncode(newContent)
- .replace(REGEXP, function (a, b) {
- const src = a.slice(1, -1);
-
- // 兼容旧的评
- // 因为旧的评论用 [img url] 方式存储的
- if (isUrl(src)) {
- return `<a href="${src}" rel="noopener noreferrer" target="_blank"><img class="comment-img" src="${src}" alt="${src}" /></a>`;
- }
- // 如果不存在对应的表情, 则返回原文
- // const emoji = emojiObejct[src];
- if (
- sessionStorage.getItem("emojiMap") &&
- JSON.parse(sessionStorage.getItem("emojiMap"))
- ) {
- const emoji = JSON.parse(sessionStorage.getItem("emojiMap"))[src];
- if (emoji) {
- return `<img class="comment-emoji" src="${emoji}" alt="${emoji.title}" style="width:28px"/>`;
- }
- }
- return `[${src}]`;
- })
- .replace(innerUrl, function (a, b) {
- const protocol = /^(https?:)?\/\//;
- const hasProtocol = protocol.test(a);
- const url = hasProtocol ? a : `//${a}`;
- // target="_blank" 存在安全性问题
- // return `<a href="${url}" target="_blank" rel="noopener noreferrer" >${a}</a>`;
- return `<a href="${url}">${a}</a>`;
- })
- .replace(/\n/g, "<br />");
- return data;
- }
-
- export function renderTextWithReply(
- text: string,
- replyContent: { content: any; reply: any }
- ): string {
- let newText = text;
- const { reply } = replyContent;
- if (reply) {
- newText = `${newText} //@${reply.user_name} ${reply.content}`;
- if (reply.reply) {
- return renderTextWithReply(newText, reply);
- }
- }
- return newText;
- }
-
- export function contentPreTreatment(contentString: string): string {
- let newContentString: string | Array<string> = contentString;
- let imagesString: string | undefined = "";
- if (contentString.indexOf(IMAGE_SPLIT) !== -1) {
- newContentString = newContentString.split(IMAGE_SPLIT);
- imagesString = newContentString.pop();
- newContentString = newContentString.join("");
- }
- return contentString;
- }
-
- export const ContentRender = ({ data, renderContent: propsRenderContent }: { data: any, renderContent?(data: any): any }) => {
- if (propsRenderContent) {
- return (
- <div className={styles.contentWrap}>
- {propsRenderContent(data)}
- </div>
- )
- }
- const contentString: string = useMemo(
- () => contentPreTreatment(data.content),
- [data]
- );
- return (
- <div className={styles.contentWrap}>
- <div
- dangerouslySetInnerHTML={{
- __html: renderContent(renderTextWithReply(contentString, data)),
- }}
- />
- </div>
- );
- };
|