LCOV - code coverage report
Current view: directory - objdir/dist/include - nsINode.h (source / functions) Found Hit Coverage
Test: app.info Lines: 269 160 59.5 %
Date: 2012-06-02 Functions: 105 63 60.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is Mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is Mozilla.com.
      18                 :  * Portions created by the Initial Developer are Copyright (C) 2006
      19                 :  * the Initial Developer. All Rights Reserved.
      20                 :  *
      21                 :  * Contributor(s):
      22                 :  *         Boris Zbarsky <bzbarsky@mit.edu> (Original Author)
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      26                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : #ifndef nsINode_h___
      39                 : #define nsINode_h___
      40                 : 
      41                 : #include "nsIDOMEventTarget.h"
      42                 : #include "nsEvent.h"
      43                 : #include "nsPropertyTable.h"
      44                 : #include "nsTObserverArray.h"
      45                 : #include "nsINodeInfo.h"
      46                 : #include "nsCOMPtr.h"
      47                 : #include "nsWrapperCache.h"
      48                 : #include "nsIProgrammingLanguage.h" // for ::JAVASCRIPT
      49                 : #include "nsDOMError.h"
      50                 : #include "nsDOMString.h"
      51                 : #include "jspubtd.h"
      52                 : #include "nsWindowMemoryReporter.h"
      53                 : #include "nsIVariant.h"
      54                 : #include "nsGkAtoms.h"
      55                 : 
      56                 : // Including 'windows.h' will #define GetClassInfo to something else.
      57                 : #ifdef XP_WIN
      58                 : #ifdef GetClassInfo
      59                 : #undef GetClassInfo
      60                 : #endif
      61                 : #endif
      62                 : 
      63                 : class nsIContent;
      64                 : class nsIDocument;
      65                 : class nsIDOMEvent;
      66                 : class nsIDOMNode;
      67                 : class nsIDOMElement;
      68                 : class nsIDOMNodeList;
      69                 : class nsINodeList;
      70                 : class nsIPresShell;
      71                 : class nsEventChainVisitor;
      72                 : class nsEventChainPreVisitor;
      73                 : class nsEventChainPostVisitor;
      74                 : class nsEventListenerManager;
      75                 : class nsIPrincipal;
      76                 : class nsIMutationObserver;
      77                 : class nsChildContentList;
      78                 : class nsNodeWeakReference;
      79                 : class nsNodeSupportsWeakRefTearoff;
      80                 : class nsIEditor;
      81                 : class nsIDOMUserDataHandler;
      82                 : class nsAttrAndChildArray;
      83                 : class nsXPCClassInfo;
      84                 : 
      85                 : namespace mozilla {
      86                 : namespace dom {
      87                 : class Element;
      88                 : } // namespace dom
      89                 : } // namespace mozilla
      90                 : 
      91                 : enum {
      92                 :   // This bit will be set if the node has a listener manager.
      93                 :   NODE_HAS_LISTENERMANAGER =     0x00000001U,
      94                 : 
      95                 :   // Whether this node has had any properties set on it
      96                 :   NODE_HAS_PROPERTIES =          0x00000002U,
      97                 : 
      98                 :   // Whether this node is the root of an anonymous subtree.  Note that this
      99                 :   // need not be a native anonymous subtree.  Any anonymous subtree, including
     100                 :   // XBL-generated ones, will do.  This flag is set-once: once a node has it,
     101                 :   // it must not be removed.
     102                 :   // NOTE: Should only be used on nsIContent nodes
     103                 :   NODE_IS_ANONYMOUS =            0x00000004U,
     104                 : 
     105                 :   // Whether the node has some ancestor, possibly itself, that is native
     106                 :   // anonymous.  This includes ancestors crossing XBL scopes, in cases when an
     107                 :   // XBL binding is attached to an element which has a native anonymous
     108                 :   // ancestor.  This flag is set-once: once a node has it, it must not be
     109                 :   // removed.
     110                 :   // NOTE: Should only be used on nsIContent nodes
     111                 :   NODE_IS_IN_ANONYMOUS_SUBTREE = 0x00000008U,
     112                 : 
     113                 :   // Whether this node is the root of a native anonymous (from the perspective
     114                 :   // of its parent) subtree.  This flag is set-once: once a node has it, it
     115                 :   // must not be removed.
     116                 :   // NOTE: Should only be used on nsIContent nodes
     117                 :   NODE_IS_NATIVE_ANONYMOUS_ROOT = 0x00000010U,
     118                 : 
     119                 :   // Forces the XBL code to treat this node as if it were
     120                 :   // in the document and therefore should get bindings attached.
     121                 :   NODE_FORCE_XBL_BINDINGS =      0x00000020U,
     122                 : 
     123                 :   // Whether a binding manager may have a pointer to this
     124                 :   NODE_MAY_BE_IN_BINDING_MNGR =  0x00000040U,
     125                 : 
     126                 :   NODE_IS_EDITABLE =             0x00000080U,
     127                 : 
     128                 :   // For all Element nodes, NODE_MAY_HAVE_CLASS is guaranteed to be set if the
     129                 :   // node in fact has a class, but may be set even if it doesn't.
     130                 :   NODE_MAY_HAVE_CLASS =          0x00000100U,
     131                 : 
     132                 :   NODE_IS_INSERTION_PARENT =     0x00000200U,
     133                 : 
     134                 :   // Node has an :empty or :-moz-only-whitespace selector
     135                 :   NODE_HAS_EMPTY_SELECTOR =      0x00000400U,
     136                 : 
     137                 :   // A child of the node has a selector such that any insertion,
     138                 :   // removal, or appending of children requires restyling the parent.
     139                 :   NODE_HAS_SLOW_SELECTOR =       0x00000800U,
     140                 : 
     141                 :   // A child of the node has a :first-child, :-moz-first-node,
     142                 :   // :only-child, :last-child or :-moz-last-node selector.
     143                 :   NODE_HAS_EDGE_CHILD_SELECTOR = 0x00001000U,
     144                 : 
     145                 :   // A child of the node has a selector such that any insertion or
     146                 :   // removal of children requires restyling later siblings of that
     147                 :   // element.  Additionally (in this manner it is stronger than
     148                 :   // NODE_HAS_SLOW_SELECTOR), if a child's style changes due to any
     149                 :   // other content tree changes (e.g., the child changes to or from
     150                 :   // matching :empty due to a grandchild insertion or removal), the
     151                 :   // child's later siblings must also be restyled.
     152                 :   NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS
     153                 :                                = 0x00002000U,
     154                 : 
     155                 :   NODE_ALL_SELECTOR_FLAGS =      NODE_HAS_EMPTY_SELECTOR |
     156                 :                                  NODE_HAS_SLOW_SELECTOR |
     157                 :                                  NODE_HAS_EDGE_CHILD_SELECTOR |
     158                 :                                  NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS,
     159                 : 
     160                 :   NODE_ATTACH_BINDING_ON_POSTCREATE
     161                 :                                = 0x00004000U,
     162                 : 
     163                 :   // This node needs to go through frame construction to get a frame (or
     164                 :   // undisplayed entry).
     165                 :   NODE_NEEDS_FRAME =             0x00008000U,
     166                 : 
     167                 :   // At least one descendant in the flattened tree has NODE_NEEDS_FRAME set.
     168                 :   // This should be set on every node on the flattened tree path between the
     169                 :   // node(s) with NODE_NEEDS_FRAME and the root content.
     170                 :   NODE_DESCENDANTS_NEED_FRAMES = 0x00010000U,
     171                 : 
     172                 :   // Set if the node has the accesskey attribute set.
     173                 :   NODE_HAS_ACCESSKEY           = 0x00020000U,
     174                 : 
     175                 :   // Set if the node is handling a click.
     176                 :   NODE_HANDLING_CLICK          = 0x00040000U,
     177                 : 
     178                 :   // Set if the node has had :hover selectors matched against it
     179                 :   NODE_HAS_RELEVANT_HOVER_RULES = 0x00080000U,
     180                 : 
     181                 :   // Two bits for the script-type ID.  Not enough to represent all
     182                 :   // nsIProgrammingLanguage values, but we don't care.  In practice,
     183                 :   // we can represent the ones we want, and we can fail the others at
     184                 :   // runtime.
     185                 :   NODE_SCRIPT_TYPE_OFFSET =               20,
     186                 : 
     187                 :   NODE_SCRIPT_TYPE_SIZE =                  2,
     188                 : 
     189                 :   NODE_SCRIPT_TYPE_MASK =  (1 << NODE_SCRIPT_TYPE_SIZE) - 1,
     190                 : 
     191                 :   // Remaining bits are node type specific.
     192                 :   NODE_TYPE_SPECIFIC_BITS_OFFSET =
     193                 :     NODE_SCRIPT_TYPE_OFFSET + NODE_SCRIPT_TYPE_SIZE
     194                 : };
     195                 : 
     196                 : PR_STATIC_ASSERT(PRUint32(nsIProgrammingLanguage::JAVASCRIPT) <=
     197                 :                    PRUint32(NODE_SCRIPT_TYPE_MASK));
     198                 : PR_STATIC_ASSERT(PRUint32(nsIProgrammingLanguage::PYTHON) <=
     199                 :                    PRUint32(NODE_SCRIPT_TYPE_MASK));
     200                 : 
     201                 : // Useful inline function for getting a node given an nsIContent and an
     202                 : // nsIDocument.  Returns the first argument cast to nsINode if it is non-null,
     203                 : // otherwise returns the second (which may be null).  We use type variables
     204                 : // instead of nsIContent* and nsIDocument* because the actual types must be
     205                 : // known for the cast to work.
     206                 : template<class C, class D>
     207          112066 : inline nsINode* NODE_FROM(C& aContent, D& aDocument)
     208                 : {
     209          112066 :   if (aContent)
     210          110681 :     return static_cast<nsINode*>(aContent);
     211            1385 :   return static_cast<nsINode*>(aDocument);
     212                 : }
     213                 : 
     214                 : /**
     215                 :  * Class used to detect unexpected mutations. To use the class create an
     216                 :  * nsMutationGuard on the stack before unexpected mutations could occur.
     217                 :  * You can then at any time call Mutated to check if any unexpected mutations
     218                 :  * have occurred.
     219                 :  *
     220                 :  * When a guard is instantiated sMutationCount is set to 300. It is then
     221                 :  * decremented by every mutation (capped at 0). This means that we can only
     222                 :  * detect 300 mutations during the lifetime of a single guard, however that
     223                 :  * should be more then we ever care about as we usually only care if more then
     224                 :  * one mutation has occurred.
     225                 :  *
     226                 :  * When the guard goes out of scope it will adjust sMutationCount so that over
     227                 :  * the lifetime of the guard the guard itself has not affected sMutationCount,
     228                 :  * while mutations that happened while the guard was alive still will. This
     229                 :  * allows a guard to be instantiated even if there is another guard higher up
     230                 :  * on the callstack watching for mutations.
     231                 :  *
     232                 :  * The only thing that has to be avoided is for an outer guard to be used
     233                 :  * while an inner guard is alive. This can be avoided by only ever
     234                 :  * instantiating a single guard per scope and only using the guard in the
     235                 :  * current scope.
     236                 :  */
     237                 : class nsMutationGuard {
     238                 : public:
     239               0 :   nsMutationGuard()
     240                 :   {
     241               0 :     mDelta = eMaxMutations - sMutationCount;
     242               0 :     sMutationCount = eMaxMutations;
     243               0 :   }
     244               0 :   ~nsMutationGuard()
     245                 :   {
     246                 :     sMutationCount =
     247               0 :       mDelta > sMutationCount ? 0 : sMutationCount - mDelta;
     248               0 :   }
     249                 : 
     250                 :   /**
     251                 :    * Returns true if any unexpected mutations have occurred. You can pass in
     252                 :    * an 8-bit ignore count to ignore a number of expected mutations.
     253                 :    */
     254               0 :   bool Mutated(PRUint8 aIgnoreCount)
     255                 :   {
     256               0 :     return sMutationCount < static_cast<PRUint32>(eMaxMutations - aIgnoreCount);
     257                 :   }
     258                 : 
     259                 :   // This function should be called whenever a mutation that we want to keep
     260                 :   // track of happen. For now this is only done when children are added or
     261                 :   // removed, but we might do it for attribute changes too in the future.
     262          123650 :   static void DidMutate()
     263                 :   {
     264          123650 :     if (sMutationCount) {
     265               0 :       --sMutationCount;
     266                 :     }
     267          123650 :   }
     268                 : 
     269                 : private:
     270                 :   // mDelta is the amount sMutationCount was adjusted when the guard was
     271                 :   // initialized. It is needed so that we can undo that adjustment once
     272                 :   // the guard dies.
     273                 :   PRUint32 mDelta;
     274                 : 
     275                 :   // The value 300 is not important, as long as it is bigger then anything
     276                 :   // ever passed to Mutated().
     277                 :   enum { eMaxMutations = 300 };
     278                 : 
     279                 :   
     280                 :   // sMutationCount is a global mutation counter which is decreased by one at
     281                 :   // every mutation. It is capped at 0 to avoid wrapping.
     282                 :   // Its value is always between 0 and 300, inclusive.
     283                 :   static PRUint32 sMutationCount;
     284                 : };
     285                 : 
     286                 : // Categories of node properties
     287                 : // 0 is global.
     288                 : #define DOM_USER_DATA         1
     289                 : #define DOM_USER_DATA_HANDLER 2
     290                 : #define SMIL_MAPPED_ATTR_ANIMVAL 3
     291                 : 
     292                 : // IID for the nsINode interface
     293                 : #define NS_INODE_IID \
     294                 : { 0xfcd3b0d1, 0x75db, 0x46c4, \
     295                 :   { 0xa1, 0xf5, 0x07, 0xc2, 0x09, 0xf8, 0x1f, 0x44 } }
     296                 : 
     297                 : /**
     298                 :  * An internal interface that abstracts some DOMNode-related parts that both
     299                 :  * nsIContent and nsIDocument share.  An instance of this interface has a list
     300                 :  * of nsIContent children and provides access to them.
     301                 :  */
     302                 : class nsINode : public nsIDOMEventTarget,
     303                 :                 public nsWrapperCache
     304                 : {
     305                 : public:
     306                 :   NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODE_IID)
     307                 : 
     308                 :   // Among the sub-classes that inherit (directly or indirectly) from nsINode,
     309                 :   // measurement of the following members may be added later if DMD finds it is
     310                 :   // worthwhile:
     311                 :   // - nsGenericHTMLElement:  mForm, mFieldSet
     312                 :   // - nsGenericHTMLFrameElement: mFrameLoader (bug 672539), mTitleChangedListener
     313                 :   // - nsHTMLBodyElement:     mContentStyleRule
     314                 :   // - nsHTMLDataListElement: mOptions
     315                 :   // - nsHTMLFieldSetElement: mElements, mDependentElements, mFirstLegend
     316                 :   // - nsHTMLFormElement:     many!
     317                 :   // - nsHTMLFrameSetElement: mRowSpecs, mColSpecs
     318                 :   // - nsHTMLInputElement:    mInputData, mFiles, mFileList, mStaticDocfileList
     319                 :   // - nsHTMLMapElement:      mAreas
     320                 :   // - nsHTMLMediaElement:    many!
     321                 :   // - nsHTMLOutputElement:   mDefaultValue, mTokenList
     322                 :   // - nsHTMLRowElement:      mCells
     323                 :   // - nsHTMLSelectElement:   mOptions, mRestoreState
     324                 :   // - nsHTMLTableElement:    mTBodies, mRows, mTableInheritedAttributes
     325                 :   // - nsHTMLTableSectionElement: mRows
     326                 :   // - nsHTMLTextAreaElement: mControllers, mState
     327                 :   //
     328                 :   // The following members don't need to be measured:
     329                 :   // - nsIContent: mPrimaryFrame, because it's non-owning and measured elsewhere
     330                 :   //
     331                 :   NS_DECL_SIZEOF_EXCLUDING_THIS
     332                 : 
     333                 :   // SizeOfIncludingThis doesn't need to be overridden by sub-classes because
     334                 :   // sub-classes of nsINode are guaranteed to be laid out in memory in such a
     335                 :   // way that |this| points to the start of the allocated object, even in
     336                 :   // methods of nsINode's sub-classes, and so |aMallocSizeOf(this)| is always
     337                 :   // safe to call no matter which object it was invoked on.
     338               0 :   virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
     339               0 :     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
     340                 :   }
     341                 : 
     342                 :   friend class nsNodeUtils;
     343                 :   friend class nsNodeWeakReference;
     344                 :   friend class nsNodeSupportsWeakRefTearoff;
     345                 :   friend class nsAttrAndChildArray;
     346                 : 
     347                 : #ifdef MOZILLA_INTERNAL_API
     348          115287 :   nsINode(already_AddRefed<nsINodeInfo> aNodeInfo)
     349                 :   : mNodeInfo(aNodeInfo),
     350                 :     mParent(nsnull),
     351                 :     mFlags(0),
     352                 :     mBoolFlags(0),
     353                 :     mNextSibling(nsnull),
     354                 :     mPreviousSibling(nsnull),
     355                 :     mFirstChild(nsnull),
     356          115287 :     mSlots(nsnull)
     357                 :   {
     358          115287 :   }
     359                 : 
     360                 : #endif
     361                 : 
     362                 :   virtual ~nsINode();
     363                 : 
     364                 :   /**
     365                 :    * Bit-flags to pass (or'ed together) to IsNodeOfType()
     366                 :    */
     367                 :   enum {
     368                 :     /** nsIContent nodes */
     369                 :     eCONTENT             = 1 << 0,
     370                 :     /** nsIDocument nodes */
     371                 :     eDOCUMENT            = 1 << 1,
     372                 :     /** nsIAttribute nodes */
     373                 :     eATTRIBUTE           = 1 << 2,
     374                 :     /** text nodes */
     375                 :     eTEXT                = 1 << 3,
     376                 :     /** xml processing instructions */
     377                 :     ePROCESSING_INSTRUCTION = 1 << 4,
     378                 :     /** comment nodes */
     379                 :     eCOMMENT             = 1 << 5,
     380                 :     /** form control elements */
     381                 :     eHTML_FORM_CONTROL   = 1 << 6,
     382                 :     /** document fragments */
     383                 :     eDOCUMENT_FRAGMENT   = 1 << 7,
     384                 :     /** data nodes (comments, PIs, text). Nodes of this type always
     385                 :      returns a non-null value for nsIContent::GetText() */
     386                 :     eDATA_NODE           = 1 << 8,
     387                 :     /** nsHTMLMediaElement */
     388                 :     eMEDIA               = 1 << 9,
     389                 :     /** animation elements */
     390                 :     eANIMATION           = 1 << 10
     391                 :   };
     392                 : 
     393                 :   /**
     394                 :    * API for doing a quick check if a content is of a given
     395                 :    * type, such as Text, Document, Comment ...  Use this when you can instead of
     396                 :    * checking the tag.
     397                 :    *
     398                 :    * @param aFlags what types you want to test for (see above)
     399                 :    * @return whether the content matches ALL flags passed in
     400                 :    */
     401                 :   virtual bool IsNodeOfType(PRUint32 aFlags) const = 0;
     402                 : 
     403                 :   /**
     404                 :    * Return whether the node is an Element node
     405                 :    */
     406         1211891 :   bool IsElement() const {
     407         1211891 :     return GetBoolFlag(NodeIsElement);
     408                 :   }
     409                 : 
     410                 :   /**
     411                 :    * Return this node as an Element.  Should only be used for nodes
     412                 :    * for which IsElement() is true.
     413                 :    */
     414                 :   mozilla::dom::Element* AsElement();
     415                 : 
     416                 :   /**
     417                 :    * Return if this node has any children.
     418                 :    */
     419               0 :   bool HasChildren() const { return !!mFirstChild; }
     420                 : 
     421                 :   /**
     422                 :    * Get the number of children
     423                 :    * @return the number of children
     424                 :    */
     425                 :   virtual PRUint32 GetChildCount() const = 0;
     426                 : 
     427                 :   /**
     428                 :    * Get a child by index
     429                 :    * @param aIndex the index of the child to get
     430                 :    * @return the child, or null if index out of bounds
     431                 :    */
     432                 :   virtual nsIContent* GetChildAt(PRUint32 aIndex) const = 0;
     433                 : 
     434                 :   /**
     435                 :    * Get a raw pointer to the child array.  This should only be used if you
     436                 :    * plan to walk a bunch of the kids, promise to make sure that nothing ever
     437                 :    * mutates (no attribute changes, not DOM tree changes, no script execution,
     438                 :    * NOTHING), and will never ever peform an out-of-bounds access here.  This
     439                 :    * method may return null if there are no children, or it may return a
     440                 :    * garbage pointer.  In all cases the out param will be set to the number of
     441                 :    * children.
     442                 :    */
     443                 :   virtual nsIContent * const * GetChildArray(PRUint32* aChildCount) const = 0;
     444                 : 
     445                 :   /**
     446                 :    * Get the index of a child within this content
     447                 :    * @param aPossibleChild the child to get the index of.
     448                 :    * @return the index of the child, or -1 if not a child
     449                 :    *
     450                 :    * If the return value is not -1, then calling GetChildAt() with that value
     451                 :    * will return aPossibleChild.
     452                 :    */
     453                 :   virtual PRInt32 IndexOf(nsINode* aPossibleChild) const = 0;
     454                 : 
     455                 :   /**
     456                 :    * Return the "owner document" of this node.  Note that this is not the same
     457                 :    * as the DOM ownerDocument -- that's null for Document nodes, whereas for a
     458                 :    * nsIDocument GetOwnerDocument returns the document itself.  For nsIContent
     459                 :    * implementations the two are the same.
     460                 :    */
     461         1296967 :   nsIDocument *OwnerDoc() const
     462                 :   {
     463         1296967 :     return mNodeInfo->GetDocument();
     464                 :   }
     465                 : 
     466                 :   /**
     467                 :    * Returns true if the content has an ancestor that is a document.
     468                 :    *
     469                 :    * @return whether this content is in a document tree
     470                 :    */
     471         1718600 :   bool IsInDoc() const
     472                 :   {
     473         1718600 :     return GetBoolFlag(IsInDocument);
     474                 :   }
     475                 : 
     476                 :   /**
     477                 :    * Get the document that this content is currently in, if any. This will be
     478                 :    * null if the content has no ancestor that is a document.
     479                 :    *
     480                 :    * @return the current document
     481                 :    */
     482         1525620 :   nsIDocument *GetCurrentDoc() const
     483                 :   {
     484         1525620 :     return IsInDoc() ? OwnerDoc() : nsnull;
     485                 :   }
     486                 : 
     487                 :   /**
     488                 :    * The values returned by this function are the ones defined for
     489                 :    * nsIDOMNode.nodeType
     490                 :    */
     491          937168 :   PRUint16 NodeType() const
     492                 :   {
     493          937168 :     return mNodeInfo->NodeType();
     494                 :   }
     495            5894 :   const nsString& NodeName() const
     496                 :   {
     497            5894 :     return mNodeInfo->NodeName();
     498                 :   }
     499            8748 :   const nsString& LocalName() const
     500                 :   {
     501            8748 :     return mNodeInfo->LocalName();
     502                 :   }
     503                 : 
     504                 :   nsINode*
     505             404 :   InsertBefore(nsINode *aNewChild, nsINode *aRefChild, nsresult *aReturn)
     506                 :   {
     507             404 :     return ReplaceOrInsertBefore(false, aNewChild, aRefChild, aReturn);
     508                 :   }
     509                 :   nsINode*
     510               0 :   ReplaceChild(nsINode *aNewChild, nsINode *aOldChild, nsresult *aReturn)
     511                 :   {
     512               0 :     return ReplaceOrInsertBefore(true, aNewChild, aOldChild, aReturn);
     513                 :   }
     514                 :   nsINode*
     515             400 :   AppendChild(nsINode *aNewChild, nsresult *aReturn)
     516                 :   {
     517             400 :     return InsertBefore(aNewChild, nsnull, aReturn);
     518                 :   }
     519                 :   nsresult RemoveChild(nsINode *aOldChild);
     520                 : 
     521                 :   /**
     522                 :    * Insert a content node at a particular index.  This method handles calling
     523                 :    * BindToTree on the child appropriately.
     524                 :    *
     525                 :    * @param aKid the content to insert
     526                 :    * @param aIndex the index it is being inserted at (the index it will have
     527                 :    *        after it is inserted)
     528                 :    * @param aNotify whether to notify the document (current document for
     529                 :    *        nsIContent, and |this| for nsIDocument) that the insert has
     530                 :    *        occurred
     531                 :    *
     532                 :    * @throws NS_ERROR_DOM_HIERARCHY_REQUEST_ERR if one attempts to have more
     533                 :    * than one element node as a child of a document.  Doing this will also
     534                 :    * assert -- you shouldn't be doing it!  Check with
     535                 :    * nsIDocument::GetRootElement() first if you're not sure.  Apart from this
     536                 :    * one constraint, this doesn't do any checking on whether aKid is a valid
     537                 :    * child of |this|.
     538                 :    *
     539                 :    * @throws NS_ERROR_OUT_OF_MEMORY in some cases (from BindToTree).
     540                 :    */
     541                 :   virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
     542                 :                                  bool aNotify) = 0;
     543                 : 
     544                 :   /**
     545                 :    * Append a content node to the end of the child list.  This method handles
     546                 :    * calling BindToTree on the child appropriately.
     547                 :    *
     548                 :    * @param aKid the content to append
     549                 :    * @param aNotify whether to notify the document (current document for
     550                 :    *        nsIContent, and |this| for nsIDocument) that the append has
     551                 :    *        occurred
     552                 :    *
     553                 :    * @throws NS_ERROR_DOM_HIERARCHY_REQUEST_ERR if one attempts to have more
     554                 :    * than one element node as a child of a document.  Doing this will also
     555                 :    * assert -- you shouldn't be doing it!  Check with
     556                 :    * nsIDocument::GetRootElement() first if you're not sure.  Apart from this
     557                 :    * one constraint, this doesn't do any checking on whether aKid is a valid
     558                 :    * child of |this|.
     559                 :    *
     560                 :    * @throws NS_ERROR_OUT_OF_MEMORY in some cases (from BindToTree).
     561                 :    */
     562          111536 :   nsresult AppendChildTo(nsIContent* aKid, bool aNotify)
     563                 :   {
     564          111536 :     return InsertChildAt(aKid, GetChildCount(), aNotify);
     565                 :   }
     566                 :   
     567                 :   /**
     568                 :    * Remove a child from this node.  This method handles calling UnbindFromTree
     569                 :    * on the child appropriately.
     570                 :    *
     571                 :    * @param aIndex the index of the child to remove
     572                 :    * @param aNotify whether to notify the document (current document for
     573                 :    *        nsIContent, and |this| for nsIDocument) that the remove has
     574                 :    *        occurred
     575                 :    * @param aMutationEvent whether to fire a mutation event
     576                 :    *
     577                 :    * Note: If there is no child at aIndex, this method will simply do nothing.
     578                 :    */
     579                 :   virtual nsresult RemoveChildAt(PRUint32 aIndex, 
     580                 :                                  bool aNotify) = 0;
     581                 : 
     582                 :   /**
     583                 :    * Get a property associated with this node.
     584                 :    *
     585                 :    * @param aPropertyName  name of property to get.
     586                 :    * @param aStatus        out parameter for storing resulting status.
     587                 :    *                       Set to NS_PROPTABLE_PROP_NOT_THERE if the property
     588                 :    *                       is not set.
     589                 :    * @return               the property. Null if the property is not set
     590                 :    *                       (though a null return value does not imply the
     591                 :    *                       property was not set, i.e. it can be set to null).
     592                 :    */
     593               0 :   void* GetProperty(nsIAtom *aPropertyName,
     594                 :                     nsresult *aStatus = nsnull) const
     595                 :   {
     596               0 :     return GetProperty(0, aPropertyName, aStatus);
     597                 :   }
     598                 : 
     599                 :   /**
     600                 :    * Get a property associated with this node.
     601                 :    *
     602                 :    * @param aCategory      category of property to get.
     603                 :    * @param aPropertyName  name of property to get.
     604                 :    * @param aStatus        out parameter for storing resulting status.
     605                 :    *                       Set to NS_PROPTABLE_PROP_NOT_THERE if the property
     606                 :    *                       is not set.
     607                 :    * @return               the property. Null if the property is not set
     608                 :    *                       (though a null return value does not imply the
     609                 :    *                       property was not set, i.e. it can be set to null).
     610                 :    */
     611                 :   virtual void* GetProperty(PRUint16 aCategory,
     612                 :                             nsIAtom *aPropertyName,
     613                 :                             nsresult *aStatus = nsnull) const;
     614                 : 
     615                 :   /**
     616                 :    * Set a property to be associated with this node. This will overwrite an
     617                 :    * existing value if one exists. The existing value is destroyed using the
     618                 :    * destructor function given when that value was set.
     619                 :    *
     620                 :    * @param aPropertyName  name of property to set.
     621                 :    * @param aValue         new value of property.
     622                 :    * @param aDtor          destructor function to be used when this property
     623                 :    *                       is destroyed.
     624                 :    * @param aTransfer      if true the property will not be deleted when the
     625                 :    *                       ownerDocument of the node changes, if false it
     626                 :    *                       will be deleted.
     627                 :    *
     628                 :    * @return NS_PROPTABLE_PROP_OVERWRITTEN (success value) if the property
     629                 :    *                                       was already set
     630                 :    * @throws NS_ERROR_OUT_OF_MEMORY if that occurs
     631                 :    */
     632               0 :   nsresult SetProperty(nsIAtom *aPropertyName,
     633                 :                        void *aValue,
     634                 :                        NSPropertyDtorFunc aDtor = nsnull,
     635                 :                        bool aTransfer = false)
     636                 :   {
     637               0 :     return SetProperty(0, aPropertyName, aValue, aDtor, aTransfer);
     638                 :   }
     639                 : 
     640                 :   /**
     641                 :    * Set a property to be associated with this node. This will overwrite an
     642                 :    * existing value if one exists. The existing value is destroyed using the
     643                 :    * destructor function given when that value was set.
     644                 :    *
     645                 :    * @param aCategory       category of property to set.
     646                 :    * @param aPropertyName   name of property to set.
     647                 :    * @param aValue          new value of property.
     648                 :    * @param aDtor           destructor function to be used when this property
     649                 :    *                        is destroyed.
     650                 :    * @param aTransfer       if true the property will not be deleted when the
     651                 :    *                        ownerDocument of the node changes, if false it
     652                 :    *                        will be deleted.
     653                 :    * @param aOldValue [out] previous value of property.
     654                 :    *
     655                 :    * @return NS_PROPTABLE_PROP_OVERWRITTEN (success value) if the property
     656                 :    *                                       was already set
     657                 :    * @throws NS_ERROR_OUT_OF_MEMORY if that occurs
     658                 :    */
     659                 :   virtual nsresult SetProperty(PRUint16 aCategory,
     660                 :                                nsIAtom *aPropertyName,
     661                 :                                void *aValue,
     662                 :                                NSPropertyDtorFunc aDtor = nsnull,
     663                 :                                bool aTransfer = false,
     664                 :                                void **aOldValue = nsnull);
     665                 : 
     666                 :   /**
     667                 :    * Destroys a property associated with this node. The value is destroyed
     668                 :    * using the destruction function given when that value was set.
     669                 :    *
     670                 :    * @param aPropertyName  name of property to destroy.
     671                 :    */
     672               0 :   void DeleteProperty(nsIAtom *aPropertyName)
     673                 :   {
     674               0 :     DeleteProperty(0, aPropertyName);
     675               0 :   }
     676                 : 
     677                 :   /**
     678                 :    * Destroys a property associated with this node. The value is destroyed
     679                 :    * using the destruction function given when that value was set.
     680                 :    *
     681                 :    * @param aCategory      category of property to destroy.
     682                 :    * @param aPropertyName  name of property to destroy.
     683                 :    */
     684                 :   virtual void DeleteProperty(PRUint16 aCategory, nsIAtom *aPropertyName);
     685                 : 
     686                 :   /**
     687                 :    * Unset a property associated with this node. The value will not be
     688                 :    * destroyed but rather returned. It is the caller's responsibility to
     689                 :    * destroy the value after that point.
     690                 :    *
     691                 :    * @param aPropertyName  name of property to unset.
     692                 :    * @param aStatus        out parameter for storing resulting status.
     693                 :    *                       Set to NS_PROPTABLE_PROP_NOT_THERE if the property
     694                 :    *                       is not set.
     695                 :    * @return               the property. Null if the property is not set
     696                 :    *                       (though a null return value does not imply the
     697                 :    *                       property was not set, i.e. it can be set to null).
     698                 :    */
     699               0 :   void* UnsetProperty(nsIAtom  *aPropertyName,
     700                 :                       nsresult *aStatus = nsnull)
     701                 :   {
     702               0 :     return UnsetProperty(0, aPropertyName, aStatus);
     703                 :   }
     704                 : 
     705                 :   /**
     706                 :    * Unset a property associated with this node. The value will not be
     707                 :    * destroyed but rather returned. It is the caller's responsibility to
     708                 :    * destroy the value after that point.
     709                 :    *
     710                 :    * @param aCategory      category of property to unset.
     711                 :    * @param aPropertyName  name of property to unset.
     712                 :    * @param aStatus        out parameter for storing resulting status.
     713                 :    *                       Set to NS_PROPTABLE_PROP_NOT_THERE if the property
     714                 :    *                       is not set.
     715                 :    * @return               the property. Null if the property is not set
     716                 :    *                       (though a null return value does not imply the
     717                 :    *                       property was not set, i.e. it can be set to null).
     718                 :    */
     719                 :   virtual void* UnsetProperty(PRUint16 aCategory,
     720                 :                               nsIAtom *aPropertyName,
     721                 :                               nsresult *aStatus = nsnull);
     722                 :   
     723          511895 :   bool HasProperties() const
     724                 :   {
     725          511895 :     return HasFlag(NODE_HAS_PROPERTIES);
     726                 :   }
     727                 : 
     728                 :   /**
     729                 :    * Return the principal of this node.  This is guaranteed to never be a null
     730                 :    * pointer.
     731                 :    */
     732            1383 :   nsIPrincipal* NodePrincipal() const {
     733            1383 :     return mNodeInfo->NodeInfoManager()->DocumentPrincipal();
     734                 :   }
     735                 : 
     736                 :   /**
     737                 :    * Get the parent nsIContent for this node.
     738                 :    * @return the parent, or null if no parent or the parent is not an nsIContent
     739                 :    */
     740          878481 :   nsIContent* GetParent() const {
     741          878481 :     return NS_LIKELY(GetBoolFlag(ParentIsContent)) ?
     742          878481 :       reinterpret_cast<nsIContent*>(mParent) : nsnull;
     743                 :   }
     744                 : 
     745                 :   /**
     746                 :    * Get the parent nsINode for this node. This can be either an nsIContent,
     747                 :    * an nsIDocument or an nsIAttribute.
     748                 :    * @return the parent node
     749                 :    */
     750         2769180 :   nsINode* GetNodeParent() const
     751                 :   {
     752         2769180 :     return mParent;
     753                 :   }
     754                 :   
     755                 :   /**
     756                 :    * Get the parent nsINode for this node if it is an Element.
     757                 :    * @return the parent node
     758                 :    */
     759               0 :   nsINode* GetElementParent() const
     760                 :   {
     761               0 :     return mParent && mParent->IsElement() ? mParent : nsnull;
     762                 :   }
     763                 : 
     764                 :   /**
     765                 :    * See nsIDOMEventTarget
     766                 :    */
     767                 :   NS_DECL_NSIDOMEVENTTARGET
     768                 :   using nsIDOMEventTarget::AddEventListener;
     769                 :   using nsIDOMEventTarget::AddSystemEventListener;
     770                 : 
     771                 :   /**
     772                 :    * Adds a mutation observer to be notified when this node, or any of its
     773                 :    * descendants, are modified. The node will hold a weak reference to the
     774                 :    * observer, which means that it is the responsibility of the observer to
     775                 :    * remove itself in case it dies before the node.  If an observer is added
     776                 :    * while observers are being notified, it may also be notified.  In general,
     777                 :    * adding observers while inside a notification is not a good idea.  An
     778                 :    * observer that is already observing the node must not be added without
     779                 :    * being removed first.
     780                 :    */
     781            5347 :   void AddMutationObserver(nsIMutationObserver* aMutationObserver)
     782                 :   {
     783            5347 :     nsSlots* s = GetSlots();
     784            5347 :     if (s) {
     785            5347 :       NS_ASSERTION(s->mMutationObservers.IndexOf(aMutationObserver) ==
     786                 :                    nsTArray<int>::NoIndex,
     787                 :                    "Observer already in the list");
     788            5347 :       s->mMutationObservers.AppendElement(aMutationObserver);
     789                 :     }
     790            5347 :   }
     791                 : 
     792                 :   /**
     793                 :    * Same as above, but only adds the observer if its not observing
     794                 :    * the node already.
     795                 :    */
     796               0 :   void AddMutationObserverUnlessExists(nsIMutationObserver* aMutationObserver)
     797                 :   {
     798               0 :     nsSlots* s = GetSlots();
     799               0 :     if (s) {
     800               0 :       s->mMutationObservers.AppendElementUnlessExists(aMutationObserver);
     801                 :     }
     802               0 :   }
     803                 : 
     804                 :   /**
     805                 :    * Removes a mutation observer.
     806                 :    */
     807            6426 :   void RemoveMutationObserver(nsIMutationObserver* aMutationObserver)
     808                 :   {
     809            6426 :     nsSlots* s = GetExistingSlots();
     810            6426 :     if (s) {
     811            6426 :       s->mMutationObservers.RemoveElement(aMutationObserver);
     812                 :     }
     813            6426 :   }
     814                 : 
     815                 :   /**
     816                 :    * Clones this node. This needs to be overriden by all node classes. aNodeInfo
     817                 :    * should be identical to this node's nodeInfo, except for the document which
     818                 :    * may be different. When cloning an element, all attributes of the element
     819                 :    * will be cloned. The children of the node will not be cloned.
     820                 :    *
     821                 :    * @param aNodeInfo the nodeinfo to use for the clone
     822                 :    * @param aResult the clone
     823                 :    */
     824                 :   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const = 0;
     825                 : 
     826                 :   /**
     827                 :    * Checks if a node has the same ownerDocument as this one. Note that this
     828                 :    * actually compares nodeinfo managers because nodes always have one, even
     829                 :    * when they don't have an ownerDocument. If this function returns true
     830                 :    * it doesn't mean that the nodes actually have an ownerDocument.
     831                 :    *
     832                 :    * @param aOther Other node to check
     833                 :    * @return Whether the owner documents of this node and of aOther are the
     834                 :    *         same.
     835                 :    */
     836          225404 :   bool HasSameOwnerDoc(nsINode *aOther)
     837                 :   {
     838                 :     // We compare nodeinfo managers because nodes always have one, even when
     839                 :     // they don't have an ownerDocument.
     840          225404 :     return mNodeInfo->NodeInfoManager() == aOther->mNodeInfo->NodeInfoManager();
     841                 :   }
     842                 : 
     843                 :   // This class can be extended by subclasses that wish to store more
     844                 :   // information in the slots.
     845                 :   class nsSlots
     846                 :   {
     847                 :   public:
     848            4611 :     nsSlots()
     849                 :       : mChildNodes(nsnull),
     850            4611 :         mWeakReference(nsnull)
     851                 :     {
     852            4611 :     }
     853                 : 
     854                 :     // If needed we could remove the vtable pointer this dtor causes by
     855                 :     // putting a DestroySlots function on nsINode
     856                 :     virtual ~nsSlots();
     857                 : 
     858                 :     void Traverse(nsCycleCollectionTraversalCallback &cb);
     859                 :     void Unlink();
     860                 : 
     861                 :     /**
     862                 :      * A list of mutation observers
     863                 :      */
     864                 :     nsTObserverArray<nsIMutationObserver*> mMutationObservers;
     865                 : 
     866                 :     /**
     867                 :      * An object implementing nsIDOMNodeList for this content (childNodes)
     868                 :      * @see nsIDOMNodeList
     869                 :      * @see nsGenericHTMLElement::GetChildNodes
     870                 :      *
     871                 :      * MSVC 7 doesn't like this as an nsRefPtr
     872                 :      */
     873                 :     nsChildContentList* mChildNodes;
     874                 : 
     875                 :     /**
     876                 :      * Weak reference to this node
     877                 :      */
     878                 :     nsNodeWeakReference* mWeakReference;
     879                 :   };
     880                 : 
     881                 :   /**
     882                 :    * Functions for managing flags and slots
     883                 :    */
     884                 : #ifdef DEBUG
     885               0 :   nsSlots* DebugGetSlots()
     886                 :   {
     887               0 :     return GetSlots();
     888                 :   }
     889                 : #endif
     890                 : 
     891         2687653 :   bool HasFlag(PtrBits aFlag) const
     892                 :   {
     893         2687653 :     return !!(GetFlags() & aFlag);
     894                 :   }
     895                 : 
     896         2687653 :   PRUint32 GetFlags() const
     897                 :   {
     898         2687653 :     return mFlags;
     899                 :   }
     900                 : 
     901           38038 :   void SetFlags(PRUint32 aFlagsToSet)
     902                 :   {
     903           38038 :     NS_ASSERTION(!(aFlagsToSet & (NODE_IS_ANONYMOUS |
     904                 :                                   NODE_IS_NATIVE_ANONYMOUS_ROOT |
     905                 :                                   NODE_IS_IN_ANONYMOUS_SUBTREE |
     906                 :                                   NODE_ATTACH_BINDING_ON_POSTCREATE |
     907                 :                                   NODE_DESCENDANTS_NEED_FRAMES |
     908                 :                                   NODE_NEEDS_FRAME)) ||
     909                 :                  IsNodeOfType(eCONTENT),
     910                 :                  "Flag only permitted on nsIContent nodes");
     911           38038 :     mFlags |= aFlagsToSet;
     912           38038 :   }
     913                 : 
     914          708221 :   void UnsetFlags(PRUint32 aFlagsToUnset)
     915                 :   {
     916          708221 :     NS_ASSERTION(!(aFlagsToUnset &
     917                 :                    (NODE_IS_ANONYMOUS |
     918                 :                     NODE_IS_IN_ANONYMOUS_SUBTREE |
     919                 :                     NODE_IS_NATIVE_ANONYMOUS_ROOT)),
     920                 :                  "Trying to unset write-only flags");
     921          708221 :     mFlags &= ~aFlagsToUnset;
     922          708221 :   }
     923                 : 
     924          112044 :   void SetEditableFlag(bool aEditable)
     925                 :   {
     926          112044 :     if (aEditable) {
     927               1 :       SetFlags(NODE_IS_EDITABLE);
     928                 :     }
     929                 :     else {
     930          112043 :       UnsetFlags(NODE_IS_EDITABLE);
     931                 :     }
     932          112044 :   }
     933                 : 
     934           49496 :   bool IsEditable() const
     935                 :   {
     936                 : #ifdef _IMPL_NS_LAYOUT
     937           49496 :     return IsEditableInternal();
     938                 : #else
     939               0 :     return IsEditableExternal();
     940                 : #endif
     941                 :   }
     942                 : 
     943                 :   /**
     944                 :    * Returns true if |this| or any of its ancestors is native anonymous.
     945                 :    */
     946           57871 :   bool IsInNativeAnonymousSubtree() const
     947                 :   {
     948                 : #ifdef DEBUG
     949           57871 :     if (HasFlag(NODE_IS_IN_ANONYMOUS_SUBTREE)) {
     950               0 :       return true;
     951                 :     }
     952           57871 :     CheckNotNativeAnonymous();
     953           57871 :     return false;
     954                 : #else
     955                 :     return HasFlag(NODE_IS_IN_ANONYMOUS_SUBTREE);
     956                 : #endif
     957                 :   }
     958                 : 
     959                 :   /**
     960                 :    * Returns true if |this| node is the common ancestor of the start/end
     961                 :    * nodes of a Range in a Selection or a descendant of such a common ancestor.
     962                 :    * This node is definitely not selected when |false| is returned, but it may
     963                 :    * or may not be selected when |true| is returned.
     964                 :    */
     965              18 :   bool IsSelectionDescendant() const
     966                 :   {
     967              18 :     return IsDescendantOfCommonAncestorForRangeInSelection() ||
     968              18 :            IsCommonAncestorForRangeInSelection();
     969                 :   }
     970                 : 
     971                 :   /**
     972                 :    * Get the root content of an editor. So, this node must be a descendant of
     973                 :    * an editor. Note that this should be only used for getting input or textarea
     974                 :    * editor's root content. This method doesn't support HTML editors.
     975                 :    */
     976                 :   nsIContent* GetTextEditorRootContent(nsIEditor** aEditor = nsnull);
     977                 : 
     978                 :   /**
     979                 :    * Get the nearest selection root, ie. the node that will be selected if the
     980                 :    * user does "Select All" while the focus is in this node. Note that if this
     981                 :    * node is not in an editor, the result comes from the nsFrameSelection that
     982                 :    * is related to aPresShell, so the result might not be the ancestor of this
     983                 :    * node. Be aware that if this node and the computed selection limiter are
     984                 :    * not in same subtree, this returns the root content of the closeset subtree.
     985                 :    */
     986                 :   nsIContent* GetSelectionRootContent(nsIPresShell* aPresShell);
     987                 : 
     988                 :   virtual nsINodeList* GetChildNodesList();
     989          491565 :   nsIContent* GetFirstChild() const { return mFirstChild; }
     990             359 :   nsIContent* GetLastChild() const
     991                 :   {
     992                 :     PRUint32 count;
     993             359 :     nsIContent* const* children = GetChildArray(&count);
     994                 : 
     995             359 :     return count > 0 ? children[count - 1] : nsnull;
     996                 :   }
     997                 : 
     998                 :   /**
     999                 :    * Implementation is in nsIDocument.h, because it needs to cast from
    1000                 :    * nsIDocument* to nsINode*.
    1001                 :    */
    1002                 :   nsIDocument* GetOwnerDocument() const;
    1003                 : 
    1004                 :   /**
    1005                 :    * The default script type (language) ID for this node.
    1006                 :    * All nodes must support fetching the default script language.
    1007                 :    */
    1008               0 :   virtual PRUint32 GetScriptTypeID() const
    1009               0 :   { return nsIProgrammingLanguage::JAVASCRIPT; }
    1010                 : 
    1011                 :   /**
    1012                 :    * Not all nodes support setting a new default language.
    1013                 :    */
    1014               0 :   NS_IMETHOD SetScriptTypeID(PRUint32 aLang)
    1015                 :   {
    1016               0 :     NS_NOTREACHED("SetScriptTypeID not implemented");
    1017               0 :     return NS_ERROR_NOT_IMPLEMENTED;
    1018                 :   }
    1019                 : 
    1020                 :   nsresult Normalize();
    1021                 : 
    1022                 :   /**
    1023                 :    * Get the base URI for any relative URIs within this piece of
    1024                 :    * content. Generally, this is the document's base URI, but certain
    1025                 :    * content carries a local base for backward compatibility, and XML
    1026                 :    * supports setting a per-node base URI.
    1027                 :    *
    1028                 :    * @return the base URI
    1029                 :    */
    1030                 :   virtual already_AddRefed<nsIURI> GetBaseURI() const = 0;
    1031                 : 
    1032                 :   /**
    1033                 :    * Facility for explicitly setting a base URI on a node.
    1034                 :    */
    1035                 :   nsresult SetExplicitBaseURI(nsIURI* aURI);
    1036                 :   /**
    1037                 :    * The explicit base URI, if set, otherwise null
    1038                 :    */
    1039                 : protected:
    1040               0 :   nsIURI* GetExplicitBaseURI() const {
    1041               0 :     if (HasExplicitBaseURI()) {
    1042               0 :       return static_cast<nsIURI*>(GetProperty(nsGkAtoms::baseURIProperty));
    1043                 :     }
    1044               0 :     return nsnull;
    1045                 :   }
    1046                 :   
    1047                 : public:
    1048                 :   nsresult GetDOMBaseURI(nsAString &aURI) const;
    1049                 : 
    1050                 :   // Note! This function must never fail. It only return an nsresult so that
    1051                 :   // we can use it to implement nsIDOMNode
    1052               0 :   NS_IMETHOD GetTextContent(nsAString &aTextContent)
    1053                 :   {
    1054               0 :     SetDOMStringToNull(aTextContent);
    1055               0 :     return NS_OK;
    1056                 :   }
    1057               0 :   NS_IMETHOD SetTextContent(const nsAString& aTextContent)
    1058                 :   {
    1059               0 :     return NS_OK;
    1060                 :   }
    1061                 : 
    1062                 :   /**
    1063                 :    * Associate an object aData to aKey on this node. If aData is null any
    1064                 :    * previously registered object and UserDataHandler associated to aKey on
    1065                 :    * this node will be removed.
    1066                 :    * Should only be used to implement the DOM Level 3 UserData API.
    1067                 :    *
    1068                 :    * @param aKey the key to associate the object to
    1069                 :    * @param aData the object to associate to aKey on this node (may be null)
    1070                 :    * @param aHandler the UserDataHandler to call when the node is
    1071                 :    *                 cloned/deleted/imported/renamed (may be null)
    1072                 :    * @param aResult [out] the previously registered object for aKey on this
    1073                 :    *                      node, if any
    1074                 :    * @return whether adding the object and UserDataHandler succeeded
    1075                 :    */
    1076                 :   nsresult SetUserData(const nsAString& aKey, nsIVariant* aData,
    1077                 :                        nsIDOMUserDataHandler* aHandler, nsIVariant** aResult);
    1078                 : 
    1079                 :   /**
    1080                 :    * Get the UserData object registered for a Key on this node, if any.
    1081                 :    * Should only be used to implement the DOM Level 3 UserData API.
    1082                 :    *
    1083                 :    * @param aKey the key to get UserData for
    1084                 :    * @return aResult the previously registered object for aKey on this node, if
    1085                 :    *                 any
    1086                 :    */
    1087               0 :   nsIVariant* GetUserData(const nsAString& aKey)
    1088                 :   {
    1089               0 :     nsCOMPtr<nsIAtom> key = do_GetAtom(aKey);
    1090               0 :     if (!key) {
    1091               0 :       return nsnull;
    1092                 :     }
    1093                 : 
    1094               0 :     return static_cast<nsIVariant*>(GetProperty(DOM_USER_DATA, key));
    1095                 :   }
    1096                 : 
    1097               0 :   nsresult GetUserData(const nsAString& aKey, nsIVariant** aResult)
    1098                 :   {
    1099               0 :     NS_IF_ADDREF(*aResult = GetUserData(aKey));
    1100                 :   
    1101               0 :     return NS_OK;
    1102                 :   }
    1103                 : 
    1104                 : 
    1105                 :   /**
    1106                 :    * Compares the document position of a node to this node.
    1107                 :    *
    1108                 :    * @param aOtherNode The node whose position is being compared to this node
    1109                 :    *
    1110                 :    * @return  The document position flags of the nodes. aOtherNode is compared
    1111                 :    *          to this node, i.e. if aOtherNode is before this node then
    1112                 :    *          DOCUMENT_POSITION_PRECEDING will be set.
    1113                 :    *
    1114                 :    * @see nsIDOMNode
    1115                 :    */
    1116                 :   PRUint16 CompareDocPosition(nsINode* aOtherNode);
    1117               0 :   nsresult CompareDocPosition(nsINode* aOtherNode, PRUint16* aReturn)
    1118                 :   {
    1119               0 :     NS_ENSURE_ARG(aOtherNode);
    1120               0 :     *aReturn = CompareDocPosition(aOtherNode);
    1121               0 :     return NS_OK;
    1122                 :   }
    1123                 :   nsresult CompareDocumentPosition(nsIDOMNode* aOther,
    1124                 :                                    PRUint16* aReturn);
    1125                 : 
    1126                 :   nsresult LookupPrefix(const nsAString& aNamespaceURI, nsAString& aPrefix);
    1127               0 :   nsresult IsDefaultNamespace(const nsAString& aNamespaceURI, bool* aResult)
    1128                 :   {
    1129               0 :     nsAutoString defaultNamespace;
    1130               0 :     LookupNamespaceURI(EmptyString(), defaultNamespace);
    1131               0 :     *aResult = aNamespaceURI.Equals(defaultNamespace);
    1132               0 :     return NS_OK;
    1133                 :   }
    1134                 :   nsresult LookupNamespaceURI(const nsAString& aNamespacePrefix,
    1135                 :                               nsAString& aNamespaceURI);
    1136                 : 
    1137                 :   nsresult IsEqualNode(nsIDOMNode* aOther, bool* aReturn);
    1138                 :   bool IsEqualTo(nsINode* aOther);
    1139                 : 
    1140          567397 :   nsIContent* GetNextSibling() const { return mNextSibling; }
    1141          112205 :   nsIContent* GetPreviousSibling() const { return mPreviousSibling; }
    1142                 : 
    1143                 :   /**
    1144                 :    * Get the next node in the pre-order tree traversal of the DOM.  If
    1145                 :    * aRoot is non-null, then it must be an ancestor of |this|
    1146                 :    * (possibly equal to |this|) and only nodes that are descendants of
    1147                 :    * aRoot, not including aRoot itself, will be returned.  Returns
    1148                 :    * null if there are no more nodes to traverse.
    1149                 :    */
    1150          433674 :   nsIContent* GetNextNode(const nsINode* aRoot = nsnull) const
    1151                 :   {
    1152          433674 :     return GetNextNodeImpl(aRoot, false);
    1153                 :   }
    1154                 : 
    1155                 :   /**
    1156                 :    * Get the next node in the pre-order tree traversal of the DOM but ignoring
    1157                 :    * the children of this node.  If aRoot is non-null, then it must be an
    1158                 :    * ancestor of |this| (possibly equal to |this|) and only nodes that are
    1159                 :    * descendants of aRoot, not including aRoot itself, will be returned.
    1160                 :    * Returns null if there are no more nodes to traverse.
    1161                 :    */
    1162               2 :   nsIContent* GetNextNonChildNode(const nsINode* aRoot = nsnull) const
    1163                 :   {
    1164               2 :     return GetNextNodeImpl(aRoot, true);
    1165                 :   }
    1166                 : 
    1167                 :   /**
    1168                 :    * Returns true if 'this' is either document or element or
    1169                 :    * document fragment and aOther is a descendant in the same
    1170                 :    * anonymous tree.
    1171                 :    */
    1172                 :   bool Contains(const nsINode* aOther) const;
    1173                 :   nsresult Contains(nsIDOMNode* aOther, bool* aReturn);
    1174                 : 
    1175                 : private:
    1176                 : 
    1177          433676 :   nsIContent* GetNextNodeImpl(const nsINode* aRoot,
    1178                 :                               const bool aSkipChildren) const
    1179                 :   {
    1180                 :     // Can't use nsContentUtils::ContentIsDescendantOf here, since we
    1181                 :     // can't include it here.
    1182                 : #ifdef DEBUG
    1183          433676 :     if (aRoot) {
    1184          433676 :       const nsINode* cur = this;
    1185         2761306 :       for (; cur; cur = cur->GetNodeParent())
    1186         2761306 :         if (cur == aRoot) break;
    1187          433676 :       NS_ASSERTION(cur, "aRoot not an ancestor of |this|?");
    1188                 :     }
    1189                 : #endif
    1190          433676 :     if (!aSkipChildren) {
    1191          433674 :       nsIContent* kid = GetFirstChild();
    1192          433674 :       if (kid) {
    1193          140813 :         return kid;
    1194                 :       }
    1195                 :     }
    1196          292863 :     if (this == aRoot) {
    1197              12 :       return nsnull;
    1198                 :     }
    1199          292851 :     const nsINode* cur = this;
    1200          137599 :     while (1) {
    1201          430450 :       nsIContent* next = cur->GetNextSibling();
    1202          430450 :       if (next) {
    1203          287613 :         return next;
    1204                 :       }
    1205          142837 :       nsINode* parent = cur->GetNodeParent();
    1206          142837 :       if (parent == aRoot) {
    1207            5238 :         return nsnull;
    1208                 :       }
    1209          137599 :       cur = parent;
    1210                 :     }
    1211                 :     NS_NOTREACHED("How did we get here?");
    1212                 :   }
    1213                 : 
    1214                 : public:
    1215                 : 
    1216                 :   /**
    1217                 :    * Get the previous nsIContent in the pre-order tree traversal of the DOM.  If
    1218                 :    * aRoot is non-null, then it must be an ancestor of |this|
    1219                 :    * (possibly equal to |this|) and only nsIContents that are descendants of
    1220                 :    * aRoot, including aRoot itself, will be returned.  Returns
    1221                 :    * null if there are no more nsIContents to traverse.
    1222                 :    */
    1223               0 :   nsIContent* GetPreviousContent(const nsINode* aRoot = nsnull) const
    1224                 :   {
    1225                 :       // Can't use nsContentUtils::ContentIsDescendantOf here, since we
    1226                 :       // can't include it here.
    1227                 : #ifdef DEBUG
    1228               0 :       if (aRoot) {
    1229               0 :         const nsINode* cur = this;
    1230               0 :         for (; cur; cur = cur->GetNodeParent())
    1231               0 :           if (cur == aRoot) break;
    1232               0 :         NS_ASSERTION(cur, "aRoot not an ancestor of |this|?");
    1233                 :       }
    1234                 : #endif
    1235                 : 
    1236               0 :     if (this == aRoot) {
    1237               0 :       return nsnull;
    1238                 :     }
    1239               0 :     nsIContent* cur = this->GetParent();
    1240               0 :     nsIContent* iter = this->GetPreviousSibling();
    1241               0 :     while (iter) {
    1242               0 :       cur = iter;
    1243               0 :       iter = reinterpret_cast<nsINode*>(iter)->GetLastChild();
    1244                 :     }
    1245               0 :     return cur;
    1246                 :   }
    1247                 : 
    1248                 :   /**
    1249                 :    * Boolean flags
    1250                 :    */
    1251                 : private:
    1252                 :   enum BooleanFlag {
    1253                 :     // Set if we're being used from -moz-element
    1254                 :     NodeHasRenderingObservers,
    1255                 :     // Set if our parent chain (including this node itself) terminates
    1256                 :     // in a document
    1257                 :     IsInDocument,
    1258                 :     // Set if mParent is an nsIContent
    1259                 :     ParentIsContent,
    1260                 :     // Set if this node is an Element
    1261                 :     NodeIsElement,
    1262                 :     // Set if the element has a non-empty id attribute. This can in rare
    1263                 :     // cases lie for nsXMLElement, such as when the node has been moved between
    1264                 :     // documents with different id mappings.
    1265                 :     ElementHasID,
    1266                 :     // Set if the element might have inline style.
    1267                 :     ElementMayHaveStyle,
    1268                 :     // Set if the element has a name attribute set.
    1269                 :     ElementHasName,
    1270                 :     // Set if the element might have a contenteditable attribute set.
    1271                 :     ElementMayHaveContentEditableAttr,
    1272                 :     // Set if the node is the common ancestor of the start/end nodes of a Range
    1273                 :     // that is in a Selection.
    1274                 :     NodeIsCommonAncestorForRangeInSelection,
    1275                 :     // Set if the node is a descendant of a node with the above bit set.
    1276                 :     NodeIsDescendantOfCommonAncestorForRangeInSelection,
    1277                 :     // Set if CanSkipInCC check has been done for this subtree root.
    1278                 :     NodeIsCCMarkedRoot,
    1279                 :     // Maybe set if this node is in black subtree.
    1280                 :     NodeIsCCBlackTree,
    1281                 :     // Maybe set if the node is a root of a subtree 
    1282                 :     // which needs to be kept in the purple buffer.
    1283                 :     NodeIsPurpleRoot,
    1284                 :     // Set if the node has an explicit base URI stored
    1285                 :     NodeHasExplicitBaseURI,
    1286                 :     // Set if the element has some style states locked
    1287                 :     ElementHasLockedStyleStates,
    1288                 :     // Guard value
    1289                 :     BooleanFlagCount
    1290                 :   };
    1291                 : 
    1292          230117 :   void SetBoolFlag(BooleanFlag name, bool value) {
    1293                 :     PR_STATIC_ASSERT(BooleanFlagCount <= 8*sizeof(mBoolFlags));
    1294          230117 :     mBoolFlags = (mBoolFlags & ~(1 << name)) | (value << name);
    1295          230117 :   }
    1296                 : 
    1297          150814 :   void SetBoolFlag(BooleanFlag name) {
    1298                 :     PR_STATIC_ASSERT(BooleanFlagCount <= 8*sizeof(mBoolFlags));
    1299          150814 :     mBoolFlags |= (1 << name);
    1300          150814 :   }
    1301                 : 
    1302          370643 :   void ClearBoolFlag(BooleanFlag name) {
    1303                 :     PR_STATIC_ASSERT(BooleanFlagCount <= 8*sizeof(mBoolFlags));
    1304          370643 :     mBoolFlags &= ~(1 << name);
    1305          370643 :   }
    1306                 : 
    1307         4442666 :   bool GetBoolFlag(BooleanFlag name) const {
    1308                 :     PR_STATIC_ASSERT(BooleanFlagCount <= 8*sizeof(mBoolFlags));
    1309         4442666 :     return mBoolFlags & (1 << name);
    1310                 :   }
    1311                 : 
    1312                 : public:
    1313               0 :   bool HasRenderingObservers() const
    1314               0 :     { return GetBoolFlag(NodeHasRenderingObservers); }
    1315               0 :   void SetHasRenderingObservers(bool aValue)
    1316               0 :     { SetBoolFlag(NodeHasRenderingObservers, aValue); }
    1317          157261 :   bool HasID() const { return GetBoolFlag(ElementHasID); }
    1318             790 :   bool MayHaveStyle() const { return GetBoolFlag(ElementMayHaveStyle); }
    1319            2038 :   bool HasName() const { return GetBoolFlag(ElementHasName); }
    1320            2040 :   bool MayHaveContentEditableAttr() const
    1321            2040 :     { return GetBoolFlag(ElementMayHaveContentEditableAttr); }
    1322              18 :   bool IsCommonAncestorForRangeInSelection() const
    1323              18 :     { return GetBoolFlag(NodeIsCommonAncestorForRangeInSelection); }
    1324               0 :   void SetCommonAncestorForRangeInSelection()
    1325               0 :     { SetBoolFlag(NodeIsCommonAncestorForRangeInSelection); }
    1326               0 :   void ClearCommonAncestorForRangeInSelection()
    1327               0 :     { ClearBoolFlag(NodeIsCommonAncestorForRangeInSelection); }
    1328              18 :   bool IsDescendantOfCommonAncestorForRangeInSelection() const
    1329              18 :     { return GetBoolFlag(NodeIsDescendantOfCommonAncestorForRangeInSelection); }
    1330               0 :   void SetDescendantOfCommonAncestorForRangeInSelection()
    1331               0 :     { SetBoolFlag(NodeIsDescendantOfCommonAncestorForRangeInSelection); }
    1332               0 :   void ClearDescendantOfCommonAncestorForRangeInSelection()
    1333               0 :     { ClearBoolFlag(NodeIsDescendantOfCommonAncestorForRangeInSelection); }
    1334                 : 
    1335             402 :   void SetCCMarkedRoot(bool aValue)
    1336             402 :     { SetBoolFlag(NodeIsCCMarkedRoot, aValue); }
    1337           26226 :   bool CCMarkedRoot() const { return GetBoolFlag(NodeIsCCMarkedRoot); }
    1338             402 :   void SetInCCBlackTree(bool aValue)
    1339             402 :     { SetBoolFlag(NodeIsCCBlackTree, aValue); }
    1340          148084 :   bool InCCBlackTree() const { return GetBoolFlag(NodeIsCCBlackTree); }
    1341            4332 :   void SetIsPurpleRoot(bool aValue)
    1342            4332 :     { SetBoolFlag(NodeIsPurpleRoot, aValue); }
    1343          297219 :   bool IsPurpleRoot() const { return GetBoolFlag(NodeIsPurpleRoot); }
    1344                 : 
    1345           36614 :   bool HasListenerManager() { return HasFlag(NODE_HAS_LISTENERMANAGER); }
    1346                 : protected:
    1347          224981 :   void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); }
    1348          112579 :   void SetInDocument() { SetBoolFlag(IsInDocument); }
    1349          370575 :   void ClearInDocument() { ClearBoolFlag(IsInDocument); }
    1350           38033 :   void SetIsElement() { SetBoolFlag(NodeIsElement); }
    1351              68 :   void ClearIsElement() { ClearBoolFlag(NodeIsElement); }
    1352             202 :   void SetHasID() { SetBoolFlag(ElementHasID); }
    1353               0 :   void ClearHasID() { ClearBoolFlag(ElementHasID); }
    1354               0 :   void SetMayHaveStyle() { SetBoolFlag(ElementMayHaveStyle); }
    1355               0 :   void SetHasName() { SetBoolFlag(ElementHasName); }
    1356               0 :   void ClearHasName() { ClearBoolFlag(ElementHasName); }
    1357               0 :   void SetMayHaveContentEditableAttr()
    1358               0 :     { SetBoolFlag(ElementMayHaveContentEditableAttr); }
    1359               0 :   bool HasExplicitBaseURI() const { return GetBoolFlag(NodeHasExplicitBaseURI); }
    1360               0 :   void SetHasExplicitBaseURI() { SetBoolFlag(NodeHasExplicitBaseURI); }
    1361               0 :   void SetHasLockedStyleStates() { SetBoolFlag(ElementHasLockedStyleStates); }
    1362               0 :   void ClearHasLockedStyleStates() { ClearBoolFlag(ElementHasLockedStyleStates); }
    1363               0 :   bool HasLockedStyleStates() const
    1364               0 :     { return GetBoolFlag(ElementHasLockedStyleStates); }
    1365                 : 
    1366                 : public:
    1367                 :   // Optimized way to get classinfo.
    1368                 :   virtual nsXPCClassInfo* GetClassInfo() = 0;
    1369                 : 
    1370                 : protected:
    1371                 : 
    1372                 :   // Override this function to create a custom slots class.
    1373                 :   virtual nsINode::nsSlots* CreateSlots();
    1374                 : 
    1375          133257 :   bool HasSlots() const
    1376                 :   {
    1377          133257 :     return mSlots != nsnull;
    1378                 :   }
    1379                 : 
    1380         1729510 :   nsSlots* GetExistingSlots() const
    1381                 :   {
    1382         1729510 :     return mSlots;
    1383                 :   }
    1384                 : 
    1385           17976 :   nsSlots* GetSlots()
    1386                 :   {
    1387           17976 :     if (!HasSlots()) {
    1388            4611 :       mSlots = CreateSlots();
    1389                 :     }
    1390           17976 :     return GetExistingSlots();
    1391                 :   }
    1392                 : 
    1393               0 :   nsTObserverArray<nsIMutationObserver*> *GetMutationObservers()
    1394                 :   {
    1395               0 :     return HasSlots() ? &GetExistingSlots()->mMutationObservers : nsnull;
    1396                 :   }
    1397                 : 
    1398                 :   bool IsEditableInternal() const;
    1399               0 :   virtual bool IsEditableExternal() const
    1400                 :   {
    1401               0 :     return IsEditableInternal();
    1402                 :   }
    1403                 : 
    1404                 : #ifdef DEBUG
    1405                 :   // Note: virtual so that IsInNativeAnonymousSubtree can be called accross
    1406                 :   // module boundaries.
    1407                 :   virtual void CheckNotNativeAnonymous() const;
    1408                 : #endif
    1409                 : 
    1410                 :   nsresult GetParentNode(nsIDOMNode** aParentNode);
    1411                 :   nsresult GetParentElement(nsIDOMElement** aParentElement);
    1412                 :   nsresult GetChildNodes(nsIDOMNodeList** aChildNodes);
    1413                 :   nsresult GetFirstChild(nsIDOMNode** aFirstChild);
    1414                 :   nsresult GetLastChild(nsIDOMNode** aLastChild);
    1415                 :   nsresult GetPreviousSibling(nsIDOMNode** aPrevSibling);
    1416                 :   nsresult GetNextSibling(nsIDOMNode** aNextSibling);
    1417                 :   nsresult GetOwnerDocument(nsIDOMDocument** aOwnerDocument);
    1418                 : 
    1419                 :   nsresult ReplaceOrInsertBefore(bool aReplace, nsIDOMNode *aNewChild,
    1420                 :                                  nsIDOMNode *aRefChild, nsIDOMNode **aReturn);
    1421             404 :   nsINode* ReplaceOrInsertBefore(bool aReplace, nsINode *aNewChild,
    1422                 :                                  nsINode *aRefChild, nsresult *aReturn)
    1423                 :   {
    1424             404 :     *aReturn = ReplaceOrInsertBefore(aReplace, aNewChild, aRefChild);
    1425             404 :     if (NS_FAILED(*aReturn)) {
    1426               0 :       return nsnull;
    1427                 :     }
    1428                 : 
    1429             404 :     return aReplace ? aRefChild : aNewChild;
    1430                 :   }
    1431                 :   virtual nsresult ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
    1432                 :                                          nsINode* aRefChild);
    1433                 :   nsresult RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn);
    1434                 : 
    1435                 :   /**
    1436                 :    * Returns the Element that should be used for resolving namespaces
    1437                 :    * on this node (ie the ownerElement for attributes, the documentElement for
    1438                 :    * documents, the node itself for elements and for other nodes the parentNode
    1439                 :    * if it is an element).
    1440                 :    */
    1441                 :   virtual mozilla::dom::Element* GetNameSpaceElement() = 0;
    1442                 : 
    1443                 :   /**
    1444                 :    * Most of the implementation of the nsINode RemoveChildAt method.
    1445                 :    * Should only be called on document, element, and document fragment
    1446                 :    * nodes.  The aChildArray passed in should be the one for |this|.
    1447                 :    *
    1448                 :    * @param aIndex The index to remove at.
    1449                 :    * @param aNotify Whether to notify.
    1450                 :    * @param aKid The kid at aIndex.  Must not be null.
    1451                 :    * @param aChildArray The child array to work with.
    1452                 :    * @param aMutationEvent whether to fire a mutation event for this removal.
    1453                 :    */
    1454                 :   nsresult doRemoveChildAt(PRUint32 aIndex, bool aNotify, nsIContent* aKid,
    1455                 :                            nsAttrAndChildArray& aChildArray);
    1456                 : 
    1457                 :   /**
    1458                 :    * Most of the implementation of the nsINode InsertChildAt method.
    1459                 :    * Should only be called on document, element, and document fragment
    1460                 :    * nodes.  The aChildArray passed in should be the one for |this|.
    1461                 :    *
    1462                 :    * @param aKid The child to insert.
    1463                 :    * @param aIndex The index to insert at.
    1464                 :    * @param aNotify Whether to notify.
    1465                 :    * @param aChildArray The child array to work with
    1466                 :    */
    1467                 :   nsresult doInsertChildAt(nsIContent* aKid, PRUint32 aIndex,
    1468                 :                            bool aNotify, nsAttrAndChildArray& aChildArray);
    1469                 : 
    1470                 : public:
    1471                 :   /* Event stuff that documents and elements share.  This needs to be
    1472                 :      NS_IMETHOD because some subclasses implement DOM methods with
    1473                 :      this exact name and signature and then the calling convention
    1474                 :      needs to match.
    1475                 : 
    1476                 :      Note that we include DOCUMENT_ONLY_EVENT events here so that we
    1477                 :      can forward all the document stuff to this implementation.
    1478                 :   */
    1479                 : #define EVENT(name_, id_, type_, struct_)                         \
    1480                 :   NS_IMETHOD GetOn##name_(JSContext *cx, JS::Value *vp);          \
    1481                 :   NS_IMETHOD SetOn##name_(JSContext *cx, const JS::Value &v);
    1482                 : #define TOUCH_EVENT EVENT
    1483                 : #define DOCUMENT_ONLY_EVENT EVENT
    1484                 : #include "nsEventNameList.h"
    1485                 : #undef DOCUMENT_ONLY_EVENT
    1486                 : #undef TOUCH_EVENT
    1487                 : #undef EVENT  
    1488                 : 
    1489                 : protected:
    1490                 :   static void Trace(nsINode *tmp, TraceCallback cb, void *closure);
    1491                 :   static bool Traverse(nsINode *tmp, nsCycleCollectionTraversalCallback &cb);
    1492                 :   static void Unlink(nsINode *tmp);
    1493                 : 
    1494                 :   nsCOMPtr<nsINodeInfo> mNodeInfo;
    1495                 : 
    1496                 :   nsINode* mParent;
    1497                 : 
    1498                 :   PRUint32 mFlags;
    1499                 : 
    1500                 : private:
    1501                 :   // Boolean flags.
    1502                 :   PRUint32 mBoolFlags;
    1503                 : 
    1504                 : protected:
    1505                 :   nsIContent* mNextSibling;
    1506                 :   nsIContent* mPreviousSibling;
    1507                 :   nsIContent* mFirstChild;
    1508                 : 
    1509                 :   // Storage for more members that are usually not needed; allocated lazily.
    1510                 :   nsSlots* mSlots;
    1511                 : };
    1512                 : 
    1513                 : 
    1514                 : extern const nsIID kThisPtrOffsetsSID;
    1515                 : 
    1516                 : // _implClass is the class to use to cast to nsISupports
    1517                 : #define NS_OFFSET_AND_INTERFACE_TABLE_BEGIN_AMBIGUOUS(_class, _implClass)     \
    1518                 :   static const QITableEntry offsetAndQITable[] = {                            \
    1519                 :     NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsISupports, _implClass)
    1520                 : 
    1521                 : #define NS_OFFSET_AND_INTERFACE_TABLE_BEGIN(_class)                           \
    1522                 :   NS_OFFSET_AND_INTERFACE_TABLE_BEGIN_AMBIGUOUS(_class, _class)
    1523                 : 
    1524                 : #define NS_OFFSET_AND_INTERFACE_TABLE_END                                     \
    1525                 :   { nsnull, 0 } };                                                            \
    1526                 :   if (aIID.Equals(kThisPtrOffsetsSID)) {                                      \
    1527                 :     *aInstancePtr =                                                           \
    1528                 :       const_cast<void*>(static_cast<const void*>(&offsetAndQITable));         \
    1529                 :     return NS_OK;                                                             \
    1530                 :   }
    1531                 : 
    1532                 : #define NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE                            \
    1533                 :   rv = NS_TableDrivenQI(this, offsetAndQITable, aIID, aInstancePtr);          \
    1534                 :   NS_INTERFACE_TABLE_TO_MAP_SEGUE
    1535                 : 
    1536                 : // nsNodeSH::PreCreate() depends on the identity pointer being the same as
    1537                 : // nsINode, so if you change the nsISupports line  below, make sure
    1538                 : // nsNodeSH::PreCreate() still does the right thing!
    1539                 : #define NS_NODE_OFFSET_AND_INTERFACE_TABLE_BEGIN(_class)                      \
    1540                 :   NS_OFFSET_AND_INTERFACE_TABLE_BEGIN_AMBIGUOUS(_class, nsINode)              \
    1541                 :     NS_INTERFACE_TABLE_ENTRY(_class, nsINode)                       
    1542                 : 
    1543                 : #define NS_NODE_INTERFACE_TABLE2(_class, _i1, _i2)                            \
    1544                 :   NS_NODE_OFFSET_AND_INTERFACE_TABLE_BEGIN(_class)                            \
    1545                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i1)                                     \
    1546                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i2)                                     \
    1547                 :   NS_OFFSET_AND_INTERFACE_TABLE_END                                           \
    1548                 :   NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
    1549                 : 
    1550                 : #define NS_NODE_INTERFACE_TABLE3(_class, _i1, _i2, _i3)                       \
    1551                 :   NS_NODE_OFFSET_AND_INTERFACE_TABLE_BEGIN(_class)                            \
    1552                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i1)                                     \
    1553                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i2)                                     \
    1554                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i3)                                     \
    1555                 :   NS_OFFSET_AND_INTERFACE_TABLE_END                                           \
    1556                 :   NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
    1557                 : 
    1558                 : #define NS_NODE_INTERFACE_TABLE4(_class, _i1, _i2, _i3, _i4)                  \
    1559                 :   NS_NODE_OFFSET_AND_INTERFACE_TABLE_BEGIN(_class)                            \
    1560                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i1)                                     \
    1561                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i2)                                     \
    1562                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i3)                                     \
    1563                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i4)                                     \
    1564                 :   NS_OFFSET_AND_INTERFACE_TABLE_END                                           \
    1565                 :   NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
    1566                 : 
    1567                 : #define NS_NODE_INTERFACE_TABLE5(_class, _i1, _i2, _i3, _i4, _i5)             \
    1568                 :   NS_NODE_OFFSET_AND_INTERFACE_TABLE_BEGIN(_class)                            \
    1569                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i1)                                     \
    1570                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i2)                                     \
    1571                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i3)                                     \
    1572                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i4)                                     \
    1573                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i5)                                     \
    1574                 :   NS_OFFSET_AND_INTERFACE_TABLE_END                                           \
    1575                 :   NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
    1576                 : 
    1577                 : #define NS_NODE_INTERFACE_TABLE6(_class, _i1, _i2, _i3, _i4, _i5, _i6)        \
    1578                 :   NS_NODE_OFFSET_AND_INTERFACE_TABLE_BEGIN(_class)                            \
    1579                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i1)                                     \
    1580                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i2)                                     \
    1581                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i3)                                     \
    1582                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i4)                                     \
    1583                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i5)                                     \
    1584                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i6)                                     \
    1585                 :   NS_OFFSET_AND_INTERFACE_TABLE_END                                           \
    1586                 :   NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
    1587                 : 
    1588                 : #define NS_NODE_INTERFACE_TABLE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7)   \
    1589                 :   NS_NODE_OFFSET_AND_INTERFACE_TABLE_BEGIN(_class)                            \
    1590                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i1)                                     \
    1591                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i2)                                     \
    1592                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i3)                                     \
    1593                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i4)                                     \
    1594                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i5)                                     \
    1595                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i6)                                     \
    1596                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i7)                                     \
    1597                 :   NS_OFFSET_AND_INTERFACE_TABLE_END                                           \
    1598                 :   NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
    1599                 : 
    1600                 : #define NS_NODE_INTERFACE_TABLE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7,   \
    1601                 :                                  _i8)                                         \
    1602                 :   NS_NODE_OFFSET_AND_INTERFACE_TABLE_BEGIN(_class)                            \
    1603                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i1)                                     \
    1604                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i2)                                     \
    1605                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i3)                                     \
    1606                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i4)                                     \
    1607                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i5)                                     \
    1608                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i6)                                     \
    1609                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i7)                                     \
    1610                 :     NS_INTERFACE_TABLE_ENTRY(_class, _i8)                                     \
    1611                 :   NS_OFFSET_AND_INTERFACE_TABLE_END                                           \
    1612                 :   NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
    1613                 : 
    1614                 : 
    1615                 : NS_DEFINE_STATIC_IID_ACCESSOR(nsINode, NS_INODE_IID)
    1616                 : 
    1617                 : 
    1618                 : #define NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER \
    1619                 :   nsContentUtils::TraceWrapper(tmp, aCallback, aClosure);
    1620                 : 
    1621                 : #define NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
    1622                 :   nsContentUtils::ReleaseWrapper(s, tmp);
    1623                 : 
    1624                 : 
    1625                 : #endif /* nsINode_h___ */

Generated by: LCOV version 1.7