Inline mvp and custom override CSS when rendering RSS posts

This commit is contained in:
2024-08-05 15:47:31 -07:00
parent 359e798cfa
commit 530bd8e350
5 changed files with 315 additions and 274 deletions

View File

@@ -13,10 +13,12 @@ use url::Url;
// TODO: figure out how to use Cow
trait Transformer {
fn should_run(&self, input: &str) -> bool;
// TODO: should input be something like `html_escape` uses:
fn should_run(&self, _html: &str) -> bool {
true
}
// TODO: should html be something like `html_escape` uses:
// <S: ?Sized + AsRef<str>>(text: &S) -> Cow<str>
fn transform(&self, input: &str) -> Result<String, TransformError>;
fn transform(&self, html: &str) -> Result<String, TransformError>;
}
// TODO: how would we make this more generic to allow good implementations of Transformer outside
@@ -35,22 +37,50 @@ struct SanitizeHtml<'a> {
}
impl<'a> Transformer for SanitizeHtml<'a> {
fn should_run(&self, _input: &str) -> bool {
true
}
fn transform(&self, input: &str) -> Result<String, TransformError> {
Ok(sanitize_html(input, self.cid_prefix, self.base_url)?)
fn transform(&self, html: &str) -> Result<String, TransformError> {
Ok(sanitize_html(html, self.cid_prefix, self.base_url)?)
}
}
struct EscapeHtml;
impl Transformer for EscapeHtml {
fn should_run(&self, input: &str) -> bool {
input.starts_with("&lt")
fn should_run(&self, html: &str) -> bool {
html.starts_with("&lt")
}
fn transform(&self, input: &str) -> Result<String, TransformError> {
Ok(html_escape::decode_html_entities(input).to_string())
fn transform(&self, html: &str) -> Result<String, TransformError> {
Ok(html_escape::decode_html_entities(html).to_string())
}
}
struct InlineStyle;
impl Transformer for InlineStyle {
fn transform(&self, html: &str) -> Result<String, TransformError> {
let css = concat!(
"/* mvp.css */\n",
include_str!("mvp.css"),
"/* Xinu Specific overrides */\n",
include_str!("custom.css"),
);
let inline_opts = InlineOptions {
inline_style_tags: false,
keep_style_tags: false,
keep_link_tags: false,
base_url: None,
load_remote_stylesheets: false,
extra_css: Some(css.into()),
preallocate_node_capacity: 32,
..InlineOptions::default()
};
Ok(match CSSInliner::new(inline_opts).inline(&html) {
Ok(inlined_html) => inlined_html,
Err(err) => {
error!("failed to inline CSS: {err}");
html.to_string()
}
})
}
}