Bug 1087541 - Make RuleNodeWithReplacement handle animations and transitions like RulesMatching codepath does. r=birtles

I originally wrote this to see if it would fix bug 1086937, but it
didn't.

Note that this conflicts a bit with the patch in bug 1085769; whoever
lands second will have some merging (though it shouldn't be difficult).

The updating of the style rule is needed as part of the animation-only
style update, but it shouldn't be in the general restyling code, so it
has moved there.
This commit is contained in:
L. David Baron 2014-11-11 15:42:57 -08:00
parent 888295aca2
commit e60f613f42
5 changed files with 33 additions and 63 deletions

View File

@ -170,12 +170,16 @@ CommonAnimationManager::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
void
CommonAnimationManager::AddStyleUpdatesTo(RestyleTracker& aTracker)
{
TimeStamp now = mPresContext->RefreshDriver()->MostRecentRefresh();
PRCList* next = PR_LIST_HEAD(&mElementCollections);
while (next != &mElementCollections) {
AnimationPlayerCollection* collection =
static_cast<AnimationPlayerCollection*>(next);
next = PR_NEXT_LINK(next);
collection->EnsureStyleRuleFor(now, EnsureStyleRule_IsNotThrottled);
dom::Element* elementToRestyle = collection->GetElementToRestyle();
if (elementToRestyle) {
nsRestyleHint rshint = collection->IsForTransitions()

View File

@ -224,6 +224,8 @@ public:
GetAnimationPlayers(mozilla::dom::Element *aElement,
nsCSSPseudoElements::Type aPseudoType,
bool aCreateIfNeeded);
nsIStyleRule* GetAnimationRule(mozilla::dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType);
protected:
virtual void ElementCollectionRemoved() MOZ_OVERRIDE
@ -250,8 +252,6 @@ private:
float aFromKey, nsStyleContext* aFromContext,
mozilla::css::Declaration* aFromDeclaration,
float aToKey, nsStyleContext* aToContext);
nsIStyleRule* GetAnimationRule(mozilla::dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType);
// The guts of DispatchEvents
void DoDispatchEvents();

View File

@ -1367,9 +1367,6 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement,
nsPrintfCString("unexpected replacement bits 0x%lX",
uint32_t(aReplacements)).get());
bool skipAnimationRules = false;
bool postAnimationRestyles = false;
// If we're changing animation phase, we have to reconsider what rules
// are in these four levels.
if (aReplacements & eRestyle_ChangeAnimationPhase) {
@ -1377,10 +1374,6 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement,
eRestyle_CSSAnimations |
eRestyle_SVGAttrAnimations |
eRestyle_StyleAttribute;
RestyleManager* restyleManager = PresContext()->RestyleManager();
skipAnimationRules = restyleManager->SkipAnimationRules();
postAnimationRestyles = restyleManager->PostAnimationRestyles();
}
// FIXME (perf): This should probably not rebuild the whole path, but
@ -1421,53 +1414,23 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement,
if (doReplace) {
switch (level->mLevelReplacementHint) {
case eRestyle_CSSAnimations: {
// FIXME: This should probably be more similar to what
// FileRules does; this feels like too much poking into the
// internals of nsAnimationManager.
nsPresContext* presContext = PresContext();
nsAnimationManager* animationManager =
presContext->AnimationManager();
AnimationPlayerCollection* collection =
animationManager->GetAnimationPlayers(aElement, aPseudoType, false);
if (collection) {
if (skipAnimationRules) {
if (postAnimationRestyles) {
collection->PostRestyleForAnimation(presContext);
}
} else {
animationManager->UpdateStyleAndEvents(
collection, PresContext()->RefreshDriver()->MostRecentRefresh(),
EnsureStyleRule_IsNotThrottled);
if (collection->mStyleRule) {
ruleWalker.ForwardOnPossiblyCSSRule(collection->mStyleRule);
}
if (aPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement ||
aPseudoType == nsCSSPseudoElements::ePseudo_before ||
aPseudoType == nsCSSPseudoElements::ePseudo_after) {
nsIStyleRule* rule = PresContext()->AnimationManager()->
GetAnimationRule(aElement, aPseudoType);
if (rule) {
ruleWalker.ForwardOnPossiblyCSSRule(rule);
}
}
break;
}
case eRestyle_CSSTransitions: {
// FIXME: This should probably be more similar to what
// FileRules does; this feels like too much poking into the
// internals of nsTransitionManager.
nsPresContext* presContext = PresContext();
AnimationPlayerCollection* collection =
presContext->TransitionManager()->GetElementTransitions(
aElement, aPseudoType, false);
if (collection) {
if (skipAnimationRules) {
if (postAnimationRestyles) {
collection->PostRestyleForAnimation(presContext);
}
} else {
collection->EnsureStyleRuleFor(
presContext->RefreshDriver()->MostRecentRefresh(),
EnsureStyleRule_IsNotThrottled);
if (collection->mStyleRule) {
ruleWalker.ForwardOnPossiblyCSSRule(collection->mStyleRule);
}
}
if (aPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement ||
aPseudoType == nsCSSPseudoElements::ePseudo_before ||
aPseudoType == nsCSSPseudoElements::ePseudo_after) {
PresContext()->TransitionManager()->
WalkTransitionRule(aElement, aPseudoType, &ruleWalker);
}
break;
}

View File

@ -626,12 +626,12 @@ nsTransitionManager::GetElementTransitions(
*/
void
nsTransitionManager::WalkTransitionRule(
ElementDependentRuleProcessorData* aData,
nsCSSPseudoElements::Type aPseudoType)
nsTransitionManager::WalkTransitionRule(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
nsRuleWalker* aRuleWalker)
{
AnimationPlayerCollection* collection =
GetElementTransitions(aData->mElement, aPseudoType, false);
GetElementTransitions(aElement, aPseudoType, false);
if (!collection) {
return;
}
@ -641,7 +641,7 @@ nsTransitionManager::WalkTransitionRule(
return;
}
RestyleManager* restyleManager = aData->mPresContext->RestyleManager();
RestyleManager* restyleManager = mPresContext->RestyleManager();
if (restyleManager->SkipAnimationRules()) {
// If we're processing a normal style change rather than one from
// animation, don't add the transition rule. This allows us to
@ -658,11 +658,11 @@ nsTransitionManager::WalkTransitionRule(
collection->mNeedsRefreshes = true;
collection->EnsureStyleRuleFor(
aData->mPresContext->RefreshDriver()->MostRecentRefresh(),
mPresContext->RefreshDriver()->MostRecentRefresh(),
EnsureStyleRule_IsNotThrottled);
if (collection->mStyleRule) {
aData->mRuleWalker->Forward(collection->mStyleRule);
aRuleWalker->Forward(collection->mStyleRule);
}
}
@ -671,8 +671,9 @@ nsTransitionManager::RulesMatching(ElementRuleProcessorData* aData)
{
NS_ABORT_IF_FALSE(aData->mPresContext == mPresContext,
"pres context mismatch");
WalkTransitionRule(aData,
nsCSSPseudoElements::ePseudo_NotPseudoElement);
WalkTransitionRule(aData->mElement,
nsCSSPseudoElements::ePseudo_NotPseudoElement,
aData->mRuleWalker);
}
/* virtual */ void
@ -684,7 +685,8 @@ nsTransitionManager::RulesMatching(PseudoElementRuleProcessorData* aData)
// Note: If we're the only thing keeping a pseudo-element frame alive
// (per ProbePseudoStyleContext), we still want to keep it alive, so
// this is ok.
WalkTransitionRule(aData, aData->mPseudoType);
WalkTransitionRule(aData->mElement, aData->mPseudoType,
aData->mRuleWalker);
}
/* virtual */ void

View File

@ -148,6 +148,9 @@ public:
mozilla::dom::Element *aElement,
nsCSSPseudoElements::Type aPseudoType,
bool aCreateIfNeeded);
void WalkTransitionRule(mozilla::dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
nsRuleWalker* aRuleWalker);
protected:
virtual void ElementCollectionRemoved() MOZ_OVERRIDE;
@ -164,8 +167,6 @@ private:
nsStyleContext* aNewStyleContext,
bool* aStartedAny,
nsCSSPropertySet* aWhichStarted);
void WalkTransitionRule(ElementDependentRuleProcessorData* aData,
nsCSSPseudoElements::Type aPseudoType);
bool mInAnimationOnlyStyleUpdate;
};