1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/style/nsRuleNode.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,807 @@ 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 + * a node in the lexicographic tree of rules that match an element, 1.11 + * responsible for converting the rules' information into computed style 1.12 + */ 1.13 + 1.14 +#ifndef nsRuleNode_h___ 1.15 +#define nsRuleNode_h___ 1.16 + 1.17 +#include "nsPresContext.h" 1.18 +#include "nsStyleStruct.h" 1.19 + 1.20 +#include <stdint.h> 1.21 + 1.22 +class nsStyleContext; 1.23 +struct nsRuleData; 1.24 +class nsIStyleRule; 1.25 +struct nsCSSValueList; 1.26 + 1.27 +class nsCSSValue; 1.28 +struct nsCSSRect; 1.29 + 1.30 +class nsStyleCoord; 1.31 +struct nsCSSValuePairList; 1.32 + 1.33 +template <nsStyleStructID MinIndex, nsStyleStructID Count> 1.34 +class FixedStyleStructArray 1.35 +{ 1.36 +private: 1.37 + void* mArray[Count]; 1.38 +public: 1.39 + void*& operator[](nsStyleStructID aIndex) { 1.40 + NS_ABORT_IF_FALSE(MinIndex <= aIndex && aIndex < (MinIndex + Count), 1.41 + "out of range"); 1.42 + return mArray[aIndex - MinIndex]; 1.43 + } 1.44 + 1.45 + const void* operator[](nsStyleStructID aIndex) const { 1.46 + NS_ABORT_IF_FALSE(MinIndex <= aIndex && aIndex < (MinIndex + Count), 1.47 + "out of range"); 1.48 + return mArray[aIndex - MinIndex]; 1.49 + } 1.50 +}; 1.51 + 1.52 +struct nsInheritedStyleData 1.53 +{ 1.54 + FixedStyleStructArray<nsStyleStructID_Inherited_Start, 1.55 + nsStyleStructID_Inherited_Count> mStyleStructs; 1.56 + 1.57 + void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW { 1.58 + return aContext->AllocateFromShell(sz); 1.59 + } 1.60 + 1.61 + void DestroyStructs(uint64_t aBits, nsPresContext* aContext) { 1.62 +#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \ 1.63 + void *name##Data = mStyleStructs[eStyleStruct_##name]; \ 1.64 + if (name##Data && !(aBits & NS_STYLE_INHERIT_BIT(name))) \ 1.65 + static_cast<nsStyle##name*>(name##Data)->Destroy(aContext); 1.66 +#define STYLE_STRUCT_RESET(name, checkdata_cb) 1.67 + 1.68 +#include "nsStyleStructList.h" 1.69 + 1.70 +#undef STYLE_STRUCT_INHERITED 1.71 +#undef STYLE_STRUCT_RESET 1.72 + } 1.73 + 1.74 + void Destroy(uint64_t aBits, nsPresContext* aContext) { 1.75 + DestroyStructs(aBits, aContext); 1.76 + aContext->FreeToShell(sizeof(nsInheritedStyleData), this); 1.77 + } 1.78 + 1.79 + nsInheritedStyleData() { 1.80 + for (nsStyleStructID i = nsStyleStructID_Inherited_Start; 1.81 + i < nsStyleStructID_Inherited_Start + nsStyleStructID_Inherited_Count; 1.82 + i = nsStyleStructID(i + 1)) { 1.83 + mStyleStructs[i] = nullptr; 1.84 + } 1.85 + } 1.86 +}; 1.87 + 1.88 +struct nsResetStyleData 1.89 +{ 1.90 + FixedStyleStructArray<nsStyleStructID_Reset_Start, 1.91 + nsStyleStructID_Reset_Count> mStyleStructs; 1.92 + 1.93 + nsResetStyleData() 1.94 + { 1.95 + for (nsStyleStructID i = nsStyleStructID_Reset_Start; 1.96 + i < nsStyleStructID_Reset_Start + nsStyleStructID_Reset_Count; 1.97 + i = nsStyleStructID(i + 1)) { 1.98 + mStyleStructs[i] = nullptr; 1.99 + } 1.100 + } 1.101 + 1.102 + void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW { 1.103 + return aContext->AllocateFromShell(sz); 1.104 + } 1.105 + 1.106 + void Destroy(uint64_t aBits, nsPresContext* aContext) { 1.107 +#define STYLE_STRUCT_RESET(name, checkdata_cb) \ 1.108 + void *name##Data = mStyleStructs[eStyleStruct_##name]; \ 1.109 + if (name##Data && !(aBits & NS_STYLE_INHERIT_BIT(name))) \ 1.110 + static_cast<nsStyle##name*>(name##Data)->Destroy(aContext); 1.111 +#define STYLE_STRUCT_INHERITED(name, checkdata_cb) 1.112 + 1.113 +#include "nsStyleStructList.h" 1.114 + 1.115 +#undef STYLE_STRUCT_RESET 1.116 +#undef STYLE_STRUCT_INHERITED 1.117 + 1.118 + aContext->FreeToShell(sizeof(nsResetStyleData), this); 1.119 + } 1.120 +}; 1.121 + 1.122 +struct nsCachedStyleData 1.123 +{ 1.124 + nsInheritedStyleData* mInheritedData; 1.125 + nsResetStyleData* mResetData; 1.126 + 1.127 + static bool IsReset(const nsStyleStructID aSID) { 1.128 + NS_ABORT_IF_FALSE(0 <= aSID && aSID < nsStyleStructID_Length, 1.129 + "must be an inherited or reset SID"); 1.130 + return nsStyleStructID_Reset_Start <= aSID; 1.131 + } 1.132 + 1.133 + static bool IsInherited(const nsStyleStructID aSID) { 1.134 + return !IsReset(aSID); 1.135 + } 1.136 + 1.137 + static uint32_t GetBitForSID(const nsStyleStructID aSID) { 1.138 + return 1 << aSID; 1.139 + } 1.140 + 1.141 + void* NS_FASTCALL GetStyleData(const nsStyleStructID aSID) { 1.142 + if (IsReset(aSID)) { 1.143 + if (mResetData) { 1.144 + return mResetData->mStyleStructs[aSID]; 1.145 + } 1.146 + } else { 1.147 + if (mInheritedData) { 1.148 + return mInheritedData->mStyleStructs[aSID]; 1.149 + } 1.150 + } 1.151 + return nullptr; 1.152 + } 1.153 + 1.154 + void NS_FASTCALL SetStyleData(const nsStyleStructID aSID, 1.155 + nsPresContext *aPresContext, void *aData) { 1.156 + if (IsReset(aSID)) { 1.157 + if (!mResetData) { 1.158 + mResetData = new (aPresContext) nsResetStyleData; 1.159 + } 1.160 + mResetData->mStyleStructs[aSID] = aData; 1.161 + } else { 1.162 + if (!mInheritedData) { 1.163 + mInheritedData = new (aPresContext) nsInheritedStyleData; 1.164 + } 1.165 + mInheritedData->mStyleStructs[aSID] = aData; 1.166 + } 1.167 + } 1.168 + 1.169 + // Typesafe and faster versions of the above 1.170 + #define STYLE_STRUCT_INHERITED(name_, checkdata_cb_) \ 1.171 + nsStyle##name_ * NS_FASTCALL GetStyle##name_ () { \ 1.172 + return mInheritedData ? static_cast<nsStyle##name_*>( \ 1.173 + mInheritedData->mStyleStructs[eStyleStruct_##name_]) : nullptr; \ 1.174 + } 1.175 + #define STYLE_STRUCT_RESET(name_, checkdata_cb_) \ 1.176 + nsStyle##name_ * NS_FASTCALL GetStyle##name_ () { \ 1.177 + return mResetData ? static_cast<nsStyle##name_*>( \ 1.178 + mResetData->mStyleStructs[eStyleStruct_##name_]) : nullptr; \ 1.179 + } 1.180 + #include "nsStyleStructList.h" 1.181 + #undef STYLE_STRUCT_RESET 1.182 + #undef STYLE_STRUCT_INHERITED 1.183 + 1.184 + void Destroy(uint64_t aBits, nsPresContext* aContext) { 1.185 + if (mResetData) 1.186 + mResetData->Destroy(aBits, aContext); 1.187 + if (mInheritedData) 1.188 + mInheritedData->Destroy(aBits, aContext); 1.189 + mResetData = nullptr; 1.190 + mInheritedData = nullptr; 1.191 + } 1.192 + 1.193 + nsCachedStyleData() :mInheritedData(nullptr), mResetData(nullptr) {} 1.194 + ~nsCachedStyleData() {} 1.195 +}; 1.196 + 1.197 +/** 1.198 + * nsRuleNode is a node in a lexicographic tree (the "rule tree") 1.199 + * indexed by style rules (implementations of nsIStyleRule). 1.200 + * 1.201 + * The rule tree is owned by the nsStyleSet and is destroyed when the 1.202 + * presentation of the document goes away. It is garbage-collected 1.203 + * (using mark-and-sweep garbage collection) during the lifetime of the 1.204 + * document (when dynamic changes cause the destruction of enough style 1.205 + * contexts). Rule nodes are marked if they are pointed to by a style 1.206 + * context or one of their descendants is. 1.207 + * 1.208 + * An nsStyleContext, which represents the computed style data for an 1.209 + * element, points to an nsRuleNode. The path from the root of the rule 1.210 + * tree to the nsStyleContext's mRuleNode gives the list of the rules 1.211 + * matched, from least important in the cascading order to most 1.212 + * important in the cascading order. 1.213 + * 1.214 + * The reason for using a lexicographic tree is that it allows for 1.215 + * sharing of style data, which saves both memory (for storing the 1.216 + * computed style data) and time (for computing them). This sharing 1.217 + * depends on the computed style data being stored in structs (nsStyle*) 1.218 + * that contain only properties that are inherited by default 1.219 + * ("inherited structs") or structs that contain only properties that 1.220 + * are not inherited by default ("reset structs"). The optimization 1.221 + * depends on the normal case being that style rules specify relatively 1.222 + * few properties and even that elements generally have relatively few 1.223 + * properties specified. This allows sharing in the following ways: 1.224 + * 1. [mainly reset structs] When a style data struct will contain the 1.225 + * same computed value for any elements that match the same set of 1.226 + * rules (common for reset structs), it can be stored on the 1.227 + * nsRuleNode instead of on the nsStyleContext. 1.228 + * 2. [only? reset structs] When (1) occurs, and an nsRuleNode doesn't 1.229 + * have any rules that change the values in the struct, the 1.230 + * nsRuleNode can share that struct with its parent nsRuleNode. 1.231 + * 3. [mainly inherited structs] When an element doesn't match any 1.232 + * rules that change the value of a property (or, in the edge case, 1.233 + * when all the values specified are 'inherit'), the nsStyleContext 1.234 + * can use the same nsStyle* struct as its parent nsStyleContext. 1.235 + * 1.236 + * Since the data represented by an nsIStyleRule are immutable, the data 1.237 + * represented by an nsRuleNode are also immutable. 1.238 + */ 1.239 + 1.240 +enum nsFontSizeType { 1.241 + eFontSize_HTML = 1, 1.242 + eFontSize_CSS = 2 1.243 +}; 1.244 + 1.245 +class nsRuleNode { 1.246 +public: 1.247 + enum RuleDetail { 1.248 + eRuleNone, // No props have been specified at all. 1.249 + eRulePartialReset, // At least one prop with a non-"inherit" value 1.250 + // has been specified. No props have been 1.251 + // specified with an "inherit" value. At least 1.252 + // one prop remains unspecified. 1.253 + eRulePartialMixed, // At least one prop with a non-"inherit" value 1.254 + // has been specified. Some props may also have 1.255 + // been specified with an "inherit" value. At 1.256 + // least one prop remains unspecified. 1.257 + eRulePartialInherited, // Only props with "inherit" values have 1.258 + // have been specified. At least one prop 1.259 + // remains unspecified. 1.260 + eRuleFullReset, // All props have been specified. None has an 1.261 + // "inherit" value. 1.262 + eRuleFullMixed, // All props have been specified. At least one has 1.263 + // a non-"inherit" value. 1.264 + eRuleFullInherited // All props have been specified with "inherit" 1.265 + // values. 1.266 + }; 1.267 + 1.268 +private: 1.269 + nsPresContext* const mPresContext; // Our pres context. 1.270 + 1.271 + nsRuleNode* const mParent; // A pointer to the parent node in the tree. 1.272 + // This enables us to walk backwards from the 1.273 + // most specific rule matched to the least 1.274 + // specific rule (which is the optimal order to 1.275 + // use for lookups of style properties. 1.276 + nsIStyleRule* const mRule; // [STRONG] A pointer to our specific rule. 1.277 + 1.278 + nsRuleNode* mNextSibling; // This value should be used only by the 1.279 + // parent, since the parent may store 1.280 + // children in a hash, which means this 1.281 + // pointer is not meaningful. Order of 1.282 + // siblings is also not meaningful. 1.283 + 1.284 + struct Key { 1.285 + nsIStyleRule* mRule; 1.286 + uint8_t mLevel; 1.287 + bool mIsImportantRule; 1.288 + 1.289 + Key(nsIStyleRule* aRule, uint8_t aLevel, bool aIsImportantRule) 1.290 + : mRule(aRule), mLevel(aLevel), mIsImportantRule(aIsImportantRule) 1.291 + {} 1.292 + 1.293 + bool operator==(const Key& aOther) const 1.294 + { 1.295 + return mRule == aOther.mRule && 1.296 + mLevel == aOther.mLevel && 1.297 + mIsImportantRule == aOther.mIsImportantRule; 1.298 + } 1.299 + 1.300 + bool operator!=(const Key& aOther) const 1.301 + { 1.302 + return !(*this == aOther); 1.303 + } 1.304 + }; 1.305 + 1.306 + static PLDHashNumber 1.307 + ChildrenHashHashKey(PLDHashTable *aTable, const void *aKey); 1.308 + 1.309 + static bool 1.310 + ChildrenHashMatchEntry(PLDHashTable *aTable, 1.311 + const PLDHashEntryHdr *aHdr, 1.312 + const void *aKey); 1.313 + 1.314 + static const PLDHashTableOps ChildrenHashOps; 1.315 + 1.316 + static PLDHashOperator 1.317 + EnqueueRuleNodeChildren(PLDHashTable *table, PLDHashEntryHdr *hdr, 1.318 + uint32_t number, void *arg); 1.319 + 1.320 + Key GetKey() const { 1.321 + return Key(mRule, GetLevel(), IsImportantRule()); 1.322 + } 1.323 + 1.324 + // The children of this node are stored in either a hashtable or list 1.325 + // that maps from rules to our nsRuleNode children. When matching 1.326 + // rules, we use this mapping to transition from node to node 1.327 + // (constructing new nodes as needed to flesh out the tree). 1.328 + 1.329 + union { 1.330 + void* asVoid; 1.331 + nsRuleNode* asList; 1.332 + PLDHashTable* asHash; 1.333 + } mChildren; // Accessed only through the methods below. 1.334 + 1.335 + enum { 1.336 + kTypeMask = 0x1, 1.337 + kListType = 0x0, 1.338 + kHashType = 0x1 1.339 + }; 1.340 + enum { 1.341 + // Maximum to have in a list before converting to a hashtable. 1.342 + // XXX Need to optimize this. 1.343 + kMaxChildrenInList = 32 1.344 + }; 1.345 + 1.346 + bool HaveChildren() const { 1.347 + return mChildren.asVoid != nullptr; 1.348 + } 1.349 + bool ChildrenAreHashed() { 1.350 + return (intptr_t(mChildren.asVoid) & kTypeMask) == kHashType; 1.351 + } 1.352 + nsRuleNode* ChildrenList() { 1.353 + return mChildren.asList; 1.354 + } 1.355 + nsRuleNode** ChildrenListPtr() { 1.356 + return &mChildren.asList; 1.357 + } 1.358 + PLDHashTable* ChildrenHash() { 1.359 + return (PLDHashTable*) (intptr_t(mChildren.asHash) & ~intptr_t(kTypeMask)); 1.360 + } 1.361 + void SetChildrenList(nsRuleNode *aList) { 1.362 + NS_ASSERTION(!(intptr_t(aList) & kTypeMask), 1.363 + "pointer not 2-byte aligned"); 1.364 + mChildren.asList = aList; 1.365 + } 1.366 + void SetChildrenHash(PLDHashTable *aHashtable) { 1.367 + NS_ASSERTION(!(intptr_t(aHashtable) & kTypeMask), 1.368 + "pointer not 2-byte aligned"); 1.369 + mChildren.asHash = (PLDHashTable*)(intptr_t(aHashtable) | kHashType); 1.370 + } 1.371 + void ConvertChildrenToHash(); 1.372 + 1.373 + nsCachedStyleData mStyleData; // Any data we cached on the rule node. 1.374 + 1.375 + uint32_t mDependentBits; // Used to cache the fact that we can look up 1.376 + // cached data under a parent rule. 1.377 + 1.378 + uint32_t mNoneBits; // Used to cache the fact that the branch to this 1.379 + // node specifies no non-inherited data for a 1.380 + // given struct type. (This usually implies that 1.381 + // the entire branch specifies no non-inherited 1.382 + // data, although not necessarily, if a 1.383 + // non-inherited value is overridden by an 1.384 + // explicit 'inherit' value.) For example, if an 1.385 + // entire rule branch specifies no color 1.386 + // information, then a bit will be set along every 1.387 + // rule node on that branch, so that you can break 1.388 + // out of the rule tree early and just inherit 1.389 + // from the parent style context. The presence of 1.390 + // this bit means we should just get inherited 1.391 + // data from the parent style context, and it is 1.392 + // never used for reset structs since their 1.393 + // Compute*Data functions don't initialize from 1.394 + // inherited data. 1.395 + 1.396 + // Reference count. This just counts the style contexts that reference this 1.397 + // rulenode. And children the rulenode has had. When this goes to 0 or 1.398 + // stops being 0, we notify the style set. 1.399 + // Note, in particular, that when a child is removed mRefCnt is NOT 1.400 + // decremented. This is on purpose; the notifications to the style set are 1.401 + // only used to determine when it's worth running GC on the ruletree, and 1.402 + // this setup makes it so we only count unused ruletree leaves for purposes 1.403 + // of deciding when to GC. We could more accurately count unused rulenodes 1.404 + // by releasing/addrefing our parent when our refcount transitions to or from 1.405 + // 0, but it doesn't seem worth it to do that. 1.406 + uint32_t mRefCnt; 1.407 + 1.408 +public: 1.409 + // Overloaded new operator. Initializes the memory to 0 and relies on an arena 1.410 + // (which comes from the presShell) to perform the allocation. 1.411 + void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW; 1.412 + void Destroy() { DestroyInternal(nullptr); } 1.413 + 1.414 + // Implemented in nsStyleSet.h, since it needs to know about nsStyleSet. 1.415 + inline void AddRef(); 1.416 + 1.417 + // Implemented in nsStyleSet.h, since it needs to know about nsStyleSet. 1.418 + inline void Release(); 1.419 + 1.420 +protected: 1.421 + void DestroyInternal(nsRuleNode ***aDestroyQueueTail); 1.422 + void PropagateDependentBit(nsStyleStructID aSID, nsRuleNode* aHighestNode, 1.423 + void* aStruct); 1.424 + void PropagateNoneBit(uint32_t aBit, nsRuleNode* aHighestNode); 1.425 + 1.426 + const void* SetDefaultOnRoot(const nsStyleStructID aSID, 1.427 + nsStyleContext* aContext); 1.428 + 1.429 + /** 1.430 + * Resolves any property values in aRuleData for a given style struct that 1.431 + * have eCSSUnit_TokenStream values, by resolving them against the computed 1.432 + * variable values on the style context and re-parsing the property. 1.433 + * 1.434 + * @return Whether any properties with eCSSUnit_TokenStream values were 1.435 + * encountered. 1.436 + */ 1.437 + static bool ResolveVariableReferences(const nsStyleStructID aSID, 1.438 + nsRuleData* aRuleData, 1.439 + nsStyleContext* aContext); 1.440 + 1.441 + const void* 1.442 + WalkRuleTree(const nsStyleStructID aSID, nsStyleContext* aContext); 1.443 + 1.444 + const void* 1.445 + ComputeDisplayData(void* aStartStruct, 1.446 + const nsRuleData* aRuleData, 1.447 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.448 + RuleDetail aRuleDetail, 1.449 + const bool aCanStoreInRuleTree); 1.450 + 1.451 + const void* 1.452 + ComputeVisibilityData(void* aStartStruct, 1.453 + const nsRuleData* aRuleData, 1.454 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.455 + RuleDetail aRuleDetail, 1.456 + const bool aCanStoreInRuleTree); 1.457 + 1.458 + const void* 1.459 + ComputeFontData(void* aStartStruct, 1.460 + const nsRuleData* aRuleData, 1.461 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.462 + RuleDetail aRuleDetail, 1.463 + const bool aCanStoreInRuleTree); 1.464 + 1.465 + const void* 1.466 + ComputeColorData(void* aStartStruct, 1.467 + const nsRuleData* aRuleData, 1.468 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.469 + RuleDetail aRuleDetail, 1.470 + const bool aCanStoreInRuleTree); 1.471 + 1.472 + const void* 1.473 + ComputeBackgroundData(void* aStartStruct, 1.474 + const nsRuleData* aRuleData, 1.475 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.476 + RuleDetail aRuleDetail, 1.477 + const bool aCanStoreInRuleTree); 1.478 + 1.479 + const void* 1.480 + ComputeMarginData(void* aStartStruct, 1.481 + const nsRuleData* aRuleData, 1.482 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.483 + RuleDetail aRuleDetail, 1.484 + const bool aCanStoreInRuleTree); 1.485 + 1.486 + const void* 1.487 + ComputeBorderData(void* aStartStruct, 1.488 + const nsRuleData* aRuleData, 1.489 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.490 + RuleDetail aRuleDetail, 1.491 + const bool aCanStoreInRuleTree); 1.492 + 1.493 + const void* 1.494 + ComputePaddingData(void* aStartStruct, 1.495 + const nsRuleData* aRuleData, 1.496 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.497 + RuleDetail aRuleDetail, 1.498 + const bool aCanStoreInRuleTree); 1.499 + 1.500 + const void* 1.501 + ComputeOutlineData(void* aStartStruct, 1.502 + const nsRuleData* aRuleData, 1.503 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.504 + RuleDetail aRuleDetail, 1.505 + const bool aCanStoreInRuleTree); 1.506 + 1.507 + const void* 1.508 + ComputeListData(void* aStartStruct, 1.509 + const nsRuleData* aRuleData, 1.510 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.511 + RuleDetail aRuleDetail, 1.512 + const bool aCanStoreInRuleTree); 1.513 + 1.514 + const void* 1.515 + ComputePositionData(void* aStartStruct, 1.516 + const nsRuleData* aRuleData, 1.517 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.518 + RuleDetail aRuleDetail, 1.519 + const bool aCanStoreInRuleTree); 1.520 + 1.521 + const void* 1.522 + ComputeTableData(void* aStartStruct, 1.523 + const nsRuleData* aRuleData, 1.524 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.525 + RuleDetail aRuleDetail, 1.526 + const bool aCanStoreInRuleTree); 1.527 + 1.528 + const void* 1.529 + ComputeTableBorderData(void* aStartStruct, 1.530 + const nsRuleData* aRuleData, 1.531 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.532 + RuleDetail aRuleDetail, 1.533 + const bool aCanStoreInRuleTree); 1.534 + 1.535 + const void* 1.536 + ComputeContentData(void* aStartStruct, 1.537 + const nsRuleData* aRuleData, 1.538 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.539 + RuleDetail aRuleDetail, 1.540 + const bool aCanStoreInRuleTree); 1.541 + 1.542 + const void* 1.543 + ComputeQuotesData(void* aStartStruct, 1.544 + const nsRuleData* aRuleData, 1.545 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.546 + RuleDetail aRuleDetail, 1.547 + const bool aCanStoreInRuleTree); 1.548 + 1.549 + const void* 1.550 + ComputeTextData(void* aStartStruct, 1.551 + const nsRuleData* aRuleData, 1.552 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.553 + RuleDetail aRuleDetail, 1.554 + const bool aCanStoreInRuleTree); 1.555 + 1.556 + const void* 1.557 + ComputeTextResetData(void* aStartStruct, 1.558 + const nsRuleData* aRuleData, 1.559 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.560 + RuleDetail aRuleDetail, 1.561 + const bool aCanStoreInRuleTree); 1.562 + 1.563 + const void* 1.564 + ComputeUserInterfaceData(void* aStartStruct, 1.565 + const nsRuleData* aRuleData, 1.566 + nsStyleContext* aContext, 1.567 + nsRuleNode* aHighestNode, 1.568 + RuleDetail aRuleDetail, 1.569 + const bool aCanStoreInRuleTree); 1.570 + 1.571 + const void* 1.572 + ComputeUIResetData(void* aStartStruct, 1.573 + const nsRuleData* aRuleData, 1.574 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.575 + RuleDetail aRuleDetail, 1.576 + const bool aCanStoreInRuleTree); 1.577 + 1.578 + const void* 1.579 + ComputeXULData(void* aStartStruct, 1.580 + const nsRuleData* aRuleData, 1.581 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.582 + RuleDetail aRuleDetail, 1.583 + const bool aCanStoreInRuleTree); 1.584 + 1.585 + const void* 1.586 + ComputeColumnData(void* aStartStruct, 1.587 + const nsRuleData* aRuleData, 1.588 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.589 + RuleDetail aRuleDetail, 1.590 + const bool aCanStoreInRuleTree); 1.591 + 1.592 + const void* 1.593 + ComputeSVGData(void* aStartStruct, 1.594 + const nsRuleData* aRuleData, 1.595 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.596 + RuleDetail aRuleDetail, 1.597 + const bool aCanStoreInRuleTree); 1.598 + 1.599 + const void* 1.600 + ComputeSVGResetData(void* aStartStruct, 1.601 + const nsRuleData* aRuleData, 1.602 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.603 + RuleDetail aRuleDetail, 1.604 + const bool aCanStoreInRuleTree); 1.605 + 1.606 + const void* 1.607 + ComputeVariablesData(void* aStartStruct, 1.608 + const nsRuleData* aRuleData, 1.609 + nsStyleContext* aContext, nsRuleNode* aHighestNode, 1.610 + RuleDetail aRuleDetail, 1.611 + const bool aCanStoreInRuleTree); 1.612 + 1.613 + // helpers for |ComputeFontData| that need access to |mNoneBits|: 1.614 + static void SetFontSize(nsPresContext* aPresContext, 1.615 + const nsRuleData* aRuleData, 1.616 + const nsStyleFont* aFont, 1.617 + const nsStyleFont* aParentFont, 1.618 + nscoord* aSize, 1.619 + const nsFont& aSystemFont, 1.620 + nscoord aParentSize, 1.621 + nscoord aScriptLevelAdjustedParentSize, 1.622 + bool aUsedStartStruct, 1.623 + bool aAtRoot, 1.624 + bool& aCanStoreInRuleTree); 1.625 + 1.626 + static void SetFont(nsPresContext* aPresContext, 1.627 + nsStyleContext* aContext, 1.628 + uint8_t aGenericFontID, 1.629 + const nsRuleData* aRuleData, 1.630 + const nsStyleFont* aParentFont, 1.631 + nsStyleFont* aFont, 1.632 + bool aStartStruct, 1.633 + bool& aCanStoreInRuleTree); 1.634 + 1.635 + static void SetGenericFont(nsPresContext* aPresContext, 1.636 + nsStyleContext* aContext, 1.637 + uint8_t aGenericFontID, 1.638 + nsStyleFont* aFont); 1.639 + 1.640 + void AdjustLogicalBoxProp(nsStyleContext* aContext, 1.641 + const nsCSSValue& aLTRSource, 1.642 + const nsCSSValue& aRTLSource, 1.643 + const nsCSSValue& aLTRLogicalValue, 1.644 + const nsCSSValue& aRTLLogicalValue, 1.645 + mozilla::css::Side aSide, 1.646 + nsCSSRect& aValueRect, 1.647 + bool& aCanStoreInRuleTree); 1.648 + 1.649 + inline RuleDetail CheckSpecifiedProperties(const nsStyleStructID aSID, 1.650 + const nsRuleData* aRuleData); 1.651 + 1.652 + already_AddRefed<nsCSSShadowArray> 1.653 + GetShadowData(const nsCSSValueList* aList, 1.654 + nsStyleContext* aContext, 1.655 + bool aIsBoxShadow, 1.656 + bool& aCanStoreInRuleTree); 1.657 + bool SetStyleFilterToCSSValue(nsStyleFilter* aStyleFilter, 1.658 + const nsCSSValue& aValue, 1.659 + nsStyleContext* aStyleContext, 1.660 + nsPresContext* aPresContext, 1.661 + bool& aCanStoreInRuleTree); 1.662 + 1.663 +private: 1.664 + nsRuleNode(nsPresContext* aPresContext, nsRuleNode* aParent, 1.665 + nsIStyleRule* aRule, uint8_t aLevel, bool aIsImportant); 1.666 + ~nsRuleNode(); 1.667 + 1.668 +public: 1.669 + static nsRuleNode* CreateRootNode(nsPresContext* aPresContext); 1.670 + 1.671 + static void EnsureBlockDisplay(uint8_t& display, 1.672 + bool aConvertListItem = false); 1.673 + 1.674 + // Transition never returns null; on out of memory it'll just return |this|. 1.675 + nsRuleNode* Transition(nsIStyleRule* aRule, uint8_t aLevel, 1.676 + bool aIsImportantRule); 1.677 + nsRuleNode* GetParent() const { return mParent; } 1.678 + bool IsRoot() const { return mParent == nullptr; } 1.679 + 1.680 + // These uint8_ts are really nsStyleSet::sheetType values. 1.681 + uint8_t GetLevel() const { 1.682 + NS_ASSERTION(!IsRoot(), "can't call on root"); 1.683 + return (mDependentBits & NS_RULE_NODE_LEVEL_MASK) >> 1.684 + NS_RULE_NODE_LEVEL_SHIFT; 1.685 + } 1.686 + bool IsImportantRule() const { 1.687 + NS_ASSERTION(!IsRoot(), "can't call on root"); 1.688 + return (mDependentBits & NS_RULE_NODE_IS_IMPORTANT) != 0; 1.689 + } 1.690 + 1.691 + /** 1.692 + * Has this rule node at some time in its lifetime been the mRuleNode 1.693 + * of some style context (as opposed to only being the ancestor of 1.694 + * some style context's mRuleNode)? 1.695 + */ 1.696 + void SetUsedDirectly(); 1.697 + bool IsUsedDirectly() const { 1.698 + return (mDependentBits & NS_RULE_NODE_USED_DIRECTLY) != 0; 1.699 + } 1.700 + 1.701 + // NOTE: Does not |AddRef|. Null only for the root. 1.702 + nsIStyleRule* GetRule() const { return mRule; } 1.703 + // NOTE: Does not |AddRef|. Never null. 1.704 + nsPresContext* PresContext() const { return mPresContext; } 1.705 + 1.706 + const void* GetStyleData(nsStyleStructID aSID, 1.707 + nsStyleContext* aContext, 1.708 + bool aComputeData); 1.709 + 1.710 + #define STYLE_STRUCT(name_, checkdata_cb_) \ 1.711 + const nsStyle##name_* GetStyle##name_(nsStyleContext* aContext, \ 1.712 + bool aComputeData); 1.713 + #include "nsStyleStructList.h" 1.714 + #undef STYLE_STRUCT 1.715 + 1.716 + /* 1.717 + * Garbage collection. Mark walks up the tree, marking any unmarked 1.718 + * ancestors until it reaches a marked one. Sweep recursively sweeps 1.719 + * the children, destroys any that are unmarked, and clears marks, 1.720 + * returning true if the node on which it was called was destroyed. 1.721 + */ 1.722 + void Mark(); 1.723 + bool Sweep(); 1.724 + 1.725 + static bool 1.726 + HasAuthorSpecifiedRules(nsStyleContext* aStyleContext, 1.727 + uint32_t ruleTypeMask, 1.728 + bool aAuthorColorsAllowed); 1.729 + 1.730 + // Expose this so media queries can use it 1.731 + static nscoord CalcLengthWithInitialFont(nsPresContext* aPresContext, 1.732 + const nsCSSValue& aValue); 1.733 + // Expose this so nsTransformFunctions can use it. 1.734 + static nscoord CalcLength(const nsCSSValue& aValue, 1.735 + nsStyleContext* aStyleContext, 1.736 + nsPresContext* aPresContext, 1.737 + bool& aCanStoreInRuleTree); 1.738 + 1.739 + struct ComputedCalc { 1.740 + nscoord mLength; 1.741 + float mPercent; 1.742 + 1.743 + ComputedCalc(nscoord aLength, float aPercent) 1.744 + : mLength(aLength), mPercent(aPercent) {} 1.745 + }; 1.746 + static ComputedCalc 1.747 + SpecifiedCalcToComputedCalc(const nsCSSValue& aValue, 1.748 + nsStyleContext* aStyleContext, 1.749 + nsPresContext* aPresContext, 1.750 + bool& aCanStoreInRuleTree); 1.751 + 1.752 + // Compute the value of an nsStyleCoord that IsCalcUnit(). 1.753 + // (Values that don't require aPercentageBasis should be handled 1.754 + // inside nsRuleNode rather than through this API.) 1.755 + static nscoord ComputeComputedCalc(const nsStyleCoord& aCoord, 1.756 + nscoord aPercentageBasis); 1.757 + 1.758 + // Compute the value of an nsStyleCoord that is either a coord, a 1.759 + // percent, or a calc expression. 1.760 + static nscoord ComputeCoordPercentCalc(const nsStyleCoord& aCoord, 1.761 + nscoord aPercentageBasis); 1.762 + 1.763 + // Return whether the rule tree for which this node is the root has 1.764 + // cached data such that we need to do dynamic change handling for 1.765 + // changes that change the results of media queries or require 1.766 + // rebuilding all style data. 1.767 + bool TreeHasCachedData() const { 1.768 + NS_ASSERTION(IsRoot(), "should only be called on root of rule tree"); 1.769 + return HaveChildren() || mStyleData.mInheritedData || mStyleData.mResetData; 1.770 + } 1.771 + 1.772 + bool NodeHasCachedData(const nsStyleStructID aSID) { 1.773 + return !!mStyleData.GetStyleData(aSID); 1.774 + } 1.775 + 1.776 + static void ComputeFontFeatures(const nsCSSValuePairList *aFeaturesList, 1.777 + nsTArray<gfxFontFeature>& aFeatureSettings); 1.778 + 1.779 + static nscoord CalcFontPointSize(int32_t aHTMLSize, int32_t aBasePointSize, 1.780 + nsPresContext* aPresContext, 1.781 + nsFontSizeType aFontSizeType = eFontSize_HTML); 1.782 + 1.783 + static nscoord FindNextSmallerFontSize(nscoord aFontSize, int32_t aBasePointSize, 1.784 + nsPresContext* aPresContext, 1.785 + nsFontSizeType aFontSizeType = eFontSize_HTML); 1.786 + 1.787 + static nscoord FindNextLargerFontSize(nscoord aFontSize, int32_t aBasePointSize, 1.788 + nsPresContext* aPresContext, 1.789 + nsFontSizeType aFontSizeType = eFontSize_HTML); 1.790 + 1.791 + /** 1.792 + * @param aValue The color value, returned from nsCSSParser::ParseColorString 1.793 + * @param aPresContext Presentation context whose preferences are used 1.794 + * for certain enumerated colors 1.795 + * @param aStyleContext Style context whose color is used for 'currentColor' 1.796 + * 1.797 + * @note aPresContext and aStyleContext may be null, but in that case, fully 1.798 + * opaque black will be returned for the values that rely on these 1.799 + * objects to compute the color. (For example, -moz-hyperlinktext.) 1.800 + * 1.801 + * @return false if we fail to extract a color; this will not happen if both 1.802 + * aPresContext and aStyleContext are non-null 1.803 + */ 1.804 + static bool ComputeColor(const nsCSSValue& aValue, 1.805 + nsPresContext* aPresContext, 1.806 + nsStyleContext* aStyleContext, 1.807 + nscolor& aResult); 1.808 +}; 1.809 + 1.810 +#endif