Fix for bug 717013 (Add new DOM binding for DOMTokenList). r=jst.
authorPeter Van der Beken <peterv@propagandism.org>
Mon, 22 Aug 2011 11:14:13 +0200
changeset 88148 b5beb0298fa5339bf35ff4ba0d94300cd50e98a3
parent 88147 512d60d499969e06f6c35b2923e7fdb71618d67d
child 88149 8199952005d60d2aba34d9d1bfa26eed53096dd7
push id22173
push userbmo@edmorley.co.uk
push dateSat, 03 Mar 2012 13:14:42 +0000
treeherdermozilla-central@ed57abebd328 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjst
bugs717013
milestone13.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 717013 (Add new DOM binding for DOMTokenList). r=jst.
content/base/src/nsDOMSettableTokenList.cpp
content/base/src/nsDOMSettableTokenList.h
content/base/src/nsDOMTokenList.cpp
content/base/src/nsDOMTokenList.h
content/base/src/nsGenericElement.cpp
content/base/src/nsGenericElement.h
content/html/content/src/nsHTMLOutputElement.cpp
dom/interfaces/core/nsIDOMDOMTokenList.idl
js/xpconnect/src/dom_quickstubs.qsconf
js/xpconnect/src/dombindings.conf
js/xpconnect/src/dombindings.h
--- a/content/base/src/nsDOMSettableTokenList.cpp
+++ b/content/base/src/nsDOMSettableTokenList.cpp
@@ -34,16 +34,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Implementation of nsIDOMDOMSettableTokenList specified by HTML5.
  */
 
 #include "nsDOMSettableTokenList.h"
+#include "dombindings.h"
 
 
 nsDOMSettableTokenList::nsDOMSettableTokenList(nsGenericElement *aElement, nsIAtom* aAttrAtom)
   : nsDOMTokenList(aElement, aAttrAtom)
 {
 }
 
 nsDOMSettableTokenList::~nsDOMSettableTokenList()
@@ -73,8 +74,15 @@ nsDOMSettableTokenList::SetValue(const n
 {
   if (!mElement) {
     return NS_OK;
   }
 
   return mElement->SetAttr(kNameSpaceID_None, mAttrAtom, aValue, true);
 }
 
+JSObject*
+nsDOMSettableTokenList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+                                   bool *triedToWrap)
+{
+  return mozilla::dom::binding::DOMSettableTokenList::create(cx, scope, this,
+                                                             triedToWrap);
+}
--- a/content/base/src/nsDOMSettableTokenList.h
+++ b/content/base/src/nsDOMSettableTokenList.h
@@ -54,14 +54,17 @@ class nsDOMSettableTokenList : public ns
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMDOMSETTABLETOKENLIST
 
   NS_FORWARD_NSIDOMDOMTOKENLIST(nsDOMTokenList::);
 
   nsDOMSettableTokenList(nsGenericElement* aElement, nsIAtom* aAttrAtom);
 
+  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+                               bool *triedToWrap);
+
 protected:
   virtual ~nsDOMSettableTokenList();
 };
 
 #endif // nsDOMSettableTokenList_h___
 
--- a/content/base/src/nsDOMTokenList.cpp
+++ b/content/base/src/nsDOMTokenList.cpp
@@ -39,39 +39,53 @@
  */
 
 #include "nsDOMTokenList.h"
 
 #include "nsAttrValue.h"
 #include "nsContentUtils.h"
 #include "nsDOMError.h"
 #include "nsGenericElement.h"
+#include "dombindings.h"
 
 
 nsDOMTokenList::nsDOMTokenList(nsGenericElement *aElement, nsIAtom* aAttrAtom)
   : mElement(aElement),
     mAttrAtom(aAttrAtom)
 {
   // We don't add a reference to our element. If it goes away,
   // we'll be told to drop our reference
+  SetIsProxy();
 }
 
 nsDOMTokenList::~nsDOMTokenList() { }
 
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMTokenList)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMTokenList)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMTokenList)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMTokenList)
+  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
 DOMCI_DATA(DOMTokenList, nsDOMTokenList)
 
 NS_INTERFACE_TABLE_HEAD(nsDOMTokenList)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_TABLE1(nsDOMTokenList,
                       nsIDOMDOMTokenList)
-  NS_INTERFACE_TABLE_TO_MAP_SEGUE
+  NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsDOMTokenList)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DOMTokenList)
 NS_INTERFACE_MAP_END
 
-NS_IMPL_ADDREF(nsDOMTokenList)
-NS_IMPL_RELEASE(nsDOMTokenList)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMTokenList)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMTokenList)
 
 void
 nsDOMTokenList::DropReference()
 {
   mElement = nsnull;
 }
 
 NS_IMETHODIMP
@@ -288,8 +302,17 @@ nsDOMTokenList::ToString(nsAString& aRes
     aResult.Truncate();
     return NS_OK;
   }
 
   mElement->GetAttr(kNameSpaceID_None, mAttrAtom, aResult);
 
   return NS_OK;
 }
+
+JSObject*
+nsDOMTokenList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+                           bool *triedToWrap)
+{
+  return mozilla::dom::binding::DOMTokenList::create(cx, scope, this,
+                                                     triedToWrap);
+}
+
--- a/content/base/src/nsDOMTokenList.h
+++ b/content/base/src/nsDOMTokenList.h
@@ -41,26 +41,36 @@
 #ifndef nsDOMTokenList_h___
 #define nsDOMTokenList_h___
 
 #include "nsGenericElement.h"
 #include "nsIDOMDOMTokenList.h"
 
 class nsAttrValue;
 
-class nsDOMTokenList : public nsIDOMDOMTokenList
+class nsDOMTokenList : public nsIDOMDOMTokenList,
+                       public nsWrapperCache
 {
 public:
-  NS_DECL_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMTokenList)
   NS_DECL_NSIDOMDOMTOKENLIST
 
   nsDOMTokenList(nsGenericElement* aElement, nsIAtom* aAttrAtom);
 
   void DropReference();
 
+  virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
+                               bool *triedToWrap);
+
+  nsINode *GetParentObject()
+  {
+    return mElement;
+  }
+
 protected:
   ~nsDOMTokenList();
 
   const nsAttrValue* GetParsedAttr() {
     if (!mElement) {
       return nsnull;
     }
     return mElement->GetAttrInfo(kNameSpaceID_None, mAttrAtom).mValue;
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -1975,17 +1975,17 @@ nsGenericElement::GetChildrenList()
     slots->mChildrenList = new nsContentList(this, kNameSpaceID_Wildcard, 
                                              nsGkAtoms::_asterix, nsGkAtoms::_asterix,
                                              false);
   }
 
   return slots->mChildrenList;
 }
 
-nsIDOMDOMTokenList*
+nsDOMTokenList*
 nsGenericElement::GetClassList(nsresult *aResult)
 {
   *aResult = NS_ERROR_OUT_OF_MEMORY;
 
   nsGenericElement::nsDOMSlots *slots = DOMSlots();
 
   if (!slots->mClassList) {
     nsCOMPtr<nsIAtom> classAttr = GetClassAttributeName();
@@ -2463,30 +2463,37 @@ nsGenericElement::nsDOMSlots::Traverse(n
 
   if (aIsXUL) {
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mControllers");
     cb.NoteXPCOMChild(mControllers);
   }
 
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mChildrenList");
   cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mChildrenList));
+
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mClassList");
+  cb.NoteXPCOMChild(mClassList.get());
 }
 
 void
 nsGenericElement::nsDOMSlots::Unlink(bool aIsXUL)
 {
   mStyle = nsnull;
   mSMILOverrideStyle = nsnull;
   if (mAttributeMap) {
     mAttributeMap->DropReference();
     mAttributeMap = nsnull;
   }
   if (aIsXUL)
     NS_IF_RELEASE(mControllers);
   mChildrenList = nsnull;
+  if (mClassList) {
+    mClassList->DropReference();
+    mClassList = nsnull;
+  }
 }
 
 nsGenericElement::nsGenericElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : Element(aNodeInfo)
 {
   NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::ELEMENT_NODE ||
                     (mNodeInfo->NodeType() ==
                        nsIDOMNode::DOCUMENT_FRAGMENT_NODE &&
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/src/nsGenericElement.h
@@ -592,17 +592,17 @@ public:
   PRInt32 GetClientWidth()
   {
     return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().width);
   }
   nsIContent* GetFirstElementChild();
   nsIContent* GetLastElementChild();
   nsIContent* GetPreviousElementSibling();
   nsIContent* GetNextElementSibling();
-  nsIDOMDOMTokenList* GetClassList(nsresult *aResult);
+  nsDOMTokenList* GetClassList(nsresult *aResult);
   bool MozMatchesSelector(const nsAString& aSelector, nsresult* aResult);
 
   /**
    * Get the attr info for the given namespace ID and attribute name.  The
    * namespace ID must not be kNameSpaceID_Unknown and the name must not be
    * null.  Note that this can only return info on attributes that actually
    * live on this element (and is only virtual to handle XUL prototypes).  That
    * is, this should only be called from methods that only care about attrs
--- a/content/html/content/src/nsHTMLOutputElement.cpp
+++ b/content/html/content/src/nsHTMLOutputElement.cpp
@@ -95,18 +95,18 @@ public:
   void DescendantsChanged();
 
   // nsIMutationObserver
   NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
 
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLOutputElement,
-                                                     nsGenericHTMLFormElement)
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLOutputElement,
+                                           nsGenericHTMLFormElement)
 
   virtual nsXPCClassInfo* GetClassInfo();
 protected:
   enum ValueModeFlag {
     eModeDefault,
     eModeValue
   };
 
@@ -131,23 +131,36 @@ nsHTMLOutputElement::nsHTMLOutputElement
 
 nsHTMLOutputElement::~nsHTMLOutputElement()
 {
   if (mTokenList) {
     mTokenList->DropReference();
   }
 }
 
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLOutputElement)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLOutputElement,
+                                                nsGenericHTMLFormElement)
+  if (tmp->mTokenList) {
+    tmp->mTokenList->DropReference();
+    NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTokenList)
+  }
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLOutputElement,
+                                                  nsGenericHTMLFormElement)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mTokenList,
+                                                       nsDOMTokenList)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(nsHTMLOutputElement, nsGenericElement)
 NS_IMPL_RELEASE_INHERITED(nsHTMLOutputElement, nsGenericElement)
 
 DOMCI_NODE_DATA(HTMLOutputElement, nsHTMLOutputElement)
 
-NS_INTERFACE_TABLE_HEAD(nsHTMLOutputElement)
+NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLOutputElement)
   NS_HTML_CONTENT_INTERFACE_TABLE3(nsHTMLOutputElement,
                                    nsIDOMHTMLOutputElement,
                                    nsIMutationObserver,
                                    nsIConstraintValidation)
   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLOutputElement,
                                                nsGenericHTMLFormElement)
 NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLOutputElement)
 
--- a/dom/interfaces/core/nsIDOMDOMTokenList.idl
+++ b/dom/interfaces/core/nsIDOMDOMTokenList.idl
@@ -44,16 +44,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;
 
-  DOMString          item(in unsigned long index);
+  [getter] 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);
 
-  DOMString          toString();
+  [stringifier] DOMString          toString();
 };
--- a/js/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/xpconnect/src/dom_quickstubs.qsconf
@@ -513,16 +513,17 @@ irregularFilenames = {
 
 customIncludes = [
     'nsINode.h',
     'nsIContent.h',
     'nsIDocument.h',
     'nsINodeList.h',
     'nsCSSPropertiesQS.h',
     'nsDocument.h',
+    'nsDOMTokenList.h',
     'nsGenericDOMDataNode.h',
     'nsGenericElement.h',
     'nsGenericHTMLElement.h',
     'nsSVGStylableElement.h',
     'nsHTMLDocument.h',
     'nsDOMQS.h',
     ]
 
@@ -780,17 +781,17 @@ customMethodCalls = {
         },
     'nsIDOMElement_GetNextElementSibling': {
         'thisType': 'nsGenericElement',
         'code': '    nsIContent *result = self->GetNextElementSibling();',
         'canFail': False
         },
     'nsIDOMElement_GetClassList': {
         'thisType': 'nsGenericElement',
-        'code': '    nsIDOMDOMTokenList *result = self->GetClassList(&rv);'
+        'code': '    nsDOMTokenList *result = self->GetClassList(&rv);'
         },
     'nsIDOMElement_SetCapture': {
         'thisType': 'nsGenericElement',
         'canFail': False
         },
     'nsIDOMElement_ReleaseCapture': {
         'thisType': 'nsGenericElement',
         'canFail': False
--- a/js/xpconnect/src/dombindings.conf
+++ b/js/xpconnect/src/dombindings.conf
@@ -1,12 +1,14 @@
 classes = {
     'NodeList': 'nsINodeList',
     'HTMLCollection': 'nsIHTMLCollection',
     'HTMLOptionsCollection': 'nsHTMLOptionCollection',
+    'DOMTokenList': 'nsDOMTokenList',
+    'DOMSettableTokenList': 'nsDOMSettableTokenList',
     }
 
 irregularFilenames = {
     'nsHTMLOptionCollection': 'nsHTMLSelectElement',
     }
 
 customInheritance = {
     'nsIDOMHTMLOptionsCollection': 'nsIDOMHTMLCollection',
--- a/js/xpconnect/src/dombindings.h
+++ b/js/xpconnect/src/dombindings.h
@@ -38,16 +38,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef dombindings_h
 #define dombindings_h
 
 #include "jsapi.h"
 #include "jsproxy.h"
 #include "xpcpublic.h"
+#include "nsString.h"
 
 namespace mozilla {
 namespace dom {
 namespace binding {
 
 inline nsWrapperCache*
 GetWrapperCache(nsWrapperCache *cache)
 {