Bug 1330190 - Part 2: Add a new function named ResolveStyleWithoutAnimation. r?heycam
Unlike the other one this function does not need an old nsStyleContext.
This function just resolves style without all animation data in the first place.
The existing ResolveStyleWithoutAnimation is renamed to
ResolveStyleByRemovingAnimation.
MozReview-Commit-ID: 1RmCQNw0MmW
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -905,18 +905,18 @@ EffectCompositor::GetBaseStyle(nsCSSProp
// Check whether there is a cached style.
result = effectSet->GetBaseStyle(aProperty);
if (!result.IsNull()) {
return result;
}
RefPtr<nsStyleContext> styleContextWithoutAnimation =
aStyleContext->PresContext()->StyleSet()->AsGecko()->
- ResolveStyleWithoutAnimation(&aElement, aStyleContext,
- eRestyle_AllHintsWithAnimations);
+ ResolveStyleByRemovingAnimation(&aElement, aStyleContext,
+ eRestyle_AllHintsWithAnimations);
DebugOnly<bool> success =
StyleAnimationValue::ExtractComputedValue(aProperty,
styleContextWithoutAnimation,
result);
MOZ_ASSERT(success, "Should be able to extract computed animation value");
MOZ_ASSERT(!result.IsNull(), "Should have a valid StyleAnimationValue");
--- a/layout/style/nsAnimationManager.cpp
+++ b/layout/style/nsAnimationManager.cpp
@@ -1036,18 +1036,18 @@ CSSAnimationBuilder::GetComputedValue(ns
nsCSSValue result;
StyleAnimationValue computedValue;
if (!mStyleWithoutAnimation) {
MOZ_ASSERT(aPresContext->StyleSet()->IsGecko(),
"ServoStyleSet should not use nsAnimationManager for "
"animations");
mStyleWithoutAnimation = aPresContext->StyleSet()->AsGecko()->
- ResolveStyleWithoutAnimation(mTarget, mStyleContext,
- eRestyle_AllHintsWithAnimations);
+ ResolveStyleByRemovingAnimation(mTarget, mStyleContext,
+ eRestyle_AllHintsWithAnimations);
}
if (StyleAnimationValue::ExtractComputedValue(aProperty,
mStyleWithoutAnimation,
computedValue)) {
DebugOnly<bool> uncomputeResult =
StyleAnimationValue::UncomputeValue(aProperty, Move(computedValue),
result);
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -1346,19 +1346,20 @@ nsStyleSet::ResolveStyleFor(Element* aEl
{
TreeMatchContext treeContext(true, nsRuleWalker::eRelevantLinkUnvisited,
aElement->OwnerDoc());
InitStyleScopes(treeContext, aElement);
return ResolveStyleFor(aElement, aParentContext, treeContext);
}
already_AddRefed<nsStyleContext>
-nsStyleSet::ResolveStyleFor(Element* aElement,
- nsStyleContext* aParentContext,
- TreeMatchContext& aTreeMatchContext)
+nsStyleSet::ResolveStyleForInternal(Element* aElement,
+ nsStyleContext* aParentContext,
+ TreeMatchContext& aTreeMatchContext,
+ AnimationFlag aAnimationFlag)
{
NS_ENSURE_FALSE(mInShutdown, nullptr);
NS_ASSERTION(aElement, "aElement must not be null");
nsRuleWalker ruleWalker(mRuleTree, mAuthorStyleDisabled);
aTreeMatchContext.ResetForUnvisitedMatching();
ElementRuleProcessorData data(PresContext(), aElement, &ruleWalker,
aTreeMatchContext);
@@ -1372,17 +1373,17 @@ nsStyleSet::ResolveStyleFor(Element* aEl
if (aTreeMatchContext.HaveRelevantLink()) {
aTreeMatchContext.ResetForVisitedMatching();
ruleWalker.Reset();
FileRules(EnumRulesMatching<ElementRuleProcessorData>, &data, aElement,
&ruleWalker);
visitedRuleNode = ruleWalker.CurrentNode();
}
- uint32_t flags = eDoAnimation;
+ uint32_t flags = (aAnimationFlag == eWithAnimation) ? eDoAnimation : eNoFlags;
if (nsCSSRuleProcessor::IsLink(aElement)) {
flags |= eIsLink;
}
if (nsCSSRuleProcessor::GetContentState(aElement, aTreeMatchContext).
HasState(NS_EVENT_STATE_VISITED)) {
flags |= eIsVisitedLink;
}
if (aTreeMatchContext.mSkippingParentDisplayBasedStyleFixup) {
@@ -1390,16 +1391,27 @@ nsStyleSet::ResolveStyleFor(Element* aEl
}
return GetContext(aParentContext, ruleNode, visitedRuleNode,
nullptr, CSSPseudoElementType::NotPseudo,
aElement, flags);
}
already_AddRefed<nsStyleContext>
+nsStyleSet::ResolveStyleFor(Element* aElement,
+ nsStyleContext* aParentContext,
+ TreeMatchContext& aTreeMatchContext)
+{
+ return ResolveStyleForInternal(aElement,
+ aParentContext,
+ aTreeMatchContext,
+ eWithAnimation);
+}
+
+already_AddRefed<nsStyleContext>
nsStyleSet::ResolveStyleForRules(nsStyleContext* aParentContext,
const nsTArray< nsCOMPtr<nsIStyleRule> > &aRules)
{
NS_ENSURE_FALSE(mInShutdown, nullptr);
nsRuleWalker ruleWalker(mRuleTree, mAuthorStyleDisabled);
// FIXME: Perhaps this should be passed in, but it probably doesn't
// matter.
@@ -1743,19 +1755,19 @@ nsStyleSet::ResolveStyleWithReplacement(
}
return GetContext(aNewParentContext, ruleNode, visitedRuleNode,
aOldStyleContext->GetPseudo(), pseudoType,
elementForAnimation, flags);
}
already_AddRefed<nsStyleContext>
-nsStyleSet::ResolveStyleWithoutAnimation(dom::Element* aTarget,
- nsStyleContext* aStyleContext,
- nsRestyleHint aWhichToRemove)
+nsStyleSet::ResolveStyleByRemovingAnimation(dom::Element* aTarget,
+ nsStyleContext* aStyleContext,
+ nsRestyleHint aWhichToRemove)
{
#ifdef DEBUG
CSSPseudoElementType pseudoType = aStyleContext->GetPseudoType();
#endif
MOZ_ASSERT(pseudoType == CSSPseudoElementType::NotPseudo ||
pseudoType == CSSPseudoElementType::before ||
pseudoType == CSSPseudoElementType::after,
"unexpected type for animations");
@@ -1773,16 +1785,44 @@ nsStyleSet::ResolveStyleWithoutAnimation
eSkipStartingAnimations);
restyleManager->SetSkipAnimationRules(oldSkipAnimationRules);
return result.forget();
}
already_AddRefed<nsStyleContext>
+nsStyleSet::ResolveStyleWithoutAnimation(Element* aTarget,
+ nsStyleContext* aParentContext)
+{
+ RestyleManager* restyleManager = PresContext()->RestyleManager()->AsGecko();
+
+ TreeMatchContext treeContext(true, nsRuleWalker::eRelevantLinkUnvisited,
+ aTarget->OwnerDoc());
+ InitStyleScopes(treeContext, aTarget);
+
+ bool oldSkipAnimationRules = restyleManager->SkipAnimationRules();
+ restyleManager->SetSkipAnimationRules(true);
+
+ // Here we can call ResolveStyleForInternal() instead of
+ // ResolveStyleWithReplacement() since we don't need any animation rules
+ // (CSS Animations, Transitions and script animations). That's because
+ // EffectCompositor::GetAnimationRule() skips all of animations rules if
+ // SkipAnimationRules flag is true.
+ RefPtr<nsStyleContext> result = ResolveStyleForInternal(aTarget,
+ aParentContext,
+ treeContext,
+ eWithoutAnimation);
+
+ restyleManager->SetSkipAnimationRules(oldSkipAnimationRules);
+
+ return result.forget();
+}
+
+already_AddRefed<nsStyleContext>
nsStyleSet::ResolveStyleForText(nsIContent* aTextNode,
nsStyleContext* aParentContext)
{
MOZ_ASSERT(aTextNode && aTextNode->IsNodeOfType(nsINode::eTEXT));
return GetContext(aParentContext, mRuleTree, nullptr,
nsCSSAnonBoxes::mozText,
CSSPseudoElementType::AnonBox, nullptr, eNoFlags);
}
--- a/layout/style/nsStyleSet.h
+++ b/layout/style/nsStyleSet.h
@@ -176,19 +176,25 @@ class nsStyleSet final
nsRestyleHint aReplacements,
uint32_t aFlags = 0);
// Resolve style by returning a style context with the specified
// animation data removed. It is allowable to remove all animation
// data with eRestyle_AllHintsWithAnimations, or by using any other
// hints that are allowed by ResolveStyleWithReplacement.
already_AddRefed<nsStyleContext>
- ResolveStyleWithoutAnimation(mozilla::dom::Element* aElement,
- nsStyleContext* aStyleContext,
- nsRestyleHint aWhichToRemove);
+ ResolveStyleByRemovingAnimation(mozilla::dom::Element* aElement,
+ nsStyleContext* aStyleContext,
+ nsRestyleHint aWhichToRemove);
+
+ // Similar to the above, but resolving style without all animation data in
+ // the first place.
+ already_AddRefed<nsStyleContext>
+ ResolveStyleWithoutAnimation(mozilla::dom::Element* aTarget,
+ nsStyleContext* aParentContext);
// Get a style context for a text node (which no rules will match).
//
// The returned style context will have nsCSSAnonBoxes::mozText as its pseudo.
//
// (Perhaps mozText should go away and we shouldn't even create style
// contexts for such content nodes, when text-combine-upright is not
// present. However, not doing any rule matching for them is a first step.)
@@ -521,16 +527,26 @@ private:
GetContext(nsStyleContext* aParentContext,
nsRuleNode* aRuleNode,
nsRuleNode* aVisitedRuleNode,
nsIAtom* aPseudoTag,
mozilla::CSSPseudoElementType aPseudoType,
mozilla::dom::Element* aElementForAnimation,
uint32_t aFlags);
+ enum AnimationFlag {
+ eWithAnimation,
+ eWithoutAnimation,
+ };
+ already_AddRefed<nsStyleContext>
+ ResolveStyleForInternal(mozilla::dom::Element* aElement,
+ nsStyleContext* aParentContext,
+ TreeMatchContext& aTreeMatchContext,
+ AnimationFlag aAnimationFlag);
+
nsPresContext* PresContext() { return mRuleTree->PresContext(); }
// The sheets in each array in mSheets are stored with the most significant
// sheet last.
// The arrays for ePresHintSheet, eStyleAttrSheet, eTransitionSheet,
// eAnimationSheet and eSVGAttrAnimationSheet are always empty.
// (FIXME: We should reduce the storage needed for them.)
mozilla::EnumeratedArray<mozilla::SheetType, mozilla::SheetType::Count,
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -553,18 +553,18 @@ nsTransitionManager::StyleContextChanged
// not stopping or starting right now.
RefPtr<nsStyleContext> afterChangeStyle;
if (collection) {
MOZ_ASSERT(mPresContext->StyleSet()->IsGecko(),
"ServoStyleSets should not use nsTransitionManager "
"for transitions");
nsStyleSet* styleSet = mPresContext->StyleSet()->AsGecko();
afterChangeStyle =
- styleSet->ResolveStyleWithoutAnimation(aElement, newStyleContext,
- eRestyle_CSSTransitions);
+ styleSet->ResolveStyleByRemovingAnimation(aElement, newStyleContext,
+ eRestyle_CSSTransitions);
} else {
afterChangeStyle = newStyleContext;
}
nsAutoAnimationMutationBatch mb(aElement->OwnerDoc());
DebugOnly<bool> startedAny = false;
// We don't have to update transitions if display:none, although we will