synpad 0.1.0

A full-featured Matrix chat client built with Dioxus
/// Sanitize HTML content for safe display.
pub fn sanitize_html(html: &str) -> String {
    ammonia::clean(html)
}

/// Strip all HTML tags, returning plain text.
pub fn strip_html(html: &str) -> String {
    ammonia::Builder::new()
        .tags(std::collections::HashSet::new())
        .clean(html)
        .to_string()
}

/// Convert Matrix HTML to safe display HTML.
///
/// Allows only safe tags used in Matrix messages.
pub fn sanitize_matrix_html(html: &str) -> String {
    let mut builder = ammonia::Builder::new();

    // Allow common formatting tags used in Matrix messages
    let tags: std::collections::HashSet<&str> = [
        "b", "i", "em", "strong", "del", "s", "strike",
        "p", "br", "hr",
        "code", "pre",
        "blockquote",
        "ul", "ol", "li",
        "a",
        "h1", "h2", "h3", "h4", "h5", "h6",
        "span", "div",
        "table", "thead", "tbody", "tfoot", "tr", "th", "td",
        "caption", "colgroup", "col",
        "sup", "sub",
        "mx-reply",
    ].iter().copied().collect();

    builder
        .tags(tags)
        .link_rel(Some("noopener noreferrer"))
        .add_tag_attributes("a", &["href", "target"])
        .add_tag_attributes("span", &["data-mx-color", "data-mx-bg-color", "data-mx-spoiler"])
        .add_tag_attributes("code", &["class"])
        .add_tag_attributes("th", &["colspan", "rowspan", "scope"])
        .add_tag_attributes("td", &["colspan", "rowspan"])
        .add_tag_attributes("col", &["span"])
        .add_tag_attributes("colgroup", &["span"]);

    let cleaned = builder.clean(html).to_string();

    // Transform spoiler spans to use a CSS class for reveal-on-click behavior
    cleaned.replace("data-mx-spoiler", "class=\"spoiler\" data-mx-spoiler")
}