Bug 816778 Part 1.5: Create nsISVGPoint and make nsSVGTranslatePoint::DOMVal a subclass r=bz
authorDavid Zbarsky <dzbarsky@gmail.com>
Sat, 22 Dec 2012 23:54:20 -0500 (2012-12-23)
changeset 116904 347128caddd541d65a16c830dc0310212668df93
parent 116903 4c295e120bccb84032e8997749b64d831fd6ed43
child 116905 9b19cd969afcaab7b9e4fde83480e37db7c20f83
push id20208
push userdzbarsky@gmail.com
push dateSun, 23 Dec 2012 04:53:49 +0000 (2012-12-23)
treeherdermozilla-inbound@a80783039603 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs816778
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 816778 Part 1.5: Create nsISVGPoint and make nsSVGTranslatePoint::DOMVal a subclass r=bz
content/svg/content/src/DOMSVGPoint.cpp
content/svg/content/src/DOMSVGPoint.h
content/svg/content/src/DOMSVGPointList.cpp
content/svg/content/src/DOMSVGPointList.h
content/svg/content/src/nsISVGPoint.h
content/svg/content/src/nsSVGSVGElement.cpp
content/svg/content/src/nsSVGSVGElement.h
dom/bindings/Bindings.conf
--- a/content/svg/content/src/DOMSVGPoint.cpp
+++ b/content/svg/content/src/DOMSVGPoint.cpp
@@ -46,16 +46,17 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGPo
 NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGPoint)
 
 DOMCI_DATA(SVGPoint, DOMSVGPoint)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGPoint)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(DOMSVGPoint) // pseudo-interface
   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGPoint)
+  NS_INTERFACE_MAP_ENTRY(nsISVGPoint)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGPoint)
 NS_INTERFACE_MAP_END
 
 float
 DOMSVGPoint::X()
 {
   if (mIsAnimValItem && HasOwner()) {
@@ -160,35 +161,29 @@ DOMSVGPoint::SetY(float aY, ErrorResult&
 NS_IMETHODIMP
 DOMSVGPoint::MatrixTransform(nsIDOMSVGMatrix *matrix,
                              nsIDOMSVGPoint **_retval)
 {
   *_retval = MatrixTransform(matrix).get();
   return NS_OK;
 }
 
-already_AddRefed<DOMSVGPoint>
+already_AddRefed<nsISVGPoint>
 DOMSVGPoint::MatrixTransform(nsIDOMSVGMatrix* matrix)
 {
   nsCOMPtr<DOMSVGMatrix> domMatrix = do_QueryInterface(matrix);
 
   float x = HasOwner() ? InternalItem().mX : mPt.mX;
   float y = HasOwner() ? InternalItem().mY : mPt.mY;
 
   gfxPoint pt = domMatrix->Matrix().Transform(gfxPoint(x, y));
-  nsRefPtr<DOMSVGPoint> newPoint = new DOMSVGPoint(pt);
+  nsCOMPtr<nsISVGPoint> newPoint = new DOMSVGPoint(pt);
   return newPoint.forget();
 }
 
-JSObject*
-DOMSVGPoint::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
-{
-  return mozilla::dom::SVGPointBinding::Wrap(cx, scope, this, triedToWrap);
-}
-
 void
 DOMSVGPoint::InsertingIntoList(DOMSVGPointList *aList,
                                uint32_t aListIndex,
                                bool aIsAnimValItem)
 {
   NS_ABORT_IF_FALSE(!HasOwner(), "Inserting item that already has an owner");
 
   mList = aList;
--- a/content/svg/content/src/DOMSVGPoint.h
+++ b/content/svg/content/src/DOMSVGPoint.h
@@ -6,17 +6,17 @@
 #ifndef MOZILLA_DOMSVGPOINT_H__
 #define MOZILLA_DOMSVGPOINT_H__
 
 #include "DOMSVGPointList.h"
 #include "gfxPoint.h"
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDebug.h"
-#include "nsIDOMSVGPoint.h"
+#include "nsISVGPoint.h"
 #include "nsTArray.h"
 #include "SVGPoint.h"
 #include "nsWrapperCache.h"
 #include "mozilla/Attributes.h"
 
 class nsSVGElement;
 
 // We make DOMSVGPoint a pseudo-interface to allow us to QI to it in order to
@@ -41,100 +41,96 @@ namespace mozilla {
  * objects.
  *
  * See the architecture comment in DOMSVGPointList.h for an overview of the
  * important points regarding these DOM wrapper structures.
  *
  * See the architecture comment in DOMSVGLength.h (yes, LENGTH) for an overview
  * of the important points regarding how this specific class works.
  */
-class DOMSVGPoint MOZ_FINAL : public nsIDOMSVGPoint,
-                              public nsWrapperCache
+class DOMSVGPoint MOZ_FINAL : public nsISVGPoint
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOMSVGPOINT_IID)
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGPoint)
   NS_DECL_NSIDOMSVGPOINT
 
   /**
    * Generic ctor for DOMSVGPoint objects that are created for an attribute.
    */
   DOMSVGPoint(DOMSVGPointList *aList,
               uint32_t aListIndex,
               bool aIsAnimValItem)
-    : mList(aList)
+    : nsISVGPoint()
+    , mList(aList)
     , mListIndex(aListIndex)
     , mIsReadonly(false)
     , mIsAnimValItem(aIsAnimValItem)
   {
-    SetIsDOMBinding();
     // These shifts are in sync with the members.
     NS_ABORT_IF_FALSE(aList &&
                       aListIndex <= MaxListIndex(), "bad arg");
 
     NS_ABORT_IF_FALSE(IndexIsValid(), "Bad index for DOMSVGPoint!");
   }
 
   explicit DOMSVGPoint(const DOMSVGPoint *aPt = nullptr)
-    : mList(nullptr)
+    : nsISVGPoint()
+    , mList(nullptr)
     , mListIndex(0)
     , mIsReadonly(false)
     , mIsAnimValItem(false)
   {
-    SetIsDOMBinding();
     if (aPt) {
       mPt = aPt->ToSVGPoint();
     }
   }
 
   DOMSVGPoint(float aX, float aY)
-    : mList(nullptr)
+    : nsISVGPoint()
+    , mList(nullptr)
     , mListIndex(0)
     , mIsReadonly(false)
     , mIsAnimValItem(false)
   {
-    SetIsDOMBinding();
     mPt.mX = aX;
     mPt.mY = aY;
   }
 
   explicit DOMSVGPoint(const gfxPoint &aPt)
-    : mList(nullptr)
+    : nsISVGPoint()
+    , mList(nullptr)
     , mListIndex(0)
     , mIsReadonly(false)
     , mIsAnimValItem(false)
   {
-    SetIsDOMBinding();
     mPt.mX = float(aPt.x);
     mPt.mY = float(aPt.y);
     NS_ASSERTION(NS_finite(mPt.mX) && NS_finite(mPt.mX),
                  "DOMSVGPoint coords are not finite");
   }
 
 
-  ~DOMSVGPoint() {
+  virtual ~DOMSVGPoint() {
     // Our mList's weak ref to us must be nulled out when we die. If GC has
     // unlinked us using the cycle collector code, then that has already
     // happened, and mList is null.
     if (mList) {
       mList->mItems[mListIndex] = nullptr;
     }
   }
 
   // WebIDL
-  float X();
-  void SetX(float aX, ErrorResult& rv);
-  float Y();
-  void SetY(float aY, ErrorResult& rv);
-  already_AddRefed<DOMSVGPoint> MatrixTransform(nsIDOMSVGMatrix* matrix);
-  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
-                               bool *triedToWrap);
-
-  nsISupports* GetParentObject() {
+  virtual float X();
+  virtual void SetX(float aX, ErrorResult& rv);
+  virtual float Y();
+  virtual void SetY(float aY, ErrorResult& rv);
+  virtual already_AddRefed<nsISVGPoint> MatrixTransform(nsIDOMSVGMatrix* matrix);
+  nsISupports* GetParentObject() MOZ_OVERRIDE {
     return mList;
   }
 
   /**
    * Create an unowned copy of this object. The caller is responsible for the
    * first AddRef()!
    */
   DOMSVGPoint* Clone() {
--- a/content/svg/content/src/DOMSVGPointList.cpp
+++ b/content/svg/content/src/DOMSVGPointList.cpp
@@ -214,56 +214,60 @@ DOMSVGPointList::Clear(ErrorResult& aErr
 NS_IMETHODIMP
 DOMSVGPointList::Clear()
 {
   ErrorResult rv;
   Clear(rv);
   return rv.ErrorCode();
 }
 
-already_AddRefed<DOMSVGPoint>
-DOMSVGPointList::Initialize(DOMSVGPoint& aNewItem, ErrorResult& aError)
+already_AddRefed<nsISVGPoint>
+DOMSVGPointList::Initialize(nsISVGPoint& aNewItem, ErrorResult& aError)
 {
   if (IsAnimValList()) {
     aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
     return nullptr;
   }
 
   // If aNewItem is already in a list we should insert a clone of aNewItem,
   // and for consistency, this should happen even if *this* is the list that
   // aNewItem is currently in. Note that in the case of aNewItem being in this
   // list, the Clear() call before the InsertItemBefore() call would remove it
   // from this list, and so the InsertItemBefore() call would not insert a
   // clone of aNewItem, it would actually insert aNewItem. To prevent that
   // from happening we have to do the clone here, if necessary.
 
-  nsRefPtr<DOMSVGPoint> newItem = &aNewItem;
-  if (aNewItem.HasOwner() || aNewItem.IsReadonly()) {
-    newItem = aNewItem.Clone();
+  nsCOMPtr<DOMSVGPoint> domItem = do_QueryInterface(&aNewItem);
+  if (!domItem) {
+    aError.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+    return nullptr;
+  }
+  if (domItem->HasOwner() || domItem->IsReadonly()) {
+    domItem = domItem->Clone(); // must do this before changing anything!
   }
 
   Clear();
-  return InsertItemBefore(*newItem, 0, aError);
+  return InsertItemBefore(*domItem, 0, aError);
 }
 
 NS_IMETHODIMP
 DOMSVGPointList::Initialize(nsIDOMSVGPoint *aNewItem,
                             nsIDOMSVGPoint **_retval)
 {
   nsCOMPtr<DOMSVGPoint> domItem = do_QueryInterface(aNewItem);
   if (!domItem) {
     *_retval = nullptr;
     return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
   }
   ErrorResult rv;
   *_retval = Initialize(*domItem, rv).get();
   return rv.ErrorCode();
 }
 
-DOMSVGPoint*
+nsISVGPoint*
 DOMSVGPointList::IndexedGetter(uint32_t aIndex, bool& aFound,
                                ErrorResult& aError)
 {
   if (IsAnimValList()) {
     Element()->FlushAnimations();
   }
   aFound = aIndex < LengthNoFlush();
   if (aFound) {
@@ -277,34 +281,38 @@ NS_IMETHODIMP
 DOMSVGPointList::GetItem(uint32_t aIndex,
                          nsIDOMSVGPoint **_retval)
 {
   ErrorResult rv;
   NS_IF_ADDREF(*_retval = GetItem(aIndex, rv));
   return rv.ErrorCode();
 }
 
-already_AddRefed<DOMSVGPoint>
-DOMSVGPointList::InsertItemBefore(DOMSVGPoint& aNewItem, uint32_t aIndex,
+already_AddRefed<nsISVGPoint>
+DOMSVGPointList::InsertItemBefore(nsISVGPoint& aNewItem, uint32_t aIndex,
                                   ErrorResult& aError)
 {
   if (IsAnimValList()) {
     aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
     return nullptr;
   }
 
   aIndex = NS_MIN(aIndex, LengthNoFlush());
   if (aIndex >= DOMSVGPoint::MaxListIndex()) {
     aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
     return nullptr;
   }
 
-  nsRefPtr<DOMSVGPoint> domItem = &aNewItem;
-  if (aNewItem.HasOwner() || aNewItem.IsReadonly()) {
-    domItem = aNewItem.Clone(); // must do this before changing anything!
+  nsCOMPtr<DOMSVGPoint> domItem = do_QueryInterface(&aNewItem);
+  if (!domItem) {
+    aError.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+    return nullptr;
+  }
+  if (domItem->HasOwner() || domItem->IsReadonly()) {
+    domItem = domItem->Clone(); // must do this before changing anything!
   }
 
   // Ensure we have enough memory so we can avoid complex error handling below:
   if (!mItems.SetCapacity(mItems.Length() + 1) ||
       !InternalList().SetCapacity(InternalList().Length() + 1)) {
     aError.Throw(NS_ERROR_OUT_OF_MEMORY);
     return nullptr;
   }
@@ -340,33 +348,37 @@ DOMSVGPointList::InsertItemBefore(nsIDOM
     *_retval = nullptr;
     return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
   }
   ErrorResult rv;
   *_retval = InsertItemBefore(*domItem, aIndex, rv).get();
   return rv.ErrorCode();
 }
 
-already_AddRefed<DOMSVGPoint>
-DOMSVGPointList::ReplaceItem(DOMSVGPoint& aNewItem, uint32_t aIndex,
+already_AddRefed<nsISVGPoint>
+DOMSVGPointList::ReplaceItem(nsISVGPoint& aNewItem, uint32_t aIndex,
                              ErrorResult& aError)
 {
   if (IsAnimValList()) {
     aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
     return nullptr;
   }
 
   if (aIndex >= LengthNoFlush()) {
     aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
     return nullptr;
   }
 
-  nsRefPtr<DOMSVGPoint> domItem = &aNewItem;
-  if (aNewItem.HasOwner() || aNewItem.IsReadonly()) {
-    domItem = aNewItem.Clone(); // must do this before changing anything!
+  nsCOMPtr<DOMSVGPoint> domItem = do_QueryInterface(&aNewItem);
+  if (!domItem) {
+    aError.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+    return nullptr;
+  }
+  if (domItem->HasOwner() || domItem->IsReadonly()) {
+    domItem = domItem->Clone(); // must do this before changing anything!
   }
 
   nsAttrValue emptyOrOldValue = Element()->WillChangePointList();
   if (mItems[aIndex]) {
     // Notify any existing DOM item of removal *before* modifying the lists so
     // that the DOM item can copy the *old* value at its index:
     mItems[aIndex]->RemovingFromList();
   }
@@ -395,17 +407,17 @@ DOMSVGPointList::ReplaceItem(nsIDOMSVGPo
     *_retval = nullptr;
     return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
   }
   ErrorResult rv;
   *_retval = ReplaceItem(*domItem, aIndex, rv).get();
   return rv.ErrorCode();
 }
 
-already_AddRefed<DOMSVGPoint>
+already_AddRefed<nsISVGPoint>
 DOMSVGPointList::RemoveItem(uint32_t aIndex, ErrorResult& aError)
 {
   if (IsAnimValList()) {
     aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
     return nullptr;
   }
 
   if (aIndex >= LengthNoFlush()) {
--- a/content/svg/content/src/DOMSVGPointList.h
+++ b/content/svg/content/src/DOMSVGPointList.h
@@ -17,16 +17,17 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/ErrorResult.h"
 
 class nsIDOMSVGPoint;
 
 namespace mozilla {
 
 class DOMSVGPoint;
+class nsISVGPoint;
 class SVGAnimatedPointList;
 
 /**
  * Class DOMSVGPointList
  *
  * This class is used to create the DOM tearoff objects that wrap internal
  * SVGPointList objects.
  *
@@ -135,38 +136,38 @@ public:
   uint32_t NumberOfItems() const
   {
     if (IsAnimValList()) {
       Element()->FlushAnimations();
     }
     return LengthNoFlush();
   }
   void Clear(ErrorResult& aError);
-  already_AddRefed<DOMSVGPoint> Initialize(DOMSVGPoint& aNewItem,
+  already_AddRefed<nsISVGPoint> Initialize(nsISVGPoint& aNewItem,
                                            ErrorResult& aError);
-  DOMSVGPoint* GetItem(uint32_t aIndex, ErrorResult& aError)
+  nsISVGPoint* GetItem(uint32_t aIndex, ErrorResult& aError)
   {
     bool found;
-    DOMSVGPoint* item = IndexedGetter(aIndex, found, aError);
+    nsISVGPoint* item = IndexedGetter(aIndex, found, aError);
     if (!found) {
       aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
     }
     return item;
   }
-  DOMSVGPoint* IndexedGetter(uint32_t aIndex, bool& aFound,
+  nsISVGPoint* IndexedGetter(uint32_t aIndex, bool& aFound,
                              ErrorResult& aError);
-  already_AddRefed<DOMSVGPoint> InsertItemBefore(DOMSVGPoint& aNewItem,
+  already_AddRefed<nsISVGPoint> InsertItemBefore(nsISVGPoint& aNewItem,
                                                  uint32_t aIndex,
                                                  ErrorResult& aError);
-  already_AddRefed<DOMSVGPoint> ReplaceItem(DOMSVGPoint& aNewItem,
+  already_AddRefed<nsISVGPoint> ReplaceItem(nsISVGPoint& aNewItem,
                                             uint32_t aIndex,
                                             ErrorResult& aError);
-  already_AddRefed<DOMSVGPoint> RemoveItem(uint32_t aIndex,
+  already_AddRefed<nsISVGPoint> RemoveItem(uint32_t aIndex,
                                            ErrorResult& aError);
-  already_AddRefed<DOMSVGPoint> AppendItem(DOMSVGPoint& aNewItem,
+  already_AddRefed<nsISVGPoint> AppendItem(nsISVGPoint& aNewItem,
                                            ErrorResult& aError)
   {
     return InsertItemBefore(aNewItem, LengthNoFlush(), aError);
   }
   uint32_t Length() const
   {
     return NumberOfItems();
   }
new file mode 100644
--- /dev/null
+++ b/content/svg/content/src/nsISVGPoint.h
@@ -0,0 +1,63 @@
+/* -*- 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/. */
+
+#pragma once
+
+#include "nsAutoPtr.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsIDOMSVGPoint.h"
+#include "nsWrapperCache.h"
+#include "mozilla/dom/SVGPointBinding.h"
+
+class nsSVGElement;
+
+// {d6b6c440-af8d-40ee-856b-02a317cab275}
+#define MOZILLA_NSISVGPOINT_IID \
+  { 0xd6b6c440, 0xaf8d, 0x40ee, \
+    { 0x85, 0x6b, 0x02, 0xa3, 0x17, 0xca, 0xb2, 0x75 } }
+
+namespace mozilla {
+
+/**
+ * Class nsISVGPoint
+ *
+ * This class creates the DOM objects that wrap internal SVGPoint objects.
+ * An nsISVGPoint can be either a DOMSVGPoint or a nsSVGTranslatePoint::DOMVal.
+ */
+class nsISVGPoint : public nsIDOMSVGPoint,
+                    public nsWrapperCache
+{
+public:
+  NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_NSISVGPOINT_IID)
+
+  /**
+   * Generic ctor for DOMSVGPoint objects that are created for an attribute.
+   */
+  explicit nsISVGPoint()
+  {
+    SetIsDOMBinding();
+  }
+
+  using nsIDOMSVGPoint::SetX;
+  using nsIDOMSVGPoint::SetY;
+  using nsIDOMSVGPoint::MatrixTransform;
+
+  // WebIDL
+  virtual float X() = 0;
+  virtual void SetX(float aX, ErrorResult& rv) = 0;
+  virtual float Y() = 0;
+  virtual void SetY(float aY, ErrorResult& rv) = 0;
+  virtual already_AddRefed<nsISVGPoint> MatrixTransform(nsIDOMSVGMatrix* matrix) = 0;
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
+                               bool *triedToWrap)
+    { return dom::SVGPointBinding::Wrap(cx, scope, this, triedToWrap); }
+
+  virtual nsISupports* GetParentObject() = 0;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsISVGPoint, MOZILLA_NSISVGPOINT_IID)
+
+} // namespace mozilla
+
--- a/content/svg/content/src/nsSVGSVGElement.cpp
+++ b/content/svg/content/src/nsSVGSVGElement.cpp
@@ -36,74 +36,130 @@
 #include "nsSMILTimeContainer.h"
 #include "nsSMILAnimationController.h"
 #include "nsSMILTypes.h"
 #include "nsIContentIterator.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
-NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGTranslatePoint::DOMVal, mElement)
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsSVGTranslatePoint::DOMVal)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsSVGTranslatePoint::DOMVal)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsSVGTranslatePoint::DOMVal)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsSVGTranslatePoint::DOMVal)
+NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSVGTranslatePoint::DOMVal)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSVGTranslatePoint::DOMVal)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGTranslatePoint::DOMVal)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGPoint)
+  NS_INTERFACE_MAP_ENTRY(nsISVGPoint)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGPoint)
 NS_INTERFACE_MAP_END
 
 nsresult
 nsSVGTranslatePoint::ToDOMVal(nsSVGSVGElement *aElement,
                               nsIDOMSVGPoint **aResult)
 {
-  *aResult = new DOMVal(this, aElement);
-  if (!*aResult)
-    return NS_ERROR_OUT_OF_MEMORY;
-  
-  NS_ADDREF(*aResult);
+  NS_ADDREF(*aResult = new DOMVal(this, aElement));
+  return NS_OK;
+}
+
+nsISupports*
+nsSVGTranslatePoint::DOMVal::GetParentObject()
+{
+  return static_cast<nsIDOMSVGSVGElement*>(mElement);
+}
+
+NS_IMETHODIMP
+nsSVGTranslatePoint::DOMVal::GetX(float* aX)
+{
+  *aX = X();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSVGTranslatePoint::DOMVal::SetX(float aValue)
+nsSVGTranslatePoint::DOMVal::GetY(float* aY)
 {
-  NS_ENSURE_FINITE(aValue, NS_ERROR_ILLEGAL_VALUE);
-  return mElement->SetCurrentTranslate(aValue, mVal->GetY());
+  *aY = Y();
+  return NS_OK;
+}
+
+void
+nsSVGTranslatePoint::DOMVal::SetX(float aValue, ErrorResult& rv)
+{
+  rv = mElement->SetCurrentTranslate(aValue, mVal->GetY());
 }
 
 NS_IMETHODIMP
-nsSVGTranslatePoint::DOMVal::SetY(float aValue)
+nsSVGTranslatePoint::DOMVal::SetX(float aX)
 {
-  NS_ENSURE_FINITE(aValue, NS_ERROR_ILLEGAL_VALUE);
-  return mElement->SetCurrentTranslate(mVal->GetX(), aValue);
+  if (!NS_finite(aX)) {
+    return NS_ERROR_ILLEGAL_VALUE;
+  }
+
+  ErrorResult rv;
+  SetX(aX, rv);
+  return rv.ErrorCode();
 }
 
-/* nsIDOMSVGPoint matrixTransform (in nsIDOMSVGMatrix matrix); */
+void
+nsSVGTranslatePoint::DOMVal::SetY(float aValue, ErrorResult& rv)
+{
+  rv = mElement->SetCurrentTranslate(mVal->GetX(), aValue);
+}
+
+NS_IMETHODIMP
+nsSVGTranslatePoint::DOMVal::SetY(float aY)
+{
+  if (!NS_finite(aY)) {
+    return NS_ERROR_ILLEGAL_VALUE;
+  }
+
+  ErrorResult rv;
+  SetY(aY, rv);
+  return rv.ErrorCode();
+}
+
 NS_IMETHODIMP
 nsSVGTranslatePoint::DOMVal::MatrixTransform(nsIDOMSVGMatrix *matrix,
                                              nsIDOMSVGPoint **_retval)
 {
-  if (!matrix)
-    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+  *_retval = MatrixTransform(matrix).get();
+  return NS_OK;
+}
 
+/* nsIDOMSVGPoint matrixTransform (in nsIDOMSVGMatrix matrix); */
+already_AddRefed<nsISVGPoint>
+nsSVGTranslatePoint::DOMVal::MatrixTransform(nsIDOMSVGMatrix *matrix)
+{
   float a, b, c, d, e, f;
   matrix->GetA(&a);
   matrix->GetB(&b);
   matrix->GetC(&c);
   matrix->GetD(&d);
   matrix->GetE(&e);
   matrix->GetF(&f);
 
   float x = mVal->GetX();
   float y = mVal->GetY();
 
-  NS_ADDREF(*_retval = new DOMSVGPoint(a*x + c*y + e, b*x + d*y + f));
-  return NS_OK;
+  nsCOMPtr<nsISVGPoint> point = new DOMSVGPoint(a*x + c*y + e, b*x + d*y + f);
+  return point.forget();
 }
 
 nsSVGElement::LengthInfo nsSVGSVGElement::sLengthInfo[4] =
 {
   { &nsGkAtoms::x, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::X },
   { &nsGkAtoms::y, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::Y },
   { &nsGkAtoms::width, 100, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::X },
   { &nsGkAtoms::height, 100, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::Y },
--- a/content/svg/content/src/nsSVGSVGElement.h
+++ b/content/svg/content/src/nsSVGSVGElement.h
@@ -5,17 +5,17 @@
 
 #ifndef __NS_SVGSVGELEMENT_H__
 #define __NS_SVGSVGELEMENT_H__
 
 #include "DOMSVGTests.h"
 #include "mozilla/dom/FromParser.h"
 #include "nsIDOMSVGFitToViewBox.h"
 #include "nsIDOMSVGLocatable.h"
-#include "nsIDOMSVGPoint.h"
+#include "nsISVGPoint.h"
 #include "nsIDOMSVGSVGElement.h"
 #include "nsIDOMSVGZoomAndPan.h"
 #include "nsSVGEnum.h"
 #include "nsSVGLength2.h"
 #include "nsSVGStylableElement.h"
 #include "nsSVGViewBox.h"
 #include "SVGAnimatedPreserveAspectRatio.h"
 #include "mozilla/Attributes.h"
@@ -55,33 +55,32 @@ public:
   nsresult ToDOMVal(nsSVGSVGElement *aElement, nsIDOMSVGPoint **aResult);
 
   bool operator!=(const nsSVGTranslatePoint &rhs) const {
     return mX != rhs.mX || mY != rhs.mY;
   }
 
 private:
 
-  struct DOMVal MOZ_FINAL : public nsIDOMSVGPoint {
+  struct DOMVal MOZ_FINAL : public mozilla::nsISVGPoint {
+    DOMVal(nsSVGTranslatePoint* aVal, nsSVGSVGElement *aElement)
+      : mozilla::nsISVGPoint(), mVal(aVal), mElement(aElement) {}
+
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-    NS_DECL_CYCLE_COLLECTION_CLASS(DOMVal)
-
-    DOMVal(nsSVGTranslatePoint* aVal, nsSVGSVGElement *aElement)
-      : mVal(aVal), mElement(aElement) {}
+    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMVal)
+    NS_DECL_NSIDOMSVGPOINT
 
-    NS_IMETHOD GetX(float *aValue)
-      { *aValue = mVal->GetX(); return NS_OK; }
-    NS_IMETHOD GetY(float *aValue)
-      { *aValue = mVal->GetY(); return NS_OK; }
+    // WebIDL
+    virtual float X() { return mVal->GetX(); }
+    virtual float Y() { return mVal->GetY(); }
+    virtual void SetX(float aValue, mozilla::ErrorResult& rv);
+    virtual void SetY(float aValue, mozilla::ErrorResult& rv);
+    virtual already_AddRefed<mozilla::nsISVGPoint> MatrixTransform(nsIDOMSVGMatrix* matrix);
 
-    NS_IMETHOD SetX(float aValue);
-    NS_IMETHOD SetY(float aValue);
-
-    NS_IMETHOD MatrixTransform(nsIDOMSVGMatrix *matrix,
-                               nsIDOMSVGPoint **_retval);
+    virtual nsISupports* GetParentObject() MOZ_OVERRIDE;
 
     nsSVGTranslatePoint *mVal; // kept alive because it belongs to mElement
     nsRefPtr<nsSVGSVGElement> mElement;
   };
 
   float mX;
   float mY;
 };
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -455,18 +455,18 @@ DOMInterfaces = {
 
 'SVGPathSegList': {
     'nativeType': 'mozilla::DOMSVGPathSegList',
     'headerFile': 'DOMSVGPathSegList.h',
     'resultNotAddRefed': [ 'getItem' ]
 },
 
 'SVGPoint': {
-    'nativeType': 'mozilla::DOMSVGPoint',
-    'headerFile': 'DOMSVGPoint.h'
+    'nativeType': 'mozilla::nsISVGPoint',
+    'headerFile': 'nsISVGPoint.h'
 },
 
 'SVGPointList': {
     'nativeType': 'mozilla::DOMSVGPointList',
     'headerFile': 'DOMSVGPointList.h',
     'resultNotAddRefed': [ 'getItem' ]
 },