mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-15 06:33:55 +01:00
[web] Support headings and code in labs experiment descriptions GitOrigin-RevId: 2a85f92fb5f0ce0696c1056087108ef2599547de
60 lines
1.3 KiB
TypeScript
60 lines
1.3 KiB
TypeScript
import { FC, useMemo } from 'react'
|
|
import { micromark } from 'micromark'
|
|
import DOMPurify from 'dompurify'
|
|
|
|
const PURIFY_CONFIG = {
|
|
ALLOWED_TAGS: [
|
|
'#text',
|
|
'p',
|
|
'em',
|
|
'strong',
|
|
'a',
|
|
'code',
|
|
'pre',
|
|
'h1',
|
|
'h2',
|
|
'h3',
|
|
'h4',
|
|
'h5',
|
|
'h6',
|
|
],
|
|
ALLOWED_ATTR: ['href'],
|
|
}
|
|
|
|
const LINK_REL = 'noreferrer noopener'
|
|
const LINK_TARGET = '_BLANK'
|
|
|
|
function sanitizeDescription(description: string) {
|
|
DOMPurify.addHook('afterSanitizeAttributes', node => {
|
|
if (node.nodeName === 'A') {
|
|
node.setAttribute('rel', LINK_REL)
|
|
node.setAttribute('target', LINK_TARGET)
|
|
}
|
|
})
|
|
|
|
try {
|
|
return DOMPurify.sanitize(micromark(description), PURIFY_CONFIG)
|
|
} finally {
|
|
DOMPurify.removeHook('afterSanitizeAttributes')
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Renders a labs experiment description from markdown to sanitized HTML.
|
|
* Only bold, italic, links, headings, inline code and code blocks are
|
|
* supported. Note that the language of a fenced code block is discarded, as
|
|
* the `class` attribute micromark puts it in is not allowed through.
|
|
*/
|
|
export const LabsDescription: FC<{ description: string }> = ({
|
|
description,
|
|
}) => {
|
|
const html = useMemo(() => sanitizeDescription(description), [description])
|
|
|
|
return (
|
|
<div
|
|
className="labs-description"
|
|
dangerouslySetInnerHTML={{ __html: html }}
|
|
/>
|
|
)
|
|
}
|