@@ -1118,3 +1118,160 @@ function hideAxisMinMax(selected,chart_number,rangeEnabled){
11181118 $ ( `.axis_range_max_${ chart_number } ` ) . removeClass ( 'hidden' ) ;
11191119 }
11201120} ;
1121+
1122+
1123+
1124+ /* HTML Sanitizer */
1125+
1126+ var HtmlSanitizer = new ( function ( ) {
1127+
1128+ var tagWhitelist_ = {
1129+ 'A' : false , 'ABBR' : true , 'B' : true , 'BLOCKQUOTE' : true , 'BODY' : true , 'BR' : true , 'CENTER' : false , 'CODE' : false , 'DIV' : false , 'EM' : true , 'FONT' : false ,
1130+ 'H1' : true , 'H2' : true , 'H3' : true , 'H4' : true , 'H5' : true , 'H6' : true , 'HR' : true , 'I' : true , 'IMG' : false , 'LABEL' : true , 'LI' : true , 'OL' : true , 'P' : true , 'PRE' : false ,
1131+ 'SMALL' : true , 'SOURCE' : false , 'SPAN' : true , 'STRONG' : true , 'TABLE' : false , 'TBODY' : false , 'TR' : false , 'TD' : false , 'TH' : false , 'THEAD' : false , 'UL' : true , 'U' : true , 'VIDEO' : false
1132+ } ;
1133+
1134+ var contentTagWhiteList_ = { 'FORM' : true } ; //tags that will be converted to DIVs
1135+
1136+ var attributeWhitelist_ = { 'align' : true , 'color' : true , 'controls' : true , 'height' : true , 'href' : true , 'src' : true , 'style' : true , 'target' : true , 'title' : true , 'type' : true , 'width' : true } ;
1137+
1138+ var cssWhitelist_ = { 'color' : true , 'background-color' : true , 'font-size' : true , 'text-align' : true , 'text-decoration' : true , 'font-weight' : true } ;
1139+
1140+ var schemaWhiteList_ = [ 'http:' , 'https:' , 'data:' , 'm-files:' , 'file:' , 'ftp:' ] ; //which "protocols" are allowed in "href", "src" etc
1141+
1142+ var uriAttributes_ = { 'href' : true , 'action' : true } ;
1143+
1144+ this . SanitizeHtml = function ( input ) {
1145+ input = input . trim ( ) ;
1146+ if ( input == "" ) return "" ; //to save performance and not create iframe
1147+
1148+ //firefox "bogus node" workaround
1149+ if ( input == "<br>" ) return "" ;
1150+
1151+ var iframe = document . createElement ( 'iframe' ) ;
1152+ if ( iframe [ 'sandbox' ] === undefined ) {
1153+ alert ( 'Your browser does not support sandboxed iframes. Please upgrade to a modern browser.' ) ;
1154+ return '' ;
1155+ }
1156+ iframe [ 'sandbox' ] = 'allow-same-origin' ;
1157+ iframe . style . display = 'none' ;
1158+ document . body . appendChild ( iframe ) ; // necessary so the iframe contains a document
1159+ var iframedoc = iframe . contentDocument || iframe . contentWindow . document ;
1160+ if ( iframedoc . body == null ) iframedoc . write ( "<body></body>" ) ; // null in IE
1161+ iframedoc . body . innerHTML = input ;
1162+
1163+ function makeSanitizedCopy ( node ) {
1164+ if ( node . nodeType == Node . TEXT_NODE ) {
1165+ var newNode = node . cloneNode ( true ) ;
1166+ } else if ( node . nodeType == Node . ELEMENT_NODE && ( tagWhitelist_ [ node . tagName ] || contentTagWhiteList_ [ node . tagName ] ) ) {
1167+
1168+ //remove useless empty spans (lots of those when pasting from MS Outlook)
1169+ if ( ( node . tagName == "SPAN" || node . tagName == "B" || node . tagName == "I" || node . tagName == "U" )
1170+ && node . innerHTML . trim ( ) == "" ) {
1171+ return document . createDocumentFragment ( ) ;
1172+ }
1173+
1174+ if ( contentTagWhiteList_ [ node . tagName ] )
1175+ newNode = iframedoc . createElement ( 'DIV' ) ; //convert to DIV
1176+ else
1177+ newNode = iframedoc . createElement ( node . tagName ) ;
1178+
1179+ for ( var i = 0 ; i < node . attributes . length ; i ++ ) {
1180+ var attr = node . attributes [ i ] ;
1181+ if ( attributeWhitelist_ [ attr . name ] ) {
1182+ if ( attr . name == "style" ) {
1183+ for ( s = 0 ; s < node . style . length ; s ++ ) {
1184+ var styleName = node . style [ s ] ;
1185+ if ( cssWhitelist_ [ styleName ] )
1186+ newNode . style . setProperty ( styleName , node . style . getPropertyValue ( styleName ) ) ;
1187+ }
1188+ }
1189+ else {
1190+ if ( uriAttributes_ [ attr . name ] ) { //if this is a "uri" attribute, that can have "javascript:" or something
1191+ if ( attr . value . indexOf ( ":" ) > - 1 && ! startsWithAny ( attr . value , schemaWhiteList_ ) )
1192+ continue ;
1193+ }
1194+ newNode . setAttribute ( attr . name , attr . value ) ;
1195+ }
1196+ }
1197+ }
1198+ for ( i = 0 ; i < node . childNodes . length ; i ++ ) {
1199+ var subCopy = makeSanitizedCopy ( node . childNodes [ i ] ) ;
1200+ newNode . appendChild ( subCopy , false ) ;
1201+ }
1202+ } else {
1203+ newNode = document . createDocumentFragment ( ) ;
1204+ }
1205+ return newNode ;
1206+ } ;
1207+
1208+ var resultElement = makeSanitizedCopy ( iframedoc . body ) ;
1209+ document . body . removeChild ( iframe ) ;
1210+ return resultElement . innerHTML
1211+ . replace ( / < b r [ ^ > ] * > ( \S ) / g, "<br>\n$1" )
1212+ . replace ( / d i v > < d i v / g, "div>\n<div" ) ; //replace is just for cleaner code
1213+ }
1214+
1215+ function startsWithAny ( str , substrings ) {
1216+ for ( var i = 0 ; i < substrings . length ; i ++ ) {
1217+ if ( str . indexOf ( substrings [ i ] ) == 0 ) {
1218+ return true ;
1219+ }
1220+ }
1221+ return false ;
1222+ }
1223+
1224+ this . AllowedTags = tagWhitelist_ ;
1225+ this . AllowedAttributes = attributeWhitelist_ ;
1226+ this . AllowedCssStyles = cssWhitelist_ ;
1227+ this . AllowedSchemas = schemaWhiteList_ ;
1228+ } ) ;
1229+
1230+
1231+ /* Sanitize HTML */
1232+ $ ( "body" ) . on ( 'change' , '.textbox_desc' , function ( ) {
1233+ var content = $ ( this ) . val ( ) ;
1234+ var html = HtmlSanitizer . SanitizeHtml ( content ) ;
1235+ $ ( this ) . val ( html ) ;
1236+ } ) ;
1237+
1238+
1239+ $ ( "body" ) . on ( 'change' , '[id^=table_field_title_]' , function ( ) {
1240+ var content = $ ( this ) . val ( ) ;
1241+ var html = HtmlSanitizer . SanitizeHtml ( content ) ;
1242+ $ ( this ) . val ( html ) ;
1243+ } ) ;
1244+
1245+ $ ( "body" ) . on ( 'change' , '[id^=chart_field_title_]' , function ( ) {
1246+ var content = $ ( this ) . val ( ) ;
1247+ var html = HtmlSanitizer . SanitizeHtml ( content ) ;
1248+ $ ( this ) . val ( html ) ;
1249+ } ) ;
1250+
1251+ $ ( "body" ) . on ( 'change' , '[id^=chart_field_desc_]' , function ( ) {
1252+ var content = $ ( this ) . val ( ) ;
1253+ var html = HtmlSanitizer . SanitizeHtml ( content ) ;
1254+ $ ( this ) . val ( html ) ;
1255+ } ) ;
1256+
1257+ $ ( "body" ) . on ( 'change' , '[id^=map_custom_title_field_]' , function ( ) {
1258+ var content = $ ( this ) . val ( ) ;
1259+ var html = HtmlSanitizer . SanitizeHtml ( content ) ;
1260+ $ ( this ) . val ( html ) ;
1261+ } ) ;
1262+
1263+ $ ( "body" ) . on ( 'change' , '[id^=field-description]' , function ( ) {
1264+ var content = $ ( this ) . val ( ) ;
1265+ var html = HtmlSanitizer . SanitizeHtml ( content ) ;
1266+ $ ( this ) . val ( html ) ;
1267+ } ) ;
1268+
1269+ $ ( "body" ) . on ( 'change' , '[id^=field-additional_description]' , function ( ) {
1270+ var content = $ ( this ) . val ( ) ;
1271+ var html = HtmlSanitizer . SanitizeHtml ( content ) ;
1272+ $ ( this ) . val ( html ) ;
1273+ } ) ;
1274+
1275+
1276+
1277+
0 commit comments