style: Cleanup and refactor how media types are represented.

This is necessary for the upcoming work in Stylo, given I plan to make MediaType
different for Servo and Gecko, and the Unknown variant doesn't fit in MediaType
to be fair, the device is never going to have any unknown media type.
This commit is contained in:
Emilio Cobos Álvarez 2016-12-26 22:13:43 +01:00
parent b49eb6f566
commit b4caebae69
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
2 changed files with 45 additions and 36 deletions

View file

@ -94,6 +94,12 @@ pub struct MediaQuery {
}
impl MediaQuery {
/// Return a media query that never matches, used for when we fail to parse
/// a given media query.
fn never_matching() -> Self {
Self::new(Some(Qualifier::Not), MediaQueryType::All, vec![])
}
pub fn new(qualifier: Option<Qualifier>, media_type: MediaQueryType,
expressions: Vec<Expression>) -> MediaQuery {
MediaQuery {
@ -115,9 +121,9 @@ impl ToCss for MediaQuery {
let mut type_ = String::new();
match self.media_type {
MediaQueryType::All => try!(write!(type_, "all")),
MediaQueryType::MediaType(MediaType::Screen) => try!(write!(type_, "screen")),
MediaQueryType::MediaType(MediaType::Print) => try!(write!(type_, "print")),
MediaQueryType::MediaType(MediaType::Unknown(ref desc)) => try!(write!(type_, "{}", desc)),
MediaQueryType::Known(MediaType::Screen) => try!(write!(type_, "screen")),
MediaQueryType::Known(MediaType::Print) => try!(write!(type_, "print")),
MediaQueryType::Unknown(ref desc) => try!(write!(type_, "{}", desc)),
};
if self.expressions.is_empty() {
return write!(dest, "{}", type_)
@ -148,7 +154,18 @@ impl ToCss for MediaQuery {
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum MediaQueryType {
All, // Always true
MediaType(MediaType),
Known(MediaType),
Unknown(Atom),
}
impl MediaQueryType {
fn matches(&self, other: &MediaType) -> bool {
match *self {
MediaQueryType::All => true,
MediaQueryType::Known(ref known_type) => known_type == other,
MediaQueryType::Unknown(..) => false,
}
}
}
#[derive(PartialEq, Eq, Clone, Debug)]
@ -156,7 +173,6 @@ pub enum MediaQueryType {
pub enum MediaType {
Screen,
Print,
Unknown(Atom),
}
#[derive(Debug)]
@ -220,10 +236,10 @@ impl MediaQuery {
let media_type;
if let Ok(ident) = input.try(|input| input.expect_ident()) {
media_type = match_ignore_ascii_case! { ident,
"screen" => MediaQueryType::MediaType(MediaType::Screen),
"print" => MediaQueryType::MediaType(MediaType::Print),
"screen" => MediaQueryType::Known(MediaType::Screen),
"print" => MediaQueryType::Known(MediaType::Print),
"all" => MediaQueryType::All,
_ => MediaQueryType::MediaType(MediaType::Unknown(Atom::from(&*ident)))
_ => MediaQueryType::Unknown(Atom::from(&*ident))
}
} else {
// Media type is only optional if qualifier is not specified.
@ -253,10 +269,8 @@ pub fn parse_media_query_list(input: &mut Parser) -> MediaList {
let mut media_queries = vec![];
loop {
media_queries.push(
input.parse_until_before(Delimiter::Comma, MediaQuery::parse)
.unwrap_or(MediaQuery::new(Some(Qualifier::Not),
MediaQueryType::All,
vec!())));
input.parse_until_before(Delimiter::Comma, MediaQuery::parse).ok()
.unwrap_or_else(MediaQuery::never_matching));
match input.next() {
Ok(Token::Comma) => {},
Ok(_) => unreachable!(),
@ -275,12 +289,7 @@ impl MediaList {
// Check if it is an empty media query list or any queries match (OR condition)
// https://drafts.csswg.org/mediaqueries-4/#mq-list
self.media_queries.is_empty() || self.media_queries.iter().any(|mq| {
// Check if media matches. Unknown media never matches.
let media_match = match mq.media_type {
MediaQueryType::MediaType(MediaType::Unknown(_)) => false,
MediaQueryType::MediaType(ref media_type) => *media_type == device.media_type,
MediaQueryType::All => true,
};
let media_match = mq.media_type.matches(&device.media_type);
// Check if all conditions match (AND condition)
let query_match = media_match && mq.expressions.iter().all(|expression| {

View file

@ -74,7 +74,7 @@ fn test_mq_screen() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == None, css.to_owned());
assert!(q.media_type == MediaQueryType::MediaType(MediaType::Screen), css.to_owned());
assert!(q.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned());
assert!(q.expressions.len() == 0, css.to_owned());
});
@ -82,7 +82,7 @@ fn test_mq_screen() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == Some(Qualifier::Only), css.to_owned());
assert!(q.media_type == MediaQueryType::MediaType(MediaType::Screen), css.to_owned());
assert!(q.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned());
assert!(q.expressions.len() == 0, css.to_owned());
});
@ -90,7 +90,7 @@ fn test_mq_screen() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == Some(Qualifier::Not), css.to_owned());
assert!(q.media_type == MediaQueryType::MediaType(MediaType::Screen), css.to_owned());
assert!(q.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned());
assert!(q.expressions.len() == 0, css.to_owned());
});
}
@ -101,7 +101,7 @@ fn test_mq_print() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == None, css.to_owned());
assert!(q.media_type == MediaQueryType::MediaType(MediaType::Print), css.to_owned());
assert!(q.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned());
assert!(q.expressions.len() == 0, css.to_owned());
});
@ -109,7 +109,7 @@ fn test_mq_print() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == Some(Qualifier::Only), css.to_owned());
assert!(q.media_type == MediaQueryType::MediaType(MediaType::Print), css.to_owned());
assert!(q.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned());
assert!(q.expressions.len() == 0, css.to_owned());
});
@ -117,7 +117,7 @@ fn test_mq_print() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == Some(Qualifier::Not), css.to_owned());
assert!(q.media_type == MediaQueryType::MediaType(MediaType::Print), css.to_owned());
assert!(q.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned());
assert!(q.expressions.len() == 0, css.to_owned());
});
}
@ -128,7 +128,7 @@ fn test_mq_unknown() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == None, css.to_owned());
assert!(q.media_type == MediaQueryType::MediaType(MediaType::Unknown(Atom::from("fridge"))), css.to_owned());
assert!(q.media_type == MediaQueryType::Unknown(Atom::from("fridge")), css.to_owned());
assert!(q.expressions.len() == 0, css.to_owned());
});
@ -136,7 +136,7 @@ fn test_mq_unknown() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == Some(Qualifier::Only), css.to_owned());
assert!(q.media_type == MediaQueryType::MediaType(MediaType::Unknown(Atom::from("glass"))), css.to_owned());
assert!(q.media_type == MediaQueryType::Unknown(Atom::from("glass")), css.to_owned());
assert!(q.expressions.len() == 0, css.to_owned());
});
@ -144,7 +144,7 @@ fn test_mq_unknown() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == Some(Qualifier::Not), css.to_owned());
assert!(q.media_type == MediaQueryType::MediaType(MediaType::Unknown(Atom::from("wood"))), css.to_owned());
assert!(q.media_type == MediaQueryType::Unknown(Atom::from("wood")), css.to_owned());
assert!(q.expressions.len() == 0, css.to_owned());
});
}
@ -182,12 +182,12 @@ fn test_mq_or() {
assert!(list.media_queries.len() == 2, css.to_owned());
let q0 = &list.media_queries[0];
assert!(q0.qualifier == None, css.to_owned());
assert!(q0.media_type == MediaQueryType::MediaType(MediaType::Screen), css.to_owned());
assert!(q0.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned());
assert!(q0.expressions.len() == 0, css.to_owned());
let q1 = &list.media_queries[1];
assert!(q1.qualifier == None, css.to_owned());
assert!(q1.media_type == MediaQueryType::MediaType(MediaType::Print), css.to_owned());
assert!(q1.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned());
assert!(q1.expressions.len() == 0, css.to_owned());
});
}
@ -225,7 +225,7 @@ fn test_mq_expressions() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == None, css.to_owned());
assert!(q.media_type == MediaQueryType::MediaType(MediaType::Screen), css.to_owned());
assert!(q.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned());
assert!(q.expressions.len() == 1, css.to_owned());
match q.expressions[0] {
Expression::Width(Range::Min(w)) => assert!(w == specified::Length::Absolute(Au::from_px(100))),
@ -237,7 +237,7 @@ fn test_mq_expressions() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == None, css.to_owned());
assert!(q.media_type == MediaQueryType::MediaType(MediaType::Print), css.to_owned());
assert!(q.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned());
assert!(q.expressions.len() == 1, css.to_owned());
match q.expressions[0] {
Expression::Width(Range::Max(w)) => assert!(w == specified::Length::Absolute(Au::from_px(43))),
@ -249,7 +249,7 @@ fn test_mq_expressions() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == None, css.to_owned());
assert!(q.media_type == MediaQueryType::MediaType(MediaType::Print), css.to_owned());
assert!(q.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned());
assert!(q.expressions.len() == 1, css.to_owned());
match q.expressions[0] {
Expression::Width(Range::Eq(w)) => assert!(w == specified::Length::Absolute(Au::from_px(43))),
@ -261,7 +261,7 @@ fn test_mq_expressions() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == None, css.to_owned());
assert!(q.media_type == MediaQueryType::MediaType(MediaType::Unknown(Atom::from("fridge"))), css.to_owned());
assert!(q.media_type == MediaQueryType::Unknown(Atom::from("fridge")), css.to_owned());
assert!(q.expressions.len() == 1, css.to_owned());
match q.expressions[0] {
Expression::Width(Range::Max(w)) => assert!(w == specified::Length::Absolute(Au::from_px(52))),
@ -302,7 +302,7 @@ fn test_mq_multiple_expressions() {
assert!(list.media_queries.len() == 1, css.to_owned());
let q = &list.media_queries[0];
assert!(q.qualifier == Some(Qualifier::Not), css.to_owned());
assert!(q.media_type == MediaQueryType::MediaType(MediaType::Screen), css.to_owned());
assert!(q.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned());
assert!(q.expressions.len() == 2, css.to_owned());
match q.expressions[0] {
Expression::Width(Range::Min(w)) => assert!(w == specified::Length::Absolute(Au::from_px(100))),
@ -377,7 +377,7 @@ fn test_mq_malformed_expressions() {
assert!(q0.expressions.len() == 0, css.to_owned());
let q1 = &list.media_queries[1];
assert!(q1.qualifier == None, css.to_owned());
assert!(q1.media_type == MediaQueryType::MediaType(MediaType::Print), css.to_owned());
assert!(q1.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned());
assert!(q1.expressions.len() == 0, css.to_owned());
});
@ -385,7 +385,7 @@ fn test_mq_malformed_expressions() {
assert!(list.media_queries.len() == 2, css.to_owned());
let q0 = &list.media_queries[0];
assert!(q0.qualifier == None, css.to_owned());
assert!(q0.media_type == MediaQueryType::MediaType(MediaType::Screen), css.to_owned());
assert!(q0.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned());
assert!(q0.expressions.len() == 0, css.to_owned());
let q1 = &list.media_queries[1];
assert!(q1.qualifier == Some(Qualifier::Not), css.to_owned());