CLOSED TREE: TraceMonkey merge head. (a=blockers)
[mozilla-central.git] / layout / style / nsRuleNode.h
blob299bc9dc4f4d50c747f21245534ac0d47a6e7c0a
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is Mozilla Communicator client code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
23 * Original Author: David W. Hyatt (hyatt@netscape.com)
24 * L. David Baron <dbaron@dbaron.org>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
41 * a node in the lexicographic tree of rules that match an element,
42 * responsible for converting the rules' information into computed style
45 #ifndef nsRuleNode_h___
46 #define nsRuleNode_h___
48 #include "nsPresContext.h"
49 #include "nsStyleStruct.h"
51 class nsStyleContext;
52 struct PLDHashTable;
53 class nsILanguageAtomService;
54 struct nsRuleData;
55 class nsIStyleRule;
56 struct nsCSSStruct;
57 struct nsCSSValueList;
58 // Copy of typedef that's in nsCSSStruct.h, for compilation speed.
59 typedef nsCSSStruct nsRuleDataStruct;
61 struct nsRuleDataFont;
62 class nsCSSValue;
63 struct nsCSSRect;
65 class nsStyleCoord;
67 struct nsInheritedStyleData
70 #define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
71 nsStyle##name * m##name##Data;
72 #define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args)
74 #include "nsStyleStructList.h"
76 #undef STYLE_STRUCT_INHERITED
77 #undef STYLE_STRUCT_RESET
79 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
80 return aContext->AllocateFromShell(sz);
83 void DestroyStructs(PRUint32 aBits, nsPresContext* aContext) {
84 #define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
85 if (m##name##Data && !(aBits & NS_STYLE_INHERIT_BIT(name))) \
86 m##name##Data->Destroy(aContext);
87 #define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args)
89 #include "nsStyleStructList.h"
91 #undef STYLE_STRUCT_INHERITED
92 #undef STYLE_STRUCT_RESET
95 void Destroy(PRUint32 aBits, nsPresContext* aContext) {
96 DestroyStructs(aBits, aContext);
97 aContext->FreeToShell(sizeof(nsInheritedStyleData), this);
100 nsInheritedStyleData() {
101 #define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
102 m##name##Data = nsnull;
103 #define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args)
105 #include "nsStyleStructList.h"
107 #undef STYLE_STRUCT_INHERITED
108 #undef STYLE_STRUCT_RESET
113 struct nsResetStyleData
115 nsResetStyleData()
117 #define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
118 m##name##Data = nsnull;
119 #define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args)
121 #include "nsStyleStructList.h"
123 #undef STYLE_STRUCT_RESET
124 #undef STYLE_STRUCT_INHERITED
127 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
128 return aContext->AllocateFromShell(sz);
131 void Destroy(PRUint32 aBits, nsPresContext* aContext) {
132 #define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
133 if (m##name##Data && !(aBits & NS_STYLE_INHERIT_BIT(name))) \
134 m##name##Data->Destroy(aContext);
135 #define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args)
137 #include "nsStyleStructList.h"
139 #undef STYLE_STRUCT_RESET
140 #undef STYLE_STRUCT_INHERITED
142 aContext->FreeToShell(sizeof(nsResetStyleData), this);
145 #define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
146 nsStyle##name * m##name##Data;
147 #define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args)
149 #include "nsStyleStructList.h"
151 #undef STYLE_STRUCT_RESET
152 #undef STYLE_STRUCT_INHERITED
156 struct nsCachedStyleData
158 struct StyleStructInfo {
159 ptrdiff_t mCachedStyleDataOffset;
160 ptrdiff_t mInheritResetOffset;
161 PRBool mIsReset;
164 static StyleStructInfo gInfo[];
166 nsInheritedStyleData* mInheritedData;
167 nsResetStyleData* mResetData;
169 static PRBool IsReset(const nsStyleStructID& aSID) {
170 return gInfo[aSID].mIsReset;
173 static PRUint32 GetBitForSID(const nsStyleStructID& aSID) {
174 return 1 << aSID;
177 void* NS_FASTCALL GetStyleData(const nsStyleStructID& aSID) {
178 // Each struct is stored at this.m##type##Data->m##name##Data where
179 // |type| is either Inherit or Reset, and |name| is the name of the
180 // style struct. The |gInfo| stores the offset of the appropriate
181 // m##type##Data for the struct within nsCachedStyleData (|this|)
182 // and the offset of the appropriate m##name##Data within the
183 // m##type##Data. Note that if we don't have any reset structs,
184 // then mResetData is null, and likewise for mInheritedData. This
185 // saves us from having to go through the long if-else cascade into
186 // which most compilers will turn a case statement.
188 // NOTE: nsStyleContext::SetStyle works roughly the same way.
190 const StyleStructInfo& info = gInfo[aSID];
192 // Get either &mInheritedData or &mResetData.
193 char* resetOrInheritSlot = reinterpret_cast<char*>(this) + info.mCachedStyleDataOffset;
195 // Get either mInheritedData or mResetData.
196 char* resetOrInherit = reinterpret_cast<char*>(*reinterpret_cast<void**>(resetOrInheritSlot));
198 void* data = nsnull;
199 if (resetOrInherit) {
200 // If we have the mInheritedData or mResetData, then we might have
201 // the struct, so get it.
202 char* dataSlot = resetOrInherit + info.mInheritResetOffset;
203 data = *reinterpret_cast<void**>(dataSlot);
205 return data;
208 // Typesafe and faster versions of the above
209 #define STYLE_STRUCT_INHERITED(name_, checkdata_cb_, ctor_args_) \
210 nsStyle##name_ * NS_FASTCALL GetStyle##name_ () { \
211 return mInheritedData ? mInheritedData->m##name_##Data : nsnull; \
213 #define STYLE_STRUCT_RESET(name_, checkdata_cb_, ctor_args_) \
214 nsStyle##name_ * NS_FASTCALL GetStyle##name_ () { \
215 return mResetData ? mResetData->m##name_##Data : nsnull; \
217 #include "nsStyleStructList.h"
218 #undef STYLE_STRUCT_RESET
219 #undef STYLE_STRUCT_INHERITED
221 void Destroy(PRUint32 aBits, nsPresContext* aContext) {
222 if (mResetData)
223 mResetData->Destroy(aBits, aContext);
224 if (mInheritedData)
225 mInheritedData->Destroy(aBits, aContext);
226 mResetData = nsnull;
227 mInheritedData = nsnull;
230 nsCachedStyleData() :mInheritedData(nsnull), mResetData(nsnull) {}
231 ~nsCachedStyleData() {}
235 * nsRuleNode is a node in a lexicographic tree (the "rule tree")
236 * indexed by style rules (implementations of nsIStyleRule).
238 * The rule tree is owned by the nsStyleSet and is destroyed when the
239 * presentation of the document goes away. It is garbage-collected
240 * (using mark-and-sweep garbage collection) during the lifetime of the
241 * document (when dynamic changes cause the destruction of enough style
242 * contexts). Rule nodes are marked if they are pointed to by a style
243 * context or one of their descendants is.
245 * An nsStyleContext, which represents the computed style data for an
246 * element, points to an nsRuleNode. The path from the root of the rule
247 * tree to the nsStyleContext's mRuleNode gives the list of the rules
248 * matched, from least important in the cascading order to most
249 * important in the cascading order.
251 * The reason for using a lexicographic tree is that it allows for
252 * sharing of style data, which saves both memory (for storing the
253 * computed style data) and time (for computing them). This sharing
254 * depends on the computed style data being stored in structs (nsStyle*)
255 * that contain only properties that are inherited by default
256 * ("inherited structs") or structs that contain only properties that
257 * are not inherited by default ("reset structs"). The optimization
258 * depends on the normal case being that style rules specify relatively
259 * few properties and even that elements generally have relatively few
260 * properties specified. This allows sharing in the following ways:
261 * 1. [mainly reset structs] When a style data struct will contain the
262 * same computed value for any elements that match the same set of
263 * rules (common for reset structs), it can be stored on the
264 * nsRuleNode instead of on the nsStyleContext.
265 * 2. [only? reset structs] When (1) occurs, and an nsRuleNode doesn't
266 * have any rules that change the values in the struct, the
267 * nsRuleNode can share that struct with its parent nsRuleNode.
268 * 3. [mainly inherited structs] When an element doesn't match any
269 * rules that change the value of a property (or, in the edge case,
270 * when all the values specified are 'inherit'), the nsStyleContext
271 * can use the same nsStyle* struct as its parent nsStyleContext.
273 * Since the data represented by an nsIStyleRule are immutable, the data
274 * represented by an nsRuleNode are also immutable.
277 class nsRuleNode {
278 public:
279 enum RuleDetail {
280 eRuleNone, // No props have been specified at all.
281 eRulePartialReset, // At least one prop with a non-"inherit" value
282 // has been specified. No props have been
283 // specified with an "inherit" value. At least
284 // one prop remains unspecified.
285 eRulePartialMixed, // At least one prop with a non-"inherit" value
286 // has been specified. Some props may also have
287 // been specified with an "inherit" value. At
288 // least one prop remains unspecified.
289 eRulePartialInherited, // Only props with "inherit" values have
290 // have been specified. At least one prop
291 // remains unspecified.
292 eRuleFullReset, // All props have been specified. None has an
293 // "inherit" value.
294 eRuleFullMixed, // All props have been specified. At least one has
295 // a non-"inherit" value.
296 eRuleFullInherited // All props have been specified with "inherit"
297 // values.
300 private:
301 nsPresContext* mPresContext; // Our pres context.
303 nsRuleNode* mParent; // A pointer to the parent node in the tree.
304 // This enables us to walk backwards from the
305 // most specific rule matched to the least
306 // specific rule (which is the optimal order to
307 // use for lookups of style properties.
308 nsIStyleRule* mRule; // [STRONG] A pointer to our specific rule.
310 nsRuleNode* mNextSibling; // This value should be used only by the
311 // parent, since the parent may store
312 // children in a hash, which means this
313 // pointer is not meaningful. Order of
314 // siblings is also not meaningful.
316 struct Key {
317 nsIStyleRule* mRule;
318 PRUint8 mLevel;
319 PRPackedBool mIsImportantRule;
321 Key(nsIStyleRule* aRule, PRUint8 aLevel, PRPackedBool aIsImportantRule)
322 : mRule(aRule), mLevel(aLevel), mIsImportantRule(aIsImportantRule)
325 PRBool operator==(const Key& aOther) const
327 return mRule == aOther.mRule &&
328 mLevel == aOther.mLevel &&
329 mIsImportantRule == aOther.mIsImportantRule;
332 PRBool operator!=(const Key& aOther) const
334 return !(*this == aOther);
338 static PLDHashNumber
339 ChildrenHashHashKey(PLDHashTable *aTable, const void *aKey);
341 static PRBool
342 ChildrenHashMatchEntry(PLDHashTable *aTable,
343 const PLDHashEntryHdr *aHdr,
344 const void *aKey);
346 static PLDHashTableOps ChildrenHashOps;
348 static PLDHashOperator
349 EnqueueRuleNodeChildren(PLDHashTable *table, PLDHashEntryHdr *hdr,
350 PRUint32 number, void *arg);
352 Key GetKey() const {
353 return Key(mRule, GetLevel(), IsImportantRule());
356 // The children of this node are stored in either a hashtable or list
357 // that maps from rules to our nsRuleNode children. When matching
358 // rules, we use this mapping to transition from node to node
359 // (constructing new nodes as needed to flesh out the tree).
361 union {
362 void* asVoid;
363 nsRuleNode* asList;
364 PLDHashTable* asHash;
365 } mChildren; // Accessed only through the methods below.
367 enum {
368 kTypeMask = 0x1,
369 kListType = 0x0,
370 kHashType = 0x1
372 enum {
373 // Maximum to have in a list before converting to a hashtable.
374 // XXX Need to optimize this.
375 kMaxChildrenInList = 32
378 PRBool HaveChildren() const {
379 return mChildren.asVoid != nsnull;
381 PRBool ChildrenAreHashed() {
382 return (PRWord(mChildren.asVoid) & kTypeMask) == kHashType;
384 nsRuleNode* ChildrenList() {
385 return mChildren.asList;
387 nsRuleNode** ChildrenListPtr() {
388 return &mChildren.asList;
390 PLDHashTable* ChildrenHash() {
391 return (PLDHashTable*) (PRWord(mChildren.asHash) & ~PRWord(kTypeMask));
393 void SetChildrenList(nsRuleNode *aList) {
394 NS_ASSERTION(!(PRWord(aList) & kTypeMask),
395 "pointer not 2-byte aligned");
396 mChildren.asList = aList;
398 void SetChildrenHash(PLDHashTable *aHashtable) {
399 NS_ASSERTION(!(PRWord(aHashtable) & kTypeMask),
400 "pointer not 2-byte aligned");
401 mChildren.asHash = (PLDHashTable*)(PRWord(aHashtable) | kHashType);
403 void ConvertChildrenToHash();
405 nsCachedStyleData mStyleData; // Any data we cached on the rule node.
407 PRUint32 mDependentBits; // Used to cache the fact that we can look up
408 // cached data under a parent rule.
410 PRUint32 mNoneBits; // Used to cache the fact that the branch to this
411 // node specifies no non-inherited data for a
412 // given struct type. (This usually implies that
413 // the entire branch specifies no non-inherited
414 // data, although not necessarily, if a
415 // non-inherited value is overridden by an
416 // explicit 'inherit' value.) For example, if an
417 // entire rule branch specifies no color
418 // information, then a bit will be set along every
419 // rule node on that branch, so that you can break
420 // out of the rule tree early and just inherit
421 // from the parent style context. The presence of
422 // this bit means we should just get inherited
423 // data from the parent style context, and it is
424 // never used for reset structs since their
425 // Compute*Data functions don't initialize from
426 // inherited data.
428 // Reference count. This just counts the style contexts that reference this
429 // rulenode. And children the rulenode has had. When this goes to 0 or
430 // stops being 0, we notify the style set.
431 // Note, in particular, that when a child is removed mRefCnt is NOT
432 // decremented. This is on purpose; the notifications to the style set are
433 // only used to determine when it's worth running GC on the ruletree, and
434 // this setup makes it so we only count unused ruletree leaves for purposes
435 // of deciding when to GC. We could more accurately count unused rulenodes
436 // by releasing/addrefing our parent when our refcount transitions to or from
437 // 0, but it doesn't seem worth it to do that.
438 PRUint32 mRefCnt;
440 public:
441 // Overloaded new operator. Initializes the memory to 0 and relies on an arena
442 // (which comes from the presShell) to perform the allocation.
443 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
444 void Destroy() { DestroyInternal(nsnull); }
445 static nsILanguageAtomService* gLangService;
447 // Implemented in nsStyleSet.h, since it needs to know about nsStyleSet.
448 inline void AddRef();
450 // Implemented in nsStyleSet.h, since it needs to know about nsStyleSet.
451 inline void Release();
453 protected:
454 void DestroyInternal(nsRuleNode ***aDestroyQueueTail);
455 void PropagateDependentBit(PRUint32 aBit, nsRuleNode* aHighestNode);
456 void PropagateNoneBit(PRUint32 aBit, nsRuleNode* aHighestNode);
458 const void* SetDefaultOnRoot(const nsStyleStructID aSID,
459 nsStyleContext* aContext);
461 const void*
462 WalkRuleTree(const nsStyleStructID aSID, nsStyleContext* aContext,
463 nsRuleData* aRuleData, nsRuleDataStruct* aSpecificData);
465 const void*
466 ComputeDisplayData(void* aStartStruct,
467 const nsRuleDataStruct& aData,
468 nsStyleContext* aContext, nsRuleNode* aHighestNode,
469 RuleDetail aRuleDetail,
470 const PRBool aCanStoreInRuleTree);
472 const void*
473 ComputeVisibilityData(void* aStartStruct,
474 const nsRuleDataStruct& aData,
475 nsStyleContext* aContext, nsRuleNode* aHighestNode,
476 RuleDetail aRuleDetail,
477 const PRBool aCanStoreInRuleTree);
479 const void*
480 ComputeFontData(void* aStartStruct,
481 const nsRuleDataStruct& aData,
482 nsStyleContext* aContext, nsRuleNode* aHighestNode,
483 RuleDetail aRuleDetail,
484 const PRBool aCanStoreInRuleTree);
486 const void*
487 ComputeColorData(void* aStartStruct,
488 const nsRuleDataStruct& aData,
489 nsStyleContext* aContext, nsRuleNode* aHighestNode,
490 RuleDetail aRuleDetail,
491 const PRBool aCanStoreInRuleTree);
493 const void*
494 ComputeBackgroundData(void* aStartStruct,
495 const nsRuleDataStruct& aData,
496 nsStyleContext* aContext, nsRuleNode* aHighestNode,
497 RuleDetail aRuleDetail,
498 const PRBool aCanStoreInRuleTree);
500 const void*
501 ComputeMarginData(void* aStartStruct,
502 const nsRuleDataStruct& aData,
503 nsStyleContext* aContext, nsRuleNode* aHighestNode,
504 RuleDetail aRuleDetail,
505 const PRBool aCanStoreInRuleTree);
507 const void*
508 ComputeBorderData(void* aStartStruct,
509 const nsRuleDataStruct& aData,
510 nsStyleContext* aContext, nsRuleNode* aHighestNode,
511 RuleDetail aRuleDetail,
512 const PRBool aCanStoreInRuleTree);
514 const void*
515 ComputePaddingData(void* aStartStruct,
516 const nsRuleDataStruct& aData,
517 nsStyleContext* aContext, nsRuleNode* aHighestNode,
518 RuleDetail aRuleDetail,
519 const PRBool aCanStoreInRuleTree);
521 const void*
522 ComputeOutlineData(void* aStartStruct,
523 const nsRuleDataStruct& aData,
524 nsStyleContext* aContext, nsRuleNode* aHighestNode,
525 RuleDetail aRuleDetail,
526 const PRBool aCanStoreInRuleTree);
528 const void*
529 ComputeListData(void* aStartStruct,
530 const nsRuleDataStruct& aData,
531 nsStyleContext* aContext, nsRuleNode* aHighestNode,
532 RuleDetail aRuleDetail,
533 const PRBool aCanStoreInRuleTree);
535 const void*
536 ComputePositionData(void* aStartStruct,
537 const nsRuleDataStruct& aData,
538 nsStyleContext* aContext, nsRuleNode* aHighestNode,
539 RuleDetail aRuleDetail,
540 const PRBool aCanStoreInRuleTree);
542 const void*
543 ComputeTableData(void* aStartStruct,
544 const nsRuleDataStruct& aData,
545 nsStyleContext* aContext, nsRuleNode* aHighestNode,
546 RuleDetail aRuleDetail,
547 const PRBool aCanStoreInRuleTree);
549 const void*
550 ComputeTableBorderData(void* aStartStruct,
551 const nsRuleDataStruct& aData,
552 nsStyleContext* aContext, nsRuleNode* aHighestNode,
553 RuleDetail aRuleDetail,
554 const PRBool aCanStoreInRuleTree);
556 const void*
557 ComputeContentData(void* aStartStruct,
558 const nsRuleDataStruct& aData,
559 nsStyleContext* aContext, nsRuleNode* aHighestNode,
560 RuleDetail aRuleDetail,
561 const PRBool aCanStoreInRuleTree);
563 const void*
564 ComputeQuotesData(void* aStartStruct,
565 const nsRuleDataStruct& aData,
566 nsStyleContext* aContext, nsRuleNode* aHighestNode,
567 RuleDetail aRuleDetail,
568 const PRBool aCanStoreInRuleTree);
570 const void*
571 ComputeTextData(void* aStartStruct,
572 const nsRuleDataStruct& aData,
573 nsStyleContext* aContext, nsRuleNode* aHighestNode,
574 RuleDetail aRuleDetail,
575 const PRBool aCanStoreInRuleTree);
577 const void*
578 ComputeTextResetData(void* aStartStruct,
579 const nsRuleDataStruct& aData,
580 nsStyleContext* aContext, nsRuleNode* aHighestNode,
581 RuleDetail aRuleDetail,
582 const PRBool aCanStoreInRuleTree);
584 const void*
585 ComputeUserInterfaceData(void* aStartStruct,
586 const nsRuleDataStruct& aData,
587 nsStyleContext* aContext,
588 nsRuleNode* aHighestNode,
589 RuleDetail aRuleDetail,
590 const PRBool aCanStoreInRuleTree);
592 const void*
593 ComputeUIResetData(void* aStartStruct,
594 const nsRuleDataStruct& aData,
595 nsStyleContext* aContext, nsRuleNode* aHighestNode,
596 RuleDetail aRuleDetail,
597 const PRBool aCanStoreInRuleTree);
599 const void*
600 ComputeXULData(void* aStartStruct,
601 const nsRuleDataStruct& aData,
602 nsStyleContext* aContext, nsRuleNode* aHighestNode,
603 RuleDetail aRuleDetail,
604 const PRBool aCanStoreInRuleTree);
606 const void*
607 ComputeColumnData(void* aStartStruct,
608 const nsRuleDataStruct& aData,
609 nsStyleContext* aContext, nsRuleNode* aHighestNode,
610 RuleDetail aRuleDetail,
611 const PRBool aCanStoreInRuleTree);
613 const void*
614 ComputeSVGData(void* aStartStruct,
615 const nsRuleDataStruct& aData,
616 nsStyleContext* aContext, nsRuleNode* aHighestNode,
617 RuleDetail aRuleDetail,
618 const PRBool aCanStoreInRuleTree);
620 const void*
621 ComputeSVGResetData(void* aStartStruct,
622 const nsRuleDataStruct& aData,
623 nsStyleContext* aContext, nsRuleNode* aHighestNode,
624 RuleDetail aRuleDetail,
625 const PRBool aCanStoreInRuleTree);
627 // helpers for |ComputeFontData| that need access to |mNoneBits|:
628 static void SetFontSize(nsPresContext* aPresContext,
629 const nsRuleDataFont& aFontData,
630 const nsStyleFont* aFont,
631 const nsStyleFont* aParentFont,
632 nscoord* aSize,
633 const nsFont& aSystemFont,
634 nscoord aParentSize,
635 nscoord aScriptLevelAdjustedParentSize,
636 PRBool aUsedStartStruct,
637 PRBool aAtRoot,
638 PRBool& aCanStoreInRuleTree);
640 static void SetFont(nsPresContext* aPresContext,
641 nsStyleContext* aContext,
642 nscoord aMinFontSize,
643 PRUint8 aGenericFontID,
644 const nsRuleDataFont& aFontData,
645 const nsStyleFont* aParentFont,
646 nsStyleFont* aFont,
647 PRBool aStartStruct,
648 PRBool& aCanStoreInRuleTree);
650 static void SetGenericFont(nsPresContext* aPresContext,
651 nsStyleContext* aContext,
652 PRUint8 aGenericFontID,
653 nscoord aMinFontSize,
654 nsStyleFont* aFont);
656 void AdjustLogicalBoxProp(nsStyleContext* aContext,
657 const nsCSSValue& aLTRSource,
658 const nsCSSValue& aRTLSource,
659 const nsCSSValue& aLTRLogicalValue,
660 const nsCSSValue& aRTLLogicalValue,
661 mozilla::css::Side aSide,
662 nsCSSRect& aValueRect,
663 PRBool& aCanStoreInRuleTree);
665 inline RuleDetail CheckSpecifiedProperties(const nsStyleStructID aSID, const nsRuleDataStruct& aRuleDataStruct);
667 const void* GetParentData(const nsStyleStructID aSID);
668 #define STYLE_STRUCT(name_, checkdata_cb_, ctor_args_) \
669 const nsStyle##name_* GetParent##name_();
670 #include "nsStyleStructList.h"
671 #undef STYLE_STRUCT
673 const void* GetDisplayData(nsStyleContext* aContext);
674 const void* GetVisibilityData(nsStyleContext* aContext);
675 const void* GetFontData(nsStyleContext* aContext);
676 const void* GetColorData(nsStyleContext* aContext);
677 const void* GetBackgroundData(nsStyleContext* aContext);
678 const void* GetMarginData(nsStyleContext* aContext);
679 const void* GetBorderData(nsStyleContext* aContext);
680 const void* GetPaddingData(nsStyleContext* aContext);
681 const void* GetOutlineData(nsStyleContext* aContext);
682 const void* GetListData(nsStyleContext* aContext);
683 const void* GetPositionData(nsStyleContext* aContext);
684 const void* GetTableData(nsStyleContext* aContext);
685 const void* GetTableBorderData(nsStyleContext* aContext);
687 const void* GetContentData(nsStyleContext* aContext);
688 const void* GetQuotesData(nsStyleContext* aContext);
689 const void* GetTextData(nsStyleContext* aContext);
690 const void* GetTextResetData(nsStyleContext* aContext);
691 const void* GetUserInterfaceData(nsStyleContext* aContext);
693 const void* GetUIResetData(nsStyleContext* aContext);
694 const void* GetXULData(nsStyleContext* aContext);
695 const void* GetColumnData(nsStyleContext* aContext);
696 const void* GetSVGData(nsStyleContext* aContext);
697 const void* GetSVGResetData(nsStyleContext* aContext);
699 already_AddRefed<nsCSSShadowArray>
700 GetShadowData(const nsCSSValueList* aList,
701 nsStyleContext* aContext,
702 PRBool aIsBoxShadow,
703 PRBool& inherited);
705 private:
706 nsRuleNode(nsPresContext* aPresContext, nsRuleNode* aParent,
707 nsIStyleRule* aRule, PRUint8 aLevel, PRBool aIsImportant);
708 ~nsRuleNode();
710 public:
711 static nsRuleNode* CreateRootNode(nsPresContext* aPresContext);
713 // Transition never returns null; on out of memory it'll just return |this|.
714 nsRuleNode* Transition(nsIStyleRule* aRule, PRUint8 aLevel,
715 PRPackedBool aIsImportantRule);
716 nsRuleNode* GetParent() const { return mParent; }
717 PRBool IsRoot() const { return mParent == nsnull; }
719 // These PRUint8s are really nsStyleSet::sheetType values.
720 PRUint8 GetLevel() const {
721 NS_ASSERTION(!IsRoot(), "can't call on root");
722 return (mDependentBits & NS_RULE_NODE_LEVEL_MASK) >>
723 NS_RULE_NODE_LEVEL_SHIFT;
725 PRBool IsImportantRule() const {
726 NS_ASSERTION(!IsRoot(), "can't call on root");
727 return (mDependentBits & NS_RULE_NODE_IS_IMPORTANT) != 0;
730 // NOTE: Does not |AddRef|.
731 nsIStyleRule* GetRule() const { return mRule; }
732 // NOTE: Does not |AddRef|.
733 nsPresContext* GetPresContext() const { return mPresContext; }
735 const void* GetStyleData(nsStyleStructID aSID,
736 nsStyleContext* aContext,
737 PRBool aComputeData);
739 #define STYLE_STRUCT(name_, checkdata_cb_, ctor_args_) \
740 const nsStyle##name_* GetStyle##name_(nsStyleContext* aContext, \
741 PRBool aComputeData);
742 #include "nsStyleStructList.h"
743 #undef STYLE_STRUCT
746 * Garbage collection. Mark walks up the tree, marking any unmarked
747 * ancestors until it reaches a marked one. Sweep recursively sweeps
748 * the children, destroys any that are unmarked, and clears marks,
749 * returning true if the node on which it was called was destroyed.
751 void Mark();
752 PRBool Sweep();
754 static PRBool
755 HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
756 PRUint32 ruleTypeMask,
757 PRBool aAuthorColorsAllowed);
759 // Expose this so media queries can use it
760 static nscoord CalcLengthWithInitialFont(nsPresContext* aPresContext,
761 const nsCSSValue& aValue);
762 // Expose this so nsTransformFunctions can use it.
763 static nscoord CalcLength(const nsCSSValue& aValue,
764 nsStyleContext* aStyleContext,
765 nsPresContext* aPresContext,
766 PRBool& aCanStoreInRuleTree);
768 struct ComputedCalc {
769 nscoord mLength;
770 float mPercent;
772 ComputedCalc(nscoord aLength, float aPercent)
773 : mLength(aLength), mPercent(aPercent) {}
775 static ComputedCalc
776 SpecifiedCalcToComputedCalc(const nsCSSValue& aValue,
777 nsStyleContext* aStyleContext,
778 nsPresContext* aPresContext,
779 PRBool& aCanStoreInRuleTree);
781 // Compute the value of an nsStyleCoord that IsCalcUnit().
782 // (Values that don't require aPercentageBasis should be handled
783 // inside nsRuleNode rather than through this API.)
784 static nscoord ComputeComputedCalc(const nsStyleCoord& aCoord,
785 nscoord aPercentageBasis);
787 // Compute the value of an nsStyleCoord that is either a coord, a
788 // percent, or a calc expression.
789 static nscoord ComputeCoordPercentCalc(const nsStyleCoord& aCoord,
790 nscoord aPercentageBasis);
792 // Return whether the rule tree for which this node is the root has
793 // cached data such that we need to do dynamic change handling for
794 // changes that change the results of media queries or require
795 // rebuilding all style data.
796 PRBool TreeHasCachedData() const {
797 NS_ASSERTION(IsRoot(), "should only be called on root of rule tree");
798 return HaveChildren() || mStyleData.mInheritedData || mStyleData.mResetData;
802 #endif