mirror of
https://github.com/swc-project/swc.git
synced 2024-12-25 06:36:08 +03:00
feat(html/minifier): Add preserve_comments
option (#4959)
This commit is contained in:
parent
4b340e2c1b
commit
2e52c18a6b
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -3965,6 +3965,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"swc_atoms",
|
||||
"swc_cached",
|
||||
"swc_common",
|
||||
"swc_css_codegen",
|
||||
"swc_css_minifier",
|
||||
|
@ -19,6 +19,7 @@ bench = false
|
||||
serde = { version = "1.0.118", features = ["derive"] }
|
||||
serde_json = "1.0.61"
|
||||
swc_atoms = { version = "0.2.9", path = "../swc_atoms" }
|
||||
swc_cached = { version = "0.1.0", path = "../swc_cached" }
|
||||
swc_common = { version = "0.18.0", path = "../swc_common" }
|
||||
swc_css_codegen = { version = "0.103.0", path = "../swc_css_codegen" }
|
||||
swc_css_parser = { version = "0.102.0", path = "../swc_css_parser" }
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
use serde_json::Value;
|
||||
use swc_atoms::{js_word, JsWord};
|
||||
use swc_cached::regex::CachedRegex;
|
||||
use swc_common::{collections::AHashSet, sync::Lrc, FileName, FilePathMapping, SourceMap};
|
||||
use swc_css_codegen::{
|
||||
writer::basic::{BasicCssWriter, BasicCssWriterConfig},
|
||||
@ -284,6 +285,7 @@ struct Minifier {
|
||||
remove_empty_attributes: bool,
|
||||
collapse_boolean_attributes: bool,
|
||||
minify_css: bool,
|
||||
preserve_comments: Option<Vec<CachedRegex>>,
|
||||
}
|
||||
|
||||
impl Minifier {
|
||||
@ -459,11 +461,9 @@ impl Minifier {
|
||||
)
|
||||
}
|
||||
|
||||
fn is_conditional_comment(&self, data: &str) -> bool {
|
||||
let trimmed = data.trim();
|
||||
|
||||
if trimmed.starts_with("[if") || trimmed.ends_with("[endif]") {
|
||||
return true;
|
||||
fn is_preserved_comment(&self, data: &str) -> bool {
|
||||
if let Some(preserve_comments) = &self.preserve_comments {
|
||||
return preserve_comments.iter().any(|regex| regex.is_match(data));
|
||||
}
|
||||
|
||||
false
|
||||
@ -707,7 +707,7 @@ impl VisitMut for Minifier {
|
||||
index += 1;
|
||||
|
||||
match child {
|
||||
Child::Comment(comment) if !self.is_conditional_comment(&comment.data) => false,
|
||||
Child::Comment(comment) if !self.is_preserved_comment(&comment.data) => false,
|
||||
// Always remove whitespaces from html and head elements (except nested elements),
|
||||
// it should be safe
|
||||
Child::Text(_)
|
||||
@ -960,5 +960,7 @@ pub fn minify(document: &mut Document, options: &MinifyOptions) {
|
||||
collapse_boolean_attributes: options.collapse_boolean_attributes,
|
||||
|
||||
minify_css: options.minify_css,
|
||||
|
||||
preserve_comments: options.preserve_comments.clone(),
|
||||
});
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use swc_cached::regex::CachedRegex;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@ -18,6 +19,8 @@ pub struct MinifyOptions {
|
||||
pub collapse_boolean_attributes: bool,
|
||||
#[serde(default = "true_by_default")]
|
||||
pub minify_css: bool,
|
||||
#[serde(default = "default_preserve_comments")]
|
||||
pub preserve_comments: Option<Vec<CachedRegex>>,
|
||||
}
|
||||
|
||||
/// Implement default using serde.
|
||||
@ -39,3 +42,20 @@ pub enum CollapseWhitespaces {
|
||||
const fn true_by_default() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn default_preserve_comments() -> Option<Vec<CachedRegex>> {
|
||||
Some(vec![
|
||||
// License comments
|
||||
CachedRegex::new("@preserve").unwrap(),
|
||||
CachedRegex::new("@copyright").unwrap(),
|
||||
CachedRegex::new("@lic").unwrap(),
|
||||
CachedRegex::new("@cc_on").unwrap(),
|
||||
// Allow to keep custom comments
|
||||
CachedRegex::new("^!").unwrap(),
|
||||
// Server-side comments
|
||||
CachedRegex::new("^\\s*#").unwrap(),
|
||||
// Conditional IE comments
|
||||
CachedRegex::new("^\\[if\\s[^\\]+]").unwrap(),
|
||||
CachedRegex::new("\\[endif]").unwrap(),
|
||||
])
|
||||
}
|
||||
|
@ -0,0 +1,82 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Document</title>
|
||||
<!--[if !IE]>-->
|
||||
<link href="non-ie.css" rel="stylesheet">
|
||||
<!--<![endif]-->
|
||||
<!--[if IE]>
|
||||
<link type="text/css" rel="stylesheet" href="/stylesheets/no-ie.css">
|
||||
<![endif]-->
|
||||
<!--[if IE 8]>
|
||||
<link href="ie8only.css" rel="stylesheet">
|
||||
<![endif]-->
|
||||
<!-- [if IE 8]>
|
||||
<link href="ie8only.css" rel="stylesheet">
|
||||
<![endif] -->
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
<p>This is a paragraph.</p>
|
||||
|
||||
<!-- Test -->
|
||||
<!-- foo --><div>baz</div><!-- bar
|
||||
|
||||
moo -->
|
||||
<script><!-- alert(1) --></script>
|
||||
<script><!--
|
||||
alert(1);
|
||||
--></script>
|
||||
<style type="text/css"><!-- p { color: red } --></style>
|
||||
<script>/*<![CDATA[*/alert(8)/*]]>*/</script>
|
||||
<script type="text/javascript"> /*
|
||||
<![CDATA[ */
|
||||
alert(10)
|
||||
/* ]]> */
|
||||
</script>
|
||||
<!-- @preserve foo -->
|
||||
<!-- @copyright foo -->
|
||||
<!-- @lic foo -->
|
||||
<!-- @cc_on foo -->
|
||||
<!--! my custom comment -->
|
||||
<!--#include virtual="/cgi-bin/counter.pl" -->
|
||||
|
||||
<p class="accent">
|
||||
<!--[if IE]>
|
||||
According to the conditional comment this is IE<br />
|
||||
<![endif]-->
|
||||
<!--[if IE 6]>
|
||||
According to the conditional comment this is IE 6<br />
|
||||
<![endif]-->
|
||||
<!--[if IE 7]>
|
||||
According to the conditional comment this is IE 7<br />
|
||||
<![endif]-->
|
||||
<!--[if IE 8]>
|
||||
According to the conditional comment this is IE 8<br />
|
||||
<![endif]-->
|
||||
<!--[if IE 9]>
|
||||
According to the conditional comment this is IE 9<br />
|
||||
<![endif]-->
|
||||
<!--[if gte IE 8]>
|
||||
According to the conditional comment this is IE 8 or higher<br />
|
||||
<![endif]-->
|
||||
<!--[if lt IE 9]>
|
||||
According to the conditional comment this is IE lower than 9<br />
|
||||
<![endif]-->
|
||||
<!--[if lte IE 7]>
|
||||
According to the conditional comment this is IE lower or equal to 7<br />
|
||||
<![endif]-->
|
||||
<!--[if gt IE 6]>
|
||||
According to the conditional comment this is IE greater than 6<br />
|
||||
<![endif]-->
|
||||
<!--[if !IE]> -->
|
||||
According to the conditional comment this is not IE 5-9<br />
|
||||
<!-- <![endif]-->
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,63 @@
|
||||
<!doctype html><html lang=en><meta charset=UTF-8><meta name=viewport content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0"><meta http-equiv=X-UA-Compatible content="ie=edge"><title>Document</title><!--[if !IE]>--><link href=non-ie.css rel=stylesheet><!--<![endif]--><!--[if IE]>
|
||||
<link type="text/css" rel="stylesheet" href="/stylesheets/no-ie.css">
|
||||
<![endif]--><!--[if IE 8]>
|
||||
<link href="ie8only.css" rel="stylesheet">
|
||||
<![endif]--><!-- [if IE 8]>
|
||||
<link href="ie8only.css" rel="stylesheet">
|
||||
<![endif] --><body>
|
||||
|
||||
|
||||
<p>This is a paragraph.</p>
|
||||
|
||||
|
||||
<div>baz</div>
|
||||
<script><!-- alert(1) --></script>
|
||||
<script><!--
|
||||
alert(1);
|
||||
--></script>
|
||||
<style>p{color:red}</style><script>/*<![CDATA[*/alert(8)/*]]>*/</script>
|
||||
<script> /*
|
||||
<![CDATA[ */
|
||||
alert(10)
|
||||
/* ]]> */
|
||||
</script>
|
||||
<!-- @preserve foo -->
|
||||
<!-- @copyright foo -->
|
||||
<!-- @lic foo -->
|
||||
<!-- @cc_on foo -->
|
||||
<!--! my custom comment -->
|
||||
<!--#include virtual="/cgi-bin/counter.pl" -->
|
||||
|
||||
<p class=accent>
|
||||
<!--[if IE]>
|
||||
According to the conditional comment this is IE<br />
|
||||
<![endif]-->
|
||||
<!--[if IE 6]>
|
||||
According to the conditional comment this is IE 6<br />
|
||||
<![endif]-->
|
||||
<!--[if IE 7]>
|
||||
According to the conditional comment this is IE 7<br />
|
||||
<![endif]-->
|
||||
<!--[if IE 8]>
|
||||
According to the conditional comment this is IE 8<br />
|
||||
<![endif]-->
|
||||
<!--[if IE 9]>
|
||||
According to the conditional comment this is IE 9<br />
|
||||
<![endif]-->
|
||||
<!--[if gte IE 8]>
|
||||
According to the conditional comment this is IE 8 or higher<br />
|
||||
<![endif]-->
|
||||
<!--[if lt IE 9]>
|
||||
According to the conditional comment this is IE lower than 9<br />
|
||||
<![endif]-->
|
||||
<!--[if lte IE 7]>
|
||||
According to the conditional comment this is IE lower or equal to 7<br />
|
||||
<![endif]-->
|
||||
<!--[if gt IE 6]>
|
||||
According to the conditional comment this is IE greater than 6<br />
|
||||
<![endif]-->
|
||||
<!--[if !IE]> -->
|
||||
According to the conditional comment this is not IE 5-9<br>
|
||||
<!-- <![endif]-->
|
||||
</p>
|
||||
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"preserveComments": ["^!", "^\\s+ko", "\/ko\\s+$"]
|
||||
}
|
@ -39,5 +39,7 @@
|
||||
alert(10)
|
||||
/* ]]> */
|
||||
</script>
|
||||
<!--! test -->
|
||||
<!-- ko if: someExpressionGoesHere --><li>test</li><!-- /ko -->
|
||||
</body>
|
||||
</html>
|
@ -1,10 +1,4 @@
|
||||
<!doctype html><html lang=en><meta charset=UTF-8><meta name=viewport content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0"><meta http-equiv=X-UA-Compatible content="ie=edge"><title>Document</title><!--[if !IE]>--><link href=non-ie.css rel=stylesheet><!--<![endif]--><!--[if IE]>
|
||||
<link type="text/css" rel="stylesheet" href="/stylesheets/no-ie.css">
|
||||
<![endif]--><!--[if IE 8]>
|
||||
<link href="ie8only.css" rel="stylesheet">
|
||||
<![endif]--><!-- [if IE 8]>
|
||||
<link href="ie8only.css" rel="stylesheet">
|
||||
<![endif] --><body>
|
||||
<!doctype html><html lang=en><meta charset=UTF-8><meta name=viewport content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0"><meta http-equiv=X-UA-Compatible content="ie=edge"><title>Document</title><link href=non-ie.css rel=stylesheet><body>
|
||||
|
||||
|
||||
<p>This is a paragraph.</p>
|
||||
@ -21,4 +15,6 @@
|
||||
alert(10)
|
||||
/* ]]> */
|
||||
</script>
|
||||
<!--! test -->
|
||||
<!-- ko if: someExpressionGoesHere --><li>test</li><!-- /ko -->
|
||||
|
Loading…
Reference in New Issue
Block a user