diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index c0d4b6b700a..5353fd7e9ab 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -4,7 +4,6 @@ //! Element nodes. -use cssparser::Color; use devtools_traits::AttrInfo; use dom::activation::Activatable; use dom::attr::{Attr, AttrHelpersForLayout}; @@ -112,7 +111,7 @@ use style::stylearc::Arc; use style::stylist::ApplicableDeclarationBlock; use style::thread_state; use style::values::{CSSFloat, Either}; -use style::values::specified::{self, CSSColor}; +use style::values::specified::{self, CSSColor, Color}; use stylesheet_loader::StylesheetOwner; // TODO: Update focus state when the top-level browsing context gains or loses system focus, diff --git a/components/style/values/specified/color.rs b/components/style/values/specified/color.rs index 3a3b45651ec..538506bfce9 100644 --- a/components/style/values/specified/color.rs +++ b/components/style/values/specified/color.rs @@ -7,34 +7,38 @@ use cssparser::{self, Color as CSSParserColor, Parser, RGBA, Token}; use itoa; use parser::{ParserContext, Parse}; +#[cfg(feature = "gecko")] +use properties::longhands::color::SystemColor; use std::fmt; use std::io::Write; use style_traits::ToCss; use super::AllowQuirks; use values::computed::{Context, ToComputedValue}; -#[cfg(not(feature = "gecko"))] pub use self::servo::Color; -#[cfg(feature = "gecko")] pub use self::gecko::Color; +/// Specified color value +#[derive(Clone, Copy, PartialEq, Debug)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub enum Color { + /// The 'currentColor' keyword + CurrentColor, + /// A specific RGBA color + RGBA(RGBA), -#[cfg(not(feature = "gecko"))] -mod servo { - pub use cssparser::Color; - use cssparser::Parser; - use parser::{Parse, ParserContext}; - - impl Parse for Color { - fn parse(_: &ParserContext, input: &mut Parser) -> Result { - Color::parse(input) - } - } + /// A system color + #[cfg(feature = "gecko")] + System(SystemColor), + /// A special color keyword value used in Gecko + #[cfg(feature = "gecko")] + Special(gecko::SpecialColorKeyword), + /// Quirksmode-only rule for inheriting color from the body + #[cfg(feature = "gecko")] + InheritFromBodyQuirk, } +no_viewport_percentage!(Color); + #[cfg(feature = "gecko")] mod gecko { - use cssparser::{Color as CSSParserColor, Parser, RGBA}; - use parser::{Parse, ParserContext}; - use properties::longhands::color::SystemColor; - use std::fmt; use style_traits::ToCss; define_css_keyword_enum! { SpecialColorKeyword: @@ -44,59 +48,53 @@ mod gecko { "-moz-activehyperlinktext" => MozActiveHyperlinktext, "-moz-visitedhyperlinktext" => MozVisitedHyperlinktext, } +} - /// Color value including non-standard -moz prefixed values. - #[derive(Clone, Copy, PartialEq, Debug)] - pub enum Color { - /// The 'currentColor' keyword - CurrentColor, - /// A specific RGBA color - RGBA(RGBA), - /// A system color - System(SystemColor), - /// A special color keyword value used in Gecko - Special(SpecialColorKeyword), - /// Quirksmode-only rule for inheriting color from the body - InheritFromBodyQuirk, - } - - no_viewport_percentage!(Color); - - impl From for Color { - fn from(value: CSSParserColor) -> Self { - match value { - CSSParserColor::CurrentColor => Color::CurrentColor, - CSSParserColor::RGBA(x) => Color::RGBA(x), - } +impl From for Color { + fn from(value: CSSParserColor) -> Self { + match value { + CSSParserColor::CurrentColor => Color::CurrentColor, + CSSParserColor::RGBA(x) => Color::RGBA(x), } } +} - impl Parse for Color { - fn parse(_: &ParserContext, input: &mut Parser) -> Result { - if let Ok(value) = input.try(CSSParserColor::parse) { - Ok(value.into()) - } else if let Ok(system) = input.try(SystemColor::parse) { - Ok(Color::System(system)) - } else if let Ok(special) = input.try(SpecialColorKeyword::parse) { - Ok(Color::Special(special)) - } else { +impl From for Color { + fn from(value: RGBA) -> Self { + Color::RGBA(value) + } +} + +impl Parse for Color { + fn parse(_: &ParserContext, input: &mut Parser) -> Result { + if let Ok(value) = input.try(CSSParserColor::parse) { + Ok(value.into()) + } else { + #[cfg(feature = "gecko")] { + if let Ok(system) = input.try(SystemColor::parse) { + Ok(Color::System(system)) + } else { + gecko::SpecialColorKeyword::parse(input).map(Color::Special) + } + } + #[cfg(not(feature = "gecko"))] { Err(()) } } } +} - impl ToCss for Color { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - // Standard values: - Color::CurrentColor => CSSParserColor::CurrentColor.to_css(dest), - Color::RGBA(rgba) => rgba.to_css(dest), - Color::System(system) => system.to_css(dest), - - // Non-standard values: - Color::Special(special) => special.to_css(dest), - Color::InheritFromBodyQuirk => Ok(()), - } +impl ToCss for Color { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + Color::CurrentColor => CSSParserColor::CurrentColor.to_css(dest), + Color::RGBA(rgba) => rgba.to_css(dest), + #[cfg(feature = "gecko")] + Color::System(system) => system.to_css(dest), + #[cfg(feature = "gecko")] + Color::Special(special) => special.to_css(dest), + #[cfg(feature = "gecko")] + Color::InheritFromBodyQuirk => Ok(()), } } } @@ -245,25 +243,18 @@ impl CSSColor { impl ToComputedValue for Color { type ComputedValue = RGBA; - #[cfg(not(feature = "gecko"))] - fn to_computed_value(&self, context: &Context) -> RGBA { - match *self { - Color::RGBA(rgba) => rgba, - Color::CurrentColor => context.inherited_style.get_color().clone_color(), - } - } - - #[cfg(feature = "gecko")] fn to_computed_value(&self, context: &Context) -> RGBA { + #[cfg(feature = "gecko")] use gecko::values::convert_nscolor_to_rgba as to_rgba; - // It's safe to access the nsPresContext immutably during style computation. - let pres_context = unsafe { &*context.device.pres_context }; match *self { Color::RGBA(rgba) => rgba, - Color::System(system) => to_rgba(system.to_computed_value(context)), Color::CurrentColor => context.inherited_style.get_color().clone_color(), + #[cfg(feature = "gecko")] + Color::System(system) => to_rgba(system.to_computed_value(context)), + #[cfg(feature = "gecko")] Color::Special(special) => { use self::gecko::SpecialColorKeyword as Keyword; + let pres_context = unsafe { &*context.device.pres_context }; to_rgba(match special { Keyword::MozDefaultColor => pres_context.mDefaultColor, Keyword::MozDefaultBackgroundColor => pres_context.mBackgroundColor, @@ -272,10 +263,12 @@ impl ToComputedValue for Color { Keyword::MozVisitedHyperlinktext => pres_context.mVisitedLinkColor, }) } + #[cfg(feature = "gecko")] Color::InheritFromBodyQuirk => { use dom::TElement; use gecko::wrapper::GeckoElement; use gecko_bindings::bindings::Gecko_GetBody; + let pres_context = unsafe { &*context.device.pres_context }; let body = unsafe { Gecko_GetBody(pres_context) }; @@ -301,20 +294,14 @@ impl ToComputedValue for Color { impl ToComputedValue for CSSColor { type ComputedValue = CSSParserColor; - #[cfg(not(feature = "gecko"))] #[inline] fn to_computed_value(&self, _context: &Context) -> CSSParserColor { - self.parsed - } - - #[cfg(feature = "gecko")] - #[inline] - fn to_computed_value(&self, context: &Context) -> CSSParserColor { match self.parsed { Color::RGBA(rgba) => CSSParserColor::RGBA(rgba), Color::CurrentColor => CSSParserColor::CurrentColor, // Resolve non-standard -moz keywords to RGBA: - non_standard => CSSParserColor::RGBA(non_standard.to_computed_value(context)), + #[cfg(feature = "gecko")] + non_standard => CSSParserColor::RGBA(non_standard.to_computed_value(_context)), } } diff --git a/tests/unit/style/parsing/ui.rs b/tests/unit/style/parsing/ui.rs index 9347b1fbc01..35985a1001e 100644 --- a/tests/unit/style/parsing/ui.rs +++ b/tests/unit/style/parsing/ui.rs @@ -2,10 +2,10 @@ * 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 cssparser::{Color, RGBA}; +use cssparser::RGBA; use parsing::parse; use style::values::{Auto, Either}; -use style::values::specified::CSSColor; +use style::values::specified::{CSSColor, Color}; use style_traits::ToCss; #[test] diff --git a/tests/unit/style/properties/serialization.rs b/tests/unit/style/properties/serialization.rs index e8009794a5a..f3e666ec65f 100644 --- a/tests/unit/style/properties/serialization.rs +++ b/tests/unit/style/properties/serialization.rs @@ -5,11 +5,11 @@ use properties::parse; use style::computed_values::display::T::inline_block; use style::properties::{PropertyDeclaration, Importance, PropertyId}; -use style::properties::longhands::outline_color::computed_value::T as ComputedColor; use style::properties::parse_property_declaration_list; use style::values::{RGBA, Auto}; use style::values::CustomIdent; -use style::values::specified::{BorderStyle, BorderSideWidth, CSSColor, Length, LengthOrPercentage}; +use style::values::specified::{BorderStyle, BorderSideWidth, CSSColor}; +use style::values::specified::{Length, LengthOrPercentage}; use style::values::specified::{LengthOrPercentageOrAuto, LengthOrPercentageOrAutoOrContent}; use style::values::specified::{NoCalcLength, PositionComponent}; use style::values::specified::position::Y; @@ -111,7 +111,7 @@ mod shorthand_serialization { let line = TextDecorationLine::OVERLINE; let style = TextDecorationStyle::dotted; let color = CSSColor { - parsed: ComputedColor::RGBA(RGBA::new(128, 0, 128, 255)), + parsed: RGBA::new(128, 0, 128, 255).into(), authored: None }; @@ -230,7 +230,7 @@ mod shorthand_serialization { properties.push(PropertyDeclaration::BorderLeftWidth(px_10.clone())); let blue = CSSColor { - parsed: ComputedColor::RGBA(RGBA::new(0, 0, 255, 255)), + parsed: RGBA::new(0, 0, 255, 255).into(), authored: None }; @@ -263,7 +263,7 @@ mod shorthand_serialization { properties.push(PropertyDeclaration::BorderLeftWidth(px_30.clone())); let blue = CSSColor { - parsed: ComputedColor::RGBA(RGBA::new(0, 0, 255, 255)), + parsed: RGBA::new(0, 0, 255, 255).into(), authored: None }; @@ -333,12 +333,12 @@ mod shorthand_serialization { let mut properties = Vec::new(); let red = CSSColor { - parsed: ComputedColor::RGBA(RGBA::new(255, 0, 0, 255)), + parsed: RGBA::new(255, 0, 0, 255).into(), authored: None }; let blue = CSSColor { - parsed: ComputedColor::RGBA(RGBA::new(0, 0, 255, 255)), + parsed: RGBA::new(0, 0, 255, 255).into(), authored: None }; @@ -406,7 +406,7 @@ mod shorthand_serialization { let width = BorderSideWidth::Length(Length::from_px(4f32)); let style = BorderStyle::solid; let color = CSSColor { - parsed: ComputedColor::RGBA(RGBA::new(255, 0, 0, 255)), + parsed: RGBA::new(255, 0, 0, 255).into(), authored: None }; @@ -533,7 +533,7 @@ mod shorthand_serialization { let width = BorderSideWidth::Length(Length::from_px(4f32)); let style = Either::Second(BorderStyle::solid); let color = CSSColor { - parsed: ComputedColor::RGBA(RGBA::new(255, 0, 0, 255)), + parsed: RGBA::new(255, 0, 0, 255).into(), authored: None }; @@ -552,7 +552,7 @@ mod shorthand_serialization { let width = BorderSideWidth::Length(Length::from_px(4f32)); let style = Either::First(Auto); let color = CSSColor { - parsed: ComputedColor::RGBA(RGBA::new(255, 0, 0, 255)), + parsed: RGBA::new(255, 0, 0, 255).into(), authored: None }; properties.push(PropertyDeclaration::OutlineWidth(width)); diff --git a/tests/unit/style/stylesheets.rs b/tests/unit/style/stylesheets.rs index 686a3979a9a..9b9c08c5b1f 100644 --- a/tests/unit/style/stylesheets.rs +++ b/tests/unit/style/stylesheets.rs @@ -160,7 +160,7 @@ fn test_parse_stylesheet() { (PropertyDeclaration::BackgroundColor( longhands::background_color::SpecifiedValue { authored: Some("blue".to_owned().into_boxed_str()), - parsed: cssparser::Color::RGBA(cssparser::RGBA::new(0, 0, 255, 255)), + parsed: cssparser::RGBA::new(0, 0, 255, 255).into(), } ), Importance::Normal),