Bug 996796 patch 8 - Pass the replacements through to ResolveStyleWithReplacement. r=heycam
authorL. David Baron <dbaron@dbaron.org>
Sat, 02 Aug 2014 19:37:44 -0700
changeset 197480 d9db9020d57ace77058e987ad5e8bef422da6b50
parent 197479 a8a810bc1b360482b6acf3c202c0c113f31543a4
child 197481 4a395d400f602f4c3bcb32603af4374ee2b5346d
push id47142
push userdbaron@mozilla.com
push dateSun, 03 Aug 2014 02:38:23 +0000
treeherdermozilla-inbound@1636ae2d7b53 [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 8 - Pass the replacements through to ResolveStyleWithReplacement. r=heycam This means ResolveStyleWithReplacement will replace only the rules in the nsRestyleHint rather than always replacing both the animations rule and the transitions rule. (This will become even more useful later when we add the ability to replace the style attribute rule.)
layout/base/RestyleManager.cpp
layout/style/AnimationCommon.cpp
layout/style/nsStyleSet.cpp
layout/style/nsStyleSet.h
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -2466,21 +2466,19 @@ ElementRestyler::RestyleSelf(nsIFrame* a
     // just used prevContinuationContext anyway and aren't reaching this code
     // to start with.
 
     Element* element = ElementForStyleContext(mParentContent, aSelf, pseudoType);
     if (aRestyleHint == nsRestyleHint(0)) {
       newContext =
         styleSet->ReparentStyleContext(oldContext, parentContext, element);
     } else {
-      MOZ_ASSERT(!(~aRestyleHint & (eRestyle_CSSTransitions |
-                                    eRestyle_CSSAnimations)),
-                 "unexpected restyle bits");
       newContext =
-        styleSet->ResolveStyleWithReplacement(element, parentContext, oldContext);
+        styleSet->ResolveStyleWithReplacement(element, parentContext, oldContext,
+                                              aRestyleHint);
     }
   } else if (pseudoType == nsCSSPseudoElements::ePseudo_AnonBox) {
     newContext = styleSet->ResolveAnonymousBoxStyle(pseudoTag,
                                                     parentContext);
   }
   else {
     Element* element = ElementForStyleContext(mParentContent, aSelf, pseudoType);
     if (pseudoTag) {
@@ -2711,23 +2709,21 @@ ElementRestyler::RestyleUndisplayedChild
       nsRefPtr<nsStyleContext> undisplayedContext;
       nsStyleSet* styleSet = mPresContext->StyleSet();
       if (thisChildHint & (eRestyle_Self | eRestyle_Subtree)) {
         undisplayedContext =
           styleSet->ResolveStyleFor(undisplayed->mContent->AsElement(),
                                     mFrame->StyleContext(),
                                     mTreeMatchContext);
       } else if (thisChildHint) {
-        MOZ_ASSERT(!(~thisChildHint & (eRestyle_CSSTransitions |
-                                       eRestyle_CSSAnimations)),
-                   "unexpected restyle bits");
         undisplayedContext =
           styleSet->ResolveStyleWithReplacement(undisplayed->mContent->AsElement(),
                                                 mFrame->StyleContext(),
-                                                undisplayed->mStyle);
+                                                undisplayed->mStyle,
+                                                thisChildHint);
       } else {
         undisplayedContext =
           styleSet->ReparentStyleContext(undisplayed->mStyle,
                                          mFrame->StyleContext(),
                                          undisplayed->mContent->AsElement());
       }
       const nsStyleDisplay* display = undisplayedContext->StyleDisplay();
       if (display->mDisplay != NS_STYLE_DISPLAY_NONE) {
--- a/layout/style/AnimationCommon.cpp
+++ b/layout/style/AnimationCommon.cpp
@@ -246,17 +246,18 @@ CommonAnimationManager::UpdateThrottledS
   if (!primaryFrame) {
     return nullptr;
   }
 
   nsStyleContext* oldStyle = primaryFrame->StyleContext();
 
   nsStyleSet* styleSet = mPresContext->StyleSet();
   nsRefPtr<nsStyleContext> newStyle =
-    styleSet->ResolveStyleWithReplacement(aElement, aParentStyle, oldStyle);
+    styleSet->ResolveStyleWithReplacement(aElement, aParentStyle, oldStyle,
+      nsRestyleHint(eRestyle_CSSTransitions | eRestyle_CSSAnimations));
 
   // We absolutely must call CalcStyleDifference in order to ensure the
   // new context has all the structs cached that the old context had.
   // We also need it for processing of the changes.
   nsChangeHint styleChange =
     oldStyle->CalcStyleDifference(newStyle, nsChangeHint(0));
   aChangeList.AppendChange(primaryFrame, primaryFrame->GetContent(),
                            styleChange);
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -29,16 +29,17 @@
 #include "nsTransitionManager.h"
 #include "nsAnimationManager.h"
 #include "nsStyleSheetService.h"
 #include "mozilla/dom/Element.h"
 #include "GeckoProfiler.h"
 #include "nsHTMLCSSStyleSheet.h"
 #include "nsHTMLStyleSheet.h"
 #include "nsCSSRules.h"
+#include "nsPrintfCString.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_ISUPPORTS(nsEmptyStyleRule, nsIStyleRule)
 
 /* virtual */ void
 nsEmptyStyleRule::MapRuleInfoInto(nsRuleData* aRuleData)
@@ -1318,55 +1319,74 @@ nsStyleSet::ResolveStyleByAddingRules(ns
                     aBaseContext->GetPseudo(),
                     aBaseContext->GetPseudoType(),
                     nullptr, flags);
 }
 
 already_AddRefed<nsStyleContext>
 nsStyleSet::ResolveStyleWithReplacement(Element* aElement,
                                         nsStyleContext* aNewParentContext,
-                                        nsStyleContext* aOldStyleContext)
+                                        nsStyleContext* aOldStyleContext,
+                                        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());
+
   nsRuleNode* ruleNode = aOldStyleContext->RuleNode();
   nsTArray<nsStyleSet::RuleAndLevel> rules;
   do {
     if (ruleNode->IsRoot()) {
       break;
     }
 
     nsStyleSet::RuleAndLevel curRule;
     curRule.mLevel = ruleNode->GetLevel();
+    curRule.mRule = ruleNode->GetRule();
 
-    if (curRule.mLevel == nsStyleSet::eAnimationSheet) {
-      nsAnimationManager* animationManager = PresContext()->AnimationManager();
-      ElementAnimationCollection* collection = animationManager->GetElementAnimations(
-        aElement, aOldStyleContext->GetPseudoType(), false);
-      NS_ASSERTION(collection,
-        "Rule has level eAnimationSheet without animation on manager");
+    // FIXME: This will eventually need to handle adding a rule where we
+    // don't currently have one!
+
+    switch (curRule.mLevel) {
+    case nsStyleSet::eAnimationSheet:
+      if (aReplacements & eRestyle_CSSAnimations) {
+        nsAnimationManager* animationManager = PresContext()->AnimationManager();
+        ElementAnimationCollection* collection = animationManager->GetElementAnimations(
+          aElement, aOldStyleContext->GetPseudoType(), false);
+        NS_ASSERTION(collection,
+          "Rule has level eAnimationSheet without animation on manager");
 
-      animationManager->UpdateStyleAndEvents(
-        collection, PresContext()->RefreshDriver()->MostRecentRefresh(),
-        EnsureStyleRule_IsNotThrottled);
-      curRule.mRule = collection->mStyleRule;
-    } else if (curRule.mLevel == nsStyleSet::eTransitionSheet) {
-      nsPresContext* presContext = PresContext();
-      ElementAnimationCollection* collection =
-        presContext->TransitionManager()->GetElementTransitions(
-          aElement,
-          aOldStyleContext->GetPseudoType(),
-          false);
-      NS_ASSERTION(collection,
-        "Rule has level eTransitionSheet without transition on manager");
+        animationManager->UpdateStyleAndEvents(
+          collection, PresContext()->RefreshDriver()->MostRecentRefresh(),
+          EnsureStyleRule_IsNotThrottled);
+        curRule.mRule = collection->mStyleRule;
+      }
+      break;
+    case nsStyleSet::eTransitionSheet:
+      if (aReplacements & eRestyle_CSSTransitions) {
+        nsPresContext* presContext = PresContext();
+        ElementAnimationCollection* collection =
+          presContext->TransitionManager()->GetElementTransitions(
+            aElement,
+            aOldStyleContext->GetPseudoType(),
+            false);
+        NS_ASSERTION(collection,
+          "Rule has level eTransitionSheet without transition on manager");
 
-      collection->EnsureStyleRuleFor(
-        presContext->RefreshDriver()->MostRecentRefresh(),
-        EnsureStyleRule_IsNotThrottled);
-      curRule.mRule = collection->mStyleRule;
-    } else {
-      curRule.mRule = ruleNode->GetRule();
+        collection->EnsureStyleRuleFor(
+          presContext->RefreshDriver()->MostRecentRefresh(),
+          EnsureStyleRule_IsNotThrottled);
+        curRule.mRule = collection->mStyleRule;
+      }
+      break;
+    default:
+      break;
     }
 
     if (curRule.mRule) {
       rules.AppendElement(curRule);
     }
   } while ((ruleNode = ruleNode->GetParent()));
 
   // FIXME: Does this handle visited contexts correctly???
--- a/layout/style/nsStyleSet.h
+++ b/layout/style/nsStyleSet.h
@@ -129,22 +129,24 @@ class nsStyleSet
 
   // Get a style context that represents aBaseContext, but as though
   // it additionally matched the rules in the aRules array (in that
   // order, as more specific than any other rules).
   already_AddRefed<nsStyleContext>
   ResolveStyleByAddingRules(nsStyleContext* aBaseContext,
                             const nsCOMArray<nsIStyleRule> &aRules);
 
-  // Resolve style by replacing the animation and transition rules, but
-  // otherwise maintaining the status quo.
+  // Resolve style by making replacements in the list of style rules as
+  // described by aReplacements, but otherwise maintaining the status
+  // quo.
   already_AddRefed<nsStyleContext>
   ResolveStyleWithReplacement(mozilla::dom::Element* aElement,
                               nsStyleContext* aNewParentContext,
-                              nsStyleContext* aOldStyleContext);
+                              nsStyleContext* aOldStyleContext,
+                              nsRestyleHint aReplacements);
 
   // Get a style context for a non-element (which no rules will match),
   // such as text nodes, placeholder frames, and the nsFirstLetterFrame
   // for everything after the first letter.
   //
   // Perhaps this should go away and we shouldn't even create style
   // contexts for such content nodes.  However, not doing any rule
   // matching for them is a first step.