Introduce TreeMatchContext for additional output from SelectorMatchesTree. (Bug 147777) r=bzbarsky

This commit is contained in:
L. David Baron 2010-04-02 18:58:26 -07:00
parent b33a804541
commit 9b0db9e924

View file

@ -1215,6 +1215,27 @@ RuleProcessorData::GetNthIndex(PRBool aIsOfType, PRBool aIsFromEnd,
return result;
}
/**
* A |TreeMatchContext| has data about matching a selector (containing
* combinators) against a node and the tree that that node is in. It
* contains both input to and output from the matching.
*
* (In contrast, a RuleProcessorData has information needed to match a
* selector (without combinators) against a single node; it only
* has input to the matching.)
*/
struct TreeMatchContext {
// Is this matching operation for the creation of a style context?
// (If it is, we need to set slow selector bits on nodes indicating
// that certain restyling needs to happen.)
const PRBool mForStyling;
TreeMatchContext(PRBool aForStyling)
: mForStyling(aForStyling)
{
}
};
static PRBool ValueIncludes(const nsSubstring& aValueList,
const nsSubstring& aValue,
const nsStringComparator& aComparator)
@ -1312,7 +1333,7 @@ static PRBool AttrMatchesValue(const nsAttrSelector* aAttrSelector,
}
static PRBool NS_FASTCALL
firstNodeMatches(RuleProcessorData& data, PRBool setNodeFlags,
firstNodeMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::firstNode,
@ -1320,7 +1341,7 @@ firstNodeMatches(RuleProcessorData& data, PRBool setNodeFlags,
nsIContent *firstNode = nsnull;
nsIContent *parent = data.mParentContent;
if (parent) {
if (setNodeFlags)
if (aTreeMatchContext.mForStyling)
parent->SetFlags(NODE_HAS_EDGE_CHILD_SELECTOR);
PRInt32 index = -1;
@ -1334,7 +1355,7 @@ firstNodeMatches(RuleProcessorData& data, PRBool setNodeFlags,
}
static PRBool NS_FASTCALL
lastNodeMatches(RuleProcessorData& data, PRBool setNodeFlags,
lastNodeMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::lastNode,
@ -1342,7 +1363,7 @@ lastNodeMatches(RuleProcessorData& data, PRBool setNodeFlags,
nsIContent *lastNode = nsnull;
nsIContent *parent = data.mParentContent;
if (parent) {
if (setNodeFlags)
if (aTreeMatchContext.mForStyling)
parent->SetFlags(NODE_HAS_EDGE_CHILD_SELECTOR);
PRUint32 index = parent->GetChildCount();
@ -1356,7 +1377,7 @@ lastNodeMatches(RuleProcessorData& data, PRBool setNodeFlags,
}
static inline PRBool
edgeChildMatches(RuleProcessorData& data, PRBool setNodeFlags,
edgeChildMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
PRBool checkFirst, PRBool checkLast)
{
nsIContent *parent = data.mParentContent;
@ -1364,7 +1385,7 @@ edgeChildMatches(RuleProcessorData& data, PRBool setNodeFlags,
return PR_FALSE;
}
if (setNodeFlags)
if (aTreeMatchContext.mForStyling)
parent->SetFlags(NODE_HAS_EDGE_CHILD_SELECTOR);
return (!checkFirst ||
@ -1374,34 +1395,35 @@ edgeChildMatches(RuleProcessorData& data, PRBool setNodeFlags,
}
static PRBool NS_FASTCALL
firstChildMatches(RuleProcessorData& data, PRBool setNodeFlags,
firstChildMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::firstChild,
"Unexpected atom");
return edgeChildMatches(data, setNodeFlags, PR_TRUE, PR_FALSE);
return edgeChildMatches(data, aTreeMatchContext, PR_TRUE, PR_FALSE);
}
static PRBool NS_FASTCALL
lastChildMatches(RuleProcessorData& data, PRBool setNodeFlags,
lastChildMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::lastChild,
"Unexpected atom");
return edgeChildMatches(data, setNodeFlags, PR_FALSE, PR_TRUE);
return edgeChildMatches(data, aTreeMatchContext, PR_FALSE, PR_TRUE);
}
static PRBool NS_FASTCALL
onlyChildMatches(RuleProcessorData& data, PRBool setNodeFlags,
onlyChildMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::onlyChild,
"Unexpected atom");
return edgeChildMatches(data, setNodeFlags, PR_TRUE, PR_TRUE);
return edgeChildMatches(data, aTreeMatchContext, PR_TRUE, PR_TRUE);
}
static inline PRBool
nthChildGenericMatches(RuleProcessorData& data, PRBool setNodeFlags,
nthChildGenericMatches(RuleProcessorData& data,
TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass,
PRBool isOfType, PRBool isFromEnd)
{
@ -1410,7 +1432,7 @@ nthChildGenericMatches(RuleProcessorData& data, PRBool setNodeFlags,
return PR_FALSE;
}
if (setNodeFlags) {
if (aTreeMatchContext.mForStyling) {
if (isFromEnd)
parent->SetFlags(NODE_HAS_SLOW_SELECTOR);
else
@ -1439,47 +1461,49 @@ nthChildGenericMatches(RuleProcessorData& data, PRBool setNodeFlags,
}
static PRBool NS_FASTCALL
nthChildMatches(RuleProcessorData& data, PRBool setNodeFlags,
nthChildMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::nthChild,
"Unexpected atom");
return nthChildGenericMatches(data, setNodeFlags, pseudoClass,
return nthChildGenericMatches(data, aTreeMatchContext, pseudoClass,
PR_FALSE, PR_FALSE);
}
static PRBool NS_FASTCALL
nthLastChildMatches(RuleProcessorData& data, PRBool setNodeFlags,
nthLastChildMatches(RuleProcessorData& data,
TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::nthLastChild,
"Unexpected atom");
return nthChildGenericMatches(data, setNodeFlags, pseudoClass,
return nthChildGenericMatches(data, aTreeMatchContext, pseudoClass,
PR_FALSE, PR_TRUE);
}
static PRBool NS_FASTCALL
nthOfTypeMatches(RuleProcessorData& data, PRBool setNodeFlags,
nthOfTypeMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::nthOfType,
"Unexpected atom");
return nthChildGenericMatches(data, setNodeFlags, pseudoClass,
return nthChildGenericMatches(data, aTreeMatchContext, pseudoClass,
PR_TRUE, PR_FALSE);
}
static PRBool NS_FASTCALL
nthLastOfTypeMatches(RuleProcessorData& data, PRBool setNodeFlags,
nthLastOfTypeMatches(RuleProcessorData& data,
TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::nthLastOfType,
"Unexpected atom");
return nthChildGenericMatches(data, setNodeFlags, pseudoClass,
return nthChildGenericMatches(data, aTreeMatchContext, pseudoClass,
PR_TRUE, PR_TRUE);
}
static inline PRBool
edgeOfTypeMatches(RuleProcessorData& data, PRBool setNodeFlags,
edgeOfTypeMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
PRBool checkFirst, PRBool checkLast)
{
nsIContent *parent = data.mParentContent;
@ -1487,7 +1511,7 @@ edgeOfTypeMatches(RuleProcessorData& data, PRBool setNodeFlags,
return PR_FALSE;
}
if (setNodeFlags) {
if (aTreeMatchContext.mForStyling) {
if (checkLast)
parent->SetFlags(NODE_HAS_SLOW_SELECTOR);
else
@ -1501,41 +1525,42 @@ edgeOfTypeMatches(RuleProcessorData& data, PRBool setNodeFlags,
}
static PRBool NS_FASTCALL
firstOfTypeMatches(RuleProcessorData& data, PRBool setNodeFlags,
firstOfTypeMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::firstOfType,
"Unexpected atom");
return edgeOfTypeMatches(data, setNodeFlags, PR_TRUE, PR_FALSE);
return edgeOfTypeMatches(data, aTreeMatchContext, PR_TRUE, PR_FALSE);
}
static PRBool NS_FASTCALL
lastOfTypeMatches(RuleProcessorData& data, PRBool setNodeFlags,
lastOfTypeMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::lastOfType,
"Unexpected atom");
return edgeOfTypeMatches(data, setNodeFlags, PR_FALSE, PR_TRUE);
return edgeOfTypeMatches(data, aTreeMatchContext, PR_FALSE, PR_TRUE);
}
static PRBool NS_FASTCALL
onlyOfTypeMatches(RuleProcessorData& data, PRBool setNodeFlags,
onlyOfTypeMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::onlyOfType,
"Unexpected atom");
return edgeOfTypeMatches(data, setNodeFlags, PR_TRUE, PR_TRUE);
return edgeOfTypeMatches(data, aTreeMatchContext, PR_TRUE, PR_TRUE);
}
static inline PRBool
checkGenericEmptyMatches(RuleProcessorData& data, PRBool setNodeFlags,
checkGenericEmptyMatches(RuleProcessorData& data,
TreeMatchContext& aTreeMatchContext,
PRBool isWhitespaceSignificant)
{
nsIContent *child = nsnull;
nsIContent *element = data.mContent;
PRInt32 index = -1;
if (setNodeFlags)
if (aTreeMatchContext.mForStyling)
element->SetFlags(NODE_HAS_EMPTY_SELECTOR);
do {
@ -1547,26 +1572,27 @@ checkGenericEmptyMatches(RuleProcessorData& data, PRBool setNodeFlags,
}
static PRBool NS_FASTCALL
emptyMatches(RuleProcessorData& data, PRBool setNodeFlags,
emptyMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::empty,
"Unexpected atom");
return checkGenericEmptyMatches(data, setNodeFlags, PR_TRUE);
return checkGenericEmptyMatches(data, aTreeMatchContext, PR_TRUE);
}
static PRBool NS_FASTCALL
mozOnlyWhitespaceMatches(RuleProcessorData& data, PRBool setNodeFlags,
mozOnlyWhitespaceMatches(RuleProcessorData& data,
TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozOnlyWhitespace,
"Unexpected atom");
return checkGenericEmptyMatches(data, setNodeFlags, PR_FALSE);
return checkGenericEmptyMatches(data, aTreeMatchContext, PR_FALSE);
}
static PRBool NS_FASTCALL
mozEmptyExceptChildrenWithLocalnameMatches(RuleProcessorData& data,
PRBool setNodeFlags,
TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom ==
@ -1577,7 +1603,7 @@ mozEmptyExceptChildrenWithLocalnameMatches(RuleProcessorData& data,
nsIContent *element = data.mContent;
PRInt32 index = -1;
if (setNodeFlags)
if (aTreeMatchContext.mForStyling)
element->SetFlags(NODE_HAS_SLOW_SELECTOR);
do {
@ -1590,7 +1616,8 @@ mozEmptyExceptChildrenWithLocalnameMatches(RuleProcessorData& data,
}
static PRBool NS_FASTCALL
mozSystemMetricMatches(RuleProcessorData& data, PRBool setNodeFlags,
mozSystemMetricMatches(RuleProcessorData& data,
TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozSystemMetric,
@ -1601,7 +1628,8 @@ mozSystemMetricMatches(RuleProcessorData& data, PRBool setNodeFlags,
}
static PRBool NS_FASTCALL
mozHasHandlerRefMatches(RuleProcessorData& data, PRBool setNodeFlags,
mozHasHandlerRefMatches(RuleProcessorData& data,
TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozHasHandlerRef,
@ -1623,7 +1651,7 @@ mozHasHandlerRefMatches(RuleProcessorData& data, PRBool setNodeFlags,
}
static PRBool NS_FASTCALL
rootMatches(RuleProcessorData& data, PRBool setNodeFlags,
rootMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::root,
@ -1633,7 +1661,8 @@ rootMatches(RuleProcessorData& data, PRBool setNodeFlags,
}
static PRBool NS_FASTCALL
mozBoundElementMatches(RuleProcessorData& data, PRBool setNodeFlags,
mozBoundElementMatches(RuleProcessorData& data,
TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozBoundElement,
@ -1645,7 +1674,7 @@ mozBoundElementMatches(RuleProcessorData& data, PRBool setNodeFlags,
}
static PRBool NS_FASTCALL
langMatches(RuleProcessorData& data, PRBool setNodeFlags,
langMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::lang,
@ -1698,7 +1727,7 @@ langMatches(RuleProcessorData& data, PRBool setNodeFlags,
}
static PRBool NS_FASTCALL
mozIsHTMLMatches(RuleProcessorData& data, PRBool setNodeFlags,
mozIsHTMLMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozIsHTML,
@ -1707,7 +1736,8 @@ mozIsHTMLMatches(RuleProcessorData& data, PRBool setNodeFlags,
}
static PRBool NS_FASTCALL
mozLocaleDirMatches(RuleProcessorData& data, PRBool setNodeFlags,
mozLocaleDirMatches(RuleProcessorData& data,
TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozLocaleDir,
@ -1723,7 +1753,7 @@ mozLocaleDirMatches(RuleProcessorData& data, PRBool setNodeFlags,
}
static PRBool NS_FASTCALL
mozLWThemeMatches(RuleProcessorData& data, PRBool setNodeFlags,
mozLWThemeMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozLWTheme,
@ -1733,7 +1763,8 @@ mozLWThemeMatches(RuleProcessorData& data, PRBool setNodeFlags,
}
static PRBool NS_FASTCALL
mozLWThemeBrightTextMatches(RuleProcessorData& data, PRBool setNodeFlags,
mozLWThemeBrightTextMatches(RuleProcessorData& data,
TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom ==
@ -1744,7 +1775,8 @@ mozLWThemeBrightTextMatches(RuleProcessorData& data, PRBool setNodeFlags,
}
static PRBool NS_FASTCALL
mozLWThemeDarkTextMatches(RuleProcessorData& data, PRBool setNodeFlags,
mozLWThemeDarkTextMatches(RuleProcessorData& data,
TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom ==
@ -1755,7 +1787,8 @@ mozLWThemeDarkTextMatches(RuleProcessorData& data, PRBool setNodeFlags,
}
static PRBool NS_FASTCALL
mozWindowInactiveMatches(RuleProcessorData& data, PRBool setNodeFlags,
mozWindowInactiveMatches(RuleProcessorData& data,
TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_PRECONDITION(pseudoClass->mAtom ==
@ -1765,7 +1798,7 @@ mozWindowInactiveMatches(RuleProcessorData& data, PRBool setNodeFlags,
}
static PRBool NS_FASTCALL
notPseudoMatches(RuleProcessorData& data, PRBool setNodeFlags,
notPseudoMatches(RuleProcessorData& data, TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass)
{
NS_NOTREACHED("Why did this get called?");
@ -1773,7 +1806,8 @@ notPseudoMatches(RuleProcessorData& data, PRBool setNodeFlags,
}
typedef PRBool
(NS_FASTCALL * PseudoClassMatcher)(RuleProcessorData&, PRBool setNodeFlags,
(NS_FASTCALL * PseudoClassMatcher)(RuleProcessorData&,
TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass);
// Only one of mFunc or mBits will be set; the other will be null or 0
// respectively. We could use a union, but then we'd still need to
@ -1807,8 +1841,6 @@ PR_STATIC_ASSERT(NS_ARRAY_LENGTH(sPseudoClassInfo) >
// it really is (e.g., determining that a :hover:active rule no longer matches
// when both states are unset).
// If |aForStyling| is false, we shouldn't mark slow-selector bits on nodes.
// |aDependence| has two functions:
// * when non-null, it indicates that we're processing a negation,
// which is done only when SelectorMatches calls itself recursively
@ -1817,7 +1849,7 @@ PR_STATIC_ASSERT(NS_ARRAY_LENGTH(sPseudoClassInfo) >
static PRBool SelectorMatches(RuleProcessorData &data,
nsCSSSelector* aSelector,
PRInt32 aStateMask, // states NOT to test
PRBool aForStyling,
TreeMatchContext& aTreeMatchContext,
PRBool* const aDependence = nsnull)
{
@ -1897,17 +1929,16 @@ static PRBool SelectorMatches(RuleProcessorData &data,
// generally quick to test, and thus earlier). If they were later,
// we'd probably avoid setting those bits in more cases where setting
// them is unnecessary.
NS_ASSERTION(aStateMask == 0 || !aForStyling,
"aForStyling must be false if we're just testing for "
NS_ASSERTION(aStateMask == 0 || !aTreeMatchContext.mForStyling,
"mForStyling must be false if we're just testing for "
"state-dependence");
const PRBool setNodeFlags = aForStyling;
// test for pseudo class match
for (nsPseudoClassList* pseudoClass = aSelector->mPseudoClassList;
pseudoClass; pseudoClass = pseudoClass->mNext) {
const PseudoClassInfo& info = sPseudoClassInfo[pseudoClass->mType];
if (info.mFunc) {
if (!(*info.mFunc)(data, setNodeFlags, pseudoClass)) {
if (!(*info.mFunc)(data, aTreeMatchContext, pseudoClass)) {
return PR_FALSE;
}
} else {
@ -2026,7 +2057,7 @@ static PRBool SelectorMatches(RuleProcessorData &data,
result && negation; negation = negation->mNegations) {
PRBool dependence = PR_FALSE;
result = !SelectorMatches(data, negation, aStateMask,
aForStyling, &dependence);
aTreeMatchContext, &dependence);
// If the selector does match due to the dependence on aStateMask,
// then we want to keep result true so that the final result of
// SelectorMatches is true. Doing so tells StateEnumFunc that
@ -2048,7 +2079,7 @@ static PRBool SelectorMatches(RuleProcessorData &data,
static PRBool SelectorMatchesTree(RuleProcessorData& aPrevData,
nsCSSSelector* aSelector,
PRBool aForStyling)
TreeMatchContext& aTreeMatchContext)
{
nsCSSSelector* selector = aSelector;
RuleProcessorData* prevdata = &aPrevData;
@ -2071,7 +2102,7 @@ static PRBool SelectorMatchesTree(RuleProcessorData& aPrevData,
nsIContent* content = prevdata->mContent;
nsIContent* parent = prevdata->mParentContent;
if (parent) {
if (aForStyling)
if (aTreeMatchContext.mForStyling)
parent->SetFlags(NODE_HAS_SLOW_SELECTOR_NOAPPEND);
PRInt32 index = parent->IndexOf(content);
@ -2107,7 +2138,7 @@ static PRBool SelectorMatchesTree(RuleProcessorData& aPrevData,
if (! data) {
return PR_FALSE;
}
if (SelectorMatches(*data, selector, 0, aForStyling)) {
if (SelectorMatches(*data, selector, 0, aTreeMatchContext)) {
// to avoid greedy matching, we need to recur if this is a
// descendant or general sibling combinator and the next
// combinator is different, but we can make an exception for
@ -2127,7 +2158,7 @@ static PRBool SelectorMatchesTree(RuleProcessorData& aPrevData,
// it tests from the top of the content tree, down. This
// doesn't matter much for performance since most selectors
// don't match. (If most did, it might be faster...)
if (SelectorMatchesTree(*data, selector, aForStyling)) {
if (SelectorMatchesTree(*data, selector, aTreeMatchContext)) {
return PR_TRUE;
}
}
@ -2150,9 +2181,10 @@ static void ContentEnumFunc(nsICSSStyleRule* aRule, nsCSSSelector* aSelector,
{
RuleProcessorData* data = (RuleProcessorData*)aData;
if (SelectorMatches(*data, aSelector, 0, PR_TRUE)) {
TreeMatchContext treeContext(PR_TRUE);
if (SelectorMatches(*data, aSelector, 0, treeContext)) {
nsCSSSelector *next = aSelector->mNext;
if (!next || SelectorMatchesTree(*data, next, PR_TRUE)) {
if (!next || SelectorMatchesTree(*data, next, treeContext)) {
// for performance, require that every implementation of
// nsICSSStyleRule return the same pointer for nsIStyleRule (why
// would anything multiply inherit nsIStyleRule anyway?)
@ -2300,9 +2332,10 @@ nsCSSRuleProcessor::HasStateDependentStyle(StateRuleProcessorData* aData)
// If hint already includes all the bits of possibleChange,
// don't bother calling SelectorMatches, since even if it returns false
// hint won't change.
TreeMatchContext treeContext(PR_FALSE);
if ((possibleChange & ~hint) &&
SelectorMatches(*aData, selector, aData->mStateMask, PR_FALSE) &&
SelectorMatchesTree(*aData, selector->mNext, PR_FALSE)) {
SelectorMatches(*aData, selector, aData->mStateMask, treeContext) &&
SelectorMatchesTree(*aData, selector->mNext, treeContext)) {
hint = nsRestyleHint(hint | possibleChange);
}
}
@ -2338,9 +2371,10 @@ AttributeEnumFunc(nsCSSSelector* aSelector, AttributeEnumData* aData)
// If enumData->change already includes all the bits of possibleChange, don't
// bother calling SelectorMatches, since even if it returns false
// enumData->change won't change.
TreeMatchContext treeContext(PR_FALSE);
if ((possibleChange & ~(aData->change)) &&
SelectorMatches(*data, aSelector, 0, PR_FALSE) &&
SelectorMatchesTree(*data, aSelector->mNext, PR_FALSE)) {
SelectorMatches(*data, aSelector, 0, treeContext) &&
SelectorMatchesTree(*data, aSelector->mNext, treeContext)) {
aData->change = nsRestyleHint(aData->change | possibleChange);
}
}
@ -2881,9 +2915,10 @@ nsCSSRuleProcessor::SelectorListMatches(RuleProcessorData& aData,
nsCSSSelector* sel = aSelectorList->mSelectors;
NS_ASSERTION(sel, "Should have *some* selectors");
NS_ASSERTION(!sel->IsPseudoElement(), "Shouldn't have been called");
if (SelectorMatches(aData, sel, 0, PR_FALSE)) {
TreeMatchContext treeContext(PR_FALSE);
if (SelectorMatches(aData, sel, 0, treeContext)) {
nsCSSSelector* next = sel->mNext;
if (!next || SelectorMatchesTree(aData, next, PR_FALSE)) {
if (!next || SelectorMatchesTree(aData, next, treeContext)) {
return PR_TRUE;
}
}