mirror of
https://github.com/swc-project/swc.git
synced 2024-11-24 18:28:13 +03:00
feat(html/minifier): Compress javascript:
URLs (#6185)
This commit is contained in:
parent
a81cc9ac88
commit
8f00d1a934
@ -173,6 +173,8 @@ static ALLOW_TO_TRIM_HTML_ATTRIBUTES: &[(&str, &str)] = &[
|
||||
("object", "usemap"),
|
||||
];
|
||||
|
||||
static ALLOW_TO_TRIM_SVG_ATTRIBUTES: &[(&str, &str)] = &[("a", "href")];
|
||||
|
||||
static COMMA_SEPARATED_HTML_ATTRIBUTES: &[(&str, &str)] = &[
|
||||
("img", "srcset"),
|
||||
("source", "srcset"),
|
||||
@ -398,6 +400,9 @@ impl Minifier<'_> {
|
||||
Namespace::HTML => {
|
||||
ALLOW_TO_TRIM_HTML_ATTRIBUTES.contains(&(&element.tag_name, attribute_name))
|
||||
}
|
||||
Namespace::SVG => {
|
||||
ALLOW_TO_TRIM_SVG_ATTRIBUTES.contains(&(&element.tag_name, attribute_name))
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -658,6 +663,16 @@ impl Minifier<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_javascript_url_element(&self, element: &Element) -> bool {
|
||||
match (element.namespace, &element.tag_name) {
|
||||
(Namespace::HTML | Namespace::SVG, &js_word!("a")) => return true,
|
||||
(Namespace::HTML, &js_word!("iframe")) => return true,
|
||||
_ => {}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn is_preserved_comment(&self, data: &str) -> bool {
|
||||
if let Some(preserve_comments) = &self.options.preserve_comments {
|
||||
return preserve_comments.iter().any(|regex| regex.is_match(data));
|
||||
@ -2419,18 +2434,42 @@ impl VisitMut for Minifier<'_> {
|
||||
_ if self.is_trimable_separated_attribute(current_element, &n.name) => {
|
||||
let mut value = value.to_string();
|
||||
|
||||
if self.options.normalize_attributes {
|
||||
value = value.trim().to_string();
|
||||
}
|
||||
let fallback = |n: &mut Attribute| {
|
||||
if self.options.normalize_attributes {
|
||||
n.value = Some(value.trim().into());
|
||||
}
|
||||
};
|
||||
|
||||
if self.need_minify_css() && n.name == js_word!("style") && !value.is_empty() {
|
||||
if let Some(minified) =
|
||||
self.minify_css(value, CssMinificationMode::ListOfDeclarations)
|
||||
let value = value.trim();
|
||||
|
||||
if let Some(minified) = self
|
||||
.minify_css(value.to_string(), CssMinificationMode::ListOfDeclarations)
|
||||
{
|
||||
n.value = Some(minified.into());
|
||||
} else {
|
||||
fallback(n);
|
||||
}
|
||||
} else if self.need_minify_js()
|
||||
&& self.is_javascript_url_element(current_element)
|
||||
{
|
||||
if value.trim().to_lowercase().starts_with("javascript:") {
|
||||
value = value.trim().chars().skip(11).collect();
|
||||
|
||||
if let Some(minified) = self.minify_js(value, false, true) {
|
||||
let mut with_javascript =
|
||||
String::with_capacity(11 + minified.len());
|
||||
|
||||
with_javascript.push_str("javascript:");
|
||||
with_javascript.push_str(&minified);
|
||||
|
||||
n.value = Some(with_javascript.into());
|
||||
}
|
||||
} else {
|
||||
fallback(n);
|
||||
}
|
||||
} else {
|
||||
n.value = Some(value.into());
|
||||
fallback(n);
|
||||
}
|
||||
}
|
||||
_ if self.options.minify_additional_attributes.is_some() => {
|
||||
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"normalizeAttributes": false
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<a href=" javascript: alert( 'test' ) ">a</a>
|
||||
<a href=" JAVASCRIPT: alert( 'test' ) ">b</a>
|
||||
<iframe src="javascript: alert( 'test' ) " frameborder="0"></iframe>
|
||||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- A link around a shape -->
|
||||
<a href="javascript: alert( 'test' ) ">
|
||||
<circle cx="50" cy="40" r="35" />
|
||||
</a>
|
||||
<!-- A link around a text -->
|
||||
<a href=" javascript: alert( 'test' ) ">
|
||||
<text x="50" y="90" text-anchor="middle"><circle></text>
|
||||
</a>
|
||||
</svg>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,13 @@
|
||||
<!doctype html><html lang=en><title>Document</title><a href='javascript:alert("test")'>a</a>
|
||||
<a href='javascript:alert("test")'>b</a>
|
||||
<iframe src='javascript:alert("test")' frameborder=0></iframe>
|
||||
<svg viewBox="0 0 100 100">
|
||||
|
||||
<a href='javascript:alert("test")'>
|
||||
<circle cx=50 cy=40 r=35 />
|
||||
</a>
|
||||
|
||||
<a href='javascript:alert("test")'>
|
||||
<text x=50 y=90 text-anchor=middle><circle></text>
|
||||
</a>
|
||||
</svg>
|
@ -0,0 +1,22 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<a href=" javascript: alert( 'test' ) ">a</a>
|
||||
<a href=" JAVASCRIPT: alert( 'test' ) ">b</a>
|
||||
<a href=" JAVASCRIPT: broken;;( ">b</a>
|
||||
<iframe src="javascript: alert( 'test' ) " frameborder="0"></iframe>
|
||||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- A link around a shape -->
|
||||
<a href="javascript: alert( 'test' ) ">
|
||||
<circle cx="50" cy="40" r="35" />
|
||||
</a>
|
||||
<!-- A link around a text -->
|
||||
<a href=" javascript: alert( 'test' ) ">
|
||||
<text x="50" y="90" text-anchor="middle"><circle></text>
|
||||
</a>
|
||||
</svg>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!doctype html><html lang=en><title>Document</title><a href='javascript:alert("test")'>a</a>
|
||||
<a href='javascript:alert("test")'>b</a>
|
||||
<a href=" JAVASCRIPT: broken;;( ">b</a>
|
||||
<iframe src='javascript:alert("test")' frameborder=0></iframe>
|
||||
<svg viewBox="0 0 100 100">
|
||||
|
||||
<a href='javascript:alert("test")'>
|
||||
<circle cx=50 cy=40 r=35 />
|
||||
</a>
|
||||
|
||||
<a href='javascript:alert("test")'>
|
||||
<text x=50 y=90 text-anchor=middle><circle></text>
|
||||
</a>
|
||||
</svg>
|
@ -286,7 +286,7 @@
|
||||
</svg>
|
||||
|
||||
<svg>
|
||||
<a href=" test.html " ondragexit='alert("testtest")' rel="nofollow noindex">Test</a>
|
||||
<a href=test.html ondragexit='alert("testtest")' rel="nofollow noindex">Test</a>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 100 100" width=160 height=60 y=30>
|
||||
|
Loading…
Reference in New Issue
Block a user