Skip to content

Commit 7efeef2

Browse files
committed
Fix handling of strings in animation-name property
Closes parcel-bundler#287
1 parent 7c58283 commit 7efeef2

File tree

2 files changed

+36
-13
lines changed

2 files changed

+36
-13
lines changed

src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8195,6 +8195,10 @@ mod tests {
81958195
minify_test(".foo { animation-name: test }", ".foo{animation-name:test}");
81968196
minify_test(".foo { animation-name: \"test\" }", ".foo{animation-name:test}");
81978197
minify_test(".foo { animation-name: foo, bar }", ".foo{animation-name:foo,bar}");
8198+
minify_test(".foo { animation-name: \"revert\" }", ".foo{animation-name:\"revert\"}");
8199+
minify_test(".foo { animation-name: \"none\" }", ".foo{animation-name:\"none\"}");
8200+
let name = crate::properties::animation::AnimationName::parse_string("default");
8201+
assert!(matches!(name, Err(..)));
81988202
minify_test(".foo { animation-duration: 100ms }", ".foo{animation-duration:.1s}");
81998203
minify_test(
82008204
".foo { animation-duration: 100ms, 2000ms }",

src/properties/animation.rs

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::properties::{Property, PropertyId, VendorPrefix};
1010
use crate::targets::Browsers;
1111
use crate::traits::{Parse, PropertyHandler, Shorthand, ToCss, Zero};
1212
use crate::values::number::CSSNumber;
13+
use crate::values::string::CowArcStr;
1314
use crate::values::{easing::EasingFunction, ident::CustomIdent, time::Time};
1415
use cssparser::*;
1516
use itertools::izip;
@@ -28,6 +29,9 @@ pub enum AnimationName<'i> {
2829
/// An identifier of a `@keyframes` rule.
2930
#[cfg_attr(feature = "serde", serde(borrow))]
3031
Ident(CustomIdent<'i>),
32+
/// A `<string>` name of a `@keyframes` rule.
33+
#[cfg_attr(feature = "serde", serde(borrow))]
34+
String(CowArcStr<'i>),
3135
}
3236

3337
impl<'i> Parse<'i> for AnimationName<'i> {
@@ -36,13 +40,12 @@ impl<'i> Parse<'i> for AnimationName<'i> {
3640
return Ok(AnimationName::None);
3741
}
3842

39-
let location = input.current_source_location();
40-
let name = match *input.next()? {
41-
Token::Ident(ref s) => s.into(),
42-
Token::QuotedString(ref s) => s.into(),
43-
ref t => return Err(location.new_unexpected_token_error(t.clone())),
44-
};
45-
Ok(AnimationName::Ident(CustomIdent(name)))
43+
if let Ok(s) = input.try_parse(|input| input.expect_string_cloned()) {
44+
return Ok(AnimationName::String(s.into()));
45+
}
46+
47+
let ident = CustomIdent::parse(input)?;
48+
Ok(AnimationName::Ident(ident))
4649
}
4750
}
4851

@@ -59,6 +62,22 @@ impl<'i> ToCss for AnimationName<'i> {
5962
}
6063
s.to_css(dest)
6164
}
65+
AnimationName::String(s) => {
66+
if let Some(css_module) = &mut dest.css_module {
67+
css_module.reference(&s, dest.loc.source_index)
68+
}
69+
70+
// CSS-wide keywords and `none` cannot remove quotes.
71+
match_ignore_ascii_case! { &*s,
72+
"none" | "initial" | "inherit" | "unset" | "default" | "revert" | "revert-layer" => {
73+
serialize_string(&s, dest)?;
74+
Ok(())
75+
},
76+
_ => {
77+
dest.write_ident(s.as_ref())
78+
}
79+
}
80+
}
6281
}
6382
}
6483
}
@@ -219,15 +238,15 @@ impl<'i> ToCss for Animation<'i> {
219238
self.name.to_css(dest)?;
220239
match &self.name {
221240
AnimationName::None => return Ok(()),
222-
AnimationName::Ident(name) => {
241+
AnimationName::Ident(CustomIdent(name)) | AnimationName::String(name) => {
223242
if !self.duration.is_zero() || !self.delay.is_zero() {
224243
dest.write_char(' ')?;
225244
self.duration.to_css(dest)?;
226245
}
227246

228247
if (self.timing_function != EasingFunction::Ease
229248
&& self.timing_function != EasingFunction::CubicBezier(0.25, 0.1, 0.25, 1.0))
230-
|| EasingFunction::is_ident(&name.0)
249+
|| EasingFunction::is_ident(&name)
231250
{
232251
dest.write_char(' ')?;
233252
self.timing_function.to_css(dest)?;
@@ -238,22 +257,22 @@ impl<'i> ToCss for Animation<'i> {
238257
self.delay.to_css(dest)?;
239258
}
240259

241-
if self.iteration_count != AnimationIterationCount::Number(1.0) || name.0 == "infinite" {
260+
if self.iteration_count != AnimationIterationCount::Number(1.0) || name.as_ref() == "infinite" {
242261
dest.write_char(' ')?;
243262
self.iteration_count.to_css(dest)?;
244263
}
245264

246-
if self.direction != AnimationDirection::Normal || AnimationDirection::parse_string(&name.0).is_ok() {
265+
if self.direction != AnimationDirection::Normal || AnimationDirection::parse_string(&name).is_ok() {
247266
dest.write_char(' ')?;
248267
self.direction.to_css(dest)?;
249268
}
250269

251-
if self.fill_mode != AnimationFillMode::None || AnimationFillMode::parse_string(&name.0).is_ok() {
270+
if self.fill_mode != AnimationFillMode::None || AnimationFillMode::parse_string(&name).is_ok() {
252271
dest.write_char(' ')?;
253272
self.fill_mode.to_css(dest)?;
254273
}
255274

256-
if self.play_state != AnimationPlayState::Running || AnimationPlayState::parse_string(&name.0).is_ok() {
275+
if self.play_state != AnimationPlayState::Running || AnimationPlayState::parse_string(&name).is_ok() {
257276
dest.write_char(' ')?;
258277
self.play_state.to_css(dest)?;
259278
}

0 commit comments

Comments
 (0)