Wed, 31 Dec 2014 13:27:57 +0100
Ignore runtime configuration files generated during quality assurance.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | /* the interface (to internal code) for retrieving computed style data */ |
michael@0 | 7 | |
michael@0 | 8 | #ifndef _nsStyleContext_h_ |
michael@0 | 9 | #define _nsStyleContext_h_ |
michael@0 | 10 | |
michael@0 | 11 | #include "nsRuleNode.h" |
michael@0 | 12 | #include "nsCSSPseudoElements.h" |
michael@0 | 13 | |
michael@0 | 14 | class nsIAtom; |
michael@0 | 15 | class nsPresContext; |
michael@0 | 16 | |
michael@0 | 17 | /** |
michael@0 | 18 | * An nsStyleContext represents the computed style data for an element. |
michael@0 | 19 | * The computed style data are stored in a set of structs (see |
michael@0 | 20 | * nsStyleStruct.h) that are cached either on the style context or in |
michael@0 | 21 | * the rule tree (see nsRuleNode.h for a description of this caching and |
michael@0 | 22 | * how the cached structs are shared). |
michael@0 | 23 | * |
michael@0 | 24 | * Since the data in |nsIStyleRule|s and |nsRuleNode|s are immutable |
michael@0 | 25 | * (with a few exceptions, like system color changes), the data in an |
michael@0 | 26 | * nsStyleContext are also immutable (with the additional exception of |
michael@0 | 27 | * GetUniqueStyleData). When style data change, |
michael@0 | 28 | * nsFrameManager::ReResolveStyleContext creates a new style context. |
michael@0 | 29 | * |
michael@0 | 30 | * Style contexts are reference counted. References are generally held |
michael@0 | 31 | * by: |
michael@0 | 32 | * 1. the |nsIFrame|s that are using the style context and |
michael@0 | 33 | * 2. any *child* style contexts (this might be the reverse of |
michael@0 | 34 | * expectation, but it makes sense in this case) |
michael@0 | 35 | * Style contexts participate in the mark phase of rule node garbage |
michael@0 | 36 | * collection. |
michael@0 | 37 | */ |
michael@0 | 38 | |
michael@0 | 39 | class nsStyleContext |
michael@0 | 40 | { |
michael@0 | 41 | public: |
michael@0 | 42 | /** |
michael@0 | 43 | * Create a new style context. |
michael@0 | 44 | * @param aParent The parent of a style context is used for CSS |
michael@0 | 45 | * inheritance. When the element or pseudo-element |
michael@0 | 46 | * this style context represents the style data of |
michael@0 | 47 | * inherits a CSS property, the value comes from the |
michael@0 | 48 | * parent style context. This means style context |
michael@0 | 49 | * parentage must match the definitions of inheritance |
michael@0 | 50 | * in the CSS specification. |
michael@0 | 51 | * @param aPseudoTag The pseudo-element or anonymous box for which |
michael@0 | 52 | * this style context represents style. Null if |
michael@0 | 53 | * this style context is for a normal DOM element. |
michael@0 | 54 | * @param aPseudoType Must match aPseudoTag. |
michael@0 | 55 | * @param aRuleNode A rule node representing the ordered sequence of |
michael@0 | 56 | * rules that any element, pseudo-element, or |
michael@0 | 57 | * anonymous box that this style context is for |
michael@0 | 58 | * matches. See |nsRuleNode| and |nsIStyleRule|. |
michael@0 | 59 | * @param aSkipFlexItemStyleFixup |
michael@0 | 60 | * If set, this flag indicates that we should skip |
michael@0 | 61 | * the chunk of ApplyStyleFixups() that modifies flex |
michael@0 | 62 | * items' display values. |
michael@0 | 63 | */ |
michael@0 | 64 | nsStyleContext(nsStyleContext* aParent, nsIAtom* aPseudoTag, |
michael@0 | 65 | nsCSSPseudoElements::Type aPseudoType, |
michael@0 | 66 | nsRuleNode* aRuleNode, |
michael@0 | 67 | bool aSkipFlexItemStyleFixup); |
michael@0 | 68 | ~nsStyleContext(); |
michael@0 | 69 | |
michael@0 | 70 | void* operator new(size_t sz, nsPresContext* aPresContext) CPP_THROW_NEW; |
michael@0 | 71 | void Destroy(); |
michael@0 | 72 | |
michael@0 | 73 | nsrefcnt AddRef() { |
michael@0 | 74 | if (mRefCnt == UINT32_MAX) { |
michael@0 | 75 | NS_WARNING("refcount overflow, leaking object"); |
michael@0 | 76 | return mRefCnt; |
michael@0 | 77 | } |
michael@0 | 78 | ++mRefCnt; |
michael@0 | 79 | NS_LOG_ADDREF(this, mRefCnt, "nsStyleContext", sizeof(nsStyleContext)); |
michael@0 | 80 | return mRefCnt; |
michael@0 | 81 | } |
michael@0 | 82 | |
michael@0 | 83 | nsrefcnt Release() { |
michael@0 | 84 | if (mRefCnt == UINT32_MAX) { |
michael@0 | 85 | NS_WARNING("refcount overflow, leaking object"); |
michael@0 | 86 | return mRefCnt; |
michael@0 | 87 | } |
michael@0 | 88 | --mRefCnt; |
michael@0 | 89 | NS_LOG_RELEASE(this, mRefCnt, "nsStyleContext"); |
michael@0 | 90 | if (mRefCnt == 0) { |
michael@0 | 91 | Destroy(); |
michael@0 | 92 | return 0; |
michael@0 | 93 | } |
michael@0 | 94 | return mRefCnt; |
michael@0 | 95 | } |
michael@0 | 96 | |
michael@0 | 97 | nsPresContext* PresContext() const { return mRuleNode->PresContext(); } |
michael@0 | 98 | |
michael@0 | 99 | nsStyleContext* GetParent() const { return mParent; } |
michael@0 | 100 | |
michael@0 | 101 | nsIAtom* GetPseudo() const { return mPseudoTag; } |
michael@0 | 102 | nsCSSPseudoElements::Type GetPseudoType() const { |
michael@0 | 103 | return static_cast<nsCSSPseudoElements::Type>(mBits >> |
michael@0 | 104 | NS_STYLE_CONTEXT_TYPE_SHIFT); |
michael@0 | 105 | } |
michael@0 | 106 | |
michael@0 | 107 | // Find, if it already exists *and is easily findable* (i.e., near the |
michael@0 | 108 | // start of the child list), a style context whose: |
michael@0 | 109 | // * GetPseudo() matches aPseudoTag |
michael@0 | 110 | // * RuleNode() matches aRules |
michael@0 | 111 | // * !GetStyleIfVisited() == !aRulesIfVisited, and, if they're |
michael@0 | 112 | // non-null, GetStyleIfVisited()->RuleNode() == aRulesIfVisited |
michael@0 | 113 | // * RelevantLinkVisited() == aRelevantLinkVisited |
michael@0 | 114 | already_AddRefed<nsStyleContext> |
michael@0 | 115 | FindChildWithRules(const nsIAtom* aPseudoTag, nsRuleNode* aRules, |
michael@0 | 116 | nsRuleNode* aRulesIfVisited, |
michael@0 | 117 | bool aRelevantLinkVisited); |
michael@0 | 118 | |
michael@0 | 119 | // Does this style context or any of its ancestors have text |
michael@0 | 120 | // decoration lines? |
michael@0 | 121 | bool HasTextDecorationLines() const |
michael@0 | 122 | { return !!(mBits & NS_STYLE_HAS_TEXT_DECORATION_LINES); } |
michael@0 | 123 | |
michael@0 | 124 | // Does this style context represent the style for a pseudo-element or |
michael@0 | 125 | // inherit data from such a style context? Whether this returns true |
michael@0 | 126 | // is equivalent to whether it or any of its ancestors returns |
michael@0 | 127 | // non-null for GetPseudo. |
michael@0 | 128 | bool HasPseudoElementData() const |
michael@0 | 129 | { return !!(mBits & NS_STYLE_HAS_PSEUDO_ELEMENT_DATA); } |
michael@0 | 130 | |
michael@0 | 131 | // Is the only link whose visitedness is allowed to influence the |
michael@0 | 132 | // style of the node this style context is for (which is that element |
michael@0 | 133 | // or its nearest ancestor that is a link) visited? |
michael@0 | 134 | bool RelevantLinkVisited() const |
michael@0 | 135 | { return !!(mBits & NS_STYLE_RELEVANT_LINK_VISITED); } |
michael@0 | 136 | |
michael@0 | 137 | // Is this a style context for a link? |
michael@0 | 138 | bool IsLinkContext() const { |
michael@0 | 139 | return |
michael@0 | 140 | GetStyleIfVisited() && GetStyleIfVisited()->GetParent() == GetParent(); |
michael@0 | 141 | } |
michael@0 | 142 | |
michael@0 | 143 | // Is this style context the GetStyleIfVisited() for some other style |
michael@0 | 144 | // context? |
michael@0 | 145 | bool IsStyleIfVisited() const |
michael@0 | 146 | { return !!(mBits & NS_STYLE_IS_STYLE_IF_VISITED); } |
michael@0 | 147 | |
michael@0 | 148 | // Tells this style context that it should return true from |
michael@0 | 149 | // IsStyleIfVisited. |
michael@0 | 150 | void SetIsStyleIfVisited() |
michael@0 | 151 | { mBits |= NS_STYLE_IS_STYLE_IF_VISITED; } |
michael@0 | 152 | |
michael@0 | 153 | // Return the style context whose style data should be used for the R, |
michael@0 | 154 | // G, and B components of color, background-color, and border-*-color |
michael@0 | 155 | // if RelevantLinkIsVisited(). |
michael@0 | 156 | // |
michael@0 | 157 | // GetPseudo() and GetPseudoType() on this style context return the |
michael@0 | 158 | // same as on |this|, and its depth in the tree (number of GetParent() |
michael@0 | 159 | // calls until null is returned) is the same as |this|, since its |
michael@0 | 160 | // parent is either |this|'s parent or |this|'s parent's |
michael@0 | 161 | // style-if-visited. |
michael@0 | 162 | // |
michael@0 | 163 | // Structs on this context should never be examined without also |
michael@0 | 164 | // examining the corresponding struct on |this|. Doing so will likely |
michael@0 | 165 | // both (1) lead to a privacy leak and (2) lead to dynamic change bugs |
michael@0 | 166 | // related to the Peek code in nsStyleContext::CalcStyleDifference. |
michael@0 | 167 | nsStyleContext* GetStyleIfVisited() const |
michael@0 | 168 | { return mStyleIfVisited; } |
michael@0 | 169 | |
michael@0 | 170 | // To be called only from nsStyleSet. |
michael@0 | 171 | void SetStyleIfVisited(already_AddRefed<nsStyleContext> aStyleIfVisited) |
michael@0 | 172 | { |
michael@0 | 173 | NS_ABORT_IF_FALSE(!IsStyleIfVisited(), "this context is not visited data"); |
michael@0 | 174 | NS_ASSERTION(!mStyleIfVisited, "should only be set once"); |
michael@0 | 175 | |
michael@0 | 176 | mStyleIfVisited = aStyleIfVisited; |
michael@0 | 177 | |
michael@0 | 178 | NS_ABORT_IF_FALSE(mStyleIfVisited->IsStyleIfVisited(), |
michael@0 | 179 | "other context is visited data"); |
michael@0 | 180 | NS_ABORT_IF_FALSE(!mStyleIfVisited->GetStyleIfVisited(), |
michael@0 | 181 | "other context does not have visited data"); |
michael@0 | 182 | NS_ASSERTION(GetStyleIfVisited()->GetPseudo() == GetPseudo(), |
michael@0 | 183 | "pseudo tag mismatch"); |
michael@0 | 184 | if (GetParent() && GetParent()->GetStyleIfVisited()) { |
michael@0 | 185 | NS_ASSERTION(GetStyleIfVisited()->GetParent() == |
michael@0 | 186 | GetParent()->GetStyleIfVisited() || |
michael@0 | 187 | GetStyleIfVisited()->GetParent() == GetParent(), |
michael@0 | 188 | "parent mismatch"); |
michael@0 | 189 | } else { |
michael@0 | 190 | NS_ASSERTION(GetStyleIfVisited()->GetParent() == GetParent(), |
michael@0 | 191 | "parent mismatch"); |
michael@0 | 192 | } |
michael@0 | 193 | } |
michael@0 | 194 | |
michael@0 | 195 | // Tell this style context to cache aStruct as the struct for aSID |
michael@0 | 196 | void SetStyle(nsStyleStructID aSID, void* aStruct); |
michael@0 | 197 | |
michael@0 | 198 | // Setters for inherit structs only, since rulenode only sets those eagerly. |
michael@0 | 199 | #define STYLE_STRUCT_INHERITED(name_, checkdata_cb_) \ |
michael@0 | 200 | void SetStyle##name_ (nsStyle##name_ * aStruct) { \ |
michael@0 | 201 | void *& slot = \ |
michael@0 | 202 | mCachedInheritedData.mStyleStructs[eStyleStruct_##name_]; \ |
michael@0 | 203 | NS_ASSERTION(!slot || \ |
michael@0 | 204 | (mBits & \ |
michael@0 | 205 | nsCachedStyleData::GetBitForSID(eStyleStruct_##name_)), \ |
michael@0 | 206 | "Going to leak styledata"); \ |
michael@0 | 207 | slot = aStruct; \ |
michael@0 | 208 | } |
michael@0 | 209 | #define STYLE_STRUCT_RESET(name_, checkdata_cb_) /* nothing */ |
michael@0 | 210 | #include "nsStyleStructList.h" |
michael@0 | 211 | #undef STYLE_STRUCT_RESET |
michael@0 | 212 | #undef STYLE_STRUCT_INHERITED |
michael@0 | 213 | |
michael@0 | 214 | nsRuleNode* RuleNode() { return mRuleNode; } |
michael@0 | 215 | void AddStyleBit(const uint64_t& aBit) { mBits |= aBit; } |
michael@0 | 216 | |
michael@0 | 217 | /* |
michael@0 | 218 | * Mark this style context's rule node (and its ancestors) to prevent |
michael@0 | 219 | * it from being garbage collected. |
michael@0 | 220 | */ |
michael@0 | 221 | void Mark(); |
michael@0 | 222 | |
michael@0 | 223 | /* |
michael@0 | 224 | * Get the style data for a style struct. This is the most important |
michael@0 | 225 | * member function of nsIStyleContext. It fills in a const pointer |
michael@0 | 226 | * to a style data struct that is appropriate for the style context's |
michael@0 | 227 | * frame. This struct may be shared with other contexts (either in |
michael@0 | 228 | * the rule tree or the style context tree), so it should not be |
michael@0 | 229 | * modified. |
michael@0 | 230 | * |
michael@0 | 231 | * This function will NOT return null (even when out of memory) when |
michael@0 | 232 | * given a valid style struct ID, so the result does not need to be |
michael@0 | 233 | * null-checked. |
michael@0 | 234 | * |
michael@0 | 235 | * The typesafe functions below are preferred to the use of this |
michael@0 | 236 | * function, both because they're easier to read and because they're |
michael@0 | 237 | * faster. |
michael@0 | 238 | */ |
michael@0 | 239 | const void* NS_FASTCALL StyleData(nsStyleStructID aSID); |
michael@0 | 240 | |
michael@0 | 241 | /** |
michael@0 | 242 | * Define typesafe getter functions for each style struct by |
michael@0 | 243 | * preprocessing the list of style structs. These functions are the |
michael@0 | 244 | * preferred way to get style data. The macro creates functions like: |
michael@0 | 245 | * const nsStyleBorder* StyleBorder(); |
michael@0 | 246 | * const nsStyleColor* StyleColor(); |
michael@0 | 247 | */ |
michael@0 | 248 | #define STYLE_STRUCT(name_, checkdata_cb_) \ |
michael@0 | 249 | const nsStyle##name_ * Style##name_() { \ |
michael@0 | 250 | return DoGetStyle##name_(true); \ |
michael@0 | 251 | } |
michael@0 | 252 | #include "nsStyleStructList.h" |
michael@0 | 253 | #undef STYLE_STRUCT |
michael@0 | 254 | |
michael@0 | 255 | /** |
michael@0 | 256 | * PeekStyle* is like GetStyle* but doesn't trigger style |
michael@0 | 257 | * computation if the data is not cached on either the style context |
michael@0 | 258 | * or the rule node. |
michael@0 | 259 | * |
michael@0 | 260 | * Perhaps this shouldn't be a public nsStyleContext API. |
michael@0 | 261 | */ |
michael@0 | 262 | #define STYLE_STRUCT(name_, checkdata_cb_) \ |
michael@0 | 263 | const nsStyle##name_ * PeekStyle##name_() { \ |
michael@0 | 264 | return DoGetStyle##name_(false); \ |
michael@0 | 265 | } |
michael@0 | 266 | #include "nsStyleStructList.h" |
michael@0 | 267 | #undef STYLE_STRUCT |
michael@0 | 268 | |
michael@0 | 269 | void* GetUniqueStyleData(const nsStyleStructID& aSID); |
michael@0 | 270 | |
michael@0 | 271 | /** |
michael@0 | 272 | * Compute the style changes needed during restyling when this style |
michael@0 | 273 | * context is being replaced by aOther. (This is nonsymmetric since |
michael@0 | 274 | * we optimize by skipping comparison for styles that have never been |
michael@0 | 275 | * requested.) |
michael@0 | 276 | * |
michael@0 | 277 | * This method returns a change hint (see nsChangeHint.h). All change |
michael@0 | 278 | * hints apply to the frame and its later continuations or ib-split |
michael@0 | 279 | * siblings. Most (all of those except the "NotHandledForDescendants" |
michael@0 | 280 | * hints) also apply to all descendants. The caller must pass in any |
michael@0 | 281 | * non-inherited hints that resulted from the parent style context's |
michael@0 | 282 | * style change. The caller *may* pass more hints than needed, but |
michael@0 | 283 | * must not pass less than needed; therefore if the caller doesn't |
michael@0 | 284 | * know, the caller should pass |
michael@0 | 285 | * nsChangeHint_Hints_NotHandledForDescendants. |
michael@0 | 286 | */ |
michael@0 | 287 | nsChangeHint CalcStyleDifference(nsStyleContext* aOther, |
michael@0 | 288 | nsChangeHint aParentHintsNotHandledForDescendants); |
michael@0 | 289 | |
michael@0 | 290 | /** |
michael@0 | 291 | * Get a color that depends on link-visitedness using this and |
michael@0 | 292 | * this->GetStyleIfVisited(). |
michael@0 | 293 | * |
michael@0 | 294 | * aProperty must be a color-valued property that nsStyleAnimation |
michael@0 | 295 | * knows how to extract. It must also be a property that we know to |
michael@0 | 296 | * do change handling for in nsStyleContext::CalcDifference. |
michael@0 | 297 | * |
michael@0 | 298 | * Note that if aProperty is eCSSProperty_border_*_color, this |
michael@0 | 299 | * function handles -moz-use-text-color. |
michael@0 | 300 | */ |
michael@0 | 301 | nscolor GetVisitedDependentColor(nsCSSProperty aProperty); |
michael@0 | 302 | |
michael@0 | 303 | /** |
michael@0 | 304 | * aColors should be a two element array of nscolor in which the first |
michael@0 | 305 | * color is the unvisited color and the second is the visited color. |
michael@0 | 306 | * |
michael@0 | 307 | * Combine the R, G, and B components of whichever of aColors should |
michael@0 | 308 | * be used based on aLinkIsVisited with the A component of aColors[0]. |
michael@0 | 309 | */ |
michael@0 | 310 | static nscolor CombineVisitedColors(nscolor *aColors, |
michael@0 | 311 | bool aLinkIsVisited); |
michael@0 | 312 | |
michael@0 | 313 | /** |
michael@0 | 314 | * Allocate a chunk of memory that is scoped to the lifetime of this |
michael@0 | 315 | * style context, i.e., memory that will automatically be freed when |
michael@0 | 316 | * this style context is destroyed. This is intended for allocations |
michael@0 | 317 | * that are stored on this style context or its style structs. (Use |
michael@0 | 318 | * on style structs is fine since any style context to which this |
michael@0 | 319 | * context's style structs are shared will be a descendant of this |
michael@0 | 320 | * style context and thus keep it alive.) |
michael@0 | 321 | * |
michael@0 | 322 | * This currently allocates the memory out of the pres shell arena. |
michael@0 | 323 | * |
michael@0 | 324 | * It would be relatively straightforward to write a Free method |
michael@0 | 325 | * for the underlying implementation, but we don't need it (or the |
michael@0 | 326 | * overhead of making a doubly-linked list or other structure to |
michael@0 | 327 | * support it). |
michael@0 | 328 | * |
michael@0 | 329 | * WARNING: Memory allocated using this method cannot be stored in the |
michael@0 | 330 | * rule tree, since rule nodes may outlive the style context. |
michael@0 | 331 | */ |
michael@0 | 332 | void* Alloc(size_t aSize); |
michael@0 | 333 | |
michael@0 | 334 | /** |
michael@0 | 335 | * Start the background image loads for this style context. |
michael@0 | 336 | */ |
michael@0 | 337 | void StartBackgroundImageLoads() { |
michael@0 | 338 | // Just get our background struct; that should do the trick |
michael@0 | 339 | StyleBackground(); |
michael@0 | 340 | } |
michael@0 | 341 | |
michael@0 | 342 | #ifdef DEBUG |
michael@0 | 343 | void List(FILE* out, int32_t aIndent); |
michael@0 | 344 | static void AssertStyleStructMaxDifferenceValid(); |
michael@0 | 345 | #endif |
michael@0 | 346 | |
michael@0 | 347 | protected: |
michael@0 | 348 | void AddChild(nsStyleContext* aChild); |
michael@0 | 349 | void RemoveChild(nsStyleContext* aChild); |
michael@0 | 350 | |
michael@0 | 351 | void ApplyStyleFixups(bool aSkipFlexItemStyleFixup); |
michael@0 | 352 | |
michael@0 | 353 | void FreeAllocations(nsPresContext* aPresContext); |
michael@0 | 354 | |
michael@0 | 355 | // Helper function that GetStyleData and GetUniqueStyleData use. Only |
michael@0 | 356 | // returns the structs we cache ourselves; never consults the ruletree. |
michael@0 | 357 | inline const void* GetCachedStyleData(nsStyleStructID aSID); |
michael@0 | 358 | |
michael@0 | 359 | // Helper functions for GetStyle* and PeekStyle* |
michael@0 | 360 | #define STYLE_STRUCT_INHERITED(name_, checkdata_cb_) \ |
michael@0 | 361 | const nsStyle##name_ * DoGetStyle##name_(bool aComputeData) { \ |
michael@0 | 362 | const nsStyle##name_ * cachedData = \ |
michael@0 | 363 | static_cast<nsStyle##name_*>( \ |
michael@0 | 364 | mCachedInheritedData.mStyleStructs[eStyleStruct_##name_]); \ |
michael@0 | 365 | if (cachedData) /* Have it cached already, yay */ \ |
michael@0 | 366 | return cachedData; \ |
michael@0 | 367 | /* Have the rulenode deal */ \ |
michael@0 | 368 | return mRuleNode->GetStyle##name_(this, aComputeData); \ |
michael@0 | 369 | } |
michael@0 | 370 | #define STYLE_STRUCT_RESET(name_, checkdata_cb_) \ |
michael@0 | 371 | const nsStyle##name_ * DoGetStyle##name_(bool aComputeData) { \ |
michael@0 | 372 | const nsStyle##name_ * cachedData = mCachedResetData \ |
michael@0 | 373 | ? static_cast<nsStyle##name_*>( \ |
michael@0 | 374 | mCachedResetData->mStyleStructs[eStyleStruct_##name_]) \ |
michael@0 | 375 | : nullptr; \ |
michael@0 | 376 | if (cachedData) /* Have it cached already, yay */ \ |
michael@0 | 377 | return cachedData; \ |
michael@0 | 378 | /* Have the rulenode deal */ \ |
michael@0 | 379 | return mRuleNode->GetStyle##name_(this, aComputeData); \ |
michael@0 | 380 | } |
michael@0 | 381 | #include "nsStyleStructList.h" |
michael@0 | 382 | #undef STYLE_STRUCT_RESET |
michael@0 | 383 | #undef STYLE_STRUCT_INHERITED |
michael@0 | 384 | |
michael@0 | 385 | nsStyleContext* const mParent; // STRONG |
michael@0 | 386 | |
michael@0 | 387 | // Children are kept in two circularly-linked lists. The list anchor |
michael@0 | 388 | // is not part of the list (null for empty), and we point to the first |
michael@0 | 389 | // child. |
michael@0 | 390 | // mEmptyChild for children whose rule node is the root rule node, and |
michael@0 | 391 | // mChild for other children. The order of children is not |
michael@0 | 392 | // meaningful. |
michael@0 | 393 | nsStyleContext* mChild; |
michael@0 | 394 | nsStyleContext* mEmptyChild; |
michael@0 | 395 | nsStyleContext* mPrevSibling; |
michael@0 | 396 | nsStyleContext* mNextSibling; |
michael@0 | 397 | |
michael@0 | 398 | // Style to be used instead for the R, G, and B components of color, |
michael@0 | 399 | // background-color, and border-*-color if the nearest ancestor link |
michael@0 | 400 | // element is visited (see RelevantLinkVisited()). |
michael@0 | 401 | nsRefPtr<nsStyleContext> mStyleIfVisited; |
michael@0 | 402 | |
michael@0 | 403 | // If this style context is for a pseudo-element or anonymous box, |
michael@0 | 404 | // the relevant atom. |
michael@0 | 405 | nsCOMPtr<nsIAtom> mPseudoTag; |
michael@0 | 406 | |
michael@0 | 407 | // The rule node is the node in the lexicographic tree of rule nodes |
michael@0 | 408 | // (the "rule tree") that indicates which style rules are used to |
michael@0 | 409 | // compute the style data, and in what cascading order. The least |
michael@0 | 410 | // specific rule matched is the one whose rule node is a child of the |
michael@0 | 411 | // root of the rule tree, and the most specific rule matched is the |
michael@0 | 412 | // |mRule| member of |mRuleNode|. |
michael@0 | 413 | nsRuleNode* const mRuleNode; |
michael@0 | 414 | |
michael@0 | 415 | // Private to nsStyleContext::Alloc and FreeAllocations. |
michael@0 | 416 | struct AllocationHeader { |
michael@0 | 417 | AllocationHeader* mNext; |
michael@0 | 418 | size_t mSize; |
michael@0 | 419 | |
michael@0 | 420 | void* mStorageStart; // ensure the storage is at least pointer-aligned |
michael@0 | 421 | }; |
michael@0 | 422 | AllocationHeader* mAllocations; |
michael@0 | 423 | |
michael@0 | 424 | // mCachedInheritedData and mCachedResetData point to both structs that |
michael@0 | 425 | // are owned by this style context and structs that are owned by one of |
michael@0 | 426 | // this style context's ancestors (which are indirectly owned since this |
michael@0 | 427 | // style context owns a reference to its parent). If the bit in |mBits| |
michael@0 | 428 | // is set for a struct, that means that the pointer for that struct is |
michael@0 | 429 | // owned by an ancestor or by mRuleNode rather than by this style context. |
michael@0 | 430 | // Since style contexts typically have some inherited data but only sometimes |
michael@0 | 431 | // have reset data, we always allocate the mCachedInheritedData, but only |
michael@0 | 432 | // sometimes allocate the mCachedResetData. |
michael@0 | 433 | nsResetStyleData* mCachedResetData; // Cached reset style data. |
michael@0 | 434 | nsInheritedStyleData mCachedInheritedData; // Cached inherited style data |
michael@0 | 435 | uint64_t mBits; // Which structs are inherited from the |
michael@0 | 436 | // parent context or owned by mRuleNode. |
michael@0 | 437 | uint32_t mRefCnt; |
michael@0 | 438 | }; |
michael@0 | 439 | |
michael@0 | 440 | already_AddRefed<nsStyleContext> |
michael@0 | 441 | NS_NewStyleContext(nsStyleContext* aParentContext, |
michael@0 | 442 | nsIAtom* aPseudoTag, |
michael@0 | 443 | nsCSSPseudoElements::Type aPseudoType, |
michael@0 | 444 | nsRuleNode* aRuleNode, |
michael@0 | 445 | bool aSkipFlexItemStyleFixup); |
michael@0 | 446 | #endif |