mirror of
https://github.com/swc-project/swc.git
synced 2024-11-28 02:29:04 +03:00
feat(html/minifier): Compress application/ld+json
(#4628)
This commit is contained in:
parent
e21a40e55e
commit
c41aca6b24
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -3877,6 +3877,7 @@ dependencies = [
|
||||
name = "swc_html_minifier"
|
||||
version = "0.4.0"
|
||||
dependencies = [
|
||||
"serde_json",
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
"swc_html_ast",
|
||||
|
@ -13,6 +13,7 @@ version = "0.4.0"
|
||||
bench = false
|
||||
|
||||
[dependencies]
|
||||
serde_json = "1.0.61"
|
||||
swc_atoms = {version = "0.2.9", path = "../swc_atoms"}
|
||||
swc_common = { version = "0.18.0", path = "../swc_common"}
|
||||
swc_html_ast = {version = "0.6.0", path = "../swc_html_ast"}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#![deny(clippy::all)]
|
||||
|
||||
use serde_json::Value;
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::collections::AHashSet;
|
||||
use swc_html_ast::*;
|
||||
@ -173,6 +174,7 @@ static SPACE_SEPARATED_ATTRIBUTES: &[&str] = &[
|
||||
|
||||
struct Minifier {
|
||||
current_element_namespace: Option<Namespace>,
|
||||
is_script_json_ld: bool,
|
||||
}
|
||||
|
||||
impl Minifier {
|
||||
@ -315,12 +317,25 @@ impl Minifier {
|
||||
impl VisitMut for Minifier {
|
||||
fn visit_mut_element(&mut self, n: &mut Element) {
|
||||
let old_current_element_namespace = self.current_element_namespace.take();
|
||||
let old_value_is_script_json_ld = self.is_script_json_ld;
|
||||
|
||||
self.current_element_namespace = Some(n.namespace);
|
||||
self.is_script_json_ld = n.namespace == Namespace::HTML
|
||||
&& &*n.tag_name == "script"
|
||||
&& n.attributes.iter().any(|attribute| match &*attribute.name {
|
||||
"type"
|
||||
if attribute.value.is_some()
|
||||
&& (&*attribute.value.as_ref().unwrap()) == "application/ld+json" =>
|
||||
{
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
});
|
||||
|
||||
n.visit_mut_children_with(self);
|
||||
|
||||
self.current_element_namespace = old_current_element_namespace;
|
||||
self.is_script_json_ld = old_value_is_script_json_ld;
|
||||
|
||||
n.children.retain(|child| !matches!(child, Child::Comment(comment) if !self.is_conditional_comment(&comment.data)));
|
||||
|
||||
@ -421,10 +436,28 @@ impl VisitMut for Minifier {
|
||||
|
||||
n.value = Some(value.into());
|
||||
}
|
||||
|
||||
fn visit_mut_text(&mut self, n: &mut Text) {
|
||||
n.visit_mut_children_with(self);
|
||||
|
||||
if self.is_script_json_ld {
|
||||
let json = match serde_json::from_str::<Value>(&*n.value) {
|
||||
Ok(json) => json,
|
||||
_ => return,
|
||||
};
|
||||
let minified_json = match serde_json::to_string(&json) {
|
||||
Ok(minified_json) => minified_json,
|
||||
_ => return,
|
||||
};
|
||||
|
||||
n.value = minified_json.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn minify(document: &mut Document) {
|
||||
document.visit_mut_with(&mut Minifier {
|
||||
current_element_namespace: None,
|
||||
is_script_json_ld: false,
|
||||
});
|
||||
}
|
||||
|
@ -0,0 +1,63 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Party Coffee Cake</title>
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org/",
|
||||
"@type": "Recipe",
|
||||
"name": "Party Coffee Cake",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "Mary Stone"
|
||||
},
|
||||
"datePublished": "2018-03-10",
|
||||
"description": "This coffee cake is awesome and perfect for parties.",
|
||||
"prepTime": "PT20M"
|
||||
}
|
||||
</script>
|
||||
<script type="application/ld+json" crossorigin="anonymous">
|
||||
{
|
||||
"@context": "https://schema.org/",
|
||||
"@type": "Recipe",
|
||||
"name": "Party Coffee Cake",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "Mary Stone"
|
||||
},
|
||||
"datePublished": "2018-03-10",
|
||||
"description": "This coffee cake is awesome and perfect for parties.",
|
||||
"prepTime": "PT20M"
|
||||
}
|
||||
</script>
|
||||
<script type="application/ld+json" crossorigin="anonymous">
|
||||
{
|
||||
broken
|
||||
</script>
|
||||
<script type="unknown">
|
||||
{
|
||||
"@context": "https://schema.org/",
|
||||
"@type": "Recipe",
|
||||
"name": "Party Coffee Cake",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "Mary Stone"
|
||||
},
|
||||
"datePublished": "2018-03-10",
|
||||
"description": "This coffee cake is awesome and perfect for parties.",
|
||||
"prepTime": "PT20M"
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Party coffee cake recipe</h2>
|
||||
<p>
|
||||
<i>by Mary Stone, 2018-03-10</i>
|
||||
</p>
|
||||
<p>
|
||||
This coffee cake is awesome and perfect for parties.
|
||||
</p>
|
||||
<p>
|
||||
Preparation time: 20 minutes
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,37 @@
|
||||
<html><head>
|
||||
<title>Party Coffee Cake</title>
|
||||
<script type=application/ld+json>{"@context":"https://schema.org/","@type":"Recipe","author":{"@type":"Person","name":"Mary Stone"},"datePublished":"2018-03-10","description":"This coffee cake is awesome and perfect for parties.","name":"Party Coffee Cake","prepTime":"PT20M"}</script>
|
||||
<script type=application/ld+json crossorigin=anonymous>{"@context":"https://schema.org/","@type":"Recipe","author":{"@type":"Person","name":"Mary Stone"},"datePublished":"2018-03-10","description":"This coffee cake is awesome and perfect for parties.","name":"Party Coffee Cake","prepTime":"PT20M"}</script>
|
||||
<script type=application/ld+json crossorigin=anonymous>
|
||||
{
|
||||
broken
|
||||
</script>
|
||||
<script type=unknown>
|
||||
{
|
||||
"@context": "https://schema.org/",
|
||||
"@type": "Recipe",
|
||||
"name": "Party Coffee Cake",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "Mary Stone"
|
||||
},
|
||||
"datePublished": "2018-03-10",
|
||||
"description": "This coffee cake is awesome and perfect for parties.",
|
||||
"prepTime": "PT20M"
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Party coffee cake recipe</h2>
|
||||
<p>
|
||||
<i>by Mary Stone, 2018-03-10</i>
|
||||
</p>
|
||||
<p>
|
||||
This coffee cake is awesome and perfect for parties.
|
||||
</p>
|
||||
<p>
|
||||
Preparation time: 20 minutes
|
||||
</p>
|
||||
|
||||
|
||||
</body></html>
|
Loading…
Reference in New Issue
Block a user