Bug 1330375 - P1: Helper for checking for ancestor of dirty reflow root. r?emilio
Including refactoring mDirtyRoots into nsIPresShell to avoid virtual call.
MozReview-Commit-ID: KxST8FMsZl9
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -4558,16 +4558,37 @@ PresShell::ContentRemoved(nsIContent* aC
void
PresShell::NotifyCounterStylesAreDirty()
{
nsAutoCauseReflowNotifier reflowNotifier(this);
mFrameConstructor->NotifyCounterStylesAreDirty();
}
+bool
+nsIPresShell::FrameIsAncestorOfDirtyRoot(nsIFrame* aFrame) const
+{
+ MOZ_ASSERT(aFrame);
+
+ // Look for a path from any dirty roots to aFrame, following GetParent().
+ // This check mirrors what FrameNeedsReflow() would have done if the reflow
+ // root didn't get in the way.
+ for (nsIFrame* dirtyFrame : mDirtyRoots) {
+ while (dirtyFrame) {
+ if (dirtyFrame == aFrame) {
+ return true;
+ }
+
+ dirtyFrame = dirtyFrame->GetParent();
+ }
+ }
+
+ return false;
+}
+
void
PresShell::ReconstructFrames()
{
MOZ_ASSERT(!mFrameConstructor->GetRootFrame() || mDidInitialize,
"Must not have root frame before initial reflow");
if (!mDidInitialize || mIsDestroying) {
// Nothing to do here
return;
--- a/layout/base/PresShell.h
+++ b/layout/base/PresShell.h
@@ -779,19 +779,16 @@ private:
// mStyleSet owns it but we maintain a ref, may be null
RefPtr<StyleSheet> mPrefStyleSheet;
// Set of frames that we should mark with NS_FRAME_HAS_DIRTY_CHILDREN after
// we finish reflowing mCurrentReflowRoot.
nsTHashtable<nsPtrHashKey<nsIFrame> > mFramesToDirty;
- // Reflow roots that need to be reflowed.
- nsTArray<nsIFrame*> mDirtyRoots;
-
nsTArray<nsAutoPtr<DelayedEvent> > mDelayedEvents;
private:
nsIFrame* mCurrentEventFrame;
nsCOMPtr<nsIContent> mCurrentEventContent;
nsTArray<nsIFrame*> mCurrentEventFrameStack;
nsCOMArray<nsIContent> mCurrentEventContentStack;
nsRevocableEventPtr<nsSynthMouseMoveEvent> mSynthMouseMoveEvent;
nsCOMPtr<nsIContent> mLastAnchorScrolledTo;
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -498,16 +498,18 @@ public:
* other than NS_FRAME_HAS_DIRTY_CHILDREN.
*/
virtual void FrameNeedsToContinueReflow(nsIFrame *aFrame) = 0;
virtual void CancelAllPendingReflows() = 0;
virtual void NotifyCounterStylesAreDirty() = 0;
+ bool FrameIsAncestorOfDirtyRoot(nsIFrame* aFrame) const;
+
/**
* Destroy the frames for aElement, and reconstruct them asynchronously if
* needed.
*
* Note that this may destroy frames for an ancestor instead.
*/
void DestroyFramesForAndRestyle(mozilla::dom::Element* aElement);
@@ -1756,16 +1758,19 @@ protected:
nsPoint mVisualViewportOffset;
// A list of stack weak frames. This is a pointer to the last item in the list.
AutoWeakFrame* mAutoWeakFrames;
// A hash table of heap allocated weak frames.
nsTHashtable<nsPtrHashKey<WeakFrame>> mWeakFrames;
+ // Reflow roots that need to be reflowed.
+ nsTArray<nsIFrame*> mDirtyRoots;
+
#ifdef MOZ_GECKO_PROFILER
// These two fields capture call stacks of any changes that require a restyle
// or a reflow. Only the first change per restyle / reflow is recorded (the
// one that caused a call to SetNeedStyleFlush() / SetNeedLayoutFlush()).
UniqueProfilerBacktrace mStyleCause;
UniqueProfilerBacktrace mReflowCause;
#endif