diff options
Diffstat (limited to 'layout/base')
-rw-r--r-- | layout/base/nsIPresShell.h | 6 | ||||
-rw-r--r-- | layout/base/nsPresShell.cpp | 32 | ||||
-rw-r--r-- | layout/base/nsPresShell.h | 7 |
3 files changed, 39 insertions, 6 deletions
diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index cf19867ef0..d368402e4f 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -486,6 +486,12 @@ public: virtual nsCanvasFrame* GetCanvasFrame() const = 0; /** + * Returns whether the scollable frame need to have a position adjustment + * based on scroll-anchoring. + */ + virtual void ScrollableFrameNeedsAnchorAdjustment(nsIScrollableFrame* aFrame) = 0; + + /** * Tell the pres shell that a frame needs to be marked dirty and needs * Reflow. It's OK if this is an ancestor of the frame needing reflow as * long as the ancestor chain between them doesn't cross a reflow root. diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 23876cc112..0fc84d736c 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -1225,6 +1225,7 @@ PresShell::Destroy() } mFramesToDirty.Clear(); + mScrollAnchorAdjustments.Clear(); if (mViewManager) { // Clear the view manager's weak pointer back to |this| in case it @@ -2049,6 +2050,11 @@ PresShell::NotifyDestroyingFrame(nsIFrame* aFrame) } mFramesToDirty.RemoveEntry(aFrame); + + nsIScrollableFrame* scrollableFrame = do_QueryFrame(aFrame); + if (scrollableFrame) { + mScrollAnchorAdjustments.RemoveEntry(scrollableFrame); + } } else { // We must delete this property in situ so that its destructor removes the // frame from FrameLayerBuilder::DisplayItemData::mFrameList -- otherwise @@ -2584,6 +2590,12 @@ PresShell::VerifyHasDirtyRootAncestor(nsIFrame* aFrame) #endif void +PresShell::ScrollableFrameNeedsAnchorAdjustment(nsIScrollableFrame* aFrame) +{ + mScrollAnchorAdjustments.PutEntry(aFrame); +} + +void PresShell::FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty, nsFrameState aBitToAdd, ReflowRootHandling aRootHandling) @@ -4106,12 +4118,21 @@ PresShell::FlushPendingNotifications(mozilla::ChangesToFlush aFlush) didLayoutFlush = true; mFrameConstructor->RecalcQuotesAndCounters(); viewManager->FlushDelayedResize(true); - if (ProcessReflowCommands(flushType < Flush_Layout) && mContentToScrollTo) { - // We didn't get interrupted. Go ahead and scroll to our content - DoScrollContentIntoView(); + if (ProcessReflowCommands(flushType < Flush_Layout)) { + // Apply scroll offset updates for scroll anchors. + for (auto iter = mScrollAnchorAdjustments.Iter(); !iter.Done(); iter.Next()) { + nsIScrollableFrame* frame = iter.Get()->GetKey(); + frame->ApplyScrollAnchorOffsetAdjustment(); + } + mScrollAnchorAdjustments.Clear(); + if (mContentToScrollTo) { - mContentToScrollTo->DeleteProperty(nsGkAtoms::scrolling); - mContentToScrollTo = nullptr; + // We didn't get interrupted; go ahead and scroll to our content. + DoScrollContentIntoView(); + if (mContentToScrollTo) { + mContentToScrollTo->DeleteProperty(nsGkAtoms::scrolling); + mContentToScrollTo = nullptr; + } } } } @@ -10833,6 +10854,7 @@ PresShell::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf, } *aPresShellSize += mApproximatelyVisibleFrames.ShallowSizeOfExcludingThis(aMallocSizeOf); *aPresShellSize += mFramesToDirty.ShallowSizeOfExcludingThis(aMallocSizeOf); + *aPresShellSize += mScrollAnchorAdjustments.ShallowSizeOfExcludingThis(aMallocSizeOf); *aPresShellSize += aArenaObjectsSize->mOther; if (nsStyleSet* styleSet = StyleSet()->GetAsGecko()) { diff --git a/layout/base/nsPresShell.h b/layout/base/nsPresShell.h index fbbcfc7ecd..de638f4bf6 100644 --- a/layout/base/nsPresShell.h +++ b/layout/base/nsPresShell.h @@ -129,6 +129,8 @@ public: virtual nsIPageSequenceFrame* GetPageSequenceFrame() const override; virtual nsCanvasFrame* GetCanvasFrame() const override; + virtual void ScrollableFrameNeedsAnchorAdjustment(nsIScrollableFrame* aFrame) override; + virtual void FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty, nsFrameState aBitToAdd, ReflowRootHandling aRootHandling = @@ -427,9 +429,10 @@ public: void SetNextPaintCompressed() { mNextPaintCompressed = true; } -protected: virtual ~PresShell(); +protected: + void HandlePostedReflowCallbacks(bool aInterruptible); void CancelPostedReflowCallbacks(); @@ -852,6 +855,8 @@ protected: // Set of frames that we should mark with NS_FRAME_HAS_DIRTY_CHILDREN after // we finish reflowing mCurrentReflowRoot. nsTHashtable<nsPtrHashKey<nsIFrame> > mFramesToDirty; + + nsTHashtable<nsPtrHashKey<nsIScrollableFrame> > mScrollAnchorAdjustments; // Reflow roots that need to be reflowed. nsTArray<nsIFrame*> mDirtyRoots; |