Bug 824327: Convert SVGMPathElement to WebIDL r=bz
☠☠ backed out by 9a315f39e03a ☠ ☠
authorDavid Zbarsky <dzbarsky@gmail.com>
Fri, 04 Jan 2013 17:28:41 -0500
changeset 126789 13acd3b74386e373e563f91e4a3f6ac52cbf1db3
parent 126788 c4470a13f216f7bc7e4882953672b971f7823a06
child 126790 2428a69911d71a4bd3458bfe2c568e4913355dfb
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs824327
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 824327: Convert SVGMPathElement to WebIDL r=bz
content/svg/content/src/Makefile.in
content/svg/content/src/SVGMPathElement.cpp
content/svg/content/src/SVGMPathElement.h
content/svg/content/src/SVGMotionSMILAnimationFunction.cpp
content/svg/content/src/SVGMotionSMILAnimationFunction.h
content/svg/content/src/nsSVGElementFactory.cpp
content/svg/content/src/nsSVGMpathElement.cpp
content/svg/content/src/nsSVGMpathElement.h
dom/webidl/SVGMPathElement.webidl
dom/webidl/SVGURIReference.webidl
dom/webidl/WebIDL.mk
--- a/content/svg/content/src/Makefile.in
+++ b/content/svg/content/src/Makefile.in
@@ -109,28 +109,28 @@ CPPSRCS		= \
 		SVGTitleElement.cpp \
 		SVGTransform.cpp \
 		SVGTransformList.cpp \
 		SVGTransformListParser.cpp \
 		nsSVGAnimateElement.cpp \
 		nsSVGAnimateTransformElement.cpp \
 		nsSVGAnimateMotionElement.cpp \
 		nsSVGAnimationElement.cpp \
-		nsSVGMpathElement.cpp \
 		nsSVGSetElement.cpp \
 		SVGAttrValueWrapper.cpp \
 		SVGContentUtils.cpp \
 		SVGDescElement.cpp \
 		SVGIntegerPairSMILType.cpp \
 		SVGLengthListSMILType.cpp \
 		SVGMetadataElement.cpp \
 		SVGMotionSMILType.cpp \
 		SVGMotionSMILAttr.cpp \
 		SVGMotionSMILAnimationFunction.cpp \
 		SVGMotionSMILPathUtils.cpp \
+		SVGMPathElement.cpp \
 		SVGNumberListSMILType.cpp \
 		SVGNumberPairSMILType.cpp \
 		SVGOrientSMILType.cpp \
 		SVGPathSegListSMILType.cpp \
 		SVGPointListSMILType.cpp \
 		SVGStopElement.cpp \
 		SVGStyleElement.cpp \
 		SVGTransformListSMILType.cpp \
@@ -151,16 +151,17 @@ EXPORTS =  			\
 EXPORTS_NAMESPACES = mozilla/dom
 
 EXPORTS_mozilla/dom = \
 	SVGAngle.h \
 	SVGAnimatedAngle.h \
 	SVGAnimatedBoolean.h \
 	SVGDescElement.h \
 	SVGMetadataElement.h \
+	SVGMPathElement.h \
 	SVGStopElement.h \
 	SVGStyleElement.h \
 	SVGTitleElement.h \
 	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 INCLUDES += 	\
rename from content/svg/content/src/nsSVGMpathElement.cpp
rename to content/svg/content/src/SVGMPathElement.cpp
--- a/content/svg/content/src/nsSVGMpathElement.cpp
+++ b/content/svg/content/src/SVGMPathElement.cpp
@@ -1,198 +1,215 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/Util.h"
 
-#include "nsSVGMpathElement.h"
+#include "mozilla/dom/SVGMPathElement.h"
 #include "nsAutoPtr.h"
 #include "nsDebug.h"
 #include "nsSVGPathElement.h"
 #include "nsSVGAnimateMotionElement.h"
 #include "nsContentUtils.h"
+#include "mozilla/dom/SVGMPathElementBinding.h"
 
-using namespace mozilla;
-using namespace mozilla::dom;
+DOMCI_NODE_DATA(SVGMpathElement, mozilla::dom::SVGMPathElement)
+
+NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(MPath)
+
+namespace mozilla {
+namespace dom {
 
-nsSVGElement::StringInfo nsSVGMpathElement::sStringInfo[1] =
+JSObject*
+SVGMPathElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap)
+{
+  return SVGMPathElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
+
+nsSVGElement::StringInfo SVGMPathElement::sStringInfo[1] =
 {
   { &nsGkAtoms::href, kNameSpaceID_XLink, false }
 };
 
-NS_IMPL_NS_NEW_SVG_ELEMENT(Mpath)
-
 // Cycle collection magic -- based on nsSVGUseElement
-NS_IMPL_CYCLE_COLLECTION_CLASS(nsSVGMpathElement)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsSVGMpathElement,
-                                                nsSVGMpathElementBase)
+NS_IMPL_CYCLE_COLLECTION_CLASS(SVGMPathElement)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SVGMPathElement,
+                                                SVGMPathElementBase)
   tmp->UnlinkHrefTarget(false);
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsSVGMpathElement,
-                                                  nsSVGMpathElementBase)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SVGMPathElement,
+                                                  SVGMPathElementBase)
   tmp->mHrefTarget.Traverse(&cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
-NS_IMPL_ADDREF_INHERITED(nsSVGMpathElement,nsSVGMpathElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGMpathElement,nsSVGMpathElementBase)
+NS_IMPL_ADDREF_INHERITED(SVGMPathElement,SVGMPathElementBase)
+NS_IMPL_RELEASE_INHERITED(SVGMPathElement,SVGMPathElementBase)
 
-DOMCI_NODE_DATA(SVGMpathElement, nsSVGMpathElement)
-
-NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsSVGMpathElement)
-  NS_NODE_INTERFACE_TABLE6(nsSVGMpathElement, nsIDOMNode, nsIDOMElement,
+NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(SVGMPathElement)
+  NS_NODE_INTERFACE_TABLE6(SVGMPathElement, nsIDOMNode, nsIDOMElement,
                            nsIDOMSVGElement,  nsIDOMSVGURIReference,
                            nsIDOMSVGMpathElement, nsIMutationObserver)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGMpathElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGMpathElementBase)
+NS_INTERFACE_MAP_END_INHERITING(SVGMPathElementBase)
 
 // Constructor
 #ifdef _MSC_VER
 // Disable "warning C4355: 'this' : used in base member initializer list".
 // We can ignore that warning because we know that mHrefTarget's constructor 
 // doesn't dereference the pointer passed to it.
 #pragma warning(push)
 #pragma warning(disable:4355)
 #endif
-nsSVGMpathElement::nsSVGMpathElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-  : nsSVGMpathElementBase(aNodeInfo),
+SVGMPathElement::SVGMPathElement(already_AddRefed<nsINodeInfo> aNodeInfo)
+  : SVGMPathElementBase(aNodeInfo),
     mHrefTarget(this)
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 {
+  SetIsDOMBinding();
 }
 
-nsSVGMpathElement::~nsSVGMpathElement()
+SVGMPathElement::~SVGMPathElement()
 {
   UnlinkHrefTarget(false);
 }
 
 //----------------------------------------------------------------------
 // nsIDOMNode methods
 
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGMpathElement)
+NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGMPathElement)
 
 //----------------------------------------------------------------------
 // nsIDOMSVGURIReference methods
 
 /* readonly attribute nsIDOMSVGAnimatedString href; */
+already_AddRefed<nsIDOMSVGAnimatedString>
+SVGMPathElement::Href()
+{
+  nsCOMPtr<nsIDOMSVGAnimatedString> href;
+  mStringAttributes[HREF].ToDOMAnimatedString(getter_AddRefs(href), this);
+  return href.forget();
+}
+
 NS_IMETHODIMP
-nsSVGMpathElement::GetHref(nsIDOMSVGAnimatedString** aHref)
+SVGMPathElement::GetHref(nsIDOMSVGAnimatedString** aHref)
 {
-  return mStringAttributes[HREF].ToDOMAnimatedString(aHref, this);
+  *aHref = Href().get();
+  return NS_OK;
 }
 
 //----------------------------------------------------------------------
 // nsIContent methods
 
 nsresult
-nsSVGMpathElement::BindToTree(nsIDocument* aDocument,
-                              nsIContent* aParent,
-                              nsIContent* aBindingParent,
-                              bool aCompileEventHandlers)
+SVGMPathElement::BindToTree(nsIDocument* aDocument,
+                            nsIContent* aParent,
+                            nsIContent* aBindingParent,
+                            bool aCompileEventHandlers)
 {
   NS_ABORT_IF_FALSE(!mHrefTarget.get(),
                     "Shouldn't have href-target yet "
                     "(or it should've been cleared)");
-  nsresult rv = nsSVGMpathElementBase::BindToTree(aDocument, aParent,
-                                                  aBindingParent,
-                                                  aCompileEventHandlers);
+  nsresult rv = SVGMPathElementBase::BindToTree(aDocument, aParent,
+                                                aBindingParent,
+                                                aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv,rv);
 
   if (aDocument) {
     const nsAttrValue* hrefAttrValue =
       mAttrsAndChildren.GetAttr(nsGkAtoms::href, kNameSpaceID_XLink);
     if (hrefAttrValue) {
       UpdateHrefTarget(aParent, hrefAttrValue->GetStringValue());
     }
   }
 
   return NS_OK;
 }
 
 void
-nsSVGMpathElement::UnbindFromTree(bool aDeep, bool aNullParent)
+SVGMPathElement::UnbindFromTree(bool aDeep, bool aNullParent)
 {
   UnlinkHrefTarget(true);
-  nsSVGMpathElementBase::UnbindFromTree(aDeep, aNullParent);
+  SVGMPathElementBase::UnbindFromTree(aDeep, aNullParent);
 }
 
 bool
-nsSVGMpathElement::ParseAttribute(int32_t aNamespaceID,
-                                  nsIAtom* aAttribute,
-                                  const nsAString& aValue,
-                                  nsAttrValue& aResult)
+SVGMPathElement::ParseAttribute(int32_t aNamespaceID,
+                                nsIAtom* aAttribute,
+                                const nsAString& aValue,
+                                nsAttrValue& aResult)
 {
   bool returnVal =
-    nsSVGMpathElementBase::ParseAttribute(aNamespaceID, aAttribute,
+    SVGMPathElementBase::ParseAttribute(aNamespaceID, aAttribute,
                                           aValue, aResult);
   if (aNamespaceID == kNameSpaceID_XLink &&
       aAttribute == nsGkAtoms::href &&
       IsInDoc()) {
     // NOTE: If we fail the IsInDoc call, it's ok -- we'll update the target
     // on next BindToTree call.
     UpdateHrefTarget(GetParent(), aValue);
   }
   return returnVal;
 }
 
 nsresult
-nsSVGMpathElement::UnsetAttr(int32_t aNamespaceID,
-                             nsIAtom* aAttribute, bool aNotify)
+SVGMPathElement::UnsetAttr(int32_t aNamespaceID,
+                           nsIAtom* aAttribute, bool aNotify)
 {
-  nsresult rv = nsSVGMpathElementBase::UnsetAttr(aNamespaceID, aAttribute,
-                                                 aNotify);
+  nsresult rv = SVGMPathElementBase::UnsetAttr(aNamespaceID, aAttribute,
+                                               aNotify);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aNamespaceID == kNameSpaceID_XLink &&
       aAttribute == nsGkAtoms::href) {
     UnlinkHrefTarget(true);
   }
 
   return NS_OK;
 }
 
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
 nsSVGElement::StringAttributesInfo
-nsSVGMpathElement::GetStringInfo()
+SVGMPathElement::GetStringInfo()
 {
   return StringAttributesInfo(mStringAttributes, sStringInfo,
                               ArrayLength(sStringInfo));
 }
 
 //----------------------------------------------------------------------
 // nsIMutationObserver methods
 
 void
-nsSVGMpathElement::AttributeChanged(nsIDocument* aDocument,
-                                    Element* aElement,
-                                    int32_t aNameSpaceID,
-                                    nsIAtom* aAttribute,
-                                    int32_t aModType)
+SVGMPathElement::AttributeChanged(nsIDocument* aDocument,
+                                  Element* aElement,
+                                  int32_t aNameSpaceID,
+                                  nsIAtom* aAttribute,
+                                  int32_t aModType)
 {
   if (aNameSpaceID == kNameSpaceID_None) {
     if (aAttribute == nsGkAtoms::d) {
       NotifyParentOfMpathChange(GetParent());
     }
   }
 }
 
 //----------------------------------------------------------------------
 // Public helper methods
 
 nsSVGPathElement*
-nsSVGMpathElement::GetReferencedPath()
+SVGMPathElement::GetReferencedPath()
 {
   if (!HasAttr(kNameSpaceID_XLink, nsGkAtoms::href)) {
     NS_ABORT_IF_FALSE(!mHrefTarget.get(),
                       "We shouldn't have an xlink:href target "
                       "if we don't have an xlink:href attribute");
     return nullptr;
   }
 
@@ -202,18 +219,18 @@ nsSVGMpathElement::GetReferencedPath()
   }
   return nullptr;
 }
 
 //----------------------------------------------------------------------
 // Protected helper methods
 
 void
-nsSVGMpathElement::UpdateHrefTarget(nsIContent* aParent,
-                                    const nsAString& aHrefStr)
+SVGMPathElement::UpdateHrefTarget(nsIContent* aParent,
+                                  const nsAString& aHrefStr)
 {
   nsCOMPtr<nsIURI> targetURI;
   nsCOMPtr<nsIURI> baseURI = GetBaseURI();
   nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI),
                                             aHrefStr, OwnerDoc(), baseURI);
 
   // Stop observing old target (if any)
   if (mHrefTarget.get()) {
@@ -235,33 +252,37 @@ nsSVGMpathElement::UpdateHrefTarget(nsIC
   if (mHrefTarget.get()) {
     mHrefTarget.get()->AddMutationObserver(this);
   }
 
   NotifyParentOfMpathChange(aParent);
 }
 
 void
-nsSVGMpathElement::UnlinkHrefTarget(bool aNotifyParent)
+SVGMPathElement::UnlinkHrefTarget(bool aNotifyParent)
 {
   // Stop observing old target (if any)
   if (mHrefTarget.get()) {
     mHrefTarget.get()->RemoveMutationObserver(this);
   }
   mHrefTarget.Unlink();
 
   if (aNotifyParent) {
     NotifyParentOfMpathChange(GetParent());
   }
 }
 
 void
-nsSVGMpathElement::NotifyParentOfMpathChange(nsIContent* aParent)
+SVGMPathElement::NotifyParentOfMpathChange(nsIContent* aParent)
 {
   if (aParent && aParent->IsSVG(nsGkAtoms::animateMotion)) {
 
     nsSVGAnimateMotionElement* animateMotionParent =
       static_cast<nsSVGAnimateMotionElement*>(aParent);
 
     animateMotionParent->MpathChanged();
     AnimationNeedsResample();
   }
 }
+
+} // namespace dom
+} // namespace mozilla
+
rename from content/svg/content/src/nsSVGMpathElement.h
rename to content/svg/content/src/SVGMPathElement.h
--- a/content/svg/content/src/nsSVGMpathElement.h
+++ b/content/svg/content/src/SVGMPathElement.h
@@ -1,54 +1,60 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 NS_SVGMPATHELEMENT_H_
-#define NS_SVGMPATHELEMENT_H_
+#ifndef mozilla_dom_SVGMPathElement_h
+#define mozilla_dom_SVGMPathElement_h
 
 #include "nsIDOMSVGMpathElement.h"
 #include "nsIDOMSVGURIReference.h"
 #include "nsSVGElement.h"
 #include "nsStubMutationObserver.h"
 #include "nsSVGPathElement.h"
 #include "nsSVGString.h"
 #include "nsReferencedElement.h"
 
+nsresult NS_NewSVGMPathElement(nsIContent **aResult,
+                               already_AddRefed<nsINodeInfo> aNodeInfo);
 
-typedef nsSVGElement nsSVGMpathElementBase;
+typedef nsSVGElement SVGMPathElementBase;
 
-class nsSVGMpathElement : public nsSVGMpathElementBase,
-                          public nsIDOMSVGMpathElement,
-                          public nsIDOMSVGURIReference,
-                          public nsStubMutationObserver
+namespace mozilla {
+namespace dom {
+
+class SVGMPathElement MOZ_FINAL : public SVGMPathElementBase,
+                                  public nsIDOMSVGMpathElement,
+                                  public nsIDOMSVGURIReference,
+                                  public nsStubMutationObserver
 {
 protected:
-  friend nsresult NS_NewSVGMpathElement(nsIContent **aResult,
-                                        already_AddRefed<nsINodeInfo> aNodeInfo);
-  nsSVGMpathElement(already_AddRefed<nsINodeInfo> aNodeInfo);
-  ~nsSVGMpathElement();
+  friend nsresult (::NS_NewSVGMPathElement(nsIContent **aResult,
+                                           already_AddRefed<nsINodeInfo> aNodeInfo));
+  SVGMPathElement(already_AddRefed<nsINodeInfo> aNodeInfo);
+  ~SVGMPathElement();
 
+  virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap) MOZ_OVERRIDE;
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGMPATHELEMENT
   NS_DECL_NSIDOMSVGURIREFERENCE
 
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsSVGMpathElement,
-                                           nsSVGMpathElementBase)
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SVGMPathElement,
+                                           SVGMPathElementBase)
 
   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
 
   // Forward interface implementations to base class
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGMpathElementBase::)
+  NS_FORWARD_NSIDOMSVGELEMENT(SVGMPathElementBase::)
 
   // nsIContent interface
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers);
   virtual void UnbindFromTree(bool aDeep, bool aNullParent);
 
@@ -63,20 +69,24 @@ public:
   // Public helper method: If our xlink:href attribute links to a <path>
   // element, this method returns a pointer to that element. Otherwise,
   // this returns nullptr.
   nsSVGPathElement* GetReferencedPath();
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
+
+  // WebIDL
+  already_AddRefed<nsIDOMSVGAnimatedString> Href();
+
 protected:
   class PathReference : public nsReferencedElement {
   public:
-    PathReference(nsSVGMpathElement* aMpathElement) :
+    PathReference(SVGMPathElement* aMpathElement) :
       mMpathElement(aMpathElement) {}
   protected:
     // We need to be notified when target changes, in order to request a sample
     // (which will clear animation effects that used the old target-path
     // and recompute the animation effects using the new target-path).
     virtual void ElementChanged(Element* aFrom, Element* aTo) {
       nsReferencedElement::ElementChanged(aFrom, aTo);
       if (aFrom) {
@@ -87,24 +97,27 @@ protected:
       }
       mMpathElement->NotifyParentOfMpathChange(mMpathElement->GetParent());
     }
 
     // We need to override IsPersistent to get persistent tracking (beyond the
     // first time the target changes)
     virtual bool IsPersistent() { return true; }
   private:
-    nsSVGMpathElement* const mMpathElement;
+    SVGMPathElement* const mMpathElement;
   };
 
   virtual StringAttributesInfo GetStringInfo();
 
   void UpdateHrefTarget(nsIContent* aParent, const nsAString& aHrefStr);
   void UnlinkHrefTarget(bool aNotifyParent);
   void NotifyParentOfMpathChange(nsIContent* aParent);
 
   enum { HREF };
   nsSVGString        mStringAttributes[1];
   static StringInfo  sStringInfo[1];
   PathReference      mHrefTarget;
 };
 
-#endif // NS_SVGMPATHELEMENT_H_
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_SVGMPathElement_h
--- a/content/svg/content/src/SVGMotionSMILAnimationFunction.cpp
+++ b/content/svg/content/src/SVGMotionSMILAnimationFunction.cpp
@@ -6,21 +6,23 @@
 #include "SVGMotionSMILAnimationFunction.h"
 #include "nsISMILAnimationElement.h"
 #include "nsSMILParserUtils.h"
 #include "nsSVGAngle.h"
 #include "SVGMotionSMILType.h"
 #include "SVGMotionSMILPathUtils.h"
 #include "nsSVGPathDataParser.h"
 #include "nsSVGPathElement.h" // for nsSVGPathList
-#include "nsSVGMpathElement.h"
+#include "SVGMPathElement.h"
 #include "nsAttrValueInlines.h"
 
 namespace mozilla {
 
+using namespace dom;
+
 SVGMotionSMILAnimationFunction::SVGMotionSMILAnimationFunction()
   : mRotateType(eRotateType_Explicit),
     mRotateAngle(0.0f),
     mPathSourceType(ePathSourceType_None),
     mIsPathStale(true)  // Try to initialize path on first GetValues call
 {
 }
 
@@ -119,24 +121,24 @@ SVGMotionSMILAnimationFunction::GetCalcM
 
 //----------------------------------------------------------------------
 // Helpers for GetValues
 
 /*
  * Returns the first <mpath> child of the given element
  */
 
-static nsSVGMpathElement*
+static SVGMPathElement*
 GetFirstMpathChild(nsIContent* aElem)
 {
   for (nsIContent* child = aElem->GetFirstChild();
        child;
        child = child->GetNextSibling()) {
     if (child->IsSVG(nsGkAtoms::mpath)) {
-      return static_cast<nsSVGMpathElement*>(child);
+      return static_cast<SVGMPathElement*>(child);
     }
   }
 
   return nullptr;
 }
 
 void
 SVGMotionSMILAnimationFunction::
@@ -205,17 +207,17 @@ SVGMotionSMILAnimationFunction::
   } else {
     // Parse failure. Leave path as null, and clear path-related member data.
     mPathVertices.Clear();
   }
 }
 
 void
 SVGMotionSMILAnimationFunction::
-  RebuildPathAndVerticesFromMpathElem(nsSVGMpathElement* aMpathElem)
+  RebuildPathAndVerticesFromMpathElem(SVGMPathElement* aMpathElem)
 {
   mPathSourceType = ePathSourceType_Mpath;
 
   // Use the path that's the target of our chosen <mpath> child.
   nsSVGPathElement* pathElem = aMpathElem->GetReferencedPath();
   if (pathElem) {
     const SVGPathData &path = pathElem->GetAnimPathSegList()->GetAnimValue();
     // Path data must contain of at least one path segment (if the path data
@@ -265,17 +267,17 @@ SVGMotionSMILAnimationFunction::
 
   // Clear stale data
   mPath = nullptr;
   mPathVertices.Clear();
   mPathSourceType = ePathSourceType_None;
 
   // Do we have a mpath child? if so, it trumps everything. Otherwise, we look
   // through our list of path-defining attributes, in order of priority.
-  nsSVGMpathElement* firstMpathChild =
+  SVGMPathElement* firstMpathChild =
     GetFirstMpathChild(&mAnimationElement->AsElement());
 
   if (firstMpathChild) {
     RebuildPathAndVerticesFromMpathElem(firstMpathChild);
     mValueNeedsReparsingEverySample = false;
   } else if (HasAttr(nsGkAtoms::path)) {
     RebuildPathAndVerticesFromPathAttr();
     mValueNeedsReparsingEverySample = false;
--- a/content/svg/content/src/SVGMotionSMILAnimationFunction.h
+++ b/content/svg/content/src/SVGMotionSMILAnimationFunction.h
@@ -12,20 +12,23 @@
 #include "nsTArray.h"
 #include "SVGMotionSMILType.h"  // for RotateType
 
 class nsAttrValue;
 class nsIAtom;
 class nsIContent;
 class nsISMILAttr;
 class nsSMILValue;
-class nsSVGMpathElement;
 
 namespace mozilla {
 
+namespace dom {
+class SVGMPathElement;
+}
+
 //----------------------------------------------------------------------
 // SVGMotionSMILAnimationFunction
 //
 // Subclass of nsSMILAnimationFunction to support a few extra features offered
 // by the <animateMotion> element.
 //
 class SVGMotionSMILAnimationFunction : public nsSMILAnimationFunction
 {
@@ -67,17 +70,17 @@ protected:
   nsresult SetKeyPoints(const nsAString& aKeyPoints, nsAttrValue& aResult);
   void     UnsetKeyPoints();
   nsresult SetRotate(const nsAString& aRotate, nsAttrValue& aResult);
   void     UnsetRotate();
 
   // Helpers for GetValues
   void     MarkStaleIfAttributeAffectsPath(nsIAtom* aAttribute);
   void     RebuildPathAndVertices(const nsIContent* aContextElem);
-  void     RebuildPathAndVerticesFromMpathElem(nsSVGMpathElement* aMpathElem);
+  void     RebuildPathAndVerticesFromMpathElem(dom::SVGMPathElement* aMpathElem);
   void     RebuildPathAndVerticesFromPathAttr();
   void     RebuildPathAndVerticesFromBasicAttrs(const nsIContent* aContextElem);
   bool     GenerateValuesForPathAndPoints(gfxFlattenedPath* aPath,
                                           bool aIsKeyPoints,
                                           nsTArray<double>& aPointDistances,
                                           nsTArray<nsSMILValue>& aResult);
 
   // Members
--- a/content/svg/content/src/nsSVGElementFactory.cpp
+++ b/content/svg/content/src/nsSVGElementFactory.cpp
@@ -196,17 +196,17 @@ NS_NewSVGAnimateElement(nsIContent **aRe
                         already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
 NS_NewSVGAnimateTransformElement(nsIContent **aResult,
                                  already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
 NS_NewSVGAnimateMotionElement(nsIContent **aResult,
                               already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
-NS_NewSVGMpathElement(nsIContent **aResult,
+NS_NewSVGMPathElement(nsIContent **aResult,
                       already_AddRefed<nsINodeInfo> aNodeInfo);
 nsresult
 NS_NewSVGSetElement(nsIContent **aResult,
                     already_AddRefed<nsINodeInfo> aNodeInfo);
 
 nsresult
 NS_NewSVGUnknownElement(nsIContent **aResult,
                         already_AddRefed<nsINodeInfo> aNodeInfo);
@@ -343,17 +343,17 @@ NS_NewSVGElement(nsIContent** aResult, a
   if (NS_SMILEnabled()) {
     if (name == nsGkAtoms::animate)
       return NS_NewSVGAnimateElement(aResult, aNodeInfo);
     if (name == nsGkAtoms::animateTransform)
       return NS_NewSVGAnimateTransformElement(aResult, aNodeInfo);
     if (name == nsGkAtoms::animateMotion)
       return NS_NewSVGAnimateMotionElement(aResult, aNodeInfo);
     if (name == nsGkAtoms::mpath)
-      return NS_NewSVGMpathElement(aResult, aNodeInfo);
+      return NS_NewSVGMPathElement(aResult, aNodeInfo);
     if (name == nsGkAtoms::set)
       return NS_NewSVGSetElement(aResult, aNodeInfo);
   }
 
   // if we don't know what to create, just create a standard svg element:
   return NS_NewSVGUnknownElement(aResult, aNodeInfo);
 }
 
new file mode 100644
--- /dev/null
+++ b/dom/webidl/SVGMPathElement.webidl
@@ -0,0 +1,17 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ *
+ * The origin of this IDL file is
+ * http://www.w3.org/TR/SVG2/
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface SVGMPathElement : SVGElement {
+};
+
+SVGMPathElement implements SVGURIReference;
+
new file mode 100644
--- /dev/null
+++ b/dom/webidl/SVGURIReference.webidl
@@ -0,0 +1,19 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ *
+ * The origin of this IDL file is
+ * http://www.w3.org/TR/SVG2/
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface SVGAnimatedString;
+
+[NoInterfaceObject]
+interface SVGURIReference {
+  readonly attribute SVGAnimatedString href;
+};
+
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -96,27 +96,29 @@ webidl_files = \
   SVGAnimatedNumberList.webidl \
   SVGAnimatedPreserveAspectRatio.webidl \
   SVGAnimatedTransformList.webidl \
   SVGDescElement.webidl \
   SVGElement.webidl \
   SVGLengthList.webidl \
   SVGMatrix.webidl \
   SVGMetadataElement.webidl \
+  SVGMPathElement.webidl \
   SVGNumberList.webidl \
   SVGPathSeg.webidl \
   SVGPathSegList.webidl \
   SVGPoint.webidl \
   SVGPointList.webidl \
   SVGPreserveAspectRatio.webidl \
   SVGStopElement.webidl \
   SVGStyleElement.webidl \
   SVGTitleElement.webidl \
   SVGTransform.webidl \
   SVGTransformList.webidl \
+  SVGURIReference.webidl \
   Text.webidl \
   TextDecoder.webidl \
   TextEncoder.webidl \
   URL.webidl \
   WebSocket.webidl \
   UndoManager.webidl \
   XMLHttpRequest.webidl \
   XMLHttpRequestEventTarget.webidl \