Repository: jugglerchris/rust-html2text
Pull request #136 (2024-03-03 11:09:39)

Improve height-0 detection.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f1aac4a..c1af223 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,12 @@ Possible log types:
 - `[fixed]` for any bug fixes.
 - `[security]` to invite users to upgrade in case of vulnerabilities.
 
+### 0.12.4
+
+- [changed] Update the previous `max-height: 0` to also look at `height: 0` and require
+  `overflow: hidden` as well.
+  This helps with a hack some e-mail senders use for e-mail previews.  (thanks tkapias)
+
 ### 0.12.3
 
 - [changed] Treat `max-height: 0` as if it's `display: none` when CSS is enabled.
diff --git a/Cargo.toml b/Cargo.toml
index bf545d8..1913a15 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "html2text"
-version = "0.12.3"
+version = "0.12.4"
 authors = ["Chris Emerson <github@mail.nosreme.org>"]
 description = "Render HTML as plain text."
 repository = "https://github.com/jugglerchris/rust-html2text/"
diff --git a/src/css.rs b/src/css.rs
index 1303d98..cf8d36c 100644
--- a/src/css.rs
+++ b/src/css.rs
@@ -7,6 +7,7 @@ use lightningcss::{
     declaration::DeclarationBlock,
     properties::{
         display::{self, DisplayKeyword},
+        overflow::{Overflow, OverflowKeyword},
         Property,
     },
     rules::CssRule,
@@ -212,6 +213,8 @@ fn is_transparent(color: &CssColor) -> bool {
 fn styles_from_properties(decls: &DeclarationBlock<'_>) -> Vec<Style> {
     let mut styles = Vec::new();
     html_trace_quiet!("styles:from_properties: {decls:?}");
+    let mut overflow_hidden = false;
+    let mut height_zero = false;
     for decl in decls
         .declarations
         .iter()
@@ -238,20 +241,36 @@ fn styles_from_properties(decls: &DeclarationBlock<'_>) -> Vec<Style> {
                 }
                 styles.push(Style::BgColour(color.clone()));
             }
+            Property::Height(height) => {
+                use lightningcss::properties::size::Size::*;
+                use lightningcss::values::percentage::DimensionPercentage::*;
+                match height {
+                    LengthPercentage(Dimension(dim)) if dim.to_px() == Some(0.0) => {
+                        height_zero = true;
+                    }
+                    _ => (),
+                }
+            }
             Property::MaxHeight(height) => {
                 use lightningcss::properties::size::MaxSize::*;
                 use lightningcss::values::percentage::DimensionPercentage::*;
-                dbg!(&height);
                 match height {
                     LengthPercentage(Dimension(dim)) => {
                         // Treat max-height: 0 the same as display: none.
                         if Some(0.0) == dim.to_px() {
-                            styles.push(Style::DisplayNone);
+                            height_zero = true;
                         }
                     }
                     _ => (),
                 }
             }
+            Property::OverflowY(OverflowKeyword::Hidden)
+            | Property::Overflow(Overflow {
+                y: OverflowKeyword::Hidden,
+                ..
+            }) => {
+                overflow_hidden = true;
+            }
             Property::Display(disp) => {
                 if let display::Display::Keyword(DisplayKeyword::None) = disp {
                     styles.push(Style::DisplayNone);
@@ -262,6 +281,10 @@ fn styles_from_properties(decls: &DeclarationBlock<'_>) -> Vec<Style> {
             }
         }
     }
+    // If the height is set to zero and overflow hidden, treat as display: none
+    if height_zero && overflow_hidden {
+        styles.push(Style::DisplayNone);
+    }
     styles
 }
 


Test patch:
diff --git a/src/tests.rs b/src/tests.rs
index 7ffe8cb..d1d5ea0 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -2328,11 +2328,23 @@ text
                   1);
     }
 
+    #[test]
+    fn test_max_height_0() {
+        test_html_css(
+            br#"
+        <div style="max-height: 0; overflow-y: hidden">This should be hidden</div>
+        <p>Hello</p>"#,
+            r#"Hello
+"#,
+            20,
+        );
+    }
+
     #[test]
     fn test_height_0() {
         test_html_css(
             br#"
-        <div style="max-height: 0">This should be hidden</div>
+        <div style="height: 0; overflow: hidden">This should be hidden</div>
         <p>Hello</p>"#,
             r#"Hello
 "#,