Bug 1383307: Remove ServoStyleContext::UpdateWithElementState. draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Sun, 23 Jul 2017 05:06:07 +0200
changeset 614045 55d5a40668a921dba6ae158f6dd729a60c226737
parent 614044 5d580823fc679666c9c63878872165364924f5f2
child 638759 a319e255ed245a955464e3a7ddc700127231b398
push id69896
push userbmo:emilio+bugs@crisal.io
push dateSun, 23 Jul 2017 21:57:53 +0000
bugs1383307
milestone56.0a1
Bug 1383307: Remove ServoStyleContext::UpdateWithElementState. And kill one GetParentAllowServo call while at it, and some other dumbness... MozReview-Commit-ID: GmvzXwGorlX
layout/base/ServoRestyleManager.cpp
layout/style/ServoStyleContext.cpp
layout/style/ServoStyleContext.h
layout/style/ServoStyleSet.cpp
layout/style/ServoStyleSet.h
--- a/layout/base/ServoRestyleManager.cpp
+++ b/layout/base/ServoRestyleManager.cpp
@@ -598,22 +598,19 @@ ServoRestyleManager::ProcessPostTraversa
   // We can't really assume as used changes from display: contents elements (or
   // other elements without frames).
   ServoRestyleState& childrenRestyleState =
     thisFrameRestyleState ? *thisFrameRestyleState : aRestyleState;
 
   RefPtr<ServoStyleContext> newContext = nullptr;
   if (wasRestyled && oldStyleContext) {
     MOZ_ASSERT(styleFrame || displayContentsNode);
-    RefPtr<ServoStyleContext> currentContext =
+    newContext =
       aRestyleState.StyleSet().ResolveServoStyle(aElement, aRestyleBehavior);
-    MOZ_ASSERT(oldStyleContext->ComputedData() != currentContext->ComputedData());
-
-    newContext = currentContext;
-    newContext->UpdateWithElementState(aElement);
+    MOZ_ASSERT(oldStyleContext->ComputedData() != newContext->ComputedData());
 
     newContext->ResolveSameStructsAs(oldStyleContext);
 
     // We want to walk all the continuations here, even the ones with different
     // styles.  In practice, the only reason we get continuations with different
     // styles here is ::first-line (::first-letter never affects element
     // styles).  But in that case, newContext is the right context for the
     // _later_ continuations anyway (the ones not affected by ::first-line), not
--- a/layout/style/ServoStyleContext.cpp
+++ b/layout/style/ServoStyleContext.cpp
@@ -27,47 +27,9 @@ ServoStyleContext::ServoStyleContext(
 {
   AddStyleBit(Servo_ComputedValues_GetStyleBits(this));
   FinishConstruction();
 
   // No need to call ApplyStyleFixups here, since fixups are handled by Servo when
   // producing the ServoComputedData.
 }
 
-void
-ServoStyleContext::UpdateWithElementState(Element* aElementForAnimation)
-{
-  bool isLink = false;
-  bool isVisitedLink = false;
-  // If we need visited styles for callers where `aElementForAnimation` is null,
-  // we can precompute these and pass them as flags, similar to nsStyleSet.cpp.
-  if (aElementForAnimation) {
-    isLink = nsCSSRuleProcessor::IsLink(aElementForAnimation);
-    isVisitedLink = nsCSSRuleProcessor::GetContentState(aElementForAnimation)
-                                       .HasState(NS_EVENT_STATE_VISITED);
-  }
-
-
-  auto parent = GetParentAllowServo();
-
-  // The true visited state of the relevant link is used to decided whether
-  // visited styles should be consulted for all visited dependent properties.
-  bool relevantLinkVisited = isLink ? isVisitedLink :
-    (parent && parent->RelevantLinkVisited());
-
-  if (relevantLinkVisited && GetStyleIfVisited()) {
-    AddStyleBit(NS_STYLE_RELEVANT_LINK_VISITED);
-  }
-
-  // Set the body color on the pres context. See nsStyleSet::GetContext
-  if (aElementForAnimation &&
-      aElementForAnimation->IsHTMLElement(nsGkAtoms::body) &&
-      GetPseudoType() == CSSPseudoElementType::NotPseudo &&
-      mPresContext->CompatibilityMode() == eCompatibility_NavQuirks) {
-    nsIDocument* doc = aElementForAnimation->GetUncomposedDoc();
-    if (doc && doc->GetBodyElement() == aElementForAnimation) {
-      // Update the prescontext's body color
-      mPresContext->SetBodyTextColor(StyleColor()->mColor);
-    }
-  }
-}
-
 } // namespace mozilla
--- a/layout/style/ServoStyleContext.h
+++ b/layout/style/ServoStyleContext.h
@@ -30,20 +30,16 @@ public:
   void AddRef() { Servo_StyleContext_AddRef(this); }
   void Release() { Servo_StyleContext_Release(this); }
 
   ServoStyleContext* GetStyleIfVisited() const
   {
     return ComputedData()->visited_style.mPtr;
   }
 
-  // Update visited state for a given element, and set the prescontext's
-  // body text color if applicable.
-  void UpdateWithElementState(dom::Element* aElement);
-
   /**
    * Makes this context match |aOther| in terms of which style structs have
    * been resolved.
    */
   inline void ResolveSameStructsAs(const ServoStyleContext* aOther);
 
 private:
   nsPresContext* mPresContext;
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -170,43 +170,24 @@ ServoStyleSet::EndUpdate()
   return NS_OK;
 }
 
 already_AddRefed<ServoStyleContext>
 ServoStyleSet::ResolveStyleFor(Element* aElement,
                                ServoStyleContext* aParentContext,
                                LazyComputeBehavior aMayCompute)
 {
-  return GetContext(aElement, aParentContext, nullptr,
-                    CSSPseudoElementType::NotPseudo, aMayCompute);
-}
-
-already_AddRefed<ServoStyleContext>
-ServoStyleSet::GetContext(nsIContent* aContent,
-                          ServoStyleContext* aParentContext,
-                          nsIAtom* aPseudoTag,
-                          CSSPseudoElementType aPseudoType,
-                          LazyComputeBehavior aMayCompute)
-{
-  MOZ_ASSERT(aContent->IsElement());
-  Element* element = aContent->AsElement();
-
   RefPtr<ServoStyleContext> computedValues;
   if (aMayCompute == LazyComputeBehavior::Allow) {
     PreTraverseSync();
-    computedValues =
-      ResolveStyleLazily(element, CSSPseudoElementType::NotPseudo, aPseudoTag, aParentContext);
-      computedValues->UpdateWithElementState(element);
-  } else {
-    computedValues = ResolveServoStyle(element,
-                                       TraversalRestyleBehavior::Normal);
+    return ResolveStyleLazily(
+        aElement, CSSPseudoElementType::NotPseudo, nullptr, aParentContext);
   }
 
-  MOZ_ASSERT(computedValues);
-  return computedValues.forget();
+  return ResolveServoStyle(aElement, TraversalRestyleBehavior::Normal);
 }
 
 
 const ServoElementSnapshotTable&
 ServoStyleSet::Snapshots()
 {
   return mPresContext->RestyleManager()->AsServo()->Snapshots();
 }
@@ -379,32 +360,29 @@ ServoStyleSet::ResolveStyleForText(nsICo
   // rules: inherit the inherit structs, reset the reset structs. This is cheap
   // enough to do on the main thread, which means that the parallel style system
   // can avoid worrying about text nodes.
   RefPtr<ServoStyleContext> computedValues =
     Servo_ComputedValues_Inherit(mRawSet.get(),
                                  nsCSSAnonBoxes::mozText,
                                  aParentContext,
                                  InheritTarget::Text).Consume();
-  computedValues->UpdateWithElementState(nullptr);
   return computedValues.forget();
 }
 
 already_AddRefed<ServoStyleContext>
 ServoStyleSet::ResolveStyleForFirstLetterContinuation(ServoStyleContext* aParentContext)
 {
   RefPtr<ServoStyleContext> computedValues =
     Servo_ComputedValues_Inherit(mRawSet.get(),
                                  nsCSSAnonBoxes::firstLetterContinuation,
                                  aParentContext,
                                  InheritTarget::FirstLetterContinuation)
                                  .Consume();
   MOZ_ASSERT(computedValues);
-
-  computedValues->UpdateWithElementState(nullptr);
   return computedValues.forget();
 }
 
 already_AddRefed<ServoStyleContext>
 ServoStyleSet::ResolveStyleForPlaceholder()
 {
   RefPtr<ServoStyleContext>& cache =
     mNonInheritingStyleContexts[nsCSSAnonBoxes::NonInheriting::oofPlaceholder];
@@ -416,17 +394,16 @@ ServoStyleSet::ResolveStyleForPlaceholde
   RefPtr<ServoStyleContext> computedValues =
     Servo_ComputedValues_Inherit(mRawSet.get(),
                                  nsCSSAnonBoxes::oofPlaceholder,
                                  nullptr,
                                  InheritTarget::PlaceholderFrame)
                                  .Consume();
   MOZ_ASSERT(computedValues);
 
-  computedValues->UpdateWithElementState(nullptr);
   cache = computedValues;
   return computedValues.forget();
 }
 
 already_AddRefed<ServoStyleContext>
 ServoStyleSet::ResolvePseudoElementStyle(Element* aOriginatingElement,
                                          CSSPseudoElementType aType,
                                          ServoStyleContext* aParentContext,
@@ -449,32 +426,27 @@ ServoStyleSet::ResolvePseudoElementStyle
       Servo_ResolvePseudoStyle(aOriginatingElement,
                                aType,
                                /* is_probe = */ false,
                                aParentContext,
                                mRawSet.get()).Consume();
   }
 
   MOZ_ASSERT(computedValues);
-
-  bool isBeforeOrAfter = aType == CSSPseudoElementType::before ||
-                         aType == CSSPseudoElementType::after;
-  computedValues->UpdateWithElementState(isBeforeOrAfter ? aOriginatingElement : nullptr);
   return computedValues.forget();
 }
 
 already_AddRefed<ServoStyleContext>
 ServoStyleSet::ResolveTransientStyle(Element* aElement,
                                      CSSPseudoElementType aPseudoType,
                                      nsIAtom* aPseudoTag,
                                      StyleRuleInclusion aRuleInclusion)
 {
   RefPtr<ServoStyleContext> result =
     ResolveTransientServoStyle(aElement, aPseudoType, aPseudoTag, aRuleInclusion);
-  result->UpdateWithElementState(nullptr);
   return result.forget();
 }
 
 already_AddRefed<ServoStyleContext>
 ServoStyleSet::ResolveTransientServoStyle(
     Element* aElement,
     CSSPseudoElementType aPseudoType,
     nsIAtom* aPseudoTag,
@@ -502,17 +474,16 @@ ServoStyleSet::ResolveInheritingAnonymou
     nsString pseudo;
     aPseudoTag->ToString(pseudo);
     NS_ERROR(nsPrintfCString("stylo: could not get anon-box: %s",
              NS_ConvertUTF16toUTF8(pseudo).get()).get());
     MOZ_CRASH();
   }
 #endif
 
-  computedValues->UpdateWithElementState(nullptr);
   return computedValues.forget();
 }
 
 already_AddRefed<ServoStyleContext>
 ServoStyleSet::ResolveNonInheritingAnonymousBoxStyle(nsIAtom* aPseudoTag)
 {
   MOZ_ASSERT(nsCSSAnonBoxes::IsAnonBox(aPseudoTag) &&
              nsCSSAnonBoxes::IsNonInheritingAnonBox(aPseudoTag));
@@ -547,17 +518,16 @@ ServoStyleSet::ResolveNonInheritingAnony
     nsString pseudo;
     aPseudoTag->ToString(pseudo);
     NS_ERROR(nsPrintfCString("stylo: could not get anon-box: %s",
              NS_ConvertUTF16toUTF8(pseudo).get()).get());
     MOZ_CRASH();
   }
 #endif
 
-  computedValues->UpdateWithElementState(nullptr);
   cache = computedValues;
   return computedValues.forget();
 }
 
 // manage the set of style sheets in the style set
 nsresult
 ServoStyleSet::AppendStyleSheet(SheetType aType,
                                 ServoStyleSheet* aSheet)
@@ -779,40 +749,38 @@ ServoStyleSet::ProbePseudoElementStyle(E
   // For :before and :after pseudo-elements, having display: none or no
   // 'content' property is equivalent to not having the pseudo-element
   // at all.
   bool isBeforeOrAfter = aType == CSSPseudoElementType::before ||
                          aType == CSSPseudoElementType::after;
   if (isBeforeOrAfter) {
     const nsStyleDisplay* display = computedValues->ComputedData()->GetStyleDisplay();
     const nsStyleContent* content = computedValues->ComputedData()->GetStyleContent();
-    // XXXldb What is contentCount for |content: ""|?
     if (display->mDisplay == StyleDisplay::None ||
         content->ContentCount() == 0) {
       return nullptr;
     }
   }
 
-  computedValues->UpdateWithElementState(isBeforeOrAfter ? aOriginatingElement : nullptr);
   return computedValues.forget();
 }
 
 nsRestyleHint
 ServoStyleSet::HasStateDependentStyle(dom::Element* aElement,
                                       EventStates aStateMask)
 {
   NS_WARNING("stylo: HasStateDependentStyle always returns zero!");
   return nsRestyleHint(0);
 }
 
 nsRestyleHint
 ServoStyleSet::HasStateDependentStyle(dom::Element* aElement,
                                       CSSPseudoElementType aPseudoType,
-                                     dom::Element* aPseudoElement,
-                                     EventStates aStateMask)
+                                      dom::Element* aPseudoElement,
+                                      EventStates aStateMask)
 {
   NS_WARNING("stylo: HasStateDependentStyle always returns zero!");
   return nsRestyleHint(0);
 }
 
 bool
 ServoStyleSet::StyleDocument(TraversalRestyleBehavior aRestyleBehavior)
 {
@@ -1083,24 +1051,55 @@ ServoStyleSet::ClearDataAndMarkDeviceDir
 }
 
 void
 ServoStyleSet::CompatibilityModeChanged()
 {
   Servo_StyleSet_CompatModeChanged(mRawSet.get());
 }
 
+inline static void
+UpdateBodyTextColorIfNeeded(
+    const Element& aElement,
+    ServoStyleContext& aStyleContext,
+    nsPresContext& aPresContext)
+{
+  if (aPresContext.CompatibilityMode() != eCompatibility_NavQuirks) {
+    return;
+  }
+
+  if (!aElement.IsHTMLElement(nsGkAtoms::body)) {
+    return;
+  }
+
+  nsIDocument* doc = aElement.GetUncomposedDoc();
+  if (!doc || doc->GetBodyElement() != &aElement) {
+    return;
+  }
+
+  MOZ_ASSERT(!aStyleContext.GetPseudo());
+
+  // NOTE(emilio): We do the ComputedData() dance to avoid triggering the
+  // IsInServoTraversal() assertion in StyleColor(), which seems useful enough
+  // in the general case, I guess...
+  aPresContext.SetBodyTextColor(
+      aStyleContext.ComputedData()->GetStyleColor()->mColor);
+}
+
 already_AddRefed<ServoStyleContext>
 ServoStyleSet::ResolveServoStyle(Element* aElement,
                                  TraversalRestyleBehavior aRestyleBehavior)
 {
   UpdateStylistIfNeeded();
-  return Servo_ResolveStyle(aElement,
-                            mRawSet.get(),
-                            aRestyleBehavior).Consume();
+  RefPtr<ServoStyleContext> result =
+    Servo_ResolveStyle(aElement,
+                       mRawSet.get(),
+                       aRestyleBehavior).Consume();
+  UpdateBodyTextColorIfNeeded(*aElement, *result, *mPresContext);
+  return result.forget();
 }
 
 void
 ServoStyleSet::ClearNonInheritingStyleContexts()
 {
   for (RefPtr<ServoStyleContext>& ptr : mNonInheritingStyleContexts) {
     ptr = nullptr;
   }
@@ -1154,16 +1153,20 @@ ServoStyleSet::ResolveStyleLazily(Elemen
     computedValues =
       Servo_ResolveStyleLazily(elementForStyleResolution,
                                pseudoTypeForStyleResolution,
                                aRuleInclusion,
                                &Snapshots(),
                                mRawSet.get()).Consume();
   }
 
+  if (aPseudoType == CSSPseudoElementType::NotPseudo) {
+    UpdateBodyTextColorIfNeeded(*aElement, *computedValues, *mPresContext);
+  }
+
   return computedValues.forget();
 }
 
 bool
 ServoStyleSet::AppendFontFaceRules(nsTArray<nsFontFaceRuleContainer>& aArray)
 {
   UpdateStylistIfNeeded();
   Servo_StyleSet_GetFontFaceRules(mRawSet.get(), &aArray);
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -476,22 +476,16 @@ private:
       sInServoTraversal = nullptr;
       mSet->RunPostTraversalTasks();
     }
 
   private:
     ServoStyleSet* mSet;
   };
 
-  already_AddRefed<ServoStyleContext> GetContext(nsIContent* aContent,
-                                                 ServoStyleContext* aParentContext,
-                                                 nsIAtom* aPseudoTag,
-                                                 CSSPseudoElementType aPseudoType,
-                                                 LazyComputeBehavior aMayCompute);
-
   /**
    * Rebuild the style data. This will force a stylesheet flush, and also
    * recompute the default computed styles.
    */
   void RebuildData();
 
   /**
    * Gets the pending snapshots to handle from the restyle manager.