Bug 1057129 patch 3 - Post restyles from CheckAnimationRule directly to pseudo-elements. r=birtles

This matches patch 2, and also fixes an incorrect use of eRestyle_Self
on the parents of pseudo-elements in order to restyle those
pseudo-elements, where it would not previously have been effective.

This should all be temporary, since this code can go away with bug
960465, when animation phases are removed.
This commit is contained in:
L. David Baron 2014-08-24 21:48:22 -07:00
parent 043753b487
commit a07671d470
3 changed files with 39 additions and 17 deletions

View File

@ -2108,8 +2108,13 @@ RestyleManager::ReparentStyleContext(nsIFrame* aFrame)
ElementForStyleContext(parentFrame ? parentFrame->GetContent() : nullptr,
aFrame,
oldContext->GetPseudoType());
nsIContent* pseudoElementContent = aFrame->GetContent();
Element* pseudoElement =
(pseudoElementContent && pseudoElementContent->IsElement())
? pseudoElementContent->AsElement() : nullptr;
newContext = mPresContext->StyleSet()->
ReparentStyleContext(oldContext, newParentContext, element);
ReparentStyleContext(oldContext, newParentContext, element,
pseudoElement);
}
if (newContext) {
@ -2187,7 +2192,7 @@ RestyleManager::ReparentStyleContext(nsIFrame* aFrame)
nsRefPtr<nsStyleContext> newExtraContext;
newExtraContext = mPresContext->StyleSet()->
ReparentStyleContext(oldExtraContext,
newContext, nullptr);
newContext, nullptr, nullptr);
if (newExtraContext) {
if (newExtraContext != oldExtraContext) {
// Make sure to call CalcStyleDifference so that the new
@ -2529,8 +2534,13 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, nsRestyleHint aRestyleHint)
Element* element = ElementForStyleContext(mParentContent, aSelf, pseudoType);
if (aRestyleHint == nsRestyleHint(0) &&
!styleSet->IsInRuleTreeReconstruct()) {
nsIContent* pseudoElementContent = aSelf->GetContent();
Element* pseudoElement =
(pseudoElementContent && pseudoElementContent->IsElement())
? pseudoElementContent->AsElement() : nullptr;
newContext =
styleSet->ReparentStyleContext(oldContext, parentContext, element);
styleSet->ReparentStyleContext(oldContext, parentContext, element,
pseudoElement);
} else {
// Use ResolveStyleWithReplacement either for actual replacements
// or, with no replacements, as a substitute for
@ -2656,8 +2666,13 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, nsRestyleHint aRestyleHint)
oldExtraContext,
nsRestyleHint(0));
} else {
nsIContent* pseudoElementContent = aSelf->GetContent();
Element* pseudoElement =
(pseudoElementContent && pseudoElementContent->IsElement())
? pseudoElementContent->AsElement() : nullptr;
newExtraContext =
styleSet->ReparentStyleContext(oldExtraContext, newContext, element);
styleSet->ReparentStyleContext(oldExtraContext, newContext, element,
pseudoElement);
}
} else if (extraPseudoType == nsCSSPseudoElements::ePseudo_AnonBox) {
newExtraContext = styleSet->ResolveAnonymousBoxStyle(extraPseudoTag,
@ -2825,7 +2840,7 @@ ElementRestyler::RestyleUndisplayedChildren(nsRestyleHint aChildRestyleHint)
undisplayedContext =
styleSet->ReparentStyleContext(undisplayed->mStyle,
mFrame->StyleContext(),
element);
element, element);
}
const nsStyleDisplay* display = undisplayedContext->StyleDisplay();
if (display->mDisplay != NS_STYLE_DISPLAY_NONE) {

View File

@ -1976,7 +1976,7 @@ nsStyleSet::GCRuleTrees()
* rules removed, and post a restyle if needed.
*/
static inline nsRuleNode*
SkipAnimationRules(nsRuleNode* aRuleNode, Element* aElement, bool isPseudo)
SkipAnimationRules(nsRuleNode* aRuleNode, Element* aElementOrPseudoElement)
{
nsRuleNode* ruleNode = aRuleNode;
// The transition rule must be at the top of the cascade.
@ -1996,12 +1996,13 @@ SkipAnimationRules(nsRuleNode* aRuleNode, Element* aElement, bool isPseudo)
}
if (ruleNode != aRuleNode) {
NS_ASSERTION(aElement, "How can we have transition rules but no element?");
NS_ASSERTION(aElementOrPseudoElement,
"How can we have transition rules but no element?");
// Need to do an animation restyle, just like
// nsTransitionManager::WalkTransitionRule and
// nsAnimationManager::GetAnimationRule would.
nsRestyleHint hint = isPseudo ? eRestyle_Subtree : eRestyle_Self;
aRuleNode->PresContext()->PresShell()->RestyleForAnimation(aElement, hint);
aRuleNode->PresContext()->PresShell()->
RestyleForAnimation(aElementOrPseudoElement, eRestyle_Self);
}
return ruleNode;
}
@ -2009,7 +2010,11 @@ SkipAnimationRules(nsRuleNode* aRuleNode, Element* aElement, bool isPseudo)
already_AddRefed<nsStyleContext>
nsStyleSet::ReparentStyleContext(nsStyleContext* aStyleContext,
nsStyleContext* aNewParentContext,
Element* aElement)
Element* aElement,
// aElementOrPseudoElement is temporary
// until bug 960465 lands, and for
// SkipAnimationRules only
Element* aElementOrPseudoElement)
{
MOZ_ASSERT(aStyleContext, "aStyleContext must not be null");
@ -2033,9 +2038,7 @@ nsStyleSet::ReparentStyleContext(nsStyleContext* aStyleContext,
// our new style context. If we need them, an animation restyle will
// provide.
ruleNode =
SkipAnimationRules(ruleNode, aElement,
pseudoType !=
nsCSSPseudoElements::ePseudo_NotPseudoElement);
SkipAnimationRules(ruleNode, aElementOrPseudoElement);
}
nsRuleNode* visitedRuleNode = nullptr;
@ -2050,9 +2053,7 @@ nsStyleSet::ReparentStyleContext(nsStyleContext* aStyleContext,
if (skipAnimationRules) {
// FIXME do something here for animations?
visitedRuleNode =
SkipAnimationRules(visitedRuleNode, aElement,
pseudoType !=
nsCSSPseudoElements::ePseudo_NotPseudoElement);
SkipAnimationRules(visitedRuleNode, aElementOrPseudoElement);
}
}

View File

@ -222,10 +222,16 @@ class nsStyleSet
// aElement should be non-null if this is a style context for an
// element or pseudo-element; in the latter case it should be the
// real element the pseudo-element is for.
// aElementOrPseudoElement should be the same, except for
// pseudo-elements it should be the pseudo-element. It is temporary
// until bug 960465 lands. It only really needs to be correct for
// things we run animations on (elements and ::before and ::after
// pseudo-elements).
already_AddRefed<nsStyleContext>
ReparentStyleContext(nsStyleContext* aStyleContext,
nsStyleContext* aNewParentContext,
mozilla::dom::Element* aElement);
mozilla::dom::Element* aElement,
mozilla::dom::Element* aElementOrPseudoElement);
// Test if style is dependent on a document state.
bool HasDocumentStateDependentStyle(nsPresContext* aPresContext,