From 6b056b0c8098bda4ce6a2937d24d819732379adc Mon Sep 17 00:00:00 2001 From: "L. David Baron" Date: Tue, 30 Jul 2013 17:36:09 -0700 Subject: [PATCH] Bug 898209 patch 1: Add ElementRestyler class to begin refactoring ReResolveStyleContext. r=heycam --- layout/base/RestyleManager.cpp | 78 +++++++++++++++--------- layout/base/RestyleManager.h | 105 +++++++++++++++++++++++---------- 2 files changed, 125 insertions(+), 58 deletions(-) diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index a597e8d3eb30..1380e7a691a8 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -1666,7 +1666,7 @@ ElementForStyleContext(nsIContent* aParentContent, aPseudoType < nsCSSPseudoElements::ePseudo_PseudoElementCount, "Unexpected pseudo"); // XXX see the comments about the various element confusion in - // ReResolveStyleContext. + // ElementRestyler::Restyle. if (aPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement) { return aFrame->GetContent()->AsElement(); } @@ -1909,14 +1909,31 @@ RestyleManager::ReparentStyleContext(nsIFrame* aFrame) return NS_OK; } -static void -CaptureChange(nsStyleContext* aOldContext, nsStyleContext* aNewContext, - nsIFrame* aFrame, nsIContent* aContent, - nsStyleChangeList* aChangeList, - /*inout*/nsChangeHint &aMinChange, - /*in*/nsChangeHint aParentHintsNotHandledForDescendants, - /*out*/nsChangeHint &aHintsNotHandledForDescendants, - nsChangeHint aChangeToAssume) +ElementRestyler::ElementRestyler(nsPresContext* aPresContext) + : mPresContext(aPresContext) +{ +} + +ElementRestyler::ElementRestyler(const ElementRestyler& aParentRestyler) + : mPresContext(aParentRestyler.mPresContext) +{ +} + +ElementRestyler::ElementRestyler(ParentContextFromChildFrame, + const ElementRestyler& aParentRestyler) + : mPresContext(aParentRestyler.mPresContext) +{ +} + +void +ElementRestyler::CaptureChange(nsStyleContext* aOldContext, + nsStyleContext* aNewContext, + nsIFrame* aFrame, nsIContent* aContent, + nsStyleChangeList* aChangeList, + /*inout*/nsChangeHint &aMinChange, + /*in*/nsChangeHint aParentHintsNotHandledForDescendants, + /*out*/nsChangeHint &aHintsNotHandledForDescendants, + nsChangeHint aChangeToAssume) { nsChangeHint ourChange = aOldContext->CalcStyleDifference(aNewContext, aParentHintsNotHandledForDescendants); @@ -1953,17 +1970,17 @@ CaptureChange(nsStyleContext* aOldContext, nsStyleContext* aNewContext, * nsStyleContext::CalcStyleDifference. */ nsChangeHint -RestyleManager::ReResolveStyleContext(nsPresContext *aPresContext, - nsIFrame *aFrame, - nsIContent *aParentContent, - nsStyleChangeList *aChangeList, - nsChangeHint aMinChange, - nsChangeHint aParentFrameHintsNotHandledForDescendants, - nsRestyleHint aRestyleHint, - RestyleTracker& aRestyleTracker, - DesiredA11yNotifications aDesiredA11yNotifications, - nsTArray& aVisibleKidsOfHiddenElement, - TreeMatchContext &aTreeMatchContext) +ElementRestyler::Restyle(nsPresContext *aPresContext, + nsIFrame *aFrame, + nsIContent *aParentContent, + nsStyleChangeList *aChangeList, + nsChangeHint aMinChange, + nsChangeHint aParentFrameHintsNotHandledForDescendants, + nsRestyleHint aRestyleHint, + RestyleTracker& aRestyleTracker, + DesiredA11yNotifications aDesiredA11yNotifications, + nsTArray& aVisibleKidsOfHiddenElement, + TreeMatchContext &aTreeMatchContext) { // We need to generate a new change list entry for every frame whose style // comparision returns one of these hints. These hints don't automatically @@ -2057,7 +2074,9 @@ RestyleManager::ReResolveStyleContext(nsPresContext *aPresContext, // style context provider will be automatically propagated to // the frame(s) with child style contexts. - assumeDifferenceHint = ReResolveStyleContext(aPresContext, providerFrame, + ElementRestyler providerRestyler(PARENT_CONTEXT_FROM_CHILD_FRAME, + *this); + assumeDifferenceHint = providerRestyler.Restyle(aPresContext, providerFrame, aParentContent, aChangeList, aMinChange, nsChangeHint_Hints_NotHandledForDescendants, @@ -2305,7 +2324,7 @@ RestyleManager::ReResolveStyleContext(nsPresContext *aPresContext, // DocElementContainingBlock. bool checkUndisplayed; nsIContent* undisplayedParent; - nsCSSFrameConstructor* frameConstructor = FrameConstructor(); + nsCSSFrameConstructor* frameConstructor = mPresContext->FrameConstructor(); if (pseudoTag) { checkUndisplayed = aFrame == frameConstructor-> GetDocElementContainingBlock(); @@ -2531,7 +2550,8 @@ RestyleManager::ReResolveStyleContext(nsPresContext *aPresContext, // |nsFrame::GetParentStyleContextFrame| checks being out // of flow so that this works correctly. do { - ReResolveStyleContext(aPresContext, outOfFlowFrame, + ElementRestyler oofRestyler(*this); + oofRestyler.Restyle(aPresContext, outOfFlowFrame, content, aChangeList, NS_SubtractHint(aMinChange, nsChangeHint_AllReflowHints), @@ -2545,7 +2565,8 @@ RestyleManager::ReResolveStyleContext(nsPresContext *aPresContext, // reresolve placeholder's context under the same parent // as the out-of-flow frame - ReResolveStyleContext(aPresContext, child, content, + ElementRestyler phRestyler(*this); + phRestyler.Restyle(aPresContext, child, content, aChangeList, aMinChange, nonInheritedHints, childRestyleHint, @@ -2556,7 +2577,8 @@ RestyleManager::ReResolveStyleContext(nsPresContext *aPresContext, } else { // regular child frame if (child != resolvedChild) { - ReResolveStyleContext(aPresContext, child, content, + ElementRestyler childRestyler(*this); + childRestyler.Restyle(aPresContext, child, content, aChangeList, aMinChange, nonInheritedHints, childRestyleHint, @@ -2644,13 +2666,15 @@ RestyleManager::ComputeStyleChangeFor(nsIFrame* aFrame, // Outer loop over special siblings do { // Inner loop over next-in-flows of the current frame + ElementRestyler restyler(mPresContext); + nsChangeHint frameChange = - ReResolveStyleContext(mPresContext, frame, nullptr, + restyler.Restyle(mPresContext, frame, nullptr, aChangeList, aMinChange, nsChangeHint(0), aRestyleDescendants ? eRestyle_Subtree : eRestyle_Self, aRestyleTracker, - eSendAllNotifications, + ElementRestyler::eSendAllNotifications, visibleKidsOfHiddenElement, treeMatchContext); diff --git a/layout/base/RestyleManager.h b/layout/base/RestyleManager.h index a4b66b999331..fb7278ae33ab 100644 --- a/layout/base/RestyleManager.h +++ b/layout/base/RestyleManager.h @@ -26,7 +26,7 @@ namespace dom { class Element; } // namespace dom -class RestyleManager { +class RestyleManager MOZ_FINAL { public: friend class ::nsRefreshDriver; friend class RestyleTracker; @@ -191,36 +191,6 @@ public: } private: - enum DesiredA11yNotifications { - eSkipNotifications, - eSendAllNotifications, - eNotifyIfShown - }; - - enum A11yNotificationType { - eDontNotify, - eNotifyShown, - eNotifyHidden - }; - - // Use eRestyle_Self for the aRestyleHint argument to mean - // "reresolve our style context but not kids", use eRestyle_Subtree - // to mean "reresolve our style context and kids", and use - // nsRestyleHint(0) to mean recompute a new style context for our - // current parent and existing rulenode, and the same for kids. - NS_HIDDEN_(nsChangeHint) - ReResolveStyleContext(nsPresContext* aPresContext, - nsIFrame* aFrame, - nsIContent* aParentContent, - nsStyleChangeList* aChangeList, - nsChangeHint aMinChange, - nsChangeHint aParentFrameHintsNotHandledForDescendants, - nsRestyleHint aRestyleHint, - RestyleTracker& aRestyleTracker, - DesiredA11yNotifications aDesiredA11yNotifications, - nsTArray& aVisibleKidsOfHiddenElement, - TreeMatchContext& aTreeMatchContext); - /** * Notify the frame constructor that an element needs to have its * style recomputed. @@ -292,6 +262,79 @@ private: RestyleTracker mPendingAnimationRestyles; }; +/** + * An ElementRestyler is created for *each* element in a subtree that we + * recompute styles for. + */ +class ElementRestyler MOZ_FINAL { +public: + typedef mozilla::dom::Element Element; + + // Construct for the root of the subtree that we're restyling. + ElementRestyler(nsPresContext* aPresContext); + + // Construct for an element whose parent is being restyled. + ElementRestyler(const ElementRestyler& aParentRestyler); + + // Construct for a frame whose parent is being restyled, but whose + // style context is the parent style context for its parent frame. + // (This is only used for table frames, whose style contexts are used + // as the parent style context for their outer table frame (table + // wrapper frame). We should probably try to get rid of this + // exception and have the inheritance go the other way.) + enum ParentContextFromChildFrame { PARENT_CONTEXT_FROM_CHILD_FRAME }; + ElementRestyler(ParentContextFromChildFrame, + const ElementRestyler& aParentFrameRestyler); + +public: // FIXME: private + enum DesiredA11yNotifications { + eSkipNotifications, + eSendAllNotifications, + eNotifyIfShown + }; + + enum A11yNotificationType { + eDontNotify, + eNotifyShown, + eNotifyHidden + }; + +public: + /** + * Restyle our frame's element and its subtree. + * + * Use eRestyle_Self for the aRestyleHint argument to mean + * "reresolve our style context but not kids", use eRestyle_Subtree + * to mean "reresolve our style context and kids", and use + * nsRestyleHint(0) to mean recompute a new style context for our + * current parent and existing rulenode, and the same for kids. + */ + nsChangeHint Restyle(nsPresContext *aPresContext, + nsIFrame *aFrame, + nsIContent *aParentContent, + nsStyleChangeList *aChangeList, + nsChangeHint aMinChange, + nsChangeHint aParentFrameHintsNotHandledForDescendants, + nsRestyleHint aRestyleHint, + RestyleTracker& aRestyleTracker, + DesiredA11yNotifications aDesiredA11yNotifications, + nsTArray& aVisibleKidsOfHiddenElement, + TreeMatchContext &aTreeMatchContext); + +private: + void CaptureChange(nsStyleContext* aOldContext, + nsStyleContext* aNewContext, + nsIFrame* aFrame, nsIContent* aContent, + nsStyleChangeList* aChangeList, + /*inout*/nsChangeHint &aMinChange, + /*in*/nsChangeHint aParentHintsNotHandledForDescendants, + /*out*/nsChangeHint &aHintsNotHandledForDescendants, + nsChangeHint aChangeToAssume); + +private: + nsPresContext* const mPresContext; +}; + } // namespace mozilla #endif /* mozilla_RestyleManager_h */