Bug 816778 Part 2: Convert SVGMatrix to WebIDL r=bz
authorDavid Zbarsky <dzbarsky@gmail.com>
Sat, 22 Dec 2012 23:54:20 -0500 (2012-12-23)
changeset 116915 9b19cd969afcaab7b9e4fde83480e37db7c20f83
parent 116914 347128caddd541d65a16c830dc0310212668df93
child 116916 0ca634658b96fd7da279869443029e9144f22f16
push id24076
push userryanvm@gmail.com
push dateSun, 23 Dec 2012 20:50:19 +0000 (2012-12-23)
treeherdermozilla-central@4f74d77d6d8b [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 2: Convert SVGMatrix to WebIDL r=bz
content/svg/content/src/DOMSVGMatrix.cpp
content/svg/content/src/DOMSVGMatrix.h
content/svg/content/src/DOMSVGPoint.cpp
content/svg/content/src/DOMSVGPoint.h
content/svg/content/src/DOMSVGTransformList.cpp
content/svg/content/src/DOMSVGTransformList.h
content/svg/content/src/nsISVGPoint.h
content/svg/content/src/nsSVGSVGElement.cpp
content/svg/content/src/nsSVGSVGElement.h
dom/bindings/Bindings.conf
dom/webidl/SVGMatrix.webidl
dom/webidl/SVGPoint.webidl
dom/webidl/SVGTransformList.webidl
dom/webidl/WebIDL.mk
--- a/content/svg/content/src/DOMSVGMatrix.cpp
+++ b/content/svg/content/src/DOMSVGMatrix.cpp
@@ -3,297 +3,472 @@
  * 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 "DOMSVGMatrix.h"
 #include "nsError.h"
 #include <math.h>
 #include "nsContentUtils.h"
+#include "mozilla/dom/SVGMatrixBinding.h"
 
 const double radPerDegree = 2.0 * M_PI / 360.0;
 
 namespace mozilla {
 
 //----------------------------------------------------------------------
 // nsISupports methods:
 
 // Make sure we clear the weak ref in the owning transform (if there is one)
 // upon unlink.
 NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGMatrix)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGMatrix)
   if (tmp->mTransform) {
     tmp->mTransform->ClearMatrixTearoff(tmp);
   }
 NS_IMPL_CYCLE_COLLECTION_UNLINK(mTransform)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGMatrix)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTransform)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGMatrix)
+NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
 NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGMatrix)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGMatrix)
 
 } // namespace mozilla
 DOMCI_DATA(SVGMatrix, mozilla::DOMSVGMatrix)
 namespace mozilla {
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGMatrix)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(mozilla::DOMSVGMatrix) // pseudo-interface
   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGMatrix)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGMatrix)
 NS_INTERFACE_MAP_END
 
+DOMSVGTransform*
+DOMSVGMatrix::GetParentObject() const
+{
+  return mTransform;
+}
+
+JSObject*
+DOMSVGMatrix::WrapObject(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap)
+{
+  return mozilla::dom::SVGMatrixBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
+
 //----------------------------------------------------------------------
 // nsIDOMSVGMatrix methods:
 
 /* attribute float a; */
 NS_IMETHODIMP DOMSVGMatrix::GetA(float *aA)
 {
-  *aA = static_cast<float>(Matrix().xx);
+  *aA = A();
   return NS_OK;
 }
-NS_IMETHODIMP DOMSVGMatrix::SetA(float aA)
+
+void
+DOMSVGMatrix::SetA(float aA, ErrorResult& rv)
 {
   if (IsAnimVal()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return;
   }
-  NS_ENSURE_FINITE(aA, NS_ERROR_ILLEGAL_VALUE);
 
   gfxMatrix mx = Matrix();
   mx.xx = aA;
   SetMatrix(mx);
-  return NS_OK;
+}
+
+NS_IMETHODIMP DOMSVGMatrix::SetA(float aA)
+{
+  NS_ENSURE_FINITE(aA, NS_ERROR_ILLEGAL_VALUE);
+  ErrorResult rv;
+  SetA(aA, rv);
+  return rv.ErrorCode();
 }
 
 /* attribute float b; */
 NS_IMETHODIMP DOMSVGMatrix::GetB(float *aB)
 {
-  *aB = static_cast<float>(Matrix().yx);
+  *aB = B();
   return NS_OK;
 }
-NS_IMETHODIMP DOMSVGMatrix::SetB(float aB)
+
+void
+DOMSVGMatrix::SetB(float aB, ErrorResult& rv)
 {
   if (IsAnimVal()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return;
   }
-  NS_ENSURE_FINITE(aB, NS_ERROR_ILLEGAL_VALUE);
 
   gfxMatrix mx = Matrix();
   mx.yx = aB;
   SetMatrix(mx);
-  return NS_OK;
+}
+
+NS_IMETHODIMP DOMSVGMatrix::SetB(float aB)
+{
+  NS_ENSURE_FINITE(aB, NS_ERROR_ILLEGAL_VALUE);
+  ErrorResult rv;
+  SetB(aB, rv);
+  return rv.ErrorCode();
 }
 
 /* attribute float c; */
 NS_IMETHODIMP DOMSVGMatrix::GetC(float *aC)
 {
-  *aC = static_cast<float>(Matrix().xy);
+  *aC = C();
   return NS_OK;
 }
-NS_IMETHODIMP DOMSVGMatrix::SetC(float aC)
+
+void
+DOMSVGMatrix::SetC(float aC, ErrorResult& rv)
 {
   if (IsAnimVal()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return;
   }
-  NS_ENSURE_FINITE(aC, NS_ERROR_ILLEGAL_VALUE);
 
   gfxMatrix mx = Matrix();
   mx.xy = aC;
   SetMatrix(mx);
-  return NS_OK;
+}
+
+NS_IMETHODIMP DOMSVGMatrix::SetC(float aC)
+{
+  NS_ENSURE_FINITE(aC, NS_ERROR_ILLEGAL_VALUE);
+  ErrorResult rv;
+  SetC(aC, rv);
+  return rv.ErrorCode();
 }
 
 /* attribute float d; */
 NS_IMETHODIMP DOMSVGMatrix::GetD(float *aD)
 {
-  *aD = static_cast<float>(Matrix().yy);
+  *aD = D();
   return NS_OK;
 }
-NS_IMETHODIMP DOMSVGMatrix::SetD(float aD)
+
+void
+DOMSVGMatrix::SetD(float aD, ErrorResult& rv)
 {
   if (IsAnimVal()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return;
   }
-  NS_ENSURE_FINITE(aD, NS_ERROR_ILLEGAL_VALUE);
 
   gfxMatrix mx = Matrix();
   mx.yy = aD;
   SetMatrix(mx);
-  return NS_OK;
+}
+
+NS_IMETHODIMP DOMSVGMatrix::SetD(float aD)
+{
+  NS_ENSURE_FINITE(aD, NS_ERROR_ILLEGAL_VALUE);
+  ErrorResult rv;
+  SetD(aD, rv);
+  return rv.ErrorCode();
 }
 
 /* attribute float e; */
 NS_IMETHODIMP DOMSVGMatrix::GetE(float *aE)
 {
-  *aE = static_cast<float>(Matrix().x0);
+  *aE = E();
   return NS_OK;
 }
-NS_IMETHODIMP DOMSVGMatrix::SetE(float aE)
+
+void
+DOMSVGMatrix::SetE(float aE, ErrorResult& rv)
 {
   if (IsAnimVal()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return;
   }
-  NS_ENSURE_FINITE(aE, NS_ERROR_ILLEGAL_VALUE);
 
   gfxMatrix mx = Matrix();
   mx.x0 = aE;
   SetMatrix(mx);
-  return NS_OK;
+}
+
+NS_IMETHODIMP DOMSVGMatrix::SetE(float aE)
+{
+  NS_ENSURE_FINITE(aE, NS_ERROR_ILLEGAL_VALUE);
+  ErrorResult rv;
+  SetE(aE, rv);
+  return rv.ErrorCode();
 }
 
 /* attribute float f; */
 NS_IMETHODIMP DOMSVGMatrix::GetF(float *aF)
 {
-  *aF = static_cast<float>(Matrix().y0);
+  *aF = F();
   return NS_OK;
 }
-NS_IMETHODIMP DOMSVGMatrix::SetF(float aF)
+
+void
+DOMSVGMatrix::SetF(float aF, ErrorResult& rv)
 {
   if (IsAnimVal()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return;
   }
-  NS_ENSURE_FINITE(aF, NS_ERROR_ILLEGAL_VALUE);
 
   gfxMatrix mx = Matrix();
   mx.y0 = aF;
   SetMatrix(mx);
-  return NS_OK;
+}
+
+NS_IMETHODIMP DOMSVGMatrix::SetF(float aF)
+{
+  NS_ENSURE_FINITE(aF, NS_ERROR_ILLEGAL_VALUE);
+  ErrorResult rv;
+  SetF(aF, rv);
+  return rv.ErrorCode();
+}
+
+already_AddRefed<DOMSVGMatrix>
+DOMSVGMatrix::Multiply(DOMSVGMatrix& aMatrix)
+{
+  nsCOMPtr<DOMSVGMatrix> matrix = new DOMSVGMatrix(aMatrix.Matrix() * Matrix());
+  return matrix.forget();
 }
 
 /* nsIDOMSVGMatrix multiply (in nsIDOMSVGMatrix secondMatrix); */
 NS_IMETHODIMP DOMSVGMatrix::Multiply(nsIDOMSVGMatrix *secondMatrix,
                                      nsIDOMSVGMatrix **_retval)
 {
   *_retval = nullptr;
   nsCOMPtr<DOMSVGMatrix> domMatrix = do_QueryInterface(secondMatrix);
   if (!domMatrix)
     return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
 
-  NS_ADDREF(*_retval = new DOMSVGMatrix(domMatrix->Matrix() * Matrix()));
+  *_retval = Multiply(*domMatrix).get();
   return NS_OK;
 }
 
+already_AddRefed<DOMSVGMatrix>
+DOMSVGMatrix::Inverse(ErrorResult& rv)
+{
+  if (Matrix().IsSingular()) {
+    rv.Throw(NS_ERROR_DOM_SVG_MATRIX_NOT_INVERTABLE);
+    return nullptr;
+  }
+  nsRefPtr<DOMSVGMatrix> matrix = new DOMSVGMatrix(gfxMatrix(Matrix()).Invert());
+  return matrix.forget();
+}
+
 /* nsIDOMSVGMatrix inverse (); */
 NS_IMETHODIMP DOMSVGMatrix::Inverse(nsIDOMSVGMatrix **_retval)
 {
-  *_retval = nullptr;
-  if (Matrix().IsSingular())
-    return NS_ERROR_DOM_SVG_MATRIX_NOT_INVERTABLE;
+  ErrorResult rv;
+  *_retval = Inverse(rv).get();
+  return rv.ErrorCode();
+}
 
-  NS_ADDREF(*_retval = new DOMSVGMatrix(gfxMatrix(Matrix()).Invert()));
-  return NS_OK;
+already_AddRefed<DOMSVGMatrix>
+DOMSVGMatrix::Translate(float x, float y)
+{
+  nsRefPtr<DOMSVGMatrix> matrix =
+    new DOMSVGMatrix(gfxMatrix(Matrix()).Translate(gfxPoint(x, y)));
+  return matrix.forget();
 }
 
+
 /* nsIDOMSVGMatrix translate (in float x, in float y); */
 NS_IMETHODIMP DOMSVGMatrix::Translate(float x, float y,
                                       nsIDOMSVGMatrix **_retval)
 {
-  *_retval = nullptr;
-  NS_ENSURE_FINITE2(x, y, NS_ERROR_ILLEGAL_VALUE);
-
-  NS_ADDREF(*_retval =
-    new DOMSVGMatrix(gfxMatrix(Matrix()).Translate(gfxPoint(x, y))));
+  if (!NS_finite(x) || !NS_finite(y)) {
+    *_retval = nullptr;
+    return NS_ERROR_ILLEGAL_VALUE;
+  }
+  *_retval = Translate(x, y).get();
   return NS_OK;
 }
 
-/* nsIDOMSVGMatrix scale (in float scaleFactor); */
+already_AddRefed<DOMSVGMatrix>
+DOMSVGMatrix::Scale(float scaleFactor)
+{
+  return ScaleNonUniform(scaleFactor, scaleFactor);
+}
+
+ /* nsIDOMSVGMatrix scale (in float scaleFactor); */
 NS_IMETHODIMP DOMSVGMatrix::Scale(float scaleFactor, nsIDOMSVGMatrix **_retval)
 {
   return ScaleNonUniform(scaleFactor, scaleFactor, _retval);
 }
 
-/* nsIDOMSVGMatrix scaleNonUniform (in float scaleFactorX,
+already_AddRefed<DOMSVGMatrix>
+DOMSVGMatrix::ScaleNonUniform(float scaleFactorX,
+                              float scaleFactorY)
+{
+  nsRefPtr<DOMSVGMatrix> matrix =
+    new DOMSVGMatrix(gfxMatrix(Matrix()).Scale(scaleFactorX, scaleFactorY));
+  return matrix.forget();
+}
+
+
+ /* nsIDOMSVGMatrix scaleNonUniform (in float scaleFactorX,
  *                                  in float scaleFactorY); */
 NS_IMETHODIMP DOMSVGMatrix::ScaleNonUniform(float scaleFactorX,
                                             float scaleFactorY,
                                             nsIDOMSVGMatrix **_retval)
 {
-  *_retval = nullptr;
-  NS_ENSURE_FINITE2(scaleFactorX, scaleFactorY, NS_ERROR_ILLEGAL_VALUE);
+  if (!NS_finite(scaleFactorX) || !NS_finite(scaleFactorY)) {
+    *_retval = nullptr;
+    return NS_ERROR_ILLEGAL_VALUE;
+  }
+  *_retval = ScaleNonUniform(scaleFactorX, scaleFactorY).get();
+  return NS_OK;
+}
 
-  NS_ADDREF(*_retval =
-    new DOMSVGMatrix(gfxMatrix(Matrix()).Scale(scaleFactorX, scaleFactorY)));
-  return NS_OK;
+already_AddRefed<DOMSVGMatrix>
+DOMSVGMatrix::Rotate(float angle)
+{
+  nsRefPtr<DOMSVGMatrix> matrix =
+    new DOMSVGMatrix(gfxMatrix(Matrix()).Rotate(angle*radPerDegree));
+  return matrix.forget();
 }
 
 /* nsIDOMSVGMatrix rotate (in float angle); */
 NS_IMETHODIMP DOMSVGMatrix::Rotate(float angle, nsIDOMSVGMatrix **_retval)
 {
-  *_retval = nullptr;
-  NS_ENSURE_FINITE(angle, NS_ERROR_ILLEGAL_VALUE);
+  if (!NS_finite(angle)) {
+    *_retval = nullptr;
+    return NS_ERROR_ILLEGAL_VALUE;
+  }
+  *_retval = Rotate(angle).get();
+  return NS_OK;
+}
 
-  NS_ADDREF(*_retval =
-    new DOMSVGMatrix(gfxMatrix(Matrix()).Rotate(angle*radPerDegree)));
-  return NS_OK;
+already_AddRefed<DOMSVGMatrix>
+DOMSVGMatrix::RotateFromVector(float x, float y, ErrorResult& rv)
+{
+  if (x == 0.0 || y == 0.0) {
+    rv.Throw(NS_ERROR_RANGE_ERR);
+    return nullptr;
+  }
+
+  nsRefPtr<DOMSVGMatrix> matrix =
+    new DOMSVGMatrix(gfxMatrix(Matrix()).Rotate(atan2(y, x)));
+  return matrix.forget();
 }
 
 /* nsIDOMSVGMatrix rotateFromVector (in float x, in float y); */
 NS_IMETHODIMP DOMSVGMatrix::RotateFromVector(float x, float y,
                                              nsIDOMSVGMatrix **_retval)
 {
-  *_retval = nullptr;
-  NS_ENSURE_FINITE2(x, y, NS_ERROR_ILLEGAL_VALUE);
+  if (!NS_finite(x) || !NS_finite(y)) {
+    *_retval = nullptr;
+    return NS_ERROR_ILLEGAL_VALUE;
+  }
 
-  if (x == 0.0 || y == 0.0)
-    return NS_ERROR_RANGE_ERR;
+  ErrorResult rv;
+  *_retval = RotateFromVector(x, y, rv).get();
+  return rv.ErrorCode();
+}
 
-  NS_ADDREF(*_retval =
-    new DOMSVGMatrix(gfxMatrix(Matrix()).Rotate(atan2(y, x))));
-  return NS_OK;
+already_AddRefed<DOMSVGMatrix>
+DOMSVGMatrix::FlipX()
+{
+  const gfxMatrix& mx = Matrix();
+  nsRefPtr<DOMSVGMatrix> matrix =
+    new DOMSVGMatrix(gfxMatrix(-mx.xx, -mx.yx, mx.xy, mx.yy, mx.x0, mx.y0));
+  return matrix.forget();
 }
 
 /* nsIDOMSVGMatrix flipX (); */
 NS_IMETHODIMP DOMSVGMatrix::FlipX(nsIDOMSVGMatrix **_retval)
 {
+  *_retval = FlipX().get();
+  return NS_OK;
+}
+
+already_AddRefed<DOMSVGMatrix>
+DOMSVGMatrix::FlipY()
+{
   const gfxMatrix& mx = Matrix();
-  NS_ADDREF(*_retval = new DOMSVGMatrix(gfxMatrix(-mx.xx, -mx.yx,
-                                                  mx.xy, mx.yy,
-                                                  mx.x0, mx.y0)));
-  return NS_OK;
+  nsRefPtr<DOMSVGMatrix> matrix =
+    new DOMSVGMatrix(gfxMatrix(mx.xx, mx.yx, -mx.xy, -mx.yy, mx.x0, mx.y0));
+  return matrix.forget();
 }
 
 /* nsIDOMSVGMatrix flipY (); */
 NS_IMETHODIMP DOMSVGMatrix::FlipY(nsIDOMSVGMatrix **_retval)
 {
-  const gfxMatrix& mx = Matrix();
-  NS_ADDREF(*_retval = new DOMSVGMatrix(gfxMatrix(mx.xx, mx.yx,
-                                                  -mx.xy, -mx.yy,
-                                                  mx.x0, mx.y0)));
+  *_retval = FlipY().get();
   return NS_OK;
 }
 
-/* nsIDOMSVGMatrix skewX (in float angle); */
-NS_IMETHODIMP DOMSVGMatrix::SkewX(float angle, nsIDOMSVGMatrix **_retval)
+already_AddRefed<DOMSVGMatrix>
+DOMSVGMatrix::SkewX(float angle, ErrorResult& rv)
 {
-  *_retval = nullptr;
-  NS_ENSURE_FINITE(angle, NS_ERROR_ILLEGAL_VALUE);
-
   double ta = tan( angle*radPerDegree );
-  NS_ENSURE_FINITE(ta, NS_ERROR_RANGE_ERR);
+  if (!NS_finite(ta)) {
+    rv.Throw(NS_ERROR_RANGE_ERR);
+    return nullptr;
+  }
 
   const gfxMatrix& mx = Matrix();
   gfxMatrix skewMx(mx.xx, mx.yx,
                    (float) (mx.xy + mx.xx*ta), (float) (mx.yy + mx.yx*ta),
                    mx.x0, mx.y0);
-  NS_ADDREF(*_retval = new DOMSVGMatrix(skewMx));
-  return NS_OK;
+  nsRefPtr<DOMSVGMatrix> matrix = new DOMSVGMatrix(skewMx);
+  return matrix.forget();
+}
+
+/* nsIDOMSVGMatrix skewX (in float angle); */
+NS_IMETHODIMP DOMSVGMatrix::SkewX(float angle, nsIDOMSVGMatrix **_retval)
+{
+  if (!NS_finite(angle)) {
+    *_retval = nullptr;
+    return NS_ERROR_ILLEGAL_VALUE;
+  }
+
+  ErrorResult rv;
+  *_retval = SkewX(angle, rv).get();
+  return rv.ErrorCode();
+}
+
+already_AddRefed<DOMSVGMatrix>
+DOMSVGMatrix::SkewY(float angle, ErrorResult& rv)
+{
+  double ta = tan( angle*radPerDegree );
+  if (!NS_finite(ta)) {
+    rv.Throw(NS_ERROR_RANGE_ERR);
+    return nullptr;
+  }
+
+  const gfxMatrix& mx = Matrix();
+  gfxMatrix skewMx((float) (mx.xx + mx.xy*ta), (float) (mx.yx + mx.yy*ta),
+                   mx.xy, mx.yy,
+                   mx.x0, mx.y0);
+
+  nsRefPtr<DOMSVGMatrix> matrix = new DOMSVGMatrix(skewMx);
+  return matrix.forget();
 }
 
 /* nsIDOMSVGMatrix skewY (in float angle); */
 NS_IMETHODIMP DOMSVGMatrix::SkewY(float angle, nsIDOMSVGMatrix **_retval)
 {
-  *_retval = nullptr;
-  NS_ENSURE_FINITE(angle, NS_ERROR_ILLEGAL_VALUE);
-
-  double ta = tan( angle*radPerDegree );
-  NS_ENSURE_FINITE(ta, NS_ERROR_RANGE_ERR);
+  if (!NS_finite(angle)) {
+    *_retval = nullptr;
+    return NS_ERROR_ILLEGAL_VALUE;
+  }
 
-  const gfxMatrix& mx = Matrix();
-  gfxMatrix skewMx((float) (mx.xx + mx.xy*ta), (float) (mx.yx + mx.yy*ta),
-                   mx.xy, mx.yy,
-                   mx.x0, mx.y0);
-  NS_ADDREF(*_retval = new DOMSVGMatrix(skewMx));
-  return NS_OK;
+  ErrorResult rv;
+  *_retval = SkewY(angle, rv).get();
+  return rv.ErrorCode();
 }
 
+
 } // namespace mozilla
--- a/content/svg/content/src/DOMSVGMatrix.h
+++ b/content/svg/content/src/DOMSVGMatrix.h
@@ -37,60 +37,102 @@
 #ifndef MOZILLA_DOMSVGMATRIX_H__
 #define MOZILLA_DOMSVGMATRIX_H__
 
 #include "DOMSVGTransform.h"
 #include "gfxMatrix.h"
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIDOMSVGMatrix.h"
+#include "nsWrapperCache.h"
 #include "mozilla/Attributes.h"
 
 // We make DOMSVGMatrix a pseudo-interface to allow us to QI to it in order
 // to check that the objects that scripts pass in are our *native* matrix
 // objects.
 //
 // {633419E5-7E88-4C3E-8A9A-856F635E90A3}
 #define MOZILLA_DOMSVGMATRIX_IID \
   { 0x633419E5, 0x7E88, 0x4C3E, \
     { 0x8A, 0x9A, 0x85, 0x6F, 0x63, 0x5E, 0x90, 0xA3 } }
 
 namespace mozilla {
 
 /**
  * DOM wrapper for an SVG matrix.
  */
-class DOMSVGMatrix MOZ_FINAL : public nsIDOMSVGMatrix
+class DOMSVGMatrix MOZ_FINAL : public nsIDOMSVGMatrix,
+                               public nsWrapperCache
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOMSVGMATRIX_IID)
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS(DOMSVGMatrix)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGMatrix)
   NS_DECL_NSIDOMSVGMATRIX
 
   /**
    * Ctor for DOMSVGMatrix objects that belong to a DOMSVGTransform.
    */
-  DOMSVGMatrix(DOMSVGTransform& aTransform) : mTransform(&aTransform) { }
+  DOMSVGMatrix(DOMSVGTransform& aTransform) : mTransform(&aTransform) {
+    SetIsDOMBinding();
+  }
 
   /**
    * Ctors for DOMSVGMatrix objects created independently of a DOMSVGTransform.
    */
-  DOMSVGMatrix() { } // Default ctor for gfxMatrix will produce identity mx
-  DOMSVGMatrix(const gfxMatrix &aMatrix) : mMatrix(aMatrix) { }
+  // Default ctor for gfxMatrix will produce identity mx
+  DOMSVGMatrix() {
+    SetIsDOMBinding();
+  }
+
+  DOMSVGMatrix(const gfxMatrix &aMatrix) : mMatrix(aMatrix) {
+    SetIsDOMBinding();
+  }
+
   ~DOMSVGMatrix() {
     if (mTransform) {
       mTransform->ClearMatrixTearoff(this);
     }
   }
 
   const gfxMatrix& Matrix() const {
     return mTransform ? mTransform->Matrix() : mMatrix;
   }
 
+  // WebIDL
+  DOMSVGTransform* GetParentObject() const;
+  virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap);
+
+  float A() const { return static_cast<float>(Matrix().xx); }
+  void SetA(float aA, ErrorResult& rv);
+  float B() const { return static_cast<float>(Matrix().yx); }
+  void SetB(float aB, ErrorResult& rv);
+  float C() const { return static_cast<float>(Matrix().xy); }
+  void SetC(float aC, ErrorResult& rv);
+  float D() const { return static_cast<float>(Matrix().yy); }
+  void SetD(float aD, ErrorResult& rv);
+  float E() const { return static_cast<float>(Matrix().x0); }
+  void SetE(float aE, ErrorResult& rv);
+  float F() const { return static_cast<float>(Matrix().y0); }
+  void SetF(float aF, ErrorResult& rv);
+  already_AddRefed<DOMSVGMatrix> Multiply(DOMSVGMatrix& aMatrix);
+  already_AddRefed<DOMSVGMatrix> Inverse(ErrorResult& aRv);
+  already_AddRefed<DOMSVGMatrix> Translate(float x, float y);
+  already_AddRefed<DOMSVGMatrix> Scale(float scaleFactor);
+  already_AddRefed<DOMSVGMatrix> ScaleNonUniform(float scaleFactorX,
+                                                 float scaleFactorY);
+  already_AddRefed<DOMSVGMatrix> Rotate(float angle);
+  already_AddRefed<DOMSVGMatrix> RotateFromVector(float x,
+                                                  float y,
+                                                  ErrorResult& aRv);
+  already_AddRefed<DOMSVGMatrix> FlipX();
+  already_AddRefed<DOMSVGMatrix> FlipY();
+  already_AddRefed<DOMSVGMatrix> SkewX(float angle, ErrorResult& rv);
+  already_AddRefed<DOMSVGMatrix> SkewY(float angle, ErrorResult& rv);
+
 private:
   void SetMatrix(const gfxMatrix& aMatrix) {
     if (mTransform) {
       mTransform->SetMatrix(aMatrix);
     } else {
       mMatrix = aMatrix;
     }
   }
--- a/content/svg/content/src/DOMSVGPoint.cpp
+++ b/content/svg/content/src/DOMSVGPoint.cpp
@@ -157,29 +157,32 @@ DOMSVGPoint::SetY(float aY, ErrorResult&
   }
   mPt.mY = aY;
 }
 
 NS_IMETHODIMP
 DOMSVGPoint::MatrixTransform(nsIDOMSVGMatrix *matrix,
                              nsIDOMSVGPoint **_retval)
 {
-  *_retval = MatrixTransform(matrix).get();
+  nsCOMPtr<DOMSVGMatrix> domMatrix = do_QueryInterface(matrix);
+  if (!domMatrix) {
+    *_retval = nullptr;
+    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+  }
+  *_retval = MatrixTransform(*domMatrix).get();
   return NS_OK;
 }
 
 already_AddRefed<nsISVGPoint>
-DOMSVGPoint::MatrixTransform(nsIDOMSVGMatrix* matrix)
+DOMSVGPoint::MatrixTransform(DOMSVGMatrix& 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));
+  gfxPoint pt = matrix.Matrix().Transform(gfxPoint(x, y));
   nsCOMPtr<nsISVGPoint> newPoint = new DOMSVGPoint(pt);
   return newPoint.forget();
 }
 
 void
 DOMSVGPoint::InsertingIntoList(DOMSVGPointList *aList,
                                uint32_t aListIndex,
                                bool aIsAnimValItem)
--- a/content/svg/content/src/DOMSVGPoint.h
+++ b/content/svg/content/src/DOMSVGPoint.h
@@ -27,16 +27,18 @@ class nsSVGElement;
 #define MOZILLA_DOMSVGPOINT_IID \
   { 0xd6b6c440, 0xaf8d, 0x40ee, \
     { 0x85, 0x6b, 0x02, 0xa3, 0x17, 0xca, 0xb2, 0x75 } }
 
 #define MOZ_SVG_LIST_INDEX_BIT_COUNT 30
 
 namespace mozilla {
 
+class DOMSVGMatrix;
+
 /**
  * Class DOMSVGPoint
  *
  * This class creates the DOM objects that wrap internal SVGPoint objects that
  * are in an SVGPointList. It is also used to create the objects returned by
  * SVGSVGElement.createSVGPoint() and other functions that return DOM SVGPoint
  * objects.
  *
@@ -119,17 +121,17 @@ public:
     }
   }
 
   // WebIDL
   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);
+  virtual already_AddRefed<nsISVGPoint> MatrixTransform(DOMSVGMatrix& matrix);
   nsISupports* GetParentObject() MOZ_OVERRIDE {
     return mList;
   }
 
   /**
    * Create an unowned copy of this object. The caller is responsible for the
    * first AddRef()!
    */
--- a/content/svg/content/src/DOMSVGTransformList.cpp
+++ b/content/svg/content/src/DOMSVGTransformList.cpp
@@ -417,38 +417,35 @@ DOMSVGTransformList::AppendItem(nsIDOMSV
                                 nsIDOMSVGTransform **_retval)
 {
   ErrorResult rv;
   *_retval = AppendItem(newItem, rv).get();
   return rv.ErrorCode();
 }
 
 already_AddRefed<nsIDOMSVGTransform>
-DOMSVGTransformList::CreateSVGTransformFromMatrix(nsIDOMSVGMatrix *matrix,
-                                                  ErrorResult& error)
+DOMSVGTransformList::CreateSVGTransformFromMatrix(DOMSVGMatrix& matrix)
 {
-  nsCOMPtr<DOMSVGMatrix> domItem = do_QueryInterface(matrix);
-  if (!domItem) {
-    error.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
-    return nullptr;
-  }
-
-  nsCOMPtr<nsIDOMSVGTransform> result = new DOMSVGTransform(domItem->Matrix());
+  nsCOMPtr<nsIDOMSVGTransform> result = new DOMSVGTransform(matrix.Matrix());
   return result.forget();
 }
 
 /* nsIDOMSVGTransform createSVGTransformFromMatrix (in nsIDOMSVGMatrix matrix);
  */
 NS_IMETHODIMP
 DOMSVGTransformList::CreateSVGTransformFromMatrix(nsIDOMSVGMatrix *matrix,
                                                   nsIDOMSVGTransform **_retval)
 {
-  ErrorResult rv;
-  *_retval = CreateSVGTransformFromMatrix(matrix, rv).get();
-  return rv.ErrorCode();
+  nsCOMPtr<DOMSVGMatrix> domItem = do_QueryInterface(matrix);
+  if (!domItem) {
+    *_retval = nullptr;
+    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+  }
+  *_retval = CreateSVGTransformFromMatrix(*domItem).get();
+  return NS_OK;
 }
 
 already_AddRefed<nsIDOMSVGTransform>
 DOMSVGTransformList::Consolidate(ErrorResult& error)
 {
   if (IsAnimValList()) {
     error.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
     return nullptr;
--- a/content/svg/content/src/DOMSVGTransformList.h
+++ b/content/svg/content/src/DOMSVGTransformList.h
@@ -17,16 +17,17 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/ErrorResult.h"
 
 class nsIDOMSVGTransform;
 class nsSVGElement;
 
 namespace mozilla {
 
+class DOMSVGMatrix;
 class DOMSVGTransform;
 
 /**
  * Class DOMSVGTransformList
  *
  * This class is used to create the DOM tearoff objects that wrap internal
  * SVGTransformList objects.
  *
@@ -116,18 +117,17 @@ public:
                                                    ErrorResult& error);
   already_AddRefed<nsIDOMSVGTransform> RemoveItem(uint32_t index,
                                                   ErrorResult& error);
   already_AddRefed<nsIDOMSVGTransform> AppendItem(nsIDOMSVGTransform *newItem,
                                                   ErrorResult& error)
   {
     return InsertItemBefore(newItem, LengthNoFlush(), error);
   }
-  already_AddRefed<nsIDOMSVGTransform>
-    CreateSVGTransformFromMatrix(nsIDOMSVGMatrix *matrix, ErrorResult& error);
+  already_AddRefed<nsIDOMSVGTransform> CreateSVGTransformFromMatrix(DOMSVGMatrix& matrix);
   already_AddRefed<nsIDOMSVGTransform> Consolidate(ErrorResult& error);
   uint32_t Length() const
   {
     return NumberOfItems();
   }
 
 private:
 
--- a/content/svg/content/src/nsISVGPoint.h
+++ b/content/svg/content/src/nsISVGPoint.h
@@ -15,16 +15,18 @@ 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 DOMSVGMatrix;
+
 /**
  * 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
@@ -44,17 +46,17 @@ public:
   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 already_AddRefed<nsISVGPoint> MatrixTransform(DOMSVGMatrix& 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)
--- a/content/svg/content/src/nsSVGSVGElement.cpp
+++ b/content/svg/content/src/nsSVGSVGElement.cpp
@@ -129,32 +129,31 @@ nsSVGTranslatePoint::DOMVal::SetY(float 
   SetY(aY, rv);
   return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
 nsSVGTranslatePoint::DOMVal::MatrixTransform(nsIDOMSVGMatrix *matrix,
                                              nsIDOMSVGPoint **_retval)
 {
-  *_retval = MatrixTransform(matrix).get();
+  nsCOMPtr<DOMSVGMatrix> domMatrix = do_QueryInterface(matrix);
+  if (!domMatrix) {
+    *_retval = nullptr;
+    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+  }
+  *_retval = MatrixTransform(*domMatrix).get();
   return NS_OK;
 }
 
 /* nsIDOMSVGPoint matrixTransform (in nsIDOMSVGMatrix matrix); */
 already_AddRefed<nsISVGPoint>
-nsSVGTranslatePoint::DOMVal::MatrixTransform(nsIDOMSVGMatrix *matrix)
+nsSVGTranslatePoint::DOMVal::MatrixTransform(DOMSVGMatrix& 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 a = matrix.A(), b = matrix.B(), c = matrix.C();
+  float d = matrix.D(), e = matrix.E(), f = matrix.F();
   float x = mVal->GetX();
   float y = mVal->GetY();
 
   nsCOMPtr<nsISVGPoint> point = new DOMSVGPoint(a*x + c*y + e, b*x + d*y + f);
   return point.forget();
 }
 
 nsSVGElement::LengthInfo nsSVGSVGElement::sLengthInfo[4] =
--- a/content/svg/content/src/nsSVGSVGElement.h
+++ b/content/svg/content/src/nsSVGSVGElement.h
@@ -15,20 +15,20 @@
 #include "nsIDOMSVGZoomAndPan.h"
 #include "nsSVGEnum.h"
 #include "nsSVGLength2.h"
 #include "nsSVGStylableElement.h"
 #include "nsSVGViewBox.h"
 #include "SVGAnimatedPreserveAspectRatio.h"
 #include "mozilla/Attributes.h"
 
-class nsIDOMSVGMatrix;
 class nsSMILTimeContainer;
 class nsSVGViewElement;
 namespace mozilla {
+  class DOMSVGMatrix;
   class SVGFragmentIdentifier;
 }
 
 typedef nsSVGStylableElement nsSVGSVGElementBase;
 
 class nsSVGSVGElement;
 
 class nsSVGTranslatePoint {
@@ -68,17 +68,17 @@ private:
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMVal)
     NS_DECL_NSIDOMSVGPOINT
 
     // 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);
+    virtual already_AddRefed<mozilla::nsISVGPoint> MatrixTransform(mozilla::DOMSVGMatrix& matrix);
 
     virtual nsISupports* GetParentObject() MOZ_OVERRIDE;
 
     nsSVGTranslatePoint *mVal; // kept alive because it belongs to mElement
     nsRefPtr<nsSVGSVGElement> mElement;
   };
 
   float mX;
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -442,16 +442,21 @@ DOMInterfaces = {
 },
 
 'SVGLengthList': {
     'nativeType': 'mozilla::DOMSVGLengthList',
     'headerFile': 'DOMSVGLengthList.h',
     'resultNotAddRefed': [ 'getItem' ]
 },
 
+'SVGMatrix': {
+    'nativeType': 'mozilla::DOMSVGMatrix',
+    'headerFile': 'DOMSVGMatrix.h'
+},
+
 'SVGNumberList': {
     'nativeType': 'mozilla::DOMSVGNumberList',
     'headerFile': 'DOMSVGNumberList.h',
     'resultNotAddRefed': [ 'getItem' ]
 },
 
 'SVGPathSegList': {
     'nativeType': 'mozilla::DOMSVGPathSegList',
@@ -857,17 +862,16 @@ addExternalIface('OutputStream', nativeT
                  notflattened=True)
 addExternalIface('Principal', nativeType='nsIPrincipal',
                  headerFile='nsIPrincipal.h', notflattened=True)
 addExternalIface('ProcessingInstruction', nativeType='nsXMLProcessingInstruction')
 addExternalIface('Range', nativeType='nsRange')
 addExternalIface("Rect")
 addExternalIface('StyleSheetList')
 addExternalIface('SVGLength')
-addExternalIface('SVGMatrix')
 addExternalIface('SVGNumber')
 addExternalIface('SVGPathSeg')
 addExternalIface('SVGTransform')
 addExternalIface('Text', nativeType='nsTextNode')
 addExternalIface('TextMetrics', headerFile='nsIDOMCanvasRenderingContext2D.h')
 addExternalIface('TreeWalker')
 addExternalIface('Touch', headerFile='nsIDOMTouchEvent.h')
 addExternalIface('TouchList', headerFile='nsIDOMTouchEvent.h')
new file mode 100644
--- /dev/null
+++ b/dom/webidl/SVGMatrix.webidl
@@ -0,0 +1,51 @@
+/* -*- 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 SVGMatrix {
+
+  [SetterThrows]
+  attribute float a;
+  [SetterThrows]
+  attribute float b;
+  [SetterThrows]
+  attribute float c;
+  [SetterThrows]
+  attribute float d;
+  [SetterThrows]
+  attribute float e;
+  [SetterThrows]
+  attribute float f;
+
+  [Creator]
+  SVGMatrix multiply(SVGMatrix secondMatrix);
+  [Creator, Throws]
+  SVGMatrix inverse();
+  [Creator]
+  SVGMatrix translate(float x, float y);
+  [Creator]
+  SVGMatrix scale(float scaleFactor);
+  [Creator]
+  SVGMatrix scaleNonUniform(float scaleFactorX, float scaleFactorY);
+  [Creator]
+  SVGMatrix rotate(float angle);
+  [Creator, Throws]
+  SVGMatrix rotateFromVector(float x, float y);
+  [Creator]
+  SVGMatrix flipX();
+  [Creator]
+  SVGMatrix flipY();
+  [Creator, Throws]
+  SVGMatrix skewX(float angle);
+  [Creator, Throws]
+  SVGMatrix skewY(float angle);
+};
+
--- a/dom/webidl/SVGPoint.webidl
+++ b/dom/webidl/SVGPoint.webidl
@@ -5,18 +5,16 @@
  *
  * 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 SVGMatrix;
-
 interface SVGPoint {
 
   [SetterThrows]
   attribute float x;
   [SetterThrows]
   attribute float y;
 
   [Creator]
--- a/dom/webidl/SVGTransformList.webidl
+++ b/dom/webidl/SVGTransformList.webidl
@@ -5,17 +5,16 @@
  *
  * The origin of this IDL file is
  * http://www.w3.org/TR/SVG11/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
-interface SVGMatrix;
 interface SVGTransform;
 
 interface SVGTransformList {
   readonly attribute unsigned long numberOfItems;
   [Throws]
   void clear();
   [Throws]
   SVGTransform initialize(SVGTransform newItem);
@@ -24,16 +23,15 @@ interface SVGTransformList {
   [Throws]
   SVGTransform insertItemBefore(SVGTransform newItem, unsigned long index);
   [Throws]
   SVGTransform replaceItem(SVGTransform newItem, unsigned long index);
   [Throws]
   SVGTransform removeItem(unsigned long index);
   [Throws]
   SVGTransform appendItem(SVGTransform newItem);
-  [Throws]
   SVGTransform createSVGTransformFromMatrix(SVGMatrix matrix);
   [Throws]
   SVGTransform consolidate();
 
   // Mozilla-specific stuff
   readonly attribute unsigned long length; // synonym for numberOfItems
 };
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -64,16 +64,17 @@ webidl_files = \
   PaintRequestList.webidl \
   PannerNode.webidl \
   Performance.webidl \
   PerformanceNavigation.webidl \
   PerformanceTiming.webidl \
   RGBColor.webidl \
   Screen.webidl \
   SVGLengthList.webidl \
+  SVGMatrix.webidl \
   SVGNumberList.webidl \
   SVGPathSegList.webidl \
   SVGPoint.webidl \
   SVGPointList.webidl \
   SVGTransformList.webidl \
   TextDecoder.webidl \
   TextEncoder.webidl \
   URL.webidl \