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