import * as xss from 'xss' ; const CUSTOM_WHITELIST = { source : [ 'src' , 'type' ] , iframe : [ 'src' , 'frameborder' , 'allowfullscreen' , 'sandbox' ] , pre : [ 'spellcheck' ] , a : [ 'target' , 'href' , 'title' , 'rel' ] , } ; const IFRAME_SANDBOX_WHITELIST = [ 'allow-scripts' , 'allow-same-origin' , 'allow-popups' , 'allow-popups-to-escape-sandbox' , 'allow-storage-access-by-user-activation' , 'allow-top-navigation-by-user-activation' , ] ; const IFRAME_DOMAIN_WHITELIST = [ 'jsfiddle.net' , 'button.like.co' , 'www.youtube.com' , 'player.vimeo.com' , 'player.youku.com' , ] ; const onTagAttr = ( tag , name , value , isWhiteAttr ) => { if ( ! isWhiteAttr ) { return ; } if ( name === 'sandbox' ) { const attrs = value . split ( ' ' ) . map ( ( a ) => a . trim ( ) . toLocaleLowerCase ( ) ) . filter ( ( a ) => IFRAME_SANDBOX_WHITELIST . includes ( a ) ) ; const newVal = attrs . join ( ' ' ) ; return `${ name }="${ newVal }"` ; } if ( tag === 'iframe' && name === 'src' ) { try { const url = new URL ( value ) ; const domain = url ?. hostname ; if ( ! IFRAME_DOMAIN_WHITELIST . includes ( domain ) ) { return '' ; } } catch ( error ) { console . error ( error ) ; return '' ; } } if ( name === 'src' ) { const newVal = value . replace ( /\s/g , '' ) ; return `${ name }="${ newVal }"` ; } } ; const onIgnoreTagAttr = ( tag , name , value ) => { see https if ( name . substr ( 0 , 5 ) === 'data-' || name . substr ( 0 , 5 ) === 'class' ) { return name + '="' + xss . escapeAttrValue ( value ) + '"' ; } } ; const onIgnoreTag = ( tag , html , options ) => { if ( tag === 'input' || tag === 'textarea' ) { return '' ; } } ; const xssOptions = { whiteList : { ... xss . whiteList , ... CUSTOM_WHITELIST } , onTagAttr , onIgnoreTagAttr , onIgnoreTag , } ; const customXSS = new xss . FilterXSS ( xssOptions ) ; export const sanitize = ( string ) => customXSS . process ( string ) ;