diff options
author | Corey Farwell <coreyf@rwell.org> | 2015-09-19 15:04:11 -0400 |
---|---|---|
committer | Corey Farwell <coreyf@rwell.org> | 2015-09-30 22:51:30 -0400 |
commit | 74e4c4fdc747669f55a639125576d69cb8fa1547 (patch) | |
tree | 80067f4cbc1bb3db7e0085d55b8e0c91cdfdca22 /components/util/str.rs | |
parent | 520c907742afbb94085c6b5e62156a5457530010 (diff) | |
download | servo-74e4c4fdc747669f55a639125576d69cb8fa1547.tar.gz servo-74e4c4fdc747669f55a639125576d69cb8fa1547.zip |
Implement `size` attribute for <font> element
Diffstat (limited to 'components/util/str.rs')
-rw-r--r-- | components/util/str.rs | 106 |
1 files changed, 84 insertions, 22 deletions
diff --git a/components/util/str.rs b/components/util/str.rs index e2759e936d6..ef84853493c 100644 --- a/components/util/str.rs +++ b/components/util/str.rs @@ -9,7 +9,7 @@ use num_lib::ToPrimitive; use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::ffi::CStr; -use std::iter::Filter; +use std::iter::{Filter, Peekable}; use std::ops::Deref; use std::str::{FromStr, Split, from_utf8}; @@ -47,17 +47,37 @@ pub fn split_html_space_chars<'a>(s: &'a str) -> s.split(HTML_SPACE_CHARACTERS).filter(not_empty as fn(&&str) -> bool) } + +fn is_ascii_digit(c: &char) -> bool { + match *c { + '0'...'9' => true, + _ => false, + } +} + + +fn read_numbers<I: Iterator<Item=char>>(mut iter: Peekable<I>) -> Option<i64> { + match iter.peek() { + Some(c) if is_ascii_digit(c) => (), + _ => return None, + } + + iter.take_while(is_ascii_digit).map(|d| { + d as i64 - '0' as i64 + }).fold(Some(0i64), |accumulator, d| { + accumulator.and_then(|accumulator| { + accumulator.checked_mul(10) + }).and_then(|accumulator| { + accumulator.checked_add(d) + }) + }) +} + + /// Shared implementation to parse an integer according to /// <https://html.spec.whatwg.org/#rules-for-parsing-integers> or /// <https://html.spec.whatwg.org/#rules-for-parsing-non-negative-integers> fn do_parse_integer<T: Iterator<Item=char>>(input: T) -> Option<i64> { - fn is_ascii_digit(c: &char) -> bool { - match *c { - '0'...'9' => true, - _ => false, - } - } - let mut input = input.skip_while(|c| { HTML_SPACE_CHARACTERS.iter().any(|s| s == c) }).peekable(); @@ -75,20 +95,7 @@ fn do_parse_integer<T: Iterator<Item=char>>(input: T) -> Option<i64> { Some(_) => 1, }; - match input.peek() { - Some(c) if is_ascii_digit(c) => (), - _ => return None, - } - - let value = input.take_while(is_ascii_digit).map(|d| { - d as i64 - '0' as i64 - }).fold(Some(0i64), |accumulator, d| { - accumulator.and_then(|accumulator| { - accumulator.checked_mul(10) - }).and_then(|accumulator| { - accumulator.checked_add(d) - }) - }); + let value = read_numbers(input); return value.and_then(|value| value.checked_mul(sign)); } @@ -166,6 +173,61 @@ pub fn parse_length(mut value: &str) -> LengthOrPercentageOrAuto { } } +/// https://html.spec.whatwg.org/multipage/#rules-for-parsing-a-legacy-font-size +pub fn parse_legacy_font_size(mut input: &str) -> Option<&'static str> { + // Steps 1 & 2 are not relevant + + // Step 3 + input = input.trim_matches(WHITESPACE); + + enum ParseMode { + RelativePlus, + RelativeMinus, + Absolute, + } + let mut input_chars = input.chars().peekable(); + let parse_mode = match input_chars.peek() { + // Step 4 + None => return None, + + // Step 5 + Some(&'+') => { + let _ = input_chars.next(); // consume the '+' + ParseMode::RelativePlus + } + Some(&'-') => { + let _ = input_chars.next(); // consume the '-' + ParseMode::RelativeMinus + } + Some(_) => ParseMode::Absolute, + }; + + // Steps 6, 7, 8 + let mut value = match read_numbers(input_chars) { + Some(v) => v, + None => return None, + }; + + // Step 9 + match parse_mode { + ParseMode::RelativePlus => value = 3 + value, + ParseMode::RelativeMinus => value = 3 - value, + ParseMode::Absolute => (), + } + + // Steps 10, 11, 12 + Some(match value { + n if n >= 7 => "xxx-large", + 6 => "xx-large", + 5 => "x-large", + 4 => "large", + 3 => "medium", + 2 => "small", + n if n <= 1 => "x-small", + _ => unreachable!(), + }) +} + /// Parses a legacy color per HTML5 § 2.4.6. If unparseable, `Err` is returned. pub fn parse_legacy_color(mut input: &str) -> Result<RGBA, ()> { // Steps 1 and 2. |