diff options
Diffstat (limited to 'components/style/media_queries.rs')
-rw-r--r-- | components/style/media_queries.rs | 418 |
1 files changed, 4 insertions, 414 deletions
diff --git a/components/style/media_queries.rs b/components/style/media_queries.rs index 69715b80885..f1eae543c1e 100644 --- a/components/style/media_queries.rs +++ b/components/style/media_queries.rs @@ -13,7 +13,7 @@ use values::specified; #[derive(Debug, PartialEq)] pub struct MediaQueryList { - media_queries: Vec<MediaQuery> + pub media_queries: Vec<MediaQuery> } #[derive(PartialEq, Eq, Copy, Debug)] @@ -71,9 +71,9 @@ pub enum Qualifier { #[derive(Debug, PartialEq)] pub struct MediaQuery { - qualifier: Option<Qualifier>, - media_type: MediaQueryType, - expressions: Vec<Expression>, + pub qualifier: Option<Qualifier>, + pub media_type: MediaQueryType, + pub expressions: Vec<Expression>, } impl MediaQuery { @@ -230,415 +230,5 @@ impl MediaQueryList { #[cfg(test)] mod tests { - use geom::size::TypedSize2D; - use util::geometry::Au; - use stylesheets::{iter_stylesheet_media_rules, iter_stylesheet_style_rules, Stylesheet}; - use stylesheets::Origin; - use super::*; - use url::Url; - use values::specified; - use std::borrow::ToOwned; - fn test_media_rule<F>(css: &str, callback: F) where F: Fn(&MediaQueryList, &str) { - let url = Url::parse("http://localhost").unwrap(); - let stylesheet = Stylesheet::from_str(css, url, Origin::Author); - let mut rule_count: int = 0; - iter_stylesheet_media_rules(&stylesheet, |rule| { - rule_count += 1; - callback(&rule.media_queries, css); - }); - assert!(rule_count > 0); - } - - fn media_query_test(device: &Device, css: &str, expected_rule_count: int) { - let url = Url::parse("http://localhost").unwrap(); - let ss = Stylesheet::from_str(css, url, Origin::Author); - let mut rule_count: int = 0; - iter_stylesheet_style_rules(&ss, device, |_| rule_count += 1); - assert!(rule_count == expected_rule_count, css.to_owned()); - } - - #[test] - fn test_mq_empty() { - test_media_rule("@media { }", |list, css| { - 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::All, css.to_owned()); - assert!(q.expressions.len() == 0, css.to_owned()); - }); - } - - #[test] - fn test_mq_screen() { - test_media_rule("@media screen { }", |list, css| { - 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.expressions.len() == 0, css.to_owned()); - }); - - test_media_rule("@media only screen { }", |list, css| { - 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.expressions.len() == 0, css.to_owned()); - }); - - test_media_rule("@media not screen { }", |list, css| { - 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.expressions.len() == 0, css.to_owned()); - }); - } - - #[test] - fn test_mq_print() { - test_media_rule("@media print { }", |list, css| { - 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.expressions.len() == 0, css.to_owned()); - }); - - test_media_rule("@media only print { }", |list, css| { - 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.expressions.len() == 0, css.to_owned()); - }); - - test_media_rule("@media not print { }", |list, css| { - 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.expressions.len() == 0, css.to_owned()); - }); - } - - #[test] - fn test_mq_unknown() { - test_media_rule("@media fridge { }", |list, css| { - 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), css.to_owned()); - assert!(q.expressions.len() == 0, css.to_owned()); - }); - - test_media_rule("@media only glass { }", |list, css| { - 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), css.to_owned()); - assert!(q.expressions.len() == 0, css.to_owned()); - }); - - test_media_rule("@media not wood { }", |list, css| { - 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), css.to_owned()); - assert!(q.expressions.len() == 0, css.to_owned()); - }); - } - - #[test] - fn test_mq_all() { - test_media_rule("@media all { }", |list, css| { - 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::All, css.to_owned()); - assert!(q.expressions.len() == 0, css.to_owned()); - }); - - test_media_rule("@media only all { }", |list, css| { - 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::All, css.to_owned()); - assert!(q.expressions.len() == 0, css.to_owned()); - }); - - test_media_rule("@media not all { }", |list, css| { - 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::All, css.to_owned()); - assert!(q.expressions.len() == 0, css.to_owned()); - }); - } - - #[test] - fn test_mq_or() { - test_media_rule("@media screen, print { }", |list, css| { - 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.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.expressions.len() == 0, css.to_owned()); - }); - } - - #[test] - fn test_mq_default_expressions() { - test_media_rule("@media (min-width: 100px) { }", |list, css| { - 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::All, 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))), - _ => panic!("wrong expression type"), - } - }); - - test_media_rule("@media (max-width: 43px) { }", |list, css| { - 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::All, 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))), - _ => panic!("wrong expression type"), - } - }); - } - - #[test] - fn test_mq_expressions() { - test_media_rule("@media screen and (min-width: 100px) { }", |list, css| { - 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.expressions.len() == 1, css.to_owned()); - match q.expressions[0] { - Expression::Width(Range::Min(w)) => assert!(w == specified::Length::Absolute(Au::from_px(100))), - _ => panic!("wrong expression type"), - } - }); - - test_media_rule("@media print and (max-width: 43px) { }", |list, css| { - 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.expressions.len() == 1, css.to_owned()); - match q.expressions[0] { - Expression::Width(Range::Max(w)) => assert!(w == specified::Length::Absolute(Au::from_px(43))), - _ => panic!("wrong expression type"), - } - }); - - test_media_rule("@media fridge and (max-width: 52px) { }", |list, css| { - 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), 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))), - _ => panic!("wrong expression type"), - } - }); - } - - #[test] - fn test_mq_multiple_expressions() { - test_media_rule("@media (min-width: 100px) and (max-width: 200px) { }", |list, css| { - 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::All, 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))), - _ => panic!("wrong expression type"), - } - match q.expressions[1] { - Expression::Width(Range::Max(w)) => assert!(w == specified::Length::Absolute(Au::from_px(200))), - _ => panic!("wrong expression type"), - } - }); - - test_media_rule("@media not screen and (min-width: 100px) and (max-width: 200px) { }", |list, css| { - 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.expressions.len() == 2, css.to_owned()); - match q.expressions[0] { - Expression::Width(Range::Min(w)) => assert!(w == specified::Length::Absolute(Au::from_px(100))), - _ => panic!("wrong expression type"), - } - match q.expressions[1] { - Expression::Width(Range::Max(w)) => assert!(w == specified::Length::Absolute(Au::from_px(200))), - _ => panic!("wrong expression type"), - } - }); - } - - #[test] - fn test_mq_malformed_expressions() { - test_media_rule("@media (min-width: 100blah) and (max-width: 200px) { }", |list, css| { - 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::All, css.to_owned()); - assert!(q.expressions.len() == 0, css.to_owned()); - }); - - test_media_rule("@media screen and (height: 200px) { }", |list, css| { - 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::All, css.to_owned()); - assert!(q.expressions.len() == 0, css.to_owned()); - }); - - test_media_rule("@media (min-width: 30em foo bar) {}", |list, css| { - 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::All, css.to_owned()); - assert!(q.expressions.len() == 0, css.to_owned()); - }); - - test_media_rule("@media not {}", |list, css| { - 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::All, css.to_owned()); - assert!(q.expressions.len() == 0, css.to_owned()); - }); - - test_media_rule("@media not (min-width: 300px) {}", |list, css| { - 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::All, css.to_owned()); - assert!(q.expressions.len() == 0, css.to_owned()); - }); - - test_media_rule("@media , {}", |list, css| { - assert!(list.media_queries.len() == 2, css.to_owned()); - let q = &list.media_queries[0]; - assert!(q.qualifier == Some(Qualifier::Not), css.to_owned()); - assert!(q.media_type == MediaQueryType::All, css.to_owned()); - assert!(q.expressions.len() == 0, css.to_owned()); - let q = &list.media_queries[1]; - assert!(q.qualifier == Some(Qualifier::Not), css.to_owned()); - assert!(q.media_type == MediaQueryType::All, css.to_owned()); - assert!(q.expressions.len() == 0, css.to_owned()); - }); - - test_media_rule("@media screen 4px, print {}", |list, css| { - assert!(list.media_queries.len() == 2, css.to_owned()); - let q0 = &list.media_queries[0]; - assert!(q0.qualifier == Some(Qualifier::Not), css.to_owned()); - assert!(q0.media_type == MediaQueryType::All, 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.expressions.len() == 0, css.to_owned()); - }); - - test_media_rule("@media screen, {}", |list, css| { - 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.expressions.len() == 0, css.to_owned()); - let q1 = &list.media_queries[1]; - assert!(q1.qualifier == Some(Qualifier::Not), css.to_owned()); - assert!(q1.media_type == MediaQueryType::All, css.to_owned()); - assert!(q1.expressions.len() == 0, css.to_owned()); - }); - } - - #[test] - fn test_matching_simple() { - let device = Device { - media_type: MediaType::Screen, - viewport_size: TypedSize2D(200.0, 100.0), - }; - - media_query_test(&device, "@media not all { a { color: red; } }", 0); - media_query_test(&device, "@media not screen { a { color: red; } }", 0); - media_query_test(&device, "@media not print { a { color: red; } }", 1); - - media_query_test(&device, "@media unknown { a { color: red; } }", 0); - media_query_test(&device, "@media not unknown { a { color: red; } }", 1); - - media_query_test(&device, "@media { a { color: red; } }", 1); - media_query_test(&device, "@media screen { a { color: red; } }", 1); - media_query_test(&device, "@media print { a { color: red; } }", 0); - } - - #[test] - fn test_matching_width() { - let device = Device { - media_type: MediaType::Screen, - viewport_size: TypedSize2D(200.0, 100.0), - }; - - media_query_test(&device, "@media { a { color: red; } }", 1); - - media_query_test(&device, "@media (min-width: 50px) { a { color: red; } }", 1); - media_query_test(&device, "@media (min-width: 150px) { a { color: red; } }", 1); - media_query_test(&device, "@media (min-width: 300px) { a { color: red; } }", 0); - - media_query_test(&device, "@media screen and (min-width: 50px) { a { color: red; } }", 1); - media_query_test(&device, "@media screen and (min-width: 150px) { a { color: red; } }", 1); - media_query_test(&device, "@media screen and (min-width: 300px) { a { color: red; } }", 0); - - media_query_test(&device, "@media not screen and (min-width: 50px) { a { color: red; } }", 0); - media_query_test(&device, "@media not screen and (min-width: 150px) { a { color: red; } }", 0); - media_query_test(&device, "@media not screen and (min-width: 300px) { a { color: red; } }", 1); - - media_query_test(&device, "@media (max-width: 50px) { a { color: red; } }", 0); - media_query_test(&device, "@media (max-width: 150px) { a { color: red; } }", 0); - media_query_test(&device, "@media (max-width: 300px) { a { color: red; } }", 1); - - media_query_test(&device, "@media screen and (min-width: 50px) and (max-width: 100px) { a { color: red; } }", 0); - media_query_test(&device, "@media screen and (min-width: 250px) and (max-width: 300px) { a { color: red; } }", 0); - media_query_test(&device, "@media screen and (min-width: 50px) and (max-width: 250px) { a { color: red; } }", 1); - - media_query_test(&device, "@media not screen and (min-width: 50px) and (max-width: 100px) { a { color: red; } }", 1); - media_query_test(&device, "@media not screen and (min-width: 250px) and (max-width: 300px) { a { color: red; } }", 1); - media_query_test(&device, "@media not screen and (min-width: 50px) and (max-width: 250px) { a { color: red; } }", 0); - - media_query_test(&device, "@media not screen and (min-width: 3.1em) and (max-width: 6em) { a { color: red; } }", 1); - media_query_test(&device, "@media not screen and (min-width: 16em) and (max-width: 19.75em) { a { color: red; } }", 1); - media_query_test(&device, "@media not screen and (min-width: 3em) and (max-width: 250px) { a { color: red; } }", 0); - } - - #[test] - fn test_matching_invalid() { - let device = Device { - media_type: MediaType::Screen, - viewport_size: TypedSize2D(200.0, 100.0), - }; - - media_query_test(&device, "@media fridge { a { color: red; } }", 0); - media_query_test(&device, "@media screen and (height: 100px) { a { color: red; } }", 0); - media_query_test(&device, "@media not print and (width: 100) { a { color: red; } }", 0); - } } |