summaryrefslogtreecommitdiff
path: root/layout/base
diff options
context:
space:
mode:
Diffstat (limited to 'layout/base')
-rw-r--r--layout/base/nsIPresShell.h6
-rw-r--r--layout/base/nsPresShell.cpp32
-rw-r--r--layout/base/nsPresShell.h7
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;