From 7f38e06e0209216200182555c7c7ddb11499e45d Mon Sep 17 00:00:00 2001 From: Alexander Akait <4567934+alexander-akait@users.noreply.github.com> Date: Fri, 8 Apr 2022 09:53:38 +0300 Subject: [PATCH] fix(css/prefixer): FIx a bug related to `writing-mode` (#4278) --- crates/swc_css_prefixer/src/prefixer.rs | 109 +++++++++++++++--- .../tests/fixture/writing-mode/input.css | 12 ++ .../tests/fixture/writing-mode/output.css | 32 +++-- 3 files changed, 127 insertions(+), 26 deletions(-) diff --git a/crates/swc_css_prefixer/src/prefixer.rs b/crates/swc_css_prefixer/src/prefixer.rs index 385c071acee..7c25228a569 100644 --- a/crates/swc_css_prefixer/src/prefixer.rs +++ b/crates/swc_css_prefixer/src/prefixer.rs @@ -430,7 +430,7 @@ struct Prefixer { in_stylesheet: bool, in_media_query_list: bool, in_keyframe_block: bool, - in_simple_block: bool, + simple_block: Option, added_rules: Vec, added_declarations: Vec, } @@ -468,6 +468,43 @@ impl Prefixer { important: n.important.clone(), }); } + + fn get_declaration_by_name(&mut self, name: &str) -> Option { + match &self.simple_block { + Some(SimpleBlock { value, .. }) => { + let mut found = None; + + for n in value.iter().rev() { + match n { + ComponentValue::DeclarationOrAtRule(DeclarationOrAtRule::Declaration( + declaration @ Declaration { + name: DeclarationName::Ident(Ident { value, .. }), + .. + }, + )) if value.as_ref().eq_ignore_ascii_case(name) => { + found = Some(declaration.clone()); + + break; + } + ComponentValue::StyleBlock(StyleBlock::Declaration( + declaration @ Declaration { + name: DeclarationName::Ident(Ident { value, .. }), + .. + }, + )) if value.as_ref().eq_ignore_ascii_case(name) => { + found = Some(declaration.clone()); + + break; + } + _ => {} + } + } + + found + } + _ => None, + } + } } pub enum Prefix { @@ -694,7 +731,7 @@ impl VisitMut for Prefixer { fn visit_mut_declaration(&mut self, n: &mut Declaration) { n.visit_mut_children_with(self); - if !self.in_simple_block { + if self.simple_block.is_none() { return; } @@ -1911,31 +1948,71 @@ impl VisitMut for Prefixer { same_content!(Prefix::O, "-o-transition-timing-function"); } - // TODO fix me, we should look at `direction` property https://github.com/postcss/autoprefixer/blob/main/lib/hacks/writing-mode.js "writing-mode" if n.value.len() == 1 => { + let direction = match self.get_declaration_by_name("direction") { + Some(Declaration { value, .. }) => match value.get(0) { + Some(ComponentValue::Ident(Ident { value, .. })) + if value.as_ref().eq_ignore_ascii_case("rtl") => + { + Some("rtl") + } + _ => Some("ltr"), + }, + _ => Some("ltr"), + }; + if let ComponentValue::Ident(Ident { value, .. }) = &n.value[0] { match &*value.to_lowercase() { - "none" => { + "vertical-lr" => { same_content!(Prefix::Webkit, "-webkit-writing-mode"); - same_content!(Prefix::Ms, "-ms-writing-mode"); + + match direction { + Some("ltr") => { + simple!("-ms-writing-mode", "tb-lr"); + } + Some("rtl") => { + simple!("-ms-writing-mode", "bt-lr"); + } + _ => {} + } } - "vertical-lr" | "sideways-lr" => { + "vertical-rl" => { same_content!(Prefix::Webkit, "-webkit-writing-mode"); - simple!("-ms-writing-mode", "tb"); - } - "vertical-rl" | "sideways-rl" => { - same_content!(Prefix::Webkit, "-webkit-writing-mode"); - simple!("-ms-writing-mode", "tb-rl"); + match direction { + Some("ltr") => { + simple!("-ms-writing-mode", "tb-rl"); + } + Some("rtl") => { + simple!("-ms-writing-mode", "bt-rl"); + } + _ => {} + } } "horizontal-tb" => { same_content!(Prefix::Webkit, "-webkit-writing-mode"); - simple!("-ms-writing-mode", "lr"); + + match direction { + Some("ltr") => { + simple!("-ms-writing-mode", "lr-tb"); + } + Some("rtl") => { + simple!("-ms-writing-mode", "rl-tb"); + } + _ => {} + } } - _ => {} + "sideways-rl" | "sideways-lr" => { + same_content!(Prefix::Webkit, "-webkit-writing-mode"); + } + + _ => { + same_content!(Prefix::Webkit, "-webkit-writing-mode"); + same_content!(Prefix::Ms, "-ms-writing-mode"); + } } } } @@ -2306,9 +2383,9 @@ impl VisitMut for Prefixer { } fn visit_mut_simple_block(&mut self, simple_block: &mut SimpleBlock) { - let old_in_simple_block = self.in_simple_block; + let old_simple_block = self.simple_block.clone(); - self.in_simple_block = true; + self.simple_block = Some(simple_block.clone()); let mut new = vec![]; @@ -2326,6 +2403,6 @@ impl VisitMut for Prefixer { simple_block.value = new; - self.in_simple_block = old_in_simple_block; + self.simple_block = old_simple_block; } } diff --git a/crates/swc_css_prefixer/tests/fixture/writing-mode/input.css b/crates/swc_css_prefixer/tests/fixture/writing-mode/input.css index 4c2b899d300..600c9256abf 100644 --- a/crates/swc_css_prefixer/tests/fixture/writing-mode/input.css +++ b/crates/swc_css_prefixer/tests/fixture/writing-mode/input.css @@ -54,3 +54,15 @@ .class { writing-mode: sideways-lr; } + +@viewport { + writing-mode: horizontal-tb; + direction: rtl; +} + +@keyframes test { + 100% { + writing-mode: horizontal-tb; + direction: rtl; + } +} diff --git a/crates/swc_css_prefixer/tests/fixture/writing-mode/output.css b/crates/swc_css_prefixer/tests/fixture/writing-mode/output.css index 0c7965ba72e..b126f47c80d 100644 --- a/crates/swc_css_prefixer/tests/fixture/writing-mode/output.css +++ b/crates/swc_css_prefixer/tests/fixture/writing-mode/output.css @@ -1,6 +1,6 @@ .one { -webkit-writing-mode: horizontal-tb; - -ms-writing-mode: lr; + -ms-writing-mode: lr-tb; writing-mode: horizontal-tb; } .two { @@ -10,30 +10,30 @@ } .three { -webkit-writing-mode: vertical-lr; - -ms-writing-mode: tb; + -ms-writing-mode: tb-lr; writing-mode: vertical-lr; } .rtl-vertical-rl { -webkit-writing-mode: vertical-rl; - -ms-writing-mode: tb-rl; + -ms-writing-mode: bt-rl; writing-mode: vertical-rl; direction: rtl; } .rtl-vertical-lr { -webkit-writing-mode: vertical-lr; - -ms-writing-mode: tb; + -ms-writing-mode: bt-lr; writing-mode: vertical-lr; direction: rtl; } .rtl-horizontal-tb { -webkit-writing-mode: horizontal-tb; - -ms-writing-mode: lr; + -ms-writing-mode: rl-tb; writing-mode: horizontal-tb; direction: rtl; } .rtl-horizontal-tb-override-direction { -webkit-writing-mode: horizontal-tb; - -ms-writing-mode: lr; + -ms-writing-mode: lr-tb; writing-mode: horizontal-tb; direction: rtl; direction: ltr; @@ -45,7 +45,7 @@ } .class { -webkit-writing-mode: vertical-lr; - -ms-writing-mode: tb; + -ms-writing-mode: tb-lr; writing-mode: vertical-lr; } .class { @@ -55,16 +55,28 @@ } .class { -webkit-writing-mode: horizontal-tb; - -ms-writing-mode: lr; + -ms-writing-mode: lr-tb; writing-mode: horizontal-tb; } .class { -webkit-writing-mode: sideways-rl; - -ms-writing-mode: tb-rl; writing-mode: sideways-rl; } .class { -webkit-writing-mode: sideways-lr; - -ms-writing-mode: tb; writing-mode: sideways-lr; } +@viewport{ + -webkit-writing-mode: horizontal-tb; + -ms-writing-mode: rl-tb; + writing-mode: horizontal-tb; + direction: rtl; +} +@keyframes test { + 100% { + -webkit-writing-mode: horizontal-tb; + -ms-writing-mode: rl-tb; + writing-mode: horizontal-tb; + direction: rtl; + } +}