LCOV - code coverage report
Current view: top level - dom/base - nsIContent.h (source / functions) Hit Total Coverage
Test: output.info Lines: 79 112 70.5 %
Date: 2017-07-14 16:53:18 Functions: 34 65 52.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : #ifndef nsIContent_h___
       7             : #define nsIContent_h___
       8             : 
       9             : #include "mozilla/Attributes.h"
      10             : #include "mozilla/dom/BorrowedAttrInfo.h"
      11             : #include "nsCaseTreatment.h" // for enum, cannot be forward-declared
      12             : #include "nsINode.h"
      13             : 
      14             : // Forward declarations
      15             : class nsAString;
      16             : class nsIAtom;
      17             : class nsIURI;
      18             : class nsRuleWalker;
      19             : class nsAttrValue;
      20             : class nsAttrName;
      21             : class nsTextFragment;
      22             : class nsIFrame;
      23             : class nsXBLBinding;
      24             : 
      25             : namespace mozilla {
      26             : class EventChainPreVisitor;
      27             : struct URLExtraData;
      28             : namespace dom {
      29             : class ShadowRoot;
      30             : } // namespace dom
      31             : namespace widget {
      32             : struct IMEState;
      33             : } // namespace widget
      34             : } // namespace mozilla
      35             : 
      36             : enum nsLinkState {
      37             :   eLinkState_Unvisited  = 1,
      38             :   eLinkState_Visited    = 2,
      39             :   eLinkState_NotLink    = 3
      40             : };
      41             : 
      42             : // IID for the nsIContent interface
      43             : #define NS_ICONTENT_IID \
      44             : { 0x8e1bab9d, 0x8815, 0x4d2c, \
      45             :   { 0xa2, 0x4d, 0x7a, 0xba, 0x52, 0x39, 0xdc, 0x22 } }
      46             : 
      47             : /**
      48             :  * A node of content in a document's content model. This interface
      49             :  * is supported by all content objects.
      50             :  */
      51          35 : class nsIContent : public nsINode {
      52             : public:
      53             :   typedef mozilla::widget::IMEState IMEState;
      54             : 
      55             : #ifdef MOZILLA_INTERNAL_API
      56             :   // If you're using the external API, the only thing you can know about
      57             :   // nsIContent is that it exists with an IID
      58             : 
      59        3572 :   explicit nsIContent(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
      60        3572 :     : nsINode(aNodeInfo)
      61             :   {
      62        3572 :     MOZ_ASSERT(mNodeInfo);
      63        3572 :     SetNodeIsContent();
      64        3572 :   }
      65             : #endif // MOZILLA_INTERNAL_API
      66             : 
      67             :   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENT_IID)
      68             : 
      69             :   /**
      70             :    * Bind this content node to a tree.  If this method throws, the caller must
      71             :    * call UnbindFromTree() on the node.  In the typical case of a node being
      72             :    * appended to a parent, this will be called after the node has been added to
      73             :    * the parent's child list and before nsIDocumentObserver notifications for
      74             :    * the addition are dispatched.
      75             :    * @param aDocument The new document for the content node.  May not be null
      76             :    *                  if aParent is null.  Must match the current document of
      77             :    *                  aParent, if aParent is not null (note that
      78             :    *                  aParent->GetUncomposedDoc() can be null, in which case
      79             :    *                  this must also be null).
      80             :    * @param aParent The new parent for the content node.  May be null if the
      81             :    *                node is being bound as a direct child of the document.
      82             :    * @param aBindingParent The new binding parent for the content node.
      83             :    *                       This is must either be non-null if a particular
      84             :    *                       binding parent is desired or match aParent's binding
      85             :    *                       parent.
      86             :    * @param aCompileEventHandlers whether to initialize the event handlers in
      87             :    *        the document (used by nsXULElement)
      88             :    * @note either aDocument or aParent must be non-null.  If both are null,
      89             :    *       this method _will_ crash.
      90             :    * @note This method must not be called by consumers of nsIContent on a node
      91             :    *       that is already bound to a tree.  Call UnbindFromTree first.
      92             :    * @note This method will handle rebinding descendants appropriately (eg
      93             :    *       changing their binding parent as needed).
      94             :    * @note This method does not add the content node to aParent's child list
      95             :    * @throws NS_ERROR_OUT_OF_MEMORY if that happens
      96             :    */
      97             :   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
      98             :                               nsIContent* aBindingParent,
      99             :                               bool aCompileEventHandlers) = 0;
     100             : 
     101             :   /**
     102             :    * Unbind this content node from a tree.  This will set its current document
     103             :    * and binding parent to null.  In the typical case of a node being removed
     104             :    * from a parent, this will be called after it has been removed from the
     105             :    * parent's child list and after the nsIDocumentObserver notifications for
     106             :    * the removal have been dispatched.
     107             :    * @param aDeep Whether to recursively unbind the entire subtree rooted at
     108             :    *        this node.  The only time false should be passed is when the
     109             :    *        parent node of the content is being destroyed.
     110             :    * @param aNullParent Whether to null out the parent pointer as well.  This
     111             :    *        is usually desirable.  This argument should only be false while
     112             :    *        recursively calling UnbindFromTree when a subtree is detached.
     113             :    * @note This method is safe to call on nodes that are not bound to a tree.
     114             :    */
     115             :   virtual void UnbindFromTree(bool aDeep = true,
     116             :                               bool aNullParent = true) = 0;
     117             : 
     118             :   enum {
     119             :     /**
     120             :      * All XBL flattened tree children of the node, as well as :before and
     121             :      * :after anonymous content and native anonymous children.
     122             :      *
     123             :      * @note the result children order is
     124             :      *   1. :before generated node
     125             :      *   2. XBL flattened tree children of this node
     126             :      *   3. native anonymous nodes
     127             :      *   4. :after generated node
     128             :      */
     129             :     eAllChildren = 0,
     130             : 
     131             :     /**
     132             :      * All XBL explicit children of the node (see
     133             :      * http://www.w3.org/TR/xbl/#explicit3 ), as well as :before and :after
     134             :      * anonymous content and native anonymous children.
     135             :      *
     136             :      * @note the result children order is
     137             :      *   1. :before generated node
     138             :      *   2. XBL explicit children of the node
     139             :      *   3. native anonymous nodes
     140             :      *   4. :after generated node
     141             :      */
     142             :     eAllButXBL = 1,
     143             : 
     144             :     /**
     145             :      * Skip native anonymous content created for placeholder of HTML input,
     146             :      * used in conjunction with eAllChildren or eAllButXBL.
     147             :      */
     148             :     eSkipPlaceholderContent = 2,
     149             : 
     150             :     /**
     151             :      * Skip native anonymous content created by ancestor frames of the root
     152             :      * element's primary frame, such as scrollbar elements created by the root
     153             :      * scroll frame.
     154             :      */
     155             :     eSkipDocumentLevelNativeAnonymousContent = 4,
     156             :   };
     157             : 
     158             :   /**
     159             :    * Return either the XBL explicit children of the node or the XBL flattened
     160             :    * tree children of the node, depending on the filter, as well as
     161             :    * native anonymous children.
     162             :    *
     163             :    * @note calling this method with eAllButXBL will return children that are
     164             :    *  also in the eAllButXBL and eAllChildren child lists of other descendants
     165             :    *  of this node in the tree, but those other nodes cannot be reached from the
     166             :    *  eAllButXBL child list.
     167             :    */
     168             :   virtual already_AddRefed<nsINodeList> GetChildren(uint32_t aFilter) = 0;
     169             : 
     170             :   /**
     171             :    * Get whether this content is C++-generated anonymous content
     172             :    * @see nsIAnonymousContentCreator
     173             :    * @return whether this content is anonymous
     174             :    */
     175       81051 :   bool IsRootOfNativeAnonymousSubtree() const
     176             :   {
     177       81051 :     NS_ASSERTION(!HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT) ||
     178             :                  (HasFlag(NODE_IS_ANONYMOUS_ROOT) &&
     179             :                   HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE)),
     180             :                  "Some flags seem to be missing!");
     181       81051 :     return HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT);
     182             :   }
     183             : 
     184        1404 :   bool IsRootOfChromeAccessOnlySubtree() const
     185             :   {
     186        1404 :     return HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT |
     187        1404 :                    NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS);
     188             :   }
     189             : 
     190             :   /**
     191             :    * Makes this content anonymous
     192             :    * @see nsIAnonymousContentCreator
     193             :    */
     194          45 :   void SetIsNativeAnonymousRoot()
     195             :   {
     196          45 :     SetFlags(NODE_IS_ANONYMOUS_ROOT | NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE |
     197          45 :              NODE_IS_NATIVE_ANONYMOUS_ROOT | NODE_IS_NATIVE_ANONYMOUS);
     198          45 :   }
     199             : 
     200             :   /**
     201             :    * Returns |this| if it is not chrome-only/native anonymous, otherwise
     202             :    * first non chrome-only/native anonymous ancestor.
     203             :    */
     204             :   virtual nsIContent* FindFirstNonChromeOnlyAccessContent() const;
     205             : 
     206             :   /**
     207             :    * Returns true if and only if this node has a parent, but is not in
     208             :    * its parent's child list.
     209             :    */
     210         888 :   bool IsRootOfAnonymousSubtree() const
     211             :   {
     212         888 :     NS_ASSERTION(!IsRootOfNativeAnonymousSubtree() ||
     213             :                  (GetParent() && GetBindingParent() == GetParent()),
     214             :                  "root of native anonymous subtree must have parent equal "
     215             :                  "to binding parent");
     216         888 :     NS_ASSERTION(!GetParent() ||
     217             :                  ((GetBindingParent() == GetParent()) ==
     218             :                   HasFlag(NODE_IS_ANONYMOUS_ROOT)) ||
     219             :                  // Unfortunately default content for XBL insertion points is
     220             :                  // anonymous content that is bound with the parent of the
     221             :                  // insertion point as the parent but the bound element for the
     222             :                  // binding as the binding parent.  So we have to complicate
     223             :                  // the assert a bit here.
     224             :                  (GetBindingParent() &&
     225             :                   (GetBindingParent() == GetParent()->GetBindingParent()) ==
     226             :                   HasFlag(NODE_IS_ANONYMOUS_ROOT)),
     227             :                  "For nodes with parent, flag and GetBindingParent() check "
     228             :                  "should match");
     229         888 :     return HasFlag(NODE_IS_ANONYMOUS_ROOT);
     230             :   }
     231             : 
     232             :   /**
     233             :    * Returns true if there is NOT a path through child lists
     234             :    * from the top of this node's parent chain back to this node or
     235             :    * if the node is in native anonymous subtree without a parent.
     236             :    */
     237        2393 :   bool IsInAnonymousSubtree() const
     238             :   {
     239        2393 :     NS_ASSERTION(!IsInNativeAnonymousSubtree() || GetBindingParent() ||
     240             :                  (!IsInUncomposedDoc() &&
     241             :                   static_cast<nsIContent*>(SubtreeRoot())->IsInNativeAnonymousSubtree()),
     242             :                  "Must have binding parent when in native anonymous subtree which is in document.\n"
     243             :                  "Native anonymous subtree which is not in document must have native anonymous root.");
     244        2393 :     return IsInNativeAnonymousSubtree() || (!IsInShadowTree() && GetBindingParent() != nullptr);
     245             :   }
     246             : 
     247             :   /*
     248             :    * Return true if this node is the shadow root of an use-element shadow tree.
     249             :    */
     250       15058 :   bool IsRootOfUseElementShadowTree() const {
     251       15104 :     return GetParent() && GetParent()->IsSVGElement(nsGkAtoms::use) &&
     252       15104 :            IsRootOfAnonymousSubtree();
     253             :   }
     254             : 
     255             :   /**
     256             :    * Return true iff this node is in an HTML document (in the HTML5 sense of
     257             :    * the term, i.e. not in an XHTML/XML document).
     258             :    */
     259             :   inline bool IsInHTMLDocument() const;
     260             : 
     261             : 
     262             :   /**
     263             :    * Returns true if in a chrome document
     264             :    */
     265             :   virtual bool IsInChromeDocument() const;
     266             : 
     267             :   /**
     268             :    * Get the namespace that this element's tag is defined in
     269             :    * @return the namespace
     270             :    */
     271      210133 :   inline int32_t GetNameSpaceID() const
     272             :   {
     273      210133 :     return mNodeInfo->NamespaceID();
     274             :   }
     275             : 
     276       11391 :   inline bool IsHTMLElement() const
     277             :   {
     278       11391 :     return IsInNamespace(kNameSpaceID_XHTML);
     279             :   }
     280             : 
     281       13731 :   inline bool IsHTMLElement(nsIAtom* aTag) const
     282             :   {
     283       13731 :     return mNodeInfo->Equals(aTag, kNameSpaceID_XHTML);
     284             :   }
     285             : 
     286             :   template<typename First, typename... Args>
     287        3281 :   inline bool IsAnyOfHTMLElements(First aFirst, Args... aArgs) const
     288             :   {
     289        3281 :     return IsHTMLElement() && IsNodeInternal(aFirst, aArgs...);
     290             :   }
     291             : 
     292       20360 :   inline bool IsSVGElement() const
     293             :   {
     294       20360 :     return IsInNamespace(kNameSpaceID_SVG);
     295             :   }
     296             : 
     297       18041 :   inline bool IsSVGElement(nsIAtom* aTag) const
     298             :   {
     299       18041 :     return mNodeInfo->Equals(aTag, kNameSpaceID_SVG);
     300             :   }
     301             : 
     302             :   template<typename First, typename... Args>
     303         148 :   inline bool IsAnyOfSVGElements(First aFirst, Args... aArgs) const
     304             :   {
     305         148 :     return IsSVGElement() && IsNodeInternal(aFirst, aArgs...);
     306             :   }
     307             : 
     308       19353 :   inline bool IsXULElement() const
     309             :   {
     310       19353 :     return IsInNamespace(kNameSpaceID_XUL);
     311             :   }
     312             : 
     313         412 :   inline bool IsXULElement(nsIAtom* aTag) const
     314             :   {
     315         412 :     return mNodeInfo->Equals(aTag, kNameSpaceID_XUL);
     316             :   }
     317             : 
     318             :   template<typename First, typename... Args>
     319        9825 :   inline bool IsAnyOfXULElements(First aFirst, Args... aArgs) const
     320             :   {
     321        9825 :     return IsXULElement() && IsNodeInternal(aFirst, aArgs...);
     322             :   }
     323             : 
     324           0 :   inline bool IsMathMLElement() const
     325             :   {
     326           0 :     return IsInNamespace(kNameSpaceID_MathML);
     327             :   }
     328             : 
     329        2501 :   inline bool IsMathMLElement(nsIAtom* aTag) const
     330             :   {
     331        2501 :     return mNodeInfo->Equals(aTag, kNameSpaceID_MathML);
     332             :   }
     333             : 
     334             :   template<typename First, typename... Args>
     335           0 :   inline bool IsAnyOfMathMLElements(First aFirst, Args... aArgs) const
     336             :   {
     337           0 :     return IsMathMLElement() && IsNodeInternal(aFirst, aArgs...);
     338             :   }
     339       12109 :   inline bool IsActiveChildrenElement() const
     340             :   {
     341       12352 :     return mNodeInfo->Equals(nsGkAtoms::children, kNameSpaceID_XBL) &&
     342       12352 :            GetBindingParent();
     343             :   }
     344             : 
     345          99 :   bool IsGeneratedContentContainerForBefore() const
     346             :   {
     347         115 :     return IsRootOfNativeAnonymousSubtree() &&
     348         115 :            mNodeInfo->NameAtom() == nsGkAtoms::mozgeneratedcontentbefore;
     349             :   }
     350             : 
     351          97 :   bool IsGeneratedContentContainerForAfter() const
     352             :   {
     353         111 :     return IsRootOfNativeAnonymousSubtree() &&
     354         111 :            mNodeInfo->NameAtom() == nsGkAtoms::mozgeneratedcontentafter;
     355             :   }
     356             : 
     357             :   /**
     358             :    * Set attribute values. All attribute values are assumed to have a
     359             :    * canonical string representation that can be used for these
     360             :    * methods. The SetAttr method is assumed to perform a translation
     361             :    * of the canonical form into the underlying content specific
     362             :    * form.
     363             :    *
     364             :    * @param aNameSpaceID the namespace of the attribute
     365             :    * @param aName the name of the attribute
     366             :    * @param aValue the value to set
     367             :    * @param aNotify specifies how whether or not the document should be
     368             :    *        notified of the attribute change.
     369             :    */
     370         402 :   nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
     371             :                    const nsAString& aValue, bool aNotify)
     372             :   {
     373         402 :     return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
     374             :   }
     375             : 
     376             :   /**
     377             :    * Set attribute values. All attribute values are assumed to have a
     378             :    * canonical String representation that can be used for these
     379             :    * methods. The SetAttr method is assumed to perform a translation
     380             :    * of the canonical form into the underlying content specific
     381             :    * form.
     382             :    *
     383             :    * @param aNameSpaceID the namespace of the attribute
     384             :    * @param aName the name of the attribute
     385             :    * @param aPrefix the prefix of the attribute
     386             :    * @param aValue the value to set
     387             :    * @param aNotify specifies how whether or not the document should be
     388             :    *        notified of the attribute change.
     389             :    */
     390             :   virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
     391             :                            nsIAtom* aPrefix, const nsAString& aValue,
     392             :                            bool aNotify) = 0;
     393             : 
     394             :   /**
     395             :    * Get the current value of the attribute. This returns a form that is
     396             :    * suitable for passing back into SetAttr.
     397             :    *
     398             :    * @param aNameSpaceID the namespace of the attr
     399             :    * @param aName the name of the attr
     400             :    * @param aResult the value (may legitimately be the empty string) [OUT]
     401             :    * @returns true if the attribute was set (even when set to empty string)
     402             :    *          false when not set.
     403             :    */
     404             :   bool GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
     405             :                nsAString& aResult) const;
     406             : 
     407             :   /**
     408             :    * Determine if an attribute has been set (empty string or otherwise).
     409             :    *
     410             :    * @param aNameSpaceId the namespace id of the attribute
     411             :    * @param aAttr the attribute name
     412             :    * @return whether an attribute exists
     413             :    */
     414             :   bool HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const;
     415             : 
     416             :   /**
     417             :    * Test whether this content node's given attribute has the given value.  If
     418             :    * the attribute is not set at all, this will return false.
     419             :    *
     420             :    * @param aNameSpaceID The namespace ID of the attribute.  Must not
     421             :    *                     be kNameSpaceID_Unknown.
     422             :    * @param aName The name atom of the attribute.  Must not be null.
     423             :    * @param aValue The value to compare to.
     424             :    * @param aCaseSensitive Whether to do a case-sensitive compare on the value.
     425             :    */
     426             :   bool AttrValueIs(int32_t aNameSpaceID,
     427             :                    nsIAtom* aName,
     428             :                    const nsAString& aValue,
     429             :                    nsCaseTreatment aCaseSensitive) const;
     430             : 
     431             :   /**
     432             :    * Test whether this content node's given attribute has the given value.  If
     433             :    * the attribute is not set at all, this will return false.
     434             :    *
     435             :    * @param aNameSpaceID The namespace ID of the attribute.  Must not
     436             :    *                     be kNameSpaceID_Unknown.
     437             :    * @param aName The name atom of the attribute.  Must not be null.
     438             :    * @param aValue The value to compare to.  Must not be null.
     439             :    * @param aCaseSensitive Whether to do a case-sensitive compare on the value.
     440             :    */
     441             :   bool AttrValueIs(int32_t aNameSpaceID,
     442             :                    nsIAtom* aName,
     443             :                    nsIAtom* aValue,
     444             :                    nsCaseTreatment aCaseSensitive) const;
     445             : 
     446             :   enum {
     447             :     ATTR_MISSING = -1,
     448             :     ATTR_VALUE_NO_MATCH = -2
     449             :   };
     450             :   /**
     451             :    * Check whether this content node's given attribute has one of a given
     452             :    * list of values. If there is a match, we return the index in the list
     453             :    * of the first matching value. If there was no attribute at all, then
     454             :    * we return ATTR_MISSING. If there was an attribute but it didn't
     455             :    * match, we return ATTR_VALUE_NO_MATCH. A non-negative result always
     456             :    * indicates a match.
     457             :    *
     458             :    * @param aNameSpaceID The namespace ID of the attribute.  Must not
     459             :    *                     be kNameSpaceID_Unknown.
     460             :    * @param aName The name atom of the attribute.  Must not be null.
     461             :    * @param aValues a nullptr-terminated array of pointers to atom values to test
     462             :    *                against.
     463             :    * @param aCaseSensitive Whether to do a case-sensitive compare on the values.
     464             :    * @return ATTR_MISSING, ATTR_VALUE_NO_MATCH or the non-negative index
     465             :    * indicating the first value of aValues that matched
     466             :    */
     467             :   typedef nsIAtom* const* const AttrValuesArray;
     468           0 :   virtual int32_t FindAttrValueIn(int32_t aNameSpaceID,
     469             :                                   nsIAtom* aName,
     470             :                                   AttrValuesArray* aValues,
     471             :                                   nsCaseTreatment aCaseSensitive) const
     472             :   {
     473           0 :     return ATTR_MISSING;
     474             :   }
     475             : 
     476             :   /**
     477             :    * Remove an attribute so that it is no longer explicitly specified.
     478             :    *
     479             :    * @param aNameSpaceID the namespace id of the attribute
     480             :    * @param aAttr the name of the attribute to unset
     481             :    * @param aNotify specifies whether or not the document should be
     482             :    * notified of the attribute change
     483             :    */
     484             :   virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttr,
     485             :                              bool aNotify) = 0;
     486             : 
     487             : 
     488             :   /**
     489             :    * Get the namespace / name / prefix of a given attribute.
     490             :    *
     491             :    * @param   aIndex the index of the attribute name
     492             :    * @returns The name at the given index, or null if the index is
     493             :    *          out-of-bounds.
     494             :    * @note    The document returned by NodeInfo()->GetDocument() (if one is
     495             :    *          present) is *not* necessarily the owner document of the element.
     496             :    * @note    The pointer returned by this function is only valid until the
     497             :    *          next call of either GetAttrNameAt or SetAttr on the element.
     498             :    */
     499             :   virtual const nsAttrName* GetAttrNameAt(uint32_t aIndex) const = 0;
     500             : 
     501             :   /**
     502             :    * Gets the attribute info (name and value) for this content at a given index.
     503             :    */
     504             :   virtual mozilla::dom::BorrowedAttrInfo GetAttrInfoAt(uint32_t aIndex) const = 0;
     505             : 
     506             :   /**
     507             :    * Get the number of all specified attributes.
     508             :    *
     509             :    * @return the number of attributes
     510             :    */
     511             :   virtual uint32_t GetAttrCount() const = 0;
     512             : 
     513             :   /**
     514             :    * Get direct access (but read only) to the text in the text content.
     515             :    * NOTE: For elements this is *not* the concatenation of all text children,
     516             :    * it is simply null;
     517             :    */
     518             :   virtual const nsTextFragment *GetText() = 0;
     519             : 
     520             :   /**
     521             :    * Get the length of the text content.
     522             :    * NOTE: This should not be called on elements.
     523             :    */
     524             :   virtual uint32_t TextLength() const = 0;
     525             : 
     526             :   /**
     527             :    * Determines if an event attribute name (such as onclick) is valid for
     528             :    * a given element type.
     529             :    * @note calls nsContentUtils::IsEventAttributeName with right flag
     530             :    * @note *Internal is overridden by subclasses as needed
     531             :    * @param aName the event name to look up
     532             :    */
     533             :   bool IsEventAttributeName(nsIAtom* aName);
     534             : 
     535           0 :   virtual bool IsEventAttributeNameInternal(nsIAtom* aName)
     536             :   {
     537           0 :     return false;
     538             :   }
     539             : 
     540             :   /**
     541             :    * Set the text to the given value. If aNotify is true then
     542             :    * the document is notified of the content change.
     543             :    * NOTE: For elements this always ASSERTS and returns NS_ERROR_FAILURE
     544             :    */
     545             :   virtual nsresult SetText(const char16_t* aBuffer, uint32_t aLength,
     546             :                            bool aNotify) = 0;
     547             : 
     548             :   /**
     549             :    * Append the given value to the current text. If aNotify is true then
     550             :    * the document is notified of the content change.
     551             :    * NOTE: For elements this always ASSERTS and returns NS_ERROR_FAILURE
     552             :    */
     553             :   virtual nsresult AppendText(const char16_t* aBuffer, uint32_t aLength,
     554             :                               bool aNotify) = 0;
     555             : 
     556             :   /**
     557             :    * Set the text to the given value. If aNotify is true then
     558             :    * the document is notified of the content change.
     559             :    * NOTE: For elements this always asserts and returns NS_ERROR_FAILURE
     560             :    */
     561          53 :   nsresult SetText(const nsAString& aStr, bool aNotify)
     562             :   {
     563          53 :     return SetText(aStr.BeginReading(), aStr.Length(), aNotify);
     564             :   }
     565             : 
     566             :   /**
     567             :    * Query method to see if the frame is nothing but whitespace
     568             :    * NOTE: Always returns false for elements
     569             :    */
     570             :   virtual bool TextIsOnlyWhitespace() = 0;
     571             : 
     572             :   /**
     573             :    * Thread-safe version of TextIsOnlyWhitespace.
     574             :    */
     575             :   virtual bool ThreadSafeTextIsOnlyWhitespace() const = 0;
     576             : 
     577             :   /**
     578             :    * Method to see if the text node contains data that is useful
     579             :    * for a translation: i.e., it consists of more than just whitespace,
     580             :    * digits and punctuation.
     581             :    * NOTE: Always returns false for elements.
     582             :    */
     583             :   virtual bool HasTextForTranslation() = 0;
     584             : 
     585             :   /**
     586             :    * Append the text content to aResult.
     587             :    * NOTE: This asserts and returns for elements
     588             :    */
     589             :   virtual void AppendTextTo(nsAString& aResult) = 0;
     590             : 
     591             :   /**
     592             :    * Append the text content to aResult.
     593             :    * NOTE: This asserts and returns for elements
     594             :    */
     595             :   MOZ_MUST_USE
     596             :   virtual bool AppendTextTo(nsAString& aResult, const mozilla::fallible_t&) = 0;
     597             : 
     598             :   /**
     599             :    * Check if this content is focusable and in the current tab order.
     600             :    * Note: most callers should use nsIFrame::IsFocusable() instead as it
     601             :    *       checks visibility and other layout factors as well.
     602             :    * Tabbable is indicated by a nonnegative tabindex & is a subset of focusable.
     603             :    * For example, only the selected radio button in a group is in the
     604             :    * tab order, unless the radio group has no selection in which case
     605             :    * all of the visible, non-disabled radio buttons in the group are
     606             :    * in the tab order. On the other hand, all of the visible, non-disabled
     607             :    * radio buttons are always focusable via clicking or script.
     608             :    * Also, depending on either the accessibility.tabfocus pref or
     609             :    * a system setting (nowadays: Full keyboard access, mac only)
     610             :    * some widgets may be focusable but removed from the tab order.
     611             :    * @param  [inout, optional] aTabIndex the computed tab index
     612             :    *         In: default tabindex for element (-1 nonfocusable, == 0 focusable)
     613             :    *         Out: computed tabindex
     614             :    * @param  [optional] aTabIndex the computed tab index
     615             :    *         < 0 if not tabbable
     616             :    *         == 0 if in normal tab order
     617             :    *         > 0 can be tabbed to in the order specified by this value
     618             :    * @return whether the content is focusable via mouse, kbd or script.
     619             :    */
     620             :   bool IsFocusable(int32_t* aTabIndex = nullptr, bool aWithMouse = false);
     621             :   virtual bool IsFocusableInternal(int32_t* aTabIndex, bool aWithMouse);
     622             : 
     623             :   /**
     624             :    * The method focuses (or activates) element that accesskey is bound to. It is
     625             :    * called when accesskey is activated.
     626             :    *
     627             :    * @param aKeyCausesActivation - if true then element should be activated
     628             :    * @param aIsTrustedEvent - if true then event that is cause of accesskey
     629             :    *                          execution is trusted.
     630             :    * @return true if the focus was changed.
     631             :    */
     632           0 :   virtual bool PerformAccesskey(bool aKeyCausesActivation,
     633             :                                 bool aIsTrustedEvent)
     634             :   {
     635           0 :     return false;
     636             :   }
     637             : 
     638             :   /*
     639             :    * Get desired IME state for the content.
     640             :    *
     641             :    * @return The desired IME status for the content.
     642             :    *         This is a combination of an IME enabled value and
     643             :    *         an IME open value of widget::IMEState.
     644             :    *         If you return DISABLED, you should not set the OPEN and CLOSE
     645             :    *         value.
     646             :    *         PASSWORD should be returned only from password editor, this value
     647             :    *         has a special meaning. It is used as alternative of DISABLED.
     648             :    *         PLUGIN should be returned only when plug-in has focus.  When a
     649             :    *         plug-in is focused content, we should send native events directly.
     650             :    *         Because we don't process some native events, but they may be needed
     651             :    *         by the plug-in.
     652             :    */
     653             :   virtual IMEState GetDesiredIMEState();
     654             : 
     655             :   /**
     656             :    * Gets content node with the binding (or native code, possibly on the
     657             :    * frame) responsible for our construction (and existence).  Used by
     658             :    * anonymous content (both XBL-generated and native-anonymous).
     659             :    *
     660             :    * null for all explicit content (i.e., content reachable from the top
     661             :    * of its GetParent() chain via child lists).
     662             :    *
     663             :    * @return the binding parent
     664             :    */
     665             :   virtual nsIContent *GetBindingParent() const = 0;
     666             : 
     667             :   /**
     668             :    * Gets the current XBL binding that is bound to this element.
     669             :    *
     670             :    * @return the current binding.
     671             :    */
     672             :   virtual nsXBLBinding *GetXBLBinding() const = 0;
     673             : 
     674             :   /**
     675             :    * Sets or unsets an XBL binding for this element. Setting a
     676             :    * binding on an element that already has a binding will remove the
     677             :    * old binding.
     678             :    *
     679             :    * @param aBinding The binding to bind to this content. If nullptr is
     680             :    *        provided as the argument, then existing binding will be
     681             :    *        removed.
     682             :    *
     683             :    * @param aOldBindingManager The old binding manager that contains
     684             :    *                           this content if this content was adopted
     685             :    *                           to another document.
     686             :    */
     687             :   virtual void SetXBLBinding(nsXBLBinding* aBinding,
     688             :                              nsBindingManager* aOldBindingManager = nullptr) = 0;
     689             : 
     690             :   /**
     691             :    * Sets the ShadowRoot binding for this element. The contents of the
     692             :    * binding is rendered in place of this node's children.
     693             :    *
     694             :    * @param aShadowRoot The ShadowRoot to be bound to this element.
     695             :    */
     696             :   virtual void SetShadowRoot(mozilla::dom::ShadowRoot* aShadowRoot) = 0;
     697             : 
     698             :   /**
     699             :    * Gets the ShadowRoot binding for this element.
     700             :    *
     701             :    * @return The ShadowRoot currently bound to this element.
     702             :    */
     703             :   inline mozilla::dom::ShadowRoot *GetShadowRoot() const;
     704             : 
     705             :   /**
     706             :    * Gets the root of the node tree for this content if it is in a shadow tree.
     707             :    * This method is called |GetContainingShadow| instead of |GetRootShadowRoot|
     708             :    * to avoid confusion with |GetShadowRoot|.
     709             :    *
     710             :    * @return The ShadowRoot that is the root of the node tree.
     711             :    */
     712             :   virtual mozilla::dom::ShadowRoot *GetContainingShadow() const = 0;
     713             : 
     714             :   /**
     715             :    * Gets an array of destination insertion points where this content
     716             :    * is distributed by web component distribution algorithms.
     717             :    * The array is created if it does not already exist.
     718             :    */
     719             :   virtual nsTArray<nsIContent*> &DestInsertionPoints() = 0;
     720             : 
     721             :   /**
     722             :    * Same as DestInsertionPoints except that this method will return
     723             :    * null if the array of destination insertion points does not already
     724             :    * exist.
     725             :    */
     726             :   virtual nsTArray<nsIContent*> *GetExistingDestInsertionPoints() const = 0;
     727             : 
     728             :   /**
     729             :    * Gets the insertion parent element of the XBL binding.
     730             :    * The insertion parent is our one true parent in the transformed DOM.
     731             :    *
     732             :    * @return the insertion parent element.
     733             :    */
     734             :   virtual nsIContent *GetXBLInsertionParent() const = 0;
     735             : 
     736             :   /**
     737             :    * Sets the insertion parent element of the XBL binding.
     738             :    *
     739             :    * @param aContent The insertion parent element.
     740             :    */
     741             :   virtual void SetXBLInsertionParent(nsIContent* aContent) = 0;
     742             : 
     743             :   /**
     744             :    * Same as GetFlattenedTreeParentNode, but returns null if the parent is
     745             :    * non-nsIContent.
     746             :    */
     747             :   inline nsIContent *GetFlattenedTreeParent() const;
     748             : 
     749             :   // Helper method, which we leave public so that it's accessible from nsINode.
     750             :   enum FlattenedParentType { eNotForStyle, eForStyle };
     751             :   nsINode* GetFlattenedTreeParentNodeInternal(FlattenedParentType aType) const;
     752             : 
     753             :   /**
     754             :    * API to check if this is a link that's traversed in response to user input
     755             :    * (e.g. a click event). Specializations for HTML/SVG/generic XML allow for
     756             :    * different types of link in different types of content.
     757             :    *
     758             :    * @param aURI Required out param. If this content is a link, a new nsIURI
     759             :    *             set to this link's URI will be passed out.
     760             :    *
     761             :    * @note The out param, aURI, is guaranteed to be set to a non-null pointer
     762             :    *   when the return value is true.
     763             :    *
     764             :    * XXXjwatt: IMO IsInteractiveLink would be a better name.
     765             :    */
     766             :   virtual bool IsLink(nsIURI** aURI) const = 0;
     767             : 
     768             :   /**
     769             :     * Get a pointer to the full href URI (fully resolved and canonicalized,
     770             :     * since it's an nsIURI object) for link elements.
     771             :     *
     772             :     * @return A pointer to the URI or null if the element is not a link or it
     773             :     *         has no HREF attribute.
     774             :     */
     775           0 :   virtual already_AddRefed<nsIURI> GetHrefURI() const
     776             :   {
     777           0 :     return nullptr;
     778             :   }
     779             : 
     780             :   /**
     781             :    * This method is called when the parser finishes creating the element.  This
     782             :    * particularly means that it has done everything you would expect it to have
     783             :    * done after it encounters the > at the end of the tag (for HTML or XML).
     784             :    * This includes setting the attributes, setting the document / form, and
     785             :    * placing the element into the tree at its proper place.
     786             :    *
     787             :    * For container elements, this is called *before* any of the children are
     788             :    * created or added into the tree.
     789             :    *
     790             :    * NOTE: this is currently only called for input and button, in the HTML
     791             :    * content sink.  If you want to call it on your element, modify the content
     792             :    * sink of your choice to do so.  This is an efficiency measure.
     793             :    *
     794             :    * If you also need to determine whether the parser is the one creating your
     795             :    * element (through createElement() or cloneNode() generally) then add a
     796             :    * uint32_t aFromParser to the NS_NewXXX() constructor for your element and
     797             :    * have the parser pass the appropriate flags. See HTMLInputElement.cpp and
     798             :    * nsHTMLContentSink::MakeContentObject().
     799             :    *
     800             :    * DO NOT USE THIS METHOD to get around the fact that it's hard to deal with
     801             :    * attributes dynamically.  If you make attributes affect your element from
     802             :    * this method, it will only happen on initialization and JavaScript will not
     803             :    * be able to create elements (which requires them to first create the
     804             :    * element and then call setAttribute() directly, at which point
     805             :    * DoneCreatingElement() has already been called and is out of the picture).
     806             :    */
     807           0 :   virtual void DoneCreatingElement()
     808             :   {
     809           0 :   }
     810             : 
     811             :   /**
     812             :    * This method is called when the parser begins creating the element's
     813             :    * children, if any are present.
     814             :    *
     815             :    * This is only called for XTF elements currently.
     816             :    */
     817           0 :   virtual void BeginAddingChildren()
     818             :   {
     819           0 :   }
     820             : 
     821             :   /**
     822             :    * This method is called when the parser finishes creating the element's children,
     823             :    * if any are present.
     824             :    *
     825             :    * NOTE: this is currently only called for textarea, select, applet, and
     826             :    * object elements in the HTML content sink.  If you want
     827             :    * to call it on your element, modify the content sink of your
     828             :    * choice to do so.  This is an efficiency measure.
     829             :    *
     830             :    * If you also need to determine whether the parser is the one creating your
     831             :    * element (through createElement() or cloneNode() generally) then add a
     832             :    * boolean aFromParser to the NS_NewXXX() constructor for your element and
     833             :    * have the parser pass true.  See HTMLInputElement.cpp and
     834             :    * nsHTMLContentSink::MakeContentObject().
     835             :    *
     836             :    * @param aHaveNotified Whether there has been a
     837             :    *        ContentInserted/ContentAppended notification for this content node
     838             :    *        yet.
     839             :    */
     840           0 :   virtual void DoneAddingChildren(bool aHaveNotified)
     841             :   {
     842           0 :   }
     843             : 
     844             :   /**
     845             :    * For HTML textarea, select, applet, and object elements, returns
     846             :    * true if all children have been added OR if the element was not
     847             :    * created by the parser. Returns true for all other elements.
     848             :    * @returns false if the element was created by the parser and
     849             :    *                   it is an HTML textarea, select, applet, or object
     850             :    *                   element and not all children have been added.
     851             :    * @returns true otherwise.
     852             :    */
     853           0 :   virtual bool IsDoneAddingChildren()
     854             :   {
     855           0 :     return true;
     856             :   }
     857             : 
     858             :   /**
     859             :    * Get the ID of this content node (the atom corresponding to the
     860             :    * value of the id attribute).  This may be null if there is no ID.
     861             :    */
     862      128711 :   nsIAtom* GetID() const {
     863      128711 :     if (HasID()) {
     864       73631 :       return DoGetID();
     865             :     }
     866       55080 :     return nullptr;
     867             :   }
     868             : 
     869             :   /**
     870             :    * Walk aRuleWalker over the content style rules (presentational
     871             :    * hint rules) for this content node.
     872             :    */
     873             :   NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) = 0;
     874             : 
     875             :   /**
     876             :    * Should be called when the node can become editable or when it can stop
     877             :    * being editable (for example when its contentEditable attribute changes,
     878             :    * when it is moved into an editable parent, ...).  If aNotify is true and
     879             :    * the node is an element, this will notify the state change.
     880             :    */
     881             :   virtual void UpdateEditableState(bool aNotify);
     882             : 
     883             :   /**
     884             :    * Destroy this node and its children. Ideally this shouldn't be needed
     885             :    * but for now we need to do it to break cycles.
     886             :    */
     887           0 :   virtual void DestroyContent()
     888             :   {
     889           0 :   }
     890             : 
     891             :   /**
     892             :    * Saves the form state of this node and its children.
     893             :    */
     894             :   virtual void SaveSubtreeState() = 0;
     895             : 
     896             :   /**
     897             :    * Getter and setter for our primary frame pointer.  This is the frame that
     898             :    * is most closely associated with the content. A frame is more closely
     899             :    * associated with the content than another frame if the one frame contains
     900             :    * directly or indirectly the other frame (e.g., when a frame is scrolled
     901             :    * there is a scroll frame that contains the frame being scrolled). This
     902             :    * frame is always the first continuation.
     903             :    *
     904             :    * In the case of absolutely positioned elements and floated elements, this
     905             :    * frame is the out of flow frame, not the placeholder.
     906             :    */
     907       16178 :   nsIFrame* GetPrimaryFrame() const
     908             :   {
     909       16178 :     return (IsInUncomposedDoc() || IsInShadowTree()) ? mPrimaryFrame : nullptr;
     910             :   }
     911         625 :   void SetPrimaryFrame(nsIFrame* aFrame) {
     912         625 :     MOZ_ASSERT(IsInUncomposedDoc() || IsInShadowTree(), "This will end badly!");
     913         625 :     NS_PRECONDITION(!aFrame || !mPrimaryFrame || aFrame == mPrimaryFrame,
     914             :                     "Losing track of existing primary frame");
     915         625 :     mPrimaryFrame = aFrame;
     916         625 :   }
     917             : 
     918             :   nsresult LookupNamespaceURIInternal(const nsAString& aNamespacePrefix,
     919             :                                       nsAString& aNamespaceURI) const;
     920             : 
     921             :   /**
     922             :    * If this content has independent selection, e.g., if this is input field
     923             :    * or textarea, this return TRUE.  Otherwise, false.
     924             :    */
     925             :   bool HasIndependentSelection();
     926             : 
     927             :   /**
     928             :    * If the content is a part of HTML editor, this returns editing
     929             :    * host content.  When the content is in designMode, this returns its body
     930             :    * element.  Also, when the content isn't editable, this returns null.
     931             :    */
     932             :   mozilla::dom::Element* GetEditingHost();
     933             : 
     934           0 :   bool SupportsLangAttr() const {
     935           0 :     return IsHTMLElement() || IsSVGElement() || IsXULElement();
     936             :   }
     937             : 
     938             :   /**
     939             :    * Determining language. Look at the nearest ancestor element that has a lang
     940             :    * attribute in the XML namespace or is an HTML/SVG element and has a lang in
     941             :    * no namespace attribute.
     942             :    *
     943             :    * Returns null if no language was specified. Can return the empty atom.
     944             :    */
     945             :   nsIAtom* GetLang() const;
     946             : 
     947           0 :   bool GetLang(nsAString& aResult) const {
     948           0 :     if (auto* lang = GetLang()) {
     949           0 :       aResult.Assign(nsDependentAtomString(lang));
     950           0 :       return true;
     951             :     }
     952             : 
     953           0 :     return false;
     954             :   }
     955             : 
     956             :   // Returns true if this element is native-anonymous scrollbar content.
     957         167 :   bool IsNativeScrollbarContent() const {
     958         311 :     return IsNativeAnonymous() &&
     959         144 :            IsAnyOfXULElements(nsGkAtoms::scrollbar,
     960             :                               nsGkAtoms::resizer,
     961         167 :                               nsGkAtoms::scrollcorner);
     962             :   }
     963             : 
     964             :   // Overloaded from nsINode
     965             :   virtual already_AddRefed<nsIURI> GetBaseURI(bool aTryUseXHRDocBaseURI = false) const override;
     966             : 
     967             :   // Returns base URI for style attribute.
     968             :   already_AddRefed<nsIURI> GetBaseURIForStyleAttr() const;
     969             : 
     970             :   // Returns the URL data for style attribute.
     971             :   mozilla::URLExtraData* GetURLDataForStyleAttr() const;
     972             : 
     973             :   virtual nsresult GetEventTargetParent(
     974             :                      mozilla::EventChainPreVisitor& aVisitor) override;
     975             : 
     976             :   virtual bool IsPurple() = 0;
     977             :   virtual void RemovePurple() = 0;
     978             : 
     979           0 :   virtual bool OwnedOnlyByTheDOMTree() { return false; }
     980             : protected:
     981             :   /**
     982             :    * Hook for implementing GetID.  This is guaranteed to only be
     983             :    * called if HasID() is true.
     984             :    */
     985             :   nsIAtom* DoGetID() const;
     986             : 
     987             :   // Returns base URI without considering xml:base.
     988             :   inline nsIURI* GetBaseURIWithoutXMLBase() const;
     989             : 
     990             : public:
     991             : #ifdef DEBUG
     992             :   /**
     993             :    * List the content (and anything it contains) out to the given
     994             :    * file stream. Use aIndent as the base indent during formatting.
     995             :    */
     996             :   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const = 0;
     997             : 
     998             :   /**
     999             :    * Dump the content (and anything it contains) out to the given
    1000             :    * file stream. Use aIndent as the base indent during formatting.
    1001             :    */
    1002             :   virtual void DumpContent(FILE* out = stdout, int32_t aIndent = 0,
    1003             :                            bool aDumpAll = true) const = 0;
    1004             : #endif
    1005             : 
    1006             :   /**
    1007             :    * Append to aOutDescription a short (preferably one line) string
    1008             :    * describing the content.
    1009             :    * Currently implemented for elements only.
    1010             :    */
    1011           0 :   virtual void Describe(nsAString& aOutDescription) const {
    1012           0 :     aOutDescription = NS_LITERAL_STRING("(not an element)");
    1013           0 :   }
    1014             : 
    1015             :   enum ETabFocusType {
    1016             :     eTabFocus_textControlsMask = (1<<0),  // textboxes and lists always tabbable
    1017             :     eTabFocus_formElementsMask = (1<<1),  // non-text form elements
    1018             :     eTabFocus_linksMask = (1<<2),         // links
    1019             :     eTabFocus_any = 1 + (1<<1) + (1<<2)   // everything that can be focused
    1020             :   };
    1021             : 
    1022             :   // Tab focus model bit field:
    1023             :   static int32_t sTabFocusModel;
    1024             : 
    1025             :   // accessibility.tabfocus_applies_to_xul pref - if it is set to true,
    1026             :   // the tabfocus bit field applies to xul elements.
    1027             :   static bool sTabFocusModelAppliesToXUL;
    1028             : };
    1029             : 
    1030             : NS_DEFINE_STATIC_IID_ACCESSOR(nsIContent, NS_ICONTENT_IID)
    1031             : 
    1032       22936 : inline nsIContent* nsINode::AsContent()
    1033             : {
    1034       22936 :   MOZ_ASSERT(IsContent());
    1035       22936 :   return static_cast<nsIContent*>(this);
    1036             : }
    1037             : 
    1038             : #define NS_IMPL_FROMCONTENT_HELPER(_class, _check)                             \
    1039             :   static _class* FromContent(nsIContent* aContent)                             \
    1040             :   {                                                                            \
    1041             :     return aContent->_check ? static_cast<_class*>(aContent) : nullptr;        \
    1042             :   }                                                                            \
    1043             :   static const _class* FromContent(const nsIContent* aContent)                 \
    1044             :   {                                                                            \
    1045             :     return aContent->_check ? static_cast<const _class*>(aContent) : nullptr;  \
    1046             :   }                                                                            \
    1047             :   static _class* FromContentOrNull(nsIContent* aContent)                       \
    1048             :   {                                                                            \
    1049             :     return aContent ? FromContent(aContent) : nullptr;                         \
    1050             :   }                                                                            \
    1051             :   static const _class* FromContentOrNull(const nsIContent* aContent)           \
    1052             :   {                                                                            \
    1053             :     return aContent ? FromContent(aContent) : nullptr;                         \
    1054             :   }
    1055             : 
    1056             : #define NS_IMPL_FROMCONTENT(_class, _nsid)                                     \
    1057             :   NS_IMPL_FROMCONTENT_HELPER(_class, IsInNamespace(_nsid))
    1058             : 
    1059             : #define NS_IMPL_FROMCONTENT_WITH_TAG(_class, _nsid, _tag)                      \
    1060             :   NS_IMPL_FROMCONTENT_HELPER(_class, NodeInfo()->Equals(nsGkAtoms::_tag, _nsid))
    1061             : 
    1062             : #define NS_IMPL_FROMCONTENT_HTML_WITH_TAG(_class, _tag)                        \
    1063             :   NS_IMPL_FROMCONTENT_WITH_TAG(_class, kNameSpaceID_XHTML, _tag)
    1064             : 
    1065             : #endif /* nsIContent_h___ */

Generated by: LCOV version 1.13