Bug 1380590 - Support None and NotSet for the fallback of SVGPaint. draft
authorKuoE0 <kuoe0.tw@gmail.com>
Fri, 01 Sep 2017 17:27:02 +0800
changeset 658886 02a60ac61d393aa4b0feab74fd45e3d600bd922e
parent 657243 2a300aa651b0f42f9da3bd71d374de5f18e0d02f
child 729788 9d14abee8be915d63c77a2d13c61c156b09ee2a9
push id77915
push userbmo:kuoe0@mozilla.com
push dateTue, 05 Sep 2017 03:38:54 +0000
bugs1380590
milestone57.0a1
Bug 1380590 - Support None and NotSet for the fallback of SVGPaint. MozReview-Commit-ID: AOu89NyLzSp
servo/components/style/properties/gecko.mako.rs
servo/components/style/values/generics/svg.rs
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -55,17 +55,17 @@ use properties::animated_properties::Tra
 use properties::computed_value_flags::ComputedValueFlags;
 use properties::{longhands, FontComputationData, Importance, LonghandId};
 use properties::{PropertyDeclaration, PropertyDeclarationBlock, PropertyDeclarationId};
 use rule_tree::StrongRuleNode;
 use selector_parser::PseudoElement;
 use servo_arc::{Arc, RawOffsetArc};
 use std::mem::{forget, uninitialized, transmute, zeroed};
 use std::{cmp, ops, ptr};
-use values::{self, Auto, CustomIdent, Either, KeyframesName};
+use values::{self, Auto, CustomIdent, Either, KeyframesName, None_};
 use values::computed::{NonNegativeAu, ToComputedValue, Percentage};
 use values::computed::effects::{BoxShadow, Filter, SimpleShadow};
 use computed_values::border_style;
 
 pub mod style_structs {
     % for style_struct in data.style_structs:
     pub use super::${style_struct.gecko_struct_name} as ${style_struct.name};
     % endfor
@@ -738,20 +738,26 @@ def set_gecko_property(ffi_name, expr):
             SVGPaintKind::Color(color) => {
                 paint.mType = nsStyleSVGPaintType::eStyleSVGPaintType_Color;
                 unsafe {
                     *paint.mPaint.mColor.as_mut() = convert_rgba_to_nscolor(&color);
                 }
             }
         }
 
-        if let Some(fallback) = fallback {
-            paint.mFallbackType = nsStyleSVGFallbackType::eStyleSVGFallbackType_Color;
-            paint.mFallbackColor = convert_rgba_to_nscolor(&fallback);
-        }
+        paint.mFallbackType = match fallback {
+            Some(Either::First(color)) => {
+                paint.mFallbackColor = convert_rgba_to_nscolor(&color);
+                nsStyleSVGFallbackType::eStyleSVGFallbackType_Color
+            },
+            Some(Either::Second(_)) => {
+                nsStyleSVGFallbackType::eStyleSVGFallbackType_None
+            },
+            None => nsStyleSVGFallbackType::eStyleSVGFallbackType_NotSet
+        };
     }
 
     #[allow(non_snake_case)]
     pub fn copy_${ident}_from(&mut self, other: &Self) {
         unsafe {
             bindings::Gecko_nsStyleSVGPaint_CopyFrom(
                 &mut ${get_gecko_property(gecko_ffi_name)},
                 & ${get_gecko_property(gecko_ffi_name, "other")}
@@ -766,21 +772,27 @@ def set_gecko_property(ffi_name, expr):
 
     #[allow(non_snake_case)]
     pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
         use values::generics::svg::{SVGPaint, SVGPaintKind};
         use values::specified::url::SpecifiedUrl;
         use self::structs::nsStyleSVGPaintType;
         use self::structs::nsStyleSVGFallbackType;
         let ref paint = ${get_gecko_property(gecko_ffi_name)};
-        let fallback = if let nsStyleSVGFallbackType::eStyleSVGFallbackType_Color = paint.mFallbackType {
-            Some(convert_nscolor_to_rgba(paint.mFallbackColor))
-        } else {
-            None
+
+        let fallback = match paint.mFallbackType {
+            nsStyleSVGFallbackType::eStyleSVGFallbackType_Color => {
+                Some(Either::First(convert_nscolor_to_rgba(paint.mFallbackColor)))
+            },
+            nsStyleSVGFallbackType::eStyleSVGFallbackType_None => {
+                Some(Either::Second(None_))
+            },
+            nsStyleSVGFallbackType::eStyleSVGFallbackType_NotSet => None,
         };
+
         let kind = match paint.mType {
             nsStyleSVGPaintType::eStyleSVGPaintType_None => SVGPaintKind::None,
             nsStyleSVGPaintType::eStyleSVGPaintType_ContextFill => SVGPaintKind::ContextFill,
             nsStyleSVGPaintType::eStyleSVGPaintType_ContextStroke => SVGPaintKind::ContextStroke,
             nsStyleSVGPaintType::eStyleSVGPaintType_Server => {
                 unsafe {
                     SVGPaintKind::PaintServer(
                         SpecifiedUrl::from_url_value_data(
--- a/servo/components/style/values/generics/svg.rs
+++ b/servo/components/style/values/generics/svg.rs
@@ -6,28 +6,29 @@
 
 use cssparser::Parser;
 use parser::{Parse, ParserContext};
 use std::fmt;
 use style_traits::{ParseError, StyleParseError, ToCss};
 use values::computed::NumberOrPercentage;
 use values::computed::length::LengthOrPercentage;
 use values::distance::{ComputeSquaredDistance, SquaredDistance};
+use values::{Either, None_};
 
 /// An SVG paint value
 ///
 /// https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint
 #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 #[derive(Animate, Clone, ComputeSquaredDistance, Debug, PartialEq)]
 #[derive(ToAnimatedValue, ToComputedValue, ToCss)]
 pub struct SVGPaint<ColorType, UrlPaintServer> {
     /// The paint source
     pub kind: SVGPaintKind<ColorType, UrlPaintServer>,
-    /// The fallback color
-    pub fallback: Option<ColorType>,
+    /// The fallback color. It would be empty, the `none` keyword or <color>.
+    pub fallback: Option<Either<ColorType, None_>>,
 }
 
 /// An SVG paint value without the fallback
 ///
 /// Whereas the spec only allows PaintServer
 /// to have a fallback, Gecko lets the context
 /// properties have a fallback as well.
 #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
@@ -54,25 +55,29 @@ impl<ColorType, UrlPaintServer> SVGPaint
             "none" => Ok(SVGPaintKind::None),
             "context-fill" => Ok(SVGPaintKind::ContextFill),
             "context-stroke" => Ok(SVGPaintKind::ContextStroke),
         }
     }
 }
 
 /// Parse SVGPaint's fallback.
-/// fallback is keyword(none) or Color.
+/// fallback is keyword(none), Color or empty.
 /// https://svgwg.org/svg2-draft/painting.html#SpecifyingPaint
 fn parse_fallback<'i, 't, ColorType: Parse>(context: &ParserContext,
                                             input: &mut Parser<'i, 't>)
-                                            -> Option<ColorType> {
+                                            -> Option<Either<ColorType, None_>> {
     if input.try(|i| i.expect_ident_matching("none")).is_ok() {
-        None
+        Some(Either::Second(None_))
     } else {
-        input.try(|i| ColorType::parse(context, i)).ok()
+        if let Ok(color) = input.try(|i| ColorType::parse(context, i)) {
+            Some(Either::First(color))
+        } else {
+            None
+        }
     }
 }
 
 impl<ColorType: Parse, UrlPaintServer: Parse> Parse for SVGPaint<ColorType, UrlPaintServer> {
     fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
         if let Ok(url) = input.try(|i| UrlPaintServer::parse(context, i)) {
             Ok(SVGPaint {
                 kind: SVGPaintKind::PaintServer(url),