Bug 1341372 - Part 1: Let animation-only restyle include css-transition.
Animation-only restyle should include both Animation and Transition
cascade levels.
MozReview-Commit-ID: Jo1sb5fGUC0
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -311,22 +311,22 @@ EffectCompositor::PostRestyleForAnimatio
eRestyle_CSSTransitions :
eRestyle_CSSAnimations;
if (mPresContext->StyleSet()->IsServo()) {
MOZ_ASSERT(NS_IsMainThread(),
"Restyle request during restyling should be requested only on "
"the main-thread. e.g. after the parallel traversal");
if (ServoStyleSet::IsInServoTraversal()) {
- // FIXME: Bug 1302946: We will handle eRestyle_CSSTransitions.
- MOZ_ASSERT(hint == eRestyle_CSSAnimations);
+ MOZ_ASSERT(hint == eRestyle_CSSAnimations ||
+ hint == eRestyle_CSSTransitions);
// We can't call Servo_NoteExplicitHints here since AtomicRefCell does not
// allow us mutate ElementData of the |aElement| in SequentialTask.
- // Instead we call Servo_NoteExplicitHints for the element in PreTraverse() right
+ // Instead we call Servo_NoteExplicitHints for the element in PreTraverse()
// which will be called right before the second traversal that we do for
// updating CSS animations.
// In that case PreTraverse() will return true so that we know to do the
// second traversal so we don't need to post any restyle requests to the
// PresShell.
return;
} else {
MOZ_ASSERT(!mPresContext->RestyleManager()->IsInStyleRefresh());
@@ -977,18 +977,20 @@ IsFlattenedTreeDescendantOf(nsINode* aPo
bool
EffectCompositor::PreTraverseInSubtree(Element* aRoot)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mPresContext->RestyleManager()->IsServo());
bool foundElementsNeedingRestyle = false;
- for (auto& elementsToRestyle : mElementsToRestyle) {
- for (auto iter = elementsToRestyle.Iter(); !iter.Done(); iter.Next()) {
+ for (size_t i = 0; i < kCascadeLevelCount; ++i) {
+ CascadeLevel cascadeLevel = CascadeLevel(i);
+ for (auto iter = mElementsToRestyle[cascadeLevel].Iter();
+ !iter.Done(); iter.Next()) {
bool postedRestyle = iter.Data();
// Ignore throttled restyle.
if (!postedRestyle) {
continue;
}
NonOwningAnimationTarget target = iter.Key();
@@ -998,17 +1000,20 @@ EffectCompositor::PreTraverseInSubtree(E
continue;
}
// We need to post restyle hints even if the target is not in EffectSet to
// ensure the final restyling for removed animations.
// We can't call PostRestyleEvent directly here since we are still in the
// middle of the servo traversal.
mPresContext->RestyleManager()->AsServo()->
- PostRestyleEventForAnimations(target.mElement, eRestyle_CSSAnimations);
+ PostRestyleEventForAnimations(target.mElement,
+ cascadeLevel == CascadeLevel::Transitions
+ ? eRestyle_CSSTransitions
+ : eRestyle_CSSAnimations);
foundElementsNeedingRestyle = true;
EffectSet* effects =
EffectSet::GetEffectSet(target.mElement, target.mPseudoType);
if (!effects) {
// Drop EffectSets that have been destroyed.
iter.Remove();
@@ -1043,35 +1048,42 @@ EffectCompositor::PreTraverse(dom::Eleme
}
CSSPseudoElementType pseudoType =
nsCSSPseudoElements::GetPseudoType(aPseudoTagOrNull,
CSSEnabledState::eForAllContent);
PseudoElementHashEntry::KeyType key = { aElement, pseudoType };
- for (auto& elementsToRestyle : mElementsToRestyle) {
- if (!elementsToRestyle.Get(key)) {
+
+ for (size_t i = 0; i < kCascadeLevelCount; ++i) {
+ CascadeLevel cascadeLevel = CascadeLevel(i);
+ auto& elementSet = mElementsToRestyle[cascadeLevel];
+
+ if (!elementSet.Get(key)) {
// Ignore throttled restyle and no restyle request.
continue;
}
mPresContext->RestyleManager()->AsServo()->
- PostRestyleEventForAnimations(aElement, eRestyle_CSSAnimations);
+ PostRestyleEventForAnimations(aElement,
+ cascadeLevel == CascadeLevel::Transitions
+ ? eRestyle_CSSTransitions
+ : eRestyle_CSSAnimations);
EffectSet* effects = EffectSet::GetEffectSet(aElement, pseudoType);
if (effects) {
MaybeUpdateCascadeResults(aElement, pseudoType);
for (KeyframeEffectReadOnly* effect : *effects) {
effect->GetAnimation()->WillComposeStyle();
}
}
- elementsToRestyle.Remove(key);
+ elementSet.Remove(key);
found = true;
}
return found;
}
// ---------------------------------------------------------
//
// Nested class: AnimationStyleRuleProcessor
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -286,17 +286,17 @@ ServoStyleSet::PrepareAndTraverseSubtree
aRestyleBehavior == TraversalRestyleBehavior::ForReconstruct;
bool postTraversalRequired =
Servo_TraverseSubtree(aRoot, mRawSet.get(), aRootBehavior, aRestyleBehavior);
MOZ_ASSERT_IF(isInitial || forReconstruct, !postTraversalRequired);
auto root = const_cast<Element*>(aRoot);
// If there are still animation restyles needed, trigger a second traversal to
- // update CSS animations' styles.
+ // update CSS animations or transitions' styles.
EffectCompositor* compositor = mPresContext->EffectCompositor();
if (forReconstruct ? compositor->PreTraverseInSubtree(root)
: compositor->PreTraverse()) {
if (Servo_TraverseSubtree(aRoot, mRawSet.get(),
aRootBehavior, aRestyleBehavior)) {
MOZ_ASSERT(!forReconstruct);
if (isInitial) {
// We're doing initial styling, and the additional animation