1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/style/nsStyleSet.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,492 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* 1.10 + * the container for the style sheets that apply to a presentation, and 1.11 + * the internal API that the style system exposes for creating (and 1.12 + * potentially re-creating) style contexts 1.13 + */ 1.14 + 1.15 +#ifndef nsStyleSet_h_ 1.16 +#define nsStyleSet_h_ 1.17 + 1.18 +#include "mozilla/Attributes.h" 1.19 +#include "mozilla/MemoryReporting.h" 1.20 + 1.21 +#include "nsIStyleRuleProcessor.h" 1.22 +#include "nsCSSStyleSheet.h" 1.23 +#include "nsBindingManager.h" 1.24 +#include "nsRuleNode.h" 1.25 +#include "nsTArray.h" 1.26 +#include "nsCOMArray.h" 1.27 +#include "nsAutoPtr.h" 1.28 +#include "nsIStyleRule.h" 1.29 +#include "nsCSSPseudoElements.h" 1.30 +#include "gfxFontFeatures.h" 1.31 + 1.32 +class nsCSSFontFaceRule; 1.33 +class nsCSSKeyframesRule; 1.34 +class nsCSSFontFeatureValuesRule; 1.35 +class nsCSSPageRule; 1.36 +class nsRuleWalker; 1.37 +struct ElementDependentRuleProcessorData; 1.38 +struct TreeMatchContext; 1.39 + 1.40 +namespace mozilla { 1.41 +class EventStates; 1.42 +} // namespace mozilla 1.43 + 1.44 +class nsEmptyStyleRule MOZ_FINAL : public nsIStyleRule 1.45 +{ 1.46 + NS_DECL_ISUPPORTS 1.47 + virtual void MapRuleInfoInto(nsRuleData* aRuleData) MOZ_OVERRIDE; 1.48 +#ifdef DEBUG 1.49 + virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE; 1.50 +#endif 1.51 +}; 1.52 + 1.53 +class nsInitialStyleRule MOZ_FINAL : public nsIStyleRule 1.54 +{ 1.55 + NS_DECL_ISUPPORTS 1.56 + virtual void MapRuleInfoInto(nsRuleData* aRuleData) MOZ_OVERRIDE; 1.57 +#ifdef DEBUG 1.58 + virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE; 1.59 +#endif 1.60 +}; 1.61 + 1.62 +class nsDisableTextZoomStyleRule MOZ_FINAL : public nsIStyleRule 1.63 +{ 1.64 + NS_DECL_ISUPPORTS 1.65 + virtual void MapRuleInfoInto(nsRuleData* aRuleData) MOZ_OVERRIDE; 1.66 +#ifdef DEBUG 1.67 + virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE; 1.68 +#endif 1.69 +}; 1.70 + 1.71 +// The style set object is created by the document viewer and ownership is 1.72 +// then handed off to the PresShell. Only the PresShell should delete a 1.73 +// style set. 1.74 + 1.75 +class nsStyleSet 1.76 +{ 1.77 + public: 1.78 + nsStyleSet(); 1.79 + 1.80 + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; 1.81 + 1.82 + void Init(nsPresContext *aPresContext); 1.83 + 1.84 + nsRuleNode* GetRuleTree() { return mRuleTree; } 1.85 + 1.86 + // enable / disable the Quirk style sheet 1.87 + void EnableQuirkStyleSheet(bool aEnable); 1.88 + 1.89 + // get a style context for a non-pseudo frame. 1.90 + already_AddRefed<nsStyleContext> 1.91 + ResolveStyleFor(mozilla::dom::Element* aElement, 1.92 + nsStyleContext* aParentContext); 1.93 + 1.94 + already_AddRefed<nsStyleContext> 1.95 + ResolveStyleFor(mozilla::dom::Element* aElement, 1.96 + nsStyleContext* aParentContext, 1.97 + TreeMatchContext& aTreeMatchContext); 1.98 + 1.99 + // Get a style context (with the given parent) for the 1.100 + // sequence of style rules in the |aRules| array. 1.101 + already_AddRefed<nsStyleContext> 1.102 + ResolveStyleForRules(nsStyleContext* aParentContext, 1.103 + const nsTArray< nsCOMPtr<nsIStyleRule> > &aRules); 1.104 + 1.105 + // used in ResolveStyleForRules below 1.106 + struct RuleAndLevel 1.107 + { 1.108 + nsIStyleRule* mRule; 1.109 + uint8_t mLevel; 1.110 + }; 1.111 + 1.112 + // Get a new style context for aElement for the rules in aRules 1.113 + // aRules is an array of rules and their levels in reverse order, 1.114 + // that is from the leaf-most to the root-most rule in the rule tree. 1.115 + already_AddRefed<nsStyleContext> 1.116 + ResolveStyleForRules(nsStyleContext* aParentContext, 1.117 + nsStyleContext* aOldStyle, 1.118 + const nsTArray<RuleAndLevel>& aRules); 1.119 + 1.120 + // Get a style context that represents aBaseContext, but as though 1.121 + // it additionally matched the rules in the aRules array (in that 1.122 + // order, as more specific than any other rules). 1.123 + already_AddRefed<nsStyleContext> 1.124 + ResolveStyleByAddingRules(nsStyleContext* aBaseContext, 1.125 + const nsCOMArray<nsIStyleRule> &aRules); 1.126 + 1.127 + // Get a style context for a non-element (which no rules will match), 1.128 + // such as text nodes, placeholder frames, and the nsFirstLetterFrame 1.129 + // for everything after the first letter. 1.130 + // 1.131 + // Perhaps this should go away and we shouldn't even create style 1.132 + // contexts for such content nodes. However, not doing any rule 1.133 + // matching for them is a first step. 1.134 + already_AddRefed<nsStyleContext> 1.135 + ResolveStyleForNonElement(nsStyleContext* aParentContext); 1.136 + 1.137 + // Get a style context for a pseudo-element. aParentElement must be 1.138 + // non-null. aPseudoID is the nsCSSPseudoElements::Type for the 1.139 + // pseudo-element. aPseudoElement must be non-null if the pseudo-element 1.140 + // type is one that allows user action pseudo-classes after it; otherwise, 1.141 + // it is ignored. 1.142 + already_AddRefed<nsStyleContext> 1.143 + ResolvePseudoElementStyle(mozilla::dom::Element* aParentElement, 1.144 + nsCSSPseudoElements::Type aType, 1.145 + nsStyleContext* aParentContext, 1.146 + mozilla::dom::Element* aPseudoElement); 1.147 + 1.148 + // This functions just like ResolvePseudoElementStyle except that it will 1.149 + // return nullptr if there are no explicit style rules for that 1.150 + // pseudo element. 1.151 + already_AddRefed<nsStyleContext> 1.152 + ProbePseudoElementStyle(mozilla::dom::Element* aParentElement, 1.153 + nsCSSPseudoElements::Type aType, 1.154 + nsStyleContext* aParentContext); 1.155 + already_AddRefed<nsStyleContext> 1.156 + ProbePseudoElementStyle(mozilla::dom::Element* aParentElement, 1.157 + nsCSSPseudoElements::Type aType, 1.158 + nsStyleContext* aParentContext, 1.159 + TreeMatchContext& aTreeMatchContext, 1.160 + mozilla::dom::Element* aPseudoElement = nullptr); 1.161 + 1.162 + // Get a style context for an anonymous box. aPseudoTag is the 1.163 + // pseudo-tag to use and must be non-null. 1.164 + already_AddRefed<nsStyleContext> 1.165 + ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag, nsStyleContext* aParentContext); 1.166 + 1.167 +#ifdef MOZ_XUL 1.168 + // Get a style context for a XUL tree pseudo. aPseudoTag is the 1.169 + // pseudo-tag to use and must be non-null. aParentContent must be 1.170 + // non-null. aComparator must be non-null. 1.171 + already_AddRefed<nsStyleContext> 1.172 + ResolveXULTreePseudoStyle(mozilla::dom::Element* aParentElement, 1.173 + nsIAtom* aPseudoTag, 1.174 + nsStyleContext* aParentContext, 1.175 + nsICSSPseudoComparator* aComparator); 1.176 +#endif 1.177 + 1.178 + // Append all the currently-active font face rules to aArray. Return 1.179 + // true for success and false for failure. 1.180 + bool AppendFontFaceRules(nsPresContext* aPresContext, 1.181 + nsTArray<nsFontFaceRuleContainer>& aArray); 1.182 + 1.183 + // Return the winning (in the cascade) @keyframes rule for the given name. 1.184 + nsCSSKeyframesRule* KeyframesRuleForName(nsPresContext* aPresContext, 1.185 + const nsString& aName); 1.186 + 1.187 + // Fetch object for looking up font feature values 1.188 + already_AddRefed<gfxFontFeatureValueSet> GetFontFeatureValuesLookup(); 1.189 + 1.190 + // Append all the currently-active font feature values rules to aArray. 1.191 + // Return true for success and false for failure. 1.192 + bool AppendFontFeatureValuesRules(nsPresContext* aPresContext, 1.193 + nsTArray<nsCSSFontFeatureValuesRule*>& aArray); 1.194 + 1.195 + // Append all the currently-active page rules to aArray. Return 1.196 + // true for success and false for failure. 1.197 + bool AppendPageRules(nsPresContext* aPresContext, 1.198 + nsTArray<nsCSSPageRule*>& aArray); 1.199 + 1.200 + // Begin ignoring style context destruction, to avoid lots of unnecessary 1.201 + // work on document teardown. 1.202 + void BeginShutdown(nsPresContext* aPresContext); 1.203 + 1.204 + // Free all of the data associated with this style set. 1.205 + void Shutdown(nsPresContext* aPresContext); 1.206 + 1.207 + // Notification that a style context is being destroyed. 1.208 + void NotifyStyleContextDestroyed(nsPresContext* aPresContext, 1.209 + nsStyleContext* aStyleContext); 1.210 + 1.211 + // Get a new style context that lives in a different parent 1.212 + // The new context will be the same as the old if the new parent is the 1.213 + // same as the old parent. 1.214 + // aElement should be non-null if this is a style context for an 1.215 + // element or pseudo-element; in the latter case it should be the 1.216 + // real element the pseudo-element is for. 1.217 + already_AddRefed<nsStyleContext> 1.218 + ReparentStyleContext(nsStyleContext* aStyleContext, 1.219 + nsStyleContext* aNewParentContext, 1.220 + mozilla::dom::Element* aElement); 1.221 + 1.222 + // Test if style is dependent on a document state. 1.223 + bool HasDocumentStateDependentStyle(nsPresContext* aPresContext, 1.224 + nsIContent* aContent, 1.225 + mozilla::EventStates aStateMask); 1.226 + 1.227 + // Test if style is dependent on content state 1.228 + nsRestyleHint HasStateDependentStyle(nsPresContext* aPresContext, 1.229 + mozilla::dom::Element* aElement, 1.230 + mozilla::EventStates aStateMask); 1.231 + nsRestyleHint HasStateDependentStyle(nsPresContext* aPresContext, 1.232 + mozilla::dom::Element* aElement, 1.233 + nsCSSPseudoElements::Type aPseudoType, 1.234 + mozilla::dom::Element* aPseudoElement, 1.235 + mozilla::EventStates aStateMask); 1.236 + 1.237 + // Test if style is dependent on the presence of an attribute. 1.238 + nsRestyleHint HasAttributeDependentStyle(nsPresContext* aPresContext, 1.239 + mozilla::dom::Element* aElement, 1.240 + nsIAtom* aAttribute, 1.241 + int32_t aModType, 1.242 + bool aAttrHasChanged); 1.243 + 1.244 + /* 1.245 + * Do any processing that needs to happen as a result of a change in 1.246 + * the characteristics of the medium, and return whether style rules 1.247 + * may have changed as a result. 1.248 + */ 1.249 + bool MediumFeaturesChanged(nsPresContext* aPresContext); 1.250 + 1.251 + // APIs for registering objects that can supply additional 1.252 + // rules during processing. 1.253 + void SetBindingManager(nsBindingManager* aBindingManager) 1.254 + { 1.255 + mBindingManager = aBindingManager; 1.256 + } 1.257 + 1.258 + // The "origins" of the CSS cascade, from lowest precedence to 1.259 + // highest (for non-!important rules). 1.260 + enum sheetType { 1.261 + eAgentSheet, // CSS 1.262 + eUserSheet, // CSS 1.263 + ePresHintSheet, 1.264 + eDocSheet, // CSS 1.265 + eScopedDocSheet, 1.266 + eStyleAttrSheet, 1.267 + eOverrideSheet, // CSS 1.268 + eAnimationSheet, 1.269 + eTransitionSheet, 1.270 + eSheetTypeCount 1.271 + // be sure to keep the number of bits in |mDirty| below and in 1.272 + // NS_RULE_NODE_LEVEL_MASK updated when changing the number of sheet 1.273 + // types 1.274 + }; 1.275 + 1.276 + // APIs to manipulate the style sheet lists. The sheets in each 1.277 + // list are stored with the most significant sheet last. 1.278 + nsresult AppendStyleSheet(sheetType aType, nsIStyleSheet *aSheet); 1.279 + nsresult PrependStyleSheet(sheetType aType, nsIStyleSheet *aSheet); 1.280 + nsresult RemoveStyleSheet(sheetType aType, nsIStyleSheet *aSheet); 1.281 + nsresult ReplaceSheets(sheetType aType, 1.282 + const nsCOMArray<nsIStyleSheet> &aNewSheets); 1.283 + nsresult InsertStyleSheetBefore(sheetType aType, nsIStyleSheet *aNewSheet, 1.284 + nsIStyleSheet *aReferenceSheet); 1.285 + 1.286 + nsresult DirtyRuleProcessors(sheetType aType); 1.287 + 1.288 + // Enable/Disable entire author style level (Doc, ScopedDoc & PresHint levels) 1.289 + bool GetAuthorStyleDisabled(); 1.290 + nsresult SetAuthorStyleDisabled(bool aStyleDisabled); 1.291 + 1.292 + int32_t SheetCount(sheetType aType) const { 1.293 + return mSheets[aType].Count(); 1.294 + } 1.295 + 1.296 + nsIStyleSheet* StyleSheetAt(sheetType aType, int32_t aIndex) const { 1.297 + return mSheets[aType].ObjectAt(aIndex); 1.298 + } 1.299 + 1.300 + nsresult RemoveDocStyleSheet(nsIStyleSheet* aSheet); 1.301 + nsresult AddDocStyleSheet(nsIStyleSheet* aSheet, nsIDocument* aDocument); 1.302 + 1.303 + void BeginUpdate(); 1.304 + nsresult EndUpdate(); 1.305 + 1.306 + // Methods for reconstructing the tree; BeginReconstruct basically moves the 1.307 + // old rule tree root and style context roots out of the way, 1.308 + // and EndReconstruct destroys the old rule tree when we're done 1.309 + nsresult BeginReconstruct(); 1.310 + // Note: EndReconstruct should not be called if BeginReconstruct fails 1.311 + void EndReconstruct(); 1.312 + 1.313 + // Let the style set know that a particular sheet is the quirks sheet. This 1.314 + // sheet must already have been added to the UA sheets. The pointer must not 1.315 + // be null. This should only be called once for a given style set. 1.316 + void SetQuirkStyleSheet(nsIStyleSheet* aQuirkStyleSheet); 1.317 + 1.318 + // Return whether the rule tree has cached data such that we need to 1.319 + // do dynamic change handling for changes that change the results of 1.320 + // media queries or require rebuilding all style data. 1.321 + // We don't care whether we have cached rule processors or whether 1.322 + // they have cached rule cascades; getting the rule cascades again in 1.323 + // order to do rule matching will get the correct rule cascade. 1.324 + bool HasCachedStyleData() const { 1.325 + return (mRuleTree && mRuleTree->TreeHasCachedData()) || !mRoots.IsEmpty(); 1.326 + } 1.327 + 1.328 + // Notify the style set that a rulenode is no longer in use, or was 1.329 + // just created and is not in use yet. 1.330 + void RuleNodeUnused() { 1.331 + ++mUnusedRuleNodeCount; 1.332 + } 1.333 + 1.334 + // Notify the style set that a rulenode that wasn't in use now is 1.335 + void RuleNodeInUse() { 1.336 + --mUnusedRuleNodeCount; 1.337 + } 1.338 + 1.339 + nsCSSStyleSheet::EnsureUniqueInnerResult EnsureUniqueInnerOnCSSSheets(); 1.340 + 1.341 + nsIStyleRule* InitialStyleRule(); 1.342 + 1.343 + private: 1.344 + nsStyleSet(const nsStyleSet& aCopy) MOZ_DELETE; 1.345 + nsStyleSet& operator=(const nsStyleSet& aCopy) MOZ_DELETE; 1.346 + 1.347 + // Run mark-and-sweep GC on mRuleTree and mOldRuleTrees, based on mRoots. 1.348 + void GCRuleTrees(); 1.349 + 1.350 + // Update the rule processor list after a change to the style sheet list. 1.351 + nsresult GatherRuleProcessors(sheetType aType); 1.352 + 1.353 + void AddImportantRules(nsRuleNode* aCurrLevelNode, 1.354 + nsRuleNode* aLastPrevLevelNode, 1.355 + nsRuleWalker* aRuleWalker); 1.356 + 1.357 + // Move aRuleWalker forward by the appropriate rule if we need to add 1.358 + // a rule due to property restrictions on pseudo-elements. 1.359 + void WalkRestrictionRule(nsCSSPseudoElements::Type aPseudoType, 1.360 + nsRuleWalker* aRuleWalker); 1.361 + 1.362 + void WalkDisableTextZoomRule(mozilla::dom::Element* aElement, 1.363 + nsRuleWalker* aRuleWalker); 1.364 + 1.365 +#ifdef DEBUG 1.366 + // Just like AddImportantRules except it doesn't actually add anything; it 1.367 + // just asserts that there are no important rules between aCurrLevelNode and 1.368 + // aLastPrevLevelNode. 1.369 + void AssertNoImportantRules(nsRuleNode* aCurrLevelNode, 1.370 + nsRuleNode* aLastPrevLevelNode); 1.371 + 1.372 + // Just like AddImportantRules except it doesn't actually add anything; it 1.373 + // just asserts that there are no CSS rules between aCurrLevelNode and 1.374 + // aLastPrevLevelNode. Mostly useful for the preshint level. 1.375 + void AssertNoCSSRules(nsRuleNode* aCurrLevelNode, 1.376 + nsRuleNode* aLastPrevLevelNode); 1.377 +#endif 1.378 + 1.379 + // Enumerate the rules in a way that cares about the order of the 1.380 + // rules. 1.381 + // aElement is the element the rules are for. It might be null. aData 1.382 + // is the closure to pass to aCollectorFunc. If aContent is not null, 1.383 + // aData must be a RuleProcessorData* 1.384 + void FileRules(nsIStyleRuleProcessor::EnumFunc aCollectorFunc, 1.385 + RuleProcessorData* aData, mozilla::dom::Element* aElement, 1.386 + nsRuleWalker* aRuleWalker); 1.387 + 1.388 + // Enumerate all the rules in a way that doesn't care about the order 1.389 + // of the rules and break out if the enumeration is halted. 1.390 + void WalkRuleProcessors(nsIStyleRuleProcessor::EnumFunc aFunc, 1.391 + ElementDependentRuleProcessorData* aData, 1.392 + bool aWalkAllXBLStylesheets); 1.393 + 1.394 + /** 1.395 + * Bit-flags that can be passed to GetContext() in its parameter 'aFlags'. 1.396 + */ 1.397 + enum { 1.398 + eNoFlags = 0, 1.399 + eIsLink = 1 << 0, 1.400 + eIsVisitedLink = 1 << 1, 1.401 + eDoAnimation = 1 << 2, 1.402 + 1.403 + // Indicates that we should skip the flex-item-specific chunk of 1.404 + // ApplyStyleFixups(). This is useful if our parent has "display: flex" 1.405 + // but we can tell it's not going to actually be a flex container (e.g. if 1.406 + // it's the outer frame of a button widget, and we're the inline frame for 1.407 + // the button's label). 1.408 + eSkipFlexItemStyleFixup = 1 << 3 1.409 + }; 1.410 + 1.411 + already_AddRefed<nsStyleContext> 1.412 + GetContext(nsStyleContext* aParentContext, 1.413 + nsRuleNode* aRuleNode, 1.414 + nsRuleNode* aVisitedRuleNode, 1.415 + nsIAtom* aPseudoTag, 1.416 + nsCSSPseudoElements::Type aPseudoType, 1.417 + mozilla::dom::Element* aElementForAnimation, 1.418 + uint32_t aFlags); 1.419 + 1.420 + nsPresContext* PresContext() { return mRuleTree->PresContext(); } 1.421 + 1.422 + // The sheets in each array in mSheets are stored with the most significant 1.423 + // sheet last. 1.424 + // The arrays for ePresHintSheet, eStyleAttrSheet, eTransitionSheet, 1.425 + // and eAnimationSheet are always empty. (FIXME: We should reduce 1.426 + // the storage needed for them.) 1.427 + nsCOMArray<nsIStyleSheet> mSheets[eSheetTypeCount]; 1.428 + 1.429 + // mRuleProcessors[eScopedDocSheet] is always null; rule processors 1.430 + // for scoped style sheets are stored in mScopedDocSheetRuleProcessors. 1.431 + nsCOMPtr<nsIStyleRuleProcessor> mRuleProcessors[eSheetTypeCount]; 1.432 + 1.433 + // Rule processors for HTML5 scoped style sheets, one per scope. 1.434 + nsTArray<nsCOMPtr<nsIStyleRuleProcessor> > mScopedDocSheetRuleProcessors; 1.435 + 1.436 + // cached instance for enabling/disabling 1.437 + nsCOMPtr<nsIStyleSheet> mQuirkStyleSheet; 1.438 + 1.439 + nsRefPtr<nsBindingManager> mBindingManager; 1.440 + 1.441 + nsRuleNode* mRuleTree; // This is the root of our rule tree. It is a 1.442 + // lexicographic tree of matched rules that style 1.443 + // contexts use to look up properties. 1.444 + 1.445 + uint16_t mBatching; 1.446 + 1.447 + unsigned mInShutdown : 1; 1.448 + unsigned mAuthorStyleDisabled: 1; 1.449 + unsigned mInReconstruct : 1; 1.450 + unsigned mInitFontFeatureValuesLookup : 1; 1.451 + unsigned mDirty : 9; // one dirty bit is used per sheet type 1.452 + 1.453 + uint32_t mUnusedRuleNodeCount; // used to batch rule node GC 1.454 + nsTArray<nsStyleContext*> mRoots; // style contexts with no parent 1.455 + 1.456 + // Empty style rules to force things that restrict which properties 1.457 + // apply into different branches of the rule tree. 1.458 + nsRefPtr<nsEmptyStyleRule> mFirstLineRule, mFirstLetterRule, mPlaceholderRule; 1.459 + 1.460 + // Style rule which sets all properties to their initial values for 1.461 + // determining when context-sensitive values are in use. 1.462 + nsRefPtr<nsInitialStyleRule> mInitialStyleRule; 1.463 + 1.464 + // Style rule that sets the internal -x-text-zoom property on 1.465 + // <svg:text> elements to disable the effect of text zooming. 1.466 + nsRefPtr<nsDisableTextZoomStyleRule> mDisableTextZoomStyleRule; 1.467 + 1.468 + // Old rule trees, which should only be non-empty between 1.469 + // BeginReconstruct and EndReconstruct, but in case of bugs that cause 1.470 + // style contexts to exist too long, may last longer. 1.471 + nsTArray<nsRuleNode*> mOldRuleTrees; 1.472 + 1.473 + // whether font feature values lookup object needs initialization 1.474 + nsRefPtr<gfxFontFeatureValueSet> mFontFeatureValuesLookup; 1.475 +}; 1.476 + 1.477 +#ifdef MOZILLA_INTERNAL_API 1.478 +inline 1.479 +void nsRuleNode::AddRef() 1.480 +{ 1.481 + if (mRefCnt++ == 0 && !IsRoot()) { 1.482 + mPresContext->StyleSet()->RuleNodeInUse(); 1.483 + } 1.484 +} 1.485 + 1.486 +inline 1.487 +void nsRuleNode::Release() 1.488 +{ 1.489 + if (--mRefCnt == 0 && !IsRoot()) { 1.490 + mPresContext->StyleSet()->RuleNodeUnused(); 1.491 + } 1.492 +} 1.493 +#endif 1.494 + 1.495 +#endif