From 55eab19bbeb284b2b93b68e25d124a07fac504ab Mon Sep 17 00:00:00 2001 From: Wilson Lin Date: Fri, 5 Feb 2021 23:54:29 +1100 Subject: [PATCH] Do not minify any whitespace in any descendants of

---
 src/lib.rs                 |  2 +-
 src/spec/tag/whitespace.rs | 12 ++++++++----
 src/tests/mod.rs           |  3 +++
 src/unit/content.rs        |  6 +++---
 src/unit/tag.rs            |  3 ++-
 5 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/src/lib.rs b/src/lib.rs
index 7fc4ac5..7cd7461 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -40,7 +40,7 @@ mod unit;
 /// ```
 pub fn in_place(code: &mut [u8], cfg: &Cfg) -> Result {
     let mut proc = Processor::new(code);
-    process_content(&mut proc, cfg, Namespace::Html, None)
+    process_content(&mut proc, cfg, Namespace::Html, None, false)
         .and_then(|_| if !proc.at_end() {
             Err(ErrorType::UnexpectedClosingTag)
         } else {
diff --git a/src/spec/tag/whitespace.rs b/src/spec/tag/whitespace.rs
index 01a10b6..8543ebc 100644
--- a/src/spec/tag/whitespace.rs
+++ b/src/spec/tag/whitespace.rs
@@ -166,9 +166,13 @@ lazy_static! {
 }
 
 #[inline(always)]
-pub fn get_whitespace_minification_for_tag(tag_name: Option<&[u8]>) -> &'static WhitespaceMinification {
-    match tag_name {
-        Some(n) => TAG_WHITESPACE_MINIFICATION.get(n).unwrap_or(&DEFAULT),
-        None => ROOT,
+pub fn get_whitespace_minification_for_tag(tag_name: Option<&[u8]>, descendant_of_pre: bool) -> &'static WhitespaceMinification {
+    if descendant_of_pre {
+        WHITESPACE_SENSITIVE
+    } else {
+        match tag_name {
+            Some(n) => TAG_WHITESPACE_MINIFICATION.get(n).unwrap_or(&DEFAULT),
+            None => ROOT,
+        }
     }
 }
diff --git a/src/tests/mod.rs b/src/tests/mod.rs
index 8f233e7..1a009b2 100644
--- a/src/tests/mod.rs
+++ b/src/tests/mod.rs
@@ -90,6 +90,9 @@ fn test_no_whitespace_minification() {
     eval(b"
   \n  \t   
", b"
   \n  \t   
"); // Tag names should be case insensitive. eval(b"
   \n  \t   
", b"
   \n  \t   
"); + eval(b"
    1    2     
", b"
    1    2     
"); + eval(b"
    1 
\n
2
", b"
    1 
\n
2
"); + eval(b"
    1 
\n
2
", b"
    1 
\n
2
"); } #[test] diff --git a/src/unit/content.rs b/src/unit/content.rs index 8bdc0f3..af1824c 100644 --- a/src/unit/content.rs +++ b/src/unit/content.rs @@ -51,8 +51,8 @@ pub struct ProcessedContent { pub closing_tag_omitted: bool, } -pub fn process_content(proc: &mut Processor, cfg: &Cfg, ns: Namespace, parent: Option) -> ProcessingResult { - let &WhitespaceMinification { collapse, destroy_whole, trim } = get_whitespace_minification_for_tag(parent.map(|r| &proc[r])); +pub fn process_content(proc: &mut Processor, cfg: &Cfg, ns: Namespace, parent: Option, descendant_of_pre: bool) -> ProcessingResult { + let &WhitespaceMinification { collapse, destroy_whole, trim } = get_whitespace_minification_for_tag(parent.map(|r| &proc[r]), descendant_of_pre); let handle_ws = collapse || destroy_whole || trim; @@ -134,7 +134,7 @@ pub fn process_content(proc: &mut Processor, cfg: &Cfg, ns: Namespace, parent: O }); }; - let new_closing_tag = process_tag(proc, cfg, ns, parent, prev_sibling_closing_tag, tag_name)?; + let new_closing_tag = process_tag(proc, cfg, ns, parent, ns == Namespace::Html && parent.filter(|p| &proc[*p] == b"pre").is_some(), prev_sibling_closing_tag, tag_name)?; prev_sibling_closing_tag.replace(new_closing_tag); } ContentType::End => { diff --git a/src/unit/tag.rs b/src/unit/tag.rs index 49308a0..a0bb5fd 100644 --- a/src/unit/tag.rs +++ b/src/unit/tag.rs @@ -99,6 +99,7 @@ pub fn process_tag( cfg: &Cfg, ns: Namespace, parent: Option, + descendant_of_pre: bool, mut prev_sibling_closing_tag: MaybeClosingTag, source_tag_name: ProcessorRange, ) -> ProcessingResult { @@ -212,7 +213,7 @@ pub fn process_tag( TagType::ScriptData => process_script(proc, cfg, false)?, TagType::ScriptJs => process_script(proc, cfg, true)?, TagType::Style => process_style(proc, cfg)?, - _ => closing_tag_omitted = process_content(proc, cfg, child_ns, Some(tag_name))?.closing_tag_omitted, + _ => closing_tag_omitted = process_content(proc, cfg, child_ns, Some(tag_name), descendant_of_pre)?.closing_tag_omitted, }; let can_omit_closing_tag = can_omit_as_last_node(proc, parent, source_tag_name);