diff --git a/crates/swc_html_minifier/src/lib.rs b/crates/swc_html_minifier/src/lib.rs index 634e7fa0e98c..bf6f343c271b 100644 --- a/crates/swc_html_minifier/src/lib.rs +++ b/crates/swc_html_minifier/src/lib.rs @@ -608,6 +608,12 @@ impl Minifier<'_> { } } + fn is_type_text_css(&self, value: &JsWord) -> bool { + let value = value.trim().to_ascii_lowercase(); + + matches!(&*value, "text/css") + } + fn is_default_attribute_value(&self, element: &Element, attribute: &Attribute) -> bool { let attribute_value = match &attribute.value { Some(value) => value, @@ -652,7 +658,7 @@ impl Minifier<'_> { }, js_word!("link") => { if attribute.name == js_word!("type") - && &*attribute_value.trim().to_ascii_lowercase() == "text/css" + && self.is_type_text_css(attribute_value) { return true; } @@ -1305,9 +1311,38 @@ impl Minifier<'_> { fn is_empty_metadata_element(&self, child: &Child) -> bool { if let Child::Element(element) = child { - if (!self.is_element_displayed(element) - || (matches!(element.namespace, Namespace::HTML | Namespace::SVG) - && element.tag_name == js_word!("script")) + if matches!(element.namespace, Namespace::HTML | Namespace::SVG) + && element.tag_name == js_word!("style") + && self.is_empty_children(&element.children) + { + if element.attributes.is_empty() { + return true; + } + + if element.attributes.len() == 1 { + return element.attributes.iter().all(|attr| { + attr.name == js_word!("type") + && attr.value.is_some() + && self.is_type_text_css(attr.value.as_ref().unwrap()) + }); + } + } else if matches!(element.namespace, Namespace::HTML | Namespace::SVG) + && element.tag_name == js_word!("script") + && self.is_empty_children(&element.children) + { + if element.attributes.is_empty() { + return true; + } + + if element.attributes.len() == 1 { + return element.attributes.iter().all(|attr| { + attr.name == js_word!("type") + && attr.value.is_some() + && (attr.value == Some(js_word!("module")) + || self.is_type_text_javascript(attr.value.as_ref().unwrap())) + }); + } + } else if (!self.is_element_displayed(element) || (element.namespace == Namespace::HTML && element.tag_name == js_word!("noscript"))) && element.attributes.is_empty() @@ -1360,7 +1395,7 @@ impl Minifier<'_> { } js_word!("type") => { if let Some(value) = &attribute.value { - if (is_style_tag && value.trim().to_ascii_lowercase() == "text/css") + if (is_style_tag && self.is_type_text_css(value)) || (is_script_tag && self.is_type_text_javascript(value)) { false @@ -1402,7 +1437,7 @@ impl Minifier<'_> { } js_word!("type") => { if let Some(value) = &attribute.value { - if (is_style_tag && value.trim().to_ascii_lowercase() == "text/css") + if (is_style_tag && self.is_type_text_css(value)) || (is_script_tag && self.is_type_text_javascript(value)) { false @@ -3005,21 +3040,14 @@ impl VisitMut for Minifier<'_> { for attribute in ¤t_element.attributes { if attribute.name == js_word!("type") && attribute.value.is_some() { - type_attribute_value = Some( - attribute - .value - .as_ref() - .unwrap() - .trim() - .to_ascii_lowercase(), - ); + type_attribute_value = Some(attribute.value.as_ref().unwrap()); break; } } if type_attribute_value.is_none() - || type_attribute_value == Some("text/css".into()) + || self.is_type_text_css(type_attribute_value.as_ref().unwrap()) { text_type = Some(MinifierType::Css) } diff --git a/crates/swc_html_minifier/tests/fixture/element/empty-metadata-elements/input.html b/crates/swc_html_minifier/tests/fixture/element/empty-metadata-elements/input.html index ef1a405fd9de..8bcbb4fba303 100644 --- a/crates/swc_html_minifier/tests/fixture/element/empty-metadata-elements/input.html +++ b/crates/swc_html_minifier/tests/fixture/element/empty-metadata-elements/input.html @@ -19,5 +19,21 @@ + +Empty modules + + +Empty scripts + +Empty styles + \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/element/empty-metadata-elements/output.min.html b/crates/swc_html_minifier/tests/fixture/element/empty-metadata-elements/output.min.html index d92d186dfaa6..c667b4c4f227 100644 --- a/crates/swc_html_minifier/tests/fixture/element/empty-metadata-elements/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/element/empty-metadata-elements/output.min.html @@ -1,4 +1,8 @@ - \ No newline at end of file + +Empty modules +Empty scripts + +Empty styles \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/element/script-group/input.html b/crates/swc_html_minifier/tests/fixture/element/script-group/input.html index 1b9a6d7be4d5..3bd9d8bcb8ce 100644 --- a/crates/swc_html_minifier/tests/fixture/element/script-group/input.html +++ b/crates/swc_html_minifier/tests/fixture/element/script-group/input.html @@ -223,5 +223,29 @@ + + + +
breaker
+ + + +
breaker
+ + + +
breaker
+ + + + \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html b/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html index 61f332ee80bc..761bfadc4b90 100644 --- a/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html @@ -97,5 +97,16 @@
breaker
- - \ No newline at end of file + + + + + + +
breaker
+ +
breaker
+ + + +
breaker
\ No newline at end of file