diff options
author | Corey Farwell <coreyf@rwell.org> | 2016-03-24 10:37:14 -0400 |
---|---|---|
committer | Corey Farwell <coreyf@rwell.org> | 2016-03-24 10:45:33 -0400 |
commit | 5efbf0fa8f6e47fba3c6ecf1a3b385f95343c558 (patch) | |
tree | a7ab9f060388b4dafcd331fe7bfcafba87d19415 | |
parent | a8264ecc1f517008168d1f02cad4aeec4eebe627 (diff) | |
download | servo-5efbf0fa8f6e47fba3c6ecf1a3b385f95343c558.tar.gz servo-5efbf0fa8f6e47fba3c6ecf1a3b385f95343c558.zip |
Move `util::str::parse_length` into 'style' component.
The function is only used in the 'style' component, so we'll move it
there alongside other relevant parse functions.
-rw-r--r-- | components/style/attr.rs | 72 | ||||
-rw-r--r-- | components/util/str.rs | 71 | ||||
-rw-r--r-- | tests/unit/style/attr.rs | 20 | ||||
-rw-r--r-- | tests/unit/util/str.rs | 20 |
4 files changed, 91 insertions, 92 deletions
diff --git a/components/style/attr.rs b/components/style/attr.rs index 76918f0c410..67d40750557 100644 --- a/components/style/attr.rs +++ b/components/style/attr.rs @@ -8,10 +8,11 @@ use euclid::num::Zero; use num::ToPrimitive; use std::ascii::AsciiExt; use std::ops::Deref; +use std::str::FromStr; use string_cache::{Atom, Namespace}; use url::Url; use util::str::{DOMString, LengthOrPercentageOrAuto, HTML_SPACE_CHARACTERS, WHITESPACE}; -use util::str::{parse_length, read_numbers, split_html_space_chars, str_join}; +use util::str::{read_numbers, split_html_space_chars, str_join}; use values::specified::{Length}; // Duplicated from script::dom::values. @@ -398,6 +399,75 @@ pub fn parse_legacy_color(mut input: &str) -> Result<RGBA, ()> { } } +/// TODO: this function can be rewritten to return Result<LengthOrPercentage, _> +/// Parses a dimension value per HTML5 § 2.4.4.4. If unparseable, `Auto` is +/// returned. +/// https://html.spec.whatwg.org/multipage/#rules-for-parsing-dimension-values +pub fn parse_length(mut value: &str) -> LengthOrPercentageOrAuto { + // Steps 1 & 2 are not relevant + + // Step 3 + value = value.trim_left_matches(WHITESPACE); + + // Step 4 + if value.is_empty() { + return LengthOrPercentageOrAuto::Auto + } + + // Step 5 + if value.starts_with("+") { + value = &value[1..] + } + + // Steps 6 & 7 + match value.chars().nth(0) { + Some('0'...'9') => {}, + _ => return LengthOrPercentageOrAuto::Auto, + } + + // Steps 8 to 13 + // We trim the string length to the minimum of: + // 1. the end of the string + // 2. the first occurence of a '%' (U+0025 PERCENT SIGN) + // 3. the second occurrence of a '.' (U+002E FULL STOP) + // 4. the occurrence of a character that is neither a digit nor '%' nor '.' + // Note: Step 10 is directly subsumed by FromStr::from_str + let mut end_index = value.len(); + let (mut found_full_stop, mut found_percent) = (false, false); + for (i, ch) in value.chars().enumerate() { + match ch { + '0'...'9' => continue, + '%' => { + found_percent = true; + end_index = i; + break + } + '.' if !found_full_stop => { + found_full_stop = true; + continue + } + _ => { + end_index = i; + break + } + } + } + value = &value[..end_index]; + + if found_percent { + let result: Result<f32, _> = FromStr::from_str(value); + match result { + Ok(number) => return LengthOrPercentageOrAuto::Percentage((number as f32) / 100.0), + Err(_) => return LengthOrPercentageOrAuto::Auto, + } + } + + match FromStr::from_str(value) { + Ok(number) => LengthOrPercentageOrAuto::Length(Au::from_f64_px(number)), + Err(_) => LengthOrPercentageOrAuto::Auto, + } +} + #[derive(Clone, HeapSizeOf, Debug)] pub struct AttrIdentifier { pub local_name: Atom, diff --git a/components/util/str.rs b/components/util/str.rs index 9d0869ccced..e7aa933cecf 100644 --- a/components/util/str.rs +++ b/components/util/str.rs @@ -10,7 +10,7 @@ use std::ffi::CStr; use std::fmt; use std::iter::{Filter, Peekable}; use std::ops::{Deref, DerefMut}; -use std::str::{Bytes, CharIndices, FromStr, Split, from_utf8}; +use std::str::{Bytes, CharIndices, Split, from_utf8}; use string_cache::Atom; #[derive(Clone, Debug, Deserialize, Eq, Hash, HeapSizeOf, Ord, PartialEq, PartialOrd, Serialize)] @@ -187,75 +187,6 @@ pub enum LengthOrPercentageOrAuto { Length(Au), } -/// TODO: this function can be rewritten to return Result<LengthOrPercentage, _> -/// Parses a dimension value per HTML5 § 2.4.4.4. If unparseable, `Auto` is -/// returned. -/// https://html.spec.whatwg.org/multipage/#rules-for-parsing-dimension-values -pub fn parse_length(mut value: &str) -> LengthOrPercentageOrAuto { - // Steps 1 & 2 are not relevant - - // Step 3 - value = value.trim_left_matches(WHITESPACE); - - // Step 4 - if value.is_empty() { - return LengthOrPercentageOrAuto::Auto - } - - // Step 5 - if value.starts_with("+") { - value = &value[1..] - } - - // Steps 6 & 7 - match value.chars().nth(0) { - Some('0'...'9') => {}, - _ => return LengthOrPercentageOrAuto::Auto, - } - - // Steps 8 to 13 - // We trim the string length to the minimum of: - // 1. the end of the string - // 2. the first occurence of a '%' (U+0025 PERCENT SIGN) - // 3. the second occurrence of a '.' (U+002E FULL STOP) - // 4. the occurrence of a character that is neither a digit nor '%' nor '.' - // Note: Step 10 is directly subsumed by FromStr::from_str - let mut end_index = value.len(); - let (mut found_full_stop, mut found_percent) = (false, false); - for (i, ch) in value.chars().enumerate() { - match ch { - '0'...'9' => continue, - '%' => { - found_percent = true; - end_index = i; - break - } - '.' if !found_full_stop => { - found_full_stop = true; - continue - } - _ => { - end_index = i; - break - } - } - } - value = &value[..end_index]; - - if found_percent { - let result: Result<f32, _> = FromStr::from_str(value); - match result { - Ok(number) => return LengthOrPercentageOrAuto::Percentage((number as f32) / 100.0), - Err(_) => return LengthOrPercentageOrAuto::Auto, - } - } - - match FromStr::from_str(value) { - Ok(number) => LengthOrPercentageOrAuto::Length(Au::from_f64_px(number)), - Err(_) => LengthOrPercentageOrAuto::Auto, - } -} - #[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize, Serialize)] pub struct LowercaseString { inner: String, diff --git a/tests/unit/style/attr.rs b/tests/unit/style/attr.rs index 7aca499beae..aa7401113c7 100644 --- a/tests/unit/style/attr.rs +++ b/tests/unit/style/attr.rs @@ -2,8 +2,9 @@ * 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 style::attr::AttrValue; -use util::str::DOMString; +use app_units::Au; +use style::attr::{AttrValue, parse_length}; +use util::str::{DOMString, LengthOrPercentageOrAuto}; #[test] fn test_from_limited_i32_should_be_default_when_less_than_0() { @@ -31,3 +32,18 @@ fn test_from_limited_i32_should_keep_parsed_value_when_not_an_int() { _ => panic!("expected an successful parsing") } } + +#[test] +pub fn test_parse_length() { + fn check(input: &str, expected: LengthOrPercentageOrAuto) { + let parsed = parse_length(input); + assert_eq!(parsed, expected); + } + + check("0", LengthOrPercentageOrAuto::Length(Au::from_px(0))); + check("0.000%", LengthOrPercentageOrAuto::Percentage(0.0)); + check("+5.82%", LengthOrPercentageOrAuto::Percentage(0.0582)); + check("5.82", LengthOrPercentageOrAuto::Length(Au::from_f64_px(5.82))); + check("invalid", LengthOrPercentageOrAuto::Auto); + check("12 followed by invalid", LengthOrPercentageOrAuto::Length(Au::from_px(12))); +} diff --git a/tests/unit/util/str.rs b/tests/unit/util/str.rs index a9069a8dca2..be217b0c5ea 100644 --- a/tests/unit/util/str.rs +++ b/tests/unit/util/str.rs @@ -2,25 +2,7 @@ * 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 app_units::Au; -use util::str::LengthOrPercentageOrAuto; -use util::str::{parse_length, search_index, split_html_space_chars, str_join}; - - -#[test] -pub fn test_parse_length() { - fn check(input: &str, expected: LengthOrPercentageOrAuto) { - let parsed = parse_length(input); - assert_eq!(parsed, expected); - } - - check("0", LengthOrPercentageOrAuto::Length(Au::from_px(0))); - check("0.000%", LengthOrPercentageOrAuto::Percentage(0.0)); - check("+5.82%", LengthOrPercentageOrAuto::Percentage(0.0582)); - check("5.82", LengthOrPercentageOrAuto::Length(Au::from_f64_px(5.82))); - check("invalid", LengthOrPercentageOrAuto::Auto); - check("12 followed by invalid", LengthOrPercentageOrAuto::Length(Au::from_px(12))); -} +use util::str::{search_index, split_html_space_chars, str_join}; #[test] pub fn split_html_space_chars_whitespace() { |