72 lines
1.7 KiB
TypeScript
72 lines
1.7 KiB
TypeScript
import sanitizeHtml from "sanitize-html";
|
|
import type { JSONContent } from "@tiptap/react";
|
|
import { generateHTML } from "@tiptap/html";
|
|
import StarterKit from "@tiptap/starter-kit";
|
|
import Underline from "@tiptap/extension-underline";
|
|
import Link from "@tiptap/extension-link";
|
|
import { TextStyle } from "@tiptap/extension-text-style";
|
|
import Color from "@tiptap/extension-color";
|
|
import Highlight from "@tiptap/extension-highlight";
|
|
import { FontFamily } from "@/lib/tiptap/fontFamily";
|
|
|
|
export function richTextToSafeHtml(doc: JSONContent): string {
|
|
const raw = generateHTML(doc, [
|
|
StarterKit,
|
|
Underline,
|
|
Link.configure({
|
|
openOnClick: false,
|
|
autolink: false,
|
|
HTMLAttributes: { rel: "noopener noreferrer", target: "_blank" },
|
|
}),
|
|
TextStyle,
|
|
FontFamily,
|
|
Color,
|
|
Highlight,
|
|
]);
|
|
|
|
return sanitizeHtml(raw, {
|
|
allowedTags: [
|
|
"p",
|
|
"br",
|
|
"h1",
|
|
"h2",
|
|
"h3",
|
|
"blockquote",
|
|
"strong",
|
|
"em",
|
|
"u",
|
|
"a",
|
|
"ul",
|
|
"ol",
|
|
"li",
|
|
"code",
|
|
"pre",
|
|
"span"
|
|
],
|
|
allowedAttributes: {
|
|
a: ["href", "rel", "target"],
|
|
span: ["style"],
|
|
code: ["class"],
|
|
pre: ["class"],
|
|
p: ["class"],
|
|
h1: ["class"],
|
|
h2: ["class"],
|
|
h3: ["class"],
|
|
blockquote: ["class"],
|
|
ul: ["class"],
|
|
ol: ["class"],
|
|
li: ["class"]
|
|
},
|
|
allowedSchemes: ["http", "https", "mailto"],
|
|
allowProtocolRelative: false,
|
|
allowedStyles: {
|
|
span: {
|
|
color: [/^#[0-9a-fA-F]{3,8}$/],
|
|
"background-color": [/^#[0-9a-fA-F]{3,8}$/],
|
|
"font-family": [/^(Inter|ui-sans-serif|ui-serif|ui-monospace)$/],
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|