Bug 1339711 - Part 2: stylo: Support most MathML presentation attributes; r?emilio draft
authorManish Goregaokar <manishearth@gmail.com>
Mon, 10 Apr 2017 15:28:48 +0800
changeset 561223 9ab135c9da1843387fe976d616747d1cd42af379
parent 561222 896f607cf52634ca300a1a6618c2118cf9d59f1e
child 561224 545ae1970c22132e5ebf7260cb28997c2bd318c3
push id53654
push userbmo:manishearth@gmail.com
push dateWed, 12 Apr 2017 09:22:24 +0000
reviewersemilio
bugs1339711
milestone55.0a1
Bug 1339711 - Part 2: stylo: Support most MathML presentation attributes; r?emilio MozReview-Commit-ID: BSR3ZW6PWkL
dom/mathml/nsMathMLElement.cpp
servo/components/style/properties/longhand/font.mako.rs
servo/components/style/properties/longhand/inherited_box.mako.rs
servo/ports/geckolib/glue.rs
--- a/dom/mathml/nsMathMLElement.cpp
+++ b/dom/mathml/nsMathMLElement.cpp
@@ -649,85 +649,80 @@ nsMathMLElement::MapMathMLAttributesInto
     //
     // "Should be the name of a font that may be available to a MathML renderer,
     // or a CSS font specification; See Section 6.5 Using CSS with MathML and
     // CSS for more information. Deprecated in favor of mathvariant."
     //
     // values: string
     // 
     value = aAttributes->GetAttr(nsGkAtoms::fontfamily_);
-    nsCSSValue* fontFamily = aData->ValueForFontFamily();
     if (value) {
       WarnDeprecated(nsGkAtoms::fontfamily_->GetUTF16String(),
                      nsGkAtoms::mathvariant_->GetUTF16String(),
                      aData->mPresContext->Document());
     }
     if (value && value->Type() == nsAttrValue::eString &&
-        fontFamily->GetUnit() == eCSSUnit_Null) {
-      nsCSSParser parser;
-      parser.ParseFontFamilyListString(value->GetStringValue(),
-                                       nullptr, 0, *fontFamily);
+        !aData->PropertyIsSet(eCSSProperty_font_family)) {
+      aData->SetFontFamily(value->GetStringValue());
     }
 
     // fontstyle
     //
     // "Specified the font style to use for the token. Deprecated in favor of
     //  mathvariant."
     //
     // values: "normal" | "italic"
     // default:	normal (except on <mi>)
     //
     // Note that the font-style property is reset in layout/style/ when
     // -moz-math-variant is specified.
-    nsCSSValue* fontStyle = aData->ValueForFontStyle();
     value = aAttributes->GetAttr(nsGkAtoms::fontstyle_);
     if (value) {
       WarnDeprecated(nsGkAtoms::fontstyle_->GetUTF16String(),
                        nsGkAtoms::mathvariant_->GetUTF16String(),
                        aData->mPresContext->Document());
       if (value->Type() == nsAttrValue::eString &&
-          fontStyle->GetUnit() == eCSSUnit_Null) {
+          !aData->PropertyIsSet(eCSSProperty_font_style)) {
         nsAutoString str(value->GetStringValue());
         str.CompressWhitespace();
         if (str.EqualsASCII("normal")) {
-          fontStyle->SetIntValue(NS_STYLE_FONT_STYLE_NORMAL,
-                                eCSSUnit_Enumerated);
+          aData->SetKeywordValue(eCSSProperty_font_style,
+                                 NS_STYLE_FONT_STYLE_NORMAL);
         } else if (str.EqualsASCII("italic")) {
-          fontStyle->SetIntValue(NS_STYLE_FONT_STYLE_ITALIC,
-                                eCSSUnit_Enumerated);
+          aData->SetKeywordValue(eCSSProperty_font_style,
+                                 NS_STYLE_FONT_STYLE_ITALIC);
         }
       }
     }
 
     // fontweight
     //
     // "Specified the font weight for the token. Deprecated in favor of
     // mathvariant."
     //
     // values: "normal" | "bold"
     // default: normal
     //
     // Note that the font-weight property is reset in layout/style/ when
     // -moz-math-variant is specified.
-    nsCSSValue* fontWeight = aData->ValueForFontWeight();
     value = aAttributes->GetAttr(nsGkAtoms::fontweight_);
     if (value) {
       WarnDeprecated(nsGkAtoms::fontweight_->GetUTF16String(),
                        nsGkAtoms::mathvariant_->GetUTF16String(),
                        aData->mPresContext->Document());
       if (value->Type() == nsAttrValue::eString &&
-          fontWeight->GetUnit() == eCSSUnit_Null) {
+          !aData->PropertyIsSet(eCSSProperty_font_weight)) {
         nsAutoString str(value->GetStringValue());
         str.CompressWhitespace();
         if (str.EqualsASCII("normal")) {
-          fontWeight->SetIntValue(NS_STYLE_FONT_WEIGHT_NORMAL,
-                                 eCSSUnit_Enumerated);
+          aData->SetKeywordValue(eCSSProperty_font_weight,
+                                 NS_STYLE_FONT_WEIGHT_NORMAL);
         } else if (str.EqualsASCII("bold")) {
-          fontWeight->SetIntValue(NS_STYLE_FONT_WEIGHT_BOLD,
-                                  eCSSUnit_Enumerated);
+          aData->SetKeywordValue(eCSSProperty_font_weight,
+                                 NS_STYLE_FONT_WEIGHT_BOLD);
         }
       }
     }
 
     // mathvariant
     //
     // "Specifies the logical class of the token. Note that this class is more
     // than styling, it typically conveys semantic intent;"
@@ -795,21 +790,20 @@ nsMathMLElement::MapMathMLAttributesInto
     if (!value) {
       value = aAttributes->GetAttr(nsGkAtoms::background);
       if (value) {
         WarnDeprecated(nsGkAtoms::background->GetUTF16String(),
                        nsGkAtoms::mathbackground_->GetUTF16String(),
                        aData->mPresContext->Document());
       }
     }
-    nsCSSValue* backgroundColor = aData->ValueForBackgroundColor();
-    if (value && backgroundColor->GetUnit() == eCSSUnit_Null) {
+    if (value) {
       nscolor color;
       if (value->GetColorValue(color)) {
-        backgroundColor->SetColorValue(color);
+        aData->SetColorValueIfUnset(eCSSProperty_background_color, color);
       }
     }
   }
 
   // mathcolor
   //
   // "Specifies the foreground color to use when drawing the components of this
   // element, such as the content for token elements or any lines, surds, or
@@ -832,20 +826,18 @@ nsMathMLElement::MapMathMLAttributesInto
       value = aAttributes->GetAttr(nsGkAtoms::color);
       if (value) {
         WarnDeprecated(nsGkAtoms::color->GetUTF16String(),
                        nsGkAtoms::mathcolor_->GetUTF16String(),
                        aData->mPresContext->Document());
       }
     }
     nscolor color;
-    nsCSSValue* colorValue = aData->ValueForColor();
-    if (value && value->GetColorValue(color) &&
-        colorValue->GetUnit() == eCSSUnit_Null) {
-      colorValue->SetColorValue(color);
+    if (value && value->GetColorValue(color)) {
+      aData->SetColorValueIfUnset(eCSSProperty_color, color);
     }
   }
 
   if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Position)) {
     // width
     //
     // "Specifies the desired width of the entire table and is intended for
     // visual user agents. When the value is a percentage value, the value is
@@ -885,27 +877,26 @@ nsMathMLElement::MapMathMLAttributesInto
   // see Section 3.1.5.1 Overall Directionality of Mathematics Formulas for
   // further discussion. It has no effect on mspace."
   //
   // values: "ltr" | "rtl"
   // default: inherited
   //
   if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Visibility)) {
     const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::dir);
-    nsCSSValue* direction = aData->ValueForDirection();
     if (value && value->Type() == nsAttrValue::eString &&
-        direction->GetUnit() == eCSSUnit_Null) {
+        !aData->PropertyIsSet(eCSSProperty_direction)) {
       nsAutoString str(value->GetStringValue());
       static const char dirs[][4] = { "ltr", "rtl" };
       static const int32_t dirValues[MOZ_ARRAY_LENGTH(dirs)] = {
         NS_STYLE_DIRECTION_LTR, NS_STYLE_DIRECTION_RTL
       };
       for (uint32_t i = 0; i < ArrayLength(dirs); ++i) {
         if (str.EqualsASCII(dirs[i])) {
-          direction->SetIntValue(dirValues[i], eCSSUnit_Enumerated);
+          aData->SetKeywordValue(eCSSProperty_direction, dirValues[i]);
           break;
         }
       }
     }
   }
 }
 
 nsresult
--- a/servo/components/style/properties/longhand/font.mako.rs
+++ b/servo/components/style/properties/longhand/font.mako.rs
@@ -220,17 +220,18 @@
 </%helpers:longhand>
 
 
 ${helpers.single_keyword("font-style",
                          "normal italic oblique",
                          gecko_constant_prefix="NS_FONT_STYLE",
                          gecko_ffi_name="mFont.style",
                          spec="https://drafts.csswg.org/css-fonts/#propdef-font-style",
-                         animation_type="none")}
+                         animation_type="none",
+                         needs_conversion=True)}
 
 ${helpers.single_keyword("font-variant",
                          "normal small-caps",
                          spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant",
                          animation_type="none")}
 
 
 <% font_variant_caps_custom_consts= { "small-caps": "SMALLCAPS",
@@ -287,29 +288,34 @@
             match_ignore_ascii_case! { &try!(input.expect_ident()),
                 "normal" => Ok(SpecifiedValue::Normal),
                 "bold" => Ok(SpecifiedValue::Bold),
                 "bolder" => Ok(SpecifiedValue::Bolder),
                 "lighter" => Ok(SpecifiedValue::Lighter),
                 _ => Err(())
             }
         }).or_else(|()| {
-            match try!(input.expect_integer()) {
-                100 => Ok(SpecifiedValue::Weight100),
-                200 => Ok(SpecifiedValue::Weight200),
-                300 => Ok(SpecifiedValue::Weight300),
-                400 => Ok(SpecifiedValue::Weight400),
-                500 => Ok(SpecifiedValue::Weight500),
-                600 => Ok(SpecifiedValue::Weight600),
-                700 => Ok(SpecifiedValue::Weight700),
-                800 => Ok(SpecifiedValue::Weight800),
-                900 => Ok(SpecifiedValue::Weight900),
+            SpecifiedValue::from_int(input.expect_integer()?)
+        })
+    }
+
+    impl SpecifiedValue {
+        pub fn from_int(kw: i32) -> Result<Self, ()> {
+            match kw {
+                % for weight in range(100, 901, 100):
+                    ${weight} => Ok(SpecifiedValue::Weight${weight}),
+                % endfor
                 _ => Err(())
             }
-        })
+        }
+
+        pub fn from_gecko_keyword(kw: u32) -> Self {
+            Self::from_int(kw as i32).expect("Found unexpected value in style
+                                              struct for font-weight property")
+        }
     }
 
     /// Used in @font-face, where relative keywords are not allowed.
     impl Parse for computed_value::T {
         fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
             match parse(context, input)? {
                 % for weight in range(100, 901, 100):
                     SpecifiedValue::Weight${weight} => Ok(computed_value::T::Weight${weight}),
--- a/servo/components/style/properties/longhand/inherited_box.mako.rs
+++ b/servo/components/style/properties/longhand/inherited_box.mako.rs
@@ -19,17 +19,18 @@
 ${helpers.single_keyword("writing-mode",
                          "horizontal-tb vertical-rl vertical-lr",
                          experimental=True,
                          need_clone=True,
                          animation_type="none",
                          spec="https://drafts.csswg.org/css-writing-modes/#propdef-writing-mode")}
 
 ${helpers.single_keyword("direction", "ltr rtl", need_clone=True, animation_type="none",
-                         spec="https://drafts.csswg.org/css-writing-modes/#propdef-direction")}
+                         spec="https://drafts.csswg.org/css-writing-modes/#propdef-direction",
+                         needs_conversion=True)}
 
 <%helpers:single_keyword_computed
     name="text-orientation"
     values="mixed upright sideways"
     extra_specified="sideways-right"
     products="gecko"
     need_clone="True"
     animation_type="none"
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -1276,26 +1276,29 @@ pub extern "C" fn Servo_DeclarationBlock
     use style::values::specified::BorderStyle;
 
     let long = get_longhand_from_id!(property);
     let value = value as u32;
 
     let prop = match_wrap_declared! { long,
         MozUserModify => longhands::_moz_user_modify::SpecifiedValue::from_gecko_keyword(value),
         // TextEmphasisPosition => FIXME implement text-emphasis-position
+        Direction => longhands::direction::SpecifiedValue::from_gecko_keyword(value),
         Display => longhands::display::SpecifiedValue::from_gecko_keyword(value),
         Float => longhands::float::SpecifiedValue::from_gecko_keyword(value),
         VerticalAlign => longhands::vertical_align::SpecifiedValue::from_gecko_keyword(value),
         TextAlign => longhands::text_align::SpecifiedValue::from_gecko_keyword(value),
         TextEmphasisPosition => longhands::text_emphasis_position::SpecifiedValue::from_gecko_keyword(value),
         Clear => longhands::clear::SpecifiedValue::from_gecko_keyword(value),
         FontSize => {
             // We rely on Gecko passing in font-size values (0...7) here.
             longhands::font_size::SpecifiedValue::from_html_size(value as u8)
         },
+        FontStyle => longhands::font_style::SpecifiedValue::from_gecko_keyword(value),
+        FontWeight => longhands::font_weight::SpecifiedValue::from_gecko_keyword(value),
         ListStyleType => longhands::list_style_type::SpecifiedValue::from_gecko_keyword(value),
         MozMathVariant => longhands::_moz_math_variant::SpecifiedValue::from_gecko_keyword(value),
         WhiteSpace => longhands::white_space::SpecifiedValue::from_gecko_keyword(value),
         CaptionSide => longhands::caption_side::SpecifiedValue::from_gecko_keyword(value),
         BorderTopStyle => BorderStyle::from_gecko_keyword(value),
         BorderRightStyle => BorderStyle::from_gecko_keyword(value),
         BorderBottomStyle => BorderStyle::from_gecko_keyword(value),
         BorderLeftStyle => BorderStyle::from_gecko_keyword(value),