Bug 649142 - Part 3: Convert logical padding properties. r=dbaron
☠☠ backed out by e7c43c3f8398 ☠ ☠
authorCameron McCormack <cam@mcc.id.au>
Wed, 31 Dec 2014 12:18:14 +1100
changeset 249222 35c42cd138e1d0af99d87687bf3bf0f8cc364b80
parent 249221 1335630cf287c48e2e1508332b0d459881320537
child 249223 15ed55c61f4e4efb1c9a224f7ee7c101e4766fd1
push id698
push userjlund@mozilla.com
push dateMon, 23 Mar 2015 22:08:11 +0000
treeherdermozilla-release@b0c0ae7b02a3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs649142
milestone37.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 649142 - Part 3: Convert logical padding properties. r=dbaron Here we convert the logical padding properties into their new resolved-at- cascade-time implementations. This involves: * converting -moz-padding-{start,end} into logical longhand properties * adding padding-inline-{start,end} aliases for -moz-padding-{start,end} * converting padding-{left,right} into longhand properties * removing padding-{left,right}-value and padding-{left,right}-{ltr,rtl}-source internal properties The CSS parser and various tests are simplified a bit as a result.
browser/devtools/layoutview/view.js
dom/html/HTMLTableElement.cpp
layout/inspector/tests/test_bug1006595.html
layout/style/Declaration.cpp
layout/style/nsCSSDataBlock.cpp
layout/style/nsCSSParser.cpp
layout/style/nsCSSPropAliasList.h
layout/style/nsCSSPropList.h
layout/style/nsCSSProps.cpp
layout/style/nsRuleData.h
layout/style/nsRuleNode.cpp
layout/style/test/ListCSSProperties.cpp
layout/style/test/css_properties_like_longhand.js
layout/style/test/property_database.js
layout/style/test/test_value_computation.html
--- a/browser/devtools/layoutview/view.js
+++ b/browser/devtools/layoutview/view.js
@@ -187,25 +187,21 @@ LayoutView.prototype = {
                   realProperty: "margin-right-value",
                   value: undefined},
       paddingTop: {selector: ".padding.top > span",
                   property: "padding-top",
                   value: undefined},
       paddingBottom: {selector: ".padding.bottom > span",
                   property: "padding-bottom",
                   value: undefined},
-      // padding-left behaves the same as margin-left
       paddingLeft: {selector: ".padding.left > span",
                   property: "padding-left",
-                  realProperty: "padding-left-value",
                   value: undefined},
-      // padding-right behaves the same as margin-left
       paddingRight: {selector: ".padding.right > span",
                   property: "padding-right",
-                  realProperty: "padding-right-value",
                   value: undefined},
       borderTop: {selector: ".border.top > span",
                   property: "border-top-width",
                   value: undefined},
       borderBottom: {selector: ".border.bottom > span",
                   property: "border-bottom-width",
                   value: undefined},
       borderLeft: {selector: ".border.left > span",
--- a/dom/html/HTMLTableElement.cpp
+++ b/dom/html/HTMLTableElement.cpp
@@ -849,22 +849,22 @@ MapInheritedTableAttributesIntoRule(cons
 {
   if (aData->mSIDs & 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->ValueForPaddingLeftValue();
+      nsCSSValue* paddingLeft = aData->ValueForPaddingLeft();
       if (paddingLeft->GetUnit() == eCSSUnit_Null) {
         *paddingLeft = padVal;
       }
 
-      nsCSSValue* paddingRight = aData->ValueForPaddingRightValue();
+      nsCSSValue* paddingRight = aData->ValueForPaddingRight();
       if (paddingRight->GetUnit() == eCSSUnit_Null) {
         *paddingRight = padVal;
       }
 
       nsCSSValue* paddingTop = aData->ValueForPaddingTop();
       if (paddingTop->GetUnit() == eCSSUnit_Null) {
         *paddingTop = padVal;
       }
--- a/layout/inspector/tests/test_bug1006595.html
+++ b/layout/inspector/tests/test_bug1006595.html
@@ -18,21 +18,19 @@ https://bugzilla.mozilla.org/show_bug.cg
     }
   }
   var utils = SpecialPowers.Cc["@mozilla.org/inspector/dom-utils;1"]
     .getService(SpecialPowers.Ci.inIDOMUtils);
 
   var paddingSubProps = utils.getSubpropertiesForCSSProperty("padding");
   arraysEqual(paddingSubProps,
               [ "padding-top",
-                "padding-right-value",
+                "padding-right",
                 "padding-bottom",
-                "padding-left-value",
-                "padding-left-ltr-source", "padding-left-rtl-source",
-                "padding-right-ltr-source", "padding-right-rtl-source" ],
+                "padding-left" ],
               "'padding' subproperties");
 
   var displaySubProps = utils.getSubpropertiesForCSSProperty("color");
   arraysEqual(displaySubProps, [ "color" ],
               "'color' subproperties");
 
   ok(utils.cssPropertyIsShorthand("padding"), "'padding' is a shorthand")
   ok(!utils.cssPropertyIsShorthand("color"), "'color' is not a shorthand")
--- a/layout/style/Declaration.cpp
+++ b/layout/style/Declaration.cpp
@@ -395,20 +395,16 @@ Declaration::GetValue(nsCSSProperty aPro
         aValue.Truncate();
       }
       break;
     }
     case eCSSProperty_margin_left:
     case eCSSProperty_margin_right:
     case eCSSProperty_margin_start:
     case eCSSProperty_margin_end:
-    case eCSSProperty_padding_left:
-    case eCSSProperty_padding_right:
-    case eCSSProperty_padding_start:
-    case eCSSProperty_padding_end:
     case eCSSProperty_border_left_color:
     case eCSSProperty_border_left_style:
     case eCSSProperty_border_left_width:
     case eCSSProperty_border_right_color:
     case eCSSProperty_border_right_style:
     case eCSSProperty_border_right_width:
     case eCSSProperty_border_start_color:
     case eCSSProperty_border_start_style:
--- a/layout/style/nsCSSDataBlock.cpp
+++ b/layout/style/nsCSSDataBlock.cpp
@@ -170,16 +170,22 @@ MapSinglePropertyInto(nsCSSProperty aPro
  */
 static inline void
 EnsurePhysicalProperty(nsCSSProperty& aProperty, nsRuleData* aRuleData)
 {
   uint8_t direction = aRuleData->mStyleContext->StyleVisibility()->mDirection;
   bool ltr = direction == NS_STYLE_DIRECTION_LTR;
 
   switch (aProperty) {
+    case eCSSProperty_padding_end:
+      aProperty = ltr ? eCSSProperty_padding_right : eCSSProperty_padding_left;
+      break;
+    case eCSSProperty_padding_start:
+      aProperty = ltr ? eCSSProperty_padding_left : eCSSProperty_padding_right;
+      break;
     default:
       NS_ABORT_IF_FALSE(nsCSSProps::PropHasFlags(aProperty,
                                                  CSS_PROPERTY_LOGICAL),
                         "unhandled logical property");
   }
 }
 
 void
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -9902,28 +9902,16 @@ CSSParserImpl::ParsePropertyByFunction(n
   case eCSSProperty_object_position:
     return ParseObjectPosition();
   case eCSSProperty_outline:
     return ParseOutline();
   case eCSSProperty_overflow:
     return ParseOverflow();
   case eCSSProperty_padding:
     return ParsePadding();
-  case eCSSProperty_padding_end:
-    return ParseDirectionalBoxProperty(eCSSProperty_padding_end,
-                                       NS_BOXPROP_SOURCE_LOGICAL);
-  case eCSSProperty_padding_left:
-    return ParseDirectionalBoxProperty(eCSSProperty_padding_left,
-                                       NS_BOXPROP_SOURCE_PHYSICAL);
-  case eCSSProperty_padding_right:
-    return ParseDirectionalBoxProperty(eCSSProperty_padding_right,
-                                       NS_BOXPROP_SOURCE_PHYSICAL);
-  case eCSSProperty_padding_start:
-    return ParseDirectionalBoxProperty(eCSSProperty_padding_start,
-                                       NS_BOXPROP_SOURCE_LOGICAL);
   case eCSSProperty_quotes:
     return ParseQuotes();
   case eCSSProperty_size:
     return ParseSize();
   case eCSSProperty_text_decoration:
     return ParseTextDecoration();
   case eCSSProperty_will_change:
     return ParseWillChange();
@@ -13080,30 +13068,21 @@ CSSParserImpl::ParseOverflow()
   return true;
 }
 
 bool
 CSSParserImpl::ParsePadding()
 {
   static const nsCSSProperty kPaddingSideIDs[] = {
     eCSSProperty_padding_top,
-    eCSSProperty_padding_right_value,
+    eCSSProperty_padding_right,
     eCSSProperty_padding_bottom,
-    eCSSProperty_padding_left_value
+    eCSSProperty_padding_left
   };
-  static const nsCSSProperty kPaddingSources[] = {
-    eCSSProperty_padding_left_ltr_source,
-    eCSSProperty_padding_left_rtl_source,
-    eCSSProperty_padding_right_ltr_source,
-    eCSSProperty_padding_right_rtl_source,
-    eCSSProperty_UNKNOWN
-  };
-
-  // do this now, in case 4 values weren't specified
-  InitBoxPropsAsPhysical(kPaddingSources);
+
   return ParseBoxProperties(kPaddingSideIDs);
 }
 
 bool
 CSSParserImpl::ParseQuotes()
 {
   nsCSSValue value;
   if (!ParseVariant(value, VARIANT_HOS, nullptr)) {
--- a/layout/style/nsCSSPropAliasList.h
+++ b/layout/style/nsCSSPropAliasList.h
@@ -134,8 +134,16 @@ CSS_PROP_ALIAS(-moz-text-decoration-colo
 CSS_PROP_ALIAS(-moz-text-decoration-line,
                text_decoration_line,
                MozTextDecorationLine,
                "")
 CSS_PROP_ALIAS(-moz-text-decoration-style,
                text_decoration_style,
                MozTextDecorationStyle,
                "")
+CSS_PROP_ALIAS(padding-inline-end,
+               padding_end,
+               PaddingInlineEnd,
+               "layout.css.vertical-text.enabled")
+CSS_PROP_ALIAS(padding-inline-start,
+               padding_start,
+               PaddingInlineStart,
+               "layout.css.vertical-text.enabled")
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -2747,169 +2747,87 @@ CSS_PROP_PADDING(
         CSS_PROPERTY_STORES_CALC |
         CSS_PROPERTY_UNITLESS_LENGTH_QUIRK |
         CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH,
     "",
     VARIANT_HLP | VARIANT_CALC,
     nullptr,
     offsetof(nsStylePadding, mPadding),
     eStyleAnimType_Sides_Bottom)
-CSS_PROP_SHORTHAND(
+CSS_PROP_LOGICAL(
     -moz-padding-end,
     padding_end,
     CSS_PROP_DOMPROP_PREFIXED(PaddingEnd),
-    CSS_PROPERTY_PARSE_FUNCTION,
-    "")
-#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
-CSS_PROP_PADDING(
-    padding-end-value,
-    padding_end_value,
-    PaddingEndValue,
-    CSS_PROPERTY_PARSE_INACCESSIBLE |
+    CSS_PROPERTY_PARSE_VALUE |
         CSS_PROPERTY_VALUE_NONNEGATIVE |
         CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
         // This is required by the UA stylesheet and can't be overridden.
         CSS_PROPERTY_APPLIES_TO_PLACEHOLDER |
-        CSS_PROPERTY_STORES_CALC,
-    "",
-    VARIANT_HLP | VARIANT_CALC, // for internal use
+        CSS_PROPERTY_STORES_CALC |
+        CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH |
+        CSS_PROPERTY_LOGICAL,
+    "",
+    VARIANT_HLP | VARIANT_CALC,
     nullptr,
+    Padding,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_None)
-#endif
-CSS_PROP_SHORTHAND(
-    padding-left,
-    padding_left,
-    PaddingLeft,
-    CSS_PROPERTY_PARSE_FUNCTION |
-        CSS_PROPERTY_UNITLESS_LENGTH_QUIRK |
-        CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH,
-    "")
-#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
-CSS_PROP_PADDING(
-    padding-left-value,
-    padding_left_value,
-    PaddingLeftValue,
-    CSS_PROPERTY_PARSE_INACCESSIBLE |
+CSS_PROP_LOGICAL(
+    -moz-padding-start,
+    padding_start,
+    CSS_PROP_DOMPROP_PREFIXED(PaddingStart),
+    CSS_PROPERTY_PARSE_VALUE |
         CSS_PROPERTY_VALUE_NONNEGATIVE |
         CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
         // This is required by the UA stylesheet and can't be overridden.
         CSS_PROPERTY_APPLIES_TO_PLACEHOLDER |
-        CSS_PROPERTY_REPORT_OTHER_NAME |
-        CSS_PROPERTY_STORES_CALC,
-    "",
-    VARIANT_HLP | VARIANT_CALC, // for internal use
+        CSS_PROPERTY_STORES_CALC |
+        CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH |
+        CSS_PROPERTY_LOGICAL,
+    "",
+    VARIANT_HLP | VARIANT_CALC,
+    nullptr,
+    Padding,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+CSS_PROP_PADDING(
+    padding-left,
+    padding_left,
+    PaddingLeft,
+    CSS_PROPERTY_PARSE_VALUE |
+        CSS_PROPERTY_VALUE_NONNEGATIVE |
+        CSS_PROPERTY_UNITLESS_LENGTH_QUIRK |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        // This is required by the UA stylesheet and can't be overridden.
+        CSS_PROPERTY_APPLIES_TO_PLACEHOLDER |
+        CSS_PROPERTY_STORES_CALC |
+        CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH,
+    "",
+    VARIANT_HLP | VARIANT_CALC,
     nullptr,
     offsetof(nsStylePadding, mPadding),
     eStyleAnimType_Sides_Left)
 CSS_PROP_PADDING(
-    padding-left-ltr-source,
-    padding_left_ltr_source,
-    PaddingLeftLTRSource,
-    CSS_PROPERTY_PARSE_INACCESSIBLE |
-        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
-        // This is required by the UA stylesheet and can't be overridden.
-        CSS_PROPERTY_APPLIES_TO_PLACEHOLDER |
-        CSS_PROPERTY_DIRECTIONAL_SOURCE,
-    "",
-    0,
-    kBoxPropSourceKTable,
-    CSS_PROP_NO_OFFSET,
-    eStyleAnimType_None)
-CSS_PROP_PADDING(
-    padding-left-rtl-source,
-    padding_left_rtl_source,
-    PaddingLeftRTLSource,
-    CSS_PROPERTY_PARSE_INACCESSIBLE |
-        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
-        // This is required by the UA stylesheet and can't be overridden.
-        CSS_PROPERTY_APPLIES_TO_PLACEHOLDER |
-        CSS_PROPERTY_DIRECTIONAL_SOURCE,
-    "",
-    0,
-    kBoxPropSourceKTable,
-    CSS_PROP_NO_OFFSET,
-    eStyleAnimType_None)
-#endif
-CSS_PROP_SHORTHAND(
     padding-right,
     padding_right,
     PaddingRight,
-    CSS_PROPERTY_PARSE_FUNCTION |
+    CSS_PROPERTY_PARSE_VALUE |
+        CSS_PROPERTY_VALUE_NONNEGATIVE |
         CSS_PROPERTY_UNITLESS_LENGTH_QUIRK |
-        CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH,
-    "")
-#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
-CSS_PROP_PADDING(
-    padding-right-value,
-    padding_right_value,
-    PaddingRightValue,
-    CSS_PROPERTY_PARSE_INACCESSIBLE |
-        CSS_PROPERTY_VALUE_NONNEGATIVE |
         CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
         // This is required by the UA stylesheet and can't be overridden.
         CSS_PROPERTY_APPLIES_TO_PLACEHOLDER |
-        CSS_PROPERTY_REPORT_OTHER_NAME |
-        CSS_PROPERTY_STORES_CALC,
-    "",
-    VARIANT_HLP | VARIANT_CALC, // for internal use
+        CSS_PROPERTY_STORES_CALC |
+        CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH,
+    "",
+    VARIANT_HLP | VARIANT_CALC,
     nullptr,
     offsetof(nsStylePadding, mPadding),
     eStyleAnimType_Sides_Right)
 CSS_PROP_PADDING(
-    padding-right-ltr-source,
-    padding_right_ltr_source,
-    PaddingRightLTRSource,
-    CSS_PROPERTY_PARSE_INACCESSIBLE |
-        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
-        // This is required by the UA stylesheet and can't be overridden.
-        CSS_PROPERTY_APPLIES_TO_PLACEHOLDER |
-        CSS_PROPERTY_DIRECTIONAL_SOURCE,
-    "",
-    0,
-    kBoxPropSourceKTable,
-    CSS_PROP_NO_OFFSET,
-    eStyleAnimType_None)
-CSS_PROP_PADDING(
-    padding-right-rtl-source,
-    padding_right_rtl_source,
-    PaddingRightRTLSource,
-    CSS_PROPERTY_PARSE_INACCESSIBLE |
-        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
-        CSS_PROPERTY_DIRECTIONAL_SOURCE,
-    "",
-    0,
-    kBoxPropSourceKTable,
-    CSS_PROP_NO_OFFSET,
-    eStyleAnimType_None)
-#endif
-CSS_PROP_SHORTHAND(
-    -moz-padding-start,
-    padding_start,
-    CSS_PROP_DOMPROP_PREFIXED(PaddingStart),
-    CSS_PROPERTY_PARSE_FUNCTION,
-    "")
-#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
-CSS_PROP_PADDING(
-    padding-start-value,
-    padding_start_value,
-    PaddingStartValue,
-    CSS_PROPERTY_PARSE_INACCESSIBLE |
-        CSS_PROPERTY_VALUE_NONNEGATIVE |
-        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
-        // This is required by the UA stylesheet and can't be overridden.
-        CSS_PROPERTY_APPLIES_TO_PLACEHOLDER |
-        CSS_PROPERTY_STORES_CALC,
-    "",
-    VARIANT_HLP | VARIANT_CALC, // for internal use
-    nullptr,
-    CSS_PROP_NO_OFFSET,
-    eStyleAnimType_None)
-#endif
-CSS_PROP_PADDING(
     padding-top,
     padding_top,
     PaddingTop,
     CSS_PROPERTY_PARSE_VALUE |
         CSS_PROPERTY_VALUE_NONNEGATIVE |
         CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
         // This is required by the UA stylesheet and can't be overridden.
         CSS_PROPERTY_APPLIES_TO_PLACEHOLDER |
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -573,20 +573,16 @@ nsCSSProps::OtherNameFor(nsCSSProperty a
     case eCSSProperty_border_right_style_value:
       return eCSSProperty_border_right_style;
     case eCSSProperty_border_right_width_value:
       return eCSSProperty_border_right_width;
     case eCSSProperty_margin_left_value:
       return eCSSProperty_margin_left;
     case eCSSProperty_margin_right_value:
       return eCSSProperty_margin_right;
-    case eCSSProperty_padding_left_value:
-      return eCSSProperty_padding_left;
-    case eCSSProperty_padding_right_value:
-      return eCSSProperty_padding_right;
     default:
       NS_ABORT_IF_FALSE(false, "bad caller");
   }
   return eCSSProperty_UNKNOWN;
 }
 
 /***************************************************************************/
 
@@ -2699,56 +2695,19 @@ static const nsCSSProperty gOverflowSubp
   eCSSProperty_overflow_x,
   eCSSProperty_overflow_y,
   eCSSProperty_UNKNOWN
 };
 
 static const nsCSSProperty gPaddingSubpropTable[] = {
   // Code relies on these being in top-right-bottom-left order.
   eCSSProperty_padding_top,
-  eCSSProperty_padding_right_value,
+  eCSSProperty_padding_right,
   eCSSProperty_padding_bottom,
-  eCSSProperty_padding_left_value,
-  // extras:
-  eCSSProperty_padding_left_ltr_source,
-  eCSSProperty_padding_left_rtl_source,
-  eCSSProperty_padding_right_ltr_source,
-  eCSSProperty_padding_right_rtl_source,
-  eCSSProperty_UNKNOWN
-};
-
-static const nsCSSProperty gPaddingLeftSubpropTable[] = {
-  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
-  eCSSProperty_padding_left_value,
-  eCSSProperty_padding_left_ltr_source,
-  eCSSProperty_padding_left_rtl_source,
-  eCSSProperty_UNKNOWN
-};
-
-static const nsCSSProperty gPaddingRightSubpropTable[] = {
-  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
-  eCSSProperty_padding_right_value,
-  eCSSProperty_padding_right_ltr_source,
-  eCSSProperty_padding_right_rtl_source,
-  eCSSProperty_UNKNOWN
-};
-
-static const nsCSSProperty gPaddingStartSubpropTable[] = {
-  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
-  eCSSProperty_padding_start_value,
-  eCSSProperty_padding_left_ltr_source,
-  eCSSProperty_padding_right_rtl_source,
-  eCSSProperty_UNKNOWN
-};
-
-static const nsCSSProperty gPaddingEndSubpropTable[] = {
-  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
-  eCSSProperty_padding_end_value,
-  eCSSProperty_padding_right_ltr_source,
-  eCSSProperty_padding_left_rtl_source,
+  eCSSProperty_padding_left,
   eCSSProperty_UNKNOWN
 };
 
 static const nsCSSProperty gTextDecorationSubpropTable[] = {
   eCSSProperty_text_decoration_color,
   eCSSProperty_text_decoration_line,
   eCSSProperty_text_decoration_style,
   eCSSProperty_UNKNOWN
--- a/layout/style/nsRuleData.h
+++ b/layout/style/nsRuleData.h
@@ -72,17 +72,17 @@ struct nsRuleData
     size_t indexInStruct = nsCSSProps::PropertyIndexInStruct(aProperty);
 
     // This should really be nsCachedStyleData::GetBitForSID, but we can't
     // include that here since it includes us.
     NS_ABORT_IF_FALSE(mSIDs & (1 << sid),
                       "calling nsRuleData::ValueFor on property not in mSIDs");
     NS_ABORT_IF_FALSE(sid != eStyleStruct_BackendOnly &&
                       indexInStruct != size_t(-1),
-                      "backend-only property");
+                      "backend-only or logical property");
 
     return mValueStorage + mValueOffsets[sid] + indexInStruct;
   }
 
   const nsCSSValue* ValueFor(nsCSSProperty aProperty) const {
     return const_cast<nsRuleData*>(this)->ValueFor(aProperty);
   }
 
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -7008,38 +7008,23 @@ nsRuleNode::ComputePaddingData(void* aSt
                                const nsRuleData* aRuleData,
                                nsStyleContext* aContext,
                                nsRuleNode* aHighestNode,
                                const RuleDetail aRuleDetail,
                                const bool aCanStoreInRuleTree)
 {
   COMPUTE_START_RESET(Padding, (), padding, parentPadding)
 
-  // padding: length, percent, inherit
-  nsStyleCoord  coord;
-  nsCSSRect ourPadding;
-  ourPadding.mTop = *aRuleData->ValueForPaddingTop();
-  ourPadding.mRight = *aRuleData->ValueForPaddingRightValue();
-  ourPadding.mBottom = *aRuleData->ValueForPaddingBottom();
-  ourPadding.mLeft = *aRuleData->ValueForPaddingLeftValue();
-  AdjustLogicalBoxProp(aContext,
-                       *aRuleData->ValueForPaddingLeftLTRSource(),
-                       *aRuleData->ValueForPaddingLeftRTLSource(),
-                       *aRuleData->ValueForPaddingStartValue(),
-                       *aRuleData->ValueForPaddingEndValue(),
-                       NS_SIDE_LEFT, ourPadding, canStoreInRuleTree);
-  AdjustLogicalBoxProp(aContext,
-                       *aRuleData->ValueForPaddingRightLTRSource(),
-                       *aRuleData->ValueForPaddingRightRTLSource(),
-                       *aRuleData->ValueForPaddingEndValue(),
-                       *aRuleData->ValueForPaddingStartValue(),
-                       NS_SIDE_RIGHT, ourPadding, canStoreInRuleTree);
+  // padding: length, percent, calc, inherit
+  const nsCSSProperty* subprops =
+    nsCSSProps::SubpropertyEntryFor(eCSSProperty_padding);
+  nsStyleCoord coord;
   NS_FOR_CSS_SIDES(side) {
     nsStyleCoord parentCoord = parentPadding->mPadding.Get(side);
-    if (SetCoord(ourPadding.*(nsCSSRect::sides[side]),
+    if (SetCoord(*aRuleData->ValueFor(subprops[side]),
                  coord, parentCoord,
                  SETCOORD_LPH | SETCOORD_INITIAL_ZERO | SETCOORD_STORE_CALC |
                    SETCOORD_UNSET_INITIAL,
                  aContext, mPresContext, canStoreInRuleTree)) {
       padding->mPadding.Set(side, coord);
     }
   }
 
@@ -9507,21 +9492,19 @@ nsRuleNode::HasAuthorSpecifiedRules(nsSt
     eCSSProperty_border_top_left_radius,
     eCSSProperty_border_top_right_radius,
     eCSSProperty_border_bottom_right_radius,
     eCSSProperty_border_bottom_left_radius,
   };
 
   static const nsCSSProperty paddingValues[] = {
     eCSSProperty_padding_top,
-    eCSSProperty_padding_right_value,
+    eCSSProperty_padding_right,
     eCSSProperty_padding_bottom,
-    eCSSProperty_padding_left_value,
-    eCSSProperty_padding_start_value,
-    eCSSProperty_padding_end_value,
+    eCSSProperty_padding_left,
   };
 
   static const nsCSSProperty textShadowValues[] = {
     eCSSProperty_text_shadow
   };
 
   // Number of properties we care about
   size_t nValues = 0;
--- a/layout/style/test/ListCSSProperties.cpp
+++ b/layout/style/test/ListCSSProperties.cpp
@@ -135,24 +135,16 @@ const char *gInaccessibleProperties[] = 
     "margin-end-value",
     "margin-left-value",
     "margin-right-value",
     "margin-start-value",
     "margin-left-ltr-source",
     "margin-left-rtl-source",
     "margin-right-ltr-source",
     "margin-right-rtl-source",
-    "padding-end-value",
-    "padding-left-value",
-    "padding-right-value",
-    "padding-start-value",
-    "padding-left-ltr-source",
-    "padding-left-rtl-source",
-    "padding-right-ltr-source",
-    "padding-right-rtl-source",
     "-moz-control-character-visibility",
     "-moz-script-level", // parsed by UA sheets only
     "-moz-script-size-multiplier",
     "-moz-script-min-size",
     "-moz-math-variant",
     "-moz-math-display" // parsed by UA sheets only
 };
 
--- a/layout/style/test/css_properties_like_longhand.js
+++ b/layout/style/test/css_properties_like_longhand.js
@@ -1,11 +1,7 @@
 var gShorthandPropertiesLikeLonghand = [
 	{ name: "-moz-margin-end", prop: "MozMarginEnd"},
 	{ name: "margin-left", prop: "marginLeft"},
 	{ name: "margin-right", prop: "marginRight"},
 	{ name: "-moz-margin-start", prop: "MozMarginStart"},
 	{ name: "overflow", prop: "overflow"},
-	{ name: "-moz-padding-end", prop: "MozPaddingEnd"},
-	{ name: "padding-left", prop: "paddingLeft"},
-	{ name: "padding-right", prop: "paddingRight"},
-	{ name: "-moz-padding-start", prop: "MozPaddingStart"},
 ];
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -1561,33 +1561,35 @@ var gCSSProperties = {
       "calc(25px*3)",
       "calc(3*25px + 50%)",
             ],
     invalid_values: [ "-1px", "4px -2px", "inherit 2px", "2px inherit", "2", "2px 2", "2 2px" ]
   },
   "-moz-padding-end": {
     domProp: "MozPaddingEnd",
     inherited: false,
-    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
+    type: CSS_TYPE_LONGHAND,
+    logical: true,
     get_computed: logical_box_prop_get_computed,
     /* no subproperties */
     initial_values: [ "0", "0px", "0%", "0em", "0ex", "calc(0pt)", "calc(0% + 0px)", "calc(-3px)", "calc(-1%)" ],
     other_values: [ "1px", "3em",
       "calc(2px)",
       "calc(50%)",
       "calc(3*25px)",
       "calc(25px*3)",
       "calc(3*25px + 50%)",
     ],
     invalid_values: [ "5" ]
   },
   "-moz-padding-start": {
     domProp: "MozPaddingStart",
     inherited: false,
-    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
+    type: CSS_TYPE_LONGHAND,
+    logical: true,
     get_computed: logical_box_prop_get_computed,
     /* no subproperties */
     initial_values: [ "0", "0px", "0%", "0em", "0ex", "calc(0pt)", "calc(0% + 0px)", "calc(-3px)", "calc(-1%)" ],
     other_values: [ "1px", "3em",
       "calc(2px)",
       "calc(50%)",
       "calc(3*25px)",
       "calc(25px*3)",
@@ -3117,34 +3119,32 @@ var gCSSProperties = {
       "calc(3*25px + 50%)",
     ],
     invalid_values: [ ],
     quirks_values: { "5": "5px" },
   },
   "padding-left": {
     domProp: "paddingLeft",
     inherited: false,
-    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
-    /* no subproperties */
+    type: CSS_TYPE_LONGHAND,
     initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)", "calc(-3px)", "calc(-1%)" ],
     other_values: [ "1px", "2em", "5%",
       "calc(2px)",
       "calc(50%)",
       "calc(3*25px)",
       "calc(25px*3)",
       "calc(3*25px + 50%)",
     ],
     invalid_values: [ ],
     quirks_values: { "5": "5px" },
   },
   "padding-right": {
     domProp: "paddingRight",
     inherited: false,
-    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
-    /* no subproperties */
+    type: CSS_TYPE_LONGHAND,
     initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)", "calc(-3px)", "calc(-1%)" ],
     other_values: [ "1px", "2em", "5%",
       "calc(2px)",
       "calc(50%)",
       "calc(3*25px)",
       "calc(25px*3)",
       "calc(3*25px + 50%)",
     ],
@@ -4515,23 +4515,37 @@ var gCSSProperties = {
     initial_values: [ "normal" ],
     other_values: [ "'ENG'", "'TRK'", "\"TRK\"", "'N\\'Ko'" ],
     invalid_values: [ "TRK", "ja" ]
   }
 }
 
 function logical_box_prop_get_computed(cs, property)
 {
-  if (! /^-moz-/.test(property))
+  var ltr = cs.getPropertyValue("direction") == "ltr";
+  if (/^-moz-/.test(property)) {
+    property = property.substring(5);
+    if (ltr) {
+      property = property.replace("-start", "-left")
+                         .replace("-end", "-right");
+    } else {
+      property = property.replace("-start", "-right")
+                         .replace("-end", "-left");
+    }
+  } else if (/-inline-(start|end)/.test(property)) {
+    if (ltr) {
+      property = property.replace("-inline-start", "-left")
+                         .replace("-inline-end", "-right");
+    } else {
+      property = property.replace("-inline-start", "-right")
+                         .replace("-inline-end", "-left");
+    }
+  } else {
     throw "Unexpected property";
-  property = property.substring(5);
-  if (cs.getPropertyValue("direction") == "ltr")
-    property = property.replace("-start", "-left").replace("-end", "-right");
-  else
-    property = property.replace("-start", "-right").replace("-end", "-left");
+  }
   return cs.getPropertyValue(property);
 }
 
 // Get the computed value for a property.  For shorthands, return the
 // computed values of all the subproperties, delimited by " ; ".
 function get_computed_value(cs, property)
 {
   var info = gCSSProperties[property];
@@ -4592,17 +4606,49 @@ if (SpecialPowers.getBoolPref("layout.cs
       domProp: "textCombineUpright",
       inherited: true,
       type: CSS_TYPE_LONGHAND,
       initial_values: [ "none" ],
       other_values: [ "all", "digits", "digits 2", "digits 3", "digits 4", "digits     3" ],
       invalid_values: [ "auto", "all 2", "none all", "digits -3", "digits 0",
                         "digits 12", "none 3", "digits 3.1415", "digits3", "digits 1",
                         "digits 3 all", "digits foo", "digits all", "digits 3.0" ]
-    }
+    },
+    "padding-inline-end": {
+      domProp: "paddingInlineEnd",
+      inherited: false,
+      type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
+      alias_for: "-moz-padding-end",
+      get_computed: logical_box_prop_get_computed,
+      initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)", "calc(-3px)", "calc(-1%)" ],
+      other_values: [ "1px", "2em", "5%",
+        "calc(2px)",
+        "calc(50%)",
+        "calc(3*25px)",
+        "calc(25px*3)",
+        "calc(3*25px + 50%)",
+      ],
+      invalid_values: [ ],
+    },
+    "padding-inline-start": {
+      domProp: "paddingInlineStart",
+      inherited: false,
+      type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
+      alias_for: "-moz-padding-start",
+      get_computed: logical_box_prop_get_computed,
+      initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)", "calc(-3px)", "calc(-1%)" ],
+      other_values: [ "1px", "2em", "5%",
+        "calc(2px)",
+        "calc(50%)",
+        "calc(3*25px)",
+        "calc(25px*3)",
+        "calc(3*25px + 50%)",
+      ],
+      invalid_values: [ ],
+    },
   };
   for (var prop in verticalTextProperties) {
     gCSSProperties[prop] = verticalTextProperties[prop];
   }
 }
 
 if (SpecialPowers.getBoolPref("layout.css.masking.enabled")) {
   gCSSProperties["mask-type"] = {
--- a/layout/style/test/test_value_computation.html
+++ b/layout/style/test/test_value_computation.html
@@ -70,16 +70,18 @@ var gBadComputedNoFrame = {
   "margin-bottom": [ "0%", "calc(0% + 0px)" ],
   "margin-left": [ "0%", "calc(0% + 0px)" ],
   "margin-right": [ "0%", "calc(0% + 0px)" ],
   "margin-top": [ "0%", "calc(0% + 0px)" ],
   "min-height": [ "calc(-1%)" ],
   "min-width": [ "calc(-1%)" ],
   "padding": [ "0% 0px 0em 0pt", "calc(0px) calc(0em) calc(-2px) calc(-1%)" ],
   "padding-bottom": [ "0%", "calc(0% + 0px)", "calc(-1%)" ],
+  "padding-inline-end": [ "0%", "calc(0% + 0px)", "calc(-1%)" ],
+  "padding-inline-start": [ "0%", "calc(0% + 0px)", "calc(-1%)" ],
   "padding-left": [ "0%", "calc(0% + 0px)", "calc(-1%)" ],
   "padding-right": [ "0%", "calc(0% + 0px)", "calc(-1%)" ],
   "padding-top": [ "0%", "calc(0% + 0px)", "calc(-1%)" ],
 };
 
 function xfail_value(property, value, is_initial, has_frame) {
   if ((property in gBadComputed) &&
       gBadComputed[property].indexOf(value) != -1)