Skip to content

Commit 72ba688

Browse files
committed
Expand logical properties and prefixes in transitions
1 parent 3735ef6 commit 72ba688

File tree

5 files changed

+458
-47
lines changed

5 files changed

+458
-47
lines changed

build-prefixes.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,8 @@ let mdnFeatures = {
201201
logicalMargin: mdn.css.properties['margin-inline-start'].__compat.support,
202202
logicalPadding: mdn.css.properties['padding-inline-start'].__compat.support,
203203
logicalInset: mdn.css.properties['inset-inline-start'].__compat.support,
204-
logicalSize: mdn.css.properties['inline-size'].__compat.support
204+
logicalSize: mdn.css.properties['inline-size'].__compat.support,
205+
logicalTextAlign: mdn.css.properties['text-align']['flow_relative_values_start_and_end'].__compat.support
205206
};
206207

207208
for (let feature in mdnFeatures) {

src/compat.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use crate::targets::Browsers;
44

5+
#[derive(Clone, Copy)]
56
pub enum Feature {
67
Clamp,
78
CssAnyLink,

src/lib.rs

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4219,6 +4219,194 @@ mod tests {
42194219
-webkit-transition-duration: 2s;
42204220
}
42214221
"#});
4222+
4223+
prefix_test(r#"
4224+
.foo {
4225+
transition-property: margin-inline-start;
4226+
}
4227+
"#, indoc! {r#"
4228+
.foo {
4229+
transition-property: var(--ltr, margin-left) var(--rtl, margin-right);
4230+
}
4231+
4232+
[dir="ltr"] {
4233+
--ltr: initial;
4234+
--rtl: ;
4235+
}
4236+
4237+
[dir="rtl"] {
4238+
--ltr: ;
4239+
--rtl: initial;
4240+
}
4241+
"#
4242+
}, Browsers {
4243+
safari: Some(8 << 16),
4244+
..Browsers::default()
4245+
});
4246+
4247+
prefix_test(r#"
4248+
.foo {
4249+
transition-property: margin-inline-start, padding-inline-start;
4250+
}
4251+
"#, indoc! {r#"
4252+
.foo {
4253+
transition-property: var(--ltr, margin-left, padding-left) var(--rtl, margin-right, padding-right);
4254+
}
4255+
4256+
[dir="ltr"] {
4257+
--ltr: initial;
4258+
--rtl: ;
4259+
}
4260+
4261+
[dir="rtl"] {
4262+
--ltr: ;
4263+
--rtl: initial;
4264+
}
4265+
"#
4266+
}, Browsers {
4267+
safari: Some(8 << 16),
4268+
..Browsers::default()
4269+
});
4270+
4271+
prefix_test(r#"
4272+
.foo {
4273+
transition-property: margin-inline-start, opacity, padding-inline-start, color;
4274+
}
4275+
"#, indoc! {r#"
4276+
.foo {
4277+
transition-property: var(--ltr, margin-left, opacity, padding-left, color) var(--rtl, margin-right, opacity, padding-right, color);
4278+
}
4279+
4280+
[dir="ltr"] {
4281+
--ltr: initial;
4282+
--rtl: ;
4283+
}
4284+
4285+
[dir="rtl"] {
4286+
--ltr: ;
4287+
--rtl: initial;
4288+
}
4289+
"#
4290+
}, Browsers {
4291+
safari: Some(8 << 16),
4292+
..Browsers::default()
4293+
});
4294+
4295+
prefix_test(r#"
4296+
.foo {
4297+
transition-property: margin-block;
4298+
}
4299+
"#, indoc! {r#"
4300+
.foo {
4301+
transition-property: margin-top, margin-bottom;
4302+
}
4303+
"#
4304+
}, Browsers {
4305+
safari: Some(8 << 16),
4306+
..Browsers::default()
4307+
});
4308+
4309+
prefix_test(r#"
4310+
.foo {
4311+
transition: margin-inline-start 2s;
4312+
}
4313+
"#, indoc! {r#"
4314+
.foo {
4315+
transition: var(--ltr, margin-left 2s) var(--rtl, margin-right 2s);
4316+
}
4317+
4318+
[dir="ltr"] {
4319+
--ltr: initial;
4320+
--rtl: ;
4321+
}
4322+
4323+
[dir="rtl"] {
4324+
--ltr: ;
4325+
--rtl: initial;
4326+
}
4327+
"#
4328+
}, Browsers {
4329+
safari: Some(8 << 16),
4330+
..Browsers::default()
4331+
});
4332+
4333+
prefix_test(r#"
4334+
.foo {
4335+
transition: margin-inline-start 2s, padding-inline-start 2s;
4336+
}
4337+
"#, indoc! {r#"
4338+
.foo {
4339+
transition: var(--ltr, margin-left 2s, padding-left 2s) var(--rtl, margin-right 2s, padding-right 2s);
4340+
}
4341+
4342+
[dir="ltr"] {
4343+
--ltr: initial;
4344+
--rtl: ;
4345+
}
4346+
4347+
[dir="rtl"] {
4348+
--ltr: ;
4349+
--rtl: initial;
4350+
}
4351+
"#
4352+
}, Browsers {
4353+
safari: Some(8 << 16),
4354+
..Browsers::default()
4355+
});
4356+
4357+
prefix_test(r#"
4358+
.foo {
4359+
transition: margin-block-start 2s;
4360+
}
4361+
"#, indoc! {r#"
4362+
.foo {
4363+
transition: margin-top 2s;
4364+
}
4365+
"#
4366+
}, Browsers {
4367+
safari: Some(8 << 16),
4368+
..Browsers::default()
4369+
});
4370+
4371+
prefix_test(r#"
4372+
.foo {
4373+
transition: transform;
4374+
}
4375+
"#, indoc! {r#"
4376+
.foo {
4377+
-webkit-transition: -webkit-transform, transform;
4378+
transition: -webkit-transform, transform;
4379+
}
4380+
"#
4381+
}, Browsers {
4382+
safari: Some(6 << 16),
4383+
..Browsers::default()
4384+
});
4385+
4386+
prefix_test(r#"
4387+
.foo {
4388+
transition: border-start-start-radius;
4389+
}
4390+
"#, indoc! {r#"
4391+
.foo {
4392+
-webkit-transition: var(--ltr, border-top-left-radius) var(--rtl, border-top-right-radius);
4393+
transition: var(--ltr, border-top-left-radius) var(--rtl, border-top-right-radius);
4394+
}
4395+
4396+
[dir="ltr"] {
4397+
--ltr: initial;
4398+
--rtl: ;
4399+
}
4400+
4401+
[dir="rtl"] {
4402+
--ltr: ;
4403+
--rtl: initial;
4404+
}
4405+
"#
4406+
}, Browsers {
4407+
safari: Some(4 << 16),
4408+
..Browsers::default()
4409+
});
42224410
}
42234411

42244412
#[test]

src/properties/mod.rs

Lines changed: 78 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,14 @@ use crate::vendor_prefix::VendorPrefix;
5555
use crate::parser::ParserOptions;
5656
use crate::error::{ParserError, PrinterError};
5757
use crate::logical::LogicalProperty;
58+
use crate::targets::Browsers;
59+
use crate::prefixes::Feature;
5860

5961
macro_rules! define_properties {
6062
(
6163
$(
6264
$(#[$meta: meta])*
63-
$name: literal: $property: ident($type: ty $(, $vp: ty)?) $( / $prefix: tt )* $( if $condition: ident )?,
65+
$name: literal: $property: ident($type: ty $(, $vp: ty)?) $( / $prefix: tt )* $( unprefixed: $unprefixed: literal )? $( if $condition: ident )?,
6466
)+
6567
) => {
6668
#[derive(Debug, Clone, PartialEq)]
@@ -107,17 +109,41 @@ macro_rules! define_properties {
107109
$(
108110
$(#[$meta])*
109111
$property$((vp_name!($vp, prefix)))? => {
110-
// TODO: this assumes there is only one prefix. How should we handle multiple?
112+
let mut first = true;
113+
macro_rules! delim {
114+
() => {
115+
#[allow(unused_assignments)]
116+
if first {
117+
first = false;
118+
} else {
119+
dest.delim(',', false)?;
120+
}
121+
};
122+
}
123+
124+
macro_rules! write {
125+
($p: expr) => {
126+
delim!();
127+
dest.write_str(&$name)?;
128+
};
129+
($v: ty, $p: expr) => {
130+
if prefix.contains($p) {
131+
delim!();
132+
$p.to_css(dest)?;
133+
dest.write_str(&$name)?;
134+
}
135+
};
136+
}
137+
111138
$(
112-
macro_rules! write_prefix {
113-
($v: ty) => {
114-
prefix.to_css(dest)?;
115-
};
116-
}
117-
118-
write_prefix!($vp);
139+
write!($vp, VendorPrefix::WebKit);
140+
write!($vp, VendorPrefix::Moz);
141+
write!($vp, VendorPrefix::Ms);
142+
write!($vp, VendorPrefix::O);
119143
)?
120-
dest.write_str(&$name)
144+
145+
write!($($vp,)? VendorPrefix::None);
146+
Ok(())
121147
},
122148
)+
123149
All => dest.write_str("all"),
@@ -172,6 +198,31 @@ macro_rules! define_properties {
172198
}
173199
}
174200

201+
fn set_prefixes_for_targets(&mut self, targets: Option<Browsers>) {
202+
match self {
203+
$(
204+
$(#[$meta])*
205+
#[allow(unused_variables)]
206+
PropertyId::$property$((vp_name!($vp, prefix)))? => {
207+
macro_rules! get_prefixed {
208+
($v: ty, $u: literal) => {};
209+
($v: ty) => {{
210+
if prefix.contains(VendorPrefix::None) {
211+
if let Some(targets) = targets {
212+
*prefix = Feature::$property.prefixes_for(targets);
213+
}
214+
};
215+
}};
216+
() => {};
217+
}
218+
219+
get_prefixed!($($vp)? $(, $unprefixed)?);
220+
},
221+
)+
222+
_ => {}
223+
}
224+
}
225+
175226
fn to_css_with_prefix<W>(&self, dest: &mut Printer<W>, prefix: VendorPrefix) -> Result<(), PrinterError> where W: std::fmt::Write {
176227
use PropertyId::*;
177228
match self {
@@ -228,7 +279,7 @@ macro_rules! define_properties {
228279
match name.as_ref() {
229280
$(
230281
$(#[$meta])*
231-
$name $(if options.$condition)? => {
282+
$name $(if $unprefixed)? $(if options.$condition)? => {
232283
if let Ok(c) = <$type>::parse(input) {
233284
if input.expect_exhausted().is_ok() {
234285
return Ok(Property::$property(c, $(<$vp>::None)?))
@@ -581,26 +632,26 @@ define_properties! {
581632
"gap": Gap(Gap),
582633

583634
// Old flex (2009): https://www.w3.org/TR/2009/WD-css3-flexbox-20090723/
584-
"box-orient": BoxOrient(BoxOrient, VendorPrefix) / "webkit" / "moz",
585-
"box-direction": BoxDirection(BoxDirection, VendorPrefix) / "webkit" / "moz",
586-
"box-ordinal-group": BoxOrdinalGroup(f32, VendorPrefix) / "webkit" / "moz",
587-
"box-align": BoxAlign(BoxAlign, VendorPrefix) / "webkit" / "moz",
588-
"box-flex": BoxFlex(f32, VendorPrefix) / "webkit" / "moz",
589-
"box-flex-group": BoxFlexGroup(f32, VendorPrefix) / "webkit",
590-
"box-pack": BoxPack(BoxPack, VendorPrefix) / "webkit" / "moz",
591-
"box-lines": BoxLines(BoxLines, VendorPrefix) / "webkit" / "moz",
635+
"box-orient": BoxOrient(BoxOrient, VendorPrefix) / "webkit" / "moz" unprefixed: false,
636+
"box-direction": BoxDirection(BoxDirection, VendorPrefix) / "webkit" / "moz" unprefixed: false,
637+
"box-ordinal-group": BoxOrdinalGroup(f32, VendorPrefix) / "webkit" / "moz" unprefixed: false,
638+
"box-align": BoxAlign(BoxAlign, VendorPrefix) / "webkit" / "moz" unprefixed: false,
639+
"box-flex": BoxFlex(f32, VendorPrefix) / "webkit" / "moz" unprefixed: false,
640+
"box-flex-group": BoxFlexGroup(f32, VendorPrefix) / "webkit" unprefixed: false,
641+
"box-pack": BoxPack(BoxPack, VendorPrefix) / "webkit" / "moz" unprefixed: false,
642+
"box-lines": BoxLines(BoxLines, VendorPrefix) / "webkit" / "moz" unprefixed: false,
592643

593644
// Old flex (2012): https://www.w3.org/TR/2012/WD-css3-flexbox-20120322/
594-
"flex-pack": FlexPack(FlexPack, VendorPrefix) / "ms",
595-
"flex-order": FlexOrder(f32, VendorPrefix) / "ms",
596-
"flex-align": FlexAlign(BoxAlign, VendorPrefix) / "ms",
597-
"flex-item-align": FlexItemAlign(FlexItemAlign, VendorPrefix) / "ms",
598-
"flex-line-pack": FlexLinePack(FlexLinePack, VendorPrefix) / "ms",
645+
"flex-pack": FlexPack(FlexPack, VendorPrefix) / "ms" unprefixed: false,
646+
"flex-order": FlexOrder(f32, VendorPrefix) / "ms" unprefixed: false,
647+
"flex-align": FlexAlign(BoxAlign, VendorPrefix) / "ms" unprefixed: false,
648+
"flex-item-align": FlexItemAlign(FlexItemAlign, VendorPrefix) / "ms" unprefixed: false,
649+
"flex-line-pack": FlexLinePack(FlexLinePack, VendorPrefix) / "ms" unprefixed: false,
599650

600651
// Microsoft extensions
601-
"flex-positive": FlexPositive(f32, VendorPrefix) / "ms",
602-
"flex-negative": FlexNegative(f32, VendorPrefix) / "ms",
603-
"flex-preferred-size": FlexPreferredSize(LengthPercentageOrAuto, VendorPrefix) / "ms",
652+
"flex-positive": FlexPositive(f32, VendorPrefix) / "ms" unprefixed: false,
653+
"flex-negative": FlexNegative(f32, VendorPrefix) / "ms" unprefixed: false,
654+
"flex-preferred-size": FlexPreferredSize(LengthPercentageOrAuto, VendorPrefix) / "ms" unprefixed: false,
604655

605656
#[cfg(feature = "grid")]
606657
"grid-template-columns": GridTemplateColumns(TrackSizing),

0 commit comments

Comments
 (0)