Fix for bug 791774 (Hook DOM lists up to the new DOM bindings). r=bz.
authorPeter Van der Beken <peterv@propagandism.org>
Wed, 13 Jun 2012 17:18:30 +0200
changeset 108850 64236acfaa803fa31e2846ba744392b7f681501e
parent 108849 f4c544d409bdcee68326c74775313ce72c573858
child 108851 1f0367f9f1b6e0f6123165dda95ae6b7cdee6c6d
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersbz
bugs791774
milestone18.0a1
Fix for bug 791774 (Hook DOM lists up to the new DOM bindings). r=bz.
content/base/src/FragmentOrElement.cpp
content/base/src/nsContentList.cpp
content/base/src/nsDOMFile.cpp
content/base/src/nsDOMSettableTokenList.cpp
content/base/src/nsDOMTokenList.cpp
content/base/src/nsGenericElement.cpp
content/events/src/nsPaintRequest.cpp
content/events/src/nsPaintRequest.h
content/html/content/src/HTMLPropertiesCollection.cpp
content/html/content/src/nsClientRect.cpp
content/html/content/src/nsHTMLFormElement.cpp
content/html/content/src/nsHTMLSelectElement.cpp
content/html/content/src/nsHTMLTableElement.cpp
content/svg/content/src/DOMSVGLengthList.cpp
content/svg/content/src/DOMSVGNumberList.cpp
content/svg/content/src/DOMSVGPathSegList.cpp
content/svg/content/src/DOMSVGPointList.cpp
content/svg/content/src/DOMSVGTransformList.cpp
content/svg/content/test/test_SVGxxxListIndexing.xhtml
content/xbl/src/nsBindingManager.cpp
dom/base/nsDOMClassInfo.cpp
dom/bindings/Codegen.py
dom/imptests/failures/webapps/DOMCore/tests/approved/test_interfaces.html.json
dom/tests/mochitest/chrome/test_moving_nodeList.xul
dom/tests/mochitest/general/file_moving_nodeList.html
js/xpconnect/src/dombindings.conf
js/xpconnect/src/dombindings.cpp
js/xpconnect/src/dombindings.h
js/xpconnect/src/dombindingsgen.py
--- a/content/base/src/FragmentOrElement.cpp
+++ b/content/base/src/FragmentOrElement.cpp
@@ -94,16 +94,17 @@
 #include "nsIView.h"
 #include "nsIViewManager.h"
 #include "nsIScrollableFrame.h"
 #include "nsXBLInsertionPoint.h"
 #include "mozilla/css/StyleRule.h" /* For nsCSSSelectorList */
 #include "nsRuleProcessorData.h"
 #include "nsAsyncDOMEvent.h"
 #include "nsTextNode.h"
+#include "mozilla/dom/NodeListBinding.h"
 #include "dombindings.h"
 
 #ifdef MOZ_XUL
 #include "nsIXULDocument.h"
 #endif /* MOZ_XUL */
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsCCUncollectableMarker.h"
@@ -384,17 +385,23 @@ NS_INTERFACE_TABLE_HEAD(nsChildContentLi
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsChildContentList)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(NodeList)
 NS_INTERFACE_MAP_END
 
 JSObject*
 nsChildContentList::WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap)
 {
-  return mozilla::dom::oldproxybindings::NodeList::create(cx, scope, this, triedToWrap);
+  JSObject* obj = NodeListBinding::Wrap(cx, scope, this, triedToWrap);
+  if (obj || *triedToWrap) {
+    return obj;
+  }
+
+  *triedToWrap = true;
+  return oldproxybindings::NodeList::create(cx, scope, this);
 }
 
 NS_IMETHODIMP
 nsChildContentList::GetLength(uint32_t* aLength)
 {
   *aLength = mNode ? mNode->GetChildCount() : 0;
 
   return NS_OK;
--- a/content/base/src/nsContentList.cpp
+++ b/content/base/src/nsContentList.cpp
@@ -14,19 +14,19 @@
 #include "nsIContent.h"
 #include "nsIDOMNode.h"
 #include "nsIDocument.h"
 #include "nsGenericElement.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsContentUtils.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsGkAtoms.h"
-
+#include "mozilla/dom/HTMLCollectionBinding.h"
+#include "mozilla/dom/NodeListBinding.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"
@@ -158,17 +158,23 @@ NS_INTERFACE_MAP_END_INHERITING(nsBaseCo
 
 NS_IMPL_ADDREF_INHERITED(nsSimpleContentList, nsBaseContentList)
 NS_IMPL_RELEASE_INHERITED(nsSimpleContentList, nsBaseContentList)
 
 JSObject*
 nsSimpleContentList::WrapObject(JSContext *cx, JSObject *scope,
                                 bool *triedToWrap)
 {
-  return mozilla::dom::oldproxybindings::NodeList::create(cx, scope, this, triedToWrap);
+  JSObject* obj = NodeListBinding::Wrap(cx, scope, this, triedToWrap);
+  if (obj || *triedToWrap) {
+    return obj;
+  }
+
+  *triedToWrap = true;
+  return oldproxybindings::NodeList::create(cx, scope, this);
 }
 
 // nsFormContentList
 
 nsFormContentList::nsFormContentList(nsIContent *aForm,
                                      nsBaseContentList& aContentList)
   : nsSimpleContentList(aForm)
 {
@@ -292,25 +298,37 @@ const nsCacheableFuncStringContentList::
 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* obj = NodeListBinding::Wrap(cx, scope, this, triedToWrap);
+  if (obj || *triedToWrap) {
+    return obj;
+  }
+
+  *triedToWrap = true;
+  return oldproxybindings::NodeList::create(cx, scope, this);
 }
 
 
 JSObject*
 nsCacheableFuncStringHTMLCollection::WrapObject(JSContext *cx, JSObject *scope,
                                                 bool *triedToWrap)
 {
-  return oldproxybindings::HTMLCollection::create(cx, scope, this, triedToWrap);
+  JSObject* obj = HTMLCollectionBinding::Wrap(cx, scope, this, triedToWrap);
+  if (obj || *triedToWrap) {
+    return obj;
+  }
+
+  *triedToWrap = true;
+  return oldproxybindings::HTMLCollection::create(cx, scope, this);
 }
 
 // Hashtable for storing nsCacheableFuncStringContentList
 static PLDHashTable gFuncStringContentListHashTable;
 
 struct FuncStringContentListHashEntry : public PLDHashEntryHdr
 {
   nsCacheableFuncStringContentList* mContentList;
@@ -529,18 +547,23 @@ nsContentList::~nsContentList()
     // Clean up mData
     (*mDestroyFunc)(mData);
   }
 }
 
 JSObject*
 nsContentList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
 {
-  return mozilla::dom::oldproxybindings::HTMLCollection::create(cx, scope, this,
-                                                       triedToWrap);
+  JSObject* obj = HTMLCollectionBinding::Wrap(cx, scope, this, triedToWrap);
+  if (obj || *triedToWrap) {
+    return obj;
+  }
+
+  *triedToWrap = true;
+  return oldproxybindings::HTMLCollection::create(cx, scope, this);
 }
 
 DOMCI_DATA(ContentList, nsContentList)
 
 // QueryInterface implementation for nsContentList
 NS_INTERFACE_TABLE_HEAD(nsContentList)
   NS_NODELIST_OFFSET_AND_INTERFACE_TABLE_BEGIN(nsContentList)
     NS_CONTENT_LIST_INTERFACES(nsContentList)
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -30,16 +30,17 @@
 #include "nsStringStream.h"
 #include "nsJSUtils.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Attributes.h"
 
 #include "plbase64.h"
 #include "prmem.h"
+#include "mozilla/dom/FileListBinding.h"
 #include "dombindings.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // XXXkhuey the input stream that we pass out of a DOMFile
 // can outlive the actual DOMFile object.  Thus, we must
 // ensure that the buffer underlying the stream we get
@@ -675,17 +676,23 @@ NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMFileList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMFileList)
 
 JSObject*
 nsDOMFileList::WrapObject(JSContext *cx, JSObject *scope,
                           bool *triedToWrap)
 {
-  return mozilla::dom::oldproxybindings::FileList::create(cx, scope, this, triedToWrap);
+  JSObject* obj = FileListBinding::Wrap(cx, scope, this, triedToWrap);
+  if (obj || *triedToWrap) {
+    return obj;
+  }
+
+  *triedToWrap = true;
+  return oldproxybindings::FileList::create(cx, scope, this);
 }
 
 nsIDOMFile*
 nsDOMFileList::GetItemAt(uint32_t aIndex)
 {
   return Item(aIndex);
 }
 
--- a/content/base/src/nsDOMSettableTokenList.cpp
+++ b/content/base/src/nsDOMSettableTokenList.cpp
@@ -2,16 +2,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/. */
 
 /*
  * Implementation of nsIDOMDOMSettableTokenList specified by HTML5.
  */
 
 #include "nsDOMSettableTokenList.h"
+#include "mozilla/dom/DOMSettableTokenListBinding.h"
 #include "dombindings.h"
 
 
 nsDOMSettableTokenList::nsDOMSettableTokenList(nsGenericElement *aElement, nsIAtom* aAttrAtom)
   : nsDOMTokenList(aElement, aAttrAtom)
 {
 }
 
@@ -46,11 +47,19 @@ nsDOMSettableTokenList::SetValue(const n
 
   return mElement->SetAttr(kNameSpaceID_None, mAttrAtom, aValue, true);
 }
 
 JSObject*
 nsDOMSettableTokenList::WrapObject(JSContext *cx, JSObject *scope,
                                    bool *triedToWrap)
 {
-  return mozilla::dom::oldproxybindings::DOMSettableTokenList::create(cx, scope, this,
-                                                             triedToWrap);
+  JSObject* obj = mozilla::dom::DOMSettableTokenListBinding::Wrap(cx, scope,
+                                                                  this,
+                                                                  triedToWrap);
+  if (obj || *triedToWrap) {
+    return obj;
+  }
+
+  *triedToWrap = true;
+  return mozilla::dom::oldproxybindings::DOMSettableTokenList::create(cx, scope,
+                                                                      this);
 }
--- a/content/base/src/nsDOMTokenList.cpp
+++ b/content/base/src/nsDOMTokenList.cpp
@@ -7,16 +7,17 @@
  */
 
 #include "nsDOMTokenList.h"
 
 #include "nsAttrValue.h"
 #include "nsContentUtils.h"
 #include "nsError.h"
 #include "nsGenericElement.h"
+#include "mozilla/dom/DOMTokenListBinding.h"
 #include "dombindings.h"
 #include "mozilla/ErrorResult.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 nsDOMTokenList::nsDOMTokenList(nsGenericElement* aElement, nsIAtom* aAttrAtom)
   : mElement(aElement),
@@ -307,12 +308,17 @@ nsDOMTokenList::ToString(nsAString& aRes
 {
   Stringify(aResult);
   return NS_OK;
 }
 
 JSObject*
 nsDOMTokenList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
 {
-  return mozilla::dom::oldproxybindings::DOMTokenList::create(cx, scope, this,
-                                                     triedToWrap);
+  JSObject* obj = DOMTokenListBinding::Wrap(cx, scope, this, triedToWrap);
+  if (obj || *triedToWrap) {
+    return obj;
+  }
+
+  *triedToWrap = true;
+  return oldproxybindings::DOMTokenList::create(cx, scope, this);
 }
 
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -97,17 +97,16 @@
 #include "nsIViewManager.h"
 #include "nsIScrollableFrame.h"
 #include "nsXBLInsertionPoint.h"
 #include "mozilla/css/StyleRule.h" /* For nsCSSSelectorList */
 #include "nsCSSRuleProcessor.h"
 #include "nsRuleProcessorData.h"
 #include "nsAsyncDOMEvent.h"
 #include "nsTextNode.h"
-#include "dombindings.h"
 
 #ifdef MOZ_XUL
 #include "nsIXULDocument.h"
 #endif /* MOZ_XUL */
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsCCUncollectableMarker.h"
 
--- a/content/events/src/nsPaintRequest.cpp
+++ b/content/events/src/nsPaintRequest.cpp
@@ -4,16 +4,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsPaintRequest.h"
 
 #include "nsDOMClassInfoID.h"
 #include "nsClientRect.h"
 #include "nsIFrame.h"
 #include "nsContentUtils.h"
+#include "mozilla/dom/PaintRequestListBinding.h"
+#include "dombindings.h"
 
 DOMCI_DATA(PaintRequest, nsPaintRequest)
 
 NS_INTERFACE_TABLE_HEAD(nsPaintRequest)
   NS_INTERFACE_TABLE1(nsPaintRequest, nsIDOMPaintRequest)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(PaintRequest)
 NS_INTERFACE_MAP_END
@@ -48,16 +50,31 @@ NS_INTERFACE_TABLE_HEAD(nsPaintRequestLi
   NS_INTERFACE_TABLE1(nsPaintRequestList, nsIDOMPaintRequestList)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsPaintRequestList)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(PaintRequestList)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPaintRequestList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPaintRequestList)
 
+JSObject*
+nsPaintRequestList::WrapObject(JSContext *cx, JSObject *scope,
+                               bool *triedToWrap)
+{
+  JSObject* obj = mozilla::dom::PaintRequestListBinding::Wrap(cx, scope, this,
+                                                              triedToWrap);
+  if (obj || *triedToWrap) {
+    return obj;
+  }
+
+  *triedToWrap = true;
+  return mozilla::dom::oldproxybindings::PaintRequestList::create(cx, scope,
+                                                                  this);
+}
+
 NS_IMETHODIMP    
 nsPaintRequestList::GetLength(uint32_t* aLength)
 {
   *aLength = Length();
   return NS_OK;
 }
 
 NS_IMETHODIMP    
--- a/content/events/src/nsPaintRequest.h
+++ b/content/events/src/nsPaintRequest.h
@@ -5,18 +5,18 @@
 
 #ifndef NSPAINTREQUEST_H_
 #define NSPAINTREQUEST_H_
 
 #include "nsIDOMPaintRequest.h"
 #include "nsIDOMPaintRequestList.h"
 #include "nsPresContext.h"
 #include "nsIDOMEvent.h"
-#include "dombindings.h"
 #include "mozilla/Attributes.h"
+#include "nsWrapperCache.h"
 
 class nsPaintRequest MOZ_FINAL : public nsIDOMPaintRequest
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMPAINTREQUEST
 
   nsPaintRequest() { mRequest.mFlags = 0; }
@@ -39,22 +39,17 @@ public:
     SetIsDOMBinding();
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsPaintRequestList)
   NS_DECL_NSIDOMPAINTREQUESTLIST
   
   virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
-                               bool *triedToWrap)
-  {
-    return mozilla::dom::oldproxybindings::PaintRequestList::create(cx, scope, this,
-                                                           triedToWrap);
-  }
-
+                               bool *triedToWrap);
   nsISupports* GetParentObject()
   {
     return mParent;
   }
 
   void Append(nsIDOMPaintRequest* aElement) { mArray.AppendObject(aElement); }
 
   static nsPaintRequestList* FromSupports(nsISupports* aSupports)
--- a/content/html/content/src/HTMLPropertiesCollection.cpp
+++ b/content/html/content/src/HTMLPropertiesCollection.cpp
@@ -7,18 +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"
+#include "mozilla/dom/HTMLPropertiesCollectionBinding.h"
 
 DOMCI_DATA(HTMLPropertiesCollection, mozilla::dom::HTMLPropertiesCollection)
 DOMCI_DATA(PropertyNodeList, mozilla::dom::PropertyNodeList)
 
 namespace mozilla {
 namespace dom {
 
 static PLDHashOperator
@@ -105,18 +105,24 @@ HTMLPropertiesCollection::SetDocument(ns
   mNamedItemEntries.EnumerateRead(SetPropertyListDocument, aDocument);
   mIsDirty = true;
 }
 
 JSObject*
 HTMLPropertiesCollection::WrapObject(JSContext* cx, JSObject* scope,
                                      bool* triedToWrap)
 {
-  return mozilla::dom::oldproxybindings::HTMLPropertiesCollection::create(cx, scope, this,
-                                                                 triedToWrap);
+  JSObject* obj = HTMLPropertiesCollectionBinding::Wrap(cx, scope, this,
+                                                        triedToWrap);
+  if (obj || *triedToWrap) {
+    return obj;
+  }
+
+  *triedToWrap = true;
+  return oldproxybindings::HTMLPropertiesCollection::create(cx, scope, this);
 }
 
 NS_IMETHODIMP
 HTMLPropertiesCollection::GetLength(uint32_t* aLength)
 {
   EnsureFresh();
   *aLength = mProperties.Length();
   return NS_OK;
@@ -441,18 +447,23 @@ PropertyNodeList::GetParentObject()
 {
   return mParent;
 }
 
 JSObject*
 PropertyNodeList::WrapObject(JSContext *cx, JSObject *scope,
                              bool *triedToWrap)
 {
-  return mozilla::dom::oldproxybindings::PropertyNodeList::create(cx, scope, this,
-                                                         triedToWrap);
+  JSObject* obj = PropertyNodeListBinding::Wrap(cx, scope, this, triedToWrap);
+  if (obj || *triedToWrap) {
+    return obj;
+  }
+
+  *triedToWrap = true;
+  return oldproxybindings::PropertyNodeList::create(cx, scope, this);
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(PropertyNodeList)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(PropertyNodeList)
   // SetDocument(nullptr) ensures that we remove ourselves as a mutation observer
   tmp->SetDocument(nullptr);
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParent)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCollection)
--- a/content/html/content/src/nsClientRect.cpp
+++ b/content/html/content/src/nsClientRect.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 "nsClientRect.h"
 #include "nsContentUtils.h"
 #include "nsDOMClassInfoID.h"
 
 #include "nsPresContext.h"
+#include "mozilla/dom/ClientRectListBinding.h"
 #include "dombindings.h"
 
 DOMCI_DATA(ClientRect, nsClientRect)
 
 NS_INTERFACE_TABLE_HEAD(nsClientRect)
   NS_INTERFACE_TABLE1(nsClientRect, nsIDOMClientRect)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ClientRect)
@@ -101,18 +102,24 @@ nsIDOMClientRect*
 nsClientRectList::GetItemAt(uint32_t aIndex)
 {
   return Item(aIndex);
 }
 
 JSObject*
 nsClientRectList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
 {
-  return mozilla::dom::oldproxybindings::ClientRectList::create(cx, scope, this,
-                                                       triedToWrap);
+  JSObject* obj = mozilla::dom::ClientRectListBinding::Wrap(cx, scope, this,
+                                                            triedToWrap);
+  if (obj || *triedToWrap) {
+    return obj;
+  }
+
+  *triedToWrap = true;
+  return mozilla::dom::oldproxybindings::ClientRectList::create(cx, scope, this);
 }
 
 static double
 RoundFloat(double aValue)
 {
   return floor(aValue + 0.5);
 }
 
--- a/content/html/content/src/nsHTMLFormElement.cpp
+++ b/content/html/content/src/nsHTMLFormElement.cpp
@@ -46,19 +46,19 @@
 #include "nsEventDispatcher.h"
 
 #include "mozAutoDocUpdate.h"
 #include "nsIHTMLCollection.h"
 
 #include "nsIConstraintValidation.h"
 
 #include "nsIDOMHTMLButtonElement.h"
+#include "mozilla/dom/HTMLCollectionBinding.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;
 
@@ -120,18 +120,23 @@ public:
    * @return NS_OK or NS_ERROR_OUT_OF_MEMORY.
    */
   nsresult GetSortedControls(nsTArray<nsGenericHTMLFormElement*>& aControls) const;
 
   // nsWrapperCache
   virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap)
   {
-    return mozilla::dom::oldproxybindings::HTMLCollection::create(cx, scope, this,
-                                                         triedToWrap);
+    JSObject* obj = HTMLCollectionBinding::Wrap(cx, scope, this, triedToWrap);
+    if (obj || *triedToWrap) {
+      return obj;
+    }
+
+    *triedToWrap = true;
+    return oldproxybindings::HTMLCollection::create(cx, scope, this);
   }
 
   nsHTMLFormElement* mForm;  // WEAK - the form owns me
 
   nsTArray<nsGenericHTMLFormElement*> mElements;  // Holds WEAK references - bug 36639
 
   // This array holds on to all form controls that are not contained
   // in mElements (form.elements in JS, see ShouldBeInFormControl()).
--- a/content/html/content/src/nsHTMLSelectElement.cpp
+++ b/content/html/content/src/nsHTMLSelectElement.cpp
@@ -30,18 +30,18 @@
 #include "nsIFrame.h"
 
 #include "nsError.h"
 #include "nsServiceManagerUtils.h"
 #include "nsRuleData.h"
 #include "nsEventDispatcher.h"
 #include "mozilla/dom/Element.h"
 #include "mozAutoDocUpdate.h"
+#include "mozilla/dom/HTMLOptionsCollectionBinding.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)
 
 //----------------------------------------------------------------------
@@ -2004,18 +2004,23 @@ NS_INTERFACE_MAP_END
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsHTMLOptionCollection)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsHTMLOptionCollection)
 
 
 JSObject*
 nsHTMLOptionCollection::WrapObject(JSContext *cx, JSObject *scope,
                                    bool *triedToWrap)
 {
-  return mozilla::dom::oldproxybindings::HTMLOptionsCollection::create(cx, scope, this,
-                                                              triedToWrap);
+  JSObject* obj = HTMLOptionsCollectionBinding::Wrap(cx, scope, this, triedToWrap);
+  if (obj || *triedToWrap) {
+    return obj;
+  }
+
+  *triedToWrap = true;
+  return oldproxybindings::HTMLOptionsCollection::create(cx, scope, this);
 }
 
 NS_IMETHODIMP
 nsHTMLOptionCollection::GetLength(uint32_t* aLength)
 {
   *aLength = mElements.Length();
 
   return NS_OK;
--- a/content/html/content/src/nsHTMLTableElement.cpp
+++ b/content/html/content/src/nsHTMLTableElement.cpp
@@ -20,19 +20,18 @@
 #include "nsHTMLParts.h"
 #include "nsRuleData.h"
 #include "nsStyleContext.h"
 #include "nsIDocument.h"
 #include "nsContentUtils.h"
 #include "nsIDOMElement.h"
 #include "nsIHTMLCollection.h"
 #include "nsHTMLStyleSheet.h"
+#include "mozilla/dom/HTMLCollectionBinding.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
  */
@@ -57,18 +56,25 @@ public:
   NS_IMETHOD    ParentDestroyed();
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TableRowsCollection)
 
   // nsWrapperCache
   virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap)
   {
-    return mozilla::dom::oldproxybindings::HTMLCollection::create(cx, scope, this,
-                                                         triedToWrap);
+    JSObject* obj = mozilla::dom::HTMLCollectionBinding::Wrap(cx, scope, this,
+                                                              triedToWrap);
+    if (obj || *triedToWrap) {
+      return obj;
+    }
+
+    *triedToWrap = true;
+    return mozilla::dom::oldproxybindings::HTMLCollection::create(cx, scope,
+                                                                  this);
   }
 
 protected:
   // Those rows that are not in table sections
   nsHTMLTableElement* mParent;
   nsRefPtr<nsContentList> mOrphanRows;  
 };
 
--- a/content/svg/content/src/DOMSVGLengthList.cpp
+++ b/content/svg/content/src/DOMSVGLengthList.cpp
@@ -5,16 +5,17 @@
 
 #include "nsSVGElement.h"
 #include "DOMSVGLengthList.h"
 #include "DOMSVGLength.h"
 #include "nsError.h"
 #include "SVGAnimatedLengthList.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
+#include "mozilla/dom/SVGLengthListBinding.h"
 #include "dombindings.h"
 
 // See the comment in this file's header.
 
 // local helper functions
 namespace {
 
 using mozilla::DOMSVGLength;
@@ -71,18 +72,24 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGLengthList)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGLengthList)
 NS_INTERFACE_MAP_END
 
 JSObject*
 DOMSVGLengthList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
 {
-  return mozilla::dom::oldproxybindings::SVGLengthList::create(cx, scope, this,
-                                                      triedToWrap);
+  JSObject* obj = mozilla::dom::SVGLengthListBinding::Wrap(cx, scope, this,
+                                                           triedToWrap);
+  if (obj || *triedToWrap) {
+    return obj;
+  }
+
+  *triedToWrap = true;
+  return mozilla::dom::oldproxybindings::SVGLengthList::create(cx, scope, this);
 }
 
 nsIDOMSVGLength*
 DOMSVGLengthList::GetItemAt(uint32_t aIndex)
 {
   ErrorResult rv;
   return GetItem(aIndex, rv);
 }
--- a/content/svg/content/src/DOMSVGNumberList.cpp
+++ b/content/svg/content/src/DOMSVGNumberList.cpp
@@ -5,16 +5,17 @@
 
 #include "nsSVGElement.h"
 #include "DOMSVGNumberList.h"
 #include "DOMSVGNumber.h"
 #include "nsError.h"
 #include "SVGAnimatedNumberList.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
+#include "mozilla/dom/SVGNumberListBinding.h"
 #include "dombindings.h"
 
 // See the comment in this file's header.
 
 namespace mozilla {
 
 // local helper functions
 namespace {
@@ -72,18 +73,24 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGNumberList)
 NS_INTERFACE_MAP_END
 
 
 JSObject*
 DOMSVGNumberList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
 {
-  return mozilla::dom::oldproxybindings::SVGNumberList::create(cx, scope, this,
-                                                      triedToWrap);
+  JSObject* obj = mozilla::dom::SVGNumberListBinding::Wrap(cx, scope, this,
+                                                           triedToWrap);
+  if (obj || *triedToWrap) {
+    return obj;
+  }
+
+  *triedToWrap = true;
+  return mozilla::dom::oldproxybindings::SVGNumberList::create(cx, scope, this);
 }
 
 nsIDOMSVGNumber*
 DOMSVGNumberList::GetItemAt(uint32_t aIndex)
 {
   ErrorResult rv;
   return GetItem(aIndex, rv);
 }
--- a/content/svg/content/src/DOMSVGPathSegList.cpp
+++ b/content/svg/content/src/DOMSVGPathSegList.cpp
@@ -6,16 +6,17 @@
 #include "nsSVGElement.h"
 #include "DOMSVGPathSegList.h"
 #include "DOMSVGPathSeg.h"
 #include "nsError.h"
 #include "SVGAnimatedPathSegList.h"
 #include "nsCOMPtr.h"
 #include "nsSVGAttrTearoffTable.h"
 #include "SVGPathSegUtils.h"
+#include "mozilla/dom/SVGPathSegListBinding.h"
 #include "dombindings.h"
 #include "nsContentUtils.h"
 
 // See the comment in this file's header.
 
 namespace mozilla {
 
 static nsSVGAttrTearoffTable<void, DOMSVGPathSegList>
@@ -78,18 +79,25 @@ DOMSVGPathSegList::~DOMSVGPathSegList()
     InternalAList().GetAnimValKey() :
     InternalAList().GetBaseValKey();
   sSVGPathSegListTearoffTable.RemoveTearoff(key);
 }
 
 JSObject*
 DOMSVGPathSegList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
 {
-  return mozilla::dom::oldproxybindings::SVGPathSegList::create(cx, scope, this,
-                                                       triedToWrap);
+  JSObject* obj = mozilla::dom::SVGPathSegListBinding::Wrap(cx, scope, this,
+                                                            triedToWrap);
+  if (obj || *triedToWrap) {
+    return obj;
+  }
+
+  *triedToWrap = true;
+  return mozilla::dom::oldproxybindings::SVGPathSegList::create(cx, scope,
+                                                                this);
 }
 
 nsIDOMSVGPathSeg*
 DOMSVGPathSegList::GetItemAt(uint32_t aIndex)
 {
   ErrorResult rv;
   return GetItem(aIndex, rv);
 }
--- a/content/svg/content/src/DOMSVGPointList.cpp
+++ b/content/svg/content/src/DOMSVGPointList.cpp
@@ -6,16 +6,17 @@
 #include "nsSVGElement.h"
 #include "DOMSVGPointList.h"
 #include "DOMSVGPoint.h"
 #include "nsError.h"
 #include "SVGAnimatedPointList.h"
 #include "nsCOMPtr.h"
 #include "nsSVGAttrTearoffTable.h"
 #include "nsContentUtils.h"
+#include "mozilla/dom/SVGPointListBinding.h"
 #include "dombindings.h"
 
 // See the comment in this file's header.
 
 // local helper functions
 namespace {
 
 using mozilla::DOMSVGPoint;
@@ -97,18 +98,24 @@ DOMSVGPointList::~DOMSVGPointList()
     InternalAList().GetAnimValKey() :
     InternalAList().GetBaseValKey();
   sSVGPointListTearoffTable.RemoveTearoff(key);
 }
 
 JSObject*
 DOMSVGPointList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
 {
-  return mozilla::dom::oldproxybindings::SVGPointList::create(cx, scope, this,
-                                                     triedToWrap);
+  JSObject* obj = mozilla::dom::SVGPointListBinding::Wrap(cx, scope, this,
+                                                          triedToWrap);
+  if (obj || *triedToWrap) {
+    return obj;
+  }
+
+  *triedToWrap = true;
+  return mozilla::dom::oldproxybindings::SVGPointList::create(cx, scope, this);
 }
 
 nsIDOMSVGPoint*
 DOMSVGPointList::GetItemAt(uint32_t aIndex)
 {
   if (IsAnimValList()) {
     Element()->FlushAnimations();
   }
--- a/content/svg/content/src/DOMSVGTransformList.cpp
+++ b/content/svg/content/src/DOMSVGTransformList.cpp
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "DOMSVGTransformList.h"
 #include "DOMSVGTransform.h"
 #include "DOMSVGMatrix.h"
 #include "SVGAnimatedTransformList.h"
 #include "nsSVGElement.h"
 #include "nsContentUtils.h"
+#include "mozilla/dom/SVGTransformListBinding.h"
 #include "dombindings.h"
 #include "nsError.h"
 
 // local helper functions
 namespace {
 
 void UpdateListIndicesFromIndex(
   nsTArray<mozilla::DOMSVGTransform*>& aItemsArray,
@@ -72,18 +73,25 @@ NS_INTERFACE_MAP_END
 
 //----------------------------------------------------------------------
 // DOMSVGTransformList methods:
 
 JSObject*
 DOMSVGTransformList::WrapObject(JSContext *cx, JSObject *scope,
                                 bool *triedToWrap)
 {
-  return mozilla::dom::oldproxybindings::SVGTransformList::create(cx, scope, this,
-                                                         triedToWrap);
+  JSObject* obj = mozilla::dom::SVGTransformListBinding::Wrap(cx, scope, this,
+                                                              triedToWrap);
+  if (obj || *triedToWrap) {
+    return obj;
+  }
+
+  *triedToWrap = true;
+  return mozilla::dom::oldproxybindings::SVGTransformList::create(cx, scope,
+                                                                  this);
 }
 
 nsIDOMSVGTransform*
 DOMSVGTransformList::GetItemAt(uint32_t aIndex)
 {
   ErrorResult rv;
   return GetItem(aIndex, rv);
 }
--- a/content/svg/content/test/test_SVGxxxListIndexing.xhtml
+++ b/content/svg/content/test/test_SVGxxxListIndexing.xhtml
@@ -20,22 +20,22 @@ https://bugzilla.mozilla.org/show_bug.cg
 var text = document.getElementById("text"),
     path = document.getElementById("path"),
     poly = document.getElementById("poly");
     g    = document.getElementById("g");
 
 function CheckList(aListObject, aExpectedListLength, aListDescription)
 {
   is(aListObject.numberOfItems, aExpectedListLength, aListDescription + ".numberOfItems");
-  is(aListObject.numberOfItems, aExpectedListLength, aListDescription + ".length");
+  is(aListObject.length, aExpectedListLength, aListDescription + ".length");
   for (let i = 0; i < aListObject.length; i++) {
     let item = aListObject.getItem(i);
     ok(aListObject[i] === item, aListDescription + "[" + i + "]");
   }
-  ok(aListObject[aListObject.length] === void 0, aListDescription + "[outOfBounds]");
+  is(typeof(aListObject[aListObject.length]), "undefined", aListDescription + "[outOfBounds]");
 }
 
 var tests = [
   { element: text,
     attribute: "x",
     listProperty: "x.baseVal",
     type: "SVGLengthList",
     subtests: [ { values: null, length: 3 },
--- a/content/xbl/src/nsBindingManager.cpp
+++ b/content/xbl/src/nsBindingManager.cpp
@@ -38,16 +38,17 @@
 #include "nsIDOMScriptObjectFactory.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsTHashtable.h"
 
 #include "nsIScriptContext.h"
 #include "nsBindingManager.h"
 
 #include "nsThreadUtils.h"
+#include "mozilla/dom/NodeListBinding.h"
 #include "dombindings.h"
 
 // ==================================================================
 // = nsAnonymousContentList 
 // ==================================================================
 
 #define NS_ANONYMOUS_CONTENT_LIST_IID \
   { 0xbfb5d8e7, 0xf718, 0x4a46, \
@@ -74,18 +75,24 @@ public:
   int32_t GetInsertionPointCount() { return mElements->Length(); }
 
   nsXBLInsertionPoint* GetInsertionPointAt(int32_t i) { return static_cast<nsXBLInsertionPoint*>(mElements->ElementAt(i)); }
   void RemoveInsertionPointAt(int32_t i) { mElements->RemoveElementAt(i); }
 
   virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap)
   {
-    return mozilla::dom::oldproxybindings::NodeList::create(cx, scope, this,
-                                                   triedToWrap);
+    JSObject* obj = mozilla::dom::NodeListBinding::Wrap(cx, scope, this,
+                                                        triedToWrap);
+    if (obj || *triedToWrap) {
+      return obj;
+    }
+
+    *triedToWrap = true;
+    return mozilla::dom::oldproxybindings::NodeList::create(cx, scope, this);
   }
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ANONYMOUS_CONTENT_LIST_IID)
 private:
   nsCOMPtr<nsIContent> mContent;
   nsInsertionPointList* mElements;
 };
 
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -549,16 +549,17 @@ using mozilla::dom::indexedDB::IDBWrappe
 #include "GeneratedEvents.h"
 #include "mozilla/Likely.h"
 #include "nsDebug.h"
 
 #undef None // something included above defines this preprocessor symbol, maybe Xlib headers
 #include "WebGLContext.h"
 #include "nsICanvasRenderingContextInternal.h"
 #include "mozilla/dom/BindingUtils.h"
+#include "mozilla/dom/HTMLCollectionBinding.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 static NS_DEFINE_CID(kDOMSOF_CID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
 
 static const char kDOMStringBundleURL[] =
   "chrome://global/locale/dom/dom.properties";
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -4857,17 +4857,16 @@ class CGDOMJSProxyHandler_defineProperty
                     "                              eStringify, eStringify, name)) {\n" +
                     "    return false;\n" +
                     "  }\n" +
                     "  %s* self = UnwrapProxy(proxy);\n" +
                     CGIndenter(CGProxyNamedGetter(self.descriptor)).define() +
                     "  if (found) {\n"
                     "    return ThrowErrorMessage(cx, MSG_NO_PROPERTY_SETTER, \"%s\");\n" +
                     "  }\n" +
-                    "  return true;\n"
                     "}\n") % (self.descriptor.nativeType, self.descriptor.name)
         return set + """return mozilla::dom::DOMProxyHandler::defineProperty(%s);""" % ", ".join(a.name for a in self.args)
 
 class CGDOMJSProxyHandler_getOwnPropertyNames(ClassMethod):
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy'),
                 Argument('JS::AutoIdVector&', 'props')]
         ClassMethod.__init__(self, "getOwnPropertyNames", "bool", args)
--- a/dom/imptests/failures/webapps/DOMCore/tests/approved/test_interfaces.html.json
+++ b/dom/imptests/failures/webapps/DOMCore/tests/approved/test_interfaces.html.json
@@ -432,34 +432,14 @@
   "NodeFilter interface: constant SHOW_ENTITY on interface prototype object": true,
   "NodeFilter interface: constant SHOW_PROCESSING_INSTRUCTION on interface prototype object": true,
   "NodeFilter interface: constant SHOW_COMMENT on interface prototype object": true,
   "NodeFilter interface: constant SHOW_DOCUMENT on interface prototype object": true,
   "NodeFilter interface: constant SHOW_DOCUMENT_TYPE on interface prototype object": true,
   "NodeFilter interface: constant SHOW_DOCUMENT_FRAGMENT on interface prototype object": true,
   "NodeFilter interface: constant SHOW_NOTATION on interface prototype object": true,
   "NodeFilter interface: operation acceptNode(Node)": true,
-  "NodeList interface: existence and properties of interface object": true,
-  "NodeList interface: existence and properties of interface prototype object": true,
-  "NodeList interface: attribute length": true,
-  "NodeList interface: calling item(unsigned long) on document.querySelectorAll(\"script\") with too few arguments must throw TypeError": true,
-  "HTMLCollection interface: existence and properties of interface object": true,
-  "HTMLCollection interface: existence and properties of interface prototype object": true,
-  "HTMLCollection interface: attribute length": true,
-  "HTMLCollection interface: calling item(unsigned long) on document.body.children with too few arguments must throw TypeError": true,
-  "HTMLCollection interface: calling namedItem(DOMString) on document.body.children with too few arguments must throw TypeError": true,
   "DOMStringList interface: existence and properties of interface object": true,
   "DOMStringList interface: existence and properties of interface prototype object": true,
   "DOMStringList interface: existence and properties of interface prototype object's \"constructor\" property": true,
   "DOMStringList interface: attribute length": true,
-  "DOMTokenList interface: existence and properties of interface object": true,
-  "DOMTokenList interface: existence and properties of interface prototype object": true,
-  "DOMTokenList interface: attribute length": true,
-  "Stringification of document.body.classList": true,
-  "DOMTokenList interface: calling item(unsigned long) on document.body.classList with too few arguments must throw TypeError": true,
-  "DOMTokenList interface: calling contains(DOMString) on document.body.classList with too few arguments must throw TypeError": true,
-  "DOMTokenList interface: calling add(DOMString) on document.body.classList with too few arguments must throw TypeError": true,
-  "DOMTokenList interface: calling remove(DOMString) on document.body.classList with too few arguments must throw TypeError": true,
-  "DOMTokenList interface: calling toggle(DOMString) on document.body.classList with too few arguments must throw TypeError": true,
-  "DOMSettableTokenList interface: existence and properties of interface object": true,
-  "DOMSettableTokenList interface: existence and properties of interface prototype object": true,
-  "DOMSettableTokenList interface: attribute value": true
+  "Stringification of document.body.classList": true
 }
--- a/dom/tests/mochitest/chrome/test_moving_nodeList.xul
+++ b/dom/tests/mochitest/chrome/test_moving_nodeList.xul
@@ -23,19 +23,20 @@ https://bugzilla.mozilla.org/show_bug.cg
       var firstWindow, secondWindow;
       function iframe_loaded() {
         if (!firstWindow || !secondWindow)
           return;
         var nodeList = firstWindow.document.childNodes;
         ok(!("expando" in nodeList), "shouldn't be able to see expandos on the NodeList");
         nodeList = firstWindow.wrappedJSObject.getNodeList();
         ok(("expando" in nodeList), "should be able to see expandos on the NodeList");
-        is(nodeList.selectedIndex, -1, "can access selectedIndex in chrome");
+        options = firstWindow.wrappedJSObject.getOptions();
+        is(options.selectedIndex, -1, "can access selectedIndex in chrome");
         secondWindow.wrappedJSObject.tryToUseNodeList(nodeList, ok);
-        nodeList = document.createElementNS("http://www.w3.org/1999/xhtml", "select").options;
+        nodeList = document.childNodes;
         secondWindow.wrappedJSObject.tryToUseNodeList(nodeList, ok);
         SimpleTest.finish();
       }
 
   ]]></script>
 
   <iframe id="one" src="http://mochi.test:8888/tests/dom/tests/mochitest/general/file_moving_nodeList.html"
           onload="firstWindow = this.contentWindow; iframe_loaded()" />
--- a/dom/tests/mochitest/general/file_moving_nodeList.html
+++ b/dom/tests/mochitest/general/file_moving_nodeList.html
@@ -1,17 +1,18 @@
 <html>
     <head>
         <script>
             document.childNodes.expando = "foo";
 
             function getNodeList() {
-                var nodeList = document.createElement("select").options;
-                nodeList.expando = "foo";
-                return nodeList;
+                return document.childNodes;
+            }
+            function getOptions() {
+                return document.createElement("select").options;
             }
 
             function tryToUseNodeList(nodeList, ok) {
                 function expectException(op, reason) {
                     try {
                         var result = op();
                         ok(false, "should have thrown an exception, got: " + result);
                     } catch (e) {
--- a/js/xpconnect/src/dombindings.conf
+++ b/js/xpconnect/src/dombindings.conf
@@ -5,17 +5,18 @@
 
 list_classes = [
     {
         'name': 'NodeList',
         'nativeClass': 'nsINodeList'
     },
     {
         'name': 'PropertyNodeList',
-        'nativeClass': 'mozilla::dom::PropertyNodeList'
+        'nativeClass': 'mozilla::dom::PropertyNodeList',
+        'newBindingHeader': 'mozilla/dom/HTMLPropertiesCollectionBinding.h'
     },
     {
         'name': 'HTMLCollection',
         'nativeClass': 'nsIHTMLCollection'
     },
     {
         'name': 'HTMLOptionsCollection',
         'nativeClass': 'nsHTMLOptionCollection'
--- a/js/xpconnect/src/dombindings.cpp
+++ b/js/xpconnect/src/dombindings.cpp
@@ -318,20 +318,18 @@ js::Class sInterfacePrototypeClass = {
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
     JS_ConvertStub
 };
 
 template<class LC>
 JSObject *
-ListBase<LC>::getPrototype(JSContext *cx, JSObject *receiver, bool *enabled)
+ListBase<LC>::getPrototype(JSContext *cx, JSObject *receiver)
 {
-    *enabled = true;
-
     XPCWrappedNativeScope *scope =
         XPCWrappedNativeScope::FindInJSObjectScope(cx, receiver);
     if (!scope)
         return NULL;
 
     return getPrototype(cx, scope, receiver);
 }
 
@@ -400,30 +398,26 @@ ListBase<LC>::getPrototype(JSContext *cx
         return NULL;
 
     return interfacePrototype;
 }
 
 template<class LC>
 JSObject *
 ListBase<LC>::create(JSContext *cx, JSObject *scope, ListType *aList,
-                     nsWrapperCache* aWrapperCache, bool *triedToWrap)
+                     nsWrapperCache* aWrapperCache)
 {
-    *triedToWrap = true;
-
     JSObject *parent = WrapNativeParent(cx, scope, aList->GetParentObject());
     if (!parent)
         return NULL;
 
     JSObject *global = js::GetGlobalForObjectCrossCompartment(parent);
     JSAutoCompartment ac(cx, global);
 
-    JSObject *proto = getPrototype(cx, global, triedToWrap);
-    if (!proto && !*triedToWrap)
-        aWrapperCache->ClearIsDOMBinding();
+    JSObject *proto = getPrototype(cx, global);
     if (!proto)
         return NULL;
     JSObject *obj = NewProxyObject(cx, &ListBase<LC>::instance,
                                    PrivateValue(aList), proto, parent);
     if (!obj)
         return NULL;
 
     NS_ADDREF(aList);
--- a/js/xpconnect/src/dombindings.h
+++ b/js/xpconnect/src/dombindings.h
@@ -146,24 +146,20 @@ private:
                                     NameSetterType item);
 
     static bool getPropertyOnPrototype(JSContext *cx, JSObject *proxy, jsid id, bool *found,
                                        JS::Value *vp);
     static bool hasPropertyOnPrototype(JSContext *cx, JSObject *proxy, jsid id);
 
 public:
     static JSObject *create(JSContext *cx, JSObject *scope, ListType *list,
-                            nsWrapperCache* cache, bool *triedToWrap);
+                            nsWrapperCache* cache);
 
-    static JSObject *getPrototype(JSContext *cx, JSObject *receiver, bool *enabled);
-    static bool DefineDOMInterface(JSContext *cx, JSObject *receiver, bool *enabled)
-    {
-        return !!getPrototype(cx, receiver, enabled);
-    }
-
+    static JSObject *getPrototype(JSContext *cx, JSObject *receiver);
+    static bool DefineDOMInterface(JSContext *cx, JSObject *receiver, bool *enabled);
     bool getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set,
                                JSPropertyDescriptor *desc);
     bool getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set,
                                   JSPropertyDescriptor *desc);
     bool defineProperty(JSContext *cx, JSObject *proxy, jsid id,
                         JSPropertyDescriptor *desc);
     bool getOwnPropertyNames(JSContext *cx, JSObject *proxy, JS::AutoIdVector &props);
     bool delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp);
--- a/js/xpconnect/src/dombindingsgen.py
+++ b/js/xpconnect/src/dombindingsgen.py
@@ -201,21 +201,23 @@ class Configuration:
         execfile(filename, config)
 
         # required settings
         if 'list_classes' not in config:
             raise UserError(filename + ": `%s` was not defined." % name)
         if 'list_classes' not in config:
             raise UserError(filename + ": `%s` was not defined." % name)
         self.list_classes = {}
+        self.newBindingHeaders = []
         for clazz in config['list_classes']:
             self.list_classes[clazz['name']] = \
                 DOMClass(name = clazz['name'],
                          nativeClass = clazz['nativeClass'],
                          prefable = False)
+            self.newBindingHeaders.append(clazz.get('newBindingHeader', "mozilla/dom/" + clazz['name'] + "Binding.h"))
 
         # optional settings
         if 'prefableClasses' in config:
             for clazz in config['prefableClasses']:
                 self.list_classes[clazz] = DOMClass(name=clazz, nativeClass=config['prefableClasses'][clazz], prefable=True)
 
         self.customInheritance = config.get('customInheritance', {})
         self.derivedClasses = {}
@@ -324,26 +326,26 @@ def getTypes(classes, map):
         if clazz.nameSetter:
             addType(types, clazz.realNameSetter.realtype, map)
     return types
 
 listDefinitionTemplate = (
 "class ${name} {\n"
 "public:\n"
 "    template<typename I>\n"
-"    static JSObject *create(JSContext *cx, JSObject *scope, I *list, bool *triedToWrap)\n"
+"    static JSObject *create(JSContext *cx, JSObject *scope, I *list)\n"
 "    {\n"
-"        return create(cx, scope, list, list, triedToWrap);\n"
+"        return create(cx, scope, list, list);\n"
 "    }\n"
 "\n"
 "    static bool objIsWrapper(JSObject *obj);\n"
 "    static ${nativeClass} *getNative(JSObject *obj);\n"
 "\n"
 "private:\n"
-"    static JSObject *create(JSContext *cx, JSObject *scope, ${nativeClass} *list, nsWrapperCache *cache, bool *triedToWrap);\n"
+"    static JSObject *create(JSContext *cx, JSObject *scope, ${nativeClass} *list, nsWrapperCache *cache);\n"
 "};"
 "\n"
 "\n")
 
 def writeHeaderFile(filename, config):
     print "Creating header file", filename
 
     headerMacro = '__gen_%s__' % filename.replace('.', '_')
@@ -429,16 +431,28 @@ listTemplate = (
 "    JS_ResolveStub,\n"
 "    JS_ConvertStub,\n"
 "    NULL,                   /* finalize    */\n"
 "    NULL,                   /* checkAccess */\n"
 "    NULL,                   /* call        */\n"
 "    interface_hasInstance,\n"
 "    NULL                    /* construct   */\n"
 "};\n"
+"\n"
+"// static\n"
+"template<>\n"
+"bool\n"
+"${name}Wrapper::DefineDOMInterface(JSContext *cx, JSObject *receiver, bool *enabled)\n"
+"{\n"
+"  bool ok = mozilla::dom::${name}Binding::DefineDOMInterface(cx, receiver, enabled);\n"
+"  if (ok || *enabled) {\n"
+"    return ok;\n"
+"  }\n"
+"  return getPrototype(cx, receiver);\n"
+"}\n"
 "\n")
 
 derivedClassTemplate = (
 "template<>\n"
 "bool\n"
 "${name}Wrapper::objIsList(JSObject *obj)\n"
 "{\n"
 "    if (!js::IsProxy(obj))\n"
@@ -549,19 +563,19 @@ methodsTemplate = (
 "template<>\n"
 "size_t ${name}Wrapper::sProtoMethodsCount = ArrayLength(${name}Wrapper::sProtoMethods);\n"
 "\n")
 
 listTemplateFooter = (
 "template class ListBase<${name}Class>;\n"
 "\n"
 "JSObject*\n"
-"${name}::create(JSContext *cx, JSObject *scope, ${nativeClass} *list, nsWrapperCache *cache, bool *triedToWrap)\n"
+"${name}::create(JSContext *cx, JSObject *scope, ${nativeClass} *list, nsWrapperCache *cache)\n"
 "{\n"
-"    return ${name}Wrapper::create(cx, scope, list, cache, triedToWrap);\n"
+"    return ${name}Wrapper::create(cx, scope, list, cache);\n"
 "}\n"
 "\n"
 "bool\n"
 "${name}::objIsWrapper(JSObject *obj)\n"
 "{\n"
 "    return ${name}Wrapper::objIsList(obj);\n"
 "}\n"
 "\n"
@@ -629,16 +643,18 @@ def writeStubFile(filename, config, inte
         for clazz in config.list_classes.itervalues():
             for member in clazz.members:
                 addType(types, member.realtype, config.irregularFilenames)
                 if member.kind == 'method':
                     for p in member.params:
                         addType(types, p.realtype, config.irregularFilenames)
 
         f.write("".join([("#include \"%s.h\"\n" % re.sub(r'(([^:]+::)*)', '', type)) for type in sorted(types)]))
+        for newBindingHeader in config.newBindingHeaders:
+            f.write("#include \"" + newBindingHeader + "\"\n")
         f.write("\n")
 
         f.write("namespace mozilla {\n"
                 "namespace dom {\n"
                 "namespace oldproxybindings {\n\n")
 
         f.write("// Property name ids\n\n")