mirror of
https://github.com/swc-project/swc.git
synced 2024-11-30 15:23:33 +03:00
feat(css/minifier): Compress declarations (#3649)
This commit is contained in:
parent
60b3d2e4a3
commit
7d15316ee1
111
crates/swc_css_minifier/src/compress/declaration.rs
Normal file
111
crates/swc_css_minifier/src/compress/declaration.rs
Normal file
@ -0,0 +1,111 @@
|
||||
use swc_common::util::take::Take;
|
||||
use swc_css_ast::*;
|
||||
use swc_css_visit::{VisitMut, VisitMutWith};
|
||||
pub fn compress_declaration() -> impl VisitMut {
|
||||
CompressDeclaration {}
|
||||
}
|
||||
|
||||
struct CompressDeclaration {}
|
||||
|
||||
impl CompressDeclaration {
|
||||
fn is_same_dimension_length_nodes(
|
||||
&mut self,
|
||||
node_1: Option<&Value>,
|
||||
node_2: Option<&Value>,
|
||||
) -> bool {
|
||||
if let Some(Value::Dimension(Dimension::Length(Length {
|
||||
value: value_1,
|
||||
unit: unit_1,
|
||||
..
|
||||
}))) = node_1
|
||||
{
|
||||
if let Some(Value::Dimension(Dimension::Length(Length {
|
||||
value: value_2,
|
||||
unit: unit_2,
|
||||
..
|
||||
}))) = node_2
|
||||
{
|
||||
if value_1.value == value_2.value
|
||||
&& unit_1.value.to_lowercase() == unit_2.value.to_lowercase()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl VisitMut for CompressDeclaration {
|
||||
fn visit_mut_declaration(&mut self, declaration: &mut Declaration) {
|
||||
declaration.visit_mut_children_with(self);
|
||||
|
||||
if let DeclarationName::Ident(Ident { value, .. }) = &declaration.name {
|
||||
match &*value.to_lowercase() {
|
||||
"padding" | "margin" | "inset" if declaration.value.len() > 1 => {
|
||||
let top = declaration.value.get(0);
|
||||
let right = declaration
|
||||
.value
|
||||
.get(1)
|
||||
.or_else(|| declaration.value.get(0));
|
||||
let bottom = declaration
|
||||
.value
|
||||
.get(2)
|
||||
.or_else(|| declaration.value.get(0));
|
||||
let left = declaration
|
||||
.value
|
||||
.get(3)
|
||||
.or_else(|| declaration.value.get(1))
|
||||
.or_else(|| declaration.value.get(0));
|
||||
|
||||
if self.is_same_dimension_length_nodes(left, right) {
|
||||
if self.is_same_dimension_length_nodes(bottom, top) {
|
||||
if self.is_same_dimension_length_nodes(right, top) {
|
||||
declaration.value = vec![top.unwrap().clone()];
|
||||
} else {
|
||||
declaration.value =
|
||||
vec![top.unwrap().clone(), right.unwrap().clone()];
|
||||
}
|
||||
} else {
|
||||
declaration.value = vec![
|
||||
top.unwrap().clone(),
|
||||
right.unwrap().clone(),
|
||||
bottom.unwrap().clone(),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
"font-weight" => {
|
||||
declaration.value = declaration
|
||||
.value
|
||||
.take()
|
||||
.into_iter()
|
||||
.map(|node| match node {
|
||||
Value::Ident(Ident { value, span, .. })
|
||||
if value.to_lowercase() == "normal" =>
|
||||
{
|
||||
Value::Number(Number {
|
||||
span,
|
||||
value: 400.0,
|
||||
raw: "400".into(),
|
||||
})
|
||||
}
|
||||
Value::Ident(Ident { value, span, .. })
|
||||
if value.to_lowercase() == "bold" =>
|
||||
{
|
||||
Value::Number(Number {
|
||||
span,
|
||||
value: 700.0,
|
||||
raw: "700".into(),
|
||||
})
|
||||
}
|
||||
_ => node,
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
pub mod angle;
|
||||
pub mod declaration;
|
||||
pub mod easing_function;
|
||||
pub mod empty;
|
||||
pub mod keyframes;
|
||||
|
@ -2,7 +2,8 @@ use swc_css_ast::*;
|
||||
use swc_css_visit::VisitMutWith;
|
||||
|
||||
use self::compress::{
|
||||
angle::compress_angle, easing_function::compress_easing_function, empty::compress_empty,
|
||||
angle::compress_angle, declaration::compress_declaration,
|
||||
easing_function::compress_easing_function, empty::compress_empty,
|
||||
keyframes::compress_keyframes, selector::compress_selector, time::compress_time,
|
||||
};
|
||||
|
||||
@ -15,4 +16,7 @@ pub fn minify(stylesheet: &mut Stylesheet) {
|
||||
stylesheet.visit_mut_with(&mut compress_easing_function());
|
||||
stylesheet.visit_mut_with(&mut compress_time());
|
||||
stylesheet.visit_mut_with(&mut compress_angle());
|
||||
stylesheet.visit_mut_with(&mut compress_declaration());
|
||||
stylesheet.visit_mut_with(&mut compress_keyframes());
|
||||
stylesheet.visit_mut_with(&mut compress_empty());
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
.class1 {font-weight: 1;}
|
||||
.class1 {font-weight: 400;}
|
||||
.class1 {font-weight: 1000;}
|
||||
.class2 {font-weight: normal;}
|
||||
.class3 {font-weight: bold;}
|
||||
.class3 {font-WEIGHT: BOLD;}
|
||||
.class4 {font-weight: normal bold;}
|
||||
.class5 {font-weight: 600 bold;}
|
1
crates/swc_css_minifier/tests/fixture/compress-declaration/font-weight/output.min.css
vendored
Normal file
1
crates/swc_css_minifier/tests/fixture/compress-declaration/font-weight/output.min.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
.class1{font-weight:1}.class1{font-weight:400}.class1{font-weight:1e3}.class2{font-weight:400}.class3{font-weight:700}.class3{font-WEIGHT:700}.class4{font-weight:400 700}.class5{font-weight:600 700}
|
@ -0,0 +1,77 @@
|
||||
.class1 {
|
||||
inset: 20px;
|
||||
}
|
||||
|
||||
.class2 {
|
||||
inset: 20px 21px 22px 23px;
|
||||
}
|
||||
|
||||
/* 4 -> 3 */
|
||||
.class4 {
|
||||
inset: 20px 21px 22px 21px;
|
||||
}
|
||||
|
||||
/* 4 -> 2 */
|
||||
.class5 {
|
||||
inset: 20px 21px 20px 21px;
|
||||
}
|
||||
|
||||
/* 4 -> 1 */
|
||||
.class6 {
|
||||
inset: 20px 20px 20px 20px;
|
||||
}
|
||||
|
||||
/* 3 -> 2 */
|
||||
.class7 {
|
||||
inset: 20px 21px 20px;
|
||||
}
|
||||
|
||||
/* 3 -> 1 */
|
||||
.class8 {
|
||||
inset: 20px 20px 20px;
|
||||
}
|
||||
|
||||
/* 2 -> 1 */
|
||||
.class10 {
|
||||
inset: 20px 20px;
|
||||
}
|
||||
|
||||
.class11 {
|
||||
inset: 20px 20px 21px;
|
||||
}
|
||||
|
||||
.class12 {
|
||||
inset: var(--inset);
|
||||
}
|
||||
|
||||
.class13 {
|
||||
inset: 20px var(--inset);
|
||||
}
|
||||
|
||||
.class14 {
|
||||
inset: 20px 20px var(--inset);
|
||||
}
|
||||
|
||||
.class15 {
|
||||
inset: 20px 20px 20px var(--inset);
|
||||
}
|
||||
|
||||
.class16 {
|
||||
inset: var(--inset);
|
||||
}
|
||||
|
||||
.class17 {
|
||||
inset: var(--inset) var(--inset);
|
||||
}
|
||||
|
||||
.class18 {
|
||||
inset: var(--inset) var(--inset) var(--inset) var(--inset);
|
||||
}
|
||||
|
||||
.class19 {
|
||||
INSET: 20PX 20pX 20Px 20px;
|
||||
}
|
||||
|
||||
.class20 {
|
||||
inset: 20px 3em 20px 3em;
|
||||
}
|
1
crates/swc_css_minifier/tests/fixture/compress-declaration/inset/output.min.css
vendored
Normal file
1
crates/swc_css_minifier/tests/fixture/compress-declaration/inset/output.min.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
.class1{inset:20px}.class2{inset:20px 21px 22px 23px}.class4{inset:20px 21px 22px}.class5{inset:20px 21px}.class6{inset:20px}.class7{inset:20px 21px}.class8{inset:20px}.class10{inset:20px}.class11{inset:20px 20px 21px}.class12{inset:var(--inset)}.class13{inset:20px var(--inset)}.class14{inset:20px 20px var(--inset)}.class15{inset:20px 20px 20px var(--inset)}.class16{inset:var(--inset)}.class17{inset:var(--inset)var(--inset)}.class18{inset:var(--inset)var(--inset)var(--inset)var(--inset)}.class19{INSET:20PX}.class20{inset:20px 3em}
|
@ -0,0 +1,77 @@
|
||||
.class1 {
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.class2 {
|
||||
margin: 20px 21px 22px 23px;
|
||||
}
|
||||
|
||||
/* 4 -> 3 */
|
||||
.class4 {
|
||||
margin: 20px 21px 22px 21px;
|
||||
}
|
||||
|
||||
/* 4 -> 2 */
|
||||
.class5 {
|
||||
margin: 20px 21px 20px 21px;
|
||||
}
|
||||
|
||||
/* 4 -> 1 */
|
||||
.class6 {
|
||||
margin: 20px 20px 20px 20px;
|
||||
}
|
||||
|
||||
/* 3 -> 2 */
|
||||
.class7 {
|
||||
margin: 20px 21px 20px;
|
||||
}
|
||||
|
||||
/* 3 -> 1 */
|
||||
.class8 {
|
||||
margin: 20px 20px 20px;
|
||||
}
|
||||
|
||||
/* 2 -> 1 */
|
||||
.class10 {
|
||||
margin: 20px 20px;
|
||||
}
|
||||
|
||||
.class11 {
|
||||
margin: 20px 20px 21px;
|
||||
}
|
||||
|
||||
.class12 {
|
||||
margin: var(--margin);
|
||||
}
|
||||
|
||||
.class13 {
|
||||
margin: 20px var(--margin);
|
||||
}
|
||||
|
||||
.class14 {
|
||||
margin: 20px 20px var(--margin);
|
||||
}
|
||||
|
||||
.class15 {
|
||||
margin: 20px 20px 20px var(--margin);
|
||||
}
|
||||
|
||||
.class16 {
|
||||
margin: var(--margin);
|
||||
}
|
||||
|
||||
.class17 {
|
||||
margin: var(--margin) var(--margin);
|
||||
}
|
||||
|
||||
.class18 {
|
||||
margin: var(--margin) var(--margin) var(--margin) var(--margin);
|
||||
}
|
||||
|
||||
.class19 {
|
||||
MARGIN: 20PX 20pX 20Px 20px;
|
||||
}
|
||||
|
||||
.class20 {
|
||||
margin: 20px 3em 20px 3em;
|
||||
}
|
1
crates/swc_css_minifier/tests/fixture/compress-declaration/margin/output.min.css
vendored
Normal file
1
crates/swc_css_minifier/tests/fixture/compress-declaration/margin/output.min.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
.class1{margin:20px}.class2{margin:20px 21px 22px 23px}.class4{margin:20px 21px 22px}.class5{margin:20px 21px}.class6{margin:20px}.class7{margin:20px 21px}.class8{margin:20px}.class10{margin:20px}.class11{margin:20px 20px 21px}.class12{margin:var(--margin)}.class13{margin:20px var(--margin)}.class14{margin:20px 20px var(--margin)}.class15{margin:20px 20px 20px var(--margin)}.class16{margin:var(--margin)}.class17{margin:var(--margin)var(--margin)}.class18{margin:var(--margin)var(--margin)var(--margin)var(--margin)}.class19{MARGIN:20PX}.class20{margin:20px 3em}
|
@ -0,0 +1,77 @@
|
||||
.class1 {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.class2 {
|
||||
padding: 20px 21px 22px 23px;
|
||||
}
|
||||
|
||||
/* 4 -> 3 */
|
||||
.class4 {
|
||||
padding: 20px 21px 22px 21px;
|
||||
}
|
||||
|
||||
/* 4 -> 2 */
|
||||
.class5 {
|
||||
padding: 20px 21px 20px 21px;
|
||||
}
|
||||
|
||||
/* 4 -> 1 */
|
||||
.class6 {
|
||||
padding: 20px 20px 20px 20px;
|
||||
}
|
||||
|
||||
/* 3 -> 2 */
|
||||
.class7 {
|
||||
padding: 20px 21px 20px;
|
||||
}
|
||||
|
||||
/* 3 -> 1 */
|
||||
.class8 {
|
||||
padding: 20px 20px 20px;
|
||||
}
|
||||
|
||||
/* 2 -> 1 */
|
||||
.class10 {
|
||||
padding: 20px 20px;
|
||||
}
|
||||
|
||||
.class11 {
|
||||
padding: 20px 20px 21px;
|
||||
}
|
||||
|
||||
.class12 {
|
||||
padding: var(--padding);
|
||||
}
|
||||
|
||||
.class13 {
|
||||
padding: 20px var(--padding);
|
||||
}
|
||||
|
||||
.class14 {
|
||||
padding: 20px 20px var(--padding);
|
||||
}
|
||||
|
||||
.class15 {
|
||||
padding: 20px 20px 20px var(--padding);
|
||||
}
|
||||
|
||||
.class16 {
|
||||
padding: var(--padding);
|
||||
}
|
||||
|
||||
.class17 {
|
||||
padding: var(--padding) var(--padding);
|
||||
}
|
||||
|
||||
.class18 {
|
||||
padding: var(--padding) var(--padding) var(--padding) var(--padding);
|
||||
}
|
||||
|
||||
.class19 {
|
||||
PADDING: 20PX 20pX 20Px 20px;
|
||||
}
|
||||
|
||||
.class20 {
|
||||
padding: 20px 3em 20px 3em;
|
||||
}
|
1
crates/swc_css_minifier/tests/fixture/compress-declaration/padding/output.min.css
vendored
Normal file
1
crates/swc_css_minifier/tests/fixture/compress-declaration/padding/output.min.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
.class1{padding:20px}.class2{padding:20px 21px 22px 23px}.class4{padding:20px 21px 22px}.class5{padding:20px 21px}.class6{padding:20px}.class7{padding:20px 21px}.class8{padding:20px}.class10{padding:20px}.class11{padding:20px 20px 21px}.class12{padding:var(--padding)}.class13{padding:20px var(--padding)}.class14{padding:20px 20px var(--padding)}.class15{padding:20px 20px 20px var(--padding)}.class16{padding:var(--padding)}.class17{padding:var(--padding)var(--padding)}.class18{padding:var(--padding)var(--padding)var(--padding)var(--padding)}.class19{PADDING:20PX}.class20{padding:20px 3em}
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user