LCOV - code coverage report
Current view: top level - layout/style - nsRuleProcessorData.h (source / functions) Hit Total Coverage
Test: output.info Lines: 135 186 72.6 %
Date: 2017-07-14 16:53:18 Functions: 30 38 78.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : /*
       7             :  * data structures passed to nsIStyleRuleProcessor methods (to pull loop
       8             :  * invariant computations out of the loop)
       9             :  */
      10             : 
      11             : #ifndef nsRuleProcessorData_h_
      12             : #define nsRuleProcessorData_h_
      13             : 
      14             : #include "nsAutoPtr.h"
      15             : #include "nsChangeHint.h"
      16             : #include "nsCompatibility.h"
      17             : #include "nsCSSPseudoElements.h"
      18             : #include "nsRuleWalker.h"
      19             : #include "nsNthIndexCache.h"
      20             : #include "nsILoadContext.h"
      21             : #include "nsIDocument.h"
      22             : #include "mozilla/AutoRestore.h"
      23             : #include "mozilla/BloomFilter.h"
      24             : #include "mozilla/EventStates.h"
      25             : #include "mozilla/GuardObjects.h"
      26             : #include "mozilla/dom/Element.h"
      27             : 
      28             : class nsIAtom;
      29             : class nsIContent;
      30             : class nsICSSPseudoComparator;
      31             : struct TreeMatchContext;
      32             : 
      33             : /**
      34             :  * An AncestorFilter is used to keep track of ancestors so that we can
      35             :  * quickly tell that a particular selector is not relevant to a given
      36             :  * element.
      37             :  */
      38        4058 : class MOZ_STACK_CLASS AncestorFilter {
      39             :   friend struct TreeMatchContext;
      40             :  public:
      41             :   /* Maintenance of our ancestor state */
      42             :   void PushAncestor(mozilla::dom::Element *aElement);
      43             :   void PopAncestor();
      44             : 
      45             :   /* Check whether we might have an ancestor matching one of the given
      46             :      atom hashes.  |hashes| must have length hashListLength */
      47             :   template<size_t hashListLength>
      48      167791 :     bool MightHaveMatchingAncestor(const uint32_t* aHashes) const
      49             :   {
      50      167791 :     MOZ_ASSERT(mFilter);
      51      177368 :     for (size_t i = 0; i < hashListLength && aHashes[i]; ++i) {
      52       74827 :       if (!mFilter->mightContain(aHashes[i])) {
      53       65250 :         return false;
      54             :       }
      55             :     }
      56             : 
      57      102541 :     return true;
      58             :   }
      59             : 
      60        9529 :   bool HasFilter() const { return mFilter; }
      61             : 
      62             : #ifdef DEBUG
      63             :   void AssertHasAllAncestors(mozilla::dom::Element *aElement) const;
      64             : #endif
      65             : 
      66             :  private:
      67             :   // Using 2^12 slots makes the Bloom filter a nice round page in
      68             :   // size, so let's do that.  We get a false positive rate of 1% or
      69             :   // less even with several hundred things in the filter.  Note that
      70             :   // we allocate the filter lazily, because not all tree match
      71             :   // contexts can use one effectively.
      72             :   typedef mozilla::BloomFilter<12, nsIAtom> Filter;
      73             :   nsAutoPtr<Filter> mFilter;
      74             : 
      75             :   // Stack of indices to pop to.  These are indices into mHashes.
      76             :   nsTArray<uint32_t> mPopTargets;
      77             : 
      78             :   // List of hashes; this is what we pop using mPopTargets.  We store
      79             :   // hashes of our ancestor element tag names, ids, and classes in
      80             :   // here.
      81             :   nsTArray<uint32_t> mHashes;
      82             : 
      83             :   // A debug-only stack of Elements for use in assertions
      84             : #ifdef DEBUG
      85             :   nsTArray<mozilla::dom::Element*> mElements;
      86             : #endif
      87             : };
      88             : 
      89             : /**
      90             :  * A |TreeMatchContext| has data about a matching operation.  The
      91             :  * data are not node-specific but are invariants of the DOM tree the
      92             :  * nodes being matched against are in.
      93             :  *
      94             :  * Most of the members are in parameters to selector matching.  The
      95             :  * one out parameter is mHaveRelevantLink.  Consumers that use a
      96             :  * TreeMatchContext for more than one matching operation and care
      97             :  * about :visited and mHaveRelevantLink need to
      98             :  * ResetForVisitedMatching() and ResetForUnvisitedMatching() as
      99             :  * needed.
     100             :  */
     101        2029 : struct MOZ_STACK_CLASS TreeMatchContext {
     102             :   // Reset this context for matching for the style-if-:visited.
     103           0 :   void ResetForVisitedMatching() {
     104           0 :     NS_PRECONDITION(mForStyling, "Why is this being called?");
     105           0 :     mHaveRelevantLink = false;
     106           0 :     mVisitedHandling = nsRuleWalker::eRelevantLinkVisited;
     107           0 :   }
     108             : 
     109       15113 :   void ResetForUnvisitedMatching() {
     110       15113 :     NS_PRECONDITION(mForStyling, "Why is this being called?");
     111       15113 :     mHaveRelevantLink = false;
     112       15113 :     mVisitedHandling = nsRuleWalker::eRelevantLinkUnvisited;
     113       15113 :   }
     114             : 
     115           0 :   void SetHaveRelevantLink() { mHaveRelevantLink = true; }
     116        2548 :   bool HaveRelevantLink() const { return mHaveRelevantLink; }
     117             : 
     118       16978 :   nsRuleWalker::VisitedHandlingType VisitedHandling() const
     119             :   {
     120       16978 :     return mVisitedHandling;
     121             :   }
     122             : 
     123           3 :   void AddScopeElement(mozilla::dom::Element* aElement) {
     124           3 :     NS_PRECONDITION(mHaveSpecifiedScope,
     125             :                     "Should be set before calling AddScopeElement()");
     126           3 :     mScopes.AppendElement(aElement);
     127           3 :   }
     128           0 :   bool IsScopeElement(mozilla::dom::Element* aElement) const {
     129           0 :     return mScopes.Contains(aElement);
     130             :   }
     131           3 :   void SetHasSpecifiedScope() {
     132           3 :     mHaveSpecifiedScope = true;
     133           3 :   }
     134           0 :   bool HasSpecifiedScope() const {
     135           0 :     return mHaveSpecifiedScope;
     136             :   }
     137             : 
     138             :   /**
     139             :    * Initialize the ancestor filter and list of style scopes.  If aElement is
     140             :    * not null, it and all its ancestors will be passed to
     141             :    * mAncestorFilter.PushAncestor and PushStyleScope, starting from the root and
     142             :    * going down the tree.  Must only be called for elements in a document.
     143             :    */
     144             :   void InitAncestors(mozilla::dom::Element *aElement);
     145             : 
     146             :   /**
     147             :    * Like InitAncestors, but only initializes the style scope list, not the
     148             :    * ancestor filter.  May be called for elements outside a document.
     149             :    */
     150             :   void InitStyleScopes(mozilla::dom::Element* aElement);
     151             : 
     152        1889 :   void PushStyleScope(mozilla::dom::Element* aElement)
     153             :   {
     154        1889 :     NS_PRECONDITION(aElement, "aElement must not be null");
     155        1889 :     if (aElement->IsScopedStyleRoot()) {
     156           0 :       mStyleScopes.AppendElement(aElement);
     157             :     }
     158        1889 :   }
     159             : 
     160        1223 :   void PopStyleScope(mozilla::dom::Element* aElement)
     161             :   {
     162        1223 :     NS_PRECONDITION(aElement, "aElement must not be null");
     163        1223 :     if (mStyleScopes.SafeLastElement(nullptr) == aElement) {
     164           0 :       mStyleScopes.TruncateLength(mStyleScopes.Length() - 1);
     165             :     }
     166        1223 :   }
     167             : 
     168           0 :   bool PopStyleScopeForSelectorMatching(mozilla::dom::Element* aElement)
     169             :   {
     170           0 :     NS_ASSERTION(mForScopedStyle, "only call PopStyleScopeForSelectorMatching "
     171             :                                   "when mForScopedStyle is true");
     172             : 
     173           0 :     if (!mCurrentStyleScope) {
     174           0 :       return false;
     175             :     }
     176           0 :     if (mCurrentStyleScope == aElement) {
     177           0 :       mCurrentStyleScope = nullptr;
     178             :     }
     179           0 :     return true;
     180             :   }
     181             : 
     182             : #ifdef DEBUG
     183             :   void AssertHasAllStyleScopes(mozilla::dom::Element* aElement) const;
     184             : #endif
     185             : 
     186      136014 :   bool SetStyleScopeForSelectorMatching(mozilla::dom::Element* aSubject,
     187             :                                         mozilla::dom::Element* aScope)
     188             :   {
     189             : #ifdef DEBUG
     190      136014 :     AssertHasAllStyleScopes(aSubject);
     191             : #endif
     192             : 
     193      136014 :     mForScopedStyle = !!aScope;
     194      136014 :     if (!aScope) {
     195             :       // This is not for a scoped style sheet; return true, as we want
     196             :       // selector matching to proceed.
     197      136014 :       mCurrentStyleScope = nullptr;
     198      136014 :       return true;
     199             :     }
     200           0 :     if (aScope == aSubject) {
     201             :       // Although the subject is the same element as the scope, as soon
     202             :       // as we continue with selector matching up the tree we don't want
     203             :       // to match any more elements.  So we return true to indicate that
     204             :       // we want to do the initial selector matching, but set
     205             :       // mCurrentStyleScope to null so that no ancestor elements will match.
     206           0 :       mCurrentStyleScope = nullptr;
     207           0 :       return true;
     208             :     }
     209           0 :     if (mStyleScopes.Contains(aScope)) {
     210             :       // mStyleScopes contains all of the scope elements that are ancestors of
     211             :       // aSubject, so if aScope is in mStyleScopes, then we do want selector
     212             :       // matching to proceed.
     213           0 :       mCurrentStyleScope = aScope;
     214           0 :       return true;
     215             :     }
     216             :     // Otherwise, we're not in the scope, and we don't want to proceed
     217             :     // with selector matching.
     218           0 :     mCurrentStyleScope = nullptr;
     219           0 :     return false;
     220             :   }
     221             : 
     222           0 :   bool IsWithinStyleScopeForSelectorMatching() const
     223             :   {
     224           0 :     NS_ASSERTION(mForScopedStyle, "only call IsWithinScopeForSelectorMatching "
     225             :                                   "when mForScopedStyle is true");
     226           0 :     return mCurrentStyleScope;
     227             :   }
     228             : 
     229             :   /*
     230             :    * Helper class for maintaining the ancestor state.
     231             :    *
     232             :    * This class does nothing if aTreeMatchContext is null, which is the case for
     233             :    * the Servo style system.
     234             :    */
     235             :   class MOZ_RAII AutoAncestorPusher {
     236             :   public:
     237        6325 :     explicit AutoAncestorPusher(TreeMatchContext* aTreeMatchContext
     238             :                                 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     239        6325 :       : mPushedAncestor(false)
     240             :       , mPushedStyleScope(false)
     241             :       , mTreeMatchContext(aTreeMatchContext)
     242        6325 :       , mElement(nullptr)
     243             :     {
     244        6325 :       MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     245        6325 :     }
     246             : 
     247        1207 :     void PushAncestorAndStyleScope(mozilla::dom::Element* aElement) {
     248        1207 :       if (!mTreeMatchContext) {
     249           0 :         MOZ_ASSERT(!aElement || aElement->IsStyledByServo());
     250           0 :         return;
     251             :       }
     252             : 
     253        1207 :       MOZ_ASSERT(!mElement);
     254        1207 :       if (aElement) {
     255        1207 :         mElement = aElement;
     256        1207 :         mPushedAncestor = true;
     257        1207 :         mPushedStyleScope = true;
     258        1207 :         mTreeMatchContext->mAncestorFilter.PushAncestor(aElement);
     259        1207 :         mTreeMatchContext->PushStyleScope(aElement);
     260             :       }
     261             :     }
     262             : 
     263        1165 :     void PushAncestorAndStyleScope(nsIContent* aContent) {
     264        1165 :       if (!mTreeMatchContext) {
     265           0 :         MOZ_ASSERT(!aContent || aContent->IsStyledByServo());
     266           0 :         return;
     267             :       }
     268             : 
     269        1165 :       if (aContent && aContent->IsElement()) {
     270        1163 :         PushAncestorAndStyleScope(aContent->AsElement());
     271             :       }
     272             :     }
     273             : 
     274          16 :     void PushStyleScope(mozilla::dom::Element* aElement) {
     275          16 :       if (!mTreeMatchContext) {
     276           0 :         MOZ_ASSERT(!aElement || aElement->IsStyledByServo());
     277           0 :         return;
     278             :       }
     279             : 
     280          16 :       MOZ_ASSERT(!mElement);
     281          16 :       if (aElement) {
     282          16 :         mElement = aElement;
     283          16 :         mPushedStyleScope = true;
     284          16 :         mTreeMatchContext->PushStyleScope(aElement);
     285             :       }
     286             :     }
     287             : 
     288          14 :     void PushStyleScope(nsIContent* aContent) {
     289          14 :       if (!mTreeMatchContext) {
     290           0 :         MOZ_ASSERT(!aContent || aContent->IsStyledByServo());
     291           0 :         return;
     292             :       }
     293             : 
     294          14 :       if (aContent && aContent->IsElement()) {
     295          14 :         PushStyleScope(aContent->AsElement());
     296             :       }
     297             :     }
     298             : 
     299       12650 :     ~AutoAncestorPusher() {
     300        6325 :       if (mPushedAncestor) {
     301        1207 :         mTreeMatchContext->mAncestorFilter.PopAncestor();
     302             :       }
     303        6325 :       if (mPushedStyleScope) {
     304        1223 :         mTreeMatchContext->PopStyleScope(mElement);
     305             :       }
     306        6325 :     }
     307             : 
     308             :   private:
     309             :     bool mPushedAncestor;
     310             :     bool mPushedStyleScope;
     311             :     TreeMatchContext* mTreeMatchContext;
     312             :     mozilla::dom::Element* mElement;
     313             :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     314             :   };
     315             : 
     316             :   /* Helper class for tracking whether we're skipping the ApplyStyleFixups
     317             :    * code for special cases where child element style is modified based on
     318             :    * parent display value.
     319             :    *
     320             :    * The optional second parameter aSkipParentDisplayBasedStyleFixup allows
     321             :    * this class to be instantiated but only conditionally activated (e.g.
     322             :    * in cases where we may or may not want to be skipping flex/grid-item
     323             :    * style fixup for a particular chunk of code).
     324             :    */
     325        1106 :   class MOZ_RAII AutoParentDisplayBasedStyleFixupSkipper {
     326             :   public:
     327        1106 :     explicit AutoParentDisplayBasedStyleFixupSkipper(TreeMatchContext& aTreeMatchContext,
     328             :                                                      bool aSkipParentDisplayBasedStyleFixup = true
     329             :                                                      MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     330        1106 :       : mAutoRestorer(aTreeMatchContext.mSkippingParentDisplayBasedStyleFixup)
     331             :     {
     332        1106 :       MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     333        1106 :       if (aSkipParentDisplayBasedStyleFixup) {
     334         326 :         aTreeMatchContext.mSkippingParentDisplayBasedStyleFixup = true;
     335             :       }
     336        1106 :     }
     337             : 
     338             :   private:
     339             :     mozilla::AutoRestore<bool> mAutoRestorer;
     340             :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     341             :   };
     342             : 
     343             :   // Is this matching operation for the creation of a style context?
     344             :   // (If it is, we need to set slow selector bits on nodes indicating
     345             :   // that certain restyling needs to happen.)
     346             :   const bool mForStyling;
     347             : 
     348             :  private:
     349             :   // When mVisitedHandling is eRelevantLinkUnvisited, this is set to true if a
     350             :   // relevant link (see explanation in definition of VisitedHandling enum) was
     351             :   // encountered during the matching process, which means that matching needs
     352             :   // to be rerun with eRelevantLinkVisited.  Otherwise, its behavior is
     353             :   // undefined (it might get set appropriately, or might not).
     354             :   bool mHaveRelevantLink;
     355             : 
     356             :   // If true, then our contextual reference element set is specified,
     357             :   // and is given by mScopes.
     358             :   bool mHaveSpecifiedScope;
     359             : 
     360             :   // How matching should be performed.  See the documentation for
     361             :   // nsRuleWalker::VisitedHandlingType.
     362             :   nsRuleWalker::VisitedHandlingType mVisitedHandling;
     363             : 
     364             :   // For matching :scope
     365             :   AutoTArray<mozilla::dom::Element*, 1> mScopes;
     366             :  public:
     367             :   // The document we're working with.
     368             :   nsIDocument* const mDocument;
     369             : 
     370             :   // Whether our document is HTML (as opposed to XML of some sort,
     371             :   // including XHTML).
     372             :   // XXX XBL2 issue: Should we be caching this?  What should it be for XBL2?
     373             :   const bool mIsHTMLDocument;
     374             : 
     375             :   // Possibly remove use of mCompatMode in SelectorMatches?
     376             :   // XXX XBL2 issue: Should we be caching this?  What should it be for XBL2?
     377             :   const nsCompatibility mCompatMode;
     378             : 
     379             :   // The nth-index cache we should use
     380             :   nsNthIndexCache mNthIndexCache;
     381             : 
     382             :   // An ancestor filter
     383             :   AncestorFilter mAncestorFilter;
     384             : 
     385             :   // Whether this document is using PB mode
     386             :   bool mUsingPrivateBrowsing;
     387             : 
     388             :   // Whether we're currently skipping the part of ApplyStyleFixups that changes
     389             :   // style of child elements based on their parent's display value
     390             :   // (e.g. for children of elements that have a mandatory frame-type for which
     391             :   // we ignore "display:flex/grid").
     392             :   bool mSkippingParentDisplayBasedStyleFixup;
     393             : 
     394             :   // Whether this TreeMatchContext is being used with an nsCSSRuleProcessor
     395             :   // for an HTML5 scoped style sheet.
     396             :   bool mForScopedStyle;
     397             : 
     398             :   // An enum that communicates the consumer's intensions for this
     399             :   // TreeMatchContext in terms of :visited handling.  eNeverMatchVisited means
     400             :   // that this TreeMatchContext's VisitedHandlingType will always be
     401             :   // eRelevantLinkUnvisited (in other words, this value will be passed to the
     402             :   // constructor and ResetForVisitedMatching() will never be called).
     403             :   // eMatchVisitedDefault doesn't communicate any information about the current
     404             :   // or future VisitedHandlingType of this TreeMatchContext.
     405             :   enum MatchVisited {
     406             :     eNeverMatchVisited,
     407             :     eMatchVisitedDefault
     408             :   };
     409             : 
     410             :   // List of ancestor elements that define a style scope (due to having a
     411             :   // <style scoped> child).
     412             :   AutoTArray<mozilla::dom::Element*, 1> mStyleScopes;
     413             : 
     414             :   // The current style scope element for selector matching.
     415             :   mozilla::dom::Element* mCurrentStyleScope;
     416             : 
     417             :   // Constructor to use when creating a tree match context for styling
     418        2029 :   TreeMatchContext(bool aForStyling,
     419             :                    nsRuleWalker::VisitedHandlingType aVisitedHandling,
     420             :                    nsIDocument* aDocument,
     421             :                    MatchVisited aMatchVisited = eMatchVisitedDefault)
     422        2029 :     : mForStyling(aForStyling)
     423             :     , mHaveRelevantLink(false)
     424             :     , mHaveSpecifiedScope(false)
     425             :     , mVisitedHandling(aVisitedHandling)
     426             :     , mDocument(aDocument)
     427        2029 :     , mIsHTMLDocument(aDocument->IsHTMLDocument())
     428        2029 :     , mCompatMode(aDocument->GetCompatibilityMode())
     429             :     , mUsingPrivateBrowsing(false)
     430             :     , mSkippingParentDisplayBasedStyleFixup(false)
     431             :     , mForScopedStyle(false)
     432        6087 :     , mCurrentStyleScope(nullptr)
     433             :   {
     434        2029 :     if (aMatchVisited != eNeverMatchVisited) {
     435        2020 :       nsILoadContext* loadContext = mDocument->GetLoadContext();
     436        2020 :       if (loadContext) {
     437        1817 :         mUsingPrivateBrowsing = loadContext->UsePrivateBrowsing();
     438             :       }
     439             :     } else {
     440           9 :       MOZ_ASSERT(aVisitedHandling == nsRuleWalker::eRelevantLinkUnvisited,
     441             :                  "You promised you'd never try to match :visited!");
     442             :     }
     443        2029 :   }
     444             : 
     445             :   enum ForFrameConstructionTag { ForFrameConstruction };
     446             : 
     447         104 :   TreeMatchContext(nsIDocument* aDocument, ForFrameConstructionTag)
     448         104 :     : TreeMatchContext(true, nsRuleWalker::eRelevantLinkUnvisited, aDocument)
     449         104 :   {}
     450             : };
     451             : 
     452             : struct MOZ_STACK_CLASS RuleProcessorData {
     453        4700 :   RuleProcessorData(nsPresContext* aPresContext,
     454             :                     nsRuleWalker* aRuleWalker)
     455        4700 :     : mPresContext(aPresContext),
     456             :       mRuleWalker(aRuleWalker),
     457        4700 :       mScope(nullptr)
     458             :   {
     459        4700 :     NS_PRECONDITION(mPresContext, "Must have prescontext");
     460        4700 :   }
     461             : 
     462             :   nsPresContext* const mPresContext;
     463             :   nsRuleWalker* const mRuleWalker; // Used to add rules to our results.
     464             :   mozilla::dom::Element* mScope;
     465             : };
     466             : 
     467             : struct MOZ_STACK_CLASS ElementDependentRuleProcessorData :
     468             :                           public RuleProcessorData {
     469        4490 :   ElementDependentRuleProcessorData(nsPresContext* aPresContext,
     470             :                                     mozilla::dom::Element* aElement,
     471             :                                     nsRuleWalker* aRuleWalker,
     472             :                                     TreeMatchContext& aTreeMatchContext)
     473        4490 :     : RuleProcessorData(aPresContext, aRuleWalker)
     474             :     , mElement(aElement)
     475        4490 :     , mTreeMatchContext(aTreeMatchContext)
     476             :   {
     477        4490 :     NS_ASSERTION(aElement, "null element leaked into SelectorMatches");
     478        4490 :     NS_ASSERTION(aElement->OwnerDoc(), "Document-less node here?");
     479        4490 :     NS_PRECONDITION(aTreeMatchContext.mForStyling == !!aRuleWalker,
     480             :                     "Should be styling if and only if we have a rule walker");
     481        4490 :   }
     482             : 
     483             :   mozilla::dom::Element* const mElement; // weak ref, must not be null
     484             :   TreeMatchContext& mTreeMatchContext;
     485             : };
     486             : 
     487             : struct MOZ_STACK_CLASS ElementRuleProcessorData :
     488             :                           public ElementDependentRuleProcessorData {
     489        2501 :   ElementRuleProcessorData(nsPresContext* aPresContext,
     490             :                            mozilla::dom::Element* aElement,
     491             :                            nsRuleWalker* aRuleWalker,
     492             :                            TreeMatchContext& aTreeMatchContext)
     493        2501 :     : ElementDependentRuleProcessorData(aPresContext, aElement, aRuleWalker,
     494        2501 :                                         aTreeMatchContext)
     495             :   {
     496        2501 :     NS_PRECONDITION(aTreeMatchContext.mForStyling, "Styling here!");
     497        2501 :     NS_PRECONDITION(aRuleWalker, "Must have rule walker");
     498        2501 :   }
     499             : };
     500             : 
     501             : struct MOZ_STACK_CLASS PseudoElementRuleProcessorData :
     502             :                           public ElementDependentRuleProcessorData {
     503        1288 :   PseudoElementRuleProcessorData(nsPresContext* aPresContext,
     504             :                                  mozilla::dom::Element* aParentElement,
     505             :                                  nsRuleWalker* aRuleWalker,
     506             :                                  mozilla::CSSPseudoElementType aPseudoType,
     507             :                                  TreeMatchContext& aTreeMatchContext,
     508             :                                  mozilla::dom::Element* aPseudoElement)
     509        1288 :     : ElementDependentRuleProcessorData(aPresContext, aParentElement, aRuleWalker,
     510             :                                         aTreeMatchContext),
     511             :       mPseudoType(aPseudoType),
     512        1288 :       mPseudoElement(aPseudoElement)
     513             :   {
     514        1288 :     NS_PRECONDITION(aPseudoType < mozilla::CSSPseudoElementType::Count,
     515             :                     "invalid aPseudoType value");
     516        1288 :     NS_PRECONDITION(aTreeMatchContext.mForStyling, "Styling here!");
     517        1288 :     NS_PRECONDITION(aRuleWalker, "Must have rule walker");
     518        1288 :   }
     519             : 
     520             :   mozilla::CSSPseudoElementType mPseudoType;
     521             :   mozilla::dom::Element* const mPseudoElement; // weak ref
     522             : };
     523             : 
     524             : struct MOZ_STACK_CLASS AnonBoxRuleProcessorData : public RuleProcessorData {
     525         210 :   AnonBoxRuleProcessorData(nsPresContext* aPresContext,
     526             :                            nsIAtom* aPseudoTag,
     527             :                            nsRuleWalker* aRuleWalker)
     528         210 :     : RuleProcessorData(aPresContext, aRuleWalker),
     529         210 :       mPseudoTag(aPseudoTag)
     530             :   {
     531         210 :     NS_PRECONDITION(aPseudoTag, "Must have pseudo tag");
     532         210 :     NS_PRECONDITION(aRuleWalker, "Must have rule walker");
     533         210 :   }
     534             : 
     535             :   nsIAtom* mPseudoTag;
     536             : };
     537             : 
     538             : #ifdef MOZ_XUL
     539             : struct MOZ_STACK_CLASS XULTreeRuleProcessorData :
     540             :                           public ElementDependentRuleProcessorData {
     541           0 :   XULTreeRuleProcessorData(nsPresContext* aPresContext,
     542             :                            mozilla::dom::Element* aParentElement,
     543             :                            nsRuleWalker* aRuleWalker,
     544             :                            nsIAtom* aPseudoTag,
     545             :                            nsICSSPseudoComparator* aComparator,
     546             :                            TreeMatchContext& aTreeMatchContext)
     547           0 :     : ElementDependentRuleProcessorData(aPresContext, aParentElement,
     548             :                                         aRuleWalker, aTreeMatchContext),
     549             :       mPseudoTag(aPseudoTag),
     550           0 :       mComparator(aComparator)
     551             :   {
     552           0 :     NS_PRECONDITION(aPseudoTag, "null pointer");
     553           0 :     NS_PRECONDITION(aRuleWalker, "Must have rule walker");
     554           0 :     NS_PRECONDITION(aComparator, "must have a comparator");
     555           0 :     NS_PRECONDITION(aTreeMatchContext.mForStyling, "Styling here!");
     556           0 :   }
     557             : 
     558             :   nsIAtom*                 mPseudoTag;
     559             :   nsICSSPseudoComparator*  mComparator;
     560             : };
     561             : #endif
     562             : 
     563             : struct MOZ_STACK_CLASS StateRuleProcessorData :
     564             :                           public ElementDependentRuleProcessorData {
     565          53 :   StateRuleProcessorData(nsPresContext* aPresContext,
     566             :                          mozilla::dom::Element* aElement,
     567             :                          mozilla::EventStates aStateMask,
     568             :                          TreeMatchContext& aTreeMatchContext)
     569          53 :     : ElementDependentRuleProcessorData(aPresContext, aElement, nullptr,
     570             :                                         aTreeMatchContext),
     571          53 :       mStateMask(aStateMask)
     572             :   {
     573          53 :     NS_PRECONDITION(!aTreeMatchContext.mForStyling, "Not styling here!");
     574          53 :   }
     575             :   // |HasStateDependentStyle| for which state(s)?
     576             :   // Constants defined in mozilla/EventStates.h .
     577             :   const mozilla::EventStates mStateMask;
     578             : };
     579             : 
     580             : struct MOZ_STACK_CLASS PseudoElementStateRuleProcessorData :
     581             :                           public StateRuleProcessorData {
     582           0 :   PseudoElementStateRuleProcessorData(nsPresContext* aPresContext,
     583             :                                       mozilla::dom::Element* aElement,
     584             :                                       mozilla::EventStates aStateMask,
     585             :                                       mozilla::CSSPseudoElementType aPseudoType,
     586             :                                       TreeMatchContext& aTreeMatchContext,
     587             :                                       mozilla::dom::Element* aPseudoElement)
     588           0 :     : StateRuleProcessorData(aPresContext, aElement, aStateMask,
     589             :                              aTreeMatchContext),
     590             :       mPseudoType(aPseudoType),
     591           0 :       mPseudoElement(aPseudoElement)
     592             :   {
     593           0 :     NS_PRECONDITION(!aTreeMatchContext.mForStyling, "Not styling here!");
     594           0 :   }
     595             : 
     596             :   // We kind of want to inherit from both StateRuleProcessorData and
     597             :   // PseudoElementRuleProcessorData.  Instead we've just copied those
     598             :   // members from PseudoElementRuleProcessorData to this struct.
     599             :   mozilla::CSSPseudoElementType mPseudoType;
     600             :   mozilla::dom::Element* const mPseudoElement; // weak ref
     601             : };
     602             : 
     603             : struct MOZ_STACK_CLASS AttributeRuleProcessorData :
     604             :                           public ElementDependentRuleProcessorData {
     605         648 :   AttributeRuleProcessorData(nsPresContext* aPresContext,
     606             :                              mozilla::dom::Element* aElement,
     607             :                              int32_t aNameSpaceID,
     608             :                              nsIAtom* aAttribute,
     609             :                              int32_t aModType,
     610             :                              bool aAttrHasChanged,
     611             :                              const nsAttrValue* aOtherValue,
     612             :                              TreeMatchContext& aTreeMatchContext)
     613         648 :     : ElementDependentRuleProcessorData(aPresContext, aElement, nullptr,
     614             :                                         aTreeMatchContext),
     615             :       mNameSpaceID(aNameSpaceID),
     616             :       mAttribute(aAttribute),
     617             :       mOtherValue(aOtherValue),
     618             :       mModType(aModType),
     619         648 :       mAttrHasChanged(aAttrHasChanged)
     620             :   {
     621         648 :     NS_PRECONDITION(!aTreeMatchContext.mForStyling, "Not styling here!");
     622         648 :   }
     623             :   int32_t mNameSpaceID; // Namespace of the attribute involved.
     624             :   nsIAtom* mAttribute; // |HasAttributeDependentStyle| for which attribute?
     625             :   // non-null if we have the value.
     626             :   const nsAttrValue* mOtherValue;
     627             :   int32_t mModType;    // The type of modification (see nsIDOMMutationEvent).
     628             :   bool mAttrHasChanged; // Whether the attribute has already changed.
     629             : };
     630             : 
     631             : #endif /* !defined(nsRuleProcessorData_h_) */

Generated by: LCOV version 1.13