server: add option to inline CSS before slurping contents

This commit is contained in:
2025-01-25 16:09:05 -08:00
parent 906ebd73b2
commit 9842c8c99c
3 changed files with 87 additions and 6 deletions

View File

@@ -110,6 +110,48 @@ impl Transformer for StripHtml {
}
}
struct InlineRemoteStyle<'a> {
base_url: &'a Option<Url>,
}
#[async_trait]
impl<'a> Transformer for InlineRemoteStyle<'a> {
async fn transform(&self, _: &Option<Url>, html: &str) -> Result<String, TransformError> {
let css = concat!(
"/* chrome-default.css */\n",
include_str!("chrome-default.css"),
"\n/* mvp.css */\n",
include_str!("mvp.css"),
"\n/* Xinu Specific overrides */\n",
include_str!("custom.css"),
);
let inline_opts = InlineOptions {
//inline_style_tags: true,
//keep_style_tags: false,
//keep_link_tags: true,
base_url: self.base_url.clone(),
//load_remote_stylesheets: true,
//preallocate_node_capacity: 32,
..InlineOptions::default()
};
//info!("HTML:\n{html}");
info!("base_url: {:#?}", self.base_url);
Ok(
match CSSInliner::options()
.base_url(self.base_url.clone())
.build()
.inline(&html)
{
Ok(inlined_html) => inlined_html,
Err(err) => {
error!("failed to inline remote CSS: {err}");
html.to_string()
}
},
)
}
}
struct InlineStyle;
#[async_trait]
@@ -229,6 +271,7 @@ impl Transformer for AddOutlink {
struct SlurpContents {
cacher: Arc<Mutex<FilesystemCacher>>,
inline_css: bool,
site_selectors: HashMap<String, Vec<Selector>>,
}
@@ -267,6 +310,36 @@ impl Transformer for SlurpContents {
cacher.set(link.as_str(), body.as_bytes());
body
};
let body = Arc::new(body);
let base_url = Some(link.clone());
let body = if self.inline_css {
let inner_body = Arc::clone(&body);
let res = tokio::task::spawn_blocking(move || {
let res = CSSInliner::options()
.base_url(base_url)
.build()
.inline(&inner_body);
match res {
Ok(inlined_html) => inlined_html,
Err(err) => {
error!("failed to inline remote CSS: {err}");
Arc::into_inner(inner_body).expect("failed to take body out of Arc")
}
}
})
.await;
match res {
Ok(inlined_html) => inlined_html,
Err(err) => {
error!("failed to spawn inline remote CSS: {err}");
Arc::into_inner(body).expect("failed to take body out of Arc")
}
}
} else {
Arc::into_inner(body).expect("failed to take body out of Arc")
};
let doc = Html::parse_document(&body);
let mut results = Vec::new();
@@ -277,7 +350,7 @@ impl Transformer for SlurpContents {
//warn!("couldn't find '{:?}' in {}", selector, link);
}
}
Ok(results.join("<hr>"))
Ok(results.join("<br>"))
}
}