fix(css): Fix stylis (#2987)

swc_css_codegen:
 - Respect `minify`.

swc_stylis:
 - Process properties only if it's in a qualified rule.
This commit is contained in:
Donny/강동윤 2021-12-07 21:04:54 +09:00 committed by GitHub
parent 144754a3ea
commit c8395bc74f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 150 additions and 23 deletions

4
Cargo.lock generated
View File

@ -2605,7 +2605,7 @@ dependencies = [
[[package]]
name = "swc_css_codegen"
version = "0.42.0"
version = "0.42.1"
dependencies = [
"auto_impl 0.4.1",
"bitflags",
@ -3356,7 +3356,7 @@ dependencies = [
[[package]]
name = "swc_stylis"
version = "0.41.0"
version = "0.41.1"
dependencies = [
"swc_atoms 0.2.9",
"swc_common",

View File

@ -6,7 +6,7 @@ edition = "2018"
license = "Apache-2.0"
name = "swc_css_codegen"
repository = "https://github.com/swc-project/swc.git"
version = "0.42.0"
version = "0.42.1"
[dependencies]
auto_impl = "0.4.1"

View File

@ -56,7 +56,9 @@ where
#[emitter]
fn emit_qualified_rule(&mut self, n: &QualifiedRule) -> Result {
emit!(self, n.prelude);
space!(self);
if !self.config.minify {
space!(self);
}
emit!(self, n.block);
}
@ -158,7 +160,7 @@ where
}
#[emitter]
fn emit_keyfram_block(&mut self, n: &KeyframeBlock) -> Result {
fn emit_keyframe_block(&mut self, n: &KeyframeBlock) -> Result {
self.emit_list(&n.selector, ListFormat::CommaDelimited)?;
space!(self);
@ -738,7 +740,30 @@ where
#[emitter]
fn emit_complex_selector(&mut self, n: &ComplexSelector) -> Result {
self.emit_list(&n.children, ListFormat::SpaceDelimited)?;
let mut need_space = false;
for (idx, node) in n.children.iter().enumerate() {
match node {
ComplexSelectorChildren::Combinator(..) => {
need_space = false;
}
_ => {}
}
if idx != 0 && need_space {
need_space = false;
self.wr.write_space()?;
}
match node {
ComplexSelectorChildren::CompoundSelector(..) => {
need_space = true;
}
_ => {}
}
emit!(self, node)
}
}
#[emitter]

View File

@ -6,7 +6,7 @@ edition = "2018"
license = "Apache-2.0"
name = "swc_stylis"
repository = "https://github.com/swc-project/swc.git"
version = "0.41.0"
version = "0.41.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@ -10,6 +10,7 @@ pub fn prefixer() -> impl VisitMut {
#[derive(Default)]
struct Prefixer {
in_block: bool,
added: Vec<Declaration>,
}
@ -83,20 +84,13 @@ impl Prefixer {
}
impl VisitMut for Prefixer {
fn visit_mut_declaration_block_items(&mut self, props: &mut Vec<DeclarationBlockItem>) {
let mut new = vec![];
for mut n in take(props) {
n.visit_mut_with(self);
new.extend(self.added.drain(..).map(DeclarationBlockItem::Declaration));
new.push(n);
}
*props = new;
}
fn visit_mut_declaration(&mut self, n: &mut Declaration) {
n.visit_mut_children_with(self);
if !self.in_block {
return;
}
macro_rules! simple {
($property:expr,$val:expr) => {{
let val = Value::Ident(Ident {
@ -616,4 +610,24 @@ impl VisitMut for Prefixer {
_ => {}
}
}
fn visit_mut_declaration_block_items(&mut self, props: &mut Vec<DeclarationBlockItem>) {
let mut new = vec![];
for mut n in take(props) {
n.visit_mut_with(self);
new.extend(self.added.drain(..).map(DeclarationBlockItem::Declaration));
new.push(n);
}
*props = new;
}
fn visit_mut_qualified_rule(&mut self, n: &mut QualifiedRule) {
let old_in_block = self.in_block;
self.in_block = true;
n.visit_mut_children_with(self);
self.in_block = old_in_block;
}
}

View File

@ -0,0 +1,17 @@
body {
color: red;
}
:hover {
color: red;
display: flex;
animation: foo 1s ease-out;
}
div a {
display: none;
}
[data-test] > div {
color: red;
}

View File

@ -0,0 +1,10 @@
body{color:red}
:hover{color:red;
display:-webkit-box;
display:-webkit-flex;
display:-ms-flexbox;
display:flex;
-webkit-animation:foo 1s ease-out;
animation:foo 1s ease-out}
div a{display:none}
[data-test]>div{color:red}

View File

@ -0,0 +1,3 @@
div.jsx-5a206f122d1cb32e > span {
color: red;
}

View File

@ -0,0 +1 @@
div.jsx-5a206f122d1cb32e>span{color:red}

View File

@ -0,0 +1,3 @@
.container.jsx-c7c3a8e231c9215a > * {
color: red;
}

View File

@ -0,0 +1 @@
.container.jsx-c7c3a8e231c9215a>*{color:red}

View File

@ -3,8 +3,10 @@
//! License is MIT, which is original license at the time of copying.
//! Original test authors have copyright for their work.
use swc_common::FileName;
use swc_css_ast::DeclarationBlockItem;
use std::path::PathBuf;
use swc_common::{FileName, DUMMY_SP};
use swc_css_ast::{Block, DeclarationBlockItem, QualifiedRule, Stylesheet};
use swc_css_codegen::{
writer::basic::{BasicCssWriter, BasicCssWriterConfig},
CodegenConfig, Emit,
@ -12,6 +14,7 @@ use swc_css_codegen::{
use swc_css_parser::{parse_file, parser::ParserConfig};
use swc_css_visit::VisitMutWith;
use swc_stylis::prefixer::prefixer;
use testing::NormalizedOutput;
#[test]
fn flex_box() {
@ -473,7 +476,7 @@ fn t(src: &str, expected: &str) {
//
let fm = cm.new_source_file(FileName::Anon, src.to_string());
let mut errors = vec![];
let mut props: Vec<DeclarationBlockItem> = parse_file(
let props: Vec<DeclarationBlockItem> = parse_file(
&fm,
ParserConfig {
parse_values: true,
@ -486,12 +489,23 @@ fn t(src: &str, expected: &str) {
err.to_diagnostics(&handler).emit();
}
props.visit_mut_with(&mut prefixer());
let mut node = QualifiedRule {
span: DUMMY_SP,
prelude: swc_css_ast::SelectorList {
span: DUMMY_SP,
children: Default::default(),
},
block: Block {
span: DUMMY_SP,
value: props,
},
};
node.visit_mut_with(&mut prefixer());
let mut wr = String::new();
{
for p in &props {
for p in &node.block.value {
let mut s = String::new();
{
let mut wr = BasicCssWriter::new(&mut s, BasicCssWriterConfig { indent: " " });
@ -514,3 +528,42 @@ fn t(src: &str, expected: &str) {
})
.unwrap();
}
#[testing::fixture("tests/fixture/**/input.css")]
fn fixture(input: PathBuf) {
let output = input.parent().unwrap().join("output.css");
testing::run_test2(false, |cm, handler| {
//
let fm = cm.load_file(&input).unwrap();
let mut errors = vec![];
let mut ss: Stylesheet = parse_file(
&fm,
ParserConfig {
allow_wrong_line_comments: true,
..Default::default()
},
&mut errors,
)
.unwrap();
for err in errors {
err.to_diagnostics(&handler).emit();
}
ss.visit_mut_with(&mut prefixer());
let mut s = String::new();
{
let mut wr = BasicCssWriter::new(&mut s, BasicCssWriterConfig { indent: " " });
let mut gen =
swc_css_codegen::CodeGenerator::new(&mut wr, CodegenConfig { minify: true });
gen.emit(&ss).unwrap();
}
NormalizedOutput::from(s).compare_to_file(&output).unwrap();
Ok(())
})
.unwrap();
}