Bug 816778 Part 5: Convert SVGPreserveAspectRatio to WebIDL r=bz
authorDavid Zbarsky <dzbarsky@gmail.com>
Sat, 22 Dec 2012 23:54:20 -0500
changeset 126020 1945ceaff5faca696a3fa0853750b6c13cc170ab
parent 126019 db3de623feca7b822530818767c4fe255ded7852
child 126021 00c8e8d5fe04c1d1a29d2d04e06f61064eedaae5
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
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 5: Convert SVGPreserveAspectRatio to WebIDL r=bz
content/svg/content/src/Makefile.in
content/svg/content/src/SVGAnimatedPreserveAspectRatio.cpp
content/svg/content/src/SVGAnimatedPreserveAspectRatio.h
content/svg/content/src/SVGPreserveAspectRatio.cpp
content/svg/content/src/SVGPreserveAspectRatio.h
content/svg/content/src/nsSVGSVGElement.h
dom/bindings/Bindings.conf
dom/webidl/SVGPreserveAspectRatio.webidl
dom/webidl/WebIDL.mk
--- a/content/svg/content/src/Makefile.in
+++ b/content/svg/content/src/Makefile.in
@@ -100,16 +100,17 @@ CPPSRCS		= \
 		SVGAnimatedTransformList.cpp \
 		SVGFragmentIdentifier.cpp \
 		SVGLength.cpp \
 		SVGLengthList.cpp \
 		SVGNumberList.cpp \
 		SVGPathData.cpp \
 		SVGPathSegUtils.cpp \
 		SVGPointList.cpp \
+		SVGPreserveAspectRatio.cpp \
 		SVGStringList.cpp \
 		SVGTransform.cpp \
 		SVGTransformList.cpp \
 		SVGTransformListParser.cpp \
 		nsSVGAnimateElement.cpp \
 		nsSVGAnimateTransformElement.cpp \
 		nsSVGAnimateMotionElement.cpp \
 		nsSVGAnimationElement.cpp \
--- a/content/svg/content/src/SVGAnimatedPreserveAspectRatio.cpp
+++ b/content/svg/content/src/SVGAnimatedPreserveAspectRatio.cpp
@@ -8,76 +8,52 @@
 #include "SVGAnimatedPreserveAspectRatio.h"
 #include "nsWhitespaceTokenizer.h"
 #include "nsSMILValue.h"
 #include "nsSVGAttrTearoffTable.h"
 #include "SMILEnumType.h"
 #include "nsAttrValueInlines.h"
 
 using namespace mozilla;
+using namespace mozilla::dom;
 
 ////////////////////////////////////////////////////////////////////////
 // SVGAnimatedPreserveAspectRatio class
 
 NS_SVG_VAL_IMPL_CYCLE_COLLECTION(
-  SVGAnimatedPreserveAspectRatio::DOMBaseVal, mSVGElement)
-NS_SVG_VAL_IMPL_CYCLE_COLLECTION(
-  SVGAnimatedPreserveAspectRatio::DOMAnimVal, mSVGElement)
-NS_SVG_VAL_IMPL_CYCLE_COLLECTION(
   SVGAnimatedPreserveAspectRatio::DOMAnimPAspectRatio, mSVGElement)
 
-NS_IMPL_CYCLE_COLLECTING_ADDREF(SVGAnimatedPreserveAspectRatio::DOMBaseVal)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(SVGAnimatedPreserveAspectRatio::DOMBaseVal)
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(SVGAnimatedPreserveAspectRatio::DOMAnimVal)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(SVGAnimatedPreserveAspectRatio::DOMAnimVal)
-
 NS_IMPL_CYCLE_COLLECTING_ADDREF(
   SVGAnimatedPreserveAspectRatio::DOMAnimPAspectRatio)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(
   SVGAnimatedPreserveAspectRatio::DOMAnimPAspectRatio)
 
-DOMCI_DATA(SVGPreserveAspectRatio, SVGAnimatedPreserveAspectRatio::DOMBaseVal)
 DOMCI_DATA(SVGAnimatedPreserveAspectRatio,
            SVGAnimatedPreserveAspectRatio::DOMAnimPAspectRatio)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
-  SVGAnimatedPreserveAspectRatio::DOMBaseVal)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMSVGPreserveAspectRatio)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGPreserveAspectRatio)
-NS_INTERFACE_MAP_END
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
-  SVGAnimatedPreserveAspectRatio::DOMAnimVal)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMSVGPreserveAspectRatio)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGPreserveAspectRatio)
-NS_INTERFACE_MAP_END
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   SVGAnimatedPreserveAspectRatio::DOMAnimPAspectRatio)
   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimatedPreserveAspectRatio)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAnimatedPreserveAspectRatio)
 NS_INTERFACE_MAP_END
 
 /* Implementation */
 
 static const char *sAlignStrings[] =
   { "none", "xMinYMin", "xMidYMin", "xMaxYMin", "xMinYMid", "xMidYMid",
     "xMaxYMid", "xMinYMax", "xMidYMax", "xMaxYMax" };
 
 static const char *sMeetOrSliceStrings[] = { "meet", "slice" };
 
 static nsSVGAttrTearoffTable<SVGAnimatedPreserveAspectRatio, SVGAnimatedPreserveAspectRatio::DOMAnimPAspectRatio>
   sSVGAnimatedPAspectRatioTearoffTable;
-static nsSVGAttrTearoffTable<SVGAnimatedPreserveAspectRatio, SVGAnimatedPreserveAspectRatio::DOMBaseVal>
+static nsSVGAttrTearoffTable<SVGAnimatedPreserveAspectRatio, DOMSVGPreserveAspectRatio>
   sBaseSVGPAspectRatioTearoffTable;
-static nsSVGAttrTearoffTable<SVGAnimatedPreserveAspectRatio, SVGAnimatedPreserveAspectRatio::DOMAnimVal>
+static nsSVGAttrTearoffTable<SVGAnimatedPreserveAspectRatio, DOMSVGPreserveAspectRatio>
   sAnimSVGPAspectRatioTearoffTable;
 
 static uint16_t
 GetAlignForString(const nsAString &aAlignString)
 {
   for (uint32_t i = 0 ; i < ArrayLength(sAlignStrings) ; i++) {
     if (aAlignString.EqualsASCII(sAlignStrings[i])) {
       return (i + nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE);
@@ -120,66 +96,57 @@ GetMeetOrSliceString(nsAString& aMeetOrS
     aMeetOrSlice <= nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE,
     "Unknown meetOrSlice");
 
   aMeetOrSliceString.AssignASCII(
     sMeetOrSliceStrings[aMeetOrSlice -
                         nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET]);
 }
 
-bool
-SVGPreserveAspectRatio::operator==(const SVGPreserveAspectRatio& aOther) const
-{
-  return mAlign == aOther.mAlign &&
-    mMeetOrSlice == aOther.mMeetOrSlice &&
-    mDefer == aOther.mDefer;
-}
-
 nsresult
 SVGAnimatedPreserveAspectRatio::ToDOMBaseVal(
   nsIDOMSVGPreserveAspectRatio **aResult,
   nsSVGElement *aSVGElement)
 {
-  nsRefPtr<DOMBaseVal> domBaseVal =
+  nsRefPtr<DOMSVGPreserveAspectRatio> domBaseVal =
     sBaseSVGPAspectRatioTearoffTable.GetTearoff(this);
   if (!domBaseVal) {
-    domBaseVal = new DOMBaseVal(this, aSVGElement);
+    domBaseVal = new DOMSVGPreserveAspectRatio(this, aSVGElement, true);
     sBaseSVGPAspectRatioTearoffTable.AddTearoff(this, domBaseVal);
   }
 
   domBaseVal.forget(aResult);
   return NS_OK;
 }
 
-SVGAnimatedPreserveAspectRatio::DOMBaseVal::~DOMBaseVal()
+DOMSVGPreserveAspectRatio::~DOMSVGPreserveAspectRatio()
 {
-  sBaseSVGPAspectRatioTearoffTable.RemoveTearoff(mVal);
+  if (mIsBaseValue) {
+    sBaseSVGPAspectRatioTearoffTable.RemoveTearoff(mVal);
+  } else {
+    sAnimSVGPAspectRatioTearoffTable.RemoveTearoff(mVal);
+  }
 }
 
 nsresult
 SVGAnimatedPreserveAspectRatio::ToDOMAnimVal(
   nsIDOMSVGPreserveAspectRatio **aResult,
   nsSVGElement *aSVGElement)
 {
-  nsRefPtr<DOMAnimVal> domAnimVal =
+  nsRefPtr<DOMSVGPreserveAspectRatio> domAnimVal =
     sAnimSVGPAspectRatioTearoffTable.GetTearoff(this);
   if (!domAnimVal) {
-    domAnimVal = new DOMAnimVal(this, aSVGElement);
+    domAnimVal = new DOMSVGPreserveAspectRatio(this, aSVGElement, true);
     sAnimSVGPAspectRatioTearoffTable.AddTearoff(this, domAnimVal);
   }
 
   domAnimVal.forget(aResult);
   return NS_OK;
 }
 
-SVGAnimatedPreserveAspectRatio::DOMAnimVal::~DOMAnimVal()
-{
-  sAnimSVGPAspectRatioTearoffTable.RemoveTearoff(mVal);
-}
-
 static nsresult
 ToPreserveAspectRatio(const nsAString &aString,
                       SVGPreserveAspectRatio *aValue)
 {
   if (aString.IsEmpty() || NS_IsAsciiWhitespace(aString[0])) {
     return NS_ERROR_DOM_SYNTAX_ERR;
   }
 
--- a/content/svg/content/src/SVGAnimatedPreserveAspectRatio.h
+++ b/content/svg/content/src/SVGAnimatedPreserveAspectRatio.h
@@ -8,82 +8,24 @@
 
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsError.h"
 #include "nsIDOMSVGAnimPresAspRatio.h"
 #include "nsIDOMSVGPresAspectRatio.h"
 #include "nsISMILAttr.h"
 #include "nsSVGElement.h"
+#include "SVGPreserveAspectRatio.h"
 #include "mozilla/Attributes.h"
 
 class nsISMILAnimationElement;
 class nsSMILValue;
 
 namespace mozilla {
 
-class SVGAnimatedPreserveAspectRatio;
-
-class SVGPreserveAspectRatio
-{
-  friend class SVGAnimatedPreserveAspectRatio;
-
-public:
-  SVGPreserveAspectRatio(uint16_t aAlign, uint16_t aMeetOrSlice, bool aDefer = false)
-    : mAlign(aAlign)
-    , mMeetOrSlice(aMeetOrSlice)
-    , mDefer(aDefer)
-  {}
-
-  SVGPreserveAspectRatio()
-    : mAlign(0)
-    , mMeetOrSlice(0)
-    , mDefer(false)
-  {}
-
-  bool operator==(const SVGPreserveAspectRatio& aOther) const;
-
-  nsresult SetAlign(uint16_t aAlign) {
-    if (aAlign < nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE ||
-        aAlign > nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX)
-      return NS_ERROR_FAILURE;
-    mAlign = static_cast<uint8_t>(aAlign);
-    return NS_OK;
-  }
-
-  uint16_t GetAlign() const {
-    return mAlign;
-  }
-
-  nsresult SetMeetOrSlice(uint16_t aMeetOrSlice) {
-    if (aMeetOrSlice < nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET ||
-        aMeetOrSlice > nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE)
-      return NS_ERROR_FAILURE;
-    mMeetOrSlice = static_cast<uint8_t>(aMeetOrSlice);
-    return NS_OK;
-  }
-
-  uint16_t GetMeetOrSlice() const {
-    return mMeetOrSlice;
-  }
-
-  void SetDefer(bool aDefer) {
-    mDefer = aDefer;
-  }
-
-  bool GetDefer() const {
-    return mDefer;
-  }
-
-private:
-  uint8_t mAlign;
-  uint8_t mMeetOrSlice;
-  bool mDefer;
-};
-
 class SVGAnimatedPreserveAspectRatio
 {
 public:
   void Init() {
     mBaseVal.mAlign = nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID;
     mBaseVal.mMeetOrSlice = nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET;
     mBaseVal.mDefer = false;
     mAnimVal = mBaseVal;
@@ -143,72 +85,16 @@ private:
   bool mIsBaseSet;
 
   nsresult ToDOMBaseVal(nsIDOMSVGPreserveAspectRatio **aResult,
                         nsSVGElement* aSVGElement);
   nsresult ToDOMAnimVal(nsIDOMSVGPreserveAspectRatio **aResult,
                         nsSVGElement* aSVGElement);
 
 public:
-  struct DOMBaseVal MOZ_FINAL : public nsIDOMSVGPreserveAspectRatio
-  {
-    NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-    NS_DECL_CYCLE_COLLECTION_CLASS(DOMBaseVal)
-
-    DOMBaseVal(SVGAnimatedPreserveAspectRatio* aVal, nsSVGElement *aSVGElement)
-      : mVal(aVal), mSVGElement(aSVGElement) {}
-    virtual ~DOMBaseVal();
-    
-    SVGAnimatedPreserveAspectRatio* mVal; // kept alive because it belongs to mSVGElement
-    nsRefPtr<nsSVGElement> mSVGElement;
-    
-    NS_IMETHOD GetAlign(uint16_t* aAlign)
-      { *aAlign = mVal->GetBaseValue().GetAlign(); return NS_OK; }
-    NS_IMETHOD SetAlign(uint16_t aAlign)
-      { return mVal->SetBaseAlign(aAlign, mSVGElement); }
-
-    NS_IMETHOD GetMeetOrSlice(uint16_t* aMeetOrSlice)
-      { *aMeetOrSlice = mVal->GetBaseValue().GetMeetOrSlice(); return NS_OK; }
-    NS_IMETHOD SetMeetOrSlice(uint16_t aMeetOrSlice)
-      { return mVal->SetBaseMeetOrSlice(aMeetOrSlice, mSVGElement); }
-  };
-
-  struct DOMAnimVal MOZ_FINAL : public nsIDOMSVGPreserveAspectRatio
-  {
-    NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-    NS_DECL_CYCLE_COLLECTION_CLASS(DOMAnimVal)
-
-    DOMAnimVal(SVGAnimatedPreserveAspectRatio* aVal, nsSVGElement *aSVGElement)
-      : mVal(aVal), mSVGElement(aSVGElement) {}
-    virtual ~DOMAnimVal();
-    
-    SVGAnimatedPreserveAspectRatio* mVal; // kept alive because it belongs to mSVGElement
-    nsRefPtr<nsSVGElement> mSVGElement;
-    
-    // Script may have modified animation parameters or timeline -- DOM getters
-    // need to flush any resample requests to reflect these modifications.
-    NS_IMETHOD GetAlign(uint16_t* aAlign)
-    {
-      mSVGElement->FlushAnimations();
-      *aAlign = mVal->GetAnimValue().GetAlign();
-      return NS_OK;
-    }
-    NS_IMETHOD SetAlign(uint16_t aAlign)
-      { return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; }
-
-    NS_IMETHOD GetMeetOrSlice(uint16_t* aMeetOrSlice)
-    {
-      mSVGElement->FlushAnimations();
-      *aMeetOrSlice = mVal->GetAnimValue().GetMeetOrSlice();
-      return NS_OK;
-    }
-    NS_IMETHOD SetMeetOrSlice(uint16_t aValue)
-      { return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; }
-  };
-
   struct DOMAnimPAspectRatio MOZ_FINAL : public nsIDOMSVGAnimatedPreserveAspectRatio
   {
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     NS_DECL_CYCLE_COLLECTION_CLASS(DOMAnimPAspectRatio)
 
     DOMAnimPAspectRatio(SVGAnimatedPreserveAspectRatio* aVal,
                         nsSVGElement *aSVGElement)
       : mVal(aVal), mSVGElement(aSVGElement) {}
new file mode 100644
--- /dev/null
+++ b/content/svg/content/src/SVGPreserveAspectRatio.cpp
@@ -0,0 +1,94 @@
+/* -*- 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 "SVGPreserveAspectRatio.h"
+#include "SVGAnimatedPreserveAspectRatio.h"
+#include "mozilla/dom/SVGPreserveAspectRatioBinding.h"
+
+using namespace mozilla;
+using namespace dom;
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGPreserveAspectRatio)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGPreserveAspectRatio)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGPreserveAspectRatio)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSVGElement)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGPreserveAspectRatio)
+NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGPreserveAspectRatio)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGPreserveAspectRatio)
+
+DOMCI_DATA(SVGPreserveAspectRatio, DOMSVGPreserveAspectRatio)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGPreserveAspectRatio)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsIDOMSVGPreserveAspectRatio)
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGPreserveAspectRatio)
+NS_INTERFACE_MAP_END
+
+bool
+SVGPreserveAspectRatio::operator==(const SVGPreserveAspectRatio& aOther) const
+{
+  return mAlign == aOther.mAlign &&
+    mMeetOrSlice == aOther.mMeetOrSlice &&
+    mDefer == aOther.mDefer;
+}
+
+JSObject*
+DOMSVGPreserveAspectRatio::WrapObject(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap)
+{
+  return mozilla::dom::SVGPreserveAspectRatioBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
+
+uint16_t
+DOMSVGPreserveAspectRatio::Align()
+{
+  if (mIsBaseValue) {
+    return mVal->GetBaseValue().GetAlign();
+  }
+
+  mSVGElement->FlushAnimations();
+  return mVal->GetAnimValue().GetAlign();
+}
+
+void
+DOMSVGPreserveAspectRatio::SetAlign(uint16_t aAlign, ErrorResult& rv)
+{
+  if (!mIsBaseValue) {
+    rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return;
+  }
+  rv = mVal->SetBaseAlign(aAlign, mSVGElement);
+}
+
+uint16_t
+DOMSVGPreserveAspectRatio::MeetOrSlice()
+{
+  if (mIsBaseValue) {
+    return mVal->GetBaseValue().GetMeetOrSlice();
+  }
+
+  mSVGElement->FlushAnimations();
+  return mVal->GetAnimValue().GetMeetOrSlice();
+}
+
+void
+DOMSVGPreserveAspectRatio::SetMeetOrSlice(uint16_t aMeetOrSlice, ErrorResult& rv)
+{
+  if (!mIsBaseValue) {
+    rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return;
+  }
+  rv = mVal->SetBaseMeetOrSlice(aMeetOrSlice, mSVGElement);
+}
+
new file mode 100644
--- /dev/null
+++ b/content/svg/content/src/SVGPreserveAspectRatio.h
@@ -0,0 +1,119 @@
+/* -*- 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 "nsIDOMSVGPresAspectRatio.h"
+#include "nsWrapperCache.h"
+#include "nsAutoPtr.h"
+#include "nsCycleCollectionParticipant.h"
+#include "mozilla/ErrorResult.h"
+
+class nsSVGElement;
+
+namespace mozilla {
+class SVGAnimatedPreserveAspectRatio;
+
+class SVGPreserveAspectRatio
+{
+  friend class SVGAnimatedPreserveAspectRatio;
+public:
+  SVGPreserveAspectRatio(uint16_t aAlign, uint16_t aMeetOrSlice, bool aDefer = false)
+    : mAlign(aAlign)
+    , mMeetOrSlice(aMeetOrSlice)
+    , mDefer(aDefer)
+  {}
+
+  bool operator==(const SVGPreserveAspectRatio& aOther) const;
+
+  explicit SVGPreserveAspectRatio()
+    : mAlign(0)
+    , mMeetOrSlice(0)
+    , mDefer(false)
+  {}
+
+  nsresult SetAlign(uint16_t aAlign) {
+    if (aAlign < nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE ||
+        aAlign > nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX)
+      return NS_ERROR_FAILURE;
+    mAlign = static_cast<uint8_t>(aAlign);
+    return NS_OK;
+  }
+
+  uint16_t GetAlign() const {
+    return mAlign;
+  }
+
+  nsresult SetMeetOrSlice(uint16_t aMeetOrSlice) {
+    if (aMeetOrSlice < nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET ||
+        aMeetOrSlice > nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE)
+      return NS_ERROR_FAILURE;
+    mMeetOrSlice = static_cast<uint8_t>(aMeetOrSlice);
+    return NS_OK;
+  }
+
+  uint16_t GetMeetOrSlice() const {
+    return mMeetOrSlice;
+  }
+
+  void SetDefer(bool aDefer) {
+    mDefer = aDefer;
+  }
+
+  bool GetDefer() const {
+    return mDefer;
+  }
+
+private:
+  uint8_t mAlign;
+  uint8_t mMeetOrSlice;
+  bool mDefer;
+};
+
+namespace dom {
+
+class DOMSVGPreserveAspectRatio MOZ_FINAL : public nsIDOMSVGPreserveAspectRatio,
+                                            public nsWrapperCache
+{
+public:
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGPreserveAspectRatio)
+
+  DOMSVGPreserveAspectRatio(SVGAnimatedPreserveAspectRatio* aVal,
+                            nsSVGElement *aSVGElement,
+                            bool aIsBaseValue)
+    : mVal(aVal), mSVGElement(aSVGElement), mIsBaseValue(aIsBaseValue)
+  {
+    SetIsDOMBinding();
+  }
+  ~DOMSVGPreserveAspectRatio();
+
+  NS_IMETHOD GetAlign(uint16_t* aAlign)
+    { *aAlign = Align(); return NS_OK; }
+  NS_IMETHOD SetAlign(uint16_t aAlign)
+    { ErrorResult rv;  SetAlign(aAlign, rv); return rv.ErrorCode(); }
+
+  NS_IMETHOD GetMeetOrSlice(uint16_t* aMeetOrSlice)
+    { *aMeetOrSlice = MeetOrSlice(); return NS_OK; }
+  NS_IMETHOD SetMeetOrSlice(uint16_t aMeetOrSlice)
+    { ErrorResult rv; SetMeetOrSlice(aMeetOrSlice, rv); return rv.ErrorCode(); }
+
+  // WebIDL
+  nsSVGElement* GetParentObject() const { return mSVGElement; }
+  virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap);
+
+  uint16_t Align();
+  void SetAlign(uint16_t aAlign, ErrorResult& rv);
+  uint16_t MeetOrSlice();
+  void SetMeetOrSlice(uint16_t aMeetOrSlice, ErrorResult& rv);
+
+protected:
+  SVGAnimatedPreserveAspectRatio* mVal; // kept alive because it belongs to mSVGElement
+  nsRefPtr<nsSVGElement> mSVGElement;
+  const bool mIsBaseValue;
+};
+
+} //namespace dom
+} //namespace mozilla
--- a/content/svg/content/src/nsSVGSVGElement.h
+++ b/content/svg/content/src/nsSVGSVGElement.h
@@ -12,16 +12,17 @@
 #include "nsIDOMSVGLocatable.h"
 #include "nsISVGPoint.h"
 #include "nsIDOMSVGSVGElement.h"
 #include "nsIDOMSVGZoomAndPan.h"
 #include "nsSVGEnum.h"
 #include "nsSVGLength2.h"
 #include "nsSVGStylableElement.h"
 #include "nsSVGViewBox.h"
+#include "SVGPreserveAspectRatio.h"
 #include "SVGAnimatedPreserveAspectRatio.h"
 #include "mozilla/Attributes.h"
 
 class nsSMILTimeContainer;
 class nsSVGViewElement;
 namespace mozilla {
   class DOMSVGMatrix;
   class SVGFragmentIdentifier;
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -475,16 +475,21 @@ DOMInterfaces = {
 },
 
 'SVGPointList': {
     'nativeType': 'mozilla::DOMSVGPointList',
     'headerFile': 'DOMSVGPointList.h',
     'resultNotAddRefed': [ 'getItem' ]
 },
 
+'SVGPreserveAspectRatio': {
+    'nativeType': 'mozilla::dom::DOMSVGPreserveAspectRatio',
+    'headerFile': 'SVGPreserveAspectRatio.h'
+},
+
 'SVGTransform': {
     'nativeType': 'mozilla::DOMSVGTransform',
     'headerFile': 'DOMSVGTransform.h'
 },
 
 'SVGTransformList': {
     'nativeType': 'mozilla::DOMSVGTransformList',
     'headerFile': 'DOMSVGTransformList.h',
new file mode 100644
--- /dev/null
+++ b/dom/webidl/SVGPreserveAspectRatio.webidl
@@ -0,0 +1,36 @@
+/* -*- 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 SVGPreserveAspectRatio {
+
+  // Alignment Types
+  const unsigned short SVG_PRESERVEASPECTRATIO_UNKNOWN = 0;
+  const unsigned short SVG_PRESERVEASPECTRATIO_NONE = 1;
+  const unsigned short SVG_PRESERVEASPECTRATIO_XMINYMIN = 2;
+  const unsigned short SVG_PRESERVEASPECTRATIO_XMIDYMIN = 3;
+  const unsigned short SVG_PRESERVEASPECTRATIO_XMAXYMIN = 4;
+  const unsigned short SVG_PRESERVEASPECTRATIO_XMINYMID = 5;
+  const unsigned short SVG_PRESERVEASPECTRATIO_XMIDYMID = 6;
+  const unsigned short SVG_PRESERVEASPECTRATIO_XMAXYMID = 7;
+  const unsigned short SVG_PRESERVEASPECTRATIO_XMINYMAX = 8;
+  const unsigned short SVG_PRESERVEASPECTRATIO_XMIDYMAX = 9;
+  const unsigned short SVG_PRESERVEASPECTRATIO_XMAXYMAX = 10;
+
+  // Meet-or-slice Types
+  const unsigned short SVG_MEETORSLICE_UNKNOWN = 0;
+  const unsigned short SVG_MEETORSLICE_MEET = 1;
+  const unsigned short SVG_MEETORSLICE_SLICE = 2;
+
+  attribute unsigned short align;
+  attribute unsigned short meetOrSlice;
+};
+
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -70,16 +70,17 @@ webidl_files = \
   Screen.webidl \
   SVGAnimatedTransformList.webidl \
   SVGLengthList.webidl \
   SVGMatrix.webidl \
   SVGNumberList.webidl \
   SVGPathSegList.webidl \
   SVGPoint.webidl \
   SVGPointList.webidl \
+  SVGPreserveAspectRatio.webidl \
   SVGTransform.webidl \
   SVGTransformList.webidl \
   TextDecoder.webidl \
   TextEncoder.webidl \
   URL.webidl \
   WebSocket.webidl \
   XMLHttpRequest.webidl \
   XMLHttpRequestEventTarget.webidl \