Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent simplifying translate: none; and scale: none; #703

Merged
merged 3 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
82 changes: 45 additions & 37 deletions node/ast.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* tslint:disable */
/* eslint-disable */
/**
* This file was automatically generated by json-schema-to-typescript.
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
Expand Down Expand Up @@ -5597,6 +5597,48 @@ export type Perspective =
type: "length";
value: Length;
};
/**
* A value for the [translate](https://drafts.csswg.org/css-transforms-2/#propdef-translate) property.
*/
export type Translate =
| "None"
| {
XYZ: {
/**
* The x translation.
*/
x: DimensionPercentageFor_LengthValue;
/**
* The y translation.
*/
y: DimensionPercentageFor_LengthValue;
/**
* The z translation.
*/
z: Length;
};
};
/**
* A value for the [scale](https://drafts.csswg.org/css-transforms-2/#propdef-scale) property.
*/
export type Scale =
| "None"
| {
XYZ: {
/**
* Scale on the x axis.
*/
x: NumberOrPercentage;
/**
* Scale on the y axis.
*/
y: NumberOrPercentage;
/**
* Scale on the z axis.
*/
z: NumberOrPercentage;
};
};
/**
* Defines how text case should be transformed in the [text-transform](https://www.w3.org/TR/2021/CRD-css-text-3-20210422/#text-transform-property) property.
*/
Expand Down Expand Up @@ -7040,8 +7082,8 @@ export type ParsedComponent =
};
}
| {
type: "token";
value: Token;
type: "token-list";
value: TokenOrValue[];
};
/**
* A [multiplier](https://drafts.css-houdini.org/css-properties-values-api/#multipliers) for a [SyntaxComponent](SyntaxComponent). Indicates whether and how the component may be repeated.
Expand Down Expand Up @@ -8489,23 +8531,6 @@ export interface Matrix3DForFloat {
m43: number;
m44: number;
}
/**
* A value for the [translate](https://drafts.csswg.org/css-transforms-2/#propdef-translate) property.
*/
export interface Translate {
/**
* The x translation.
*/
x: DimensionPercentageFor_LengthValue;
/**
* The y translation.
*/
y: DimensionPercentageFor_LengthValue;
/**
* The z translation.
*/
z: Length;
}
/**
* A value for the [rotate](https://drafts.csswg.org/css-transforms-2/#propdef-rotate) property.
*/
Expand All @@ -8527,23 +8552,6 @@ export interface Rotate {
*/
z: number;
}
/**
* A value for the [scale](https://drafts.csswg.org/css-transforms-2/#propdef-scale) property.
*/
export interface Scale {
/**
* Scale on the x axis.
*/
x: NumberOrPercentage;
/**
* Scale on the y axis.
*/
y: NumberOrPercentage;
/**
* Scale on the z axis.
*/
z: NumberOrPercentage;
}
/**
* A value for the [text-transform](https://www.w3.org/TR/2021/CRD-css-text-3-20210422/#text-transform-property) property.
*/
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11645,7 +11645,7 @@ mod tests {
minify_test(".foo { translate: 1px 0px 0px }", ".foo{translate:1px}");
minify_test(".foo { translate: 1px 2px 0px }", ".foo{translate:1px 2px}");
minify_test(".foo { translate: 1px 0px 2px }", ".foo{translate:1px 0 2px}");
minify_test(".foo { translate: none }", ".foo{translate:0}");
minify_test(".foo { translate: none }", ".foo{translate:none}");
minify_test(".foo { rotate: 10deg }", ".foo{rotate:10deg}");
minify_test(".foo { rotate: z 10deg }", ".foo{rotate:10deg}");
minify_test(".foo { rotate: 0 0 1 10deg }", ".foo{rotate:10deg}");
Expand All @@ -11659,7 +11659,7 @@ mod tests {
minify_test(".foo { scale: 1 }", ".foo{scale:1}");
minify_test(".foo { scale: 1 1 }", ".foo{scale:1}");
minify_test(".foo { scale: 1 1 1 }", ".foo{scale:1}");
minify_test(".foo { scale: none }", ".foo{scale:1}");
minify_test(".foo { scale: none }", ".foo{scale:none}");
minify_test(".foo { scale: 1 0 }", ".foo{scale:1 0}");
minify_test(".foo { scale: 1 0 1 }", ".foo{scale:1 0}");
minify_test(".foo { scale: 1 0 0 }", ".foo{scale:1 0 0}");
Expand Down
119 changes: 75 additions & 44 deletions src/properties/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1457,23 +1457,25 @@ impl ToCss for Perspective {
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "into_owned", derive(static_self::IntoOwned))]
pub struct Translate {
/// The x translation.
pub x: LengthPercentage,
/// The y translation.
pub y: LengthPercentage,
/// The z translation.
pub z: Length,
pub enum Translate {
/// The "none" keyword.
None,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also use Keyword(&'a str) but not sure if it's worth it to do that honestly especially since keywords could all be known upfront and the 'none' value is the only one we care about right now.


/// The x, y, and z translations.
XYZ {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could use a better name, but I don't hate it. I also noticed there are some structs like this in the colors.rs file. E.g.: XYZd50

/// The x translation.
x: LengthPercentage,
/// The y translation.
y: LengthPercentage,
/// The z translation.
z: Length,
},
}

impl<'i> Parse<'i> for Translate {
fn parse<'t>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i, ParserError<'i>>> {
if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
return Ok(Translate {
x: LengthPercentage::zero(),
y: LengthPercentage::zero(),
z: Length::zero(),
});
return Ok(Translate::None);
}

let x = LengthPercentage::parse(input)?;
Expand All @@ -1484,7 +1486,7 @@ impl<'i> Parse<'i> for Translate {
None
};

Ok(Translate {
Ok(Translate::XYZ {
x,
y: y.unwrap_or(LengthPercentage::zero()),
z: z.unwrap_or(Length::zero()),
Expand All @@ -1497,23 +1499,36 @@ impl ToCss for Translate {
where
W: std::fmt::Write,
{
self.x.to_css(dest)?;
if !self.y.is_zero() || !self.z.is_zero() {
dest.write_char(' ')?;
self.y.to_css(dest)?;
if !self.z.is_zero() {
dest.write_char(' ')?;
self.z.to_css(dest)?;
match self {
Translate::None => {
dest.write_str("none")?;
}
}
Translate::XYZ { x, y, z } => {
x.to_css(dest)?;
if !y.is_zero() || !z.is_zero() {
dest.write_char(' ')?;
y.to_css(dest)?;
if !z.is_zero() {
dest.write_char(' ')?;
z.to_css(dest)?;
}
}
}
};

Ok(())
}
}

impl Translate {
/// Converts the translation to a transform function.
pub fn to_transform(&self) -> Transform {
Transform::Translate3d(self.x.clone(), self.y.clone(), self.z.clone())
match self {
Translate::None => {
Transform::Translate3d(LengthPercentage::zero(), LengthPercentage::zero(), Length::zero())
}
Translate::XYZ { x, y, z } => Transform::Translate3d(x.clone(), y.clone(), z.clone()),
}
}
}

Expand Down Expand Up @@ -1610,23 +1625,25 @@ impl Rotate {
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "into_owned", derive(static_self::IntoOwned))]
pub struct Scale {
/// Scale on the x axis.
pub x: NumberOrPercentage,
/// Scale on the y axis.
pub y: NumberOrPercentage,
/// Scale on the z axis.
pub z: NumberOrPercentage,
pub enum Scale {
/// The "none" keyword.
None,

/// Scale on the x, y, and z axis.
XYZ {
/// Scale on the x axis.
x: NumberOrPercentage,
/// Scale on the y axis.
y: NumberOrPercentage,
/// Scale on the z axis.
z: NumberOrPercentage,
},
}

impl<'i> Parse<'i> for Scale {
fn parse<'t>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i, ParserError<'i>>> {
if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
return Ok(Scale {
x: NumberOrPercentage::Number(1.0),
y: NumberOrPercentage::Number(1.0),
z: NumberOrPercentage::Number(1.0),
});
return Ok(Scale::None);
}

let x = NumberOrPercentage::parse(input)?;
Expand All @@ -1637,7 +1654,7 @@ impl<'i> Parse<'i> for Scale {
None
};

Ok(Scale {
Ok(Scale::XYZ {
x: x.clone(),
y: y.unwrap_or(x),
z: z.unwrap_or(NumberOrPercentage::Number(1.0)),
Expand All @@ -1650,14 +1667,21 @@ impl ToCss for Scale {
where
W: std::fmt::Write,
{
self.x.to_css(dest)?;
let zv: f32 = (&self.z).into();
if self.y != self.x || zv != 1.0 {
dest.write_char(' ')?;
self.y.to_css(dest)?;
if zv != 1.0 {
dest.write_char(' ')?;
self.z.to_css(dest)?;
match self {
Scale::None => {
dest.write_str("none")?;
}
Scale::XYZ { x, y, z } => {
x.to_css(dest)?;
let zv: f32 = z.into();
if y != x || zv != 1.0 {
dest.write_char(' ')?;
y.to_css(dest)?;
if zv != 1.0 {
dest.write_char(' ')?;
z.to_css(dest)?;
}
}
}
}

Expand All @@ -1668,7 +1692,14 @@ impl ToCss for Scale {
impl Scale {
/// Converts the scale to a transform function.
pub fn to_transform(&self) -> Transform {
Transform::Scale3d(self.x.clone(), self.y.clone(), self.z.clone())
match self {
Scale::None => Transform::Scale3d(
NumberOrPercentage::Number(1.0),
NumberOrPercentage::Number(1.0),
NumberOrPercentage::Number(1.0),
),
Scale::XYZ { x, y, z } => Transform::Scale3d(x.clone(), y.clone(), z.clone()),
}
}
}

Expand Down