Bug 1300374: child index selectors should match without a parent element. r?heycam
MozReview-Commit-ID: L7aj7itX8zh
--- a/layout/style/nsCSSRuleProcessor.cpp
+++ b/layout/style/nsCSSRuleProcessor.cpp
@@ -1458,44 +1458,36 @@ static bool AttrMatchesValue(const nsAtt
return false;
}
}
static inline bool
edgeChildMatches(Element* aElement, TreeMatchContext& aTreeMatchContext,
bool checkFirst, bool checkLast)
{
- nsIContent *parent = aElement->GetParent();
- if (!parent) {
- return false;
- }
-
- if (aTreeMatchContext.mForStyling)
+ nsIContent* parent = aElement->GetParent();
+ if (parent && aTreeMatchContext.mForStyling)
parent->SetFlags(NODE_HAS_EDGE_CHILD_SELECTOR);
return (!checkFirst ||
aTreeMatchContext.mNthIndexCache.
GetNthIndex(aElement, false, false, true) == 1) &&
(!checkLast ||
aTreeMatchContext.mNthIndexCache.
GetNthIndex(aElement, false, true, true) == 1);
}
static inline bool
nthChildGenericMatches(Element* aElement,
TreeMatchContext& aTreeMatchContext,
nsPseudoClassList* pseudoClass,
bool isOfType, bool isFromEnd)
{
- nsIContent *parent = aElement->GetParent();
- if (!parent) {
- return false;
- }
-
- if (aTreeMatchContext.mForStyling) {
+ nsIContent* parent = aElement->GetParent();
+ if (parent && aTreeMatchContext.mForStyling) {
if (isFromEnd)
parent->SetFlags(NODE_HAS_SLOW_SELECTOR);
else
parent->SetFlags(NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS);
}
const int32_t index = aTreeMatchContext.mNthIndexCache.
GetNthIndex(aElement, isOfType, isFromEnd, false);
@@ -1522,21 +1514,17 @@ nthChildGenericMatches(Element* aElement
a * n == indexMinusB;
}
static inline bool
edgeOfTypeMatches(Element* aElement, TreeMatchContext& aTreeMatchContext,
bool checkFirst, bool checkLast)
{
nsIContent *parent = aElement->GetParent();
- if (!parent) {
- return false;
- }
-
- if (aTreeMatchContext.mForStyling) {
+ if (parent && aTreeMatchContext.mForStyling) {
if (checkLast)
parent->SetFlags(NODE_HAS_SLOW_SELECTOR);
else
parent->SetFlags(NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS);
}
return (!checkFirst ||
aTreeMatchContext.mNthIndexCache.
@@ -1938,17 +1926,17 @@ static bool SelectorMatches(Element* aEl
case CSSPseudoClassType::lastNode:
{
nsIContent *lastNode = nullptr;
nsIContent *parent = aElement->GetParent();
if (parent) {
if (aTreeMatchContext.mForStyling)
parent->SetFlags(NODE_HAS_EDGE_CHILD_SELECTOR);
-
+
uint32_t index = parent->GetChildCount();
do {
lastNode = parent->GetChildAt(--index);
// stop at first non-comment and non-whitespace node
} while (lastNode &&
!IsSignificantChild(lastNode, true, false));
}
if (aElement != lastNode) {
--- a/layout/style/nsNthIndexCache.cpp
+++ b/layout/style/nsNthIndexCache.cpp
@@ -68,42 +68,40 @@ nsNthIndexCache::IndexDeterminedFromPrev
return false;
}
int32_t
nsNthIndexCache::GetNthIndex(Element* aChild, bool aIsOfType,
bool aIsFromEnd, bool aCheckEdgeOnly)
{
- NS_ASSERTION(aChild->GetParent(), "caller should check GetParent()");
-
if (aChild->IsRootOfAnonymousSubtree()) {
return 0;
}
- Cache &cache = mCaches[aIsOfType][aIsFromEnd];
+ Cache& cache = mCaches[aIsOfType][aIsFromEnd];
if (!cache.initialized() && !cache.init()) {
// Give up and just don't match.
return 0;
}
Cache::AddPtr entry = cache.lookupForAdd(aChild);
// Default the value to -2 when adding
if (!entry && !cache.add(entry, aChild, -2)) {
// No good; don't match.
return 0;
}
- int32_t &slot = entry->value();
+ int32_t& slot = entry->value();
if (slot != -2 && (slot != -1 || aCheckEdgeOnly)) {
return slot;
}
-
+
int32_t result = 1;
if (aCheckEdgeOnly) {
// The caller only cares whether or not the result is 1, so we can
// stop as soon as we see any other elements that match us.
if (aIsFromEnd) {
for (nsIContent *cur = aChild->GetNextSibling();
cur;
cur = cur->GetNextSibling()) {