diff --git a/content/base/public/nsINode.h b/content/base/public/nsINode.h --- a/content/base/public/nsINode.h +++ b/content/base/public/nsINode.h @@ -114,23 +114,27 @@ enum { NODE_HAS_EDGE_CHILD_SELECTOR = 0x00008000U, // A child of the node has a selector such that any insertion or // removal of children requires restyling the parent (but append is // OK). NODE_HAS_SLOW_SELECTOR_NOAPPEND = 0x00010000U, + NODE_OWNS_OWNER_DOCUMENT = 0x00020000U, + + NODE_OWNS_PARENT = 0x00040000U, + NODE_ALL_SELECTOR_FLAGS = NODE_HAS_EMPTY_SELECTOR | NODE_HAS_SLOW_SELECTOR | NODE_HAS_EDGE_CHILD_SELECTOR | NODE_HAS_SLOW_SELECTOR_NOAPPEND, // Four bits for the script-type ID - NODE_SCRIPT_TYPE_OFFSET = 17, + NODE_SCRIPT_TYPE_OFFSET = 19, NODE_SCRIPT_TYPE_SIZE = 4, // Remaining bits are node type specific. NODE_TYPE_SPECIFIC_BITS_OFFSET = NODE_SCRIPT_TYPE_OFFSET + NODE_SCRIPT_TYPE_SIZE }; diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -1304,16 +1304,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN( if (tmp->mLinkMap.IsInitialized()) { tmp->mLinkMap.EnumerateEntries(LinkMapTraverser, &cb); } // Traverse all our nsCOMArrays. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mStyleSheets) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mCatalogSheets) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mVisitednessChangedURIs) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mNativeAnonymousContents) // Traverse any associated preserved wrapper. NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "[preserved wrapper]"); cb.NoteXPCOMChild(tmp->GetReference(tmp)); if (tmp->mSubDocuments && tmp->mSubDocuments->ops) { PL_DHashTableEnumerate(tmp->mSubDocuments, SubDocTraverser, &cb); } @@ -1331,18 +1332,24 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns // Unlink the mChildren nsAttrAndChildArray. for (PRInt32 indx = PRInt32(tmp->mChildren.ChildCount()) - 1; indx >= 0; --indx) { tmp->mChildren.ChildAt(indx)->UnbindFromTree(); tmp->mChildren.RemoveChildAt(indx); } NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCachedRootContent) - + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mNativeAnonymousContents) NS_IMPL_CYCLE_COLLECTION_UNLINK_USERDATA + + if (tmp->mBoxObjectTable) { + tmp->mBoxObjectTable->EnumerateRead(ClearAllBoxObjects, nsnull); + delete tmp->mBoxObjectTable; + tmp->mBoxObjectTable = nsnull; + } // Drop the content hash. delete tmp->mContentWrapperHash; tmp->mContentWrapperHash = nsnull; tmp->mParentDocument = nsnull; // nsDocument has a pretty complex destructor, so we're going to diff --git a/content/base/src/nsDocument.h b/content/base/src/nsDocument.h --- a/content/base/src/nsDocument.h +++ b/content/base/src/nsDocument.h @@ -814,16 +814,20 @@ public: nsIDOMNodeList** aReturn); void DoNotifyPossibleTitleChange(); void SetLoadedAsData(PRBool aLoadedAsData) { mLoadedAsData = aLoadedAsData; } nsresult CloneDocHelper(nsDocument* clone) const; + void AddNativeAnonymous(nsIContent* aContent) + { + mNativeAnonymousContents.AppendObject(aContent); + } protected: void RegisterNamedItems(nsIContent *aContent); void UnregisterNamedItems(nsIContent *aContent); void UpdateNameTableEntry(nsIContent *aContent); void UpdateIdTableEntry(nsIContent *aContent); void RemoveFromNameTable(nsIContent *aContent); void RemoveFromIdTable(nsIContent *aContent); @@ -1082,11 +1086,13 @@ private: // Member to store out last-selected stylesheet set. nsString mLastStyleSheetSet; nsTArray > mInitializableFrameLoaders; nsTArray > mFinalizableFrameLoaders; nsRevocableEventPtr > mPendingTitleChangeEvent; + + nsCOMArray mNativeAnonymousContents; }; #endif /* nsDocument_h___ */ diff --git a/content/base/src/nsGenericDOMDataNode.cpp b/content/base/src/nsGenericDOMDataNode.cpp --- a/content/base/src/nsGenericDOMDataNode.cpp +++ b/content/base/src/nsGenericDOMDataNode.cpp @@ -37,17 +37,17 @@ /* * Base class for DOM Core's nsIDOMComment, nsIDOMDocumentType, nsIDOMText, * nsIDOMCDATASection, and nsIDOMProcessingInstruction nodes. */ #include "nsGenericDOMDataNode.h" #include "nsGenericElement.h" -#include "nsIDocument.h" +#include "nsDocument.h" #include "nsIEventListenerManager.h" #include "nsIDOMDocument.h" #include "nsReadableUtils.h" #include "nsMutationEvent.h" #include "nsINameSpaceManager.h" #include "nsIDOM3Node.h" #include "nsIURI.h" #include "nsIPrivateDOMEvent.h" @@ -65,49 +65,70 @@ #include "mozAutoDocUpdate.h" #include "pldhash.h" #include "prprf.h" nsGenericDOMDataNode::nsGenericDOMDataNode(nsINodeInfo *aNodeInfo) : nsIContent(aNodeInfo) { + nsIDocument* ownerDoc = GetOwnerDoc(); + if (ownerDoc) { + NS_ADDREF(ownerDoc); + SetFlags(NODE_OWNS_OWNER_DOCUMENT); + } } nsGenericDOMDataNode::~nsGenericDOMDataNode() { NS_PRECONDITION(!IsInDoc(), "Please remove this from the document properly"); + if (HasFlag(NODE_OWNS_OWNER_DOCUMENT)) { + nsIDocument* ownerDoc = GetOwnerDoc(); + NS_RELEASE(ownerDoc); + UnsetFlags(NODE_OWNS_OWNER_DOCUMENT); + } } NS_IMPL_CYCLE_COLLECTION_CLASS(nsGenericDOMDataNode) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGenericDOMDataNode) nsIDocument* currentDoc = tmp->GetCurrentDoc(); if (currentDoc && nsCCUncollectableMarker::InGeneration( currentDoc->GetMarkedCCGeneration())) { return NS_OK; } NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNodeInfo) + if (tmp->HasFlag(NODE_OWNS_PARENT)) { + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(GetParent()) + } nsIDocument* ownerDoc = tmp->GetOwnerDoc(); if (ownerDoc) { ownerDoc->BindingManager()->Traverse(tmp, cb); + if (tmp->HasFlag(NODE_OWNS_OWNER_DOCUMENT)) { + cb.NoteXPCOMChild(ownerDoc); + } } NS_IMPL_CYCLE_COLLECTION_TRAVERSE_LISTENERMANAGER NS_IMPL_CYCLE_COLLECTION_TRAVERSE_USERDATA NS_IMPL_CYCLE_COLLECTION_TRAVERSE_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGenericDOMDataNode) NS_IMPL_CYCLE_COLLECTION_UNLINK_LISTENERMANAGER NS_IMPL_CYCLE_COLLECTION_UNLINK_USERDATA NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER + if (tmp->HasFlag(NODE_OWNS_OWNER_DOCUMENT)) { + nsIDocument* ownerDoc = tmp->GetOwnerDoc(); + tmp->UnsetFlags(NODE_OWNS_OWNER_DOCUMENT); + NS_RELEASE(ownerDoc); + } NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGenericDOMDataNode) NS_INTERFACE_MAP_ENTRY(nsIContent) NS_INTERFACE_MAP_ENTRY(nsINode) NS_INTERFACE_MAP_ENTRY(nsPIDOMEventTarget) NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMEventTarget, nsDOMEventRTTearoff::Create(this)) @@ -617,18 +638,32 @@ nsGenericDOMDataNode::BindToTree(nsIDocu if (IsRootOfNativeAnonymousSubtree() || aParent->IsInNativeAnonymousSubtree()) { SetFlags(NODE_IS_IN_ANONYMOUS_SUBTREE); } } // Set parent if (aParent) { + NS_ASSERTION(!GetParent() || GetParent() == aParent, "Whaat?"); + nsIContent* oldParent = GetParent(); mParentPtrBits = reinterpret_cast(aParent) | PARENT_BIT_PARENT_IS_CONTENT; + if (oldParent != aParent && !IsInNativeAnonymousSubtree() && + !IsInAnonymousSubtree()) { + SetFlags(NODE_OWNS_PARENT); + NS_ADDREF(aParent); + } + /*if (IsInNativeAnonymousSubtree() || IsInAnonymousSubtree()) { + nsIDocument* doc = GetOwnerDoc(); + if (doc) { + UnsetFlags(NODE_OWNS_OWNER_DOCUMENT); + NS_RELEASE(doc); + } + }*/ } else { mParentPtrBits = reinterpret_cast(aDocument); } // XXXbz sXBL/XBL2 issue! // Set document @@ -658,17 +693,22 @@ nsGenericDOMDataNode::UnbindFromTree(PRB nsIDocument *document = GetCurrentDoc(); if (document) { // Notify XBL- & nsIAnonymousContentCreator-generated // anonymous content that the document is changing. // This is needed to update the insertion point. document->BindingManager()->ChangeDocumentFor(this, document, nsnull); } + nsIContent* parent = GetParent(); mParentPtrBits = aNullParent ? 0 : mParentPtrBits & ~PARENT_BIT_INDOCUMENT; + if (!GetParent() && parent && HasFlag(NODE_OWNS_PARENT)) { + UnsetFlags(NODE_OWNS_PARENT); + NS_RELEASE(parent); + } nsDataSlots *slots = GetExistingDataSlots(); if (slots) { slots->mBindingParent = nsnull; } nsNodeUtils::ParentChainChanged(this); } diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp --- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -42,17 +42,17 @@ */ #include "nsGenericElement.h" #include "nsDOMAttribute.h" #include "nsDOMAttributeMap.h" #include "nsIAtom.h" #include "nsINodeInfo.h" -#include "nsIDocument.h" +#include "nsDocument.h" #include "nsIDOMNodeList.h" #include "nsIDOMDocument.h" #include "nsIDOMText.h" #include "nsIContentIterator.h" #include "nsIEventListenerManager.h" #include "nsIFocusController.h" #include "nsILinkHandler.h" #include "nsIScriptGlobalObject.h" @@ -1653,25 +1653,35 @@ nsGenericElement::nsDOMSlots::~nsDOMSlot if (mAttributeMap) { mAttributeMap->DropReference(); } } nsGenericElement::nsGenericElement(nsINodeInfo *aNodeInfo) : nsIContent(aNodeInfo) { + nsIDocument* ownerDoc = GetOwnerDoc(); + if (ownerDoc) { + NS_ADDREF(ownerDoc); + SetFlags(NODE_OWNS_OWNER_DOCUMENT); + } // Set the default scriptID to JS - but skip SetScriptTypeID as it // does extra work we know isn't necessary here... SetFlags(nsIProgrammingLanguage::JAVASCRIPT << NODE_SCRIPT_TYPE_OFFSET); } nsGenericElement::~nsGenericElement() { NS_PRECONDITION(!IsInDoc(), "Please remove this from the document properly"); + if (HasFlag(NODE_OWNS_OWNER_DOCUMENT)) { + nsIDocument* ownerDoc = GetOwnerDoc(); + NS_RELEASE(ownerDoc); + UnsetFlags(NODE_OWNS_OWNER_DOCUMENT); + } } NS_IMETHODIMP nsGenericElement::GetNodeName(nsAString& aNodeName) { mNodeInfo->GetQualifiedName(aNodeName); return NS_OK; } @@ -2544,17 +2554,31 @@ nsGenericElement::BindToTree(nsIDocument aParent && aParent->IsInNativeAnonymousSubtree()) { SetFlags(NODE_IS_IN_ANONYMOUS_SUBTREE); } PRBool hadForceXBL = HasFlag(NODE_FORCE_XBL_BINDINGS); // Now set the parent and set the "Force attach xbl" flag if needed. if (aParent) { + NS_ASSERTION(!GetParent() || GetParent() == aParent, "Whaat?"); + nsIContent* oldParent = GetParent(); mParentPtrBits = reinterpret_cast(aParent) | PARENT_BIT_PARENT_IS_CONTENT; + if (oldParent != aParent && !IsInNativeAnonymousSubtree() && + !IsInAnonymousSubtree()) { + SetFlags(NODE_OWNS_PARENT); + NS_ADDREF(aParent); + } + /*if (IsInNativeAnonymousSubtree() || IsInAnonymousSubtree()) { + nsIDocument* doc = GetOwnerDoc(); + if (doc) { + UnsetFlags(NODE_OWNS_OWNER_DOCUMENT); + NS_RELEASE(doc); + } + }*/ if (aParent->HasFlag(NODE_FORCE_XBL_BINDINGS)) { SetFlags(NODE_FORCE_XBL_BINDINGS); } } else { mParentPtrBits = reinterpret_cast(aDocument); } @@ -2662,18 +2686,23 @@ nsGenericElement::UnbindFromTree(PRBool if (HasAttr(kNameSpaceID_XLink, nsGkAtoms::href)) { document->ForgetLink(this); } document->ClearBoxObjectFor(this); } + nsIContent* parent = GetParent(); // Unset things in the reverse order from how we set them in BindToTree mParentPtrBits = aNullParent ? 0 : mParentPtrBits & ~PARENT_BIT_INDOCUMENT; + if (!GetParent() && parent && HasFlag(NODE_OWNS_PARENT)) { + UnsetFlags(NODE_OWNS_PARENT); + NS_RELEASE(parent); + } // Unset this since that's what the old code effectively did. UnsetFlags(NODE_FORCE_XBL_BINDINGS); #ifdef MOZ_XUL nsXULElement* xulElem = nsXULElement::FromContent(this); if (xulElem) { xulElem->SetXULBindingParent(nsnull); @@ -4006,28 +4035,36 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns slots->mAttributeMap->DropReference(); slots->mAttributeMap = nsnull; } if (tmp->IsNodeOfType(nsINode::eXUL)) NS_IF_RELEASE(slots->mControllers); slots->mChildrenList = nsnull; } } + if (tmp->HasFlag(NODE_OWNS_OWNER_DOCUMENT)) { + nsIDocument* ownerDoc = tmp->GetOwnerDoc(); + tmp->UnsetFlags(NODE_OWNS_OWNER_DOCUMENT); + NS_RELEASE(ownerDoc); + } NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGenericElement) nsIDocument* currentDoc = tmp->GetCurrentDoc(); if (currentDoc && nsCCUncollectableMarker::InGeneration( currentDoc->GetMarkedCCGeneration())) { return NS_OK; } nsIDocument* ownerDoc = tmp->GetOwnerDoc(); if (ownerDoc) { ownerDoc->BindingManager()->Traverse(tmp, cb); + if (tmp->HasFlag(NODE_OWNS_OWNER_DOCUMENT)) { + cb.NoteXPCOMChild(ownerDoc); + } } NS_IMPL_CYCLE_COLLECTION_TRAVERSE_LISTENERMANAGER NS_IMPL_CYCLE_COLLECTION_TRAVERSE_USERDATA NS_IMPL_CYCLE_COLLECTION_TRAVERSE_PRESERVED_WRAPPER if (tmp->HasProperties() && tmp->IsNodeOfType(nsINode::eXUL)) { nsISupports* property = @@ -4052,16 +4089,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN( PRUint32 kids = tmp->mAttrsAndChildren.ChildCount(); for (i = 0; i < kids; i++) { NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mAttrsAndChildren[i]"); cb.NoteXPCOMChild(tmp->mAttrsAndChildren.GetSafeChildAt(i)); } } NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNodeInfo) + if (tmp->HasFlag(NODE_OWNS_PARENT)) { + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(GetParent()) + } // Traverse any DOM slots of interest. { nsDOMSlots *slots = tmp->GetExistingDOMSlots(); if (slots) { cb.NoteXPCOMChild(slots->mAttributeMap.get()); if (tmp->IsNodeOfType(nsINode::eXUL)) cb.NoteXPCOMChild(slots->mControllers); diff --git a/content/base/src/nsNodeUtils.cpp b/content/base/src/nsNodeUtils.cpp --- a/content/base/src/nsNodeUtils.cpp +++ b/content/base/src/nsNodeUtils.cpp @@ -555,16 +555,20 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod if (oldDoc) { if (aNode->IsNodeOfType(nsINode::eELEMENT)) { oldDoc->ClearBoxObjectFor(static_cast(aNode)); } oldRef = oldDoc->GetReference(aNode); if (oldRef) { oldDoc->RemoveReference(aNode); } + if (aNode->HasFlag(NODE_OWNS_OWNER_DOCUMENT)) { + NS_RELEASE(oldDoc); + aNode->UnsetFlags(NODE_OWNS_OWNER_DOCUMENT); + } } aNode->mNodeInfo.swap(newNodeInfo); nsIDocument* newDoc = aNode->GetOwnerDoc(); if (newDoc) { if (oldRef) { newDoc->AddReference(aNode, oldRef); @@ -572,16 +576,21 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod nsPIDOMWindow* window = newDoc->GetInnerWindow(); if (window) { nsCOMPtr elm; aNode->GetListenerManager(PR_FALSE, getter_AddRefs(elm)); if (elm) { window->SetMutationListeners(elm->MutationListenerBits()); } + } + // Currently only content objects own their owner document. + if (aNode->IsNodeOfType(nsINode::eCONTENT)) { + NS_ADDREF(newDoc); + aNode->SetFlags(NODE_OWNS_OWNER_DOCUMENT); } } if (elem) { elem->RecompileScriptEventListeners(); } if (aCx) { diff --git a/content/base/src/nsRange.cpp b/content/base/src/nsRange.cpp --- a/content/base/src/nsRange.cpp +++ b/content/base/src/nsRange.cpp @@ -232,28 +232,40 @@ nsRange::~nsRange() DoSetRange(nsnull, 0, nsnull, 0, nsnull); // we want the side effects (releases and list removals) } /****************************************************** * nsISupports ******************************************************/ +NS_IMPL_CYCLE_COLLECTION_CLASS(nsRange) + +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsRange) +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsRange) + // QueryInterface implementation for nsRange -NS_INTERFACE_MAP_BEGIN(nsRange) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsRange) NS_INTERFACE_MAP_ENTRY(nsIDOMRange) NS_INTERFACE_MAP_ENTRY(nsIRange) NS_INTERFACE_MAP_ENTRY(nsIDOMNSRange) NS_INTERFACE_MAP_ENTRY(nsIMutationObserver) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRange) NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(Range) NS_INTERFACE_MAP_END -NS_IMPL_ADDREF(nsRange) -NS_IMPL_RELEASE(nsRange) +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsRange) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mStartParent) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mEndParent) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsRange) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mStartParent) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mEndParent) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END /****************************************************** * nsIMutationObserver implementation ******************************************************/ void nsRange::CharacterDataChanged(nsIDocument* aDocument, nsIContent* aContent, diff --git a/content/base/src/nsRange.h b/content/base/src/nsRange.h --- a/content/base/src/nsRange.h +++ b/content/base/src/nsRange.h @@ -80,17 +80,18 @@ class nsRange : public nsIRange, public nsStubMutationObserver { public: nsRange() { } virtual ~nsRange(); - NS_DECL_ISUPPORTS + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsRange, nsIRange) // nsIDOMRange interface NS_DECL_NSIDOMRANGE // nsIDOMNSRange interface NS_DECL_NSIDOMNSRANGE // nsIRange interface diff --git a/content/events/test/Makefile.in b/content/events/test/Makefile.in --- a/content/events/test/Makefile.in +++ b/content/events/test/Makefile.in @@ -40,35 +40,17 @@ srcdir = @srcdir@ srcdir = @srcdir@ VPATH = @srcdir@ relativesrcdir = content/events/test include $(DEPTH)/config/autoconf.mk include $(topsrcdir)/config/rules.mk _TEST_FILES = \ - test_bug238987.html \ - test_bug288392.html \ test_bug328885.html \ - test_bug336682_1.html \ - test_bug336682_2.xul \ - test_bug336682.js \ - test_bug350471.xul \ - test_bug367781.html \ - test_bug368835.html \ - test_bug379120.html \ - test_bug391568.xhtml \ - test_bug402089.html \ - test_bug405632.html \ - test_bug409604.html \ - test_bug412567.html \ - test_bug443985.html \ - test_bug447736.html \ - test_draggableprop.html \ - test_dragstart.html \ $(NULL) _CHROME_FILES = \ test_bug415498.xul \ bug415498-doc1.html \ bug415498-doc2.html \ $(NULL) diff --git a/content/html/document/src/nsHTMLDocument.cpp b/content/html/document/src/nsHTMLDocument.cpp --- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -242,16 +242,29 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mEmbeds) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLinks) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mAnchors) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFragmentParser) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mForms, nsIDOMNodeList) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mFormControls, nsIDOMNodeList) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLDocument, nsDocument) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mImageMaps) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mImages) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mApplets) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mEmbeds) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mLinks) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mAnchors) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mForms) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFormControls) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mMidasCommandManager) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFragmentParser) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_ADDREF_INHERITED(nsHTMLDocument, nsDocument) NS_IMPL_RELEASE_INHERITED(nsHTMLDocument, nsDocument) // QueryInterface implementation for nsHTMLDocument NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLDocument) NS_INTERFACE_TABLE_INHERITED3(nsHTMLDocument, diff --git a/content/html/document/src/nsHTMLDocument.h b/content/html/document/src/nsHTMLDocument.h --- a/content/html/document/src/nsHTMLDocument.h +++ b/content/html/document/src/nsHTMLDocument.h @@ -212,17 +212,17 @@ public: private: nsHTMLDocument* mDoc; EditingState mSavedState; }; friend class nsAutoEditingState; void EndUpdate(nsUpdateType aUpdateType); - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLDocument, nsDocument) + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLDocument, nsDocument) virtual already_AddRefed GetFragmentParser() { return mFragmentParser.forget(); } virtual void SetFragmentParser(nsIParser* aParser) { mFragmentParser = aParser; } diff --git a/content/html/document/src/nsImageDocument.cpp b/content/html/document/src/nsImageDocument.cpp --- a/content/html/document/src/nsImageDocument.cpp +++ b/content/html/document/src/nsImageDocument.cpp @@ -112,16 +112,18 @@ public: NS_DECL_NSIIMAGEDOCUMENT // imgIDecoderObserver (override nsStubImageDecoderObserver) NS_IMETHOD OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage); // nsIDOMEventListener NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent); + + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsImageDocument, nsMediaDocument) friend class ImageListener; protected: nsresult CreateSyntheticDocument(); nsresult CheckOverflowing(PRBool changeState); void UpdateTitleAndCharset(); @@ -267,18 +269,26 @@ nsImageDocument::nsImageDocument() // bother initializing members to 0. } nsImageDocument::~nsImageDocument() { } -// XXXbz shouldn't this participate in cycle collection? It's got -// mImageContent! +NS_IMPL_CYCLE_COLLECTION_CLASS(nsImageDocument) + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsImageDocument, nsMediaDocument) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mImageContent) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsImageDocument, nsMediaDocument) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mImageContent) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + NS_IMPL_ADDREF_INHERITED(nsImageDocument, nsMediaDocument) NS_IMPL_RELEASE_INHERITED(nsImageDocument, nsMediaDocument) NS_INTERFACE_TABLE_HEAD(nsImageDocument) NS_INTERFACE_TABLE_INHERITED4(nsImageDocument, nsIImageDocument, imgIDecoderObserver, imgIContainerObserver, diff --git a/content/html/document/src/nsPluginDocument.cpp b/content/html/document/src/nsPluginDocument.cpp --- a/content/html/document/src/nsPluginDocument.cpp +++ b/content/html/document/src/nsPluginDocument.cpp @@ -66,16 +66,17 @@ public: nsIContentSink* aSink = nsnull); virtual void SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject); virtual PRBool CanSavePresentation(nsIRequest *aNewRequest); const nsCString& GetType() const { return mMimeType; } nsIContent* GetPluginContent() { return mPluginContent; } + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsPluginDocument, nsMediaDocument) protected: nsresult CreateSyntheticPluginDocument(); nsCOMPtr mPluginContent; nsRefPtr mStreamListener; nsCString mMimeType; }; @@ -140,18 +141,26 @@ nsPluginDocument::nsPluginDocument() nsPluginDocument::nsPluginDocument() { } nsPluginDocument::~nsPluginDocument() { } -// XXXbz shouldn't this participate in cycle collection? It's got -// mPluginContent! +NS_IMPL_CYCLE_COLLECTION_CLASS(nsPluginDocument) + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsPluginDocument, nsMediaDocument) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mPluginContent) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsPluginDocument, nsMediaDocument) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mPluginContent) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + NS_IMPL_ISUPPORTS_INHERITED1(nsPluginDocument, nsMediaDocument, nsIPluginDocument) void nsPluginDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject) { if (!aScriptGlobalObject) { mStreamListener = nsnull; diff --git a/content/xbl/src/nsBindingManager.cpp b/content/xbl/src/nsBindingManager.cpp --- a/content/xbl/src/nsBindingManager.cpp +++ b/content/xbl/src/nsBindingManager.cpp @@ -145,17 +145,20 @@ NS_INTERFACE_MAP_BEGIN(nsAnonymousConten if (aIID.Equals(NS_GET_IID(nsAnonymousContentList))) foundInterface = static_cast(this); else NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMNodeList) NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(NodeList) NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsAnonymousContentList) NS_INTERFACE_MAP_END -NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsAnonymousContentList) +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsAnonymousContentList) + tmp->mElements->Clear(); +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsAnonymousContentList) { PRInt32 i, count = tmp->mElements->Length(); for (i = 0; i < count; ++i) { NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mElements->ElementAt(i), nsXBLInsertionPoint); } } diff --git a/layout/xul/base/src/nsBoxObject.cpp b/layout/xul/base/src/nsBoxObject.cpp --- a/layout/xul/base/src/nsBoxObject.cpp +++ b/layout/xul/base/src/nsBoxObject.cpp @@ -61,27 +61,34 @@ #include "nsSupportsPrimitives.h" // Implementation ///////////////////////////////////////////////////////////////// // Static member variable initialization // Implement our nsISupports methods +NS_IMPL_CYCLE_COLLECTION_CLASS(nsBoxObject) + +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsBoxObject) +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsBoxObject) + // QueryInterface implementation for nsBoxObject -NS_INTERFACE_MAP_BEGIN(nsBoxObject) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsBoxObject) NS_INTERFACE_MAP_ENTRY(nsIBoxObject) NS_INTERFACE_MAP_ENTRY(nsPIBoxObject) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY_DOM_CLASSINFO(BoxObject) NS_INTERFACE_MAP_END +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsBoxObject) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END -NS_IMPL_ADDREF(nsBoxObject) -NS_IMPL_RELEASE(nsBoxObject) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsBoxObject) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END // Constructors/Destructors nsBoxObject::nsBoxObject(void) :mContent(nsnull) { } diff --git a/layout/xul/base/src/nsBoxObject.h b/layout/xul/base/src/nsBoxObject.h --- a/layout/xul/base/src/nsBoxObject.h +++ b/layout/xul/base/src/nsBoxObject.h @@ -40,24 +40,26 @@ #include "nsCOMPtr.h" #include "nsIBoxObject.h" #include "nsPIBoxObject.h" #include "nsPoint.h" #include "nsAutoPtr.h" #include "nsHashKeys.h" #include "nsInterfaceHashtable.h" +#include "nsCycleCollectionParticipant.h" class nsIFrame; class nsIDocShell; struct nsRect; class nsBoxObject : public nsPIBoxObject { - NS_DECL_ISUPPORTS + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_CLASS(nsBoxObject) NS_DECL_NSIBOXOBJECT public: nsBoxObject(); virtual ~nsBoxObject(); // nsPIBoxObject virtual nsresult Init(nsIContent* aContent); diff --git a/layout/xul/base/src/tree/src/nsTreeBoxObject.cpp b/layout/xul/base/src/tree/src/nsTreeBoxObject.cpp --- a/layout/xul/base/src/tree/src/nsTreeBoxObject.cpp +++ b/layout/xul/base/src/tree/src/nsTreeBoxObject.cpp @@ -44,17 +44,32 @@ #include "nsIXULTemplateBuilder.h" #include "nsTreeContentView.h" #include "nsITreeSelection.h" #include "nsChildIterator.h" #include "nsContentUtils.h" #include "nsDOMError.h" #include "nsTreeBodyFrame.h" -NS_IMPL_ISUPPORTS_INHERITED1(nsTreeBoxObject, nsBoxObject, nsITreeBoxObject) +NS_IMPL_CYCLE_COLLECTION_CLASS(nsTreeBoxObject) + +NS_IMPL_ADDREF_INHERITED(nsTreeBoxObject, nsBoxObject) +NS_IMPL_RELEASE_INHERITED(nsTreeBoxObject, nsBoxObject) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsTreeBoxObject) + NS_INTERFACE_MAP_ENTRY(nsITreeBoxObject) +NS_INTERFACE_MAP_END_INHERITING(nsBoxObject) + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsTreeBoxObject, nsBoxObject) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mView) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsTreeBoxObject, nsBoxObject) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mView) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END void nsTreeBoxObject::Clear() { ClearCachedValues(); // Drop the view's ref to us. if (mView) { diff --git a/layout/xul/base/src/tree/src/nsTreeBoxObject.h b/layout/xul/base/src/tree/src/nsTreeBoxObject.h --- a/layout/xul/base/src/tree/src/nsTreeBoxObject.h +++ b/layout/xul/base/src/tree/src/nsTreeBoxObject.h @@ -44,16 +44,17 @@ #include "nsBoxObject.h" #include "nsITreeView.h" #include "nsITreeBoxObject.h" class nsTreeBoxObject : public nsITreeBoxObject, public nsBoxObject { public: NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsTreeBoxObject, nsBoxObject) NS_DECL_NSITREEBOXOBJECT nsTreeBoxObject(); ~nsTreeBoxObject(); nsITreeBoxObject* GetTreeBody(); nsITreeBoxObject* GetCachedTreeBody() { return mTreeBody; } diff --git a/layout/xul/base/src/tree/src/nsTreeColumns.cpp b/layout/xul/base/src/tree/src/nsTreeColumns.cpp --- a/layout/xul/base/src/tree/src/nsTreeColumns.cpp +++ b/layout/xul/base/src/tree/src/nsTreeColumns.cpp @@ -68,28 +68,38 @@ nsTreeColumn::~nsTreeColumn() nsTreeColumn::~nsTreeColumn() { if (mNext) { mNext->SetPrevious(nsnull); NS_RELEASE(mNext); } } +NS_IMPL_CYCLE_COLLECTION_CLASS(nsTreeColumn) + +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTreeColumn) +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTreeColumn) + // QueryInterface implementation for nsTreeColumn -NS_INTERFACE_MAP_BEGIN(nsTreeColumn) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTreeColumn) NS_INTERFACE_MAP_ENTRY(nsITreeColumn) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY_DOM_CLASSINFO(TreeColumn) if (aIID.Equals(kTreeColumnImplCID)) foundInterface = static_cast(this); else NS_INTERFACE_MAP_END - -NS_IMPL_ADDREF(nsTreeColumn) -NS_IMPL_RELEASE(nsTreeColumn) + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsTreeColumn) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContent) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsTreeColumn) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContent) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END nsIFrame* nsTreeColumn::GetFrame(nsTreeBodyFrame* aBodyFrame) { NS_PRECONDITION(aBodyFrame, "null frame?"); nsIPresShell *shell = aBodyFrame->PresContext()->PresShell(); if (!shell) diff --git a/layout/xul/base/src/tree/src/nsTreeColumns.h b/layout/xul/base/src/tree/src/nsTreeColumns.h --- a/layout/xul/base/src/tree/src/nsTreeColumns.h +++ b/layout/xul/base/src/tree/src/nsTreeColumns.h @@ -50,17 +50,18 @@ class nsTreeColumns; // This class is our column info. We use it to iterate our columns and to obtain // information about each column. class nsTreeColumn : public nsITreeColumn { public: nsTreeColumn(nsTreeColumns* aColumns, nsIContent* aContent); ~nsTreeColumn(); - NS_DECL_ISUPPORTS + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_CLASS(nsTreeColumn) NS_DECL_NSITREECOLUMN friend class nsTreeBodyFrame; friend class nsTreeColumns; protected: nsIFrame* GetFrame(); nsIFrame* GetFrame(nsTreeBodyFrame* aBodyFrame); diff --git a/layout/xul/base/src/tree/src/nsTreeContentView.cpp b/layout/xul/base/src/tree/src/nsTreeContentView.cpp --- a/layout/xul/base/src/tree/src/nsTreeContentView.cpp +++ b/layout/xul/base/src/tree/src/nsTreeContentView.cpp @@ -153,27 +153,43 @@ NS_NewTreeContentView(nsITreeView** aRes { *aResult = new nsTreeContentView; if (! *aResult) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(*aResult); return NS_OK; } -NS_IMPL_ADDREF(nsTreeContentView) -NS_IMPL_RELEASE(nsTreeContentView) +NS_IMPL_CYCLE_COLLECTION_CLASS(nsTreeContentView) -NS_INTERFACE_MAP_BEGIN(nsTreeContentView) +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTreeContentView) +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTreeContentView) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTreeContentView) NS_INTERFACE_MAP_ENTRY(nsITreeView) NS_INTERFACE_MAP_ENTRY(nsITreeContentView) NS_INTERFACE_MAP_ENTRY(nsIDocumentObserver) NS_INTERFACE_MAP_ENTRY(nsIMutationObserver) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsITreeContentView) NS_INTERFACE_MAP_ENTRY_DOM_CLASSINFO(TreeContentView) NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsTreeContentView) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mBoxObject) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSelection) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRoot) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mBody) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsTreeContentView) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mBoxObject) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSelection) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRoot) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mBody) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMETHODIMP nsTreeContentView::GetRowCount(PRInt32* aRowCount) { *aRowCount = mRows.Count(); return NS_OK; } diff --git a/layout/xul/base/src/tree/src/nsTreeContentView.h b/layout/xul/base/src/tree/src/nsTreeContentView.h --- a/layout/xul/base/src/tree/src/nsTreeContentView.h +++ b/layout/xul/base/src/tree/src/nsTreeContentView.h @@ -54,17 +54,19 @@ class nsTreeContentView : public nsINati public nsITreeContentView, public nsStubDocumentObserver { public: nsTreeContentView(void); ~nsTreeContentView(void); - NS_DECL_ISUPPORTS + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsTreeContentView, + nsINativeTreeView) NS_DECL_NSITREEVIEW // nsINativeTreeView: Untrusted code can use us NS_IMETHOD EnsureNative() { return NS_OK; } NS_DECL_NSITREECONTENTVIEW // nsIDocumentObserver diff --git a/layout/xul/base/src/tree/src/nsTreeSelection.cpp b/layout/xul/base/src/tree/src/nsTreeSelection.cpp --- a/layout/xul/base/src/tree/src/nsTreeSelection.cpp +++ b/layout/xul/base/src/tree/src/nsTreeSelection.cpp @@ -265,25 +265,35 @@ nsTreeSelection::nsTreeSelection(nsITree { } nsTreeSelection::~nsTreeSelection() { delete mFirstRange; } +NS_IMPL_CYCLE_COLLECTION_CLASS(nsTreeSelection) + +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTreeSelection) +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTreeSelection) + // QueryInterface implementation for nsBoxObject -NS_INTERFACE_MAP_BEGIN(nsTreeSelection) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTreeSelection) NS_INTERFACE_MAP_ENTRY(nsITreeSelection) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY_DOM_CLASSINFO(TreeSelection) NS_INTERFACE_MAP_END -NS_IMPL_ADDREF(nsTreeSelection) -NS_IMPL_RELEASE(nsTreeSelection) +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsTreeSelection) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCurrentColumn) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsTreeSelection) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCurrentColumn) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMETHODIMP nsTreeSelection::GetTree(nsITreeBoxObject * *aTree) { NS_IF_ADDREF(mTree); *aTree = mTree; return NS_OK; } diff --git a/layout/xul/base/src/tree/src/nsTreeSelection.h b/layout/xul/base/src/tree/src/nsTreeSelection.h --- a/layout/xul/base/src/tree/src/nsTreeSelection.h +++ b/layout/xul/base/src/tree/src/nsTreeSelection.h @@ -40,27 +40,29 @@ * ***** END LICENSE BLOCK ***** */ #ifndef nsTreeSelection_h__ #define nsTreeSelection_h__ #include "nsITreeSelection.h" #include "nsITreeColumns.h" #include "nsITimer.h" +#include "nsCycleCollectionParticipant.h" class nsITreeBoxObject; struct nsTreeRange; class nsTreeSelection : public nsITreeSelection { public: nsTreeSelection(nsITreeBoxObject* aTree); ~nsTreeSelection(); - NS_DECL_ISUPPORTS + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_CLASS(nsTreeSelection) NS_DECL_NSITREESELECTION friend struct nsTreeRange; protected: nsresult FireOnSelectHandler(); static void SelectCallback(nsITimer *aTimer, void *aClosure);