diff --git a/crates/swc_html_minifier/src/lib.rs b/crates/swc_html_minifier/src/lib.rs index c816f05aa59..8ab5b03e9b9 100644 --- a/crates/swc_html_minifier/src/lib.rs +++ b/crates/swc_html_minifier/src/lib.rs @@ -47,16 +47,6 @@ static BOOLEAN_ATTRIBUTES: &[&str] = &[ "visible", ]; -static EXECUTABLE_SCRIPTS_MIME_TYPES: &[&str] = &[ - "text/javascript", - "text/ecmascript", - "text/jscript", - "application/javascript", - "application/x-javascript", - "application/ecmascript", - "module", -]; - struct Minifier {} impl Minifier { @@ -64,6 +54,99 @@ impl Minifier { BOOLEAN_ATTRIBUTES.contains(&name) } + fn is_default_attribute_value( + &self, + namespace: Namespace, + tag_name: &str, + attribute_name: &str, + attribute_value: &str, + ) -> bool { + matches!( + ( + namespace, + tag_name, + attribute_name, + attribute_value.to_ascii_lowercase().trim() + ), + (Namespace::HTML, "iframe", "height", "150") + | (Namespace::HTML, "iframe", "width", "300") + | (Namespace::HTML, "iframe", "frameborder", "1") + | (Namespace::HTML, "iframe", "loading", "eager") + | (Namespace::HTML, "iframe", "fetchpriority", "auto") + | ( + Namespace::HTML, + "iframe", + "referrerpolicy", + "strict-origin-when-cross-origin" + ) + | ( + Namespace::HTML, + "a", + "referrerpolicy", + "strict-origin-when-cross-origin" + ) + | (Namespace::HTML, "a", "target", "_self") + | (Namespace::HTML, "area", "target", "_self") + | (Namespace::HTML, "area", "shape", "rect") + | ( + Namespace::HTML, + "area", + "referrerpolicy", + "strict-origin-when-cross-origin" + ) + | (Namespace::HTML, "form", "method", "get") + | (Namespace::HTML, "form", "target", "_self") + | (Namespace::HTML, "input", "type", "text") + | (Namespace::HTML, "input", "size", "20") + | (Namespace::HTML, "track", "kind", "subtitles") + | (Namespace::HTML, "textarea", "cols", "20") + | (Namespace::HTML, "textarea", "rows", "2") + | (Namespace::HTML, "textarea", "wrap", "sort") + | (Namespace::HTML, "progress", "max", "1") + | (Namespace::HTML, "meter", "min", "0") + | (Namespace::HTML, "img", "decoding", "auto") + | (Namespace::HTML, "img", "fetchpriority", "auto") + | (Namespace::HTML, "img", "loading", "eager") + | ( + Namespace::HTML, + "img", + "referrerpolicy", + "strict-origin-when-cross-origin" + ) + | (Namespace::HTML, "link", "type", "text/css") + | (Namespace::HTML, "link", "fetchpriority", "auto") + | ( + Namespace::HTML, + "link", + "referrerpolicy", + "strict-origin-when-cross-origin" + ) + | (Namespace::HTML, "style", "type", "text/css") + | (Namespace::HTML, "script", "type", "text/javascript") + | (Namespace::HTML, "script", "type", "text/ecmascript") + | (Namespace::HTML, "script", "type", "text/jscript") + | (Namespace::HTML, "script", "type", "application/javascript") + | ( + Namespace::HTML, + "script", + "type", + "application/x-javascript" + ) + | (Namespace::HTML, "script", "type", "application/ecmascript") + | (Namespace::HTML, "script", "fetchpriority", "auto") + | ( + Namespace::HTML, + "script", + "referrerpolicy", + "strict-origin-when-cross-origin" + ) + | (Namespace::HTML, "ol", "type", "1") + | (Namespace::HTML, "base", "target", "_self") + | (Namespace::HTML, "canvas", "height", "150") + | (Namespace::HTML, "canvas", "width", "300") + ) + } + fn is_conditional_comment(&self, data: &str) -> bool { let trimmed = data.trim(); @@ -80,40 +163,23 @@ impl VisitMut for Minifier { n.visit_mut_children_with(self); n.children.retain(|child| !matches!(child, Child::Comment(comment) if !self.is_conditional_comment(&comment.data))); - n.attributes.retain(|attribute| match &*attribute.name { - "type" - if n.namespace == Namespace::HTML - && matches!(n.tag_name.as_ref(), "script") - && (attribute.value.is_some() - && attribute - .value - .as_ref() - .map(|v| { - EXECUTABLE_SCRIPTS_MIME_TYPES - .iter() - .any(|mime| v.eq_str_ignore_ascii_case(mime)) - }) - .unwrap_or_default()) => - { - false + n.attributes.retain(|attribute| { + if attribute.value.is_none() { + return true; } - "type" - if n.namespace == Namespace::HTML - && matches!(n.tag_name.as_ref(), "style" | "link") - && (attribute.value.is_some() - && matches!( - attribute - .value - .as_ref() - .unwrap() - .to_ascii_lowercase() - .trim(), - "text/css" - )) => - { - false + + match &*attribute.name { + _ if self.is_default_attribute_value( + n.namespace, + &n.tag_name, + &attribute.name, + attribute.value.as_ref().unwrap(), + ) => + { + false + } + _ => true, } - _ => true, }); } diff --git a/crates/swc_html_minifier/tests/fixture/attribute/iframe/input.html b/crates/swc_html_minifier/tests/fixture/attribute/iframe/input.html new file mode 100644 index 00000000000..c4763bd4ae6 --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/attribute/iframe/input.html @@ -0,0 +1,13 @@ + + + + + + + Document + + + + + \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/attribute/iframe/output.min.html b/crates/swc_html_minifier/tests/fixture/attribute/iframe/output.min.html new file mode 100644 index 00000000000..d4ec5d42c82 --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/attribute/iframe/output.min.html @@ -0,0 +1,10 @@ + + + + + Document + + + + + diff --git a/crates/swc_html_minifier/tests/fixture/attribute/img/input.html b/crates/swc_html_minifier/tests/fixture/attribute/img/input.html new file mode 100644 index 00000000000..58ff653da1f --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/attribute/img/input.html @@ -0,0 +1,9 @@ + + + + Document + + +test + + \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/attribute/img/output.min.html b/crates/swc_html_minifier/tests/fixture/attribute/img/output.min.html new file mode 100644 index 00000000000..faf745af484 --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/attribute/img/output.min.html @@ -0,0 +1,7 @@ + + Document + + +test + + diff --git a/crates/swc_html_minifier/tests/fixture/attribute/input/input.html b/crates/swc_html_minifier/tests/fixture/attribute/input/input.html new file mode 100644 index 00000000000..75a1d95d742 --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/attribute/input/input.html @@ -0,0 +1,12 @@ + + + + Document + + + + + + + + \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/attribute/input/output.min.html b/crates/swc_html_minifier/tests/fixture/attribute/input/output.min.html new file mode 100644 index 00000000000..4a160bdc899 --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/attribute/input/output.min.html @@ -0,0 +1,10 @@ + + Document + + + + + + + + diff --git a/crates/swc_html_minifier/tests/fixture/attribute/meter/input.html b/crates/swc_html_minifier/tests/fixture/attribute/meter/input.html new file mode 100644 index 00000000000..b96e193d20f --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/attribute/meter/input.html @@ -0,0 +1,14 @@ + + + + Document + + + + at 50/100 + + + \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/attribute/meter/output.min.html b/crates/swc_html_minifier/tests/fixture/attribute/meter/output.min.html new file mode 100644 index 00000000000..929cd64b38f --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/attribute/meter/output.min.html @@ -0,0 +1,9 @@ + + Document + + + + at 50/100 + + + diff --git a/crates/swc_html_minifier/tests/fixture/attribute/ol/input.html b/crates/swc_html_minifier/tests/fixture/attribute/ol/input.html new file mode 100644 index 00000000000..080b063b944 --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/attribute/ol/input.html @@ -0,0 +1,15 @@ + + + + Document + + +
    +
  1. Mix flour, baking powder, sugar, and salt.
  2. +
  3. In another bowl, mix eggs, milk, and oil.
  4. +
  5. Stir both mixtures together.
  6. +
  7. Fill muffin tray 3/4 full.
  8. +
  9. Bake for 20 minutes.
  10. +
+ + \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/attribute/ol/output.min.html b/crates/swc_html_minifier/tests/fixture/attribute/ol/output.min.html new file mode 100644 index 00000000000..71555aa183b --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/attribute/ol/output.min.html @@ -0,0 +1,13 @@ + + Document + + +
    +
  1. Mix flour, baking powder, sugar, and salt.
  2. +
  3. In another bowl, mix eggs, milk, and oil.
  4. +
  5. Stir both mixtures together.
  6. +
  7. Fill muffin tray 3/4 full.
  8. +
  9. Bake for 20 minutes.
  10. +
+ + diff --git a/crates/swc_html_minifier/tests/fixture/attribute/progress/input.html b/crates/swc_html_minifier/tests/fixture/attribute/progress/input.html new file mode 100644 index 00000000000..c63ecf9b9bb --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/attribute/progress/input.html @@ -0,0 +1,9 @@ + + + + Document + + + + + \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/attribute/progress/output.min.html b/crates/swc_html_minifier/tests/fixture/attribute/progress/output.min.html new file mode 100644 index 00000000000..5cddbd9acf4 --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/attribute/progress/output.min.html @@ -0,0 +1,7 @@ + + Document + + + + + diff --git a/crates/swc_html_minifier/tests/fixture/attribute/script-type/output.min.html b/crates/swc_html_minifier/tests/fixture/attribute/script-type/output.min.html index beb97a8ef4f..eec919351ff 100644 --- a/crates/swc_html_minifier/tests/fixture/attribute/script-type/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/attribute/script-type/output.min.html @@ -4,7 +4,7 @@ - diff --git a/crates/swc_html_minifier/tests/fixture/attribute/textarea/input.html b/crates/swc_html_minifier/tests/fixture/attribute/textarea/input.html new file mode 100644 index 00000000000..2fefc4006ec --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/attribute/textarea/input.html @@ -0,0 +1,9 @@ + + + + Document + + + + + \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/attribute/textarea/output.min.html b/crates/swc_html_minifier/tests/fixture/attribute/textarea/output.min.html new file mode 100644 index 00000000000..0adf7002a31 --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/attribute/textarea/output.min.html @@ -0,0 +1,7 @@ + + Document + + + +</> +</> diff --git a/crates/swc_html_minifier/tests/fixture/attribute/track/input.html b/crates/swc_html_minifier/tests/fixture/attribute/track/input.html new file mode 100644 index 00000000000..fb64175a7fb --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/attribute/track/input.html @@ -0,0 +1,31 @@ + + + + + + + Document + + + + + + + + + \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/attribute/track/output.min.html b/crates/swc_html_minifier/tests/fixture/attribute/track/output.min.html new file mode 100644 index 00000000000..c74db17f26f --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/attribute/track/output.min.html @@ -0,0 +1,20 @@ + + + + + Document + + + + + + + + +