Back to index

lightning-sunbird  0.9+nobinonly
nsContentList.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 #ifndef nsContentList_h___
00038 #define nsContentList_h___
00039 
00040 #include "nsISupports.h"
00041 #include "nsCOMArray.h"
00042 #include "nsString.h"
00043 #include "nsIDOMHTMLCollection.h"
00044 #include "nsIDOMNodeList.h"
00045 #include "nsStubDocumentObserver.h"
00046 #include "nsIAtom.h"
00047 #include "nsINameSpaceManager.h"
00048 
00049 // This is a callback function type that can be used to implement an
00050 // arbitrary matching algorithm.  aContent is the content that may
00051 // match the list, while aNamespaceID, aAtom, and aData are whatever
00052 // was passed to the list's constructor.
00053 typedef PRBool (*nsContentListMatchFunc)(nsIContent* aContent,
00054                                          PRInt32 aNamespaceID,
00055                                          nsIAtom* aAtom,
00056                                          const nsAString& aData);
00057 
00058 class nsIDocument;
00059 class nsIDOMHTMLFormElement;
00060 
00061 
00062 class nsBaseContentList : public nsIDOMNodeList
00063 {
00064 public:
00065   nsBaseContentList();
00066   virtual ~nsBaseContentList();
00067 
00068   NS_DECL_ISUPPORTS
00069 
00070   // nsIDOMNodeList
00071   NS_DECL_NSIDOMNODELIST
00072 
00073   virtual void AppendElement(nsIContent *aContent);
00074   virtual void RemoveElement(nsIContent *aContent);
00075   virtual PRInt32 IndexOf(nsIContent *aContent, PRBool aDoFlush);
00076   virtual void Reset();
00077 
00078   static void Shutdown();
00079 
00080 protected:
00081   nsCOMArray<nsIContent> mElements;
00082 };
00083 
00084 
00085 // This class is used only by form element code and this is a static
00086 // list of elements. NOTE! This list holds strong references to
00087 // the elements in the list.
00088 class nsFormContentList : public nsBaseContentList
00089 {
00090 public:
00091   nsFormContentList(nsIDOMHTMLFormElement *aForm,
00092                     nsBaseContentList& aContentList);
00093 };
00094 
00099 class nsContentListKey
00100 {
00101 public:
00102   nsContentListKey(nsIDocument *aDocument,
00103                    nsIAtom* aMatchAtom, 
00104                    PRInt32 aMatchNameSpaceId,
00105                    nsIContent* aRootContent)
00106     : mMatchAtom(aMatchAtom),
00107       mMatchNameSpaceId(aMatchNameSpaceId),
00108       mDocument(aDocument),
00109       mRootContent(aRootContent)
00110   {
00111   }
00112   
00113   nsContentListKey(const nsContentListKey& aContentListKey)
00114     : mMatchAtom(aContentListKey.mMatchAtom),
00115       mMatchNameSpaceId(aContentListKey.mMatchNameSpaceId),
00116       mDocument(aContentListKey.mDocument),
00117       mRootContent(aContentListKey.mRootContent)
00118   {
00119   }
00120 
00121   PRBool Equals(const nsContentListKey& aContentListKey) const
00122   {
00123     return
00124       mMatchAtom == aContentListKey.mMatchAtom &&
00125       mMatchNameSpaceId == aContentListKey.mMatchNameSpaceId &&
00126       mDocument == aContentListKey.mDocument &&
00127       mRootContent == aContentListKey.mRootContent;
00128   }
00129   inline PRUint32 GetHash(void) const
00130   {
00131     return
00132       NS_PTR_TO_INT32(mMatchAtom.get()) ^
00133       (NS_PTR_TO_INT32(mRootContent) << 8) ^
00134       (NS_PTR_TO_INT32(mDocument) << 16) ^
00135       (mMatchNameSpaceId << 24);
00136   }
00137   
00138 protected:
00139   nsCOMPtr<nsIAtom> mMatchAtom;
00140   PRInt32 mMatchNameSpaceId;
00141   nsIDocument* mDocument;   // Weak ref
00142   // XXX What if the mRootContent is detached from the doc and _then_
00143   // goes away (so we never get notified)?  Note that we work around
00144   // that a little by not caching lists with an mRootContent in
00145   // gCachedContentList.  If we fix this, we can remove that check.
00146   nsIContent* mRootContent; // Weak ref
00147 };
00148 
00153 #define LIST_UP_TO_DATE 0
00154 
00159 #define LIST_DIRTY 1
00160 
00167 #define LIST_LAZY 2
00168 
00173 class nsContentList : public nsBaseContentList,
00174                       protected nsContentListKey,
00175                       public nsIDOMHTMLCollection,
00176                       public nsStubDocumentObserver
00177 {
00178 public:
00179   NS_DECL_ISUPPORTS_INHERITED
00180 
00181   nsContentList(nsIDocument *aDocument, 
00182                 nsIAtom* aMatchAtom, 
00183                 PRInt32 aMatchNameSpaceId,
00184                 nsIContent* aRootContent = nsnull,
00185                 PRBool aDeep = PR_TRUE);
00186   nsContentList(nsIDocument *aDocument, 
00187                 nsContentListMatchFunc aFunc,
00188                 const nsAString& aData,
00189                 nsIContent* aRootContent = nsnull,
00190                 PRBool aDeep = PR_TRUE,
00191                 nsIAtom* aMatchAtom = nsnull,
00192                 PRInt32 aMatchNameSpaceId = kNameSpaceID_None);
00193   virtual ~nsContentList();
00194 
00195   // nsIDOMHTMLCollection
00196   NS_DECL_NSIDOMHTMLCOLLECTION
00197 
00198   // nsBaseContentList overrides
00199   virtual PRInt32 IndexOf(nsIContent *aContent, PRBool aDoFlush);
00200 
00201   // nsContentList public methods
00202   NS_HIDDEN_(nsISupports*) GetParentObject();
00203   NS_HIDDEN_(PRUint32) Length(PRBool aDoFlush);
00204   NS_HIDDEN_(nsIContent*) Item(PRUint32 aIndex, PRBool aDoFlush);
00205   NS_HIDDEN_(nsIContent*) NamedItem(const nsAString& aName, PRBool aDoFlush);
00206   NS_HIDDEN_(void) RootDestroyed();
00207 
00208   nsContentListKey* GetKey() {
00209     return NS_STATIC_CAST(nsContentListKey*, this);
00210   }
00211   
00212 
00213   // nsIDocumentObserver
00214   virtual void AttributeChanged(nsIDocument *aDocument, nsIContent* aContent,
00215                                 PRInt32 aNameSpaceID, nsIAtom* aAttribute,
00216                                 PRInt32 aModType);
00217   virtual void ContentAppended(nsIDocument *aDocument, nsIContent* aContainer,
00218                                PRInt32 aNewIndexInContainer);
00219   virtual void ContentInserted(nsIDocument *aDocument, nsIContent* aContainer,
00220                                nsIContent* aChild, PRInt32 aIndexInContainer);
00221   virtual void ContentRemoved(nsIDocument *aDocument, nsIContent* aContainer,
00222                               nsIContent* aChild, PRInt32 aIndexInContainer);
00223   virtual void DocumentWillBeDestroyed(nsIDocument *aDocument);
00224 
00225   static void OnDocumentDestroy(nsIDocument *aDocument);
00226 
00227 protected:
00228   void Init(nsIDocument *aDocument);
00235   PRBool Match(nsIContent *aContent);
00243   PRBool MatchSelf(nsIContent *aContent);
00244 
00256   void PopulateWith(nsIContent *aContent, PRBool aIncludeRoot,
00257                     PRUint32 & aElementsToAppend);
00270   void PopulateWithStartingAfter(nsIContent *aStartRoot,
00271                                  nsIContent *aStartChild,
00272                                  PRUint32 & aElementsToAppend);
00284   void PopulateSelf(PRUint32 aNeededLength);
00285 
00292   void DisconnectFromDocument();
00293 
00302   PRBool MayContainRelevantNodes(nsIContent* aContainer);
00310   PRBool ContainsRoot(nsIContent* aContent);
00316   void CheckDocumentExistence();
00321   void RemoveFromHashtable();
00328   inline void BringSelfUpToDate(PRBool aDoFlush);
00334   PRBool IsContentAnonymous(nsIContent* aContent);
00335 
00340   void SetDirty()
00341   {
00342     mState = LIST_DIRTY;
00343     Reset();
00344   }
00345 
00350   nsContentListMatchFunc mFunc;
00354   const nsAFlatString* mData;
00358   PRPackedBool mMatchAll;
00363   PRUint8 mState;
00368   PRPackedBool mDeep;
00369 };
00370 
00371 already_AddRefed<nsContentList>
00372 NS_GetContentList(nsIDocument* aDocument, nsIAtom* aMatchAtom,
00373                   PRInt32 aMatchNameSpaceId, nsIContent* aRootContent);
00374 
00375 #endif // nsContentList_h___