mirror of
https://github.com/swc-project/swc.git
synced 2024-11-28 11:13:43 +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"
|
name = "swc_html_minifier"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"serde_json",
|
||||||
"swc_atoms",
|
"swc_atoms",
|
||||||
"swc_common",
|
"swc_common",
|
||||||
"swc_html_ast",
|
"swc_html_ast",
|
||||||
|
@ -13,6 +13,7 @@ version = "0.4.0"
|
|||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
serde_json = "1.0.61"
|
||||||
swc_atoms = {version = "0.2.9", path = "../swc_atoms"}
|
swc_atoms = {version = "0.2.9", path = "../swc_atoms"}
|
||||||
swc_common = { version = "0.18.0", path = "../swc_common"}
|
swc_common = { version = "0.18.0", path = "../swc_common"}
|
||||||
swc_html_ast = {version = "0.6.0", path = "../swc_html_ast"}
|
swc_html_ast = {version = "0.6.0", path = "../swc_html_ast"}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#![deny(clippy::all)]
|
#![deny(clippy::all)]
|
||||||
|
|
||||||
|
use serde_json::Value;
|
||||||
use swc_atoms::JsWord;
|
use swc_atoms::JsWord;
|
||||||
use swc_common::collections::AHashSet;
|
use swc_common::collections::AHashSet;
|
||||||
use swc_html_ast::*;
|
use swc_html_ast::*;
|
||||||
@ -173,6 +174,7 @@ static SPACE_SEPARATED_ATTRIBUTES: &[&str] = &[
|
|||||||
|
|
||||||
struct Minifier {
|
struct Minifier {
|
||||||
current_element_namespace: Option<Namespace>,
|
current_element_namespace: Option<Namespace>,
|
||||||
|
is_script_json_ld: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Minifier {
|
impl Minifier {
|
||||||
@ -315,12 +317,25 @@ impl Minifier {
|
|||||||
impl VisitMut for Minifier {
|
impl VisitMut for Minifier {
|
||||||
fn visit_mut_element(&mut self, n: &mut Element) {
|
fn visit_mut_element(&mut self, n: &mut Element) {
|
||||||
let old_current_element_namespace = self.current_element_namespace.take();
|
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.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);
|
n.visit_mut_children_with(self);
|
||||||
|
|
||||||
self.current_element_namespace = old_current_element_namespace;
|
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)));
|
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());
|
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) {
|
pub fn minify(document: &mut Document) {
|
||||||
document.visit_mut_with(&mut Minifier {
|
document.visit_mut_with(&mut Minifier {
|
||||||
current_element_namespace: None,
|
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