Various cleanup and commenting in nsRuleNode and nsStyleContext. A few minor performance tweaks to nsRuleNode::WalkRuleTree. Fix correctness / crash errors that were caused by not setting the parent struct in the Compute*Data functions for inherited structs. b=111815 r=hewitt sr=hyatt

This commit is contained in:
dbaron%fas.harvard.edu 2001-12-02 00:44:45 +00:00
Родитель 313c7b7393
Коммит e3bc6fd309
4 изменённых файлов: 312 добавлений и 256 удалений

Просмотреть файл

@ -580,10 +580,8 @@ inline void
nsRuleNode::PropagateNoneBit(PRUint32 aBit, nsRuleNode* aHighestNode) nsRuleNode::PropagateNoneBit(PRUint32 aBit, nsRuleNode* aHighestNode)
{ {
nsRuleNode* curr = this; nsRuleNode* curr = this;
while (curr && curr != aHighestNode) { while (curr != aHighestNode) {
if (curr->mNoneBits & aBit) NS_ASSERTION(!(curr->mNoneBits & aBit), "propagating too far");
break;
curr->mNoneBits |= aBit; curr->mNoneBits |= aBit;
curr = curr->mParent; curr = curr->mParent;
} }
@ -596,7 +594,17 @@ nsRuleNode::PropagateInheritBit(PRUint32 aBit, nsRuleNode* aHighestNode)
return; // Already set. return; // Already set.
nsRuleNode* curr = this; nsRuleNode* curr = this;
while (curr && curr != aHighestNode) { while (curr != aHighestNode) {
if (curr->mInheritBits & aBit) {
#ifdef DEBUG
while (curr != aHighestNode) {
NS_ASSERTION(curr->mInheritBits & aBit, "bit not set");
curr = curr->mParent;
}
#endif
break;
}
curr->mInheritBits |= aBit; curr->mInheritBits |= aBit;
curr = curr->mParent; curr = curr->mParent;
} }
@ -1357,49 +1365,65 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID,
// We start at the most specific rule in the tree. // We start at the most specific rule in the tree.
nsStyleStruct* startStruct = nsnull; nsStyleStruct* startStruct = nsnull;
nsCOMPtr<nsIStyleRule> rule = mRule;
nsRuleNode* ruleNode = this; nsRuleNode* ruleNode = this;
nsRuleNode* highestNode = nsnull; nsRuleNode* highestNode = nsnull; // The highest node in the rule tree
nsRuleNode* rootNode = this; // that has the same properties
// specified for struct |aSID| as
// |this| does.
nsRuleNode* rootNode = this; // After the loop below, this will be the
// highest node that we've walked without
// finding cached data on the rule tree.
// If we don't find any cached data, it
// will be the root. (XXX misnamed)
RuleDetail detail = eRuleNone; RuleDetail detail = eRuleNone;
PRUint32 bit = nsCachedStyleData::GetBitForSID(aSID); PRUint32 bit = nsCachedStyleData::GetBitForSID(aSID);
while (ruleNode) { while (ruleNode) {
startStruct = ruleNode->mStyleData.GetStyleData(aSID); startStruct = ruleNode->mStyleData.GetStyleData(aSID);
if (startStruct) if (startStruct)
break; // We found a rule with fully specified data. We don't need to go up break; // We found a rule with fully specified data. We don't
// the tree any further, since the remainder of this branch has already // need to go up the tree any further, since the remainder
// been computed. // of this branch has already been computed.
// See if this rule node has cached the fact that the remaining nodes along this // See if this rule node has cached the fact that the remaining
// path specify no data whatsoever. // nodes along this path specify no data whatsoever.
if (ruleNode->mNoneBits & bit) if (ruleNode->mNoneBits & bit)
break; break;
// Failing the following test mean that we have specified no rule information yet // If the inherit bit is set on a rule node for this struct, that
// along this branch, but some ancestor in the rule tree actually has the data. We // means its rule won't have any information to add, so skip it.
// continue walking up the rule tree without asking the style rules for any information // XXXldb I don't understand why we need to check |detail| here, but
// (since the bit being set tells us that the rules aren't going to supply any info anyway. // we do.
if (!(detail == eRuleNone && ruleNode->mInheritBits & bit)) { if (detail == eRuleNone)
// Ask the rule to fill in the properties that it specifies. while (ruleNode->mInheritBits & bit) {
ruleNode->GetRule(getter_AddRefs(rule)); NS_ASSERTION(ruleNode->mStyleData.GetStyleData(aSID) == nsnull,
if (rule) "inherit bit with cached data makes no sense");
rule->MapRuleInfoInto(aRuleData); // Climb up to the next rule in the tree (a less specific rule).
rootNode = ruleNode;
ruleNode = ruleNode->mParent;
NS_ASSERTION(!(ruleNode->mNoneBits & bit), "can't have both bits set");
}
// Now we check to see how many properties have been specified by the rules // Ask the rule to fill in the properties that it specifies.
// we've examined so far. nsIStyleRule *rule = ruleNode->mRule;
RuleDetail oldDetail = detail; if (rule)
detail = CheckSpecifiedProperties(aSID, *aSpecificData); rule->MapRuleInfoInto(aRuleData);
if (oldDetail == eRuleNone && detail != oldDetail)
highestNode = ruleNode;
if (detail == eRuleFullMixed || detail == eRuleFullInherited) // Now we check to see how many properties have been specified by
break; // We don't need to examine any more rules. All properties have been fully specified. // the rules we've examined so far.
} RuleDetail oldDetail = detail;
detail = CheckSpecifiedProperties(aSID, *aSpecificData);
if (oldDetail == eRuleNone && detail != eRuleNone)
highestNode = ruleNode;
if (detail == eRuleFullMixed || detail == eRuleFullInherited)
break; // We don't need to examine any more rules. All properties
// have been fully specified.
// Climb up to the next rule in the tree (a less specific rule).
rootNode = ruleNode; rootNode = ruleNode;
ruleNode = ruleNode->mParent; // Climb up to the next rule in the tree (a less specific rule). ruleNode = ruleNode->mParent;
} }
PRBool isReset = nsCachedStyleData::IsReset(aSID); PRBool isReset = nsCachedStyleData::IsReset(aSID);
@ -1423,16 +1447,23 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID,
} }
else if (!startStruct && ((!isReset && (detail == eRuleNone || detail == eRulePartialInherited)) else if (!startStruct && ((!isReset && (detail == eRuleNone || detail == eRulePartialInherited))
|| detail == eRuleFullInherited)) { || detail == eRuleFullInherited)) {
// We specified no non-inherited information and neither did any of our parent rules. We set a bit // We specified no non-inherited information and neither did any of
// along the branch from the highest node down to our node indicating that no non-inherited data // our parent rules.
// was specified.
// We set a bit along the branch from the highest node (ruleNode)
// down to our node (this) indicating that no non-inherited data was
// specified. This bit is guaranteed to be set already on the path
// from the highest node to the root node. (We can only set this
// bit if detail == eRuleNone because an explicit inherit value
// could override a non-inherited value higher in the rule tree.)
if (detail == eRuleNone) if (detail == eRuleNone)
PropagateNoneBit(bit, ruleNode); PropagateNoneBit(bit, ruleNode);
// All information must necessarily be inherited from our parent style context. // All information must necessarily be inherited from our parent style context.
// In the absence of any computed data in the rule tree and with // In the absence of any computed data in the rule tree and with
// no rules specified that didn't have values of 'inherit', we should check our parent. // no rules specified that didn't have values of 'inherit', we should check our parent.
nsCOMPtr<nsIStyleContext> parentContext = getter_AddRefs(aContext->GetParent()); nsCOMPtr<nsIStyleContext> parentContext =
dont_AddRef(aContext->GetParent());
if (parentContext) { if (parentContext) {
// We have a parent, and so we should just inherit from the parent. // We have a parent, and so we should just inherit from the parent.
// Set the inherit bits on our context. These bits tell the style context that // Set the inherit bits on our context. These bits tell the style context that
@ -2039,6 +2070,9 @@ nsRuleNode::ComputeFontData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDat
const nsStyleFont* parentFont = nsnull; const nsStyleFont* parentFont = nsnull;
PRBool inherited = aInherited; PRBool inherited = aInherited;
if (parentContext)
parentFont = NS_STATIC_CAST(const nsStyleFont*,
parentContext->GetStyleData(eStyleStruct_Font));
if (aStartStruct) if (aStartStruct)
// We only need to compute the delta between this computed data and our // We only need to compute the delta between this computed data and our
// computed data. // computed data.
@ -2048,9 +2082,6 @@ nsRuleNode::ComputeFontData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDat
// No question. We will have to inherit. Go ahead and init // No question. We will have to inherit. Go ahead and init
// with inherited vals from parent. // with inherited vals from parent.
inherited = PR_TRUE; inherited = PR_TRUE;
if (parentContext)
parentFont = NS_STATIC_CAST(const nsStyleFont*,
parentContext->GetStyleData(eStyleStruct_Font));
if (parentFont) if (parentFont)
font = new (mPresContext) nsStyleFont(*parentFont); font = new (mPresContext) nsStyleFont(*parentFont);
} }
@ -2061,6 +2092,8 @@ nsRuleNode::ComputeFontData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDat
mPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID, defaultFont); mPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID, defaultFont);
font = new (mPresContext) nsStyleFont(defaultFont); font = new (mPresContext) nsStyleFont(defaultFont);
} }
if (!parentFont)
parentFont = font;
// See if there is a minimum font-size constraint to honor // See if there is a minimum font-size constraint to honor
nscoord minimumFontSize = 0; // unconstrained by default nscoord minimumFontSize = 0; // unconstrained by default
@ -2114,11 +2147,6 @@ nsRuleNode::ComputeFontData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDat
// Now compute our font struct // Now compute our font struct
if (generic == kGenericFont_NONE) { if (generic == kGenericFont_NONE) {
// continue the normal processing // continue the normal processing
if (!parentFont) {
parentFont = parentContext
? (nsStyleFont*)parentContext->GetStyleData(eStyleStruct_Font)
: font;
}
// our default font is the most recent generic font // our default font is the most recent generic font
generic = parentFont->mFlags & NS_STYLE_FONT_FACE_MASK; generic = parentFont->mFlags & NS_STYLE_FONT_FACE_MASK;
mPresContext->GetDefaultFont(generic, defaultFont); mPresContext->GetDefaultFont(generic, defaultFont);
@ -2169,6 +2197,9 @@ nsRuleNode::ComputeTextData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDat
const nsStyleText* parentText = nsnull; const nsStyleText* parentText = nsnull;
PRBool inherited = aInherited; PRBool inherited = aInherited;
if (parentContext)
parentText = NS_STATIC_CAST(const nsStyleText*,
parentContext->GetStyleData(eStyleStruct_Text));
if (aStartStruct) if (aStartStruct)
// We only need to compute the delta between this computed data and our // We only need to compute the delta between this computed data and our
// computed data. // computed data.
@ -2178,16 +2209,15 @@ nsRuleNode::ComputeTextData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDat
// No question. We will have to inherit. Go ahead and init // No question. We will have to inherit. Go ahead and init
// with inherited vals from parent. // with inherited vals from parent.
inherited = PR_TRUE; inherited = PR_TRUE;
if (parentContext)
parentText = NS_STATIC_CAST(const nsStyleText*,
parentContext->GetStyleData(eStyleStruct_Text));
if (parentText) if (parentText)
text = new (mPresContext) nsStyleText(*parentText); text = new (mPresContext) nsStyleText(*parentText);
} }
} }
if (!text) if (!text)
parentText = text = new (mPresContext) nsStyleText(); text = new (mPresContext) nsStyleText();
if (!parentText)
parentText = text;
// letter-spacing: normal, length, inherit // letter-spacing: normal, length, inherit
SetCoord(textData.mLetterSpacing, text->mLetterSpacing, parentText->mLetterSpacing, SetCoord(textData.mLetterSpacing, text->mLetterSpacing, parentText->mLetterSpacing,
@ -2356,6 +2386,9 @@ nsRuleNode::ComputeUIData(nsStyleStruct* aStartData, const nsCSSStruct& aData,
const nsStyleUserInterface* parentUI = nsnull; const nsStyleUserInterface* parentUI = nsnull;
PRBool inherited = aInherited; PRBool inherited = aInherited;
if (parentContext)
parentUI = NS_STATIC_CAST(const nsStyleUserInterface*,
parentContext->GetStyleData(eStyleStruct_UserInterface));
if (aStartData) if (aStartData)
// We only need to compute the delta between this computed data and our // We only need to compute the delta between this computed data and our
// computed data. // computed data.
@ -2365,16 +2398,15 @@ nsRuleNode::ComputeUIData(nsStyleStruct* aStartData, const nsCSSStruct& aData,
// No question. We will have to inherit. Go ahead and init // No question. We will have to inherit. Go ahead and init
// with inherited vals from parent. // with inherited vals from parent.
inherited = PR_TRUE; inherited = PR_TRUE;
if (parentContext)
parentUI = NS_STATIC_CAST(const nsStyleUserInterface*,
parentContext->GetStyleData(eStyleStruct_UserInterface));
if (parentUI) if (parentUI)
ui = new (mPresContext) nsStyleUserInterface(*parentUI); ui = new (mPresContext) nsStyleUserInterface(*parentUI);
} }
} }
if (!ui) if (!ui)
parentUI = ui = new (mPresContext) nsStyleUserInterface(); ui = new (mPresContext) nsStyleUserInterface();
if (!parentUI)
parentUI = ui;
// cursor: enum, auto, url, inherit // cursor: enum, auto, url, inherit
nsCSSValueList* list = uiData.mCursor; nsCSSValueList* list = uiData.mCursor;
@ -2762,9 +2794,12 @@ nsRuleNode::ComputeVisibilityData(nsStyleStruct* aStartStruct, const nsCSSStruct
const nsCSSDisplay& displayData = NS_STATIC_CAST(const nsCSSDisplay&, aData); const nsCSSDisplay& displayData = NS_STATIC_CAST(const nsCSSDisplay&, aData);
nsStyleVisibility* visibility = nsnull; nsStyleVisibility* visibility = nsnull;
const nsStyleVisibility* parentVisibility = visibility; const nsStyleVisibility* parentVisibility = nsnull;
PRBool inherited = aInherited; PRBool inherited = aInherited;
if (parentContext)
parentVisibility = NS_STATIC_CAST(const nsStyleVisibility*,
parentContext->GetStyleData(eStyleStruct_Visibility));
if (aStartStruct) if (aStartStruct)
// We only need to compute the delta between this computed data and our // We only need to compute the delta between this computed data and our
// computed data. // computed data.
@ -2774,16 +2809,15 @@ nsRuleNode::ComputeVisibilityData(nsStyleStruct* aStartStruct, const nsCSSStruct
// No question. We will have to inherit. Go ahead and init // No question. We will have to inherit. Go ahead and init
// with inherited vals from parent. // with inherited vals from parent.
inherited = PR_TRUE; inherited = PR_TRUE;
if (parentContext)
parentVisibility = NS_STATIC_CAST(const nsStyleVisibility*,
parentContext->GetStyleData(eStyleStruct_Visibility));
if (parentVisibility) if (parentVisibility)
visibility = new (mPresContext) nsStyleVisibility(*parentVisibility); visibility = new (mPresContext) nsStyleVisibility(*parentVisibility);
} }
} }
if (!visibility) if (!visibility)
parentVisibility = visibility = new (mPresContext) nsStyleVisibility(mPresContext); visibility = new (mPresContext) nsStyleVisibility(mPresContext);
if (!parentVisibility)
parentVisibility = visibility;
// opacity: factor, percent, inherit // opacity: factor, percent, inherit
if (eCSSUnit_Percent == displayData.mOpacity.GetUnit()) { if (eCSSUnit_Percent == displayData.mOpacity.GetUnit()) {
@ -2860,6 +2894,9 @@ nsRuleNode::ComputeColorData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDa
const nsStyleColor* parentColor = nsnull; const nsStyleColor* parentColor = nsnull;
PRBool inherited = aInherited; PRBool inherited = aInherited;
if (parentContext)
parentColor = NS_STATIC_CAST(const nsStyleColor*,
parentContext->GetStyleData(eStyleStruct_Color));
if (aStartStruct) if (aStartStruct)
// We only need to compute the delta between this computed data and our // We only need to compute the delta between this computed data and our
// computed data. // computed data.
@ -2869,16 +2906,15 @@ nsRuleNode::ComputeColorData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDa
// No question. We will have to inherit. Go ahead and init // No question. We will have to inherit. Go ahead and init
// with inherited vals from parent. // with inherited vals from parent.
inherited = PR_TRUE; inherited = PR_TRUE;
if (parentContext)
parentColor = NS_STATIC_CAST(const nsStyleColor*,
parentContext->GetStyleData(eStyleStruct_Color));
if (parentColor) if (parentColor)
color = new (mPresContext) nsStyleColor(*parentColor); color = new (mPresContext) nsStyleColor(*parentColor);
} }
} }
if (!color) if (!color)
parentColor = color = new (mPresContext) nsStyleColor(mPresContext); color = new (mPresContext) nsStyleColor(mPresContext);
if (!parentColor)
parentColor = color;
// color: color, string, inherit // color: color, string, inherit
SetColor(colorData.mColor, parentColor->mColor, mPresContext, color->mColor, inherited); SetColor(colorData.mColor, parentColor->mColor, mPresContext, color->mColor, inherited);
@ -3524,6 +3560,9 @@ nsRuleNode::ComputeListData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDat
const nsStyleList* parentList = nsnull; const nsStyleList* parentList = nsnull;
PRBool inherited = aInherited; PRBool inherited = aInherited;
if (parentContext)
parentList = NS_STATIC_CAST(const nsStyleList*,
parentContext->GetStyleData(eStyleStruct_List));
if (aStartStruct) if (aStartStruct)
// We only need to compute the delta between this computed data and our // We only need to compute the delta between this computed data and our
// computed data. // computed data.
@ -3533,16 +3572,15 @@ nsRuleNode::ComputeListData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDat
// No question. We will have to inherit. Go ahead and init // No question. We will have to inherit. Go ahead and init
// with inherited vals from parent. // with inherited vals from parent.
inherited = PR_TRUE; inherited = PR_TRUE;
if (parentContext)
parentList = NS_STATIC_CAST(const nsStyleList*,
parentContext->GetStyleData(eStyleStruct_List));
if (parentList) if (parentList)
list = new (mPresContext) nsStyleList(*parentList); list = new (mPresContext) nsStyleList(*parentList);
} }
} }
if (!list) if (!list)
parentList = list = new (mPresContext) nsStyleList(); list = new (mPresContext) nsStyleList();
if (!parentList)
parentList = list;
// list-style-type: enum, none, inherit // list-style-type: enum, none, inherit
if (eCSSUnit_Enumerated == listData.mType.GetUnit()) { if (eCSSUnit_Enumerated == listData.mType.GetUnit()) {
@ -3787,6 +3825,9 @@ nsRuleNode::ComputeTableBorderData(nsStyleStruct* aStartStruct, const nsCSSStruc
const nsStyleTableBorder* parentTable = nsnull; const nsStyleTableBorder* parentTable = nsnull;
PRBool inherited = aInherited; PRBool inherited = aInherited;
if (parentContext)
parentTable = NS_STATIC_CAST(const nsStyleTableBorder*,
parentContext->GetStyleData(eStyleStruct_TableBorder));
if (aStartStruct) if (aStartStruct)
// We only need to compute the delta between this computed data and our // We only need to compute the delta between this computed data and our
// computed data. // computed data.
@ -3796,16 +3837,15 @@ nsRuleNode::ComputeTableBorderData(nsStyleStruct* aStartStruct, const nsCSSStruc
// No question. We will have to inherit. Go ahead and init // No question. We will have to inherit. Go ahead and init
// with inherited vals from parent. // with inherited vals from parent.
inherited = PR_TRUE; inherited = PR_TRUE;
if (parentContext)
parentTable = NS_STATIC_CAST(const nsStyleTableBorder*,
parentContext->GetStyleData(eStyleStruct_TableBorder));
if (parentTable) if (parentTable)
table = new (mPresContext) nsStyleTableBorder(*parentTable); table = new (mPresContext) nsStyleTableBorder(*parentTable);
} }
} }
if (!table) if (!table)
parentTable = table = new (mPresContext) nsStyleTableBorder(mPresContext); table = new (mPresContext) nsStyleTableBorder(mPresContext);
if (!parentTable)
parentTable = table;
// border-collapse: enum, inherit // border-collapse: enum, inherit
if (eCSSUnit_Enumerated == tableData.mBorderCollapse.GetUnit()) { if (eCSSUnit_Enumerated == tableData.mBorderCollapse.GetUnit()) {
@ -4081,6 +4121,9 @@ nsRuleNode::ComputeQuotesData(nsStyleStruct* aStartStruct, const nsCSSStruct& aD
const nsStyleQuotes* parentQuotes = nsnull; const nsStyleQuotes* parentQuotes = nsnull;
PRBool inherited = aInherited; PRBool inherited = aInherited;
if (parentContext)
parentQuotes = NS_STATIC_CAST(const nsStyleQuotes*,
parentContext->GetStyleData(eStyleStruct_Quotes));
if (aStartStruct) if (aStartStruct)
// We only need to compute the delta between this computed data and our // We only need to compute the delta between this computed data and our
// computed data. // computed data.
@ -4090,16 +4133,15 @@ nsRuleNode::ComputeQuotesData(nsStyleStruct* aStartStruct, const nsCSSStruct& aD
// No question. We will have to inherit. Go ahead and init // No question. We will have to inherit. Go ahead and init
// with inherited vals from parent. // with inherited vals from parent.
inherited = PR_TRUE; inherited = PR_TRUE;
if (parentContext)
parentQuotes = NS_STATIC_CAST(const nsStyleQuotes*,
parentContext->GetStyleData(eStyleStruct_Quotes));
if (parentQuotes) if (parentQuotes)
quotes = new (mPresContext) nsStyleQuotes(*parentQuotes); quotes = new (mPresContext) nsStyleQuotes(*parentQuotes);
} }
} }
if (!quotes) if (!quotes)
parentQuotes = quotes = new (mPresContext) nsStyleQuotes(); quotes = new (mPresContext) nsStyleQuotes();
if (!parentQuotes)
parentQuotes = quotes;
// quotes: [string string]+, none, inherit // quotes: [string string]+, none, inherit
PRUint32 count; PRUint32 count;
@ -4180,7 +4222,6 @@ nsRuleNode::ComputeXULData(nsStyleStruct* aStartStruct, const nsCSSStruct& aData
xul = new (mPresContext) nsStyleXUL(); xul = new (mPresContext) nsStyleXUL();
const nsStyleXUL* parentXUL = xul; const nsStyleXUL* parentXUL = xul;
if (parentContext) if (parentContext)
parentXUL = NS_STATIC_CAST(const nsStyleXUL*, parentXUL = NS_STATIC_CAST(const nsStyleXUL*,
parentContext->GetStyleData(eStyleStruct_XUL)); parentContext->GetStyleData(eStyleStruct_XUL));

Просмотреть файл

@ -69,8 +69,7 @@ class nsStyleContext : public nsIStyleContext
{ {
public: public:
nsStyleContext(nsIStyleContext* aParent, nsIAtom* aPseudoTag, nsStyleContext(nsIStyleContext* aParent, nsIAtom* aPseudoTag,
nsRuleNode* aRuleNode, nsRuleNode* aRuleNode, nsIPresContext* aPresContext);
nsIPresContext* aPresContext);
virtual ~nsStyleContext(); virtual ~nsStyleContext();
void* operator new(size_t sz, nsIPresContext* aPresContext); void* operator new(size_t sz, nsIPresContext* aPresContext);
@ -130,32 +129,39 @@ protected:
nsStyleContext* mPrevSibling; nsStyleContext* mPrevSibling;
nsStyleContext* mNextSibling; nsStyleContext* mNextSibling;
nsIAtom* mPseudoTag; // If this style context is for a pseudo-element, the pseudo-element
// atom. Otherwise, null.
nsCOMPtr<nsIAtom> mPseudoTag;
PRUint32 mBits; // Which structs are inherited from the parent context.
nsRuleNode* mRuleNode; nsRuleNode* mRuleNode;
// |mCachedStyleData| points to both structs that are owned by this
// style context and structs that are owned by one of this style
// context's ancestors (which are indirectly owned since this style
// context owns a reference to its parent). If the bit in |mBits| is
// set for a struct, that means that the pointer for that struct is
// owned by an ancestor rather than by this style context.
nsCachedStyleData mCachedStyleData; // Our cached style data. nsCachedStyleData mCachedStyleData; // Our cached style data.
PRUint32 mBits; // Which structs are inherited from the
// parent context.
}; };
static PRInt32 gLastDataCode;
nsStyleContext::nsStyleContext(nsIStyleContext* aParent, nsStyleContext::nsStyleContext(nsIStyleContext* aParent,
nsIAtom* aPseudoTag, nsIAtom* aPseudoTag,
nsRuleNode* aRuleNode, nsRuleNode* aRuleNode,
nsIPresContext* aPresContext) nsIPresContext* aPresContext)
: mParent((nsStyleContext*)aParent), : mParent((nsStyleContext*)aParent),
mChild(nsnull), mChild(nsnull),
mEmptyChild(nsnull), mEmptyChild(nsnull),
mPseudoTag(aPseudoTag), mPseudoTag(aPseudoTag),
mBits(0), mRuleNode(aRuleNode),
mRuleNode(aRuleNode) mBits(0)
{ {
NS_INIT_REFCNT(); NS_INIT_ISUPPORTS();
NS_IF_ADDREF(mPseudoTag);
mNextSibling = this; mNextSibling = this;
mPrevSibling = this; mPrevSibling = this;
if (nsnull != mParent) { if (mParent) {
NS_ADDREF(mParent); NS_ADDREF(mParent);
mParent->AppendChild(this); mParent->AppendChild(this);
} }
@ -172,8 +178,6 @@ nsStyleContext::~nsStyleContext()
NS_RELEASE(mParent); NS_RELEASE(mParent);
} }
NS_IF_RELEASE(mPseudoTag);
// Free up our data structs. // Free up our data structs.
if (mCachedStyleData.mResetData || mCachedStyleData.mInheritedData) { if (mCachedStyleData.mResetData || mCachedStyleData.mInheritedData) {
nsCOMPtr<nsIPresContext> presContext; nsCOMPtr<nsIPresContext> presContext;
@ -184,27 +188,7 @@ nsStyleContext::~nsStyleContext()
NS_IMPL_ADDREF(nsStyleContext) NS_IMPL_ADDREF(nsStyleContext)
NS_IMPL_RELEASE_WITH_DESTROY(nsStyleContext, Destroy()) NS_IMPL_RELEASE_WITH_DESTROY(nsStyleContext, Destroy())
NS_IMPL_QUERY_INTERFACE1(nsStyleContext, nsIStyleContext)
NS_IMETHODIMP
nsStyleContext::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
NS_PRECONDITION(nsnull != aInstancePtr, "null pointer");
if (nsnull == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
if (aIID.Equals(NS_GET_IID(nsIStyleContext))) {
*aInstancePtr = (void*)(nsIStyleContext*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*) (nsISupports*)(nsIStyleContext*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
nsIStyleContext* nsStyleContext::GetParent(void) const nsIStyleContext* nsStyleContext::GetParent(void) const
{ {
@ -396,10 +380,10 @@ nsStyleContext::GetBorderPaddingFor(nsStyleBorderPadding& aBorderPadding)
const nsStyleBorder* borderData = (const nsStyleBorder*)GetStyleData(eStyleStruct_Border); const nsStyleBorder* borderData = (const nsStyleBorder*)GetStyleData(eStyleStruct_Border);
const nsStylePadding* paddingData = (const nsStylePadding*)GetStyleData(eStyleStruct_Padding); const nsStylePadding* paddingData = (const nsStylePadding*)GetStyleData(eStyleStruct_Padding);
if (borderData->GetBorder(border)) { if (borderData->GetBorder(border)) {
if (paddingData->GetPadding(padding)) { if (paddingData->GetPadding(padding)) {
border += padding; border += padding;
aBorderPadding.SetBorderPadding(border); aBorderPadding.SetBorderPadding(border);
} }
} }
return NS_OK; return NS_OK;
@ -459,15 +443,18 @@ nsStyleContext::SetStyle(nsStyleStructID aSID, const nsStyleStruct& aStruct)
nsresult result = NS_OK; nsresult result = NS_OK;
PRBool isReset = mCachedStyleData.IsReset(aSID); PRBool isReset = mCachedStyleData.IsReset(aSID);
if (isReset && !mCachedStyleData.mResetData) { if (isReset) {
nsCOMPtr<nsIPresContext> presContext; if (!mCachedStyleData.mResetData) {
mRuleNode->GetPresContext(getter_AddRefs(presContext)); nsCOMPtr<nsIPresContext> presContext;
mCachedStyleData.mResetData = new (presContext.get()) nsResetStyleData; mRuleNode->GetPresContext(getter_AddRefs(presContext));
} mCachedStyleData.mResetData = new (presContext.get()) nsResetStyleData;
else if (!isReset && !mCachedStyleData.mInheritedData) { }
nsCOMPtr<nsIPresContext> presContext; } else {
mRuleNode->GetPresContext(getter_AddRefs(presContext)); if (!mCachedStyleData.mInheritedData) {
mCachedStyleData.mInheritedData = new (presContext.get()) nsInheritedStyleData; nsCOMPtr<nsIPresContext> presContext;
mRuleNode->GetPresContext(getter_AddRefs(presContext));
mCachedStyleData.mInheritedData = new (presContext.get()) nsInheritedStyleData;
}
} }
switch (aSID) { switch (aSID) {
@ -597,7 +584,7 @@ nsStyleContext::ClearStyleData(nsIPresContext* aPresContext, nsIStyleRule* aRule
mCachedStyleData.Destroy(mBits, aPresContext); mCachedStyleData.Destroy(mBits, aPresContext);
mBits = 0; // Clear all bits. mBits = 0; // Clear all bits.
aRule = nsnull; aRule = nsnull; // Force all structs to be blown away in the children.
} }
ApplyStyleFixups(aPresContext); ApplyStyleFixups(aPresContext);
@ -910,7 +897,7 @@ void nsStyleContext::List(FILE* out, PRInt32 aIndent)
PRInt32 ix; PRInt32 ix;
for (ix = aIndent; --ix >= 0; ) fputs(" ", out); for (ix = aIndent; --ix >= 0; ) fputs(" ", out);
fprintf(out, "%p(%d) ", (void*)this, mRefCnt); fprintf(out, "%p(%d) ", (void*)this, mRefCnt);
if (nsnull != mPseudoTag) { if (mPseudoTag) {
nsAutoString buffer; nsAutoString buffer;
mPseudoTag->ToString(buffer); mPseudoTag->ToString(buffer);
fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out); fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out);
@ -988,7 +975,7 @@ void nsStyleContext::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize)
// get the size of an empty instance and add to the sizeof handler // get the size of an empty instance and add to the sizeof handler
aSize = sizeof(*this); aSize = sizeof(*this);
// add in the size of the member mPseudoTag // add in the size of the member mPseudoTag
if(mPseudoTag){ if (mPseudoTag){
mPseudoTag->SizeOf(aSizeOfHandler, &localSize); mPseudoTag->SizeOf(aSizeOfHandler, &localSize);
aSize += localSize; aSize += localSize;
} }

Просмотреть файл

@ -580,10 +580,8 @@ inline void
nsRuleNode::PropagateNoneBit(PRUint32 aBit, nsRuleNode* aHighestNode) nsRuleNode::PropagateNoneBit(PRUint32 aBit, nsRuleNode* aHighestNode)
{ {
nsRuleNode* curr = this; nsRuleNode* curr = this;
while (curr && curr != aHighestNode) { while (curr != aHighestNode) {
if (curr->mNoneBits & aBit) NS_ASSERTION(!(curr->mNoneBits & aBit), "propagating too far");
break;
curr->mNoneBits |= aBit; curr->mNoneBits |= aBit;
curr = curr->mParent; curr = curr->mParent;
} }
@ -596,7 +594,17 @@ nsRuleNode::PropagateInheritBit(PRUint32 aBit, nsRuleNode* aHighestNode)
return; // Already set. return; // Already set.
nsRuleNode* curr = this; nsRuleNode* curr = this;
while (curr && curr != aHighestNode) { while (curr != aHighestNode) {
if (curr->mInheritBits & aBit) {
#ifdef DEBUG
while (curr != aHighestNode) {
NS_ASSERTION(curr->mInheritBits & aBit, "bit not set");
curr = curr->mParent;
}
#endif
break;
}
curr->mInheritBits |= aBit; curr->mInheritBits |= aBit;
curr = curr->mParent; curr = curr->mParent;
} }
@ -1357,49 +1365,65 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID,
// We start at the most specific rule in the tree. // We start at the most specific rule in the tree.
nsStyleStruct* startStruct = nsnull; nsStyleStruct* startStruct = nsnull;
nsCOMPtr<nsIStyleRule> rule = mRule;
nsRuleNode* ruleNode = this; nsRuleNode* ruleNode = this;
nsRuleNode* highestNode = nsnull; nsRuleNode* highestNode = nsnull; // The highest node in the rule tree
nsRuleNode* rootNode = this; // that has the same properties
// specified for struct |aSID| as
// |this| does.
nsRuleNode* rootNode = this; // After the loop below, this will be the
// highest node that we've walked without
// finding cached data on the rule tree.
// If we don't find any cached data, it
// will be the root. (XXX misnamed)
RuleDetail detail = eRuleNone; RuleDetail detail = eRuleNone;
PRUint32 bit = nsCachedStyleData::GetBitForSID(aSID); PRUint32 bit = nsCachedStyleData::GetBitForSID(aSID);
while (ruleNode) { while (ruleNode) {
startStruct = ruleNode->mStyleData.GetStyleData(aSID); startStruct = ruleNode->mStyleData.GetStyleData(aSID);
if (startStruct) if (startStruct)
break; // We found a rule with fully specified data. We don't need to go up break; // We found a rule with fully specified data. We don't
// the tree any further, since the remainder of this branch has already // need to go up the tree any further, since the remainder
// been computed. // of this branch has already been computed.
// See if this rule node has cached the fact that the remaining nodes along this // See if this rule node has cached the fact that the remaining
// path specify no data whatsoever. // nodes along this path specify no data whatsoever.
if (ruleNode->mNoneBits & bit) if (ruleNode->mNoneBits & bit)
break; break;
// Failing the following test mean that we have specified no rule information yet // If the inherit bit is set on a rule node for this struct, that
// along this branch, but some ancestor in the rule tree actually has the data. We // means its rule won't have any information to add, so skip it.
// continue walking up the rule tree without asking the style rules for any information // XXXldb I don't understand why we need to check |detail| here, but
// (since the bit being set tells us that the rules aren't going to supply any info anyway. // we do.
if (!(detail == eRuleNone && ruleNode->mInheritBits & bit)) { if (detail == eRuleNone)
// Ask the rule to fill in the properties that it specifies. while (ruleNode->mInheritBits & bit) {
ruleNode->GetRule(getter_AddRefs(rule)); NS_ASSERTION(ruleNode->mStyleData.GetStyleData(aSID) == nsnull,
if (rule) "inherit bit with cached data makes no sense");
rule->MapRuleInfoInto(aRuleData); // Climb up to the next rule in the tree (a less specific rule).
rootNode = ruleNode;
ruleNode = ruleNode->mParent;
NS_ASSERTION(!(ruleNode->mNoneBits & bit), "can't have both bits set");
}
// Now we check to see how many properties have been specified by the rules // Ask the rule to fill in the properties that it specifies.
// we've examined so far. nsIStyleRule *rule = ruleNode->mRule;
RuleDetail oldDetail = detail; if (rule)
detail = CheckSpecifiedProperties(aSID, *aSpecificData); rule->MapRuleInfoInto(aRuleData);
if (oldDetail == eRuleNone && detail != oldDetail)
highestNode = ruleNode;
if (detail == eRuleFullMixed || detail == eRuleFullInherited) // Now we check to see how many properties have been specified by
break; // We don't need to examine any more rules. All properties have been fully specified. // the rules we've examined so far.
} RuleDetail oldDetail = detail;
detail = CheckSpecifiedProperties(aSID, *aSpecificData);
if (oldDetail == eRuleNone && detail != eRuleNone)
highestNode = ruleNode;
if (detail == eRuleFullMixed || detail == eRuleFullInherited)
break; // We don't need to examine any more rules. All properties
// have been fully specified.
// Climb up to the next rule in the tree (a less specific rule).
rootNode = ruleNode; rootNode = ruleNode;
ruleNode = ruleNode->mParent; // Climb up to the next rule in the tree (a less specific rule). ruleNode = ruleNode->mParent;
} }
PRBool isReset = nsCachedStyleData::IsReset(aSID); PRBool isReset = nsCachedStyleData::IsReset(aSID);
@ -1423,16 +1447,23 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID,
} }
else if (!startStruct && ((!isReset && (detail == eRuleNone || detail == eRulePartialInherited)) else if (!startStruct && ((!isReset && (detail == eRuleNone || detail == eRulePartialInherited))
|| detail == eRuleFullInherited)) { || detail == eRuleFullInherited)) {
// We specified no non-inherited information and neither did any of our parent rules. We set a bit // We specified no non-inherited information and neither did any of
// along the branch from the highest node down to our node indicating that no non-inherited data // our parent rules.
// was specified.
// We set a bit along the branch from the highest node (ruleNode)
// down to our node (this) indicating that no non-inherited data was
// specified. This bit is guaranteed to be set already on the path
// from the highest node to the root node. (We can only set this
// bit if detail == eRuleNone because an explicit inherit value
// could override a non-inherited value higher in the rule tree.)
if (detail == eRuleNone) if (detail == eRuleNone)
PropagateNoneBit(bit, ruleNode); PropagateNoneBit(bit, ruleNode);
// All information must necessarily be inherited from our parent style context. // All information must necessarily be inherited from our parent style context.
// In the absence of any computed data in the rule tree and with // In the absence of any computed data in the rule tree and with
// no rules specified that didn't have values of 'inherit', we should check our parent. // no rules specified that didn't have values of 'inherit', we should check our parent.
nsCOMPtr<nsIStyleContext> parentContext = getter_AddRefs(aContext->GetParent()); nsCOMPtr<nsIStyleContext> parentContext =
dont_AddRef(aContext->GetParent());
if (parentContext) { if (parentContext) {
// We have a parent, and so we should just inherit from the parent. // We have a parent, and so we should just inherit from the parent.
// Set the inherit bits on our context. These bits tell the style context that // Set the inherit bits on our context. These bits tell the style context that
@ -2039,6 +2070,9 @@ nsRuleNode::ComputeFontData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDat
const nsStyleFont* parentFont = nsnull; const nsStyleFont* parentFont = nsnull;
PRBool inherited = aInherited; PRBool inherited = aInherited;
if (parentContext)
parentFont = NS_STATIC_CAST(const nsStyleFont*,
parentContext->GetStyleData(eStyleStruct_Font));
if (aStartStruct) if (aStartStruct)
// We only need to compute the delta between this computed data and our // We only need to compute the delta between this computed data and our
// computed data. // computed data.
@ -2048,9 +2082,6 @@ nsRuleNode::ComputeFontData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDat
// No question. We will have to inherit. Go ahead and init // No question. We will have to inherit. Go ahead and init
// with inherited vals from parent. // with inherited vals from parent.
inherited = PR_TRUE; inherited = PR_TRUE;
if (parentContext)
parentFont = NS_STATIC_CAST(const nsStyleFont*,
parentContext->GetStyleData(eStyleStruct_Font));
if (parentFont) if (parentFont)
font = new (mPresContext) nsStyleFont(*parentFont); font = new (mPresContext) nsStyleFont(*parentFont);
} }
@ -2061,6 +2092,8 @@ nsRuleNode::ComputeFontData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDat
mPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID, defaultFont); mPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID, defaultFont);
font = new (mPresContext) nsStyleFont(defaultFont); font = new (mPresContext) nsStyleFont(defaultFont);
} }
if (!parentFont)
parentFont = font;
// See if there is a minimum font-size constraint to honor // See if there is a minimum font-size constraint to honor
nscoord minimumFontSize = 0; // unconstrained by default nscoord minimumFontSize = 0; // unconstrained by default
@ -2114,11 +2147,6 @@ nsRuleNode::ComputeFontData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDat
// Now compute our font struct // Now compute our font struct
if (generic == kGenericFont_NONE) { if (generic == kGenericFont_NONE) {
// continue the normal processing // continue the normal processing
if (!parentFont) {
parentFont = parentContext
? (nsStyleFont*)parentContext->GetStyleData(eStyleStruct_Font)
: font;
}
// our default font is the most recent generic font // our default font is the most recent generic font
generic = parentFont->mFlags & NS_STYLE_FONT_FACE_MASK; generic = parentFont->mFlags & NS_STYLE_FONT_FACE_MASK;
mPresContext->GetDefaultFont(generic, defaultFont); mPresContext->GetDefaultFont(generic, defaultFont);
@ -2169,6 +2197,9 @@ nsRuleNode::ComputeTextData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDat
const nsStyleText* parentText = nsnull; const nsStyleText* parentText = nsnull;
PRBool inherited = aInherited; PRBool inherited = aInherited;
if (parentContext)
parentText = NS_STATIC_CAST(const nsStyleText*,
parentContext->GetStyleData(eStyleStruct_Text));
if (aStartStruct) if (aStartStruct)
// We only need to compute the delta between this computed data and our // We only need to compute the delta between this computed data and our
// computed data. // computed data.
@ -2178,16 +2209,15 @@ nsRuleNode::ComputeTextData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDat
// No question. We will have to inherit. Go ahead and init // No question. We will have to inherit. Go ahead and init
// with inherited vals from parent. // with inherited vals from parent.
inherited = PR_TRUE; inherited = PR_TRUE;
if (parentContext)
parentText = NS_STATIC_CAST(const nsStyleText*,
parentContext->GetStyleData(eStyleStruct_Text));
if (parentText) if (parentText)
text = new (mPresContext) nsStyleText(*parentText); text = new (mPresContext) nsStyleText(*parentText);
} }
} }
if (!text) if (!text)
parentText = text = new (mPresContext) nsStyleText(); text = new (mPresContext) nsStyleText();
if (!parentText)
parentText = text;
// letter-spacing: normal, length, inherit // letter-spacing: normal, length, inherit
SetCoord(textData.mLetterSpacing, text->mLetterSpacing, parentText->mLetterSpacing, SetCoord(textData.mLetterSpacing, text->mLetterSpacing, parentText->mLetterSpacing,
@ -2356,6 +2386,9 @@ nsRuleNode::ComputeUIData(nsStyleStruct* aStartData, const nsCSSStruct& aData,
const nsStyleUserInterface* parentUI = nsnull; const nsStyleUserInterface* parentUI = nsnull;
PRBool inherited = aInherited; PRBool inherited = aInherited;
if (parentContext)
parentUI = NS_STATIC_CAST(const nsStyleUserInterface*,
parentContext->GetStyleData(eStyleStruct_UserInterface));
if (aStartData) if (aStartData)
// We only need to compute the delta between this computed data and our // We only need to compute the delta between this computed data and our
// computed data. // computed data.
@ -2365,16 +2398,15 @@ nsRuleNode::ComputeUIData(nsStyleStruct* aStartData, const nsCSSStruct& aData,
// No question. We will have to inherit. Go ahead and init // No question. We will have to inherit. Go ahead and init
// with inherited vals from parent. // with inherited vals from parent.
inherited = PR_TRUE; inherited = PR_TRUE;
if (parentContext)
parentUI = NS_STATIC_CAST(const nsStyleUserInterface*,
parentContext->GetStyleData(eStyleStruct_UserInterface));
if (parentUI) if (parentUI)
ui = new (mPresContext) nsStyleUserInterface(*parentUI); ui = new (mPresContext) nsStyleUserInterface(*parentUI);
} }
} }
if (!ui) if (!ui)
parentUI = ui = new (mPresContext) nsStyleUserInterface(); ui = new (mPresContext) nsStyleUserInterface();
if (!parentUI)
parentUI = ui;
// cursor: enum, auto, url, inherit // cursor: enum, auto, url, inherit
nsCSSValueList* list = uiData.mCursor; nsCSSValueList* list = uiData.mCursor;
@ -2762,9 +2794,12 @@ nsRuleNode::ComputeVisibilityData(nsStyleStruct* aStartStruct, const nsCSSStruct
const nsCSSDisplay& displayData = NS_STATIC_CAST(const nsCSSDisplay&, aData); const nsCSSDisplay& displayData = NS_STATIC_CAST(const nsCSSDisplay&, aData);
nsStyleVisibility* visibility = nsnull; nsStyleVisibility* visibility = nsnull;
const nsStyleVisibility* parentVisibility = visibility; const nsStyleVisibility* parentVisibility = nsnull;
PRBool inherited = aInherited; PRBool inherited = aInherited;
if (parentContext)
parentVisibility = NS_STATIC_CAST(const nsStyleVisibility*,
parentContext->GetStyleData(eStyleStruct_Visibility));
if (aStartStruct) if (aStartStruct)
// We only need to compute the delta between this computed data and our // We only need to compute the delta between this computed data and our
// computed data. // computed data.
@ -2774,16 +2809,15 @@ nsRuleNode::ComputeVisibilityData(nsStyleStruct* aStartStruct, const nsCSSStruct
// No question. We will have to inherit. Go ahead and init // No question. We will have to inherit. Go ahead and init
// with inherited vals from parent. // with inherited vals from parent.
inherited = PR_TRUE; inherited = PR_TRUE;
if (parentContext)
parentVisibility = NS_STATIC_CAST(const nsStyleVisibility*,
parentContext->GetStyleData(eStyleStruct_Visibility));
if (parentVisibility) if (parentVisibility)
visibility = new (mPresContext) nsStyleVisibility(*parentVisibility); visibility = new (mPresContext) nsStyleVisibility(*parentVisibility);
} }
} }
if (!visibility) if (!visibility)
parentVisibility = visibility = new (mPresContext) nsStyleVisibility(mPresContext); visibility = new (mPresContext) nsStyleVisibility(mPresContext);
if (!parentVisibility)
parentVisibility = visibility;
// opacity: factor, percent, inherit // opacity: factor, percent, inherit
if (eCSSUnit_Percent == displayData.mOpacity.GetUnit()) { if (eCSSUnit_Percent == displayData.mOpacity.GetUnit()) {
@ -2860,6 +2894,9 @@ nsRuleNode::ComputeColorData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDa
const nsStyleColor* parentColor = nsnull; const nsStyleColor* parentColor = nsnull;
PRBool inherited = aInherited; PRBool inherited = aInherited;
if (parentContext)
parentColor = NS_STATIC_CAST(const nsStyleColor*,
parentContext->GetStyleData(eStyleStruct_Color));
if (aStartStruct) if (aStartStruct)
// We only need to compute the delta between this computed data and our // We only need to compute the delta between this computed data and our
// computed data. // computed data.
@ -2869,16 +2906,15 @@ nsRuleNode::ComputeColorData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDa
// No question. We will have to inherit. Go ahead and init // No question. We will have to inherit. Go ahead and init
// with inherited vals from parent. // with inherited vals from parent.
inherited = PR_TRUE; inherited = PR_TRUE;
if (parentContext)
parentColor = NS_STATIC_CAST(const nsStyleColor*,
parentContext->GetStyleData(eStyleStruct_Color));
if (parentColor) if (parentColor)
color = new (mPresContext) nsStyleColor(*parentColor); color = new (mPresContext) nsStyleColor(*parentColor);
} }
} }
if (!color) if (!color)
parentColor = color = new (mPresContext) nsStyleColor(mPresContext); color = new (mPresContext) nsStyleColor(mPresContext);
if (!parentColor)
parentColor = color;
// color: color, string, inherit // color: color, string, inherit
SetColor(colorData.mColor, parentColor->mColor, mPresContext, color->mColor, inherited); SetColor(colorData.mColor, parentColor->mColor, mPresContext, color->mColor, inherited);
@ -3524,6 +3560,9 @@ nsRuleNode::ComputeListData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDat
const nsStyleList* parentList = nsnull; const nsStyleList* parentList = nsnull;
PRBool inherited = aInherited; PRBool inherited = aInherited;
if (parentContext)
parentList = NS_STATIC_CAST(const nsStyleList*,
parentContext->GetStyleData(eStyleStruct_List));
if (aStartStruct) if (aStartStruct)
// We only need to compute the delta between this computed data and our // We only need to compute the delta between this computed data and our
// computed data. // computed data.
@ -3533,16 +3572,15 @@ nsRuleNode::ComputeListData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDat
// No question. We will have to inherit. Go ahead and init // No question. We will have to inherit. Go ahead and init
// with inherited vals from parent. // with inherited vals from parent.
inherited = PR_TRUE; inherited = PR_TRUE;
if (parentContext)
parentList = NS_STATIC_CAST(const nsStyleList*,
parentContext->GetStyleData(eStyleStruct_List));
if (parentList) if (parentList)
list = new (mPresContext) nsStyleList(*parentList); list = new (mPresContext) nsStyleList(*parentList);
} }
} }
if (!list) if (!list)
parentList = list = new (mPresContext) nsStyleList(); list = new (mPresContext) nsStyleList();
if (!parentList)
parentList = list;
// list-style-type: enum, none, inherit // list-style-type: enum, none, inherit
if (eCSSUnit_Enumerated == listData.mType.GetUnit()) { if (eCSSUnit_Enumerated == listData.mType.GetUnit()) {
@ -3787,6 +3825,9 @@ nsRuleNode::ComputeTableBorderData(nsStyleStruct* aStartStruct, const nsCSSStruc
const nsStyleTableBorder* parentTable = nsnull; const nsStyleTableBorder* parentTable = nsnull;
PRBool inherited = aInherited; PRBool inherited = aInherited;
if (parentContext)
parentTable = NS_STATIC_CAST(const nsStyleTableBorder*,
parentContext->GetStyleData(eStyleStruct_TableBorder));
if (aStartStruct) if (aStartStruct)
// We only need to compute the delta between this computed data and our // We only need to compute the delta between this computed data and our
// computed data. // computed data.
@ -3796,16 +3837,15 @@ nsRuleNode::ComputeTableBorderData(nsStyleStruct* aStartStruct, const nsCSSStruc
// No question. We will have to inherit. Go ahead and init // No question. We will have to inherit. Go ahead and init
// with inherited vals from parent. // with inherited vals from parent.
inherited = PR_TRUE; inherited = PR_TRUE;
if (parentContext)
parentTable = NS_STATIC_CAST(const nsStyleTableBorder*,
parentContext->GetStyleData(eStyleStruct_TableBorder));
if (parentTable) if (parentTable)
table = new (mPresContext) nsStyleTableBorder(*parentTable); table = new (mPresContext) nsStyleTableBorder(*parentTable);
} }
} }
if (!table) if (!table)
parentTable = table = new (mPresContext) nsStyleTableBorder(mPresContext); table = new (mPresContext) nsStyleTableBorder(mPresContext);
if (!parentTable)
parentTable = table;
// border-collapse: enum, inherit // border-collapse: enum, inherit
if (eCSSUnit_Enumerated == tableData.mBorderCollapse.GetUnit()) { if (eCSSUnit_Enumerated == tableData.mBorderCollapse.GetUnit()) {
@ -4081,6 +4121,9 @@ nsRuleNode::ComputeQuotesData(nsStyleStruct* aStartStruct, const nsCSSStruct& aD
const nsStyleQuotes* parentQuotes = nsnull; const nsStyleQuotes* parentQuotes = nsnull;
PRBool inherited = aInherited; PRBool inherited = aInherited;
if (parentContext)
parentQuotes = NS_STATIC_CAST(const nsStyleQuotes*,
parentContext->GetStyleData(eStyleStruct_Quotes));
if (aStartStruct) if (aStartStruct)
// We only need to compute the delta between this computed data and our // We only need to compute the delta between this computed data and our
// computed data. // computed data.
@ -4090,16 +4133,15 @@ nsRuleNode::ComputeQuotesData(nsStyleStruct* aStartStruct, const nsCSSStruct& aD
// No question. We will have to inherit. Go ahead and init // No question. We will have to inherit. Go ahead and init
// with inherited vals from parent. // with inherited vals from parent.
inherited = PR_TRUE; inherited = PR_TRUE;
if (parentContext)
parentQuotes = NS_STATIC_CAST(const nsStyleQuotes*,
parentContext->GetStyleData(eStyleStruct_Quotes));
if (parentQuotes) if (parentQuotes)
quotes = new (mPresContext) nsStyleQuotes(*parentQuotes); quotes = new (mPresContext) nsStyleQuotes(*parentQuotes);
} }
} }
if (!quotes) if (!quotes)
parentQuotes = quotes = new (mPresContext) nsStyleQuotes(); quotes = new (mPresContext) nsStyleQuotes();
if (!parentQuotes)
parentQuotes = quotes;
// quotes: [string string]+, none, inherit // quotes: [string string]+, none, inherit
PRUint32 count; PRUint32 count;
@ -4180,7 +4222,6 @@ nsRuleNode::ComputeXULData(nsStyleStruct* aStartStruct, const nsCSSStruct& aData
xul = new (mPresContext) nsStyleXUL(); xul = new (mPresContext) nsStyleXUL();
const nsStyleXUL* parentXUL = xul; const nsStyleXUL* parentXUL = xul;
if (parentContext) if (parentContext)
parentXUL = NS_STATIC_CAST(const nsStyleXUL*, parentXUL = NS_STATIC_CAST(const nsStyleXUL*,
parentContext->GetStyleData(eStyleStruct_XUL)); parentContext->GetStyleData(eStyleStruct_XUL));

Просмотреть файл

@ -69,8 +69,7 @@ class nsStyleContext : public nsIStyleContext
{ {
public: public:
nsStyleContext(nsIStyleContext* aParent, nsIAtom* aPseudoTag, nsStyleContext(nsIStyleContext* aParent, nsIAtom* aPseudoTag,
nsRuleNode* aRuleNode, nsRuleNode* aRuleNode, nsIPresContext* aPresContext);
nsIPresContext* aPresContext);
virtual ~nsStyleContext(); virtual ~nsStyleContext();
void* operator new(size_t sz, nsIPresContext* aPresContext); void* operator new(size_t sz, nsIPresContext* aPresContext);
@ -130,32 +129,39 @@ protected:
nsStyleContext* mPrevSibling; nsStyleContext* mPrevSibling;
nsStyleContext* mNextSibling; nsStyleContext* mNextSibling;
nsIAtom* mPseudoTag; // If this style context is for a pseudo-element, the pseudo-element
// atom. Otherwise, null.
nsCOMPtr<nsIAtom> mPseudoTag;
PRUint32 mBits; // Which structs are inherited from the parent context.
nsRuleNode* mRuleNode; nsRuleNode* mRuleNode;
// |mCachedStyleData| points to both structs that are owned by this
// style context and structs that are owned by one of this style
// context's ancestors (which are indirectly owned since this style
// context owns a reference to its parent). If the bit in |mBits| is
// set for a struct, that means that the pointer for that struct is
// owned by an ancestor rather than by this style context.
nsCachedStyleData mCachedStyleData; // Our cached style data. nsCachedStyleData mCachedStyleData; // Our cached style data.
PRUint32 mBits; // Which structs are inherited from the
// parent context.
}; };
static PRInt32 gLastDataCode;
nsStyleContext::nsStyleContext(nsIStyleContext* aParent, nsStyleContext::nsStyleContext(nsIStyleContext* aParent,
nsIAtom* aPseudoTag, nsIAtom* aPseudoTag,
nsRuleNode* aRuleNode, nsRuleNode* aRuleNode,
nsIPresContext* aPresContext) nsIPresContext* aPresContext)
: mParent((nsStyleContext*)aParent), : mParent((nsStyleContext*)aParent),
mChild(nsnull), mChild(nsnull),
mEmptyChild(nsnull), mEmptyChild(nsnull),
mPseudoTag(aPseudoTag), mPseudoTag(aPseudoTag),
mBits(0), mRuleNode(aRuleNode),
mRuleNode(aRuleNode) mBits(0)
{ {
NS_INIT_REFCNT(); NS_INIT_ISUPPORTS();
NS_IF_ADDREF(mPseudoTag);
mNextSibling = this; mNextSibling = this;
mPrevSibling = this; mPrevSibling = this;
if (nsnull != mParent) { if (mParent) {
NS_ADDREF(mParent); NS_ADDREF(mParent);
mParent->AppendChild(this); mParent->AppendChild(this);
} }
@ -172,8 +178,6 @@ nsStyleContext::~nsStyleContext()
NS_RELEASE(mParent); NS_RELEASE(mParent);
} }
NS_IF_RELEASE(mPseudoTag);
// Free up our data structs. // Free up our data structs.
if (mCachedStyleData.mResetData || mCachedStyleData.mInheritedData) { if (mCachedStyleData.mResetData || mCachedStyleData.mInheritedData) {
nsCOMPtr<nsIPresContext> presContext; nsCOMPtr<nsIPresContext> presContext;
@ -184,27 +188,7 @@ nsStyleContext::~nsStyleContext()
NS_IMPL_ADDREF(nsStyleContext) NS_IMPL_ADDREF(nsStyleContext)
NS_IMPL_RELEASE_WITH_DESTROY(nsStyleContext, Destroy()) NS_IMPL_RELEASE_WITH_DESTROY(nsStyleContext, Destroy())
NS_IMPL_QUERY_INTERFACE1(nsStyleContext, nsIStyleContext)
NS_IMETHODIMP
nsStyleContext::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
NS_PRECONDITION(nsnull != aInstancePtr, "null pointer");
if (nsnull == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
if (aIID.Equals(NS_GET_IID(nsIStyleContext))) {
*aInstancePtr = (void*)(nsIStyleContext*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*) (nsISupports*)(nsIStyleContext*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
nsIStyleContext* nsStyleContext::GetParent(void) const nsIStyleContext* nsStyleContext::GetParent(void) const
{ {
@ -396,10 +380,10 @@ nsStyleContext::GetBorderPaddingFor(nsStyleBorderPadding& aBorderPadding)
const nsStyleBorder* borderData = (const nsStyleBorder*)GetStyleData(eStyleStruct_Border); const nsStyleBorder* borderData = (const nsStyleBorder*)GetStyleData(eStyleStruct_Border);
const nsStylePadding* paddingData = (const nsStylePadding*)GetStyleData(eStyleStruct_Padding); const nsStylePadding* paddingData = (const nsStylePadding*)GetStyleData(eStyleStruct_Padding);
if (borderData->GetBorder(border)) { if (borderData->GetBorder(border)) {
if (paddingData->GetPadding(padding)) { if (paddingData->GetPadding(padding)) {
border += padding; border += padding;
aBorderPadding.SetBorderPadding(border); aBorderPadding.SetBorderPadding(border);
} }
} }
return NS_OK; return NS_OK;
@ -459,15 +443,18 @@ nsStyleContext::SetStyle(nsStyleStructID aSID, const nsStyleStruct& aStruct)
nsresult result = NS_OK; nsresult result = NS_OK;
PRBool isReset = mCachedStyleData.IsReset(aSID); PRBool isReset = mCachedStyleData.IsReset(aSID);
if (isReset && !mCachedStyleData.mResetData) { if (isReset) {
nsCOMPtr<nsIPresContext> presContext; if (!mCachedStyleData.mResetData) {
mRuleNode->GetPresContext(getter_AddRefs(presContext)); nsCOMPtr<nsIPresContext> presContext;
mCachedStyleData.mResetData = new (presContext.get()) nsResetStyleData; mRuleNode->GetPresContext(getter_AddRefs(presContext));
} mCachedStyleData.mResetData = new (presContext.get()) nsResetStyleData;
else if (!isReset && !mCachedStyleData.mInheritedData) { }
nsCOMPtr<nsIPresContext> presContext; } else {
mRuleNode->GetPresContext(getter_AddRefs(presContext)); if (!mCachedStyleData.mInheritedData) {
mCachedStyleData.mInheritedData = new (presContext.get()) nsInheritedStyleData; nsCOMPtr<nsIPresContext> presContext;
mRuleNode->GetPresContext(getter_AddRefs(presContext));
mCachedStyleData.mInheritedData = new (presContext.get()) nsInheritedStyleData;
}
} }
switch (aSID) { switch (aSID) {
@ -597,7 +584,7 @@ nsStyleContext::ClearStyleData(nsIPresContext* aPresContext, nsIStyleRule* aRule
mCachedStyleData.Destroy(mBits, aPresContext); mCachedStyleData.Destroy(mBits, aPresContext);
mBits = 0; // Clear all bits. mBits = 0; // Clear all bits.
aRule = nsnull; aRule = nsnull; // Force all structs to be blown away in the children.
} }
ApplyStyleFixups(aPresContext); ApplyStyleFixups(aPresContext);
@ -910,7 +897,7 @@ void nsStyleContext::List(FILE* out, PRInt32 aIndent)
PRInt32 ix; PRInt32 ix;
for (ix = aIndent; --ix >= 0; ) fputs(" ", out); for (ix = aIndent; --ix >= 0; ) fputs(" ", out);
fprintf(out, "%p(%d) ", (void*)this, mRefCnt); fprintf(out, "%p(%d) ", (void*)this, mRefCnt);
if (nsnull != mPseudoTag) { if (mPseudoTag) {
nsAutoString buffer; nsAutoString buffer;
mPseudoTag->ToString(buffer); mPseudoTag->ToString(buffer);
fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out); fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out);
@ -988,7 +975,7 @@ void nsStyleContext::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize)
// get the size of an empty instance and add to the sizeof handler // get the size of an empty instance and add to the sizeof handler
aSize = sizeof(*this); aSize = sizeof(*this);
// add in the size of the member mPseudoTag // add in the size of the member mPseudoTag
if(mPseudoTag){ if (mPseudoTag){
mPseudoTag->SizeOf(aSizeOfHandler, &localSize); mPseudoTag->SizeOf(aSizeOfHandler, &localSize);
aSize += localSize; aSize += localSize;
} }