Auto merge of #15516 - absoludity:fix-animation-serialization-15398, r=upsuper

Animation longhand serialization should be a list of each animation rather than a list of lists for each longhand.

Fixes part of #15398 -  serialization should be a list of each animation, rather than a list of lists for each longhand.

---
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes are prework for #15398

- [X] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15516)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-02-19 19:41:19 -08:00 committed by GitHub
commit 978a603190
2 changed files with 136 additions and 16 deletions

View file

@ -308,28 +308,55 @@ macro_rules! try_parse_one {
impl<'a> LonghandsToSerialize<'a> {
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
try!(self.animation_duration.to_css(dest));
try!(write!(dest, " "));
fn extract_value<T>(x: &DeclaredValue<T>) -> Option< &T> {
match *x {
DeclaredValue::Value(ref val) => Some(val),
_ => None,
}
}
try!(self.animation_timing_function.to_css(dest));
try!(write!(dest, " "));
// TODO: When the lengths are different, shorthand shouldn't be serialized
// at all.
use std::cmp;
let mut len = 0;
% for name in "duration timing_function delay direction fill_mode iteration_count play_state name".split():
len = cmp::max(len, extract_value(self.animation_${name}).map(|i| i.0.len())
.unwrap_or(0));
% endfor
try!(self.animation_delay.to_css(dest));
try!(write!(dest, " "));
// There should be at least one declared value
if len == 0 {
return dest.write_str("")
}
try!(self.animation_direction.to_css(dest));
try!(write!(dest, " "));
let mut first = true;
for i in 0..len {
% for name in "duration timing_function delay direction fill_mode iteration_count play_state name".split():
let ${name} = if let DeclaredValue::Value(ref arr) = *self.animation_${name} {
arr.0.get(i % arr.0.len())
} else {
None
};
% endfor
try!(self.animation_fill_mode.to_css(dest));
try!(write!(dest, " "));
if first {
first = false;
} else {
try!(write!(dest, ", "));
}
try!(self.animation_iteration_count.to_css(dest));
try!(write!(dest, " "));
% for name in "duration timing_function delay direction fill_mode iteration_count play_state".split():
if let Some(${name}) = ${name} {
try!(${name}.to_css(dest));
try!(write!(dest, " "));
}
% endfor
try!(self.animation_play_state.to_css(dest));
try!(write!(dest, " "));
self.animation_name.to_css(dest)
if let Some(name) = name {
try!(name.to_css(dest));
}
}
Ok(())
}
}
</%helpers:shorthand>

View file

@ -1136,6 +1136,99 @@ mod shorthand_serialization {
assert_eq!(try_serialize.is_ok(), true);
assert_eq!(s, "none");
}
}
mod animation {
pub use super::*;
use cssparser::Parser;
use media_queries::CSSErrorReporterTest;
use servo_url::ServoUrl;
use style::parser::ParserContext;
use style::properties::{parse_property_declaration_list, PropertyDeclarationBlock};
use style::stylesheets::Origin;
fn property_declaration_block(css_properties: &str) -> PropertyDeclarationBlock {
let url = ServoUrl::parse("http://localhost").unwrap();
let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest));
let mut parser = Parser::new(css_properties);
parse_property_declaration_list(&context, &mut parser)
}
#[test]
fn serialize_single_animation() {
let block = property_declaration_block("\
animation-name: bounce;\
animation-duration: 1s;\
animation-timing-function: ease-in;\
animation-delay: 0s;\
animation-direction: normal;\
animation-fill-mode: forwards;\
animation-iteration-count: infinite;\
animation-play-state: paused;");
let serialization = block.to_css_string();
assert_eq!(serialization, "animation: 1s ease-in 0s normal forwards infinite paused bounce;")
}
#[test]
fn serialize_multiple_animations() {
let block = property_declaration_block("\
animation-name: bounce, roll;\
animation-duration: 1s, 0.2s;\
animation-timing-function: ease-in, linear;\
animation-delay: 0s, 1s;\
animation-direction: normal, reverse;\
animation-fill-mode: forwards, backwards;\
animation-iteration-count: infinite, 2;\
animation-play-state: paused, running;");
let serialization = block.to_css_string();
assert_eq!(serialization,
"animation: 1s ease-in 0s normal forwards infinite paused bounce, \
0.2s linear 1s reverse backwards 2 running roll;");
}
#[test]
fn serialize_multiple_animations_unequal_property_lists() {
// Currently the implementation cycles values if the lists are
// uneven. This is incorrect, in that we should serialize only
// when the lists have the same length (both here and for background
// and transition. See https://github.com/servo/servo/issues/15398 )
let block = property_declaration_block("\
animation-name: bounce, roll, flip, jump;\
animation-duration: 1s, 0.2s;\
animation-timing-function: ease-in, linear;\
animation-delay: 0s, 1s, 0.5s;\
animation-direction: normal;\
animation-fill-mode: forwards, backwards;\
animation-iteration-count: infinite, 2;\
animation-play-state: paused, running;");
let serialization = block.to_css_string();
assert_eq!(serialization, "animation: \
1s ease-in 0s normal forwards infinite paused bounce, \
0.2s linear 1s normal backwards 2 running roll, \
1s ease-in 0.5s normal forwards infinite paused flip, \
0.2s linear 0s normal backwards 2 running jump;")
}
#[test]
fn serialize_multiple_without_all_properties_returns_longhand() {
// timing function and direction are missing, so no shorthand is returned.
let block_text = "animation-name: bounce, roll; \
animation-duration: 1s, 0.2s; \
animation-delay: 0s, 1s; \
animation-fill-mode: forwards, backwards; \
animation-iteration-count: infinite, 2; \
animation-play-state: paused, running;";
let block = property_declaration_block(block_text);
let serialization = block.to_css_string();
assert_eq!(serialization, block_text);
}
}
}