nsCSSRuleProcessor.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. // vim:cindent:tabstop=2:expandtab:shiftwidth=2:
  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. * style rule processor for CSS style sheets, responsible for selector
  8. * matching and cascading
  9. */
  10. #ifndef nsCSSRuleProcessor_h_
  11. #define nsCSSRuleProcessor_h_
  12. #include "mozilla/Attributes.h"
  13. #include "mozilla/EventStates.h"
  14. #include "mozilla/MemoryReporting.h"
  15. #include "mozilla/RefCountType.h"
  16. #include "mozilla/SheetType.h"
  17. #include "mozilla/UniquePtr.h"
  18. #include "nsExpirationTracker.h"
  19. #include "nsIMediaList.h"
  20. #include "nsIStyleRuleProcessor.h"
  21. #include "nsRuleWalker.h"
  22. #include "nsTArray.h"
  23. struct CascadeEnumData;
  24. struct ElementDependentRuleProcessorData;
  25. struct nsCSSSelector;
  26. struct nsCSSSelectorList;
  27. struct nsFontFaceRuleContainer;
  28. struct RuleCascadeData;
  29. struct TreeMatchContext;
  30. class nsCSSKeyframesRule;
  31. class nsCSSPageRule;
  32. class nsCSSFontFeatureValuesRule;
  33. class nsCSSCounterStyleRule;
  34. namespace mozilla {
  35. class CSSStyleSheet;
  36. enum class CSSPseudoElementType : uint8_t;
  37. namespace css {
  38. class DocumentRule;
  39. } // namespace css
  40. } // namespace mozilla
  41. /**
  42. * The CSS style rule processor provides a mechanism for sibling style
  43. * sheets to combine their rule processing in order to allow proper
  44. * cascading to happen.
  45. *
  46. * CSS style rule processors keep a live reference on all style sheets
  47. * bound to them. The CSS style sheets keep a weak reference to all the
  48. * processors that they are bound to (many to many). The CSS style sheet
  49. * is told when the rule processor is going away (via DropRuleProcessor).
  50. */
  51. class nsCSSRuleProcessor: public nsIStyleRuleProcessor {
  52. public:
  53. typedef nsTArray<RefPtr<mozilla::CSSStyleSheet>> sheet_array_type;
  54. // aScopeElement must be non-null iff aSheetType is
  55. // SheetType::ScopedDoc.
  56. // aPreviousCSSRuleProcessor is the rule processor (if any) that this
  57. // one is replacing.
  58. nsCSSRuleProcessor(const sheet_array_type& aSheets,
  59. mozilla::SheetType aSheetType,
  60. mozilla::dom::Element* aScopeElement,
  61. nsCSSRuleProcessor* aPreviousCSSRuleProcessor,
  62. bool aIsShared = false);
  63. nsCSSRuleProcessor(sheet_array_type&& aSheets,
  64. mozilla::SheetType aSheetType,
  65. mozilla::dom::Element* aScopeElement,
  66. nsCSSRuleProcessor* aPreviousCSSRuleProcessor,
  67. bool aIsShared = false);
  68. NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  69. NS_DECL_CYCLE_COLLECTION_CLASS(nsCSSRuleProcessor)
  70. public:
  71. nsresult ClearRuleCascades();
  72. static void Startup();
  73. static void Shutdown();
  74. static void FreeSystemMetrics();
  75. static bool HasSystemMetric(nsIAtom* aMetric);
  76. /*
  77. * Returns true if the given aElement matches one of the
  78. * selectors in aSelectorList. Note that this method will assume
  79. * the given aElement is not a relevant link. aSelectorList must not
  80. * include any pseudo-element selectors. aSelectorList is allowed
  81. * to be null; in this case false will be returned.
  82. */
  83. static bool SelectorListMatches(mozilla::dom::Element* aElement,
  84. TreeMatchContext& aTreeMatchContext,
  85. nsCSSSelectorList* aSelectorList);
  86. /*
  87. * Helper to get the content state for a content node. This may be
  88. * slightly adjusted from IntrinsicState().
  89. */
  90. static mozilla::EventStates GetContentState(
  91. mozilla::dom::Element* aElement,
  92. const TreeMatchContext& aTreeMatchContext);
  93. /*
  94. * Helper to get the content state for :visited handling for an element
  95. */
  96. static mozilla::EventStates GetContentStateForVisitedHandling(
  97. mozilla::dom::Element* aElement,
  98. const TreeMatchContext& aTreeMatchContext,
  99. nsRuleWalker::VisitedHandlingType aVisitedHandling,
  100. bool aIsRelevantLink);
  101. /*
  102. * Helper to test whether a node is a link
  103. */
  104. static bool IsLink(const mozilla::dom::Element* aElement);
  105. /**
  106. * Returns true if the given aElement matches aSelector.
  107. * Like nsCSSRuleProcessor.cpp's SelectorMatches (and unlike
  108. * SelectorMatchesTree), this does not check an entire selector list
  109. * separated by combinators.
  110. *
  111. * :visited and :link will match both visited and non-visited links,
  112. * as if aTreeMatchContext->mVisitedHandling were eLinksVisitedOrUnvisited.
  113. *
  114. * aSelector is restricted to not containing pseudo-elements.
  115. */
  116. static bool RestrictedSelectorMatches(mozilla::dom::Element* aElement,
  117. nsCSSSelector* aSelector,
  118. TreeMatchContext& aTreeMatchContext);
  119. // nsIStyleRuleProcessor
  120. virtual void RulesMatching(ElementRuleProcessorData* aData) override;
  121. virtual void RulesMatching(PseudoElementRuleProcessorData* aData) override;
  122. virtual void RulesMatching(AnonBoxRuleProcessorData* aData) override;
  123. #ifdef MOZ_XUL
  124. virtual void RulesMatching(XULTreeRuleProcessorData* aData) override;
  125. #endif
  126. virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData) override;
  127. virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override;
  128. virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override;
  129. virtual nsRestyleHint
  130. HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
  131. mozilla::RestyleHintData& aRestyleHintDataResult)
  132. override;
  133. virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override;
  134. /**
  135. * If this rule processor currently has a substantive media query
  136. * result cache key, return a copy of it.
  137. */
  138. mozilla::UniquePtr<nsMediaQueryResultCacheKey> CloneMQCacheKey();
  139. virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)
  140. const MOZ_MUST_OVERRIDE override;
  141. virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf)
  142. const MOZ_MUST_OVERRIDE override;
  143. // Append all the currently-active font face rules to aArray. Return
  144. // true for success and false for failure.
  145. bool AppendFontFaceRules(nsPresContext* aPresContext,
  146. nsTArray<nsFontFaceRuleContainer>& aArray);
  147. nsCSSKeyframesRule* KeyframesRuleForName(nsPresContext* aPresContext,
  148. const nsString& aName);
  149. nsCSSCounterStyleRule* CounterStyleRuleForName(nsPresContext* aPresContext,
  150. const nsAString& aName);
  151. bool AppendPageRules(nsPresContext* aPresContext,
  152. nsTArray<nsCSSPageRule*>& aArray);
  153. bool AppendFontFeatureValuesRules(nsPresContext* aPresContext,
  154. nsTArray<nsCSSFontFeatureValuesRule*>& aArray);
  155. /**
  156. * Returns the scope element for the scoped style sheets this rule
  157. * processor is for. If this is not a rule processor for scoped style
  158. * sheets, it returns null.
  159. */
  160. mozilla::dom::Element* GetScopeElement() const { return mScopeElement; }
  161. void TakeDocumentRulesAndCacheKey(
  162. nsPresContext* aPresContext,
  163. nsTArray<mozilla::css::DocumentRule*>& aDocumentRules,
  164. nsDocumentRuleResultCacheKey& aDocumentRuleResultCacheKey);
  165. bool IsShared() const { return mIsShared; }
  166. nsExpirationState* GetExpirationState() { return &mExpirationState; }
  167. void AddStyleSetRef();
  168. void ReleaseStyleSetRef();
  169. void SetInRuleProcessorCache(bool aVal) {
  170. MOZ_ASSERT(mIsShared);
  171. mInRuleProcessorCache = aVal;
  172. }
  173. bool IsInRuleProcessorCache() const { return mInRuleProcessorCache; }
  174. bool IsUsedByMultipleStyleSets() const { return mStyleSetRefCnt > 1; }
  175. #ifdef XP_WIN
  176. // Cached theme identifier for the moz-windows-theme media query.
  177. static uint8_t GetWindowsThemeIdentifier();
  178. static void SetWindowsThemeIdentifier(uint8_t aId) {
  179. sWinThemeId = aId;
  180. }
  181. #endif
  182. struct StateSelector {
  183. StateSelector(mozilla::EventStates aStates, nsCSSSelector* aSelector)
  184. : mStates(aStates),
  185. mSelector(aSelector)
  186. {}
  187. mozilla::EventStates mStates;
  188. nsCSSSelector* mSelector;
  189. };
  190. protected:
  191. virtual ~nsCSSRuleProcessor();
  192. private:
  193. static bool CascadeSheet(mozilla::CSSStyleSheet* aSheet,
  194. CascadeEnumData* aData);
  195. RuleCascadeData* GetRuleCascade(nsPresContext* aPresContext);
  196. void RefreshRuleCascade(nsPresContext* aPresContext);
  197. nsRestyleHint HasStateDependentStyle(ElementDependentRuleProcessorData* aData,
  198. mozilla::dom::Element* aStatefulElement,
  199. mozilla::CSSPseudoElementType aPseudoType,
  200. mozilla::EventStates aStateMask);
  201. void ClearSheets();
  202. // The sheet order here is the same as in nsStyleSet::mSheets
  203. sheet_array_type mSheets;
  204. // active first, then cached (most recent first)
  205. RuleCascadeData* mRuleCascades;
  206. // If we cleared our mRuleCascades or replaced a previous rule
  207. // processor, this is the media query result cache key that was used
  208. // before we lost the old rule cascades.
  209. mozilla::UniquePtr<nsMediaQueryResultCacheKey> mPreviousCacheKey;
  210. // The last pres context for which GetRuleCascades was called.
  211. nsPresContext *mLastPresContext;
  212. // The scope element for this rule processor's scoped style sheets.
  213. // Only used if mSheetType == nsStyleSet::eScopedDocSheet.
  214. RefPtr<mozilla::dom::Element> mScopeElement;
  215. nsTArray<mozilla::css::DocumentRule*> mDocumentRules;
  216. nsDocumentRuleResultCacheKey mDocumentCacheKey;
  217. nsExpirationState mExpirationState;
  218. MozRefCountType mStyleSetRefCnt;
  219. // type of stylesheet using this processor
  220. mozilla::SheetType mSheetType;
  221. const bool mIsShared;
  222. // Whether we need to build up mDocumentCacheKey and mDocumentRules as
  223. // we build a RuleCascadeData. Is true only for shared rule processors
  224. // and only before we build the first RuleCascadeData. See comment in
  225. // RefreshRuleCascade for why.
  226. bool mMustGatherDocumentRules;
  227. bool mInRuleProcessorCache;
  228. #ifdef DEBUG
  229. bool mDocumentRulesAndCacheKeyValid;
  230. #endif
  231. #ifdef XP_WIN
  232. static uint8_t sWinThemeId;
  233. #endif
  234. };
  235. #endif /* nsCSSRuleProcessor_h_ */