Merge mozilla-central to mozilla-inbound a=merge CLOSED TREE
authorMihai Alexandru Michis <malexandru@mozilla.com>
Thu, 16 May 2019 12:47:56 +0300
changeset 532989 3b622e5dea3a9472380cce2d042e7f1bccb8d606
parent 532988 a0464187dbfa6b296752aeb9e34779ac1b85be77 (current diff)
parent 532860 4b635d928b2bd42890ffc97c55622072092351e9 (diff)
child 532990 1be11bf256eea87f795b6cac5b3ee2656b98cc6f
push id11276
push userrgurzau@mozilla.com
push dateMon, 20 May 2019 13:11:24 +0000
treeherdermozilla-beta@847755a7c325 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to mozilla-inbound a=merge CLOSED TREE
dom/svg/SVGGeometryProperty.cpp
dom/svg/SVGGeometryProperty.h
layout/reftests/svg/geometry-properties-in-css-ref.html
layout/reftests/svg/geometry-properties-in-css.html
--- a/devtools/server/actors/animation-type-longhand.js
+++ b/devtools/server/actors/animation-type-longhand.js
@@ -288,18 +288,16 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
     "border-top-right-radius",
     "border-start-start-radius",
     "border-start-end-radius",
     "border-end-start-radius",
     "border-end-end-radius",
     "bottom",
     "column-gap",
     "column-width",
-    "cx",
-    "cy",
     "flex-basis",
     "height",
     "left",
     "letter-spacing",
     "line-height",
     "margin-bottom",
     "margin-left",
     "margin-right",
@@ -312,19 +310,16 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
     "-moz-outline-radius-bottomright",
     "-moz-outline-radius-topleft",
     "-moz-outline-radius-topright",
     "padding-bottom",
     "padding-left",
     "padding-right",
     "padding-top",
     "perspective",
-    "r",
-    "rx",
-    "ry",
     "right",
     "row-gap",
     "scroll-padding-block-start",
     "scroll-padding-block-end",
     "scroll-padding-inline-start",
     "scroll-padding-inline-end",
     "scroll-padding-top",
     "scroll-padding-right",
@@ -342,18 +337,16 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
     "stroke-dashoffset",
     "stroke-width",
     "-moz-tab-size",
     "text-indent",
     "top",
     "vertical-align",
     "width",
     "word-spacing",
-    "x",
-    "y",
     "z-index",
   ])],
   ["float", new Set([
     "-moz-box-flex",
     "fill-opacity",
     "flex-grow",
     "flex-shrink",
     "flood-opacity",
--- a/devtools/shared/css/generated/properties-db.js
+++ b/devtools/shared/css/generated/properties-db.js
@@ -3310,23 +3310,16 @@ exports.CSS_PROPERTIES = {
       "mask-repeat",
       "mask-position-x",
       "mask-position-y",
       "mask-clip",
       "mask-origin",
       "mask-size",
       "mask-composite",
       "mask-image",
-      "x",
-      "y",
-      "cx",
-      "cy",
-      "rx",
-      "ry",
-      "r",
       "-moz-box-align",
       "-moz-box-direction",
       "-moz-box-flex",
       "-moz-box-orient",
       "-moz-box-pack",
       "-moz-stack-sizing",
       "-moz-box-ordinal-group"
     ],
@@ -5834,42 +5827,16 @@ exports.CSS_PROPERTIES = {
       "url",
       "vertical-text",
       "w-resize",
       "wait",
       "zoom-in",
       "zoom-out"
     ]
   },
-  "cx": {
-    "isInherited": false,
-    "subproperties": [
-      "cx"
-    ],
-    "supports": [],
-    "values": [
-      "inherit",
-      "initial",
-      "revert",
-      "unset"
-    ]
-  },
-  "cy": {
-    "isInherited": false,
-    "subproperties": [
-      "cy"
-    ],
-    "supports": [],
-    "values": [
-      "inherit",
-      "initial",
-      "revert",
-      "unset"
-    ]
-  },
   "direction": {
     "isInherited": true,
     "subproperties": [
       "direction"
     ],
     "supports": [],
     "values": [
       "inherit",
@@ -8943,29 +8910,16 @@ exports.CSS_PROPERTIES = {
     "values": [
       "inherit",
       "initial",
       "none",
       "revert",
       "unset"
     ]
   },
-  "r": {
-    "isInherited": false,
-    "subproperties": [
-      "r"
-    ],
-    "supports": [],
-    "values": [
-      "inherit",
-      "initial",
-      "revert",
-      "unset"
-    ]
-  },
   "resize": {
     "isInherited": false,
     "subproperties": [
       "resize"
     ],
     "supports": [],
     "values": [
       "block",
@@ -9035,44 +8989,16 @@ exports.CSS_PROPERTIES = {
       "inherit",
       "initial",
       "over",
       "revert",
       "under",
       "unset"
     ]
   },
-  "rx": {
-    "isInherited": false,
-    "subproperties": [
-      "rx"
-    ],
-    "supports": [],
-    "values": [
-      "auto",
-      "inherit",
-      "initial",
-      "revert",
-      "unset"
-    ]
-  },
-  "ry": {
-    "isInherited": false,
-    "subproperties": [
-      "ry"
-    ],
-    "supports": [],
-    "values": [
-      "auto",
-      "inherit",
-      "initial",
-      "revert",
-      "unset"
-    ]
-  },
   "scroll-behavior": {
     "isInherited": false,
     "subproperties": [
       "scroll-behavior"
     ],
     "supports": [],
     "values": [
       "auto",
@@ -10513,42 +10439,16 @@ exports.CSS_PROPERTIES = {
       "sideways-rl",
       "tb",
       "tb-rl",
       "unset",
       "vertical-lr",
       "vertical-rl"
     ]
   },
-  "x": {
-    "isInherited": false,
-    "subproperties": [
-      "x"
-    ],
-    "supports": [],
-    "values": [
-      "inherit",
-      "initial",
-      "revert",
-      "unset"
-    ]
-  },
-  "y": {
-    "isInherited": false,
-    "subproperties": [
-      "y"
-    ],
-    "supports": [],
-    "values": [
-      "inherit",
-      "initial",
-      "revert",
-      "unset"
-    ]
-  },
   "z-index": {
     "isInherited": false,
     "subproperties": [
       "z-index"
     ],
     "supports": [],
     "values": [
       "auto",
@@ -10692,16 +10592,48 @@ exports.PREFERENCES = [
     "scroll-snap-destination",
     "layout.css.scroll-snap.enabled"
   ],
   [
     "-moz-binding",
     "layout.css.moz-binding.content.enabled"
   ],
   [
+    "scroll-padding-block-end",
+    "layout.css.scroll-snap-v1.enabled"
+  ],
+  [
+    "scroll-padding-block-start",
+    "layout.css.scroll-snap-v1.enabled"
+  ],
+  [
+    "scroll-padding-bottom",
+    "layout.css.scroll-snap-v1.enabled"
+  ],
+  [
+    "scroll-padding-inline-end",
+    "layout.css.scroll-snap-v1.enabled"
+  ],
+  [
+    "scroll-padding-inline-start",
+    "layout.css.scroll-snap-v1.enabled"
+  ],
+  [
+    "scroll-padding-left",
+    "layout.css.scroll-snap-v1.enabled"
+  ],
+  [
+    "scroll-padding-right",
+    "layout.css.scroll-snap-v1.enabled"
+  ],
+  [
+    "scroll-padding-top",
+    "layout.css.scroll-snap-v1.enabled"
+  ],
+  [
     "scroll-margin-block-end",
     "layout.css.scroll-snap-v1.enabled"
   ],
   [
     "scroll-margin-block-start",
     "layout.css.scroll-snap-v1.enabled"
   ],
   [
@@ -10724,48 +10656,16 @@ exports.PREFERENCES = [
     "scroll-margin-right",
     "layout.css.scroll-snap-v1.enabled"
   ],
   [
     "scroll-margin-top",
     "layout.css.scroll-snap-v1.enabled"
   ],
   [
-    "scroll-padding-block-end",
-    "layout.css.scroll-snap-v1.enabled"
-  ],
-  [
-    "scroll-padding-block-start",
-    "layout.css.scroll-snap-v1.enabled"
-  ],
-  [
-    "scroll-padding-bottom",
-    "layout.css.scroll-snap-v1.enabled"
-  ],
-  [
-    "scroll-padding-inline-end",
-    "layout.css.scroll-snap-v1.enabled"
-  ],
-  [
-    "scroll-padding-inline-start",
-    "layout.css.scroll-snap-v1.enabled"
-  ],
-  [
-    "scroll-padding-left",
-    "layout.css.scroll-snap-v1.enabled"
-  ],
-  [
-    "scroll-padding-right",
-    "layout.css.scroll-snap-v1.enabled"
-  ],
-  [
-    "scroll-padding-top",
-    "layout.css.scroll-snap-v1.enabled"
-  ],
-  [
     "-webkit-text-stroke-width",
     "layout.css.prefixes.webkit"
   ],
   [
     "-webkit-text-fill-color",
     "layout.css.prefixes.webkit"
   ],
   [
--- a/dom/media/mp4/Index.cpp
+++ b/dom/media/mp4/Index.cpp
@@ -137,17 +137,17 @@ already_AddRefed<MediaRawData> SampleIte
     }
     if (moofParser->mSinf.mDefaultEncryptionType == AtomType("cenc")) {
       cryptoScheme = CryptoScheme::Cenc;
       writer->mCrypto.mCryptoScheme = CryptoScheme::Cenc;
       writer->mCrypto.mInitDataType = NS_LITERAL_STRING("cenc");
     } else if (moofParser->mSinf.mDefaultEncryptionType == AtomType("cbcs")) {
       cryptoScheme = CryptoScheme::Cbcs;
       writer->mCrypto.mCryptoScheme = CryptoScheme::Cbcs;
-      writer->mCrypto.mInitDataType = NS_LITERAL_STRING("cbcs");
+      writer->mCrypto.mInitDataType = NS_LITERAL_STRING("cenc");
     } else {
       MOZ_ASSERT_UNREACHABLE(
           "Sample description entry reports sample is encrypted, but no "
           "scheme, or an unsupported shceme is in use!");
       return nullptr;
     }
   }
 
--- a/dom/smil/SMILCompositor.cpp
+++ b/dom/smil/SMILCompositor.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SMILCompositor.h"
 
-#include "mozilla/dom/SVGSVGElement.h"
 #include "nsComputedDOMStyle.h"
 #include "nsCSSProps.h"
 #include "nsHashKeys.h"
 #include "SMILCSSProperty.h"
 
 namespace mozilla {
 
 // PLDHashEntryHdr methods
@@ -143,31 +142,29 @@ nsCSSPropertyID SMILCompositor::GetCSSPr
       nsCSSProps::LookupProperty(nsDependentAtomString(mKey.mAttributeName));
 
   if (!SMILCSSProperty::IsPropertyAnimatable(propID)) {
     return eCSSProperty_UNKNOWN;
   }
 
   // If we are animating the 'width' or 'height' of an outer SVG
   // element we should animate it as a CSS property, but for other elements
-  // in SVG namespace (e.g. <rect>) we should animate it as a length attribute.
+  // (e.g. <rect>) we should animate it as a length attribute.
+  // The easiest way to test for an outer SVG element, is to see if it is an
+  // SVG-namespace element mapping its width/height attribute to style.
+  //
+  // If we have animation of 'width' or 'height' on an SVG element that is
+  // NOT mapping that attributes to style then it must not be an outermost SVG
+  // element so we should return eCSSProperty_UNKNOWN to indicate that we
+  // should animate as an attribute instead.
   if ((mKey.mAttributeName == nsGkAtoms::width ||
        mKey.mAttributeName == nsGkAtoms::height) &&
-      mKey.mElement->GetNameSpaceID() == kNameSpaceID_SVG) {
-    // Not an <svg> element.
-    if (!mKey.mElement->IsSVGElement(nsGkAtoms::svg)) {
-      return eCSSProperty_UNKNOWN;
-    }
-
-    // An inner <svg> element
-    if (static_cast<dom::SVGSVGElement const&>(*mKey.mElement).IsInner()) {
-      return eCSSProperty_UNKNOWN;
-    }
-
-    // Indeed an outer <svg> element, fall through.
+      mKey.mElement->GetNameSpaceID() == kNameSpaceID_SVG &&
+      !mKey.mElement->IsAttributeMapped(mKey.mAttributeName)) {
+    return eCSSProperty_UNKNOWN;
   }
 
   return propID;
 }
 
 bool SMILCompositor::MightNeedBaseStyle() const {
   if (GetCSSPropertyToAnimate() == eCSSProperty_UNKNOWN) {
     return false;
--- a/dom/svg/SVGCircleElement.cpp
+++ b/dom/svg/SVGCircleElement.cpp
@@ -1,21 +1,19 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "ComputedStyle.h"
 #include "mozilla/dom/SVGCircleElement.h"
 #include "mozilla/gfx/2D.h"
 #include "nsGkAtoms.h"
 #include "mozilla/dom/SVGCircleElementBinding.h"
 #include "mozilla/dom/SVGLengthBinding.h"
-#include "SVGGeometryProperty.h"
 
 NS_IMPL_NS_NEW_SVG_ELEMENT(Circle)
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace dom {
 
@@ -34,23 +32,16 @@ SVGElement::LengthInfo SVGCircleElement:
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGCircleElement::SVGCircleElement(
     already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
     : SVGCircleElementBase(std::move(aNodeInfo)) {}
 
-bool SVGCircleElement::IsAttributeMapped(const nsAtom* aAttribute) const {
-  return IsInLengthInfo(aAttribute, sLengthInfo) ||
-         SVGCircleElementBase::IsAttributeMapped(aAttribute);
-}
-
-namespace SVGT = SVGGeometryProperty::Tags;
-
 //----------------------------------------------------------------------
 // nsINode methods
 
 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGCircleElement)
 
 //----------------------------------------------------------------------
 
 already_AddRefed<DOMSVGAnimatedLength> SVGCircleElement::Cx() {
@@ -65,39 +56,33 @@ already_AddRefed<DOMSVGAnimatedLength> S
   return mLengthAttributes[ATTR_R].ToDOMAnimatedLength(this);
 }
 
 //----------------------------------------------------------------------
 // SVGElement methods
 
 /* virtual */
 bool SVGCircleElement::HasValidDimensions() const {
-  float r;
-
-  MOZ_ASSERT(GetPrimaryFrame());
-  SVGGeometryProperty::ResolveAll<SVGT::R>(this, &r);
-  return r > 0;
+  return mLengthAttributes[ATTR_R].IsExplicitlySet() &&
+         mLengthAttributes[ATTR_R].GetAnimValInSpecifiedUnits() > 0;
 }
 
 SVGElement::LengthAttributesInfo SVGCircleElement::GetLengthInfo() {
   return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
                               ArrayLength(sLengthInfo));
 }
 
 //----------------------------------------------------------------------
 // SVGGeometryElement methods
 
 bool SVGCircleElement::GetGeometryBounds(
     Rect* aBounds, const StrokeOptions& aStrokeOptions,
     const Matrix& aToBoundsSpace, const Matrix* aToNonScalingStrokeSpace) {
   float x, y, r;
-
-  MOZ_ASSERT(GetPrimaryFrame());
-  SVGGeometryProperty::ResolveAll<SVGT::Cx, SVGT::Cy, SVGT::R>(this, &x, &y,
-                                                               &r);
+  GetAnimatedLengthValues(&x, &y, &r, nullptr);
 
   if (r <= 0.f) {
     // Rendering of the element is disabled
     *aBounds = Rect(aToBoundsSpace.TransformPoint(Point(x, y)), Size());
     return true;
   }
 
   if (aToBoundsSpace.IsRectilinear()) {
@@ -122,48 +107,21 @@ bool SVGCircleElement::GetGeometryBounds
     return true;
   }
 
   return false;
 }
 
 already_AddRefed<Path> SVGCircleElement::BuildPath(PathBuilder* aBuilder) {
   float x, y, r;
-  MOZ_ASSERT(GetPrimaryFrame());
-  SVGGeometryProperty::ResolveAll<SVGT::Cx, SVGT::Cy, SVGT::R>(this, &x, &y,
-                                                               &r);
+  GetAnimatedLengthValues(&x, &y, &r, nullptr);
 
   if (r <= 0.0f) {
     return nullptr;
   }
 
   aBuilder->Arc(Point(x, y), r, 0, Float(2 * M_PI));
 
   return aBuilder->Finish();
 }
 
-bool SVGCircleElement::IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
-                                             const ComputedStyle& aOldStyle) {
-  auto *newSVGReset = aNewStyle.StyleSVGReset(),
-       *oldSVGReset = aOldStyle.StyleSVGReset();
-
-  return newSVGReset->mCx != oldSVGReset->mCx ||
-         newSVGReset->mCy != oldSVGReset->mCy ||
-         newSVGReset->mR != oldSVGReset->mR;
-}
-
-nsCSSPropertyID SVGCircleElement::GetCSSPropertyIdForAttrEnum(
-    uint8_t aAttrEnum) {
-  switch (aAttrEnum) {
-    case ATTR_CX:
-      return eCSSProperty_cx;
-    case ATTR_CY:
-      return eCSSProperty_cy;
-    case ATTR_R:
-      return eCSSProperty_r;
-    default:
-      MOZ_ASSERT_UNREACHABLE("Unknown attr enum");
-      return eCSSProperty_UNKNOWN;
-  }
-}
-
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/svg/SVGCircleElement.h
+++ b/dom/svg/SVGCircleElement.h
@@ -2,59 +2,50 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_SVGCircleElement_h
 #define mozilla_dom_SVGCircleElement_h
 
-#include "nsCSSPropertyID.h"
 #include "SVGGeometryElement.h"
 #include "SVGAnimatedLength.h"
 
 nsresult NS_NewSVGCircleElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 namespace mozilla {
-class ComputedStyle;
-
 namespace dom {
 
 typedef SVGGeometryElement SVGCircleElementBase;
 
 class SVGCircleElement final : public SVGCircleElementBase {
  protected:
   explicit SVGCircleElement(
       already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext* cx,
                              JS::Handle<JSObject*> aGivenProto) override;
   friend nsresult(::NS_NewSVGCircleElement(
       nsIContent** aResult,
       already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 
  public:
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
-
   // nsSVGSVGElement methods:
   virtual bool HasValidDimensions() const override;
 
   // SVGGeometryElement methods:
   virtual bool GetGeometryBounds(
       Rect* aBounds, const StrokeOptions& aStrokeOptions,
       const Matrix& aToBoundsSpace,
       const Matrix* aToNonScalingStrokeSpace = nullptr) override;
   virtual already_AddRefed<Path> BuildPath(PathBuilder* aBuilder) override;
 
   virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
 
-  static bool IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
-                                    const ComputedStyle& aOldStyle);
-  static nsCSSPropertyID GetCSSPropertyIdForAttrEnum(uint8_t aAttrEnum);
-
   // WebIDL
   already_AddRefed<DOMSVGAnimatedLength> Cx();
   already_AddRefed<DOMSVGAnimatedLength> Cy();
   already_AddRefed<DOMSVGAnimatedLength> R();
 
  protected:
   virtual LengthAttributesInfo GetLengthInfo() override;
 
--- a/dom/svg/SVGElement.cpp
+++ b/dom/svg/SVGElement.cpp
@@ -25,17 +25,16 @@
 #include "mozilla/SVGContentUtils.h"
 #include "mozilla/Unused.h"
 
 #include "DOMSVGAnimatedEnumeration.h"
 #include "mozAutoDocUpdate.h"
 #include "nsAttrValueOrString.h"
 #include "nsCSSProps.h"
 #include "nsContentUtils.h"
-#include "nsDOMCSSAttrDeclaration.h"
 #include "nsICSSDeclaration.h"
 #include "nsIContentInlines.h"
 #include "mozilla/dom/Document.h"
 #include "nsError.h"
 #include "nsGkAtoms.h"
 #include "nsIFrame.h"
 #include "nsQueryObject.h"
 #include "nsLayoutUtils.h"
@@ -49,17 +48,16 @@
 #include "SVGAnimatedInteger.h"
 #include "SVGAnimatedIntegerPair.h"
 #include "SVGAnimatedLength.h"
 #include "SVGAnimatedNumber.h"
 #include "SVGAnimatedNumberPair.h"
 #include "SVGAnimatedOrient.h"
 #include "SVGAnimatedString.h"
 #include "SVGAnimatedViewBox.h"
-#include "SVGGeometryProperty.h"
 #include "SVGMotionSMILAttr.h"
 #include <stdarg.h>
 
 // This is needed to ensure correct handling of calls to the
 // vararg-list methods in this file:
 //   SVGElement::GetAnimated{Length,Number,Integer}Values
 // See bug 547964 for details:
 static_assert(sizeof(void*) == sizeof(nullptr),
@@ -1017,69 +1015,31 @@ SVGSVGElement* SVGElement::GetOwnerSVGEl
 SVGElement* SVGElement::GetViewportElement() {
   return SVGContentUtils::GetNearestViewportElement(this);
 }
 
 already_AddRefed<DOMSVGAnimatedString> SVGElement::ClassName() {
   return mClassAttribute.ToDOMAnimatedString(this);
 }
 
-/* static */
-bool SVGElement::UpdateDeclarationBlockFromLength(
-    DeclarationBlock& aBlock, nsCSSPropertyID aPropId,
-    const SVGAnimatedLength& aLength, ValToUse aValToUse) {
-  aBlock.AssertMutable();
-
-  float value;
-  if (aValToUse == ValToUse::Anim) {
-    value = aLength.GetAnimValInSpecifiedUnits();
-  } else {
-    MOZ_ASSERT(aValToUse == ValToUse::Base);
-    value = aLength.GetBaseValInSpecifiedUnits();
-  }
-
-  // SVG parser doesn't check non-negativity of some parsed value,
-  // we should not pass those to CSS side.
-  if (value < 0 &&
-      SVGGeometryProperty::IsNonNegativeGeometryProperty(aPropId)) {
-    return false;
-  }
-
-  nsCSSUnit cssUnit = SVGGeometryProperty::SpecifiedUnitTypeToCSSUnit(
-      aLength.GetSpecifiedUnitType());
-
-  if (cssUnit == eCSSUnit_Percent) {
-    Servo_DeclarationBlock_SetPercentValue(aBlock.Raw(), aPropId,
-                                           value / 100.f);
-  } else {
-    Servo_DeclarationBlock_SetLengthValue(aBlock.Raw(), aPropId, value,
-                                          cssUnit);
-  }
-
-  return true;
-}
-
 //------------------------------------------------------------------------
 // Helper class: MappedAttrParser, for parsing values of mapped attributes
 
 namespace {
 
 class MOZ_STACK_CLASS MappedAttrParser {
  public:
   MappedAttrParser(css::Loader* aLoader, nsIURI* aDocURI,
                    already_AddRefed<nsIURI> aBaseURI, SVGElement* aElement);
   ~MappedAttrParser();
 
   // Parses a mapped attribute value.
   void ParseMappedAttrValue(nsAtom* aMappedAttrName,
                             const nsAString& aMappedAttrValue);
 
-  void TellStyleAlreadyParsedResult(nsAtom const* aAtom,
-                                    SVGAnimatedLength const& aLength);
-
   // If we've parsed any values for mapped attributes, this method returns the
   // already_AddRefed css::Declaration that incorporates the parsed
   // values. Otherwise, this method returns null.
   already_AddRefed<DeclarationBlock> GetDeclarationBlock();
 
  private:
   // MEMBER DATA
   // -----------
@@ -1157,28 +1117,16 @@ void MappedAttrParser::ParseMappedAttrVa
   // nsCSSParser doesn't know about 'lang', so we need to handle it specially.
   if (aMappedAttrName == nsGkAtoms::lang) {
     propertyID = eCSSProperty__x_lang;
     RefPtr<nsAtom> atom = NS_Atomize(aMappedAttrValue);
     Servo_DeclarationBlock_SetIdentStringValue(mDecl->Raw(), propertyID, atom);
   }
 }
 
-void MappedAttrParser::TellStyleAlreadyParsedResult(
-    nsAtom const* aAtom, SVGAnimatedLength const& aLength) {
-  if (!mDecl) {
-    mDecl = new DeclarationBlock();
-  }
-  nsCSSPropertyID propertyID =
-      nsCSSProps::LookupProperty(nsDependentAtomString(aAtom));
-
-  SVGElement::UpdateDeclarationBlockFromLength(*mDecl, propertyID, aLength,
-                                               SVGElement::ValToUse::Base);
-}
-
 already_AddRefed<DeclarationBlock> MappedAttrParser::GetDeclarationBlock() {
   return mDecl.forget();
 }
 
 }  // namespace
 
 //----------------------------------------------------------------------
 // Implementation Helpers:
@@ -1192,19 +1140,16 @@ void SVGElement::UpdateContentDeclaratio
     // nothing to do
     return;
   }
 
   Document* doc = OwnerDoc();
   MappedAttrParser mappedAttrParser(doc->CSSLoader(), doc->GetDocumentURI(),
                                     GetBaseURI(), this);
 
-  bool lengthAffectsStyle =
-      SVGGeometryProperty::ElementMapsLengthsToStyle(this);
-
   for (uint32_t i = 0; i < attrCount; ++i) {
     const nsAttrName* attrName = mAttrs.AttrNameAt(i);
     if (!attrName->IsAtom() || !IsAttributeMapped(attrName->Atom())) continue;
 
     if (attrName->NamespaceID() != kNameSpaceID_None &&
         !attrName->Equals(nsGkAtoms::lang, kNameSpaceID_XML)) {
       continue;
     }
@@ -1227,30 +1172,16 @@ void SVGElement::UpdateContentDeclaratio
         continue;
       }
       if (attrName->Atom() == nsGkAtoms::height &&
           !GetAnimatedLength(nsGkAtoms::height)->HasBaseVal()) {
         continue;
       }
     }
 
-    if (lengthAffectsStyle) {
-      auto const* length = GetAnimatedLength(attrName->Atom());
-
-      if (length && length->HasBaseVal()) {
-        // This is an element with geometry property set via SVG attribute,
-        // and the attribute is already successfully parsed. We want to go
-        // through the optimized path to tell the style system the result
-        // directly, rather than let it parse the same thing again.
-        mappedAttrParser.TellStyleAlreadyParsedResult(attrName->Atom(),
-                                                      *length);
-        continue;
-      }
-    }
-
     nsAutoString value;
     mAttrs.AttrAt(i)->ToString(value);
     mappedAttrParser.ParseMappedAttrValue(attrName->Atom(), value);
   }
   mContentDeclarationBlock = mappedAttrParser.GetDeclarationBlock();
 }
 
 const DeclarationBlock* SVGElement::GetContentDeclarationBlock() const {
@@ -1455,25 +1386,16 @@ void SVGElement::DidChangeLength(uint8_t
 
   nsAttrValue newValue;
   newValue.SetTo(info.mLengths[aAttrEnum], nullptr);
 
   DidChangeValue(info.mLengthInfo[aAttrEnum].mName, aEmptyOrOldValue, newValue);
 }
 
 void SVGElement::DidAnimateLength(uint8_t aAttrEnum) {
-  if (SVGGeometryProperty::ElementMapsLengthsToStyle(this)) {
-    nsCSSPropertyID propId =
-        SVGGeometryProperty::AttrEnumToCSSPropId(this, aAttrEnum);
-
-    SMILOverrideStyle()->SetSMILValue(propId,
-                                      GetLengthInfo().mLengths[aAttrEnum]);
-    return;
-  }
-
   ClearAnyCachedPath();
 
   nsIFrame* frame = GetPrimaryFrame();
 
   if (frame) {
     LengthAttributesInfo info = GetLengthInfo();
     frame->AttributeChanged(kNameSpaceID_None,
                             info.mLengthInfo[aAttrEnum].mName,
@@ -1484,16 +1406,17 @@ void SVGElement::DidAnimateLength(uint8_
 SVGAnimatedLength* SVGElement::GetAnimatedLength(const nsAtom* aAttrName) {
   LengthAttributesInfo lengthInfo = GetLengthInfo();
 
   for (uint32_t i = 0; i < lengthInfo.mLengthCount; i++) {
     if (aAttrName == lengthInfo.mLengthInfo[i].mName) {
       return &lengthInfo.mLengths[i];
     }
   }
+  MOZ_ASSERT(false, "no matching length found");
   return nullptr;
 }
 
 void SVGElement::GetAnimatedLengthValues(float* aFirst, ...) {
   LengthAttributesInfo info = GetLengthInfo();
 
   NS_ASSERTION(info.mLengthCount > 0,
                "GetAnimatedLengthValues on element with no length attribs");
--- a/dom/svg/SVGElement.h
+++ b/dom/svg/SVGElement.h
@@ -160,22 +160,16 @@ class SVGElement : public SVGElementBase
     return GetStringInfo().mStringInfo[aAttrEnum].mIsAnimatable;
   }
   bool NumberAttrAllowsPercentage(uint8_t aAttrEnum) {
     return GetNumberInfo().mNumberInfo[aAttrEnum].mPercentagesAllowed;
   }
   virtual bool HasValidDimensions() const { return true; }
   void SetLength(nsAtom* aName, const SVGAnimatedLength& aLength);
 
-  enum class ValToUse { Base, Anim };
-  static bool UpdateDeclarationBlockFromLength(DeclarationBlock& aBlock,
-                                               nsCSSPropertyID aPropId,
-                                               const SVGAnimatedLength& aLength,
-                                               ValToUse aValToUse);
-
   nsAttrValue WillChangeLength(uint8_t aAttrEnum);
   nsAttrValue WillChangeNumberPair(uint8_t aAttrEnum);
   nsAttrValue WillChangeIntegerPair(uint8_t aAttrEnum);
   nsAttrValue WillChangeOrient();
   nsAttrValue WillChangeViewBox();
   nsAttrValue WillChangePreserveAspectRatio();
   nsAttrValue WillChangeNumberList(uint8_t aAttrEnum);
   nsAttrValue WillChangeLengthList(uint8_t aAttrEnum);
--- a/dom/svg/SVGEllipseElement.cpp
+++ b/dom/svg/SVGEllipseElement.cpp
@@ -1,22 +1,20 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "ComputedStyle.h"
 #include "mozilla/dom/SVGEllipseElement.h"
 #include "mozilla/dom/SVGEllipseElementBinding.h"
 #include "mozilla/dom/SVGLengthBinding.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/PathHelpers.h"
 #include "mozilla/RefPtr.h"
-#include "SVGGeometryProperty.h"
 
 NS_IMPL_NS_NEW_SVG_ELEMENT(Ellipse)
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace dom {
 
@@ -38,23 +36,16 @@ SVGElement::LengthInfo SVGEllipseElement
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGEllipseElement::SVGEllipseElement(
     already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
     : SVGEllipseElementBase(std::move(aNodeInfo)) {}
 
-bool SVGEllipseElement::IsAttributeMapped(const nsAtom* aAttribute) const {
-  return IsInLengthInfo(aAttribute, sLengthInfo) ||
-         SVGEllipseElementBase::IsAttributeMapped(aAttribute);
-}
-
-namespace SVGT = SVGGeometryProperty::Tags;
-
 //----------------------------------------------------------------------
 // nsINode methods
 
 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGEllipseElement)
 
 //----------------------------------------------------------------------
 // nsIDOMSVGEllipseElement methods
 
@@ -74,40 +65,35 @@ already_AddRefed<DOMSVGAnimatedLength> S
   return mLengthAttributes[RY].ToDOMAnimatedLength(this);
 }
 
 //----------------------------------------------------------------------
 // SVGElement methods
 
 /* virtual */
 bool SVGEllipseElement::HasValidDimensions() const {
-  float rx, ry;
-
-  MOZ_ASSERT(GetPrimaryFrame());
-  SVGGeometryProperty::ResolveAll<SVGT::Rx, SVGT::Ry>(this, &rx, &ry);
-
-  return rx > 0 && ry > 0;
+  return mLengthAttributes[RX].IsExplicitlySet() &&
+         mLengthAttributes[RX].GetAnimValInSpecifiedUnits() > 0 &&
+         mLengthAttributes[RY].IsExplicitlySet() &&
+         mLengthAttributes[RY].GetAnimValInSpecifiedUnits() > 0;
 }
 
 SVGElement::LengthAttributesInfo SVGEllipseElement::GetLengthInfo() {
   return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
                               ArrayLength(sLengthInfo));
 }
 
 //----------------------------------------------------------------------
 // SVGGeometryElement methods
 
 bool SVGEllipseElement::GetGeometryBounds(
     Rect* aBounds, const StrokeOptions& aStrokeOptions,
     const Matrix& aToBoundsSpace, const Matrix* aToNonScalingStrokeSpace) {
   float x, y, rx, ry;
-
-  MOZ_ASSERT(GetPrimaryFrame());
-  SVGGeometryProperty::ResolveAll<SVGT::Cx, SVGT::Cy, SVGT::Rx, SVGT::Ry>(
-      this, &x, &y, &rx, &ry);
+  GetAnimatedLengthValues(&x, &y, &rx, &ry, nullptr);
 
   if (rx <= 0.f || ry <= 0.f) {
     // Rendering of the element is disabled
     *aBounds = Rect(aToBoundsSpace.TransformPoint(Point(x, y)), Size());
     return true;
   }
 
   if (aToBoundsSpace.IsRectilinear()) {
@@ -133,52 +119,21 @@ bool SVGEllipseElement::GetGeometryBound
     return true;
   }
 
   return false;
 }
 
 already_AddRefed<Path> SVGEllipseElement::BuildPath(PathBuilder* aBuilder) {
   float x, y, rx, ry;
-
-  MOZ_ASSERT(GetPrimaryFrame());
-  SVGGeometryProperty::ResolveAll<SVGT::Cx, SVGT::Cy, SVGT::Rx, SVGT::Ry>(
-      this, &x, &y, &rx, &ry);
+  GetAnimatedLengthValues(&x, &y, &rx, &ry, nullptr);
 
   if (rx <= 0.0f || ry <= 0.0f) {
     return nullptr;
   }
 
   EllipseToBezier(aBuilder, Point(x, y), Size(rx, ry));
 
   return aBuilder->Finish();
 }
 
-bool SVGEllipseElement::IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
-                                              const ComputedStyle& aOldStyle) {
-  auto *newSVGReset = aNewStyle.StyleSVGReset(),
-       *oldSVGReset = aOldStyle.StyleSVGReset();
-
-  return newSVGReset->mCx != oldSVGReset->mCx ||
-         newSVGReset->mCy != oldSVGReset->mCy ||
-         newSVGReset->mRx != oldSVGReset->mRx ||
-         newSVGReset->mRy != oldSVGReset->mRy;
-}
-
-nsCSSPropertyID SVGEllipseElement::GetCSSPropertyIdForAttrEnum(
-    uint8_t aAttrEnum) {
-  switch (aAttrEnum) {
-    case CX:
-      return eCSSProperty_cx;
-    case CY:
-      return eCSSProperty_cy;
-    case RX:
-      return eCSSProperty_rx;
-    case RY:
-      return eCSSProperty_ry;
-    default:
-      MOZ_ASSERT_UNREACHABLE("Unknown attr enum");
-      return eCSSProperty_UNKNOWN;
-  }
-}
-
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/svg/SVGEllipseElement.h
+++ b/dom/svg/SVGEllipseElement.h
@@ -2,59 +2,50 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_SVGEllipseElement_h
 #define mozilla_dom_SVGEllipseElement_h
 
-#include "nsCSSPropertyID.h"
 #include "SVGAnimatedLength.h"
 #include "SVGGeometryElement.h"
 
 nsresult NS_NewSVGEllipseElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 namespace mozilla {
-class ComputedStyle;
-
 namespace dom {
 
 typedef SVGGeometryElement SVGEllipseElementBase;
 
 class SVGEllipseElement final : public SVGEllipseElementBase {
  protected:
   explicit SVGEllipseElement(
       already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext* cx,
                              JS::Handle<JSObject*> aGivenProto) override;
   friend nsresult(::NS_NewSVGEllipseElement(
       nsIContent** aResult,
       already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 
  public:
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
-
   // nsSVGSVGElement methods:
   virtual bool HasValidDimensions() const override;
 
   // SVGGeometryElement methods:
   virtual bool GetGeometryBounds(
       Rect* aBounds, const StrokeOptions& aStrokeOptions,
       const Matrix& aToBoundsSpace,
       const Matrix* aToNonScalingStrokeSpace = nullptr) override;
   virtual already_AddRefed<Path> BuildPath(PathBuilder* aBuilder) override;
 
   virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
 
-  static bool IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
-                                    const ComputedStyle& aOldStyle);
-  static nsCSSPropertyID GetCSSPropertyIdForAttrEnum(uint8_t aAttrEnum);
-
   // WebIDL
   already_AddRefed<DOMSVGAnimatedLength> Cx();
   already_AddRefed<DOMSVGAnimatedLength> Cy();
   already_AddRefed<DOMSVGAnimatedLength> Rx();
   already_AddRefed<DOMSVGAnimatedLength> Ry();
 
  protected:
   virtual LengthAttributesInfo GetLengthInfo() override;
--- a/dom/svg/SVGForeignObjectElement.cpp
+++ b/dom/svg/SVGForeignObjectElement.cpp
@@ -6,17 +6,16 @@
 
 #include "mozilla/dom/SVGForeignObjectElement.h"
 
 #include "mozilla/AlreadyAddRefed.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/dom/SVGDocument.h"
 #include "mozilla/dom/SVGForeignObjectElementBinding.h"
 #include "mozilla/dom/SVGLengthBinding.h"
-#include "SVGGeometryProperty.h"
 
 NS_IMPL_NS_NEW_SVG_ELEMENT(ForeignObject)
 
 namespace mozilla {
 namespace dom {
 
 JSObject* SVGForeignObjectElement::WrapNode(JSContext* aCx,
                                             JS::Handle<JSObject*> aGivenProto) {
@@ -36,18 +35,16 @@ SVGElement::LengthInfo SVGForeignObjectE
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGForeignObjectElement::SVGForeignObjectElement(
     already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
     : SVGGraphicsElement(std::move(aNodeInfo)) {}
 
-namespace SVGT = SVGGeometryProperty::Tags;
-
 //----------------------------------------------------------------------
 // nsINode methods
 
 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGForeignObjectElement)
 
 //----------------------------------------------------------------------
 
 already_AddRefed<DOMSVGAnimatedLength> SVGForeignObjectElement::X() {
@@ -75,82 +72,54 @@ gfxMatrix SVGForeignObjectElement::Prepe
   // 'transform' attribute:
   gfxMatrix fromUserSpace =
       SVGGraphicsElement::PrependLocalTransformsTo(aMatrix, aWhich);
   if (aWhich == eUserSpaceToParent) {
     return fromUserSpace;
   }
   // our 'x' and 'y' attributes:
   float x, y;
-
-  if (GetPrimaryFrame()) {
-    SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y>(this, &x, &y);
-  } else {
-    // This function might be called for element in display:none subtree
-    // (e.g. getScreenCTM), we fall back to use SVG attributes.
-    const_cast<SVGForeignObjectElement*>(this)->GetAnimatedLengthValues(
-        &x, &y, nullptr);
-  }
-
+  const_cast<SVGForeignObjectElement*>(this)->GetAnimatedLengthValues(&x, &y,
+                                                                      nullptr);
   gfxMatrix toUserSpace = gfxMatrix::Translation(x, y);
   if (aWhich == eChildToUserSpace) {
     return toUserSpace * aMatrix;
   }
   MOZ_ASSERT(aWhich == eAllTransforms, "Unknown TransformTypes");
   return toUserSpace * fromUserSpace;
 }
 
 /* virtual */
 bool SVGForeignObjectElement::HasValidDimensions() const {
-  float width, height;
-
-  MOZ_ASSERT(GetPrimaryFrame());
-  SVGGeometryProperty::ResolveAll<SVGT::Width, SVGT::Height>(
-      const_cast<SVGForeignObjectElement*>(this), &width, &height);
-  return width > 0 && height > 0;
+  return mLengthAttributes[ATTR_WIDTH].IsExplicitlySet() &&
+         mLengthAttributes[ATTR_WIDTH].GetAnimValInSpecifiedUnits() > 0 &&
+         mLengthAttributes[ATTR_HEIGHT].IsExplicitlySet() &&
+         mLengthAttributes[ATTR_HEIGHT].GetAnimValInSpecifiedUnits() > 0;
 }
 
 //----------------------------------------------------------------------
 // nsIContent methods
 
 NS_IMETHODIMP_(bool)
 SVGForeignObjectElement::IsAttributeMapped(const nsAtom* name) const {
   static const MappedAttributeEntry* const map[] = {sFEFloodMap,
                                                     sFiltersMap,
                                                     sFontSpecificationMap,
                                                     sGradientStopMap,
                                                     sLightingEffectsMap,
                                                     sMarkersMap,
                                                     sTextContentElementsMap,
                                                     sViewportsMap};
 
-  return IsInLengthInfo(name, sLengthInfo) ||
-         FindAttributeDependence(name, map) ||
+  return FindAttributeDependence(name, map) ||
          SVGGraphicsElement::IsAttributeMapped(name);
 }
 
 //----------------------------------------------------------------------
 // SVGElement methods
 
 SVGElement::LengthAttributesInfo SVGForeignObjectElement::GetLengthInfo() {
   return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
                               ArrayLength(sLengthInfo));
 }
 
-nsCSSPropertyID SVGForeignObjectElement::GetCSSPropertyIdForAttrEnum(
-    uint8_t aAttrEnum) {
-  switch (aAttrEnum) {
-    case ATTR_X:
-      return eCSSProperty_x;
-    case ATTR_Y:
-      return eCSSProperty_y;
-    case ATTR_WIDTH:
-      return eCSSProperty_width;
-    case ATTR_HEIGHT:
-      return eCSSProperty_height;
-    default:
-      MOZ_ASSERT_UNREACHABLE("Unknown attr enum");
-      return eCSSProperty_UNKNOWN;
-  }
-}
-
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/svg/SVGForeignObjectElement.h
+++ b/dom/svg/SVGForeignObjectElement.h
@@ -3,17 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_SVGForeignObjectElement_h
 #define mozilla_dom_SVGForeignObjectElement_h
 
 #include "mozilla/dom/SVGGraphicsElement.h"
-#include "nsCSSPropertyID.h"
 #include "SVGAnimatedLength.h"
 
 nsresult NS_NewSVGForeignObjectElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 class nsSVGForeignObjectFrame;
 
 namespace mozilla {
@@ -38,18 +37,16 @@ class SVGForeignObjectElement final : pu
       SVGTransformTypes aWhich = eAllTransforms) const override;
   virtual bool HasValidDimensions() const override;
 
   // nsIContent interface
   NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* name) const override;
 
   virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
 
-  static nsCSSPropertyID GetCSSPropertyIdForAttrEnum(uint8_t aAttrEnum);
-
   // WebIDL
   already_AddRefed<DOMSVGAnimatedLength> X();
   already_AddRefed<DOMSVGAnimatedLength> Y();
   already_AddRefed<DOMSVGAnimatedLength> Width();
   already_AddRefed<DOMSVGAnimatedLength> Height();
 
  protected:
   virtual LengthAttributesInfo GetLengthInfo() override;
--- a/dom/svg/SVGGeometryElement.cpp
+++ b/dom/svg/SVGGeometryElement.cpp
@@ -5,21 +5,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SVGGeometryElement.h"
 
 #include "DOMSVGPoint.h"
 #include "gfxPlatform.h"
 #include "nsCOMPtr.h"
 #include "nsComputedDOMStyle.h"
+#include "SVGAnimatedLength.h"
 #include "nsSVGUtils.h"
-#include "SVGAnimatedLength.h"
-#include "SVGCircleElement.h"
-#include "SVGEllipseElement.h"
-#include "SVGRectElement.h"
 #include "mozilla/dom/SVGLengthBinding.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/SVGContentUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 using namespace mozilla::dom;
@@ -109,32 +106,16 @@ already_AddRefed<Path> SVGGeometryElemen
 
 already_AddRefed<Path> SVGGeometryElement::GetOrBuildPathForMeasuring() {
   RefPtr<DrawTarget> drawTarget =
       gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget();
   FillRule fillRule = mCachedPath ? mCachedPath->GetFillRule() : GetFillRule();
   return GetOrBuildPath(drawTarget, fillRule);
 }
 
-bool SVGGeometryElement::IsGeometryChangedViaCSS(
-    ComputedStyle const& aNewStyle, ComputedStyle const& aOldStyle) const {
-  if (IsSVGElement(nsGkAtoms::rect)) {
-    return SVGRectElement::IsLengthChangedViaCSS(aNewStyle, aOldStyle);
-  }
-
-  if (IsSVGElement(nsGkAtoms::circle)) {
-    return SVGCircleElement::IsLengthChangedViaCSS(aNewStyle, aOldStyle);
-  }
-
-  if (IsSVGElement(nsGkAtoms::ellipse)) {
-    return SVGEllipseElement::IsLengthChangedViaCSS(aNewStyle, aOldStyle);
-  }
-  return false;
-}
-
 FillRule SVGGeometryElement::GetFillRule() {
   FillRule fillRule =
       FillRule::FILL_WINDING;  // Equivalent to StyleFillRule::Nonzero
 
   RefPtr<ComputedStyle> computedStyle =
       nsComputedDOMStyle::GetComputedStyleNoFlush(this, nullptr);
 
   if (computedStyle) {
--- a/dom/svg/SVGGeometryElement.h
+++ b/dom/svg/SVGGeometryElement.h
@@ -187,23 +187,16 @@ class SVGGeometryElement : public SVGGeo
    * In principle these inserted lines could interfere with path measurement,
    * so we keep callers that are looking to do measurement separate in case we
    * run into problems with the inserted lines negatively affecting measuring
    * for content.
    */
   virtual already_AddRefed<Path> GetOrBuildPathForMeasuring();
 
   /**
-   * Return |true| if some geometry properties (|x|, |y|, etc) are changed
-   * because of CSS change.
-   */
-  bool IsGeometryChangedViaCSS(ComputedStyle const& aNewStyle,
-                               ComputedStyle const& aOldStyle) const;
-
-  /**
    * Returns the current computed value of the CSS property 'fill-rule' for
    * this element.
    */
   FillRule GetFillRule();
 
   enum PathLengthScaleForType { eForTextPath, eForStroking };
 
   /**
deleted file mode 100644
--- a/dom/svg/SVGGeometryProperty.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "SVGGeometryProperty.h"
-#include "SVGCircleElement.h"
-#include "SVGEllipseElement.h"
-#include "SVGForeignObjectElement.h"
-#include "SVGRectElement.h"
-
-namespace mozilla {
-namespace dom {
-namespace SVGGeometryProperty {
-
-nsCSSUnit SpecifiedUnitTypeToCSSUnit(uint8_t aSpecifiedUnit) {
-  switch (aSpecifiedUnit) {
-    case SVGLength_Binding::SVG_LENGTHTYPE_NUMBER:
-    case SVGLength_Binding::SVG_LENGTHTYPE_PX:
-      return nsCSSUnit::eCSSUnit_Pixel;
-
-    case SVGLength_Binding::SVG_LENGTHTYPE_MM:
-      return nsCSSUnit::eCSSUnit_Millimeter;
-
-    case SVGLength_Binding::SVG_LENGTHTYPE_CM:
-      return nsCSSUnit::eCSSUnit_Centimeter;
-
-    case SVGLength_Binding::SVG_LENGTHTYPE_IN:
-      return nsCSSUnit::eCSSUnit_Inch;
-
-    case SVGLength_Binding::SVG_LENGTHTYPE_PT:
-      return nsCSSUnit::eCSSUnit_Point;
-
-    case SVGLength_Binding::SVG_LENGTHTYPE_PC:
-      return nsCSSUnit::eCSSUnit_Pica;
-
-    case SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE:
-      return nsCSSUnit::eCSSUnit_Percent;
-
-    case SVGLength_Binding::SVG_LENGTHTYPE_EMS:
-      return nsCSSUnit::eCSSUnit_EM;
-
-    case SVGLength_Binding::SVG_LENGTHTYPE_EXS:
-      return nsCSSUnit::eCSSUnit_XHeight;
-
-    default:
-      MOZ_ASSERT_UNREACHABLE("Unknown unit type");
-      return nsCSSUnit::eCSSUnit_Pixel;
-  }
-}
-
-nsCSSPropertyID AttrEnumToCSSPropId(const SVGElement* aElement,
-                                    uint8_t aAttrEnum) {
-  // This is a very trivial function only applied to a few elements,
-  // so we want to avoid making it virtual.
-  if (aElement->IsSVGElement(nsGkAtoms::rect)) {
-    return SVGRectElement::GetCSSPropertyIdForAttrEnum(aAttrEnum);
-  }
-  if (aElement->IsSVGElement(nsGkAtoms::circle)) {
-    return SVGCircleElement::GetCSSPropertyIdForAttrEnum(aAttrEnum);
-  }
-  if (aElement->IsSVGElement(nsGkAtoms::ellipse)) {
-    return SVGEllipseElement::GetCSSPropertyIdForAttrEnum(aAttrEnum);
-  }
-  if (aElement->IsSVGElement(nsGkAtoms::foreignObject)) {
-    return SVGForeignObjectElement::GetCSSPropertyIdForAttrEnum(aAttrEnum);
-  }
-  return eCSSProperty_UNKNOWN;
-}
-
-bool IsNonNegativeGeometryProperty(nsCSSPropertyID aProp) {
-  return aProp == eCSSProperty_r || aProp == eCSSProperty_rx ||
-         aProp == eCSSProperty_ry || aProp == eCSSProperty_width ||
-         aProp == eCSSProperty_height;
-}
-
-bool ElementMapsLengthsToStyle(SVGElement const* aElement) {
-  return aElement->IsSVGElement(nsGkAtoms::rect) ||
-         aElement->IsSVGElement(nsGkAtoms::circle) ||
-         aElement->IsSVGElement(nsGkAtoms::ellipse) ||
-         aElement->IsSVGElement(nsGkAtoms::foreignObject);
-}
-
-}  // namespace SVGGeometryProperty
-}  // namespace dom
-}  // namespace mozilla
deleted file mode 100644
--- a/dom/svg/SVGGeometryProperty.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_SVGGeometryProperty_SVGGeometryProperty_h
-#define mozilla_dom_SVGGeometryProperty_SVGGeometryProperty_h
-
-#include "mozilla/dom/SVGElement.h"
-#include "SVGAnimatedLength.h"
-#include "ComputedStyle.h"
-#include "nsIFrame.h"
-#include <type_traits>
-
-namespace mozilla {
-namespace dom {
-
-namespace SVGGeometryProperty {
-namespace ResolverTypes {
-struct LengthPercentNoAuto {};
-struct LengthPercentRXY {};
-struct LengthPercentWidthHeight {};
-}  // namespace ResolverTypes
-
-namespace Tags {
-
-#define SVGGEOMETRYPROPERTY_GENERATETAG(tagName, resolver, direction, \
-                                        styleStruct)                  \
-  struct tagName {                                                    \
-    using ResolverType = ResolverTypes::resolver;                     \
-    constexpr static auto CtxDirection = SVGContentUtils::direction;  \
-    constexpr static auto Getter = &styleStruct::m##tagName;          \
-  }
-
-SVGGEOMETRYPROPERTY_GENERATETAG(X, LengthPercentNoAuto, X, nsStyleSVGReset);
-SVGGEOMETRYPROPERTY_GENERATETAG(Y, LengthPercentNoAuto, Y, nsStyleSVGReset);
-SVGGEOMETRYPROPERTY_GENERATETAG(Cx, LengthPercentNoAuto, X, nsStyleSVGReset);
-SVGGEOMETRYPROPERTY_GENERATETAG(Cy, LengthPercentNoAuto, Y, nsStyleSVGReset);
-SVGGEOMETRYPROPERTY_GENERATETAG(R, LengthPercentNoAuto, XY, nsStyleSVGReset);
-SVGGEOMETRYPROPERTY_GENERATETAG(Width, LengthPercentWidthHeight, X,
-                                nsStylePosition);
-SVGGEOMETRYPROPERTY_GENERATETAG(Height, LengthPercentWidthHeight, Y,
-                                nsStylePosition);
-
-#undef SVGGEOMETRYPROPERTY_GENERATETAG
-
-struct Ry;
-struct Rx {
-  using ResolverType = ResolverTypes::LengthPercentRXY;
-  constexpr static auto CtxDirection = SVGContentUtils::X;
-  constexpr static auto Getter = &nsStyleSVGReset::mRx;
-  using CounterPart = Ry;
-};
-struct Ry {
-  using ResolverType = ResolverTypes::LengthPercentRXY;
-  constexpr static auto CtxDirection = SVGContentUtils::Y;
-  constexpr static auto Getter = &nsStyleSVGReset::mRy;
-  using CounterPart = Rx;
-};
-
-}  // namespace Tags
-
-namespace details {
-template <class T>
-using AlwaysFloat = float;
-
-using CtxDirectionType = decltype(SVGContentUtils::X);
-
-template <CtxDirectionType CTD>
-float ResolvePureLengthPercentage(SVGElement* aElement,
-                                  const LengthPercentage& aLP) {
-  return aLP.ResolveToCSSPixelsWith(
-      [&] { return CSSCoord{SVGElementMetrics(aElement).GetAxisLength(CTD)}; });
-}
-
-template <class Tag>
-float ResolveImpl(ComputedStyle const& aStyle, SVGElement* aElement,
-                  ResolverTypes::LengthPercentNoAuto) {
-  auto const& value = aStyle.StyleSVGReset()->*Tag::Getter;
-  return ResolvePureLengthPercentage<Tag::CtxDirection>(aElement, value);
-}
-
-template <class Tag>
-float ResolveImpl(ComputedStyle const& aStyle, SVGElement* aElement,
-                  ResolverTypes::LengthPercentWidthHeight) {
-  static_assert(
-      std::is_same<Tag, Tags::Width>{} || std::is_same<Tag, Tags::Height>{},
-      "Wrong tag");
-
-  auto const& value = aStyle.StylePosition()->*Tag::Getter;
-  if (value.IsLengthPercentage()) {
-    return ResolvePureLengthPercentage<Tag::CtxDirection>(
-        aElement, value.AsLengthPercentage());
-  }
-
-  // |auto| and |max-content| etc. are treated as 0.
-  return 0.f;
-}
-
-template <class Tag>
-float ResolveImpl(ComputedStyle const& aStyle, SVGElement* aElement,
-                  ResolverTypes::LengthPercentRXY) {
-  static_assert(std::is_same<Tag, Tags::Rx>{} || std::is_same<Tag, Tags::Ry>{},
-                "Wrong tag");
-
-  auto const& value = aStyle.StyleSVGReset()->*Tag::Getter;
-  if (value.IsLengthPercentage()) {
-    return ResolvePureLengthPercentage<Tag::CtxDirection>(
-        aElement, value.AsLengthPercentage());
-  }
-
-  MOZ_ASSERT(value.IsAuto());
-  using Rother = typename Tag::CounterPart;
-  auto const& valueOther = aStyle.StyleSVGReset()->*Rother::Getter;
-
-  if (valueOther.IsAuto()) {
-    // Per SVG2, |Rx|, |Ry| resolve to 0 if both are |auto|
-    return 0.f;
-  }
-
-  // If |Rx| is auto while |Ry| not, |Rx| gets the value of |Ry|.
-  return ResolvePureLengthPercentage<Rother::CtxDirection>(
-      aElement, valueOther.AsLengthPercentage());
-}
-
-}  // namespace details
-
-template <class Tag>
-float ResolveWith(const ComputedStyle& aStyle, const SVGElement* aElement) {
-  // TODO: There are a lot of utilities lacking const-ness in dom/svg.
-  // We should fix that problem and remove this `const_cast`.
-  return details::ResolveImpl<Tag>(aStyle, const_cast<SVGElement*>(aElement),
-                                   typename Tag::ResolverType{});
-}
-
-// To add support for new properties, or to handle special cases for
-// existing properties, you can add a new tag in |Tags| and |ResolverTypes|
-// namespace, then implement the behavior in |details::ResolveImpl|.
-template <class... Tags>
-bool ResolveAll(const SVGElement* aElement,
-                details::AlwaysFloat<Tags>*... aRes) {
-  if (nsIFrame const* f = aElement->GetPrimaryFrame()) {
-    using dummy = int[];
-    (void)dummy{0, (*aRes = ResolveWith<Tags>(*f->Style(), aElement), 0)...};
-    return true;
-  }
-  return false;
-}
-
-nsCSSUnit SpecifiedUnitTypeToCSSUnit(uint8_t aSpecifiedUnit);
-nsCSSPropertyID AttrEnumToCSSPropId(const SVGElement* aElement,
-                                    uint8_t aAttrEnum);
-
-bool IsNonNegativeGeometryProperty(nsCSSPropertyID aProp);
-bool ElementMapsLengthsToStyle(SVGElement const* aElement);
-
-}  // namespace SVGGeometryProperty
-}  // namespace dom
-}  // namespace mozilla
-
-#endif
--- a/dom/svg/SVGGraphicsElement.h
+++ b/dom/svg/SVGGraphicsElement.h
@@ -27,24 +27,14 @@ class SVGGraphicsElement : public SVGGra
 
   bool IsFocusableInternal(int32_t* aTabIndex, bool aWithMouse) override;
   SVGElement* AsSVGElement() final { return this; }
 
  protected:
   // returns true if focusability has been definitively determined otherwise
   // false
   bool IsSVGFocusable(bool* aIsFocusable, int32_t* aTabIndex);
-
-  template <typename T>
-  bool IsInLengthInfo(const nsAtom* aAttribute, const T& aLengthInfos) const {
-    for (auto const& e : aLengthInfos) {
-      if (e.mName == aAttribute) {
-        return true;
-      }
-    }
-    return false;
-  }
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
 #endif  // mozilla_dom_SVGGraphicsElement_h
--- a/dom/svg/SVGImageElement.cpp
+++ b/dom/svg/SVGImageElement.cpp
@@ -213,18 +213,17 @@ EventStates SVGImageElement::IntrinsicSt
 }
 
 NS_IMETHODIMP_(bool)
 SVGImageElement::IsAttributeMapped(const nsAtom* name) const {
   static const MappedAttributeEntry* const map[] = {
       sViewportsMap,
   };
 
-  return IsInLengthInfo(name, sLengthInfo) ||
-         FindAttributeDependence(name, map) ||
+  return FindAttributeDependence(name, map) ||
          SVGImageElementBase::IsAttributeMapped(name);
 }
 
 //----------------------------------------------------------------------
 // SVGGeometryElement methods
 
 /* For the purposes of the update/invalidation logic pretend to
    be a rectangle. */
--- a/dom/svg/SVGRectElement.cpp
+++ b/dom/svg/SVGRectElement.cpp
@@ -1,23 +1,22 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/SVGRectElement.h"
+#include "nsGkAtoms.h"
 #include "mozilla/dom/SVGLengthBinding.h"
 #include "mozilla/dom/SVGRectElementBinding.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Matrix.h"
 #include "mozilla/gfx/Rect.h"
 #include "mozilla/gfx/PathHelpers.h"
-#include "nsGkAtoms.h"
-#include "SVGGeometryProperty.h"
 #include <algorithm>
 
 NS_IMPL_NS_NEW_SVG_ELEMENT(Rect)
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace dom {
@@ -45,23 +44,16 @@ SVGElement::LengthInfo SVGRectElement::s
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGRectElement::SVGRectElement(
     already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
     : SVGRectElementBase(std::move(aNodeInfo)) {}
 
-bool SVGRectElement::IsAttributeMapped(const nsAtom* aAttribute) const {
-  return IsInLengthInfo(aAttribute, sLengthInfo) ||
-         SVGRectElementBase::IsAttributeMapped(aAttribute);
-}
-
-namespace SVGT = SVGGeometryProperty::Tags;
-
 //----------------------------------------------------------------------
 // nsINode methods
 
 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGRectElement)
 
 //----------------------------------------------------------------------
 
 already_AddRefed<DOMSVGAnimatedLength> SVGRectElement::X() {
@@ -88,44 +80,38 @@ already_AddRefed<DOMSVGAnimatedLength> S
   return mLengthAttributes[ATTR_RY].ToDOMAnimatedLength(this);
 }
 
 //----------------------------------------------------------------------
 // SVGElement methods
 
 /* virtual */
 bool SVGRectElement::HasValidDimensions() const {
-  float width, height;
-
-  MOZ_ASSERT(GetPrimaryFrame());
-  SVGGeometryProperty::ResolveAll<SVGT::Width, SVGT::Height>(this, &width,
-                                                             &height);
-
-  return width > 0 && height > 0;
+  return mLengthAttributes[ATTR_WIDTH].IsExplicitlySet() &&
+         mLengthAttributes[ATTR_WIDTH].GetAnimValInSpecifiedUnits() > 0 &&
+         mLengthAttributes[ATTR_HEIGHT].IsExplicitlySet() &&
+         mLengthAttributes[ATTR_HEIGHT].GetAnimValInSpecifiedUnits() > 0;
 }
 
 SVGElement::LengthAttributesInfo SVGRectElement::GetLengthInfo() {
   return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
                               ArrayLength(sLengthInfo));
 }
 
 //----------------------------------------------------------------------
 // SVGGeometryElement methods
 
 bool SVGRectElement::GetGeometryBounds(Rect* aBounds,
                                        const StrokeOptions& aStrokeOptions,
                                        const Matrix& aToBoundsSpace,
                                        const Matrix* aToNonScalingStrokeSpace) {
   Rect rect;
   Float rx, ry;
-
-  MOZ_ASSERT(GetPrimaryFrame());
-  SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y, SVGT::Width, SVGT::Height,
-                                  SVGT::Rx, SVGT::Ry>(
-      this, &rect.x, &rect.y, &rect.width, &rect.height, &rx, &ry);
+  GetAnimatedLengthValues(&rect.x, &rect.y, &rect.width, &rect.height, &rx, &ry,
+                          nullptr);
 
   if (rect.IsEmpty()) {
     // Rendering of the element disabled
     rect.SetEmpty();  // Make sure width/height are zero and not negative
     // We still want the x/y position from 'rect'
     *aBounds = aToBoundsSpace.TransformBounds(rect);
     return true;
   }
@@ -164,21 +150,17 @@ bool SVGRectElement::GetGeometryBounds(R
   }
 
   *aBounds = aToBoundsSpace.TransformBounds(rect);
   return true;
 }
 
 void SVGRectElement::GetAsSimplePath(SimplePath* aSimplePath) {
   float x, y, width, height, rx, ry;
-
-  MOZ_ASSERT(GetPrimaryFrame());
-  SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y, SVGT::Width, SVGT::Height,
-                                  SVGT::Rx, SVGT::Ry>(this, &x, &y, &width,
-                                                      &height, &rx, &ry);
+  GetAnimatedLengthValues(&x, &y, &width, &height, &rx, &ry, nullptr);
 
   if (width <= 0 || height <= 0) {
     aSimplePath->Reset();
     return;
   }
 
   rx = std::max(rx, 0.0f);
   ry = std::max(ry, 0.0f);
@@ -188,21 +170,17 @@ void SVGRectElement::GetAsSimplePath(Sim
     return;
   }
 
   aSimplePath->SetRect(x, y, width, height);
 }
 
 already_AddRefed<Path> SVGRectElement::BuildPath(PathBuilder* aBuilder) {
   float x, y, width, height, rx, ry;
-
-  MOZ_ASSERT(GetPrimaryFrame());
-  SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y, SVGT::Width, SVGT::Height,
-                                  SVGT::Rx, SVGT::Ry>(this, &x, &y, &width,
-                                                      &height, &rx, &ry);
+  GetAnimatedLengthValues(&x, &y, &width, &height, &rx, &ry, nullptr);
 
   if (width <= 0 || height <= 0) {
     return nullptr;
   }
 
   rx = std::max(rx, 0.0f);
   ry = std::max(ry, 0.0f);
 
@@ -210,56 +188,33 @@ already_AddRefed<Path> SVGRectElement::B
     // Optimization for the no rounded corners case.
     Rect r(x, y, width, height);
     aBuilder->MoveTo(r.TopLeft());
     aBuilder->LineTo(r.TopRight());
     aBuilder->LineTo(r.BottomRight());
     aBuilder->LineTo(r.BottomLeft());
     aBuilder->Close();
   } else {
+    // If either the 'rx' or the 'ry' attribute isn't set, then we have to
+    // set it to the value of the other:
+    bool hasRx = mLengthAttributes[ATTR_RX].IsExplicitlySet();
+    bool hasRy = mLengthAttributes[ATTR_RY].IsExplicitlySet();
+    MOZ_ASSERT(hasRx || hasRy);
+
+    if (hasRx && !hasRy) {
+      ry = rx;
+    } else if (hasRy && !hasRx) {
+      rx = ry;
+    }
+
     // Clamp rx and ry to half the rect's width and height respectively:
     rx = std::min(rx, width / 2);
     ry = std::min(ry, height / 2);
 
     RectCornerRadii radii(rx, ry);
     AppendRoundedRectToPath(aBuilder, Rect(x, y, width, height), radii);
   }
 
   return aBuilder->Finish();
 }
 
-bool SVGRectElement::IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
-                                           const ComputedStyle& aOldStyle) {
-  auto *newSVGReset = aNewStyle.StyleSVGReset(),
-       *oldSVGReset = aOldStyle.StyleSVGReset();
-  auto *newPosition = aNewStyle.StylePosition(),
-       *oldPosition = aOldStyle.StylePosition();
-
-  return newSVGReset->mX != oldSVGReset->mX ||
-         newSVGReset->mY != oldSVGReset->mY ||
-         newPosition->mWidth != oldPosition->mWidth ||
-         newPosition->mHeight != oldPosition->mHeight ||
-         newSVGReset->mRx != oldSVGReset->mRx ||
-         newSVGReset->mRy != oldSVGReset->mRy;
-}
-
-nsCSSPropertyID SVGRectElement::GetCSSPropertyIdForAttrEnum(uint8_t aAttrEnum) {
-  switch (aAttrEnum) {
-    case ATTR_X:
-      return eCSSProperty_x;
-    case ATTR_Y:
-      return eCSSProperty_y;
-    case ATTR_WIDTH:
-      return eCSSProperty_width;
-    case ATTR_HEIGHT:
-      return eCSSProperty_height;
-    case ATTR_RX:
-      return eCSSProperty_rx;
-    case ATTR_RY:
-      return eCSSProperty_ry;
-    default:
-      MOZ_ASSERT_UNREACHABLE("Unknown attr enum");
-      return eCSSProperty_UNKNOWN;
-  }
-}
-
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/svg/SVGRectElement.h
+++ b/dom/svg/SVGRectElement.h
@@ -2,60 +2,51 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_SVGRectElement_h
 #define mozilla_dom_SVGRectElement_h
 
-#include "nsCSSPropertyID.h"
 #include "SVGAnimatedLength.h"
 #include "SVGGeometryElement.h"
 
 nsresult NS_NewSVGRectElement(
     nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 namespace mozilla {
-class ComputedStyle;
-
 namespace dom {
 
 typedef SVGGeometryElement SVGRectElementBase;
 
 class SVGRectElement final : public SVGRectElementBase {
  protected:
   explicit SVGRectElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   virtual JSObject* WrapNode(JSContext* cx,
                              JS::Handle<JSObject*> aGivenProto) override;
   friend nsresult(::NS_NewSVGRectElement(
       nsIContent** aResult,
       already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
 
  public:
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
-
   // nsSVGSVGElement methods:
   virtual bool HasValidDimensions() const override;
 
   // SVGGeometryElement methods:
   virtual bool GetGeometryBounds(
       Rect* aBounds, const StrokeOptions& aStrokeOptions,
       const Matrix& aToBoundsSpace,
       const Matrix* aToNonScalingStrokeSpace = nullptr) override;
   virtual void GetAsSimplePath(SimplePath* aSimplePath) override;
   virtual already_AddRefed<Path> BuildPath(
       PathBuilder* aBuilder = nullptr) override;
 
   virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
 
-  static bool IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
-                                    const ComputedStyle& aOldStyle);
-  static nsCSSPropertyID GetCSSPropertyIdForAttrEnum(uint8_t aAttrEnum);
-
   // WebIDL
   already_AddRefed<DOMSVGAnimatedLength> X();
   already_AddRefed<DOMSVGAnimatedLength> Y();
   already_AddRefed<DOMSVGAnimatedLength> Height();
   already_AddRefed<DOMSVGAnimatedLength> Width();
   already_AddRefed<DOMSVGAnimatedLength> Rx();
   already_AddRefed<DOMSVGAnimatedLength> Ry();
 
--- a/dom/svg/SVGViewportElement.h
+++ b/dom/svg/SVGViewportElement.h
@@ -119,43 +119,43 @@ class SVGViewportElement : public SVGGra
     return svgFloatSize(mViewportWidth, mViewportHeight);
   }
 
   void SetViewportSize(const svgFloatSize& aSize) {
     mViewportWidth = aSize.width;
     mViewportHeight = aSize.height;
   }
 
-  /**
-   * Returns true if either this is an SVG <svg> element that is the child of
-   * another non-foreignObject SVG element, or this is a SVG <symbol> element
-   * this is the root of a use-element shadow tree.
-   */
-  bool IsInner() const {
-    const nsIContent* parent = GetFlattenedTreeParent();
-    return parent && parent->IsSVGElement() &&
-           !parent->IsSVGElement(nsGkAtoms::foreignObject);
-  }
-
   // WebIDL
   already_AddRefed<SVGAnimatedRect> ViewBox();
   already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
   virtual SVGAnimatedViewBox* GetAnimatedViewBox() override;
 
  protected:
   // implementation helpers:
 
   bool IsRoot() const {
     NS_ASSERTION((IsInUncomposedDoc() && !GetParent()) ==
                      (OwnerDoc()->GetRootElement() == this),
                  "Can't determine if we're root");
     return IsInUncomposedDoc() && !GetParent();
   }
 
   /**
+   * Returns true if either this is an SVG <svg> element that is the child of
+   * another non-foreignObject SVG element, or this is a SVG <symbol> element
+   * this is the root of a use-element shadow tree.
+   */
+  bool IsInner() const {
+    const nsIContent* parent = GetFlattenedTreeParent();
+    return parent && parent->IsSVGElement() &&
+           !parent->IsSVGElement(nsGkAtoms::foreignObject);
+  }
+
+  /**
    * Returns the explicit or default preserveAspectRatio, unless we're
    * synthesizing a viewBox, in which case it returns the "none" value.
    */
   virtual SVGPreserveAspectRatio GetPreserveAspectRatioWithOverride() const {
     return mPreserveAspectRatio.GetAnimValue();
   }
 
   /**
--- a/dom/svg/moz.build
+++ b/dom/svg/moz.build
@@ -176,17 +176,16 @@ UNIFIED_SOURCES += [
     'SVGFETileElement.cpp',
     'SVGFETurbulenceElement.cpp',
     'SVGFilterElement.cpp',
     'SVGFilters.cpp',
     'SVGForeignObjectElement.cpp',
     'SVGFragmentIdentifier.cpp',
     'SVGGElement.cpp',
     'SVGGeometryElement.cpp',
-    'SVGGeometryProperty.cpp',
     'SVGGradientElement.cpp',
     'SVGGraphicsElement.cpp',
     'SVGImageElement.cpp',
     'SVGIntegerPairSMILType.cpp',
     'SVGLength.cpp',
     'SVGLengthList.cpp',
     'SVGLengthListSMILType.cpp',
     'SVGLineElement.cpp',
--- a/layout/base/nsILayoutHistoryState.idl
+++ b/layout/base/nsILayoutHistoryState.idl
@@ -34,18 +34,17 @@ interface nsILayoutHistoryState : nsISup
   * Whether this LayoutHistoryState contains any PresStates.
   */
   readonly attribute boolean hasStates;
 
   /**
   * Get the keys of all PresStates held by this LayoutHistoryState.
   * Note: Check hasStates first.
   */
-  void getKeys([optional] out uint32_t aCount,
-               [array, size_is(aCount), retval] out string aKeys);
+  Array<ACString> getKeys();
 
   /*
   * Attempts to get the data of the PresState corresponding to
   * the passed key. Throws if no data could be found.
   */
   void getPresState(in ACString aKey,
                     out float aScrollX, out float aScrollY,
                     out boolean aAllowScrollOriginDowngrade,
--- a/layout/base/nsLayoutHistoryState.cpp
+++ b/layout/base/nsLayoutHistoryState.cpp
@@ -43,29 +43,24 @@ NS_IMPL_ISUPPORTS(nsLayoutHistoryState, 
 
 NS_IMETHODIMP
 nsLayoutHistoryState::GetHasStates(bool* aHasStates) {
   *aHasStates = HasStates();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsLayoutHistoryState::GetKeys(uint32_t* aCount, char*** aKeys) {
+nsLayoutHistoryState::GetKeys(nsTArray<nsCString>& aKeys) {
   if (!HasStates()) {
     return NS_ERROR_FAILURE;
   }
 
-  char** keys =
-      static_cast<char**>(moz_xmalloc(sizeof(char*) * mStates.Count()));
-  *aCount = mStates.Count();
-  *aKeys = keys;
-
+  aKeys.SetCapacity(mStates.Count());
   for (auto iter = mStates.Iter(); !iter.Done(); iter.Next()) {
-    *keys = ToNewCString(iter.Key());
-    keys++;
+    aKeys.AppendElement(iter.Key());
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsLayoutHistoryState::GetPresState(const nsACString& aKey, float* aScrollX,
                                    float* aScrollY,
deleted file mode 100644
--- a/layout/reftests/svg/geometry-properties-in-css-ref.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!doctype html>
-<svg width="800" height="600">
-  <g>
-    <rect x="40" y="40" width="100" height="100" rx="30" ry="30" fill="purple" />
-    <rect x="40" y="150" width="30" height="200" rx="20" ry="20" fill="magenta" />
-  </g>
-  <circle cx="170" cy="340" r="70px" fill="pink" />
-  <g>
-    <circle cx="230" cy="130" r="70px" fill="skyblue" />
-  </g>
-  <svg x="300" width="200" height="200" viewBox="0 0 100 100">
-    <ellipse cx="30" cy="100" rx="20" ry="40" fill="cyan" />
-    <ellipse cx="80" cy="50" rx="20" ry="40" fill="navy" />
-  </svg>
-  <foreignObject x="450" y="200" width="80" height="130">
-    <svg>
-      <rect width="50" height="50" rx="4" ry="4" fill="brown" />
-    </svg>
-  </foreignObject>
-</svg>
deleted file mode 100644
--- a/layout/reftests/svg/geometry-properties-in-css.html
+++ /dev/null
@@ -1,75 +0,0 @@
-<!doctype html>
-<style>
-  svg {
-    width: 800px;
-    height: 600px;
-    font-size: 10px;
-  }
-  svg svg {
-    width: 80px;
-    height: 80px;
-  }
-  rect:first-child {
-    x: 40px;
-    y: calc(5% + 10px);
-    width: calc(80px + 2em);
-    height: 10em;
-    rx: auto;
-    ry: 5%;
-    cx: 100px;
-    cy: 200px;
-  }
-  circle {
-    r: calc(70px);
-  }
-  g > #c2 {
-    cx: 80px;
-    cy: calc(20% + 10px);
-    x: 40px;
-    y: calc(5% + 10px);
-  }
-  svg > svg > ellipse {
-    cx: 30%;
-    cy: 100px;
-    rx: 20px;
-    ry: 40px;
-  }
-  svg > svg > ellipse:nth-child(2) {
-    transform: translate(50px, -50px);
-  }
-  svg ellipse {
-    cx: 10px;
-    cy: 10px;
-    rx: 10px;
-    ry: 10px;
-  }
-  foreignObject {
-    transform: translate(450px,0);
-    y: 200px;
-    width: 80px;
-    height: 130px;
-  }
-  #r2 {
-    width: 50px;
-    height:50px;
-  }
-</style>
-<svg>
-  <g>
-    <rect x="0" y="-10" width="30px" height="10px" rx="-5px" ry="auto" fill="purple" />
-    <rect x=" 40px /* some nonsense */ " y="150" width="30" height="20em" rx="20px" ry="20px" fill="magenta" />
-  </g>
-  <circle cx="/* more nonsense */ 170" cy="340" r="-5px" fill="pink" />
-  <g transform="translate(150,0)">
-    <circle id="c2" cx="20" cy="40" fill="skyblue" />
-  </g>
-  <svg x="300" width="200px" height="200px" viewBox="0 0 100 100">
-    <ellipse fill="cyan" />
-    <ellipse fill="navy" />
-  </svg>
-  <foreignObject>
-    <svg>
-      <rect id="r2" style="x:0;y:0" fill="brown" />
-    </svg>
-  </foreignObject>
-</svg>
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -239,17 +239,16 @@ fuzzy-if(Android,0-18,0-600) == foreignO
 == foreignObject-dynamic-line-height-01.html foreignObject-dynamic-line-height-01-ref.html
 == foreignObject-vertical-01.svg foreignObject-vertical-01-ref.svg
 
 == fragmentIdentifier-01.xhtml pass.svg
 
 == g-transform-01.svg pass.svg
 
 == getElementById-a-element-01.svg pass.svg
-== geometry-properties-in-css.html geometry-properties-in-css-ref.html
 
 fuzzy-if(Android,0-9,0-980) fuzzy-if(skiaContent,0-3,0-32000) == gradient-live-01a.svg gradient-live-01-ref.svg
 fuzzy-if(Android,0-9,0-980) fuzzy-if(skiaContent,0-3,0-32000) == gradient-live-01b.svg gradient-live-01-ref.svg
 fuzzy-if(Android,0-9,0-980) fuzzy-if(skiaContent,0-3,0-32000) == gradient-live-01c.svg gradient-live-01-ref.svg
 fuzzy-if(Android,0-9,0-980) fuzzy-if(skiaContent,0-3,0-32000) == gradient-live-01d.svg gradient-live-01-ref.svg
 == gradient-transform-01.svg pass.svg
 == href-attr-change-restyles.svg href-attr-change-restyles-ref.svg
 fuzzy-if(skiaContent,0-1,0-550) == import-svg-01.html pass.svg
--- a/layout/style/nsDOMCSSAttrDeclaration.cpp
+++ b/layout/style/nsDOMCSSAttrDeclaration.cpp
@@ -5,22 +5,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* DOM object for element.style */
 
 #include "nsDOMCSSAttrDeclaration.h"
 
 #include "mozilla/dom/Document.h"
 #include "mozilla/dom/Element.h"
-#include "mozilla/dom/SVGElement.h"
 #include "mozilla/dom/MutationEventBinding.h"
 #include "mozilla/DeclarationBlock.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "mozilla/SMILCSSValueType.h"
-#include "mozilla/SMILValue.h"
 #include "mozAutoDocUpdate.h"
 #include "nsIURI.h"
 #include "nsNodeUtils.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsIFrame.h"
 #include "ActiveLayerTracker.h"
 
 using namespace mozilla;
@@ -130,59 +128,39 @@ nsDOMCSSAttributeDeclaration::GetParsing
     nsIPrincipal* aSubjectPrincipal) const {
   return {
       mElement->GetURLDataForStyleAttr(aSubjectPrincipal),
       mElement->OwnerDoc()->GetCompatibilityMode(),
       mElement->OwnerDoc()->CSSLoader(),
   };
 }
 
-template <typename SetterFunc>
-nsresult nsDOMCSSAttributeDeclaration::SetSMILValueHelper(SetterFunc aFunc) {
+nsresult nsDOMCSSAttributeDeclaration::SetSMILValue(
+    const nsCSSPropertyID aPropID, const SMILValue& aValue) {
   MOZ_ASSERT(mIsSMILOverride);
-
   // No need to do the ActiveLayerTracker / ScrollLinkedEffectDetector bits,
   // since we're in a SMIL animation anyway, no need to try to detect we're a
   // scripted animation.
   RefPtr<DeclarationBlock> created;
   DeclarationBlock* olddecl =
       GetOrCreateCSSDeclaration(eOperation_Modify, getter_AddRefs(created));
   if (!olddecl) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   mozAutoDocUpdate autoUpdate(DocToUpdate(), true);
   RefPtr<DeclarationBlock> decl = olddecl->EnsureMutable();
-
-  bool changed = aFunc(*decl);
-
+  bool changed = SMILCSSValueType::SetPropertyValues(aValue, *decl);
   if (changed) {
     // We can pass nullptr as the latter param, since this is
     // mIsSMILOverride == true case.
     SetCSSDeclaration(decl, nullptr);
   }
   return NS_OK;
 }
 
-nsresult nsDOMCSSAttributeDeclaration::SetSMILValue(
-    const nsCSSPropertyID /*aPropID*/, const SMILValue& aValue) {
-  MOZ_ASSERT(aValue.mType == &SMILCSSValueType::sSingleton,
-             "We should only try setting a CSS value type");
-  return SetSMILValueHelper([&aValue](DeclarationBlock& aDecl) {
-    return SMILCSSValueType::SetPropertyValues(aValue, aDecl);
-  });
-}
-
-nsresult nsDOMCSSAttributeDeclaration::SetSMILValue(
-    const nsCSSPropertyID aPropID, const SVGAnimatedLength& aLength) {
-  return SetSMILValueHelper([aPropID, &aLength](DeclarationBlock& aDecl) {
-    return SVGElement::UpdateDeclarationBlockFromLength(
-        aDecl, aPropID, aLength, SVGElement::ValToUse::Anim);
-  });
-}
-
 nsresult nsDOMCSSAttributeDeclaration::SetPropertyValue(
     const nsCSSPropertyID aPropID, const nsAString& aValue,
     nsIPrincipal* aSubjectPrincipal) {
   // Scripted modifications to style.opacity or style.transform (or other
   // transform-like properties, e.g. style.translate, style.rotate, style.scale)
   // could immediately force us into the animated state if heuristics suggest
   // this is scripted animation.
   // FIXME: This is missing the margin shorthand and the logical versions of
--- a/layout/style/nsDOMCSSAttrDeclaration.h
+++ b/layout/style/nsDOMCSSAttrDeclaration.h
@@ -13,48 +13,44 @@
 #include "mozilla/dom/DocGroup.h"
 #include "nsDOMCSSDeclaration.h"
 
 struct RawServoUnlockedDeclarationBlock;
 
 namespace mozilla {
 
 class SMILValue;
-class SVGAnimatedLength;
 
 namespace dom {
 class DomGroup;
 class Element;
 }  // namespace dom
 }  // namespace mozilla
 
 class nsDOMCSSAttributeDeclaration final : public nsDOMCSSDeclaration {
  public:
   typedef mozilla::dom::Element Element;
   typedef mozilla::SMILValue SMILValue;
-  typedef mozilla::SVGAnimatedLength SVGAnimatedLength;
   nsDOMCSSAttributeDeclaration(Element* aContent, bool aIsSMILOverride);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(
       nsDOMCSSAttributeDeclaration, nsICSSDeclaration)
 
   mozilla::DeclarationBlock* GetOrCreateCSSDeclaration(
       Operation aOperation, mozilla::DeclarationBlock** aCreated) final;
 
   nsDOMCSSDeclaration::ParsingEnvironment GetParsingEnvironment(
       nsIPrincipal* aSubjectPrincipal) const final;
 
   mozilla::css::Rule* GetParentRule() override { return nullptr; }
 
   nsINode* GetParentObject() override { return mElement; }
 
-  nsresult SetSMILValue(const nsCSSPropertyID aPropID, const SMILValue& aValue);
-  nsresult SetSMILValue(const nsCSSPropertyID aPropID,
-                        const SVGAnimatedLength& aLength);
+  nsresult SetSMILValue(const nsCSSPropertyID aPropID, const SMILValue&);
 
   nsresult SetPropertyValue(const nsCSSPropertyID aPropID,
                             const nsAString& aValue,
                             nsIPrincipal* aSubjectPrincipal) override;
 
   static void MutationClosureFunction(void* aData);
 
   void GetPropertyChangeClosure(
@@ -78,15 +74,11 @@ class nsDOMCSSAttributeDeclaration final
 
   RefPtr<Element> mElement;
 
   /* If true, this indicates that this nsDOMCSSAttributeDeclaration
    * should interact with mContent's SMIL override style rule (rather
    * than the inline style rule).
    */
   const bool mIsSMILOverride;
-
- private:
-  template <typename SetterFunc>
-  nsresult SetSMILValueHelper(SetterFunc aFunc);
 };
 
 #endif /* nsDOMCSSAttributeDeclaration_h */
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1064,46 +1064,32 @@ void nsStyleFilter::SetDropShadow(nsCSSS
   mDropShadow->AddRef();
   mType = NS_STYLE_FILTER_DROP_SHADOW;
 }
 
 // --------------------
 // nsStyleSVGReset
 //
 nsStyleSVGReset::nsStyleSVGReset(const Document& aDocument)
-    : mX(LengthPercentage::Zero()),
-      mY(LengthPercentage::Zero()),
-      mCx(LengthPercentage::Zero()),
-      mCy(LengthPercentage::Zero()),
-      mRx(NonNegativeLengthPercentageOrAuto::Auto()),
-      mRy(NonNegativeLengthPercentageOrAuto::Auto()),
-      mR(NonNegativeLengthPercentage::Zero()),
-      mMask(nsStyleImageLayers::LayerType::Mask),
+    : mMask(nsStyleImageLayers::LayerType::Mask),
       mStopColor(StyleColor::Black()),
       mFloodColor(StyleColor::Black()),
       mLightingColor(StyleColor::White()),
       mStopOpacity(1.0f),
       mFloodOpacity(1.0f),
       mDominantBaseline(NS_STYLE_DOMINANT_BASELINE_AUTO),
       mVectorEffect(NS_STYLE_VECTOR_EFFECT_NONE),
       mMaskType(NS_STYLE_MASK_TYPE_LUMINANCE) {
   MOZ_COUNT_CTOR(nsStyleSVGReset);
 }
 
 nsStyleSVGReset::~nsStyleSVGReset() { MOZ_COUNT_DTOR(nsStyleSVGReset); }
 
 nsStyleSVGReset::nsStyleSVGReset(const nsStyleSVGReset& aSource)
-    : mX(aSource.mX),
-      mY(aSource.mY),
-      mCx(aSource.mCx),
-      mCy(aSource.mCy),
-      mRx(aSource.mRx),
-      mRy(aSource.mRy),
-      mR(aSource.mR),
-      mMask(aSource.mMask),
+    : mMask(aSource.mMask),
       mClipPath(aSource.mClipPath),
       mStopColor(aSource.mStopColor),
       mFloodColor(aSource.mFloodColor),
       mLightingColor(aSource.mLightingColor),
       mStopOpacity(aSource.mStopOpacity),
       mFloodOpacity(aSource.mFloodOpacity),
       mDominantBaseline(aSource.mDominantBaseline),
       mVectorEffect(aSource.mVectorEffect),
@@ -1145,22 +1131,16 @@ void nsStyleSVGReset::TriggerImageLoads(
     }
   }
 }
 
 nsChangeHint nsStyleSVGReset::CalcDifference(
     const nsStyleSVGReset& aNewData) const {
   nsChangeHint hint = nsChangeHint(0);
 
-  if (mX != aNewData.mX || mY != aNewData.mY || mCx != aNewData.mCx ||
-      mCy != aNewData.mCy || mR != aNewData.mR || mRx != aNewData.mRx ||
-      mRy != aNewData.mRy) {
-    hint |= nsChangeHint_InvalidateRenderingObservers | nsChangeHint_NeedReflow;
-  }
-
   if (mClipPath != aNewData.mClipPath) {
     hint |= nsChangeHint_UpdateEffects | nsChangeHint_RepaintFrame;
   }
 
   if (mDominantBaseline != aNewData.mDominantBaseline) {
     // XXXjwatt: why NS_STYLE_HINT_REFLOW? Isn't that excessive?
     hint |= NS_STYLE_HINT_REFLOW;
   } else if (mVectorEffect != aNewData.mVectorEffect) {
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2854,25 +2854,16 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
   }
 
   bool HasMask() const;
 
   bool HasNonScalingStroke() const {
     return mVectorEffect == NS_STYLE_VECTOR_EFFECT_NON_SCALING_STROKE;
   }
 
-  // geometry properties
-  mozilla::LengthPercentage mX;
-  mozilla::LengthPercentage mY;
-  mozilla::LengthPercentage mCx;
-  mozilla::LengthPercentage mCy;
-  mozilla::NonNegativeLengthPercentageOrAuto mRx;
-  mozilla::NonNegativeLengthPercentageOrAuto mRy;
-  mozilla::NonNegativeLengthPercentage mR;
-
   nsStyleImageLayers mMask;
   mozilla::StyleShapeSource mClipPath;
   mozilla::StyleColor mStopColor;
   mozilla::StyleColor mFloodColor;
   mozilla::StyleColor mLightingColor;
 
   float mStopOpacity;
   float mFloodOpacity;
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -5627,72 +5627,16 @@ var gCSSProperties = {
   "stroke-width": {
     domProp: "strokeWidth",
     inherited: true,
     type: CSS_TYPE_LONGHAND,
     initial_values: [ "1px" ],
     other_values: [ "0", "0px", "-0em", "17px", "0.2em", "0.0002", "context-value" ],
     invalid_values: [ "-0.1px", "-3px" ]
   },
-  "x": {
-    domProp: "x",
-    inherited: false,
-    type: CSS_TYPE_LONGHAND,
-    initial_values: [ "0px" ],
-    other_values: [ "-1em", "17px", "0.2em", "23.4%" ],
-    invalid_values: [ "auto", "context-value", "0.0002" ]
-  },
-  "y": {
-    domProp: "y",
-    inherited: false,
-    type: CSS_TYPE_LONGHAND,
-    initial_values: [ "0px" ],
-    other_values: [ "-1em", "17px", "0.2em", "23.4%" ],
-    invalid_values: [ "auto", "context-value", "0.0002" ]
-  },
-  "cx": {
-    domProp: "cx",
-    inherited: false,
-    type: CSS_TYPE_LONGHAND,
-    initial_values: [ "0px" ],
-    other_values: [ "-1em", "17px", "0.2em", "23.4%" ],
-    invalid_values: [ "auto", "context-value", "0.0002" ]
-  },
-  "cy": {
-    domProp: "cy",
-    inherited: false,
-    type: CSS_TYPE_LONGHAND,
-    initial_values: [ "0px" ],
-    other_values: [ "-1em", "17px", "0.2em", "23.4%" ],
-    invalid_values: [ "auto", "context-value", "0.0002" ]
-  },
-  "r": {
-    domProp: "r",
-    inherited: false,
-    type: CSS_TYPE_LONGHAND,
-    initial_values: [ "0px" ],
-    other_values: [ "17px", "0.2em", "23.4%" ],
-    invalid_values: [ "auto", "-1", "-1.5px", "0.0002" ]
-  },
-  "rx": {
-    domProp: "rx",
-    inherited: false,
-    type: CSS_TYPE_LONGHAND,
-    initial_values: [ "auto" ],
-    other_values: [ "17px", "0.2em", "23.4%" ],
-    invalid_values: [ "hello", "-12px", "0.0002" ]
-  },
-  "ry": {
-    domProp: "ry",
-    inherited: false,
-    type: CSS_TYPE_LONGHAND,
-    initial_values: [ "auto" ],
-    other_values: [ "17px", "0.2em", "23.4%" ],
-    invalid_values: [ "hello", "-1.3px", "0.0002" ]
-  },
   "text-anchor": {
     domProp: "textAnchor",
     inherited: true,
     type: CSS_TYPE_LONGHAND,
     initial_values: [ "start" ],
     other_values: [ "middle", "end" ],
     invalid_values: []
   },
--- a/layout/style/test/test_transitions_per_property.html
+++ b/layout/style/test/test_transitions_per_property.html
@@ -75,20 +75,16 @@ var supported_properties = {
     "column-count": [ test_pos_integer_or_auto_transition,
                       test_integer_at_least_one_clamping ],
     "column-rule-color": [ test_color_transition,
                            test_currentcolor_transition ],
     "column-rule-width": [ test_length_transition,
                            test_length_clamped ],
     "column-width": [ test_length_transition,
                       test_length_clamped ],
-    "cx": [ test_length_transition, test_percent_transition,
-            test_length_unclamped, test_percent_unclamped ],
-    "cy": [ test_length_transition, test_percent_transition,
-            test_length_unclamped, test_percent_unclamped ],
     "-moz-image-region": [ test_rect_transition ],
     "-moz-outline-radius-bottomleft": [ test_radius_transition ],
     "-moz-outline-radius-bottomright": [ test_radius_transition ],
     "-moz-outline-radius-topleft": [ test_radius_transition ],
     "-moz-outline-radius-topright": [ test_radius_transition ],
     "background-color": [ test_color_transition,
                           test_currentcolor_transition ],
     "background-position": [ test_background_position_transition,
@@ -243,22 +239,16 @@ var supported_properties = {
                      test_length_clamped, test_percent_clamped ],
     "perspective": [ test_length_transition ],
     "perspective-origin": [ test_length_pair_transition,
                             test_length_percent_pair_transition,
                             test_length_percent_pair_unclamped ],
     "right": [ test_length_transition, test_percent_transition,
                test_length_percent_calc_transition,
                test_length_unclamped, test_percent_unclamped ],
-    "r": [ test_length_transition, test_percent_transition,
-           test_length_clamped, test_percent_clamped ],
-    "rx": [ test_length_transition, test_percent_transition,
-            test_length_clamped, test_percent_clamped ],
-    "ry": [ test_length_transition, test_percent_transition,
-            test_length_clamped, test_percent_clamped ],
     "shape-image-threshold": [ test_float_zeroToOne_transition,
                                // shape-image-threshold (like opacity) is
                                // clamped in computed style
                                // (not parsing/interpolation)
                                test_float_zeroToOne_clamped ],
     "shape-margin": [ test_length_transition, test_percent_transition,
                       test_length_clamped, test_percent_clamped ],
     "shape-outside": [ test_basic_shape_or_url_transition ],
@@ -302,20 +292,16 @@ var supported_properties = {
                           test_length_percent_pair_unclamped ],
     "vertical-align": [ test_length_transition, test_percent_transition,
                         test_length_unclamped, test_percent_unclamped ],
     "visibility": [ test_visibility_transition ],
     "width": [ test_length_transition, test_percent_transition,
                test_length_percent_calc_transition,
                test_length_clamped, test_percent_clamped ],
     "word-spacing": [ test_length_transition, test_length_unclamped ],
-    "x": [ test_length_transition, test_percent_transition,
-           test_length_unclamped, test_percent_unclamped ],
-    "y": [ test_length_transition, test_percent_transition,
-           test_length_unclamped, test_percent_unclamped ],
     "z-index": [ test_integer_transition, test_pos_integer_or_auto_transition ],
     "-webkit-line-clamp": [ test_pos_integer_or_none_transition ],
     "-webkit-text-fill-color": [ test_color_transition,
                                  test_currentcolor_transition ],
     "-webkit-text-stroke-color": [ test_color_transition,
                                    test_currentcolor_transition ]
 };
 
--- a/layout/svg/SVGGeometryFrame.cpp
+++ b/layout/svg/SVGGeometryFrame.cpp
@@ -192,20 +192,16 @@ void SVGGeometryFrame::DidSetComputedSty
         }
       } else {
         if (StyleSVG()->mFillRule != oldStyleSVG->mFillRule) {
           // Moz2D Path objects are fill-rule specific.
           element->ClearAnyCachedPath();
         }
       }
     }
-
-    if (element->IsGeometryChangedViaCSS(*Style(), *aOldComputedStyle)) {
-      element->ClearAnyCachedPath();
-    }
   }
 }
 
 bool SVGGeometryFrame::IsSVGTransformed(
     gfx::Matrix* aOwnTransform, gfx::Matrix* aFromParentTransform) const {
   bool foundTransform = false;
 
   // Check if our parent has children-only transforms:
--- a/layout/svg/nsSVGForeignObjectFrame.cpp
+++ b/layout/svg/nsSVGForeignObjectFrame.cpp
@@ -14,26 +14,24 @@
 #include "mozilla/PresShell.h"
 #include "mozilla/dom/SVGForeignObjectElement.h"
 #include "nsDisplayList.h"
 #include "nsGkAtoms.h"
 #include "nsNameSpaceManager.h"
 #include "nsLayoutUtils.h"
 #include "nsRegion.h"
 #include "nsSVGContainerFrame.h"
-#include "SVGGeometryProperty.h"
 #include "SVGObserverUtils.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGOuterSVGFrame.h"
 #include "nsSVGUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::image;
-namespace SVGT = SVGGeometryProperty::Tags;
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsContainerFrame* NS_NewSVGForeignObjectFrame(PresShell* aPresShell,
                                               ComputedStyle* aStyle) {
   return new (aPresShell)
       nsSVGForeignObjectFrame(aStyle, aPresShell->GetPresContext());
@@ -239,19 +237,18 @@ void nsSVGForeignObjectFrame::PaintSVG(g
       return;
     }
   }
 
   aContext.Save();
 
   if (StyleDisplay()->IsScrollableOverflow()) {
     float x, y, width, height;
-    SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y, SVGT::Width,
-                                    SVGT::Height>(
-        static_cast<SVGElement*>(GetContent()), &x, &y, &width, &height);
+    static_cast<SVGElement*>(GetContent())
+        ->GetAnimatedLengthValues(&x, &y, &width, &height, nullptr);
 
     gfxRect clipRect =
         nsSVGUtils::GetClipRectForFrame(this, 0.0f, 0.0f, width, height);
     nsSVGUtils::SetClipRect(&aContext, aTransform, clipRect);
   }
 
   // SVG paints in CSS px, but normally frames paint in dev pixels. Here we
   // multiply a CSS-px-to-dev-pixel factor onto aTransform so our children
@@ -289,18 +286,18 @@ nsIFrame* nsSVGForeignObjectFrame::GetFr
   }
 
   nsIFrame* kid = PrincipalChildList().FirstChild();
   if (!kid) {
     return nullptr;
   }
 
   float x, y, width, height;
-  SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y, SVGT::Width, SVGT::Height>(
-      static_cast<SVGElement*>(GetContent()), &x, &y, &width, &height);
+  static_cast<SVGElement*>(GetContent())
+      ->GetAnimatedLengthValues(&x, &y, &width, &height, nullptr);
 
   if (!gfxRect(x, y, width, height).Contains(aPoint) ||
       !nsSVGUtils::HitTestClip(this, aPoint)) {
     return nullptr;
   }
 
   // Convert the point to app units relative to the top-left corner of the
   // viewport that's established by the foreignObject element:
@@ -321,18 +318,18 @@ void nsSVGForeignObjectFrame::ReflowSVG(
   if (!nsSVGUtils::NeedsReflowSVG(this)) {
     return;
   }
 
   // We update mRect before the DoReflow call so that DoReflow uses the
   // correct dimensions:
 
   float x, y, w, h;
-  SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y, SVGT::Width, SVGT::Height>(
-      static_cast<SVGElement*>(GetContent()), &x, &y, &w, &h);
+  static_cast<SVGForeignObjectElement*>(GetContent())
+      ->GetAnimatedLengthValues(&x, &y, &w, &h, nullptr);
 
   // If mRect's width or height are negative, reflow blows up! We must clamp!
   if (w < 0.0f) w = 0.0f;
   if (h < 0.0f) h = 0.0f;
 
   mRect = nsLayoutUtils::RoundGfxRectToAppRect(gfxRect(x, y, w, h),
                                                AppUnitsPerCSSPixel());
 
@@ -374,27 +371,31 @@ void nsSVGForeignObjectFrame::NotifySVGC
   MOZ_ASSERT(aFlags & (TRANSFORM_CHANGED | COORD_CONTEXT_CHANGED),
              "Invalidation logic may need adjusting");
 
   bool needNewBounds = false;  // i.e. mRect or visual overflow rect
   bool needReflow = false;
   bool needNewCanvasTM = false;
 
   if (aFlags & COORD_CONTEXT_CHANGED) {
+    SVGForeignObjectElement* fO =
+        static_cast<SVGForeignObjectElement*>(GetContent());
     // Coordinate context changes affect mCanvasTM if we have a
     // percentage 'x' or 'y'
-    if (StyleSVGReset()->mX.HasPercent() || StyleSVGReset()->mY.HasPercent()) {
+    if (fO->mLengthAttributes[SVGForeignObjectElement::ATTR_X].IsPercentage() ||
+        fO->mLengthAttributes[SVGForeignObjectElement::ATTR_Y].IsPercentage()) {
       needNewBounds = true;
       needNewCanvasTM = true;
     }
-
     // Our coordinate context's width/height has changed. If we have a
     // percentage width/height our dimensions will change so we must reflow.
-    if (StylePosition()->mWidth.HasPercent() ||
-        StylePosition()->mHeight.HasPercent()) {
+    if (fO->mLengthAttributes[SVGForeignObjectElement::ATTR_WIDTH]
+            .IsPercentage() ||
+        fO->mLengthAttributes[SVGForeignObjectElement::ATTR_HEIGHT]
+            .IsPercentage()) {
       needNewBounds = true;
       needReflow = true;
     }
   }
 
   if (aFlags & TRANSFORM_CHANGED) {
     if (mCanvasTM && mCanvasTM->IsSingular()) {
       needNewBounds = true;  // old bounds are bogus
@@ -437,18 +438,17 @@ void nsSVGForeignObjectFrame::NotifySVGC
 }
 
 SVGBBox nsSVGForeignObjectFrame::GetBBoxContribution(
     const Matrix& aToBBoxUserspace, uint32_t aFlags) {
   SVGForeignObjectElement* content =
       static_cast<SVGForeignObjectElement*>(GetContent());
 
   float x, y, w, h;
-  SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y, SVGT::Width, SVGT::Height>(
-      content, &x, &y, &w, &h);
+  content->GetAnimatedLengthValues(&x, &y, &w, &h, nullptr);
 
   if (w < 0.0f) w = 0.0f;
   if (h < 0.0f) h = 0.0f;
 
   if (aToBBoxUserspace.IsSingular()) {
     // XXX ReportToConsole
     return SVGBBox();
   }
--- a/servo/components/style/properties/data.py
+++ b/servo/components/style/properties/data.py
@@ -167,17 +167,17 @@ def parse_property_aliases(alias_list):
 
 class Longhand(object):
     def __init__(self, style_struct, name, spec=None, animation_value_type=None, keyword=None,
                  predefined_type=None, servo_pref=None, gecko_pref=None,
                  enabled_in="content", need_index=False,
                  gecko_ffi_name=None,
                  allowed_in_keyframe_block=True, cast_type='u8',
                  logical=False, logical_group=None, alias=None, extra_prefixes=None, boxed=False,
-                 flags=None, allowed_in_page_rule=False, allow_quirks="No",
+                 flags=None, allowed_in_page_rule=False, allow_quirks=False,
                  ignored_when_colors_disabled=False,
                  vector=False, servo_restyle_damage="repaint"):
         self.name = name
         if not spec:
             raise TypeError("Spec should be specified for %s" % name)
         self.spec = spec
         self.keyword = keyword
         self.predefined_type = predefined_type
--- a/servo/components/style/properties/helpers.mako.rs
+++ b/servo/components/style/properties/helpers.mako.rs
@@ -5,17 +5,17 @@
 <%!
     from data import Keyword, to_rust_ident, to_camel_case, SYSTEM_FONT_LONGHANDS
     from data import LOGICAL_CORNERS, PHYSICAL_CORNERS, LOGICAL_SIDES, PHYSICAL_SIDES, LOGICAL_SIZES
 %>
 
 <%def name="predefined_type(name, type, initial_value, parse_method='parse',
             needs_context=True, vector=False,
             computed_type=None, initial_specified_value=None,
-            allow_quirks='No', allow_empty=False, **kwargs)">
+            allow_quirks=False, allow_empty=False, **kwargs)">
     <%def name="predefined_type_inner(name, type, initial_value, parse_method)">
         #[allow(unused_imports)]
         use app_units::Au;
         #[allow(unused_imports)]
         use cssparser::{Color as CSSParserColor, RGBA};
         #[allow(unused_imports)]
         use crate::values::specified::AllowQuirks;
         #[allow(unused_imports)]
@@ -37,18 +37,18 @@
         #[inline] pub fn get_initial_specified_value() -> SpecifiedValue { ${initial_specified_value} }
         % endif
         #[allow(unused_variables)]
         #[inline]
         pub fn parse<'i, 't>(
             context: &ParserContext,
             input: &mut Parser<'i, 't>,
         ) -> Result<SpecifiedValue, ParseError<'i>> {
-            % if allow_quirks != "No":
-            specified::${type}::${parse_method}_quirky(context, input, AllowQuirks::${allow_quirks})
+            % if allow_quirks:
+            specified::${type}::${parse_method}_quirky(context, input, AllowQuirks::Yes)
             % elif needs_context:
             specified::${type}::${parse_method}(context, input)
             % else:
             specified::${type}::${parse_method}(input)
             % endif
         }
     </%def>
     % if vector:
@@ -400,18 +400,18 @@
                 context.builder.set_${property.ident}(computed)
             % endif
         }
 
         pub fn parse_declared<'i, 't>(
             context: &ParserContext,
             input: &mut Parser<'i, 't>,
         ) -> Result<PropertyDeclaration, ParseError<'i>> {
-            % if property.allow_quirks != "No":
-                parse_quirky(context, input, specified::AllowQuirks::${property.allow_quirks})
+            % if property.allow_quirks:
+                parse_quirky(context, input, specified::AllowQuirks::Yes)
             % else:
                 parse(context, input)
             % endif
             % if property.boxed:
                 .map(Box::new)
             % endif
                 .map(PropertyDeclaration::${property.camel_case})
         }
@@ -863,31 +863,31 @@
             }
             Ok(())
         }
     }
 </%call>
 </%def>
 
 <%def name="four_sides_shorthand(name, sub_property_pattern, parser_function,
-                                 needs_context=True, allow_quirks='No', **kwargs)">
+                                 needs_context=True, allow_quirks=False, **kwargs)">
     <% sub_properties=' '.join(sub_property_pattern % side for side in PHYSICAL_SIDES) %>
     <%call expr="self.shorthand(name, sub_properties=sub_properties, **kwargs)">
         #[allow(unused_imports)]
         use crate::parser::Parse;
         use crate::values::generics::rect::Rect;
         use crate::values::specified;
 
         pub fn parse_value<'i, 't>(
             context: &ParserContext,
             input: &mut Parser<'i, 't>,
         ) -> Result<Longhands, ParseError<'i>> {
             let rect = Rect::parse_with(context, input, |_c, i| {
-            % if allow_quirks != "No":
-                ${parser_function}_quirky(_c, i, specified::AllowQuirks::${allow_quirks})
+            % if allow_quirks:
+                ${parser_function}_quirky(_c, i, specified::AllowQuirks::Yes)
             % elif needs_context:
                 ${parser_function}(_c, i)
             % else:
                 ${parser_function}(i)
             % endif
             })?;
             Ok(expanded! {
                 % for index, side in enumerate(["top", "right", "bottom", "left"]):
--- a/servo/components/style/properties/longhands/background.mako.rs
+++ b/servo/components/style/properties/longhands/background.mako.rs
@@ -9,17 +9,17 @@
 ${helpers.predefined_type(
     "background-color",
     "Color",
     "computed::Color::transparent()",
     initial_specified_value="SpecifiedValue::transparent()",
     spec="https://drafts.csswg.org/css-backgrounds/#background-color",
     animation_value_type="AnimatedColor",
     ignored_when_colors_disabled=True,
-    allow_quirks="Yes",
+    allow_quirks=True,
     flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER \
            CAN_ANIMATE_ON_COMPOSITOR",
 )}
 
 ${helpers.predefined_type(
     "background-image",
     "ImageLayer",
     initial_value="Either::First(None_)",
--- a/servo/components/style/properties/longhands/border.mako.rs
+++ b/servo/components/style/properties/longhands/border.mako.rs
@@ -23,17 +23,17 @@
     ${helpers.predefined_type(
         "border-%s-color" % side_name, "Color",
         "computed_value::T::currentcolor()",
         alias=maybe_moz_logical_alias(product, side, "-moz-border-%s-color"),
         spec=maybe_logical_spec(side, "color"),
         animation_value_type="AnimatedColor",
         logical=is_logical,
         logical_group="border-color",
-        allow_quirks="No" if is_logical else "Yes",
+        allow_quirks=not is_logical,
         flags="APPLIES_TO_FIRST_LETTER",
         ignored_when_colors_disabled=True,
     )}
 
     ${helpers.predefined_type(
         "border-%s-style" % side_name, "BorderStyle",
         "specified::BorderStyle::None",
         alias=maybe_moz_logical_alias(product, side, "-moz-border-%s-style"),
@@ -51,17 +51,17 @@
         "crate::values::computed::NonNegativeLength::new(3.)",
         computed_type="crate::values::computed::NonNegativeLength",
         alias=maybe_moz_logical_alias(product, side, "-moz-border-%s-width"),
         spec=maybe_logical_spec(side, "width"),
         animation_value_type="NonNegativeLength",
         logical=is_logical,
         logical_group="border-width",
         flags="APPLIES_TO_FIRST_LETTER GETCS_NEEDS_LAYOUT_FLUSH",
-        allow_quirks="No" if is_logical else "Yes",
+        allow_quirks=not is_logical,
         servo_restyle_damage="reflow rebuild_and_reflow_inline"
     )}
 % endfor
 
 % for corner in ALL_CORNERS:
     <%
         corner_name = corner[0]
         is_logical = corner[1]
--- a/servo/components/style/properties/longhands/effects.mako.rs
+++ b/servo/components/style/properties/longhands/effects.mako.rs
@@ -32,17 +32,17 @@
 )}
 
 ${helpers.predefined_type(
     "clip",
     "ClipRectOrAuto",
     "computed::ClipRectOrAuto::auto()",
     animation_value_type="ComputedValue",
     boxed=True,
-    allow_quirks="Yes",
+    allow_quirks=True,
     spec="https://drafts.fxtf.org/css-masking/#clip-property",
 )}
 
 ${helpers.predefined_type(
     "filter",
     "Filter",
     None,
     vector=True,
--- a/servo/components/style/properties/longhands/font.mako.rs
+++ b/servo/components/style/properties/longhands/font.mako.rs
@@ -59,17 +59,17 @@
 )}
 
 ${helpers.predefined_type(
     "font-size",
     "FontSize",
     initial_value="computed::FontSize::medium()",
     initial_specified_value="specified::FontSize::medium()",
     animation_value_type="NonNegativeLength",
-    allow_quirks="Yes",
+    allow_quirks=True,
     flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
     spec="https://drafts.csswg.org/css-fonts/#propdef-font-size",
     servo_restyle_damage="rebuild_and_reflow",
 )}
 
 ${helpers.predefined_type(
     "font-size-adjust",
     "FontSizeAdjust",
--- a/servo/components/style/properties/longhands/inherited_text.mako.rs
+++ b/servo/components/style/properties/longhands/inherited_text.mako.rs
@@ -51,17 +51,17 @@
 )}
 
 ${helpers.predefined_type(
     "text-indent",
     "LengthPercentage",
     "computed::LengthPercentage::zero()",
     animation_value_type="ComputedValue",
     spec="https://drafts.csswg.org/css-text/#propdef-text-indent",
-    allow_quirks="Yes",
+    allow_quirks=True,
     servo_restyle_damage = "reflow",
 )}
 
 // Also known as "word-wrap" (which is more popular because of IE), but this is
 // the preferred name per CSS-TEXT 6.2.
 ${helpers.predefined_type(
     "overflow-wrap",
     "OverflowWrap",
--- a/servo/components/style/properties/longhands/margin.mako.rs
+++ b/servo/components/style/properties/longhands/margin.mako.rs
@@ -12,17 +12,17 @@
         if side[1]:
             spec = "https://drafts.csswg.org/css-logical-props/#propdef-margin-%s" % side[1]
     %>
     ${helpers.predefined_type(
         "margin-%s" % side[0],
         "LengthPercentageOrAuto",
         "computed::LengthPercentageOrAuto::zero()",
         alias=maybe_moz_logical_alias(product, side, "-moz-margin-%s"),
-        allow_quirks="No" if side[1] else "Yes",
+        allow_quirks=not side[1],
         animation_value_type="ComputedValue",
         logical=side[1],
         logical_group="margin",
         spec=spec,
         flags="APPLIES_TO_FIRST_LETTER GETCS_NEEDS_LAYOUT_FLUSH",
         allowed_in_page_rule=True,
         servo_restyle_damage="reflow"
     )}
--- a/servo/components/style/properties/longhands/padding.mako.rs
+++ b/servo/components/style/properties/longhands/padding.mako.rs
@@ -19,17 +19,17 @@
         "NonNegativeLengthPercentage",
         "computed::NonNegativeLengthPercentage::zero()",
         alias=maybe_moz_logical_alias(product, side, "-moz-padding-%s"),
         animation_value_type="NonNegativeLengthPercentage",
         logical=side[1],
         logical_group="padding",
         spec=spec,
         flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_PLACEHOLDER GETCS_NEEDS_LAYOUT_FLUSH",
-        allow_quirks="No" if side[1] else "Yes",
+        allow_quirks=not side[1],
         servo_restyle_damage="reflow rebuild_and_reflow_inline"
     )}
 % endfor
 
 % for side in ALL_SIDES:
     ${helpers.predefined_type(
         "scroll-padding-%s" % side[0],
         "NonNegativeLengthPercentageOrAuto",
--- a/servo/components/style/properties/longhands/position.mako.rs
+++ b/servo/components/style/properties/longhands/position.mako.rs
@@ -12,17 +12,17 @@
 % for side in PHYSICAL_SIDES:
     ${helpers.predefined_type(
         side,
         "LengthPercentageOrAuto",
         "computed::LengthPercentageOrAuto::auto()",
         spec="https://www.w3.org/TR/CSS2/visuren.html#propdef-%s" % side,
         flags="GETCS_NEEDS_LAYOUT_FLUSH",
         animation_value_type="ComputedValue",
-        allow_quirks="Yes",
+        allow_quirks=True,
         servo_restyle_damage="reflow_out_of_flow",
         logical_group="inset",
     )}
 % endfor
 // inset-* logical properties, map to "top" / "left" / "bottom" / "right"
 % for side in LOGICAL_SIDES:
     ${helpers.predefined_type(
         "inset-%s" % side,
@@ -248,41 +248,41 @@ macro_rules! impl_align_conversions {
     %>
     // width, height, block-size, inline-size
     ${helpers.predefined_type(
         size,
         "Size",
         "computed::Size::auto()",
         logical=logical,
         logical_group="size",
-        allow_quirks="No" if logical else "Yes",
+        allow_quirks=not logical,
         spec=spec % size,
         animation_value_type="Size",
         flags="GETCS_NEEDS_LAYOUT_FLUSH",
         servo_restyle_damage="reflow",
     )}
     // min-width, min-height, min-block-size, min-inline-size
     ${helpers.predefined_type(
         "min-%s" % size,
         "Size",
         "computed::Size::auto()",
         logical=logical,
         logical_group="min-size",
-        allow_quirks="No" if logical else "Yes",
+        allow_quirks=not logical,
         spec=spec % size,
         animation_value_type="Size",
         servo_restyle_damage="reflow",
     )}
     ${helpers.predefined_type(
         "max-%s" % size,
         "MaxSize",
         "computed::MaxSize::none()",
         logical=logical,
         logical_group="max-size",
-        allow_quirks="No" if logical else "Yes",
+        allow_quirks=not logical,
         spec=spec % size,
         animation_value_type="MaxSize",
         servo_restyle_damage="reflow",
     )}
 % endfor
 
 ${helpers.single_keyword(
     "box-sizing",
--- a/servo/components/style/properties/longhands/svg.mako.rs
+++ b/servo/components/style/properties/longhands/svg.mako.rs
@@ -186,71 +186,8 @@
     parse_method="parse_with_cors_anonymous",
     spec="https://drafts.fxtf.org/css-masking/#propdef-mask-image",
     vector=True,
     products="gecko",
     extra_prefixes="webkit",
     animation_value_type="discrete",
     flags="CREATES_STACKING_CONTEXT",
 )}
-
-${helpers.predefined_type(
-    "x",
-    "LengthPercentage",
-    "computed::LengthPercentage::zero()",
-    products="gecko",
-    animation_value_type="ComputedValue",
-    spec="https://svgwg.org/svg2-draft/geometry.html#X",
-)}
-
-${helpers.predefined_type(
-    "y",
-    "LengthPercentage",
-    "computed::LengthPercentage::zero()",
-    products="gecko",
-    animation_value_type="ComputedValue",
-    spec="https://svgwg.org/svg2-draft/geometry.html#Y",
-)}
-
-${helpers.predefined_type(
-    "cx",
-    "LengthPercentage",
-    "computed::LengthPercentage::zero()",
-    products="gecko",
-    animation_value_type="ComputedValue",
-    spec="https://svgwg.org/svg2-draft/geometry.html#CX",
-)}
-
-${helpers.predefined_type(
-    "cy",
-    "LengthPercentage",
-    "computed::LengthPercentage::zero()",
-    products="gecko",
-    animation_value_type="ComputedValue",
-    spec="https://svgwg.org/svg2-draft/geometry.html#CY",
-)}
-
-${helpers.predefined_type(
-    "rx",
-    "NonNegativeLengthPercentageOrAuto",
-    "computed::NonNegativeLengthPercentageOrAuto::auto()",
-    products="gecko",
-    animation_value_type="LengthPercentageOrAuto",
-    spec="https://svgwg.org/svg2-draft/geometry.html#RX",
-)}
-
-${helpers.predefined_type(
-    "ry",
-    "NonNegativeLengthPercentageOrAuto",
-    "computed::NonNegativeLengthPercentageOrAuto::auto()",
-    products="gecko",
-    animation_value_type="LengthPercentageOrAuto",
-    spec="https://svgwg.org/svg2-draft/geometry.html#RY",
-)}
-
-${helpers.predefined_type(
-    "r",
-    "NonNegativeLengthPercentage",
-    "computed::NonNegativeLengthPercentage::zero()",
-    products="gecko",
-    animation_value_type="LengthPercentage",
-    spec="https://svgwg.org/svg2-draft/geometry.html#R",
-)}
--- a/servo/components/style/properties/shorthands/border.mako.rs
+++ b/servo/components/style/properties/shorthands/border.mako.rs
@@ -2,17 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 <% from data import to_rust_ident, ALL_SIDES, PHYSICAL_SIDES, maybe_moz_logical_alias %>
 
 ${helpers.four_sides_shorthand("border-color", "border-%s-color", "specified::Color::parse",
                                spec="https://drafts.csswg.org/css-backgrounds/#border-color",
-                               allow_quirks="Yes")}
+                               allow_quirks=True)}
 
 ${helpers.four_sides_shorthand(
     "border-style",
     "border-%s-style",
     "specified::BorderStyle::parse",
     needs_context=False,
     spec="https://drafts.csswg.org/css-backgrounds/#border-style",
 )}
--- a/servo/components/style/properties/shorthands/margin.mako.rs
+++ b/servo/components/style/properties/shorthands/margin.mako.rs
@@ -5,17 +5,17 @@
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
 ${helpers.four_sides_shorthand(
     "margin",
     "margin-%s",
     "specified::LengthPercentageOrAuto::parse",
     spec="https://drafts.csswg.org/css-box/#propdef-margin",
     allowed_in_page_rule=True,
-    allow_quirks="Yes",
+    allow_quirks=True,
 )}
 
 ${helpers.two_properties_shorthand(
     "margin-block",
     "margin-block-start",
     "margin-block-end",
     "specified::LengthPercentageOrAuto::parse",
     spec="https://drafts.csswg.org/css-logical/#propdef-margin-block"
--- a/servo/components/style/properties/shorthands/padding.mako.rs
+++ b/servo/components/style/properties/shorthands/padding.mako.rs
@@ -4,17 +4,17 @@
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
 ${helpers.four_sides_shorthand(
     "padding",
     "padding-%s",
     "specified::NonNegativeLengthPercentage::parse",
     spec="https://drafts.csswg.org/css-box-3/#propdef-padding",
-    allow_quirks="Yes",
+    allow_quirks=True,
 )}
 
 ${helpers.two_properties_shorthand(
     "padding-block",
     "padding-block-start",
     "padding-block-end",
     "specified::NonNegativeLengthPercentage::parse",
     spec="https://drafts.csswg.org/css-logical/#propdef-padding-block"
--- a/servo/components/style/properties/shorthands/position.mako.rs
+++ b/servo/components/style/properties/shorthands/position.mako.rs
@@ -763,17 +763,17 @@
 </%helpers:shorthand>
 
 // See https://github.com/w3c/csswg-drafts/issues/3525 for the quirks stuff.
 ${helpers.four_sides_shorthand(
     "inset",
     "%s",
     "specified::LengthPercentageOrAuto::parse",
     spec="https://drafts.csswg.org/css-logical/#propdef-inset",
-    allow_quirks="No",
+    allow_quirks=False,
 )}
 
 ${helpers.two_properties_shorthand(
     "inset-block",
     "inset-block-start",
     "inset-block-end",
     "specified::LengthPercentageOrAuto::parse",
     spec="https://drafts.csswg.org/css-logical/#propdef-inset-block"
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -4508,17 +4508,17 @@ pub extern "C" fn Servo_DeclarationBlock
     declarations: &RawServoDeclarationBlock,
     property: nsCSSPropertyID,
     value: f32,
     unit: structs::nsCSSUnit,
 ) {
     use style::properties::longhands::_moz_script_min_size::SpecifiedValue as MozScriptMinSize;
     use style::properties::PropertyDeclaration;
     use style::values::generics::NonNegative;
-    use style::values::generics::length::{Size, LengthPercentageOrAuto};
+    use style::values::generics::length::Size;
     use style::values::specified::length::NoCalcLength;
     use style::values::specified::length::{AbsoluteLength, FontRelativeLength};
     use style::values::specified::length::LengthPercentage;
 
     let long = get_longhand_from_id!(property);
     let nocalc = match unit {
         structs::nsCSSUnit::eCSSUnit_EM => {
             NoCalcLength::FontRelative(FontRelativeLength::Em(value))
@@ -4537,24 +4537,16 @@ pub extern "C" fn Servo_DeclarationBlock
         structs::nsCSSUnit::eCSSUnit_Point => NoCalcLength::Absolute(AbsoluteLength::Pt(value)),
         structs::nsCSSUnit::eCSSUnit_Pica => NoCalcLength::Absolute(AbsoluteLength::Pc(value)),
         structs::nsCSSUnit::eCSSUnit_Quarter => NoCalcLength::Absolute(AbsoluteLength::Q(value)),
         _ => unreachable!("Unknown unit passed to SetLengthValue"),
     };
 
     let prop = match_wrap_declared! { long,
         Width => Size::LengthPercentage(NonNegative(LengthPercentage::Length(nocalc))),
-        Height => Size::LengthPercentage(NonNegative(LengthPercentage::Length(nocalc))),
-        X =>  LengthPercentage::Length(nocalc),
-        Y =>  LengthPercentage::Length(nocalc),
-        Cx => LengthPercentage::Length(nocalc),
-        Cy => LengthPercentage::Length(nocalc),
-        R =>  NonNegative(LengthPercentage::Length(nocalc)),
-        Rx => LengthPercentageOrAuto::LengthPercentage(NonNegative(LengthPercentage::Length(nocalc))),
-        Ry => LengthPercentageOrAuto::LengthPercentage(NonNegative(LengthPercentage::Length(nocalc))),
         FontSize => LengthPercentage::from(nocalc).into(),
         MozScriptMinSize => MozScriptMinSize(nocalc),
     };
     write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
         decls.push(prop, Importance::Normal);
     })
 }
 
@@ -4595,23 +4587,16 @@ pub extern "C" fn Servo_DeclarationBlock
     let long = get_longhand_from_id!(property);
     let pc = Percentage(value);
     let lp = LengthPercentage::Percentage(pc);
     let lp_or_auto = LengthPercentageOrAuto::LengthPercentage(lp.clone());
 
     let prop = match_wrap_declared! { long,
         Height => Size::LengthPercentage(NonNegative(lp)),
         Width => Size::LengthPercentage(NonNegative(lp)),
-        X =>  lp,
-        Y =>  lp,
-        Cx => lp,
-        Cy => lp,
-        R =>  NonNegative(lp),
-        Rx => LengthPercentageOrAuto::LengthPercentage(NonNegative(lp)),
-        Ry => LengthPercentageOrAuto::LengthPercentage(NonNegative(lp)),
         MarginTop => lp_or_auto,
         MarginRight => lp_or_auto,
         MarginBottom => lp_or_auto,
         MarginLeft => lp_or_auto,
         FontSize => LengthPercentage::from(pc).into(),
     };
     write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
         decls.push(prop, Importance::Normal);
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/embedded/image-embedding-svg-with-viewport-units-inline-style.svg.ini
@@ -0,0 +1,2 @@
+[image-embedding-svg-with-viewport-units-inline-style.svg]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/embedded/image-embedding-svg-with-viewport-units.svg.ini
@@ -0,0 +1,2 @@
+[image-embedding-svg-with-viewport-units.svg]
+  expected: FAIL
--- a/testing/web-platform/meta/svg/extensibility/foreignObject/properties.svg.ini
+++ b/testing/web-platform/meta/svg/extensibility/foreignObject/properties.svg.ini
@@ -1,6 +1,19 @@
 [properties.svg]
+  [Untitled]
+    expected: FAIL
+
   [width and height default to auto]
     expected: FAIL
 
+  [style rules are applied]
+    expected: FAIL
+
+  [attributes set properties]
+    expected: FAIL
+
+  [style rules override attributes]
+    expected: FAIL
+
   [width and height default to auto (which computes to "0px")]
     expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/geometry/parsing/cx-valid.svg.ini
@@ -0,0 +1,16 @@
+[cx-valid.svg]
+  [e.style['cx'\] = "4%" should set the property value]
+    expected: FAIL
+
+  [e.style['cx'\] = "-1px" should set the property value]
+    expected: FAIL
+
+  [e.style['cx'\] = "calc(2em + 3ex)" should set the property value]
+    expected: FAIL
+
+  [e.style['cx'\] = "0" should set the property value]
+    expected: FAIL
+
+  [e.style['cx'\] = "5ch" should set the property value]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/geometry/parsing/cy-valid.svg.ini
@@ -0,0 +1,16 @@
+[cy-valid.svg]
+  [e.style['cy'\] = "0" should set the property value]
+    expected: FAIL
+
+  [e.style['cy'\] = "calc(2em + 3ex)" should set the property value]
+    expected: FAIL
+
+  [e.style['cy'\] = "4%" should set the property value]
+    expected: FAIL
+
+  [e.style['cy'\] = "-1px" should set the property value]
+    expected: FAIL
+
+  [e.style['cy'\] = "5rem" should set the property value]
+    expected: FAIL
+
--- a/testing/web-platform/meta/svg/geometry/parsing/height-computed.svg.ini
+++ b/testing/web-platform/meta/svg/geometry/parsing/height-computed.svg.ini
@@ -1,18 +1,24 @@
 [height-computed.svg]
   [SVG Geometry Properties: getComputedStyle().height, <svg> inline style (percentage)]
     expected: FAIL
 
   [SVG Geometry Properties: getComputedStyle().height, <rect> initial]
     expected: FAIL
 
+  [SVG Geometry Properties: getComputedStyle().height, <rect> presentation attribute]
+    expected: FAIL
+
   [SVG Geometry Properties: getComputedStyle().height, <rect> inline style (auto)]
     expected: FAIL
 
+  [SVG Geometry Properties: getComputedStyle().height, <foreignObject> presentation attribute]
+    expected: FAIL
+
   [SVG Geometry Properties: getComputedStyle().height, <image> initial]
     expected: FAIL
 
   [SVG Geometry Properties: getComputedStyle().height, <svg> inline style (auto)]
     expected: FAIL
 
   [SVG Geometry Properties: getComputedStyle().height, <foreignObject> initial]
     expected: FAIL
@@ -33,8 +39,11 @@
     expected: FAIL
 
   [SVG Geometry Properties: getComputedStyle().height, <foreignObject> inline style (percentage)]
     expected: FAIL
 
   [SVG Geometry Properties: getComputedStyle().height, <image> inline style (percentage)]
     expected: FAIL
 
+  [SVG Geometry Properties: getComputedStyle().height, <image> presentation attribute]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/geometry/parsing/r-valid.svg.ini
@@ -0,0 +1,16 @@
+[r-valid.svg]
+  [e.style['r'\] = "1px" should set the property value]
+    expected: FAIL
+
+  [e.style['r'\] = "0" should set the property value]
+    expected: FAIL
+
+  [e.style['r'\] = "calc(2em + 3ex)" should set the property value]
+    expected: FAIL
+
+  [e.style['r'\] = "4%" should set the property value]
+    expected: FAIL
+
+  [e.style['r'\] = "5vmin" should set the property value]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/geometry/parsing/rx-valid.svg.ini
@@ -0,0 +1,19 @@
+[rx-valid.svg]
+  [e.style['rx'\] = "auto" should set the property value]
+    expected: FAIL
+
+  [e.style['rx'\] = "4%" should set the property value]
+    expected: FAIL
+
+  [e.style['rx'\] = "calc(2em + 3ex)" should set the property value]
+    expected: FAIL
+
+  [e.style['rx'\] = "0" should set the property value]
+    expected: FAIL
+
+  [e.style['rx'\] = "1px" should set the property value]
+    expected: FAIL
+
+  [e.style['rx'\] = "5vw" should set the property value]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/geometry/parsing/ry-valid.svg.ini
@@ -0,0 +1,37 @@
+[ry-valid.svg]
+  [e.style['rx'\] = "auto" should set the property value]
+    expected: FAIL
+
+  [e.style['rx'\] = "4%" should set the property value]
+    expected: FAIL
+
+  [e.style['rx'\] = "calc(2em + 3ex)" should set the property value]
+    expected: FAIL
+
+  [e.style['rx'\] = "0" should set the property value]
+    expected: FAIL
+
+  [e.style['rx'\] = "1px" should set the property value]
+    expected: FAIL
+
+  [e.style['rx'\] = "5vh" should set the property value]
+    expected: FAIL
+
+  [e.style['ry'\] = "auto" should set the property value]
+    expected: FAIL
+
+  [e.style['ry'\] = "0" should set the property value]
+    expected: FAIL
+
+  [e.style['ry'\] = "calc(2em + 3ex)" should set the property value]
+    expected: FAIL
+
+  [e.style['ry'\] = "4%" should set the property value]
+    expected: FAIL
+
+  [e.style['ry'\] = "1px" should set the property value]
+    expected: FAIL
+
+  [e.style['ry'\] = "5vh" should set the property value]
+    expected: FAIL
+
--- a/testing/web-platform/meta/svg/geometry/parsing/width-computed.svg.ini
+++ b/testing/web-platform/meta/svg/geometry/parsing/width-computed.svg.ini
@@ -9,22 +9,28 @@
     expected: FAIL
 
   [SVG Geometry Properties: getComputedStyle().width, <svg> inline style (auto)]
     expected: FAIL
 
   [SVG Geometry Properties: getComputedStyle().width, <rect> initial]
     expected: FAIL
 
+  [SVG Geometry Properties: getComputedStyle().width, <rect> presentation attribute]
+    expected: FAIL
+
   [SVG Geometry Properties: getComputedStyle().width, <image> inline style (percentage)]
     expected: FAIL
 
   [SVG Geometry Properties: getComputedStyle().width, <svg> presentation attribute]
     expected: FAIL
 
+  [SVG Geometry Properties: getComputedStyle().width, <foreignObject> presentation attribute]
+    expected: FAIL
+
   [SVG Geometry Properties: getComputedStyle().width, <foreignObject> inline style (percentage)]
     expected: FAIL
 
   [SVG Geometry Properties: getComputedStyle().width, <rect> inline style (auto)]
     expected: FAIL
 
   [SVG Geometry Properties: getComputedStyle().width, <foreignObject> initial]
     expected: FAIL
@@ -33,8 +39,11 @@
     expected: FAIL
 
   [SVG Geometry Properties: getComputedStyle().width, <svg> initial]
     expected: FAIL
 
   [SVG Geometry Properties: getComputedStyle().width, <image> inline style (auto)]
     expected: FAIL
 
+  [SVG Geometry Properties: getComputedStyle().width, <image> presentation attribute]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/geometry/parsing/x-valid.svg.ini
@@ -0,0 +1,16 @@
+[x-valid.svg]
+  [e.style['x'\] = "-1px" should set the property value]
+    expected: FAIL
+
+  [e.style['x'\] = "0" should set the property value]
+    expected: FAIL
+
+  [e.style['x'\] = "calc(2em + 3ex)" should set the property value]
+    expected: FAIL
+
+  [e.style['x'\] = "4%" should set the property value]
+    expected: FAIL
+
+  [e.style['x'\] = "5cm" should set the property value]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/geometry/parsing/y-valid.svg.ini
@@ -0,0 +1,16 @@
+[y-valid.svg]
+  [e.style['y'\] = "-1px" should set the property value]
+    expected: FAIL
+
+  [e.style['y'\] = "4%" should set the property value]
+    expected: FAIL
+
+  [e.style['y'\] = "0" should set the property value]
+    expected: FAIL
+
+  [e.style['y'\] = "calc(2em + 3ex)" should set the property value]
+    expected: FAIL
+
+  [e.style['y'\] = "5mm" should set the property value]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/geometry/reftests/percentage.svg.ini
@@ -0,0 +1,2 @@
+[percentage.svg]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/shapes/ellipse-01.svg.ini
@@ -0,0 +1,4 @@
+[ellipse-01.svg]
+  expected:
+    if (not (os == "win")): FAIL
+    if (os == "win"): FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/shapes/ellipse-02.svg.ini
@@ -0,0 +1,4 @@
+[ellipse-02.svg]
+  expected:
+    if (not (os == "win")): FAIL
+    if (os == "win"): FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/shapes/ellipse-03.svg.ini
@@ -0,0 +1,4 @@
+[ellipse-03.svg]
+  expected:
+    if (not (os == "win")): FAIL
+    if (os == "win"): FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/shapes/ellipse-05.svg.ini
@@ -0,0 +1,4 @@
+[ellipse-05.svg]
+  expected:
+    if (not (os == "win")): FAIL
+    if (os == "win"): FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/shapes/ellipse-06.svg.ini
@@ -0,0 +1,4 @@
+[ellipse-06.svg]
+  expected:
+    if (not (os == "win")): FAIL
+    if (os == "win"): FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/shapes/ellipse-07.svg.ini
@@ -0,0 +1,4 @@
+[ellipse-07.svg]
+  expected:
+    if (not (os == "win")): FAIL
+    if (os == "win"): FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/shapes/ellipse-08.svg.ini
@@ -0,0 +1,4 @@
+[ellipse-08.svg]
+  expected:
+    if (not (os == "win")): FAIL
+    if (os == "win"): FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/svg/shapes/rx-ry-not-inherited.svg.ini
@@ -0,0 +1,7 @@
+[rx-ry-not-inherited.svg]
+  [Untitled]
+    expected: FAIL
+
+  [rx-ry-not-inherited]
+    expected: FAIL
+
--- a/testing/web-platform/tests/svg/shapes/reftests/disabled-shapes-01.svg
+++ b/testing/web-platform/tests/svg/shapes/reftests/disabled-shapes-01.svg
@@ -16,36 +16,35 @@
       <rect style="width: 0"/>
       <rect style="width: 0" height="10"/>
       <rect style="width: -10px"/>
       <rect style="width: -10px" height="10"/>
       <rect style="height: 0"/>
       <rect style="height: 0" width="10"/>
       <rect style="height: -10px"/>
       <rect style="height: -10px" width="10"/>
-      <rect style="width: calc(-10px); height: calc(-10px)"/>
     </g>
 
     <g transform="translate(150, 50)">
       <circle/>
       <circle r="0"/>
       <circle r="-10"/>
       <circle style="r: 0"/>
       <circle style="r: -10px"/>
-      <circle style="r: calc(-10px)"/>
     </g>
 
     <g transform="translate(250, 50)">
       <ellipse/>
       <ellipse rx="0"/>
       <ellipse rx="0" ry="10"/>
+      <ellipse rx="-10" ry="10"/>
       <ellipse ry="0"/>
       <ellipse ry="0" rx="10"/>
+      <ellipse ry="-10" rx="10"/>
       <ellipse style="rx: 0"/>
       <ellipse style="rx: -10px"/>
       <ellipse style="rx: 0" ry="10"/>
       <ellipse style="ry: 0"/>
       <ellipse style="ry: -10px"/>
       <ellipse style="ry: 0" rx="10"/>
-      <ellipse style="rx: calc(-10px); ry: calc(-10px)"/>
     </g>
   </g>
 </svg>
--- a/testing/web-platform/tests/svg/shapes/scripted/disabled-shapes-not-hit.svg
+++ b/testing/web-platform/tests/svg/shapes/scripted/disabled-shapes-not-hit.svg
@@ -17,41 +17,40 @@
       <rect style="width: 0"/>
       <rect style="width: 0" height="10"/>
       <rect style="width: -10px"/>
       <rect style="width: -10px" height="10"/>
       <rect style="height: 0"/>
       <rect style="height: 0" width="10"/>
       <rect style="height: -10px"/>
       <rect style="height: -10px" width="10"/>
-      <rect style="width: calc(-10px); height: calc(-10px)"/>
     </g>
 
     <g transform="translate(150, 50)">
       <circle/>
       <circle r="0"/>
       <circle r="-10"/>
       <circle style="r: 0"/>
       <circle style="r: -10px"/>
-      <circle style="r: calc(-10px)"/>
     </g>
 
     <g transform="translate(250, 50)">
       <ellipse/>
       <ellipse rx="0"/>
       <ellipse rx="0" ry="10"/>
+      <ellipse rx="-10" ry="10"/>
       <ellipse ry="0"/>
       <ellipse ry="0" rx="10"/>
+      <ellipse ry="-10" rx="10"/>
       <ellipse style="rx: 0"/>
       <ellipse style="rx: -10px"/>
       <ellipse style="rx: 0" ry="10"/>
       <ellipse style="ry: 0"/>
       <ellipse style="ry: -10px"/>
       <ellipse style="ry: 0" rx="10"/>
-      <ellipse style="rx: calc(-10px); ry: calc(-10px)"/>
     </g>
   </g>
   <script><![CDATA[
     test(function() {
       let element = document.elementFromPoint(50, 50);
       assert_equals(element, document.documentElement, "does not hit one of the shapes");
     }, document.title + ": <rect>");