Make what FindChildWithRules does actually be an MRU cache, and condense some if-else chains over mChild and mEmptyChild. b=335733 r+sr=bzbarsky
git-svn-id: svn://10.0.0.236/trunk@195616 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -81,14 +81,15 @@ nsStyleContext::nsStyleContext(nsStyleContext* aParent,
|
||||
mPrevSibling = this;
|
||||
if (mParent) {
|
||||
mParent->AddRef();
|
||||
mParent->AppendChild(this);
|
||||
mParent->AddChild(this);
|
||||
}
|
||||
|
||||
ApplyStyleFixups(aPresContext);
|
||||
|
||||
NS_ASSERTION(NS_STYLE_INHERIT_MASK &
|
||||
(1 << PRInt32(nsStyleStructID_Length - 1)) != 0,
|
||||
#define eStyleStruct_LastItem (nsStyleStructID_Length - 1)
|
||||
NS_ASSERTION(NS_STYLE_INHERIT_MASK & NS_STYLE_INHERIT_BIT(LastItem),
|
||||
"NS_STYLE_INHERIT_MASK must be bigger, and other bits shifted");
|
||||
#undef eStyleStruct_LastItem
|
||||
}
|
||||
|
||||
nsStyleContext::~nsStyleContext()
|
||||
@@ -111,61 +112,41 @@ nsStyleContext::~nsStyleContext()
|
||||
}
|
||||
}
|
||||
|
||||
void nsStyleContext::AppendChild(nsStyleContext* aChild)
|
||||
void nsStyleContext::AddChild(nsStyleContext* aChild)
|
||||
{
|
||||
if (aChild->mRuleNode->IsRoot()) {
|
||||
// The child matched no rules.
|
||||
if (!mEmptyChild) {
|
||||
mEmptyChild = aChild;
|
||||
}
|
||||
else {
|
||||
aChild->mNextSibling = mEmptyChild;
|
||||
aChild->mPrevSibling = mEmptyChild->mPrevSibling;
|
||||
mEmptyChild->mPrevSibling->mNextSibling = aChild;
|
||||
mEmptyChild->mPrevSibling = aChild;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!mChild) {
|
||||
mChild = aChild;
|
||||
}
|
||||
else {
|
||||
aChild->mNextSibling = mChild;
|
||||
aChild->mPrevSibling = mChild->mPrevSibling;
|
||||
mChild->mPrevSibling->mNextSibling = aChild;
|
||||
mChild->mPrevSibling = aChild;
|
||||
}
|
||||
NS_ASSERTION(aChild->mPrevSibling == aChild &&
|
||||
aChild->mNextSibling == aChild,
|
||||
"child already in a child list");
|
||||
|
||||
nsStyleContext **list = aChild->mRuleNode->IsRoot() ? &mEmptyChild : &mChild;
|
||||
|
||||
// Insert at the beginning of the list. See also FindChildWithRules.
|
||||
if (*list) {
|
||||
// Link into existing elements, if there are any.
|
||||
aChild->mNextSibling = (*list);
|
||||
aChild->mPrevSibling = (*list)->mPrevSibling;
|
||||
(*list)->mPrevSibling->mNextSibling = aChild;
|
||||
(*list)->mPrevSibling = aChild;
|
||||
}
|
||||
(*list) = aChild;
|
||||
}
|
||||
|
||||
void nsStyleContext::RemoveChild(nsStyleContext* aChild)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aChild && this == aChild->mParent, "bad argument");
|
||||
|
||||
if (aChild->mRuleNode->IsRoot()) { // is empty
|
||||
if (aChild->mPrevSibling != aChild) { // has siblings
|
||||
if (mEmptyChild == aChild) {
|
||||
mEmptyChild = mEmptyChild->mNextSibling;
|
||||
}
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(mEmptyChild == aChild, "bad sibling pointers");
|
||||
mEmptyChild = nsnull;
|
||||
}
|
||||
}
|
||||
else { // isn't empty
|
||||
if (aChild->mPrevSibling != aChild) { // has siblings
|
||||
if (mChild == aChild) {
|
||||
mChild = mChild->mNextSibling;
|
||||
}
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(mChild == aChild, "bad sibling pointers");
|
||||
if (mChild == aChild) {
|
||||
mChild = nsnull;
|
||||
}
|
||||
nsStyleContext **list = aChild->mRuleNode->IsRoot() ? &mEmptyChild : &mChild;
|
||||
|
||||
if (aChild->mPrevSibling != aChild) { // has siblings
|
||||
if ((*list) == aChild) {
|
||||
(*list) = (*list)->mNextSibling;
|
||||
}
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION((*list) == aChild, "bad sibling pointers");
|
||||
(*list) = nsnull;
|
||||
}
|
||||
|
||||
aChild->mPrevSibling->mNextSibling = aChild->mNextSibling;
|
||||
aChild->mNextSibling->mPrevSibling = aChild->mPrevSibling;
|
||||
aChild->mNextSibling = aChild;
|
||||
@@ -179,45 +160,35 @@ nsStyleContext::FindChildWithRules(const nsIAtom* aPseudoTag,
|
||||
PRUint32 threshold = 10; // The # of siblings we're willing to examine
|
||||
// before just giving this whole thing up.
|
||||
|
||||
nsStyleContext* aResult = nsnull;
|
||||
nsStyleContext* result = nsnull;
|
||||
nsStyleContext *list = aRuleNode->IsRoot() ? mEmptyChild : mChild;
|
||||
|
||||
if ((nsnull != mChild) || (nsnull != mEmptyChild)) {
|
||||
nsStyleContext* child;
|
||||
if (aRuleNode->IsRoot()) {
|
||||
if (nsnull != mEmptyChild) {
|
||||
child = mEmptyChild;
|
||||
do {
|
||||
if (aPseudoTag == child->mPseudoTag) {
|
||||
aResult = child;
|
||||
break;
|
||||
}
|
||||
child = child->mNextSibling;
|
||||
threshold--;
|
||||
if (threshold == 0)
|
||||
break;
|
||||
} while (child != mEmptyChild);
|
||||
if (list) {
|
||||
nsStyleContext *child = list;
|
||||
do {
|
||||
if (child->mRuleNode == aRuleNode && child->mPseudoTag == aPseudoTag) {
|
||||
result = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (nsnull != mChild) {
|
||||
child = mChild;
|
||||
|
||||
do {
|
||||
if (child->mRuleNode == aRuleNode && child->mPseudoTag == aPseudoTag) {
|
||||
aResult = child;
|
||||
break;
|
||||
}
|
||||
child = child->mNextSibling;
|
||||
threshold--;
|
||||
if (threshold == 0)
|
||||
break;
|
||||
} while (child != mChild);
|
||||
}
|
||||
child = child->mNextSibling;
|
||||
threshold--;
|
||||
if (threshold == 0)
|
||||
break;
|
||||
} while (child != list);
|
||||
}
|
||||
|
||||
if (aResult)
|
||||
aResult->AddRef();
|
||||
if (result) {
|
||||
if (result != list) {
|
||||
// Move result to the front of the list.
|
||||
RemoveChild(result);
|
||||
AddChild(result);
|
||||
}
|
||||
|
||||
return aResult;
|
||||
// Add reference for the caller.
|
||||
result->AddRef();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -175,14 +175,16 @@ public:
|
||||
#endif
|
||||
|
||||
protected:
|
||||
NS_HIDDEN_(void) AppendChild(nsStyleContext* aChild);
|
||||
NS_HIDDEN_(void) AddChild(nsStyleContext* aChild);
|
||||
NS_HIDDEN_(void) RemoveChild(nsStyleContext* aChild);
|
||||
|
||||
NS_HIDDEN_(void) ApplyStyleFixups(nsPresContext* aPresContext);
|
||||
|
||||
nsStyleContext* mParent;
|
||||
|
||||
// children are maintained in two circular doubly-linked lists,
|
||||
// Children are kept in two circularly-linked lists. The list anchor
|
||||
// is not part of the list (null for empty), and we point to the first
|
||||
// child.
|
||||
// mEmptyChild for children whose rule node is the root rule node, and
|
||||
// mChild for other children. The order of children is not
|
||||
// meaningful.
|
||||
|
||||
Reference in New Issue
Block a user