Back out 9 changesets (bug 649142)
authorPhil Ringnalda <philringnalda@gmail.com>
Tue, 30 Dec 2014 20:04:20 -0800
changeset 247540 e7c43c3f839829d88d65bd7ad3d684c1c7b1fd40
parent 247539 a95386a2c7ea27699deb435a8907aa8010ec5502
child 247541 a58f4fffeed222e5b807bc8dc7e2129b5b95e53c
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs649142
milestone37.0a1
backs out936703c75200e3c36d86b2245fcb81f5c6734814
b0252d2620d804b2086ac1f9b6e9d5f8212d68a1
69ddb2036c50412b3c3f39a578a3ccbc877e53fa
67748675e6695bdd028aa3bcdbde92bc664fef2b
15ed55c61f4e4efb1c9a224f7ee7c101e4766fd1
35c42cd138e1d0af99d87687bf3bf0f8cc364b80
1335630cf287c48e2e1508332b0d459881320537
b5725cd39a3152c75d1a84ccb88a9767a337e356
b0eb691d6695b03ff6f8572a748370c6203384ec
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
Back out 9 changesets (bug 649142) Backed out changeset 936703c75200 (bug 649142) Backed out changeset b0252d2620d8 (bug 649142) Backed out changeset 69ddb2036c50 (bug 649142) Backed out changeset 67748675e669 (bug 649142) Backed out changeset 15ed55c61f4e (bug 649142) Backed out changeset 35c42cd138e1 (bug 649142) Backed out changeset 1335630cf287 (bug 649142) Backed out changeset b5725cd39a31 (bug 649142) Backed out changeset b0eb691d6695 (bug 649142)
browser/devtools/layoutview/view.js
dom/base/nsDOMWindowUtils.cpp
dom/html/HTMLBodyElement.cpp
dom/html/HTMLHRElement.cpp
dom/html/HTMLIFrameElement.cpp
dom/html/HTMLTableElement.cpp
dom/html/nsGenericHTMLElement.cpp
dom/webidl/CSS2PropertiesProps.h
layout/inspector/inDOMUtils.cpp
layout/inspector/tests/test_bug1006595.html
layout/style/Declaration.cpp
layout/style/StyleAnimationValue.cpp
layout/style/nsCSSDataBlock.cpp
layout/style/nsCSSParser.cpp
layout/style/nsCSSPropAliasList.h
layout/style/nsCSSPropList.h
layout/style/nsCSSProperty.h
layout/style/nsCSSProps.cpp
layout/style/nsCSSProps.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsDOMCSSDeclaration.h
layout/style/nsRuleData.h
layout/style/nsRuleNode.cpp
layout/style/nsRuleNode.h
layout/style/nsStyleConsts.h
layout/style/nsStyleContext.cpp
layout/style/nsTransitionManager.cpp
layout/style/test/ListCSSProperties.cpp
layout/style/test/css_properties_like_longhand.js
layout/style/test/mochitest.ini
layout/style/test/property_database.js
layout/style/test/test_logical_properties.html
layout/style/test/test_page_parser.html
layout/style/test/test_property_database.html
layout/style/test/test_value_computation.html
--- a/browser/devtools/layoutview/view.js
+++ b/browser/devtools/layoutview/view.js
@@ -169,33 +169,43 @@ LayoutView.prototype = {
                  property: "position",
                  value: undefined},
       marginTop: {selector: ".margin.top > span",
                   property: "margin-top",
                   value: undefined},
       marginBottom: {selector: ".margin.bottom > span",
                   property: "margin-bottom",
                   value: undefined},
+      // margin-left is a shorthand for some internal properties,
+      // margin-left-ltr-source and margin-left-rtl-source for example. The
+      // real margin value we want is in margin-left-value
       marginLeft: {selector: ".margin.left > span",
                   property: "margin-left",
+                  realProperty: "margin-left-value",
                   value: undefined},
+      // margin-right behaves the same as margin-left
       marginRight: {selector: ".margin.right > span",
                   property: "margin-right",
+                  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",
@@ -250,19 +260,21 @@ LayoutView.prototype = {
     this.reflowFront.off("reflows", this.update);
     this.reflowFront.stop();
   },
 
   /**
    * Called when the user clicks on one of the editable values in the layoutview
    */
   initEditor: function(element, event, dimension) {
-    let { property } = dimension;
+    let { property, realProperty } = dimension;
+    if (!realProperty)
+      realProperty = property;
     let session = new EditingSession(document, this.elementRules);
-    let initialValue = session.getProperty(property);
+    let initialValue = session.getProperty(realProperty);
 
     let editor = new InplaceEditor({
       element: element,
       initial: initialValue,
 
       start: (editor) => {
         editor.elt.parentNode.classList.add("editing");
       },
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2749,20 +2749,28 @@ nsDOMWindowUtils::ComputeAnimationDistan
                                            double* aResult)
 {
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
   nsresult rv;
   nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  // Convert direction-dependent properties as appropriate, e.g.,
+  // border-left to border-left-value.
   nsCSSProperty property =
     nsCSSProps::LookupProperty(aProperty, nsCSSProps::eIgnoreEnabledState);
   if (property != eCSSProperty_UNKNOWN && nsCSSProps::IsShorthand(property)) {
-    property = eCSSProperty_UNKNOWN;
+    nsCSSProperty subprop0 = *nsCSSProps::SubpropertyEntryFor(property);
+    if (nsCSSProps::PropHasFlags(subprop0, CSS_PROPERTY_REPORT_OTHER_NAME) &&
+        nsCSSProps::OtherNameFor(subprop0) == property) {
+      property = subprop0;
+    } else {
+      property = eCSSProperty_UNKNOWN;
+    }
   }
 
   NS_ABORT_IF_FALSE(property == eCSSProperty_UNKNOWN ||
                     !nsCSSProps::IsShorthand(property),
                     "should not have shorthand");
 
   StyleAnimationValue v1, v2;
   if (property == eCSSProperty_UNKNOWN ||
--- a/dom/html/HTMLBodyElement.cpp
+++ b/dom/html/HTMLBodyElement.cpp
@@ -57,20 +57,20 @@ BodyRule::MapRuleInfoInto(nsRuleData* aD
 
   const nsAttrValue* value;
   if (mPart->GetAttrCount() > 0) {
     // if marginwidth/marginheight are set, reflect them as 'margin'
     value = mPart->GetParsedAttr(nsGkAtoms::marginwidth);
     if (value && value->Type() == nsAttrValue::eInteger) {
       bodyMarginWidth = value->GetIntegerValue();
       if (bodyMarginWidth < 0) bodyMarginWidth = 0;
-      nsCSSValue* marginLeft = aData->ValueForMarginLeft();
+      nsCSSValue* marginLeft = aData->ValueForMarginLeftValue();
       if (marginLeft->GetUnit() == eCSSUnit_Null)
         marginLeft->SetFloatValue((float)bodyMarginWidth, eCSSUnit_Pixel);
-      nsCSSValue* marginRight = aData->ValueForMarginRight();
+      nsCSSValue* marginRight = aData->ValueForMarginRightValue();
       if (marginRight->GetUnit() == eCSSUnit_Null)
         marginRight->SetFloatValue((float)bodyMarginWidth, eCSSUnit_Pixel);
     }
 
     value = mPart->GetParsedAttr(nsGkAtoms::marginheight);
     if (value && value->Type() == nsAttrValue::eInteger) {
       bodyMarginHeight = value->GetIntegerValue();
       if (bodyMarginHeight < 0) bodyMarginHeight = 0;
@@ -102,27 +102,27 @@ BodyRule::MapRuleInfoInto(nsRuleData* aD
         marginBottom->SetFloatValue((float)bodyBottomMargin, eCSSUnit_Pixel);
     }
 
       // leftmargin (IE-attribute)
     value = mPart->GetParsedAttr(nsGkAtoms::leftmargin);
     if (value && value->Type() == nsAttrValue::eInteger) {
       bodyLeftMargin = value->GetIntegerValue();
       if (bodyLeftMargin < 0) bodyLeftMargin = 0;
-      nsCSSValue* marginLeft = aData->ValueForMarginLeft();
+      nsCSSValue* marginLeft = aData->ValueForMarginLeftValue();
       if (marginLeft->GetUnit() == eCSSUnit_Null)
         marginLeft->SetFloatValue((float)bodyLeftMargin, eCSSUnit_Pixel);
     }
 
       // rightmargin (IE-attribute)
     value = mPart->GetParsedAttr(nsGkAtoms::rightmargin);
     if (value && value->Type() == nsAttrValue::eInteger) {
       bodyRightMargin = value->GetIntegerValue();
       if (bodyRightMargin < 0) bodyRightMargin = 0;
-      nsCSSValue* marginRight = aData->ValueForMarginRight();
+      nsCSSValue* marginRight = aData->ValueForMarginRightValue();
       if (marginRight->GetUnit() == eCSSUnit_Null)
         marginRight->SetFloatValue((float)bodyRightMargin, eCSSUnit_Pixel);
     }
 
   }
 
   // if marginwidth or marginheight is set in the <frame> and not set in the <body>
   // reflect them as margin in the <body>
@@ -142,20 +142,20 @@ BodyRule::MapRuleInfoInto(nsRuleData* aD
       if ((frameMarginHeight >= 0) && (bodyMarginHeight == -1)) { // set in <frame> & not in <body>
         if (eCompatibility_NavQuirks == mode) {
           if ((bodyMarginWidth == -1) && (0 > frameMarginWidth)) // nav quirk
             frameMarginWidth = 0;
         }
       }
 
       if ((bodyMarginWidth == -1) && (frameMarginWidth >= 0)) {
-        nsCSSValue* marginLeft = aData->ValueForMarginLeft();
+        nsCSSValue* marginLeft = aData->ValueForMarginLeftValue();
         if (marginLeft->GetUnit() == eCSSUnit_Null)
           marginLeft->SetFloatValue((float)frameMarginWidth, eCSSUnit_Pixel);
-        nsCSSValue* marginRight = aData->ValueForMarginRight();
+        nsCSSValue* marginRight = aData->ValueForMarginRightValue();
         if (marginRight->GetUnit() == eCSSUnit_Null)
           marginRight->SetFloatValue((float)frameMarginWidth, eCSSUnit_Pixel);
       }
 
       if ((bodyMarginHeight == -1) && (frameMarginHeight >= 0)) {
         nsCSSValue* marginTop = aData->ValueForMarginTop();
         if (marginTop->GetUnit() == eCSSUnit_Null)
           marginTop->SetFloatValue((float)frameMarginHeight, eCSSUnit_Pixel);
--- a/dom/html/HTMLHRElement.cpp
+++ b/dom/html/HTMLHRElement.cpp
@@ -83,18 +83,18 @@ HTMLHRElement::MapAttributesIntoRule(con
     }
   }
 
   if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Margin)) {
     // align: enum
     const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);
     if (value && value->Type() == nsAttrValue::eEnum) {
       // Map align attribute into auto side margins
-      nsCSSValue* marginLeft = aData->ValueForMarginLeft();
-      nsCSSValue* marginRight = aData->ValueForMarginRight();
+      nsCSSValue* marginLeft = aData->ValueForMarginLeftValue();
+      nsCSSValue* marginRight = aData->ValueForMarginRightValue();
       switch (value->GetEnumValue()) {
       case NS_STYLE_TEXT_ALIGN_LEFT:
         if (marginLeft->GetUnit() == eCSSUnit_Null)
           marginLeft->SetFloatValue(0.0f, eCSSUnit_Pixel);
         if (marginRight->GetUnit() == eCSSUnit_Null)
           marginRight->SetAutoValue();
         break;
       case NS_STYLE_TEXT_ALIGN_RIGHT:
@@ -160,47 +160,47 @@ HTMLHRElement::MapAttributesIntoRule(con
     } else {
       sizePerSide = 1.0f; // default to a 2px high line
     }
     nsCSSValue* borderTopWidth = aData->ValueForBorderTopWidth();
     if (borderTopWidth->GetUnit() == eCSSUnit_Null) {
       borderTopWidth->SetFloatValue(sizePerSide, eCSSUnit_Pixel);
     }
     if (allSides) {
-      nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidth();
+      nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidthValue();
       if (borderRightWidth->GetUnit() == eCSSUnit_Null) {
         borderRightWidth->SetFloatValue(sizePerSide, eCSSUnit_Pixel);
       }
       nsCSSValue* borderBottomWidth = aData->ValueForBorderBottomWidth();
       if (borderBottomWidth->GetUnit() == eCSSUnit_Null) {
         borderBottomWidth->SetFloatValue(sizePerSide, eCSSUnit_Pixel);
       }
-      nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidth();
+      nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidthValue();
       if (borderLeftWidth->GetUnit() == eCSSUnit_Null) {
         borderLeftWidth->SetFloatValue(sizePerSide, eCSSUnit_Pixel);
       }
     }
 
     nsCSSValue* borderTopStyle = aData->ValueForBorderTopStyle();
     if (borderTopStyle->GetUnit() == eCSSUnit_Null) {
       borderTopStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID,
                                   eCSSUnit_Enumerated);
     }
     if (allSides) {
-      nsCSSValue* borderRightStyle = aData->ValueForBorderRightStyle();
+      nsCSSValue* borderRightStyle = aData->ValueForBorderRightStyleValue();
       if (borderRightStyle->GetUnit() == eCSSUnit_Null) {
         borderRightStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID,
                                       eCSSUnit_Enumerated);
       }
       nsCSSValue* borderBottomStyle = aData->ValueForBorderBottomStyle();
       if (borderBottomStyle->GetUnit() == eCSSUnit_Null) {
         borderBottomStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID,
                                        eCSSUnit_Enumerated);
       }
-      nsCSSValue* borderLeftStyle = aData->ValueForBorderLeftStyle();
+      nsCSSValue* borderLeftStyle = aData->ValueForBorderLeftStyleValue();
       if (borderLeftStyle->GetUnit() == eCSSUnit_Null) {
         borderLeftStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID,
                                      eCSSUnit_Enumerated);
       }
 
       // If it would be noticeable, set the border radius to
       // 10000px on all corners; this triggers the clamping to make
       // circular ends.  This assumes the <hr> isn't larger than
--- a/dom/html/HTMLIFrameElement.cpp
+++ b/dom/html/HTMLIFrameElement.cpp
@@ -116,20 +116,20 @@ HTMLIFrameElement::MapAttributesIntoRule
     // If frameborder is 0 or No, set border to 0
     // else leave it as the value set in html.css
     const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::frameborder);
     if (value && value->Type() == nsAttrValue::eEnum) {
       int32_t frameborder = value->GetEnumValue();
       if (NS_STYLE_FRAME_0 == frameborder ||
           NS_STYLE_FRAME_NO == frameborder ||
           NS_STYLE_FRAME_OFF == frameborder) {
-        nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidth();
+        nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidthValue();
         if (borderLeftWidth->GetUnit() == eCSSUnit_Null)
           borderLeftWidth->SetFloatValue(0.0f, eCSSUnit_Pixel);
-        nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidth();
+        nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidthValue();
         if (borderRightWidth->GetUnit() == eCSSUnit_Null)
           borderRightWidth->SetFloatValue(0.0f, eCSSUnit_Pixel);
         nsCSSValue* borderTopWidth = aData->ValueForBorderTopWidth();
         if (borderTopWidth->GetUnit() == eCSSUnit_Null)
           borderTopWidth->SetFloatValue(0.0f, eCSSUnit_Pixel);
         nsCSSValue* borderBottomWidth = aData->ValueForBorderBottomWidth();
         if (borderBottomWidth->GetUnit() == eCSSUnit_Null)
           borderBottomWidth->SetFloatValue(0.0f, eCSSUnit_Pixel);
--- a/dom/html/HTMLTableElement.cpp
+++ b/dom/html/HTMLTableElement.cpp
@@ -700,36 +700,36 @@ HTMLTableElement::MapAttributesIntoRule(
   if (aData->mSIDs & 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();
+        nsCSSValue* marginLeft = aData->ValueForMarginLeftValue();
         if (marginLeft->GetUnit() == eCSSUnit_Null)
           marginLeft->SetAutoValue();
-        nsCSSValue* marginRight = aData->ValueForMarginRight();
+        nsCSSValue* marginRight = aData->ValueForMarginRightValue();
         if (marginRight->GetUnit() == eCSSUnit_Null)
           marginRight->SetAutoValue();
       }
     }
 
     // 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();
+        nsCSSValue* marginLeft = aData->ValueForMarginLeftValue();
         if (marginLeft->GetUnit() == eCSSUnit_Null)
           marginLeft->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel); 
-        nsCSSValue* marginRight = aData->ValueForMarginRight();
+        nsCSSValue* marginRight = aData->ValueForMarginRightValue();
         if (marginRight->GetUnit() == eCSSUnit_Null)
           marginRight->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
       }
 
       value = aAttributes->GetAttr(nsGkAtoms::vspace);
 
       if (value && value->Type() == nsAttrValue::eInteger) {
         nsCSSValue* marginTop = aData->ValueForMarginTop();
@@ -763,20 +763,20 @@ HTMLTableElement::MapAttributesIntoRule(
     }
   }
   if (aData->mSIDs & 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();
+      nsCSSValue* borderLeftColor = aData->ValueForBorderLeftColorValue();
       if (borderLeftColor->GetUnit() == eCSSUnit_Null)
         borderLeftColor->SetColorValue(color);
-      nsCSSValue* borderRightColor = aData->ValueForBorderRightColor();
+      nsCSSValue* borderRightColor = aData->ValueForBorderRightColorValue();
       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);
@@ -787,20 +787,20 @@ HTMLTableElement::MapAttributesIntoRule(
     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();
+      nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidthValue();
       if (borderLeftWidth->GetUnit() == eCSSUnit_Null)
         borderLeftWidth->SetFloatValue((float)borderThickness, eCSSUnit_Pixel);
-      nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidth();
+      nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidthValue();
       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);
@@ -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->ValueForPaddingLeft();
+      nsCSSValue* paddingLeft = aData->ValueForPaddingLeftValue();
       if (paddingLeft->GetUnit() == eCSSUnit_Null) {
         *paddingLeft = padVal;
       }
 
-      nsCSSValue* paddingRight = aData->ValueForPaddingRight();
+      nsCSSValue* paddingRight = aData->ValueForPaddingRightValue();
       if (paddingRight->GetUnit() == eCSSUnit_Null) {
         *paddingRight = padVal;
       }
 
       nsCSSValue* paddingTop = aData->ValueForPaddingTop();
       if (paddingTop->GetUnit() == eCSSUnit_Null) {
         *paddingTop = padVal;
       }
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -1439,20 +1439,20 @@ nsGenericHTMLElement::MapImageMarginAttr
   if (value) {
     nsCSSValue hval;
     if (value->Type() == nsAttrValue::eInteger)
       hval.SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
     else if (value->Type() == nsAttrValue::ePercent)
       hval.SetPercentValue(value->GetPercentValue());
 
     if (hval.GetUnit() != eCSSUnit_Null) {
-      nsCSSValue* left = aData->ValueForMarginLeft();
+      nsCSSValue* left = aData->ValueForMarginLeftValue();
       if (left->GetUnit() == eCSSUnit_Null)
         *left = hval;
-      nsCSSValue* right = aData->ValueForMarginRight();
+      nsCSSValue* right = aData->ValueForMarginRightValue();
       if (right->GetUnit() == eCSSUnit_Null)
         *right = hval;
     }
   }
 
   // vspace: value
   value = aAttributes->GetAttr(nsGkAtoms::vspace);
   if (value) {
@@ -1512,49 +1512,49 @@ nsGenericHTMLElement::MapImageBorderAttr
   const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::border);
   if (!value)
     return;
   
   nscoord val = 0;
   if (value->Type() == nsAttrValue::eInteger)
     val = value->GetIntegerValue();
 
-  nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidth();
+  nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidthValue();
   if (borderLeftWidth->GetUnit() == eCSSUnit_Null)
     borderLeftWidth->SetFloatValue((float)val, eCSSUnit_Pixel);
   nsCSSValue* borderTopWidth = aData->ValueForBorderTopWidth();
   if (borderTopWidth->GetUnit() == eCSSUnit_Null)
     borderTopWidth->SetFloatValue((float)val, eCSSUnit_Pixel);
-  nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidth();
+  nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidthValue();
   if (borderRightWidth->GetUnit() == eCSSUnit_Null)
     borderRightWidth->SetFloatValue((float)val, eCSSUnit_Pixel);
   nsCSSValue* borderBottomWidth = aData->ValueForBorderBottomWidth();
   if (borderBottomWidth->GetUnit() == eCSSUnit_Null)
     borderBottomWidth->SetFloatValue((float)val, eCSSUnit_Pixel);
 
-  nsCSSValue* borderLeftStyle = aData->ValueForBorderLeftStyle();
+  nsCSSValue* borderLeftStyle = aData->ValueForBorderLeftStyleValue();
   if (borderLeftStyle->GetUnit() == eCSSUnit_Null)
     borderLeftStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID, eCSSUnit_Enumerated);
   nsCSSValue* borderTopStyle = aData->ValueForBorderTopStyle();
   if (borderTopStyle->GetUnit() == eCSSUnit_Null)
     borderTopStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID, eCSSUnit_Enumerated);
-  nsCSSValue* borderRightStyle = aData->ValueForBorderRightStyle();
+  nsCSSValue* borderRightStyle = aData->ValueForBorderRightStyleValue();
   if (borderRightStyle->GetUnit() == eCSSUnit_Null)
     borderRightStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID, eCSSUnit_Enumerated);
   nsCSSValue* borderBottomStyle = aData->ValueForBorderBottomStyle();
   if (borderBottomStyle->GetUnit() == eCSSUnit_Null)
     borderBottomStyle->SetIntValue(NS_STYLE_BORDER_STYLE_SOLID, eCSSUnit_Enumerated);
 
-  nsCSSValue* borderLeftColor = aData->ValueForBorderLeftColor();
+  nsCSSValue* borderLeftColor = aData->ValueForBorderLeftColorValue();
   if (borderLeftColor->GetUnit() == eCSSUnit_Null)
     borderLeftColor->SetIntValue(NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR, eCSSUnit_Enumerated);
   nsCSSValue* borderTopColor = aData->ValueForBorderTopColor();
   if (borderTopColor->GetUnit() == eCSSUnit_Null)
     borderTopColor->SetIntValue(NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR, eCSSUnit_Enumerated);
-  nsCSSValue* borderRightColor = aData->ValueForBorderRightColor();
+  nsCSSValue* borderRightColor = aData->ValueForBorderRightColorValue();
   if (borderRightColor->GetUnit() == eCSSUnit_Null)
     borderRightColor->SetIntValue(NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR, eCSSUnit_Enumerated);
   nsCSSValue* borderBottomColor = aData->ValueForBorderBottomColor();
   if (borderBottomColor->GetUnit() == eCSSUnit_Null)
     borderBottomColor->SetIntValue(NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR, eCSSUnit_Enumerated);
 }
 
 void
--- a/dom/webidl/CSS2PropertiesProps.h
+++ b/dom/webidl/CSS2PropertiesProps.h
@@ -12,21 +12,19 @@
   [ #name, #method, #id, PROP_STRINGIFY(flags), pref ],
 #define CSS_PROP(name, id, method, flags, pref, parsevariant, kwtable, \
 		 stylestruct, stylestructofset, animtype) \
   DO_PROP(name, method, id, flags, pref)
 #define CSS_PROP_SHORTHAND(name, id, method, flags, pref) \
   DO_PROP(name, method, id, flags, pref)
 #define CSS_PROP_PUBLIC_OR_PRIVATE(publicname_, privatename_) publicname_
 #define CSS_PROP_LIST_EXCLUDE_INTERNAL
-#define CSS_PROP_LIST_INCLUDE_LOGICAL
 
 #include "nsCSSPropList.h"
 
-#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP_LIST_EXCLUDE_INTERNAL
 #undef CSS_PROP_PUBLIC_OR_PRIVATE
 #undef CSS_PROP_SHORTHAND
 #undef CSS_PROP
 
 #define CSS_PROP_ALIAS(name, id, method, pref) \
   DO_PROP(name, method, id, 0, pref)
 
--- a/layout/inspector/inDOMUtils.cpp
+++ b/layout/inspector/inDOMUtils.cpp
@@ -517,17 +517,17 @@ static void GetKeywordsForProperty(const
                                    nsTArray<nsString>& aArray)
 {
   if (nsCSSProps::IsShorthand(aProperty)) {
     // Shorthand props have no keywords.
     return;
   }
   const nsCSSProps::KTableValue *keywordTable =
     nsCSSProps::kKeywordTableTable[aProperty];
-  if (keywordTable) {
+  if (keywordTable && keywordTable != nsCSSProps::kBoxPropSourceKTable) {
     size_t i = 0;
     while (nsCSSKeyword(keywordTable[i]) != eCSSKeyword_UNKNOWN) {
       nsCSSKeyword word = nsCSSKeyword(keywordTable[i]);
       InsertNoDuplicates(aArray,
                          NS_ConvertASCIItoUTF16(nsCSSKeywords::GetStringValue(word)));
       // Increment counter by 2, because in this table every second
       // element is a nsCSSKeyword.
       i += 2;
--- a/layout/inspector/tests/test_bug1006595.html
+++ b/layout/inspector/tests/test_bug1006595.html
@@ -18,19 +18,21 @@ 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",
+                "padding-right-value",
                 "padding-bottom",
-                "padding-left" ],
+                "padding-left-value",
+                "padding-left-ltr-source", "padding-left-rtl-source",
+                "padding-right-ltr-source", "padding-right-rtl-source" ],
               "'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
@@ -164,18 +164,19 @@ Declaration::GetValue(nsCSSProperty aPro
   // variable reference and none of its component longhand properties were
   // then overridden on the declaration, we return the token stream
   // assigned to the shorthand.
   const nsCSSValue* tokenStream = nullptr;
   uint32_t totalCount = 0, importantCount = 0,
            initialCount = 0, inheritCount = 0, unsetCount = 0,
            matchingTokenStreamCount = 0, nonMatchingTokenStreamCount = 0;
   CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aProperty) {
-    if (*p == eCSSProperty__x_system_font) {
-      // The system-font subproperty doesn't count.
+    if (*p == eCSSProperty__x_system_font ||
+         nsCSSProps::PropHasFlags(*p, CSS_PROPERTY_DIRECTIONAL_SOURCE)) {
+      // The system-font subproperty and the *-source properties don't count.
       continue;
     }
     ++totalCount;
     const nsCSSValue *val = mData->ValueFor(*p);
     NS_ABORT_IF_FALSE(!val || !mImportantData || !mImportantData->ValueFor(*p),
                       "can't be in both blocks");
     if (!val && mImportantData) {
       ++importantCount;
@@ -343,16 +344,18 @@ Declaration::GetValue(nsCSSProperty aPro
         nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_color),
         nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_style),
         nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_width)
       };
       bool match = true;
       for (const nsCSSProperty** subprops = subproptables,
                **subprops_end = ArrayEnd(subproptables);
            subprops < subprops_end; ++subprops) {
+        // Check only the first four subprops in each table, since the
+        // others are extras for dimensional box properties.
         const nsCSSValue *firstSide = data->ValueFor((*subprops)[0]);
         for (int32_t side = 1; side < 4; ++side) {
           const nsCSSValue *otherSide =
             data->ValueFor((*subprops)[side]);
           if (*firstSide != *otherSide)
             match = false;
         }
       }
@@ -369,33 +372,62 @@ Declaration::GetValue(nsCSSProperty aPro
     case eCSSProperty_border_left:
     case eCSSProperty_border_start:
     case eCSSProperty_border_end:
     case eCSSProperty__moz_column_rule:
     case eCSSProperty_outline: {
       const nsCSSProperty* subprops =
         nsCSSProps::SubpropertyEntryFor(aProperty);
       NS_ABORT_IF_FALSE(StringEndsWith(nsCSSProps::GetStringValue(subprops[2]),
-                                       NS_LITERAL_CSTRING("-color")),
+                                       NS_LITERAL_CSTRING("-color")) ||
+                        StringEndsWith(nsCSSProps::GetStringValue(subprops[2]),
+                                       NS_LITERAL_CSTRING("-color-value")),
                         "third subprop must be the color property");
       const nsCSSValue *colorValue = data->ValueFor(subprops[2]);
       bool isMozUseTextColor =
         colorValue->GetUnit() == eCSSUnit_Enumerated &&
         colorValue->GetIntValue() == NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR;
       if (!AppendValueToString(subprops[0], aValue, aSerialization) ||
           !(aValue.Append(char16_t(' ')),
             AppendValueToString(subprops[1], aValue, aSerialization)) ||
           // Don't output a third value when it's -moz-use-text-color.
           !(isMozUseTextColor ||
             (aValue.Append(char16_t(' ')),
              AppendValueToString(subprops[2], aValue, aSerialization)))) {
         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:
+    case eCSSProperty_border_start_width:
+    case eCSSProperty_border_end_color:
+    case eCSSProperty_border_end_style:
+    case eCSSProperty_border_end_width: {
+      const nsCSSProperty* subprops =
+        nsCSSProps::SubpropertyEntryFor(aProperty);
+      NS_ABORT_IF_FALSE(subprops[3] == eCSSProperty_UNKNOWN,
+                        "not box property with physical vs. logical cascading");
+      AppendValueToString(subprops[0], aValue, aSerialization);
+      break;
+    }
     case eCSSProperty_background: {
       // We know from above that all subproperties were specified.
       // However, we still can't represent that in the shorthand unless
       // they're all lists of the same length.  So if they're different
       // lengths, we need to bail out.
       // We also need to bail out if an item has background-clip and
       // background-origin that are different and not the default
       // values.  (We omit them if they're both default.)
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -2534,19 +2534,23 @@ StyleAnimationValue::ComputeValue(nsCSSP
                                   StyleAnimationValue& aComputedValue,
                                   bool* aIsContextSensitive)
 {
   NS_ABORT_IF_FALSE(aTargetElement, "null target element");
   NS_ABORT_IF_FALSE(aTargetElement->GetCurrentDoc(),
                     "we should only be able to actively animate nodes that "
                     "are in a document");
 
+  nsCSSProperty propToParse =
+    nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_REPORT_OTHER_NAME)
+      ? nsCSSProps::OtherNameFor(aProperty) : aProperty;
+
   // Parse specified value into a temporary css::StyleRule
   nsRefPtr<css::StyleRule> styleRule =
-    BuildStyleRule(aProperty, aTargetElement, aSpecifiedValue, aUseSVGMode);
+    BuildStyleRule(propToParse, aTargetElement, aSpecifiedValue, aUseSVGMode);
   if (!styleRule) {
     return false;
   }
 
   if (nsCSSProps::IsShorthand(aProperty) ||
       nsCSSProps::kAnimTypeTable[aProperty] == eStyleAnimType_None) {
     // Just capture the specified value
     aComputedValue.SetUnparsedStringValue(nsString(aSpecifiedValue));
@@ -2918,36 +2922,36 @@ StyleAnimationValue::ExtractComputedValu
 
         #define BORDER_WIDTH_CASE(prop_, side_)                               \
         case prop_:                                                           \
           aComputedValue.SetCoordValue(                                       \
             static_cast<const nsStyleBorder*>(styleStruct)->                  \
               GetComputedBorder().side_);                                     \
           break;
         BORDER_WIDTH_CASE(eCSSProperty_border_bottom_width, bottom)
-        BORDER_WIDTH_CASE(eCSSProperty_border_left_width, left)
-        BORDER_WIDTH_CASE(eCSSProperty_border_right_width, right)
+        BORDER_WIDTH_CASE(eCSSProperty_border_left_width_value, left)
+        BORDER_WIDTH_CASE(eCSSProperty_border_right_width_value, right)
         BORDER_WIDTH_CASE(eCSSProperty_border_top_width, top)
         #undef BORDER_WIDTH_CASE
 
         case eCSSProperty__moz_column_rule_width:
           aComputedValue.SetCoordValue(
             static_cast<const nsStyleColumn*>(styleStruct)->
               GetComputedColumnRuleWidth());
           break;
 
         case eCSSProperty_border_bottom_color:
           ExtractBorderColor(aStyleContext, styleStruct, NS_SIDE_BOTTOM,
                              aComputedValue);
           break;
-        case eCSSProperty_border_left_color:
+        case eCSSProperty_border_left_color_value:
           ExtractBorderColor(aStyleContext, styleStruct, NS_SIDE_LEFT,
                              aComputedValue);
           break;
-        case eCSSProperty_border_right_color:
+        case eCSSProperty_border_right_color_value:
           ExtractBorderColor(aStyleContext, styleStruct, NS_SIDE_RIGHT,
                              aComputedValue);
           break;
         case eCSSProperty_border_top_color:
           ExtractBorderColor(aStyleContext, styleStruct, NS_SIDE_TOP,
                              aComputedValue);
           break;
 
--- a/layout/style/nsCSSDataBlock.cpp
+++ b/layout/style/nsCSSDataBlock.cpp
@@ -158,95 +158,30 @@ MapSinglePropertyInto(nsCSSProperty aPro
             }
         } else {
             // Ignore 'color', 'border-*-color', etc.
             *aTarget = nsCSSValue();
         }
     }
 }
 
-/**
- * If aProperty is a logical property, converts it to the equivalent physical
- * property based on writing mode information obtained from aRuleData's
- * style context.  Returns true if aProperty was changed.
- */
-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_margin_end:
-      aProperty = ltr ? eCSSProperty_margin_right : eCSSProperty_margin_left;
-      break;
-    case eCSSProperty_margin_start:
-      aProperty = ltr ? eCSSProperty_margin_left : eCSSProperty_margin_right;
-      break;
-    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;
-    case eCSSProperty_border_end_color:
-      aProperty = ltr ? eCSSProperty_border_right_color :
-                        eCSSProperty_border_left_color;
-      break;
-    case eCSSProperty_border_end_style:
-      aProperty = ltr ? eCSSProperty_border_right_style :
-                        eCSSProperty_border_left_style;
-      break;
-    case eCSSProperty_border_end_width:
-      aProperty = ltr ? eCSSProperty_border_right_width :
-                        eCSSProperty_border_left_width;
-      break;
-    case eCSSProperty_border_start_color:
-      aProperty = ltr ? eCSSProperty_border_left_color :
-                        eCSSProperty_border_right_color;
-      break;
-    case eCSSProperty_border_start_style:
-      aProperty = ltr ? eCSSProperty_border_left_style :
-                        eCSSProperty_border_right_style;
-      break;
-    case eCSSProperty_border_start_width:
-      aProperty = ltr ? eCSSProperty_border_left_width :
-                        eCSSProperty_border_right_width;
-      break;
-    default:
-      NS_ABORT_IF_FALSE(nsCSSProps::PropHasFlags(aProperty,
-                                                 CSS_PROPERTY_LOGICAL),
-                        "unhandled logical property");
-  }
-}
-
 void
 nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
 {
     // If we have no data for these structs, then return immediately.
     // This optimization should make us return most of the time, so we
     // have to worry much less (although still some) about the speed of
     // the rest of the function.
     if (!(aRuleData->mSIDs & mStyleBits))
         return;
 
-    // We process these in reverse order so that we end up mapping the
-    // right property when one can be expressed using both logical and
-    // physical property names.
-    for (uint32_t i = mNumProps; i-- > 0; ) {
+    for (uint32_t i = 0; i < mNumProps; i++) {
         nsCSSProperty iProp = PropertyAtIndex(i);
         if (nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[iProp]) &
             aRuleData->mSIDs) {
-            if (nsCSSProps::PropHasFlags(iProp, CSS_PROPERTY_LOGICAL)) {
-                EnsurePhysicalProperty(iProp, aRuleData);
-                // We can't cache anything on the rule tree if we use any data from
-                // the style context, since data cached in the rule tree could be
-                // used with a style context with a different value.
-                aRuleData->mCanStoreInRuleTree = false;
-            }
             nsCSSValue* target = aRuleData->ValueFor(iProp);
             if (target->GetUnit() == eCSSUnit_Null) {
                 const nsCSSValue *val = ValueAtIndex(i);
                 MapSinglePropertyInto(iProp, val, target, aRuleData);
             }
         }
     }
 }
@@ -665,27 +600,21 @@ void
 nsCSSExpandedDataBlock::MapRuleInfoInto(nsCSSProperty aPropID,
                                         nsRuleData* aRuleData) const
 {
   MOZ_ASSERT(!nsCSSProps::IsShorthand(aPropID));
 
   const nsCSSValue* src = PropertyAt(aPropID);
   MOZ_ASSERT(src->GetUnit() != eCSSUnit_Null);
 
-  nsCSSProperty physicalProp = aPropID;
-  if (nsCSSProps::PropHasFlags(aPropID, CSS_PROPERTY_LOGICAL)) {
-    EnsurePhysicalProperty(physicalProp, aRuleData);
-    aRuleData->mCanStoreInRuleTree = false;
-  }
-
-  nsCSSValue* dest = aRuleData->ValueFor(physicalProp);
+  nsCSSValue* dest = aRuleData->ValueFor(aPropID);
   MOZ_ASSERT(dest->GetUnit() == eCSSUnit_TokenStream &&
              dest->GetTokenStreamValue()->mPropertyID == aPropID);
 
-  MapSinglePropertyInto(physicalProp, src, dest, aRuleData);
+  MapSinglePropertyInto(aPropID, src, dest, aRuleData);
 }
 
 #ifdef DEBUG
 void
 nsCSSExpandedDataBlock::DoAssertInitialState()
 {
     mPropertiesSet.AssertIsEmpty("not initial state");
     mPropertiesImportant.AssertIsEmpty("not initial state");
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -54,19 +54,17 @@ using namespace mozilla;
 
 typedef nsCSSProps::KTableValue KTableValue;
 
 const uint32_t
 nsCSSProps::kParserVariantTable[eCSSProperty_COUNT_no_shorthands] = {
 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
                  stylestruct_, stylestructoffset_, animtype_)                 \
   parsevariant_,
-#define CSS_PROP_LIST_INCLUDE_LOGICAL
 #include "nsCSSPropList.h"
-#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP
 };
 
 // Maximum number of repetitions for the repeat() function
 // in the grid-template-columns and grid-template-rows properties,
 // to limit high memory usage from small stylesheets.
 // Must be a positive integer. Should be large-ish.
 #define GRID_TEMPLATE_MAX_REPETITIONS 10000
@@ -625,16 +623,18 @@ protected:
     ePriority_Error
   };
   PriorityParsingStatus ParsePriority();
 
 #ifdef MOZ_XUL
   bool ParseTreePseudoElement(nsAtomList **aPseudoElementArgs);
 #endif
 
+  void InitBoxPropsAsPhysical(const nsCSSProperty *aSourceProperties);
+
   // Property specific parsing routines
   bool ParseBackground();
 
   struct BackgroundParseState {
     nsCSSValue&  mColor;
     nsCSSValueList* mImage;
     nsCSSValuePairList* mRepeat;
     nsCSSValueList* mAttachment;
@@ -681,16 +681,18 @@ protected:
   // aConsumedTokens is always true.
   bool ParseBorderImageSlice(bool aAcceptsInherit, bool* aConsumedTokens);
   bool ParseBorderImageWidth(bool aAcceptsInherit);
   bool ParseBorderImageOutset(bool aAcceptsInherit);
   bool ParseBorderImage();
   bool ParseBorderSpacing();
   bool ParseBorderSide(const nsCSSProperty aPropIDs[],
                          bool aSetAllSides);
+  bool ParseDirectionalBorderSide(const nsCSSProperty aPropIDs[],
+                                    int32_t aSourceType);
   bool ParseBorderStyle();
   bool ParseBorderWidth();
 
   bool ParseCalc(nsCSSValue &aValue, int32_t aVariantMask);
   bool ParseCalcAdditiveExpression(nsCSSValue& aValue,
                                      int32_t& aVariantMask);
   bool ParseCalcMultiplicativeExpression(nsCSSValue& aValue,
                                            int32_t& aVariantMask,
@@ -880,16 +882,18 @@ protected:
    */
   void AppendImpliedEOFCharacters(nsAString& aResult);
 
   // Reused utility parsing routines
   void AppendValue(nsCSSProperty aPropID, const nsCSSValue& aValue);
   bool ParseBoxProperties(const nsCSSProperty aPropIDs[]);
   bool ParseGroupedBoxProperty(int32_t aVariantMask,
                                nsCSSValue& aValue);
+  bool ParseDirectionalBoxProperty(nsCSSProperty aProperty,
+                                     int32_t aSourceType);
   bool ParseBoxCornerRadius(const nsCSSProperty aPropID);
   bool ParseBoxCornerRadiiInternals(nsCSSValue array[]);
   bool ParseBoxCornerRadii(const nsCSSProperty aPropIDs[]);
 
   int32_t ParseChoice(nsCSSValue aValues[],
                       const nsCSSProperty aPropIDs[], int32_t aNumIDs);
   bool ParseColor(nsCSSValue& aValue);
   bool ParseNumberColorComponent(uint8_t& aComponent, char aStop);
@@ -6603,36 +6607,48 @@ CSSParserImpl::ParseDeclaration(css::Dec
 }
 
 static const nsCSSProperty kBorderTopIDs[] = {
   eCSSProperty_border_top_width,
   eCSSProperty_border_top_style,
   eCSSProperty_border_top_color
 };
 static const nsCSSProperty kBorderRightIDs[] = {
+  eCSSProperty_border_right_width_value,
+  eCSSProperty_border_right_style_value,
+  eCSSProperty_border_right_color_value,
   eCSSProperty_border_right_width,
   eCSSProperty_border_right_style,
   eCSSProperty_border_right_color
 };
 static const nsCSSProperty kBorderBottomIDs[] = {
   eCSSProperty_border_bottom_width,
   eCSSProperty_border_bottom_style,
   eCSSProperty_border_bottom_color
 };
 static const nsCSSProperty kBorderLeftIDs[] = {
+  eCSSProperty_border_left_width_value,
+  eCSSProperty_border_left_style_value,
+  eCSSProperty_border_left_color_value,
   eCSSProperty_border_left_width,
   eCSSProperty_border_left_style,
   eCSSProperty_border_left_color
 };
 static const nsCSSProperty kBorderStartIDs[] = {
+  eCSSProperty_border_start_width_value,
+  eCSSProperty_border_start_style_value,
+  eCSSProperty_border_start_color_value,
   eCSSProperty_border_start_width,
   eCSSProperty_border_start_style,
   eCSSProperty_border_start_color
 };
 static const nsCSSProperty kBorderEndIDs[] = {
+  eCSSProperty_border_end_width_value,
+  eCSSProperty_border_end_style_value,
+  eCSSProperty_border_end_color_value,
   eCSSProperty_border_end_width,
   eCSSProperty_border_end_style,
   eCSSProperty_border_end_color
 };
 static const nsCSSProperty kColumnRuleIDs[] = {
   eCSSProperty__moz_column_rule_width,
   eCSSProperty__moz_column_rule_style,
   eCSSProperty__moz_column_rule_color
@@ -9309,16 +9325,35 @@ CSSParserImpl::ParseGroupedBoxProperty(i
     case 3: // Make left == right
       result.mLeft = result.mRight;
   }
 
   return true;
 }
 
 bool
+CSSParserImpl::ParseDirectionalBoxProperty(nsCSSProperty aProperty,
+                                           int32_t aSourceType)
+{
+  const nsCSSProperty* subprops = nsCSSProps::SubpropertyEntryFor(aProperty);
+  NS_ASSERTION(subprops[3] == eCSSProperty_UNKNOWN,
+               "not box property with physical vs. logical cascading");
+  nsCSSValue value;
+  if (!ParseSingleValueProperty(value, subprops[0])) {
+    return false;
+  }
+
+  AppendValue(subprops[0], value);
+  nsCSSValue typeVal(aSourceType, eCSSUnit_Enumerated);
+  AppendValue(subprops[1], typeVal);
+  AppendValue(subprops[2], typeVal);
+  return true;
+}
+
+bool
 CSSParserImpl::ParseBoxCornerRadius(nsCSSProperty aPropID)
 {
   nsCSSValue dimenX, dimenY;
   // required first value
   if (! ParseNonNegativeVariant(dimenX, VARIANT_HLP | VARIANT_CALC, nullptr))
     return false;
 
   // optional second value (forbidden if first value is inherit/initial/unset)
@@ -9424,31 +9459,31 @@ CSSParserImpl::ParseBoxCornerRadii(const
     AppendValue(aPropIDs[side], value[side]);
   }
   return true;
 }
 
 // These must be in CSS order (top,right,bottom,left) for indexing to work
 static const nsCSSProperty kBorderStyleIDs[] = {
   eCSSProperty_border_top_style,
-  eCSSProperty_border_right_style,
+  eCSSProperty_border_right_style_value,
   eCSSProperty_border_bottom_style,
-  eCSSProperty_border_left_style
+  eCSSProperty_border_left_style_value
 };
 static const nsCSSProperty kBorderWidthIDs[] = {
   eCSSProperty_border_top_width,
-  eCSSProperty_border_right_width,
+  eCSSProperty_border_right_width_value,
   eCSSProperty_border_bottom_width,
-  eCSSProperty_border_left_width
+  eCSSProperty_border_left_width_value
 };
 static const nsCSSProperty kBorderColorIDs[] = {
   eCSSProperty_border_top_color,
-  eCSSProperty_border_right_color,
+  eCSSProperty_border_right_color_value,
   eCSSProperty_border_bottom_color,
-  eCSSProperty_border_left_color
+  eCSSProperty_border_left_color_value
 };
 static const nsCSSProperty kBorderRadiusIDs[] = {
   eCSSProperty_border_top_left_radius,
   eCSSProperty_border_top_right_radius,
   eCSSProperty_border_bottom_right_radius,
   eCSSProperty_border_bottom_left_radius
 };
 static const nsCSSProperty kOutlineRadiusIDs[] = {
@@ -9704,23 +9739,27 @@ CSSParserImpl::ParsePropertyByFunction(n
     return ParseBorderColor();
   case eCSSProperty_border_spacing:
     return ParseBorderSpacing();
   case eCSSProperty_border_style:
     return ParseBorderStyle();
   case eCSSProperty_border_bottom:
     return ParseBorderSide(kBorderBottomIDs, false);
   case eCSSProperty_border_end:
-    return ParseBorderSide(kBorderEndIDs, false);
-  case eCSSProperty_border_start:
-    return ParseBorderSide(kBorderStartIDs, false);
+    return ParseDirectionalBorderSide(kBorderEndIDs,
+                                      NS_BOXPROP_SOURCE_LOGICAL);
   case eCSSProperty_border_left:
-    return ParseBorderSide(kBorderLeftIDs, false);
+    return ParseDirectionalBorderSide(kBorderLeftIDs,
+                                      NS_BOXPROP_SOURCE_PHYSICAL);
   case eCSSProperty_border_right:
-    return ParseBorderSide(kBorderRightIDs, false);
+    return ParseDirectionalBorderSide(kBorderRightIDs,
+                                      NS_BOXPROP_SOURCE_PHYSICAL);
+  case eCSSProperty_border_start:
+    return ParseDirectionalBorderSide(kBorderStartIDs,
+                                      NS_BOXPROP_SOURCE_LOGICAL);
   case eCSSProperty_border_top:
     return ParseBorderSide(kBorderTopIDs, false);
   case eCSSProperty_border_bottom_colors:
   case eCSSProperty_border_left_colors:
   case eCSSProperty_border_right_colors:
   case eCSSProperty_border_top_colors:
     return ParseBorderColors(aPropID);
   case eCSSProperty_border_image_slice:
@@ -9730,16 +9769,52 @@ CSSParserImpl::ParsePropertyByFunction(n
   case eCSSProperty_border_image_outset:
     return ParseBorderImageOutset(true);
   case eCSSProperty_border_image_repeat:
     return ParseBorderImageRepeat(true);
   case eCSSProperty_border_image:
     return ParseBorderImage();
   case eCSSProperty_border_width:
     return ParseBorderWidth();
+  case eCSSProperty_border_end_color:
+    return ParseDirectionalBoxProperty(eCSSProperty_border_end_color,
+                                       NS_BOXPROP_SOURCE_LOGICAL);
+  case eCSSProperty_border_left_color:
+    return ParseDirectionalBoxProperty(eCSSProperty_border_left_color,
+                                       NS_BOXPROP_SOURCE_PHYSICAL);
+  case eCSSProperty_border_right_color:
+    return ParseDirectionalBoxProperty(eCSSProperty_border_right_color,
+                                       NS_BOXPROP_SOURCE_PHYSICAL);
+  case eCSSProperty_border_start_color:
+    return ParseDirectionalBoxProperty(eCSSProperty_border_start_color,
+                                       NS_BOXPROP_SOURCE_LOGICAL);
+  case eCSSProperty_border_end_width:
+    return ParseDirectionalBoxProperty(eCSSProperty_border_end_width,
+                                       NS_BOXPROP_SOURCE_LOGICAL);
+  case eCSSProperty_border_left_width:
+    return ParseDirectionalBoxProperty(eCSSProperty_border_left_width,
+                                       NS_BOXPROP_SOURCE_PHYSICAL);
+  case eCSSProperty_border_right_width:
+    return ParseDirectionalBoxProperty(eCSSProperty_border_right_width,
+                                       NS_BOXPROP_SOURCE_PHYSICAL);
+  case eCSSProperty_border_start_width:
+    return ParseDirectionalBoxProperty(eCSSProperty_border_start_width,
+                                       NS_BOXPROP_SOURCE_LOGICAL);
+  case eCSSProperty_border_end_style:
+    return ParseDirectionalBoxProperty(eCSSProperty_border_end_style,
+                                       NS_BOXPROP_SOURCE_LOGICAL);
+  case eCSSProperty_border_left_style:
+    return ParseDirectionalBoxProperty(eCSSProperty_border_left_style,
+                                       NS_BOXPROP_SOURCE_PHYSICAL);
+  case eCSSProperty_border_right_style:
+    return ParseDirectionalBoxProperty(eCSSProperty_border_right_style,
+                                       NS_BOXPROP_SOURCE_PHYSICAL);
+  case eCSSProperty_border_start_style:
+    return ParseDirectionalBoxProperty(eCSSProperty_border_start_style,
+                                       NS_BOXPROP_SOURCE_LOGICAL);
   case eCSSProperty_border_radius:
     return ParseBoxCornerRadii(kBorderRadiusIDs);
   case eCSSProperty__moz_outline_radius:
     return ParseBoxCornerRadii(kOutlineRadiusIDs);
 
   case eCSSProperty_border_top_left_radius:
   case eCSSProperty_border_top_right_radius:
   case eCSSProperty_border_bottom_right_radius:
@@ -9805,24 +9880,48 @@ CSSParserImpl::ParsePropertyByFunction(n
   case eCSSProperty_grid_area:
     return ParseGridArea();
   case eCSSProperty_image_region:
     return ParseRect(eCSSProperty_image_region);
   case eCSSProperty_list_style:
     return ParseListStyle();
   case eCSSProperty_margin:
     return ParseMargin();
+  case eCSSProperty_margin_end:
+    return ParseDirectionalBoxProperty(eCSSProperty_margin_end,
+                                       NS_BOXPROP_SOURCE_LOGICAL);
+  case eCSSProperty_margin_left:
+    return ParseDirectionalBoxProperty(eCSSProperty_margin_left,
+                                       NS_BOXPROP_SOURCE_PHYSICAL);
+  case eCSSProperty_margin_right:
+    return ParseDirectionalBoxProperty(eCSSProperty_margin_right,
+                                       NS_BOXPROP_SOURCE_PHYSICAL);
+  case eCSSProperty_margin_start:
+    return ParseDirectionalBoxProperty(eCSSProperty_margin_start,
+                                       NS_BOXPROP_SOURCE_LOGICAL);
   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();
@@ -10022,16 +10121,26 @@ CSSParserImpl::ParseFontDescriptorValue(
   case eCSSFontDesc_COUNT:
     NS_NOTREACHED("bad nsCSSFontDesc code");
   }
   // explicitly do NOT have a default case to let the compiler
   // help find missing descriptors
   return false;
 }
 
+void
+CSSParserImpl::InitBoxPropsAsPhysical(const nsCSSProperty *aSourceProperties)
+{
+  nsCSSValue physical(NS_BOXPROP_SOURCE_PHYSICAL, eCSSUnit_Enumerated);
+  for (const nsCSSProperty *prop = aSourceProperties;
+       *prop != eCSSProperty_UNKNOWN; ++prop) {
+    AppendValue(*prop, physical);
+  }
+}
+
 static nsCSSValue
 BoxPositionMaskToCSSValue(int32_t aMask, bool isX)
 {
   int32_t val = NS_STYLE_BG_POSITION_CENTER;
   if (isX) {
     if (aMask & BG_LEFT) {
       val = NS_STYLE_BG_POSITION_LEFT;
     }
@@ -10764,16 +10873,26 @@ bool CSSParserImpl::ParseBackgroundSizeV
   yValue.Reset();
   return true;
 }
 #undef BG_SIZE_VARIANT
 
 bool
 CSSParserImpl::ParseBorderColor()
 {
+  static const nsCSSProperty kBorderColorSources[] = {
+    eCSSProperty_border_left_color_ltr_source,
+    eCSSProperty_border_left_color_rtl_source,
+    eCSSProperty_border_right_color_ltr_source,
+    eCSSProperty_border_right_color_rtl_source,
+    eCSSProperty_UNKNOWN
+  };
+
+  // do this now, in case 4 values weren't specified
+  InitBoxPropsAsPhysical(kBorderColorSources);
   return ParseBoxProperties(kBorderColorIDs);
 }
 
 void
 CSSParserImpl::SetBorderImageInitialValues()
 {
   // border-image-source: none
   nsCSSValue source;
@@ -11070,16 +11189,34 @@ CSSParserImpl::ParseBorderSide(const nsC
   if ((found & 2) == 0) { // Provide default border-style
     values[1].SetIntValue(NS_STYLE_BORDER_STYLE_NONE, eCSSUnit_Enumerated);
   }
   if ((found & 4) == 0) { // text color will be used
     values[2].SetIntValue(NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR, eCSSUnit_Enumerated);
   }
 
   if (aSetAllSides) {
+    static const nsCSSProperty kBorderSources[] = {
+      eCSSProperty_border_left_color_ltr_source,
+      eCSSProperty_border_left_color_rtl_source,
+      eCSSProperty_border_right_color_ltr_source,
+      eCSSProperty_border_right_color_rtl_source,
+      eCSSProperty_border_left_style_ltr_source,
+      eCSSProperty_border_left_style_rtl_source,
+      eCSSProperty_border_right_style_ltr_source,
+      eCSSProperty_border_right_style_rtl_source,
+      eCSSProperty_border_left_width_ltr_source,
+      eCSSProperty_border_left_width_rtl_source,
+      eCSSProperty_border_right_width_ltr_source,
+      eCSSProperty_border_right_width_rtl_source,
+      eCSSProperty_UNKNOWN
+    };
+
+    InitBoxPropsAsPhysical(kBorderSources);
+
     // Parsing "border" shorthand; set all four sides to the same thing
     for (int32_t index = 0; index < 4; index++) {
       NS_ASSERTION(numProps == 3, "This code needs updating");
       AppendValue(kBorderWidthIDs[index], values[0]);
       AppendValue(kBorderStyleIDs[index], values[1]);
       AppendValue(kBorderColorIDs[index], values[2]);
     }
 
@@ -11119,24 +11256,78 @@ CSSParserImpl::ParseBorderSide(const nsC
     for (int32_t index = 0; index < numProps; index++) {
       AppendValue(aPropIDs[index], values[index]);
     }
   }
   return true;
 }
 
 bool
+CSSParserImpl::ParseDirectionalBorderSide(const nsCSSProperty aPropIDs[],
+                                          int32_t aSourceType)
+{
+  const int32_t numProps = 3;
+  nsCSSValue  values[numProps];
+
+  int32_t found = ParseChoice(values, aPropIDs, numProps);
+  if (found < 1) {
+    return false;
+  }
+
+  if ((found & 1) == 0) { // Provide default border-width
+    values[0].SetIntValue(NS_STYLE_BORDER_WIDTH_MEDIUM, eCSSUnit_Enumerated);
+  }
+  if ((found & 2) == 0) { // Provide default border-style
+    values[1].SetIntValue(NS_STYLE_BORDER_STYLE_NONE, eCSSUnit_Enumerated);
+  }
+  if ((found & 4) == 0) { // text color will be used
+    values[2].SetIntValue(NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR, eCSSUnit_Enumerated);
+  }
+  for (int32_t index = 0; index < numProps; index++) {
+    const nsCSSProperty* subprops =
+      nsCSSProps::SubpropertyEntryFor(aPropIDs[index + numProps]);
+    NS_ASSERTION(subprops[3] == eCSSProperty_UNKNOWN,
+                 "not box property with physical vs. logical cascading");
+    AppendValue(subprops[0], values[index]);
+    nsCSSValue typeVal(aSourceType, eCSSUnit_Enumerated);
+    AppendValue(subprops[1], typeVal);
+    AppendValue(subprops[2], typeVal);
+  }
+  return true;
+}
+
+bool
 CSSParserImpl::ParseBorderStyle()
 {
+  static const nsCSSProperty kBorderStyleSources[] = {
+    eCSSProperty_border_left_style_ltr_source,
+    eCSSProperty_border_left_style_rtl_source,
+    eCSSProperty_border_right_style_ltr_source,
+    eCSSProperty_border_right_style_rtl_source,
+    eCSSProperty_UNKNOWN
+  };
+
+  // do this now, in case 4 values weren't specified
+  InitBoxPropsAsPhysical(kBorderStyleSources);
   return ParseBoxProperties(kBorderStyleIDs);
 }
 
 bool
 CSSParserImpl::ParseBorderWidth()
 {
+  static const nsCSSProperty kBorderWidthSources[] = {
+    eCSSProperty_border_left_width_ltr_source,
+    eCSSProperty_border_left_width_rtl_source,
+    eCSSProperty_border_right_width_ltr_source,
+    eCSSProperty_border_right_width_rtl_source,
+    eCSSProperty_UNKNOWN
+  };
+
+  // do this now, in case 4 values weren't specified
+  InitBoxPropsAsPhysical(kBorderWidthSources);
   return ParseBoxProperties(kBorderWidthIDs);
 }
 
 bool
 CSSParserImpl::ParseBorderColors(nsCSSProperty aProperty)
 {
   nsCSSValue value;
   // 'inherit', 'initial', 'unset' and 'none' are only allowed on their own
@@ -12769,21 +12960,30 @@ CSSParserImpl::ParseListStyleType(nsCSSV
   return false;
 }
 
 bool
 CSSParserImpl::ParseMargin()
 {
   static const nsCSSProperty kMarginSideIDs[] = {
     eCSSProperty_margin_top,
-    eCSSProperty_margin_right,
+    eCSSProperty_margin_right_value,
     eCSSProperty_margin_bottom,
-    eCSSProperty_margin_left
+    eCSSProperty_margin_left_value
   };
-
+  static const nsCSSProperty kMarginSources[] = {
+    eCSSProperty_margin_left_ltr_source,
+    eCSSProperty_margin_left_rtl_source,
+    eCSSProperty_margin_right_ltr_source,
+    eCSSProperty_margin_right_rtl_source,
+    eCSSProperty_UNKNOWN
+  };
+
+  // do this now, in case 4 values weren't specified
+  InitBoxPropsAsPhysical(kMarginSources);
   return ParseBoxProperties(kMarginSideIDs);
 }
 
 bool
 CSSParserImpl::ParseMarks(nsCSSValue& aValue)
 {
   if (ParseVariant(aValue, VARIANT_HK, nsCSSProps::kPageMarksKTable)) {
     if (eCSSUnit_Enumerated == aValue.GetUnit()) {
@@ -12878,21 +13078,30 @@ CSSParserImpl::ParseOverflow()
   return true;
 }
 
 bool
 CSSParserImpl::ParsePadding()
 {
   static const nsCSSProperty kPaddingSideIDs[] = {
     eCSSProperty_padding_top,
-    eCSSProperty_padding_right,
+    eCSSProperty_padding_right_value,
     eCSSProperty_padding_bottom,
-    eCSSProperty_padding_left
+    eCSSProperty_padding_left_value
   };
-
+  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,56 +134,8 @@ 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")
-CSS_PROP_ALIAS(margin-inline-end,
-               margin_end,
-               MarginInlineEnd,
-               "layout.css.vertical-text.enabled")
-CSS_PROP_ALIAS(margin-inline-start,
-               margin_start,
-               MarginInlineStart,
-               "layout.css.vertical-text.enabled")
-CSS_PROP_ALIAS(border-inline-end,
-               border_end,
-               BorderInlineEnd,
-               "layout.css.vertical-text.enabled")
-CSS_PROP_ALIAS(border-inline-end-color,
-               border_end_color,
-               BorderInlineEndColor,
-               "layout.css.vertical-text.enabled")
-CSS_PROP_ALIAS(border-inline-end-style,
-               border_end_style,
-               BorderInlineEndStyle,
-               "layout.css.vertical-text.enabled")
-CSS_PROP_ALIAS(border-inline-end-width,
-               border_end_width,
-               BorderInlineEndWidth,
-               "layout.css.vertical-text.enabled")
-CSS_PROP_ALIAS(border-inline-start,
-               border_start,
-               BorderInlineStart,
-               "layout.css.vertical-text.enabled")
-CSS_PROP_ALIAS(border-inline-start-color,
-               border_start_color,
-               BorderInlineStartColor,
-               "layout.css.vertical-text.enabled")
-CSS_PROP_ALIAS(border-inline-start-style,
-               border_start_style,
-               BorderInlineStartStyle,
-               "layout.css.vertical-text.enabled")
-CSS_PROP_ALIAS(border-inline-start-width,
-               border_start_width,
-               BorderInlineStartWidth,
-               "layout.css.vertical-text.enabled")
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -12,17 +12,17 @@
 
   This file contains the list of all parsed CSS properties.  It is
   designed to be used as inline input through the magic of C
   preprocessing.  All entries must be enclosed in the appropriate
   CSS_PROP_* macro which will have cruel and unusual things done to it.
   It is recommended (but not strictly necessary) to keep all entries in
   alphabetical order.
 
-  The arguments to CSS_PROP, CSS_PROP_LOGICAL and CSS_PROP_* are:
+  The arguments to CSS_PROP and CSS_PROP_* are:
 
   -. 'name' entries represent a CSS property name and *must* use only
   lowercase characters.
 
   -. 'id' should be the same as 'name' except that all hyphens ('-')
   in 'name' are converted to underscores ('_') in 'id'. For properties
   on a standards track, any '-moz-' prefix is removed in 'id'. This
   lets us do nice things with the macros without having to copy/convert
@@ -46,35 +46,30 @@
   or if the boolean property whose name is 'pref' is set to true.
 
   -. 'parsevariant', to be passed to ParseVariant in the parser.
 
   -. 'kwtable', which is either nullptr or the name of the appropriate
   keyword table member of class nsCSSProps, for use in
   nsCSSProps::LookupPropertyValue.
 
-  -. 'stylestruct_' [used only for CSS_PROP and CSS_PROP_LOGICAL, not
-  CSS_PROP_*] gives the name of the style struct.  Can be used to make
-  nsStyle##stylestruct_ and eStyleStruct_##stylestruct_
+  -. 'stylestruct_' [used only for CSS_PROP, not CSS_PROP_*] gives the
+  name of the style struct.  Can be used to make nsStyle##stylestruct_
+  and eStyleStruct_##stylestruct_
 
   -. 'stylestructoffset_' [not used for CSS_PROP_BACKENDONLY] gives the
   result of offsetof(nsStyle*, member).  Ignored (and generally
   CSS_PROP_NO_OFFSET, or -1) for properties whose animtype_ is
   eStyleAnimType_None.
 
   -. 'animtype_' [not used for CSS_PROP_BACKENDONLY] gives the
   animation type (see nsStyleAnimType) of this property.
 
   CSS_PROP_SHORTHAND only takes 1-5.
 
-  CSS_PROP_LOGICAL should be used instead of CSS_PROP_struct when
-  defining logical properties (which also must be defined with the
-  CSS_PROPERTY_LOGICAL flag).  Logical shorthand properties should still
-  be defined with CSS_PROP_SHORTHAND.
-
  ******/
 
 
 /*************************************************************************/
 
 
 // All includers must explicitly define CSS_PROP_SHORTHAND if they
 // want it.
@@ -87,36 +82,16 @@
   CSS_PROP_PUBLIC_OR_PRIVATE(Moz ## name_, name_)
 
 #define CSS_PROP_NO_OFFSET (-1)
 
 // Callers may define CSS_PROP_LIST_EXCLUDE_INTERNAL if they want to
 // exclude internal properties that are not represented in the DOM (only
 // the DOM style code defines this).
 
-// When capturing all properties by defining CSS_PROP, callers must also
-// define one of the following three macros:
-//
-//   CSS_PROP_LIST_EXCLUDE_LOGICAL
-//     Does not include logical properties (defined with CSS_PROP_LOGICAL,
-//     such as -moz-margin-start) when capturing properties to CSS_PROP.
-//
-//   CSS_PROP_LIST_INCLUDE_LOGICAL
-//     Does include logical properties when capturing properties to
-//     CSS_PROP.
-//
-//   CSS_PROP_LOGICAL
-//     Captures logical properties separately to CSS_PROP_LOGICAL.
-//
-// (CSS_PROP_LIST_EXCLUDE_LOGICAL is used for example to ensure
-// gPropertyCountInStruct and gPropertyIndexInStruct do not allocate any
-// storage to logical properties, since the result of the cascade, stored
-// in an nsRuleData, does not need to store both logical and physical
-// property values.)
-
 // Callers may also define CSS_PROP_LIST_ONLY_COMPONENTS_OF_ALL_SHORTHAND
 // to exclude properties that are not considered to be components of the 'all'
 // shorthand property.  Currently this excludes 'direction' and 'unicode-bidi',
 // as required by the CSS Cascading and Inheritance specification, and any
 // internal properties that cannot be changed by using CSS syntax.  For example,
 // the internal '-moz-system-font' property is not excluded, as it is set by the
 // 'font' shorthand, while '-x-lang' is excluded as there is no way to set this
 // internal property from a style sheet.
@@ -154,46 +129,22 @@
 // For properties that are stored in the CSS backend but are not
 // computed.  An includer may define this in addition to CSS_PROP, but
 // otherwise we treat it as the same.
 #ifndef CSS_PROP_BACKENDONLY
 #define CSS_PROP_BACKENDONLY(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_) CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, BackendOnly, CSS_PROP_NO_OFFSET, eStyleAnimType_None)
 #define DEFINED_CSS_PROP_BACKENDONLY
 #endif
 
-// And similarly for logical properties.  An includer can define
-// CSS_PROP_LOGICAL to capture all logical properties, but otherwise they
-// are included in CSS_PROP (as long as CSS_PROP_LIST_INCLUDE_LOGICAL is
-// defined).
-#if defined(CSS_PROP_LOGICAL) && defined(CSS_PROP_LIST_EXCLUDE_LOGICAL) || defined(CSS_PROP_LOGICAL) && defined(CSS_PROP_LIST_INCLUDE_LOGICAL) || defined(CSS_PROP_LIST_EXCLUDE_LOGICAL) && defined(CSS_PROP_LIST_INCLUDE_LOGICAL)
-#error Do not define more than one of CSS_PROP_LOGICAL, CSS_PROP_LIST_EXCLUDE_LOGICAL and CSS_PROP_LIST_INCLUDE_LOGICAL when capturing properties using CSS_PROP.
-#endif
-
-#ifndef CSS_PROP_LOGICAL
-#ifdef CSS_PROP_LIST_INCLUDE_LOGICAL
-#define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, struct_, stylestructoffset_, animtype_) CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, struct_, stylestructoffset_, animtype_)
-#else
-#ifndef CSS_PROP_LIST_EXCLUDE_LOGICAL
-#error Must define exactly one of CSS_PROP_LOGICAL, CSS_PROP_LIST_EXCLUDE_LOGICAL and CSS_PROP_LIST_INCLUDE_LOGICAL when capturing properties using CSS_PROP.
-#endif
-#define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, struct_, stylestructoffset_, animtype_) /* nothing */
-#endif
-#define DEFINED_CSS_PROP_LOGICAL
-#endif
-
 #else /* !defined(CSS_PROP) */
 
 // An includer who does not define CSS_PROP can define any or all of the
 // per-struct macros that are equivalent to it, and the rest will be
 // ignored.
 
-#if defined(CSS_PROP_LIST_EXCLUDE_LOGICAL) || defined(CSS_PROP_LIST_INCLUDE_LOGICAL)
-#error Do not define CSS_PROP_LIST_EXCLUDE_LOGICAL or CSS_PROP_LIST_INCLUDE_LOGICAL when not capturing properties using CSS_PROP.
-#endif
-
 #ifndef CSS_PROP_FONT
 #define CSS_PROP_FONT(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, stylestructoffset_, animtype_) /* nothing */
 #define DEFINED_CSS_PROP_FONT
 #endif
 #ifndef CSS_PROP_COLOR
 #define CSS_PROP_COLOR(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, stylestructoffset_, animtype_) /* nothing */
 #define DEFINED_CSS_PROP_COLOR
 #endif
@@ -285,20 +236,16 @@
 #define CSS_PROP_VARIABLES(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, stylestructoffset_, animtype_) /* nothing */
 #define DEFINED_CSS_PROP_VARIABLES
 #endif
 
 #ifndef CSS_PROP_BACKENDONLY
 #define CSS_PROP_BACKENDONLY(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_) /* nothing */
 #define DEFINED_CSS_PROP_BACKENDONLY
 #endif
-#ifndef CSS_PROP_LOGICAL
-#define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, struct_, stylestructoffset_, animtype_) /* nothing */
-#define DEFINED_CSS_PROP_LOGICAL
-#endif
 
 #endif /* !defined(CSS_PROP) */
 
 /*************************************************************************/
 
 // For notes XXX bug 3935 below, the names being parsed do not correspond
 // to the constants used internally.  It would be nice to bring the
 // constants into line sometime.
@@ -739,16 +686,80 @@ CSS_PROP_TABLEBORDER(
 CSS_PROP_SHORTHAND(
     border-color,
     border_color,
     BorderColor,
     CSS_PROPERTY_PARSE_FUNCTION |
         CSS_PROPERTY_HASHLESS_COLOR_QUIRK,
     "")
 CSS_PROP_SHORTHAND(
+    -moz-border-end,
+    border_end,
+    CSS_PROP_DOMPROP_PREFIXED(BorderEnd),
+    CSS_PROPERTY_PARSE_FUNCTION,
+    "")
+CSS_PROP_SHORTHAND(
+    -moz-border-end-color,
+    border_end_color,
+    CSS_PROP_DOMPROP_PREFIXED(BorderEndColor),
+    CSS_PROPERTY_PARSE_FUNCTION,
+    "")
+#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
+CSS_PROP_BORDER(
+    border-end-color-value,
+    border_end_color_value,
+    BorderEndColorValue,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER,
+    "",
+    VARIANT_HCK, // used only internally
+    kBorderColorKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+#endif
+CSS_PROP_SHORTHAND(
+    -moz-border-end-style,
+    border_end_style,
+    CSS_PROP_DOMPROP_PREFIXED(BorderEndStyle),
+    CSS_PROPERTY_PARSE_FUNCTION,
+    "")
+#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
+CSS_PROP_BORDER(
+    border-end-style-value,
+    border_end_style_value,
+    BorderEndStyleValue,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER,
+    "",
+    VARIANT_HK, // used only internally
+    kBorderStyleKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+#endif
+CSS_PROP_SHORTHAND(
+    -moz-border-end-width,
+    border_end_width,
+    CSS_PROP_DOMPROP_PREFIXED(BorderEndWidth),
+    CSS_PROPERTY_PARSE_FUNCTION,
+    "")
+#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
+CSS_PROP_BORDER(
+    border-end-width-value,
+    border_end_width_value,
+    BorderEndWidthValue,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_VALUE_NONNEGATIVE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER,
+    "",
+    VARIANT_HKL | VARIANT_CALC,
+    kBorderWidthKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+#endif
+CSS_PROP_SHORTHAND(
     border-image,
     border_image,
     BorderImage,
     CSS_PROPERTY_PARSE_FUNCTION,
     "")
 CSS_PROP_BORDER(
     border-image-source,
     border_image_source,
@@ -801,231 +812,405 @@ CSS_PROP_BORDER(
     CSS_PROPERTY_PARSE_FUNCTION |
         CSS_PROPERTY_APPLIES_TO_FIRST_LETTER,
     "",
     0,
     kBorderImageRepeatKTable,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_None)
 CSS_PROP_SHORTHAND(
-    -moz-border-end,
-    border_end,
-    CSS_PROP_DOMPROP_PREFIXED(BorderEnd),
-    CSS_PROPERTY_PARSE_FUNCTION,
-    "")
-CSS_PROP_LOGICAL(
-    -moz-border-end-color,
-    border_end_color,
-    CSS_PROP_DOMPROP_PREFIXED(BorderEndColor),
-    CSS_PROPERTY_PARSE_VALUE |
-        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
-        CSS_PROPERTY_LOGICAL,
-    "",
-    VARIANT_HCK,
-    kBorderColorKTable,
-    Border,
-    CSS_PROP_NO_OFFSET,
-    eStyleAnimType_None)
-CSS_PROP_LOGICAL(
-    -moz-border-end-style,
-    border_end_style,
-    CSS_PROP_DOMPROP_PREFIXED(BorderEndStyle),
-    CSS_PROPERTY_PARSE_VALUE |
-        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
-        CSS_PROPERTY_LOGICAL,
-    "",
-    VARIANT_HK,
-    kBorderStyleKTable,
-    Border,
-    CSS_PROP_NO_OFFSET,
-    eStyleAnimType_None)
-CSS_PROP_LOGICAL(
-    -moz-border-end-width,
-    border_end_width,
-    CSS_PROP_DOMPROP_PREFIXED(BorderEndWidth),
-    CSS_PROPERTY_PARSE_VALUE |
-        CSS_PROPERTY_VALUE_NONNEGATIVE |
-        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
-        CSS_PROPERTY_LOGICAL,
-    "",
-    VARIANT_HKL | VARIANT_CALC,
-    kBorderWidthKTable,
-    Border,
-    CSS_PROP_NO_OFFSET,
-    eStyleAnimType_None)
-CSS_PROP_SHORTHAND(
-    -moz-border-start,
-    border_start,
-    CSS_PROP_DOMPROP_PREFIXED(BorderStart),
-    CSS_PROPERTY_PARSE_FUNCTION,
-    "")
-CSS_PROP_LOGICAL(
-    -moz-border-start-color,
-    border_start_color,
-    CSS_PROP_DOMPROP_PREFIXED(BorderStartColor),
-    CSS_PROPERTY_PARSE_VALUE |
-        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
-        CSS_PROPERTY_LOGICAL,
-    "",
-    VARIANT_HCK,
-    kBorderColorKTable,
-    Border,
-    CSS_PROP_NO_OFFSET,
-    eStyleAnimType_None)
-CSS_PROP_LOGICAL(
-    -moz-border-start-style,
-    border_start_style,
-    CSS_PROP_DOMPROP_PREFIXED(BorderStartStyle),
-    CSS_PROPERTY_PARSE_VALUE |
-        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
-        CSS_PROPERTY_LOGICAL,
-    "",
-    VARIANT_HK,
-    kBorderStyleKTable,
-    Border,
-    CSS_PROP_NO_OFFSET,
-    eStyleAnimType_None)
-CSS_PROP_LOGICAL(
-    -moz-border-start-width,
-    border_start_width,
-    CSS_PROP_DOMPROP_PREFIXED(BorderStartWidth),
-    CSS_PROPERTY_PARSE_VALUE |
-        CSS_PROPERTY_VALUE_NONNEGATIVE |
-        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
-        CSS_PROPERTY_LOGICAL,
-    "",
-    VARIANT_HKL | VARIANT_CALC,
-    kBorderWidthKTable,
-    Border,
-    CSS_PROP_NO_OFFSET,
-    eStyleAnimType_None)
-CSS_PROP_SHORTHAND(
     border-left,
     border_left,
     BorderLeft,
     CSS_PROPERTY_PARSE_FUNCTION,
     "")
-CSS_PROP_BORDER(
+CSS_PROP_SHORTHAND(
     border-left-color,
     border_left_color,
     BorderLeftColor,
-    CSS_PROPERTY_PARSE_VALUE |
-        CSS_PROPERTY_HASHLESS_COLOR_QUIRK |
+    CSS_PROPERTY_PARSE_FUNCTION |
+        CSS_PROPERTY_HASHLESS_COLOR_QUIRK,
+    "")
+#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
+CSS_PROP_BORDER(
+    border-left-color-value,
+    border_left_color_value,
+    BorderLeftColorValue,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
         CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
-        CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
-    "",
-    VARIANT_HCK,
+        CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED |
+        CSS_PROPERTY_REPORT_OTHER_NAME,
+    "",
+    VARIANT_HCK, // used only internally
     kBorderColorKTable,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_Custom)
 CSS_PROP_BORDER(
+    border-left-color-ltr-source,
+    border_left_color_ltr_source,
+    BorderLeftColorLTRSource,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_DIRECTIONAL_SOURCE |
+        CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
+    "",
+    0,
+    kBoxPropSourceKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+CSS_PROP_BORDER(
+    border-left-color-rtl-source,
+    border_left_color_rtl_source,
+    BorderLeftColorRTLSource,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_DIRECTIONAL_SOURCE |
+        CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
+    "",
+    0,
+    kBoxPropSourceKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+#endif
+CSS_PROP_BORDER(
     -moz-border-left-colors,
     border_left_colors,
     CSS_PROP_DOMPROP_PREFIXED(BorderLeftColors),
     CSS_PROPERTY_PARSE_FUNCTION |
         CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
         CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
     "",
     0,
     nullptr,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_None)
-CSS_PROP_BORDER(
+CSS_PROP_SHORTHAND(
     border-left-style,
     border_left_style,
     BorderLeftStyle,
-    CSS_PROPERTY_PARSE_VALUE |
-        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER,
-    "",
-    VARIANT_HK,
+    CSS_PROPERTY_PARSE_FUNCTION,
+    "") // on/off will need reflow
+#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
+CSS_PROP_BORDER(
+    border-left-style-value,
+    border_left_style_value,
+    BorderLeftStyleValue,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_REPORT_OTHER_NAME,
+    "",
+    VARIANT_HK, // used only internally
     kBorderStyleKTable,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_None)
 CSS_PROP_BORDER(
+    border-left-style-ltr-source,
+    border_left_style_ltr_source,
+    BorderLeftStyleLTRSource,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_DIRECTIONAL_SOURCE,
+    "",
+    0,
+    kBoxPropSourceKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+CSS_PROP_BORDER(
+    border-left-style-rtl-source,
+    border_left_style_rtl_source,
+    BorderLeftStyleRTLSource,
+    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(
     border-left-width,
     border_left_width,
     BorderLeftWidth,
-    CSS_PROPERTY_PARSE_VALUE |
+    CSS_PROPERTY_PARSE_FUNCTION |
         CSS_PROPERTY_UNITLESS_LENGTH_QUIRK |
+        CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH,
+    "")
+#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
+CSS_PROP_BORDER(
+    border-left-width-value,
+    border_left_width_value,
+    BorderLeftWidthValue,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
         CSS_PROPERTY_VALUE_NONNEGATIVE |
-        CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH |
-        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER,
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_REPORT_OTHER_NAME,
     "",
     VARIANT_HKL | VARIANT_CALC,
     kBorderWidthKTable,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_Custom)
+CSS_PROP_BORDER(
+    border-left-width-ltr-source,
+    border_left_width_ltr_source,
+    BorderLeftWidthLTRSource,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_DIRECTIONAL_SOURCE,
+    "",
+    0,
+    kBoxPropSourceKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+CSS_PROP_BORDER(
+    border-left-width-rtl-source,
+    border_left_width_rtl_source,
+    BorderLeftWidthRTLSource,
+    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(
     border-right,
     border_right,
     BorderRight,
     CSS_PROPERTY_PARSE_FUNCTION,
     "")
-CSS_PROP_BORDER(
+CSS_PROP_SHORTHAND(
     border-right-color,
     border_right_color,
     BorderRightColor,
-    CSS_PROPERTY_PARSE_VALUE |
-        CSS_PROPERTY_HASHLESS_COLOR_QUIRK |
+    CSS_PROPERTY_PARSE_FUNCTION |
+        CSS_PROPERTY_HASHLESS_COLOR_QUIRK,
+    "")
+#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
+CSS_PROP_BORDER(
+    border-right-color-value,
+    border_right_color_value,
+    BorderRightColorValue,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
         CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
-        CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
-    "",
-    VARIANT_HCK,
+        CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED |
+        CSS_PROPERTY_REPORT_OTHER_NAME,
+    "",
+    VARIANT_HCK, // used only internally
     kBorderColorKTable,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_Custom)
 CSS_PROP_BORDER(
+    border-right-color-ltr-source,
+    border_right_color_ltr_source,
+    BorderRightColorLTRSource,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_DIRECTIONAL_SOURCE |
+        CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
+    "",
+    0,
+    kBoxPropSourceKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+CSS_PROP_BORDER(
+    border-right-color-rtl-source,
+    border_right_color_rtl_source,
+    BorderRightColorRTLSource,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_DIRECTIONAL_SOURCE |
+        CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
+    "",
+    0,
+    kBoxPropSourceKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+#endif
+CSS_PROP_BORDER(
     -moz-border-right-colors,
     border_right_colors,
     CSS_PROP_DOMPROP_PREFIXED(BorderRightColors),
     CSS_PROPERTY_PARSE_FUNCTION |
         CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
         CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
     "",
     0,
     nullptr,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_None)
-CSS_PROP_BORDER(
+CSS_PROP_SHORTHAND(
     border-right-style,
     border_right_style,
     BorderRightStyle,
-    CSS_PROPERTY_PARSE_VALUE |
-        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER,
-    "",
-    VARIANT_HK,
+    CSS_PROPERTY_PARSE_FUNCTION,
+    "") // on/off will need reflow
+#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
+CSS_PROP_BORDER(
+    border-right-style-value,
+    border_right_style_value,
+    BorderRightStyleValue,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_REPORT_OTHER_NAME,
+    "",
+    VARIANT_HK, // used only internally
     kBorderStyleKTable,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_None)
 CSS_PROP_BORDER(
+    border-right-style-ltr-source,
+    border_right_style_ltr_source,
+    BorderRightStyleLTRSource,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_DIRECTIONAL_SOURCE,
+    "",
+    0,
+    kBoxPropSourceKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+CSS_PROP_BORDER(
+    border-right-style-rtl-source,
+    border_right_style_rtl_source,
+    BorderRightStyleRTLSource,
+    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(
     border-right-width,
     border_right_width,
     BorderRightWidth,
-    CSS_PROPERTY_PARSE_VALUE |
-        CSS_PROPERTY_VALUE_NONNEGATIVE |
+    CSS_PROPERTY_PARSE_FUNCTION |
         CSS_PROPERTY_UNITLESS_LENGTH_QUIRK |
-        CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH |
-        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER,
+        CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH,
+    "")
+#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
+CSS_PROP_BORDER(
+    border-right-width-value,
+    border_right_width_value,
+    BorderRightWidthValue,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_VALUE_NONNEGATIVE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_REPORT_OTHER_NAME,
     "",
     VARIANT_HKL | VARIANT_CALC,
     kBorderWidthKTable,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_Custom)
+CSS_PROP_BORDER(
+    border-right-width-ltr-source,
+    border_right_width_ltr_source,
+    BorderRightWidthLTRSource,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_DIRECTIONAL_SOURCE,
+    "",
+    0,
+    kBoxPropSourceKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+CSS_PROP_BORDER(
+    border-right-width-rtl-source,
+    border_right_width_rtl_source,
+    BorderRightWidthRTLSource,
+    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_TABLEBORDER(
     border-spacing,
     border_spacing,
     BorderSpacing,
     CSS_PROPERTY_PARSE_FUNCTION |
         CSS_PROPERTY_VALUE_NONNEGATIVE,
     "",
     0,
     nullptr,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_Custom)
 CSS_PROP_SHORTHAND(
+    -moz-border-start,
+    border_start,
+    CSS_PROP_DOMPROP_PREFIXED(BorderStart),
+    CSS_PROPERTY_PARSE_FUNCTION,
+    "")
+CSS_PROP_SHORTHAND(
+    -moz-border-start-color,
+    border_start_color,
+    CSS_PROP_DOMPROP_PREFIXED(BorderStartColor),
+    CSS_PROPERTY_PARSE_FUNCTION,
+    "")
+#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
+CSS_PROP_BORDER(
+    border-start-color-value,
+    border_start_color_value,
+    BorderStartColorValue,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER,
+    "",
+    VARIANT_HCK, // used only internally
+    kBorderColorKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+#endif
+CSS_PROP_SHORTHAND(
+    -moz-border-start-style,
+    border_start_style,
+    CSS_PROP_DOMPROP_PREFIXED(BorderStartStyle),
+    CSS_PROPERTY_PARSE_FUNCTION,
+    "")
+#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
+CSS_PROP_BORDER(
+    border-start-style-value,
+    border_start_style_value,
+    BorderStartStyleValue,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER,
+    "",
+    VARIANT_HK, // used only internally
+    kBorderStyleKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+#endif
+CSS_PROP_SHORTHAND(
+    -moz-border-start-width,
+    border_start_width,
+    CSS_PROP_DOMPROP_PREFIXED(BorderStartWidth),
+    CSS_PROPERTY_PARSE_FUNCTION,
+    "")
+#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
+CSS_PROP_BORDER(
+    border-start-width-value,
+    border_start_width_value,
+    BorderStartWidthValue,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_VALUE_NONNEGATIVE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER,
+    "",
+    VARIANT_HKL | VARIANT_CALC,
+    kBorderWidthKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+#endif
+CSS_PROP_SHORTHAND(
     border-style,
     border_style,
     BorderStyle,
     CSS_PROPERTY_PARSE_FUNCTION,
     "")  // on/off will need reflow
 CSS_PROP_SHORTHAND(
     border-top,
     border_top,
@@ -2088,77 +2273,163 @@ CSS_PROP_MARGIN(
         CSS_PROPERTY_UNITLESS_LENGTH_QUIRK |
         CSS_PROPERTY_APPLIES_TO_PAGE_RULE |
         CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH,
     "",
     VARIANT_AHLP | VARIANT_CALC,
     nullptr,
     offsetof(nsStyleMargin, mMargin),
     eStyleAnimType_Sides_Bottom)
-CSS_PROP_LOGICAL(
+CSS_PROP_SHORTHAND(
     -moz-margin-end,
     margin_end,
     CSS_PROP_DOMPROP_PREFIXED(MarginEnd),
-    CSS_PROPERTY_PARSE_VALUE |
+    CSS_PROPERTY_PARSE_FUNCTION |
+        CSS_PROPERTY_APPLIES_TO_PAGE_RULE,
+    "")
+#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
+CSS_PROP_MARGIN(
+    margin-end-value,
+    margin_end_value,
+    MarginEndValue,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
         CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
         CSS_PROPERTY_STORES_CALC |
-        CSS_PROPERTY_APPLIES_TO_PAGE_RULE |
-        CSS_PROPERTY_LOGICAL,
-    "",
-    VARIANT_AHLP | VARIANT_CALC,
+        CSS_PROPERTY_APPLIES_TO_PAGE_RULE,
+    "",
+    VARIANT_AHLP | VARIANT_CALC, // for internal use
     nullptr,
-    Margin,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_None)
-CSS_PROP_LOGICAL(
-    -moz-margin-start,
-    margin_start,
-    CSS_PROP_DOMPROP_PREFIXED(MarginStart),
-    CSS_PROPERTY_PARSE_VALUE |
-        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
-        CSS_PROPERTY_STORES_CALC |
-        CSS_PROPERTY_APPLIES_TO_PAGE_RULE |
-        CSS_PROPERTY_LOGICAL,
-    "",
-    VARIANT_AHLP | VARIANT_CALC,
-    nullptr,
-    Margin,
-    CSS_PROP_NO_OFFSET,
-    eStyleAnimType_None)
-CSS_PROP_MARGIN(
+#endif
+CSS_PROP_SHORTHAND(
     margin-left,
     margin_left,
     MarginLeft,
-    CSS_PROPERTY_PARSE_VALUE |
+    CSS_PROPERTY_PARSE_FUNCTION |
         CSS_PROPERTY_UNITLESS_LENGTH_QUIRK |
-        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
-        CSS_PROPERTY_STORES_CALC |
         CSS_PROPERTY_APPLIES_TO_PAGE_RULE |
         CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH,
-    "",
-    VARIANT_AHLP | VARIANT_CALC,
+    "")
+#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
+CSS_PROP_MARGIN(
+    margin-left-value,
+    margin_left_value,
+    MarginLeftValue,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_REPORT_OTHER_NAME |
+        CSS_PROPERTY_STORES_CALC |
+        CSS_PROPERTY_APPLIES_TO_PAGE_RULE,
+    "",
+    VARIANT_AHLP | VARIANT_CALC, // for internal use
     nullptr,
     offsetof(nsStyleMargin, mMargin),
     eStyleAnimType_Sides_Left)
 CSS_PROP_MARGIN(
+    margin-left-ltr-source,
+    margin_left_ltr_source,
+    MarginLeftLTRSource,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_DIRECTIONAL_SOURCE |
+        CSS_PROPERTY_APPLIES_TO_PAGE_RULE,
+    "",
+    0,
+    kBoxPropSourceKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+CSS_PROP_MARGIN(
+    margin-left-rtl-source,
+    margin_left_rtl_source,
+    MarginLeftRTLSource,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_DIRECTIONAL_SOURCE |
+        CSS_PROPERTY_APPLIES_TO_PAGE_RULE,
+    "",
+    0,
+    kBoxPropSourceKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+#endif
+CSS_PROP_SHORTHAND(
     margin-right,
     margin_right,
     MarginRight,
-    CSS_PROPERTY_PARSE_VALUE |
+    CSS_PROPERTY_PARSE_FUNCTION |
         CSS_PROPERTY_UNITLESS_LENGTH_QUIRK |
-        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
-        CSS_PROPERTY_STORES_CALC |
         CSS_PROPERTY_APPLIES_TO_PAGE_RULE |
         CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH,
-    "",
-    VARIANT_AHLP | VARIANT_CALC,
+    "")
+#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
+CSS_PROP_MARGIN(
+    margin-right-value,
+    margin_right_value,
+    MarginRightValue,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_REPORT_OTHER_NAME |
+        CSS_PROPERTY_STORES_CALC |
+        CSS_PROPERTY_APPLIES_TO_PAGE_RULE,
+    "",
+    VARIANT_AHLP | VARIANT_CALC, // for internal use
     nullptr,
     offsetof(nsStyleMargin, mMargin),
     eStyleAnimType_Sides_Right)
 CSS_PROP_MARGIN(
+    margin-right-ltr-source,
+    margin_right_ltr_source,
+    MarginRightLTRSource,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_DIRECTIONAL_SOURCE |
+        CSS_PROPERTY_APPLIES_TO_PAGE_RULE,
+    "",
+    0,
+    kBoxPropSourceKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+CSS_PROP_MARGIN(
+    margin-right-rtl-source,
+    margin_right_rtl_source,
+    MarginRightRTLSource,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_DIRECTIONAL_SOURCE |
+        CSS_PROPERTY_APPLIES_TO_PAGE_RULE,
+    "",
+    0,
+    kBoxPropSourceKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+#endif
+CSS_PROP_SHORTHAND(
+    -moz-margin-start,
+    margin_start,
+    CSS_PROP_DOMPROP_PREFIXED(MarginStart),
+    CSS_PROPERTY_PARSE_FUNCTION |
+    CSS_PROPERTY_APPLIES_TO_PAGE_RULE,
+    "")
+#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
+CSS_PROP_MARGIN(
+    margin-start-value,
+    margin_start_value,
+    MarginStartValue,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
+        CSS_PROPERTY_STORES_CALC |
+        CSS_PROPERTY_APPLIES_TO_PAGE_RULE,
+    "",
+    VARIANT_AHLP | VARIANT_CALC, // for internal use
+    nullptr,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+#endif
+CSS_PROP_MARGIN(
     margin-top,
     margin_top,
     MarginTop,
     CSS_PROPERTY_PARSE_VALUE |
         CSS_PROPERTY_APPLIES_TO_FIRST_LETTER |
         CSS_PROPERTY_STORES_CALC |
         CSS_PROPERTY_UNITLESS_LENGTH_QUIRK |
         CSS_PROPERTY_APPLIES_TO_PAGE_RULE |
@@ -2423,86 +2694,168 @@ 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_LOGICAL(
+CSS_PROP_SHORTHAND(
     -moz-padding-end,
     padding_end,
     CSS_PROP_DOMPROP_PREFIXED(PaddingEnd),
-    CSS_PROPERTY_PARSE_VALUE |
+    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_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 |
-        CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH |
-        CSS_PROPERTY_LOGICAL,
-    "",
-    VARIANT_HLP | VARIANT_CALC,
+        CSS_PROPERTY_STORES_CALC,
+    "",
+    VARIANT_HLP | VARIANT_CALC, // for internal use
     nullptr,
-    Padding,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_None)
-CSS_PROP_LOGICAL(
-    -moz-padding-start,
-    padding_start,
-    CSS_PROP_DOMPROP_PREFIXED(PaddingStart),
-    CSS_PROPERTY_PARSE_VALUE |
+#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_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 |
-        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,
+        CSS_PROPERTY_REPORT_OTHER_NAME |
+        CSS_PROPERTY_STORES_CALC,
+    "",
+    VARIANT_HLP | VARIANT_CALC, // for internal use
     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_VALUE |
+    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-right-value,
+    padding_right_value,
+    PaddingRightValue,
+    CSS_PROPERTY_PARSE_INACCESSIBLE |
         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_REPORT_OTHER_NAME |
+        CSS_PROPERTY_STORES_CALC,
+    "",
+    VARIANT_HLP | VARIANT_CALC, // for internal use
+    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_STORES_CALC |
-        CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH,
-    "",
-    VARIANT_HLP | VARIANT_CALC,
+        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,
-    offsetof(nsStylePadding, mPadding),
-    eStyleAnimType_Sides_Right)
+    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.
@@ -3831,14 +4184,10 @@ CSS_PROP_FONT(
 #endif
 
 #endif /* !defined(USED_CSS_PROP) */
 
 #ifdef DEFINED_CSS_PROP_SHORTHAND
 #undef CSS_PROP_SHORTHAND
 #undef DEFINED_CSS_PROP_SHORTHAND
 #endif
-#ifdef DEFINED_CSS_PROP_LOGICAL
-#undef CSS_PROP_LOGICAL
-#undef DEFINED_CSS_PROP_LOGICAL
-#endif
 
 #undef CSS_PROP_DOMPROP_PREFIXED
--- a/layout/style/nsCSSProperty.h
+++ b/layout/style/nsCSSProperty.h
@@ -16,19 +16,17 @@
 
  */
 enum nsCSSProperty {
   eCSSProperty_UNKNOWN = -1,
 
   #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \
                    kwtable_, stylestruct_, stylestructoffset_, animtype_) \
     eCSSProperty_##id_,
-  #define CSS_PROP_LIST_INCLUDE_LOGICAL
   #include "nsCSSPropList.h"
-  #undef CSS_PROP_LIST_INCLUDE_LOGICAL
   #undef CSS_PROP
 
   eCSSProperty_COUNT_no_shorthands,
   // Make the count continue where it left off:
   eCSSProperty_COUNT_DUMMY = eCSSProperty_COUNT_no_shorthands - 1,
 
   #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) \
     eCSSProperty_##id_,
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -31,19 +31,17 @@ typedef nsCSSProps::KTableValue KTableVa
 // required to make the symbol external, so that TestCSSPropertyLookup.cpp can link with it
 extern const char* const kCSSRawProperties[];
 
 // define an array of all CSS properties
 const char* const kCSSRawProperties[eCSSProperty_COUNT_with_aliases] = {
 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
                  stylestruct_, stylestructoffset_, animtype_)                 \
   #name_,
-#define CSS_PROP_LIST_INCLUDE_LOGICAL
 #include "nsCSSPropList.h"
-#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP
 #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) #name_,
 #include "nsCSSPropList.h"
 #undef CSS_PROP_SHORTHAND
 #define CSS_PROP_ALIAS(aliasname_, id_, method_, pref_) #aliasname_,
 #include "nsCSSPropAliasList.h"
 #undef CSS_PROP_ALIAS
 };
@@ -166,19 +164,17 @@ nsCSSProps::AddRefTable(void)
         if (pref_[0]) {                                                       \
           Preferences::AddBoolVarCache(&gPropertyEnabled[id_],                \
                                        pref_);                                \
         }
 
       #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,     \
                        kwtable_, stylestruct_, stylestructoffset_, animtype_) \
         OBSERVE_PROP(pref_, eCSSProperty_##id_)
-      #define CSS_PROP_LIST_INCLUDE_LOGICAL
       #include "nsCSSPropList.h"
-      #undef CSS_PROP_LIST_INCLUDE_LOGICAL
       #undef CSS_PROP
 
       #define  CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) \
         OBSERVE_PROP(pref_, eCSSProperty_##id_)
       #include "nsCSSPropList.h"
       #undef CSS_PROP_SHORTHAND
 
       #define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_)    \
@@ -553,16 +549,46 @@ nsCSSProps::GetStringValue(nsCSSCounterD
   if (gCounterDescTable) {
     return gCounterDescTable->GetStringValue(int32_t(aCounterDesc));
   } else {
     static nsDependentCString sNullStr("");
     return sNullStr;
   }
 }
 
+nsCSSProperty
+nsCSSProps::OtherNameFor(nsCSSProperty aProperty)
+{
+  switch (aProperty) {
+    case eCSSProperty_border_left_color_value:
+      return eCSSProperty_border_left_color;
+    case eCSSProperty_border_left_style_value:
+      return eCSSProperty_border_left_style;
+    case eCSSProperty_border_left_width_value:
+      return eCSSProperty_border_left_width;
+    case eCSSProperty_border_right_color_value:
+      return eCSSProperty_border_right_color;
+    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;
+}
+
 /***************************************************************************/
 
 const KTableValue nsCSSProps::kAnimationDirectionKTable[] = {
   eCSSKeyword_normal, NS_STYLE_ANIMATION_DIRECTION_NORMAL,
   eCSSKeyword_reverse, NS_STYLE_ANIMATION_DIRECTION_REVERSE,
   eCSSKeyword_alternate, NS_STYLE_ANIMATION_DIRECTION_ALTERNATE,
   eCSSKeyword_alternate_reverse, NS_STYLE_ANIMATION_DIRECTION_ALTERNATE_REVERSE,
   eCSSKeyword_UNKNOWN,-1
@@ -830,16 +856,22 @@ const KTableValue nsCSSProps::kBorderSty
 
 const KTableValue nsCSSProps::kBorderWidthKTable[] = {
   eCSSKeyword_thin, NS_STYLE_BORDER_WIDTH_THIN,
   eCSSKeyword_medium, NS_STYLE_BORDER_WIDTH_MEDIUM,
   eCSSKeyword_thick, NS_STYLE_BORDER_WIDTH_THICK,
   eCSSKeyword_UNKNOWN,-1
 };
 
+const KTableValue nsCSSProps::kBoxPropSourceKTable[] = {
+  eCSSKeyword_physical,     NS_BOXPROP_SOURCE_PHYSICAL,
+  eCSSKeyword_logical,      NS_BOXPROP_SOURCE_LOGICAL,
+  eCSSKeyword_UNKNOWN,-1
+};
+
 const KTableValue nsCSSProps::kBoxDecorationBreakKTable[] = {
   eCSSKeyword_slice, NS_STYLE_BOX_DECORATION_BREAK_SLICE,
   eCSSKeyword_clone, NS_STYLE_BOX_DECORATION_BREAK_CLONE,
   eCSSKeyword_UNKNOWN,-1
 };
 
 const KTableValue nsCSSProps::kBoxShadowTypeKTable[] = {
   eCSSKeyword_inset, NS_STYLE_BOX_SHADOW_INSET,
@@ -2082,19 +2114,17 @@ nsCSSProps::ValueToKeyword(int32_t aValu
   }
 }
 
 /* static */ const KTableValue* const
 nsCSSProps::kKeywordTableTable[eCSSProperty_COUNT_no_shorthands] = {
   #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,     \
                    kwtable_, stylestruct_, stylestructoffset_, animtype_) \
     kwtable_,
-  #define CSS_PROP_LIST_INCLUDE_LOGICAL
   #include "nsCSSPropList.h"
-  #undef CSS_PROP_LIST_INCLUDE_LOGICAL
   #undef CSS_PROP
 };
 
 const nsAFlatCString&
 nsCSSProps::LookupPropertyValue(nsCSSProperty aProp, int32_t aValue)
 {
   NS_ABORT_IF_FALSE(aProp >= 0 && aProp < eCSSProperty_COUNT,
                     "property out of range");
@@ -2130,68 +2160,58 @@ bool nsCSSProps::GetColorName(int32_t aP
 
 const nsStyleStructID nsCSSProps::kSIDTable[eCSSProperty_COUNT_no_shorthands] = {
     // Note that this uses the special BackendOnly style struct ID
     // (which does need to be valid for storing in the
     // nsCSSCompressedDataBlock::mStyleBits bitfield).
     #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,     \
                      kwtable_, stylestruct_, stylestructoffset_, animtype_) \
         eStyleStruct_##stylestruct_,
-    #define CSS_PROP_LIST_INCLUDE_LOGICAL
 
     #include "nsCSSPropList.h"
 
-    #undef CSS_PROP_LIST_INCLUDE_LOGICAL
     #undef CSS_PROP
 };
 
 const nsStyleAnimType
 nsCSSProps::kAnimTypeTable[eCSSProperty_COUNT_no_shorthands] = {
 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
                  stylestruct_, stylestructoffset_, animtype_)                 \
   animtype_,
-#define CSS_PROP_LIST_INCLUDE_LOGICAL
 #include "nsCSSPropList.h"
-#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP
 };
 
 const ptrdiff_t
 nsCSSProps::kStyleStructOffsetTable[eCSSProperty_COUNT_no_shorthands] = {
 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
                  stylestruct_, stylestructoffset_, animtype_)                 \
   stylestructoffset_,
-#define CSS_PROP_LIST_INCLUDE_LOGICAL
 #include "nsCSSPropList.h"
-#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP
 };
 
 const uint32_t nsCSSProps::kFlagsTable[eCSSProperty_COUNT] = {
 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
                  stylestruct_, stylestructoffset_, animtype_)                 \
   flags_,
-#define CSS_PROP_LIST_INCLUDE_LOGICAL
 #include "nsCSSPropList.h"
-#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP
 #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) flags_,
 #include "nsCSSPropList.h"
 #undef CSS_PROP_SHORTHAND
 };
 
 static const nsCSSProperty gAllSubpropTable[] = {
 #define CSS_PROP_LIST_ONLY_COMPONENTS_OF_ALL_SHORTHAND
-#define CSS_PROP_LIST_INCLUDE_LOGICAL
 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
                  stylestruct_, stylestructoffset_, animtype_)                 \
   eCSSProperty_##id_,
 #include "nsCSSPropList.h"
 #undef CSS_PROP
-#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP_LIST_ONLY_COMPONENTS_OF_ALL_SHORTHAND
   eCSSProperty_UNKNOWN
 };
 
 static const nsCSSProperty gAnimationSubpropTable[] = {
   eCSSProperty_animation_duration,
   eCSSProperty_animation_timing_function,
   eCSSProperty_animation_delay,
@@ -2235,121 +2255,272 @@ static const nsCSSProperty gBackgroundSu
   eCSSProperty_background_clip,
   eCSSProperty_background_origin,
   eCSSProperty_background_size,
   eCSSProperty_UNKNOWN
 };
 
 static const nsCSSProperty gBorderSubpropTable[] = {
   eCSSProperty_border_top_width,
-  eCSSProperty_border_right_width,
+  eCSSProperty_border_right_width_value,
+  eCSSProperty_border_right_width_ltr_source,
+  eCSSProperty_border_right_width_rtl_source,
   eCSSProperty_border_bottom_width,
-  eCSSProperty_border_left_width,
+  eCSSProperty_border_left_width_value,
+  eCSSProperty_border_left_width_ltr_source,
+  eCSSProperty_border_left_width_rtl_source,
   eCSSProperty_border_top_style,
-  eCSSProperty_border_right_style,
+  eCSSProperty_border_right_style_value,
+  eCSSProperty_border_right_style_ltr_source,
+  eCSSProperty_border_right_style_rtl_source,
   eCSSProperty_border_bottom_style,
-  eCSSProperty_border_left_style,
+  eCSSProperty_border_left_style_value,
+  eCSSProperty_border_left_style_ltr_source,
+  eCSSProperty_border_left_style_rtl_source,
   eCSSProperty_border_top_color,
-  eCSSProperty_border_right_color,
+  eCSSProperty_border_right_color_value,
+  eCSSProperty_border_right_color_ltr_source,
+  eCSSProperty_border_right_color_rtl_source,
   eCSSProperty_border_bottom_color,
-  eCSSProperty_border_left_color,
+  eCSSProperty_border_left_color_value,
+  eCSSProperty_border_left_color_ltr_source,
+  eCSSProperty_border_left_color_rtl_source,
   eCSSProperty_border_top_colors,
   eCSSProperty_border_right_colors,
   eCSSProperty_border_bottom_colors,
   eCSSProperty_border_left_colors,
   eCSSProperty_border_image_source,
   eCSSProperty_border_image_slice,
   eCSSProperty_border_image_width,
   eCSSProperty_border_image_outset,
   eCSSProperty_border_image_repeat,
   eCSSProperty_UNKNOWN
 };
 
 static const nsCSSProperty gBorderBottomSubpropTable[] = {
-  // Declaration.cpp outputs the subproperties in this order.
+  // nsCSSDeclaration.cpp outputs the subproperties in this order.
   // It also depends on the color being third.
   eCSSProperty_border_bottom_width,
   eCSSProperty_border_bottom_style,
   eCSSProperty_border_bottom_color,
   eCSSProperty_UNKNOWN
 };
 
 static_assert(NS_SIDE_TOP == 0 && NS_SIDE_RIGHT == 1 &&
               NS_SIDE_BOTTOM == 2 && NS_SIDE_LEFT == 3,
               "box side constants not top/right/bottom/left == 0/1/2/3");
 static const nsCSSProperty gBorderColorSubpropTable[] = {
   // Code relies on these being in top-right-bottom-left order.
   // Code relies on these matching the NS_SIDE_* constants.
   eCSSProperty_border_top_color,
-  eCSSProperty_border_right_color,
+  eCSSProperty_border_right_color_value,
   eCSSProperty_border_bottom_color,
-  eCSSProperty_border_left_color,
+  eCSSProperty_border_left_color_value,
+  // extras:
+  eCSSProperty_border_left_color_ltr_source,
+  eCSSProperty_border_left_color_rtl_source,
+  eCSSProperty_border_right_color_ltr_source,
+  eCSSProperty_border_right_color_rtl_source,
+  eCSSProperty_UNKNOWN
+};
+
+static const nsCSSProperty gBorderEndColorSubpropTable[] = {
+  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
+  eCSSProperty_border_end_color_value,
+  eCSSProperty_border_right_color_ltr_source,
+  eCSSProperty_border_left_color_rtl_source,
+  eCSSProperty_UNKNOWN
+};
+
+static const nsCSSProperty gBorderLeftColorSubpropTable[] = {
+  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
+  eCSSProperty_border_left_color_value,
+  eCSSProperty_border_left_color_ltr_source,
+  eCSSProperty_border_left_color_rtl_source,
+  eCSSProperty_UNKNOWN
+};
+
+static const nsCSSProperty gBorderRightColorSubpropTable[] = {
+  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
+  eCSSProperty_border_right_color_value,
+  eCSSProperty_border_right_color_ltr_source,
+  eCSSProperty_border_right_color_rtl_source,
+  eCSSProperty_UNKNOWN
+};
+
+static const nsCSSProperty gBorderStartColorSubpropTable[] = {
+  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
+  eCSSProperty_border_start_color_value,
+  eCSSProperty_border_left_color_ltr_source,
+  eCSSProperty_border_right_color_rtl_source,
   eCSSProperty_UNKNOWN
 };
 
 static const nsCSSProperty gBorderEndSubpropTable[] = {
-  // Declaration.cpp output the subproperties in this order.
+  // nsCSSDeclaration.cpp output the subproperties in this order.
   // It also depends on the color being third.
-  eCSSProperty_border_end_width,
-  eCSSProperty_border_end_style,
-  eCSSProperty_border_end_color,
+  eCSSProperty_border_end_width_value,
+  eCSSProperty_border_end_style_value,
+  eCSSProperty_border_end_color_value,
+  // extras:
+  eCSSProperty_border_right_width_ltr_source,
+  eCSSProperty_border_left_width_rtl_source,
+  eCSSProperty_border_right_style_ltr_source,
+  eCSSProperty_border_left_style_rtl_source,
+  eCSSProperty_border_right_color_ltr_source,
+  eCSSProperty_border_left_color_rtl_source,
   eCSSProperty_UNKNOWN
 };
 
 static const nsCSSProperty gBorderLeftSubpropTable[] = {
-  // Declaration.cpp outputs the subproperties in this order.
+  // nsCSSDeclaration.cpp outputs the subproperties in this order.
   // It also depends on the color being third.
-  eCSSProperty_border_left_width,
-  eCSSProperty_border_left_style,
-  eCSSProperty_border_left_color,
+  eCSSProperty_border_left_width_value,
+  eCSSProperty_border_left_style_value,
+  eCSSProperty_border_left_color_value,
+  // extras:
+  eCSSProperty_border_left_width_ltr_source,
+  eCSSProperty_border_left_width_rtl_source,
+  eCSSProperty_border_left_style_ltr_source,
+  eCSSProperty_border_left_style_rtl_source,
+  eCSSProperty_border_left_color_ltr_source,
+  eCSSProperty_border_left_color_rtl_source,
   eCSSProperty_UNKNOWN
 };
 
 static const nsCSSProperty gBorderRightSubpropTable[] = {
-  // Declaration.cpp outputs the subproperties in this order.
+  // nsCSSDeclaration.cpp outputs the subproperties in this order.
   // It also depends on the color being third.
-  eCSSProperty_border_right_width,
-  eCSSProperty_border_right_style,
-  eCSSProperty_border_right_color,
+  eCSSProperty_border_right_width_value,
+  eCSSProperty_border_right_style_value,
+  eCSSProperty_border_right_color_value,
+  // extras:
+  eCSSProperty_border_right_width_ltr_source,
+  eCSSProperty_border_right_width_rtl_source,
+  eCSSProperty_border_right_style_ltr_source,
+  eCSSProperty_border_right_style_rtl_source,
+  eCSSProperty_border_right_color_ltr_source,
+  eCSSProperty_border_right_color_rtl_source,
   eCSSProperty_UNKNOWN
 };
 
 static const nsCSSProperty gBorderStartSubpropTable[] = {
-  // Declaration.cpp outputs the subproperties in this order.
+  // nsCSSDeclaration.cpp outputs the subproperties in this order.
   // It also depends on the color being third.
-  eCSSProperty_border_start_width,
-  eCSSProperty_border_start_style,
-  eCSSProperty_border_start_color,
+  eCSSProperty_border_start_width_value,
+  eCSSProperty_border_start_style_value,
+  eCSSProperty_border_start_color_value,
+  // extras:
+  eCSSProperty_border_left_width_ltr_source,
+  eCSSProperty_border_right_width_rtl_source,
+  eCSSProperty_border_left_style_ltr_source,
+  eCSSProperty_border_right_style_rtl_source,
+  eCSSProperty_border_left_color_ltr_source,
+  eCSSProperty_border_right_color_rtl_source,
   eCSSProperty_UNKNOWN
 };
 
 static const nsCSSProperty gBorderStyleSubpropTable[] = {
   // Code relies on these being in top-right-bottom-left order.
   eCSSProperty_border_top_style,
-  eCSSProperty_border_right_style,
+  eCSSProperty_border_right_style_value,
   eCSSProperty_border_bottom_style,
-  eCSSProperty_border_left_style,
+  eCSSProperty_border_left_style_value,
+  // extras:
+  eCSSProperty_border_left_style_ltr_source,
+  eCSSProperty_border_left_style_rtl_source,
+  eCSSProperty_border_right_style_ltr_source,
+  eCSSProperty_border_right_style_rtl_source,
+  eCSSProperty_UNKNOWN
+};
+
+static const nsCSSProperty gBorderLeftStyleSubpropTable[] = {
+  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
+  eCSSProperty_border_left_style_value,
+  eCSSProperty_border_left_style_ltr_source,
+  eCSSProperty_border_left_style_rtl_source,
+  eCSSProperty_UNKNOWN
+};
+
+static const nsCSSProperty gBorderRightStyleSubpropTable[] = {
+  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
+  eCSSProperty_border_right_style_value,
+  eCSSProperty_border_right_style_ltr_source,
+  eCSSProperty_border_right_style_rtl_source,
+  eCSSProperty_UNKNOWN
+};
+
+static const nsCSSProperty gBorderStartStyleSubpropTable[] = {
+  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
+  eCSSProperty_border_start_style_value,
+  eCSSProperty_border_left_style_ltr_source,
+  eCSSProperty_border_right_style_rtl_source,
+  eCSSProperty_UNKNOWN
+};
+
+static const nsCSSProperty gBorderEndStyleSubpropTable[] = {
+  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
+  eCSSProperty_border_end_style_value,
+  eCSSProperty_border_right_style_ltr_source,
+  eCSSProperty_border_left_style_rtl_source,
   eCSSProperty_UNKNOWN
 };
 
 static const nsCSSProperty gBorderTopSubpropTable[] = {
-  // Declaration.cpp outputs the subproperties in this order.
+  // nsCSSDeclaration.cpp outputs the subproperties in this order.
   // It also depends on the color being third.
   eCSSProperty_border_top_width,
   eCSSProperty_border_top_style,
   eCSSProperty_border_top_color,
   eCSSProperty_UNKNOWN
 };
 
 static const nsCSSProperty gBorderWidthSubpropTable[] = {
   // Code relies on these being in top-right-bottom-left order.
   eCSSProperty_border_top_width,
-  eCSSProperty_border_right_width,
+  eCSSProperty_border_right_width_value,
   eCSSProperty_border_bottom_width,
-  eCSSProperty_border_left_width,
+  eCSSProperty_border_left_width_value,
+  // extras:
+  eCSSProperty_border_left_width_ltr_source,
+  eCSSProperty_border_left_width_rtl_source,
+  eCSSProperty_border_right_width_ltr_source,
+  eCSSProperty_border_right_width_rtl_source,
+  eCSSProperty_UNKNOWN
+};
+
+static const nsCSSProperty gBorderLeftWidthSubpropTable[] = {
+  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
+  eCSSProperty_border_left_width_value,
+  eCSSProperty_border_left_width_ltr_source,
+  eCSSProperty_border_left_width_rtl_source,
+  eCSSProperty_UNKNOWN
+};
+
+static const nsCSSProperty gBorderRightWidthSubpropTable[] = {
+  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
+  eCSSProperty_border_right_width_value,
+  eCSSProperty_border_right_width_ltr_source,
+  eCSSProperty_border_right_width_rtl_source,
+  eCSSProperty_UNKNOWN
+};
+
+static const nsCSSProperty gBorderStartWidthSubpropTable[] = {
+  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
+  eCSSProperty_border_start_width_value,
+  eCSSProperty_border_left_width_ltr_source,
+  eCSSProperty_border_right_width_rtl_source,
+  eCSSProperty_UNKNOWN
+};
+
+static const nsCSSProperty gBorderEndWidthSubpropTable[] = {
+  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
+  eCSSProperty_border_end_width_value,
+  eCSSProperty_border_right_width_ltr_source,
+  eCSSProperty_border_left_width_rtl_source,
   eCSSProperty_UNKNOWN
 };
 
 static const nsCSSProperty gFontSubpropTable[] = {
   eCSSProperty_font_family,
   eCSSProperty_font_style,
   eCSSProperty_font_weight,
   eCSSProperty_font_size,
@@ -2385,19 +2556,56 @@ static const nsCSSProperty gListStyleSub
   eCSSProperty_list_style_image,
   eCSSProperty_list_style_position,
   eCSSProperty_UNKNOWN
 };
 
 static const nsCSSProperty gMarginSubpropTable[] = {
   // Code relies on these being in top-right-bottom-left order.
   eCSSProperty_margin_top,
-  eCSSProperty_margin_right,
+  eCSSProperty_margin_right_value,
   eCSSProperty_margin_bottom,
-  eCSSProperty_margin_left,
+  eCSSProperty_margin_left_value,
+  // extras:
+  eCSSProperty_margin_left_ltr_source,
+  eCSSProperty_margin_left_rtl_source,
+  eCSSProperty_margin_right_ltr_source,
+  eCSSProperty_margin_right_rtl_source,
+  eCSSProperty_UNKNOWN
+};
+
+static const nsCSSProperty gMarginLeftSubpropTable[] = {
+  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
+  eCSSProperty_margin_left_value,
+  eCSSProperty_margin_left_ltr_source,
+  eCSSProperty_margin_left_rtl_source,
+  eCSSProperty_UNKNOWN
+};
+
+static const nsCSSProperty gMarginRightSubpropTable[] = {
+  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
+  eCSSProperty_margin_right_value,
+  eCSSProperty_margin_right_ltr_source,
+  eCSSProperty_margin_right_rtl_source,
+  eCSSProperty_UNKNOWN
+};
+
+static const nsCSSProperty gMarginStartSubpropTable[] = {
+  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
+  eCSSProperty_margin_start_value,
+  eCSSProperty_margin_left_ltr_source,
+  eCSSProperty_margin_right_rtl_source,
+  eCSSProperty_UNKNOWN
+};
+
+static const nsCSSProperty gMarginEndSubpropTable[] = {
+  // nsCSSParser::ParseDirectionalBoxProperty depends on this order
+  eCSSProperty_margin_end_value,
+  eCSSProperty_margin_right_ltr_source,
+  eCSSProperty_margin_left_rtl_source,
   eCSSProperty_UNKNOWN
 };
 
 
 static const nsCSSProperty gOutlineSubpropTable[] = {
   // nsCSSDeclaration.cpp outputs the subproperties in this order.
   // It also depends on the color being third.
   eCSSProperty_outline_width,
@@ -2475,19 +2683,56 @@ 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,
+  eCSSProperty_padding_right_value,
   eCSSProperty_padding_bottom,
-  eCSSProperty_padding_left,
+  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_UNKNOWN
 };
 
 static const nsCSSProperty gTextDecorationSubpropTable[] = {
   eCSSProperty_text_decoration_color,
   eCSSProperty_text_decoration_line,
   eCSSProperty_text_decoration_style,
   eCSSProperty_UNKNOWN
@@ -2725,59 +2970,35 @@ nsCSSProps::gPropertyCountInStruct[nsSty
 };
 
 /* static */ const size_t
 nsCSSProps::gPropertyIndexInStruct[eCSSProperty_COUNT_no_shorthands] = {
 
   #define CSS_PROP_BACKENDONLY(name_, id_, method_, flags_, pref_, \
                                parsevariant_, kwtable_)            \
       size_t(-1),
-  #define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, \
-                           kwtable_, stylestruct_, stylestructoffset_,        \
-                           animtype_)                                         \
-      size_t(-1),
   #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,     \
                    kwtable_, stylestruct_, stylestructoffset_, animtype_) \
     ePropertyIndex_for_##id_,
   #include "nsCSSPropList.h"
   #undef CSS_PROP
-  #undef CSS_PROP_LOGICAL
   #undef CSS_PROP_BACKENDONLY
 
 };
 
 /* static */ bool
 nsCSSProps::gPropertyEnabled[eCSSProperty_COUNT_with_aliases] = {
   #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,     \
                    kwtable_, stylestruct_, stylestructoffset_, animtype_) \
     true,
-  #define CSS_PROP_LIST_INCLUDE_LOGICAL
   #include "nsCSSPropList.h"
-  #undef CSS_PROP_LIST_INCLUDE_LOGICAL
   #undef CSS_PROP
 
   #define  CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) \
     true,
   #include "nsCSSPropList.h"
   #undef CSS_PROP_SHORTHAND
 
   #define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_) \
     true,
   #include "nsCSSPropAliasList.h"
   #undef CSS_PROP_ALIAS
 };
-
-// Check that all properties defined using CSS_PROP_*_LOGICAL macros use
-// the CSS_PROPERTY_LOGICAL flag.
-#define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,         \
-                 kwtable_, stylestruct_, stylestructoffset_, animtype_)     \
-  static_assert(!((flags_) & CSS_PROPERTY_LOGICAL),                         \
-                "only properties defined with CSS_PROP_LOGICAL can use "    \
-                "the CSS_PROPERTY_LOGICAL flag");
-#define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, \
-                         kwtable_, stylestruct_, stylestructoffset_,        \
-                         animtype_)                                         \
-  static_assert((flags_) & CSS_PROPERTY_LOGICAL,                            \
-                "properties defined with CSS_PROP_LOGICAL must also use "   \
-                "the CSS_PROPERTY_LOGICAL flag");
-#include "nsCSSPropList.h"
-#undef CSS_PROP_LOGICAL
-#undef CSS_PROP
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -98,18 +98,19 @@
 #define VARIANT_LPCALC (VARIANT_LCALC | VARIANT_PERCENT)
 #define VARIANT_LNCALC (VARIANT_LCALC | VARIANT_NUMBER)
 #define VARIANT_LPNCALC (VARIANT_LNCALC | VARIANT_PERCENT)
 #define VARIANT_IMAGE   (VARIANT_URL | VARIANT_NONE | VARIANT_GRADIENT | \
                         VARIANT_IMAGE_RECT | VARIANT_ELEMENT)
 
 // Flags for the kFlagsTable bitfield (flags_ in nsCSSPropList.h)
 
-// This property is a logical property (such as padding-inline-start).
-#define CSS_PROPERTY_LOGICAL                      (1<<0)
+// A property that is a *-ltr-source or *-rtl-source property for one of
+// the directional pseudo-shorthand properties.
+#define CSS_PROPERTY_DIRECTIONAL_SOURCE           (1<<0)
 
 #define CSS_PROPERTY_VALUE_LIST_USES_COMMAS       (1<<1) /* otherwise spaces */
 
 #define CSS_PROPERTY_APPLIES_TO_FIRST_LETTER      (1<<2)
 #define CSS_PROPERTY_APPLIES_TO_FIRST_LINE        (1<<3)
 #define CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE \
   (CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | CSS_PROPERTY_APPLIES_TO_FIRST_LINE)
 
@@ -125,17 +126,22 @@
 #define CSS_PROPERTY_START_IMAGE_LOADS            (1<<5)
 
 // Should be set only for properties with START_IMAGE_LOADS.  Indicates
 // that the property has an array value with a URL/image value at index
 // 0 in the array, rather than the URL/image being in the value or value
 // list.
 #define CSS_PROPERTY_IMAGE_IS_IN_ARRAY_0          (1<<6)
 
-// Flag (1<<7) is currently free.
+// This is a property for which the computed value should generally be
+// reported as the computed value of a property of a different name.  In
+// particular, the directional box properties (margin-left-value, etc.)
+// should be reported as being margin-left, etc.  Call
+// nsCSSProps::OtherNameFor to get the other property.
+#define CSS_PROPERTY_REPORT_OTHER_NAME            (1<<7)
 
 // This property allows calc() between lengths and percentages and
 // stores such calc() expressions in its style structs (typically in an
 // nsStyleCoord, although this is not the case for 'background-position'
 // and 'background-size').
 #define CSS_PROPERTY_STORES_CALC                  (1<<8)
 
 // Define what mechanism the CSS parser uses for parsing the property.
@@ -315,16 +321,21 @@ public:
   static bool IsPredefinedCounterStyle(const nsAString& aStyle);
   static bool IsPredefinedCounterStyle(const nsACString& aStyle);
 
   // Given a property enum, get the string value
   static const nsAFlatCString& GetStringValue(nsCSSProperty aProperty);
   static const nsAFlatCString& GetStringValue(nsCSSFontDesc aFontDesc);
   static const nsAFlatCString& GetStringValue(nsCSSCounterDesc aCounterDesc);
 
+  // Get the property to report the computed value of aProperty as being
+  // the computed value of.  aProperty must have the
+  // CSS_PROPERTY_REPORT_OTHER_NAME bit set.
+  static nsCSSProperty OtherNameFor(nsCSSProperty aProperty);
+
   // Given a CSS Property and a Property Enum Value
   // Return back a const nsString& representation of the
   // value. Return back nullstr if no value is found
   static const nsAFlatCString& LookupPropertyValue(nsCSSProperty aProperty, int32_t aValue);
 
   // Get a color name for a predefined color value like buttonhighlight or activeborder
   // Sets the aStr param to the name of the propertyID
   static bool GetColorName(int32_t aPropID, nsCString &aStr);
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -5863,32 +5863,28 @@ nsComputedDOMStyle::RegisterPrefChangeCa
   nsComputedStyleMap* data = GetComputedStyleMap();
 #define REGISTER_CALLBACK(pref_)                                             \
   if (pref_[0]) {                                                            \
     Preferences::RegisterCallback(MarkComputedStyleMapDirty, pref_, data);   \
   }
 #define CSS_PROP(prop_, id_, method_, flags_, pref_, parsevariant_,          \
                  kwtable_, stylestruct_, stylestructoffset_, animtype_)      \
   REGISTER_CALLBACK(pref_)
-#define CSS_PROP_LIST_INCLUDE_LOGICAL
 #include "nsCSSPropList.h"
-#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP
 #undef REGISTER_CALLBACK
 }
 
 /* static */ void
 nsComputedDOMStyle::UnregisterPrefChangeCallbacks()
 {
   nsComputedStyleMap* data = GetComputedStyleMap();
 #define UNREGISTER_CALLBACK(pref_)                                             \
   if (pref_[0]) {                                                              \
     Preferences::UnregisterCallback(MarkComputedStyleMapDirty, pref_, data);   \
   }
 #define CSS_PROP(prop_, id_, method_, flags_, pref_, parsevariant_,            \
                  kwtable_, stylestruct_, stylestructoffset_, animtype_)        \
   UNREGISTER_CALLBACK(pref_)
-#define CSS_PROP_LIST_INCLUDE_LOGICAL
 #include "nsCSSPropList.h"
-#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP
 #undef UNREGISTER_CALLBACK
 }
--- a/layout/style/nsDOMCSSDeclaration.h
+++ b/layout/style/nsDOMCSSDeclaration.h
@@ -74,28 +74,26 @@ public:
                                                                              \
   void                                                                       \
   Set##method_(const nsAString& aValue, mozilla::ErrorResult& rv)            \
   {                                                                          \
     rv = SetPropertyValue(eCSSProperty_##id_, aValue);                       \
   }
 
 #define CSS_PROP_LIST_EXCLUDE_INTERNAL
-#define CSS_PROP_LIST_INCLUDE_LOGICAL
 #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_)  \
   CSS_PROP(name_, id_, method_, flags_, pref_, X, X, X, X, X)
 #include "nsCSSPropList.h"
 
 #define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_)  \
   CSS_PROP(X, propid_, aliasmethod_, X, pref_, X, X, X, X, X)
 #include "nsCSSPropAliasList.h"
 #undef CSS_PROP_ALIAS
 
 #undef CSS_PROP_SHORTHAND
-#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP_LIST_EXCLUDE_INTERNAL
 #undef CSS_PROP
 #undef CSS_PROP_PUBLIC_OR_PRIVATE
 
   virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName) MOZ_OVERRIDE;
 
   virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
 
--- 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 or logical property");
+                      "backend-only property");
 
     return mValueStorage + mValueOffsets[sid] + indexInStruct;
   }
 
   const nsCSSValue* ValueFor(nsCSSProperty aProperty) const {
     return const_cast<nsRuleData*>(this)->ValueFor(aProperty);
   }
 
@@ -111,19 +111,17 @@ struct nsRuleData
       return mValueStorage + mValueOffsets[sid] + indexInStruct;             \
     }                                                                        \
     const nsCSSValue* ValueFor##method_() const {                            \
       return const_cast<nsRuleData*>(this)->ValueFor##method_();             \
     }
   #define CSS_PROP_BACKENDONLY(name_, id_, method_, flags_, pref_,           \
                              parsevariant_, kwtable_)                        \
     /* empty; backend-only structs are not in nsRuleData  */
-  #define CSS_PROP_LIST_EXCLUDE_LOGICAL
   #include "nsCSSPropList.h"
-  #undef CSS_PROP_LIST_EXCLUDE_LOGICAL
   #undef CSS_PROP
   #undef CSS_PROP_PUBLIC_OR_PRIVATE
   #undef CSS_PROP_BACKENDONLY
 
 private:
   inline size_t GetPoisonOffset();
 
 };
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -2567,16 +2567,75 @@ nsRuleNode::SetDefaultOnRoot(const nsSty
        * last item of nsStyleStructID, to know its length.
        */
       NS_ABORT_IF_FALSE(false, "unexpected SID");
       return nullptr;
   }
   return nullptr;
 }
 
+/*
+ * This function handles cascading of *-left or *-right box properties
+ * against *-start (which is L for LTR and R for RTL) or *-end (which is
+ * R for LTR and L for RTL).
+ *
+ * Cascading these properties correctly is hard because we need to
+ * cascade two properties as one, but which two properties depends on a
+ * third property ('direction').  We solve this by treating each of
+ * these properties (say, 'margin-start') as a shorthand that sets a
+ * property containing the value of the property specified
+ * ('margin-start-value') and sets a pair of properties
+ * ('margin-left-ltr-source' and 'margin-right-rtl-source') saying which
+ * of the properties we use.  Thus, when we want to compute the value of
+ * 'margin-left' when 'direction' is 'ltr', we look at the value of
+ * 'margin-left-ltr-source', which tells us whether to use the highest
+ * 'margin-left' in the cascade or the highest 'margin-start'.
+ *
+ * Finally, since we can compute the normal (*-left and *-right)
+ * properties in a loop, this function works by modifying the data we
+ * will use in that loop (which the caller must copy from the const
+ * input).
+ */
+void
+nsRuleNode::AdjustLogicalBoxProp(nsStyleContext* aContext,
+                                 const nsCSSValue& aLTRSource,
+                                 const nsCSSValue& aRTLSource,
+                                 const nsCSSValue& aLTRLogicalValue,
+                                 const nsCSSValue& aRTLLogicalValue,
+                                 mozilla::css::Side aSide,
+                                 nsCSSRect& aValueRect,
+                                 bool& aCanStoreInRuleTree)
+{
+  bool LTRlogical = aLTRSource.GetUnit() == eCSSUnit_Enumerated &&
+                      aLTRSource.GetIntValue() == NS_BOXPROP_SOURCE_LOGICAL;
+  bool RTLlogical = aRTLSource.GetUnit() == eCSSUnit_Enumerated &&
+                      aRTLSource.GetIntValue() == NS_BOXPROP_SOURCE_LOGICAL;
+  if (LTRlogical || RTLlogical) {
+    // We can't cache anything on the rule tree if we use any data from
+    // the style context, since data cached in the rule tree could be
+    // used with a style context with a different value.
+    aCanStoreInRuleTree = false;
+    uint8_t dir = aContext->StyleVisibility()->mDirection;
+
+    if (dir == NS_STYLE_DIRECTION_LTR) {
+      if (LTRlogical)
+        aValueRect.*(nsCSSRect::sides[aSide]) = aLTRLogicalValue;
+    } else {
+      if (RTLlogical)
+        aValueRect.*(nsCSSRect::sides[aSide]) = aRTLLogicalValue;
+    }
+  } else if (aLTRLogicalValue.GetUnit() == eCSSUnit_Inherit ||
+             aRTLLogicalValue.GetUnit() == eCSSUnit_Inherit) {
+    // It actually is valid to store this in the ruletree, since
+    // LTRlogical and RTLlogical are both false, but doing that will
+    // trigger asserts.  Silence those.
+    aCanStoreInRuleTree = false;
+  }
+}
+
 /**
  * Begin an nsRuleNode::Compute*Data function for an inherited struct.
  *
  * @param type_ The nsStyle* type this function computes.
  * @param ctorargs_ The arguments used for the default nsStyle* constructor.
  * @param data_ Variable (declared here) holding the result of this
  *              function.
  * @param parentdata_ Variable (declared here) holding the parent style
@@ -6438,23 +6497,38 @@ nsRuleNode::ComputeMarginData(void* aSta
                               const nsRuleData* aRuleData,
                               nsStyleContext* aContext,
                               nsRuleNode* aHighestNode,
                               const RuleDetail aRuleDetail,
                               const bool aCanStoreInRuleTree)
 {
   COMPUTE_START_RESET(Margin, (), margin, parentMargin)
 
-  // margin: length, percent, calc, inherit
-  const nsCSSProperty* subprops =
-    nsCSSProps::SubpropertyEntryFor(eCSSProperty_margin);
-  nsStyleCoord coord;
+  // margin: length, percent, auto, inherit
+  nsStyleCoord  coord;
+  nsCSSRect ourMargin;
+  ourMargin.mTop = *aRuleData->ValueForMarginTop();
+  ourMargin.mRight = *aRuleData->ValueForMarginRightValue();
+  ourMargin.mBottom = *aRuleData->ValueForMarginBottom();
+  ourMargin.mLeft = *aRuleData->ValueForMarginLeftValue();
+  AdjustLogicalBoxProp(aContext,
+                       *aRuleData->ValueForMarginLeftLTRSource(),
+                       *aRuleData->ValueForMarginLeftRTLSource(),
+                       *aRuleData->ValueForMarginStartValue(),
+                       *aRuleData->ValueForMarginEndValue(),
+                       NS_SIDE_LEFT, ourMargin, canStoreInRuleTree);
+  AdjustLogicalBoxProp(aContext,
+                       *aRuleData->ValueForMarginRightLTRSource(),
+                       *aRuleData->ValueForMarginRightRTLSource(),
+                       *aRuleData->ValueForMarginEndValue(),
+                       *aRuleData->ValueForMarginStartValue(),
+                       NS_SIDE_RIGHT, ourMargin, canStoreInRuleTree);
   NS_FOR_CSS_SIDES(side) {
     nsStyleCoord parentCoord = parentMargin->mMargin.Get(side);
-    if (SetCoord(*aRuleData->ValueFor(subprops[side]),
+    if (SetCoord(ourMargin.*(nsCSSRect::sides[side]),
                  coord, parentCoord,
                  SETCOORD_LPAH | SETCOORD_INITIAL_ZERO | SETCOORD_STORE_CALC |
                    SETCOORD_UNSET_INITIAL,
                  aContext, mPresContext, canStoreInRuleTree)) {
       margin->mMargin.Set(side, coord);
     }
   }
 
@@ -6581,22 +6655,37 @@ nsRuleNode::ComputeBorderData(void* aSta
 
   default:
     NS_ABORT_IF_FALSE(false,
                       nsPrintfCString("unrecognized shadow unit %d",
                                       boxShadowValue->GetUnit()).get());
   }
 
   // border-width, border-*-width: length, enum, inherit
-  nsStyleCoord coord;
-  {
-    const nsCSSProperty* subprops =
-      nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_width);
+  nsStyleCoord  coord;
+  nsCSSRect ourBorderWidth;
+  ourBorderWidth.mTop = *aRuleData->ValueForBorderTopWidth();
+  ourBorderWidth.mRight = *aRuleData->ValueForBorderRightWidthValue();
+  ourBorderWidth.mBottom = *aRuleData->ValueForBorderBottomWidth();
+  ourBorderWidth.mLeft = *aRuleData->ValueForBorderLeftWidthValue();
+  AdjustLogicalBoxProp(aContext,
+                       *aRuleData->ValueForBorderLeftWidthLTRSource(),
+                       *aRuleData->ValueForBorderLeftWidthRTLSource(),
+                       *aRuleData->ValueForBorderStartWidthValue(),
+                       *aRuleData->ValueForBorderEndWidthValue(),
+                       NS_SIDE_LEFT, ourBorderWidth, canStoreInRuleTree);
+  AdjustLogicalBoxProp(aContext,
+                       *aRuleData->ValueForBorderRightWidthLTRSource(),
+                       *aRuleData->ValueForBorderRightWidthRTLSource(),
+                       *aRuleData->ValueForBorderEndWidthValue(),
+                       *aRuleData->ValueForBorderStartWidthValue(),
+                       NS_SIDE_RIGHT, ourBorderWidth, canStoreInRuleTree);
+  { // scope for compilers with broken |for| loop scoping
     NS_FOR_CSS_SIDES(side) {
-      const nsCSSValue& value = *aRuleData->ValueFor(subprops[side]);
+      const nsCSSValue &value = ourBorderWidth.*(nsCSSRect::sides[side]);
       NS_ASSERTION(eCSSUnit_Percent != value.GetUnit(),
                    "Percentage borders not implemented yet "
                    "If implementing, make sure to fix all consumers of "
                    "nsStyleBorder, the IsPercentageAwareChild method, "
                    "the nsAbsoluteContainingBlock::FrameDependsOnContainer "
                    "method, the "
                    "nsLineLayout::IsPercentageAwareReplacedElement method "
                    "and probably some other places");
@@ -6629,21 +6718,36 @@ nsRuleNode::ComputeBorderData(void* aSta
       else {
         NS_ASSERTION(eCSSUnit_Null == value.GetUnit(),
                      "missing case handling border width");
       }
     }
   }
 
   // border-style, border-*-style: enum, inherit
-  {
-    const nsCSSProperty* subprops =
-      nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_style);
+  nsCSSRect ourBorderStyle;
+  ourBorderStyle.mTop = *aRuleData->ValueForBorderTopStyle();
+  ourBorderStyle.mRight = *aRuleData->ValueForBorderRightStyleValue();
+  ourBorderStyle.mBottom = *aRuleData->ValueForBorderBottomStyle();
+  ourBorderStyle.mLeft = *aRuleData->ValueForBorderLeftStyleValue();
+  AdjustLogicalBoxProp(aContext,
+                       *aRuleData->ValueForBorderLeftStyleLTRSource(),
+                       *aRuleData->ValueForBorderLeftStyleRTLSource(),
+                       *aRuleData->ValueForBorderStartStyleValue(),
+                       *aRuleData->ValueForBorderEndStyleValue(),
+                       NS_SIDE_LEFT, ourBorderStyle, canStoreInRuleTree);
+  AdjustLogicalBoxProp(aContext,
+                       *aRuleData->ValueForBorderRightStyleLTRSource(),
+                       *aRuleData->ValueForBorderRightStyleRTLSource(),
+                       *aRuleData->ValueForBorderEndStyleValue(),
+                       *aRuleData->ValueForBorderStartStyleValue(),
+                       NS_SIDE_RIGHT, ourBorderStyle, canStoreInRuleTree);
+  { // scope for compilers with broken |for| loop scoping
     NS_FOR_CSS_SIDES(side) {
-      const nsCSSValue& value = *aRuleData->ValueFor(subprops[side]);
+      const nsCSSValue &value = ourBorderStyle.*(nsCSSRect::sides[side]);
       nsCSSUnit unit = value.GetUnit();
       NS_ABORT_IF_FALSE(eCSSUnit_None != unit,
                         "'none' should be handled as enumerated value");
       if (eCSSUnit_Enumerated == unit) {
         border->SetBorderStyle(side, value.GetIntValue());
       }
       else if (eCSSUnit_Initial == unit ||
                eCSSUnit_Unset == unit) {
@@ -6713,22 +6817,37 @@ nsRuleNode::ComputeBorderData(void* aSta
     }
 
     default:
       NS_ABORT_IF_FALSE(false, "unrecognized border color unit");
     }
   }
 
   // border-color, border-*-color: color, string, enum, inherit
-  {
-    const nsCSSProperty* subprops =
-      nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_color);
-    bool foreground;
+  bool foreground;
+  nsCSSRect ourBorderColor;
+  ourBorderColor.mTop = *aRuleData->ValueForBorderTopColor();
+  ourBorderColor.mRight = *aRuleData->ValueForBorderRightColorValue();
+  ourBorderColor.mBottom = *aRuleData->ValueForBorderBottomColor();
+  ourBorderColor.mLeft = *aRuleData->ValueForBorderLeftColorValue();
+  AdjustLogicalBoxProp(aContext,
+                       *aRuleData->ValueForBorderLeftColorLTRSource(),
+                       *aRuleData->ValueForBorderLeftColorRTLSource(),
+                       *aRuleData->ValueForBorderStartColorValue(),
+                       *aRuleData->ValueForBorderEndColorValue(),
+                       NS_SIDE_LEFT, ourBorderColor, canStoreInRuleTree);
+  AdjustLogicalBoxProp(aContext,
+                       *aRuleData->ValueForBorderRightColorLTRSource(),
+                       *aRuleData->ValueForBorderRightColorRTLSource(),
+                       *aRuleData->ValueForBorderEndColorValue(),
+                       *aRuleData->ValueForBorderStartColorValue(),
+                       NS_SIDE_RIGHT, ourBorderColor, canStoreInRuleTree);
+  { // scope for compilers with broken |for| loop scoping
     NS_FOR_CSS_SIDES(side) {
-      const nsCSSValue& value = *aRuleData->ValueFor(subprops[side]);
+      const nsCSSValue &value = ourBorderColor.*(nsCSSRect::sides[side]);
       if (eCSSUnit_Inherit == value.GetUnit()) {
         canStoreInRuleTree = false;
         if (parentContext) {
           parentBorder->GetBorderColor(side, borderColor, foreground);
           if (foreground) {
             // We want to inherit the color from the parent, not use the
             // color on the element where this chunk of style data will be
             // used.  We can ensure that the data for the parent are fully
@@ -6889,23 +7008,38 @@ 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, calc, inherit
-  const nsCSSProperty* subprops =
-    nsCSSProps::SubpropertyEntryFor(eCSSProperty_padding);
-  nsStyleCoord coord;
+  // 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);
   NS_FOR_CSS_SIDES(side) {
     nsStyleCoord parentCoord = parentPadding->mPadding.Get(side);
-    if (SetCoord(*aRuleData->ValueFor(subprops[side]),
+    if (SetCoord(ourPadding.*(nsCSSRect::sides[side]),
                  coord, parentCoord,
                  SETCOORD_LPH | SETCOORD_INITIAL_ZERO | SETCOORD_STORE_CALC |
                    SETCOORD_UNSET_INITIAL,
                  aContext, mPresContext, canStoreInRuleTree)) {
       padding->mPadding.Set(side, coord);
     }
   }
 
@@ -9350,36 +9484,44 @@ nsRuleNode::HasAuthorSpecifiedRules(nsSt
     eCSSProperty_background_color,
     eCSSProperty_background_image,
   };
 
   static const nsCSSProperty borderValues[] = {
     eCSSProperty_border_top_color,
     eCSSProperty_border_top_style,
     eCSSProperty_border_top_width,
-    eCSSProperty_border_right_color,
-    eCSSProperty_border_right_style,
-    eCSSProperty_border_right_width,
+    eCSSProperty_border_right_color_value,
+    eCSSProperty_border_right_style_value,
+    eCSSProperty_border_right_width_value,
     eCSSProperty_border_bottom_color,
     eCSSProperty_border_bottom_style,
     eCSSProperty_border_bottom_width,
-    eCSSProperty_border_left_color,
-    eCSSProperty_border_left_style,
-    eCSSProperty_border_left_width,
+    eCSSProperty_border_left_color_value,
+    eCSSProperty_border_left_style_value,
+    eCSSProperty_border_left_width_value,
+    eCSSProperty_border_start_color_value,
+    eCSSProperty_border_start_style_value,
+    eCSSProperty_border_start_width_value,
+    eCSSProperty_border_end_color_value,
+    eCSSProperty_border_end_style_value,
+    eCSSProperty_border_end_width_value,
     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,
+    eCSSProperty_padding_right_value,
     eCSSProperty_padding_bottom,
-    eCSSProperty_padding_left,
+    eCSSProperty_padding_left_value,
+    eCSSProperty_padding_start_value,
+    eCSSProperty_padding_end_value,
   };
 
   static const nsCSSProperty textShadowValues[] = {
     eCSSProperty_text_shadow
   };
 
   // Number of properties we care about
   size_t nValues = 0;
--- a/layout/style/nsRuleNode.h
+++ b/layout/style/nsRuleNode.h
@@ -638,16 +638,25 @@ protected:
                       bool aStartStruct,
                       bool& aCanStoreInRuleTree);
 
   static void SetGenericFont(nsPresContext* aPresContext,
                              nsStyleContext* aContext,
                              uint8_t aGenericFontID,
                              nsStyleFont* aFont);
 
+  void AdjustLogicalBoxProp(nsStyleContext* aContext,
+                            const nsCSSValue& aLTRSource,
+                            const nsCSSValue& aRTLSource,
+                            const nsCSSValue& aLTRLogicalValue,
+                            const nsCSSValue& aRTLLogicalValue,
+                            mozilla::css::Side aSide,
+                            nsCSSRect& aValueRect,
+                            bool& aCanStoreInRuleTree);
+
   inline RuleDetail CheckSpecifiedProperties(const nsStyleStructID aSID,
                                              const nsRuleData* aRuleData);
 
   already_AddRefed<nsCSSShadowArray>
               GetShadowData(const nsCSSValueList* aList,
                             nsStyleContext* aContext,
                             bool aIsBoxShadow,
                             bool& aCanStoreInRuleTree);
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -51,16 +51,20 @@ static inline mozilla::css::Side operato
 #define NS_FULL_TO_HALF_CORNER(var_, vert_) ((var_)*2 + !!(vert_))
 
 #define NS_SIDE_IS_VERTICAL(side_) ((side_) % 2)
 #define NS_SIDE_TO_FULL_CORNER(side_, second_) \
   (((side_) + !!(second_)) % 4)
 #define NS_SIDE_TO_HALF_CORNER(side_, second_, parallel_) \
   ((((side_) + !!(second_))*2 + ((side_) + !(parallel_))%2) % 8)
 
+// {margin,border-{width,style,color},padding}-{left,right}-{ltr,rtl}-source
+#define NS_BOXPROP_SOURCE_PHYSICAL 0
+#define NS_BOXPROP_SOURCE_LOGICAL  1
+
 // box-sizing
 #define NS_STYLE_BOX_SIZING_CONTENT       0
 #define NS_STYLE_BOX_SIZING_PADDING       1
 #define NS_STYLE_BOX_SIZING_BORDER        2
 
 // clip-path sizing
 #define NS_STYLE_CLIP_SHAPE_SIZING_NOBOX   0
 #define NS_STYLE_CLIP_SHAPE_SIZING_CONTENT 1
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -999,19 +999,19 @@ struct ColorIndexSet {
 static const ColorIndexSet gVisitedIndices[2] = { { 0, 0 }, { 1, 0 } };
 
 nscolor
 nsStyleContext::GetVisitedDependentColor(nsCSSProperty aProperty)
 {
   NS_ASSERTION(aProperty == eCSSProperty_color ||
                aProperty == eCSSProperty_background_color ||
                aProperty == eCSSProperty_border_top_color ||
-               aProperty == eCSSProperty_border_right_color ||
+               aProperty == eCSSProperty_border_right_color_value ||
                aProperty == eCSSProperty_border_bottom_color ||
-               aProperty == eCSSProperty_border_left_color ||
+               aProperty == eCSSProperty_border_left_color_value ||
                aProperty == eCSSProperty_outline_color ||
                aProperty == eCSSProperty__moz_column_rule_color ||
                aProperty == eCSSProperty_text_decoration_color ||
                aProperty == eCSSProperty_fill ||
                aProperty == eCSSProperty_stroke,
                "we need to add to nsStyleContext::CalcStyleDifference");
 
   bool isPaintProperty = aProperty == eCSSProperty_fill ||
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -690,16 +690,20 @@ nsTransitionManager::FlushTransitions(Fl
           MOZ_ASSERT(player->GetSource(),
                      "Transitions should have source content");
           ComputedTiming computedTiming =
             player->GetSource()->GetComputedTiming();
           if (computedTiming.mPhase == ComputedTiming::AnimationPhase_After) {
             MOZ_ASSERT(player->GetSource()->Properties().Length() == 1,
                        "Should have one animation property for a transition");
             nsCSSProperty prop = player->GetSource()->Properties()[0].mProperty;
+            if (nsCSSProps::PropHasFlags(prop, CSS_PROPERTY_REPORT_OTHER_NAME))
+            {
+              prop = nsCSSProps::OtherNameFor(prop);
+            }
             TimeDuration duration =
               player->GetSource()->Timing().mIterationDuration;
             events.AppendElement(
               TransitionEventInfo(collection->mElement, prop,
                                   duration,
                                   collection->PseudoElement()));
 
             // Leave this transition in the list for one more refresh
--- a/layout/style/test/ListCSSProperties.cpp
+++ b/layout/style/test/ListCSSProperties.cpp
@@ -16,42 +16,38 @@ struct PropertyInfo {
 };
 
 const PropertyInfo gLonghandProperties[] = {
 
 #define CSS_PROP_PUBLIC_OR_PRIVATE(publicname_, privatename_) publicname_
 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
                  stylestruct_, stylestructoffset_, animtype_)                 \
     { #name_, #method_, pref_ },
-#define CSS_PROP_LIST_INCLUDE_LOGICAL
 
 #include "nsCSSPropList.h"
 
-#undef CSS_PROP_LIST_EXCLUDE_LOGICAL
 #undef CSS_PROP
 #undef CSS_PROP_PUBLIC_OR_PRIVATE
 
 };
 
 /*
  * These are the properties for which domName in the above list should
  * be used.  They're in the same order as the above list, with some
  * items skipped.
  */
 const char* gLonghandPropertiesWithDOMProp[] = {
 
 #define CSS_PROP_LIST_EXCLUDE_INTERNAL
 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
                  stylestruct_, stylestructoffset_, animtype_)                 \
     #name_,
-#define CSS_PROP_LIST_INCLUDE_LOGICAL
 
 #include "nsCSSPropList.h"
 
-#undef CSS_PROP_LIST_INCLUDE_LOGICAL
 #undef CSS_PROP
 #undef CSS_PROP_LIST_EXCLUDE_INTERNAL
 
 };
 
 const PropertyInfo gShorthandProperties[] = {
 
 #define CSS_PROP_PUBLIC_OR_PRIVATE(publicname_, privatename_) publicname_
@@ -103,16 +99,56 @@ const char* gShorthandPropertiesWithDOMP
 const char *gInaccessibleProperties[] = {
     // Don't print the properties that aren't accepted by the parser, per
     // CSSParserImpl::ParseProperty
     "-x-cols",
     "-x-lang",
     "-x-span",
     "-x-system-font",
     "-x-text-zoom",
+    "border-end-color-value",
+    "border-end-style-value",
+    "border-end-width-value",
+    "border-left-color-value",
+    "border-left-color-ltr-source",
+    "border-left-color-rtl-source",
+    "border-left-style-value",
+    "border-left-style-ltr-source",
+    "border-left-style-rtl-source",
+    "border-left-width-value",
+    "border-left-width-ltr-source",
+    "border-left-width-rtl-source",
+    "border-right-color-value",
+    "border-right-color-ltr-source",
+    "border-right-color-rtl-source",
+    "border-right-style-value",
+    "border-right-style-ltr-source",
+    "border-right-style-rtl-source",
+    "border-right-width-value",
+    "border-right-width-ltr-source",
+    "border-right-width-rtl-source",
+    "border-start-color-value",
+    "border-start-style-value",
+    "border-start-width-value",
+    "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,3 +1,11 @@
 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/mochitest.ini
+++ b/layout/style/test/mochitest.ini
@@ -238,17 +238,16 @@ skip-if = buildapp == 'b2g' || toolkit =
 [test_visited_lying.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262, :visited support) b2g-debug(bug 870262, :visited support) b2g-desktop(bug 870262, :visited support)
 [test_visited_pref.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262, :visited support) b2g-debug(bug 870262, :visited support) b2g-desktop(bug 870262, :visited support)
 [test_visited_reftests.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262, :visited support) b2g-debug(bug 870262, :visited support) b2g-desktop(bug 870262, :visited support)
 [test_bug525952.html]
 [test_load_events_on_stylesheets.html]
-[test_logical_properties.html]
 [test_page_parser.html]
 [test_bug732153.html]
 [test_bug732209.html]
 support-files = bug732209-css.sjs
 [test_bug795520.html]
 [test_background_blend_mode.html]
 [test_property_database.html]
 [test_counter_style.html]
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -17,18 +17,16 @@ const CSS_TYPE_SHORTHAND_AND_LONGHAND = 
 // Each property has the following fields:
 //   domProp: The name of the relevant member of nsIDOM[NS]CSS2Properties
 //   inherited: Whether the property is inherited by default (stated as
 //     yes or no in the property header in all CSS specs)
 //   type: see above
 //   alias_for: optional, indicates that the property is an alias for
 //     some other property that is the preferred serialization.  (Type
 //     must not be CSS_TYPE_LONGHAND.)
-//   logical: optional, indicates that the property is a logical directional
-//     property.  (Type must be CSS_TYPE_LONGHAND.)
 //   get_computed: if present, the property's computed value shows up on
 //     another property, and this is a function used to get it
 //   initial_values: Values whose computed value should be the same as the
 //     computed value for the property's initial value.
 //   other_values: Values whose computed value should be different from the
 //     computed value for the property's initial value.
 //   XXX Should have a third field for values whose computed value may or
 //     may not be the same as for the property's initial value.
@@ -692,39 +690,36 @@ var gCSSProperties = {
     subproperties: [ "-moz-border-end-color", "-moz-border-end-style", "-moz-border-end-width" ],
     initial_values: [ "none", "medium", "currentColor", "thin", "none medium currentcolor" ],
     other_values: [ "solid", "green", "medium solid", "green solid", "10px solid", "thick solid", "5px green none" ],
     invalid_values: [ "5%", "5", "5 green none" ]
   },
   "-moz-border-end-color": {
     domProp: "MozBorderEndColor",
     inherited: false,
-    type: CSS_TYPE_LONGHAND,
-    logical: true,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     get_computed: logical_box_prop_get_computed,
     initial_values: [ "currentColor" ],
     other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ],
     invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "000000" ]
   },
   "-moz-border-end-style": {
     domProp: "MozBorderEndStyle",
     inherited: false,
-    type: CSS_TYPE_LONGHAND,
-    logical: true,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     get_computed: logical_box_prop_get_computed,
     /* XXX hidden is sometimes the same as initial */
     initial_values: [ "none" ],
     other_values: [ "solid", "dashed", "dotted", "double", "outset", "inset", "groove", "ridge" ],
     invalid_values: []
   },
   "-moz-border-end-width": {
     domProp: "MozBorderEndWidth",
     inherited: false,
-    type: CSS_TYPE_LONGHAND,
-    logical: true,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     get_computed: logical_box_prop_get_computed,
     prerequisites: { "-moz-border-end-style": "solid" },
     initial_values: [ "medium", "3px", "calc(4px - 1px)" ],
     other_values: [ "thin", "thick", "1px", "2em",
       "calc(2px)",
       "calc(-2px)",
       "calc(0em)",
       "calc(0px)",
@@ -938,39 +933,36 @@ var gCSSProperties = {
     subproperties: [ "-moz-border-start-color", "-moz-border-start-style", "-moz-border-start-width" ],
     initial_values: [ "none", "medium", "currentColor", "thin", "none medium currentcolor" ],
     other_values: [ "solid", "green", "medium solid", "green solid", "10px solid", "thick solid", "5px green none" ],
     invalid_values: [ "5%", "5", "5 green solid" ]
   },
   "-moz-border-start-color": {
     domProp: "MozBorderStartColor",
     inherited: false,
-    type: CSS_TYPE_LONGHAND,
-    logical: true,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     get_computed: logical_box_prop_get_computed,
     initial_values: [ "currentColor" ],
     other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ],
     invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "000000" ]
   },
   "-moz-border-start-style": {
     domProp: "MozBorderStartStyle",
     inherited: false,
-    type: CSS_TYPE_LONGHAND,
-    logical: true,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     get_computed: logical_box_prop_get_computed,
     /* XXX hidden is sometimes the same as initial */
     initial_values: [ "none" ],
     other_values: [ "solid", "dashed", "dotted", "double", "outset", "inset", "groove", "ridge" ],
     invalid_values: []
   },
   "-moz-border-start-width": {
     domProp: "MozBorderStartWidth",
     inherited: false,
-    type: CSS_TYPE_LONGHAND,
-    logical: true,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     get_computed: logical_box_prop_get_computed,
     prerequisites: { "-moz-border-start-style": "solid" },
     initial_values: [ "medium", "3px", "calc(4px - 1px)" ],
     other_values: [ "thin", "thick", "1px", "2em",
       "calc(2px)",
       "calc(-2px)",
       "calc(0em)",
       "calc(0px)",
@@ -1433,18 +1425,17 @@ var gCSSProperties = {
     type: CSS_TYPE_LONGHAND,
     initial_values: [ "auto" ],
     other_values: [ "rect(3px 20px 15px 4px)", "rect(17px, 21px, 33px, 2px)" ],
     invalid_values: [ "rect(17px, 21px, 33, 2px)" ]
   },
   "-moz-margin-end": {
     domProp: "MozMarginEnd",
     inherited: false,
-    type: CSS_TYPE_LONGHAND,
-    logical: true,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     get_computed: logical_box_prop_get_computed,
     /* no subproperties */
     /* auto may or may not be initial */
     initial_values: [ "0", "0px", "0%", "0em", "0ex", "calc(0pt)", "calc(0% + 0px)" ],
     other_values: [ "1px", "3em",
       "calc(2px)",
       "calc(-2px)",
       "calc(50%)",
@@ -1452,18 +1443,17 @@ var gCSSProperties = {
       "calc(25px*3)",
       "calc(3*25px + 50%)",
     ],
     invalid_values: [ "5" ]
   },
   "-moz-margin-start": {
     domProp: "MozMarginStart",
     inherited: false,
-    type: CSS_TYPE_LONGHAND,
-    logical: true,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     get_computed: logical_box_prop_get_computed,
     /* no subproperties */
     /* auto may or may not be initial */
     initial_values: [ "0", "0px", "0%", "0em", "0ex", "calc(0pt)", "calc(0% + 0px)" ],
     other_values: [ "1px", "3em",
       "calc(2px)",
       "calc(-2px)",
       "calc(50%)",
@@ -1569,35 +1559,33 @@ 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_LONGHAND,
-    logical: true,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     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_LONGHAND,
-    logical: true,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     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)",
@@ -2140,36 +2128,36 @@ var gCSSProperties = {
     subproperties: [ "border-left-color", "border-left-style", "border-left-width" ],
     initial_values: [ "none", "medium", "currentColor", "thin", "none medium currentcolor" ],
     other_values: [ "solid", "green", "medium solid", "green solid", "10px solid", "thick solid", "5px green none" ],
     invalid_values: [ "5%", "5", "5 solid green" ]
   },
   "border-left-color": {
     domProp: "borderLeftColor",
     inherited: false,
-    type: CSS_TYPE_LONGHAND,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     prerequisites: { "color": "black" },
     initial_values: [ "currentColor", "-moz-use-text-color" ],
     other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ],
     invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000" ],
     quirks_values: { "000000": "#000000", "96ed2a": "#96ed2a" },
   },
   "border-left-style": {
     domProp: "borderLeftStyle",
     inherited: false,
-    type: CSS_TYPE_LONGHAND,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     /* XXX hidden is sometimes the same as initial */
     initial_values: [ "none" ],
     other_values: [ "solid", "dashed", "dotted", "double", "outset", "inset", "groove", "ridge" ],
     invalid_values: []
   },
   "border-left-width": {
     domProp: "borderLeftWidth",
     inherited: false,
-    type: CSS_TYPE_LONGHAND,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     prerequisites: { "border-left-style": "solid" },
     initial_values: [ "medium", "3px", "calc(4px - 1px)" ],
     other_values: [ "thin", "thick", "1px", "2em",
       "calc(2px)",
       "calc(-2px)",
       "calc(0em)",
       "calc(0px)",
       "calc(5em)",
@@ -2187,36 +2175,36 @@ var gCSSProperties = {
     subproperties: [ "border-right-color", "border-right-style", "border-right-width" ],
     initial_values: [ "none", "medium", "currentColor", "thin", "none medium currentcolor" ],
     other_values: [ "solid", "green", "medium solid", "green solid", "10px solid", "thick solid", "5px green none" ],
     invalid_values: [ "5%", "5", "5 solid green" ]
   },
   "border-right-color": {
     domProp: "borderRightColor",
     inherited: false,
-    type: CSS_TYPE_LONGHAND,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     prerequisites: { "color": "black" },
     initial_values: [ "currentColor", "-moz-use-text-color" ],
     other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ],
     invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000" ],
     quirks_values: { "000000": "#000000", "96ed2a": "#96ed2a" },
   },
   "border-right-style": {
     domProp: "borderRightStyle",
     inherited: false,
-    type: CSS_TYPE_LONGHAND,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     /* XXX hidden is sometimes the same as initial */
     initial_values: [ "none" ],
     other_values: [ "solid", "dashed", "dotted", "double", "outset", "inset", "groove", "ridge" ],
     invalid_values: []
   },
   "border-right-width": {
     domProp: "borderRightWidth",
     inherited: false,
-    type: CSS_TYPE_LONGHAND,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     prerequisites: { "border-right-style": "solid" },
     initial_values: [ "medium", "3px", "calc(4px - 1px)" ],
     other_values: [ "thin", "thick", "1px", "2em",
       "calc(2px)",
       "calc(-2px)",
       "calc(0em)",
       "calc(0px)",
       "calc(5em)",
@@ -2854,34 +2842,36 @@ var gCSSProperties = {
       "calc(3*25px + 50%)",
     ],
     invalid_values: [ ],
     quirks_values: { "5": "5px" },
   },
   "margin-left": {
     domProp: "marginLeft",
     inherited: false,
-    type: CSS_TYPE_LONGHAND,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
+    /* no subproperties */
     /* XXX testing auto has prerequisites */
     initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)" ],
     other_values: [ "1px", "2em", "5%", ".5px", "+32px", "+.789px", "-.328px", "+0.56px", "-0.974px", "237px", "-289px", "-056px", "1987.45px", "-84.32px",
       "calc(2px)",
       "calc(-2px)",
       "calc(50%)",
       "calc(3*25px)",
       "calc(25px*3)",
       "calc(3*25px + 50%)",
     ],
     invalid_values: [ "..25px", ".+5px", ".px", "-.px", "++5px", "-+4px", "+-3px", "--7px", "+-.6px", "-+.5px", "++.7px", "--.4px" ],
     quirks_values: { "5": "5px" },
   },
   "margin-right": {
     domProp: "marginRight",
     inherited: false,
-    type: CSS_TYPE_LONGHAND,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
+    /* no subproperties */
     /* XXX testing auto has prerequisites */
     initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)" ],
     other_values: [ "1px", "2em", "5%",
       "calc(2px)",
       "calc(-2px)",
       "calc(50%)",
       "calc(3*25px)",
       "calc(25px*3)",
@@ -3125,32 +3115,34 @@ var gCSSProperties = {
       "calc(3*25px + 50%)",
     ],
     invalid_values: [ ],
     quirks_values: { "5": "5px" },
   },
   "padding-left": {
     domProp: "paddingLeft",
     inherited: false,
-    type: CSS_TYPE_LONGHAND,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
+    /* no subproperties */
     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_LONGHAND,
+    type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
+    /* no subproperties */
     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%)",
     ],
@@ -4521,37 +4513,23 @@ var gCSSProperties = {
     initial_values: [ "normal" ],
     other_values: [ "'ENG'", "'TRK'", "\"TRK\"", "'N\\'Ko'" ],
     invalid_values: [ "TRK", "ja" ]
   }
 }
 
 function logical_box_prop_get_computed(cs, 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 {
+  if (! /^-moz-/.test(property))
     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];
@@ -4612,187 +4590,17 @@ 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" ]
-    },
-    "border-inline-end": {
-      domProp: "borderInlineEnd",
-      inherited: false,
-      type: CSS_TYPE_TRUE_SHORTHAND,
-      alias_for: "-moz-border-end",
-      subproperties: [ "border-inline-end-color", "border-inline-end-style", "border-inline-end-width" ],
-      initial_values: [ "none", "medium", "currentColor", "thin", "none medium currentcolor" ],
-      other_values: [ "solid", "green", "medium solid", "green solid", "10px solid", "thick solid", "5px green none" ],
-      invalid_values: [ "5%", "5", "5 green none" ]
-    },
-    "border-inline-end-color": {
-      domProp: "borderInlineEndColor",
-      inherited: false,
-      type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
-      alias_for: "-moz-border-end-color",
-      get_computed: logical_box_prop_get_computed,
-      initial_values: [ "currentColor" ],
-      other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ],
-      invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "000000" ]
-    },
-    "border-inline-end-style": {
-      domProp: "borderInlineEndStyle",
-      inherited: false,
-      type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
-      alias_for: "-moz-border-end-style",
-      get_computed: logical_box_prop_get_computed,
-      /* XXX hidden is sometimes the same as initial */
-      initial_values: [ "none" ],
-      other_values: [ "solid", "dashed", "dotted", "double", "outset", "inset", "groove", "ridge" ],
-      invalid_values: []
-    },
-    "border-inline-end-width": {
-      domProp: "borderInlineEndWidth",
-      inherited: false,
-      type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
-      alias_for: "-moz-border-end-width",
-      get_computed: logical_box_prop_get_computed,
-      prerequisites: { "border-inline-end-style": "solid" },
-      initial_values: [ "medium", "3px", "calc(4px - 1px)" ],
-      other_values: [ "thin", "thick", "1px", "2em",
-        "calc(2px)",
-        "calc(-2px)",
-        "calc(0em)",
-        "calc(0px)",
-        "calc(5em)",
-        "calc(3*25px)",
-        "calc(25px*3)",
-        "calc(3*25px + 5em)",
-      ],
-      invalid_values: [ "5%", "5" ]
-    },
-    "border-inline-start": {
-      domProp: "borderInlineStart",
-      inherited: false,
-      type: CSS_TYPE_TRUE_SHORTHAND,
-      alias_for: "-moz-border-start",
-      subproperties: [ "border-inline-start-color", "border-inline-start-style", "border-inline-start-width" ],
-      initial_values: [ "none", "medium", "currentColor", "thin", "none medium currentcolor" ],
-      other_values: [ "solid", "green", "medium solid", "green solid", "10px solid", "thick solid", "5px green none" ],
-      invalid_values: [ "5%", "5", "5 green solid" ]
-    },
-    "border-inline-start-color": {
-      domProp: "borderInlineStartColor",
-      inherited: false,
-      type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
-      alias_for: "-moz-border-start-color",
-      get_computed: logical_box_prop_get_computed,
-      initial_values: [ "currentColor" ],
-      other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ],
-      invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "000000" ]
-    },
-    "border-inline-start-style": {
-      domProp: "borderInlineStartStyle",
-      inherited: false,
-      type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
-      alias_for: "-moz-border-start-style",
-      get_computed: logical_box_prop_get_computed,
-      /* XXX hidden is sometimes the same as initial */
-      initial_values: [ "none" ],
-      other_values: [ "solid", "dashed", "dotted", "double", "outset", "inset", "groove", "ridge" ],
-      invalid_values: []
-    },
-    "border-inline-start-width": {
-      domProp: "borderInlineStartWidth",
-      inherited: false,
-      type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
-      alias_for: "-moz-border-start-width",
-      get_computed: logical_box_prop_get_computed,
-      prerequisites: { "border-inline-start-style": "solid" },
-      initial_values: [ "medium", "3px", "calc(4px - 1px)" ],
-      other_values: [ "thin", "thick", "1px", "2em",
-        "calc(2px)",
-        "calc(-2px)",
-        "calc(0em)",
-        "calc(0px)",
-        "calc(5em)",
-        "calc(3*25px)",
-        "calc(25px*3)",
-        "calc(3*25px + 5em)",
-      ],
-      invalid_values: [ "5%", "5" ]
-    },
-    "margin-inline-end": {
-      domProp: "marginInlineEnd",
-      inherited: false,
-      type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
-      alias_for: "-moz-margin-end",
-      get_computed: logical_box_prop_get_computed,
-      /* XXX testing auto has prerequisites */
-      initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)" ],
-      other_values: [ "1px", "2em", "5%",
-        "calc(2px)",
-        "calc(-2px)",
-        "calc(50%)",
-        "calc(3*25px)",
-        "calc(25px*3)",
-        "calc(3*25px + 50%)",
-      ],
-      invalid_values: [ "..25px", ".+5px", ".px", "-.px", "++5px", "-+4px", "+-3px", "--7px", "+-.6px", "-+.5px", "++.7px", "--.4px" ],
-    },
-    "margin-inline-start": {
-      domProp: "marginInlineStart",
-      inherited: false,
-      type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
-      alias_for: "-moz-margin-start",
-      get_computed: logical_box_prop_get_computed,
-      /* XXX testing auto has prerequisites */
-      initial_values: [ "0", "0px", "0%", "calc(0pt)", "calc(0% + 0px)" ],
-      other_values: [ "1px", "2em", "5%",
-        "calc(2px)",
-        "calc(-2px)",
-        "calc(50%)",
-        "calc(3*25px)",
-        "calc(25px*3)",
-        "calc(3*25px + 50%)",
-      ],
-      invalid_values: [ "..25px", ".+5px", ".px", "-.px", "++5px", "-+4px", "+-3px", "--7px", "+-.6px", "-+.5px", "++.7px", "--.4px" ],
-    },
-    "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"] = {
deleted file mode 100644
--- a/layout/style/test/test_logical_properties.html
+++ /dev/null
@@ -1,273 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Test for handling of logical and physical properties</title>
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-<script src="/tests/SimpleTest/SimpleTest.js"></script>
-
-<style id="sheet"></style>
-<div id="test" class="test"></div>
-
-<script>
-var gSheet = document.getElementById("sheet");
-var gTest  = document.getElementById("test");
-
-// list of groups of physical and logical properties, such as
-// { left: "margin-left", right: "margin-right",
-//   inlineStart: "margin-inline-start", inlineEnd: "margin-inline-end",
-//   type: "length" }
-// where the type is a key from the gValues object
-var gPropertyGroups;
-
-// values to use while testing
-var gValues = {
-  "length":       ["1px", "2px", "3px"],
-  "color":        ["rgb(1, 1, 1)", "rgb(2, 2, 2)", "rgb(3, 3, 3)"],
-  "border-style": ["solid", "dashed", "dotted"],
-};
-
-function init() {
-  gPropertyGroups = [];
-
-  for (var p in gCSSProperties) {
-    var type = gCSSProperties[p].type;
-
-    if (type == CSS_TYPE_SHORTHAND_AND_LONGHAND && /-inline-end/.test(p)) {
-      var valueType;
-      if (/margin|padding|width/.test(p)) {
-        valueType = "length";
-      } else if (/color/.test(p)) {
-        valueType = "color";
-      } else if (/border.*style/.test(p)) {
-        valueType = "border-style";
-      } else {
-        throw `unexpected property ${p}`;
-      }
-      gPropertyGroups.push({
-        left:        p.replace("-inline-end", "-left"),
-        right:       p.replace("-inline-end", "-right"),
-        inlineStart: p.replace("-inline-end", "-inline-start"),
-        inlineEnd:   p,
-        type:        valueType
-      });
-    }
-  }
-}
-
-function test_computed_values(aTestName, aRules, aExpectedValues) {
-  gSheet.textContent = aRules;
-  var cs = getComputedStyle(gTest);
-  aExpectedValues.forEach(function(aPair) {
-    is(cs.getPropertyValue(aPair[0]), aPair[1], `${aTestName} ${aPair[0]}`);
-  });
-  gSheet.textContent = "";
-}
-
-function make_declaration(aObject) {
-  var decl = "";
-  if (aObject) {
-    for (var p in aObject) {
-      decl += `${p}: ${aObject[p]}; `;
-    }
-  }
-  return decl;
-}
-
-function start() {
-  // load property_database.js once the pref change has gone into effect
-  var script = document.createElement("script");
-  script.src = "property_database.js";
-  script.onload = function() {
-    init();
-    run_tests();
-  };
-  document.body.appendChild(script);
-}
-
-function run_tests() {
-  gPropertyGroups.forEach(function(aGroup) {
-    var values = gValues[aGroup.type];
-    var decl;
-
-    // Test that logical properties are converted to their physical equivalent
-    // correctly when present on a single declaration, with no overwriting of
-    // previous properties.
-
-    decl = `${aGroup.inlineStart}: ${values[0]}; ` +
-           `${aGroup.inlineEnd}: ${values[1]}; ` +
-           make_declaration(gCSSProperties[aGroup.left].prerequisites) +
-           make_declaration(gCSSProperties[aGroup.right].prerequisites);
-
-    test_computed_values("ltr inline single declaration",
-                         `.test { direction: ltr; ${decl} }`,
-                         [[aGroup.left,  values[0]],
-                          [aGroup.right, values[1]]]);
-
-    test_computed_values("rtl inline single declaration",
-                         `.test { direction: rtl; ${decl} }`,
-                         [[aGroup.left,  values[1]],
-                          [aGroup.right, values[0]]]);
-
-    // Test that logical and physical properties are cascaded together, honoring
-    // their relative order on a single declaration.
-
-    decl = `${aGroup.left}: ${values[0]}; ` +
-           `${aGroup.right}: ${values[1]}; ` +
-           `${aGroup.inlineStart}: ${values[2]}; ` +
-           make_declaration(gCSSProperties[aGroup.left].prerequisites) +
-           make_declaration(gCSSProperties[aGroup.right].prerequisites);
-
-    test_computed_values("ltr inline-start single declaration, logical last",
-                         `.test { direction: ltr; ${decl} }`,
-                         [[aGroup.left,  values[2]],
-                          [aGroup.right, values[1]]]);
-
-    test_computed_values("rtl inline-start single declaration, logical last",
-                         `.test { direction: rtl; ${decl} }`,
-                         [[aGroup.left,  values[0]],
-                          [aGroup.right, values[2]]]);
-
-    decl = `${aGroup.left}: ${values[0]}; ` +
-           `${aGroup.right}: ${values[1]}; ` +
-           `${aGroup.inlineEnd}: ${values[2]}; ` +
-           make_declaration(gCSSProperties[aGroup.left].prerequisites) +
-           make_declaration(gCSSProperties[aGroup.right].prerequisites);
-
-    test_computed_values("ltr inline-end single declaration, logical last",
-                         `.test { direction: ltr; ${decl} }`,
-                         [[aGroup.left,  values[0]],
-                          [aGroup.right, values[2]]]);
-
-    test_computed_values("rtl inline-end single declaration, logical last",
-                         `.test { direction: rtl; ${decl} }`,
-                         [[aGroup.left,  values[2]],
-                          [aGroup.right, values[1]]]);
-
-    decl = `${aGroup.inlineStart}: ${values[0]}; ` +
-           `${aGroup.inlineEnd}: ${values[1]}; ` +
-           `${aGroup.left}: ${values[2]}; ` +
-           make_declaration(gCSSProperties[aGroup.left].prerequisites) +
-           make_declaration(gCSSProperties[aGroup.right].prerequisites);
-
-    test_computed_values("ltr inline left single declaration, physical last",
-                         `.test { direction: ltr; ${decl} }`,
-                         [[aGroup.left,  values[2]],
-                          [aGroup.right, values[1]]]);
-
-    test_computed_values("rtl inline left single declaration, physical last",
-                         `.test { direction: rtl; ${decl} }`,
-                         [[aGroup.left,  values[2]],
-                          [aGroup.right, values[0]]]);
-
-    decl = `${aGroup.inlineStart}: ${values[0]}; ` +
-           `${aGroup.inlineEnd}: ${values[1]}; ` +
-           `${aGroup.right}: ${values[2]}; ` +
-           make_declaration(gCSSProperties[aGroup.left].prerequisites) +
-           make_declaration(gCSSProperties[aGroup.right].prerequisites);
-
-    test_computed_values("ltr inline right single declaration, physical last",
-                         `.test { direction: ltr; ${decl} }`,
-                         [[aGroup.left,  values[0]],
-                          [aGroup.right, values[2]]]);
-
-    test_computed_values("rtl inline right single declaration, physical last",
-                         `.test { direction: rtl; ${decl} }`,
-                         [[aGroup.left,  values[1]],
-                          [aGroup.right, values[2]]]);
-
-    // Test that logical and physical properties are cascaded properly when on
-    // different declarations.
-
-    var hiDecl;  // higher specificity
-    var loDecl;  // lower specifity
-
-    hiDecl = `${aGroup.inlineStart}: ${values[0]}; `;
-    loDecl = `${aGroup.left}: ${values[1]}; ` +
-             `${aGroup.right}: ${values[2]}; ` +
-             make_declaration(gCSSProperties[aGroup.left].prerequisites) +
-             make_declaration(gCSSProperties[aGroup.right].prerequisites);
-
-    test_computed_values("ltr inline-start two declarations",
-                         `#test { ${hiDecl} } ` +
-                         `.test { direction: ltr; ${loDecl} }`,
-                         [[aGroup.left,  values[0]],
-                          [aGroup.right, values[2]]]);
-
-    test_computed_values("rtl inline-start two declarations",
-                         `#test { ${hiDecl} } ` +
-                         `.test { direction: rtl; ${loDecl} }`,
-                         [[aGroup.left,  values[1]],
-                          [aGroup.right, values[0]]]);
-
-    hiDecl = `${aGroup.inlineEnd}: ${values[0]}; `;
-
-    test_computed_values("ltr inline-end two declarations",
-                         `#test { ${hiDecl} } ` +
-                         `.test { direction: ltr; ${loDecl} }`,
-                         [[aGroup.left,  values[1]],
-                          [aGroup.right, values[0]]]);
-
-    test_computed_values("rtl inline-end two declarations",
-                         `#test { ${hiDecl} } ` +
-                         `.test { direction: rtl; ${loDecl} }`,
-                         [[aGroup.left,  values[0]],
-                          [aGroup.right, values[2]]]);
-
-    hiDecl = `${aGroup.left}: ${values[0]}; `;
-    loDecl = `${aGroup.inlineStart}: ${values[1]}; ` +
-             `${aGroup.inlineEnd}: ${values[2]}; ` +
-             make_declaration(gCSSProperties[aGroup.left].prerequisites) +
-             make_declaration(gCSSProperties[aGroup.right].prerequisites);
-
-    test_computed_values("ltr inline left two declarations",
-                         `#test { ${hiDecl} } ` +
-                         `.test { direction: ltr; ${loDecl} }`,
-                         [[aGroup.left,  values[0]],
-                          [aGroup.right, values[2]]]);
-
-    test_computed_values("rtl inline left two declarations",
-                         `#test { ${hiDecl} } ` +
-                         `.test { direction: rtl; ${loDecl} }`,
-                         [[aGroup.left,  values[0]],
-                          [aGroup.right, values[1]]]);
-
-    hiDecl = `${aGroup.right}: ${values[0]}; `;
-
-    test_computed_values("ltr inline right two declarations",
-                         `#test { ${hiDecl} } ` +
-                         `.test { direction: ltr; ${loDecl} }`,
-                         [[aGroup.left,  values[1]],
-                          [aGroup.right, values[0]]]);
-
-    test_computed_values("rtl inline right two declarations",
-                         `#test { ${hiDecl} } ` +
-                         `.test { direction: rtl; ${loDecl} }`,
-                         [[aGroup.left,  values[2]],
-                          [aGroup.right, values[0]]]);
-
-    // Test that the computed value of direction is used, not the value on
-    // the declaration.
-
-    loDecl = `${aGroup.inlineStart}: ${values[0]}; ` +
-             `${aGroup.inlineEnd}: ${values[1]}; ` +
-             make_declaration(gCSSProperties[aGroup.left].prerequisites) +
-             make_declaration(gCSSProperties[aGroup.right].prerequisites);
-
-    test_computed_values("ltr on different declaration",
-                         `#test { direction: ltr; } ` +
-                         `.test { direction: rtl; ${loDecl} }`,
-                         [[aGroup.left,  values[0]],
-                          [aGroup.right, values[1]]]);
-
-    test_computed_values("rtl on different declaration",
-                         `#test { direction: rtl; } ` +
-                         `.test { direction: ltr; ${loDecl} }`,
-                         [[aGroup.left,  values[1]],
-                          [aGroup.right, values[0]]]);
-  });
-
-  SimpleTest.finish();
-}
-
-SimpleTest.waitForExplicitFinish();
-SpecialPowers.pushPrefEnv({ "set": [["layout.css.vertical-text.enabled", true]] }, start);
-</script>
--- a/layout/style/test/test_page_parser.html
+++ b/layout/style/test/test_page_parser.html
@@ -21,36 +21,54 @@
     // CSS 2.1 only allows margin properties in the page rule.
 
     // Check a bad property.
     { rule: "position: absolute;" },
 
     // Check good properties with invalid units.
     { rule: _("margin: 2in; margin: 2vw;"), expected: {
       "margin-top": "2in",
-      "margin-right": "2in",
+      "margin-right-value": "2in",
       "margin-bottom": "2in",
-      "margin-left": "2in"
+      "margin-left-value": "2in",
+      "margin-left-ltr-source": "physical",
+      "margin-left-rtl-source": "physical",
+      "margin-right-ltr-source": "physical",
+      "margin-right-rtl-source": "physical"
     }},
     { rule: _("margin-top: 2in; margin-top: 2vw;"), expected: {"margin-top": "2in"}},
     { rule: _("margin-top: 2in; margin-top: 2vh;"), expected: {"margin-top": "2in"}},
     { rule: _("margin-top: 2in; margin-top: 2vmax;"), expected: {"margin-top": "2in"}},
     { rule: _("margin-top: 2in; margin-top: 2vmin;"), expected: {"margin-top": "2in"}},
 
     // Check good properties.
+    // NOTE: The margin-*-value and margin-*-source properties are not really
+    // expected and will need to be removed once bug 241234 is addressed.
     { rule: _("margin: 2in;"), expected: {
       "margin-top": "2in",
-      "margin-right": "2in",
+      "margin-right-value": "2in",
       "margin-bottom": "2in",
-      "margin-left": "2in"
+      "margin-left-value": "2in",
+      "margin-left-ltr-source": "physical",
+      "margin-left-rtl-source": "physical",
+      "margin-right-ltr-source": "physical",
+      "margin-right-rtl-source": "physical"
     }},
     { rule: _("margin-top: 2in;"), expected: {"margin-top": "2in"}},
-    { rule: _("margin-left: 2in;"), expected: {"margin-left": "2in"}},
+    { rule: _("margin-left: 2in;"), expected: {
+      "margin-left-value": "2in",
+      "margin-left-ltr-source": "physical",
+      "margin-left-rtl-source": "physical",
+    }},
     { rule: _("margin-bottom: 2in;"), expected: {"margin-bottom": "2in"}},
-    { rule: _("margin-right: 2in;"), expected: {"margin-right": "2in"}}
+    { rule: _("margin-right: 2in;"), expected: {
+      "margin-right-value": "2in",
+      "margin-right-ltr-source": "physical",
+      "margin-right-rtl-source": "physical",
+    }}
   ];
 
   var display = document.getElementById("display");
   var sheet = document.styleSheets[1];
 
   for (var curTest = 0; curTest < testset.length; curTest++) {
     try {
       while(sheet.cssRules.length > 0)
--- a/layout/style/test/test_property_database.html
+++ b/layout/style/test/test_property_database.html
@@ -117,23 +117,12 @@ for (var prop in gCSSProperties) {
   }
 
   ok("initial_values" in info && info.initial_values.length >= 1,
      "must have initial values for property '" + prop + "'");
   ok("other_values" in info && info.other_values.length >= 1,
      "must have non-initial values for property '" + prop + "'");
 }
 
-/*
- * Test that only longhand properties are listed as logical properties.
- */
-for (var prop in gCSSProperties) {
-  var info = gCSSProperties[prop];
-  if (info.logical) {
-    is(info.type, CSS_TYPE_LONGHAND,
-       "property '" + prop + "' is listed as CSS_TYPE_LONGHAND due to its " +
-       "being a logical property");
-  }
-}
 </script>
 </pre>
 </body>
 </html>
--- a/layout/style/test/test_value_computation.html
+++ b/layout/style/test/test_value_computation.html
@@ -8,22 +8,17 @@
   <script type="text/javascript" src="property_database.js"></script>
   <style type="text/css" id="stylesheet"></style>
   <style type="text/css">
   /* For 'width', 'height', etc., need a constant size container. */
   #display { width: 500px; height: 200px }
   </style>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <script type="text/javascript">
-  var numAssertions = 9;
-  if (SpecialPowers.getBoolPref("layout.css.vertical-text.enabled")) {
-    // these are from the additional margin-inline-{start,end} tests
-    numAssertions += 2;
-  }
-  SimpleTest.expectAssertions(numAssertions);
+  SimpleTest.expectAssertions(9);
   SimpleTest.waitForExplicitFinish();
   SimpleTest.requestLongerTimeout(2);
 
   var load_count = 0;
   function load_done() {
     if (++load_count == 3)
       run_tests();
   }
@@ -57,38 +52,34 @@ var gBadComputed = {
 
 var gBadComputedNoFrame = {
   // These are probably bogus tests...
   "border-radius": [ "0%", "calc(-1%)", "calc(0px) calc(0pt) calc(0%) calc(0em)" ],
   "border-bottom-left-radius": [ "0%", "calc(-1%)" ],
   "border-bottom-right-radius": [ "0%", "calc(-1%)" ],
   "border-top-left-radius": [ "0%", "calc(-1%)" ],
   "border-top-right-radius": [ "0%", "calc(-1%)" ],
-  "-moz-margin-end": [ "0%", "calc(0% + 0px)" ],
-  "-moz-margin-start": [ "0%", "calc(0% + 0px)" ],
+  "-moz-margin-end": [ "0%", "calc(0% + 0px)", "calc(-1%)" ],
+  "-moz-margin-start": [ "0%", "calc(0% + 0px)", "calc(-1%)" ],
   "-moz-outline-radius": [ "0%", "calc(-1%)", "calc(0px) calc(0pt) calc(0%) calc(0em)" ],
   "-moz-outline-radius-bottomleft": [ "0%", "calc(-1%)" ],
   "-moz-outline-radius-bottomright": [ "0%", "calc(-1%)" ],
   "-moz-outline-radius-topleft": [ "0%", "calc(-1%)" ],
   "-moz-outline-radius-topright": [ "0%", "calc(-1%)" ],
   "-moz-padding-end": [ "0%", "calc(0% + 0px)", "calc(-1%)" ],
   "-moz-padding-start": [ "0%", "calc(0% + 0px)", "calc(-1%)" ],
   "margin": [ "0% 0px 0em 0pt" ],
   "margin-bottom": [ "0%", "calc(0% + 0px)" ],
-  "margin-inline-end": [ "0%", "calc(0% + 0px)" ],
-  "margin-inline-start": [ "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)