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
15 * The Original Code is mozilla.org 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.
23 * David Hyatt <hyatt@netscape.com>
24 * Pierre Phaneuf <pp@ludusdesign.com>
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 ***** */
40 /* the interface (to internal code) for retrieving computed style data */
42 #include "nsStyleConsts.h"
44 #include "nsPresContext.h"
45 #include "nsIStyleRule.h"
49 #include "nsStyleSet.h"
50 #include "nsIPresShell.h"
53 #include "nsRuleNode.h"
54 #include "nsStyleContext.h"
55 #include "imgIRequest.h"
57 #include "nsPrintfCString.h"
60 // #define NOISY_DEBUG
63 //----------------------------------------------------------------------
66 nsStyleContext::nsStyleContext(nsStyleContext
* aParent
,
68 nsRuleNode
* aRuleNode
,
69 nsPresContext
* aPresContext
)
73 mPseudoTag(aPseudoTag
),
82 mParent
->AddChild(this);
85 ApplyStyleFixups(aPresContext
);
87 #define eStyleStruct_LastItem (nsStyleStructID_Length - 1)
88 NS_ASSERTION(NS_STYLE_INHERIT_MASK
& NS_STYLE_INHERIT_BIT(LastItem
),
89 "NS_STYLE_INHERIT_MASK must be bigger, and other bits shifted");
90 #undef eStyleStruct_LastItem
93 nsStyleContext::~nsStyleContext()
95 NS_ASSERTION((nsnull
== mChild
) && (nsnull
== mEmptyChild
), "destructing context with children");
97 nsPresContext
*presContext
= mRuleNode
->GetPresContext();
99 presContext
->PresShell()->StyleSet()->
100 NotifyStyleContextDestroyed(presContext
, this);
103 mParent
->RemoveChild(this);
107 // Free up our data structs.
108 if (mCachedStyleData
.mResetData
|| mCachedStyleData
.mInheritedData
) {
109 mCachedStyleData
.Destroy(mBits
, presContext
);
113 void nsStyleContext::AddChild(nsStyleContext
* aChild
)
115 NS_ASSERTION(aChild
->mPrevSibling
== aChild
&&
116 aChild
->mNextSibling
== aChild
,
117 "child already in a child list");
119 nsStyleContext
**list
= aChild
->mRuleNode
->IsRoot() ? &mEmptyChild
: &mChild
;
121 // Insert at the beginning of the list. See also FindChildWithRules.
123 // Link into existing elements, if there are any.
124 aChild
->mNextSibling
= (*list
);
125 aChild
->mPrevSibling
= (*list
)->mPrevSibling
;
126 (*list
)->mPrevSibling
->mNextSibling
= aChild
;
127 (*list
)->mPrevSibling
= aChild
;
132 void nsStyleContext::RemoveChild(nsStyleContext
* aChild
)
134 NS_PRECONDITION(nsnull
!= aChild
&& this == aChild
->mParent
, "bad argument");
136 nsStyleContext
**list
= aChild
->mRuleNode
->IsRoot() ? &mEmptyChild
: &mChild
;
138 if (aChild
->mPrevSibling
!= aChild
) { // has siblings
139 if ((*list
) == aChild
) {
140 (*list
) = (*list
)->mNextSibling
;
144 NS_ASSERTION((*list
) == aChild
, "bad sibling pointers");
148 aChild
->mPrevSibling
->mNextSibling
= aChild
->mNextSibling
;
149 aChild
->mNextSibling
->mPrevSibling
= aChild
->mPrevSibling
;
150 aChild
->mNextSibling
= aChild
;
151 aChild
->mPrevSibling
= aChild
;
154 already_AddRefed
<nsStyleContext
>
155 nsStyleContext::FindChildWithRules(const nsIAtom
* aPseudoTag
,
156 nsRuleNode
* aRuleNode
)
158 PRUint32 threshold
= 10; // The # of siblings we're willing to examine
159 // before just giving this whole thing up.
161 nsStyleContext
* result
= nsnull
;
162 nsStyleContext
*list
= aRuleNode
->IsRoot() ? mEmptyChild
: mChild
;
165 nsStyleContext
*child
= list
;
167 if (child
->mRuleNode
== aRuleNode
&& child
->mPseudoTag
== aPseudoTag
) {
171 child
= child
->mNextSibling
;
175 } while (child
!= list
);
179 if (result
!= list
) {
180 // Move result to the front of the list.
185 // Add reference for the caller.
193 PRBool
nsStyleContext::Equals(const nsStyleContext
* aOther
) const
195 PRBool result
= PR_TRUE
;
196 const nsStyleContext
* other
= (nsStyleContext
*)aOther
;
199 if (mParent
!= other
->mParent
) {
202 else if (mBits
!= other
->mBits
) {
205 else if (mPseudoTag
!= other
->mPseudoTag
) {
208 else if (mRuleNode
!= other
->mRuleNode
) {
215 //=========================================================================================================
217 const void* nsStyleContext::GetStyleData(nsStyleStructID aSID
)
219 const void* cachedData
= mCachedStyleData
.GetStyleData(aSID
);
221 return cachedData
; // We have computed data stored on this node in the context tree.
222 return mRuleNode
->GetStyleData(aSID
, this, PR_TRUE
); // Our rule node will take care of it for us.
225 #define STYLE_STRUCT(name_, checkdata_cb_, ctor_args_) \
226 const nsStyle##name_ * nsStyleContext::GetStyle##name_ () \
228 const nsStyle##name_ * cachedData = mCachedStyleData.GetStyle##name_(); \
230 return cachedData; /* We have computed data stored on this node */ \
231 /* in the context tree. */ \
232 /* Else our rule node will take care of it for us. */ \
233 return mRuleNode->GetStyle##name_(this, PR_TRUE); \
235 #include "nsStyleStructList.h"
238 const void* nsStyleContext::PeekStyleData(nsStyleStructID aSID
)
240 const void* cachedData
= mCachedStyleData
.GetStyleData(aSID
);
242 return cachedData
; // We have computed data stored on this node in the context tree.
243 return mRuleNode
->GetStyleData(aSID
, this, PR_FALSE
); // Our rule node will take care of it for us.
246 // This is an evil evil function, since it forces you to alloc your own separate copy of
247 // style data! Do not use this function unless you absolutely have to! You should avoid
248 // this at all costs! -dwh
250 nsStyleContext::GetUniqueStyleData(const nsStyleStructID
& aSID
)
252 // If we already own the struct and no kids could depend on it, then
253 // just return it. (We leak in this case if there are kids -- and this
254 // function really shouldn't be called for style contexts that could
255 // have kids depending on the data. ClearStyleData would be OK, but
256 // this test for no mChild or mEmptyChild doesn't catch that case.)
257 const void *current
= GetStyleData(aSID
);
258 if (!mChild
&& !mEmptyChild
&&
259 !(mBits
& nsCachedStyleData::GetBitForSID(aSID
)) &&
260 mCachedStyleData
.GetStyleData(aSID
))
261 return const_cast<void*>(current
);
264 nsPresContext
*presContext
= PresContext();
267 #define UNIQUE_CASE(c_) \
268 case eStyleStruct_##c_: \
269 result = new (presContext) nsStyle##c_( \
270 * static_cast<const nsStyle##c_ *>(current)); \
274 UNIQUE_CASE(Background
)
276 UNIQUE_CASE(TextReset
)
281 NS_ERROR("Struct type not supported. Please find another way to do this if you can!\n");
286 NS_WARNING("Ran out of memory while trying to allocate memory for a unique style struct! "
287 "Returning the non-unique data.");
288 return const_cast<void*>(current
);
291 SetStyle(aSID
, result
);
292 mBits
&= ~nsCachedStyleData::GetBitForSID(aSID
);
298 nsStyleContext::SetStyle(nsStyleStructID aSID
, void* aStruct
)
300 // This method should only be called from nsRuleNode! It is not a public
303 NS_ASSERTION(aSID
>= 0 && aSID
< nsStyleStructID_Length
, "out of bounds");
305 // NOTE: nsCachedStyleData::GetStyleData works roughly the same way.
306 // See the comments there (in nsRuleNode.h) for more details about
307 // what this is doing and why.
309 const nsCachedStyleData::StyleStructInfo
& info
=
310 nsCachedStyleData::gInfo
[aSID
];
311 char* resetOrInheritSlot
= reinterpret_cast<char*>(&mCachedStyleData
) +
312 info
.mCachedStyleDataOffset
;
313 char* resetOrInherit
= reinterpret_cast<char*>
314 (*reinterpret_cast<void**>(resetOrInheritSlot
));
315 if (!resetOrInherit
) {
316 nsPresContext
*presContext
= mRuleNode
->GetPresContext();
317 if (mCachedStyleData
.IsReset(aSID
)) {
318 mCachedStyleData
.mResetData
= new (presContext
) nsResetStyleData
;
319 resetOrInherit
= reinterpret_cast<char*>(mCachedStyleData
.mResetData
);
321 mCachedStyleData
.mInheritedData
=
322 new (presContext
) nsInheritedStyleData
;
324 reinterpret_cast<char*>(mCachedStyleData
.mInheritedData
);
327 char* dataSlot
= resetOrInherit
+ info
.mInheritResetOffset
;
328 *reinterpret_cast<void**>(dataSlot
) = aStruct
;
332 nsStyleContext::ApplyStyleFixups(nsPresContext
* aPresContext
)
334 // See if we have any text decorations.
335 // First see if our parent has text decorations. If our parent does, then we inherit the bit.
336 if (mParent
&& mParent
->HasTextDecorations())
337 mBits
|= NS_STYLE_HAS_TEXT_DECORATIONS
;
339 // We might have defined a decoration.
340 const nsStyleTextReset
* text
= GetStyleTextReset();
341 if (text
->mTextDecoration
!= NS_STYLE_TEXT_DECORATION_NONE
&&
342 text
->mTextDecoration
!= NS_STYLE_TEXT_DECORATION_OVERRIDE_ALL
)
343 mBits
|= NS_STYLE_HAS_TEXT_DECORATIONS
;
347 const nsStyleDisplay
* disp
= GetStyleDisplay();
348 if (disp
->mDisplay
== NS_STYLE_DISPLAY_TABLE
) {
349 // -moz-center and -moz-right are used for HTML's alignment
350 // This is covering the <div align="right"><table>...</table></div> case.
351 // In this case, we don't want to inherit the text alignment into the table.
352 const nsStyleText
* text
= GetStyleText();
354 if (text
->mTextAlign
== NS_STYLE_TEXT_ALIGN_MOZ_CENTER
||
355 text
->mTextAlign
== NS_STYLE_TEXT_ALIGN_MOZ_RIGHT
)
357 nsStyleText
* uniqueText
= (nsStyleText
*)GetUniqueStyleData(eStyleStruct_Text
);
358 uniqueText
->mTextAlign
= NS_STYLE_TEXT_ALIGN_DEFAULT
;
362 // CSS2.1 section 9.2.4 specifies fixups for the 'display' property of
363 // the root element. We can't implement them in nsRuleNode because we
364 // don't want to store all display structs that aren't 'block',
365 // 'inline', or 'table' in the style context tree on the off chance
366 // that the root element has its style reresolved later. So do them
367 // here if needed, by changing the style data, so that other code
368 // doesn't get confused by looking at the style data.
370 if (disp
->mDisplay
!= NS_STYLE_DISPLAY_NONE
&&
371 disp
->mDisplay
!= NS_STYLE_DISPLAY_BLOCK
&&
372 disp
->mDisplay
!= NS_STYLE_DISPLAY_TABLE
) {
373 nsStyleDisplay
*mutable_display
= static_cast<nsStyleDisplay
*>
374 (GetUniqueStyleData(eStyleStruct_Display
));
375 if (mutable_display
->mDisplay
== NS_STYLE_DISPLAY_INLINE_TABLE
)
376 mutable_display
->mDisplay
= NS_STYLE_DISPLAY_TABLE
;
378 mutable_display
->mDisplay
= NS_STYLE_DISPLAY_BLOCK
;
382 // Computer User Interface style, to trigger loads of cursors
383 GetStyleUserInterface();
387 nsStyleContext::CalcStyleDifference(nsStyleContext
* aOther
)
389 nsChangeHint hint
= NS_STYLE_HINT_NONE
;
390 NS_ENSURE_TRUE(aOther
, hint
);
391 // We must always ensure that we populate the structs on the new style
392 // context that are filled in on the old context, so that if we get
393 // two style changes in succession, the second of which causes a real
394 // style change, the PeekStyleData doesn't return null (implying that
395 // nobody ever looked at that struct's data). In other words, we
396 // can't skip later structs if we get a big change up front, because
397 // we could later get a small change in one of those structs that we
398 // don't want to miss.
400 // If our rule nodes are the same, then we are looking at the same
401 // style data. We know this because CalcStyleDifference is always
402 // called on two style contexts that point to the same element, so we
403 // know that our position in the style context tree is the same and
404 // our position in the rule node tree is also the same.
405 PRBool compare
= mRuleNode
!= aOther
->mRuleNode
;
407 nsChangeHint maxHint
= nsChangeHint(NS_STYLE_HINT_FRAMECHANGE
|
408 nsChangeHint_UpdateCursor
);
410 #define DO_STRUCT_DIFFERENCE(struct_) \
412 NS_ASSERTION(NS_IsHintSubset(nsStyle##struct_::MaxDifference(), maxHint), \
413 "Struct placed in the wrong maxHint section"); \
414 const nsStyle##struct_* this##struct_ = \
415 static_cast<const nsStyle##struct_*>( \
416 PeekStyleData(eStyleStruct_##struct_)); \
417 if (this##struct_) { \
418 const nsStyle##struct_* other##struct_ = aOther->GetStyle##struct_(); \
420 !NS_IsHintSubset(maxHint, hint) && \
421 this##struct_ != other##struct_) { \
422 NS_ASSERTION(NS_IsHintSubset( \
423 this##struct_->CalcDifference(*other##struct_), \
424 nsStyle##struct_::MaxDifference()), \
425 "CalcDifference() returned bigger hint than MaxDifference()"); \
426 NS_UpdateHint(hint, this##struct_->CalcDifference(*other##struct_)); \
431 // We begin by examining those style structs that are capable of
432 // causing the maximal difference, a FRAMECHANGE.
433 // FRAMECHANGE Structs: Display, XUL, Content, UserInterface,
434 // Visibility, Outline, TableBorder, Table, UIReset, Quotes
435 DO_STRUCT_DIFFERENCE(Display
);
436 DO_STRUCT_DIFFERENCE(XUL
);
437 DO_STRUCT_DIFFERENCE(Column
);
438 DO_STRUCT_DIFFERENCE(Content
);
439 DO_STRUCT_DIFFERENCE(UserInterface
);
440 DO_STRUCT_DIFFERENCE(Visibility
);
441 DO_STRUCT_DIFFERENCE(Outline
);
442 DO_STRUCT_DIFFERENCE(TableBorder
);
443 DO_STRUCT_DIFFERENCE(Table
);
444 DO_STRUCT_DIFFERENCE(UIReset
);
445 DO_STRUCT_DIFFERENCE(List
);
446 // If the quotes implementation is ever going to change we might not need
447 // a framechange here and a reflow should be sufficient. See bug 35768.
448 DO_STRUCT_DIFFERENCE(Quotes
);
451 maxHint
= nsChangeHint(NS_STYLE_HINT_REFLOW
| nsChangeHint_UpdateEffects
);
452 DO_STRUCT_DIFFERENCE(SVGReset
);
453 DO_STRUCT_DIFFERENCE(SVG
);
456 // At this point, we know that the worst kind of damage we could do is
458 maxHint
= NS_STYLE_HINT_REFLOW
;
460 // The following structs cause (as their maximal difference) a reflow
461 // to occur. REFLOW Structs: Font, Margin, Padding, Border, List,
462 // Position, Text, TextReset
463 DO_STRUCT_DIFFERENCE(Font
);
464 DO_STRUCT_DIFFERENCE(Margin
);
465 DO_STRUCT_DIFFERENCE(Padding
);
466 DO_STRUCT_DIFFERENCE(Border
);
467 DO_STRUCT_DIFFERENCE(Position
);
468 DO_STRUCT_DIFFERENCE(Text
);
469 DO_STRUCT_DIFFERENCE(TextReset
);
471 // At this point, we know that the worst kind of damage we could do is
472 // a re-render (i.e., a VISUAL change).
473 maxHint
= NS_STYLE_HINT_VISUAL
;
475 // The following structs cause (as their maximal difference) a
476 // re-render to occur. VISUAL Structs: Color, Background
477 DO_STRUCT_DIFFERENCE(Color
);
478 DO_STRUCT_DIFFERENCE(Background
);
480 #undef DO_STRUCT_DIFFERENCE
486 nsStyleContext::Mark()
488 // Mark our rule node.
491 // Mark our children (i.e., tell them to mark their rule nodes, etc.).
493 nsStyleContext
* child
= mChild
;
496 child
= child
->mNextSibling
;
497 } while (mChild
!= child
);
501 nsStyleContext
* child
= mEmptyChild
;
504 child
= child
->mNextSibling
;
505 } while (mEmptyChild
!= child
);
511 class URICString
: public nsCAutoString
{
513 URICString(nsIURI
* aURI
) {
515 aURI
->GetSpec(*this);
521 URICString(imgIRequest
* aImageRequest
) {
522 nsCOMPtr
<nsIURI
> uri
;
524 aImageRequest
->GetURI(getter_AddRefs(uri
));
533 URICString(nsCSSValue::URL
* aURI
) {
535 NS_ASSERTION(aURI
->mURI
, "Must have URI here!");
536 aURI
->mURI
->GetSpec(*this);
542 URICString
& operator=(const URICString
& aOther
) {
548 void nsStyleContext::List(FILE* out
, PRInt32 aIndent
)
552 for (ix
= aIndent
; --ix
>= 0; ) fputs(" ", out
);
553 fprintf(out
, "%p(%d) parent=%p ",
554 (void*)this, mRefCnt
, (void *)mParent
);
557 mPseudoTag
->ToString(buffer
);
558 fputs(NS_LossyConvertUTF16toASCII(buffer
).get(), out
);
564 nsRuleNode
* ruleNode
= mRuleNode
;
566 nsIStyleRule
*styleRule
= ruleNode
->GetRule();
568 styleRule
->List(out
, aIndent
+ 1);
570 ruleNode
= ruleNode
->GetParent();
572 for (ix
= aIndent
; --ix
>= 0; ) fputs(" ", out
);
579 if (nsnull
!= mChild
) {
580 nsStyleContext
* child
= mChild
;
582 child
->List(out
, aIndent
+ 1);
583 child
= child
->mNextSibling
;
584 } while (mChild
!= child
);
586 if (nsnull
!= mEmptyChild
) {
587 nsStyleContext
* child
= mEmptyChild
;
589 child
->List(out
, aIndent
+ 1);
590 child
= child
->mNextSibling
;
591 } while (mEmptyChild
!= child
);
595 static void IndentBy(FILE* out
, PRInt32 aIndent
) {
596 while (--aIndent
>= 0) fputs(" ", out
);
599 void nsStyleContext::DumpRegressionData(nsPresContext
* aPresContext
, FILE* out
, PRInt32 aIndent
)
604 IndentBy(out
,aIndent
);
605 const nsStyleFont
* font
= GetStyleFont();
606 fprintf(out
, "<font %s %d %d %d />\n",
607 NS_ConvertUTF16toUTF8(font
->mFont
.name
).get(),
613 IndentBy(out
,aIndent
);
614 const nsStyleColor
* color
= GetStyleColor();
615 fprintf(out
, "<color data=\"%ld\"/>\n",
616 (long)color
->mColor
);
619 IndentBy(out
,aIndent
);
620 const nsStyleBackground
* bg
= GetStyleBackground();
621 fprintf(out
, "<background data=\"%d %d %d %ld %ld %ld %s\"/>\n",
622 (int)bg
->mBackgroundAttachment
,
623 (int)bg
->mBackgroundFlags
,
624 (int)bg
->mBackgroundRepeat
,
625 (long)bg
->mBackgroundColor
,
626 // XXX These aren't initialized unless flags are set:
627 (long)bg
->mBackgroundXPosition
.mCoord
, // potentially lossy on some platforms
628 (long)bg
->mBackgroundYPosition
.mCoord
, // potentially lossy on some platforms
629 URICString(bg
->mBackgroundImage
).get());
631 // SPACING (ie. margin, padding, border, outline)
632 IndentBy(out
,aIndent
);
633 fprintf(out
, "<spacing data=\"");
635 const nsStyleMargin
* margin
= GetStyleMargin();
636 margin
->mMargin
.ToString(str
);
637 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
639 const nsStylePadding
* padding
= GetStylePadding();
640 padding
->mPadding
.ToString(str
);
641 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
643 const nsStyleBorder
* border
= GetStyleBorder();
644 #ifdef NS_COORD_IS_FLOAT
645 const char format
[] = "top: %ftw right: %ftw bottom: %ftw left: %ftw";
647 const char format
[] = "top: %dtw right: %dtw bottom: %dtw left: %dtw";
649 nsPrintfCString
output(format
,
650 border
->GetActualBorderWidth(NS_SIDE_TOP
),
651 border
->GetActualBorderWidth(NS_SIDE_RIGHT
),
652 border
->GetActualBorderWidth(NS_SIDE_BOTTOM
),
653 border
->GetActualBorderWidth(NS_SIDE_LEFT
));
654 fprintf(out
, "%s ", output
.get());
655 border
->mBorderRadius
.ToString(str
);
656 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
658 const nsStyleOutline
* outline
= GetStyleOutline();
659 outline
->mOutlineRadius
.ToString(str
);
660 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
661 outline
->mOutlineWidth
.ToString(str
);
662 fprintf(out
, "%s", NS_ConvertUTF16toUTF8(str
).get());
663 fprintf(out
, "%d", (int)border
->mFloatEdge
);
664 fprintf(out
, "\" />\n");
667 IndentBy(out
,aIndent
);
668 const nsStyleList
* list
= GetStyleList();
669 fprintf(out
, "<list data=\"%d %d %s\" />\n",
670 (int)list
->mListStyleType
,
671 (int)list
->mListStyleType
,
672 URICString(list
->mListStyleImage
).get());
675 IndentBy(out
,aIndent
);
676 const nsStylePosition
* pos
= GetStylePosition();
677 fprintf(out
, "<position data=\"");
678 pos
->mOffset
.ToString(str
);
679 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
680 pos
->mWidth
.ToString(str
);
681 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
682 pos
->mMinWidth
.ToString(str
);
683 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
684 pos
->mMaxWidth
.ToString(str
);
685 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
686 pos
->mHeight
.ToString(str
);
687 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
688 pos
->mMinHeight
.ToString(str
);
689 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
690 pos
->mMaxHeight
.ToString(str
);
691 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
692 fprintf(out
, "%d ", (int)pos
->mBoxSizing
);
693 pos
->mZIndex
.ToString(str
);
694 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
695 fprintf(out
, "\" />\n");
698 IndentBy(out
,aIndent
);
699 const nsStyleText
* text
= GetStyleText();
700 fprintf(out
, "<text data=\"%d %d %d %d",
701 (int)text
->mTextAlign
,
702 (int)text
->mTextTransform
,
703 (int)text
->mWhiteSpace
,
704 (int)text
->mWordWrap
);
705 text
->mLetterSpacing
.ToString(str
);
706 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
707 text
->mLineHeight
.ToString(str
);
708 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
709 text
->mTextIndent
.ToString(str
);
710 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
711 text
->mWordSpacing
.ToString(str
);
712 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
713 fprintf(out
, "\" />\n");
716 IndentBy(out
,aIndent
);
717 const nsStyleTextReset
* textReset
= GetStyleTextReset();
718 fprintf(out
, "<textreset data=\"%d ",
719 (int)textReset
->mTextDecoration
);
720 textReset
->mVerticalAlign
.ToString(str
);
721 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
722 fprintf(out
, "\" />\n");
725 IndentBy(out
,aIndent
);
726 const nsStyleDisplay
* disp
= GetStyleDisplay();
727 fprintf(out
, "<display data=\"%d %d %f %d %d %d %d %d %d %d %ld %ld %ld %ld %s\" />\n",
728 (int)disp
->mPosition
,
730 (float)disp
->mOpacity
,
732 (int)disp
->mBreakType
,
733 (int)disp
->mBreakBefore
,
734 (int)disp
->mBreakAfter
,
735 (int)disp
->mOverflowX
,
736 (int)disp
->mOverflowY
,
737 (int)disp
->mClipFlags
,
740 (long)disp
->mClip
.width
,
741 (long)disp
->mClip
.height
,
742 URICString(disp
->mBinding
).get()
746 IndentBy(out
,aIndent
);
747 const nsStyleVisibility
* vis
= GetStyleVisibility();
748 fprintf(out
, "<visibility data=\"%d %d\" />\n",
749 (int)vis
->mDirection
,
754 IndentBy(out
,aIndent
);
755 const nsStyleTable
* table
= GetStyleTable();
756 fprintf(out
, "<table data=\"%d %d %d ",
757 (int)table
->mLayoutStrategy
,
760 fprintf(out
, "%ld %ld ",
763 fprintf(out
, "\" />\n");
766 IndentBy(out
,aIndent
);
767 const nsStyleTableBorder
* tableBorder
= GetStyleTableBorder();
768 fprintf(out
, "<tableborder data=\"%d %d %d %d %d ",
769 (int)tableBorder
->mBorderCollapse
,
770 (int)tableBorder
->mBorderSpacingX
,
771 (int)tableBorder
->mBorderSpacingY
,
772 (int)tableBorder
->mCaptionSide
,
773 (int)tableBorder
->mEmptyCells
);
774 fprintf(out
, "\" />\n");
777 IndentBy(out
,aIndent
);
778 const nsStyleContent
* content
= GetStyleContent();
779 fprintf(out
, "<content data=\"%ld %ld %ld ",
780 (long)content
->ContentCount(),
781 (long)content
->CounterIncrementCount(),
782 (long)content
->CounterResetCount());
783 // XXX: iterate over the content and counters...
784 content
->mMarkerOffset
.ToString(str
);
785 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
786 fprintf(out
, "\" />\n");
789 IndentBy(out
,aIndent
);
790 const nsStyleQuotes
* quotes
= GetStyleQuotes();
791 fprintf(out
, "<quotes data=\"%ld ",
792 (long)quotes
->QuotesCount());
793 // XXX: iterate over the quotes...
794 fprintf(out
, "\" />\n");
797 IndentBy(out
,aIndent
);
798 const nsStyleUserInterface
* ui
= GetStyleUserInterface();
799 fprintf(out
, "<ui data=\"%d %d %d %d\" />\n",
801 (int)ui
->mUserModify
,
806 IndentBy(out
,aIndent
);
807 const nsStyleUIReset
* uiReset
= GetStyleUIReset();
808 fprintf(out
, "<uireset data=\"%d %d %d\" />\n",
809 (int)uiReset
->mUserSelect
,
810 (int)uiReset
->mIMEMode
,
811 (int)uiReset
->mWindowShadow
);
814 IndentBy(out
,aIndent
);
815 const nsStyleColumn
* column
= GetStyleColumn();
816 fprintf(out
, "<column data=\"%d ",
817 (int)column
->mColumnCount
);
818 column
->mColumnWidth
.ToString(str
);
819 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
820 column
->mColumnGap
.ToString(str
);
821 fprintf(out
, "%s ", NS_ConvertUTF16toUTF8(str
).get());
822 fprintf(out
, "%d %d %ld",
823 (int)column
->GetComputedColumnRuleWidth(),
824 (int)column
->mColumnRuleStyle
,
825 (long)column
->mColumnRuleColor
);
826 fprintf(out
, "\" />\n");
829 IndentBy(out
,aIndent
);
830 const nsStyleXUL
* xul
= GetStyleXUL();
831 fprintf(out
, "<xul data=\"%d %d %d %d %d %d",
833 (int)xul
->mBoxDirection
,
835 (int)xul
->mBoxOrient
,
837 (int)xul
->mBoxOrdinal
);
838 fprintf(out
, "\" />\n");
842 IndentBy(out
,aIndent
);
843 const nsStyleSVG
* svg
= GetStyleSVG();
844 fprintf(out
, "<svg data=\"%d ",(int)svg
->mFill
.mType
);
845 if (svg
->mFill
.mType
== eStyleSVGPaintType_Server
)
846 fprintf(out
, "%s %ld ", URICString(svg
->mFill
.mPaint
.mPaintServer
).get(),
847 (long)svg
->mFill
.mFallbackColor
);
849 fprintf(out
, "%ld ", (long)svg
->mFill
.mPaint
.mColor
);
851 fprintf(out
, "%d ", (int)svg
->mStroke
.mType
);
852 if (svg
->mStroke
.mType
== eStyleSVGPaintType_Server
)
853 fprintf(out
, "%s %ld ", URICString(svg
->mStroke
.mPaint
.mPaintServer
).get(),
854 (long)svg
->mStroke
.mFallbackColor
);
856 fprintf(out
, "%ld ", (long)svg
->mStroke
.mPaint
.mColor
);
858 fprintf(out
, "%s %s %s ",
859 URICString(svg
->mMarkerEnd
).get(),
860 URICString(svg
->mMarkerMid
).get(),
861 URICString(svg
->mMarkerStart
).get());
863 for (PRUint32 i
= 0; i
< svg
->mStrokeDasharrayLength
; i
++) {
864 svg
->mStrokeDasharray
[i
].ToString(str
);
867 NS_ConvertUTF16toUTF8(str
).get(),
868 (i
== svg
->mStrokeDasharrayLength
) ? ' ' : ',');
871 svg
->mStrokeDashoffset
.ToString(str
);
872 fprintf(out
, "%f %s %f %f ",
874 NS_ConvertUTF16toUTF8(str
).get(),
875 svg
->mStrokeMiterlimit
,
876 svg
->mStrokeOpacity
);
877 svg
->mStrokeWidth
.ToString(str
);
878 fprintf(out
, "%s %d %d %d %d %d %d %d %d %d %d %d\" />\n",
879 NS_ConvertUTF16toUTF8(str
).get(),
880 (int)svg
->mStrokeDasharrayLength
,
882 (int)svg
->mColorInterpolation
,
883 (int)svg
->mColorInterpolationFilters
,
885 (int)svg
->mPointerEvents
,
886 (int)svg
->mShapeRendering
,
887 (int)svg
->mStrokeLinecap
,
888 (int)svg
->mStrokeLinejoin
,
889 (int)svg
->mTextAnchor
,
890 (int)svg
->mTextRendering
);
893 IndentBy(out
,aIndent
);
894 const nsStyleSVGReset
* svgReset
= GetStyleSVGReset();
896 fprintf(out
, "<svgreset data=\"%ld ", (long)svgReset
->mStopColor
);
898 fprintf(out
, "%ld ", (long)svgReset
->mFloodColor
);
900 fprintf(out
, "%ld ", (long)svgReset
->mLightingColor
);
902 fprintf(out
, "%s %s %s %f %f %d\" />\n",
903 URICString(svgReset
->mClipPath
).get(),
904 URICString(svgReset
->mFilter
).get(),
905 URICString(svgReset
->mMask
).get(),
906 svgReset
->mStopOpacity
,
907 svgReset
->mFloodOpacity
,
908 (int)svgReset
->mDominantBaseline
);
910 //#insert new style structs here#
914 // Overloaded new operator. Initializes the memory to 0 and relies on an arena
915 // (which comes from the presShell) to perform the allocation.
917 nsStyleContext::operator new(size_t sz
, nsPresContext
* aPresContext
) CPP_THROW_NEW
919 // Check the recycle list first.
920 return aPresContext
->AllocateFromShell(sz
);
923 // Overridden to prevent the global delete from being called, since the memory
924 // came out of an nsIArena instead of the global delete operator's heap.
926 nsStyleContext::Destroy()
928 // Get the pres context from our rule node.
929 nsCOMPtr
<nsPresContext
> presContext
= mRuleNode
->GetPresContext();
931 // Call our destructor.
932 this->~nsStyleContext();
934 // Don't let the memory be freed, since it will be recycled
935 // instead. Don't call the global operator delete.
936 presContext
->FreeToShell(sizeof(nsStyleContext
), this);
939 already_AddRefed
<nsStyleContext
>
940 NS_NewStyleContext(nsStyleContext
* aParentContext
,
942 nsRuleNode
* aRuleNode
,
943 nsPresContext
* aPresContext
)
945 nsStyleContext
* context
= new (aPresContext
) nsStyleContext(aParentContext
, aPseudoTag
,
946 aRuleNode
, aPresContext
);