LCOV - code coverage report
Current view: top level - dom/base - Element.h (source / functions) Hit Total Coverage
Test: output.info Lines: 156 294 53.1 %
Date: 2017-07-14 16:53:18 Functions: 48 94 51.1 %
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             : 
       7             : /*
       8             :  * Base class for all element classes; this provides an implementation
       9             :  * of DOM Core's nsIDOMElement, implements nsIContent, provides
      10             :  * utility methods for subclasses, and so forth.
      11             :  */
      12             : 
      13             : #ifndef mozilla_dom_Element_h__
      14             : #define mozilla_dom_Element_h__
      15             : 
      16             : #include "mozilla/dom/FragmentOrElement.h" // for base class
      17             : #include "nsChangeHint.h"                  // for enum
      18             : #include "mozilla/EventStates.h"           // for member
      19             : #include "mozilla/ServoTypes.h"
      20             : #include "mozilla/dom/DirectionalityUtils.h"
      21             : #include "nsIDOMElement.h"
      22             : #include "nsILinkHandler.h"
      23             : #include "nsINodeList.h"
      24             : #include "nsNodeUtils.h"
      25             : #include "nsAttrAndChildArray.h"
      26             : #include "mozilla/FlushType.h"
      27             : #include "nsDOMAttributeMap.h"
      28             : #include "nsPresContext.h"
      29             : #include "mozilla/CORSMode.h"
      30             : #include "mozilla/Attributes.h"
      31             : #include "nsIScrollableFrame.h"
      32             : #include "mozilla/dom/Attr.h"
      33             : #include "nsISMILAttr.h"
      34             : #include "mozilla/dom/DOMRect.h"
      35             : #include "nsAttrValue.h"
      36             : #include "mozilla/EventForwards.h"
      37             : #include "mozilla/dom/BindingDeclarations.h"
      38             : #include "mozilla/dom/DOMTokenListSupportedTokens.h"
      39             : #include "mozilla/dom/WindowBinding.h"
      40             : #include "mozilla/dom/ElementBinding.h"
      41             : #include "mozilla/dom/Nullable.h"
      42             : #include "mozilla/UniquePtr.h"
      43             : #include "Units.h"
      44             : #include "DOMIntersectionObserver.h"
      45             : 
      46             : class mozAutoDocUpdate;
      47             : class nsIFrame;
      48             : class nsIDOMMozNamedAttrMap;
      49             : class nsIMozBrowserFrame;
      50             : class nsIURI;
      51             : class nsIScrollableFrame;
      52             : class nsAttrValueOrString;
      53             : class nsContentList;
      54             : class nsDOMTokenList;
      55             : struct nsRect;
      56             : class nsFocusManager;
      57             : class nsGlobalWindow;
      58             : class nsICSSDeclaration;
      59             : class nsISMILAttr;
      60             : class nsDocument;
      61             : class nsDOMStringMap;
      62             : 
      63             : namespace mozilla {
      64             : class DeclarationBlock;
      65             : class TextEditor;
      66             : namespace dom {
      67             :   struct AnimationFilter;
      68             :   struct ScrollIntoViewOptions;
      69             :   struct ScrollToOptions;
      70             :   class DOMIntersectionObserver;
      71             :   class DOMMatrixReadOnly;
      72             :   class ElementOrCSSPseudoElement;
      73             :   class UnrestrictedDoubleOrKeyframeAnimationOptions;
      74             :   enum class CallerType : uint32_t;
      75             : } // namespace dom
      76             : } // namespace mozilla
      77             : 
      78             : 
      79             : already_AddRefed<nsContentList>
      80             : NS_GetContentList(nsINode* aRootNode,
      81             :                   int32_t  aMatchNameSpaceId,
      82             :                   const nsAString& aTagname);
      83             : 
      84             : #define ELEMENT_FLAG_BIT(n_) NODE_FLAG_BIT(NODE_TYPE_SPECIFIC_BITS_OFFSET + (n_))
      85             : 
      86             : // Element-specific flags
      87             : enum {
      88             :   // These two bits are shared by Gecko's and Servo's restyle systems for
      89             :   // different purposes. They should not be accessed directly, and access to
      90             :   // them should be properly guarded by asserts.
      91             :   ELEMENT_SHARED_RESTYLE_BIT_1 = ELEMENT_FLAG_BIT(0),
      92             :   ELEMENT_SHARED_RESTYLE_BIT_2 = ELEMENT_FLAG_BIT(1),
      93             :   ELEMENT_SHARED_RESTYLE_BIT_3 = ELEMENT_FLAG_BIT(2),
      94             :   ELEMENT_SHARED_RESTYLE_BIT_4 = ELEMENT_FLAG_BIT(3),
      95             : 
      96             :   // Whether this node has dirty descendants for Servo's style system.
      97             :   ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO = ELEMENT_SHARED_RESTYLE_BIT_1,
      98             : 
      99             :   // Whether this node has dirty descendants for animation-only restyle for
     100             :   // Servo's style system.
     101             :   ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO =
     102             :     ELEMENT_SHARED_RESTYLE_BIT_2,
     103             : 
     104             :   // Whether the element has been snapshotted due to attribute or state changes
     105             :   // by the Servo restyle manager.
     106             :   ELEMENT_HAS_SNAPSHOT = ELEMENT_SHARED_RESTYLE_BIT_3,
     107             : 
     108             :   // Whether the element has already handled its relevant snapshot.
     109             :   //
     110             :   // Used by the servo restyle process in order to accurately track whether the
     111             :   // style of an element is up-to-date, even during the same restyle process.
     112             :   ELEMENT_HANDLED_SNAPSHOT = ELEMENT_SHARED_RESTYLE_BIT_4,
     113             : 
     114             :   // Set if the element has a pending style change.
     115             :   ELEMENT_HAS_PENDING_RESTYLE = ELEMENT_SHARED_RESTYLE_BIT_1,
     116             : 
     117             :   // Set if the element is a potential restyle root (that is, has a style
     118             :   // change pending _and_ that style change will attempt to restyle
     119             :   // descendants).
     120             :   ELEMENT_IS_POTENTIAL_RESTYLE_ROOT = ELEMENT_SHARED_RESTYLE_BIT_2,
     121             : 
     122             :   // Set if the element has a pending animation-only style change as
     123             :   // part of an animation-only style update (where we update styles from
     124             :   // animation to the current refresh tick, but leave everything else as
     125             :   // it was).
     126             :   ELEMENT_HAS_PENDING_ANIMATION_ONLY_RESTYLE = ELEMENT_SHARED_RESTYLE_BIT_3,
     127             : 
     128             :   // Set if the element is a potential animation-only restyle root (that
     129             :   // is, has an animation-only style change pending _and_ that style
     130             :   // change will attempt to restyle descendants).
     131             :   ELEMENT_IS_POTENTIAL_ANIMATION_ONLY_RESTYLE_ROOT = ELEMENT_SHARED_RESTYLE_BIT_4,
     132             : 
     133             :   // Set if this element has a pending restyle with an eRestyle_SomeDescendants
     134             :   // restyle hint.
     135             :   ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR = ELEMENT_FLAG_BIT(4),
     136             : 
     137             :   // Just the HAS_PENDING bits, for convenience
     138             :   ELEMENT_PENDING_RESTYLE_FLAGS =
     139             :     ELEMENT_HAS_PENDING_RESTYLE |
     140             :     ELEMENT_HAS_PENDING_ANIMATION_ONLY_RESTYLE,
     141             : 
     142             :   // Just the IS_POTENTIAL bits, for convenience
     143             :   ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS =
     144             :     ELEMENT_IS_POTENTIAL_RESTYLE_ROOT |
     145             :     ELEMENT_IS_POTENTIAL_ANIMATION_ONLY_RESTYLE_ROOT,
     146             : 
     147             :   // All of the restyle bits together, for convenience.
     148             :   ELEMENT_ALL_RESTYLE_FLAGS = ELEMENT_PENDING_RESTYLE_FLAGS |
     149             :                               ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS |
     150             :                               ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR,
     151             : 
     152             :   // ELEMENT_FLAG_BIT(5) is currently unused
     153             : 
     154             :   // Remaining bits are for subclasses
     155             :   ELEMENT_TYPE_SPECIFIC_BITS_OFFSET = NODE_TYPE_SPECIFIC_BITS_OFFSET + 6
     156             : };
     157             : 
     158             : #undef ELEMENT_FLAG_BIT
     159             : 
     160             : // Make sure we have space for our bits
     161             : ASSERT_NODE_FLAGS_SPACE(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET);
     162             : 
     163             : namespace mozilla {
     164             : enum class CSSPseudoElementType : uint8_t;
     165             : class EventChainPostVisitor;
     166             : class EventChainPreVisitor;
     167             : class EventChainVisitor;
     168             : class EventListenerManager;
     169             : class EventStateManager;
     170             : 
     171             : namespace dom {
     172             : 
     173             : class Animation;
     174             : class CustomElementRegistry;
     175             : class Link;
     176             : class DOMRect;
     177             : class DOMRectList;
     178             : class DestinationInsertionPointList;
     179             : class Grid;
     180             : 
     181             : // IID for the dom::Element interface
     182             : #define NS_ELEMENT_IID \
     183             : { 0xc67ed254, 0xfd3b, 0x4b10, \
     184             :   { 0x96, 0xa2, 0xc5, 0x8b, 0x7b, 0x64, 0x97, 0xd1 } }
     185             : 
     186             : class Element : public FragmentOrElement
     187             : {
     188             : public:
     189             : #ifdef MOZILLA_INTERNAL_API
     190        3168 :   explicit Element(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo) :
     191             :     FragmentOrElement(aNodeInfo),
     192        3168 :     mState(NS_EVENT_STATE_MOZ_READONLY)
     193             :   {
     194        3168 :     MOZ_ASSERT(mNodeInfo->NodeType() == nsIDOMNode::ELEMENT_NODE,
     195             :                "Bad NodeType in aNodeInfo");
     196        3168 :     SetIsElement();
     197        3168 :   }
     198             : 
     199          32 :   ~Element()
     200          64 :   {
     201          32 :     NS_ASSERTION(!HasServoData(), "expected ServoData to be cleared earlier");
     202          32 :   }
     203             : 
     204             : #endif // MOZILLA_INTERNAL_API
     205             : 
     206             :   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ELEMENT_IID)
     207             : 
     208             :   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
     209             : 
     210             :   /**
     211             :    * Method to get the full state of this element.  See mozilla/EventStates.h
     212             :    * for the possible bits that could be set here.
     213             :    */
     214         488 :   EventStates State() const
     215             :   {
     216             :     // mState is maintained by having whoever might have changed it
     217             :     // call UpdateState() or one of the other mState mutators.
     218         488 :     return mState;
     219             :   }
     220             : 
     221             :   /**
     222             :    * Ask this element to update its state.  If aNotify is false, then
     223             :    * state change notifications will not be dispatched; in that
     224             :    * situation it is the caller's responsibility to dispatch them.
     225             :    *
     226             :    * In general, aNotify should only be false if we're guaranteed that
     227             :    * the element can't have a frame no matter what its style is
     228             :    * (e.g. if we're in the middle of adding it to the document or
     229             :    * removing it from the document).
     230             :    */
     231             :   void UpdateState(bool aNotify);
     232             : 
     233             :   /**
     234             :    * Method to update mState with link state information.  This does not notify.
     235             :    */
     236             :   void UpdateLinkState(EventStates aState);
     237             : 
     238           0 :   virtual int32_t TabIndexDefault()
     239             :   {
     240           0 :     return -1;
     241             :   }
     242             : 
     243             :   /**
     244             :    * Get tabIndex of this element. If not found, return TabIndexDefault.
     245             :    */
     246             :   int32_t TabIndex();
     247             : 
     248             :   /**
     249             :    * Set tabIndex value to this element.
     250             :    */
     251             :   void SetTabIndex(int32_t aTabIndex, mozilla::ErrorResult& aError);
     252             : 
     253             :   /**
     254             :    * Make focus on this element.
     255             :    */
     256             :   virtual void Focus(mozilla::ErrorResult& aError);
     257             : 
     258             :   /**
     259             :    * Show blur and clear focus.
     260             :    */
     261             :   virtual void Blur(mozilla::ErrorResult& aError);
     262             : 
     263             :   /**
     264             :    * The style state of this element. This is the real state of the element
     265             :    * with any style locks applied for pseudo-class inspecting.
     266             :    */
     267       55360 :   EventStates StyleState() const
     268             :   {
     269       55360 :     if (!HasLockedStyleStates()) {
     270       55360 :       return mState;
     271             :     }
     272           0 :     return StyleStateFromLocks();
     273             :   }
     274             : 
     275             :   /**
     276             :    * StyleStateLocks is used to specify which event states should be locked,
     277             :    * and whether they should be locked to on or off.
     278             :    */
     279           0 :   struct StyleStateLocks {
     280             :     // mLocks tracks which event states should be locked.
     281             :     EventStates mLocks;
     282             :     // mValues tracks if the locked state should be on or off.
     283             :     EventStates mValues;
     284             :   };
     285             : 
     286             :   /**
     287             :    * The style state locks applied to this element.
     288             :    */
     289             :   StyleStateLocks LockedStyleStates() const;
     290             : 
     291             :   /**
     292             :    * Add a style state lock on this element.
     293             :    * aEnabled is the value to lock the given state bits to.
     294             :    */
     295             :   void LockStyleStates(EventStates aStates, bool aEnabled);
     296             : 
     297             :   /**
     298             :    * Remove a style state lock on this element.
     299             :    */
     300             :   void UnlockStyleStates(EventStates aStates);
     301             : 
     302             :   /**
     303             :    * Clear all style state locks on this element.
     304             :    */
     305             :   void ClearStyleStateLocks();
     306             : 
     307             :   /**
     308             :    * Accessors for the state of our dir attribute.
     309             :    */
     310         456 :   bool HasDirAuto() const
     311             :   {
     312         456 :     return State().HasState(NS_EVENT_STATE_DIR_ATTR_LIKE_AUTO);
     313             :   }
     314             : 
     315             :   /**
     316             :    * Elements with dir="rtl" or dir="ltr".
     317             :    */
     318           0 :   bool HasFixedDir() const
     319             :   {
     320           0 :     return State().HasAtLeastOneOfStates(NS_EVENT_STATE_DIR_ATTR_LTR |
     321      156453 :                                          NS_EVENT_STATE_DIR_ATTR_RTL);
     322             :   }
     323             : 
     324             :   /**
     325             :    * Get the inline style declaration, if any, for this element.
     326             :    */
     327             :   DeclarationBlock* GetInlineStyleDeclaration() const;
     328             : 
     329             :   /**
     330             :    * Get the mapped attributes, if any, for this element.
     331             :    */
     332             :   const nsMappedAttributes* GetMappedAttributes() const;
     333             : 
     334           0 :   void ClearMappedServoStyle() {
     335           0 :     mAttrsAndChildren.ClearMappedServoStyle();
     336           0 :   }
     337             : 
     338             :   /**
     339             :    * Set the inline style declaration for this element. This will send
     340             :    * an appropriate AttributeChanged notification if aNotify is true.
     341             :    */
     342             :   virtual nsresult SetInlineStyleDeclaration(DeclarationBlock* aDeclaration,
     343             :                                              const nsAString* aSerialized,
     344             :                                              bool aNotify);
     345             : 
     346             :   /**
     347             :    * Get the SMIL override style declaration for this element. If the
     348             :    * rule hasn't been created, this method simply returns null.
     349             :    */
     350             :   DeclarationBlock* GetSMILOverrideStyleDeclaration();
     351             : 
     352             :   /**
     353             :    * Set the SMIL override style declaration for this element. If
     354             :    * aNotify is true, this method will notify the document's pres
     355             :    * context, so that the style changes will be noticed.
     356             :    */
     357             :   nsresult SetSMILOverrideStyleDeclaration(DeclarationBlock* aDeclaration,
     358             :                                            bool aNotify);
     359             : 
     360             :   /**
     361             :    * Returns a new nsISMILAttr that allows the caller to animate the given
     362             :    * attribute on this element.
     363             :    */
     364           0 :   virtual UniquePtr<nsISMILAttr> GetAnimatedAttr(int32_t aNamespaceID,
     365             :                                                  nsIAtom* aName)
     366             :   {
     367           0 :     return nullptr;
     368             :   }
     369             : 
     370             :   /**
     371             :    * Get the SMIL override style for this element. This is a style declaration
     372             :    * that is applied *after* the inline style, and it can be used e.g. to store
     373             :    * animated style values.
     374             :    *
     375             :    * Note: This method is analogous to the 'GetStyle' method in
     376             :    * nsGenericHTMLElement and nsStyledElement.
     377             :    */
     378             :   nsICSSDeclaration* GetSMILOverrideStyle();
     379             : 
     380             :   /**
     381             :    * Returns if the element is labelable as per HTML specification.
     382             :    */
     383             :   virtual bool IsLabelable() const;
     384             : 
     385             :   /**
     386             :    * Returns if the element is interactive content as per HTML specification.
     387             :    */
     388             :   virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const;
     389             : 
     390             :   /**
     391             :    * Returns |this| as an nsIMozBrowserFrame* if the element is a frame or
     392             :    * iframe element.
     393             :    *
     394             :    * We have this method, rather than using QI, so that we can use it during
     395             :    * the servo traversal, where we can't QI DOM nodes because of non-thread-safe
     396             :    * refcounts.
     397             :    */
     398           0 :   virtual nsIMozBrowserFrame* GetAsMozBrowserFrame() { return nullptr; }
     399             : 
     400             :   /**
     401             :    * Is the attribute named stored in the mapped attributes?
     402             :    *
     403             :    * // XXXbz we use this method in HasAttributeDependentStyle, so svg
     404             :    *    returns true here even though it stores nothing in the mapped
     405             :    *    attributes.
     406             :    */
     407             :   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
     408             : 
     409             :   /**
     410             :    * Get a hint that tells the style system what to do when
     411             :    * an attribute on this node changes, if something needs to happen
     412             :    * in response to the change *other* than the result of what is
     413             :    * mapped into style data via any type of style rule.
     414             :    */
     415             :   virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
     416             :                                               int32_t aModType) const;
     417             : 
     418         502 :   inline Directionality GetDirectionality() const {
     419         502 :     if (HasFlag(NODE_HAS_DIRECTION_RTL)) {
     420           0 :       return eDir_RTL;
     421             :     }
     422             : 
     423         502 :     if (HasFlag(NODE_HAS_DIRECTION_LTR)) {
     424         416 :       return eDir_LTR;
     425             :     }
     426             : 
     427          86 :     return eDir_NotSet;
     428             :   }
     429             : 
     430         140 :   inline void SetDirectionality(Directionality aDir, bool aNotify) {
     431         140 :     UnsetFlags(NODE_ALL_DIRECTION_FLAGS);
     432         140 :     if (!aNotify) {
     433         140 :       RemoveStatesSilently(DIRECTION_STATES);
     434             :     }
     435             : 
     436         140 :     switch (aDir) {
     437             :       case (eDir_RTL):
     438           0 :         SetFlags(NODE_HAS_DIRECTION_RTL);
     439           0 :         if (!aNotify) {
     440           0 :           AddStatesSilently(NS_EVENT_STATE_RTL);
     441             :         }
     442           0 :         break;
     443             : 
     444             :       case(eDir_LTR):
     445         140 :         SetFlags(NODE_HAS_DIRECTION_LTR);
     446         140 :         if (!aNotify) {
     447         140 :           AddStatesSilently(NS_EVENT_STATE_LTR);
     448             :         }
     449         140 :         break;
     450             : 
     451             :       default:
     452           0 :         break;
     453             :     }
     454             : 
     455             :     /*
     456             :      * Only call UpdateState if we need to notify, because we call
     457             :      * SetDirectionality for every element, and UpdateState is very very slow
     458             :      * for some elements.
     459             :      */
     460         140 :     if (aNotify) {
     461           0 :       UpdateState(true);
     462             :     }
     463         140 :   }
     464             : 
     465             :   bool GetBindingURL(nsIDocument* aDocument, css::URLValue **aResult);
     466             : 
     467             :   Directionality GetComputedDirectionality() const;
     468             : 
     469             :   inline Element* GetFlattenedTreeParentElement() const;
     470             :   inline Element* GetFlattenedTreeParentElementForStyle() const;
     471             : 
     472           0 :   bool HasDirtyDescendantsForServo() const
     473             :   {
     474           0 :     MOZ_ASSERT(IsStyledByServo());
     475           0 :     return HasFlag(ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO);
     476             :   }
     477             : 
     478           0 :   void SetHasDirtyDescendantsForServo() {
     479           0 :     MOZ_ASSERT(IsStyledByServo());
     480           0 :     SetFlags(ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO);
     481           0 :   }
     482             : 
     483           0 :   void UnsetHasDirtyDescendantsForServo() {
     484           0 :     MOZ_ASSERT(IsStyledByServo());
     485           0 :     UnsetFlags(ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO);
     486           0 :   }
     487             : 
     488             :   inline void NoteDirtyDescendantsForServo();
     489             : 
     490           0 :   bool HasAnimationOnlyDirtyDescendantsForServo() const {
     491           0 :     MOZ_ASSERT(IsStyledByServo());
     492           0 :     return HasFlag(ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO);
     493             :   }
     494             : 
     495           0 :   void UnsetHasAnimationOnlyDirtyDescendantsForServo() {
     496           0 :     MOZ_ASSERT(IsStyledByServo());
     497           0 :     UnsetFlags(ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO);
     498           0 :   }
     499             : 
     500             : #ifdef DEBUG
     501             :   inline bool DirtyDescendantsBitIsPropagatedForServo();
     502             : #endif
     503             : 
     504         956 :   bool HasServoData() const {
     505         956 :     return !!mServoData.Get();
     506             :   }
     507             : 
     508             :   void ClearServoData();
     509             : 
     510             :   /**
     511             :    * Gets the custom element data used by web components custom element.
     512             :    * Custom element data is created at the first attempt to enqueue a callback.
     513             :    *
     514             :    * @return The custom element data or null if none.
     515             :    */
     516        5551 :   inline CustomElementData* GetCustomElementData() const
     517             :   {
     518        5551 :     nsDOMSlots *slots = GetExistingDOMSlots();
     519        5551 :     if (slots) {
     520        1038 :       return slots->mCustomElementData;
     521             :     }
     522        4513 :     return nullptr;
     523             :   }
     524             : 
     525             :   /**
     526             :    * Sets the custom element data, ownership of the
     527             :    * callback data is taken by this element.
     528             :    *
     529             :    * @param aData The custom element data.
     530             :    */
     531             :   void SetCustomElementData(CustomElementData* aData);
     532             : 
     533             : protected:
     534             :   /**
     535             :    * Method to get the _intrinsic_ content state of this element.  This is the
     536             :    * state that is independent of the element's presentation.  To get the full
     537             :    * content state, use State().  See mozilla/EventStates.h for
     538             :    * the possible bits that could be set here.
     539             :    */
     540             :   virtual EventStates IntrinsicState() const;
     541             : 
     542             :   /**
     543             :    * Method to add state bits.  This should be called from subclass
     544             :    * constructors to set up our event state correctly at construction
     545             :    * time and other places where we don't want to notify a state
     546             :    * change.
     547             :    */
     548        1348 :   void AddStatesSilently(EventStates aStates)
     549             :   {
     550        1348 :     mState |= aStates;
     551        1348 :   }
     552             : 
     553             :   /**
     554             :    * Method to remove state bits.  This should be called from subclass
     555             :    * constructors to set up our event state correctly at construction
     556             :    * time and other places where we don't want to notify a state
     557             :    * change.
     558             :    */
     559        1225 :   void RemoveStatesSilently(EventStates aStates)
     560             :   {
     561        1225 :     mState &= ~aStates;
     562        1225 :   }
     563             : 
     564             : private:
     565             :   // Need to allow the ESM, nsGlobalWindow, and the focus manager to
     566             :   // set our state
     567             :   friend class mozilla::EventStateManager;
     568             :   friend class ::nsGlobalWindow;
     569             :   friend class ::nsFocusManager;
     570             : 
     571             :   // Allow CusomtElementRegistry to call AddStates.
     572             :   friend class CustomElementRegistry;
     573             : 
     574             :   // Also need to allow Link to call UpdateLinkState.
     575             :   friend class Link;
     576             : 
     577             :   void NotifyStateChange(EventStates aStates);
     578             : 
     579             :   void NotifyStyleStateChange(EventStates aStates);
     580             : 
     581             :   // Style state computed from element's state and style locks.
     582             :   EventStates StyleStateFromLocks() const;
     583             : 
     584             : protected:
     585             :   // Methods for the ESM, nsGlobalWindow and focus manager to manage state bits.
     586             :   // These will handle setting up script blockers when they notify, so no need
     587             :   // to do it in the callers unless desired.  States passed here must only be
     588             :   // those in EXTERNALLY_MANAGED_STATES.
     589          31 :   virtual void AddStates(EventStates aStates)
     590             :   {
     591          31 :     NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
     592             :                     "Should only be adding externally-managed states here");
     593          31 :     AddStatesSilently(aStates);
     594          31 :     NotifyStateChange(aStates);
     595          31 :   }
     596          14 :   virtual void RemoveStates(EventStates aStates)
     597             :   {
     598          14 :     NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
     599             :                     "Should only be removing externally-managed states here");
     600          14 :     RemoveStatesSilently(aStates);
     601          14 :     NotifyStateChange(aStates);
     602          14 :   }
     603           0 :   virtual void ToggleStates(EventStates aStates, bool aNotify)
     604             :   {
     605           0 :     NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
     606             :                     "Should only be removing externally-managed states here");
     607           0 :     mState ^= aStates;
     608           0 :     if (aNotify) {
     609           0 :       NotifyStateChange(aStates);
     610             :     }
     611           0 :   }
     612             : 
     613             : public:
     614             :   // Public methods to manage state bits in MANUALLY_MANAGED_STATES.
     615           0 :   void AddManuallyManagedStates(EventStates aStates)
     616             :   {
     617           0 :     MOZ_ASSERT(MANUALLY_MANAGED_STATES.HasAllStates(aStates),
     618             :                "Should only be adding manually-managed states here");
     619           0 :     AddStates(aStates);
     620           0 :   }
     621           0 :   void RemoveManuallyManagedStates(EventStates aStates)
     622             :   {
     623           0 :     MOZ_ASSERT(MANUALLY_MANAGED_STATES.HasAllStates(aStates),
     624             :                "Should only be removing manually-managed states here");
     625           0 :     RemoveStates(aStates);
     626           0 :   }
     627             : 
     628             :   virtual void UpdateEditableState(bool aNotify) override;
     629             : 
     630             :   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
     631             :                               nsIContent* aBindingParent,
     632             :                               bool aCompileEventHandlers) override;
     633             :   virtual void UnbindFromTree(bool aDeep = true,
     634             :                               bool aNullParent = true) override;
     635             : 
     636             :   /**
     637             :    * Normalizes an attribute name and returns it as a nodeinfo if an attribute
     638             :    * with that name exists. This method is intended for character case
     639             :    * conversion if the content object is case insensitive (e.g. HTML). Returns
     640             :    * the nodeinfo of the attribute with the specified name if one exists or
     641             :    * null otherwise.
     642             :    *
     643             :    * @param aStr the unparsed attribute string
     644             :    * @return the node info. May be nullptr.
     645             :    */
     646             :   already_AddRefed<mozilla::dom::NodeInfo>
     647             :   GetExistingAttrNameFromQName(const nsAString& aStr) const;
     648             : 
     649             :   MOZ_ALWAYS_INLINE  // Avoid a crashy hook from Avast 10 Beta (Bug 1058131)
     650         418 :   nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
     651             :                    const nsAString& aValue, bool aNotify)
     652             :   {
     653         418 :     return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
     654             :   }
     655             : 
     656             :   /**
     657             :    * Helper for SetAttr/SetParsedAttr. This method will return true if aNotify
     658             :    * is true or there are mutation listeners that must be triggered, the
     659             :    * attribute is currently set, and the new value that is about to be set is
     660             :    * different to the current value. As a perf optimization the new and old
     661             :    * values will not actually be compared if we aren't notifying and we don't
     662             :    * have mutation listeners (in which case it's cheap to just return false
     663             :    * and let the caller go ahead and set the value).
     664             :    * @param aOldValue [out] Set to the old value of the attribute, but only if
     665             :    *   there are event listeners. If set, the type of aOldValue will be either
     666             :    *   nsAttrValue::eString or nsAttrValue::eAtom.
     667             :    * @param aModType [out] Set to nsIDOMMutationEvent::MODIFICATION or to
     668             :    *   nsIDOMMutationEvent::ADDITION, but only if this helper returns true
     669             :    * @param aHasListeners [out] Set to true if there are mutation event
     670             :    *   listeners listening for NS_EVENT_BITS_MUTATION_ATTRMODIFIED
     671             :    * @param aOldValueSet [out] Indicates whether an old attribute value has been
     672             :    *   stored in aOldValue. The bool will be set to true if a value was stored.
     673             :    */
     674             :   bool MaybeCheckSameAttrVal(int32_t aNamespaceID, nsIAtom* aName,
     675             :                              nsIAtom* aPrefix,
     676             :                              const nsAttrValueOrString& aValue,
     677             :                              bool aNotify, nsAttrValue& aOldValue,
     678             :                              uint8_t* aModType, bool* aHasListeners,
     679             :                              bool* aOldValueSet);
     680             : 
     681             :   /**
     682             :    * Notifies mutation listeners if aNotify is true, there are mutation
     683             :    * listeners, and the attribute value is changing.
     684             :    *
     685             :    * @param aNamespaceID The namespace of the attribute
     686             :    * @param aName The local name of the attribute
     687             :    * @param aPrefix The prefix of the attribute
     688             :    * @param aValue The value that the attribute is being changed to
     689             :    * @param aNotify If true, mutation listeners will be notified if they exist
     690             :    *   and the attribute value is changing
     691             :    * @param aOldValue [out] Set to the old value of the attribute, but only if
     692             :    *   there are event listeners. If set, the type of aOldValue will be either
     693             :    *   nsAttrValue::eString or nsAttrValue::eAtom.
     694             :    * @param aModType [out] Set to nsIDOMMutationEvent::MODIFICATION or to
     695             :    *   nsIDOMMutationEvent::ADDITION, but only if this helper returns true
     696             :    * @param aHasListeners [out] Set to true if there are mutation event
     697             :    *   listeners listening for NS_EVENT_BITS_MUTATION_ATTRMODIFIED
     698             :    * @param aOldValueSet [out] Indicates whether an old attribute value has been
     699             :    *   stored in aOldValue. The bool will be set to true if a value was stored.
     700             :    */
     701             :   bool OnlyNotifySameValueSet(int32_t aNamespaceID, nsIAtom* aName,
     702             :                               nsIAtom* aPrefix,
     703             :                               const nsAttrValueOrString& aValue,
     704             :                               bool aNotify, nsAttrValue& aOldValue,
     705             :                               uint8_t* aModType, bool* aHasListeners,
     706             :                               bool* aOldValueSet);
     707             : 
     708             :   virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
     709             :                            const nsAString& aValue, bool aNotify) override;
     710             :   // aParsedValue receives the old value of the attribute. That's useful if
     711             :   // either the input or output value of aParsedValue is StoresOwnData.
     712             :   nsresult SetParsedAttr(int32_t aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
     713             :                          nsAttrValue& aParsedValue, bool aNotify);
     714             :   // GetAttr is not inlined on purpose, to keep down codesize from all
     715             :   // the inlined nsAttrValue bits for C++ callers.
     716             :   bool GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
     717             :                nsAString& aResult) const;
     718             :   inline bool HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const;
     719             :   // aCaseSensitive == eIgnoreCaase means ASCII case-insensitive matching.
     720             :   inline bool AttrValueIs(int32_t aNameSpaceID, nsIAtom* aName,
     721             :                           const nsAString& aValue,
     722             :                           nsCaseTreatment aCaseSensitive) const;
     723             :   inline bool AttrValueIs(int32_t aNameSpaceID, nsIAtom* aName,
     724             :                           nsIAtom* aValue,
     725             :                           nsCaseTreatment aCaseSensitive) const;
     726             :   virtual int32_t FindAttrValueIn(int32_t aNameSpaceID,
     727             :                                   nsIAtom* aName,
     728             :                                   AttrValuesArray* aValues,
     729             :                                   nsCaseTreatment aCaseSensitive) const override;
     730             :   virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
     731             :                              bool aNotify) override;
     732             :   virtual const nsAttrName* GetAttrNameAt(uint32_t aIndex) const override;
     733             :   virtual BorrowedAttrInfo GetAttrInfoAt(uint32_t aIndex) const override;
     734             :   virtual uint32_t GetAttrCount() const override;
     735             :   virtual bool IsNodeOfType(uint32_t aFlags) const override;
     736             : 
     737             :   /**
     738             :    * Get the class list of this element (this corresponds to the value of the
     739             :    * class attribute).  This may be null if there are no classes, but that's not
     740             :    * guaranteed (e.g. we could have class="").
     741             :    */
     742       30850 :   const nsAttrValue* GetClasses() const {
     743       30850 :     if (MayHaveClass()) {
     744       18576 :       return DoGetClasses();
     745             :     }
     746       12274 :     return nullptr;
     747             :   }
     748             : 
     749             : #ifdef DEBUG
     750           0 :   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override
     751             :   {
     752           0 :     List(out, aIndent, EmptyCString());
     753           0 :   }
     754             :   virtual void DumpContent(FILE* out, int32_t aIndent, bool aDumpAll) const override;
     755             :   void List(FILE* out, int32_t aIndent, const nsCString& aPrefix) const;
     756             :   void ListAttributes(FILE* out) const;
     757             : #endif
     758             : 
     759             :   void Describe(nsAString& aOutDescription) const override;
     760             : 
     761             :   /*
     762             :    * Attribute Mapping Helpers
     763             :    */
     764             :   struct MappedAttributeEntry {
     765             :     nsIAtom** attribute;
     766             :   };
     767             : 
     768             :   /**
     769             :    * A common method where you can just pass in a list of maps to check
     770             :    * for attribute dependence. Most implementations of
     771             :    * IsAttributeMapped should use this function as a default
     772             :    * handler.
     773             :    */
     774             :   template<size_t N>
     775             :   static bool
     776        1861 :   FindAttributeDependence(const nsIAtom* aAttribute,
     777             :                           const MappedAttributeEntry* const (&aMaps)[N])
     778             :   {
     779        1861 :     return FindAttributeDependence(aAttribute, aMaps, N);
     780             :   }
     781             : 
     782             :   static nsIAtom*** HTMLSVGPropertiesToTraverseAndUnlink();
     783             : 
     784             : private:
     785             :   void DescribeAttribute(uint32_t index, nsAString& aOutDescription) const;
     786             : 
     787             :   static bool
     788             :   FindAttributeDependence(const nsIAtom* aAttribute,
     789             :                           const MappedAttributeEntry* const aMaps[],
     790             :                           uint32_t aMapCount);
     791             : 
     792             : protected:
     793       21342 :   inline bool GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
     794             :                       DOMString& aResult) const
     795             :   {
     796       21342 :     NS_ASSERTION(nullptr != aName, "must have attribute name");
     797       21342 :     NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown,
     798             :                  "must have a real namespace ID!");
     799       21342 :     MOZ_ASSERT(aResult.HasStringBuffer() && aResult.StringBufferLength() == 0,
     800             :                "Should have empty string coming in");
     801       21342 :     const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
     802       21342 :     if (val) {
     803        1960 :       val->ToString(aResult);
     804        1960 :       return true;
     805             :     }
     806             :     // else DOMString comes pre-emptied.
     807       19382 :     return false;
     808             :   }
     809             : 
     810             : public:
     811       56070 :   bool HasAttrs() const { return mAttrsAndChildren.HasAttrs(); }
     812             : 
     813           0 :   inline bool GetAttr(const nsAString& aName, DOMString& aResult) const
     814             :   {
     815           0 :     MOZ_ASSERT(aResult.HasStringBuffer() && aResult.StringBufferLength() == 0,
     816             :                "Should have empty string coming in");
     817           0 :     const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName);
     818           0 :     if (val) {
     819           0 :       val->ToString(aResult);
     820           0 :       return true;
     821             :     }
     822             :     // else DOMString comes pre-emptied.
     823           0 :     return false;
     824             :   }
     825             : 
     826           0 :   void GetTagName(nsAString& aTagName) const
     827             :   {
     828           0 :     aTagName = NodeName();
     829           0 :   }
     830           3 :   void GetId(nsAString& aId) const
     831             :   {
     832           3 :     GetAttr(kNameSpaceID_None, nsGkAtoms::id, aId);
     833           3 :   }
     834          74 :   void GetId(DOMString& aId) const
     835             :   {
     836          74 :     GetAttr(kNameSpaceID_None, nsGkAtoms::id, aId);
     837          74 :   }
     838          41 :   void SetId(const nsAString& aId)
     839             :   {
     840          41 :     SetAttr(kNameSpaceID_None, nsGkAtoms::id, aId, true);
     841          41 :   }
     842             :   void GetClassName(nsAString& aClassName)
     843             :   {
     844             :     GetAttr(kNameSpaceID_None, nsGkAtoms::_class, aClassName);
     845             :   }
     846           0 :   void GetClassName(DOMString& aClassName)
     847             :   {
     848           0 :     GetAttr(kNameSpaceID_None, nsGkAtoms::_class, aClassName);
     849           0 :   }
     850           8 :   void SetClassName(const nsAString& aClassName)
     851             :   {
     852           8 :     SetAttr(kNameSpaceID_None, nsGkAtoms::_class, aClassName, true);
     853           8 :   }
     854             : 
     855             :   nsDOMTokenList* ClassList();
     856           0 :   nsDOMAttributeMap* Attributes()
     857             :   {
     858           0 :     nsDOMSlots* slots = DOMSlots();
     859           0 :     if (!slots->mAttributeMap) {
     860           0 :       slots->mAttributeMap = new nsDOMAttributeMap(this);
     861             :     }
     862             : 
     863           0 :     return slots->mAttributeMap;
     864             :   }
     865             : 
     866             :   void GetAttributeNames(nsTArray<nsString>& aResult);
     867             : 
     868          29 :   void GetAttribute(const nsAString& aName, nsString& aReturn)
     869             :   {
     870          58 :     DOMString str;
     871          29 :     GetAttribute(aName, str);
     872          29 :     str.ToString(aReturn);
     873          29 :   }
     874             : 
     875             :   void GetAttribute(const nsAString& aName, DOMString& aReturn);
     876             :   void GetAttributeNS(const nsAString& aNamespaceURI,
     877             :                       const nsAString& aLocalName,
     878             :                       nsAString& aReturn);
     879             :   void SetAttribute(const nsAString& aName, const nsAString& aValue,
     880             :                     ErrorResult& aError);
     881             :   void SetAttributeNS(const nsAString& aNamespaceURI,
     882             :                       const nsAString& aLocalName,
     883             :                       const nsAString& aValue,
     884             :                       ErrorResult& aError);
     885             :   void RemoveAttribute(const nsAString& aName,
     886             :                        ErrorResult& aError);
     887             :   void RemoveAttributeNS(const nsAString& aNamespaceURI,
     888             :                          const nsAString& aLocalName,
     889             :                          ErrorResult& aError);
     890          33 :   bool HasAttribute(const nsAString& aName) const
     891             :   {
     892          33 :     return InternalGetAttrNameFromQName(aName) != nullptr;
     893             :   }
     894             :   bool HasAttributeNS(const nsAString& aNamespaceURI,
     895             :                       const nsAString& aLocalName) const;
     896           0 :   bool HasAttributes() const
     897             :   {
     898           0 :     return HasAttrs();
     899             :   }
     900             :   Element* Closest(const nsAString& aSelector,
     901             :                    ErrorResult& aResult);
     902             :   bool Matches(const nsAString& aSelector,
     903             :                ErrorResult& aError);
     904             :   already_AddRefed<nsIHTMLCollection>
     905             :     GetElementsByTagName(const nsAString& aQualifiedName);
     906             :   already_AddRefed<nsIHTMLCollection>
     907             :     GetElementsByTagNameNS(const nsAString& aNamespaceURI,
     908             :                            const nsAString& aLocalName,
     909             :                            ErrorResult& aError);
     910             :   already_AddRefed<nsIHTMLCollection>
     911             :     GetElementsByClassName(const nsAString& aClassNames);
     912             : 
     913        4223 :   CSSPseudoElementType GetPseudoElementType() const {
     914        4223 :     nsresult rv = NS_OK;
     915        4223 :     auto raw = GetProperty(nsGkAtoms::pseudoProperty, &rv);
     916        4223 :     if (rv == NS_PROPTABLE_PROP_NOT_THERE) {
     917        4129 :       return CSSPseudoElementType::NotPseudo;
     918             :     }
     919          94 :     return CSSPseudoElementType(reinterpret_cast<uintptr_t>(raw));
     920             :   }
     921             : 
     922          10 :   void SetPseudoElementType(CSSPseudoElementType aPseudo) {
     923             :     static_assert(sizeof(CSSPseudoElementType) <= sizeof(uintptr_t),
     924             :                   "Need to be able to store this in a void*");
     925          10 :     MOZ_ASSERT(aPseudo != CSSPseudoElementType::NotPseudo);
     926          10 :     SetProperty(nsGkAtoms::pseudoProperty, reinterpret_cast<void*>(aPseudo));
     927          10 :   }
     928             : 
     929             : private:
     930             :   /**
     931             :    * Implement the algorithm specified at
     932             :    * https://dom.spec.whatwg.org/#insert-adjacent for both
     933             :    * |insertAdjacentElement()| and |insertAdjacentText()| APIs.
     934             :    */
     935             :   nsINode* InsertAdjacent(const nsAString& aWhere,
     936             :                           nsINode* aNode,
     937             :                           ErrorResult& aError);
     938             : 
     939             : public:
     940             :   Element* InsertAdjacentElement(const nsAString& aWhere,
     941             :                                  Element& aElement,
     942             :                                  ErrorResult& aError);
     943             : 
     944             :   void InsertAdjacentText(const nsAString& aWhere,
     945             :                           const nsAString& aData,
     946             :                           ErrorResult& aError);
     947             : 
     948           0 :   void SetPointerCapture(int32_t aPointerId, ErrorResult& aError)
     949             :   {
     950           0 :     bool activeState = false;
     951           0 :     if (!nsIPresShell::GetPointerInfo(aPointerId, activeState)) {
     952           0 :       aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
     953           0 :       return;
     954             :     }
     955           0 :     if (!IsInUncomposedDoc()) {
     956           0 :       aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     957           0 :       return;
     958             :     }
     959           0 :     if (!activeState) {
     960           0 :       return;
     961             :     }
     962           0 :     nsIPresShell::SetPointerCapturingContent(aPointerId, this);
     963             :   }
     964           0 :   void ReleasePointerCapture(int32_t aPointerId, ErrorResult& aError)
     965             :   {
     966           0 :     bool activeState = false;
     967           0 :     if (!nsIPresShell::GetPointerInfo(aPointerId, activeState)) {
     968           0 :       aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
     969           0 :       return;
     970             :     }
     971           0 :     if (HasPointerCapture(aPointerId)) {
     972           0 :       nsIPresShell::ReleasePointerCapturingContent(aPointerId);
     973             :     }
     974             :   }
     975           0 :   bool HasPointerCapture(long aPointerId)
     976             :   {
     977             :     nsIPresShell::PointerCaptureInfo* pointerCaptureInfo =
     978           0 :       nsIPresShell::GetPointerCaptureInfo(aPointerId);
     979           0 :     if (pointerCaptureInfo && pointerCaptureInfo->mPendingContent == this) {
     980           0 :       return true;
     981             :     }
     982           0 :     return false;
     983             :   }
     984           0 :   void SetCapture(bool aRetargetToElement)
     985             :   {
     986             :     // If there is already an active capture, ignore this request. This would
     987             :     // occur if a splitter, frame resizer, etc had already captured and we don't
     988             :     // want to override those.
     989           0 :     if (!nsIPresShell::GetCapturingContent()) {
     990           0 :       nsIPresShell::SetCapturingContent(this, CAPTURE_PREVENTDRAG |
     991           0 :         (aRetargetToElement ? CAPTURE_RETARGETTOELEMENT : 0));
     992             :     }
     993           0 :   }
     994             : 
     995           0 :   void SetCaptureAlways(bool aRetargetToElement)
     996             :   {
     997           0 :     nsIPresShell::SetCapturingContent(this,
     998             :         CAPTURE_PREVENTDRAG | CAPTURE_IGNOREALLOWED |
     999           0 :         (aRetargetToElement ? CAPTURE_RETARGETTOELEMENT : 0));
    1000           0 :   }
    1001             : 
    1002           0 :   void ReleaseCapture()
    1003             :   {
    1004           0 :     if (nsIPresShell::GetCapturingContent() == this) {
    1005           0 :       nsIPresShell::SetCapturingContent(nullptr, 0);
    1006             :     }
    1007           0 :   }
    1008             : 
    1009             :   void RequestFullscreen(CallerType aCallerType, ErrorResult& aError);
    1010             :   void RequestPointerLock(CallerType aCallerType);
    1011             :   Attr* GetAttributeNode(const nsAString& aName);
    1012             :   already_AddRefed<Attr> SetAttributeNode(Attr& aNewAttr,
    1013             :                                           ErrorResult& aError);
    1014             :   already_AddRefed<Attr> RemoveAttributeNode(Attr& aOldAttr,
    1015             :                                              ErrorResult& aError);
    1016             :   Attr* GetAttributeNodeNS(const nsAString& aNamespaceURI,
    1017             :                            const nsAString& aLocalName);
    1018             :   already_AddRefed<Attr> SetAttributeNodeNS(Attr& aNewAttr,
    1019             :                                             ErrorResult& aError);
    1020             : 
    1021             :   already_AddRefed<DOMRectList> GetClientRects();
    1022             :   already_AddRefed<DOMRect> GetBoundingClientRect();
    1023             : 
    1024             :   already_AddRefed<ShadowRoot> CreateShadowRoot(ErrorResult& aError);
    1025             :   already_AddRefed<DestinationInsertionPointList> GetDestinationInsertionPoints();
    1026             : 
    1027       17316 :   ShadowRoot *FastGetShadowRoot() const
    1028             :   {
    1029       17316 :     nsDOMSlots* slots = GetExistingDOMSlots();
    1030       17316 :     return slots ? slots->mShadowRoot.get() : nullptr;
    1031             :   }
    1032             : 
    1033             :   void ScrollIntoView();
    1034             :   void ScrollIntoView(bool aTop);
    1035             :   void ScrollIntoView(const ScrollIntoViewOptions &aOptions);
    1036             :   void Scroll(double aXScroll, double aYScroll);
    1037             :   void Scroll(const ScrollToOptions& aOptions);
    1038             :   void ScrollTo(double aXScroll, double aYScroll);
    1039             :   void ScrollTo(const ScrollToOptions& aOptions);
    1040             :   void ScrollBy(double aXScrollDif, double aYScrollDif);
    1041             :   void ScrollBy(const ScrollToOptions& aOptions);
    1042             :   /* Scrolls without flushing the layout.
    1043             :    * aDx is the x offset, aDy the y offset in CSS pixels.
    1044             :    * Returns true if we actually scrolled.
    1045             :    */
    1046             :   bool ScrollByNoFlush(int32_t aDx, int32_t aDy);
    1047             :   int32_t ScrollTop();
    1048             :   void SetScrollTop(int32_t aScrollTop);
    1049             :   int32_t ScrollLeft();
    1050             :   void SetScrollLeft(int32_t aScrollLeft);
    1051             :   int32_t ScrollWidth();
    1052             :   int32_t ScrollHeight();
    1053             :   void MozScrollSnap();
    1054           0 :   int32_t ClientTop()
    1055             :   {
    1056           0 :     return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().y);
    1057             :   }
    1058           0 :   int32_t ClientLeft()
    1059             :   {
    1060           0 :     return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().x);
    1061             :   }
    1062           0 :   int32_t ClientWidth()
    1063             :   {
    1064           0 :     return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().width);
    1065             :   }
    1066           0 :   int32_t ClientHeight()
    1067             :   {
    1068           0 :     return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().height);
    1069             :   }
    1070           0 :   int32_t ScrollTopMin()
    1071             :   {
    1072           0 :     nsIScrollableFrame* sf = GetScrollFrame();
    1073           0 :     return sf ?
    1074           0 :            nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollRange().y) : 0;
    1075             :   }
    1076           0 :   int32_t ScrollTopMax()
    1077             :   {
    1078           0 :     nsIScrollableFrame* sf = GetScrollFrame();
    1079           0 :     return sf ?
    1080           0 :            nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollRange().YMost()) :
    1081           0 :            0;
    1082             :   }
    1083           1 :   int32_t ScrollLeftMin()
    1084             :   {
    1085           1 :     nsIScrollableFrame* sf = GetScrollFrame();
    1086           3 :     return sf ?
    1087           3 :            nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollRange().x) : 0;
    1088             :   }
    1089           1 :   int32_t ScrollLeftMax()
    1090             :   {
    1091           1 :     nsIScrollableFrame* sf = GetScrollFrame();
    1092           3 :     return sf ?
    1093           4 :            nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollRange().XMost()) :
    1094           2 :            0;
    1095             :   }
    1096             : 
    1097             :   void GetGridFragments(nsTArray<RefPtr<Grid>>& aResult);
    1098             : 
    1099             :   already_AddRefed<DOMMatrixReadOnly> GetTransformToAncestor(Element& aAncestor);
    1100             :   already_AddRefed<DOMMatrixReadOnly> GetTransformToParent();
    1101             :   already_AddRefed<DOMMatrixReadOnly> GetTransformToViewport();
    1102             : 
    1103             :   already_AddRefed<Animation>
    1104             :   Animate(JSContext* aContext,
    1105             :           JS::Handle<JSObject*> aKeyframes,
    1106             :           const UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions,
    1107             :           ErrorResult& aError);
    1108             : 
    1109             :   // A helper method that factors out the common functionality needed by
    1110             :   // Element::Animate and CSSPseudoElement::Animate
    1111             :   static already_AddRefed<Animation>
    1112             :   Animate(const Nullable<ElementOrCSSPseudoElement>& aTarget,
    1113             :           JSContext* aContext,
    1114             :           JS::Handle<JSObject*> aKeyframes,
    1115             :           const UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions,
    1116             :           ErrorResult& aError);
    1117             : 
    1118             :   // Note: GetAnimations will flush style while GetAnimationsUnsorted won't.
    1119             :   // Callers must keep this element alive because flushing style may destroy
    1120             :   // this element.
    1121             :   void GetAnimations(const AnimationFilter& filter,
    1122             :                      nsTArray<RefPtr<Animation>>& aAnimations);
    1123             :   static void GetAnimationsUnsorted(Element* aElement,
    1124             :                                     CSSPseudoElementType aPseudoType,
    1125             :                                     nsTArray<RefPtr<Animation>>& aAnimations);
    1126             : 
    1127             :   NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML);
    1128             :   virtual void SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError);
    1129             :   void GetOuterHTML(nsAString& aOuterHTML);
    1130             :   void SetOuterHTML(const nsAString& aOuterHTML, ErrorResult& aError);
    1131             :   void InsertAdjacentHTML(const nsAString& aPosition, const nsAString& aText,
    1132             :                           ErrorResult& aError);
    1133             : 
    1134             :   //----------------------------------------
    1135             : 
    1136             :   /**
    1137             :    * Add a script event listener with the given event handler name
    1138             :    * (like onclick) and with the value as JS
    1139             :    * @param aEventName the event listener name
    1140             :    * @param aValue the JS to attach
    1141             :    * @param aDefer indicates if deferred execution is allowed
    1142             :    */
    1143             :   nsresult SetEventHandler(nsIAtom* aEventName,
    1144             :                            const nsAString& aValue,
    1145             :                            bool aDefer = true);
    1146             : 
    1147             :   /**
    1148             :    * Do whatever needs to be done when the mouse leaves a link
    1149             :    */
    1150             :   nsresult LeaveLink(nsPresContext* aPresContext);
    1151             : 
    1152             :   static bool ShouldBlur(nsIContent *aContent);
    1153             : 
    1154             :   /**
    1155             :    * Method to create and dispatch a left-click event loosely based on
    1156             :    * aSourceEvent. If aFullDispatch is true, the event will be dispatched
    1157             :    * through the full dispatching of the presshell of the aPresContext; if it's
    1158             :    * false the event will be dispatched only as a DOM event.
    1159             :    * If aPresContext is nullptr, this does nothing.
    1160             :    *
    1161             :    * @param aFlags      Extra flags for the dispatching event.  The true flags
    1162             :    *                    will be respected.
    1163             :    */
    1164             :   static nsresult DispatchClickEvent(nsPresContext* aPresContext,
    1165             :                                      WidgetInputEvent* aSourceEvent,
    1166             :                                      nsIContent* aTarget,
    1167             :                                      bool aFullDispatch,
    1168             :                                      const EventFlags* aFlags,
    1169             :                                      nsEventStatus* aStatus);
    1170             : 
    1171             :   /**
    1172             :    * Method to dispatch aEvent to aTarget. If aFullDispatch is true, the event
    1173             :    * will be dispatched through the full dispatching of the presshell of the
    1174             :    * aPresContext; if it's false the event will be dispatched only as a DOM
    1175             :    * event.
    1176             :    * If aPresContext is nullptr, this does nothing.
    1177             :    */
    1178             :   using nsIContent::DispatchEvent;
    1179             :   static nsresult DispatchEvent(nsPresContext* aPresContext,
    1180             :                                 WidgetEvent* aEvent,
    1181             :                                 nsIContent* aTarget,
    1182             :                                 bool aFullDispatch,
    1183             :                                 nsEventStatus* aStatus);
    1184             : 
    1185             :   /**
    1186             :    * Get the primary frame for this content with flushing
    1187             :    *
    1188             :    * @param aType the kind of flush to do, typically FlushType::Frames or
    1189             :    *              FlushType::Layout
    1190             :    * @return the primary frame
    1191             :    */
    1192             :   nsIFrame* GetPrimaryFrame(FlushType aType);
    1193             :   // Work around silly C++ name hiding stuff
    1194        4702 :   nsIFrame* GetPrimaryFrame() const { return nsIContent::GetPrimaryFrame(); }
    1195             : 
    1196       93613 :   const nsAttrValue* GetParsedAttr(nsIAtom* aAttr) const
    1197             :   {
    1198       93613 :     return mAttrsAndChildren.GetAttr(aAttr);
    1199             :   }
    1200             : 
    1201        2501 :   const nsAttrValue* GetParsedAttr(nsIAtom* aAttr, int32_t aNameSpaceID) const
    1202             :   {
    1203        2501 :     return mAttrsAndChildren.GetAttr(aAttr, aNameSpaceID);
    1204             :   }
    1205             : 
    1206             :   /**
    1207             :    * Returns the attribute map, if there is one.
    1208             :    *
    1209             :    * @return existing attribute map or nullptr.
    1210             :    */
    1211           0 :   nsDOMAttributeMap *GetAttributeMap()
    1212             :   {
    1213           0 :     nsDOMSlots *slots = GetExistingDOMSlots();
    1214             : 
    1215           0 :     return slots ? slots->mAttributeMap.get() : nullptr;
    1216             :   }
    1217             : 
    1218           0 :   virtual void RecompileScriptEventListeners()
    1219             :   {
    1220           0 :   }
    1221             : 
    1222             :   /**
    1223             :    * Get the attr info for the given namespace ID and attribute name.  The
    1224             :    * namespace ID must not be kNameSpaceID_Unknown and the name must not be
    1225             :    * null.  Note that this can only return info on attributes that actually
    1226             :    * live on this element (and is only virtual to handle XUL prototypes).  That
    1227             :    * is, this should only be called from methods that only care about attrs
    1228             :    * that effectively live in mAttrsAndChildren.
    1229             :    */
    1230             :   virtual BorrowedAttrInfo GetAttrInfo(int32_t aNamespaceID, nsIAtom* aName) const;
    1231             : 
    1232             :   /**
    1233             :    * Called when we have been adopted, and the information of the
    1234             :    * node has been changed.
    1235             :    *
    1236             :    * The new document can be reached via OwnerDoc().
    1237             :    *
    1238             :    * If you override this method,
    1239             :    * please call up to the parent NodeInfoChanged.
    1240             :    *
    1241             :    * If you change this, change also the similar method in Link.
    1242             :    */
    1243           0 :   virtual void NodeInfoChanged(nsIDocument* aOldDoc) {}
    1244             : 
    1245             :   /**
    1246             :    * Parse a string into an nsAttrValue for a CORS attribute.  This
    1247             :    * never fails.  The resulting value is an enumerated value whose
    1248             :    * GetEnumValue() returns one of the above constants.
    1249             :    */
    1250             :   static void ParseCORSValue(const nsAString& aValue, nsAttrValue& aResult);
    1251             : 
    1252             :   /**
    1253             :    * Return the CORS mode for a given string
    1254             :    */
    1255             :   static CORSMode StringToCORSMode(const nsAString& aValue);
    1256             : 
    1257             :   /**
    1258             :    * Return the CORS mode for a given nsAttrValue (which may be null,
    1259             :    * but if not should have been parsed via ParseCORSValue).
    1260             :    */
    1261             :   static CORSMode AttrValueToCORSMode(const nsAttrValue* aValue);
    1262             : 
    1263             :   virtual JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) final override;
    1264             : 
    1265             :   nsINode* GetScopeChainParent() const override;
    1266             : 
    1267             :   /**
    1268             :    * Locate a TextEditor rooted at this content node, if there is one.
    1269             :    */
    1270             :   mozilla::TextEditor* GetTextEditorInternal();
    1271             : 
    1272             :   /**
    1273             :    * Helper method for NS_IMPL_BOOL_ATTR macro.
    1274             :    * Gets value of boolean attribute. Only works for attributes in null
    1275             :    * namespace.
    1276             :    *
    1277             :    * @param aAttr    name of attribute.
    1278             :    * @param aValue   Boolean value of attribute.
    1279             :    */
    1280          74 :   bool GetBoolAttr(nsIAtom* aAttr) const
    1281             :   {
    1282          74 :     return HasAttr(kNameSpaceID_None, aAttr);
    1283             :   }
    1284             : 
    1285             :   /**
    1286             :    * Helper method for NS_IMPL_BOOL_ATTR macro.
    1287             :    * Sets value of boolean attribute by removing attribute or setting it to
    1288             :    * the empty string. Only works for attributes in null namespace.
    1289             :    *
    1290             :    * @param aAttr    name of attribute.
    1291             :    * @param aValue   Boolean value of attribute.
    1292             :    */
    1293             :   nsresult SetBoolAttr(nsIAtom* aAttr, bool aValue);
    1294             : 
    1295             :   /**
    1296             :    * Helper method for NS_IMPL_ENUM_ATTR_DEFAULT_VALUE.
    1297             :    * Gets the enum value string of an attribute and using a default value if
    1298             :    * the attribute is missing or the string is an invalid enum value.
    1299             :    *
    1300             :    * @param aType     the name of the attribute.
    1301             :    * @param aDefault  the default value if the attribute is missing or invalid.
    1302             :    * @param aResult   string corresponding to the value [out].
    1303             :    */
    1304             :   void GetEnumAttr(nsIAtom* aAttr,
    1305             :                    const char* aDefault,
    1306             :                    nsAString& aResult) const;
    1307             : 
    1308             :   /**
    1309             :    * Helper method for NS_IMPL_ENUM_ATTR_DEFAULT_MISSING_INVALID_VALUES.
    1310             :    * Gets the enum value string of an attribute and using the default missing
    1311             :    * value if the attribute is missing or the default invalid value if the
    1312             :    * string is an invalid enum value.
    1313             :    *
    1314             :    * @param aType            the name of the attribute.
    1315             :    * @param aDefaultMissing  the default value if the attribute is missing.  If
    1316             :                              null and the attribute is missing, aResult will be
    1317             :                              set to the null DOMString; this only matters for
    1318             :                              cases in which we're reflecting a nullable string.
    1319             :    * @param aDefaultInvalid  the default value if the attribute is invalid.
    1320             :    * @param aResult          string corresponding to the value [out].
    1321             :    */
    1322             :   void GetEnumAttr(nsIAtom* aAttr,
    1323             :                    const char* aDefaultMissing,
    1324             :                    const char* aDefaultInvalid,
    1325             :                    nsAString& aResult) const;
    1326             : 
    1327             :   /**
    1328             :    * Unset an attribute.
    1329             :    */
    1330           0 :   void UnsetAttr(nsIAtom* aAttr, ErrorResult& aError)
    1331             :   {
    1332           0 :     aError = UnsetAttr(kNameSpaceID_None, aAttr, true);
    1333           0 :   }
    1334             : 
    1335             :   /**
    1336             :    * Set an attribute in the simplest way possible.
    1337             :    */
    1338          12 :   void SetAttr(nsIAtom* aAttr, const nsAString& aValue, ErrorResult& aError)
    1339             :   {
    1340          12 :     aError = SetAttr(kNameSpaceID_None, aAttr, aValue, true);
    1341          12 :   }
    1342             : 
    1343             :   /**
    1344             :    * Set a content attribute via a reflecting nullable string IDL
    1345             :    * attribute (e.g. a CORS attribute).  If DOMStringIsNull(aValue),
    1346             :    * this will actually remove the content attribute.
    1347             :    */
    1348             :   void SetOrRemoveNullableStringAttr(nsIAtom* aName, const nsAString& aValue,
    1349             :                                      ErrorResult& aError);
    1350             : 
    1351             :   /**
    1352             :    * Retrieve the ratio of font-size-inflated text font size to computed font
    1353             :    * size for this element. This will query the element for its primary frame,
    1354             :    * and then use this to get font size inflation information about the frame.
    1355             :    *
    1356             :    * @returns The font size inflation ratio (inflated font size to uninflated
    1357             :    *          font size) for the primary frame of this element. Returns 1.0
    1358             :    *          by default if font size inflation is not enabled. Returns -1
    1359             :    *          if the element does not have a primary frame.
    1360             :    *
    1361             :    * @note The font size inflation ratio that is returned is actually the
    1362             :    *       font size inflation data for the element's _primary frame_, not the
    1363             :    *       element itself, but for most purposes, this should be sufficient.
    1364             :    */
    1365             :   float FontSizeInflation();
    1366             : 
    1367             :   net::ReferrerPolicy GetReferrerPolicyAsEnum();
    1368             :   net::ReferrerPolicy ReferrerPolicyFromAttr(const nsAttrValue* aValue);
    1369             : 
    1370             :   /*
    1371             :    * Helpers for .dataset.  This is implemented on Element, though only some
    1372             :    * sorts of elements expose it to JS as a .dataset property
    1373             :    */
    1374             :   // Getter, to be called from bindings.
    1375             :   already_AddRefed<nsDOMStringMap> Dataset();
    1376             :   // Callback for destructor of dataset to ensure to null out our weak pointer
    1377             :   // to it.
    1378             :   void ClearDataset();
    1379             : 
    1380             :   void RegisterIntersectionObserver(DOMIntersectionObserver* aObserver);
    1381             :   void UnregisterIntersectionObserver(DOMIntersectionObserver* aObserver);
    1382             :   bool UpdateIntersectionObservation(DOMIntersectionObserver* aObserver, int32_t threshold);
    1383             : 
    1384             : protected:
    1385             :   /*
    1386             :    * Named-bools for use with SetAttrAndNotify to make call sites easier to
    1387             :    * read.
    1388             :    */
    1389             :   static const bool kFireMutationEvent           = true;
    1390             :   static const bool kDontFireMutationEvent       = false;
    1391             :   static const bool kNotifyDocumentObservers     = true;
    1392             :   static const bool kDontNotifyDocumentObservers = false;
    1393             :   static const bool kCallAfterSetAttr            = true;
    1394             :   static const bool kDontCallAfterSetAttr        = false;
    1395             : 
    1396             :   /**
    1397             :    * Set attribute and (if needed) notify documentobservers and fire off
    1398             :    * mutation events.  This will send the AttributeChanged notification.
    1399             :    * Callers of this method are responsible for calling AttributeWillChange,
    1400             :    * since that needs to happen before the new attr value has been set, and
    1401             :    * in particular before it has been parsed.
    1402             :    *
    1403             :    * For the boolean parameters, consider using the named bools above to aid
    1404             :    * code readability.
    1405             :    *
    1406             :    * @param aNamespaceID  namespace of attribute
    1407             :    * @param aAttribute    local-name of attribute
    1408             :    * @param aPrefix       aPrefix of attribute
    1409             :    * @param aOldValue     The old value of the attribute to use as a fallback
    1410             :    *                      in the cases where the actual old value (i.e.
    1411             :    *                      its current value) is !StoresOwnData() --- in which
    1412             :    *                      case the current value is probably already useless.
    1413             :    *                      If the current value is StoresOwnData() (or absent),
    1414             :    *                      aOldValue will not be used. aOldValue will only be set
    1415             :    *                      in certain circumstances (there are mutation
    1416             :    *                      listeners, element is a custom element, attribute was
    1417             :    *                      not previously unset). Otherwise it will be null.
    1418             :    * @param aParsedValue  parsed new value of attribute. Replaced by the
    1419             :    *                      old value of the attribute. This old value is only
    1420             :    *                      useful if either it or the new value is StoresOwnData.
    1421             :    * @param aModType      nsIDOMMutationEvent::MODIFICATION or ADDITION.  Only
    1422             :    *                      needed if aFireMutation or aNotify is true.
    1423             :    * @param aFireMutation should mutation-events be fired?
    1424             :    * @param aNotify       should we notify document-observers?
    1425             :    * @param aCallAfterSetAttr should we call AfterSetAttr?
    1426             :    * @param aComposedDocument The current composed document of the element.
    1427             :    */
    1428             :   nsresult SetAttrAndNotify(int32_t aNamespaceID,
    1429             :                             nsIAtom* aName,
    1430             :                             nsIAtom* aPrefix,
    1431             :                             const nsAttrValue* aOldValue,
    1432             :                             nsAttrValue& aParsedValue,
    1433             :                             uint8_t aModType,
    1434             :                             bool aFireMutation,
    1435             :                             bool aNotify,
    1436             :                             bool aCallAfterSetAttr,
    1437             :                             nsIDocument* aComposedDocument,
    1438             :                             const mozAutoDocUpdate& aGuard);
    1439             : 
    1440             :   /**
    1441             :    * Scroll to a new position using behavior evaluated from CSS and
    1442             :    * a CSSOM-View DOM method ScrollOptions dictionary.  The scrolling may
    1443             :    * be performed asynchronously or synchronously depending on the resolved
    1444             :    * scroll-behavior.
    1445             :    *
    1446             :    * @param aScroll       Destination of scroll, in CSS pixels
    1447             :    * @param aOptions      Dictionary of options to be evaluated
    1448             :    */
    1449             :   void Scroll(const CSSIntPoint& aScroll, const ScrollOptions& aOptions);
    1450             : 
    1451             :   /**
    1452             :    * Convert an attribute string value to attribute type based on the type of
    1453             :    * attribute.  Called by SetAttr().  Note that at the moment we only do this
    1454             :    * for attributes in the null namespace (kNameSpaceID_None).
    1455             :    *
    1456             :    * @param aNamespaceID the namespace of the attribute to convert
    1457             :    * @param aAttribute the attribute to convert
    1458             :    * @param aValue the string value to convert
    1459             :    * @param aResult the nsAttrValue [OUT]
    1460             :    * @return true if the parsing was successful, false otherwise
    1461             :    */
    1462             :   virtual bool ParseAttribute(int32_t aNamespaceID,
    1463             :                                 nsIAtom* aAttribute,
    1464             :                                 const nsAString& aValue,
    1465             :                                 nsAttrValue& aResult);
    1466             : 
    1467             :   /**
    1468             :    * Try to set the attribute as a mapped attribute, if applicable.  This will
    1469             :    * only be called for attributes that are in the null namespace and only on
    1470             :    * attributes that returned true when passed to IsAttributeMapped.  The
    1471             :    * caller will not try to set the attr in any other way if this method
    1472             :    * returns true (the value of aRetval does not matter for that purpose).
    1473             :    *
    1474             :    * @param aName the name of the attribute
    1475             :    * @param aValue the nsAttrValue to set. Will be swapped with the existing
    1476             :    *               value of the attribute if the attribute already exists.
    1477             :    * @param [out] aValueWasSet If the attribute was not set previously,
    1478             :    *                           aValue will be swapped with an empty attribute
    1479             :    *                           and aValueWasSet will be set to false. Otherwise,
    1480             :    *                           aValueWasSet will be set to true and aValue will
    1481             :    *                           contain the previous value set.
    1482             :    * @param [out] aRetval the nsresult status of the operation, if any.
    1483             :    * @return true if the setting was attempted, false otherwise.
    1484             :    */
    1485             :   virtual bool SetAndSwapMappedAttribute(nsIAtom* aName,
    1486             :                                          nsAttrValue& aValue,
    1487             :                                          bool* aValueWasSet,
    1488             :                                          nsresult* aRetval);
    1489             : 
    1490             :   /**
    1491             :    * Hook that is called by Element::SetAttr to allow subclasses to
    1492             :    * deal with attribute sets.  This will only be called after we verify that
    1493             :    * we're actually doing an attr set and will be called before
    1494             :    * AttributeWillChange and before ParseAttribute and hence before we've set
    1495             :    * the new value.
    1496             :    *
    1497             :    * @param aNamespaceID the namespace of the attr being set
    1498             :    * @param aName the localname of the attribute being set
    1499             :    * @param aValue the value it's being set to represented as either a string or
    1500             :    *        a parsed nsAttrValue. Alternatively, if the attr is being removed it
    1501             :    *        will be null.
    1502             :    * @param aNotify Whether we plan to notify document observers.
    1503             :    */
    1504             :   virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
    1505             :                                  const nsAttrValueOrString* aValue,
    1506             :                                  bool aNotify);
    1507             : 
    1508             :   /**
    1509             :    * Hook that is called by Element::SetAttr to allow subclasses to
    1510             :    * deal with attribute sets.  This will only be called after we have called
    1511             :    * SetAndSwapAttr (that is, after we have actually set the attr).  It will
    1512             :    * always be called under a scriptblocker.
    1513             :    *
    1514             :    * @param aNamespaceID the namespace of the attr being set
    1515             :    * @param aName the localname of the attribute being set
    1516             :    * @param aValue the value it's being set to.  If null, the attr is being
    1517             :    *        removed.
    1518             :    * @param aOldValue the value that the attribute had previously. If null,
    1519             :    *        the attr was not previously set. This argument may not have the
    1520             :    *        correct value for SVG elements, or other cases in which the
    1521             :    *        attribute value doesn't store its own data
    1522             :    * @param aNotify Whether we plan to notify document observers.
    1523             :    */
    1524             :   // Note that this is inlined so that when subclasses call it it gets
    1525             :   // inlined.  Those calls don't go through a vtable.
    1526        1952 :   virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
    1527             :                                 const nsAttrValue* aValue,
    1528             :                                 const nsAttrValue* aOldValue, bool aNotify)
    1529             :   {
    1530        1952 :     return NS_OK;
    1531             :   }
    1532             : 
    1533             :   /**
    1534             :    * This function shall be called just before the id attribute changes. It will
    1535             :    * be called after BeforeSetAttr. If the attribute being changed is not the id
    1536             :    * attribute, this function does nothing. Otherwise, it will remove the old id
    1537             :    * from the document's id cache.
    1538             :    *
    1539             :    * This must happen after BeforeSetAttr (rather than during) because the
    1540             :    * the subclasses' calls to BeforeSetAttr may notify on state changes. If they
    1541             :    * incorrectly determine whether the element had an id, the element may not be
    1542             :    * restyled properly.
    1543             :    *
    1544             :    * @param aNamespaceID the namespace of the attr being set
    1545             :    * @param aName the localname of the attribute being set
    1546             :    * @param aValue the new id value. Will be null if the id is being unset.
    1547             :    */
    1548             :   void PreIdMaybeChange(int32_t aNamespaceID, nsIAtom* aName,
    1549             :                         const nsAttrValueOrString* aValue);
    1550             : 
    1551             :   /**
    1552             :    * This function shall be called just after the id attribute changes. It will
    1553             :    * be called before AfterSetAttr. If the attribute being changed is not the id
    1554             :    * attribute, this function does nothing. Otherwise, it will add the new id to
    1555             :    * the document's id cache and properly set the ElementHasID flag.
    1556             :    *
    1557             :    * This must happen before AfterSetAttr (rather than during) because the
    1558             :    * the subclasses' calls to AfterSetAttr may notify on state changes. If they
    1559             :    * incorrectly determine whether the element now has an id, the element may
    1560             :    * not be restyled properly.
    1561             :    *
    1562             :    * @param aNamespaceID the namespace of the attr being set
    1563             :    * @param aName the localname of the attribute being set
    1564             :    * @param aValue the new id value. Will be null if the id is being unset.
    1565             :    */
    1566             :   void PostIdMaybeChange(int32_t aNamespaceID, nsIAtom* aName,
    1567             :                          const nsAttrValue* aValue);
    1568             : 
    1569             :   /**
    1570             :    * Usually, setting an attribute to the value that it already has results in
    1571             :    * no action. However, in some cases, setting an attribute to its current
    1572             :    * value should have the effect of, for example, forcing a reload of
    1573             :    * network data. To address that, this function will be called in this
    1574             :    * situation to allow the handling of such a case.
    1575             :    *
    1576             :    * @param aNamespaceID the namespace of the attr being set
    1577             :    * @param aName the localname of the attribute being set
    1578             :    * @param aValue the value it's being set to represented as either a string or
    1579             :    *        a parsed nsAttrValue.
    1580             :    * @param aNotify Whether we plan to notify document observers.
    1581             :    */
    1582             :   // Note that this is inlined so that when subclasses call it it gets
    1583             :   // inlined.  Those calls don't go through a vtable.
    1584         101 :   virtual nsresult OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
    1585             :                                           const nsAttrValueOrString& aValue,
    1586             :                                           bool aNotify)
    1587             :   {
    1588         101 :     return NS_OK;
    1589             :   }
    1590             : 
    1591             :   /**
    1592             :    * Hook to allow subclasses to produce a different EventListenerManager if
    1593             :    * needed for attachment of attribute-defined handlers
    1594             :    */
    1595             :   virtual EventListenerManager*
    1596             :     GetEventListenerManagerForAttr(nsIAtom* aAttrName, bool* aDefer);
    1597             : 
    1598             :   /**
    1599             :    * Internal hook for converting an attribute name-string to nsAttrName in
    1600             :    * case there is such existing attribute. aNameToUse can be passed to get
    1601             :    * name which was used for looking for the attribute (lowercase in HTML).
    1602             :    */
    1603             :   const nsAttrName*
    1604             :   InternalGetAttrNameFromQName(const nsAString& aStr,
    1605             :                                nsAutoString* aNameToUse = nullptr) const;
    1606             : 
    1607             :   nsIFrame* GetStyledFrame();
    1608             : 
    1609           2 :   virtual Element* GetNameSpaceElement() override
    1610             :   {
    1611           2 :     return this;
    1612             :   }
    1613             : 
    1614             :   Attr* GetAttributeNodeNSInternal(const nsAString& aNamespaceURI,
    1615             :                                    const nsAString& aLocalName);
    1616             : 
    1617             :   inline void RegisterActivityObserver();
    1618             :   inline void UnregisterActivityObserver();
    1619             : 
    1620             :   /**
    1621             :    * Add/remove this element to the documents id cache
    1622             :    */
    1623             :   void AddToIdTable(nsIAtom* aId);
    1624             :   void RemoveFromIdTable();
    1625             : 
    1626             :   /**
    1627             :    * Functions to carry out event default actions for links of all types
    1628             :    * (HTML links, XLinks, SVG "XLinks", etc.)
    1629             :    */
    1630             : 
    1631             :   /**
    1632             :    * Check that we meet the conditions to handle a link event
    1633             :    * and that we are actually on a link.
    1634             :    *
    1635             :    * @param aVisitor event visitor
    1636             :    * @param aURI the uri of the link, set only if the return value is true [OUT]
    1637             :    * @return true if we can handle the link event, false otherwise
    1638             :    */
    1639             :   bool CheckHandleEventForLinksPrecondition(EventChainVisitor& aVisitor,
    1640             :                                             nsIURI** aURI) const;
    1641             : 
    1642             :   /**
    1643             :    * Handle status bar updates before they can be cancelled.
    1644             :    */
    1645             :   nsresult GetEventTargetParentForLinks(EventChainPreVisitor& aVisitor);
    1646             : 
    1647             :   /**
    1648             :    * Handle default actions for link event if the event isn't consumed yet.
    1649             :    */
    1650             :   nsresult PostHandleEventForLinks(EventChainPostVisitor& aVisitor);
    1651             : 
    1652             :   /**
    1653             :    * Get the target of this link element. Consumers should established that
    1654             :    * this element is a link (probably using IsLink) before calling this
    1655             :    * function (or else why call it?)
    1656             :    *
    1657             :    * Note: for HTML this gets the value of the 'target' attribute; for XLink
    1658             :    * this gets the value of the xlink:_moz_target attribute, or failing that,
    1659             :    * the value of xlink:show, converted to a suitably equivalent named target
    1660             :    * (e.g. _blank).
    1661             :    */
    1662             :   virtual void GetLinkTarget(nsAString& aTarget);
    1663             : 
    1664             :   nsDOMTokenList* GetTokenList(nsIAtom* aAtom,
    1665             :                                const DOMTokenListSupportedTokenArray aSupportedTokens = nullptr);
    1666             : 
    1667             :   nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>*
    1668             :     RegisteredIntersectionObservers();
    1669             : 
    1670             : private:
    1671             :   /**
    1672             :    * Hook for implementing GetClasses.  This is guaranteed to only be
    1673             :    * called if the NODE_MAY_HAVE_CLASS flag is set.
    1674             :    */
    1675             :   const nsAttrValue* DoGetClasses() const;
    1676             : 
    1677             :   /**
    1678             :    * Get this element's client area rect in app units.
    1679             :    * @return the frame's client area
    1680             :    */
    1681             :   nsRect GetClientAreaRect();
    1682             : 
    1683             :   nsIScrollableFrame* GetScrollFrame(nsIFrame **aStyledFrame = nullptr,
    1684             :                                      FlushType aFlushType = FlushType::Layout);
    1685             : 
    1686             :   // Data members
    1687             :   EventStates mState;
    1688             :   // Per-node data managed by Servo.
    1689             :   mozilla::ServoCell<ServoNodeData*> mServoData;
    1690             : };
    1691             : 
    1692             : class RemoveFromBindingManagerRunnable : public mozilla::Runnable
    1693             : {
    1694             : public:
    1695             :   RemoveFromBindingManagerRunnable(nsBindingManager* aManager,
    1696             :                                    nsIContent* aContent,
    1697             :                                    nsIDocument* aDoc);
    1698             : 
    1699             :   NS_IMETHOD Run() override;
    1700             : private:
    1701             :   virtual ~RemoveFromBindingManagerRunnable();
    1702             :   RefPtr<nsBindingManager> mManager;
    1703             :   RefPtr<nsIContent> mContent;
    1704             :   nsCOMPtr<nsIDocument> mDoc;
    1705             : };
    1706             : 
    1707             : class DestinationInsertionPointList : public nsINodeList
    1708             : {
    1709             : public:
    1710             :   explicit DestinationInsertionPointList(Element* aElement);
    1711             : 
    1712             :   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
    1713           0 :   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DestinationInsertionPointList)
    1714             : 
    1715             :   // nsIDOMNodeList
    1716             :   NS_DECL_NSIDOMNODELIST
    1717             : 
    1718             :   // nsINodeList
    1719             :   virtual nsIContent* Item(uint32_t aIndex) override;
    1720             :   virtual int32_t IndexOf(nsIContent* aContent) override;
    1721           0 :   virtual nsINode* GetParentObject() override { return mParent; }
    1722             :   virtual uint32_t Length() const;
    1723             :   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
    1724             : protected:
    1725             :   virtual ~DestinationInsertionPointList();
    1726             : 
    1727             :   RefPtr<Element> mParent;
    1728             :   nsCOMArray<nsIContent> mDestinationPoints;
    1729             : };
    1730             : 
    1731             : NS_DEFINE_STATIC_IID_ACCESSOR(Element, NS_ELEMENT_IID)
    1732             : 
    1733             : inline bool
    1734       19670 : Element::HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const
    1735             : {
    1736       19670 :   NS_ASSERTION(nullptr != aName, "must have attribute name");
    1737       19670 :   NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown,
    1738             :                "must have a real namespace ID!");
    1739             : 
    1740       19670 :   return mAttrsAndChildren.IndexOfAttr(aName, aNameSpaceID) >= 0;
    1741             : }
    1742             : 
    1743             : inline bool
    1744       42685 : Element::AttrValueIs(int32_t aNameSpaceID,
    1745             :                      nsIAtom* aName,
    1746             :                      const nsAString& aValue,
    1747             :                      nsCaseTreatment aCaseSensitive) const
    1748             : {
    1749       42685 :   NS_ASSERTION(aName, "Must have attr name");
    1750       42685 :   NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, "Must have namespace");
    1751             : 
    1752       42685 :   const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
    1753       42685 :   return val && val->Equals(aValue, aCaseSensitive);
    1754             : }
    1755             : 
    1756             : inline bool
    1757        3375 : Element::AttrValueIs(int32_t aNameSpaceID,
    1758             :                      nsIAtom* aName,
    1759             :                      nsIAtom* aValue,
    1760             :                      nsCaseTreatment aCaseSensitive) const
    1761             : {
    1762        3375 :   NS_ASSERTION(aName, "Must have attr name");
    1763        3375 :   NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, "Must have namespace");
    1764        3375 :   NS_ASSERTION(aValue, "Null value atom");
    1765             : 
    1766        3375 :   const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
    1767        3375 :   return val && val->Equals(aValue, aCaseSensitive);
    1768             : }
    1769             : 
    1770             : } // namespace dom
    1771             : } // namespace mozilla
    1772             : 
    1773      863300 : inline mozilla::dom::Element* nsINode::AsElement()
    1774             : {
    1775      863300 :   MOZ_ASSERT(IsElement());
    1776      863300 :   return static_cast<mozilla::dom::Element*>(this);
    1777             : }
    1778             : 
    1779      111484 : inline const mozilla::dom::Element* nsINode::AsElement() const
    1780             : {
    1781      111484 :   MOZ_ASSERT(IsElement());
    1782      111484 :   return static_cast<const mozilla::dom::Element*>(this);
    1783             : }
    1784             : 
    1785        3759 : inline void nsINode::UnsetRestyleFlagsIfGecko()
    1786             : {
    1787        3759 :   if (IsElement() && !AsElement()->IsStyledByServo()) {
    1788        3644 :     UnsetFlags(ELEMENT_ALL_RESTYLE_FLAGS);
    1789             :   }
    1790        3759 : }
    1791             : 
    1792             : /**
    1793             :  * Macros to implement Clone(). _elementName is the class for which to implement
    1794             :  * Clone.
    1795             :  */
    1796             : #define NS_IMPL_ELEMENT_CLONE(_elementName)                                 \
    1797             : nsresult                                                                    \
    1798             : _elementName::Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,   \
    1799             :                     bool aPreallocateChildren) const                        \
    1800             : {                                                                           \
    1801             :   *aResult = nullptr;                                                       \
    1802             :   already_AddRefed<mozilla::dom::NodeInfo> ni =                             \
    1803             :     RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();                   \
    1804             :   _elementName *it = new _elementName(ni);                                  \
    1805             :   if (!it) {                                                                \
    1806             :     return NS_ERROR_OUT_OF_MEMORY;                                          \
    1807             :   }                                                                         \
    1808             :                                                                             \
    1809             :   nsCOMPtr<nsINode> kungFuDeathGrip = it;                                   \
    1810             :   nsresult rv = const_cast<_elementName*>(this)->CopyInnerTo(it, aPreallocateChildren); \
    1811             :   if (NS_SUCCEEDED(rv)) {                                                   \
    1812             :     kungFuDeathGrip.swap(*aResult);                                         \
    1813             :   }                                                                         \
    1814             :                                                                             \
    1815             :   return rv;                                                                \
    1816             : }
    1817             : 
    1818             : #define EXPAND(...) __VA_ARGS__
    1819             : #define NS_IMPL_ELEMENT_CLONE_WITH_INIT_HELPER(_elementName, extra_args_)   \
    1820             : nsresult                                                                    \
    1821             : _elementName::Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,   \
    1822             :                     bool aPreallocateChildren) const                        \
    1823             : {                                                                           \
    1824             :   *aResult = nullptr;                                                       \
    1825             :   already_AddRefed<mozilla::dom::NodeInfo> ni =                             \
    1826             :     RefPtr<mozilla::dom::NodeInfo>(aNodeInfo).forget();                     \
    1827             :   _elementName *it = new _elementName(ni EXPAND extra_args_);               \
    1828             :   if (!it) {                                                                \
    1829             :     return NS_ERROR_OUT_OF_MEMORY;                                          \
    1830             :   }                                                                         \
    1831             :                                                                             \
    1832             :   nsCOMPtr<nsINode> kungFuDeathGrip = it;                                   \
    1833             :   nsresult rv = it->Init();                                                 \
    1834             :   nsresult rv2 = const_cast<_elementName*>(this)->CopyInnerTo(it, aPreallocateChildren); \
    1835             :   if (NS_FAILED(rv2)) {                                                     \
    1836             :     rv = rv2;                                                               \
    1837             :   }                                                                         \
    1838             :   if (NS_SUCCEEDED(rv)) {                                                   \
    1839             :     kungFuDeathGrip.swap(*aResult);                                         \
    1840             :   }                                                                         \
    1841             :                                                                             \
    1842             :   return rv;                                                                \
    1843             : }
    1844             : 
    1845             : #define NS_IMPL_ELEMENT_CLONE_WITH_INIT(_elementName) \
    1846             :   NS_IMPL_ELEMENT_CLONE_WITH_INIT_HELPER(_elementName, ())
    1847             : #define NS_IMPL_ELEMENT_CLONE_WITH_INIT_AND_PARSER(_elementName) \
    1848             :   NS_IMPL_ELEMENT_CLONE_WITH_INIT_HELPER(_elementName, (, NOT_FROM_PARSER))
    1849             : 
    1850             : /**
    1851             :  * A macro to implement the getter and setter for a given string
    1852             :  * valued content property. The method uses the generic GetAttr and
    1853             :  * SetAttr methods.  We use the 5-argument form of SetAttr, because
    1854             :  * some consumers only implement that one, hiding superclass
    1855             :  * 4-argument forms.
    1856             :  */
    1857             : #define NS_IMPL_STRING_ATTR(_class, _method, _atom)                     \
    1858             :   NS_IMETHODIMP                                                         \
    1859             :   _class::Get##_method(nsAString& aValue)                               \
    1860             :   {                                                                     \
    1861             :     GetAttr(kNameSpaceID_None, nsGkAtoms::_atom, aValue);               \
    1862             :     return NS_OK;                                                       \
    1863             :   }                                                                     \
    1864             :   NS_IMETHODIMP                                                         \
    1865             :   _class::Set##_method(const nsAString& aValue)                         \
    1866             :   {                                                                     \
    1867             :     return SetAttr(kNameSpaceID_None, nsGkAtoms::_atom, nullptr, aValue, true); \
    1868             :   }
    1869             : 
    1870             : /**
    1871             :  * A macro to implement the getter and setter for a given boolean
    1872             :  * valued content property. The method uses the GetBoolAttr and
    1873             :  * SetBoolAttr methods.
    1874             :  */
    1875             : #define NS_IMPL_BOOL_ATTR(_class, _method, _atom)                     \
    1876             :   NS_IMETHODIMP                                                       \
    1877             :   _class::Get##_method(bool* aValue)                                  \
    1878             :   {                                                                   \
    1879             :     *aValue = GetBoolAttr(nsGkAtoms::_atom);                          \
    1880             :     return NS_OK;                                                     \
    1881             :   }                                                                   \
    1882             :   NS_IMETHODIMP                                                       \
    1883             :   _class::Set##_method(bool aValue)                                   \
    1884             :   {                                                                   \
    1885             :     return SetBoolAttr(nsGkAtoms::_atom, aValue);                     \
    1886             :   }
    1887             : 
    1888             : #define NS_FORWARD_NSIDOMELEMENT_TO_GENERIC                                   \
    1889             : typedef mozilla::dom::Element Element;                                        \
    1890             : NS_IMETHOD GetTagName(nsAString& aTagName) final override                     \
    1891             : {                                                                             \
    1892             :   Element::GetTagName(aTagName);                                              \
    1893             :   return NS_OK;                                                               \
    1894             : }                                                                             \
    1895             : NS_IMETHOD GetAttributes(nsIDOMMozNamedAttrMap** aAttributes) final override  \
    1896             : {                                                                             \
    1897             :   NS_ADDREF(*aAttributes = Attributes());                                     \
    1898             :   return NS_OK;                                                               \
    1899             : }                                                                             \
    1900             : using Element::GetAttribute;                                                  \
    1901             : NS_IMETHOD GetAttribute(const nsAString& name, nsAString& _retval) final      \
    1902             :   override                                                                    \
    1903             : {                                                                             \
    1904             :   nsString attr;                                                              \
    1905             :   GetAttribute(name, attr);                                                   \
    1906             :   _retval = attr;                                                             \
    1907             :   return NS_OK;                                                               \
    1908             : }                                                                             \
    1909             : NS_IMETHOD SetAttribute(const nsAString& name,                                \
    1910             :                         const nsAString& value) override                      \
    1911             : {                                                                             \
    1912             :   mozilla::ErrorResult rv;                                                    \
    1913             :   Element::SetAttribute(name, value, rv);                                     \
    1914             :   return rv.StealNSResult();                                                  \
    1915             : }                                                                             \
    1916             : using Element::HasAttribute;                                                  \
    1917             : NS_IMETHOD HasAttribute(const nsAString& name,                                \
    1918             :                            bool* _retval) final override                      \
    1919             : {                                                                             \
    1920             :   *_retval = HasAttribute(name);                                              \
    1921             :   return NS_OK;                                                               \
    1922             : }                                                                             \
    1923             : NS_IMETHOD GetAttributeNode(const nsAString& name,                            \
    1924             :                             nsIDOMAttr** _retval) final override              \
    1925             : {                                                                             \
    1926             :   NS_IF_ADDREF(*_retval = Element::GetAttributeNode(name));                   \
    1927             :   return NS_OK;                                                               \
    1928             : }                                                                             \
    1929             : NS_IMETHOD GetAttributeNodeNS(const nsAString& namespaceURI,                  \
    1930             :                               const nsAString& localName,                     \
    1931             :                               nsIDOMAttr** _retval) final override            \
    1932             : {                                                                             \
    1933             :   NS_IF_ADDREF(*_retval = Element::GetAttributeNodeNS(namespaceURI,           \
    1934             :                                                       localName));            \
    1935             :   return NS_OK;                                                               \
    1936             : }
    1937             : #endif // mozilla_dom_Element_h__

Generated by: LCOV version 1.13