Index: Source/core/css/SelectorChecker.cpp |
diff --git a/Source/core/css/SelectorChecker.cpp b/Source/core/css/SelectorChecker.cpp |
index 663de6f0d19a4320fbdff2a377933702badb8ca0..14eeb664ce4d30dcf57410742b27f3256c2ccf95 100644 |
--- a/Source/core/css/SelectorChecker.cpp |
+++ b/Source/core/css/SelectorChecker.cpp |
@@ -64,13 +64,13 @@ SelectorChecker::SelectorChecker(Document& document, Mode mode) |
{ |
} |
-static bool matchesCustomPseudoElement(const Element* element, const CSSSelector* selector) |
+static bool matchesCustomPseudoElement(const Element* element, const CSSSelector& selector) |
{ |
ShadowRoot* root = element->containingShadowRoot(); |
if (!root || root->type() != ShadowRoot::UserAgentShadowRoot) |
return false; |
- if (element->shadowPseudoId() != selector->value()) |
+ if (element->shadowPseudoId() != selector.value()) |
return false; |
return true; |
@@ -133,7 +133,7 @@ SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext& con |
if (context.selector->m_match == CSSSelector::PseudoElement) { |
if (context.selector->isCustomPseudoElement()) { |
- if (!matchesCustomPseudoElement(context.element, context.selector)) |
+ if (!matchesCustomPseudoElement(context.element, *context.selector)) |
return SelectorFailsLocally; |
} else if (context.selector->isContentPseudoElement()) { |
if (!context.element->isInShadowTree() || !context.element->isInsertionPoint()) |
@@ -467,33 +467,34 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib |
{ |
ASSERT(context.element); |
Element& element = *context.element; |
- const CSSSelector* const & selector = context.selector; |
- ASSERT(selector); |
+ ASSERT(context.selector); |
+ const CSSSelector& selector = *context.selector; |
+ |
bool elementIsHostInItsShadowTree = isHostInItsShadowTree(element, context.behaviorAtBoundary, context.scope); |
- if (selector->m_match == CSSSelector::Tag) |
- return SelectorChecker::tagMatches(element, selector->tagQName(), elementIsHostInItsShadowTree ? MatchingHostInItsShadowTree : MatchingElement); |
+ if (selector.m_match == CSSSelector::Tag) |
+ return SelectorChecker::tagMatches(element, selector.tagQName(), elementIsHostInItsShadowTree ? MatchingHostInItsShadowTree : MatchingElement); |
- if (selector->m_match == CSSSelector::Class) |
- return element.hasClass() && element.classNames().contains(selector->value()) && !elementIsHostInItsShadowTree; |
+ if (selector.m_match == CSSSelector::Class) |
+ return element.hasClass() && element.classNames().contains(selector.value()) && !elementIsHostInItsShadowTree; |
- if (selector->m_match == CSSSelector::Id) |
- return element.hasID() && element.idForStyleResolution() == selector->value() && !elementIsHostInItsShadowTree; |
+ if (selector.m_match == CSSSelector::Id) |
+ return element.hasID() && element.idForStyleResolution() == selector.value() && !elementIsHostInItsShadowTree; |
- if (selector->isAttributeSelector()) { |
+ if (selector.isAttributeSelector()) { |
if (elementIsHostInItsShadowTree) |
return false; |
- if (!anyAttributeMatches(element, static_cast<CSSSelector::Match>(selector->m_match), *selector)) |
+ if (!anyAttributeMatches(element, static_cast<CSSSelector::Match>(selector.m_match), selector)) |
return false; |
} |
- if (selector->m_match == CSSSelector::PseudoClass) { |
+ if (selector.m_match == CSSSelector::PseudoClass) { |
// Handle :not up front. |
- if (selector->pseudoType() == CSSSelector::PseudoNot) { |
+ if (selector.pseudoType() == CSSSelector::PseudoNot) { |
SelectorCheckingContext subContext(context); |
subContext.isSubSelector = true; |
- ASSERT(selector->selectorList()); |
- for (subContext.selector = selector->selectorList()->first(); subContext.selector; subContext.selector = subContext.selector->tagHistory()) { |
+ ASSERT(selector.selectorList()); |
+ for (subContext.selector = selector.selectorList()->first(); subContext.selector; subContext.selector = subContext.selector->tagHistory()) { |
// :not cannot nest. I don't really know why this is a |
// restriction in CSS3, but it is, so let's honor it. |
// the parser enforces that this never occurs |
@@ -509,12 +510,12 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib |
// (since there are no elements involved). |
return checkScrollbarPseudoClass(context, &element.document(), selector); |
} else if (context.hasSelectionPseudo) { |
- if (selector->pseudoType() == CSSSelector::PseudoWindowInactive) |
+ if (selector.pseudoType() == CSSSelector::PseudoWindowInactive) |
return !element.document().page()->focusController().isActive(); |
} |
// Normal element pseudo class checking. |
- switch (selector->pseudoType()) { |
+ switch (selector.pseudoType()) { |
// Pseudo classes: |
case CSSSelector::PseudoNot: |
break; // Already handled up above. |
@@ -617,7 +618,7 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib |
} |
break; |
case CSSSelector::PseudoNthChild: |
- if (!selector->parseNth()) |
+ if (!selector.parseNth()) |
break; |
if (Element* parent = element.parentElement()) { |
int count = 1 + siblingTraversalStrategy.countElementsBefore(&element); |
@@ -629,24 +630,24 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib |
parent->setChildrenAffectedByForwardPositionalRules(); |
} |
- if (selector->matchNth(count)) |
+ if (selector.matchNth(count)) |
return true; |
} |
break; |
case CSSSelector::PseudoNthOfType: |
- if (!selector->parseNth()) |
+ if (!selector.parseNth()) |
break; |
if (Element* parent = element.parentElement()) { |
int count = 1 + siblingTraversalStrategy.countElementsOfTypeBefore(&element, element.tagQName()); |
if (m_mode == ResolvingStyle) |
parent->setChildrenAffectedByForwardPositionalRules(); |
- if (selector->matchNth(count)) |
+ if (selector.matchNth(count)) |
return true; |
} |
break; |
case CSSSelector::PseudoNthLastChild: |
- if (!selector->parseNth()) |
+ if (!selector.parseNth()) |
break; |
if (Element* parent = element.parentElement()) { |
if (m_mode == ResolvingStyle) |
@@ -654,12 +655,12 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib |
if (!parent->isFinishedParsingChildren()) |
return false; |
int count = 1 + siblingTraversalStrategy.countElementsAfter(&element); |
- if (selector->matchNth(count)) |
+ if (selector.matchNth(count)) |
return true; |
} |
break; |
case CSSSelector::PseudoNthLastOfType: |
- if (!selector->parseNth()) |
+ if (!selector.parseNth()) |
break; |
if (Element* parent = element.parentElement()) { |
if (m_mode == ResolvingStyle) |
@@ -668,7 +669,7 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib |
return false; |
int count = 1 + siblingTraversalStrategy.countElementsOfTypeAfter(&element, element.tagQName()); |
- if (selector->matchNth(count)) |
+ if (selector.matchNth(count)) |
return true; |
} |
break; |
@@ -680,8 +681,8 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib |
{ |
SelectorCheckingContext subContext(context); |
subContext.isSubSelector = true; |
- ASSERT(selector->selectorList()); |
- for (subContext.selector = selector->selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(subContext.selector)) { |
+ ASSERT(selector.selectorList()); |
+ for (subContext.selector = selector.selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(*subContext.selector)) { |
if (match(subContext, siblingTraversalStrategy) == SelectorMatches) |
return true; |
} |
@@ -719,7 +720,7 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib |
case CSSSelector::PseudoHover: |
// If we're in quirks mode, then hover should never match anchors with no |
// href and *:hover should not match anything. This is important for sites like wsj.com. |
- if (m_strictParsing || context.isSubSelector || (selector->m_match == CSSSelector::Tag && selector->tagQName() != anyQName() && !element.hasTagName(aTag)) || element.isLink()) { |
+ if (m_strictParsing || context.isSubSelector || (selector.m_match == CSSSelector::Tag && selector.tagQName() != anyQName() && !element.hasTagName(aTag)) || element.isLink()) { |
if (m_mode == ResolvingStyle) { |
if (context.elementStyle) |
context.elementStyle->setAffectedByHover(); |
@@ -733,7 +734,7 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib |
case CSSSelector::PseudoActive: |
// If we're in quirks mode, then :active should never match anchors with no |
// href and *:active should not match anything. |
- if (m_strictParsing || context.isSubSelector || (selector->m_match == CSSSelector::Tag && selector->tagQName() != anyQName() && !element.hasTagName(aTag)) || element.isLink()) { |
+ if (m_strictParsing || context.isSubSelector || (selector.m_match == CSSSelector::Tag && selector.tagQName() != anyQName() && !element.hasTagName(aTag)) || element.isLink()) { |
if (m_mode == ResolvingStyle) { |
if (context.elementStyle) |
context.elementStyle->setAffectedByActive(); |
@@ -799,7 +800,7 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib |
value = toVTTElement(element).language(); |
else |
value = element.computeInheritedLanguage(); |
- const AtomicString& argument = selector->argument(); |
+ const AtomicString& argument = selector.argument(); |
if (value.isEmpty() || !value.startsWith(argument, false)) |
break; |
if (value.length() != argument.length() && value[argument.length()] != '-') |
@@ -860,7 +861,7 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib |
ASSERT(element.shadow()); |
// For empty parameter case, i.e. just :host or :host(). |
- if (!selector->selectorList()) // Use *'s specificity. So just 0. |
+ if (!selector.selectorList()) // Use *'s specificity. So just 0. |
return true; |
SelectorCheckingContext subContext(context); |
@@ -870,7 +871,7 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib |
unsigned maxSpecificity = 0; |
// If one of simple selectors matches an element, returns SelectorMatches. Just "OR". |
- for (subContext.selector = selector->selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(subContext.selector)) { |
+ for (subContext.selector = selector.selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(*subContext.selector)) { |
subContext.behaviorAtBoundary = ScopeIsShadowHostInPseudoHostParameter; |
subContext.scope = context.scope; |
// Use NodeRenderingTraversal to traverse a composed ancestor list of a given element. |
@@ -887,7 +888,7 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib |
subContext.behaviorAtBoundary = DoesNotCrossBoundary; |
subContext.scope = 0; |
- if (selector->pseudoType() == CSSSelector::PseudoHost) |
+ if (selector.pseudoType() == CSSSelector::PseudoHost) |
break; |
nextElement = NodeRenderingTraversal::parentElement(nextElement); |
@@ -920,14 +921,14 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib |
break; |
} |
return false; |
- } |
- else if (selector->m_match == CSSSelector::PseudoElement && selector->pseudoType() == CSSSelector::PseudoCue) { |
+ } else if (selector.m_match == CSSSelector::PseudoElement && selector.pseudoType() == CSSSelector::PseudoCue) { |
SelectorCheckingContext subContext(context); |
subContext.isSubSelector = true; |
subContext.behaviorAtBoundary = StaysWithinTreeScope; |
- const CSSSelector* const & selector = context.selector; |
- for (subContext.selector = selector->selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(subContext.selector)) { |
+ const CSSSelector* contextSelector = context.selector; |
+ ASSERT(contextSelector); |
+ for (subContext.selector = contextSelector->selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(*subContext.selector)) { |
if (match(subContext, siblingTraversalStrategy) == SelectorMatches) |
return true; |
} |
@@ -937,21 +938,21 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib |
return true; |
} |
-bool SelectorChecker::checkScrollbarPseudoClass(const SelectorCheckingContext& context, Document* document, const CSSSelector* selector) const |
+bool SelectorChecker::checkScrollbarPseudoClass(const SelectorCheckingContext& context, Document* document, const CSSSelector& selector) const |
{ |
RenderScrollbar* scrollbar = context.scrollbar; |
ScrollbarPart part = context.scrollbarPart; |
// FIXME: This is a temporary hack for resizers and scrollbar corners. Eventually :window-inactive should become a real |
// pseudo class and just apply to everything. |
- if (selector->pseudoType() == CSSSelector::PseudoWindowInactive) |
+ if (selector.pseudoType() == CSSSelector::PseudoWindowInactive) |
return !document->page()->focusController().isActive(); |
if (!scrollbar) |
return false; |
- ASSERT(selector->m_match == CSSSelector::PseudoClass); |
- switch (selector->pseudoType()) { |
+ ASSERT(selector.m_match == CSSSelector::PseudoClass); |
+ switch (selector.pseudoType()) { |
case CSSSelector::PseudoEnabled: |
return scrollbar->enabled(); |
case CSSSelector::PseudoDisabled: |
@@ -1018,19 +1019,19 @@ bool SelectorChecker::checkScrollbarPseudoClass(const SelectorCheckingContext& c |
} |
} |
-unsigned SelectorChecker::determineLinkMatchType(const CSSSelector* selector) |
+unsigned SelectorChecker::determineLinkMatchType(const CSSSelector& selector) |
{ |
unsigned linkMatchType = MatchAll; |
// Statically determine if this selector will match a link in visited, unvisited or any state, or never. |
// :visited never matches other elements than the innermost link element. |
- for (; selector; selector = selector->tagHistory()) { |
- switch (selector->pseudoType()) { |
+ for (const CSSSelector* current = &selector; current; current = current->tagHistory()) { |
+ switch (current->pseudoType()) { |
case CSSSelector::PseudoNot: |
{ |
// :not(:visited) is equivalent to :link. Parser enforces that :not can't nest. |
- ASSERT(selector->selectorList()); |
- for (const CSSSelector* subSelector = selector->selectorList()->first(); subSelector; subSelector = subSelector->tagHistory()) { |
+ ASSERT(current->selectorList()); |
+ for (const CSSSelector* subSelector = current->selectorList()->first(); subSelector; subSelector = subSelector->tagHistory()) { |
CSSSelector::PseudoType subType = subSelector->pseudoType(); |
if (subType == CSSSelector::PseudoVisited) |
linkMatchType &= ~SelectorChecker::MatchVisited; |
@@ -1049,7 +1050,7 @@ unsigned SelectorChecker::determineLinkMatchType(const CSSSelector* selector) |
// We don't support :link and :visited inside :-webkit-any. |
break; |
} |
- CSSSelector::Relation relation = selector->relation(); |
+ CSSSelector::Relation relation = current->relation(); |
if (relation == CSSSelector::SubSelector) |
continue; |
if (relation != CSSSelector::Descendant && relation != CSSSelector::Child) |