diff --git a/src/html.rs b/src/html.rs
index d43c233..869c220 100644
--- a/src/html.rs
+++ b/src/html.rs
@@ -2,7 +2,7 @@ use html5ever::interface::QualName;
use html5ever::parse_document;
use html5ever::rcdom::{Handle, NodeData, RcDom};
use html5ever::serialize::{serialize, SerializeOpts};
-use html5ever::tendril::{format_tendril, TendrilSink};
+use html5ever::tendril::{format_tendril, Tendril, TendrilSink};
use html5ever::tree_builder::{Attribute, TreeSink};
use html5ever::{local_name, namespace_url, ns};
use http::retrieve_asset;
@@ -168,35 +168,50 @@ pub fn walk_and_embed_assets(
}
}
"img" => {
- for attr in attrs_mut.iter_mut() {
- if &attr.name.local == "src" {
- let value = attr.value.to_string();
-
- // Ignore images with empty source
- if value == str!() {
- continue;
- }
-
- if opt_no_images {
- attr.value.clear();
- attr.value.push_slice(TRANSPARENT_PIXEL);
- } else {
- let src_full_url: String =
- resolve_url(&url, &value).unwrap_or(str!());
- let (img_dataurl, _) = retrieve_asset(
- cache,
- client,
- &src_full_url,
- true,
- "",
- opt_silent,
- )
- .unwrap_or((str!(), str!()));
- attr.value.clear();
- attr.value.push_slice(img_dataurl.as_str());
- }
+ // Find source tags
+ let mut found_src: Option = None;
+ let mut found_datasrc: Option = None;
+ let mut i = 0;
+ while i < attrs_mut.len() {
+ let name = attrs_mut[i].name.local.as_ref();
+ if name.eq_ignore_ascii_case("src") {
+ found_src = Some(attrs_mut.remove(i));
+ } else if name.eq_ignore_ascii_case("data-src") {
+ found_datasrc = Some(attrs_mut.remove(i));
+ } else {
+ i += 1;
}
}
+
+ // If images are disabled, clear both sources
+ if opt_no_images {
+ attrs_mut.push(Attribute {
+ name: QualName::new(None, ns!(), local_name!("src")),
+ value: Tendril::from_slice(TRANSPARENT_PIXEL),
+ });
+ } else if let Some((dataurl, _)) = (&found_datasrc)
+ .into_iter()
+ .chain(&found_src) // Give dataurl priority
+ .map(|attr| &attr.value)
+ .filter(|src| !src.is_empty()) // Ignore empty srcs
+ .next()
+ .and_then(|src| resolve_url(&url, src).ok()) // Make absolute
+ .and_then(|abs_src| // Download and convert to dataurl
+ retrieve_asset(
+ cache,
+ client,
+ &abs_src,
+ true,
+ "",
+ opt_silent,
+ ).ok())
+ {
+ // Add the new dataurl src attribute
+ attrs_mut.push(Attribute {
+ name: QualName::new(None, ns!(), local_name!("src")),
+ value: Tendril::from_slice(dataurl.as_ref()),
+ });
+ }
}
"source" => {
for attr in attrs_mut.iter_mut() {