Compare commits

..

2 Commits

Author SHA1 Message Date
acd590111e chore: Release
All checks were successful
Continuous integration / Check (push) Successful in 36s
Continuous integration / Test Suite (push) Successful in 41s
Continuous integration / Trunk (push) Successful in 45s
Continuous integration / Rustfmt (push) Successful in 54s
Continuous integration / build (push) Successful in 1m35s
Continuous integration / Disallow unused dependencies (push) Successful in 3m30s
2025-04-09 19:17:52 -07:00
b5f24ba1f2 server: strip element sizing attributes and inline style 2025-04-09 19:17:19 -07:00
7 changed files with 90 additions and 40 deletions

10
Cargo.lock generated
View File

@ -3001,7 +3001,7 @@ dependencies = [
[[package]] [[package]]
name = "letterbox-notmuch" name = "letterbox-notmuch"
version = "0.10.9" version = "0.10.10"
dependencies = [ dependencies = [
"itertools", "itertools",
"log", "log",
@ -3016,14 +3016,14 @@ dependencies = [
[[package]] [[package]]
name = "letterbox-procmail2notmuch" name = "letterbox-procmail2notmuch"
version = "0.10.9" version = "0.10.10"
dependencies = [ dependencies = [
"anyhow", "anyhow",
] ]
[[package]] [[package]]
name = "letterbox-server" name = "letterbox-server"
version = "0.10.9" version = "0.10.10"
dependencies = [ dependencies = [
"ammonia", "ammonia",
"anyhow", "anyhow",
@ -3065,7 +3065,7 @@ dependencies = [
[[package]] [[package]]
name = "letterbox-shared" name = "letterbox-shared"
version = "0.10.9" version = "0.10.10"
dependencies = [ dependencies = [
"build-info", "build-info",
"letterbox-notmuch", "letterbox-notmuch",
@ -3074,7 +3074,7 @@ dependencies = [
[[package]] [[package]]
name = "letterbox-web" name = "letterbox-web"
version = "0.10.9" version = "0.10.10"
dependencies = [ dependencies = [
"build-info", "build-info",
"build-info-build", "build-info-build",

View File

@ -8,7 +8,7 @@ authors = ["Bill Thiede <git@xinu.tv>"]
edition = "2021" edition = "2021"
license = "UNLICENSED" license = "UNLICENSED"
publish = ["xinu"] publish = ["xinu"]
version = "0.10.9" version = "0.10.10"
repository = "https://git.z.xinu.tv/wathiede/letterbox" repository = "https://git.z.xinu.tv/wathiede/letterbox"
[profile.dev] [profile.dev]

View File

@ -47,8 +47,8 @@ urlencoding = "2.1.3"
#xtracing = { path = "../../xtracing" } #xtracing = { path = "../../xtracing" }
#xtracing = { git = "http://git-private.h.xinu.tv/wathiede/xtracing.git" } #xtracing = { git = "http://git-private.h.xinu.tv/wathiede/xtracing.git" }
xtracing = { version = "0.3.0", registry = "xinu" } xtracing = { version = "0.3.0", registry = "xinu" }
letterbox-notmuch = { version = "0.10.9", path = "../notmuch", registry = "xinu" } letterbox-notmuch = { version = "0.10.10", path = "../notmuch", registry = "xinu" }
letterbox-shared = { version = "0.10.9", path = "../shared", registry = "xinu" } letterbox-shared = { version = "0.10.10", path = "../shared", registry = "xinu" }
[build-dependencies] [build-dependencies]
build-info-build = "0.0.40" build-info-build = "0.0.40"

View File

@ -441,6 +441,38 @@ pub fn sanitize_html(
} }
}; };
let mut element_content_handlers = vec![ let mut element_content_handlers = vec![
// Remove width and height attributes on elements
element!("[width],[height]", |el| {
println!("width or height {el:?}");
el.remove_attribute("width");
el.remove_attribute("height");
Ok(())
}),
// Remove width and height values from inline styles
element!("[style]", |el| {
println!("style {el:?}");
let style = el.get_attribute("style").unwrap();
let style = style
.split(";")
.filter(|s| {
println!("s {s}");
let Some((k, _)) = s.split_once(':') else {
return true;
};
match k {
"width" | "max-width" | "min-width" | "height" | "max-height"
| "min-height" => false,
_ => true,
}
})
.collect::<Vec<_>>()
.join(";");
println!("style: {style}");
if let Err(e) = el.set_attribute("style", &style) {
error!("Failed to set style attribute: {e}");
}
Ok(())
}),
// Open links in new tab // Open links in new tab
element!("a[href]", |el| { element!("a[href]", |el| {
el.set_attribute("target", "_blank").unwrap(); el.set_attribute("target", "_blank").unwrap();
@ -913,3 +945,21 @@ async fn clean_title(title: &str) -> Result<String, ServerError> {
} }
Ok(title) Ok(title)
} }
#[cfg(test)]
mod tests {
use super::{SanitizeHtml, Transformer};
#[tokio::test]
async fn strip_sizes() -> Result<(), Box<dyn std::error::Error>> {
let ss = SanitizeHtml {
cid_prefix: "",
base_url: &None,
};
let input = r#"<p width=16 height=16 style="color:blue;width:16px;height:16px;">This el has width and height attributes and inline styles</p>"#;
let want = r#"<p style="color:blue;">This el has width and height attributes and inline styles</p>"#;
let got = ss.transform(&None, input).await?;
assert_eq!(got, want);
Ok(())
}
}

View File

@ -12,5 +12,5 @@ version.workspace = true
[dependencies] [dependencies]
build-info = "0.0.40" build-info = "0.0.40"
letterbox-notmuch = { version = "0.10.9", path = "../notmuch", registry = "xinu" } letterbox-notmuch = { version = "0.10.10", path = "../notmuch", registry = "xinu" }
serde = { version = "1.0.147", features = ["derive"] } serde = { version = "1.0.147", features = ["derive"] }

View File

@ -33,8 +33,8 @@ wasm-bindgen = "=0.2.100"
uuid = { version = "1.13.1", features = [ uuid = { version = "1.13.1", features = [
"js", "js",
] } # direct dep to set js feature, prevents Rng issues ] } # direct dep to set js feature, prevents Rng issues
letterbox-shared = { version = "0.10.9", path = "../shared", registry = "xinu" } letterbox-shared = { version = "0.10.10", path = "../shared", registry = "xinu" }
letterbox-notmuch = { version = "0.10.9", path = "../notmuch", registry = "xinu" } letterbox-notmuch = { version = "0.10.10", path = "../notmuch", registry = "xinu" }
seed_hooks = { version = "0.4.0", registry = "xinu" } seed_hooks = { version = "0.4.0", registry = "xinu" }
strum_macros = "0.27.1" strum_macros = "0.27.1"

View File

@ -1,18 +1,18 @@
html { html {
background-color: black; background-color: black;
} }
.mail-thread a, .mail-thread a,
.news-post a { .news-post a {
color: var(--color-link) !important; color: var(--color-link) !important;
text-decoration: underline; text-decoration: underline;
} }
.mail-thread br, .mail-thread br,
.news-post br { .news-post br {
display: block; display: block;
margin-top: 1em; margin-top: 1em;
content: " "; content: " ";
} }
.mail-thread h1, .mail-thread h1,
@ -23,61 +23,61 @@ html {
.news-post h2, .news-post h2,
.news-post h3, .news-post h3,
.news-post h4 { .news-post h4 {
margin-top: 1em !important; margin-top: 1em !important;
margin-bottom: 1em !important; margin-bottom: 1em !important;
} }
.mail-thread p, .mail-thread p,
.news-post p { .news-post p {
margin-bottom: 1em; margin-bottom: 1em;
} }
.mail-thread pre, .mail-thread pre,
.news-post pre { .news-post pre {
font-family: monospace; font-family: monospace;
background-color: #eee !important; background-color: #eee !important;
padding: 0.5em; padding: 0.5em;
white-space: break-spaces; white-space: break-spaces;
} }
.mail-thread code, .mail-thread code,
.news-post code { .news-post code {
font-family: monospace; font-family: monospace;
white-space: break-spaces; white-space: break-spaces;
} }
.mail-thread blockquote { .mail-thread blockquote {
padding-left: 1em; padding-left: 1em;
border-left: 2px solid #ddd; border-left: 2px solid #ddd;
} }
.mail-thread ol, .mail-thread ol,
.mail-thread ul { .mail-thread ul {
margin-left: 2em; margin-left: 2em;
} }
.mail-thread .noreply-news-bloomberg-com img.logo-image { .mail-thread .noreply-news-bloomberg-com a {
width: initial !important; background-color: initial !important;
max-width: 100% !important;
} }
.mail-thread .noreply-news-bloomberg-com h2 { .mail-thread .noreply-news-bloomberg-com h2 {
margin: 0 !important; margin: 0 !important;
padding: 0 !important; padding: 0 !important;
} }
/* Hackaday figures have unreadable black on dark grey */ /* Hackaday figures have unreadable black on dark grey */
.news-post figcaption.wp-caption-text { .news-post figcaption.wp-caption-text {
background-color: initial !important; background-color: initial !important;
} }
.news-post.site-nautilus .article-ad, .news-post.site-nautilus .article-ad,
.news-post.site-nautilus .primis-ad { .news-post.site-nautilus .primis-ad {
display: none !important; display: none !important;
} }
.news-post.site-slashdot .story-byline { .news-post.site-slashdot .story-byline {
display: block !important; display: block !important;
height: initial !important; height: initial !important;
overflow: auto !important; overflow: auto !important;
position: static !important; position: static !important;
} }