LCOV - code coverage report
Current view: top level - layout/style - GeckoStyleContext.h (source / functions) Hit Total Coverage
Test: output.info Lines: 25 26 96.2 %
Date: 2017-07-14 16:53:18 Functions: 6 7 85.7 %
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             : #ifndef mozilla_GeckoStyleContext_h
       8             : #define mozilla_GeckoStyleContext_h
       9             : 
      10             : #include "nsStyleContext.h"
      11             : 
      12             : namespace mozilla {
      13             : 
      14             : class GeckoStyleContext final : public nsStyleContext {
      15             : public:
      16             :   GeckoStyleContext(nsStyleContext* aParent,
      17             :                     nsIAtom* aPseudoTag,
      18             :                     CSSPseudoElementType aPseudoType,
      19             :                     already_AddRefed<nsRuleNode> aRuleNode,
      20             :                     bool aSkipParentDisplayBasedStyleFixup);
      21             : 
      22             :   void* operator new(size_t sz, nsPresContext* aPresContext);
      23             : 
      24       76305 :   nsPresContext* PresContext() const {
      25       76305 :     return RuleNode()->PresContext();
      26             :   }
      27             : 
      28             :   void AddChild(GeckoStyleContext* aChild);
      29             :   void RemoveChild(GeckoStyleContext* aChild);
      30             : 
      31             :   void* GetUniqueStyleData(const nsStyleStructID& aSID);
      32             :   void* CreateEmptyStyleData(const nsStyleStructID& aSID);
      33             : 
      34             :   /**
      35             :    * Ensures the same structs are cached on this style context as would be
      36             :    * done if we called aOther->CalcDifference(this).
      37             :    */
      38             :   void EnsureSameStructsCached(nsStyleContext* aOldContext);
      39             : 
      40             :   /**
      41             :    * Sets the NS_STYLE_INELIGIBLE_FOR_SHARING bit on this style context
      42             :    * and its descendants.  If it finds a descendant that has the bit
      43             :    * already set, assumes that it can skip that subtree.
      44             :    */
      45             :   void SetIneligibleForSharing();
      46             :   /**
      47             :    * On each descendant of this style context, clears out any cached inherited
      48             :    * structs indicated in aStructs.
      49             :    */
      50             :   void ClearCachedInheritedStyleDataOnDescendants(uint32_t aStructs);
      51             :   // Find, if it already exists *and is easily findable* (i.e., near the
      52             :   // start of the child list), a style context whose:
      53             :   //  * GetPseudo() matches aPseudoTag
      54             :   //  * mRuleNode matches aSource
      55             :   //  * !!GetStyleIfVisited() == !!aSourceIfVisited, and, if they're
      56             :   //    non-null, GetStyleIfVisited()->mRuleNode == aSourceIfVisited
      57             :   //  * RelevantLinkVisited() == aRelevantLinkVisited
      58             :   already_AddRefed<GeckoStyleContext>
      59             :   FindChildWithRules(const nsIAtom* aPseudoTag,
      60             :                      nsRuleNode* aSource,
      61             :                      nsRuleNode* aSourceIfVisited,
      62             :                      bool aRelevantLinkVisited);
      63             : 
      64             :   // Tell this style context to cache aStruct as the struct for aSID
      65             :   void SetStyle(nsStyleStructID aSID, void* aStruct);
      66             : 
      67             : 
      68             :   /*
      69             :    * Get the style data for a style struct.  This is the most important
      70             :    * member function of nsStyleContext.  It fills in a const pointer
      71             :    * to a style data struct that is appropriate for the style context's
      72             :    * frame.  This struct may be shared with other contexts (either in
      73             :    * the rule tree or the style context tree), so it should not be
      74             :    * modified.
      75             :    *
      76             :    * This function will NOT return null (even when out of memory) when
      77             :    * given a valid style struct ID, so the result does not need to be
      78             :    * null-checked.
      79             :    *
      80             :    * The typesafe functions below are preferred to the use of this
      81             :    * function, both because they're easier to read and because they're
      82             :    * faster.
      83             :    */
      84             :   const void* NS_FASTCALL StyleData(nsStyleStructID aSID) MOZ_NONNULL_RETURN;
      85             : 
      86             : #ifdef DEBUG
      87             :   void ListDescendants(FILE* out, int32_t aIndent);
      88             : 
      89             : #endif
      90             : 
      91             : #ifdef RESTYLE_LOGGING
      92             : 
      93             :   // This only gets called under call trees where we've already checked
      94             :   // that PresContext()->RestyleManager()->ShouldLogRestyle() returned true.
      95             :   // It exists here just to satisfy LOG_RESTYLE's expectations.
      96           0 :   bool ShouldLogRestyle() { return true; }
      97             :   void LogStyleContextTree(int32_t aLoggingDepth, uint32_t aStructs);
      98             :   void LogStyleContextTree(bool aFirst, uint32_t aStructs);
      99             :   int32_t& LoggingDepth();
     100             :   nsCString GetCachedStyleDataAsString(uint32_t aStructs);
     101             : #endif
     102             : 
     103             :   // Only called for Gecko-backed nsStyleContexts.
     104             :   void ApplyStyleFixups(bool aSkipParentDisplayBasedStyleFixup);
     105             : 
     106             :   bool HasNoChildren() const;
     107             : 
     108      380527 :   nsRuleNode* RuleNode() const {
     109      380527 :     MOZ_ASSERT(mRuleNode);
     110      380527 :     return mRuleNode;
     111             :   }
     112             : 
     113        3236 :   ~GeckoStyleContext() {
     114        1618 :     Destructor();
     115        1618 :   }
     116             : 
     117             :   /**
     118             :    * Swaps owned style struct pointers between this and aNewContext, on
     119             :    * the assumption that aNewContext is the new style context for a frame
     120             :    * and this is the old one.  aStructs indicates which structs to consider
     121             :    * swapping; only those which are owned in both this and aNewContext
     122             :    * will be swapped.
     123             :    *
     124             :    * Additionally, if there are identical struct pointers for one of the
     125             :    * structs indicated by aStructs, and it is not an owned struct on this,
     126             :    * then the cached struct slot on this will be set to null.  If the struct
     127             :    * has been swapped on an ancestor, this style context (being the old one)
     128             :    * will be left caching the struct pointer on the new ancestor, despite
     129             :    * inheriting from the old ancestor.  This is not normally a problem, as
     130             :    * this style context will usually be destroyed by being released at the
     131             :    * end of ElementRestyler::Restyle; but for style contexts held on to outside
     132             :    * of the frame, we need to clear out the cached pointer so that if we need
     133             :    * it again we'll re-fetch it from the new ancestor.
     134             :    */
     135             :   void SwapStyleData(GeckoStyleContext* aNewContext, uint32_t aStructs);
     136             : 
     137             :   void DestroyCachedStructs(nsPresContext* aPresContext);
     138             : 
     139             :   /**
     140             :    * Return style data that is currently cached on the style context.
     141             :    * Only returns the structs we cache ourselves; never consults the
     142             :    * rule tree.
     143             :    *
     144             :    * For "internal" use only in nsStyleContext and nsRuleNode.
     145             :    */
     146      291591 :   const void* GetCachedStyleData(nsStyleStructID aSID)
     147             :   {
     148             :     const void* cachedData;
     149      291591 :     if (nsCachedStyleData::IsReset(aSID)) {
     150      283075 :       if (mCachedResetData) {
     151      173481 :         cachedData = mCachedResetData->mStyleStructs[aSID];
     152             :       } else {
     153      109594 :         cachedData = nullptr;
     154             :       }
     155             :     } else {
     156        8516 :       cachedData = mCachedInheritedData.mStyleStructs[aSID];
     157             :     }
     158      291591 :     return cachedData;
     159             :   }
     160             : 
     161             :   // mCachedInheritedData and mCachedResetData point to both structs that
     162             :   // are owned by this style context and structs that are owned by one of
     163             :   // this style context's ancestors (which are indirectly owned since this
     164             :   // style context owns a reference to its parent).  If the bit in |mBits|
     165             :   // is set for a struct, that means that the pointer for that struct is
     166             :   // owned by an ancestor or by the rule node rather than by this style context.
     167             :   // Since style contexts typically have some inherited data but only sometimes
     168             :   // have reset data, we always allocate the mCachedInheritedData, but only
     169             :   // sometimes allocate the mCachedResetData.
     170             :   nsResetStyleData*       mCachedResetData; // Cached reset style data.
     171             :   nsInheritedStyleData    mCachedInheritedData; // Cached inherited style data
     172             : 
     173             : #ifdef DEBUG
     174             :   void AssertStructsNotUsedElsewhere(GeckoStyleContext* aDestroyingContext,
     175             :                                      int32_t aLevels) const;
     176             : #endif
     177             : 
     178             : private:
     179             :   // Helper for ClearCachedInheritedStyleDataOnDescendants.
     180             :   void DoClearCachedInheritedStyleDataOnDescendants(uint32_t aStructs);
     181             : 
     182             :   // Children are kept in two circularly-linked lists.  The list anchor
     183             :   // is not part of the list (null for empty), and we point to the first
     184             :   // child.
     185             :   // mEmptyChild for children whose rule node is the root rule node, and
     186             :   // mChild for other children.  The order of children is not
     187             :   // meaningful.
     188             :   GeckoStyleContext* mChild;
     189             :   GeckoStyleContext* mEmptyChild;
     190             :   GeckoStyleContext* mPrevSibling;
     191             :   GeckoStyleContext* mNextSibling;
     192             :   RefPtr<nsRuleNode> mRuleNode;
     193             : 
     194             : #ifdef DEBUG
     195             : public:
     196             :   struct AutoCheckDependency {
     197             : 
     198             :     GeckoStyleContext* mStyleContext;
     199             :     nsStyleStructID mOuterSID;
     200             : 
     201      286889 :     AutoCheckDependency(GeckoStyleContext* aContext, nsStyleStructID aInnerSID)
     202      286889 :       : mStyleContext(aContext)
     203             :     {
     204      286889 :       mOuterSID = aContext->mComputingStruct;
     205      286889 :       MOZ_ASSERT(mOuterSID == nsStyleStructID_None ||
     206             :                  DependencyAllowed(mOuterSID, aInnerSID),
     207             :                  "Undeclared dependency, see generate-stylestructlist.py");
     208      286889 :       aContext->mComputingStruct = aInnerSID;
     209      286889 :     }
     210             : 
     211      286889 :     ~AutoCheckDependency()
     212      286889 :     {
     213      286889 :       mStyleContext->mComputingStruct = mOuterSID;
     214      286889 :     }
     215             : 
     216             :   };
     217             : 
     218             : private:
     219             :   // Used to check for undeclared dependencies.
     220             :   // See AUTO_CHECK_DEPENDENCY in nsStyleContextInlines.h.
     221             :   nsStyleStructID         mComputingStruct;
     222             : 
     223             : #define AUTO_CHECK_DEPENDENCY(gecko_, sid_) \
     224             :   mozilla::GeckoStyleContext::AutoCheckDependency checkNesting_(gecko_, sid_)
     225             : #else
     226             : #define AUTO_CHECK_DEPENDENCY(gecko_, sid_)
     227             : #endif
     228             : };
     229             : }
     230             : 
     231             : #endif // mozilla_GeckoStyleContext_h

Generated by: LCOV version 1.13