nsStyleContext* nsTransitionManager::UpdateThrottledStyle(dom::Element* aElement, nsStyleContext* aParentStyle) { NS_ASSERTION(GetElementTransitions(aElement, nsCSSPseudoElements::ePseudo_NotPseudoElement, false), "element not transitioning"); nsIFrame* primaryFrame = aElement->GetPrimaryFrame(); if (!primaryFrame) { return nullptr; } nsStyleContext* oldStyle = primaryFrame->GetStyleContext(); nsRuleNode* ruleNode = oldStyle->GetRuleNode(); nsTArray<nsStyleSet::RuleAndLevel> rules; do { if (ruleNode->IsRoot()) { break; } nsStyleSet::RuleAndLevel* curRule = rules.AppendElement(); curRule->mLevel = ruleNode->GetLevel(); if (curRule->mLevel == nsStyleSet::eAnimationSheet) { ElementAnimations* ea = mPresContext->AnimationManager()->GetElementAnimations(aElement, oldStyle->GetPseudoType(), false); NS_ASSERTION(ea, "Rule has level eAnimationSheet without animation on manager"); mPresContext->AnimationManager()->EnsureStyleRuleFor(ea); curRule->mRule = ea->mStyleRule; ForceLayerRerendering(primaryFrame, ea); } else if (curRule->mLevel == nsStyleSet::eTransitionSheet) { ElementTransitions *et = GetElementTransitions(aElement, oldStyle->GetPseudoType(), false); NS_ASSERTION(et, "Rule has level eTransitionSheet without transition on manager"); et->EnsureStyleRuleFor(mPresContext->RefreshDriver()->MostRecentRefresh()); curRule->mRule = et->mStyleRule; ForceLayerRerendering(primaryFrame, et); } else { curRule->mRule = ruleNode->GetRule(); } } while ((ruleNode = ruleNode->GetParent())); nsRefPtr<nsStyleContext> newStyle = mPresContext->PresShell()->StyleSet()-> ResolveStyleForRules(aParentStyle, oldStyle, rules); primaryFrame->SetStyleContextWithoutNotification(newStyle); ReparentBeforeAndAfter(aElement, primaryFrame, newStyle, mPresContext->PresShell()->StyleSet()); return newStyle; }
nsStyleContext* CommonAnimationManager::UpdateThrottledStyle(dom::Element* aElement, nsStyleContext* aParentStyle, nsStyleChangeList& aChangeList) { NS_ASSERTION(mPresContext->TransitionManager()->GetElementTransitions( aElement, nsCSSPseudoElements::ePseudo_NotPseudoElement, false) || mPresContext->AnimationManager()->GetElementAnimations( aElement, nsCSSPseudoElements::ePseudo_NotPseudoElement, false), "element not animated"); nsIFrame* primaryFrame = nsLayoutUtils::GetStyleFrame(aElement); if (!primaryFrame) { return nullptr; } nsStyleContext* oldStyle = primaryFrame->StyleContext(); nsRuleNode* ruleNode = oldStyle->RuleNode(); nsTArray<nsStyleSet::RuleAndLevel> rules; do { if (ruleNode->IsRoot()) { break; } nsStyleSet::RuleAndLevel curRule; curRule.mLevel = ruleNode->GetLevel(); if (curRule.mLevel == nsStyleSet::eAnimationSheet) { ElementAnimations* ea = mPresContext->AnimationManager()->GetElementAnimations( aElement, oldStyle->GetPseudoType(), false); NS_ASSERTION(ea, "Rule has level eAnimationSheet without animation on manager"); mPresContext->AnimationManager()->EnsureStyleRuleFor(ea); curRule.mRule = ea->mStyleRule; } else if (curRule.mLevel == nsStyleSet::eTransitionSheet) { ElementTransitions *et = mPresContext->TransitionManager()->GetElementTransitions( aElement, oldStyle->GetPseudoType(), false); NS_ASSERTION(et, "Rule has level eTransitionSheet without transition on manager"); et->EnsureStyleRuleFor(mPresContext->RefreshDriver()->MostRecentRefresh()); curRule.mRule = et->mStyleRule; } else { curRule.mRule = ruleNode->GetRule(); } if (curRule.mRule) { rules.AppendElement(curRule); } } while ((ruleNode = ruleNode->GetParent())); nsRefPtr<nsStyleContext> newStyle = mPresContext->PresShell()->StyleSet()-> ResolveStyleForRules(aParentStyle, oldStyle, rules); // We absolutely must call CalcStyleDifference in order to ensure the // new context has all the structs cached that the old context had. // We also need it for processing of the changes. nsChangeHint styleChange = oldStyle->CalcStyleDifference(newStyle, nsChangeHint(0)); aChangeList.AppendChange(primaryFrame, primaryFrame->GetContent(), styleChange); primaryFrame->SetStyleContext(newStyle); ReparentBeforeAndAfter(aElement, primaryFrame, newStyle, mPresContext->PresShell()->StyleSet()); return newStyle; }
nsStyleContext* nsTransitionManager::UpdateThrottledStyle(dom::Element* aElement, nsStyleContext* aParentStyle, nsStyleChangeList& aChangeList) { NS_ASSERTION(GetElementTransitions(aElement, nsCSSPseudoElements::ePseudo_NotPseudoElement, false), "element not transitioning"); nsIFrame* primaryFrame = aElement->GetPrimaryFrame(); if (!primaryFrame) { return nullptr; } nsStyleContext* oldStyle = primaryFrame->GetStyleContext(); nsRuleNode* ruleNode = oldStyle->GetRuleNode(); nsTArray<nsStyleSet::RuleAndLevel> rules; do { if (ruleNode->IsRoot()) { break; } nsStyleSet::RuleAndLevel curRule; curRule.mLevel = ruleNode->GetLevel(); if (curRule.mLevel == nsStyleSet::eAnimationSheet) { ElementAnimations* ea = mPresContext->AnimationManager()->GetElementAnimations(aElement, oldStyle->GetPseudoType(), false); NS_ASSERTION(ea, "Rule has level eAnimationSheet without animation on manager"); mPresContext->AnimationManager()->EnsureStyleRuleFor(ea); curRule.mRule = ea->mStyleRule; // FIXME: maybe not needed anymore: ForceLayerRerendering(primaryFrame, ea); } else if (curRule.mLevel == nsStyleSet::eTransitionSheet) { ElementTransitions *et = GetElementTransitions(aElement, oldStyle->GetPseudoType(), false); NS_ASSERTION(et, "Rule has level eTransitionSheet without transition on manager"); et->EnsureStyleRuleFor(mPresContext->RefreshDriver()->MostRecentRefresh()); curRule.mRule = et->mStyleRule; // FIXME: maybe not needed anymore: ForceLayerRerendering(primaryFrame, et); } else { curRule.mRule = ruleNode->GetRule(); } if (curRule.mRule) { rules.AppendElement(curRule); } } while ((ruleNode = ruleNode->GetParent())); nsRefPtr<nsStyleContext> newStyle = mPresContext->PresShell()->StyleSet()-> ResolveStyleForRules(aParentStyle, oldStyle, rules); // We absolutely must call CalcStyleDifference in order to ensure the // new context has all the structs cached that the old context had. // We also need it for processing of the changes. nsChangeHint styleChange = oldStyle->CalcStyleDifference(newStyle, nsChangeHint(0)); // This isn't particularly dangerous, but I want to catch if it happens: NS_ABORT_IF_FALSE(NS_IsHintSubset(styleChange, NS_CombineHint(nsChangeHint_UpdateOpacityLayer, NS_CombineHint(nsChangeHint_UpdateTransformLayer, nsChangeHint_UpdateOverflow))), "unexpected change hint"); aChangeList.AppendChange(primaryFrame, primaryFrame->GetContent(), styleChange); primaryFrame->SetStyleContextWithoutNotification(newStyle); ReparentBeforeAndAfter(aElement, primaryFrame, newStyle, mPresContext->PresShell()->StyleSet()); return newStyle; }