Fix for bug 788532 (Add the new DOM bindings API to DOM lists). r=bz.
authorPeter Van der Beken <peterv@propagandism.org>
Wed, 05 Sep 2012 22:49:53 +0200
changeset 107225 0bb263ef39aeb446d0be8d0a8f1fa261f9108da5
parent 107224 9ea3c67106904e21d59daffdee08b8ed099d635f
child 107226 fc7232da08efccfb5cd583424b696ba0288b1f41
push id23478
push useremorley@mozilla.com
push dateMon, 17 Sep 2012 19:20:15 +0000
treeherdermozilla-central@0d3b17a88d5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs788532
milestone18.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
Fix for bug 788532 (Add the new DOM bindings API to DOM lists). r=bz.
content/base/public/nsDOMFile.h
content/base/public/nsINodeList.h
content/base/src/nsContentList.cpp
content/base/src/nsContentList.h
content/base/src/nsContentUtils.cpp
content/base/src/nsDOMFile.cpp
content/base/src/nsDOMTokenList.cpp
content/base/src/nsDOMTokenList.h
content/base/src/nsGenericElement.h
content/base/src/nsTextNode.cpp
content/events/src/nsPaintRequest.cpp
content/events/src/nsPaintRequest.h
content/html/content/public/nsIHTMLCollection.h
content/html/content/src/HTMLPropertiesCollection.cpp
content/html/content/src/HTMLPropertiesCollection.h
content/html/content/src/nsClientRect.cpp
content/html/content/src/nsClientRect.h
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/src/nsGenericHTMLElement.h
content/html/content/src/nsHTMLDataListElement.cpp
content/html/content/src/nsHTMLFieldSetElement.cpp
content/html/content/src/nsHTMLFormElement.cpp
content/html/content/src/nsHTMLOptGroupElement.cpp
content/html/content/src/nsHTMLOptGroupElement.h
content/html/content/src/nsHTMLSelectElement.cpp
content/html/content/src/nsHTMLSelectElement.h
content/html/content/src/nsHTMLStyleElement.cpp
content/html/content/src/nsHTMLTableElement.cpp
content/html/content/src/nsHTMLTitleElement.cpp
content/html/document/src/nsHTMLDocument.cpp
content/html/document/src/nsHTMLDocument.h
content/svg/content/src/DOMSVGLengthList.cpp
content/svg/content/src/DOMSVGLengthList.h
content/svg/content/src/DOMSVGNumberList.cpp
content/svg/content/src/DOMSVGNumberList.h
content/svg/content/src/DOMSVGPathSegList.cpp
content/svg/content/src/DOMSVGPathSegList.h
content/svg/content/src/DOMSVGPointList.cpp
content/svg/content/src/DOMSVGPointList.h
content/svg/content/src/DOMSVGTransformList.cpp
content/svg/content/src/DOMSVGTransformList.h
content/svg/content/src/nsSVGStyleElement.cpp
content/svg/content/src/nsSVGTitleElement.cpp
dom/base/nsDOMClassInfo.cpp
dom/bindings/Bindings.conf
dom/imptests/failures/html/tests/submission/Opera/microdata/test_001.html.json
dom/interfaces/core/nsIDOMDOMTokenList.idl
dom/tests/mochitest/chrome/test_sandbox_bindings.xul
dom/webidl/ClientRectList.webidl
dom/webidl/DOMTokenList.webidl
dom/webidl/FileList.webidl
dom/webidl/HTMLCollection.webidl
dom/webidl/HTMLOptionsCollection.webidl
dom/webidl/HTMLPropertiesCollection.webidl
dom/webidl/NodeList.webidl
dom/webidl/PaintRequestList.webidl
dom/webidl/SVGLengthList.webidl
dom/webidl/SVGNumberList.webidl
dom/webidl/SVGPathSegList.webidl
dom/webidl/SVGPointList.webidl
dom/webidl/SVGTransformList.webidl
dom/webidl/TouchList.webidl
dom/webidl/WebIDL.mk
js/xpconnect/src/nsDOMQS.h
layout/forms/nsComboboxControlFrame.cpp
layout/forms/nsFileControlFrame.cpp
layout/forms/nsGfxButtonControlFrame.cpp
layout/forms/nsMeterFrame.cpp
layout/forms/nsProgressFrame.cpp
layout/forms/nsTextControlFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsVideoFrame.cpp
layout/printing/nsPrintEngine.cpp
layout/svg/base/src/nsSVGUseFrame.cpp
--- a/content/base/public/nsDOMFile.h
+++ b/content/base/public/nsDOMFile.h
@@ -425,16 +425,30 @@ public:
       NS_ASSERTION(list_qi == static_cast<nsIDOMFileList*>(aSupports),
                    "Uh, fix QI!");
     }
 #endif
 
     return static_cast<nsDOMFileList*>(aSupports);
   }
 
+  nsIDOMFile* Item(uint32_t aIndex)
+  {
+    return mFiles.SafeObjectAt(aIndex);
+  }
+  nsIDOMFile* IndexedGetter(uint32_t aIndex, bool& aFound)
+  {
+    aFound = aIndex < static_cast<uint32_t>(mFiles.Count());
+    return aFound ? mFiles.ObjectAt(aIndex) : nullptr;
+  }
+  uint32_t Length()
+  {
+    return mFiles.Count();
+  }
+
 private:
   nsCOMArray<nsIDOMFile> mFiles;
   nsISupports *mParent;
 };
 
 class NS_STACK_CLASS nsDOMFileInternalUrlHolder {
 public:
   nsDOMFileInternalUrlHolder(nsIDOMBlob* aFile, nsIPrincipal* aPrincipal
--- a/content/base/public/nsINodeList.h
+++ b/content/base/public/nsINodeList.h
@@ -31,16 +31,35 @@ public:
    * is not in the list.
    */
   virtual int32_t IndexOf(nsIContent* aContent) = 0;
 
   /**
    * Get the root node for this nodelist.
    */
   virtual nsINode* GetParentObject() = 0;
+
+  using nsIDOMNodeList::Item;
+
+  uint32_t Length()
+  {
+    uint32_t length;
+    GetLength(&length);
+    return length;
+  }
+  nsIContent* Item(uint32_t aIndex)
+  {
+    return GetNodeAt(aIndex);
+  }
+  nsIContent* IndexedGetter(uint32_t aIndex, bool& aFound)
+  {
+    nsIContent* item = Item(aIndex);
+    aFound = !!item;
+    return item;
+  }
 };
 
 #define NS_NODELIST_OFFSET_AND_INTERFACE_TABLE_BEGIN(_class)                  \
   NS_OFFSET_AND_INTERFACE_TABLE_BEGIN_AMBIGUOUS(_class, nsINodeList)
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsINodeList, NS_INODELIST_IID)
 
 #endif /* nsINodeList_h___ */
--- a/content/base/src/nsContentList.cpp
+++ b/content/base/src/nsContentList.cpp
@@ -16,16 +16,17 @@
 #include "nsIDocument.h"
 #include "nsGenericElement.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsContentUtils.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsGkAtoms.h"
 
 #include "dombindings.h"
+#include "mozilla/dom/BindingUtils.h"
 
 // Form related includes
 #include "nsIDOMHTMLFormElement.h"
 
 #include "pldhash.h"
 
 #ifdef DEBUG_CONTENT_LIST
 #include "nsIContentIterator.h"
@@ -280,16 +281,38 @@ NS_GetContentList(nsINode* aRootNode,
     }
   }
 
   NS_ADDREF(list);
 
   return list;
 }
 
+#ifdef DEBUG
+const nsCacheableFuncStringContentList::ContentListType
+  nsCacheableFuncStringNodeList::sType = nsCacheableFuncStringContentList::eNodeList;
+const nsCacheableFuncStringContentList::ContentListType
+  nsCacheableFuncStringHTMLCollection::sType = nsCacheableFuncStringContentList::eHTMLCollection;
+#endif
+
+JSObject*
+nsCacheableFuncStringNodeList::WrapObject(JSContext *cx, JSObject *scope,
+                                          bool *triedToWrap)
+{
+  return oldproxybindings::NodeList::create(cx, scope, this, triedToWrap);
+}
+
+
+JSObject*
+nsCacheableFuncStringHTMLCollection::WrapObject(JSContext *cx, JSObject *scope,
+                                                bool *triedToWrap)
+{
+  return oldproxybindings::HTMLCollection::create(cx, scope, this, triedToWrap);
+}
+
 // Hashtable for storing nsCacheableFuncStringContentList
 static PLDHashTable gFuncStringContentListHashTable;
 
 struct FuncStringContentListHashEntry : public PLDHashEntryHdr
 {
   nsCacheableFuncStringContentList* mContentList;
 };
 
@@ -309,22 +332,23 @@ FuncStringContentListHashtableMatchEntry
   const FuncStringContentListHashEntry *e =
     static_cast<const FuncStringContentListHashEntry *>(entry);
   const nsFuncStringCacheKey* ourKey =
     static_cast<const nsFuncStringCacheKey *>(key);
 
   return e->mContentList->Equals(ourKey);
 }
 
+template<class ListType>
 already_AddRefed<nsContentList>
-NS_GetFuncStringContentList(nsINode* aRootNode,
-                            nsContentListMatchFunc aFunc,
-                            nsContentListDestroyFunc aDestroyFunc,
-                            nsFuncStringContentListDataAllocator aDataAllocator,
-                            const nsAString& aString)
+GetFuncStringContentList(nsINode* aRootNode,
+                         nsContentListMatchFunc aFunc,
+                         nsContentListDestroyFunc aDestroyFunc,
+                         nsFuncStringContentListDataAllocator aDataAllocator,
+                         const nsAString& aString)
 {
   NS_ASSERTION(aRootNode, "content list has to have a root");
 
   nsCacheableFuncStringContentList* list = nullptr;
 
   static PLDHashTableOps hash_table_ops =
   {
     PL_DHashAllocTable,
@@ -354,25 +378,29 @@ NS_GetFuncStringContentList(nsINode* aRo
     nsFuncStringCacheKey hashKey(aRootNode, aFunc, aString);
 
     // A PL_DHASH_ADD is equivalent to a PL_DHASH_LOOKUP for cases
     // when the entry is already in the hashtable.
     entry = static_cast<FuncStringContentListHashEntry *>
                        (PL_DHashTableOperate(&gFuncStringContentListHashTable,
                                              &hashKey,
                                              PL_DHASH_ADD));
-    if (entry)
+    if (entry) {
       list = entry->mContentList;
+#ifdef DEBUG
+      MOZ_ASSERT_IF(list, list->mType == ListType::sType);
+#endif
+    }
   }
 
   if (!list) {
     // We need to create a ContentList and add it to our new entry, if
     // we have an entry
-    list = new nsCacheableFuncStringContentList(aRootNode, aFunc, aDestroyFunc,
-                                                aDataAllocator, aString);
+    list = new ListType(aRootNode, aFunc, aDestroyFunc, aDataAllocator,
+                        aString);
     if (list && !list->AllocatedData()) {
       // Failed to allocate the data
       delete list;
       list = nullptr;
     }
 
     if (entry) {
       if (list)
@@ -386,16 +414,44 @@ NS_GetFuncStringContentList(nsINode* aRo
 
   NS_ADDREF(list);
 
   // Don't cache these lists globally
 
   return list;
 }
 
+already_AddRefed<nsContentList>
+NS_GetFuncStringNodeList(nsINode* aRootNode,
+                         nsContentListMatchFunc aFunc,
+                         nsContentListDestroyFunc aDestroyFunc,
+                         nsFuncStringContentListDataAllocator aDataAllocator,
+                         const nsAString& aString)
+{
+  return GetFuncStringContentList<nsCacheableFuncStringNodeList>(aRootNode,
+                                                                 aFunc,
+                                                                 aDestroyFunc,
+                                                                 aDataAllocator,
+                                                                 aString);
+}
+
+already_AddRefed<nsContentList>
+NS_GetFuncStringHTMLCollection(nsINode* aRootNode,
+                               nsContentListMatchFunc aFunc,
+                               nsContentListDestroyFunc aDestroyFunc,
+                               nsFuncStringContentListDataAllocator aDataAllocator,
+                               const nsAString& aString)
+{
+  return GetFuncStringContentList<nsCacheableFuncStringHTMLCollection>(aRootNode,
+                                                                       aFunc,
+                                                                       aDestroyFunc,
+                                                                       aDataAllocator,
+                                                                       aString);
+}
+
 // nsContentList implementation
 
 nsContentList::nsContentList(nsINode* aRootNode,
                              int32_t aMatchNameSpaceId,
                              nsIAtom* aHTMLMatchAtom,
                              nsIAtom* aXMLMatchAtom,
                              bool aDeep)
   : nsBaseContentList(),
@@ -634,16 +690,34 @@ nsContentList::GetNodeAt(uint32_t aIndex
 nsISupports*
 nsContentList::GetNamedItem(const nsAString& aName, nsWrapperCache **aCache)
 {
   nsIContent *item;
   *aCache = item = NamedItem(aName, true);
   return item;
 }
 
+JSObject*
+nsContentList::NamedItem(JSContext* cx, const nsAString& name,
+                         mozilla::ErrorResult& error)
+{
+  nsIContent *item = NamedItem(name, true);
+  if (!item) {
+    return nullptr;
+  }
+  JSObject* wrapper = GetWrapper();
+  JSAutoCompartment ac(cx, wrapper);
+  JS::Value v;
+  if (!mozilla::dom::WrapObject(cx, wrapper, item, item, nullptr, &v)) {
+    error.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+  return &v.toObject();
+}
+
 void
 nsContentList::AttributeChanged(nsIDocument *aDocument, Element* aElement,
                                 int32_t aNameSpaceID, nsIAtom* aAttribute,
                                 int32_t aModType)
 {
   NS_PRECONDITION(aElement, "Must have a content node to work with");
   
   if (!mFunc || !mFuncMayDependOnAttr || mState == LIST_DIRTY ||
--- a/content/base/src/nsContentList.h
+++ b/content/base/src/nsContentList.h
@@ -269,16 +269,18 @@ public:
   virtual int32_t IndexOf(nsIContent *aContent, bool aDoFlush);
   virtual int32_t IndexOf(nsIContent* aContent);
   virtual nsINode* GetParentObject()
   {
     return mRootNode;
   }
 
   virtual nsIContent* GetNodeAt(uint32_t aIndex);
+  virtual JSObject* NamedItem(JSContext* cx, const nsAString& name,
+                              mozilla::ErrorResult& error);
 
   // nsContentList public methods
   NS_HIDDEN_(uint32_t) Length(bool aDoFlush);
   NS_HIDDEN_(nsIContent*) Item(uint32_t aIndex, bool aDoFlush);
   NS_HIDDEN_(nsIContent*) NamedItem(const nsAString& aName, bool aDoFlush);
 
   // nsIMutationObserver
   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
@@ -474,53 +476,118 @@ private:
  * that case the destructor function should be a no-op.
  */
 typedef void* (*nsFuncStringContentListDataAllocator)(nsINode* aRootNode,
                                                       const nsString* aString);
 
 // aDestroyFunc is allowed to be null
 class nsCacheableFuncStringContentList : public nsContentList {
 public:
+  virtual ~nsCacheableFuncStringContentList();
+
+  bool Equals(const nsFuncStringCacheKey* aKey) {
+    return mRootNode == aKey->mRootNode && mFunc == aKey->mFunc &&
+      mString == aKey->mString;
+  }
+
+  bool AllocatedData() const { return !!mData; }
+
+#ifdef DEBUG
+  enum ContentListType {
+    eNodeList,
+    eHTMLCollection
+  };
+  ContentListType mType;
+#endif
+
+protected:
   nsCacheableFuncStringContentList(nsINode* aRootNode,
                                    nsContentListMatchFunc aFunc,
                                    nsContentListDestroyFunc aDestroyFunc,
                                    nsFuncStringContentListDataAllocator aDataAllocator,
                                    const nsAString& aString) :
     nsContentList(aRootNode, aFunc, aDestroyFunc, nullptr),
     mString(aString)
   {
     mData = (*aDataAllocator)(aRootNode, &mString);
   }
 
-  virtual ~nsCacheableFuncStringContentList();
-
-  bool Equals(const nsFuncStringCacheKey* aKey) {
-    return mRootNode == aKey->mRootNode && mFunc == aKey->mFunc &&
-      mString == aKey->mString;
-  }
-
-  bool AllocatedData() const { return !!mData; }
-protected:
   virtual void RemoveFromCaches() {
     RemoveFromFuncStringHashtable();
   }
   void RemoveFromFuncStringHashtable();
 
   nsString mString;
 };
 
+class nsCacheableFuncStringNodeList
+  : public nsCacheableFuncStringContentList
+{
+public:
+  nsCacheableFuncStringNodeList(nsINode* aRootNode,
+                                nsContentListMatchFunc aFunc,
+                                nsContentListDestroyFunc aDestroyFunc,
+                                nsFuncStringContentListDataAllocator aDataAllocator,
+                                const nsAString& aString)
+    : nsCacheableFuncStringContentList(aRootNode, aFunc, aDestroyFunc,
+                                       aDataAllocator, aString)
+  {
+#ifdef DEBUG
+    mType = eNodeList;
+#endif
+  }
+
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
+                               bool *triedToWrap);
+
+#ifdef DEBUG
+  static const ContentListType sType;
+#endif
+};
+
+class nsCacheableFuncStringHTMLCollection
+  : public nsCacheableFuncStringContentList
+{
+public:
+  nsCacheableFuncStringHTMLCollection(nsINode* aRootNode,
+                                      nsContentListMatchFunc aFunc,
+                                      nsContentListDestroyFunc aDestroyFunc,
+                                      nsFuncStringContentListDataAllocator aDataAllocator,
+                                      const nsAString& aString)
+    : nsCacheableFuncStringContentList(aRootNode, aFunc, aDestroyFunc,
+                                       aDataAllocator, aString)
+  {
+#ifdef DEBUG
+    mType = eHTMLCollection;
+#endif
+  }
+
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
+                               bool *triedToWrap);
+
+#ifdef DEBUG
+  static const ContentListType sType;
+#endif
+};
+
 // If aMatchNameSpaceId is kNameSpaceID_Unknown, this will return a
 // content list which matches ASCIIToLower(aTagname) against HTML
 // elements in HTML documents and aTagname against everything else.
 // For any other value of aMatchNameSpaceId, the list will match
 // aTagname against all elements.
 already_AddRefed<nsContentList>
 NS_GetContentList(nsINode* aRootNode,
                   int32_t aMatchNameSpaceId,
                   const nsAString& aTagname);
 
 already_AddRefed<nsContentList>
-NS_GetFuncStringContentList(nsINode* aRootNode,
-                            nsContentListMatchFunc aFunc,
-                            nsContentListDestroyFunc aDestroyFunc,
-                            nsFuncStringContentListDataAllocator aDataAllocator,
-                            const nsAString& aString);
+NS_GetFuncStringNodeList(nsINode* aRootNode,
+                         nsContentListMatchFunc aFunc,
+                         nsContentListDestroyFunc aDestroyFunc,
+                         nsFuncStringContentListDataAllocator aDataAllocator,
+                         const nsAString& aString);
+already_AddRefed<nsContentList>
+NS_GetFuncStringHTMLCollection(nsINode* aRootNode,
+                               nsContentListMatchFunc aFunc,
+                               nsContentListDestroyFunc aDestroyFunc,
+                               nsFuncStringContentListDataAllocator aDataAllocator,
+                               const nsAString& aString);
 #endif // nsContentList_h___
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -6253,20 +6253,20 @@ AllocClassMatchingInfo(nsINode* aRootNod
 nsresult
 nsContentUtils::GetElementsByClassName(nsINode* aRootNode,
                                        const nsAString& aClasses,
                                        nsIDOMNodeList** aReturn)
 {
   NS_PRECONDITION(aRootNode, "Must have root node");
   
   nsContentList* elements =
-    NS_GetFuncStringContentList(aRootNode, MatchClassNames,
-                                DestroyClassNameArray,
-                                AllocClassMatchingInfo,
-                                aClasses).get();
+    NS_GetFuncStringHTMLCollection(aRootNode, MatchClassNames,
+                                   DestroyClassNameArray,
+                                   AllocClassMatchingInfo,
+                                   aClasses).get();
   NS_ENSURE_TRUE(elements, NS_ERROR_OUT_OF_MEMORY);
 
   // Transfer ownership
   *aReturn = elements;
 
   return NS_OK;
 }
 
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -677,31 +677,31 @@ nsDOMFileList::WrapObject(JSContext *cx,
                           bool *triedToWrap)
 {
   return mozilla::dom::oldproxybindings::FileList::create(cx, scope, this, triedToWrap);
 }
 
 nsIDOMFile*
 nsDOMFileList::GetItemAt(uint32_t aIndex)
 {
-  return mFiles.SafeObjectAt(aIndex);
+  return Item(aIndex);
 }
 
 NS_IMETHODIMP
 nsDOMFileList::GetLength(uint32_t* aLength)
 {
-  *aLength = mFiles.Count();
+  *aLength = Length();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMFileList::Item(uint32_t aIndex, nsIDOMFile **aFile)
 {
-  NS_IF_ADDREF(*aFile = nsDOMFileList::GetItemAt(aIndex));
+  NS_IF_ADDREF(*aFile = Item(aIndex));
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////
 // nsDOMFileInternalUrlHolder implementation
 
 nsDOMFileInternalUrlHolder::nsDOMFileInternalUrlHolder(nsIDOMBlob* aFile,
--- a/content/base/src/nsDOMTokenList.cpp
+++ b/content/base/src/nsDOMTokenList.cpp
@@ -8,16 +8,17 @@
 
 #include "nsDOMTokenList.h"
 
 #include "nsAttrValue.h"
 #include "nsContentUtils.h"
 #include "nsError.h"
 #include "nsGenericElement.h"
 #include "dombindings.h"
+#include "mozilla/ErrorResult.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 nsDOMTokenList::nsDOMTokenList(nsGenericElement* aElement, nsIAtom* aAttrAtom)
   : mElement(aElement),
     mAttrAtom(aAttrAtom)
 {
@@ -44,41 +45,52 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMTok
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMTokenList)
 
 void
 nsDOMTokenList::DropReference()
 {
   mElement = nullptr;
 }
 
-NS_IMETHODIMP
-nsDOMTokenList::GetLength(uint32_t *aLength)
+uint32_t
+nsDOMTokenList::Length()
 {
   const nsAttrValue* attr = GetParsedAttr();
   if (!attr) {
-    *aLength = 0;
-    return NS_OK;
+    return 0;
   }
 
-  *aLength = attr->GetAtomCount();
+  return attr->GetAtomCount();
+}
+
+NS_IMETHODIMP
+nsDOMTokenList::GetLength(uint32_t *aLength)
+{
+  *aLength = Length();
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsDOMTokenList::Item(uint32_t aIndex, nsAString& aResult)
+void
+nsDOMTokenList::IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aResult)
 {
   const nsAttrValue* attr = GetParsedAttr();
 
-  if (!attr || aIndex >= static_cast<uint32_t>(attr->GetAtomCount())) {
-    SetDOMStringToNull(aResult);
-    return NS_OK;
+  if (attr && aIndex < static_cast<uint32_t>(attr->GetAtomCount())) {
+    aFound = true;
+    attr->AtomAt(aIndex)->ToString(aResult);
+  } else {
+    aFound = false;
   }
-  attr->AtomAt(aIndex)->ToString(aResult);
+}
 
+NS_IMETHODIMP
+nsDOMTokenList::MozItem(uint32_t aIndex, nsAString& aResult)
+{
+  Item(aIndex, aResult);
   return NS_OK;
 }
 
 nsresult
 nsDOMTokenList::CheckToken(const nsAString& aStr)
 {
   if (aStr.IsEmpty()) {
     return NS_ERROR_DOM_SYNTAX_ERR;
@@ -92,31 +104,34 @@ nsDOMTokenList::CheckToken(const nsAStri
     if (nsContentUtils::IsHTMLWhitespace(*iter))
       return NS_ERROR_DOM_INVALID_CHARACTER_ERR;
     ++iter;
   }
 
   return NS_OK;
 }
 
+bool
+nsDOMTokenList::Contains(const nsAString& aToken, ErrorResult& aError)
+{
+  aError = CheckToken(aToken);
+  if (aError.Failed()) {
+    return false;
+  }
+
+  const nsAttrValue* attr = GetParsedAttr();
+  return attr && attr->Contains(aToken);
+}
+
 NS_IMETHODIMP
 nsDOMTokenList::Contains(const nsAString& aToken, bool* aResult)
 {
-  nsresult rv = CheckToken(aToken);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  const nsAttrValue* attr = GetParsedAttr();
-  if (!attr) {
-    *aResult = false;
-    return NS_OK;
-  }
-
-  *aResult = attr->Contains(aToken);
-
-  return NS_OK;
+  ErrorResult rv;
+  *aResult = Contains(aToken, rv);
+  return rv.ErrorCode();
 }
 
 void
 nsDOMTokenList::AddInternal(const nsAttrValue* aAttr,
                             const nsAString& aToken)
 {
   if (!mElement) {
     return;
@@ -133,31 +148,39 @@ nsDOMTokenList::AddInternal(const nsAttr
           resultStr.CharAt(resultStr.Length() - 1))) {
     resultStr.Append(NS_LITERAL_STRING(" ") + aToken);
   } else {
     resultStr.Append(aToken);
   }
   mElement->SetAttr(kNameSpaceID_None, mAttrAtom, resultStr, true);
 }
 
-NS_IMETHODIMP
-nsDOMTokenList::Add(const nsAString& aToken)
+void
+nsDOMTokenList::Add(const nsAString& aToken, ErrorResult& aError)
 {
-  nsresult rv = CheckToken(aToken);
-  NS_ENSURE_SUCCESS(rv, rv);
+  aError = CheckToken(aToken);
+  if (aError.Failed()) {
+    return;
+  }
 
   const nsAttrValue* attr = GetParsedAttr();
 
   if (attr && attr->Contains(aToken)) {
-    return NS_OK;
+    return;
   }
 
   AddInternal(attr, aToken);
+}
 
-  return NS_OK;
+NS_IMETHODIMP
+nsDOMTokenList::Add(const nsAString& aToken)
+{
+  ErrorResult rv;
+  Add(aToken, rv);
+  return rv.ErrorCode();
 }
 
 void
 nsDOMTokenList::RemoveInternal(const nsAttrValue* aAttr,
                                const nsAString& aToken)
 {
   NS_ABORT_IF_FALSE(aAttr, "Need an attribute");
 
@@ -212,65 +235,82 @@ nsDOMTokenList::RemoveInternal(const nsA
       output.Append(Substring(copyStart, iter));
       copyStart = iter;
     }
   }
 
   mElement->SetAttr(kNameSpaceID_None, mAttrAtom, output, true);
 }
 
+void
+nsDOMTokenList::Remove(const nsAString& aToken, ErrorResult& aError)
+{
+  aError = CheckToken(aToken);
+  if (aError.Failed()) {
+    return;
+  }
+
+  const nsAttrValue* attr = GetParsedAttr();
+  if (!attr || !attr->Contains(aToken)) {
+    return;
+  }
+
+  RemoveInternal(attr, aToken);
+}
+
 NS_IMETHODIMP
 nsDOMTokenList::Remove(const nsAString& aToken)
 {
-  nsresult rv = CheckToken(aToken);
-  NS_ENSURE_SUCCESS(rv, rv);
+  ErrorResult rv;
+  Remove(aToken, rv);
+  return rv.ErrorCode();
+}
 
-  const nsAttrValue* attr = GetParsedAttr();
-  if (!attr) {
-    return NS_OK;
+bool
+nsDOMTokenList::Toggle(const nsAString& aToken, ErrorResult& aError)
+{
+  aError = CheckToken(aToken);
+  if (aError.Failed()) {
+    return false;
   }
 
-  if (!attr->Contains(aToken)) {
-    return NS_OK;
+  const nsAttrValue* attr = GetParsedAttr();
+
+  if (attr && attr->Contains(aToken)) {
+    RemoveInternal(attr, aToken);
+    return false;
   }
 
-  RemoveInternal(attr, aToken);
-
-  return NS_OK;
+  AddInternal(attr, aToken);
+  return true;
 }
 
 NS_IMETHODIMP
 nsDOMTokenList::Toggle(const nsAString& aToken, bool* aResult)
 {
-  nsresult rv = CheckToken(aToken);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  const nsAttrValue* attr = GetParsedAttr();
+  ErrorResult rv;
+  *aResult = Toggle(aToken, rv);
+  return rv.ErrorCode();
+}
 
-  if (attr && attr->Contains(aToken)) {
-    RemoveInternal(attr, aToken);
-    *aResult = false;
-  } else {
-    AddInternal(attr, aToken);
-    *aResult = true;
+void
+nsDOMTokenList::Stringify(nsAString& aResult)
+{
+  if (!mElement) {
+    aResult.Truncate();
+    return;
   }
 
-  return NS_OK;
+  mElement->GetAttr(kNameSpaceID_None, mAttrAtom, aResult);
 }
 
 NS_IMETHODIMP
 nsDOMTokenList::ToString(nsAString& aResult)
 {
-  if (!mElement) {
-    aResult.Truncate();
-    return NS_OK;
-  }
-
-  mElement->GetAttr(kNameSpaceID_None, mAttrAtom, aResult);
-
+  Stringify(aResult);
   return NS_OK;
 }
 
 JSObject*
 nsDOMTokenList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
 {
   return mozilla::dom::oldproxybindings::DOMTokenList::create(cx, scope, this,
                                                      triedToWrap);
--- a/content/base/src/nsDOMTokenList.h
+++ b/content/base/src/nsDOMTokenList.h
@@ -7,16 +7,19 @@
  */
 
 #ifndef nsDOMTokenList_h___
 #define nsDOMTokenList_h___
 
 #include "nsGenericElement.h"
 #include "nsIDOMDOMTokenList.h"
 
+namespace mozilla {
+class ErrorResult;
+}
 class nsAttrValue;
 
 // nsISupports must be on the primary inheritance chain 
 // because nsDOMSettableTokenList is traversed by nsGenericElement.
 class nsDOMTokenList : public nsIDOMDOMTokenList,
                        public nsWrapperCache
 {
 public:
@@ -38,16 +41,32 @@ public:
 
   const nsAttrValue* GetParsedAttr() {
     if (!mElement) {
       return nullptr;
     }
     return mElement->GetAttrInfo(kNameSpaceID_None, mAttrAtom).mValue;
   }
 
+  uint32_t Length();
+  void Item(uint32_t aIndex, nsAString& aResult)
+  {
+    bool found;
+    IndexedGetter(aIndex, found, aResult);
+    if (!found) {
+      SetDOMStringToNull(aResult);
+    }
+  }
+  void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aResult);
+  bool Contains(const nsAString& aToken, mozilla::ErrorResult& aError);
+  void Add(const nsAString& aToken, mozilla::ErrorResult& aError);
+  void Remove(const nsAString& aToken, mozilla::ErrorResult& aError);
+  bool Toggle(const nsAString& aToken, mozilla::ErrorResult& aError);
+  void Stringify(nsAString& aResult);
+
 protected:
   virtual ~nsDOMTokenList();
 
   nsresult CheckToken(const nsAString& aStr);
   void AddInternal(const nsAttrValue* aAttr, const nsAString& aToken);
   void RemoveInternal(const nsAttrValue* aAttr, const nsAString& aToken);
 
   nsGenericElement* mElement;
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/src/nsGenericElement.h
@@ -25,23 +25,23 @@
 #include "nsDOMAttributeMap.h"
 #include "nsIWeakReference.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIDocument.h"
 #include "nsIDOMNodeSelector.h"
 #include "nsIDOMXPathNSResolver.h"
 #include "nsPresContext.h"
 #include "nsIDOMDOMStringMap.h"
-#include "nsContentList.h"
 #include "nsDOMClassInfoID.h" // DOMCI_DATA
 #include "nsIDOMTouchEvent.h"
 #include "nsIInlineEventHandlers.h"
 #include "mozilla/CORSMode.h"
 #include "mozilla/Attributes.h"
 #include "nsContentUtils.h"
+#include "nsINodeList.h"
 #include "nsISMILAttr.h"
 
 class nsIDOMAttr;
 class nsIDOMEventListener;
 class nsIFrame;
 class nsIDOMNamedNodeMap;
 class nsICSSDeclaration;
 class nsIDOMCSSStyleDeclaration;
--- a/content/base/src/nsTextNode.cpp
+++ b/content/base/src/nsTextNode.cpp
@@ -8,16 +8,17 @@
  */
 
 #include "nsTextNode.h"
 #include "nsContentUtils.h"
 #include "nsIDOMEventListener.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsIDocument.h"
 #include "nsThreadUtils.h"
+#include "nsStubMutationObserver.h"
 #ifdef DEBUG
 #include "nsRange.h"
 #endif
 
 using namespace mozilla::dom;
 
 /**
  * class used to implement attr() generated content
--- a/content/events/src/nsPaintRequest.cpp
+++ b/content/events/src/nsPaintRequest.cpp
@@ -61,24 +61,24 @@ NS_INTERFACE_TABLE_HEAD(nsPaintRequestLi
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPaintRequestList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPaintRequestList)
 
 NS_IMETHODIMP    
 nsPaintRequestList::GetLength(uint32_t* aLength)
 {
-  *aLength = mArray.Count();
+  *aLength = Length();
   return NS_OK;
 }
 
 NS_IMETHODIMP    
 nsPaintRequestList::Item(uint32_t aIndex, nsIDOMPaintRequest** aReturn)
 {
-  NS_IF_ADDREF(*aReturn = nsPaintRequestList::GetItemAt(aIndex));
+  NS_IF_ADDREF(*aReturn = Item(aIndex));
   return NS_OK;
 }
 
 nsIDOMPaintRequest*
 nsPaintRequestList::GetItemAt(uint32_t aIndex)
 {
-  return mArray.SafeObjectAt(aIndex);
+  return Item(aIndex);
 }
--- a/content/events/src/nsPaintRequest.h
+++ b/content/events/src/nsPaintRequest.h
@@ -69,16 +69,31 @@ public:
       NS_ASSERTION(list_qi == static_cast<nsIDOMPaintRequestList*>(aSupports),
                    "Uh, fix QI!");
     }
 #endif
 
     return static_cast<nsPaintRequestList*>(aSupports);
   }
 
+  uint32_t Length()
+  {
+    return mArray.Count();
+  }
+
+  nsIDOMPaintRequest* Item(uint32_t aIndex)
+  {
+    return mArray.SafeObjectAt(aIndex);
+  }
+  nsIDOMPaintRequest* IndexedGetter(uint32_t aIndex, bool& aFound)
+  {
+    aFound = aIndex < static_cast<uint32_t>(mArray.Count());
+    return aFound ? mArray.ObjectAt(aIndex) : nullptr;
+  }
+
 private:
   ~nsPaintRequestList() {}
 
   nsCOMArray<nsIDOMPaintRequest> mArray;
   nsCOMPtr<nsIDOMEvent> mParent;
 };
 
 #endif /*NSPAINTREQUEST_H_*/
--- a/content/html/content/public/nsIHTMLCollection.h
+++ b/content/html/content/public/nsIHTMLCollection.h
@@ -2,34 +2,68 @@
 /* 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 nsIHTMLCollection_h___
 #define nsIHTMLCollection_h___
 
 #include "nsIDOMHTMLCollection.h"
+#include "nsWrapperCache.h"
 
+struct JSContext;
+struct JSObject;
 class nsINode;
-class nsWrapperCache;
+namespace mozilla {
+class ErrorResult;
+}
 
 // IID for the nsIHTMLCollection interface
 #define NS_IHTMLCOLLECTION_IID \
-{ 0xdea91ad6, 0x57d1, 0x4e7a, \
- { 0xb5, 0x5a, 0xdb, 0xfc, 0x36, 0x7b, 0xc8, 0x22 } }
+{ 0x5c6012c3, 0xa816, 0x4f28, \
+ { 0xab, 0x93, 0xe9, 0x8a, 0x36, 0x16, 0x88, 0xf2 } }
 
 /**
  * An internal interface
  */
 class nsIHTMLCollection : public nsIDOMHTMLCollection
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IHTMLCOLLECTION_IID)
 
   /**
    * Get the root node for this HTML collection.
    */
   virtual nsINode* GetParentObject() = 0;
+
+  using nsIDOMHTMLCollection::Item;
+  using nsIDOMHTMLCollection::NamedItem;
+
+  uint32_t Length()
+  {
+    uint32_t length;
+    GetLength(&length);
+    return length;
+  }
+  nsGenericElement* Item(uint32_t index)
+  {
+    return GetElementAt(index);
+  }
+  nsGenericElement* IndexedGetter(uint32_t index, bool& aFound)
+  {
+    nsGenericElement* item = Item(index);
+    aFound = !!item;
+    return item;
+  }
+  virtual JSObject* NamedItem(JSContext* cx, const nsAString& name,
+                              mozilla::ErrorResult& error) = 0;
+  JSObject* NamedGetter(JSContext* cx, const nsAString& name,
+                        bool& found, mozilla::ErrorResult& error)
+  {
+    JSObject* namedItem = NamedItem(cx, name, error);
+    found = !!namedItem;
+    return namedItem;
+  }
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIHTMLCollection, NS_IHTMLCOLLECTION_IID)
 
 #endif /* nsIHTMLCollection_h___ */
--- a/content/html/content/src/HTMLPropertiesCollection.cpp
+++ b/content/html/content/src/HTMLPropertiesCollection.cpp
@@ -7,16 +7,18 @@
 #include "HTMLPropertiesCollection.h"
 #include "dombindings.h"
 #include "nsIDocument.h"
 #include "nsContentUtils.h"
 #include "nsGenericHTMLElement.h"
 #include "nsVariant.h"
 #include "nsDOMSettableTokenList.h"
 #include "nsAttrValue.h"
+#include "mozilla/ErrorResult.h"
+#include "nsWrapperCacheInlines.h"
 
 DOMCI_DATA(HTMLPropertiesCollection, mozilla::dom::HTMLPropertiesCollection)
 DOMCI_DATA(PropertyNodeList, mozilla::dom::PropertyNodeList)
 
 namespace mozilla {
 namespace dom {
 
 static PLDHashOperator
@@ -118,37 +120,48 @@ HTMLPropertiesCollection::GetLength(uint
   EnsureFresh();
   *aLength = mProperties.Length();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLPropertiesCollection::Item(uint32_t aIndex, nsIDOMNode** aResult)
 {
-  EnsureFresh();
-  nsGenericHTMLElement* property = mProperties.SafeElementAt(aIndex);
-  *aResult = property ? property->AsDOMNode() : NULL;
-  NS_IF_ADDREF(*aResult);
+  nsINode* result = nsIHTMLCollection::Item(aIndex);
+  if (result) {
+    NS_ADDREF(*aResult = result->AsDOMNode());
+  } else {
+    *aResult = nullptr;
+  }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLPropertiesCollection::NamedItem(const nsAString& aName,
                                     nsIDOMNode** aResult)
 {
   *aResult = NULL;
   return NS_OK;
 }
 
+JSObject*
+HTMLPropertiesCollection::NamedItem(JSContext* cx, const nsAString& name,
+                                    mozilla::ErrorResult& error)
+{
+  // HTMLPropertiesCollection.namedItem and the named getter call the NamedItem
+  // that returns a PropertyNodeList, calling HTMLCollection.namedItem doesn't
+  // make sense so this returns null.
+  return nullptr;
+}
+
 nsISupports*
 HTMLPropertiesCollection::GetNamedItem(const nsAString& aName,
                                        nsWrapperCache **aCache)
 {
-  EnsureFresh();
-  if (!mNames->ContainsInternal(aName)) {
+  if (!IsSupportedNamedProperty(aName)) {
     *aCache = NULL;
     return NULL;
   }
 
   nsRefPtr<PropertyNodeList> propertyList;
   if (!mNamedItemEntries.Get(aName, getter_AddRefs(propertyList))) {
     propertyList = new PropertyNodeList(this, mRoot, aName);
     mNamedItemEntries.Put(aName, propertyList);
@@ -165,36 +178,43 @@ HTMLPropertiesCollection::GetElementAt(u
 }
 
 nsINode*
 HTMLPropertiesCollection::GetParentObject()
 {
   return mRoot;
 }
 
+PropertyNodeList*
+HTMLPropertiesCollection::NamedItem(const nsAString& aName)
+{
+  EnsureFresh();
+
+  PropertyNodeList* propertyList = mNamedItemEntries.GetWeak(aName);
+  if (!propertyList) {
+    nsRefPtr<PropertyNodeList> newPropertyList =
+      new PropertyNodeList(this, mRoot, aName);
+    mNamedItemEntries.Put(aName, newPropertyList);
+    propertyList = newPropertyList;
+  }
+  return propertyList;
+}
+
 NS_IMETHODIMP
 HTMLPropertiesCollection::NamedItem(const nsAString& aName,
                                     nsIDOMPropertyNodeList** aResult)
 {
-  EnsureFresh();
- 
-  nsRefPtr<PropertyNodeList> propertyList;
-  if (!mNamedItemEntries.Get(aName, getter_AddRefs(propertyList))) {
-    propertyList = new PropertyNodeList(this, mRoot, aName);
-    mNamedItemEntries.Put(aName, propertyList);
-  }
-  propertyList.forget(aResult);
+  NS_ADDREF(*aResult = NamedItem(aName));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLPropertiesCollection::GetNames(nsIDOMDOMStringList** aResult)
 {
-  EnsureFresh();
-  NS_ADDREF(*aResult = mNames);
+  NS_ADDREF(*aResult = Names());
   return NS_OK;
 }
 
 void
 HTMLPropertiesCollection::AttributeChanged(nsIDocument *aDocument, Element* aElement,
                                            int32_t aNameSpaceID, nsIAtom* aAttribute,
                                            int32_t aModType)
 {
@@ -459,16 +479,34 @@ NS_INTERFACE_TABLE_HEAD(PropertyNodeList
                         nsIDOMPropertyNodeList,
                         nsIDOMNodeList,
                         nsINodeList,
                         nsIMutationObserver)
     NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(PropertyNodeList)
     NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(PropertyNodeList)
 NS_INTERFACE_MAP_END
 
+void
+PropertyNodeList::GetValues(JSContext* aCx, nsTArray<JS::Value >& aResult,
+                            ErrorResult& aError)
+{
+  EnsureFresh();
+
+  JSObject* wrapper = GetWrapper();
+  JSAutoCompartment ac(aCx, wrapper);
+  uint32_t length = mElements.Length();
+  for (uint32_t i = 0; i < length; ++i) {
+    JS::Value v = mElements.ElementAt(i)->GetItemValue(aCx, wrapper, aError);
+    if (aError.Failed()) {
+      return;
+    }
+    aResult.AppendElement(v);
+  }
+}
+
 NS_IMETHODIMP
 PropertyNodeList::GetValues(nsIVariant** aValues)
 {
   EnsureFresh();
   nsCOMPtr<nsIWritableVariant> out = new nsVariant();
 
   // We have to use an nsTArray<nsIVariant*> here and do manual refcounting because 
   // nsWritableVariant::SetAsArray takes an nsIVariant**.
--- a/content/html/content/src/HTMLPropertiesCollection.h
+++ b/content/html/content/src/HTMLPropertiesCollection.h
@@ -40,33 +40,46 @@ public:
   NS_DECL_NSIDOMDOMSTRINGLIST
 
   bool ContainsInternal(const nsAString& aString);
 
 protected:
   nsRefPtr<HTMLPropertiesCollection> mCollection;
 };
 
-class HTMLPropertiesCollection : public nsIDOMHTMLPropertiesCollection,
+class HTMLPropertiesCollection : public nsIHTMLCollection,
+                                 public nsIDOMHTMLPropertiesCollection,
                                  public nsStubMutationObserver,
-                                 public nsWrapperCache,
-                                 public nsIHTMLCollection
+                                 public nsWrapperCache
 {
   friend class PropertyNodeList;
   friend class PropertyStringList;
 public:
   HTMLPropertiesCollection(nsGenericHTMLElement* aRoot);
   virtual ~HTMLPropertiesCollection();
 
   virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap);
 
   NS_IMETHOD NamedItem(const nsAString& aName, nsIDOMNode** aResult);
   void SetDocument(nsIDocument* aDocument);
   nsINode* GetParentObject();
+  virtual JSObject* NamedItem(JSContext* cx, const nsAString& name,
+                              mozilla::ErrorResult& error);
+  PropertyNodeList* NamedItem(const nsAString& aName);
+  PropertyNodeList* NamedGetter(const nsAString& aName, bool& aFound)
+  {
+    aFound = IsSupportedNamedProperty(aName);
+    return aFound ? NamedItem(aName) : nullptr;
+  }
+  nsDOMStringList* Names()
+  {
+    EnsureFresh();
+    return mNames;
+  }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_NSIDOMHTMLPROPERTIESCOLLECTION
 
   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
@@ -81,16 +94,22 @@ protected:
   void EnsureFresh();
   
   // Crawl the properties of mRoot, following any itemRefs it may have
   void CrawlProperties();
 
   // Crawl startNode and its descendants, looking for items
   void CrawlSubtree(Element* startNode);
 
+  bool IsSupportedNamedProperty(const nsAString& aName)
+  {
+    EnsureFresh();
+    return mNames->ContainsInternal(aName);
+  }
+
   // the items that make up this collection
   nsTArray<nsRefPtr<nsGenericHTMLElement> > mProperties; 
   
   // the itemprop attribute of the properties
   nsRefPtr<PropertyStringList> mNames; 
  
   // The cached PropertyNodeLists that are NamedItems of this collection 
   nsRefPtrHashtable<nsStringHashKey, PropertyNodeList> mNamedItemEntries;
@@ -114,16 +133,19 @@ public:
                    nsIContent* aRoot, const nsAString& aName);
   virtual ~PropertyNodeList();
 
   virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap);
 
   void SetDocument(nsIDocument* aDocument);
 
+  void GetValues(JSContext* aCx, nsTArray<JS::Value >& aResult,
+                 ErrorResult& aError);
+
   NS_DECL_NSIDOMPROPERTYNODELIST
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(PropertyNodeList,
                                                          nsINodeList)
 
   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
--- a/content/html/content/src/nsClientRect.cpp
+++ b/content/html/content/src/nsClientRect.cpp
@@ -81,31 +81,31 @@ NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsClientRectList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsClientRectList)
 
 
 NS_IMETHODIMP    
 nsClientRectList::GetLength(uint32_t* aLength)
 {
-  *aLength = mArray.Count();
+  *aLength = Length();
   return NS_OK;
 }
 
 NS_IMETHODIMP    
 nsClientRectList::Item(uint32_t aIndex, nsIDOMClientRect** aReturn)
 {
-  NS_IF_ADDREF(*aReturn = nsClientRectList::GetItemAt(aIndex));
+  NS_IF_ADDREF(*aReturn = Item(aIndex));
   return NS_OK;
 }
 
 nsIDOMClientRect*
 nsClientRectList::GetItemAt(uint32_t aIndex)
 {
-  return mArray.SafeObjectAt(aIndex);
+  return Item(aIndex);
 }
 
 JSObject*
 nsClientRectList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
 {
   return mozilla::dom::oldproxybindings::ClientRectList::create(cx, scope, this,
                                                        triedToWrap);
 }
--- a/content/html/content/src/nsClientRect.h
+++ b/content/html/content/src/nsClientRect.h
@@ -69,16 +69,30 @@ public:
       NS_ASSERTION(list_qi == static_cast<nsIDOMClientRectList*>(aSupports),
                    "Uh, fix QI!");
     }
 #endif
 
     return static_cast<nsClientRectList*>(aSupports);
   }
 
+  uint32_t Length()
+  {
+    return mArray.Count();
+  }
+  nsIDOMClientRect* Item(uint32_t aIndex)
+  {
+    return mArray.SafeObjectAt(aIndex);
+  }
+  nsIDOMClientRect* IndexedGetter(uint32_t aIndex, bool& aFound)
+  {
+    aFound = aIndex < static_cast<uint32_t>(mArray.Count());
+    return aFound ? mArray.ObjectAt(aIndex) : nullptr;
+  }
+
 protected:
   virtual ~nsClientRectList() {}
 
   nsCOMArray<nsIDOMClientRect> mArray;
   nsCOMPtr<nsISupports> mParent;
 };
 
 #endif /*NSCLIENTRECT_H_*/
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -89,16 +89,18 @@
 #include "mozilla/dom/FromParser.h"
 #include "mozilla/BloomFilter.h"
 
 #include "HTMLPropertiesCollection.h"
 #include "nsVariant.h"
 #include "nsDOMSettableTokenList.h"
 #include "nsThreadUtils.h"
 #include "nsTextFragment.h"
+#include "mozilla/dom/BindingUtils.h"
+#include "mozilla/ErrorResult.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::directionality;
 
 class nsINodeInfo;
 class nsIDOMNodeList;
 class nsRuleWalker;
@@ -4156,16 +4158,45 @@ nsGenericHTMLElement::ChangeEditableStat
   // We might as well wrap it all in one script blocker.
   nsAutoScriptBlocker scriptBlocker;
   MakeContentDescendantsEditable(this, document);
 }
 
 NS_IMPL_BOOL_ATTR(nsGenericHTMLElement, ItemScope, itemscope)
 NS_IMPL_URI_ATTR(nsGenericHTMLElement, ItemId, itemid)
 
+JS::Value
+nsGenericHTMLElement::GetItemValue(JSContext* aCx, JSObject* aScope,
+                                   ErrorResult& error)
+{
+  if (!HasAttr(kNameSpaceID_None, nsGkAtoms::itemprop)) {
+    return JS::NullValue();
+  }
+
+  bool itemScope;
+  GetItemScope(&itemScope);
+  if (itemScope) {
+    JS::Value v;
+    if (!mozilla::dom::WrapObject(aCx, aScope, this, &v)) {
+      error.Throw(NS_ERROR_FAILURE);
+      return JS::UndefinedValue();
+    }
+    return v;
+  }
+
+  nsString string;
+  GetItemValueText(string);
+  JS::Value v;
+  if (!xpc::NonVoidStringToJsval(aCx, string, &v)) {
+    error.Throw(NS_ERROR_FAILURE);
+    return JS::UndefinedValue();
+  }
+  return v;
+}
+
 NS_IMETHODIMP
 nsGenericHTMLElement::GetItemValue(nsIVariant** aValue)
 {
   nsCOMPtr<nsIWritableVariant> out = new nsVariant();
 
   if (!HasAttr(kNameSpaceID_None, nsGkAtoms::itemprop)) {
     out->SetAsEmpty();
     out.forget(aValue);
@@ -4290,33 +4321,33 @@ nsGenericHTMLElement::SetItemType(nsIVar
 {
   nsDOMSettableTokenList* itemType = GetTokenList(nsGkAtoms::itemtype);
   nsAutoString string;
   aValue->GetAsAString(string);
   return itemType->SetValue(string);
 }
 
 static void
-nsIDOMHTMLPropertiesCollectionDestructor(void *aObject, nsIAtom *aProperty,
-                                         void *aPropertyValue, void *aData)
+HTMLPropertiesCollectionDestructor(void *aObject, nsIAtom *aProperty,
+                                   void *aPropertyValue, void *aData)
 {
-  nsIDOMHTMLPropertiesCollection* properties = 
-    static_cast<nsIDOMHTMLPropertiesCollection*>(aPropertyValue);
+  HTMLPropertiesCollection* properties = 
+    static_cast<HTMLPropertiesCollection*>(aPropertyValue);
   NS_IF_RELEASE(properties);
 }
 
 NS_IMETHODIMP
 nsGenericHTMLElement::GetProperties(nsIDOMHTMLPropertiesCollection** aReturn)
 {
-  nsIDOMHTMLPropertiesCollection* properties = 
-    static_cast<nsIDOMHTMLPropertiesCollection*>(GetProperty(nsGkAtoms::microdataProperties));
+  HTMLPropertiesCollection* properties = 
+    static_cast<HTMLPropertiesCollection*>(GetProperty(nsGkAtoms::microdataProperties));
   if (!properties) {
      properties = new HTMLPropertiesCollection(this);
      NS_ADDREF(properties);
-     SetProperty(nsGkAtoms::microdataProperties, properties, nsIDOMHTMLPropertiesCollectionDestructor);
+     SetProperty(nsGkAtoms::microdataProperties, properties, HTMLPropertiesCollectionDestructor);
   }
   NS_ADDREF(*aReturn = properties);
   return NS_OK;
 }
 
 nsSize
 nsGenericHTMLElement::GetWidthHeightForImage(imgIRequest *aImageRequest)
 {
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -30,16 +30,19 @@ class nsIEditor;
 struct nsRect;
 struct nsSize;
 class nsHTMLFormElement;
 class nsIDOMDOMStringMap;
 class nsIDOMHTMLMenuElement;
 class nsIDOMHTMLCollection;
 class nsDOMSettableTokenList;
 class nsIDOMHTMLPropertiesCollection;
+namespace mozilla {
+class ErrorResult;
+}
 
 typedef nsMappedAttributeElement nsGenericHTMLElementBase;
 
 /**
  * A common superclass for HTML elements
  */
 class nsGenericHTMLElement : public nsGenericHTMLElementBase
 {
@@ -116,16 +119,18 @@ public:
   NS_IMETHOD SetHidden(bool aHidden);
   NS_IMETHOD GetSpellcheck(bool* aSpellcheck);
   NS_IMETHOD SetSpellcheck(bool aSpellcheck);
   NS_IMETHOD GetDraggable(bool* aDraggable);
   NS_IMETHOD SetDraggable(bool aDraggable);
   NS_IMETHOD GetItemScope(bool* aItemScope);
   NS_IMETHOD SetItemScope(bool aItemScope);
   NS_IMETHOD GetItemValue(nsIVariant** aValue);
+  JS::Value GetItemValue(JSContext* aCx, JSObject* aScope,
+                         mozilla::ErrorResult& error);
   NS_IMETHOD SetItemValue(nsIVariant* aValue);
 protected:
   // These methods are used to implement element-specific behavior of Get/SetItemValue
   // when an element has @itemprop but no @itemscope.
   virtual void GetItemValueText(nsAString& text);
   virtual void SetItemValueText(const nsAString& text);
   nsDOMSettableTokenList* GetTokenList(nsIAtom* aAtom);
 public:
--- a/content/html/content/src/nsHTMLDataListElement.cpp
+++ b/content/html/content/src/nsHTMLDataListElement.cpp
@@ -3,16 +3,17 @@
  * 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 "nsIDOMHTMLDataListElement.h"
 #include "nsGenericHTMLElement.h"
 #include "nsIDOMEventTarget.h"
 #include "nsGkAtoms.h"
 #include "nsIDOMHTMLOptionElement.h"
+#include "nsContentList.h"
 
 
 class nsHTMLDataListElement : public nsGenericHTMLElement,
                               public nsIDOMHTMLDataListElement
 {
 public:
   nsHTMLDataListElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLDataListElement();
--- a/content/html/content/src/nsHTMLFieldSetElement.cpp
+++ b/content/html/content/src/nsHTMLFieldSetElement.cpp
@@ -6,16 +6,17 @@
 #include "nsHTMLFieldSetElement.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIDOMEventTarget.h"
 #include "nsStyleConsts.h"
 #include "nsIForm.h"
 #include "nsIFormControl.h"
 #include "nsGUIEvent.h"
 #include "nsEventDispatcher.h"
+#include "nsContentList.h"
 
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(FieldSet)
 
 
 nsHTMLFieldSetElement::nsHTMLFieldSetElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericHTMLFormElement(aNodeInfo)
   , mElements(nullptr)
--- a/content/html/content/src/nsHTMLFormElement.cpp
+++ b/content/html/content/src/nsHTMLFormElement.cpp
@@ -48,16 +48,17 @@
 #include "mozAutoDocUpdate.h"
 #include "nsIHTMLCollection.h"
 
 #include "nsIConstraintValidation.h"
 
 #include "nsIDOMHTMLButtonElement.h"
 #include "dombindings.h"
 #include "nsSandboxFlags.h"
+#include "mozilla/dom/BindingUtils.h"
 
 using namespace mozilla::dom;
 
 static const int NS_FORM_CONTROL_LIST_HASHTABLE_SIZE = 16;
 
 static const uint8_t NS_FORM_AUTOCOMPLETE_ON  = 1;
 static const uint8_t NS_FORM_AUTOCOMPLETE_OFF = 0;
 
@@ -92,16 +93,19 @@ public:
   // nsIDOMHTMLCollection interface
   NS_DECL_NSIDOMHTMLCOLLECTION
 
   virtual nsINode* GetParentObject()
   {
     return mForm;
   }
 
+  virtual JSObject* NamedItem(JSContext* cx, const nsAString& name,
+                              mozilla::ErrorResult& error);
+
   nsresult AddElementToTable(nsGenericHTMLFormElement* aChild,
                              const nsAString& aName);
   nsresult RemoveElementFromTable(nsGenericHTMLFormElement* aChild,
                                   const nsAString& aName);
   nsresult IndexOfControl(nsIFormControl* aControl,
                           int32_t* aIndex);
 
   nsISupports* NamedItemInternal(const nsAString& aName, bool aFlushContent);
@@ -2522,8 +2526,26 @@ nsFormControlList::GetElementAt(uint32_t
 
 nsISupports*
 nsFormControlList::GetNamedItem(const nsAString& aName, nsWrapperCache **aCache)
 {
   nsISupports *item = NamedItemInternal(aName, true);
   *aCache = nullptr;
   return item;
 }
+
+JSObject*
+nsFormControlList::NamedItem(JSContext* cx, const nsAString& name,
+                             mozilla::ErrorResult& error)
+{
+  nsISupports *item = NamedItemInternal(name, true);
+  if (!item) {
+    return nullptr;
+  }
+  JSObject* wrapper = GetWrapper();
+  JSAutoCompartment ac(cx, wrapper);
+  JS::Value v;
+  if (!mozilla::dom::WrapObject(cx, wrapper, item, &v)) {
+    error.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+  return &v.toObject();
+}
--- a/content/html/content/src/nsHTMLOptGroupElement.cpp
+++ b/content/html/content/src/nsHTMLOptGroupElement.cpp
@@ -1,80 +1,26 @@
 /* -*- 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 "nsIDOMHTMLOptGroupElement.h"
+#include "nsHTMLOptGroupElement.h"
 #include "nsIDOMEventTarget.h"
-#include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsIFrame.h"
 #include "nsIFormControlFrame.h"
 #include "nsEventStates.h"
 
 #include "nsEventDispatcher.h"
 #include "nsHTMLSelectElement.h"
 
 /**
  * The implementation of &lt;optgroup&gt;
  */
-class nsHTMLOptGroupElement : public nsGenericHTMLElement,
-                              public nsIDOMHTMLOptGroupElement
-{
-public:
-  nsHTMLOptGroupElement(already_AddRefed<nsINodeInfo> aNodeInfo);
-  virtual ~nsHTMLOptGroupElement();
-
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
-
-  // nsIDOMHTMLOptGroupElement
-  NS_DECL_NSIDOMHTMLOPTGROUPELEMENT
-
-  // nsINode
-  virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex,
-                                 bool aNotify);
-  virtual void RemoveChildAt(uint32_t aIndex, bool aNotify);
-
-  // nsIContent
-  virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
-
-  virtual nsEventStates IntrinsicState() const;
- 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual nsXPCClassInfo* GetClassInfo();
-
-  virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
-                                const nsAttrValue* aValue, bool aNotify);
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-
-  virtual bool IsDisabled() const {
-    return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
-  }
-protected:
-
-  /**
-   * Get the select content element that contains this option
-   * @param aSelectElement the select element [OUT]
-   */
-  nsIContent* GetSelect();
-};
-
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(OptGroup)
 
 
 nsHTMLOptGroupElement::nsHTMLOptGroupElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo)
 {
   // We start off enabled
new file mode 100644
--- /dev/null
+++ b/content/html/content/src/nsHTMLOptGroupElement.h
@@ -0,0 +1,65 @@
+/* -*- 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 nsGenericHTMLElement_h
+#define nsGenericHTMLElement_h
+
+#include "nsIDOMHTMLOptGroupElement.h"
+#include "nsGenericHTMLElement.h"
+
+class nsHTMLOptGroupElement : public nsGenericHTMLElement,
+                              public nsIDOMHTMLOptGroupElement
+{
+public:
+  nsHTMLOptGroupElement(already_AddRefed<nsINodeInfo> aNodeInfo);
+  virtual ~nsHTMLOptGroupElement();
+
+  // nsISupports
+  NS_DECL_ISUPPORTS_INHERITED
+
+  // nsIDOMNode
+  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+
+  // nsIDOMElement
+  NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
+
+  // nsIDOMHTMLElement
+  NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
+
+  // nsIDOMHTMLOptGroupElement
+  NS_DECL_NSIDOMHTMLOPTGROUPELEMENT
+
+  // nsINode
+  virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex,
+                                 bool aNotify);
+  virtual void RemoveChildAt(uint32_t aIndex, bool aNotify);
+
+  // nsIContent
+  virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
+
+  virtual nsEventStates IntrinsicState() const;
+ 
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+
+  virtual nsXPCClassInfo* GetClassInfo();
+
+  virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
+                                const nsAttrValue* aValue, bool aNotify);
+
+  virtual nsIDOMNode* AsDOMNode() { return this; }
+
+  virtual bool IsDisabled() const {
+    return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
+  }
+protected:
+
+  /**
+   * Get the select content element that contains this option
+   * @param aSelectElement the select element [OUT]
+   */
+  nsIContent* GetSelect();
+};
+
+#endif /* nsGenericHTMLElement_h */
--- a/content/html/content/src/nsHTMLSelectElement.cpp
+++ b/content/html/content/src/nsHTMLSelectElement.cpp
@@ -31,16 +31,17 @@
 
 #include "nsError.h"
 #include "nsServiceManagerUtils.h"
 #include "nsRuleData.h"
 #include "nsEventDispatcher.h"
 #include "mozilla/dom/Element.h"
 #include "mozAutoDocUpdate.h"
 #include "dombindings.h"
+#include "mozilla/dom/BindingUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_ISUPPORTS1(nsSelectState, nsSelectState)
 NS_DEFINE_STATIC_IID_ACCESSOR(nsSelectState, NS_SELECT_STATE_IID)
 
 //----------------------------------------------------------------------
@@ -657,24 +658,17 @@ nsHTMLSelectElement::Add(nsIDOMHTMLEleme
     NS_ENSURE_TRUE(beforeElement, NS_ERROR_DOM_SYNTAX_ERR);
     return Add(aElement, beforeElement);
   }
 
   // otherwise, whether aBefore is long
   int32_t index;
   NS_ENSURE_SUCCESS(aBefore->GetAsInt32(&index), NS_ERROR_DOM_SYNTAX_ERR);
 
-  // If item index is out of range, insert to last.
-  // (since beforeElement becomes null, it is inserted to last)
-  nsCOMPtr<nsIDOMNode> beforeNode;
-  if (NS_SUCCEEDED(Item(index, getter_AddRefs(beforeNode)))) {
-    beforeElement = do_QueryInterface(beforeNode);
-  }
-
-  return Add(aElement, beforeElement);
+  return Add(aElement, index);
 }
 
 NS_IMETHODIMP
 nsHTMLSelectElement::Remove(int32_t aIndex)
 {
   nsCOMPtr<nsIDOMNode> option;
   Item(aIndex, getter_AddRefs(option));
 
@@ -2082,30 +2076,55 @@ nsHTMLOptionCollection::SetOption(uint32
     if (parent) {
       rv = parent->ReplaceChild(aOption, refChild, getter_AddRefs(ret));
     }
   }
 
   return rv;
 }
 
+int32_t
+nsHTMLOptionCollection::GetSelectedIndex(ErrorResult& aError)
+{
+  if (!mSelect) {
+    aError.Throw(NS_ERROR_UNEXPECTED);
+    return 0;
+  }
+
+  int32_t selectedIndex;
+  aError = mSelect->GetSelectedIndex(&selectedIndex);
+  return selectedIndex;
+}
+
 NS_IMETHODIMP
 nsHTMLOptionCollection::GetSelectedIndex(int32_t *aSelectedIndex)
 {
-  NS_ENSURE_TRUE(mSelect, NS_ERROR_UNEXPECTED);
+  ErrorResult rv;
+  *aSelectedIndex = GetSelectedIndex(rv);
+  return rv.ErrorCode();
+}
 
-  return mSelect->GetSelectedIndex(aSelectedIndex);
+void
+nsHTMLOptionCollection::SetSelectedIndex(int32_t aSelectedIndex,
+                                         ErrorResult& aError)
+{
+  if (!mSelect) {
+    aError.Throw(NS_ERROR_UNEXPECTED);
+    return;
+  }
+
+  aError = mSelect->SetSelectedIndex(aSelectedIndex);
 }
 
 NS_IMETHODIMP
 nsHTMLOptionCollection::SetSelectedIndex(int32_t aSelectedIndex)
 {
-  NS_ENSURE_TRUE(mSelect, NS_ERROR_UNEXPECTED);
-
-  return mSelect->SetSelectedIndex(aSelectedIndex);
+  ErrorResult rv;
+  SetSelectedIndex(aSelectedIndex, rv);
+  return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
 nsHTMLOptionCollection::Item(uint32_t aIndex, nsIDOMNode** aReturn)
 {
   nsISupports* item = GetElementAt(aIndex);
   if (!item) {
     *aReturn = nullptr;
@@ -2148,28 +2167,46 @@ nsHTMLOptionCollection::GetNamedItem(con
   nsINode *item = GetNamedItemHelper(mElements, aName);
   *aCache = item;
   return item;
 }
 
 nsINode*
 nsHTMLOptionCollection::GetParentObject()
 {
-    return mSelect;
+  return mSelect;
 }
 
 NS_IMETHODIMP
 nsHTMLOptionCollection::NamedItem(const nsAString& aName,
                                   nsIDOMNode** aReturn)
 {
   NS_IF_ADDREF(*aReturn = GetNamedItemHelper(mElements, aName));
 
   return NS_OK;
 }
 
+JSObject*
+nsHTMLOptionCollection::NamedItem(JSContext* cx, const nsAString& name,
+                                  ErrorResult& error)
+{
+  nsINode *item = GetNamedItemHelper(mElements, name);
+  if (!item) {
+    return nullptr;
+  }
+  JSObject* wrapper = GetWrapper();
+  JSAutoCompartment ac(cx, wrapper);
+  JS::Value v;
+  if (!mozilla::dom::WrapObject(cx, wrapper, item, item, nullptr, &v)) {
+    error.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+  return &v.toObject();
+}
+
 NS_IMETHODIMP
 nsHTMLOptionCollection::GetSelect(nsIDOMHTMLSelectElement **aReturn)
 {
   NS_IF_ADDREF(*aReturn = mSelect);
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -2182,27 +2219,38 @@ nsHTMLOptionCollection::Add(nsIDOMHTMLOp
 
   if (!mSelect) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   return mSelect->Add(aOption, aBefore);
 }
 
-NS_IMETHODIMP
-nsHTMLOptionCollection::Remove(int32_t aIndex)
+void
+nsHTMLOptionCollection::Remove(int32_t aIndex, ErrorResult& aError)
 {
-  NS_ENSURE_TRUE(mSelect, NS_ERROR_UNEXPECTED);
+  if (!mSelect) {
+    aError.Throw(NS_ERROR_UNEXPECTED);
+    return;
+  }
 
   uint32_t len = 0;
   mSelect->GetLength(&len);
   if (aIndex < 0 || (uint32_t)aIndex >= len)
     aIndex = 0;
 
-  return mSelect->Remove(aIndex);
+  aError = mSelect->Remove(aIndex);
+}
+
+NS_IMETHODIMP
+nsHTMLOptionCollection::Remove(int32_t aIndex)
+{
+  ErrorResult rv;
+  Remove(aIndex, rv);
+  return rv.ErrorCode();
 }
 
 void
 nsHTMLSelectElement::UpdateBarredFromConstraintValidation()
 {
   SetBarredFromConstraintValidation(IsDisabled());
 }
 
--- a/content/html/content/src/nsHTMLSelectElement.h
+++ b/content/html/content/src/nsHTMLSelectElement.h
@@ -5,41 +5,47 @@
 #ifndef nsHTMLSelectElement_h___
 #define nsHTMLSelectElement_h___
 
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
 #include "nsGenericHTMLElement.h"
 #include "nsIDOMHTMLSelectElement.h"
 #include "nsIDOMHTMLFormElement.h"
+#include "nsIDOMHTMLOptGroupElement.h"
 #include "nsIDOMHTMLOptionElement.h"
 #include "nsIDOMHTMLOptionsCollection.h"
 #include "nsISelectControlFrame.h"
 #include "nsIHTMLCollection.h"
 #include "nsIConstraintValidation.h"
 
 // PresState
 #include "nsXPCOM.h"
 #include "nsPresState.h"
 #include "nsIComponentManager.h"
 #include "nsCheapSets.h"
 #include "nsError.h"
+#include "nsHTMLOptGroupElement.h"
 #include "nsHTMLOptionElement.h"
 #include "nsHTMLFormElement.h"
+#include "mozilla/ErrorResult.h"
+#include "mozilla/dom/UnionTypes.h"
 
 class nsHTMLSelectElement;
 
 /**
  * The collection of options in the select (what you get back when you do
  * select.options in DOM)
  */
-class nsHTMLOptionCollection: public nsIDOMHTMLOptionsCollection,
-                              public nsIHTMLCollection,
+class nsHTMLOptionCollection: public nsIHTMLCollection,
+                              public nsIDOMHTMLOptionsCollection,
                               public nsWrapperCache
 {
+typedef mozilla::dom::HTMLOptionElementOrHTMLOptGroupElement HTMLOptionOrOptGroupElement;
+typedef mozilla::dom::HTMLElementOrLong HTMLElementOrLong;
 public:
   nsHTMLOptionCollection(nsHTMLSelectElement* aSelect);
   virtual ~nsHTMLOptionCollection();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap);
@@ -116,16 +122,31 @@ public:
    * @param aStartIndex the index to start looking at
    * @param aForward TRUE to look forward, FALSE to look backward
    * @return the option index
    */
   nsresult GetOptionIndex(mozilla::dom::Element* aOption,
                           int32_t aStartIndex, bool aForward,
                           int32_t* aIndex);
 
+  virtual JSObject* NamedItem(JSContext* aCx, const nsAString& aName,
+                              mozilla::ErrorResult& error);
+
+  inline void Add(const HTMLOptionOrOptGroupElement& aElement,
+                  const Nullable<HTMLElementOrLong>& aBefore,
+                  mozilla::ErrorResult& aError);
+  void Remove(int32_t aIndex, mozilla::ErrorResult& aError);
+  int32_t GetSelectedIndex(mozilla::ErrorResult& aError);
+  void SetSelectedIndex(int32_t aSelectedIndex, mozilla::ErrorResult& aError);
+  void IndexedSetter(uint32_t aIndex, nsIDOMHTMLOptionElement *aOption,
+                     mozilla::ErrorResult& aError)
+  {
+    aError = SetOption(aIndex, aOption);
+  }
+
 private:
   /** The list of options (holds strong references).  This is infallible, so
    * various members such as InsertOptionAt are also infallible. */
   nsTArray<nsRefPtr<nsHTMLOptionElement> > mElements;
   /** The select element that contains this array */
   nsHTMLSelectElement* mSelect;
 };
 
@@ -396,16 +417,30 @@ public:
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 
   // nsIConstraintValidation
   nsresult GetValidationMessage(nsAString& aValidationMessage,
                                 ValidityStateType aType);
 
+  /**
+   * Insert aElement before the node given by aBefore
+   */
+  nsresult Add(nsIDOMHTMLElement* aElement, nsIDOMHTMLElement* aBefore = nullptr);
+  nsresult Add(nsIDOMHTMLElement* aElement, int32_t aIndex)
+  {
+    // If item index is out of range, insert to last.
+    // (since beforeElement becomes null, it is inserted to last)
+    nsCOMPtr<nsIDOMHTMLElement> beforeElement =
+      do_QueryInterface(mOptions->GetElementAt(aIndex));
+
+    return Add(aElement, beforeElement);
+  }
+
 protected:
   friend class nsSafeOptionListMutation;
 
   // Helper Methods
   /**
    * Check whether the option specified by the index is selected
    * @param aIndex the index
    * @return whether the option at the index is selected
@@ -589,21 +624,16 @@ protected:
      */
     if (mForm && mForm->HasEverTriedInvalidSubmit()) {
       return true;
     }
 
     return mSelectionHasChanged;
   }
 
-  /**
-   * Insert aElement before the node given by aBefore
-   */
-  nsresult Add(nsIDOMHTMLElement* aElement, nsIDOMHTMLElement* aBefore = nullptr);
-
   /** The options[] array */
   nsRefPtr<nsHTMLOptionCollection> mOptions;
   /** false if the parser is in the middle of adding children. */
   bool            mIsDoneAddingChildren;
   /** true if our disabled state has changed from the default **/
   bool            mDisabledChanged;
   /** true if child nodes are being added or removed.
    *  Used by nsSafeOptionListMutation.
@@ -641,9 +671,30 @@ protected:
   int32_t   mSelectedIndex;
   /**
    * The temporary restore state in case we try to restore before parser is
    * done adding options
    */
   nsCOMPtr<nsSelectState> mRestoreState;
 };
 
+void
+nsHTMLOptionCollection::Add(const HTMLOptionOrOptGroupElement& aElement,
+                            const Nullable<HTMLElementOrLong>& aBefore,
+                            mozilla::ErrorResult& aError)
+{
+  nsIDOMHTMLElement* element;
+  if (aElement.IsHTMLOptionElement()) {
+    element = aElement.GetAsHTMLOptionElement();
+  } else {
+    element = aElement.GetAsHTMLOptGroupElement();
+  }
+
+  if (aBefore.IsNull()) {
+    aError = mSelect->Add(element, (nsIDOMHTMLElement*)nullptr);
+  } else if (aBefore.Value().IsHTMLElement()) {
+    aError = mSelect->Add(element, aBefore.Value().GetAsHTMLElement());
+  } else {
+    aError = mSelect->Add(element, aBefore.Value().GetAsLong());
+  }
+}
+
 #endif
--- a/content/html/content/src/nsHTMLStyleElement.cpp
+++ b/content/html/content/src/nsHTMLStyleElement.cpp
@@ -11,16 +11,17 @@
 #include "nsIDOMStyleSheet.h"
 #include "nsIStyleSheet.h"
 #include "nsStyleLinkElement.h"
 #include "nsNetUtil.h"
 #include "nsIDocument.h"
 #include "nsUnicharUtils.h"
 #include "nsThreadUtils.h"
 #include "nsContentUtils.h"
+#include "nsStubMutationObserver.h"
 
 class nsHTMLStyleElement : public nsGenericHTMLElement,
                            public nsIDOMHTMLStyleElement,
                            public nsStyleLinkElement,
                            public nsStubMutationObserver
 {
 public:
   nsHTMLStyleElement(already_AddRefed<nsINodeInfo> aNodeInfo);
--- a/content/html/content/src/nsHTMLTableElement.cpp
+++ b/content/html/content/src/nsHTMLTableElement.cpp
@@ -20,16 +20,18 @@
 #include "nsRuleData.h"
 #include "nsStyleContext.h"
 #include "nsIDocument.h"
 #include "nsContentUtils.h"
 #include "nsIDOMElement.h"
 #include "nsIHTMLCollection.h"
 #include "nsHTMLStyleSheet.h"
 #include "dombindings.h"
+#include "mozilla/ErrorResult.h"
+#include "mozilla/dom/BindingUtils.h"
 
 using namespace mozilla;
 
 /* ------------------------------ TableRowsCollection -------------------------------- */
 /**
  * This class provides a late-bound collection of rows in a table.
  * mParent is NOT ref-counted to avoid circular references
  */
@@ -43,16 +45,19 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_NSIDOMHTMLCOLLECTION
 
   virtual nsINode* GetParentObject()
   {
     return mParent;
   }
 
+  virtual JSObject* NamedItem(JSContext* cx, const nsAString& name,
+                              ErrorResult& error);
+
   NS_IMETHOD    ParentDestroyed();
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TableRowsCollection)
 
   // nsWrapperCache
   virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap)
   {
@@ -259,16 +264,37 @@ TableRowsCollection::GetNamedItem(const 
     if (item) {
       return item;
     }
   );
   *aCache = nullptr;
   return nullptr;
 }
 
+JSObject*
+TableRowsCollection::NamedItem(JSContext* cx, const nsAString& name,
+                               ErrorResult& error)
+{
+  nsWrapperCache* cache;
+  DO_FOR_EACH_ROWGROUP(
+    nsISupports* item = GetNamedItemInRowGroup(rows, name, &cache);
+    if (item) {
+      JSObject* wrapper = GetWrapper();
+      JSAutoCompartment ac(cx, wrapper);
+      JS::Value v;
+      if (!mozilla::dom::WrapObject(cx, wrapper, item, cache, nullptr, &v)) {
+        error.Throw(NS_ERROR_FAILURE);
+        return nullptr;
+      }
+      return &v.toObject();
+    }
+  );
+  return nullptr;
+}
+
 NS_IMETHODIMP 
 TableRowsCollection::NamedItem(const nsAString& aName,
                                nsIDOMNode** aReturn)
 {
   nsWrapperCache *cache;
   nsISupports* item = GetNamedItem(aName, &cache);
   if (!item) {
     *aReturn = nullptr;
--- a/content/html/content/src/nsHTMLTitleElement.cpp
+++ b/content/html/content/src/nsHTMLTitleElement.cpp
@@ -3,16 +3,17 @@
  * 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 "nsIDOMHTMLTitleElement.h"
 #include "nsIDOMEventTarget.h"
 #include "nsGenericHTMLElement.h"
 #include "nsStyleConsts.h"
 #include "nsIDocument.h"
 #include "nsContentUtils.h"
+#include "nsStubMutationObserver.h"
 
 class nsHTMLTitleElement : public nsGenericHTMLElement,
                            public nsIDOMHTMLTitleElement,
                            public nsStubMutationObserver
 {
 public:
   using nsGenericElement::GetText;
   using nsGenericElement::SetText;
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -1855,18 +1855,18 @@ static void* CreateTokens(nsINode* aRoot
   }
   return tokens;
 }
 
 NS_IMETHODIMP
 nsHTMLDocument::GetItems(const nsAString& types, nsIDOMNodeList** aReturn)
 {
   nsRefPtr<nsContentList> elements = 
-    NS_GetFuncStringContentList(this, MatchItems, DestroyTokens, 
-                                CreateTokens, types);
+    NS_GetFuncStringNodeList(this, MatchItems, DestroyTokens, CreateTokens,
+                             types);
   NS_ENSURE_TRUE(elements, NS_ERROR_OUT_OF_MEMORY);
   elements.forget(aReturn);
   return NS_OK;
 }
 
 
 void
 nsHTMLDocument::AddedForm()
--- a/content/html/document/src/nsHTMLDocument.h
+++ b/content/html/document/src/nsHTMLDocument.h
@@ -100,18 +100,18 @@ public:
   nsISupports *GetDocumentAllResult(const nsAString& aID,
                                     nsWrapperCache **aCache,
                                     nsresult *aResult);
 
   nsIContent *GetBody();
   Element *GetHead() { return GetHeadElement(); }
   already_AddRefed<nsContentList> GetElementsByName(const nsAString & aName)
   {
-    return NS_GetFuncStringContentList(this, MatchNameAttribute, nullptr,
-                                       UseExistingNameString, aName);
+    return NS_GetFuncStringNodeList(this, MatchNameAttribute, nullptr,
+                                    UseExistingNameString, aName);
   }
 
   virtual nsresult ResolveName(const nsAString& aName,
                                nsIContent *aForm,
                                nsISupports **aResult,
                                nsWrapperCache **aCache);
 
   virtual void AddedForm();
--- a/content/svg/content/src/DOMSVGLengthList.cpp
+++ b/content/svg/content/src/DOMSVGLengthList.cpp
@@ -78,24 +78,18 @@ DOMSVGLengthList::WrapObject(JSContext *
 {
   return mozilla::dom::oldproxybindings::SVGLengthList::create(cx, scope, this,
                                                       triedToWrap);
 }
 
 nsIDOMSVGLength*
 DOMSVGLengthList::GetItemAt(uint32_t aIndex)
 {
-  if (IsAnimValList()) {
-    Element()->FlushAnimations();
-  }
-  if (aIndex < LengthNoFlush()) {
-    EnsureItemAt(aIndex);
-    return mItems[aIndex];
-  }
-  return nullptr;
+  ErrorResult rv;
+  return GetItem(aIndex, rv);
 }
 
 void
 DOMSVGLengthList::InternalListLengthWillChange(uint32_t aNewLength)
 {
   uint32_t oldLength = mItems.Length();
 
   if (aNewLength > DOMSVGLength::MaxListIndex()) {
@@ -139,115 +133,144 @@ DOMSVGLengthList::InternalList() const
 }
 
 // ----------------------------------------------------------------------------
 // nsIDOMSVGLengthList implementation:
 
 NS_IMETHODIMP
 DOMSVGLengthList::GetNumberOfItems(uint32_t *aNumberOfItems)
 {
-  if (IsAnimValList()) {
-    Element()->FlushAnimations();
-  }
-  *aNumberOfItems = LengthNoFlush();
+  *aNumberOfItems = NumberOfItems();
   return NS_OK;
 }
 
-NS_IMETHODIMP
-DOMSVGLengthList::Clear()
+void
+DOMSVGLengthList::Clear(ErrorResult& aError)
 {
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return;
   }
 
   if (LengthNoFlush() > 0) {
     nsAttrValue emptyOrOldValue = Element()->WillChangeLengthList(AttrEnum());
     // Notify any existing DOM items of removal *before* truncating the lists
     // so that they can find their SVGLength internal counterparts and copy
     // their values. This also notifies the animVal list:
     mAList->InternalBaseValListWillChangeTo(SVGLengthList());
 
     mItems.Clear();
     InternalList().Clear();
     Element()->DidChangeLengthList(AttrEnum(), emptyOrOldValue);
     if (mAList->IsAnimating()) {
       Element()->AnimationNeedsResample();
     }
   }
-  return NS_OK;
 }
 
 NS_IMETHODIMP
-DOMSVGLengthList::Initialize(nsIDOMSVGLength *newItem,
-                             nsIDOMSVGLength **_retval)
+DOMSVGLengthList::Clear()
 {
-  *_retval = nullptr;
+  ErrorResult rv;
+  Clear(rv);
+  return rv.ErrorCode();
+}
+
+already_AddRefed<nsIDOMSVGLength>
+DOMSVGLengthList::Initialize(nsIDOMSVGLength *newItem,
+                             ErrorResult& error)
+{
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    error.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   // If newItem is already in a list we should insert a clone of newItem, and
   // for consistency, this should happen even if *this* is the list that
   // newItem is currently in. Note that in the case of newItem 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 newItem, it would actually insert newItem. To prevent that from
   // happening we have to do the clone here, if necessary.
 
   nsCOMPtr<DOMSVGLength> domItem = do_QueryInterface(newItem);
   if (!domItem) {
-    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+    error.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+    return nullptr;
   }
   if (domItem->HasOwner()) {
     newItem = domItem->Copy();
   }
 
   Clear();
-  return InsertItemBefore(newItem, 0, _retval);
+  return InsertItemBefore(newItem, 0, error);
+}
+
+NS_IMETHODIMP
+DOMSVGLengthList::Initialize(nsIDOMSVGLength *newItem,
+                             nsIDOMSVGLength **_retval)
+{
+  ErrorResult rv;
+  *_retval = Initialize(newItem, rv).get();
+  return rv.ErrorCode();
+}
+
+nsIDOMSVGLength*
+DOMSVGLengthList::IndexedGetter(uint32_t index, bool& found, ErrorResult& error)
+{
+  if (IsAnimValList()) {
+    Element()->FlushAnimations();
+  }
+  found = index < LengthNoFlush();
+  if (found) {
+    EnsureItemAt(index);
+    return mItems[index];
+  }
+  return nullptr;
 }
 
 NS_IMETHODIMP
 DOMSVGLengthList::GetItem(uint32_t index,
                           nsIDOMSVGLength **_retval)
 {
-  *_retval = GetItemAt(index);
-  if (!*_retval) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
-  }
-  NS_ADDREF(*_retval);
-  return NS_OK;
+  ErrorResult rv;
+  NS_IF_ADDREF(*_retval = GetItem(index, rv));
+  return rv.ErrorCode();
 }
 
-NS_IMETHODIMP
+already_AddRefed<nsIDOMSVGLength>
 DOMSVGLengthList::InsertItemBefore(nsIDOMSVGLength *newItem,
                                    uint32_t index,
-                                   nsIDOMSVGLength **_retval)
+                                   ErrorResult& error)
 {
-  *_retval = nullptr;
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    error.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   index = NS_MIN(index, LengthNoFlush());
   if (index >= DOMSVGLength::MaxListIndex()) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return nullptr;
   }
 
   nsCOMPtr<DOMSVGLength> domItem = do_QueryInterface(newItem);
   if (!domItem) {
-    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+    error.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+    return nullptr;
   }
   if (domItem->HasOwner()) {
     domItem = domItem->Copy(); // 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)) {
-    return NS_ERROR_OUT_OF_MEMORY;
+    error.Throw(NS_ERROR_OUT_OF_MEMORY);
+    return nullptr;
   }
 
   nsAttrValue emptyOrOldValue = Element()->WillChangeLengthList(AttrEnum());
   // Now that we know we're inserting, keep animVal list in sync as necessary.
   MaybeInsertNullInAnimValListAt(index);
 
   InternalList().InsertItem(index, domItem->ToSVGLength());
   mItems.InsertElementAt(index, domItem.get());
@@ -258,36 +281,47 @@ DOMSVGLengthList::InsertItemBefore(nsIDO
   domItem->InsertingIntoList(this, AttrEnum(), index, IsAnimValList());
 
   UpdateListIndicesFromIndex(mItems, index + 1);
 
   Element()->DidChangeLengthList(AttrEnum(), emptyOrOldValue);
   if (mAList->IsAnimating()) {
     Element()->AnimationNeedsResample();
   }
-  domItem.forget(_retval);
-  return NS_OK;
+  return domItem.forget();
 }
 
 NS_IMETHODIMP
+DOMSVGLengthList::InsertItemBefore(nsIDOMSVGLength *newItem,
+                                   uint32_t index,
+                                   nsIDOMSVGLength **_retval)
+{
+  ErrorResult rv;
+  *_retval = InsertItemBefore(newItem, index, rv).get();
+  return rv.ErrorCode();
+}
+
+already_AddRefed<nsIDOMSVGLength>
 DOMSVGLengthList::ReplaceItem(nsIDOMSVGLength *newItem,
                               uint32_t index,
-                              nsIDOMSVGLength **_retval)
+                              ErrorResult& error)
 {
-  *_retval = nullptr;
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    error.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   nsCOMPtr<DOMSVGLength> domItem = do_QueryInterface(newItem);
   if (!domItem) {
-    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+    error.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+    return nullptr;
   }
   if (index >= LengthNoFlush()) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return nullptr;
   }
   if (domItem->HasOwner()) {
     domItem = domItem->Copy(); // must do this before changing anything!
   }
 
   nsAttrValue emptyOrOldValue = Element()->WillChangeLengthList(AttrEnum());
   if (mItems[index]) {
     // Notify any existing DOM item of removal *before* modifying the lists so
@@ -301,70 +335,92 @@ DOMSVGLengthList::ReplaceItem(nsIDOMSVGL
   // This MUST come after the ToSVGPoint() call, otherwise that call
   // would end up reading bad data from InternalList()!
   domItem->InsertingIntoList(this, AttrEnum(), index, IsAnimValList());
 
   Element()->DidChangeLengthList(AttrEnum(), emptyOrOldValue);
   if (mAList->IsAnimating()) {
     Element()->AnimationNeedsResample();
   }
-  NS_ADDREF(*_retval = domItem.get());
-  return NS_OK;
+  return domItem.forget();
 }
 
 NS_IMETHODIMP
-DOMSVGLengthList::RemoveItem(uint32_t index,
-                             nsIDOMSVGLength **_retval)
+DOMSVGLengthList::ReplaceItem(nsIDOMSVGLength *newItem,
+                              uint32_t index,
+                              nsIDOMSVGLength **_retval)
 {
-  *_retval = nullptr;
+  ErrorResult rv;
+  *_retval = ReplaceItem(newItem, index, rv).get();
+  return rv.ErrorCode();
+}
+
+already_AddRefed<nsIDOMSVGLength>
+DOMSVGLengthList::RemoveItem(uint32_t index,
+                             ErrorResult& error)
+{
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    error.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   if (index >= LengthNoFlush()) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return nullptr;
   }
 
   nsAttrValue emptyOrOldValue = Element()->WillChangeLengthList(AttrEnum());
   // Now that we know we're removing, keep animVal list in sync as necessary.
   // Do this *before* touching InternalList() so the removed item can get its
   // internal value.
   MaybeRemoveItemFromAnimValListAt(index);
 
   // We have to return the removed item, so make sure it exists:
   EnsureItemAt(index);
 
   // Notify the DOM item of removal *before* modifying the lists so that the
   // DOM item can copy its *old* value:
   mItems[index]->RemovingFromList();
-  NS_ADDREF(*_retval = mItems[index]);
+  nsCOMPtr<nsIDOMSVGLength> result = mItems[index];
 
   InternalList().RemoveItem(index);
   mItems.RemoveElementAt(index);
 
   UpdateListIndicesFromIndex(mItems, index);
 
   Element()->DidChangeLengthList(AttrEnum(), emptyOrOldValue);
   if (mAList->IsAnimating()) {
     Element()->AnimationNeedsResample();
   }
-  return NS_OK;
+  return result.forget();
+}
+
+NS_IMETHODIMP
+DOMSVGLengthList::RemoveItem(uint32_t index,
+                             nsIDOMSVGLength **_retval)
+{
+  ErrorResult rv;
+  *_retval = RemoveItem(index, rv).get();
+  return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
 DOMSVGLengthList::AppendItem(nsIDOMSVGLength *newItem,
                              nsIDOMSVGLength **_retval)
 {
-  return InsertItemBefore(newItem, LengthNoFlush(), _retval);
+  ErrorResult rv;
+  *_retval = AppendItem(newItem, rv).get();
+  return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
-DOMSVGLengthList::GetLength(uint32_t *aNumberOfItems)
+DOMSVGLengthList::GetLength(uint32_t *aLength)
 {
-  return GetNumberOfItems(aNumberOfItems);
+  *aLength = Length();
+  return NS_OK;
 }
 
 void
 DOMSVGLengthList::EnsureItemAt(uint32_t aIndex)
 {
   if (!mItems[aIndex]) {
     mItems[aIndex] = new DOMSVGLength(this, AttrEnum(), aIndex, IsAnimValList());
   }
--- a/content/svg/content/src/DOMSVGLengthList.h
+++ b/content/svg/content/src/DOMSVGLengthList.h
@@ -9,16 +9,17 @@
 #include "DOMSVGAnimatedLengthList.h"
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDebug.h"
 #include "nsIDOMSVGLengthList.h"
 #include "nsTArray.h"
 #include "SVGLengthList.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/ErrorResult.h"
 
 class nsIDOMSVGLength;
 class nsSVGElement;
 
 namespace mozilla {
 
 class DOMSVGLength;
 
@@ -89,16 +90,55 @@ public:
                       mItems.Length() == InternalList().Length(),
                       "DOM wrapper's list length is out of sync");
     return mItems.Length();
   }
 
   /// Called to notify us to syncronize our length and detach excess items.
   void InternalListLengthWillChange(uint32_t aNewLength);
 
+  uint32_t NumberOfItems() const
+  {
+    if (IsAnimValList()) {
+      Element()->FlushAnimations();
+    }
+    return LengthNoFlush();
+  }
+  void Clear(ErrorResult& aError);
+  already_AddRefed<nsIDOMSVGLength> Initialize(nsIDOMSVGLength *newItem,
+                                               ErrorResult& error);
+  nsIDOMSVGLength* GetItem(uint32_t index, ErrorResult& error)
+  {
+    bool found;
+    nsIDOMSVGLength* item = IndexedGetter(index, found, error);
+    if (!found) {
+      error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    }
+    return item;
+  }
+  nsIDOMSVGLength* IndexedGetter(uint32_t index, bool& found,
+                                 ErrorResult& error);
+  already_AddRefed<nsIDOMSVGLength> InsertItemBefore(nsIDOMSVGLength *newItem,
+                                                     uint32_t index,
+                                                     ErrorResult& error);
+  already_AddRefed<nsIDOMSVGLength> ReplaceItem(nsIDOMSVGLength *newItem,
+                                                uint32_t index,
+                                                ErrorResult& error);
+  already_AddRefed<nsIDOMSVGLength> RemoveItem(uint32_t index,
+                                               ErrorResult& error);
+  already_AddRefed<nsIDOMSVGLength> AppendItem(nsIDOMSVGLength *newItem,
+                                               ErrorResult& error)
+  {
+    return InsertItemBefore(newItem, LengthNoFlush(), error);
+  }
+  uint32_t Length() const
+  {
+    return NumberOfItems();
+  }
+
 private:
 
   nsSVGElement* Element() const {
     return mAList->mElement;
   }
 
   uint8_t AttrEnum() const {
     return mAList->mAttrEnum;
--- a/content/svg/content/src/DOMSVGNumberList.cpp
+++ b/content/svg/content/src/DOMSVGNumberList.cpp
@@ -79,24 +79,18 @@ DOMSVGNumberList::WrapObject(JSContext *
 {
   return mozilla::dom::oldproxybindings::SVGNumberList::create(cx, scope, this,
                                                       triedToWrap);
 }
 
 nsIDOMSVGNumber*
 DOMSVGNumberList::GetItemAt(uint32_t aIndex)
 {
-  if (IsAnimValList()) {
-    Element()->FlushAnimations();
-  }
-  if (aIndex < LengthNoFlush()) {
-    EnsureItemAt(aIndex);
-    return mItems[aIndex];
-  }
-  return nullptr;
+  ErrorResult rv;
+  return GetItem(aIndex, rv);
 }
 
 void
 DOMSVGNumberList::InternalListLengthWillChange(uint32_t aNewLength)
 {
   uint32_t oldLength = mItems.Length();
 
   if (aNewLength > DOMSVGNumber::MaxListIndex()) {
@@ -140,115 +134,144 @@ DOMSVGNumberList::InternalList() const
 }
 
 // ----------------------------------------------------------------------------
 // nsIDOMSVGNumberList implementation:
 
 NS_IMETHODIMP
 DOMSVGNumberList::GetNumberOfItems(uint32_t *aNumberOfItems)
 {
-  if (IsAnimValList()) {
-    Element()->FlushAnimations();
-  }
-  *aNumberOfItems = LengthNoFlush();
+  *aNumberOfItems = NumberOfItems();
   return NS_OK;
 }
 
-NS_IMETHODIMP
-DOMSVGNumberList::Clear()
+void
+DOMSVGNumberList::Clear(ErrorResult& error)
 {
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    error.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return;
   }
 
   if (LengthNoFlush() > 0) {
     nsAttrValue emptyOrOldValue = Element()->WillChangeNumberList(AttrEnum());
     // Notify any existing DOM items of removal *before* truncating the lists
     // so that they can find their SVGNumber internal counterparts and copy
     // their values. This also notifies the animVal list:
     mAList->InternalBaseValListWillChangeTo(SVGNumberList());
 
     mItems.Clear();
     InternalList().Clear();
     Element()->DidChangeNumberList(AttrEnum(), emptyOrOldValue);
     if (mAList->IsAnimating()) {
       Element()->AnimationNeedsResample();
     }
   }
-  return NS_OK;
 }
 
 NS_IMETHODIMP
-DOMSVGNumberList::Initialize(nsIDOMSVGNumber *newItem,
-                             nsIDOMSVGNumber **_retval)
+DOMSVGNumberList::Clear()
 {
-  *_retval = nullptr;
+  ErrorResult rv;
+  Clear(rv);
+  return rv.ErrorCode();
+}
+
+already_AddRefed<nsIDOMSVGNumber>
+DOMSVGNumberList::Initialize(nsIDOMSVGNumber *newItem,
+                             ErrorResult& error)
+{
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    error.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   // If newItem is already in a list we should insert a clone of newItem, and
   // for consistency, this should happen even if *this* is the list that
   // newItem is currently in. Note that in the case of newItem 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 newItem, it would actually insert newItem. To prevent that from
   // happening we have to do the clone here, if necessary.
 
   nsCOMPtr<DOMSVGNumber> domItem = do_QueryInterface(newItem);
   if (!domItem) {
-    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+    error.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+    return nullptr;
   }
   if (domItem->HasOwner()) {
     newItem = domItem->Clone();
   }
 
   Clear();
-  return InsertItemBefore(newItem, 0, _retval);
+  return InsertItemBefore(newItem, 0, error);
+}
+
+NS_IMETHODIMP
+DOMSVGNumberList::Initialize(nsIDOMSVGNumber *newItem,
+                             nsIDOMSVGNumber **_retval)
+{
+  ErrorResult rv;
+  *_retval = Initialize(newItem, rv).get();
+  return rv.ErrorCode();
+}
+
+nsIDOMSVGNumber*
+DOMSVGNumberList::IndexedGetter(uint32_t index, bool& found, ErrorResult& error)
+{
+  if (IsAnimValList()) {
+    Element()->FlushAnimations();
+  }
+  found = index < LengthNoFlush();
+  if (found) {
+    EnsureItemAt(index);
+    return mItems[index];
+  }
+  return nullptr;
 }
 
 NS_IMETHODIMP
 DOMSVGNumberList::GetItem(uint32_t index,
                           nsIDOMSVGNumber **_retval)
 {
-  *_retval = GetItemAt(index);
-  if (!*_retval) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
-  }
-  NS_ADDREF(*_retval);
-  return NS_OK;
+  ErrorResult rv;
+  NS_IF_ADDREF(*_retval = GetItem(index, rv));
+  return rv.ErrorCode();
 }
 
-NS_IMETHODIMP
+already_AddRefed<nsIDOMSVGNumber>
 DOMSVGNumberList::InsertItemBefore(nsIDOMSVGNumber *newItem,
                                    uint32_t index,
-                                   nsIDOMSVGNumber **_retval)
+                                   ErrorResult& error)
 {
-  *_retval = nullptr;
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    error.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   index = NS_MIN(index, LengthNoFlush());
   if (index >= DOMSVGNumber::MaxListIndex()) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return nullptr;
   }
 
   nsCOMPtr<DOMSVGNumber> domItem = do_QueryInterface(newItem);
   if (!domItem) {
-    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+    error.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+    return nullptr;
   }
   if (domItem->HasOwner()) {
     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)) {
-    return NS_ERROR_OUT_OF_MEMORY;
+    error.Throw(NS_ERROR_OUT_OF_MEMORY);
+    return nullptr;
   }
 
   nsAttrValue emptyOrOldValue = Element()->WillChangeNumberList(AttrEnum());
   // Now that we know we're inserting, keep animVal list in sync as necessary.
   MaybeInsertNullInAnimValListAt(index);
 
   InternalList().InsertItem(index, domItem->ToSVGNumber());
   mItems.InsertElementAt(index, domItem.get());
@@ -259,36 +282,47 @@ DOMSVGNumberList::InsertItemBefore(nsIDO
   domItem->InsertingIntoList(this, AttrEnum(), index, IsAnimValList());
 
   UpdateListIndicesFromIndex(mItems, index + 1);
 
   Element()->DidChangeNumberList(AttrEnum(), emptyOrOldValue);
   if (mAList->IsAnimating()) {
     Element()->AnimationNeedsResample();
   }
-  domItem.forget(_retval);
-  return NS_OK;
+  return domItem.forget();
 }
 
 NS_IMETHODIMP
+DOMSVGNumberList::InsertItemBefore(nsIDOMSVGNumber *newItem,
+                                   uint32_t index,
+                                   nsIDOMSVGNumber **_retval)
+{
+  ErrorResult rv;
+  *_retval = InsertItemBefore(newItem, index, rv).get();
+  return rv.ErrorCode();
+}
+
+already_AddRefed<nsIDOMSVGNumber>
 DOMSVGNumberList::ReplaceItem(nsIDOMSVGNumber *newItem,
                               uint32_t index,
-                              nsIDOMSVGNumber **_retval)
+                              ErrorResult& error)
 {
-  *_retval = nullptr;
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    error.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   nsCOMPtr<DOMSVGNumber> domItem = do_QueryInterface(newItem);
   if (!domItem) {
-    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+    error.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+    return nullptr;
   }
   if (index >= LengthNoFlush()) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return nullptr;
   }
   if (domItem->HasOwner()) {
     domItem = domItem->Clone(); // must do this before changing anything!
   }
 
   nsAttrValue emptyOrOldValue = Element()->WillChangeNumberList(AttrEnum());
   if (mItems[index]) {
     // Notify any existing DOM item of removal *before* modifying the lists so
@@ -302,70 +336,92 @@ DOMSVGNumberList::ReplaceItem(nsIDOMSVGN
   // This MUST come after the ToSVGPoint() call, otherwise that call
   // would end up reading bad data from InternalList()!
   domItem->InsertingIntoList(this, AttrEnum(), index, IsAnimValList());
 
   Element()->DidChangeNumberList(AttrEnum(), emptyOrOldValue);
   if (mAList->IsAnimating()) {
     Element()->AnimationNeedsResample();
   }
-  NS_ADDREF(*_retval = domItem.get());
-  return NS_OK;
+  return domItem.forget();
 }
 
 NS_IMETHODIMP
-DOMSVGNumberList::RemoveItem(uint32_t index,
-                             nsIDOMSVGNumber **_retval)
+DOMSVGNumberList::ReplaceItem(nsIDOMSVGNumber *newItem,
+                              uint32_t index,
+                              nsIDOMSVGNumber **_retval)
 {
-  *_retval = nullptr;
+  ErrorResult rv;
+  *_retval = ReplaceItem(newItem, index, rv).get();
+  return rv.ErrorCode();
+}
+
+already_AddRefed<nsIDOMSVGNumber>
+DOMSVGNumberList::RemoveItem(uint32_t index,
+                             ErrorResult& error)
+{
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    error.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   if (index >= LengthNoFlush()) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return nullptr;
   }
 
   // Now that we know we're removing, keep animVal list in sync as necessary.
   // Do this *before* touching InternalList() so the removed item can get its
   // internal value.
   MaybeRemoveItemFromAnimValListAt(index);
 
   // We have to return the removed item, so make sure it exists:
   EnsureItemAt(index);
 
   nsAttrValue emptyOrOldValue = Element()->WillChangeNumberList(AttrEnum());
   // Notify the DOM item of removal *before* modifying the lists so that the
   // DOM item can copy its *old* value:
   mItems[index]->RemovingFromList();
-  NS_ADDREF(*_retval = mItems[index]);
+  nsCOMPtr<nsIDOMSVGNumber> result = mItems[index];
 
   InternalList().RemoveItem(index);
   mItems.RemoveElementAt(index);
 
   UpdateListIndicesFromIndex(mItems, index);
 
   Element()->DidChangeNumberList(AttrEnum(), emptyOrOldValue);
   if (mAList->IsAnimating()) {
     Element()->AnimationNeedsResample();
   }
-  return NS_OK;
+  return result.forget();
+}
+
+NS_IMETHODIMP
+DOMSVGNumberList::RemoveItem(uint32_t index,
+                             nsIDOMSVGNumber **_retval)
+{
+  ErrorResult rv;
+  *_retval = RemoveItem(index, rv).get();
+  return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
 DOMSVGNumberList::AppendItem(nsIDOMSVGNumber *newItem,
                              nsIDOMSVGNumber **_retval)
 {
-  return InsertItemBefore(newItem, LengthNoFlush(), _retval);
+  ErrorResult rv;
+  *_retval = AppendItem(newItem, rv).get();
+  return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
-DOMSVGNumberList::GetLength(uint32_t *aNumberOfItems)
+DOMSVGNumberList::GetLength(uint32_t *aLength)
 {
-  return GetNumberOfItems(aNumberOfItems);
+  *aLength = Length();
+  return NS_OK;
 }
 
 void
 DOMSVGNumberList::EnsureItemAt(uint32_t aIndex)
 {
   if (!mItems[aIndex]) {
     mItems[aIndex] = new DOMSVGNumber(this, AttrEnum(), aIndex, IsAnimValList());
   }
--- a/content/svg/content/src/DOMSVGNumberList.h
+++ b/content/svg/content/src/DOMSVGNumberList.h
@@ -9,16 +9,17 @@
 #include "DOMSVGAnimatedNumberList.h"
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDebug.h"
 #include "nsIDOMSVGNumberList.h"
 #include "nsTArray.h"
 #include "SVGNumberList.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/ErrorResult.h"
 
 class nsSVGElement;
 
 namespace mozilla {
 
 class DOMSVGNumber;
 
 /**
@@ -88,16 +89,55 @@ public:
                       mItems.Length() == InternalList().Length(),
                       "DOM wrapper's list length is out of sync");
     return mItems.Length();
   }
 
   /// Called to notify us to syncronize our length and detach excess items.
   void InternalListLengthWillChange(uint32_t aNewLength);
 
+  uint32_t NumberOfItems() const
+  {
+    if (IsAnimValList()) {
+      Element()->FlushAnimations();
+    }
+    return LengthNoFlush();
+  }
+  void Clear(ErrorResult& error);
+  already_AddRefed<nsIDOMSVGNumber> Initialize(nsIDOMSVGNumber *newItem,
+                                               ErrorResult& error);
+  nsIDOMSVGNumber* GetItem(uint32_t index, ErrorResult& error)
+  {
+    bool found;
+    nsIDOMSVGNumber* item = IndexedGetter(index, found, error);
+    if (!found) {
+      error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    }
+    return item;
+  }
+  nsIDOMSVGNumber* IndexedGetter(uint32_t index, bool& found,
+                                 ErrorResult& error);
+  already_AddRefed<nsIDOMSVGNumber> InsertItemBefore(nsIDOMSVGNumber *newItem,
+                                                     uint32_t index,
+                                                     ErrorResult& error);
+  already_AddRefed<nsIDOMSVGNumber> ReplaceItem(nsIDOMSVGNumber *newItem,
+                                                uint32_t index,
+                                                ErrorResult& error);
+  already_AddRefed<nsIDOMSVGNumber> RemoveItem(uint32_t index,
+                                               ErrorResult& error);
+  already_AddRefed<nsIDOMSVGNumber> AppendItem(nsIDOMSVGNumber *newItem,
+                                               ErrorResult& error)
+  {
+    return InsertItemBefore(newItem, LengthNoFlush(), error);
+  }
+  uint32_t Length() const
+  {
+    return NumberOfItems();
+  }
+
 private:
 
   nsSVGElement* Element() const {
     return mAList->mElement;
   }
 
   uint8_t AttrEnum() const {
     return mAList->mAttrEnum;
--- a/content/svg/content/src/DOMSVGPathSegList.cpp
+++ b/content/svg/content/src/DOMSVGPathSegList.cpp
@@ -85,24 +85,18 @@ DOMSVGPathSegList::WrapObject(JSContext 
 {
   return mozilla::dom::oldproxybindings::SVGPathSegList::create(cx, scope, this,
                                                        triedToWrap);
 }
 
 nsIDOMSVGPathSeg*
 DOMSVGPathSegList::GetItemAt(uint32_t aIndex)
 {
-  if (IsAnimValList()) {
-    Element()->FlushAnimations();
-  }
-  if (aIndex < LengthNoFlush()) {
-    EnsureItemAt(aIndex);
-    return ItemAt(aIndex);
-  }
-  return nullptr;
+  ErrorResult rv;
+  return GetItem(aIndex, rv);
 }
 
 void
 DOMSVGPathSegList::InternalListWillChangeTo(const SVGPathData& aNewValue)
 {
   // When the number of items in our internal counterpart changes, we MUST stay
   // in sync. Everything in the scary comment in
   // DOMSVGLengthList::InternalBaseValListWillChangeTo applies here just as
@@ -239,28 +233,26 @@ DOMSVGPathSegList::InternalAList() const
 }
 
 // ----------------------------------------------------------------------------
 // nsIDOMSVGPathSegList implementation:
 
 NS_IMETHODIMP
 DOMSVGPathSegList::GetNumberOfItems(uint32_t *aNumberOfItems)
 {
-  if (IsAnimValList()) {
-    Element()->FlushAnimations();
-  }
-  *aNumberOfItems = LengthNoFlush();
+  *aNumberOfItems = NumberOfItems();
   return NS_OK;
 }
 
-NS_IMETHODIMP
-DOMSVGPathSegList::Clear()
+void
+DOMSVGPathSegList::Clear(ErrorResult& aError)
 {
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return;
   }
 
   if (LengthNoFlush() > 0) {
     nsAttrValue emptyOrOldValue = Element()->WillChangePathSegList();
     // DOM list items that are to be removed must be removed before we change
     // the internal list, otherwise they wouldn't be able to copy their
     // internal counterparts' values!
 
@@ -276,95 +268,127 @@ DOMSVGPathSegList::Clear()
     }
 
     InternalList().Clear();
     Element()->DidChangePathSegList(emptyOrOldValue);
     if (AttrIsAnimating()) {
       Element()->AnimationNeedsResample();
     }
   }
-  return NS_OK;
 }
 
 NS_IMETHODIMP
-DOMSVGPathSegList::Initialize(nsIDOMSVGPathSeg *aNewItem,
-                              nsIDOMSVGPathSeg **_retval)
+DOMSVGPathSegList::Clear()
 {
-  *_retval = nullptr;
+  ErrorResult rv;
+  Clear(rv);
+  return rv.ErrorCode();
+}
+
+already_AddRefed<nsIDOMSVGPathSeg>
+DOMSVGPathSegList::Initialize(nsIDOMSVGPathSeg *aNewItem, ErrorResult& aError)
+{
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    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.
 
   nsCOMPtr<DOMSVGPathSeg> domItem = do_QueryInterface(aNewItem);
   if (!domItem) {
-    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+    aError.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+    return nullptr;
   }
   if (domItem->HasOwner()) {
     aNewItem = domItem->Clone();
   }
 
-  Clear();
-  return InsertItemBefore(aNewItem, 0, _retval);
+  Clear(aError);
+  MOZ_ASSERT(!aError.Failed(), "How could this fail?");
+  return InsertItemBefore(aNewItem, 0, aError);
+}
+
+NS_IMETHODIMP
+DOMSVGPathSegList::Initialize(nsIDOMSVGPathSeg *newItem,
+                              nsIDOMSVGPathSeg **_retval)
+{
+  ErrorResult rv;
+  *_retval = Initialize(newItem, rv).get();
+  return rv.ErrorCode();
+}
+
+nsIDOMSVGPathSeg*
+DOMSVGPathSegList::IndexedGetter(uint32_t aIndex, bool& aFound,
+                                 ErrorResult& aError)
+{
+  if (IsAnimValList()) {
+    Element()->FlushAnimations();
+  }
+  aFound = aIndex < LengthNoFlush();
+  if (aFound) {
+    EnsureItemAt(aIndex);
+    return ItemAt(aIndex);
+  }
+  return nullptr;
 }
 
 NS_IMETHODIMP
 DOMSVGPathSegList::GetItem(uint32_t aIndex,
                            nsIDOMSVGPathSeg **_retval)
 {
-  *_retval = GetItemAt(aIndex);
-  if (!*_retval) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
-  }
-  NS_ADDREF(*_retval);
-  return NS_OK;
+  ErrorResult rv;
+  NS_IF_ADDREF(*_retval = GetItem(aIndex, rv));
+  return rv.ErrorCode();
 }
 
-NS_IMETHODIMP
+already_AddRefed<nsIDOMSVGPathSeg>
 DOMSVGPathSegList::InsertItemBefore(nsIDOMSVGPathSeg *aNewItem,
                                     uint32_t aIndex,
-                                    nsIDOMSVGPathSeg **_retval)
+                                    ErrorResult& aError)
 {
-  *_retval = nullptr;
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   uint32_t internalIndex;
   if (aIndex < LengthNoFlush()) {
     internalIndex = mItems[aIndex].mInternalDataIndex;
   } else {
     aIndex = LengthNoFlush();
     internalIndex = InternalList().mData.Length();
   }
   if (aIndex >= DOMSVGPathSeg::MaxListIndex()) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return nullptr;
   }
 
   nsCOMPtr<DOMSVGPathSeg> domItem = do_QueryInterface(aNewItem);
   if (!domItem) {
-    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+    aError.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+    return nullptr;
   }
   if (domItem->HasOwner()) {
     domItem = domItem->Clone(); // must do this before changing anything!
   }
 
   uint32_t argCount = SVGPathSegUtils::ArgCountForType(domItem->Type());
 
   // Ensure we have enough memory so we can avoid complex error handling below:
   if (!mItems.SetCapacity(mItems.Length() + 1) ||
       !InternalList().mData.SetCapacity(InternalList().mData.Length() + 1 + argCount)) {
-    return NS_ERROR_OUT_OF_MEMORY;
+    aError.Throw(NS_ERROR_OUT_OF_MEMORY);
+    return nullptr;
   }
 
   nsAttrValue emptyOrOldValue = Element()->WillChangePathSegList();
   // Now that we know we're inserting, keep animVal list in sync as necessary.
   MaybeInsertNullInAnimValListAt(aIndex, internalIndex, argCount);
 
   float segAsRaw[1 + NS_SVG_PATH_SEG_MAX_ARGS];
   domItem->ToSVGPathSegEncodedData(segAsRaw);
@@ -378,36 +402,47 @@ DOMSVGPathSegList::InsertItemBefore(nsID
   domItem->InsertingIntoList(this, aIndex, IsAnimValList());
 
   UpdateListIndicesFromIndex(aIndex + 1, argCount + 1);
 
   Element()->DidChangePathSegList(emptyOrOldValue);
   if (AttrIsAnimating()) {
     Element()->AnimationNeedsResample();
   }
-  domItem.forget(_retval);
-  return NS_OK;
+  return domItem.forget();
 }
 
 NS_IMETHODIMP
+DOMSVGPathSegList::InsertItemBefore(nsIDOMSVGPathSeg *aNewItem,
+                                    uint32_t aIndex,
+                                    nsIDOMSVGPathSeg **_retval)
+{
+  ErrorResult rv;
+  *_retval = InsertItemBefore(aNewItem, aIndex, rv).get();
+  return rv.ErrorCode();
+}
+
+already_AddRefed<nsIDOMSVGPathSeg>
 DOMSVGPathSegList::ReplaceItem(nsIDOMSVGPathSeg *aNewItem,
                                uint32_t aIndex,
-                               nsIDOMSVGPathSeg **_retval)
+                               ErrorResult& aError)
 {
-  *_retval = nullptr;
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   nsCOMPtr<DOMSVGPathSeg> domItem = do_QueryInterface(aNewItem);
   if (!domItem) {
-    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+    aError.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+    return nullptr;
   }
   if (aIndex >= LengthNoFlush()) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return nullptr;
   }
   if (domItem->HasOwner()) {
     domItem = domItem->Clone(); // must do this before changing anything!
   }
 
   nsAttrValue emptyOrOldValue = Element()->WillChangePathSegList();
   if (ItemAt(aIndex)) {
     // Notify any existing DOM item of removal *before* modifying the lists so
@@ -424,17 +459,18 @@ DOMSVGPathSegList::ReplaceItem(nsIDOMSVG
 
   float segAsRaw[1 + NS_SVG_PATH_SEG_MAX_ARGS];
   domItem->ToSVGPathSegEncodedData(segAsRaw);
 
   bool ok = !!InternalList().mData.ReplaceElementsAt(
                   internalIndex, 1 + oldArgCount,
                   segAsRaw, 1 + newArgCount);
   if (!ok) {
-    return NS_ERROR_OUT_OF_MEMORY;
+    aError.Throw(NS_ERROR_OUT_OF_MEMORY);
+    return nullptr;
   }
   ItemAt(aIndex) = domItem;
 
   // This MUST come after the ToSVGPathSegEncodedData call, otherwise that call
   // would end up reading bad data from InternalList()!
   domItem->InsertingIntoList(this, aIndex, IsAnimValList());
 
   uint32_t delta = newArgCount - oldArgCount;
@@ -443,40 +479,50 @@ DOMSVGPathSegList::ReplaceItem(nsIDOMSVG
       mItems[i].mInternalDataIndex += delta;
     }
   }
 
   Element()->DidChangePathSegList(emptyOrOldValue);
   if (AttrIsAnimating()) {
     Element()->AnimationNeedsResample();
   }
-  NS_ADDREF(*_retval = domItem.get());
-  return NS_OK;
+  return domItem.forget();
 }
 
 NS_IMETHODIMP
-DOMSVGPathSegList::RemoveItem(uint32_t aIndex,
-                              nsIDOMSVGPathSeg **_retval)
+DOMSVGPathSegList::ReplaceItem(nsIDOMSVGPathSeg *aNewItem,
+                               uint32_t aIndex,
+                               nsIDOMSVGPathSeg **_retval)
 {
-  *_retval = nullptr;
+  ErrorResult rv;
+  *_retval = ReplaceItem(aNewItem, aIndex, rv).get();
+  return rv.ErrorCode();
+}
+
+already_AddRefed<nsIDOMSVGPathSeg>
+DOMSVGPathSegList::RemoveItem(uint32_t aIndex,
+                              ErrorResult& aError)
+{
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   if (aIndex >= LengthNoFlush()) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return nullptr;
   }
   // We have to return the removed item, so make sure it exists:
   EnsureItemAt(aIndex);
 
   nsAttrValue emptyOrOldValue = Element()->WillChangePathSegList();
   // Notify the DOM item of removal *before* modifying the lists so that the
   // DOM item can copy its *old* value:
   ItemAt(aIndex)->RemovingFromList();
-  NS_ADDREF(*_retval = ItemAt(aIndex));
+  nsCOMPtr<nsIDOMSVGPathSeg> result = ItemAt(aIndex);
 
   uint32_t internalIndex = mItems[aIndex].mInternalDataIndex;
   uint32_t segType = SVGPathSegUtils::DecodeType(InternalList().mData[internalIndex]);
   uint32_t argCount = SVGPathSegUtils::ArgCountForType(segType);
 
   // Now that we know we're removing, keep animVal list in sync as necessary.
   // Do this *before* touching InternalList() so the removed item can get its
   // internal value.
@@ -486,24 +532,35 @@ DOMSVGPathSegList::RemoveItem(uint32_t a
   mItems.RemoveElementAt(aIndex);
 
   UpdateListIndicesFromIndex(aIndex, -(argCount + 1));
 
   Element()->DidChangePathSegList(emptyOrOldValue);
   if (AttrIsAnimating()) {
     Element()->AnimationNeedsResample();
   }
-  return NS_OK;
+  return result.forget();
+}
+
+NS_IMETHODIMP
+DOMSVGPathSegList::RemoveItem(uint32_t aIndex,
+                              nsIDOMSVGPathSeg **_retval)
+{
+  ErrorResult rv;
+  *_retval = RemoveItem(aIndex, rv).get();
+  return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
 DOMSVGPathSegList::AppendItem(nsIDOMSVGPathSeg *aNewItem,
                               nsIDOMSVGPathSeg **_retval)
 {
-  return InsertItemBefore(aNewItem, LengthNoFlush(), _retval);
+  ErrorResult rv;
+  *_retval = AppendItem(aNewItem, rv).get();
+  return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
 DOMSVGPathSegList::GetLength(uint32_t *aNumberOfItems)
 {
   return GetNumberOfItems(aNumberOfItems);
 }
 
--- a/content/svg/content/src/DOMSVGPathSegList.h
+++ b/content/svg/content/src/DOMSVGPathSegList.h
@@ -10,16 +10,17 @@
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDebug.h"
 #include "nsIDOMSVGPathSegList.h"
 #include "nsSVGElement.h"
 #include "nsTArray.h"
 #include "SVGPathData.h" // IWYU pragma: keep
 #include "mozilla/Attributes.h"
+#include "mozilla/ErrorResult.h"
 
 class nsIDOMSVGPathSeg;
 
 namespace mozilla {
 
 class DOMSVGPathSeg;
 class SVGAnimatedPathSegList;
 
@@ -126,16 +127,55 @@ public:
   void InternalListWillChangeTo(const SVGPathData& aNewValue);
 
   /**
    * Returns true if our attribute is animating (in which case our animVal is
    * not simply a mirror of our baseVal).
    */
   bool AttrIsAnimating() const;
 
+  uint32_t NumberOfItems() const
+  {
+    if (IsAnimValList()) {
+      Element()->FlushAnimations();
+    }
+    return LengthNoFlush();
+  }
+  void Clear(ErrorResult& aError);
+  already_AddRefed<nsIDOMSVGPathSeg> Initialize(nsIDOMSVGPathSeg *aNewItem,
+                                                ErrorResult& aError);
+  nsIDOMSVGPathSeg* GetItem(uint32_t aIndex, ErrorResult& aError)
+  {
+    bool found;
+    nsIDOMSVGPathSeg* item = IndexedGetter(aIndex, found, aError);
+    if (!found) {
+      aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    }
+    return item;
+  }
+  nsIDOMSVGPathSeg* IndexedGetter(uint32_t aIndex, bool& found,
+                                  ErrorResult& aError);
+  already_AddRefed<nsIDOMSVGPathSeg> InsertItemBefore(nsIDOMSVGPathSeg *aNewItem,
+                                                      uint32_t aIndex,
+                                                      ErrorResult& aError);
+  already_AddRefed<nsIDOMSVGPathSeg> ReplaceItem(nsIDOMSVGPathSeg *aNewItem,
+                                                 uint32_t aIndex,
+                                                 ErrorResult& aError);
+  already_AddRefed<nsIDOMSVGPathSeg> RemoveItem(uint32_t aIndex,
+                                                ErrorResult& aError);
+  already_AddRefed<nsIDOMSVGPathSeg> AppendItem(nsIDOMSVGPathSeg *aNewItem,
+                                                ErrorResult& aError)
+  {
+    return InsertItemBefore(aNewItem, LengthNoFlush(), aError);
+  }
+  uint32_t Length() const
+  {
+    return NumberOfItems();
+  }
+
 private:
 
   /**
    * Only our static GetDOMWrapper() factory method may create objects of our
    * type.
    */
   DOMSVGPathSegList(nsSVGElement *aElement, bool aIsAnimValList)
     : mElement(aElement)
@@ -143,17 +183,17 @@ private:
   {
     SetIsDOMBinding();
 
     InternalListWillChangeTo(InternalList()); // Sync mItems
   }
 
   ~DOMSVGPathSegList();
 
-  nsSVGElement* Element() {
+  nsSVGElement* Element() const {
     return mElement.get();
   }
 
   /// Used to determine if this list is the baseVal or animVal list.
   bool IsAnimValList() const {
     return mIsAnimValList;
   }
 
--- a/content/svg/content/src/DOMSVGPointList.cpp
+++ b/content/svg/content/src/DOMSVGPointList.cpp
@@ -183,28 +183,26 @@ DOMSVGPointList::InternalAList() const
 }
 
 // ----------------------------------------------------------------------------
 // nsIDOMSVGPointList implementation:
 
 NS_IMETHODIMP
 DOMSVGPointList::GetNumberOfItems(uint32_t *aNumberOfItems)
 {
-  if (IsAnimValList()) {
-    Element()->FlushAnimations();
-  }
-  *aNumberOfItems = LengthNoFlush();
+  *aNumberOfItems = NumberOfItems();
   return NS_OK;
 }
 
-NS_IMETHODIMP
-DOMSVGPointList::Clear()
+void
+DOMSVGPointList::Clear(ErrorResult& aError)
 {
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return;
   }
 
   if (LengthNoFlush() > 0) {
     nsAttrValue emptyOrOldValue = Element()->WillChangePointList();
     // DOM list items that are to be removed must be removed before we change
     // the internal list, otherwise they wouldn't be able to copy their
     // internal counterparts' values!
 
@@ -220,87 +218,117 @@ DOMSVGPointList::Clear()
     }
 
     InternalList().Clear();
     Element()->DidChangePointList(emptyOrOldValue);
     if (AttrIsAnimating()) {
       Element()->AnimationNeedsResample();
     }
   }
-  return NS_OK;
 }
 
 NS_IMETHODIMP
-DOMSVGPointList::Initialize(nsIDOMSVGPoint *aNewItem,
-                            nsIDOMSVGPoint **_retval)
+DOMSVGPointList::Clear()
 {
-  *_retval = nullptr;
+  ErrorResult rv;
+  Clear(rv);
+  return rv.ErrorCode();
+}
+
+already_AddRefed<nsIDOMSVGPoint>
+DOMSVGPointList::Initialize(nsIDOMSVGPoint *aNewItem, ErrorResult& aError)
+{
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    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.
 
   nsCOMPtr<DOMSVGPoint> domItem = do_QueryInterface(aNewItem);
   if (!domItem) {
-    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+    aError.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+    return nullptr;
   }
   if (domItem->HasOwner() || domItem->IsReadonly()) {
     aNewItem = domItem->Clone();
   }
 
   Clear();
-  return InsertItemBefore(aNewItem, 0, _retval);
+  return InsertItemBefore(aNewItem, 0, aError);
+}
+
+NS_IMETHODIMP
+DOMSVGPointList::Initialize(nsIDOMSVGPoint *aNewItem,
+                            nsIDOMSVGPoint **_retval)
+{
+  ErrorResult rv;
+  *_retval = Initialize(aNewItem, rv).get();
+  return rv.ErrorCode();
+}
+
+nsIDOMSVGPoint*
+DOMSVGPointList::IndexedGetter(uint32_t aIndex, bool& aFound,
+                               ErrorResult& aError)
+{
+  if (IsAnimValList()) {
+    Element()->FlushAnimations();
+  }
+  aFound = aIndex < LengthNoFlush();
+  if (aFound) {
+    EnsureItemAt(aIndex);
+    return mItems[aIndex];
+  }
+  return nullptr;
 }
 
 NS_IMETHODIMP
 DOMSVGPointList::GetItem(uint32_t aIndex,
                          nsIDOMSVGPoint **_retval)
 {
-  *_retval = GetItemAt(aIndex);
-  if (!*_retval) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
-  }
-  NS_ADDREF(*_retval);
-  return NS_OK;
+  ErrorResult rv;
+  NS_IF_ADDREF(*_retval = GetItem(aIndex, rv));
+  return rv.ErrorCode();
 }
 
-NS_IMETHODIMP
-DOMSVGPointList::InsertItemBefore(nsIDOMSVGPoint *aNewItem,
-                                  uint32_t aIndex,
-                                  nsIDOMSVGPoint **_retval)
+already_AddRefed<nsIDOMSVGPoint>
+DOMSVGPointList::InsertItemBefore(nsIDOMSVGPoint *aNewItem, uint32_t aIndex,
+                                  ErrorResult& aError)
 {
-  *_retval = nullptr;
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   aIndex = NS_MIN(aIndex, LengthNoFlush());
   if (aIndex >= DOMSVGPoint::MaxListIndex()) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return nullptr;
   }
 
   nsCOMPtr<DOMSVGPoint> domItem = do_QueryInterface(aNewItem);
   if (!domItem) {
-    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+    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)) {
-    return NS_ERROR_OUT_OF_MEMORY;
+    aError.Throw(NS_ERROR_OUT_OF_MEMORY);
+    return nullptr;
   }
 
   nsAttrValue emptyOrOldValue = Element()->WillChangePointList();
   // Now that we know we're inserting, keep animVal list in sync as necessary.
   MaybeInsertNullInAnimValListAt(aIndex);
 
   InternalList().InsertItem(aIndex, domItem->ToSVGPoint());
   mItems.InsertElementAt(aIndex, domItem.get());
@@ -311,36 +339,46 @@ DOMSVGPointList::InsertItemBefore(nsIDOM
   domItem->InsertingIntoList(this, aIndex, IsAnimValList());
 
   UpdateListIndicesFromIndex(mItems, aIndex + 1);
 
   Element()->DidChangePointList(emptyOrOldValue);
   if (AttrIsAnimating()) {
     Element()->AnimationNeedsResample();
   }
-  domItem.forget(_retval);
-  return NS_OK;
+  return domItem.forget();
 }
 
 NS_IMETHODIMP
-DOMSVGPointList::ReplaceItem(nsIDOMSVGPoint *aNewItem,
-                             uint32_t aIndex,
-                             nsIDOMSVGPoint **_retval)
+DOMSVGPointList::InsertItemBefore(nsIDOMSVGPoint *aNewItem,
+                                  uint32_t aIndex,
+                                  nsIDOMSVGPoint **_retval)
 {
-  *_retval = nullptr;
+  ErrorResult rv;
+  *_retval = InsertItemBefore(aNewItem, aIndex, rv).get();
+  return rv.ErrorCode();
+}
+
+already_AddRefed<nsIDOMSVGPoint>
+DOMSVGPointList::ReplaceItem(nsIDOMSVGPoint *aNewItem, uint32_t aIndex,
+                             ErrorResult& aError)
+{
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   nsCOMPtr<DOMSVGPoint> domItem = do_QueryInterface(aNewItem);
   if (!domItem) {
-    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+    aError.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+    return nullptr;
   }
   if (aIndex >= LengthNoFlush()) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    aError.Throw(NS_ERROR_DOM_INDEX_SIZE_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
@@ -354,70 +392,91 @@ DOMSVGPointList::ReplaceItem(nsIDOMSVGPo
   // This MUST come after the ToSVGPoint() call, otherwise that call
   // would end up reading bad data from InternalList()!
   domItem->InsertingIntoList(this, aIndex, IsAnimValList());
 
   Element()->DidChangePointList(emptyOrOldValue);
   if (AttrIsAnimating()) {
     Element()->AnimationNeedsResample();
   }
-  NS_ADDREF(*_retval = domItem.get());
-  return NS_OK;
+  return domItem.forget();
 }
 
 NS_IMETHODIMP
-DOMSVGPointList::RemoveItem(uint32_t aIndex,
-                            nsIDOMSVGPoint **_retval)
+DOMSVGPointList::ReplaceItem(nsIDOMSVGPoint *aNewItem,
+                             uint32_t aIndex,
+                             nsIDOMSVGPoint **_retval)
 {
-  *_retval = nullptr;
+  ErrorResult rv;
+  *_retval = ReplaceItem(aNewItem, aIndex, rv).get();
+  return rv.ErrorCode();
+}
+
+already_AddRefed<nsIDOMSVGPoint>
+DOMSVGPointList::RemoveItem(uint32_t aIndex, ErrorResult& aError)
+{
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   if (aIndex >= LengthNoFlush()) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return nullptr;
   }
 
   nsAttrValue emptyOrOldValue = Element()->WillChangePointList();
   // Now that we know we're removing, keep animVal list in sync as necessary.
   // Do this *before* touching InternalList() so the removed item can get its
   // internal value.
   MaybeRemoveItemFromAnimValListAt(aIndex);
 
   // We have to return the removed item, so make sure it exists:
   EnsureItemAt(aIndex);
 
   // Notify the DOM item of removal *before* modifying the lists so that the
   // DOM item can copy its *old* value:
   mItems[aIndex]->RemovingFromList();
-  NS_ADDREF(*_retval = mItems[aIndex]);
+  nsCOMPtr<nsIDOMSVGPoint> result = mItems[aIndex];
 
   InternalList().RemoveItem(aIndex);
   mItems.RemoveElementAt(aIndex);
 
   UpdateListIndicesFromIndex(mItems, aIndex);
 
   Element()->DidChangePointList(emptyOrOldValue);
   if (AttrIsAnimating()) {
     Element()->AnimationNeedsResample();
   }
-  return NS_OK;
+  return result.forget();
+}
+
+NS_IMETHODIMP
+DOMSVGPointList::RemoveItem(uint32_t aIndex,
+                            nsIDOMSVGPoint **_retval)
+{
+  ErrorResult rv;
+  *_retval = RemoveItem(aIndex, rv).get();
+  return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
 DOMSVGPointList::AppendItem(nsIDOMSVGPoint *aNewItem,
                             nsIDOMSVGPoint **_retval)
 {
-  return InsertItemBefore(aNewItem, LengthNoFlush(), _retval);
+  ErrorResult rv;
+  *_retval = AppendItem(aNewItem, rv).get();
+  return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
-DOMSVGPointList::GetLength(uint32_t *aNumberOfItems)
+DOMSVGPointList::GetLength(uint32_t *aLength)
 {
-  return GetNumberOfItems(aNumberOfItems);
+  *aLength = LengthNoFlush();
+  return NS_OK;
 }
 
 void
 DOMSVGPointList::EnsureItemAt(uint32_t aIndex)
 {
   if (!mItems[aIndex]) {
     mItems[aIndex] = new DOMSVGPoint(this, aIndex, IsAnimValList());
   }
--- a/content/svg/content/src/DOMSVGPointList.h
+++ b/content/svg/content/src/DOMSVGPointList.h
@@ -10,16 +10,17 @@
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDebug.h"
 #include "nsIDOMSVGPointList.h"
 #include "nsSVGElement.h"
 #include "nsTArray.h"
 #include "SVGPointList.h" // IWYU pragma: keep
 #include "mozilla/Attributes.h"
+#include "mozilla/ErrorResult.h"
 
 class nsIDOMSVGPoint;
 
 namespace mozilla {
 
 class DOMSVGPoint;
 class SVGAnimatedPointList;
 
@@ -126,16 +127,55 @@ public:
   void InternalListWillChangeTo(const SVGPointList& aNewValue);
 
   /**
    * Returns true if our attribute is animating (in which case our animVal is
    * not simply a mirror of our baseVal).
    */
   bool AttrIsAnimating() const;
 
+  uint32_t NumberOfItems() const
+  {
+    if (IsAnimValList()) {
+      Element()->FlushAnimations();
+    }
+    return LengthNoFlush();
+  }
+  void Clear(ErrorResult& aError);
+  already_AddRefed<nsIDOMSVGPoint> Initialize(nsIDOMSVGPoint *aNewItem,
+                                              ErrorResult& aError);
+  nsIDOMSVGPoint* GetItem(uint32_t aIndex, ErrorResult& aError)
+  {
+    bool found;
+    nsIDOMSVGPoint* item = IndexedGetter(aIndex, found, aError);
+    if (!found) {
+      aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    }
+    return item;
+  }
+  nsIDOMSVGPoint* IndexedGetter(uint32_t aIndex, bool& aFound,
+                                ErrorResult& aError);
+  already_AddRefed<nsIDOMSVGPoint> InsertItemBefore(nsIDOMSVGPoint *aNewItem,
+                                                     uint32_t aIndex,
+                                                     ErrorResult& aError);
+  already_AddRefed<nsIDOMSVGPoint> ReplaceItem(nsIDOMSVGPoint *aNewItem,
+                                               uint32_t aIndex,
+                                               ErrorResult& aError);
+  already_AddRefed<nsIDOMSVGPoint> RemoveItem(uint32_t aIndex,
+                                              ErrorResult& aError);
+  already_AddRefed<nsIDOMSVGPoint> AppendItem(nsIDOMSVGPoint *aNewItem,
+                                              ErrorResult& aError)
+  {
+    return InsertItemBefore(aNewItem, LengthNoFlush(), aError);
+  }
+  uint32_t Length() const
+  {
+    return NumberOfItems();
+  }
+
 private:
 
   /**
    * Only our static GetDOMWrapper() factory method may create objects of our
    * type.
    */
   DOMSVGPointList(nsSVGElement *aElement, bool aIsAnimValList)
     : mElement(aElement)
@@ -143,17 +183,17 @@ private:
   {
     SetIsDOMBinding();
 
     InternalListWillChangeTo(InternalList()); // Sync mItems
   }
 
   ~DOMSVGPointList();
 
-  nsSVGElement* Element() {
+  nsSVGElement* Element() const {
     return mElement.get();
   }
 
   /// Used to determine if this list is the baseVal or animVal list.
   bool IsAnimValList() const {
     return mIsAnimValList;
   }
 
--- a/content/svg/content/src/DOMSVGTransformList.cpp
+++ b/content/svg/content/src/DOMSVGTransformList.cpp
@@ -79,24 +79,18 @@ DOMSVGTransformList::WrapObject(JSContex
 {
   return mozilla::dom::oldproxybindings::SVGTransformList::create(cx, scope, this,
                                                          triedToWrap);
 }
 
 nsIDOMSVGTransform*
 DOMSVGTransformList::GetItemAt(uint32_t aIndex)
 {
-  if (IsAnimValList()) {
-    Element()->FlushAnimations();
-  }
-  if (aIndex < LengthNoFlush()) {
-    EnsureItemAt(aIndex);
-    return mItems[aIndex];
-  }
-  return nullptr;
+  ErrorResult rv;
+  return GetItem(aIndex, rv);
 }
 
 void
 DOMSVGTransformList::InternalListLengthWillChange(uint32_t aNewLength)
 {
   uint32_t oldLength = mItems.Length();
 
   if (aNewLength > DOMSVGTransform::MaxListIndex()) {
@@ -143,126 +137,154 @@ DOMSVGTransformList::InternalList() cons
 
 //----------------------------------------------------------------------
 // nsIDOMSVGTransformList methods:
 
 /* readonly attribute unsigned long numberOfItems; */
 NS_IMETHODIMP
 DOMSVGTransformList::GetNumberOfItems(uint32_t *aNumberOfItems)
 {
-  if (IsAnimValList()) {
-    Element()->FlushAnimations();
-  }
-  *aNumberOfItems = LengthNoFlush();
+  *aNumberOfItems = NumberOfItems();
   return NS_OK;
 }
 
 /* readonly attribute unsigned long length; */
 NS_IMETHODIMP
 DOMSVGTransformList::GetLength(uint32_t *aLength)
 {
-  return GetNumberOfItems(aLength);
+  *aLength = Length();
+  return NS_OK;
 }
 
-/* void clear (); */
-NS_IMETHODIMP
-DOMSVGTransformList::Clear()
+void
+DOMSVGTransformList::Clear(ErrorResult& error)
 {
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    error.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return;
   }
 
   if (LengthNoFlush() > 0) {
     nsAttrValue emptyOrOldValue = Element()->WillChangeTransformList();
     // Notify any existing DOM items of removal *before* truncating the lists
     // so that they can find their SVGTransform internal counterparts and copy
     // their values. This also notifies the animVal list:
     mAList->InternalBaseValListWillChangeLengthTo(0);
 
     mItems.Clear();
     InternalList().Clear();
     Element()->DidChangeTransformList(emptyOrOldValue);
     if (mAList->IsAnimating()) {
       Element()->AnimationNeedsResample();
     }
   }
-  return NS_OK;
 }
 
-/* nsIDOMSVGTransform initialize (in nsIDOMSVGTransform newItem); */
+/* void clear (); */
 NS_IMETHODIMP
-DOMSVGTransformList::Initialize(nsIDOMSVGTransform *newItem,
-                                nsIDOMSVGTransform **_retval)
+DOMSVGTransformList::Clear()
 {
-  *_retval = nullptr;
+  ErrorResult rv;
+  Clear(rv);
+  return rv.ErrorCode();
+}
+
+already_AddRefed<nsIDOMSVGTransform>
+DOMSVGTransformList::Initialize(nsIDOMSVGTransform *newItem, ErrorResult& error)
+{
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    error.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   // If newItem is already in a list we should insert a clone of newItem, and
   // for consistency, this should happen even if *this* is the list that
   // newItem is currently in. Note that in the case of newItem 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 newItem, it would actually insert newItem. To prevent that from
   // happening we have to do the clone here, if necessary.
 
   nsCOMPtr<DOMSVGTransform> domItem = do_QueryInterface(newItem);
   if (!domItem) {
-    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+    error.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+    return nullptr;
   }
   if (domItem->HasOwner()) {
     newItem = domItem->Clone();
   }
 
-  Clear();
-  return InsertItemBefore(newItem, 0, _retval);
+  Clear(error);
+  MOZ_ASSERT(!error.Failed(), "How could this fail?");
+  return InsertItemBefore(newItem, 0, error);
+}
+
+/* nsIDOMSVGTransform initialize (in nsIDOMSVGTransform newItem); */
+NS_IMETHODIMP
+DOMSVGTransformList::Initialize(nsIDOMSVGTransform *newItem,
+                                nsIDOMSVGTransform **_retval)
+{
+  ErrorResult rv;
+  *_retval = Initialize(newItem, rv).get();
+  return rv.ErrorCode();
+}
+
+nsIDOMSVGTransform*
+DOMSVGTransformList::IndexedGetter(uint32_t index, bool& found,
+                                   ErrorResult& error)
+{
+  if (IsAnimValList()) {
+    Element()->FlushAnimations();
+  }
+  found = index < LengthNoFlush();
+  if (found) {
+    EnsureItemAt(index);
+    return mItems[index];
+  }
+  return nullptr;
 }
 
 /* nsIDOMSVGTransform getItem (in unsigned long index); */
 NS_IMETHODIMP
 DOMSVGTransformList::GetItem(uint32_t index, nsIDOMSVGTransform **_retval)
 {
-  *_retval = GetItemAt(index);
-  if (!*_retval) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
-  }
-  NS_ADDREF(*_retval);
-  return NS_OK;
+  ErrorResult rv;
+  NS_IF_ADDREF(*_retval = GetItem(index, rv));
+  return rv.ErrorCode();
 }
 
-/* nsIDOMSVGTransform insertItemBefore (in nsIDOMSVGTransform newItem,
- *                                      in unsigned long index); */
-NS_IMETHODIMP
+already_AddRefed<nsIDOMSVGTransform>
 DOMSVGTransformList::InsertItemBefore(nsIDOMSVGTransform *newItem,
-                                      uint32_t index,
-                                      nsIDOMSVGTransform **_retval)
+                                      uint32_t index, ErrorResult& error)
 {
-  *_retval = nullptr;
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    error.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   index = NS_MIN(index, LengthNoFlush());
   if (index >= DOMSVGTransform::MaxListIndex()) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return nullptr;
   }
 
   nsCOMPtr<DOMSVGTransform> domItem = do_QueryInterface(newItem);
   if (!domItem) {
-    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+    error.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+    return nullptr;
   }
   if (domItem->HasOwner()) {
     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)) {
-    return NS_ERROR_OUT_OF_MEMORY;
+    error.Throw(NS_ERROR_OUT_OF_MEMORY);
+    return nullptr;
   }
 
   nsAttrValue emptyOrOldValue = Element()->WillChangeTransformList();
   // Now that we know we're inserting, keep animVal list in sync as necessary.
   MaybeInsertNullInAnimValListAt(index);
 
   InternalList().InsertItem(index, domItem->ToSVGTransform());
   mItems.InsertElementAt(index, domItem.get());
@@ -273,38 +295,48 @@ DOMSVGTransformList::InsertItemBefore(ns
   domItem->InsertingIntoList(this, index, IsAnimValList());
 
   UpdateListIndicesFromIndex(mItems, index + 1);
 
   Element()->DidChangeTransformList(emptyOrOldValue);
   if (mAList->IsAnimating()) {
     Element()->AnimationNeedsResample();
   }
-  domItem.forget(_retval);
-  return NS_OK;
+  return domItem.forget();
 }
 
-/* nsIDOMSVGTransform replaceItem (in nsIDOMSVGTransform newItem,
- *                                 in unsigned long index); */
+/* nsIDOMSVGTransform insertItemBefore (in nsIDOMSVGTransform newItem,
+ *                                      in unsigned long index); */
 NS_IMETHODIMP
+DOMSVGTransformList::InsertItemBefore(nsIDOMSVGTransform *newItem,
+                                      uint32_t index,
+                                      nsIDOMSVGTransform **_retval)
+{
+  ErrorResult rv;
+  *_retval = InsertItemBefore(newItem, index, rv).get();
+  return rv.ErrorCode();
+}
+
+already_AddRefed<nsIDOMSVGTransform>
 DOMSVGTransformList::ReplaceItem(nsIDOMSVGTransform *newItem,
-                                 uint32_t index,
-                                 nsIDOMSVGTransform **_retval)
+                                 uint32_t index, ErrorResult& error)
 {
-  *_retval = nullptr;
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    error.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   nsCOMPtr<DOMSVGTransform> domItem = do_QueryInterface(newItem);
   if (!domItem) {
-    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
+    error.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
+    return nullptr;
   }
   if (index >= LengthNoFlush()) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return nullptr;
   }
   if (domItem->HasOwner()) {
     domItem = domItem->Clone(); // must do this before changing anything!
   }
 
   nsAttrValue emptyOrOldValue = Element()->WillChangeTransformList();
   if (mItems[index]) {
     // Notify any existing DOM item of removal *before* modifying the lists so
@@ -318,108 +350,149 @@ DOMSVGTransformList::ReplaceItem(nsIDOMS
   // This MUST come after the ToSVGPoint() call, otherwise that call
   // would end up reading bad data from InternalList()!
   domItem->InsertingIntoList(this, index, IsAnimValList());
 
   Element()->DidChangeTransformList(emptyOrOldValue);
   if (mAList->IsAnimating()) {
     Element()->AnimationNeedsResample();
   }
-  NS_ADDREF(*_retval = domItem.get());
-  return NS_OK;
+  return domItem.forget();
 }
 
-/* nsIDOMSVGTransform removeItem (in unsigned long index); */
+/* nsIDOMSVGTransform replaceItem (in nsIDOMSVGTransform newItem,
+ *                                 in unsigned long index); */
 NS_IMETHODIMP
-DOMSVGTransformList::RemoveItem(uint32_t index, nsIDOMSVGTransform **_retval)
+DOMSVGTransformList::ReplaceItem(nsIDOMSVGTransform *newItem,
+                                 uint32_t index,
+                                 nsIDOMSVGTransform **_retval)
 {
-  *_retval = nullptr;
+  ErrorResult rv;
+  *_retval = ReplaceItem(newItem, index, rv).get();
+  return rv.ErrorCode();
+}
+
+already_AddRefed<nsIDOMSVGTransform>
+DOMSVGTransformList::RemoveItem(uint32_t index, ErrorResult& error)
+{
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    error.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   if (index >= LengthNoFlush()) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return nullptr;
   }
 
   nsAttrValue emptyOrOldValue = Element()->WillChangeTransformList();
   // Now that we know we're removing, keep animVal list in sync as necessary.
   // Do this *before* touching InternalList() so the removed item can get its
   // internal value.
   MaybeRemoveItemFromAnimValListAt(index);
 
   // We have to return the removed item, so make sure it exists:
   EnsureItemAt(index);
 
   // Notify the DOM item of removal *before* modifying the lists so that the
   // DOM item can copy its *old* value:
   mItems[index]->RemovingFromList();
-  NS_ADDREF(*_retval = mItems[index]);
+  nsCOMPtr<nsIDOMSVGTransform> result = mItems[index];
 
   InternalList().RemoveItem(index);
   mItems.RemoveElementAt(index);
 
   UpdateListIndicesFromIndex(mItems, index);
 
   Element()->DidChangeTransformList(emptyOrOldValue);
   if (mAList->IsAnimating()) {
     Element()->AnimationNeedsResample();
   }
-  return NS_OK;
+  return result.forget();
+}
+
+/* nsIDOMSVGTransform removeItem (in unsigned long index); */
+NS_IMETHODIMP
+DOMSVGTransformList::RemoveItem(uint32_t index, nsIDOMSVGTransform **_retval)
+{
+  ErrorResult rv;
+  *_retval = RemoveItem(index, rv).get();
+  return rv.ErrorCode();
 }
 
 /* nsIDOMSVGTransform appendItem (in nsIDOMSVGTransform newItem); */
 NS_IMETHODIMP
 DOMSVGTransformList::AppendItem(nsIDOMSVGTransform *newItem,
                                 nsIDOMSVGTransform **_retval)
 {
-  return InsertItemBefore(newItem, LengthNoFlush(), _retval);
+  ErrorResult rv;
+  *_retval = AppendItem(newItem, rv).get();
+  return rv.ErrorCode();
+}
+
+already_AddRefed<nsIDOMSVGTransform>
+DOMSVGTransformList::CreateSVGTransformFromMatrix(nsIDOMSVGMatrix *matrix,
+                                                  ErrorResult& error)
+{
+  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());
+  return result.forget();
 }
 
 /* nsIDOMSVGTransform createSVGTransformFromMatrix (in nsIDOMSVGMatrix matrix);
  */
 NS_IMETHODIMP
 DOMSVGTransformList::CreateSVGTransformFromMatrix(nsIDOMSVGMatrix *matrix,
                                                   nsIDOMSVGTransform **_retval)
 {
-  nsCOMPtr<DOMSVGMatrix> domItem = do_QueryInterface(matrix);
-  if (!domItem) {
-    return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
-  }
-
-  NS_ADDREF(*_retval = new DOMSVGTransform(domItem->Matrix()));
-  return NS_OK;
+  ErrorResult rv;
+  *_retval = CreateSVGTransformFromMatrix(matrix, rv).get();
+  return rv.ErrorCode();
 }
 
-/* nsIDOMSVGTransform consolidate (); */
-NS_IMETHODIMP
-DOMSVGTransformList::Consolidate(nsIDOMSVGTransform **_retval)
+already_AddRefed<nsIDOMSVGTransform>
+DOMSVGTransformList::Consolidate(ErrorResult& error)
 {
-  *_retval = nullptr;
   if (IsAnimValList()) {
-    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
+    error.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
+    return nullptr;
   }
 
   if (LengthNoFlush() == 0)
-    return NS_OK;
+    return nullptr;
 
   // Note that SVG 1.1 says, "The consolidation operation creates new
   // SVGTransform object as the first and only item in the list" hence, even if
   // LengthNoFlush() == 1 we can't return that one item (after making it a
   // matrix type). We must orphan the existing item and then make a new one.
 
   // First calculate our matrix
   gfxMatrix mx = InternalList().GetConsolidationMatrix();
 
   // Then orphan the existing items
-  Clear();
+  Clear(error);
+  MOZ_ASSERT(!error.Failed(), "How could this fail?");
 
   // And append the new transform
   nsRefPtr<DOMSVGTransform> transform = new DOMSVGTransform(mx);
-  return InsertItemBefore(transform, LengthNoFlush(), _retval);
+  return InsertItemBefore(transform, LengthNoFlush(), error);
+}
+
+/* nsIDOMSVGTransform consolidate (); */
+NS_IMETHODIMP
+DOMSVGTransformList::Consolidate(nsIDOMSVGTransform **_retval)
+{
+  ErrorResult rv;
+  *_retval = Consolidate(rv).get();
+  return rv.ErrorCode();
 }
 
 //----------------------------------------------------------------------
 // Implementation helpers:
 
 void
 DOMSVGTransformList::EnsureItemAt(uint32_t aIndex)
 {
--- a/content/svg/content/src/DOMSVGTransformList.h
+++ b/content/svg/content/src/DOMSVGTransformList.h
@@ -10,16 +10,17 @@
 #include "DOMSVGAnimatedTransformList.h"
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDebug.h"
 #include "nsIDOMSVGTransformList.h"
 #include "nsTArray.h"
 #include "SVGTransformList.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/ErrorResult.h"
 
 class nsIDOMSVGTransform;
 class nsSVGElement;
 
 namespace mozilla {
 
 class DOMSVGTransform;
 
@@ -81,16 +82,58 @@ public:
       mItems.Length() == InternalList().Length(),
       "DOM wrapper's list length is out of sync");
     return mItems.Length();
   }
 
   /// Called to notify us to synchronize our length and detach excess items.
   void InternalListLengthWillChange(uint32_t aNewLength);
 
+  uint32_t NumberOfItems() const
+  {
+    if (IsAnimValList()) {
+      Element()->FlushAnimations();
+    }
+    return LengthNoFlush();
+  }
+  void Clear(ErrorResult& error);
+  already_AddRefed<nsIDOMSVGTransform> Initialize(nsIDOMSVGTransform *newItem,
+                                                  ErrorResult& error);
+  nsIDOMSVGTransform* GetItem(uint32_t index, ErrorResult& error)
+  {
+    bool found;
+    nsIDOMSVGTransform* item = IndexedGetter(index, found, error);
+    if (!found) {
+      error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    }
+    return item;
+  }
+  nsIDOMSVGTransform* IndexedGetter(uint32_t index, bool& found,
+                                    ErrorResult& error);
+  already_AddRefed<nsIDOMSVGTransform> InsertItemBefore(nsIDOMSVGTransform *newItem,
+                                                        uint32_t index,
+                                                        ErrorResult& error);
+  already_AddRefed<nsIDOMSVGTransform> ReplaceItem(nsIDOMSVGTransform *newItem,
+                                                   uint32_t index,
+                                                   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> Consolidate(ErrorResult& error);
+  uint32_t Length() const
+  {
+    return NumberOfItems();
+  }
+
 private:
 
   nsSVGElement* Element() const {
     return mAList->mElement;
   }
 
   /// Used to determine if this list is the baseVal or animVal list.
   bool IsAnimValList() const {
--- a/content/svg/content/src/nsSVGStyleElement.cpp
+++ b/content/svg/content/src/nsSVGStyleElement.cpp
@@ -5,16 +5,17 @@
 
 #include "nsSVGElement.h"
 #include "nsGkAtoms.h"
 #include "nsIDOMSVGStyleElement.h"
 #include "nsUnicharUtils.h"
 #include "nsIDocument.h"
 #include "nsStyleLinkElement.h"
 #include "nsContentUtils.h"
+#include "nsStubMutationObserver.h"
 
 using namespace mozilla;
 
 typedef nsSVGElement nsSVGStyleElementBase;
 
 class nsSVGStyleElement : public nsSVGStyleElementBase,
                           public nsIDOMSVGStyleElement,
                           public nsStyleLinkElement,
--- a/content/svg/content/src/nsSVGTitleElement.cpp
+++ b/content/svg/content/src/nsSVGTitleElement.cpp
@@ -1,15 +1,16 @@
 /* -*- 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 "nsSVGStylableElement.h"
 #include "nsIDOMSVGTitleElement.h"
+#include "nsStubMutationObserver.h"
 
 typedef nsSVGStylableElement nsSVGTitleElementBase;
 
 class nsSVGTitleElement : public nsSVGTitleElementBase,
                           public nsIDOMSVGTitleElement,
                           public nsStubMutationObserver
 {
 protected:
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -483,16 +483,17 @@ using mozilla::dom::indexedDB::IDBWrappe
 
 #include "nsIDOMMediaQueryList.h"
 
 #include "nsDOMTouchEvent.h"
 #include "nsDOMMutationObserver.h"
 
 #include "nsWrapperCacheInlines.h"
 #include "dombindings.h"
+#include "mozilla/dom/HTMLCollectionBinding.h"
 
 #include "nsIDOMBatteryManager.h"
 #include "BatteryManager.h"
 #include "nsIDOMPowerManager.h"
 #include "nsIDOMWakeLock.h"
 #include "nsIDOMSmsManager.h"
 #include "nsIDOMSmsMessage.h"
 #include "nsIDOMSmsEvent.h"
@@ -8854,25 +8855,26 @@ nsHTMLDocumentSH::GetDocumentAllNodeList
   // in a reserved slot (0) on the document.all JSObject.
   nsresult rv = NS_OK;
 
   jsval collection = JS_GetReservedSlot(obj, 0);
 
   if (!JSVAL_IS_PRIMITIVE(collection)) {
     // We already have a node list in our reserved slot, use it.
     JSObject *obj = JSVAL_TO_OBJECT(collection);
-    if (mozilla::dom::oldproxybindings::HTMLCollection::objIsWrapper(obj)) {
-      nsIHTMLCollection *native =
-        mozilla::dom::oldproxybindings::HTMLCollection::getNative(obj);
-      NS_ADDREF(*nodeList = static_cast<nsContentList*>(native));
+    nsIHTMLCollection* htmlCollection;
+    rv = mozilla::dom::UnwrapObject<nsIHTMLCollection>(cx, obj, htmlCollection);
+    if (NS_SUCCEEDED(rv)) {
+      NS_ADDREF(*nodeList = static_cast<nsContentList*>(htmlCollection));
     }
     else {
       nsISupports *native = sXPConnect->GetNativeOfWrapper(cx, obj);
       if (native) {
         NS_ADDREF(*nodeList = nsContentList::FromSupports(native));
+        rv = NS_OK;
       }
       else {
         rv = NS_ERROR_FAILURE;
       }
     }
   } else {
     // No node list for this document.all yet, create one...
 
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -86,16 +86,24 @@ DOMInterfaces = {
     ],
     'resultNotAddRefed': [ 'canvas' ],
     'binaryNames': {
         'mozImageSmoothingEnabled': 'imageSmoothingEnabled',
         'mozFillRule': 'fillRule'
     }
 }],
 
+'ClientRectList': [
+{
+    'nativeType': 'nsClientRectList',
+    'headerFile': 'nsClientRect.h',
+    'prefable': True,
+    'resultNotAddRefed': [ 'item' ]
+}],
+
 'CSS2Properties': {
   'nativeType': 'nsDOMCSSDeclaration',
   'prefable': True,
 },
 
 'CSSStyleDeclaration': {
   'nativeType': 'nsICSSDeclaration',
   'prefable': True
@@ -104,16 +112,34 @@ DOMInterfaces = {
 'Document': [
 {
     'nativeType': 'nsIDocument',
 },
 {
     'workers': True,
 }],
 
+'DOMSettableTokenList': [
+{
+    'nativeType': 'nsDOMSettableTokenList',
+    'prefable': True,
+    'binaryNames': {
+        '__stringifier': 'Stringify'
+    }
+}],
+
+'DOMTokenList': [
+{
+    'nativeType': 'nsDOMTokenList',
+    'prefable': True,
+    'binaryNames': {
+        '__stringifier': 'Stringify'
+    }
+}],
+
 'Event': [
 {
 },
 {
     'workers': True,
 }],
 
 'EventListener': [
@@ -131,23 +157,56 @@ DOMInterfaces = {
     'prefable': True,
 },
 {
     'workers': True,
     'headerFile': 'mozilla/dom/workers/bindings/EventTarget.h',
     'concrete': False
 }],
 
+'FileList': [
+{
+    'nativeType': 'nsDOMFileList',
+    'headerFile': 'nsDOMFile.h',
+    'prefable': True,
+    'resultNotAddRefed': [ 'item' ]
+}],
+
 'FormData': [
 {
 },
 {
     'workers': True,
 }],
 
+'HTMLCollection': [
+{
+    'nativeType': 'nsIHTMLCollection',
+    'prefable': True,
+    'resultNotAddRefed': [ 'item' ]
+}],
+
+'HTMLOptionsCollection': [
+{
+    'nativeType': 'nsHTMLOptionCollection',
+    'headerFile': 'nsHTMLSelectElement.h',
+    'prefable': True,
+    'resultNotAddRefed': [ 'item' ],
+    'binaryNames': {
+        '__indexedsettercreator': 'SetOption'
+    }
+}],
+
+'HTMLPropertiesCollection': [
+{
+    'headerFile': 'HTMLPropertiesCollection.h',
+    'prefable': True,
+    'resultNotAddRefed': [ 'item', 'namedItem', 'names' ]
+}],
+
 'IID': [
 {
     'nativeType': 'nsIJSIID',
     'headerFile': 'xpcjsid.h',
 },
 {
     'workers': True,
 }],
@@ -165,31 +224,93 @@ DOMInterfaces = {
 {
     'nativeType': 'nsIChannel',
     'notflattened': True
 },
 {
     'workers': True,
 }],
 
+'NodeList': [
+{
+    'nativeType': 'nsINodeList',
+    'prefable': True,
+    'resultNotAddRefed': [ 'item' ]
+}],
+
+'PaintRequestList': [
+{
+    'nativeType': 'nsPaintRequestList',
+    'headerFile': 'nsPaintRequest.h',
+    'prefable': True,
+    'resultNotAddRefed': [ 'item' ]
+}],
+
 'Performance': {
     'nativeType': 'nsPerformance',
     'resultNotAddRefed': [ 'timing', 'navigation' ]
 },
 
 'PerformanceTiming': {
     'nativeType': 'nsPerformanceTiming',
     'headerFile': 'nsPerformance.h'
 },
 
 'PerformanceNavigation': {
     'nativeType': 'nsPerformanceNavigation',
     'headerFile': 'nsPerformance.h'
 },
 
+'PropertyNodeList': [
+{
+    'headerFile': 'HTMLPropertiesCollection.h',
+    'prefable': True,
+    'resultNotAddRefed': [ 'item' ]
+}],
+
+'SVGLengthList': [
+{
+    'nativeType': 'mozilla::DOMSVGLengthList',
+    'headerFile': 'DOMSVGLengthList.h',
+    'prefable': True,
+    'resultNotAddRefed': [ 'getItem' ]
+}],
+
+'SVGNumberList': [
+{
+    'nativeType': 'mozilla::DOMSVGNumberList',
+    'headerFile': 'DOMSVGNumberList.h',
+    'prefable': True,
+    'resultNotAddRefed': [ 'getItem' ]
+}],
+
+'SVGPathSegList': [
+{
+    'nativeType': 'mozilla::DOMSVGPathSegList',
+    'headerFile': 'DOMSVGPathSegList.h',
+    'prefable': True,
+    'resultNotAddRefed': [ 'getItem' ]
+}],
+
+'SVGPointList': [
+{
+    'nativeType': 'mozilla::DOMSVGPointList',
+    'headerFile': 'DOMSVGPointList.h',
+    'prefable': True,
+    'resultNotAddRefed': [ 'getItem' ]
+}],
+
+'SVGTransformList': [
+{
+    'nativeType': 'mozilla::DOMSVGTransformList',
+    'headerFile': 'DOMSVGTransformList.h',
+    'prefable': True,
+    'resultNotAddRefed': [ 'getItem' ]
+}],
+
 'WebGLRenderingContext': {
   'nativeType': 'mozilla::WebGLContext',
   'headerFile': 'WebGLContext.h',
   'prefable': True,
   'resultNotAddRefed': [ 'canvas', 'getContextAttributes', 'getExtension',
                          'getAttachedShaders' ],
   'implicitJSContext': [ 'texImage2D', 'texSubImage2D' ],
 },
@@ -352,24 +473,41 @@ def addExternalIface(iface, nativeType=N
 # macros added for it
 def addExternalHTMLElement(element):
    nativeElement = 'ns' + element
    addExternalIface(element, nativeType=nativeElement,
                     headerFile=nativeElement + '.h')
 
 addExternalHTMLElement('HTMLCanvasElement')
 addExternalHTMLElement('HTMLImageElement')
+addExternalHTMLElement('HTMLOptionElement')
+addExternalHTMLElement('HTMLOptGroupElement')
 addExternalHTMLElement('HTMLVideoElement')
 addExternalIface('CanvasGradient', headerFile='nsIDOMCanvasRenderingContext2D.h')
 addExternalIface('CanvasPattern', headerFile='nsIDOMCanvasRenderingContext2D.h')
+addExternalIface('ClientRect')
 addExternalIface('CSSRule')
 addExternalIface('CSSValue')
+addExternalIface('DOMStringList', nativeType='nsDOMStringList',
+                 headerFile='nsDOMLists.h')
+addExternalIface('Element', nativeType='nsGenericElement')
+addExternalIface('File')
 addExternalIface('HitRegionOptions', nativeType='nsISupports')
+addExternalIface('HTMLElement')
 addExternalIface('ImageData', nativeType='mozilla::dom::ImageData')
+addExternalIface('Node', nativeType='nsINode')
+addExternalIface('PaintRequest')
+addExternalIface('SVGLength')
+addExternalIface('SVGMatrix')
+addExternalIface('SVGNumber')
+addExternalIface('SVGPathSeg')
+addExternalIface('SVGPoint')
+addExternalIface('SVGTransform')
 addExternalIface('TextMetrics', headerFile='nsIDOMCanvasRenderingContext2D.h')
+addExternalIface('Touch', headerFile='nsIDOMTouchEvent.h')
 addExternalIface('WebGLActiveInfo', nativeType='mozilla::WebGLActiveInfo',
                  headerFile='WebGLContext.h')
 addExternalIface('WebGLBuffer', nativeType='mozilla::WebGLBuffer',
                  headerFile='WebGLContext.h')
 addExternalIface('WebGLContextAttributes', nativeType='JSObject',
                  headerFile='jsapi.h')
 addExternalIface('WebGLExtension', nativeType='nsIWebGLExtension',
                  headerFile='WebGLContext.h')
--- a/dom/imptests/failures/html/tests/submission/Opera/microdata/test_001.html.json
+++ b/dom/imptests/failures/html/tests/submission/Opera/microdata/test_001.html.json
@@ -1,7 +1,6 @@
 {
-  "document.getItems must return a NodeList": true,
   "itemValue must reflect the src attribute on track elements": true,
   "itemValue must reflect the textContent of time elements with no datetime attribute": true,
   "itemValue must reflect the datetime attribute of time elements with a datetime attribute": true
 }
 
--- a/dom/interfaces/core/nsIDOMDOMTokenList.idl
+++ b/dom/interfaces/core/nsIDOMDOMTokenList.idl
@@ -12,16 +12,16 @@
  * For more information on this interface please see
  * <http://www.whatwg.org/html5/#domtokenlist>
  */
 [scriptable, uuid(c6f1e160-eeeb-404a-98b0-6f1246520b6e)]
 interface nsIDOMDOMTokenList : nsISupports
 {
   readonly attribute unsigned long length;
 
-  [getter] DOMString item(in unsigned long index);
+  [getter,binaryname(MozItem)] DOMString item(in unsigned long index);
   boolean            contains([Null(Stringify)] in DOMString token);
   void               add([Null(Stringify)] in DOMString token);
   void               remove([Null(Stringify)] in DOMString token);
   boolean            toggle([Null(Stringify)] in DOMString token);
 
   [stringifier] DOMString          toString();
 };
--- a/dom/tests/mochitest/chrome/test_sandbox_bindings.xul
+++ b/dom/tests/mochitest/chrome/test_sandbox_bindings.xul
@@ -21,17 +21,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   <![CDATA[
 
   /** Test for Bug 741267 **/
     function doTest() {
       var win = $("t").contentWindow;
       var sandbox = Components.utils.Sandbox(win, { sandboxPrototype: win });
       try {
         var nl = Components.utils.evalInSandbox("NodeList", sandbox);
-        is(nl, "[object NodeList]", "'NodeList' in a sandbox should return the NodeList interface prototype object");
+        is(nl, String(NodeList), "'NodeList' in a sandbox should return the NodeList interface prototype object");
       } catch (e) {
         ok(false, "'NodeList' shouldn't throw in a sandbox");
       }
       try {
         var et = Components.utils.evalInSandbox("EventTarget", sandbox);
         ok(et, "'EventTarget' in a sandbox should return the EventTarget interface prototype object");
       } catch (e) {
         ok(false, "'EventTarget' shouldn't throw in a sandbox");
new file mode 100644
--- /dev/null
+++ b/dom/webidl/ClientRectList.webidl
@@ -0,0 +1,12 @@
+/* -*- 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/.
+ */
+
+interface ClientRect;
+
+interface ClientRectList {
+  readonly attribute unsigned long length;
+  getter ClientRect? item(unsigned long index);
+};
--- a/dom/webidl/DOMTokenList.webidl
+++ b/dom/webidl/DOMTokenList.webidl
@@ -8,14 +8,18 @@
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface DOMTokenList {
   readonly attribute unsigned long length;
   getter DOMString? item(unsigned long index);
+  [Throws]
   boolean contains(DOMString token);
+  [Throws]
   void add(DOMString token);
+  [Throws]
   void remove(DOMString token);
+  [Throws]
   boolean toggle(DOMString token);
   stringifier DOMString ();
 };
new file mode 100644
--- /dev/null
+++ b/dom/webidl/FileList.webidl
@@ -0,0 +1,18 @@
+/* -*- 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://dev.w3.org/2006/webapi/FileAPI/
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface File;
+
+interface FileList {
+  getter File? item(unsigned long index);
+  readonly attribute unsigned long length;
+};
--- a/dom/webidl/HTMLCollection.webidl
+++ b/dom/webidl/HTMLCollection.webidl
@@ -5,13 +5,16 @@
  *
  * The origin of this IDL file is
  * http://www.w3.org/TR/2012/WD-dom-20120105/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
+interface Element;
+
 interface HTMLCollection {
   readonly attribute unsigned long length;
   getter Element? item(unsigned long index);
+  [Throws]
   getter object? namedItem(DOMString name); // only returns Element
 };
new file mode 100644
--- /dev/null
+++ b/dom/webidl/HTMLOptionsCollection.webidl
@@ -0,0 +1,29 @@
+/* -*- 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/2012/WD-html5-20120329/
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface HTMLElement;
+interface HTMLOptionElement;
+interface HTMLOptGroupElement;
+
+interface HTMLOptionsCollection : HTMLCollection {
+           attribute unsigned long length;
+  [Throws]
+  getter object? namedItem(DOMString name);
+  [Throws]
+  setter creator void (unsigned long index, HTMLOptionElement option);
+  [Throws]
+  void add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or long)? before = null);
+  [Throws]
+  void remove(long index);
+  [Throws]
+           attribute long selectedIndex;
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/HTMLPropertiesCollection.webidl
@@ -0,0 +1,26 @@
+/* -*- 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.whatwg.org/specs/web-apps/current-work/
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface DOMStringList;
+
+interface HTMLPropertiesCollection : HTMLCollection {
+  // inherits length and item()
+  getter PropertyNodeList? namedItem(DOMString name); // overrides inherited namedItem()
+  readonly attribute DOMStringList names;
+};
+
+typedef sequence<any> PropertyValueArray;
+
+interface PropertyNodeList : NodeList {
+  [Throws]
+  PropertyValueArray getValues();
+};
--- a/dom/webidl/NodeList.webidl
+++ b/dom/webidl/NodeList.webidl
@@ -5,12 +5,14 @@
  *
  * The origin of this IDL file is
  * http://www.w3.org/TR/2012/WD-dom-20120105/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
+interface Node;
+
 interface NodeList {
   getter Node? item(unsigned long index);
   readonly attribute unsigned long length;
 };
new file mode 100644
--- /dev/null
+++ b/dom/webidl/PaintRequestList.webidl
@@ -0,0 +1,12 @@
+/* -*- 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/.
+ */
+
+interface PaintRequest;
+
+interface PaintRequestList {
+  readonly attribute unsigned long length;
+  getter PaintRequest? item(unsigned long index);
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/SVGLengthList.webidl
@@ -0,0 +1,34 @@
+/* -*- 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/SVG11/
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface SVGLength;
+
+interface SVGLengthList {
+  readonly attribute unsigned long numberOfItems;
+  [Throws]
+  void clear();
+  [Throws]
+  SVGLength initialize(SVGLength newItem);
+  [Throws]
+  getter SVGLength getItem(unsigned long index);
+  [Throws]
+  SVGLength insertItemBefore(SVGLength newItem, unsigned long index);
+  [Throws]
+  SVGLength replaceItem(SVGLength newItem, unsigned long index);
+  [Throws]
+  SVGLength removeItem(unsigned long index);
+  [Throws]
+  SVGLength appendItem(SVGLength newItem);
+
+  // Mozilla-specific stuff
+  readonly attribute unsigned long length; // synonym for numberOfItems
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/SVGNumberList.webidl
@@ -0,0 +1,34 @@
+/* -*- 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/SVG11/
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface SVGNumber;
+
+interface SVGNumberList {
+  readonly attribute unsigned long numberOfItems;
+  [Throws]
+  void clear();
+  [Throws]
+  SVGNumber initialize(SVGNumber newItem);
+  [Throws]
+  getter SVGNumber getItem(unsigned long index);
+  [Throws]
+  SVGNumber insertItemBefore(SVGNumber newItem, unsigned long index);
+  [Throws]
+  SVGNumber replaceItem(SVGNumber newItem, unsigned long index);
+  [Throws]
+  SVGNumber removeItem(unsigned long index);
+  [Throws]
+  SVGNumber appendItem(SVGNumber newItem);
+
+  // Mozilla-specific stuff
+  readonly attribute unsigned long length; // synonym for numberOfItems
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/SVGPathSegList.webidl
@@ -0,0 +1,34 @@
+/* -*- 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/SVG11/
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface SVGPathSeg;
+
+interface SVGPathSegList {
+  readonly attribute unsigned long numberOfItems;
+  [Throws]
+  void clear();
+  [Throws]
+  SVGPathSeg initialize(SVGPathSeg newItem);
+  [Throws]
+  getter SVGPathSeg getItem(unsigned long index);
+  [Throws]
+  SVGPathSeg insertItemBefore(SVGPathSeg newItem, unsigned long index);
+  [Throws]
+  SVGPathSeg replaceItem(SVGPathSeg newItem, unsigned long index);
+  [Throws]
+  SVGPathSeg removeItem(unsigned long index);
+  [Throws]
+  SVGPathSeg appendItem(SVGPathSeg newItem);
+
+  // Mozilla-specific stuff
+  readonly attribute unsigned long length; // synonym for numberOfItems
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/SVGPointList.webidl
@@ -0,0 +1,34 @@
+/* -*- 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/SVG11/
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface SVGPoint;
+
+interface SVGPointList {
+  readonly attribute unsigned long numberOfItems;
+  [Throws]
+  void clear();
+  [Throws]
+  SVGPoint initialize(SVGPoint newItem);
+  [Throws]
+  getter SVGPoint getItem(unsigned long index);
+  [Throws]
+  SVGPoint insertItemBefore(SVGPoint newItem, unsigned long index);
+  [Throws]
+  SVGPoint replaceItem(SVGPoint newItem, unsigned long index);
+  [Throws]
+  SVGPoint removeItem(unsigned long index);
+  [Throws]
+  SVGPoint appendItem(SVGPoint newItem);
+
+  // Mozilla-specific stuff
+  readonly attribute unsigned long length; // synonym for numberOfItems
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/SVGTransformList.webidl
@@ -0,0 +1,39 @@
+/* -*- 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/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);
+  [Throws]
+  getter SVGTransform getItem(unsigned long index);
+  [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
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/TouchList.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://dvcs.w3.org/hg/webevents/raw-file/default/touchevents.html
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface Touch;
+
+interface TouchList {
+  readonly attribute unsigned long length;
+  getter Touch? item(unsigned long index);
+  Touch identifiedTouch(long identifier);
+};
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -7,23 +7,37 @@ webidl_base = $(topsrcdir)/dom/webidl
 generated_webidl_files = \
   CSS2Properties.webidl \
   $(NULL)
 
 webidl_files = \
   AudioContext.webidl \
   Blob.webidl \
   CanvasRenderingContext2D.webidl \
+  ClientRectList.webidl \
   CSSStyleDeclaration.webidl \
+  DOMTokenList.webidl \
+  DOMSettableTokenList.webidl \
   Function.webidl \
   EventListener.webidl \
   EventTarget.webidl \
+  FileList.webidl \
+  HTMLCollection.webidl \
+  HTMLOptionsCollection.webidl \
+  HTMLPropertiesCollection.webidl \
+  NodeList.webidl \
+  PaintRequestList.webidl \
   Performance.webidl \
   PerformanceNavigation.webidl \
   PerformanceTiming.webidl \
+  SVGLengthList.webidl \
+  SVGNumberList.webidl \
+  SVGPathSegList.webidl \
+  SVGPointList.webidl \
+  SVGTransformList.webidl \
   WebSocket.webidl \
   XMLHttpRequest.webidl \
   XMLHttpRequestEventTarget.webidl \
   XMLHttpRequestUpload.webidl \
   $(NULL)
 
 ifdef MOZ_WEBGL
 webidl_files += \
--- a/js/xpconnect/src/nsDOMQS.h
+++ b/js/xpconnect/src/nsDOMQS.h
@@ -5,16 +5,18 @@
 #ifndef nsDOMQS_h__
 #define nsDOMQS_h__
 
 #include "mozilla/dom/ImageData.h"
 #include "nsDOMClassInfoID.h"
 #include "nsGenericHTMLElement.h"
 #include "nsHTMLCanvasElement.h"
 #include "nsHTMLImageElement.h"
+#include "nsHTMLOptionElement.h"
+#include "nsHTMLOptGroupElement.h"
 #include "nsHTMLVideoElement.h"
 #include "nsHTMLDocument.h"
 #include "nsICSSDeclaration.h"
 #include "nsSVGStylableElement.h"
 
 #define DEFINE_UNWRAP_CAST(_interface, _base, _bit)                           \
 template <>                                                                   \
 MOZ_ALWAYS_INLINE JSBool                                                      \
@@ -172,16 +174,18 @@ xpc_qsUnwrapArg<_clazz>(JSContext *cx, j
     nsISupports* argRef = static_cast<nsIContent*>(*ppArgRef);                \
     nsresult rv = xpc_qsUnwrapArg<_clazz>(cx, v, ppArg, &argRef, vp);         \
     *ppArgRef = static_cast<_clazz*>(static_cast<nsIContent*>(argRef));       \
     return rv;                                                                \
 }
 
 DEFINE_UNWRAP_CAST_HTML(canvas, nsHTMLCanvasElement)
 DEFINE_UNWRAP_CAST_HTML(img, nsHTMLImageElement)
+DEFINE_UNWRAP_CAST_HTML(optgroup, nsHTMLOptGroupElement)
+DEFINE_UNWRAP_CAST_HTML(option, nsHTMLOptionElement)
 DEFINE_UNWRAP_CAST_HTML(video, nsHTMLVideoElement)
 
 template <>
 inline nsresult
 xpc_qsUnwrapArg<mozilla::dom::ImageData>(JSContext *cx, jsval v,
                                          mozilla::dom::ImageData **ppArg,
                                          mozilla::dom::ImageData **ppArgRef,
                                          jsval *vp)
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -50,16 +50,17 @@
 #include "nsContentCreatorFunctions.h"
 #include "nsLayoutUtils.h"
 #include "nsDisplayList.h"
 #include "nsITheme.h"
 #include "nsThemeConstants.h"
 #include "nsAsyncDOMEvent.h"
 #include "nsRenderingContext.h"
 #include "mozilla/Preferences.h"
+#include "nsContentList.h"
 
 using namespace mozilla;
 
 NS_IMETHODIMP
 nsComboboxControlFrame::RedisplayTextEvent::Run()
 {
   if (mControlFrame)
     mControlFrame->HandleRedisplayTextEvent();
--- a/layout/forms/nsFileControlFrame.cpp
+++ b/layout/forms/nsFileControlFrame.cpp
@@ -48,16 +48,17 @@
 #include "nsICapturePicker.h"
 #include "nsIFileURL.h"
 #include "nsDOMFile.h"
 #include "nsEventStates.h"
 #include "nsTextControlFrame.h"
 
 #include "nsIDOMDOMStringList.h"
 #include "nsIDOMDragEvent.h"
+#include "nsContentList.h"
 
 namespace dom = mozilla::dom;
 
 #define SYNC_TEXT 0x1
 #define SYNC_BUTTON 0x2
 
 nsIFrame*
 NS_NewFileControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
--- a/layout/forms/nsGfxButtonControlFrame.cpp
+++ b/layout/forms/nsGfxButtonControlFrame.cpp
@@ -19,16 +19,17 @@
 #include "nsContentUtils.h"
 // MouseEvent suppression in PP
 #include "nsGUIEvent.h"
 #include "nsContentList.h"
 #include "nsContentCreatorFunctions.h"
 
 #include "nsNodeInfoManager.h"
 #include "nsIDOMHTMLInputElement.h"
+#include "nsContentList.h"
 
 const nscoord kSuggestedNotSet = -1;
 
 nsGfxButtonControlFrame::nsGfxButtonControlFrame(nsStyleContext* aContext):
   nsHTMLButtonControlFrame(aContext)
 {
 }
 
--- a/layout/forms/nsMeterFrame.cpp
+++ b/layout/forms/nsMeterFrame.cpp
@@ -16,16 +16,17 @@
 #include "nsNodeInfoManager.h"
 #include "nsINodeInfo.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsContentUtils.h"
 #include "nsFormControlFrame.h"
 #include "nsFontMetrics.h"
 #include "nsContentList.h"
 #include "mozilla/dom/Element.h"
+#include "nsContentList.h"
 
 
 nsIFrame*
 NS_NewMeterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsMeterFrame(aContext);
 }
 
--- a/layout/forms/nsProgressFrame.cpp
+++ b/layout/forms/nsProgressFrame.cpp
@@ -16,16 +16,17 @@
 #include "nsNodeInfoManager.h"
 #include "nsINodeInfo.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsContentUtils.h"
 #include "nsFormControlFrame.h"
 #include "nsContentList.h"
 #include "nsFontMetrics.h"
 #include "mozilla/dom/Element.h"
+#include "nsContentList.h"
 
 
 nsIFrame*
 NS_NewProgressFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsProgressFrame(aContext);
 }
 
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -65,16 +65,17 @@
 #include "nsIDOMText.h" //for multiline getselection
 #include "nsNodeInfoManager.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsINativeKeyBindings.h"
 #include "nsIJSContextStack.h"
 #include "nsFocusManager.h"
 #include "nsTextEditRules.h"
 #include "nsPresState.h"
+#include "nsContentList.h"
 
 #include "mozilla/FunctionTimer.h"
 #include "mozilla/Selection.h"
 
 #define DEFAULT_COLUMN_WIDTH 20
 
 using namespace mozilla;
 
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -50,16 +50,17 @@
 #include "mozilla/Util.h"
 #include "FrameLayerBuilder.h"
 #include "nsSMILKeySpline.h"
 #include "nsSubDocumentFrame.h"
 #include "nsSVGOuterSVGFrame.h"
 #include "mozilla/Attributes.h"
 #include "ScrollbarActivity.h"
 #include "nsRefreshDriver.h"
+#include "nsContentList.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 //----------------------------------------------------------------------
 
 //----------nsHTMLScrollFrame-------------------------------------------
 
--- a/layout/generic/nsVideoFrame.cpp
+++ b/layout/generic/nsVideoFrame.cpp
@@ -25,16 +25,17 @@
 #include "nsBoxFrame.h"
 #include "nsImageFrame.h"
 #include "nsIImageLoadingContent.h"
 #include "nsCSSRendering.h"
 #include "nsContentUtils.h"
 #include "mozilla/layers/ShadowLayers.h"
 #include "ImageContainer.h"
 #include "ImageLayers.h"
+#include "nsContentList.h"
 
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::dom;
--- a/layout/printing/nsPrintEngine.cpp
+++ b/layout/printing/nsPrintEngine.cpp
@@ -115,16 +115,17 @@ static const char kPrintingPromptService
 #include "nsIContentViewer.h"
 #include "nsIDocumentViewerPrint.h"
 
 #include "nsFocusManager.h"
 #include "nsRange.h"
 #include "nsCDefaultURIFixup.h"
 #include "nsIURIFixup.h"
 #include "mozilla/dom/Element.h"
+#include "nsContentList.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 //-----------------------------------------------------
 // PR LOGGING
 #ifdef MOZ_LOGGING
 #define FORCE_PR_LOG /* Allow logging in the release build */
--- a/layout/svg/base/src/nsSVGUseFrame.cpp
+++ b/layout/svg/base/src/nsSVGUseFrame.cpp
@@ -3,16 +3,17 @@
  * 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/. */
 
 // Keep in (case-insensitive) order:
 #include "nsIAnonymousContentCreator.h"
 #include "nsIDOMSVGUseElement.h"
 #include "nsSVGGFrame.h"
 #include "nsSVGUseElement.h"
+#include "nsContentList.h"
 
 typedef nsSVGGFrame nsSVGUseFrameBase;
 
 class nsSVGUseFrame : public nsSVGUseFrameBase,
                       public nsIAnonymousContentCreator
 {
   friend nsIFrame*
   NS_NewSVGUseFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);