Bug 1398806 - GetCtx and GetNearestViewport should return the nearest svg or symbol element which is now an SVGViewportElement rather than only returning the nearest svg element because a symbol establishes a viewport too. r=dholbert
authorRobert Longson <longsonr@gmail.com>
Tue, 10 Oct 2017 07:58:34 +0100
changeset 427854 813d4e250712d296eb4b11b0b89e10ed6a94e3d4
parent 427853 8dd2fefd471b508a6233042abc5d2ed5b7b754a4
child 427855 6e336c49b6e76c16142b47dd977ceb4215861224
push id97
push userfmarier@mozilla.com
push dateSat, 14 Oct 2017 01:12:59 +0000
reviewersdholbert
bugs1398806
milestone58.0a1
Bug 1398806 - GetCtx and GetNearestViewport should return the nearest svg or symbol element which is now an SVGViewportElement rather than only returning the nearest svg element because a symbol establishes a viewport too. r=dholbert
dom/svg/SVGContentUtils.cpp
dom/svg/SVGContentUtils.h
dom/svg/SVGLength.cpp
dom/svg/SVGMarkerElement.cpp
dom/svg/SVGMarkerElement.h
dom/svg/SVGSVGElement.h
dom/svg/SVGViewportElement.h
dom/svg/nsSVGElement.cpp
dom/svg/nsSVGElement.h
layout/base/nsLayoutUtils.cpp
layout/reftests/svg/reftest.list
layout/reftests/svg/viewBox-and-symbol-01.svg
layout/svg/nsCSSClipPathInstance.cpp
layout/svg/nsSVGImageFrame.cpp
layout/svg/nsSVGImageFrame.h
layout/svg/nsSVGMarkerFrame.cpp
layout/svg/nsSVGMarkerFrame.h
layout/svg/nsSVGPatternFrame.cpp
layout/svg/nsSVGUtils.cpp
--- a/dom/svg/SVGContentUtils.cpp
+++ b/dom/svg/SVGContentUtils.cpp
@@ -369,27 +369,31 @@ SVGContentUtils::EstablishesViewport(nsI
   // Although SVG 1.1 states that <image> is an element that establishes a
   // viewport, this is really only for the document it references, not
   // for any child content, which is what this function is used for.
   return aContent && aContent->IsAnyOfSVGElements(nsGkAtoms::svg,
                                                   nsGkAtoms::foreignObject,
                                                   nsGkAtoms::symbol);
 }
 
-nsSVGElement*
-SVGContentUtils::GetNearestViewportElement(nsIContent *aContent)
+SVGViewportElement*
+SVGContentUtils::GetNearestViewportElement(const nsIContent *aContent)
 {
   nsIContent *element = aContent->GetFlattenedTreeParent();
 
   while (element && element->IsSVGElement()) {
     if (EstablishesViewport(element)) {
       if (element->IsSVGElement(nsGkAtoms::foreignObject)) {
         return nullptr;
       }
-      return static_cast<nsSVGElement*>(element);
+      MOZ_ASSERT(element->IsAnyOfSVGElements(nsGkAtoms::svg,
+                                             nsGkAtoms::symbol),
+                 "upcoming static_cast is only valid for "
+                 "SVGViewportElement subclasses");
+      return static_cast<SVGViewportElement*>(element);
     }
     element = element->GetFlattenedTreeParent();
   }
   return nullptr;
 }
 
 static gfx::Matrix
 GetCTMInternal(nsSVGElement *aElement, bool aScreenCTM, bool aHaveRecursed)
@@ -823,17 +827,17 @@ SVGContentUtils::CoordToFloat(nsSVGEleme
   case eStyleUnit_Factor:
     // user units
     return aCoord.GetFactorValue();
 
   case eStyleUnit_Coord:
     return nsPresContext::AppUnitsToFloatCSSPixels(aCoord.GetCoordValue());
 
   case eStyleUnit_Percent: {
-    SVGSVGElement* ctx = aContent->GetCtx();
+    SVGViewportElement* ctx = aContent->GetCtx();
     return ctx ? aCoord.GetPercentValue() * ctx->GetLength(SVGContentUtils::XY) : 0.0f;
   }
   default:
     return 0.0f;
   }
 }
 
 already_AddRefed<gfx::Path>
--- a/dom/svg/SVGContentUtils.h
+++ b/dom/svg/SVGContentUtils.h
@@ -27,16 +27,17 @@ class nsSVGElement;
 namespace mozilla {
 class nsSVGAnimatedTransformList;
 class SVGAnimatedPreserveAspectRatio;
 class SVGContextPaint;
 class SVGPreserveAspectRatio;
 namespace dom {
 class Element;
 class SVGSVGElement;
+class SVGViewportElement;
 } // namespace dom
 
 } // namespace mozilla
 
 #define SVG_ZERO_LENGTH_PATH_FIX_FACTOR 512
 
 /**
  * SVGTransformTypes controls the transforms that PrependLocalTransformsTo
@@ -233,18 +234,18 @@ public:
                              Rect* aBounds);
 
   /**
    * Check if this is one of the SVG elements that SVG 1.1 Full says
    * establishes a viewport: svg, symbol, image or foreignObject.
    */
   static bool EstablishesViewport(nsIContent *aContent);
 
-  static nsSVGElement*
-  GetNearestViewportElement(nsIContent *aContent);
+  static mozilla::dom::SVGViewportElement*
+  GetNearestViewportElement(const nsIContent *aContent);
 
   /* enum for specifying coordinate direction for ObjectSpace/UserSpace */
   enum ctxDirection { X, Y, XY };
 
   /**
    * Computes sqrt((aWidth^2 + aHeight^2)/2);
    */
   static double ComputeNormalizedHypotenuse(double aWidth, double aHeight);
--- a/dom/svg/SVGLength.cpp
+++ b/dom/svg/SVGLength.cpp
@@ -168,17 +168,17 @@ SVGLength::GetUserUnitsPerUnit(const nsS
       return std::numeric_limits<float>::quiet_NaN();
   }
 }
 
 /* static */ float
 SVGLength::GetUserUnitsPerPercent(const nsSVGElement *aElement, uint8_t aAxis)
 {
   if (aElement) {
-    dom::SVGSVGElement *viewportElement = aElement->GetCtx();
+    dom::SVGViewportElement *viewportElement = aElement->GetCtx();
     if (viewportElement) {
       return std::max(viewportElement->GetLength(aAxis) / 100.0f, 0.0f);
     }
   }
   return std::numeric_limits<float>::quiet_NaN();
 }
 
 // Helpers:
--- a/dom/svg/SVGMarkerElement.cpp
+++ b/dom/svg/SVGMarkerElement.cpp
@@ -245,17 +245,17 @@ SVGMarkerElement::UnsetAttr(int32_t aNam
 
   return nsSVGElement::UnsetAttr(aNamespaceID, aName, aNotify);
 }
 
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
 void
-SVGMarkerElement::SetParentCoordCtxProvider(SVGSVGElement *aContext)
+SVGMarkerElement::SetParentCoordCtxProvider(SVGViewportElement *aContext)
 {
   mCoordCtx = aContext;
   mViewBoxToViewportTransform = nullptr;
 }
 
 /* virtual */ bool
 SVGMarkerElement::HasValidDimensions() const
 {
--- a/dom/svg/SVGMarkerElement.h
+++ b/dom/svg/SVGMarkerElement.h
@@ -148,17 +148,17 @@ public:
   void SetOrientToAngle(SVGAngle& angle, ErrorResult& rv);
 
 protected:
 
   virtual bool ParseAttribute(int32_t aNameSpaceID, nsAtom* aName,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult) override;
 
-  void SetParentCoordCtxProvider(SVGSVGElement *aContext);
+  void SetParentCoordCtxProvider(SVGViewportElement *aContext);
 
   virtual LengthAttributesInfo GetLengthInfo() override;
   virtual AngleAttributesInfo GetAngleInfo() override;
   virtual EnumAttributesInfo GetEnumInfo() override;
   virtual nsSVGViewBox *GetViewBox() override;
   virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio() override;
 
   enum { REFX, REFY, MARKERWIDTH, MARKERHEIGHT };
@@ -175,16 +175,16 @@ protected:
   static AngleInfo sAngleInfo[1];
 
   nsSVGViewBox             mViewBox;
   SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
 
   // derived properties (from 'orient') handled separately
   nsSVGOrientType                        mOrientType;
 
-  SVGSVGElement                         *mCoordCtx;
+  SVGViewportElement*                    mCoordCtx;
   nsAutoPtr<gfx::Matrix>                 mViewBoxToViewportTransform;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_SVGMarkerElement_h
--- a/dom/svg/SVGSVGElement.h
+++ b/dom/svg/SVGSVGElement.h
@@ -177,25 +177,16 @@ public:
   int32_t GetIntrinsicWidth();
   int32_t GetIntrinsicHeight();
 
   // This services any pending notifications for the transform on on this root
   // <svg> node needing to be recalculated.  (Only applicable in
   // SVG-as-an-image documents.)
   virtual void FlushImageTransformInvalidation();
 
-  svgFloatSize GetViewportSize() const {
-    return svgFloatSize(mViewportWidth, mViewportHeight);
-  }
-
-  void SetViewportSize(const svgFloatSize& aSize) {
-    mViewportWidth  = aSize.width;
-    mViewportHeight = aSize.height;
-  }
-
 private:
   // SVGViewportElement methods:
 
   virtual SVGViewElement* GetCurrentViewElement() const;
   virtual SVGPreserveAspectRatio GetPreserveAspectRatioWithOverride() const override;
 
   // implementation helpers:
 
--- a/dom/svg/SVGViewportElement.h
+++ b/dom/svg/SVGViewportElement.h
@@ -122,16 +122,25 @@ public:
    * The reason we have this method instead of overriding
    * GetAttributeChangeHint is because we need to act on non-attribute (e.g.
    * currentScale) changes in addition to attribute (e.g. viewBox) changes.
    */
   void ChildrenOnlyTransformChanged(uint32_t aFlags = 0);
 
   gfx::Matrix GetViewBoxTransform() const;
 
+  svgFloatSize GetViewportSize() const {
+    return svgFloatSize(mViewportWidth, mViewportHeight);
+  }
+
+  void SetViewportSize(const svgFloatSize& aSize) {
+    mViewportWidth  = aSize.width;
+    mViewportHeight = aSize.height;
+  }
+
   // WebIDL
   already_AddRefed<SVGAnimatedRect> ViewBox();
   already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
   virtual nsSVGViewBox* GetViewBox() override;
 
 protected:
 
   // implementation helpers:
--- a/dom/svg/nsSVGElement.cpp
+++ b/dom/svg/nsSVGElement.cpp
@@ -1104,17 +1104,30 @@ nsSVGElement::GetOwnerSVGElement(nsIDOMS
 {
   NS_IF_ADDREF(*aOwnerSVGElement = GetOwnerSVGElement());
   return NS_OK;
 }
 
 SVGSVGElement*
 nsSVGElement::GetOwnerSVGElement()
 {
-  return GetCtx(); // this may return nullptr
+  nsIContent* ancestor = GetFlattenedTreeParent();
+
+  while (ancestor && ancestor->IsSVGElement()) {
+    if (ancestor->IsSVGElement(nsGkAtoms::foreignObject)) {
+      return nullptr;
+    }
+    if (ancestor->IsSVGElement(nsGkAtoms::svg)) {
+      return static_cast<SVGSVGElement*>(ancestor);
+    }
+    ancestor = ancestor->GetFlattenedTreeParent();
+  }
+
+  // we don't have an ancestor <svg> element...
+  return nullptr;
 }
 
 NS_IMETHODIMP
 nsSVGElement::GetViewportElement(nsIDOMSVGElement * *aViewportElement)
 {
   nsSVGElement* elem = GetViewportElement();
   NS_ADDREF(*aViewportElement = elem);
   return NS_OK;
@@ -1540,33 +1553,20 @@ nsAtom* nsSVGElement::GetEventNameForAtt
   if (aAttr == nsGkAtoms::onrepeat)
     return nsGkAtoms::onrepeatEvent;
   if (aAttr == nsGkAtoms::onend)
     return nsGkAtoms::onendEvent;
 
   return aAttr;
 }
 
-SVGSVGElement *
+SVGViewportElement *
 nsSVGElement::GetCtx() const
 {
-  nsIContent* ancestor = GetFlattenedTreeParent();
-
-  while (ancestor && ancestor->IsSVGElement()) {
-    if (ancestor->IsSVGElement(nsGkAtoms::foreignObject)) {
-      return nullptr;
-    }
-    if (ancestor->IsSVGElement(nsGkAtoms::svg)) {
-      return static_cast<SVGSVGElement*>(ancestor);
-    }
-    ancestor = ancestor->GetFlattenedTreeParent();
-  }
-
-  // we don't have an ancestor <svg> element...
-  return nullptr;
+  return SVGContentUtils::GetNearestViewportElement(this);
 }
 
 /* virtual */ gfxMatrix
 nsSVGElement::PrependLocalTransformsTo(
   const gfxMatrix &aMatrix, SVGTransformTypes aWhich) const
 {
   return aMatrix;
 }
@@ -1655,17 +1655,17 @@ nsSVGElement::GetAnimatedLength(const ns
 void
 nsSVGElement::GetAnimatedLengthValues(float *aFirst, ...)
 {
   LengthAttributesInfo info = GetLengthInfo();
 
   NS_ASSERTION(info.mLengthCount > 0,
                "GetAnimatedLengthValues on element with no length attribs");
 
-  SVGSVGElement *ctx = nullptr;
+  SVGViewportElement *ctx = nullptr;
 
   float *f = aFirst;
   uint32_t i = 0;
 
   va_list args;
   va_start(args, aFirst);
 
   while (f && i < info.mLengthCount) {
--- a/dom/svg/nsSVGElement.h
+++ b/dom/svg/nsSVGElement.h
@@ -39,16 +39,17 @@ class nsSVGNumberPair;
 class nsSVGString;
 class nsSVGViewBox;
 
 namespace mozilla {
 class DeclarationBlock;
 
 namespace dom {
 class SVGSVGElement;
+class SVGViewportElement;
 
 static const unsigned short SVG_UNIT_TYPE_UNKNOWN           = 0;
 static const unsigned short SVG_UNIT_TYPE_USERSPACEONUSE    = 1;
 static const unsigned short SVG_UNIT_TYPE_OBJECTBOUNDINGBOX = 2;
 
 } // namespace dom
 
 class SVGAnimatedNumberList;
@@ -140,17 +141,17 @@ public:
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
   NS_DECL_NSIDOMSVGELEMENT
 
   NS_IMPL_FROMCONTENT(nsSVGElement, kNameSpaceID_SVG)
 
   // Gets the element that establishes the rectangular viewport against which
   // we should resolve percentage lengths (our "coordinate context"). Returns
   // nullptr for outer <svg> or SVG without an <svg> parent (invalid SVG).
-  mozilla::dom::SVGSVGElement* GetCtx() const;
+  mozilla::dom::SVGViewportElement* GetCtx() const;
 
   /**
    * Returns aMatrix pre-multiplied by (explicit or implicit) transforms that
    * are introduced by attributes on this element.
    *
    * If aWhich is eAllTransforms, then all the transforms from the coordinate
    * space established by this element for its children to the coordinate
    * space established by this element's parent element for this element, are
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -116,17 +116,17 @@
 #include "mozilla/Telemetry.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/RuleNodeCacheConditions.h"
 #include "mozilla/StyleAnimationValue.h"
 #include "mozilla/StyleSetHandle.h"
 #include "mozilla/StyleSetHandleInlines.h"
 #include "RegionBuilder.h"
-#include "SVGSVGElement.h"
+#include "SVGViewportElement.h"
 #include "DisplayItemClip.h"
 #include "mozilla/layers/WebRenderLayerManager.h"
 #include "prenv.h"
 #include "TextDrawTarget.h"
 #include "nsDeckFrame.h"
 #include "nsIEffectiveTLDService.h" // for IsInStyloBlocklist
 
 #ifdef MOZ_XUL
@@ -9759,17 +9759,17 @@ ComputeSVGReferenceRect(nsIFrame* aFrame
                 nsSVGUtils::eBBoxIncludeFill | nsSVGUtils::eBBoxIncludeStroke);
       r = nsLayoutUtils::RoundGfxRectToAppRect(bbox,
                                          nsPresContext::AppUnitsPerCSSPixel());
       break;
     }
     case StyleGeometryBox::ViewBox: {
       nsIContent* content = aFrame->GetContent();
       nsSVGElement* element = static_cast<nsSVGElement*>(content);
-      SVGSVGElement* svgElement = element->GetCtx();
+      SVGViewportElement* svgElement = element->GetCtx();
       MOZ_ASSERT(svgElement);
 
       if (svgElement && svgElement->HasViewBoxRect()) {
         // If a ‘viewBox‘ attribute is specified for the SVG viewport creating
         // element:
         // 1. The reference box is positioned at the origin of the coordinate
         //    system established by the ‘viewBox‘ attribute.
         // 2. The dimension of the reference box is set to the width and height
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -526,16 +526,17 @@ fuzzy-if(skiaContent,1,100) == tspan-xy-
 == use-localRef-mask-01.svg use-localRef-mask-01-ref.svg
 
 == userSpaceOnUse-and-pattern-01.svg userSpaceOnUse-and-pattern-01-ref.svg
 
 == viewBox-and-pattern-01.svg pass.svg
 == viewBox-and-pattern-02.svg pass.svg
 == viewBox-and-pattern-03.svg pass.svg
 == viewBox-and-pattern-04.svg pass.svg
+== viewBox-and-symbol-01.svg pass.svg
 == viewBox-invalid-01.svg pass.svg
 == viewBox-invalid-02.svg pass.svg
 == viewBox-valid-01.svg pass.svg
 == viewBox-valid-02.xhtml pass.svg
 == viewport-percent-graphic-user-01.svg pass.svg
 == winding-01.svg pass.svg
 
 == zero-stroke-01.svg pass.svg
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/viewBox-and-symbol-01.svg
@@ -0,0 +1,14 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+  <defs>
+    <symbol id="mySymbol" viewBox="0 0 20 20">
+      <rect fill="lime" x="50%" height="20px" width="3%"/>
+    </symbol>
+  </defs>
+  <rect width="100%" height="100%" fill="lime"/>
+  <svg viewBox="0 0 20 20">
+    <rect fill="red" x="50%" height="20px" width="2%"/>
+  </svg>
+  <svg>
+    <use href="#mySymbol"/>
+  </svg>
+</svg>
--- a/layout/svg/nsCSSClipPathInstance.cpp
+++ b/layout/svg/nsCSSClipPathInstance.cpp
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Main header first:
 #include "nsCSSClipPathInstance.h"
 
 #include "gfx2DGlue.h"
 #include "gfxContext.h"
 #include "gfxPlatform.h"
-#include "mozilla/dom/SVGSVGElement.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/PathHelpers.h"
 #include "mozilla/ShapeUtils.h"
 #include "nsCSSRendering.h"
 #include "nsIFrame.h"
 #include "nsLayoutUtils.h"
 #include "nsRuleNode.h"
 #include "nsSVGElement.h"
--- a/layout/svg/nsSVGImageFrame.cpp
+++ b/layout/svg/nsSVGImageFrame.cpp
@@ -11,17 +11,16 @@
 #include "mozilla/gfx/2D.h"
 #include "imgIContainer.h"
 #include "nsContainerFrame.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsIImageLoadingContent.h"
 #include "nsLayoutUtils.h"
 #include "imgINotificationObserver.h"
 #include "SVGObserverUtils.h"
-#include "mozilla/dom/SVGSVGElement.h"
 #include "nsSVGUtils.h"
 #include "SVGContentUtils.h"
 #include "SVGGeometryFrame.h"
 #include "SVGImageContext.h"
 #include "mozilla/dom/SVGImageElement.h"
 #include "nsContentUtils.h"
 #include "nsIReflowCallback.h"
 #include "mozilla/Unused.h"
--- a/layout/svg/nsSVGImageFrame.h
+++ b/layout/svg/nsSVGImageFrame.h
@@ -12,17 +12,16 @@
 #include "mozilla/gfx/2D.h"
 #include "imgIContainer.h"
 #include "nsContainerFrame.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsIImageLoadingContent.h"
 #include "nsLayoutUtils.h"
 #include "imgINotificationObserver.h"
 #include "SVGObserverUtils.h"
-#include "mozilla/dom/SVGSVGElement.h"
 #include "nsSVGUtils.h"
 #include "SVGContentUtils.h"
 #include "SVGGeometryFrame.h"
 #include "SVGImageContext.h"
 #include "mozilla/dom/SVGImageElement.h"
 #include "nsContentUtils.h"
 #include "nsIReflowCallback.h"
 #include "mozilla/Unused.h"
--- a/layout/svg/nsSVGMarkerFrame.cpp
+++ b/layout/svg/nsSVGMarkerFrame.cpp
@@ -189,17 +189,17 @@ nsSVGMarkerFrame::GetMarkBBoxContributio
   // We need to include zero width/height vertical/horizontal lines, so we have
   // to use UnionEdges.
   bbox.UnionEdges(child->GetBBoxContribution(tm, aFlags));
 
   return bbox;
 }
 
 void
-nsSVGMarkerFrame::SetParentCoordCtxProvider(SVGSVGElement *aContext)
+nsSVGMarkerFrame::SetParentCoordCtxProvider(SVGViewportElement *aContext)
 {
   SVGMarkerElement *marker = static_cast<SVGMarkerElement*>(GetContent());
   marker->SetParentCoordCtxProvider(aContext);
 }
 
 void
 nsSVGMarkerFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult)
 {
@@ -214,17 +214,17 @@ nsSVGMarkerFrame::AutoMarkerReferencer::
     SVGGeometryFrame *aMarkedFrame
     MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
       : mFrame(aFrame)
 {
   MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   mFrame->mInUse = true;
   mFrame->mMarkedFrame = aMarkedFrame;
 
-  SVGSVGElement *ctx =
+  SVGViewportElement *ctx =
     static_cast<nsSVGElement*>(aMarkedFrame->GetContent())->GetCtx();
   mFrame->SetParentCoordCtxProvider(ctx);
 }
 
 nsSVGMarkerFrame::AutoMarkerReferencer::~AutoMarkerReferencer()
 {
   mFrame->SetParentCoordCtxProvider(nullptr);
 
--- a/layout/svg/nsSVGMarkerFrame.h
+++ b/layout/svg/nsSVGMarkerFrame.h
@@ -15,17 +15,17 @@
 #include "nsSVGContainerFrame.h"
 #include "nsSVGUtils.h"
 
 class gfxContext;
 
 namespace mozilla {
 class SVGGeometryFrame;
 namespace dom {
-class SVGSVGElement;
+class SVGViewportElement;
 } // namespace dom
 } // namespace mozilla
 
 struct nsSVGMark;
 
 class nsSVGMarkerFrame final : public nsSVGContainerFrame
 {
   typedef mozilla::image::imgDrawingParams imgDrawingParams;
@@ -113,17 +113,17 @@ private:
                          MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
     ~AutoMarkerReferencer();
   private:
     nsSVGMarkerFrame *mFrame;
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   };
 
   // nsSVGMarkerFrame methods:
-  void SetParentCoordCtxProvider(mozilla::dom::SVGSVGElement *aContext);
+  void SetParentCoordCtxProvider(mozilla::dom::SVGViewportElement *aContext);
 
   // recursion prevention flag
   bool mInUse;
 
   // second recursion prevention flag, for GetCanvasTM()
   bool mInUse2;
 };
 
--- a/layout/svg/nsSVGPatternFrame.cpp
+++ b/layout/svg/nsSVGPatternFrame.cpp
@@ -655,17 +655,17 @@ nsSVGPatternFrame::GetPatternRect(uint16
 gfxMatrix
 nsSVGPatternFrame::ConstructCTM(const nsSVGViewBox& aViewBox,
                                 uint16_t aPatternContentUnits,
                                 uint16_t aPatternUnits,
                                 const gfxRect &callerBBox,
                                 const Matrix &callerCTM,
                                 nsIFrame *aTarget)
 {
-  SVGSVGElement *ctx = nullptr;
+  SVGViewportElement *ctx = nullptr;
   nsIContent* targetContent = aTarget->GetContent();
   gfxFloat scaleX, scaleY;
 
   // The objectBoundingBox conversion must be handled in the CTM:
   if (IncludeBBoxScale(aViewBox, aPatternContentUnits, aPatternUnits)) {
     scaleX = callerBBox.Width();
     scaleY = callerBBox.Height();
   } else {
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -44,17 +44,17 @@
 #include "nsSVGLength2.h"
 #include "nsSVGMaskFrame.h"
 #include "nsSVGOuterSVGFrame.h"
 #include "mozilla/dom/SVGClipPathElement.h"
 #include "mozilla/dom/SVGPathElement.h"
 #include "SVGGeometryElement.h"
 #include "SVGGeometryFrame.h"
 #include "nsSVGPaintServerFrame.h"
-#include "mozilla/dom/SVGSVGElement.h"
+#include "mozilla/dom/SVGViewportElement.h"
 #include "nsTextFrame.h"
 #include "SVGContentUtils.h"
 #include "SVGTextFrame.h"
 #include "mozilla/Unused.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
@@ -285,17 +285,17 @@ nsSVGUtils::NotifyAncestorsOfFilterRegio
 Size
 nsSVGUtils::GetContextSize(const nsIFrame* aFrame)
 {
   Size size;
 
   MOZ_ASSERT(aFrame->GetContent()->IsSVGElement(), "bad cast");
   const nsSVGElement* element = static_cast<nsSVGElement*>(aFrame->GetContent());
 
-  SVGSVGElement* ctx = element->GetCtx();
+  SVGViewportElement* ctx = element->GetCtx();
   if (ctx) {
     size.width = ctx->GetLength(SVGContentUtils::X);
     size.height = ctx->GetLength(SVGContentUtils::Y);
   }
   return size;
 }
 
 float
@@ -318,17 +318,17 @@ nsSVGUtils::ObjectSpace(const gfxRect &a
     NS_NOTREACHED("unexpected ctx type");
     axis = 0.0f;
     break;
   }
   if (aLength->IsPercentage()) {
     // Multiply first to avoid precision errors:
     return axis * aLength->GetAnimValInSpecifiedUnits() / 100;
   }
-  return aLength->GetAnimValue(static_cast<SVGSVGElement*>(nullptr)) * axis;
+  return aLength->GetAnimValue(static_cast<SVGViewportElement*>(nullptr)) * axis;
 }
 
 float
 nsSVGUtils::UserSpace(nsSVGElement *aSVGElement, const nsSVGLength2 *aLength)
 {
   return aLength->GetAnimValue(aSVGElement);
 }