diff --git a/server/src/lib.rs b/server/src/lib.rs index 6c339f8..13f867f 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -9,7 +9,10 @@ use async_trait::async_trait; use css_inline::{CSSInliner, InlineError, InlineOptions}; use linkify::{LinkFinder, LinkKind}; use log::{error, info, warn}; -use lol_html::{element, errors::RewritingError, rewrite_str, text, RewriteStrSettings}; +use lol_html::{ + element, errors::RewritingError, html_content::ContentType, rewrite_str, text, + RewriteStrSettings, +}; use maplit::{hashmap, hashset}; use scraper::{error::SelectorErrorKind, Html, Selector}; use thiserror::Error; @@ -129,6 +132,36 @@ impl Transformer for InlineStyle { } } +/// Frame images will extract any alt or title tags on images and place them as labels below said +/// image. +struct FrameImages; + +#[async_trait] +impl Transformer for FrameImages { + async fn transform(&self, link: &Option, html: &str) -> Result { + Ok(rewrite_str( + html, + RewriteStrSettings { + element_content_handlers: vec![element!("img[alt], img[title]", |el| { + info!("found image with alt or title {el:?}"); + let src = el + .get_attribute("src") + .unwrap_or("https://placehold.co/600x400".to_string()); + let alt = el.get_attribute("alt"); + let title = el.get_attribute("title"); + let mut frags = vec!["
".to_string(), format!(r#""#)]; + alt.map(|t| frags.push(format!("
Alt: {t}
"))); + title.map(|t| frags.push(format!("
Title: {t}
"))); + frags.push("
".to_string()); + el.replace(&frags.join("\n"), ContentType::Html); + + Ok(()) + })], + ..RewriteStrSettings::default() + }, + )?) + } +} struct AddOutlink; #[async_trait] diff --git a/server/src/newsreader.rs b/server/src/newsreader.rs index bdec610..3be5ff0 100644 --- a/server/src/newsreader.rs +++ b/server/src/newsreader.rs @@ -15,7 +15,8 @@ use crate::{ compute_offset_limit, error::ServerError, graphql::{Body, Email, Html, Message, NewsPost, Tag, Thread, ThreadSummary}, - AddOutlink, EscapeHtml, InlineStyle, SanitizeHtml, SlurpContents, StripHtml, Transformer, + AddOutlink, EscapeHtml, FrameImages, InlineStyle, SanitizeHtml, SlurpContents, StripHtml, + Transformer, }; pub fn is_newsreader_search(query: &str) -> bool { @@ -193,6 +194,7 @@ pub async fn thread(pool: &PgPool, thread_id: String) -> Result