nsStyleSet.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  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. * the container for the style sheets that apply to a presentation, and
  7. * the internal API that the style system exposes for creating (and
  8. * potentially re-creating) style contexts
  9. */
  10. #ifndef nsStyleSet_h_
  11. #define nsStyleSet_h_
  12. #include "mozilla/Attributes.h"
  13. #include "mozilla/StyleSheetInlines.h"
  14. #include "mozilla/EnumeratedArray.h"
  15. #include "mozilla/LinkedList.h"
  16. #include "mozilla/MemoryReporting.h"
  17. #include "mozilla/SheetType.h"
  18. #include "nsIStyleRuleProcessor.h"
  19. #include "nsBindingManager.h"
  20. #include "nsRuleNode.h"
  21. #include "nsTArray.h"
  22. #include "nsCOMArray.h"
  23. #include "nsIStyleRule.h"
  24. class gfxFontFeatureValueSet;
  25. class nsCSSKeyframesRule;
  26. class nsCSSFontFeatureValuesRule;
  27. class nsCSSPageRule;
  28. class nsCSSCounterStyleRule;
  29. class nsICSSPseudoComparator;
  30. class nsRuleWalker;
  31. struct ElementDependentRuleProcessorData;
  32. struct nsFontFaceRuleContainer;
  33. struct TreeMatchContext;
  34. namespace mozilla {
  35. class CSSStyleSheet;
  36. class EventStates;
  37. enum class CSSPseudoElementType : uint8_t;
  38. } // namespace mozilla
  39. class nsEmptyStyleRule final : public nsIStyleRule
  40. {
  41. private:
  42. ~nsEmptyStyleRule() {}
  43. public:
  44. NS_DECL_ISUPPORTS
  45. virtual void MapRuleInfoInto(nsRuleData* aRuleData) override;
  46. virtual bool MightMapInheritedStyleData() override;
  47. virtual bool GetDiscretelyAnimatedCSSValue(nsCSSPropertyID aProperty,
  48. nsCSSValue* aValue) override;
  49. #ifdef DEBUG
  50. virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
  51. #endif
  52. };
  53. class nsInitialStyleRule final : public nsIStyleRule
  54. {
  55. private:
  56. ~nsInitialStyleRule() {}
  57. public:
  58. NS_DECL_ISUPPORTS
  59. virtual void MapRuleInfoInto(nsRuleData* aRuleData) override;
  60. virtual bool MightMapInheritedStyleData() override;
  61. virtual bool GetDiscretelyAnimatedCSSValue(nsCSSPropertyID aProperty,
  62. nsCSSValue* aValue) override;
  63. #ifdef DEBUG
  64. virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
  65. #endif
  66. };
  67. class nsDisableTextZoomStyleRule final : public nsIStyleRule
  68. {
  69. private:
  70. ~nsDisableTextZoomStyleRule() {}
  71. public:
  72. NS_DECL_ISUPPORTS
  73. virtual void MapRuleInfoInto(nsRuleData* aRuleData) override;
  74. virtual bool MightMapInheritedStyleData() override;
  75. virtual bool GetDiscretelyAnimatedCSSValue(nsCSSPropertyID aProperty,
  76. nsCSSValue* aValue) override;
  77. #ifdef DEBUG
  78. virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
  79. #endif
  80. };
  81. // The style set object is created by the document viewer and ownership is
  82. // then handed off to the PresShell. Only the PresShell should delete a
  83. // style set.
  84. class nsStyleSet final
  85. {
  86. public:
  87. nsStyleSet();
  88. ~nsStyleSet();
  89. size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
  90. void Init(nsPresContext *aPresContext);
  91. nsRuleNode* GetRuleTree() { return mRuleTree; }
  92. // get a style context for a non-pseudo frame.
  93. already_AddRefed<nsStyleContext>
  94. ResolveStyleFor(mozilla::dom::Element* aElement,
  95. nsStyleContext* aParentContext);
  96. already_AddRefed<nsStyleContext>
  97. ResolveStyleFor(mozilla::dom::Element* aElement,
  98. nsStyleContext* aParentContext,
  99. TreeMatchContext& aTreeMatchContext);
  100. // Get a style context (with the given parent) for the
  101. // sequence of style rules in the |aRules| array.
  102. already_AddRefed<nsStyleContext>
  103. ResolveStyleForRules(nsStyleContext* aParentContext,
  104. const nsTArray< nsCOMPtr<nsIStyleRule> > &aRules);
  105. // Get a style context that represents aBaseContext, but as though
  106. // it additionally matched the rules in the aRules array (in that
  107. // order, as more specific than any other rules).
  108. //
  109. // One of the following must hold:
  110. // 1. The resulting style context must be used only on a temporary
  111. // basis, and it must never be put into the style context tree
  112. // (and, in particular, we must never call
  113. // ResolveStyleWithReplacement with it as the old context, which
  114. // might happen if it is put in the style context tree), or
  115. // 2. The additional rules must be appropriate for the transitions
  116. // level of the cascade, which is the highest level of the cascade.
  117. // (This is the case for one current caller, the cover rule used
  118. // for CSS transitions.)
  119. already_AddRefed<nsStyleContext>
  120. ResolveStyleByAddingRules(nsStyleContext* aBaseContext,
  121. const nsCOMArray<nsIStyleRule> &aRules);
  122. // Resolve style by making replacements in the list of style rules as
  123. // described by aReplacements, but otherwise maintaining the status
  124. // quo.
  125. // aPseudoElement must follow the same rules as for
  126. // ResolvePseudoElementStyle, and be null for non-pseudo-element cases
  127. enum { // flags for aFlags
  128. // Skip starting CSS animations that result from the style.
  129. eSkipStartingAnimations = (1<<0),
  130. };
  131. already_AddRefed<nsStyleContext>
  132. ResolveStyleWithReplacement(mozilla::dom::Element* aElement,
  133. mozilla::dom::Element* aPseudoElement,
  134. nsStyleContext* aNewParentContext,
  135. nsStyleContext* aOldStyleContext,
  136. nsRestyleHint aReplacements,
  137. uint32_t aFlags = 0);
  138. // Resolve style by returning a style context with the specified
  139. // animation data removed. It is allowable to remove all animation
  140. // data with eRestyle_AllHintsWithAnimations, or by using any other
  141. // hints that are allowed by ResolveStyleWithReplacement.
  142. already_AddRefed<nsStyleContext>
  143. ResolveStyleWithoutAnimation(mozilla::dom::Element* aElement,
  144. nsStyleContext* aStyleContext,
  145. nsRestyleHint aWhichToRemove);
  146. // Get a style context for a text node (which no rules will match).
  147. //
  148. // The returned style context will have nsCSSAnonBoxes::mozText as its pseudo.
  149. //
  150. // (Perhaps mozText should go away and we shouldn't even create style
  151. // contexts for such content nodes, when text-combine-upright is not
  152. // present. However, not doing any rule matching for them is a first step.)
  153. already_AddRefed<nsStyleContext>
  154. ResolveStyleForText(nsIContent* aTextNode, nsStyleContext* aParentContext);
  155. // Get a style context for a non-element (which no rules will match)
  156. // other than a text node, such as placeholder frames, and the
  157. // nsFirstLetterFrame for everything after the first letter.
  158. //
  159. // The returned style context will have nsCSSAnonBoxes::mozOtherNonElement as
  160. // its pseudo.
  161. //
  162. // (Perhaps mozOtherNonElement should go away and we shouldn't even
  163. // create style contexts for such content nodes. However, not doing
  164. // any rule matching for them is a first step.)
  165. already_AddRefed<nsStyleContext>
  166. ResolveStyleForOtherNonElement(nsStyleContext* aParentContext);
  167. // Get a style context for a pseudo-element. aParentElement must be
  168. // non-null. aPseudoID is the CSSPseudoElementType for the
  169. // pseudo-element. aPseudoElement must be non-null if the pseudo-element
  170. // type is one that allows user action pseudo-classes after it or allows
  171. // style attributes; otherwise, it is ignored.
  172. already_AddRefed<nsStyleContext>
  173. ResolvePseudoElementStyle(mozilla::dom::Element* aParentElement,
  174. mozilla::CSSPseudoElementType aType,
  175. nsStyleContext* aParentContext,
  176. mozilla::dom::Element* aPseudoElement);
  177. // This functions just like ResolvePseudoElementStyle except that it will
  178. // return nullptr if there are no explicit style rules for that
  179. // pseudo element.
  180. already_AddRefed<nsStyleContext>
  181. ProbePseudoElementStyle(mozilla::dom::Element* aParentElement,
  182. mozilla::CSSPseudoElementType aType,
  183. nsStyleContext* aParentContext);
  184. already_AddRefed<nsStyleContext>
  185. ProbePseudoElementStyle(mozilla::dom::Element* aParentElement,
  186. mozilla::CSSPseudoElementType aType,
  187. nsStyleContext* aParentContext,
  188. TreeMatchContext& aTreeMatchContext,
  189. mozilla::dom::Element* aPseudoElement = nullptr);
  190. /**
  191. * Bit-flags that can be passed to ResolveAnonymousBoxStyle and GetContext
  192. * in their parameter 'aFlags'.
  193. */
  194. enum {
  195. eNoFlags = 0,
  196. eIsLink = 1 << 0,
  197. eIsVisitedLink = 1 << 1,
  198. eDoAnimation = 1 << 2,
  199. // Indicates that we should skip the flex/grid item specific chunk of
  200. // ApplyStyleFixups(). This is useful if our parent has "display: flex"
  201. // or "display: grid" but we can tell we're not going to honor that (e.g. if
  202. // it's the outer frame of a button widget, and we're the inline frame for
  203. // the button's label).
  204. eSkipParentDisplayBasedStyleFixup = 1 << 3
  205. };
  206. // Get a style context for an anonymous box. aPseudoTag is the
  207. // pseudo-tag to use and must be non-null. aFlags will be forwarded
  208. // to a GetContext call internally.
  209. already_AddRefed<nsStyleContext>
  210. ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag, nsStyleContext* aParentContext,
  211. uint32_t aFlags = eNoFlags);
  212. #ifdef MOZ_XUL
  213. // Get a style context for a XUL tree pseudo. aPseudoTag is the
  214. // pseudo-tag to use and must be non-null. aParentContent must be
  215. // non-null. aComparator must be non-null.
  216. already_AddRefed<nsStyleContext>
  217. ResolveXULTreePseudoStyle(mozilla::dom::Element* aParentElement,
  218. nsIAtom* aPseudoTag,
  219. nsStyleContext* aParentContext,
  220. nsICSSPseudoComparator* aComparator);
  221. #endif
  222. // Append all the currently-active font face rules to aArray. Return
  223. // true for success and false for failure.
  224. bool AppendFontFaceRules(nsTArray<nsFontFaceRuleContainer>& aArray);
  225. // Return the winning (in the cascade) @keyframes rule for the given name.
  226. nsCSSKeyframesRule* KeyframesRuleForName(const nsString& aName);
  227. // Return the winning (in the cascade) @counter-style rule for the given name.
  228. nsCSSCounterStyleRule* CounterStyleRuleForName(const nsAString& aName);
  229. // Fetch object for looking up font feature values
  230. already_AddRefed<gfxFontFeatureValueSet> GetFontFeatureValuesLookup();
  231. // Append all the currently-active font feature values rules to aArray.
  232. // Return true for success and false for failure.
  233. bool AppendFontFeatureValuesRules(
  234. nsTArray<nsCSSFontFeatureValuesRule*>& aArray);
  235. // Append all the currently-active page rules to aArray. Return
  236. // true for success and false for failure.
  237. bool AppendPageRules(nsTArray<nsCSSPageRule*>& aArray);
  238. // Begin ignoring style context destruction, to avoid lots of unnecessary
  239. // work on document teardown.
  240. void BeginShutdown();
  241. // Free all of the data associated with this style set.
  242. void Shutdown();
  243. // Get a new style context that lives in a different parent
  244. // The new context will be the same as the old if the new parent is the
  245. // same as the old parent.
  246. // aElement should be non-null if this is a style context for an
  247. // element or pseudo-element; in the latter case it should be the
  248. // real element the pseudo-element is for.
  249. already_AddRefed<nsStyleContext>
  250. ReparentStyleContext(nsStyleContext* aStyleContext,
  251. nsStyleContext* aNewParentContext,
  252. mozilla::dom::Element* aElement);
  253. // Test if style is dependent on a document state.
  254. bool HasDocumentStateDependentStyle(nsIContent* aContent,
  255. mozilla::EventStates aStateMask);
  256. // Test if style is dependent on content state
  257. nsRestyleHint HasStateDependentStyle(mozilla::dom::Element* aElement,
  258. mozilla::EventStates aStateMask);
  259. nsRestyleHint HasStateDependentStyle(mozilla::dom::Element* aElement,
  260. mozilla::CSSPseudoElementType aPseudoType,
  261. mozilla::dom::Element* aPseudoElement,
  262. mozilla::EventStates aStateMask);
  263. // Test if style is dependent on the presence of an attribute.
  264. nsRestyleHint HasAttributeDependentStyle(mozilla::dom::Element* aElement,
  265. int32_t aNameSpaceID,
  266. nsIAtom* aAttribute,
  267. int32_t aModType,
  268. bool aAttrHasChanged,
  269. const nsAttrValue* aOtherValue,
  270. mozilla::RestyleHintData&
  271. aRestyleHintDataResult);
  272. /*
  273. * Do any processing that needs to happen as a result of a change in
  274. * the characteristics of the medium, and return whether style rules
  275. * may have changed as a result.
  276. */
  277. bool MediumFeaturesChanged();
  278. // APIs for registering objects that can supply additional
  279. // rules during processing.
  280. void SetBindingManager(nsBindingManager* aBindingManager)
  281. {
  282. mBindingManager = aBindingManager;
  283. }
  284. // APIs to manipulate the style sheet lists. The sheets in each
  285. // list are stored with the most significant sheet last.
  286. nsresult AppendStyleSheet(mozilla::SheetType aType,
  287. mozilla::CSSStyleSheet* aSheet);
  288. nsresult PrependStyleSheet(mozilla::SheetType aType,
  289. mozilla::CSSStyleSheet* aSheet);
  290. nsresult RemoveStyleSheet(mozilla::SheetType aType,
  291. mozilla::CSSStyleSheet* aSheet);
  292. nsresult ReplaceSheets(mozilla::SheetType aType,
  293. const nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aNewSheets);
  294. nsresult InsertStyleSheetBefore(mozilla::SheetType aType,
  295. mozilla::CSSStyleSheet* aNewSheet,
  296. mozilla::CSSStyleSheet* aReferenceSheet);
  297. // Enable/Disable entire author style level (Doc, ScopedDoc & PresHint levels)
  298. bool GetAuthorStyleDisabled() const;
  299. nsresult SetAuthorStyleDisabled(bool aStyleDisabled);
  300. int32_t SheetCount(mozilla::SheetType aType) const {
  301. return mSheets[aType].Length();
  302. }
  303. mozilla::CSSStyleSheet* StyleSheetAt(mozilla::SheetType aType,
  304. int32_t aIndex) const {
  305. return mSheets[aType][aIndex];
  306. }
  307. void AppendAllXBLStyleSheets(nsTArray<mozilla::CSSStyleSheet*>& aArray) const;
  308. nsresult RemoveDocStyleSheet(mozilla::CSSStyleSheet* aSheet);
  309. nsresult AddDocStyleSheet(mozilla::CSSStyleSheet* aSheet,
  310. nsIDocument* aDocument);
  311. void BeginUpdate();
  312. nsresult EndUpdate();
  313. // Methods for reconstructing the tree; BeginReconstruct basically moves the
  314. // old rule tree root and style context roots out of the way,
  315. // and EndReconstruct destroys the old rule tree when we're done
  316. nsresult BeginReconstruct();
  317. // Note: EndReconstruct should not be called if BeginReconstruct fails
  318. void EndReconstruct();
  319. bool IsInRuleTreeReconstruct() const {
  320. return mInReconstruct;
  321. }
  322. void RootStyleContextAdded() {
  323. ++mRootStyleContextCount;
  324. }
  325. void RootStyleContextRemoved() {
  326. MOZ_ASSERT(mRootStyleContextCount > 0);
  327. --mRootStyleContextCount;
  328. }
  329. // Return whether the rule tree has cached data such that we need to
  330. // do dynamic change handling for changes that change the results of
  331. // media queries or require rebuilding all style data.
  332. // We don't care whether we have cached rule processors or whether
  333. // they have cached rule cascades; getting the rule cascades again in
  334. // order to do rule matching will get the correct rule cascade.
  335. bool HasCachedStyleData() const {
  336. return (mRuleTree && mRuleTree->TreeHasCachedData()) || mRootStyleContextCount > 0;
  337. }
  338. // Notify the style set that a rulenode is no longer in use, or was
  339. // just created and is not in use yet.
  340. static const uint32_t kGCInterval = 300;
  341. void RuleNodeUnused(nsRuleNode* aNode, bool aMayGC) {
  342. ++mUnusedRuleNodeCount;
  343. mUnusedRuleNodeList.insertBack(aNode);
  344. if (aMayGC && mUnusedRuleNodeCount >= kGCInterval && !mInGC && !mInReconstruct) {
  345. GCRuleTrees();
  346. }
  347. }
  348. // Notify the style set that a rulenode that wasn't in use now is
  349. void RuleNodeInUse(nsRuleNode* aNode) {
  350. MOZ_ASSERT(mUnusedRuleNodeCount > 0);
  351. --mUnusedRuleNodeCount;
  352. aNode->removeFrom(mUnusedRuleNodeList);
  353. }
  354. // Returns true if a restyle of the document is needed due to cloning
  355. // sheet inners.
  356. bool EnsureUniqueInnerOnCSSSheets();
  357. // Called by CSSStyleSheet::EnsureUniqueInner to let us know it cloned
  358. // its inner.
  359. void SetNeedsRestyleAfterEnsureUniqueInner() {
  360. mNeedsRestyleAfterEnsureUniqueInner = true;
  361. }
  362. nsIStyleRule* InitialStyleRule();
  363. bool HasRuleProcessorUsedByMultipleStyleSets(mozilla::SheetType aSheetType);
  364. // Tells the RestyleManager for the document using this style set
  365. // to drop any nsCSSSelector pointers it has.
  366. void ClearSelectors();
  367. // Returns whether aSheetType represents a level of the cascade that uses
  368. // CSSStyleSheets. See gCSSSheetTypes in nsStyleSet.cpp for the list
  369. // of CSS sheet types.
  370. static bool IsCSSSheetType(mozilla::SheetType aSheetType);
  371. private:
  372. nsStyleSet(const nsStyleSet& aCopy) = delete;
  373. nsStyleSet& operator=(const nsStyleSet& aCopy) = delete;
  374. // Free all the rules with reference-count zero. This continues iterating
  375. // over the free list until it is empty, which allows immediate collection
  376. // of nodes whose reference-count drops to zero during the destruction of
  377. // a child node. This allows the collection of entire trees at once, since
  378. // children hold their parents alive.
  379. void GCRuleTrees();
  380. nsresult DirtyRuleProcessors(mozilla::SheetType aType);
  381. // Update the rule processor list after a change to the style sheet list.
  382. nsresult GatherRuleProcessors(mozilla::SheetType aType);
  383. void AddImportantRules(nsRuleNode* aCurrLevelNode,
  384. nsRuleNode* aLastPrevLevelNode,
  385. nsRuleWalker* aRuleWalker);
  386. // Move aRuleWalker forward by the appropriate rule if we need to add
  387. // a rule due to property restrictions on pseudo-elements.
  388. void WalkRestrictionRule(mozilla::CSSPseudoElementType aPseudoType,
  389. nsRuleWalker* aRuleWalker);
  390. void WalkDisableTextZoomRule(mozilla::dom::Element* aElement,
  391. nsRuleWalker* aRuleWalker);
  392. #ifdef DEBUG
  393. // Just like AddImportantRules except it doesn't actually add anything; it
  394. // just asserts that there are no important rules between aCurrLevelNode and
  395. // aLastPrevLevelNode.
  396. void AssertNoImportantRules(nsRuleNode* aCurrLevelNode,
  397. nsRuleNode* aLastPrevLevelNode);
  398. // Just like AddImportantRules except it doesn't actually add anything; it
  399. // just asserts that there are no CSS rules between aCurrLevelNode and
  400. // aLastPrevLevelNode. Mostly useful for the preshint level.
  401. void AssertNoCSSRules(nsRuleNode* aCurrLevelNode,
  402. nsRuleNode* aLastPrevLevelNode);
  403. #endif
  404. // Enumerate the rules in a way that cares about the order of the
  405. // rules.
  406. // aElement is the element the rules are for. It might be null. aData
  407. // is the closure to pass to aCollectorFunc. If aContent is not null,
  408. // aData must be a RuleProcessorData*
  409. void FileRules(nsIStyleRuleProcessor::EnumFunc aCollectorFunc,
  410. RuleProcessorData* aData, mozilla::dom::Element* aElement,
  411. nsRuleWalker* aRuleWalker);
  412. // Enumerate all the rules in a way that doesn't care about the order
  413. // of the rules and break out if the enumeration is halted.
  414. void WalkRuleProcessors(nsIStyleRuleProcessor::EnumFunc aFunc,
  415. ElementDependentRuleProcessorData* aData,
  416. bool aWalkAllXBLStylesheets);
  417. // Helper for ResolveStyleWithReplacement
  418. // aPseudoElement must follow the same rules as for
  419. // ResolvePseudoElementStyle, and be null for non-pseudo-element cases
  420. nsRuleNode* RuleNodeWithReplacement(mozilla::dom::Element* aElement,
  421. mozilla::dom::Element* aPseudoElement,
  422. nsRuleNode* aOldRuleNode,
  423. mozilla::CSSPseudoElementType aPseudoType,
  424. nsRestyleHint aReplacements);
  425. already_AddRefed<nsStyleContext>
  426. GetContext(nsStyleContext* aParentContext,
  427. nsRuleNode* aRuleNode,
  428. nsRuleNode* aVisitedRuleNode,
  429. nsIAtom* aPseudoTag,
  430. mozilla::CSSPseudoElementType aPseudoType,
  431. mozilla::dom::Element* aElementForAnimation,
  432. uint32_t aFlags);
  433. nsPresContext* PresContext() { return mRuleTree->PresContext(); }
  434. // The sheets in each array in mSheets are stored with the most significant
  435. // sheet last.
  436. // The arrays for ePresHintSheet, eStyleAttrSheet, eTransitionSheet,
  437. // eAnimationSheet and eSVGAttrAnimationSheet are always empty.
  438. // (FIXME: We should reduce the storage needed for them.)
  439. mozilla::EnumeratedArray<mozilla::SheetType, mozilla::SheetType::Count,
  440. nsTArray<RefPtr<mozilla::CSSStyleSheet>>> mSheets;
  441. // mRuleProcessors[eScopedDocSheet] is always null; rule processors
  442. // for scoped style sheets are stored in mScopedDocSheetRuleProcessors.
  443. mozilla::EnumeratedArray<mozilla::SheetType, mozilla::SheetType::Count,
  444. nsCOMPtr<nsIStyleRuleProcessor>> mRuleProcessors;
  445. // Rule processors for HTML5 scoped style sheets, one per scope.
  446. nsTArray<nsCOMPtr<nsIStyleRuleProcessor> > mScopedDocSheetRuleProcessors;
  447. RefPtr<nsBindingManager> mBindingManager;
  448. RefPtr<nsRuleNode> mRuleTree; // This is the root of our rule tree. It is a
  449. // lexicographic tree of matched rules that style
  450. // contexts use to look up properties.
  451. uint16_t mBatching;
  452. unsigned mInShutdown : 1;
  453. unsigned mInGC : 1;
  454. unsigned mAuthorStyleDisabled: 1;
  455. unsigned mInReconstruct : 1;
  456. unsigned mInitFontFeatureValuesLookup : 1;
  457. unsigned mNeedsRestyleAfterEnsureUniqueInner : 1;
  458. unsigned mDirty : int(mozilla::SheetType::Count); // one bit per sheet type
  459. uint32_t mRootStyleContextCount;
  460. #ifdef DEBUG
  461. // In debug builds, we stash a weak pointer here to the old root during
  462. // reconstruction. During GC, we check for this pointer, and null it out
  463. // when we encounter it. This allows us to assert that the old root (and
  464. // thus all of its subtree) was GCed after reconstruction, which implies
  465. // that there are no style contexts holding on to old rule nodes.
  466. nsRuleNode* mOldRootNode;
  467. #endif
  468. // Track our rule nodes with zero refcount. When this hits a threshold, we
  469. // sweep and free. Keeping unused rule nodes around for a bit allows us to
  470. // reuse them in many cases.
  471. mozilla::LinkedList<nsRuleNode> mUnusedRuleNodeList;
  472. uint32_t mUnusedRuleNodeCount;
  473. // Empty style rules to force things that restrict which properties
  474. // apply into different branches of the rule tree.
  475. RefPtr<nsEmptyStyleRule> mFirstLineRule, mFirstLetterRule, mPlaceholderRule;
  476. // Style rule which sets all properties to their initial values for
  477. // determining when context-sensitive values are in use.
  478. RefPtr<nsInitialStyleRule> mInitialStyleRule;
  479. // Style rule that sets the internal -x-text-zoom property on
  480. // <svg:text> elements to disable the effect of text zooming.
  481. RefPtr<nsDisableTextZoomStyleRule> mDisableTextZoomStyleRule;
  482. // whether font feature values lookup object needs initialization
  483. RefPtr<gfxFontFeatureValueSet> mFontFeatureValuesLookup;
  484. };
  485. #ifdef MOZILLA_INTERNAL_API
  486. inline
  487. void nsRuleNode::AddRef()
  488. {
  489. if (mRefCnt++ == 0) {
  490. MOZ_ASSERT(mPresContext->StyleSet()->IsGecko(),
  491. "ServoStyleSets should not have rule nodes");
  492. mPresContext->StyleSet()->AsGecko()->RuleNodeInUse(this);
  493. }
  494. }
  495. inline
  496. void nsRuleNode::Release()
  497. {
  498. if (--mRefCnt == 0) {
  499. MOZ_ASSERT(mPresContext->StyleSet()->IsGecko(),
  500. "ServoStyleSets should not have rule nodes");
  501. mPresContext->StyleSet()->AsGecko()->RuleNodeUnused(this, /* aMayGC = */ true);
  502. }
  503. }
  504. #endif
  505. #endif