Bug 1331047: Look at the style with animations in ResolveStyleLazily. draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Wed, 26 Apr 2017 14:01:25 +0200
changeset 568757 f3a3b2ed1553526ec9bcfff7d594823522ba2b44
parent 568646 b06b31b54d18d705a0f21f1c60b25c59c48095ec
child 626023 ba6c581ef3dba8708e9a727afe8c7cb6e622b9ba
push id55974
push userbmo:emilio+bugs@crisal.io
push dateWed, 26 Apr 2017 15:19:06 +0000
bugs1331047
milestone55.0a1
Bug 1331047: Look at the style with animations in ResolveStyleLazily. MozReview-Commit-ID: 1p4D5p0jymb
layout/style/ServoStyleSet.cpp
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -899,26 +899,56 @@ ServoStyleSet::ClearNonInheritingStyleCo
     ptr = nullptr;
   }
 }
 
 already_AddRefed<ServoComputedValues>
 ServoStyleSet::ResolveStyleLazily(Element* aElement, nsIAtom* aPseudoTag)
 {
   mPresContext->EffectCompositor()->PreTraverse(aElement, aPseudoTag);
-
   MOZ_ASSERT(!sInServoTraversal);
   sInServoTraversal = true;
+
+  /**
+   * NB: This is needed because we process animations and transitions on the
+   * pseudo-elements themselves, not on the parent's EagerPseudoStyles.
+   *
+   * That means that that style doesn't account for animations, and we can't do
+   * that easily from the traversal without doing wasted work.
+   *
+   * As such, we just lie here a bit, which is the entrypoint of
+   * getComputedStyle, the only API where this can be observed, to look at the
+   * style of the pseudo-element if it exists instead.
+   */
+  Element* elementForStyleResolution = aElement;
+  nsIAtom* pseudoTagForStyleResolution = aPseudoTag;
+  if (aPseudoTag == nsCSSPseudoElements::before) {
+    if (Element* pseudo = nsLayoutUtils::GetBeforePseudo(aElement)) {
+      elementForStyleResolution = pseudo;
+      pseudoTagForStyleResolution = nullptr;
+    }
+  } else if (aPseudoTag == nsCSSPseudoElements::after) {
+    if (Element* pseudo = nsLayoutUtils::GetAfterPseudo(aElement)) {
+      elementForStyleResolution = pseudo;
+      pseudoTagForStyleResolution = nullptr;
+    }
+  }
+
   RefPtr<ServoComputedValues> computedValues =
-    Servo_ResolveStyleLazily(aElement, aPseudoTag, mRawSet.get()).Consume();
+    Servo_ResolveStyleLazily(elementForStyleResolution,
+                             pseudoTagForStyleResolution,
+                             mRawSet.get()).Consume();
 
   if (mPresContext->EffectCompositor()->PreTraverse(aElement, aPseudoTag)) {
     computedValues =
-      Servo_ResolveStyleLazily(aElement, aPseudoTag, mRawSet.get()).Consume();
+      Servo_ResolveStyleLazily(elementForStyleResolution,
+                               pseudoTagForStyleResolution,
+                               mRawSet.get()).Consume();
   }
+
   sInServoTraversal = false;
 
   return computedValues.forget();
 }
 
 bool
 ServoStyleSet::AppendFontFaceRules(nsTArray<nsFontFaceRuleContainer>& aArray)
 {