-
Notifications
You must be signed in to change notification settings - Fork 188
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
Transform as an html attribute not parsed correctly #834
Comments
Yeah the syntax for SVG transform attributes is completely different from CSS. For example rotate takes additional arguments for the center point instead of using transform-origin. I'd probably recommend using a different parser and value type for the presentation attributes vs CSS. |
Yep, absolutely -- SVG transform seems to be a kind of superset of CSS transforms. Thought it'd be worth making this issue for awareness anyway. use lazy_static::lazy_static;
fn svg_transform_to_css_transform(css_string: String) -> Cow<'_, str> {
// transform `rotate(r, x, y)` -> `matrix(a, b, c, d, e, f)`
// see https://github.com/svg/svgo/blob/a8472bc45fe1d92d5f848a08cf4d5c8f4a531ad9/plugins/_transforms.js#L511
let v = ROTATE_LONG.replace_all(&value, |caps: ®ex::Captures| {
let original = format!("rotate({} {} {})", &caps["r"], &caps["x"], &caps["y"]);
let Ok(deg) = caps["r"].parse::<f64>() else {
log::debug!("r failed: {}", &caps["r"]);
return original;
};
let Ok(x) = caps["x"].parse::<f64>() else {
log::debug!("x failed: {}", &caps["x"]);
return original;
};
let Ok(y) = caps["y"].parse::<f64>() else {
log::debug!("y failed: {}", &caps["y"]);
return original;
};
let rad = deg.to_radians();
let cos = rad.cos();
let sin = rad.sin();
format!(
"matrix({cos} {sin} {} {cos} {} {})",
-sin,
(1.0 - cos) * x + sin * y,
(1.0 - cos) * y - sin * x
)
});
// transform `f(a b ...)` -> `f(a, b, ...)`
let v = LIST_SEP_SPACE.replace_all(&v, "$a, ");
// transform `rotate(r)` -> `rotate(rdeg)`
value = ROTATE
.replace_all(&v, |caps: ®ex::Captures| {
format!("{}({}deg", &caps["f"], &caps["v"])
})
}
lazy_static! {
static ref LIST_SEP_SPACE: regex::Regex = regex::Regex::new(r"(?<a>\d)\s+").unwrap();
static ref ROTATE: regex::Regex =
regex::Regex::new(r"(?<f>rotate|skewX|skewY)\((?<v>\s*[^\s\),]+)").unwrap();
static ref ROTATE_LONG: regex::Regex = regex::Regex::new(
r"rotate\((?<r>[\d\.e-]+)[^\d\)]+?(?<x>[\d\.e-]+)[^\d\)]+?(?<y>[\d\.e-]+)\)"
)
.unwrap();
} In terms of lightningcss, having a separate parser makes sense to me. |
Because
transform="..."
tends to be unit-less and space-separated they aren't parsed correctly by lightning-css despite being a presentation attribute.For example, the following is a valid transform in HTML, but not CSS
/* eg <g transform="translate(0 10)"></g> */ translate(0 10)
While the following is valid in both CSS and HTML
Yet, they are functionally equivalent.
Since in a HTML context the expected syntax is slightly difference, it might be nice to specify in the parser options whether a property being parsed is a presentation attribute
The text was updated successfully, but these errors were encountered: