Bug 1334330 - Part 6: stylo: Use GenericSpecifiedValue abstraction for table elements; r=emilio
authorManish Goregaokar <manishearth@gmail.com>
Thu, 26 Jan 2017 16:51:01 -0800
changeset 341458 33211bf1f4d84b5910ba7c029498aea9b46007a8
parent 341457 42f6914789d470f6ed827a8fb3478574907e7c59
child 341459 07e22347b23f25a27bf31e12d80a630ef0e2d841
push id37130
push usermanishearth@gmail.com
push dateWed, 08 Feb 2017 22:06:06 +0000
treeherderautoland@530f32f16316 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1334330
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1334330 - Part 6: stylo: Use GenericSpecifiedValue abstraction for table elements; r=emilio MozReview-Commit-ID: 6wo4iw4zEWP
dom/html/HTMLTableCaptionElement.cpp
dom/html/HTMLTableCellElement.cpp
dom/html/HTMLTableColElement.cpp
dom/html/HTMLTableElement.cpp
dom/html/HTMLTableRowElement.cpp
dom/html/HTMLTableSectionElement.cpp
dom/html/nsGenericHTMLElement.cpp
dom/html/nsGenericHTMLElement.h
layout/style/GenericSpecifiedValues.h
layout/style/nsRuleData.h
--- a/dom/html/HTMLTableCaptionElement.cpp
+++ b/dom/html/HTMLTableCaptionElement.cpp
@@ -46,29 +46,27 @@ HTMLTableCaptionElement::ParseAttribute(
   }
 
   return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                               aResult);
 }
 
 void
 HTMLTableCaptionElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
-                                               GenericSpecifiedValues* aGenericData)
+                                               GenericSpecifiedValues* aData)
 {
-  nsRuleData* aData = aGenericData->AsRuleData();
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(TableBorder)) {
-    nsCSSValue* captionSide = aData->ValueForCaptionSide();
-    if (captionSide->GetUnit() == eCSSUnit_Null) {
+  if (aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(TableBorder))) {
+    if (!aData->PropertyIsSet(eCSSProperty_caption_side)) {
       const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);
       if (value && value->Type() == nsAttrValue::eEnum)
-        captionSide->SetIntValue(value->GetEnumValue(), eCSSUnit_Enumerated);
+        aData->SetKeywordValue(eCSSProperty_caption_side, value->GetEnumValue());
     }
   }
 
-  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aGenericData);
+  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
 }
 
 NS_IMETHODIMP_(bool)
 HTMLTableCaptionElement::IsAttributeMapped(const nsIAtom* aAttribute) const
 {
   static const MappedAttributeEntry attributes[] = {
     { &nsGkAtoms::align },
     { nullptr }
--- a/dom/html/HTMLTableCellElement.cpp
+++ b/dom/html/HTMLTableCellElement.cpp
@@ -435,88 +435,68 @@ HTMLTableCellElement::ParseAttribute(int
                                                         aAttribute, aValue,
                                                         aResult) ||
          nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                               aResult);
 }
 
 void
 HTMLTableCellElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
-                                            GenericSpecifiedValues* aGenericData)
+                                            GenericSpecifiedValues* aData)
 {
-  nsRuleData* aData = aGenericData->AsRuleData();
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Position)) {
+  if (aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Position))) {
     // width: value
-    nsCSSValue* width = aData->ValueForWidth();
-    if (width->GetUnit() == eCSSUnit_Null) {
+    if (!aData->PropertyIsSet(eCSSProperty_width)) {
       const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width);
       if (value && value->Type() == nsAttrValue::eInteger) {
         if (value->GetIntegerValue() > 0)
-          width->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel); 
+          aData->SetPixelValue(eCSSProperty_width, (float)value->GetIntegerValue());
         // else 0 implies auto for compatibility.
       }
       else if (value && value->Type() == nsAttrValue::ePercent) {
         if (value->GetPercentValue() > 0.0f)
-          width->SetPercentValue(value->GetPercentValue());
+          aData->SetPercentValue(eCSSProperty_width, value->GetPercentValue());
         // else 0 implies auto for compatibility
       }
     }
-
     // height: value
-    nsCSSValue* height = aData->ValueForHeight();
-    if (height->GetUnit() == eCSSUnit_Null) {
+    if (!aData->PropertyIsSet(eCSSProperty_height)) {
       const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::height);
       if (value && value->Type() == nsAttrValue::eInteger) {
         if (value->GetIntegerValue() > 0)
-          height->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
+          aData->SetPixelValue(eCSSProperty_height, (float)value->GetIntegerValue());
         // else 0 implies auto for compatibility.
       }
       else if (value && value->Type() == nsAttrValue::ePercent) {
         if (value->GetPercentValue() > 0.0f)
-          height->SetPercentValue(value->GetPercentValue());
+          aData->SetPercentValue(eCSSProperty_height, value->GetPercentValue());
         // else 0 implies auto for compatibility
       }
     }
   }
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Text)) {
-    nsCSSValue* textAlign = aData->ValueForTextAlign();
-    if (textAlign->GetUnit() == eCSSUnit_Null) {
-      // align: enum
-      const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);
-      if (value && value->Type() == nsAttrValue::eEnum)
-        textAlign->SetIntValue(value->GetEnumValue(), eCSSUnit_Enumerated);
-    }
-
-    nsCSSValue* whiteSpace = aData->ValueForWhiteSpace();
-    if (whiteSpace->GetUnit() == eCSSUnit_Null) {
+  if (aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Text))) {
+    if (!aData->PropertyIsSet(eCSSProperty_white_space)) {
       // nowrap: enum
       if (aAttributes->GetAttr(nsGkAtoms::nowrap)) {
         // See if our width is not a nonzero integer width.
         const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width);
-        nsCompatibility mode = aData->mPresContext->CompatibilityMode();
+        nsCompatibility mode = aData->PresContext()->CompatibilityMode();
         if (!value || value->Type() != nsAttrValue::eInteger ||
             value->GetIntegerValue() == 0 ||
             eCompatibility_NavQuirks != mode) {
-          whiteSpace->SetIntValue(NS_STYLE_WHITESPACE_NOWRAP, eCSSUnit_Enumerated);
+          aData->SetKeywordValue(eCSSProperty_white_space, NS_STYLE_WHITESPACE_NOWRAP);
         }
       }
     }
   }
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Display)) {
-    nsCSSValue* verticalAlign = aData->ValueForVerticalAlign();
-    if (verticalAlign->GetUnit() == eCSSUnit_Null) {
-      // valign: enum
-      const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::valign);
-      if (value && value->Type() == nsAttrValue::eEnum)
-        verticalAlign->SetIntValue(value->GetEnumValue(), eCSSUnit_Enumerated);
-    }
-  }
-  
-  nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aGenericData);
-  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aGenericData);
+
+  nsGenericHTMLElement::MapDivAlignAttributeInto(aAttributes, aData);
+  nsGenericHTMLElement::MapVAlignAttributeInto(aAttributes, aData);
+  nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aData);
+  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
 }
 
 NS_IMETHODIMP_(bool)
 HTMLTableCellElement::IsAttributeMapped(const nsIAtom* aAttribute) const
 {
   static const MappedAttributeEntry attributes[] = {
     { &nsGkAtoms::align }, 
     { &nsGkAtoms::valign },
--- a/dom/html/HTMLTableColElement.cpp
+++ b/dom/html/HTMLTableColElement.cpp
@@ -59,76 +59,38 @@ HTMLTableColElement::ParseAttribute(int3
   }
 
   return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                               aResult);
 }
 
 void
 HTMLTableColElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
-                                           GenericSpecifiedValues* aGenericData)
+                                           GenericSpecifiedValues* aData)
 {
-  nsRuleData* aData = aGenericData->AsRuleData();
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Table)) {
-    nsCSSValue *span = aData->ValueForSpan();
-    if (span->GetUnit() == eCSSUnit_Null) {
+  if (aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Table))) {
+    if (!aData->PropertyIsSet(eCSSProperty__x_span)) {
       // span: int
       const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::span);
       if (value && value->Type() == nsAttrValue::eInteger) {
         int32_t val = value->GetIntegerValue();
         // Note: Do NOT use this code for table cells!  The value "0"
         // means something special for colspan and rowspan, but for <col
         // span> and <colgroup span> it's just disallowed.
         if (val > 0) {
-          span->SetIntValue(value->GetIntegerValue(), eCSSUnit_Integer);
+          aData->SetIntValue(eCSSProperty__x_span, value->GetIntegerValue());
         }
       }
     }
   }
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Position)) {
-    nsCSSValue* width = aData->ValueForWidth();
-    if (width->GetUnit() == eCSSUnit_Null) {
-      // width
-      const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width);
-      if (value) {
-        switch (value->Type()) {
-        case nsAttrValue::ePercent: {
-          width->SetPercentValue(value->GetPercentValue());
-          break;
-        }
-        case nsAttrValue::eInteger: {
-          width->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
-          break;
-        }
-        default:
-          break;
-        }
-      }
-    }
-  }
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Text)) {
-    nsCSSValue* textAlign = aData->ValueForTextAlign();
-    if (textAlign->GetUnit() == eCSSUnit_Null) {
-      // align: enum
-      const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);
-      if (value && value->Type() == nsAttrValue::eEnum)
-        textAlign->SetIntValue(value->GetEnumValue(), eCSSUnit_Enumerated);
-    }
-  }
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Display)) {
-    nsCSSValue* verticalAlign = aData->ValueForVerticalAlign();
-    if (verticalAlign->GetUnit() == eCSSUnit_Null) {
-      // valign: enum
-      const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::valign);
-      if (value && value->Type() == nsAttrValue::eEnum)
-        verticalAlign->SetIntValue(value->GetEnumValue(), eCSSUnit_Enumerated);
-    }
-  }
 
-  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aGenericData);
+  nsGenericHTMLElement::MapWidthAttributeInto(aAttributes, aData);
+  nsGenericHTMLElement::MapDivAlignAttributeInto(aAttributes, aData);
+  nsGenericHTMLElement::MapVAlignAttributeInto(aAttributes, aData);
+  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
 }
 
 NS_IMETHODIMP_(bool)
 HTMLTableColElement::IsAttributeMapped(const nsIAtom* aAttribute) const
 {
   static const MappedAttributeEntry attributes[] = {
     { &nsGkAtoms::width },
     { &nsGkAtoms::align },
--- a/dom/html/HTMLTableElement.cpp
+++ b/dom/html/HTMLTableElement.cpp
@@ -702,153 +702,102 @@ HTMLTableElement::ParseAttribute(int32_t
          nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                               aResult);
 }
 
 
 
 void
 HTMLTableElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
-                                        GenericSpecifiedValues* aGenericData)
+                                        GenericSpecifiedValues* aData)
 {
-  nsRuleData* aData = aGenericData->AsRuleData();
   // XXX Bug 211636:  This function is used by a single style rule
   // that's used to match two different type of elements -- tables, and
   // table cells.  (nsHTMLTableCellElement overrides
   // WalkContentStyleRules so that this happens.)  This violates the
   // nsIStyleRule contract, since it's the same style rule object doing
   // the mapping in two different ways.  It's also incorrect since it's
   // testing the display type of the style context rather than checking
   // which *element* it's matching (style rules should not stop matching
   // when the display type is changed).
 
-  nsPresContext* presContext = aData->mPresContext;
+  nsPresContext* presContext = aData->PresContext();
   nsCompatibility mode = presContext->CompatibilityMode();
 
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(TableBorder)) {
+  if (aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(TableBorder))) {
     // cellspacing
     const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::cellspacing);
-    nsCSSValue* borderSpacing = aData->ValueForBorderSpacing();
     if (value && value->Type() == nsAttrValue::eInteger &&
-        borderSpacing->GetUnit() == eCSSUnit_Null) {
-      borderSpacing->
-        SetFloatValue(float(value->GetIntegerValue()), eCSSUnit_Pixel);
+        !aData->PropertyIsSet(eCSSProperty_border_spacing)) {
+      aData->SetPixelValue(eCSSProperty_border_spacing, float(value->GetIntegerValue()));
     }
   }
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Margin)) {
+  if (aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Margin))) {
     // align; Check for enumerated type (it may be another type if
     // illegal)
     const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);
 
     if (value && value->Type() == nsAttrValue::eEnum) {
       if (value->GetEnumValue() == NS_STYLE_TEXT_ALIGN_CENTER ||
           value->GetEnumValue() == NS_STYLE_TEXT_ALIGN_MOZ_CENTER) {
-        nsCSSValue* marginLeft = aData->ValueForMarginLeft();
-        if (marginLeft->GetUnit() == eCSSUnit_Null)
-          marginLeft->SetAutoValue();
-        nsCSSValue* marginRight = aData->ValueForMarginRight();
-        if (marginRight->GetUnit() == eCSSUnit_Null)
-          marginRight->SetAutoValue();
+        aData->SetAutoValueIfUnset(eCSSProperty_margin_left);
+        aData->SetAutoValueIfUnset(eCSSProperty_margin_right);
       }
     }
 
     // hspace is mapped into left and right margin,
     // vspace is mapped into top and bottom margins
     // - *** Quirks Mode only ***
     if (eCompatibility_NavQuirks == mode) {
       value = aAttributes->GetAttr(nsGkAtoms::hspace);
 
       if (value && value->Type() == nsAttrValue::eInteger) {
-        nsCSSValue* marginLeft = aData->ValueForMarginLeft();
-        if (marginLeft->GetUnit() == eCSSUnit_Null)
-          marginLeft->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
-        nsCSSValue* marginRight = aData->ValueForMarginRight();
-        if (marginRight->GetUnit() == eCSSUnit_Null)
-          marginRight->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
+        aData->SetPixelValueIfUnset(eCSSProperty_margin_left, (float)value->GetIntegerValue());
+        aData->SetPixelValueIfUnset(eCSSProperty_margin_right, (float)value->GetIntegerValue());
       }
 
       value = aAttributes->GetAttr(nsGkAtoms::vspace);
 
       if (value && value->Type() == nsAttrValue::eInteger) {
-        nsCSSValue* marginTop = aData->ValueForMarginTop();
-        if (marginTop->GetUnit() == eCSSUnit_Null)
-          marginTop->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
-        nsCSSValue* marginBottom = aData->ValueForMarginBottom();
-        if (marginBottom->GetUnit() == eCSSUnit_Null)
-          marginBottom->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
+        aData->SetPixelValueIfUnset(eCSSProperty_margin_top, (float)value->GetIntegerValue());
+        aData->SetPixelValueIfUnset(eCSSProperty_margin_bottom, (float)value->GetIntegerValue());
       }
     }
   }
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Position)) {
-    // width: value
-    nsCSSValue* width = aData->ValueForWidth();
-    if (width->GetUnit() == eCSSUnit_Null) {
-      const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width);
-      if (value && value->Type() == nsAttrValue::eInteger)
-        width->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
-      else if (value && value->Type() == nsAttrValue::ePercent)
-        width->SetPercentValue(value->GetPercentValue());
-    }
-
-    // height: value
-    nsCSSValue* height = aData->ValueForHeight();
-    if (height->GetUnit() == eCSSUnit_Null) {
-      const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::height);
-      if (value && value->Type() == nsAttrValue::eInteger)
-        height->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
-      else if (value && value->Type() == nsAttrValue::ePercent)
-        height->SetPercentValue(value->GetPercentValue());
-    }
-  }
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Border)) {
+  if (aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Border))) {
     // bordercolor
     const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::bordercolor);
     nscolor color;
     if (value && presContext->UseDocumentColors() &&
         value->GetColorValue(color)) {
-      nsCSSValue* borderLeftColor = aData->ValueForBorderLeftColor();
-      if (borderLeftColor->GetUnit() == eCSSUnit_Null)
-        borderLeftColor->SetColorValue(color);
-      nsCSSValue* borderRightColor = aData->ValueForBorderRightColor();
-      if (borderRightColor->GetUnit() == eCSSUnit_Null)
-        borderRightColor->SetColorValue(color);
-      nsCSSValue* borderTopColor = aData->ValueForBorderTopColor();
-      if (borderTopColor->GetUnit() == eCSSUnit_Null)
-        borderTopColor->SetColorValue(color);
-      nsCSSValue* borderBottomColor = aData->ValueForBorderBottomColor();
-      if (borderBottomColor->GetUnit() == eCSSUnit_Null)
-        borderBottomColor->SetColorValue(color);
+      aData->SetColorValueIfUnset(eCSSProperty_border_top_color, color);
+      aData->SetColorValueIfUnset(eCSSProperty_border_left_color, color);
+      aData->SetColorValueIfUnset(eCSSProperty_border_bottom_color, color);
+      aData->SetColorValueIfUnset(eCSSProperty_border_right_color, color);
     }
 
     // border
     const nsAttrValue* borderValue = aAttributes->GetAttr(nsGkAtoms::border);
     if (borderValue) {
       // border = 1 pixel default
       int32_t borderThickness = 1;
 
       if (borderValue->Type() == nsAttrValue::eInteger)
         borderThickness = borderValue->GetIntegerValue();
 
       // by default, set all border sides to the specified width
-      nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidth();
-      if (borderLeftWidth->GetUnit() == eCSSUnit_Null)
-        borderLeftWidth->SetFloatValue((float)borderThickness, eCSSUnit_Pixel);
-      nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidth();
-      if (borderRightWidth->GetUnit() == eCSSUnit_Null)
-        borderRightWidth->SetFloatValue((float)borderThickness, eCSSUnit_Pixel);
-      nsCSSValue* borderTopWidth = aData->ValueForBorderTopWidth();
-      if (borderTopWidth->GetUnit() == eCSSUnit_Null)
-        borderTopWidth->SetFloatValue((float)borderThickness, eCSSUnit_Pixel);
-      nsCSSValue* borderBottomWidth = aData->ValueForBorderBottomWidth();
-      if (borderBottomWidth->GetUnit() == eCSSUnit_Null)
-        borderBottomWidth->SetFloatValue((float)borderThickness, eCSSUnit_Pixel);
+      aData->SetPixelValueIfUnset(eCSSProperty_border_top_width, (float)borderThickness);
+      aData->SetPixelValueIfUnset(eCSSProperty_border_left_width, (float)borderThickness);
+      aData->SetPixelValueIfUnset(eCSSProperty_border_bottom_width, (float)borderThickness);
+      aData->SetPixelValueIfUnset(eCSSProperty_border_right_width, (float)borderThickness);
     }
   }
-  nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aGenericData);
-  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aGenericData);
+  nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes, aData);
+  nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aData);
+  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
 }
 
 NS_IMETHODIMP_(bool)
 HTMLTableElement::IsAttributeMapped(const nsIAtom* aAttribute) const
 {
   static const MappedAttributeEntry attributes[] = {
     { &nsGkAtoms::cellpadding },
     { &nsGkAtoms::cellspacing },
@@ -876,45 +825,29 @@ HTMLTableElement::IsAttributeMapped(cons
 nsMapRuleToAttributesFunc
 HTMLTableElement::GetAttributeMappingFunction() const
 {
   return &MapAttributesIntoRule;
 }
 
 static void
 MapInheritedTableAttributesIntoRule(const nsMappedAttributes* aAttributes,
-                                    GenericSpecifiedValues* aGenericData)
+                                    GenericSpecifiedValues* aData)
 {
-  nsRuleData* aData = aGenericData->AsRuleData();
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Padding)) {
+  if (aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Padding))) {
     const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::cellpadding);
     if (value && value->Type() == nsAttrValue::eInteger) {
       // We have cellpadding.  This will override our padding values if we
       // don't have any set.
-      nsCSSValue padVal(float(value->GetIntegerValue()), eCSSUnit_Pixel);
-
-      nsCSSValue* paddingLeft = aData->ValueForPaddingLeft();
-      if (paddingLeft->GetUnit() == eCSSUnit_Null) {
-        *paddingLeft = padVal;
-      }
+      float pad = float(value->GetIntegerValue());
 
-      nsCSSValue* paddingRight = aData->ValueForPaddingRight();
-      if (paddingRight->GetUnit() == eCSSUnit_Null) {
-        *paddingRight = padVal;
-      }
-
-      nsCSSValue* paddingTop = aData->ValueForPaddingTop();
-      if (paddingTop->GetUnit() == eCSSUnit_Null) {
-        *paddingTop = padVal;
-      }
-
-      nsCSSValue* paddingBottom = aData->ValueForPaddingBottom();
-      if (paddingBottom->GetUnit() == eCSSUnit_Null) {
-        *paddingBottom = padVal;
-      }
+      aData->SetPixelValueIfUnset(eCSSProperty_padding_top, pad);
+      aData->SetPixelValueIfUnset(eCSSProperty_padding_right, pad);
+      aData->SetPixelValueIfUnset(eCSSProperty_padding_bottom, pad);
+      aData->SetPixelValueIfUnset(eCSSProperty_padding_left, pad);
     }
   }
 }
 
 nsMappedAttributes*
 HTMLTableElement::GetAttributesMappedForCell()
 {
   if (mTableInheritedAttributes) {
--- a/dom/html/HTMLTableRowElement.cpp
+++ b/dom/html/HTMLTableRowElement.cpp
@@ -259,51 +259,23 @@ HTMLTableRowElement::ParseAttribute(int3
                                                         aAttribute, aValue,
                                                         aResult) ||
          nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                               aResult);
 }
 
 void
 HTMLTableRowElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
-                                           GenericSpecifiedValues* aGenericData)
+                                           GenericSpecifiedValues* aData)
 {
-  nsRuleData* aData = aGenericData->AsRuleData();
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Position)) {
-    // height: value
-    nsCSSValue* height = aData->ValueForHeight();
-    if (height->GetUnit() == eCSSUnit_Null) {
-      const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::height);
-      if (value && value->Type() == nsAttrValue::eInteger)
-        height->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
-      else if (value && value->Type() == nsAttrValue::ePercent)
-        height->SetPercentValue(value->GetPercentValue());
-    }
-  }
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Text)) {
-    nsCSSValue* textAlign = aData->ValueForTextAlign();
-    if (textAlign->GetUnit() == eCSSUnit_Null) {
-      // align: enum
-      const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);
-      if (value && value->Type() == nsAttrValue::eEnum)
-        textAlign->SetIntValue(value->GetEnumValue(), eCSSUnit_Enumerated);
-    }
-  }
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Display)) {
-    nsCSSValue* verticalAlign = aData->ValueForVerticalAlign();
-    if (verticalAlign->GetUnit() == eCSSUnit_Null) {
-      // valign: enum
-      const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::valign);
-      if (value && value->Type() == nsAttrValue::eEnum)
-        verticalAlign->SetIntValue(value->GetEnumValue(), eCSSUnit_Enumerated);
-    }
-  }
-
-  nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aGenericData);
-  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aGenericData);
+  nsGenericHTMLElement::MapHeightAttributeInto(aAttributes, aData);
+  nsGenericHTMLElement::MapDivAlignAttributeInto(aAttributes, aData);
+  nsGenericHTMLElement::MapVAlignAttributeInto(aAttributes, aData);
+  nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aData);
+  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
 }
 
 NS_IMETHODIMP_(bool)
 HTMLTableRowElement::IsAttributeMapped(const nsIAtom* aAttribute) const
 {
   static const MappedAttributeEntry attributes[] = {
     { &nsGkAtoms::align },
     { &nsGkAtoms::valign }, 
--- a/dom/html/HTMLTableSectionElement.cpp
+++ b/dom/html/HTMLTableSectionElement.cpp
@@ -162,49 +162,30 @@ HTMLTableSectionElement::ParseAttribute(
                                                         aAttribute, aValue,
                                                         aResult) ||
          nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                               aResult);
 }
 
 void
 HTMLTableSectionElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
-                                               GenericSpecifiedValues* aGenericData)
+                                               GenericSpecifiedValues* aData)
 {
-  nsRuleData* aData = aGenericData->AsRuleData();
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Position)) {
+  if (aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Position))) {
     // height: value
-    nsCSSValue* height = aData->ValueForHeight();
-    if (height->GetUnit() == eCSSUnit_Null) {
+    if (!aData->PropertyIsSet(eCSSProperty_height)) {
       const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::height);
       if (value && value->Type() == nsAttrValue::eInteger)
-        height->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
+        aData->SetPixelValue(eCSSProperty_height, (float)value->GetIntegerValue());
     }
   }
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Text)) {
-    nsCSSValue* textAlign = aData->ValueForTextAlign();
-    if (textAlign->GetUnit() == eCSSUnit_Null) {
-      // align: enum
-      const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);
-      if (value && value->Type() == nsAttrValue::eEnum)
-        textAlign->SetIntValue(value->GetEnumValue(), eCSSUnit_Enumerated);
-    }
-  }
-  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Display)) {
-    nsCSSValue* verticalAlign = aData->ValueForVerticalAlign();
-    if (verticalAlign->GetUnit() == eCSSUnit_Null) {
-      // valign: enum
-      const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::valign);
-      if (value && value->Type() == nsAttrValue::eEnum)
-        verticalAlign->SetIntValue(value->GetEnumValue(), eCSSUnit_Enumerated);
-    }
-  }
-
-  nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aGenericData);
-  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aGenericData);
+  nsGenericHTMLElement::MapDivAlignAttributeInto(aAttributes, aData);
+  nsGenericHTMLElement::MapVAlignAttributeInto(aAttributes, aData);
+  nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aData);
+  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
 }
 
 NS_IMETHODIMP_(bool)
 HTMLTableSectionElement::IsAttributeMapped(const nsIAtom* aAttribute) const
 {
   static const MappedAttributeEntry attributes[] = {
     { &nsGkAtoms::align },
     { &nsGkAtoms::valign },
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -1368,16 +1368,29 @@ nsGenericHTMLElement::MapDivAlignAttribu
       // align: enum
       const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);
       if (value && value->Type() == nsAttrValue::eEnum)
         aData->SetKeywordValue(eCSSProperty_text_align, value->GetEnumValue());
     }
   }
 }
 
+void
+nsGenericHTMLElement::MapVAlignAttributeInto(const nsMappedAttributes* aAttributes,
+                                             GenericSpecifiedValues* aData)
+{
+  if (aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Display))) {
+    if (!aData->PropertyIsSet(eCSSProperty_vertical_align)) {
+      // align: enum
+      const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::valign);
+      if (value && value->Type() == nsAttrValue::eEnum)
+        aData->SetKeywordValue(eCSSProperty_vertical_align, value->GetEnumValue());
+    }
+  }
+}
 
 void
 nsGenericHTMLElement::MapImageMarginAttributeInto(const nsMappedAttributes* aAttributes,
                                                   GenericSpecifiedValues* aData)
 {
   if (!aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Margin)))
     return;
 
@@ -1412,48 +1425,65 @@ nsGenericHTMLElement::MapImageMarginAttr
                                     value->GetPercentValue());
       aData->SetPercentValueIfUnset(eCSSProperty_margin_bottom,
                                     value->GetPercentValue());
     }
   }
 }
 
 void
-nsGenericHTMLElement::MapImageSizeAttributesInto(const nsMappedAttributes* aAttributes,
-                                                 GenericSpecifiedValues* aData)
+nsGenericHTMLElement::MapWidthAttributeInto(const nsMappedAttributes* aAttributes,
+                                            GenericSpecifiedValues* aData)
 {
-  if (!aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Position)))
+  if (!aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Position))) {
     return;
+  }
 
   // width: value
   if (!aData->PropertyIsSet(eCSSProperty_width)) {
     const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width);
     if (value && value->Type() == nsAttrValue::eInteger) {
       aData->SetPixelValue(eCSSProperty_width,
                            (float)value->GetIntegerValue());
     } else if (value && value->Type() == nsAttrValue::ePercent) {
       aData->SetPercentValue(eCSSProperty_width,
                              value->GetPercentValue());
     }
   }
+}
+
+void
+nsGenericHTMLElement::MapHeightAttributeInto(const nsMappedAttributes* aAttributes,
+                                             GenericSpecifiedValues* aData)
+{
+  if (!aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Position)))
+    return;
 
   // height: value
   if (!aData->PropertyIsSet(eCSSProperty_height)) {
     const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::height);
     if (value && value->Type() == nsAttrValue::eInteger) {
       aData->SetPixelValue(eCSSProperty_height,
                            (float)value->GetIntegerValue());
     } else if (value && value->Type() == nsAttrValue::ePercent) {
       aData->SetPercentValue(eCSSProperty_height,
                              value->GetPercentValue());
     }
   }
 }
 
 void
+nsGenericHTMLElement::MapImageSizeAttributesInto(const nsMappedAttributes* aAttributes,
+                                                 GenericSpecifiedValues* aData)
+{
+  nsGenericHTMLElement::MapWidthAttributeInto(aAttributes, aData);
+  nsGenericHTMLElement::MapHeightAttributeInto(aAttributes, aData);
+}
+
+void
 nsGenericHTMLElement::MapImageBorderAttributeInto(const nsMappedAttributes* aAttributes,
                                                   GenericSpecifiedValues* aData)
 {
   if (!(aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Border))))
     return;
 
   // border: pixels
   const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::border);
--- a/dom/html/nsGenericHTMLElement.h
+++ b/dom/html/nsGenericHTMLElement.h
@@ -687,17 +687,28 @@ public:
    * Helper to map the align attribute into a style struct for things
    * like <div>, <h1>, etc.
    *
    * @param aAttributes the list of attributes to map
    * @param aData the returned rule data [INOUT]
    * @see GetAttributeMappingFunction
    */
   static void MapDivAlignAttributeInto(const nsMappedAttributes* aAttributes,
-                                       GenericSpecifiedValues* aGenericData);
+                                    GenericSpecifiedValues* aGenericData);
+
+  /**
+   * Helper to map the valign attribute into a style struct for things
+   * like <col>, <tr>, <section>, etc.
+   *
+   * @param aAttributes the list of attributes to map
+   * @param aData the returned rule data [INOUT]
+   * @see GetAttributeMappingFunction
+   */
+  static void MapVAlignAttributeInto(const nsMappedAttributes* aAttributes,
+                                    GenericSpecifiedValues* aGenericData);
 
   /**
    * Helper to map the image border attribute into a style struct.
    *
    * @param aAttributes the list of attributes to map
    * @param aData the returned rule data [INOUT]
    * @see GetAttributeMappingFunction
    */
@@ -716,16 +727,35 @@ public:
    * Helper to map the image position attribute into a style struct.
    *
    * @param aAttributes the list of attributes to map
    * @param aData the returned rule data [INOUT]
    * @see GetAttributeMappingFunction
    */
   static void MapImageSizeAttributesInto(const nsMappedAttributes* aAttributes,
                                          GenericSpecifiedValues* aGenericData);
+
+  /**
+   * Helper to map `width` attribute into a style struct.
+   *
+   * @param aAttributes the list of attributes to map
+   * @param aData the returned rule data [INOUT]
+   * @see GetAttributeMappingFunction
+   */
+  static void MapWidthAttributeInto(const nsMappedAttributes* aAttributes,
+                                    GenericSpecifiedValues* aGenericData);
+  /**
+   * Helper to map `height` attribute into a style struct.
+   *
+   * @param aAttributes the list of attributes to map
+   * @param aData the returned rule data [INOUT]
+   * @see GetAttributeMappingFunction
+   */
+  static void MapHeightAttributeInto(const nsMappedAttributes* aAttributes,
+                                     GenericSpecifiedValues* aGenericData);
   /**
    * Helper to map the background attribute
    * into a style struct.
    *
    * @param aAttributes the list of attributes to map
    * @param aData the returned rule data [INOUT]
    * @see GetAttributeMappingFunction
    */
--- a/layout/style/GenericSpecifiedValues.h
+++ b/layout/style/GenericSpecifiedValues.h
@@ -51,27 +51,34 @@ public:
     template<typename T,
              typename = typename std::enable_if<std::is_enum<T>::value>::type>
     void SetKeywordValueIfUnset(nsCSSPropertyID aId, T aValue) {
         static_assert(mozilla::EnumTypeFitsWithin<T, int32_t>::value,
                       "aValue must be an enum that fits within 32 bits");
         SetKeywordValueIfUnset(aId, static_cast<int32_t>(aValue));
     }
 
+    // Set a property to an integer value
+    virtual void SetIntValue(nsCSSPropertyID aId, int32_t aValue) = 0;
     // Set a property to a pixel value
     virtual void SetPixelValue(nsCSSPropertyID aId, float aValue) = 0;
     virtual void SetPixelValueIfUnset(nsCSSPropertyID aId, float aValue) = 0;
 
     // Set a property to a percent value
     virtual void SetPercentValue(nsCSSPropertyID aId, float aValue) = 0;
     virtual void SetPercentValueIfUnset(nsCSSPropertyID aId, float aValue) = 0;
 
+    // Set a property to `auto`
+    virtual void SetAutoValue(nsCSSPropertyID aId) = 0;
+    virtual void SetAutoValueIfUnset(nsCSSPropertyID aId) = 0;
+
     // Set a property to `currentcolor`
     virtual void SetCurrentColor(nsCSSPropertyID aId) = 0;
     virtual void SetCurrentColorIfUnset(nsCSSPropertyID aId) = 0;
 
     // Set a property to an RGBA nscolor value
     virtual void SetColorValue(nsCSSPropertyID aId, nscolor aValue) = 0;
+    virtual void SetColorValueIfUnset(nsCSSPropertyID aId, nscolor aValue) = 0;
 
     virtual nsRuleData* AsRuleData() = 0;
 };
 
-#endif // mozilla_GenericSpecifiedValues_h
\ No newline at end of file
+#endif // mozilla_GenericSpecifiedValues_h
--- a/layout/style/nsRuleData.h
+++ b/layout/style/nsRuleData.h
@@ -153,16 +153,22 @@ struct nsRuleData final: GenericSpecifie
 
   void SetKeywordValueIfUnset(nsCSSPropertyID aId,
                               int32_t aValue) override {
     if (!PropertyIsSet(aId)) {
       SetKeywordValue(aId, aValue);
     }
   }
 
+
+  void SetIntValue(nsCSSPropertyID aId,
+                   int32_t aValue) override {
+    ValueFor(aId)->SetIntValue(aValue, eCSSUnit_Integer);
+  }
+
   void SetPixelValue(nsCSSPropertyID aId,
                      float aValue) override {
     ValueFor(aId)->SetFloatValue(aValue, eCSSUnit_Pixel);
   }
 
   void SetPixelValueIfUnset(nsCSSPropertyID aId,
                             float aValue) override {
     if (!PropertyIsSet(aId)) {
@@ -170,16 +176,26 @@ struct nsRuleData final: GenericSpecifie
     }
   }
 
   void SetPercentValue(nsCSSPropertyID aId,
                        float aValue) override {
     ValueFor(aId)->SetPercentValue(aValue);
   }
 
+  void SetAutoValue(nsCSSPropertyID aId) override {
+    ValueFor(aId)->SetAutoValue();
+  }
+
+  void SetAutoValueIfUnset(nsCSSPropertyID aId) override {
+    if (!PropertyIsSet(aId)) {
+      SetAutoValue(aId);
+    }
+  }
+
   void SetPercentValueIfUnset(nsCSSPropertyID aId,
                               float aValue) override {
     if (!PropertyIsSet(aId)) {
       SetPercentValue(aId, aValue);
     }
   }
 
   void SetCurrentColor(nsCSSPropertyID aId) override {
@@ -192,16 +208,23 @@ struct nsRuleData final: GenericSpecifie
     }
   }
 
   void SetColorValue(nsCSSPropertyID aId,
                      nscolor aValue) override {
     ValueFor(aId)->SetColorValue(aValue);
   }
 
+  void SetColorValueIfUnset(nsCSSPropertyID aId,
+                            nscolor aValue) override {
+    if (!PropertyIsSet(aId)) {
+      SetColorValue(aId, aValue);
+    }
+  }
+
   nsRuleData* AsRuleData() override {
     return this;
   }
 
 private:
   inline size_t GetPoisonOffset();
 
 };