packageDocumentation module import * as React from "react" ; import * as DOMPurify from "dompurify" ; import { isHTMLElement , isReactMessage , MessageType } from "./MessageType" ; import { ClassNameProps } from "../utils/Props" ; public export interface MessageRendererProps extends ClassNameProps { /** Message to render */ message : MessageType ; /** Indicates whether to use a `span` or `div` element for rendering */ useSpan ? : boolean ; } public export function MessageRenderer ( props ) { let messageNode = null ; const OutElement = props . useSpan ? "span" : "div" ; if ( typeof props . message === "string" ) { messageNode = < OutElement className = { props . className } > { props . message } < /OutElement>; } else if ( isHTMLElement ( props . message ) ) { const sanitizer = DOMPurify . sanitize ; let validAnchors = false ; let hasAnchors = false ; const isAnchorValid = ( anchor ) : boolean => { return anchor . hasAttribute ( "rel" ) && ( anchor . rel . includes ( "noopener" ) || anchor . rel . includes ( "noreferrer" ) ) ; } ; const checkChildAnchors = ( parent ) => { const children = Array . from ( parent . children ) ; for ( const child of children ) { if ( child . hasAttribute ( "target" ) && ( child as HTMLAnchorElement ) . target === "_blank" ) { hasAnchors = true ; validAnchors = isAnchorValid ( child as HTMLAnchorElement ) ; if ( ! validAnchors ) { return ; } } checkChildAnchors ( child ) ; } } ; if ( props . message . hasAttribute ( "target" ) && ( props . message as HTMLAnchorElement ) . target === "_blank" ) { hasAnchors = true ; validAnchors = isAnchorValid ( props . message as HTMLAnchorElement ) ; } else { if ( props . message . children ) { checkChildAnchors ( props . message ) ; } } let sanitizedHtml ; if ( hasAnchors && validAnchors ) { sanitizedHtml = sanitizer ( props . message . outerHTML , { ADD_ATTR : [ "target" ] } ) ; } else { sanitizedHtml = sanitizer ( props . message . outerHTML ) ; } messageNode = < OutElement className = { props . className } dangerouslySetInnerHTML = { { __html : sanitizedHtml } } />; } else { if ( isReactMessage ( props . message ) ) messageNode = < OutElement className = { props . className } > { props . message . reactNode } < /OutElement>; } return messageNode ; }