Bug 1125455 patch 2 - Set mWinsInCascade for transitions based on whether there are animations. r=birtles

This commit is contained in:
L. David Baron 2015-03-19 21:10:00 -07:00
Родитель 43ffda7be5
Коммит f93a10293b
5 изменённых файлов: 133 добавлений и 0 удалений

Просмотреть файл

@ -741,6 +741,14 @@ AnimationPlayerCollection::EnsureStyleRuleFor(TimeStamp aRefreshTime,
}
mManager->CheckNeedsRefresh();
// If one of our animations just started or stopped filling, we need
// to notify the transition manager. This does the notification a bit
// more than necessary, but it's easier than doing it exactly.
if (mManager->IsAnimationManager()) {
mManager->mPresContext->TransitionManager()->
UpdateCascadeResultsWithAnimations(this);
}
}
bool

Просмотреть файл

@ -24,6 +24,7 @@
#include "mozilla/FloatingPoint.h"
#include "nsCSSPseudoElements.h"
#include "nsCycleCollectionParticipant.h"
#include "nsCSSPropertySet.h"
class nsIFrame;
class nsPresContext;
@ -191,6 +192,14 @@ public:
mozilla::StyleAnimationValue mValue;
};
void AddPropertiesToSet(nsCSSPropertySet& aSet) const
{
for (size_t i = 0, i_end = mPropertyValuePairs.Length(); i < i_end; ++i) {
const PropertyValuePair &cv = mPropertyValuePairs[i];
aSet.AddProperty(cv.mProperty);
}
}
private:
~AnimValuesStyleRule() {}
@ -324,6 +333,19 @@ struct AnimationPlayerCollection : public PRCList
return NS_LITERAL_STRING("::after");
}
nsCSSPseudoElements::Type PseudoElementType() const
{
if (IsForElement()) {
return nsCSSPseudoElements::ePseudo_NotPseudoElement;
}
if (IsForBeforePseudo()) {
return nsCSSPseudoElements::ePseudo_before;
}
MOZ_ASSERT(IsForAfterPseudo(),
"::before & ::after should be the only pseudo-elements here");
return nsCSSPseudoElements::ePseudo_after;
}
mozilla::dom::Element* GetElementToRestyle() const;
void PostRestyleForAnimation(nsPresContext *aPresContext) {

Просмотреть файл

@ -272,6 +272,11 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext,
if (newPlayers.IsEmpty()) {
if (collection) {
// There might be transitions that run now that animations don't
// override them.
mPresContext->TransitionManager()->
UpdateCascadeResultsWithAnimationsToBeDestroyed(collection);
collection->Destroy();
}
return nullptr;

Просмотреть файл

@ -347,6 +347,8 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
"must have element transitions if we started any transitions");
if (collection) {
UpdateCascadeResultsWithTransitions(collection);
// Set the style rule refresh time to null so that EnsureStyleRuleFor
// creates a new style rule if we started *or* stopped transitions.
collection->mStyleRuleRefreshTime = TimeStamp();
@ -600,6 +602,93 @@ nsTransitionManager::ConsiderStartingTransition(
aWhichStarted->AddProperty(aProperty);
}
void
nsTransitionManager::UpdateCascadeResultsWithTransitions(
AnimationPlayerCollection* aTransitions)
{
AnimationPlayerCollection* animations =
mPresContext->AnimationManager()->
GetAnimationPlayers(aTransitions->mElement,
aTransitions->PseudoElementType(), false);
UpdateCascadeResults(aTransitions, animations);
}
void
nsTransitionManager::UpdateCascadeResultsWithAnimations(
const AnimationPlayerCollection* aAnimations)
{
AnimationPlayerCollection* transitions =
mPresContext->TransitionManager()->
GetAnimationPlayers(aAnimations->mElement,
aAnimations->PseudoElementType(), false);
UpdateCascadeResults(transitions, aAnimations);
}
void
nsTransitionManager::UpdateCascadeResultsWithAnimationsToBeDestroyed(
const AnimationPlayerCollection* aAnimations)
{
// aAnimations is about to be destroyed. So get transitions from it,
// but then don't pass it to UpdateCascadeResults, since it has
// information that may now be incorrect.
AnimationPlayerCollection* transitions =
mPresContext->TransitionManager()->
GetAnimationPlayers(aAnimations->mElement,
aAnimations->PseudoElementType(), false);
UpdateCascadeResults(transitions, nullptr);
}
void
nsTransitionManager::UpdateCascadeResults(
AnimationPlayerCollection* aTransitions,
const AnimationPlayerCollection* aAnimations)
{
if (!aTransitions) {
// Nothing to do.
return;
}
nsCSSPropertySet propertiesUsed;
#ifdef DEBUG
nsCSSPropertySet propertiesWithTransitions;
#endif
// http://dev.w3.org/csswg/css-transitions/#application says that
// transitions do not apply when the same property has a CSS Animation
// on that element (even though animations are lower in the cascade).
if (aAnimations && aAnimations->mStyleRule) {
aAnimations->mStyleRule->AddPropertiesToSet(propertiesUsed);
}
// Since we should never have more than one transition for the same
// property, it doesn't matter what order we iterate the transitions.
// But let's go the same way as animations.
bool changed = false;
AnimationPlayerPtrArray& players = aTransitions->mPlayers;
for (size_t playerIdx = players.Length(); playerIdx-- != 0; ) {
MOZ_ASSERT(players[playerIdx]->GetSource() &&
players[playerIdx]->GetSource()->Properties().Length() == 1,
"Should have one animation property for a transition");
AnimationProperty& prop = players[playerIdx]->GetSource()->Properties()[0];
bool newWinsInCascade = !propertiesUsed.HasProperty(prop.mProperty);
if (prop.mWinsInCascade != newWinsInCascade) {
changed = true;
}
prop.mWinsInCascade = newWinsInCascade;
// assert that we don't need to bother adding the transitioned
// properties into propertiesUsed
#ifdef DEBUG
MOZ_ASSERT(!propertiesWithTransitions.HasProperty(prop.mProperty),
"we're assuming we have only one transition per property");
propertiesWithTransitions.AddProperty(prop.mProperty);
#endif
}
if (changed) {
aTransitions->UpdateAnimationGeneration(mPresContext);
}
}
/*
* nsIStyleRuleProcessor implementation
*/

Просмотреть файл

@ -128,6 +128,15 @@ public:
nsStyleContext *aOldStyleContext,
nsRefPtr<nsStyleContext>* aNewStyleContext /* inout */);
void UpdateCascadeResultsWithTransitions(
AnimationPlayerCollection* aTransitions);
void UpdateCascadeResultsWithAnimations(
const AnimationPlayerCollection* aAnimations);
void UpdateCascadeResultsWithAnimationsToBeDestroyed(
const AnimationPlayerCollection* aAnimations);
void UpdateCascadeResults(AnimationPlayerCollection* aTransitions,
const AnimationPlayerCollection* aAnimations);
void SetInAnimationOnlyStyleUpdate(bool aInAnimationOnlyUpdate) {
mInAnimationOnlyStyleUpdate = aInAnimationOnlyUpdate;
}