Bug 996796 patch 10 - Separate the rule node replacement code from the style context handling so that we can make visited handling correct. r=heycam
authorL. David Baron <dbaron@dbaron.org>
Sat, 02 Aug 2014 19:37:44 -0700
changeset 197591 720eed827027169056170ddf8ecf43be85b02fe6
parent 197590 4a395d400f602f4c3bcb32603af4374ee2b5346d
child 197592 6a9de658d4b4e93101649d1e3431d0eaa2e698b5
push id27249
push userryanvm@gmail.com
push dateMon, 04 Aug 2014 20:14:35 +0000
treeherdermozilla-central@7f81be7db528 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs996796
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 996796 patch 10 - Separate the rule node replacement code from the style context handling so that we can make visited handling correct. r=heycam
layout/style/nsStyleSet.cpp
layout/style/nsStyleSet.h
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -1322,31 +1322,31 @@ static const CascadeLevel gCascadeLevels
   { nsStyleSet::eDocSheet,        true,  nsRestyleHint(0) },
   { nsStyleSet::eStyleAttrSheet,  true,  nsRestyleHint(0) },
   { nsStyleSet::eOverrideSheet,   true,  nsRestyleHint(0) },
   { nsStyleSet::eUserSheet,       true,  nsRestyleHint(0) },
   { nsStyleSet::eAgentSheet,      true,  nsRestyleHint(0) },
   { nsStyleSet::eTransitionSheet, false, eRestyle_CSSTransitions },
 };
 
-already_AddRefed<nsStyleContext>
-nsStyleSet::ResolveStyleWithReplacement(Element* aElement,
-                                        nsStyleContext* aNewParentContext,
-                                        nsStyleContext* aOldStyleContext,
-                                        nsRestyleHint aReplacements)
+nsRuleNode*
+nsStyleSet::RuleNodeWithReplacement(Element* aElement,
+                                    nsRuleNode* aOldRuleNode,
+                                    nsCSSPseudoElements::Type aPseudoType,
+                                    nsRestyleHint aReplacements)
 {
   NS_ABORT_IF_FALSE(!(aReplacements & ~(eRestyle_CSSTransitions |
                                         eRestyle_CSSAnimations)),
                     // FIXME: Once bug 931668 lands we'll have a better
                     // way to print these.
                     nsPrintfCString("unexpected replacement bits 0x%lX",
                                     uint32_t(aReplacements)).get());
 
   nsTArray<RuleNodeInfo> rules;
-  for (nsRuleNode* ruleNode = aOldStyleContext->RuleNode(); !ruleNode->IsRoot();
+  for (nsRuleNode* ruleNode = aOldRuleNode; !ruleNode->IsRoot();
        ruleNode = ruleNode->GetParent()) {
     RuleNodeInfo* curRule = rules.AppendElement();
     curRule->mRule = ruleNode->GetRule();
     curRule->mLevel = ruleNode->GetLevel();
     curRule->mIsImportant = ruleNode->IsImportantRule();
   }
 
   nsRuleWalker ruleWalker(mRuleTree, mAuthorStyleDisabled);
@@ -1359,35 +1359,33 @@ nsStyleSet::ResolveStyleWithReplacement(
 
     bool doReplace = level->mLevelReplacementHint & aReplacements;
     if (doReplace) {
       switch (level->mLevelReplacementHint) {
         case eRestyle_CSSAnimations: {
           nsAnimationManager* animationManager =
             PresContext()->AnimationManager();
           ElementAnimationCollection* collection = animationManager->GetElementAnimations(
-            aElement, aOldStyleContext->GetPseudoType(), false);
+            aElement, aPseudoType, false);
 
           if (collection) {
             animationManager->UpdateStyleAndEvents(
               collection, PresContext()->RefreshDriver()->MostRecentRefresh(),
               EnsureStyleRule_IsNotThrottled);
             if (collection->mStyleRule) {
               ruleWalker.ForwardOnPossiblyCSSRule(collection->mStyleRule);
             }
           }
           break;
         }
         case eRestyle_CSSTransitions: {
           nsPresContext* presContext = PresContext();
           ElementAnimationCollection* collection =
             presContext->TransitionManager()->GetElementTransitions(
-              aElement,
-              aOldStyleContext->GetPseudoType(),
-              false);
+              aElement, aPseudoType, false);
 
           if (collection) {
             collection->EnsureStyleRuleFor(
               presContext->RefreshDriver()->MostRecentRefresh(),
               EnsureStyleRule_IsNotThrottled);
             if (collection->mStyleRule) {
               ruleWalker.ForwardOnPossiblyCSSRule(collection->mStyleRule);
             }
@@ -1410,27 +1408,40 @@ nsStyleSet::ResolveStyleWithReplacement(
       }
 
       if (!doReplace) {
         ruleWalker.ForwardOnPossiblyCSSRule(ruleInfo.mRule);
       }
     }
   }
 
+  return ruleWalker.CurrentNode();
+}
+
+already_AddRefed<nsStyleContext>
+nsStyleSet::ResolveStyleWithReplacement(Element* aElement,
+                                        nsStyleContext* aNewParentContext,
+                                        nsStyleContext* aOldStyleContext,
+                                        nsRestyleHint aReplacements)
+{
+  nsRuleNode* ruleNode =
+    RuleNodeWithReplacement(aElement, aOldStyleContext->RuleNode(),
+                            aOldStyleContext->GetPseudoType(), aReplacements);
+
   // FIXME: Does this handle visited contexts correctly???
 
   uint32_t flags = eNoFlags;
   if (aOldStyleContext->IsLinkContext()) {
     flags |= eIsLink;
   }
   if (aOldStyleContext->RelevantLinkVisited()) {
     flags |= eIsVisitedLink;
   }
 
-  return GetContext(aNewParentContext, ruleWalker.CurrentNode(), nullptr,
+  return GetContext(aNewParentContext, ruleNode, nullptr,
                     nullptr, nsCSSPseudoElements::ePseudo_NotPseudoElement,
                     nullptr, flags);
 }
 
 
 already_AddRefed<nsStyleContext>
 nsStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext)
 {
--- a/layout/style/nsStyleSet.h
+++ b/layout/style/nsStyleSet.h
@@ -394,16 +394,22 @@ class nsStyleSet
                  nsRuleWalker* aRuleWalker);
 
   // Enumerate all the rules in a way that doesn't care about the order
   // of the rules and break out if the enumeration is halted.
   void WalkRuleProcessors(nsIStyleRuleProcessor::EnumFunc aFunc,
                           ElementDependentRuleProcessorData* aData,
                           bool aWalkAllXBLStylesheets);
 
+  // Helper for ResolveStyleWithReplacement
+  nsRuleNode* RuleNodeWithReplacement(mozilla::dom::Element* aElement,
+                                      nsRuleNode* aOldRuleNode,
+                                      nsCSSPseudoElements::Type aPseudoType,
+                                      nsRestyleHint aReplacements);
+
   /**
    * Bit-flags that can be passed to GetContext() in its parameter 'aFlags'.
    */
   enum {
     eNoFlags =          0,
     eIsLink =           1 << 0,
     eIsVisitedLink =    1 << 1,
     eDoAnimation =      1 << 2,