layout/style/nsRuleProcessorData.h

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

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

mercurial