diff options
author | Cameron McCormack <cam@mcc.id.au> | 2017-10-16 08:51:55 +0800 |
---|---|---|
committer | Cameron McCormack <cam@mcc.id.au> | 2017-10-16 15:56:22 +0800 |
commit | 1db1c7f54476a1c775d73c95c33f4db442bfd2dd (patch) | |
tree | 414828a2e8ab8e50f67c3c55e3b6f506aa99f10a | |
parent | 086c48210c1ea0b65c91e1b300f796758080871f (diff) | |
download | servo-1db1c7f54476a1c775d73c95c33f4db442bfd2dd.tar.gz servo-1db1c7f54476a1c775d73c95c33f4db442bfd2dd.zip |
style: Refactor specified::Color parsing/computation functions.
So they can be called without a context.
-rw-r--r-- | components/style/values/specified/color.rs | 157 |
1 files changed, 90 insertions, 67 deletions
diff --git a/components/style/values/specified/color.rs b/components/style/values/specified/color.rs index bee0daecfea..aae2674803e 100644 --- a/components/style/values/specified/color.rs +++ b/components/style/values/specified/color.rs @@ -67,42 +67,7 @@ impl From<RGBA> for Color { impl Parse for Color { fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { - // Currently we only store authored value for color keywords, - // because all browsers serialize those values as keywords for - // specified value. - let start = input.state(); - let authored = match input.next() { - Ok(&Token::Ident(ref s)) => Some(s.to_lowercase().into_boxed_str()), - _ => None, - }; - input.reset(&start); - match input.try(CSSParserColor::parse) { - Ok(value) => - Ok(match value { - CSSParserColor::CurrentColor => Color::CurrentColor, - CSSParserColor::RGBA(rgba) => Color::Numeric { - parsed: rgba, - authored: authored, - }, - }), - Err(e) => { - #[cfg(feature = "gecko")] { - if let Ok(system) = input.try(SystemColor::parse) { - return Ok(Color::System(system)); - } else if let Ok(c) = gecko::SpecialColorKeyword::parse(input) { - return Ok(Color::Special(c)); - } - } - match e { - BasicParseError { kind: BasicParseErrorKind::UnexpectedToken(t), location } => { - Err(location.new_custom_error( - StyleParseErrorKind::ValueError(ValueParseErrorKind::InvalidColor(t)) - )) - } - e => Err(e.into()) - } - } - } + Color::parse_color(input) } } @@ -244,6 +209,46 @@ impl Color { _ => true, } } + + /// Parse a <color> value. + pub fn parse_color<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { + // Currently we only store authored value for color keywords, + // because all browsers serialize those values as keywords for + // specified value. + let start = input.state(); + let authored = match input.next() { + Ok(&Token::Ident(ref s)) => Some(s.to_lowercase().into_boxed_str()), + _ => None, + }; + input.reset(&start); + match input.try(CSSParserColor::parse) { + Ok(value) => + Ok(match value { + CSSParserColor::CurrentColor => Color::CurrentColor, + CSSParserColor::RGBA(rgba) => Color::Numeric { + parsed: rgba, + authored: authored, + }, + }), + Err(e) => { + #[cfg(feature = "gecko")] { + if let Ok(system) = input.try(SystemColor::parse) { + return Ok(Color::System(system)); + } else if let Ok(c) = gecko::SpecialColorKeyword::parse(input) { + return Ok(Color::Special(c)); + } + } + match e { + BasicParseError { kind: BasicParseErrorKind::UnexpectedToken(t), location } => { + Err(location.new_custom_error( + StyleParseErrorKind::ValueError(ValueParseErrorKind::InvalidColor(t)) + )) + } + e => Err(e.into()) + } + } + } + } } #[cfg(feature = "gecko")] @@ -252,53 +257,71 @@ fn convert_nscolor_to_computedcolor(color: nscolor) -> ComputedColor { ComputedColor::rgba(convert_nscolor_to_rgba(color)) } -impl ToComputedValue for Color { - type ComputedValue = ComputedColor; - - fn to_computed_value(&self, context: &Context) -> ComputedColor { +impl Color { + /// Converts this Color into a ComputedColor. + /// + /// If `context` is `None`, and the specified color requires data from + /// the context to resolve, then `None` is returned. + pub fn to_computed_color( + &self, + _context: Option<&Context>, + ) -> Option<ComputedColor> { match *self { Color::CurrentColor => { - if let Some(longhand) = context.for_non_inherited_property { - if longhand.stores_complex_colors_lossily() { - context.rule_cache_conditions.borrow_mut() - .set_uncacheable(); - } - } - ComputedColor::currentcolor() + Some(ComputedColor::currentcolor()) + } + Color::Numeric { ref parsed, .. } => { + Some(ComputedColor::rgba(*parsed)) } - Color::Numeric { ref parsed, .. } => ComputedColor::rgba(*parsed), Color::Complex(ref complex) => { - if complex.foreground_ratio != 0 { - if let Some(longhand) = context.for_non_inherited_property { - if longhand.stores_complex_colors_lossily() { - context.rule_cache_conditions.borrow_mut() - .set_uncacheable(); - } - } - } - *complex + Some(*complex) } #[cfg(feature = "gecko")] - Color::System(system) => - convert_nscolor_to_computedcolor(system.to_computed_value(context)), + Color::System(system) => { + _context.map(|context| { + convert_nscolor_to_computedcolor( + system.to_computed_value(context) + ) + }) + } #[cfg(feature = "gecko")] Color::Special(special) => { use self::gecko::SpecialColorKeyword as Keyword; - let pres_context = context.device().pres_context(); - convert_nscolor_to_computedcolor(match special { - Keyword::MozDefaultColor => pres_context.mDefaultColor, - Keyword::MozDefaultBackgroundColor => pres_context.mBackgroundColor, - Keyword::MozHyperlinktext => pres_context.mLinkColor, - Keyword::MozActiveHyperlinktext => pres_context.mActiveLinkColor, - Keyword::MozVisitedHyperlinktext => pres_context.mVisitedLinkColor, + _context.map(|context| { + let pres_context = context.device().pres_context(); + convert_nscolor_to_computedcolor(match special { + Keyword::MozDefaultColor => pres_context.mDefaultColor, + Keyword::MozDefaultBackgroundColor => pres_context.mBackgroundColor, + Keyword::MozHyperlinktext => pres_context.mLinkColor, + Keyword::MozActiveHyperlinktext => pres_context.mActiveLinkColor, + Keyword::MozVisitedHyperlinktext => pres_context.mVisitedLinkColor, + }) }) } #[cfg(feature = "gecko")] Color::InheritFromBodyQuirk => { - ComputedColor::rgba(context.device().body_text_color()) + _context.map(|context| { + ComputedColor::rgba(context.device().body_text_color()) + }) }, } } +} + +impl ToComputedValue for Color { + type ComputedValue = ComputedColor; + + fn to_computed_value(&self, context: &Context) -> ComputedColor { + let result = self.to_computed_color(Some(context)).unwrap(); + if result.foreground_ratio != 0 { + if let Some(longhand) = context.for_non_inherited_property { + if longhand.stores_complex_colors_lossily() { + context.rule_cache_conditions.borrow_mut().set_uncacheable(); + } + } + } + result + } fn from_computed_value(computed: &ComputedColor) -> Self { if computed.is_numeric() { |