Bug 1328509 - GetContentStateForVisitedHandling can access state directly. r=dbaron
While studying `GetContentStateForVisitedHandling` for adaptation to Stylo, I
noticed it calls through to `GetContentState`, which depends on external state
such as private browser, etc.
However, there's no need to call `GetContentState` here since this function
always clears both unvisited and visited if either is set.
MozReview-Commit-ID: JLwKnowQbJ2
--- a/layout/style/nsCSSRuleProcessor.cpp
+++ b/layout/style/nsCSSRuleProcessor.cpp
@@ -1259,41 +1259,43 @@ nsCSSRuleProcessor::IsLink(const Element
EventStates state = aElement->StyleState();
return state.HasAtLeastOneOfStates(NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED);
}
/* static */
EventStates
nsCSSRuleProcessor::GetContentStateForVisitedHandling(
Element* aElement,
- const TreeMatchContext& aTreeMatchContext,
nsRuleWalker::VisitedHandlingType aVisitedHandling,
bool aIsRelevantLink)
{
- EventStates contentState = GetContentState(aElement, aTreeMatchContext);
- if (contentState.HasAtLeastOneOfStates(NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED)) {
+ // It's unnecessary to call GetContentState() here (which may flip visited to
+ // unvisited) since this function will remove both unvisited and visited if
+ // either is set and produce a new value.
+ EventStates state = aElement->StyleState();
+ if (state.HasAtLeastOneOfStates(NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED)) {
MOZ_ASSERT(IsLink(aElement), "IsLink() should match state");
- contentState &= ~(NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED);
+ state &= ~(NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED);
if (aIsRelevantLink) {
switch (aVisitedHandling) {
case nsRuleWalker::eRelevantLinkUnvisited:
- contentState |= NS_EVENT_STATE_UNVISITED;
+ state |= NS_EVENT_STATE_UNVISITED;
break;
case nsRuleWalker::eRelevantLinkVisited:
- contentState |= NS_EVENT_STATE_VISITED;
+ state |= NS_EVENT_STATE_VISITED;
break;
case nsRuleWalker::eLinksVisitedOrUnvisited:
- contentState |= NS_EVENT_STATE_UNVISITED | NS_EVENT_STATE_VISITED;
+ state |= NS_EVENT_STATE_UNVISITED | NS_EVENT_STATE_VISITED;
break;
}
} else {
- contentState |= NS_EVENT_STATE_UNVISITED;
+ state |= NS_EVENT_STATE_UNVISITED;
}
}
- return contentState;
+ return state;
}
/**
* A |NodeMatchContext| has data about matching a selector (without
* combinators) against a single node. It contains only input to the
* matching.
*
* Unlike |RuleProcessorData|, which is similar, a |NodeMatchContext|
@@ -1599,17 +1601,16 @@ StateSelectorMatches(Element* aElement,
if (aNodeMatchContext.mStateMask.HasAtLeastOneOfStates(aStatesToCheck)) {
if (aDependence) {
*aDependence = true;
}
} else {
EventStates contentState =
nsCSSRuleProcessor::GetContentStateForVisitedHandling(
aElement,
- aTreeMatchContext,
aTreeMatchContext.VisitedHandling(),
aNodeMatchContext.mIsRelevantLink);
if (!contentState.HasAtLeastOneOfStates(aStatesToCheck)) {
return false;
}
}
return true;
--- a/layout/style/nsCSSRuleProcessor.h
+++ b/layout/style/nsCSSRuleProcessor.h
@@ -106,17 +106,16 @@ public:
mozilla::dom::Element* aElement,
const TreeMatchContext& aTreeMatchContext);
/*
* Helper to get the content state for :visited handling for an element
*/
static mozilla::EventStates GetContentStateForVisitedHandling(
mozilla::dom::Element* aElement,
- const TreeMatchContext& aTreeMatchContext,
nsRuleWalker::VisitedHandlingType aVisitedHandling,
bool aIsRelevantLink);
/*
* Helper to test whether a node is a link
*/
static bool IsLink(const mozilla::dom::Element* aElement);
--- a/layout/style/nsHTMLStyleSheet.cpp
+++ b/layout/style/nsHTMLStyleSheet.cpp
@@ -303,17 +303,16 @@ nsHTMLStyleSheet::RulesMatching(ElementR
nsRuleWalker *ruleWalker = aData->mRuleWalker;
if (!ruleWalker->AuthorStyleDisabled()) {
// if we have anchor colors, check if this is an anchor with an href
if (aData->mElement->IsHTMLElement(nsGkAtoms::a)) {
if (mLinkRule || mVisitedRule || mActiveRule) {
EventStates state =
nsCSSRuleProcessor::GetContentStateForVisitedHandling(
aData->mElement,
- aData->mTreeMatchContext,
aData->mTreeMatchContext.VisitedHandling(),
// If the node being matched is a link,
// it's the relevant link.
nsCSSRuleProcessor::IsLink(aData->mElement));
if (mLinkRule && state.HasState(NS_EVENT_STATE_UNVISITED)) {
ruleWalker->Forward(mLinkRule);
aData->mTreeMatchContext.SetHaveRelevantLink();
}