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
WIP #17808
WIP #17808
Changes from 1 commit
File filter...
Jump to…
Parse Sizes Attribute
- Loading branch information
Some generated files are not rendered by default. Learn more.
| @@ -3,6 +3,7 @@ | ||
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
|
||
| use app_units::{Au, AU_PER_PX}; | ||
| use cssparser::{Parser, ParserInput}; | ||
| use document_loader::{LoadType, LoadBlocker}; | ||
| use dom::activation::Activatable; | ||
| use dom::attr::Attr; | ||
| @@ -52,10 +53,17 @@ use script_thread::{Runnable, ScriptThread}; | ||
| use servo_url::ServoUrl; | ||
| use servo_url::origin::ImmutableOrigin; | ||
| use std::cell::{Cell, RefMut}; | ||
| use std::char; | ||
| use std::default::Default; | ||
| use std::i32; | ||
| use std::sync::{Arc, Mutex}; | ||
| use style::attr::{AttrValue, LengthOrPercentageOrAuto}; | ||
| use style::context::QuirksMode; | ||
| use style::media_queries::MediaQuery; | ||
| use style::parser::ParserContext; | ||
| use style::values::specified::{Length, ViewportPercentageLength}; | ||
| use style::values::specified::length::NoCalcLength; | ||
| use style_traits::ParsingMode; | ||
| use task_source::TaskSource; | ||
|
|
||
| #[derive(Clone, Copy, HeapSizeOf, JSTraceable)] | ||
| @@ -66,6 +74,12 @@ enum State { | ||
| CompletelyAvailable, | ||
| Broken, | ||
| } | ||
| #[derive(PartialEq)] | ||
|
||
| #[derive(Debug)] | ||
| pub struct Size { | ||
| pub query: Option<MediaQuery>, | ||
| pub length: Length, | ||
| } | ||
| #[derive(Clone, Copy, HeapSizeOf, JSTraceable)] | ||
| enum ImageRequestPhase { | ||
| Pending, | ||
| @@ -780,6 +794,63 @@ impl LayoutHTMLImageElementHelpers for LayoutJS<HTMLImageElement> { | ||
| } | ||
| } | ||
|
|
||
| //https://html.spec.whatwg.org/multipage/#parse-a-sizes-attribute | ||
| pub fn parse_a_sizes_attribute(input: DOMString, width: Option<u32>) -> Vec<Size> { | ||
jdm
Member
|
||
| let mut sizes = Vec::<Size>::new(); | ||
| let unparsed_sizes = input.split(',').collect::<Vec<_>>(); | ||
|
|
||
| for unparsed_size in &unparsed_sizes { | ||
wafflespeanut
Member
|
||
| let whitespace = unparsed_size.chars().rev().take_while(|c| char::is_whitespace(*c)).count(); | ||
| let trimmed: String = unparsed_size.chars().take(unparsed_size.chars().count() - whitespace).collect(); | ||
|
|
||
| if trimmed.is_empty() { | ||
| continue; | ||
| } | ||
| let mut input = ParserInput::new(&trimmed); | ||
| let url = ServoUrl::parse("about:blank").unwrap(); | ||
| let context = ParserContext::new_for_cssom(&url, | ||
| None, | ||
| ParsingMode::empty(), | ||
| QuirksMode::NoQuirks); | ||
| let mut parser = Parser::new(&mut input); | ||
| let length = parser.try(|i| Length::parse_non_negative(&context, i)); | ||
| println!("\n{:?}", length); | ||
| match length { | ||
| Ok(len) => sizes.push(Size { | ||
| length: len, | ||
| query: None | ||
| }), | ||
| Err(_) => { | ||
| let mut media_query_parser = parser; | ||
| let media_query = media_query_parser.try(|i| MediaQuery::parse(&context, i)); | ||
| if let Ok(query) = media_query { | ||
| let length = Length::parse_non_negative(&context, &mut media_query_parser); | ||
| if let Ok(length) = length { | ||
| sizes.push(Size { | ||
| length: length, | ||
| query: Some(query) | ||
| }) | ||
| } | ||
| } | ||
| }, | ||
| } | ||
| } | ||
| if sizes.is_empty() { | ||
| let size = match width { | ||
| Some(w) => Size { | ||
| length: Length::from_px(w as f32), | ||
| query: None | ||
| }, | ||
| None => Size { | ||
| length: Length::NoCalc(NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vw(100.))), | ||
| query: None | ||
| }, | ||
| }; | ||
| sizes.push(size); | ||
| } | ||
| sizes | ||
| } | ||
|
|
||
| impl HTMLImageElementMethods for HTMLImageElement { | ||
| // https://html.spec.whatwg.org/multipage/#dom-img-alt | ||
| make_getter!(Alt, "alt"); | ||
| @@ -791,6 +862,11 @@ impl HTMLImageElementMethods for HTMLImageElement { | ||
| // https://html.spec.whatwg.org/multipage/#dom-img-src | ||
| make_setter!(SetSrc, "src"); | ||
|
|
||
| // https://html.spec.whatwg.org/multipage/#parse-a-sizes-attribute | ||
| make_getter!(Sizes, "sizes"); | ||
| // https://html.spec.whatwg.org/multipage/#parse-a-sizes-attribute | ||
| make_setter!(SetSizes, "sizes"); | ||
|
|
||
|
||
| // https://html.spec.whatwg.org/multipage/#dom-img-crossOrigin | ||
| fn GetCrossOrigin(&self) -> Option<DOMString> { | ||
| reflect_cross_origin_attribute(self.upcast::<Element>()) | ||
| @@ -0,0 +1,103 @@ | ||
| /* This Source Code Form is subject to the terms of the Mozilla Public | ||
| * License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
|
||
| use script::test::DOMString; | ||
| use script::test::sizes::{parse_a_sizes_attribute, Size}; | ||
| use style::media_queries::{MediaQuery, MediaQueryType}; | ||
| use style::media_queries::Expression; | ||
| use style::servo::media_queries::{ExpressionKind, Range}; | ||
| use style::values::specified::{Length, NoCalcLength, AbsoluteLength, ViewportPercentageLength}; | ||
|
|
||
|
|
||
| pub fn test_length_for_no_default_provided(len: f32) -> Length { | ||
| let length = Length::NoCalc(NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vw(len))); | ||
| return length; | ||
| } | ||
|
|
||
| #[test] | ||
| fn no_default_provided() { | ||
| let mut a = vec![]; | ||
| let length = test_length_for_no_default_provided(100f32); | ||
| let size = Size { query: None, length: length }; | ||
| a.push(size); | ||
| assert_eq!(parse_a_sizes_attribute(DOMString::new(), None), a); | ||
| println!("{:?}", parse_a_sizes_attribute(DOMString::new(), None)); | ||
wafflespeanut
Member
|
||
| } | ||
|
|
||
| pub fn test_length_for_default_provided(len: f32) -> Length { | ||
| let length = Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px(len))); | ||
| return length; | ||
| } | ||
|
|
||
| #[test] | ||
| fn default_provided() { | ||
| let mut a = vec![]; | ||
| let length = test_length_for_default_provided(2f32); | ||
| let size = Size { query: None, length: length }; | ||
| a.push(size); | ||
wafflespeanut
Member
|
||
| assert_eq!(parse_a_sizes_attribute(DOMString::new(), Some(2)), a); | ||
| println!("{:?}", parse_a_sizes_attribute(DOMString::new(), Some(2))); | ||
|
||
| } | ||
|
|
||
| pub fn test_media_query(len: f32) -> MediaQuery { | ||
| let length = Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px(len))); | ||
| let expr = Expression(ExpressionKind::Width(Range::Max(length))); | ||
| let media_query = MediaQuery { | ||
| qualifier: None, | ||
| media_type: MediaQueryType::All, | ||
| expressions: vec![expr] | ||
| }; | ||
| media_query | ||
| } | ||
|
|
||
| pub fn test_length(len: f32) -> Length { | ||
| let length = Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px(len))); | ||
| return length; | ||
| } | ||
|
|
||
| #[test] | ||
| fn one_value() { | ||
| let mut a = vec![]; | ||
| let media_query = test_media_query(200f32); | ||
| let length = test_length(545f32); | ||
| let size = Size { query: Some(media_query), length: length }; | ||
| a.push(size); | ||
| assert_eq!(parse_a_sizes_attribute(DOMString::from("(max-width: 200px) 545px"), None), a); | ||
| } | ||
|
|
||
| #[test] | ||
| fn more_then_one_value() { | ||
| let media_query = test_media_query(900f32); | ||
| let length = test_length(1000f32); | ||
| let size = Size { query: Some(media_query), length: length }; | ||
| let media_query1 = test_media_query(900f32); | ||
| let length1 = test_length(50f32); | ||
| let size1 = Size { query: Some(media_query1), length: length1 }; | ||
| let a = &[size, size1]; | ||
| assert_eq!(parse_a_sizes_attribute(DOMString::from("(max-width: 900px) 1000px, (max-width: 900px) 50px"), | ||
| None), a); | ||
| } | ||
|
|
||
| #[test] | ||
| fn no_extra_whitespace() { | ||
| let mut a = vec![]; | ||
| let media_query = test_media_query(200f32); | ||
| let length = test_length(545f32); | ||
| let size = Size { query: Some(media_query), length: length }; | ||
| a.push(size); | ||
| assert_eq!(parse_a_sizes_attribute(DOMString::from("(max-width: 200px) 545px"), None), a); | ||
| } | ||
|
|
||
| #[test] | ||
| fn extra_whitespace() { | ||
| let media_query = test_media_query(900f32); | ||
| let length = test_length(1000f32); | ||
| let size = Size { query: Some(media_query), length: length }; | ||
| let media_query1 = test_media_query(900f32); | ||
| let length1 = test_length(50f32); | ||
| let size1 = Size { query: Some(media_query1), length: length1 }; | ||
| let a = &[size, size1]; | ||
| assert_eq!(parse_a_sizes_attribute(DOMString::from("(max-width: 900px) 1000px, (max-width: 900px) 50px"), | ||
| None), a); | ||
| } | ||
Nit: newline before types please