From 89e50f89ed8a9c3dbc7b2bc653d6af9970c70110 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 29 May 2012 00:17:45 -0400 Subject: [PATCH] Bug 758885. Don't apply the dynamic :hover reresolution skipping optimization to selectors which can match on mutable state other than :hover. r=dbaron --- layout/base/nsCSSFrameConstructor.cpp | 9 ++------- layout/style/nsCSSRuleProcessor.cpp | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 1493a8acafa..1de55c19877 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -8092,14 +8092,9 @@ nsCSSFrameConstructor::ContentStateChanged(nsIContent* aContent, primaryFrame->ContentStatesChanged(aStateMask); } - if (aStateMask.HasState(NS_EVENT_STATE_HOVER) && - !aElement->HasFlag(NODE_HAS_RELEVANT_HOVER_RULES)) { - aStateMask &= ~NS_EVENT_STATE_HOVER; - } - nsRestyleHint rshint = aStateMask.IsEmpty() ? - nsRestyleHint(0) : - styleSet->HasStateDependentStyle(presContext, aElement, aStateMask); + nsRestyleHint rshint = + styleSet->HasStateDependentStyle(presContext, aElement, aStateMask); if (aStateMask.HasState(NS_EVENT_STATE_HOVER) && rshint != 0) { ++mHoverGeneration; diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index baf19bafd82..184b6468738 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -2391,6 +2391,24 @@ nsCSSRuleProcessor::HasStateDependentStyle(StateRuleProcessorData* aData) // states passed in are relevant here. if ((possibleChange & ~hint) && states.HasAtLeastOneOfStates(aData->mStateMask) && + // We can optimize away testing selectors that only involve :hover, a + // namespace, and a tag name against nodes that don't have the + // NODE_HAS_RELEVANT_HOVER_RULES flag: such a selector didn't match + // the tag name or namespace the first time around (since the :hover + // didn't set the NODE_HAS_RELEVANT_HOVER_RULES flag), so it won't + // match it now. Check for our selector only having :hover states, or + // the element having the hover rules flag, or the selector having + // some sort of non-namespace, non-tagname data in it. + (states != NS_EVENT_STATE_HOVER || + aData->mElement->HasFlag(NODE_HAS_RELEVANT_HOVER_RULES) || + selector->mIDList || selector->mClassList || + // We generally expect an mPseudoClassList, since we have a :hover. + // The question is whether we have anything else in there. + (selector->mPseudoClassList && + (selector->mPseudoClassList->mNext || + selector->mPseudoClassList->mType != + nsCSSPseudoClasses::ePseudoClass_hover)) || + selector->mAttrList || selector->mNegations) && SelectorMatches(aData->mElement, selector, nodeContext, aData->mTreeMatchContext) && SelectorMatchesTree(aData->mElement, selector->mNext,