diff --git a/src/html.rs b/src/html.rs index 2711266..106f264 100644 --- a/src/html.rs +++ b/src/html.rs @@ -207,16 +207,54 @@ pub fn walk_and_embed_assets( } } } + "body" => { + // Find and remove background attribute(s), keep reference to the last one + let mut found_background: Option = None; + let mut i = 0; + while i < attrs_mut.len() { + let attr_name = attrs_mut[i].name.local.as_ref(); + if attr_name.eq_ignore_ascii_case("background") { + found_background = Some(attrs_mut.remove(i)); + } else { + i += 1; + } + } + + if !opt_no_images { + if let Some((data_url, _)) = found_background + .iter() + .map(|attr| attr.value.trim()) + .filter(|background| !background.is_empty()) // Skip if empty + .next() + .and_then(|background| resolve_url(&url, background).ok()) // Make absolute + .and_then(|abs_src| // Download and convert to data_url + retrieve_asset( + cache, + client, + &abs_src, + true, + "", + opt_silent, + ).ok()) + { + // Add new data_url background attribute + attrs_mut.push(Attribute { + name: QualName::new(None, ns!(), local_name!("background")), + value: Tendril::from_slice(data_url.as_ref()), + }); + } + } + } "img" => { - // Find source tags + // Find source attribute(s) 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") { + let attr_name = attrs_mut[i].name.local.as_ref(); + if attr_name.eq_ignore_ascii_case("src") { found_src = Some(attrs_mut.remove(i)); - } else if name.eq_ignore_ascii_case("data-src") { + } else if attr_name.eq_ignore_ascii_case("data-src") { found_datasrc = Some(attrs_mut.remove(i)); } else { i += 1; @@ -233,7 +271,7 @@ pub fn walk_and_embed_assets( .iter() .chain(&found_src) // Give data_url priority .map(|attr| attr.value.trim()) - .filter(|src| !src.is_empty()) // Ignore empty srcs + .filter(|src| !src.is_empty()) // Skip if empty .next() .and_then(|src| resolve_url(&url, src).ok()) // Make absolute .and_then(|abs_src| // Download and convert to data_url @@ -246,7 +284,7 @@ pub fn walk_and_embed_assets( opt_silent, ).ok()) { - // Add the new data_url src attribute + // Add new data_url src attribute attrs_mut.push(Attribute { name: QualName::new(None, ns!(), local_name!("src")), value: Tendril::from_slice(data_url.as_ref()), diff --git a/src/tests/html.rs b/src/tests/html.rs index 00c5a31..8a17c6f 100644 --- a/src/tests/html.rs +++ b/src/tests/html.rs @@ -261,6 +261,42 @@ fn test_walk_and_embed_assets_no_images() { ); } +#[test] +fn walk_and_embed_assets_no_body_background_images() { + let html = ""; + let dom = html_to_dom(&html); + let url = "http://localhost"; + let cache = &mut HashMap::new(); + + let opt_no_css: bool = false; + let opt_no_frames: bool = false; + let opt_no_js: bool = false; + let opt_no_images: bool = true; + let opt_silent = true; + + let client = Client::new(); + + walk_and_embed_assets( + cache, + &client, + &url, + &dom.document, + opt_no_css, + opt_no_js, + opt_no_images, + opt_silent, + opt_no_frames, + ); + + let mut buf: Vec = Vec::new(); + serialize(&mut buf, &dom.document, SerializeOpts::default()).unwrap(); + + assert_eq!( + buf.iter().map(|&c| c as char).collect::(), + "" + ); +} + #[test] fn test_walk_and_embed_assets_no_frames() { let html = "";