Bug 898209 patch 1: Add ElementRestyler class to begin refactoring ReResolveStyleContext. r=heycam

This commit is contained in:
L. David Baron 2013-07-30 17:36:09 -07:00
parent 75e4462ced
commit 7ad914dbc3
2 changed files with 125 additions and 58 deletions

View File

@ -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<nsIContent*>& aVisibleKidsOfHiddenElement,
TreeMatchContext &aTreeMatchContext)
ElementRestyler::Restyle(nsPresContext *aPresContext,
nsIFrame *aFrame,
nsIContent *aParentContent,
nsStyleChangeList *aChangeList,
nsChangeHint aMinChange,
nsChangeHint aParentFrameHintsNotHandledForDescendants,
nsRestyleHint aRestyleHint,
RestyleTracker& aRestyleTracker,
DesiredA11yNotifications aDesiredA11yNotifications,
nsTArray<nsIContent*>& 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);

View File

@ -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<nsIContent*>& 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<nsIContent*>& 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 */