Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upWIP #17808
WIP #17808
Conversation
highfive
commented
Jul 20, 2017
|
Thanks for the pull request, and welcome! The Servo team is excited to review your changes, and you should hear from @asajeffrey (or someone else) soon. |
highfive
commented
Jul 20, 2017
highfive
commented
Jul 20, 2017
|
|
|
Good start! |
| @@ -782,6 +797,71 @@ impl LayoutHTMLImageElementHelpers for LayoutJS<HTMLImageElement> { | |||
| } | |||
| } | |||
|
|
|||
| pub fn parse_a_sizes_attribute(input: DOMString, width: Option<u32>) -> Result<Vec<Size>, String> { | |||
This comment has been minimized.
This comment has been minimized.
jdm
Jul 27, 2017
Member
Since we only return Ok from this method (and not Err), there is no reason to return a Result value.
| let trimmed: String = unparsed_size.chars().take(unparsed_size.chars().count() - whitespace).collect(); | ||
|
|
||
| if trimmed.is_empty() { | ||
| // return Err("reason".to_owned()); |
This comment has been minimized.
This comment has been minimized.
| }, | ||
| } | ||
| } | ||
| if sizes.len() == 0 { |
This comment has been minimized.
This comment has been minimized.
|
|
||
| #[test] | ||
| fn empty_vector() { | ||
| assert!(parse_a_sizes_attribute(DOMString::new(), None).is_ok()); |
This comment has been minimized.
This comment has been minimized.
jdm
Jul 27, 2017
Member
We will want to assert that the result is an empty vector (as the test name implies ;))
This comment has been minimized.
This comment has been minimized.
creativcoder
Jul 30, 2017
Contributor
@Rakhisharma As discussed, the test case depicts the situation where sizes is an empty string (DOMString::new()), so here we should also check if the vector contains a single Size with the value 100vw. (i.e., the default value returned from spec algorithm)
| #[test] | ||
| fn test_whitespace() { | ||
| assert!(parse_a_sizes_attribute(DOMString::from(" (min-width: 500px)"), | ||
| None).is_ok()); |
This comment has been minimized.
This comment has been minimized.
jdm
Jul 27, 2017
Member
Let's think about what this test is checking. (min-width: 500px) by itself is not a valid size; it is a media query, and the sizes algorithm then tries to parse a length that follows it. Since there is no length present, this string would be considered a parse error. That's fine, but we should also verify in a separate test that a valid size with extra whitespace parses correctly and gives us a real parsed size.
| let media_query = media_query_parser.try(|i| MediaQuery::parse(&context, i)); | ||
| match media_query { | ||
| Ok(query) => { | ||
| let length = media_query_parser.try(|i| Length::parse_non_negative(&context, i)); |
This comment has been minimized.
This comment has been minimized.
jdm
Jul 27, 2017
Member
We can use Length::parse_non_negative directly instead of Parser::try: let length = Length::parse_non_negative(&context, &mut media_query_parser);
| match media_query { | ||
| Ok(query) => { | ||
| let length = media_query_parser.try(|i| Length::parse_non_negative(&context, i)); | ||
| if length.is_ok() { |
This comment has been minimized.
This comment has been minimized.
jdm
Jul 27, 2017
Member
Instead of using is_ok and unwrap, we can write if let Ok(length) = length {.
| let mut media_query_parser = Parser::new(&mut input); | ||
| let media_query = media_query_parser.try(|i| MediaQuery::parse(&context, i)); | ||
| match media_query { | ||
| Ok(query) => { |
This comment has been minimized.
This comment has been minimized.
jdm
Jul 27, 2017
Member
Since the Err branch of this match is empty except for continue, we can write if let Ok(query) = media_query { and omit it entirely.
| @@ -66,6 +76,11 @@ enum State { | |||
| CompletelyAvailable, | |||
| Broken, | |||
| } | |||
| #[allow(dead_code)] | |||
This comment has been minimized.
This comment has been minimized.
| @@ -3,6 +3,8 @@ | |||
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |||
|
|
|||
| use app_units::{Au, AU_PER_PX}; | |||
| use core::ops::Deref; | |||
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Rakhisharma
Jul 29, 2017
Author
Contributor
we are using this at line: 802: let unparsed_sizes = input.deref().split(',').collect::<Vec<_>>();
This comment has been minimized.
This comment has been minimized.
KiChjang
Jul 29, 2017
Member
An explicit call to deref should not be necessary, if let unparsed_sizes = input.split(',').collect::<Vec<_>>(); does not work, try let unparsed_sizes = (*input).split(',').collect::<Vec<_>>();.
This comment has been minimized.
This comment has been minimized.
Rakhisharma
Jul 30, 2017
Author
Contributor
let unparsed_sizes = input.split(',').collect::<Vec<_>>(); worked! thanks.
| None, | ||
| ParsingMode::empty(), | ||
| QuirksMode::NoQuirks); | ||
| let url = ServoUrl::parse("about:blank").unwrap(); |
This comment has been minimized.
This comment has been minimized.
creativcoder
Jul 30, 2017
Contributor
You already have url declared in line 813. So you can remove this.
| @@ -12,4 +12,6 @@ extern crate servo_url; | |||
| #[cfg(test)] mod textinput; | |||
| #[cfg(test)] mod headers; | |||
| #[cfg(test)] mod htmlareaelement; | |||
| #[cfg(test)] mod htmlimageelement; | |||
|
|
|||
This comment has been minimized.
This comment has been minimized.
|
|
|
This is a good start! The tests can use a bit more refining, but I think we're close to having something that's ready to be merged! |
| None, | ||
| ParsingMode::empty(), | ||
| QuirksMode::NoQuirks); | ||
| let length = Parser::new(&mut input).try(|i| Length::parse_non_negative(&context, i)); |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Rakhisharma
Sep 6, 2017
Author
Contributor
How to create a separate parser object here? I am not clear if we can create a Parser object without any input string and reuse it later.
This comment has been minimized.
This comment has been minimized.
jdm
Sep 6, 2017
Member
let mut parser = Parser::new(&mut input);
/* ... */
let length = parser.try(..);
/* .. */
let something_else = parser.foo(..).| query: None | ||
| }), | ||
| Err(_) => { | ||
| let mut media_query_parser = Parser::new(&mut input); |
This comment has been minimized.
This comment has been minimized.
| 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 length.is_ok() { |
This comment has been minimized.
This comment has been minimized.
jdm
Aug 31, 2017
Member
We can use if let Ok(length) = length { here and avoid calling unwrap below.
| @@ -782,6 +798,63 @@ impl LayoutHTMLImageElementHelpers for LayoutJS<HTMLImageElement> { | |||
| } | |||
| } | |||
|
|
|||
| pub fn parse_a_sizes_attribute(input: DOMString, width: Option<u32>) -> Vec<Size> { | |||
This comment has been minimized.
This comment has been minimized.
jdm
Aug 31, 2017
•
Member
Add a comment like // https://html.spec.whatwg.org/multipage/#parse-a-sizes-attribute so it's clear which algorithm this is based on.
| make_getter!(Sizes, "sizes"); | ||
| // https://html.spec.whatwg.org/multipage/#parse-a-sizes-attribute | ||
| make_setter!(SetSizes, "sizes"); | ||
|
|
This comment has been minimized.
This comment has been minimized.
|
|
||
| #[test] | ||
| fn no_default_provided() { | ||
| assert!(parse_a_sizes_attribute(DOMString::new(), None).len() == 1); |
This comment has been minimized.
This comment has been minimized.
jdm
Aug 31, 2017
Member
Instead of asserting the length, we should be asserting the actual value that is returned in all of these tests.
|
|
||
| #[test] | ||
| fn no_size() { | ||
| assert!(parse_a_sizes_attribute(DOMString::new(), None).len() == 1); |
This comment has been minimized.
This comment has been minimized.
| 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); |
This comment has been minimized.
This comment has been minimized.
jdm
Aug 31, 2017
Member
It's confusing how this is called no_extra_whitespace but the test includes a leading space.
This comment has been minimized.
This comment has been minimized.
Rakhisharma
Sep 6, 2017
Author
Contributor
Here what you mean with the extra whitespace, "does the middle spaces also count as extra whitespace or only the leading and trailing spaces counts as extra whitespace ?"
This comment has been minimized.
This comment has been minimized.
jdm
Sep 6, 2017
Member
Extra whitespace generally means any additional whitespace beyond what is necessary to separate two tokens, regardless of where the whitespace exists in the string.
| (max-width: 900px) and (min-width: 400px) 50em, | ||
| 100vw "), | ||
| None); | ||
| assert_eq!(result.len(), 3); |
This comment has been minimized.
This comment has been minimized.
| 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: 320px) 280px, (max-width: 480px) 440px, 800px"), None), a); |
This comment has been minimized.
This comment has been minimized.
jdm
Aug 31, 2017
Member
Why does this test pass? We are parsing a string that contains three different sizes, but the expected results only contain one size that does not match any of them.
|
Sorry, but which issue does this PR solve? |
|
This is part of #11416 |
|
Nice work! This mostly looks good to me. Just a few nits, and we'll be good to go. |
| @@ -66,6 +74,12 @@ enum State { | |||
| CompletelyAvailable, | |||
| Broken, | |||
| } | |||
| #[derive(PartialEq)] | |||
This comment has been minimized.
This comment has been minimized.
| pub fn parse_a_sizes_attribute(input: DOMString, width: Option<u32>) -> Vec<Size> { | ||
| let mut sizes = Vec::<Size>::new(); | ||
| let unparsed_sizes = input.split(',').collect::<Vec<_>>(); | ||
| for unparsed_size in &unparsed_sizes { |
This comment has been minimized.
This comment has been minimized.
wafflespeanut
Sep 24, 2017
Member
Since unparsed_sizes is used only in the loop, let's iterate on input.split directly (which avoids an iteration and vector allocation).
This comment has been minimized.
This comment has been minimized.
Rakhisharma
Sep 25, 2017
Author
Contributor
Not sure what you want me to do here. Would you please elaborate little more. Thanks :)
This comment has been minimized.
This comment has been minimized.
wafflespeanut
Sep 25, 2017
Member
I meant,
for unparsed_size in input.split(',') {This way, we perform lazy iteration.
| 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); |
This comment has been minimized.
This comment has been minimized.
| 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)); |
This comment has been minimized.
This comment has been minimized.
wafflespeanut
Sep 24, 2017
Member
Nit: Please remove println! usage.
Note for the future: println! is not useful in the testsuite because the stdout is captured by cargo. Instead, we should panic! so that cargo prints the captured stdout (which also has the panic message).
| let size = Size { query: None, length: length }; | ||
| a.push(size); | ||
| assert_eq!(parse_a_sizes_attribute(DOMString::new(), Some(2)), a); | ||
| println!("{:?}", parse_a_sizes_attribute(DOMString::new(), Some(2))); |
This comment has been minimized.
This comment has been minimized.
| let mut a = vec![]; | ||
| let length = test_length_for_default_provided(2f32); | ||
| let size = Size { query: None, length: length }; | ||
| a.push(size); |
This comment has been minimized.
This comment has been minimized.
wafflespeanut
Sep 24, 2017
Member
Nit: If it's just a single size, then let's have let a = vec![size]; (here and everywhere below)
|
I went ahead and squashed these commits and opened a new PR in #18714. |
Parse sizes attribute values Squashed version of #17808. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix (partially) #11416 - [x] There are tests for these changes <!-- 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/18714) <!-- Reviewable:end -->
Rakhisharma commentedJul 20, 2017
•
edited
Parse sizes attribute implementation.
./mach build -ddoes not report any errors./mach test-tidydoes not report any errorsThis change is