From 21cadee1b6657cdde08bd7c575921f94a33e4bbe Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Wed, 19 Oct 2022 04:13:19 +0300 Subject: [PATCH 1/3] fix(html/minifier): bug with merging and removing metadata elements --- crates/swc_html_minifier/src/lib.rs | 62 +++++++++++++----- .../fixture/element/style-group-2/config.json | 4 ++ .../fixture/element/style-group-2/input.html | 64 +++++++++++++++++++ .../element/style-group-2/output.min.html | 4 ++ .../element/style-group/output.min.html | 1 - 5 files changed, 117 insertions(+), 18 deletions(-) create mode 100644 crates/swc_html_minifier/tests/fixture/element/style-group-2/config.json create mode 100644 crates/swc_html_minifier/tests/fixture/element/style-group-2/input.html create mode 100644 crates/swc_html_minifier/tests/fixture/element/style-group-2/output.min.html diff --git a/crates/swc_html_minifier/src/lib.rs b/crates/swc_html_minifier/src/lib.rs index 88f97ec90c4a..1ad6b74e0430 100644 --- a/crates/swc_html_minifier/src/lib.rs +++ b/crates/swc_html_minifier/src/lib.rs @@ -11,6 +11,7 @@ use swc_common::{ collections::AHashMap, comments::SingleThreadedComments, sync::Lrc, EqIgnoreSpan, FileName, FilePathMapping, Mark, SourceMap, DUMMY_SP, }; +use swc_ecma_transforms_base::perf::Items; use swc_html_ast::*; use swc_html_parser::parser::ParserConfig; use swc_html_utils::{HTML_ELEMENTS_AND_ATTRIBUTES, SVG_ELEMENTS_AND_ATTRIBUTES}; @@ -1204,7 +1205,25 @@ impl Minifier<'_> { None } - fn empty_children(&self, children: &Vec) -> bool { + fn is_empty_metadata_element(&self, child: &Child) -> bool { + if let Child::Element(element) = child { + if (!self.is_element_displayed(element.namespace, &element.tag_name) + || (matches!(element.namespace, Namespace::HTML | Namespace::SVG) + && element.tag_name == js_word!("script")) + || (element.namespace == Namespace::HTML + && element.tag_name == js_word!("noscript"))) + && element.attributes.is_empty() + && self.is_empty_children(&element.children) + && element.content.is_none() + { + return true; + } + } + + false + } + + fn is_empty_children(&self, children: &Vec) -> bool { for child in children { match child { Child::Text(text) if text.data.chars().all(is_whitespace) => { @@ -1266,22 +1285,6 @@ impl Minifier<'_> { Child::Comment(comment) if self.options.remove_comments => { self.is_preserved_comment(&comment.data) } - Child::Element(element) - if self.options.remove_empty_metadata_elements - && (!self - .is_element_displayed(element.namespace, &element.tag_name) - || (matches!( - element.namespace, - Namespace::HTML | Namespace::SVG - ) && element.tag_name == js_word!("script")) - || (element.namespace == Namespace::HTML - && element.tag_name == js_word!("noscript"))) - && element.attributes.is_empty() - && self.empty_children(&element.children) - && element.content.is_none() => - { - false - } Child::Element(element) if self.options.merge_metadata_elements && self.allow_elements_to_merge(prev_children.last(), element) => @@ -1601,6 +1604,31 @@ impl Minifier<'_> { let result = child_will_be_retained(&mut child, &mut new_children, children); if result { + if self.options.remove_redundant_attributes + && self.is_empty_metadata_element(&child) + { + let need_continue = { + let next_element = if let Some(Child::Element(element)) = children.get(0) { + Some(element) + } else if let Some(Child::Element(element)) = children.get(1) { + Some(element) + } else { + None + }; + + if let Some(element) = next_element { + self.options.merge_metadata_elements + && !self.allow_elements_to_merge(Some(&child), element) + } else { + true + } + }; + + if need_continue { + continue; + } + } + new_children.push(child); } } diff --git a/crates/swc_html_minifier/tests/fixture/element/style-group-2/config.json b/crates/swc_html_minifier/tests/fixture/element/style-group-2/config.json new file mode 100644 index 000000000000..51608d00a98a --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/element/style-group-2/config.json @@ -0,0 +1,4 @@ +{ + "mergeMetadataElements": false, + "removeEmptyMetadataElements": false +} diff --git a/crates/swc_html_minifier/tests/fixture/element/style-group-2/input.html b/crates/swc_html_minifier/tests/fixture/element/style-group-2/input.html new file mode 100644 index 000000000000..634842353c31 --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/element/style-group-2/input.html @@ -0,0 +1,64 @@ + + + + Document + + + + + + + + + + + +
test
+ + +
test
+ + + + \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/element/style-group-2/output.min.html b/crates/swc_html_minifier/tests/fixture/element/style-group-2/output.min.html new file mode 100644 index 000000000000..10c43b6212e5 --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/element/style-group-2/output.min.html @@ -0,0 +1,4 @@ +Document
test
+ +
test
+ \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/element/style-group/output.min.html b/crates/swc_html_minifier/tests/fixture/element/style-group/output.min.html index 82a7f7fca393..a5e2c3ab00ec 100644 --- a/crates/swc_html_minifier/tests/fixture/element/style-group/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/element/style-group/output.min.html @@ -4,5 +4,4 @@
test
test
- \ No newline at end of file From ce697f3c0376b5d5c2420857924ead7158d7d8e8 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Wed, 19 Oct 2022 04:28:14 +0300 Subject: [PATCH 2/3] perf: small improve --- crates/swc_html_minifier/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/swc_html_minifier/src/lib.rs b/crates/swc_html_minifier/src/lib.rs index 1ad6b74e0430..68e58c4cf50c 100644 --- a/crates/swc_html_minifier/src/lib.rs +++ b/crates/swc_html_minifier/src/lib.rs @@ -1270,6 +1270,10 @@ impl Minifier<'_> { } fn minify_children(&mut self, children: &mut Vec) -> Vec { + if children.is_empty() { + return vec![]; + } + let (namespace, tag_name) = match &self.current_element { Some(element) => (element.namespace, &element.tag_name), _ => { From 7427d908b46f61ff7be0e8e1620361258f4cf4b8 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Wed, 19 Oct 2022 04:44:30 +0300 Subject: [PATCH 3/3] refactor: fix --- crates/swc_html_minifier/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/swc_html_minifier/src/lib.rs b/crates/swc_html_minifier/src/lib.rs index 68e58c4cf50c..36f56e6fdd55 100644 --- a/crates/swc_html_minifier/src/lib.rs +++ b/crates/swc_html_minifier/src/lib.rs @@ -11,7 +11,6 @@ use swc_common::{ collections::AHashMap, comments::SingleThreadedComments, sync::Lrc, EqIgnoreSpan, FileName, FilePathMapping, Mark, SourceMap, DUMMY_SP, }; -use swc_ecma_transforms_base::perf::Items; use swc_html_ast::*; use swc_html_parser::parser::ParserConfig; use swc_html_utils::{HTML_ELEMENTS_AND_ATTRIBUTES, SVG_ELEMENTS_AND_ATTRIBUTES};