Back to index

lightning-sunbird  0.9+nobinonly
nsGenericElement.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 Communicator client 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 nsGenericElement_h___
00038 #define nsGenericElement_h___
00039 
00040 #include "nsCOMPtr.h"
00041 #include "nsAutoPtr.h"
00042 #include "nsIXMLContent.h"
00043 #include "nsIDOMElement.h"
00044 #include "nsIDOMDocumentFragment.h"
00045 #include "nsIDOMEventReceiver.h"
00046 #include "nsIDOM3EventTarget.h"
00047 #include "nsIDOM3Node.h"
00048 #include "nsIDOMNSEventTarget.h"
00049 #include "nsILinkHandler.h"
00050 #include "nsGenericDOMNodeList.h"
00051 #include "nsIEventListenerManager.h"
00052 #include "nsContentUtils.h"
00053 #include "pldhash.h"
00054 #include "nsAttrAndChildArray.h"
00055 
00056 class nsIDOMAttr;
00057 class nsIDOMEventListener;
00058 class nsIFrame;
00059 class nsISupportsArray;
00060 class nsIDOMNamedNodeMap;
00061 class nsDOMCSSDeclaration;
00062 class nsIDOMCSSStyleDeclaration;
00063 class nsDOMAttributeMap;
00064 class nsIURI;
00065 class nsVoidArray;
00066 class nsINodeInfo;
00067 class nsIControllers;
00068 class nsIDOMNSFeatureFactory;
00069 
00070 typedef unsigned long PtrBits;
00071 
00075 #define GENERIC_ELEMENT_DOESNT_HAVE_DOMSLOTS   0x00000001U
00076 
00080 #define GENERIC_ELEMENT_HAS_RANGELIST          0x00000002U
00081 
00086 #define GENERIC_ELEMENT_HAS_LISTENERMANAGER    0x00000004U
00087 
00089 #define GENERIC_ELEMENT_IS_ANONYMOUS           0x00000008U
00090 
00092 #define GENERIC_ELEMENT_HAS_PROPERTIES         0x00000010U
00093 
00095 #define GENERIC_ELEMENT_MAY_HAVE_FRAME         0x00000020U
00096 
00098 #define ELEMENT_TYPE_SPECIFIC_BITS_OFFSET      6
00099 
00101 #define GENERIC_ELEMENT_CONTENT_ID_BITS_OFFSET 9
00102 
00104 #define GENERIC_ELEMENT_CONTENT_ID_MASK \
00105   ((~PtrBits(0)) << GENERIC_ELEMENT_CONTENT_ID_BITS_OFFSET)
00106 
00111 #define GENERIC_ELEMENT_CONTENT_ID_MAX_VALUE \
00112   ((PRUint32)((~PtrBits(0)) >> GENERIC_ELEMENT_CONTENT_ID_BITS_OFFSET))
00113 
00114 
00115 #define PARENT_BIT_INDOCUMENT ((PtrBits)0x1 << 0)
00116 
00123 class nsChildContentList : public nsGenericDOMNodeList 
00124 {
00125 public:
00129   nsChildContentList(nsIContent *aContent);
00130   virtual ~nsChildContentList();
00131 
00132   // nsIDOMNodeList interface
00133   NS_DECL_NSIDOMNODELIST
00134   
00136   void DropReference();
00137 
00138 private:
00140   nsIContent *mContent;
00141 };
00142 
00151 class nsDOMSlots
00152 {
00153 public:
00154   nsDOMSlots(PtrBits aFlags);
00155   ~nsDOMSlots();
00156 
00157   PRBool IsEmpty();
00158 
00159   PtrBits mFlags;
00160 
00166   nsRefPtr<nsChildContentList> mChildNodes;
00167 
00172   nsRefPtr<nsDOMCSSDeclaration> mStyle;
00173 
00178   nsRefPtr<nsDOMAttributeMap> mAttributeMap;
00179 
00180   union {
00185     nsIContent* mBindingParent;  // [Weak]
00186 
00190     nsIControllers* mControllers; // [OWNER]
00191   };
00192 
00193   // DEPRECATED, DON'T USE THIS
00194   PRUint32 mContentID;
00195 };
00196 
00197 class RangeListMapEntry : public PLDHashEntryHdr
00198 {
00199 public:
00200   RangeListMapEntry(const void *aKey)
00201     : mKey(aKey), mRangeList(nsnull)
00202   {
00203   }
00204 
00205   ~RangeListMapEntry()
00206   {
00207     delete mRangeList;
00208   }
00209 
00210 private:
00211   const void *mKey; // must be first to look like PLDHashEntryStub
00212 
00213 public:
00214   // We want mRangeList to be an nsAutoVoidArray but we can't make an
00215   // nsAutoVoidArray a direct member of RangeListMapEntry since it
00216   // will be moved around in memory, and nsAutoVoidArray can't deal
00217   // with that.
00218   nsVoidArray *mRangeList;
00219 };
00220 
00221 class EventListenerManagerMapEntry : public PLDHashEntryHdr
00222 {
00223 public:
00224   EventListenerManagerMapEntry(const void *aKey)
00225     : mKey(aKey)
00226   {
00227   }
00228 
00229   ~EventListenerManagerMapEntry()
00230   {
00231     NS_ASSERTION(!mListenerManager, "caller must release and disconnect ELM");
00232   }
00233 
00234 private:
00235   const void *mKey; // must be first, to look like PLDHashEntryStub
00236 
00237 public:
00238   nsCOMPtr<nsIEventListenerManager> mListenerManager;
00239 };
00240 
00241 
00245 class nsNode3Tearoff : public nsIDOM3Node
00246 {
00247 public:
00248   NS_DECL_ISUPPORTS
00249 
00250   NS_DECL_NSIDOM3NODE
00251 
00252   nsNode3Tearoff(nsIContent *aContent) : mContent(aContent)
00253   {
00254   }
00255 
00256   static nsresult GetTextContent(nsIContent *aContent,
00257                                  nsAString &aTextContent);
00258 
00259   static nsresult SetTextContent(nsIContent *aContent,
00260                                  const nsAString &aTextContent);
00261 
00262 protected:
00263   virtual ~nsNode3Tearoff() {};
00264 
00265 private:
00266   nsCOMPtr<nsIContent> mContent;
00267 };
00268 
00269 
00270 #define NS_EVENT_TEAROFF_CACHE_SIZE 4
00271 
00281 class nsDOMEventRTTearoff : public nsIDOMEventReceiver,
00282                             public nsIDOM3EventTarget,
00283                             public nsIDOMNSEventTarget
00284 {
00285 private:
00286   // This class uses a caching scheme so we don't let users of this
00287   // class create new instances with 'new', in stead the callers
00288   // should use the static method
00289   // nsDOMEventRTTearoff::Create(). That's why the constructor and
00290   // destrucor of this class is private.
00291 
00292   nsDOMEventRTTearoff(nsIContent *aContent);
00293 
00294   static nsDOMEventRTTearoff *mCachedEventTearoff[NS_EVENT_TEAROFF_CACHE_SIZE];
00295   static PRUint32 mCachedEventTearoffCount;
00296 
00302   void LastRelease();
00303 
00304   nsresult GetEventReceiver(nsIDOMEventReceiver **aReceiver);
00305   nsresult GetDOM3EventTarget(nsIDOM3EventTarget **aTarget);
00306 
00307 public:
00308   virtual ~nsDOMEventRTTearoff();
00309 
00314   static nsDOMEventRTTearoff *Create(nsIContent *aContent);
00315 
00319   static void Shutdown();
00320 
00321   // nsISupports
00322   NS_DECL_ISUPPORTS
00323 
00324   // nsIDOMEventTarget
00325   NS_DECL_NSIDOMEVENTTARGET
00326 
00327   // nsIDOM3EventTarget
00328   NS_DECL_NSIDOM3EVENTTARGET
00329 
00330   // nsIDOMEventReceiver
00331   NS_IMETHOD AddEventListenerByIID(nsIDOMEventListener *aListener,
00332                                    const nsIID& aIID);
00333   NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener,
00334                                       const nsIID& aIID);
00335   NS_IMETHOD GetListenerManager(nsIEventListenerManager** aResult);
00336   NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent);
00337   NS_IMETHOD GetSystemEventGroup(nsIDOMEventGroup** aGroup);
00338 
00339   // nsIDOMNSEventTarget
00340   NS_DECL_NSIDOMNSEVENTTARGET
00341 
00342 private:
00347   nsCOMPtr<nsIContent> mContent;
00348 };
00349 
00373 class nsMutationGuard {
00374 public:
00375   nsMutationGuard()
00376   {
00377     mDelta = eMaxMutations - sMutationCount;
00378     sMutationCount = eMaxMutations;
00379   }
00380   ~nsMutationGuard()
00381   {
00382     sMutationCount =
00383       mDelta > sMutationCount ? 0 : sMutationCount - mDelta;
00384   }
00385 
00390   PRBool Mutated(PRUint8 aIgnoreCount)
00391   {
00392     return sMutationCount < NS_STATIC_CAST(PRUint32, eMaxMutations - aIgnoreCount);
00393   }
00394 
00395   // This function should be called whenever a mutation that we want to keep
00396   // track of happen. For now this is only done when children are added or
00397   // removed, but we might do it for attribute changes too in the future.
00398   static void DidMutate()
00399   {
00400     if (sMutationCount) {
00401       --sMutationCount;
00402     }
00403   }
00404 
00405 private:
00406   // mDelta is the amount sMutationCount was adjusted when the guard was
00407   // initialized. It is needed so that we can undo that adjustment once
00408   // the guard dies.
00409   PRUint32 mDelta;
00410 
00411   // The value 300 is not important, as long as it is bigger then anything
00412   // ever passed to Mutated().
00413   enum { eMaxMutations = 300 };
00414 
00415   
00416   // sMutationCount is a global mutation counter which is decreased by one at
00417   // every mutation. It is capped at 0 to avoid wrapping.
00418   // It's value is always between 0 and 300, inclusive.
00419   static PRUint32 sMutationCount;
00420 };
00421 
00426 class nsGenericElement : public nsIXMLContent
00427 {
00428 public:
00429   nsGenericElement(nsINodeInfo *aNodeInfo);
00430   virtual ~nsGenericElement();
00431 
00432   NS_DECL_ISUPPORTS
00433 
00438   nsresult PostQueryInterface(REFNSIID aIID, void** aInstancePtr);
00439 
00441   static void Shutdown();
00442 
00443   // nsIDOMGCParticipant interface methods
00444   virtual nsIDOMGCParticipant* GetSCCIndex();
00445   virtual void AppendReachableList(nsCOMArray<nsIDOMGCParticipant>& aArray);
00446 
00447   // nsIContent interface methods
00448   nsIDocument* GetDocument() const
00449   {
00450     return IsInDoc() ? GetOwnerDoc() : nsnull;
00451   }
00452   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
00453                               nsIContent* aBindingParent,
00454                               PRBool aCompileEventHandlers);
00455   virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
00456                               PRBool aNullParent = PR_TRUE);
00457   PRBool IsInDoc() const
00458   {
00459     return mParentPtrBits & PARENT_BIT_INDOCUMENT;
00460   }
00461   nsIDocument *GetOwnerDoc() const
00462   {
00463     return nsContentUtils::GetDocument(mNodeInfo);
00464   }
00465   virtual PRBool IsNativeAnonymous() const;
00466   virtual void SetNativeAnonymous(PRBool aAnonymous);
00467   virtual PRInt32 GetNameSpaceID() const;
00468   virtual nsIAtom *Tag() const;
00469   virtual nsINodeInfo *GetNodeInfo() const;
00470   virtual PRUint32 GetChildCount() const;
00471   virtual nsIContent *GetChildAt(PRUint32 aIndex) const;
00472   virtual PRInt32 IndexOf(nsIContent* aPossibleChild) const;
00473   virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
00474                                  PRBool aNotify);
00475   virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify);
00476   virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
00477   virtual nsIAtom *GetIDAttributeName() const;
00478   virtual nsIAtom *GetClassAttributeName() const;
00479   virtual already_AddRefed<nsINodeInfo> GetExistingAttrNameFromQName(const nsAString& aStr) const;
00480   nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
00481                    const nsAString& aValue, PRBool aNotify)
00482   {
00483     return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
00484   }
00485   virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
00486                            const nsAString& aValue, PRBool aNotify);
00487   virtual nsresult GetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
00488                            nsAString& aResult) const;
00489   virtual PRBool HasAttr(PRInt32 aNameSpaceID, nsIAtom* aName) const;
00490   virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
00491                              PRBool aNotify);
00492   virtual nsresult GetAttrNameAt(PRUint32 aIndex, PRInt32* aNameSpaceID,
00493                                  nsIAtom** aName, nsIAtom** aPrefix) const;
00494   virtual PRUint32 GetAttrCount() const;
00495   virtual nsresult RangeAdd(nsIDOMRange* aRange);
00496   virtual void RangeRemove(nsIDOMRange* aRange);
00497   virtual const nsVoidArray *GetRangeList() const;
00498   virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
00499                             nsEvent* aEvent,
00500                             nsIDOMEvent** aDOMEvent,
00501                             PRUint32 aFlags,
00502                             nsEventStatus* aEventStatus);
00503   virtual PRUint32 ContentID() const;
00504   virtual void SetContentID(PRUint32 aID);
00505   virtual void SetFocus(nsPresContext* aContext);
00506   virtual nsIContent *GetBindingParent() const;
00507   virtual PRBool IsContentOfType(PRUint32 aFlags) const;
00508   virtual nsresult GetListenerManager(nsIEventListenerManager** aResult);
00509   virtual already_AddRefed<nsIURI> GetBaseURI() const;
00510   virtual void* GetProperty(nsIAtom  *aPropertyName,
00511                             nsresult *aStatus = nsnull) const;
00512   virtual nsresult SetProperty(nsIAtom            *aPropertyName,
00513                                void               *aValue,
00514                                NSPropertyDtorFunc  aDtor);
00515   virtual nsresult DeleteProperty(nsIAtom  *aPropertyName);
00516   virtual void*    UnsetProperty(nsIAtom *aPropertyName,
00517                                  nsresult *aStatus = nsnull);
00518   virtual void SetMayHaveFrame(PRBool aMayHaveFrame);
00519   virtual PRBool MayHaveFrame() const;
00520 
00521 #ifdef DEBUG
00522   virtual void List(FILE* out, PRInt32 aIndent) const;
00523   virtual void DumpContent(FILE* out, PRInt32 aIndent,PRBool aDumpAll) const;
00524 #endif
00525 
00526   // nsIStyledContent interface methods
00527   virtual nsIAtom* GetID() const;
00528   virtual const nsAttrValue* GetClasses() const;
00529   NS_IMETHOD_(PRBool) HasClass(nsIAtom* aClass, PRBool aCaseSensitive) const;
00530   NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
00531   virtual nsICSSStyleRule* GetInlineStyleRule();
00532   NS_IMETHOD SetInlineStyleRule(nsICSSStyleRule* aStyleRule, PRBool aNotify);
00533   NS_IMETHOD_(PRBool)
00534     IsAttributeMapped(const nsIAtom* aAttribute) const;
00535   virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute, 
00536                                               PRInt32 aModType) const;
00537   /*
00538    * Attribute Mapping Helpers
00539    */
00540   struct MappedAttributeEntry {
00541     nsIAtom** attribute;
00542   };
00543   
00550   static PRBool
00551   FindAttributeDependence(const nsIAtom* aAttribute,
00552                           const MappedAttributeEntry* const aMaps[],
00553                           PRUint32 aMapCount);
00554 
00555   // nsIXMLContent interface methods
00556   NS_IMETHOD MaybeTriggerAutoLink(nsIDocShell *aShell);
00557 
00558   // nsIDOMNode method implementation
00559   NS_IMETHOD GetNodeName(nsAString& aNodeName);
00560   NS_IMETHOD GetLocalName(nsAString& aLocalName);
00561   NS_IMETHOD GetNodeValue(nsAString& aNodeValue);
00562   NS_IMETHOD SetNodeValue(const nsAString& aNodeValue);
00563   NS_IMETHOD GetNodeType(PRUint16* aNodeType);
00564   NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode);
00565   NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes);
00566   NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling);
00567   NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling);
00568   NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument);
00569   NS_IMETHOD GetNamespaceURI(nsAString& aNamespaceURI);
00570   NS_IMETHOD GetPrefix(nsAString& aPrefix);
00571   NS_IMETHOD SetPrefix(const nsAString& aPrefix);
00572   NS_IMETHOD Normalize();
00573   NS_IMETHOD IsSupported(const nsAString& aFeature,
00574                          const nsAString& aVersion, PRBool* aReturn);
00575   NS_IMETHOD HasAttributes(PRBool* aHasAttributes);
00576   NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes);
00577   NS_IMETHOD HasChildNodes(PRBool* aHasChildNodes);
00578   NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild);
00579   NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild);
00580   NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
00581                           nsIDOMNode** aReturn);
00582   NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
00583                           nsIDOMNode** aReturn);
00584   NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn);
00585   NS_IMETHOD AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
00586   {
00587     return InsertBefore(aNewChild, nsnull, aReturn);
00588   }
00589 
00590   // nsIDOMElement method implementation
00591   NS_IMETHOD GetTagName(nsAString& aTagName);
00592   NS_IMETHOD GetAttribute(const nsAString& aName,
00593                           nsAString& aReturn);
00594   NS_IMETHOD SetAttribute(const nsAString& aName,
00595                           const nsAString& aValue);
00596   NS_IMETHOD RemoveAttribute(const nsAString& aName);
00597   NS_IMETHOD GetAttributeNode(const nsAString& aName,
00598                               nsIDOMAttr** aReturn);
00599   NS_IMETHOD SetAttributeNode(nsIDOMAttr* aNewAttr, nsIDOMAttr** aReturn);
00600   NS_IMETHOD RemoveAttributeNode(nsIDOMAttr* aOldAttr, nsIDOMAttr** aReturn);
00601   NS_IMETHOD GetElementsByTagName(const nsAString& aTagname,
00602                                   nsIDOMNodeList** aReturn);
00603   NS_IMETHOD GetAttributeNS(const nsAString& aNamespaceURI,
00604                             const nsAString& aLocalName,
00605                             nsAString& aReturn);
00606   NS_IMETHOD SetAttributeNS(const nsAString& aNamespaceURI,
00607                             const nsAString& aQualifiedName,
00608                             const nsAString& aValue);
00609   NS_IMETHOD RemoveAttributeNS(const nsAString& aNamespaceURI,
00610                                const nsAString& aLocalName);
00611   NS_IMETHOD GetAttributeNodeNS(const nsAString& aNamespaceURI,
00612                                 const nsAString& aLocalName,
00613                                 nsIDOMAttr** aReturn);
00614   NS_IMETHOD SetAttributeNodeNS(nsIDOMAttr* aNewAttr, nsIDOMAttr** aReturn);
00615   NS_IMETHOD GetElementsByTagNameNS(const nsAString& aNamespaceURI,
00616                                     const nsAString& aLocalName,
00617                                     nsIDOMNodeList** aReturn);
00618   NS_IMETHOD HasAttribute(const nsAString& aName, PRBool* aReturn);
00619   NS_IMETHOD HasAttributeNS(const nsAString& aNamespaceURI,
00620                             const nsAString& aLocalName,
00621                             PRBool* aReturn);
00622 
00623   //----------------------------------------
00624 
00631   nsresult AddScriptEventListener(nsIAtom* aAttribute,
00632                                   const nsAString& aValue);
00633 
00648   nsresult TriggerLink(nsPresContext* aPresContext,
00649                        nsLinkVerb aVerb,
00650                        nsIURI* aLinkURI,
00651                        const nsAFlatString& aTargetSpec,
00652                        PRBool aClick,
00653                        PRBool aIsUserTriggered);
00657   nsresult LeaveLink(nsPresContext* aPresContext);
00658 
00664   nsresult JoinTextNodes(nsIContent* aFirst,
00665                          nsIContent* aSecond);
00666 
00677   static void SetDocumentInChildrenOf(nsIContent* aContent, 
00678                                   nsIDocument* aDocument, PRBool aCompileEventHandlers);
00679 
00688   static nsresult InternalIsSupported(nsISupports* aObject,
00689                                       const nsAString& aFeature,
00690                                       const nsAString& aVersion,
00691                                       PRBool* aReturn);
00692 
00693   static nsresult InternalGetFeature(nsISupports* aObject,
00694                                      const nsAString& aFeature,
00695                                      const nsAString& aVersion,
00696                                      nsISupports** aReturn);
00697   
00698   static already_AddRefed<nsIDOMNSFeatureFactory>
00699     GetDOMFeatureFactory(const nsAString& aFeature, const nsAString& aVersion);
00700 
00709   static PRBool HasMutationListeners(nsIContent* aContent,
00710                                      PRUint32 aType);
00711 
00712   static PRBool ShouldFocus(nsIContent *aContent);
00713 
00729   static nsresult doReplaceOrInsertBefore(PRBool aReplace,
00730                                           nsIDOMNode* aNewChild,
00731                                           nsIDOMNode* aRefChild,
00732                                           nsIContent* aParent,
00733                                           nsIDocument* aDocument,
00734                                           nsAttrAndChildArray& aChildArray,
00735                                           nsIDOMNode** aReturn);
00736 
00737   static nsresult InitHashes();
00738 
00739   static PLDHashTable sEventListenerManagersHash;
00740   static PLDHashTable sRangeListsHash;
00741 
00742 protected:
00748   nsresult CopyInnerTo(nsGenericElement* aDest, PRBool aDeep);
00749 
00753   virtual const nsAttrName* InternalGetExistingAttrNameFromQName(const nsAString& aStr) const;
00754 
00755   PRBool HasDOMSlots() const
00756   {
00757     return !(mFlagsOrSlots & GENERIC_ELEMENT_DOESNT_HAVE_DOMSLOTS);
00758   }
00759 
00760   nsDOMSlots *GetDOMSlots()
00761   {
00762     if (!HasDOMSlots()) {
00763       nsDOMSlots *slots = new nsDOMSlots(mFlagsOrSlots);
00764 
00765       if (!slots) {
00766         return nsnull;
00767       }
00768 
00769       mFlagsOrSlots = NS_REINTERPRET_CAST(PtrBits, slots);
00770     }
00771 
00772     return NS_REINTERPRET_CAST(nsDOMSlots *, mFlagsOrSlots);
00773   }
00774 
00775   nsDOMSlots *GetExistingDOMSlots() const
00776   {
00777     if (!HasDOMSlots()) {
00778       return nsnull;
00779     }
00780 
00781     return NS_REINTERPRET_CAST(nsDOMSlots *, mFlagsOrSlots);
00782   }
00783 
00784   PtrBits GetFlags() const
00785   {
00786     if (HasDOMSlots()) {
00787       return NS_REINTERPRET_CAST(nsDOMSlots *, mFlagsOrSlots)->mFlags;
00788     }
00789 
00790     return mFlagsOrSlots;
00791   }
00792 
00793   void SetFlags(PtrBits aFlagsToSet)
00794   {
00795     NS_ASSERTION(!((aFlagsToSet & GENERIC_ELEMENT_CONTENT_ID_MASK) &&
00796                    (aFlagsToSet & ~GENERIC_ELEMENT_CONTENT_ID_MASK)),
00797                  "Whaaa, don't set content ID bits and flags together!!!");
00798 
00799     nsDOMSlots *slots = GetExistingDOMSlots();
00800 
00801     if (slots) {
00802       slots->mFlags |= aFlagsToSet;
00803 
00804       return;
00805     }
00806 
00807     mFlagsOrSlots |= aFlagsToSet;
00808   }
00809 
00810   void UnsetFlags(PtrBits aFlagsToUnset)
00811   {
00812     NS_ASSERTION(!((aFlagsToUnset & GENERIC_ELEMENT_CONTENT_ID_MASK) &&
00813                    (aFlagsToUnset & ~GENERIC_ELEMENT_CONTENT_ID_MASK)),
00814                  "Whaaa, don't set content ID bits and flags together!!!");
00815 
00816     nsDOMSlots *slots = GetExistingDOMSlots();
00817 
00818     if (slots) {
00819       slots->mFlags &= ~aFlagsToUnset;
00820 
00821       return;
00822     }
00823 
00824     mFlagsOrSlots &= ~aFlagsToUnset;
00825   }
00826 
00827   PRBool HasRangeList() const
00828   {
00829     PtrBits flags = GetFlags();
00830 
00831     return (flags & GENERIC_ELEMENT_HAS_RANGELIST && sRangeListsHash.ops);
00832   }
00833 
00834   PRBool HasEventListenerManager() const
00835   {
00836     PtrBits flags = GetFlags();
00837 
00838     return (flags & GENERIC_ELEMENT_HAS_LISTENERMANAGER &&
00839             sEventListenerManagersHash.ops);
00840   }
00841 
00842   PRBool HasProperties() const
00843   {
00844     PtrBits flags = GetFlags();
00845 
00846     return (flags & GENERIC_ELEMENT_HAS_PROPERTIES) != 0;
00847   }
00848 
00858   void GetContentsAsText(nsAString& aText);
00859 
00863   PRBool IsAnonymousForEvents() const
00864   {
00865     return !!(GetFlags() & GENERIC_ELEMENT_IS_ANONYMOUS);
00866   }
00867 
00871   nsCOMPtr<nsINodeInfo> mNodeInfo;          // OWNER
00872 
00879   PtrBits mFlagsOrSlots;
00880 
00884   nsAttrAndChildArray mAttrsAndChildren;
00885 };
00886 
00887 #define NS_FORWARD_NSIDOMNODE_NO_CLONENODE(_to)                               \
00888   NS_IMETHOD GetNodeName(nsAString& aNodeName) {                              \
00889     return _to GetNodeName(aNodeName);                                        \
00890   }                                                                           \
00891   NS_IMETHOD GetNodeValue(nsAString& aNodeValue) {                            \
00892     return _to GetNodeValue(aNodeValue);                                      \
00893   }                                                                           \
00894   NS_IMETHOD SetNodeValue(const nsAString& aNodeValue) {                      \
00895     return _to SetNodeValue(aNodeValue);                                      \
00896   }                                                                           \
00897   NS_IMETHOD GetNodeType(PRUint16* aNodeType) {                               \
00898     return _to GetNodeType(aNodeType);                                        \
00899   }                                                                           \
00900   NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode) {                        \
00901     return _to GetParentNode(aParentNode);                                    \
00902   }                                                                           \
00903   NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes) {                    \
00904     return _to GetChildNodes(aChildNodes);                                    \
00905   }                                                                           \
00906   NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild) {                        \
00907     return _to GetFirstChild(aFirstChild);                                    \
00908   }                                                                           \
00909   NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild) {                          \
00910     return _to GetLastChild(aLastChild);                                      \
00911   }                                                                           \
00912   NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling) {              \
00913     return _to GetPreviousSibling(aPreviousSibling);                          \
00914   }                                                                           \
00915   NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling) {                      \
00916     return _to GetNextSibling(aNextSibling);                                  \
00917   }                                                                           \
00918   NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes) {                \
00919     return _to GetAttributes(aAttributes);                                    \
00920   }                                                                           \
00921   NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument) {              \
00922     return _to GetOwnerDocument(aOwnerDocument);                              \
00923   }                                                                           \
00924   NS_IMETHOD GetNamespaceURI(nsAString& aNamespaceURI) {                      \
00925     return _to GetNamespaceURI(aNamespaceURI);                                \
00926   }                                                                           \
00927   NS_IMETHOD GetPrefix(nsAString& aPrefix) {                                  \
00928     return _to GetPrefix(aPrefix);                                            \
00929   }                                                                           \
00930   NS_IMETHOD SetPrefix(const nsAString& aPrefix) {                            \
00931     return _to SetPrefix(aPrefix);                                            \
00932   }                                                                           \
00933   NS_IMETHOD GetLocalName(nsAString& aLocalName) {                            \
00934     return _to GetLocalName(aLocalName);                                      \
00935   }                                                                           \
00936   NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,       \
00937                           nsIDOMNode** aReturn) {                             \
00938     return _to InsertBefore(aNewChild, aRefChild, aReturn);                   \
00939   }                                                                           \
00940   NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,       \
00941                           nsIDOMNode** aReturn) {                             \
00942     return _to ReplaceChild(aNewChild, aOldChild, aReturn);                   \
00943   }                                                                           \
00944   NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) {       \
00945     return _to RemoveChild(aOldChild, aReturn);                               \
00946   }                                                                           \
00947   NS_IMETHOD AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn) {       \
00948     return _to AppendChild(aNewChild, aReturn);                               \
00949   }                                                                           \
00950   NS_IMETHOD HasChildNodes(PRBool* aReturn) {                                 \
00951     return _to HasChildNodes(aReturn);                                        \
00952   }                                                                           \
00953   NS_IMETHOD Normalize() {                                                    \
00954     return _to Normalize();                                                   \
00955   }                                                                           \
00956   NS_IMETHOD IsSupported(const nsAString& aFeature,                           \
00957                          const nsAString& aVersion, PRBool* aReturn) {        \
00958     return _to IsSupported(aFeature, aVersion, aReturn);                      \
00959   }                                                                           \
00960   NS_IMETHOD HasAttributes(PRBool* aReturn) {                                 \
00961     return _to HasAttributes(aReturn);                                        \
00962   }                                                                           \
00963   NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn);
00964 
00968 #define NS_IMPL_DOM_CLONENODE(_elementName)                                 \
00969 NS_IMPL_DOM_CLONENODE_AMBIGUOUS(_elementName, nsIDOMNode)
00970 
00971 #define NS_IMPL_DOM_CLONENODE_AMBIGUOUS(_elementName, _implClass)           \
00972 NS_IMETHODIMP                                                               \
00973 _elementName::CloneNode(PRBool aDeep, nsIDOMNode **aResult)                 \
00974 {                                                                           \
00975   *aResult = nsnull;                                                        \
00976                                                                             \
00977   _elementName *it = new _elementName(mNodeInfo);                           \
00978   if (!it) {                                                                \
00979     return NS_ERROR_OUT_OF_MEMORY;                                          \
00980   }                                                                         \
00981                                                                             \
00982   nsCOMPtr<nsIDOMNode> kungFuDeathGrip = NS_STATIC_CAST(_implClass*, it);   \
00983                                                                             \
00984   nsresult rv = CopyInnerTo(it, aDeep);                                     \
00985   if (NS_SUCCEEDED(rv)) {                                                   \
00986     kungFuDeathGrip.swap(*aResult);                                         \
00987   }                                                                         \
00988                                                                             \
00989   return rv;                                                                \
00990 }
00991 
00992 #define NS_IMPL_DOM_CLONENODE_WITH_INIT(_elementName)                       \
00993 NS_IMETHODIMP                                                               \
00994 _elementName::CloneNode(PRBool aDeep, nsIDOMNode **aResult)                 \
00995 {                                                                           \
00996   *aResult = nsnull;                                                        \
00997                                                                             \
00998   _elementName *it = new _elementName(mNodeInfo);                           \
00999   if (!it) {                                                                \
01000     return NS_ERROR_OUT_OF_MEMORY;                                          \
01001   }                                                                         \
01002                                                                             \
01003   nsCOMPtr<nsIDOMNode> kungFuDeathGrip(it);                                 \
01004                                                                             \
01005   nsresult rv = it->Init();                                                 \
01006                                                                             \
01007   rv |= CopyInnerTo(it, aDeep);                                             \
01008   if (NS_SUCCEEDED(rv)) {                                                   \
01009     kungFuDeathGrip.swap(*aResult);                                         \
01010   }                                                                         \
01011                                                                             \
01012   return rv;                                                                \
01013 }
01014 
01015 #endif /* nsGenericElement_h___ */