diff options
author | Xidorn Quan <me@upsuper.org> | 2017-06-08 10:42:27 +1000 |
---|---|---|
committer | Xidorn Quan <me@upsuper.org> | 2017-06-08 12:59:22 +1000 |
commit | 7568a196885ed1f1ed2a38aa30d733e66a8e866e (patch) | |
tree | 730929c05ec3141b49ceab59f3e8dfe14b2a5127 /components | |
parent | bf77f81ed639af0e9b305f6672db696f8a144ff4 (diff) | |
download | servo-7568a196885ed1f1ed2a38aa30d733e66a8e866e.tar.gz servo-7568a196885ed1f1ed2a38aa30d733e66a8e866e.zip |
Merge CSSColor into Color.
Diffstat (limited to 'components')
20 files changed, 159 insertions, 212 deletions
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 5353fd7e9ab..58a1200b915 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -111,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, Color}; +use style::values::specified; use stylesheet_loader::StylesheetOwner; // TODO: Update focus state when the top-level browsing context gains or loses system focus, @@ -420,8 +420,8 @@ impl LayoutElementHelpers for LayoutJS<Element> { if let Some(color) = bgcolor { hints.push(from_declaration( shared_lock, - PropertyDeclaration::BackgroundColor( - CSSColor { parsed: Color::RGBA(color), authored: None }))); + PropertyDeclaration::BackgroundColor(color.into()) + )); } let background = if let Some(this) = self.downcast::<HTMLBodyElement>() { @@ -455,10 +455,7 @@ impl LayoutElementHelpers for LayoutJS<Element> { hints.push(from_declaration( shared_lock, PropertyDeclaration::Color( - longhands::color::SpecifiedValue(CSSColor { - parsed: Color::RGBA(color), - authored: None, - }) + longhands::color::SpecifiedValue(color.into()) ) )); } diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index fb8a0ea8970..721598b66f9 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -319,16 +319,7 @@ def set_gecko_property(ffi_name, expr): #[allow(unreachable_code)] #[allow(non_snake_case)] pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) { - % if complex_color: - let result = v.into(); - % else: - let result = match color { - Color::RGBA(rgba) => convert_rgba_to_nscolor(&rgba), - // FIXME handle currentcolor - Color::CurrentColor => 0, - }; - % endif - ${set_gecko_property(gecko_ffi_name, "result")} + ${set_gecko_property(gecko_ffi_name, "v.into()")} } </%def> @@ -343,11 +334,7 @@ def set_gecko_property(ffi_name, expr): <%def name="impl_color_clone(ident, gecko_ffi_name, complex_color=True)"> #[allow(non_snake_case)] pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { - % if complex_color: - ${get_gecko_property(gecko_ffi_name)}.into() - % else: - Color::RGBA(convert_nscolor_to_rgba(${get_gecko_property(gecko_ffi_name)})) - % endif + ${get_gecko_property(gecko_ffi_name)}.into() } </%def> @@ -721,7 +708,7 @@ impl Debug for ${style_struct.gecko_struct_name} { "Number": impl_simple, "Integer": impl_simple, "Opacity": impl_simple, - "CSSColor": impl_color, + "Color": impl_color, "RGBAColor": impl_rgba_color, "SVGPaint": impl_svg_paint, "UrlOrNone": impl_css_url, @@ -742,8 +729,6 @@ impl Debug for ${style_struct.gecko_struct_name} { args.update(cast_type=longhand.cast_type) else: method = predefined_types[longhand.predefined_type] - if longhand.predefined_type in ["CSSColor"]: - args.update(complex_color=longhand.complex_color) method(**args) diff --git a/components/style/properties/longhand/background.mako.rs b/components/style/properties/longhand/background.mako.rs index 4937a2569b0..273fc43eac5 100644 --- a/components/style/properties/longhand/background.mako.rs +++ b/components/style/properties/longhand/background.mako.rs @@ -6,7 +6,7 @@ <% data.new_style_struct("Background", inherited=False) %> -${helpers.predefined_type("background-color", "CSSColor", +${helpers.predefined_type("background-color", "Color", "::cssparser::Color::RGBA(::cssparser::RGBA::transparent())", initial_specified_value="SpecifiedValue::transparent()", spec="https://drafts.csswg.org/css-backgrounds/#background-color", diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs index 142825cabda..8c0bf0aa9f2 100644 --- a/components/style/properties/longhand/border.mako.rs +++ b/components/style/properties/longhand/border.mako.rs @@ -16,7 +16,7 @@ return "https://drafts.csswg.org/css-backgrounds/#border-%s-%s" % (side[0], kind) %> % for side in ALL_SIDES: - ${helpers.predefined_type("border-%s-color" % side[0], "CSSColor", + ${helpers.predefined_type("border-%s-color" % side[0], "Color", "::cssparser::Color::CurrentColor", alias=maybe_moz_logical_alias(product, side, "-moz-border-%s-color"), spec=maybe_logical_spec(side, "color"), diff --git a/components/style/properties/longhand/color.mako.rs b/components/style/properties/longhand/color.mako.rs index 0728516ab41..bcdd97dedb0 100644 --- a/components/style/properties/longhand/color.mako.rs +++ b/components/style/properties/longhand/color.mako.rs @@ -12,26 +12,30 @@ animation_value_type="IntermediateRGBA" ignored_when_colors_disabled="True" spec="https://drafts.csswg.org/css-color/#color"> - use cssparser::RGBA; - use values::specified::{AllowQuirks, Color, CSSColor}; + use cssparser::{Color as CSSParserColor, RGBA}; + use values::specified::{AllowQuirks, Color}; impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; #[inline] fn to_computed_value(&self, context: &Context) -> computed_value::T { - self.0.parsed.to_computed_value(context) + match self.0.to_computed_value(context) { + CSSParserColor::RGBA(rgba) => rgba, + CSSParserColor::CurrentColor => + context.inherited_style.get_color().clone_color(), + } } #[inline] fn from_computed_value(computed: &computed_value::T) -> Self { - SpecifiedValue(Color::RGBA(*computed).into()) + SpecifiedValue(Color::rgba(*computed).into()) } } #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[derive(Clone, Debug, PartialEq, ToCss)] - pub struct SpecifiedValue(pub CSSColor); + pub struct SpecifiedValue(pub Color); no_viewport_percentage!(SpecifiedValue); pub mod computed_value { @@ -43,7 +47,7 @@ RGBA::new(0, 0, 0, 255) // black } pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { - CSSColor::parse_quirky(context, input, AllowQuirks::Yes).map(SpecifiedValue) + Color::parse_quirky(context, input, AllowQuirks::Yes).map(SpecifiedValue) } // FIXME(#15973): Add servo support for system colors diff --git a/components/style/properties/longhand/column.mako.rs b/components/style/properties/longhand/column.mako.rs index 2c99a7f1dc3..5b7ea05073d 100644 --- a/components/style/properties/longhand/column.mako.rs +++ b/components/style/properties/longhand/column.mako.rs @@ -51,9 +51,9 @@ ${helpers.predefined_type("column-rule-width", extra_prefixes="moz")} // https://drafts.csswg.org/css-multicol-1/#crc -${helpers.predefined_type("column-rule-color", "CSSColor", +${helpers.predefined_type("column-rule-color", "Color", "::cssparser::Color::CurrentColor", - initial_specified_value="specified::CSSColor::currentcolor()", + initial_specified_value="specified::Color::currentcolor()", products="gecko", animation_value_type="IntermediateColor", extra_prefixes="moz", complex_color=True, need_clone=True, ignored_when_colors_disabled=True, diff --git a/components/style/properties/longhand/inherited_text.mako.rs b/components/style/properties/longhand/inherited_text.mako.rs index 9b4004712ec..2e0b9cd0d39 100644 --- a/components/style/properties/longhand/inherited_text.mako.rs +++ b/components/style/properties/longhand/inherited_text.mako.rs @@ -685,9 +685,9 @@ ${helpers.predefined_type("word-spacing", % endif </%helpers:longhand> -${helpers.predefined_type("text-emphasis-color", "CSSColor", +${helpers.predefined_type("text-emphasis-color", "Color", "::cssparser::Color::CurrentColor", - initial_specified_value="specified::CSSColor::currentcolor()", + initial_specified_value="specified::Color::currentcolor()", products="gecko", animation_value_type="IntermediateColor", complex_color=True, need_clone=True, ignored_when_colors_disabled=True, @@ -705,7 +705,7 @@ ${helpers.predefined_type( // CSS Compatibility // https://compat.spec.whatwg.org ${helpers.predefined_type( - "-webkit-text-fill-color", "CSSColor", + "-webkit-text-fill-color", "Color", "CSSParserColor::CurrentColor", products="gecko", animation_value_type="IntermediateColor", complex_color=True, need_clone=True, @@ -713,9 +713,9 @@ ${helpers.predefined_type( spec="https://compat.spec.whatwg.org/#the-webkit-text-fill-color")} ${helpers.predefined_type( - "-webkit-text-stroke-color", "CSSColor", + "-webkit-text-stroke-color", "Color", "CSSParserColor::CurrentColor", - initial_specified_value="specified::CSSColor::currentcolor()", + initial_specified_value="specified::Color::currentcolor()", products="gecko", animation_value_type="IntermediateColor", complex_color=True, need_clone=True, ignored_when_colors_disabled=True, diff --git a/components/style/properties/longhand/outline.mako.rs b/components/style/properties/longhand/outline.mako.rs index 1640953e305..51a0aea350e 100644 --- a/components/style/properties/longhand/outline.mako.rs +++ b/components/style/properties/longhand/outline.mako.rs @@ -10,8 +10,8 @@ additional_methods=[Method("outline_has_nonzero_width", "bool")]) %> // TODO(pcwalton): `invert` -${helpers.predefined_type("outline-color", "CSSColor", "computed::CSSColor::CurrentColor", - initial_specified_value="specified::CSSColor::currentcolor()", +${helpers.predefined_type("outline-color", "Color", "computed::Color::CurrentColor", + initial_specified_value="specified::Color::currentcolor()", animation_value_type="IntermediateColor", complex_color=True, need_clone=True, ignored_when_colors_disabled=True, spec="https://drafts.csswg.org/css-ui/#propdef-outline-color")} diff --git a/components/style/properties/longhand/text.mako.rs b/components/style/properties/longhand/text.mako.rs index d636ed3cb64..04af1b35924 100644 --- a/components/style/properties/longhand/text.mako.rs +++ b/components/style/properties/longhand/text.mako.rs @@ -278,9 +278,9 @@ ${helpers.single_keyword("text-decoration-style", spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-style")} ${helpers.predefined_type( - "text-decoration-color", "CSSColor", - "computed::CSSColor::CurrentColor", - initial_specified_value="specified::CSSColor::currentcolor()", + "text-decoration-color", "Color", + "computed::Color::CurrentColor", + initial_specified_value="specified::Color::currentcolor()", complex_color=True, products="gecko", animation_value_type="IntermediateColor", diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index a0264d41e8c..d9d95a82024 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -40,7 +40,6 @@ use stylesheets::{CssRuleType, MallocSizeOf, MallocSizeOfFn, Origin, UrlExtraDat #[cfg(feature = "servo")] use values::Either; use values::generics::text::LineHeight; use values::computed; -use values::specified::Color; use cascade_info::CascadeInfo; use rule_tree::{CascadeLevel, StrongRuleNode}; use style_adjuster::StyleAdjuster; @@ -2626,7 +2625,7 @@ pub fn apply_declarations<'a, F, I>(device: &Device, let ignore_colors = !device.use_document_colors(); let default_background_color_decl = if ignore_colors { let color = device.default_background_color(); - Some(PropertyDeclaration::BackgroundColor(Color::RGBA(color).into())) + Some(PropertyDeclaration::BackgroundColor(color.into())) } else { None }; diff --git a/components/style/properties/shorthand/background.mako.rs b/components/style/properties/shorthand/background.mako.rs index 36652a73520..3767d80bed9 100644 --- a/components/style/properties/shorthand/background.mako.rs +++ b/components/style/properties/shorthand/background.mako.rs @@ -15,7 +15,7 @@ use properties::longhands::background_clip; use properties::longhands::background_clip::single_value::computed_value::T as Clip; use properties::longhands::background_origin::single_value::computed_value::T as Origin; - use values::specified::{CSSColor, Position, PositionComponent}; + use values::specified::{Color, Position, PositionComponent}; use parser::Parse; impl From<background_origin::single_value::SpecifiedValue> for background_clip::single_value::SpecifiedValue { @@ -50,7 +50,7 @@ % endfor loop { if background_color.is_none() { - if let Ok(value) = input.try(|i| CSSColor::parse(context, i)) { + if let Ok(value) = input.try(|i| Color::parse(context, i)) { background_color = Some(value); continue } @@ -112,7 +112,7 @@ })); Ok(expanded! { - background_color: background_color.unwrap_or(CSSColor::transparent()), + background_color: background_color.unwrap_or(Color::transparent()), background_image: background_image, background_position_x: background_position_x, background_position_y: background_position_y, diff --git a/components/style/properties/shorthand/border.mako.rs b/components/style/properties/shorthand/border.mako.rs index c84549a544f..b5ebe773c66 100644 --- a/components/style/properties/shorthand/border.mako.rs +++ b/components/style/properties/shorthand/border.mako.rs @@ -5,7 +5,7 @@ <%namespace name="helpers" file="/helpers.mako.rs" /> <% from data import to_rust_ident, ALL_SIDES, PHYSICAL_SIDES, maybe_moz_logical_alias %> -${helpers.four_sides_shorthand("border-color", "border-%s-color", "specified::CSSColor::parse", +${helpers.four_sides_shorthand("border-color", "border-%s-color", "specified::Color::parse", spec="https://drafts.csswg.org/css-backgrounds/#border-color", allow_quirks=True)} @@ -44,10 +44,10 @@ ${helpers.four_sides_shorthand("border-style", "border-%s-style", pub fn parse_border(context: &ParserContext, input: &mut Parser) - -> Result<(specified::CSSColor, + -> Result<(specified::Color, specified::BorderStyle, specified::BorderSideWidth), ()> { - use values::specified::{CSSColor, BorderStyle, BorderSideWidth}; + use values::specified::{Color, BorderStyle, BorderSideWidth}; let _unused = context; let mut color = None; let mut style = None; @@ -55,7 +55,7 @@ pub fn parse_border(context: &ParserContext, input: &mut Parser) let mut any = false; loop { if color.is_none() { - if let Ok(value) = input.try(|i| CSSColor::parse(context, i)) { + if let Ok(value) = input.try(|i| Color::parse(context, i)) { color = Some(value); any = true; continue @@ -78,7 +78,7 @@ pub fn parse_border(context: &ParserContext, input: &mut Parser) break } if any { - Ok((color.unwrap_or_else(|| CSSColor::currentcolor()), + Ok((color.unwrap_or_else(|| Color::currentcolor()), style.unwrap_or(BorderStyle::none), width.unwrap_or(BorderSideWidth::Medium))) } else { diff --git a/components/style/properties/shorthand/outline.mako.rs b/components/style/properties/shorthand/outline.mako.rs index 8a1ab5900da..649651c02d9 100644 --- a/components/style/properties/shorthand/outline.mako.rs +++ b/components/style/properties/shorthand/outline.mako.rs @@ -18,7 +18,7 @@ let mut any = false; loop { if color.is_none() { - if let Ok(value) = input.try(|i| specified::CSSColor::parse(context, i)) { + if let Ok(value) = input.try(|i| specified::Color::parse(context, i)) { color = Some(value); any = true; continue diff --git a/components/style/properties/shorthand/serialize.mako.rs b/components/style/properties/shorthand/serialize.mako.rs index f8c1ef9bc3e..a86704a5488 100644 --- a/components/style/properties/shorthand/serialize.mako.rs +++ b/components/style/properties/shorthand/serialize.mako.rs @@ -3,18 +3,18 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use style_traits::ToCss; -use values::specified::{BorderStyle, Color, CSSColor}; +use values::specified::{BorderStyle, Color}; use std::fmt; fn serialize_directional_border<W, I,>(dest: &mut W, width: &I, style: &BorderStyle, - color: &CSSColor) + color: &Color) -> fmt::Result where W: fmt::Write, I: ToCss { width.to_css(dest)?; dest.write_str(" ")?; style.to_css(dest)?; - if color.parsed != Color::CurrentColor { + if *color != Color::CurrentColor { dest.write_str(" ")?; color.to_css(dest)?; } diff --git a/components/style/properties/shorthand/text.mako.rs b/components/style/properties/shorthand/text.mako.rs index c5e7ba12c5e..111adb4de1b 100644 --- a/components/style/properties/shorthand/text.mako.rs +++ b/components/style/properties/shorthand/text.mako.rs @@ -70,7 +70,7 @@ self.text_decoration_style.to_css(dest)?; } - if self.text_decoration_color.parsed != specified::Color::CurrentColor { + if *self.text_decoration_color != specified::Color::CurrentColor { dest.write_str(" ")?; self.text_decoration_color.to_css(dest)?; } diff --git a/components/style/rule_tree/mod.rs b/components/style/rule_tree/mod.rs index 37e7334b9db..c51f6f94ff7 100644 --- a/components/style/rule_tree/mod.rs +++ b/components/style/rule_tree/mod.rs @@ -912,7 +912,6 @@ impl StrongRuleNode { -> bool where E: ::dom::TElement { - use cssparser::RGBA; use gecko_bindings::structs::{NS_AUTHOR_SPECIFIED_BACKGROUND, NS_AUTHOR_SPECIFIED_BORDER}; use gecko_bindings::structs::{NS_AUTHOR_SPECIFIED_PADDING, NS_AUTHOR_SPECIFIED_TEXT_SHADOW}; use properties::{CSSWideKeyword, LonghandId, LonghandIdSet}; @@ -1083,7 +1082,7 @@ impl StrongRuleNode { if properties.contains(id) { if !author_colors_allowed { if let PropertyDeclaration::BackgroundColor(ref color) = *declaration { - return color.parsed == Color::RGBA(RGBA::transparent()) + return *color == Color::transparent() } } return true diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index b5bb04a8963..50ad4bbb82d 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -23,7 +23,7 @@ use super::generics::grid::TrackList as GenericTrackList; use super::specified; pub use app_units::Au; -pub use cssparser::Color as CSSColor; +pub use cssparser::Color; pub use properties::animated_properties::TransitionProperty; pub use self::background::BackgroundSize; pub use self::border::{BorderImageSlice, BorderImageWidth, BorderImageSideWidth}; @@ -402,7 +402,7 @@ pub struct Shadow { pub offset_y: Au, pub blur_radius: Au, pub spread_radius: Au, - pub color: CSSColor, + pub color: Color, pub inset: bool, } @@ -584,4 +584,4 @@ impl ClipRectOrAuto { } /// <color> | auto -pub type ColorOrAuto = Either<CSSColor, Auto>; +pub type ColorOrAuto = Either<Color, Auto>; diff --git a/components/style/values/specified/color.rs b/components/style/values/specified/color.rs index 64ef534a337..d18bd574479 100644 --- a/components/style/values/specified/color.rs +++ b/components/style/values/specified/color.rs @@ -4,7 +4,9 @@ //! Specified color values. -use cssparser::{self, Color as CSSParserColor, Parser, RGBA, Token}; +use cssparser::{Color as CSSParserColor, Parser, RGBA, Token}; +#[cfg(feature = "gecko")] +use gecko_bindings::structs::nscolor; use itoa; use parser::{ParserContext, Parse}; #[cfg(feature = "gecko")] @@ -16,13 +18,18 @@ use super::AllowQuirks; use values::computed::{Context, ToComputedValue}; /// Specified color value -#[derive(Clone, Copy, PartialEq, Debug)] +#[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum Color { /// The 'currentColor' keyword CurrentColor, /// A specific RGBA color - RGBA(RGBA), + Numeric { + /// Parsed RGBA color + parsed: RGBA, + /// Authored representation + authored: Option<Box<str>>, + }, /// A system color #[cfg(feature = "gecko")] @@ -50,25 +57,31 @@ mod gecko { } } -impl From<CSSParserColor> for Color { - fn from(value: CSSParserColor) -> Self { - match value { - CSSParserColor::CurrentColor => Color::CurrentColor, - CSSParserColor::RGBA(x) => Color::RGBA(x), - } - } -} - impl From<RGBA> for Color { fn from(value: RGBA) -> Self { - Color::RGBA(value) + Color::rgba(value) } } impl Parse for Color { fn parse(_: &ParserContext, input: &mut Parser) -> Result<Self, ()> { + // Currently we only store authored value for color keywords, + // because all browsers serialize those values as keywords for + // specified value. + let start_position = input.position(); + let authored = match input.next() { + Ok(Token::Ident(s)) => Some(s.to_lowercase().into_boxed_str()), + _ => None, + }; + input.reset(start_position); if let Ok(value) = input.try(CSSParserColor::parse) { - Ok(value.into()) + Ok(match value { + CSSParserColor::CurrentColor => Color::CurrentColor, + CSSParserColor::RGBA(rgba) => Color::Numeric { + parsed: rgba, + authored: authored, + }, + }) } else { #[cfg(feature = "gecko")] { if let Ok(system) = input.try(SystemColor::parse) { @@ -88,7 +101,8 @@ impl ToCss for Color { fn to_css<W>(&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), + Color::Numeric { authored: Some(ref authored), .. } => dest.write_str(authored), + Color::Numeric { parsed: ref rgba, .. } => rgba.to_css(dest), #[cfg(feature = "gecko")] Color::System(system) => system.to_css(dest), #[cfg(feature = "gecko")] @@ -99,21 +113,44 @@ impl ToCss for Color { } } -#[derive(Clone, PartialEq, Debug)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[allow(missing_docs)] -pub struct CSSColor { - pub parsed: Color, - pub authored: Option<Box<str>>, +/// A wrapper of cssparser::Color::parse_hash. +/// +/// That function should never return CurrentColor, so it makes no sense +/// to handle a cssparser::Color here. This should really be done in +/// cssparser directly rather than here. +fn parse_hash_color(value: &[u8]) -> Result<RGBA, ()> { + CSSParserColor::parse_hash(value).map(|color| { + match color { + CSSParserColor::RGBA(rgba) => rgba, + CSSParserColor::CurrentColor => + unreachable!("parse_hash should never return currentcolor"), + } + }) } -impl Parse for CSSColor { - fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { - Self::parse_quirky(context, input, AllowQuirks::No) +impl Color { + /// Returns currentcolor value. + #[inline] + pub fn currentcolor() -> Color { + Color::CurrentColor + } + + /// Returns transparent value. + #[inline] + pub fn transparent() -> Color { + // We should probably set authored to "transparent", but maybe it doesn't matter. + Color::rgba(RGBA::transparent()) + } + + /// Returns a numeric RGBA color value. + #[inline] + pub fn rgba(rgba: RGBA) -> Self { + Color::Numeric { + parsed: rgba, + authored: None, + } } -} -impl CSSColor { /// Parse a color, with quirks. /// /// https://quirks.spec.whatwg.org/#the-hashless-hex-color-quirk @@ -121,21 +158,18 @@ impl CSSColor { input: &mut Parser, allow_quirks: AllowQuirks) -> Result<Self, ()> { - let start_position = input.position(); - let authored = match input.next() { - Ok(Token::Ident(s)) => Some(s.into_owned().into_boxed_str()), - _ => None, - }; - input.reset(start_position); - if let Ok(parsed) = input.try(|i| Parse::parse(context, i)) { - return Ok(CSSColor { - parsed: parsed, - authored: authored, - }); - } - if !allow_quirks.allowed(context.quirks_mode) { - return Err(()); - } + input.try(|i| Self::parse(context, i)).or_else(|_| { + if !allow_quirks.allowed(context.quirks_mode) { + return Err(()); + } + Color::parse_quirky_color(input).map(|rgba| Color::rgba(rgba)) + }) + } + + /// Parse a <quirky-color> value. + /// + /// https://quirks.spec.whatwg.org/#the-hashless-hex-color-quirk + fn parse_quirky_color(input: &mut Parser) -> Result<RGBA, ()> { let (number, dimension) = match input.next()? { Token::Number(number) => { (number, None) @@ -147,12 +181,7 @@ impl CSSColor { if ident.len() != 3 && ident.len() != 6 { return Err(()); } - return cssparser::Color::parse_hash(ident.as_bytes()).map(|color| { - Self { - parsed: color.into(), - authored: None - } - }); + return parse_hash_color(ident.as_bytes()); } _ => { return Err(()); @@ -189,72 +218,38 @@ impl CSSColor { written += (&mut serialization[written..]).write(dimension.as_bytes()).unwrap(); } debug_assert!(written == 6); - Ok(CSSColor { - parsed: cssparser::Color::parse_hash(&serialization).map(From::from)?, - authored: None, - }) + parse_hash_color(&serialization) } /// Returns false if the color is completely transparent, and /// true otherwise. pub fn is_non_transparent(&self) -> bool { - match self.parsed { - Color::RGBA(rgba) if rgba.alpha == 0 => false, + match *self { + Color::Numeric { ref parsed, .. } => parsed.alpha != 0, _ => true, } } } -no_viewport_percentage!(CSSColor); - -impl ToCss for CSSColor { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match self.authored { - Some(ref s) => dest.write_str(s), - None => self.parsed.to_css(dest), - } - } -} - -impl From<Color> for CSSColor { - fn from(color: Color) -> Self { - CSSColor { - parsed: color, - authored: None, - } - } -} - -impl CSSColor { - #[inline] - /// Returns currentcolor value. - pub fn currentcolor() -> CSSColor { - Color::CurrentColor.into() - } - - #[inline] - /// Returns transparent value. - pub fn transparent() -> CSSColor { - // We should probably set authored to "transparent", but maybe it doesn't matter. - Color::RGBA(cssparser::RGBA::transparent()).into() - } +#[cfg(feature = "gecko")] +fn to_rgba(color: nscolor) -> CSSParserColor { + use gecko::values::convert_nscolor_to_rgba; + CSSParserColor::RGBA(convert_nscolor_to_rgba(color)) } impl ToComputedValue for Color { - type ComputedValue = RGBA; + type ComputedValue = CSSParserColor; - fn to_computed_value(&self, context: &Context) -> RGBA { - #[cfg(feature = "gecko")] - use gecko::values::convert_nscolor_to_rgba as to_rgba; + fn to_computed_value(&self, _context: &Context) -> CSSParserColor { match *self { - Color::RGBA(rgba) => rgba, - Color::CurrentColor => context.inherited_style.get_color().clone_color(), + Color::CurrentColor => CSSParserColor::CurrentColor, + Color::Numeric { ref parsed, .. } => CSSParserColor::RGBA(*parsed), #[cfg(feature = "gecko")] - Color::System(system) => to_rgba(system.to_computed_value(context)), + 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 }; + let pres_context = unsafe { &*_context.device.pres_context }; to_rgba(match special { Keyword::MozDefaultColor => pres_context.mDefaultColor, Keyword::MozDefaultBackgroundColor => pres_context.mBackgroundColor, @@ -268,17 +263,17 @@ impl ToComputedValue for Color { use dom::TElement; use gecko::wrapper::GeckoElement; use gecko_bindings::bindings::Gecko_GetBody; - let pres_context = unsafe { &*context.device.pres_context }; + let pres_context = unsafe { &*_context.device.pres_context }; let body = unsafe { Gecko_GetBody(pres_context) }; if let Some(body) = body { let wrap = GeckoElement(body); let borrow = wrap.borrow_data(); - borrow.as_ref().unwrap() - .styles().primary.values() - .get_color() - .clone_color() + CSSParserColor::RGBA(borrow.as_ref().unwrap() + .styles().primary.values() + .get_color() + .clone_color()) } else { to_rgba(pres_context.mDefaultColor) } @@ -286,31 +281,11 @@ impl ToComputedValue for Color { } } - fn from_computed_value(computed: &RGBA) -> Self { - Color::RGBA(*computed) - } -} - -impl ToComputedValue for CSSColor { - type ComputedValue = CSSParserColor; - - #[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: - #[cfg(feature = "gecko")] - non_standard => CSSParserColor::RGBA(non_standard.to_computed_value(_context)), - } - } - - #[inline] fn from_computed_value(computed: &CSSParserColor) -> Self { - (match *computed { - CSSParserColor::RGBA(rgba) => Color::RGBA(rgba), - CSSParserColor::CurrentColor => Color::CurrentColor, - }).into() + match *computed { + CSSParserColor::RGBA(rgba) => Color::rgba(rgba), + CSSParserColor::CurrentColor => Color::currentcolor(), + } } } @@ -318,13 +293,13 @@ impl ToComputedValue for CSSColor { /// with value from color property at the same context. #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -pub struct RGBAColor(pub CSSColor); +pub struct RGBAColor(pub Color); no_viewport_percentage!(RGBAColor); impl Parse for RGBAColor { fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { - CSSColor::parse(context, input).map(RGBAColor) + Color::parse(context, input).map(RGBAColor) } } @@ -345,24 +320,12 @@ impl ToComputedValue for RGBAColor { } fn from_computed_value(computed: &RGBA) -> Self { - RGBAColor(CSSColor { - parsed: Color::RGBA(*computed), - authored: None, - }) + RGBAColor(Color::rgba(*computed)) } } impl From<Color> for RGBAColor { fn from(color: Color) -> RGBAColor { - RGBAColor(CSSColor { - parsed: color, - authored: None, - }) - } -} - -impl From<CSSColor> for RGBAColor { - fn from(color: CSSColor) -> RGBAColor { RGBAColor(color) } } diff --git a/components/style/values/specified/image.rs b/components/style/values/specified/image.rs index a4441bcda67..4284f2f2a43 100644 --- a/components/style/values/specified/image.rs +++ b/components/style/values/specified/image.rs @@ -24,7 +24,7 @@ use values::generics::image::{Image as GenericImage, ImageRect as GenericImageRe use values::generics::image::{LineDirection as GenericsLineDirection, ShapeExtent}; use values::generics::image::PaintWorklet; use values::generics::position::Position as GenericPosition; -use values::specified::{Angle, CSSColor, Color, Length, LengthOrPercentage}; +use values::specified::{Angle, Color, Length, LengthOrPercentage}; use values::specified::{Number, NumberOrPercentage, Percentage, RGBAColor}; use values::specified::position::{Position, PositionComponent, Side, X, Y}; use values::specified::url::SpecifiedUrl; @@ -386,8 +386,8 @@ impl Gradient { "to" => 1., _ => return Err(()), }; - let color = CSSColor::parse(context, i)?; - if color.parsed == Color::CurrentColor { + let color = Color::parse(context, i)?; + if color == Color::CurrentColor { return Err(()); } Ok((color.into(), p)) @@ -405,11 +405,11 @@ impl Gradient { if items.is_empty() { items = vec![ GenericGradientItem::ColorStop(GenericColorStop { - color: CSSColor::transparent().into(), + color: Color::transparent().into(), position: Some(Percentage(0.).into()), }), GenericGradientItem::ColorStop(GenericColorStop { - color: CSSColor::transparent().into(), + color: Color::transparent().into(), position: Some(Percentage(1.).into()), }), ]; diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index b157498ff61..c0f9c6c96aa 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -31,7 +31,7 @@ pub use self::align::{AlignItems, AlignJustifyContent, AlignJustifySelf, Justify pub use self::background::BackgroundSize; pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth}; pub use self::border::{BorderImageSideWidth, BorderRadius, BorderSideWidth}; -pub use self::color::{CSSColor, Color, RGBAColor}; +pub use self::color::{Color, RGBAColor}; pub use self::rect::LengthOrNumberRect; #[cfg(feature = "gecko")] pub use self::gecko::ScrollSnapPoint; @@ -681,7 +681,7 @@ pub struct Shadow { pub offset_y: Length, pub blur_radius: Length, pub spread_radius: Length, - pub color: Option<CSSColor>, + pub color: Option<Color>, pub inset: bool, } @@ -771,7 +771,7 @@ impl Shadow { } } if color.is_none() { - if let Ok(value) = input.try(|i| CSSColor::parse(context, i)) { + if let Ok(value) = input.try(|i| Color::parse(context, i)) { color = Some(value); continue } @@ -997,7 +997,7 @@ impl ClipRectOrAuto { } /// <color> | auto -pub type ColorOrAuto = Either<CSSColor, Auto>; +pub type ColorOrAuto = Either<Color, Auto>; /// Whether quirks are allowed in this context. #[derive(Clone, Copy, PartialEq)] |