import cn from "classnames" ; import React , { FunctionComponent , useMemo } from "react" ; import markPhrasesHTML from "coral-admin/helpers/markHTMLNode" ; import { ALL_FEATURES , createSanitize , Sanitize , WORDLIST_FORBID_TAGS , } from "coral-common/helpers/sanitize" ; import { GQLWordlistMatch } from "coral-framework/schema" ; import styles from "./CommentContent.css" ; /**
 * Return a purify instance that will be used to handle HTML content.
 */ const getSanitize = ( ( ) => { let sanitizers = null ; return ( highlight ) => { if ( ! sanitizers ) { sanitizers = { default : createSanitize ( window , { features : ALL_FEATURES , } ) , highlight : createSanitize ( window , { normalize : true , features : ALL_FEATURES , config : { FORBID_TAGS : highlight ? WORDLIST_FORBID_TAGS : [ ] , } , } ) , } ; } if ( highlight ) { return sanitizers . highlight ! ; } return sanitizers . default ! ; } ; } ) ( ) ; interface Props { className ? : string ; children : string | React . ReactElement ; highlight ? : boolean ; bannedWords ? : Readonly < Readonly < GQLWordlistMatch > [ ] > ; suspectWords ? : Readonly < Readonly < GQLWordlistMatch > [ ] > ; } const CommentContent = ( { className , children , bannedWords , suspectWords , highlight = false , } ) => { const parsed = useMemo ( ( ) => { if ( typeof children !== "string" ) { return null ; } let words = [ ] ; if ( bannedWords ) { words = [ ... words , ... bannedWords ] ; } if ( suspectWords ) { words = [ ... words , ... suspectWords ] ; } const node = getSanitize ( highlight ) ( children ) ; const replacement = markPhrasesHTML ( node . innerHTML , words ) ; node . innerHTML = replacement ; return node ; } , [ bannedWords , children , highlight , suspectWords ] ) ; if ( parsed ) { return ( < div className = { cn ( className , styles . root , highlight && styles . highlight ) } dangerouslySetInnerHTML = { { __html : parsed . innerHTML } } />); } return < > { children } < />; } ; export default CommentContent ;