// This is a fork of https://github.com/mehmetcansahin/html-purifier use lol_html::html_content::{Comment, Element}; use lol_html::{comments, element, rewrite_str, RewriteStrSettings}; pub struct AllowedElement { pub name: &'static str, pub attributes: &'static [&'static str], } const ALLOWED: &'static [AllowedElement] = &[ AllowedElement { name: "div", attributes: &[], }, AllowedElement { name: "b", attributes: &[], }, AllowedElement { name: "strong", attributes: &[], }, AllowedElement { name: "i", attributes: &[], }, AllowedElement { name: "em", attributes: &[], }, AllowedElement { name: "u", attributes: &[], }, AllowedElement { name: "a", attributes: &["href", "title"], }, AllowedElement { name: "ul", attributes: &[], }, AllowedElement { name: "ol", attributes: &[], }, AllowedElement { name: "li", attributes: &[], }, AllowedElement { name: "p", attributes: &["style"], }, AllowedElement { name: "br", attributes: &[], }, AllowedElement { name: "span", attributes: &["style"], }, AllowedElement { name: "img", attributes: &["width", "height", "alt", "src"], }, ]; pub fn process_message_html(input: &str) -> String { let element_handler = |el: &mut Element| { let find = ALLOWED.iter().find(|e| e.name.eq(&el.tag_name())); match find { Some(find) => { let remove_attributes = el .attributes() .iter() .filter(|e| find.attributes.iter().any(|a| a.eq(&e.name())) == false) .map(|m| m.name()) .collect::>(); for attr in remove_attributes { el.remove_attribute(&attr); } } None => { el.remove_and_keep_content(); } } if el.tag_name() == "a" { el.set_attribute("target", "_blank"); } Ok(()) }; let comment_handler = |c: &mut Comment| { c.remove(); Ok(()) }; let output = rewrite_str( input, RewriteStrSettings { element_content_handlers: vec![ element!("*", element_handler), comments!("*", comment_handler), ], ..RewriteStrSettings::default() }, ) .unwrap(); return output; }