зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1305957 part 4 - Add basic ScrollAnchorContainer implementation. r=hiro
This commit adds a barebones class called 'ScrollAnchorContainer' that will contain most of the logic for scroll anchoring. It is owned as a member of ScrollFrameHelper, and has the same lifetime. Differential Revision: https://phabricator.services.mozilla.com/D13267 --HG-- extra : rebase_source : 41f6f7691af60401f18f98a89f1878cfad2e74d3 extra : source : 3033401ef320414ef5f489c53526d015c38a89d7
This commit is contained in:
Родитель
3627f69c8f
Коммит
91f41f3a0a
|
@ -0,0 +1,44 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ScrollAnchorContainer.h"
|
||||
|
||||
#include "nsGfxScrollFrame.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
#define ANCHOR_LOG(...)
|
||||
// #define ANCHOR_LOG(...) printf_stderr("ANCHOR: " __VA_ARGS__)
|
||||
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
|
||||
ScrollAnchorContainer::ScrollAnchorContainer(ScrollFrameHelper* aScrollFrame)
|
||||
: mScrollFrame(aScrollFrame) {}
|
||||
|
||||
ScrollAnchorContainer::~ScrollAnchorContainer() {}
|
||||
|
||||
ScrollAnchorContainer* ScrollAnchorContainer::FindFor(nsIFrame* aFrame) {
|
||||
aFrame = aFrame->GetParent();
|
||||
if (!aFrame) {
|
||||
return nullptr;
|
||||
}
|
||||
nsIScrollableFrame* nearest = nsLayoutUtils::GetNearestScrollableFrame(
|
||||
aFrame, nsLayoutUtils::SCROLLABLE_SAME_DOC |
|
||||
nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN);
|
||||
if (nearest) {
|
||||
return nearest->GetAnchor();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIFrame* ScrollAnchorContainer::Frame() const { return mScrollFrame->mOuter; }
|
||||
|
||||
nsIScrollableFrame* ScrollAnchorContainer::ScrollableFrame() const {
|
||||
return Frame()->GetScrollTargetFrame();
|
||||
}
|
||||
|
||||
} // namespace layout
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,55 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_layout_ScrollAnchorContainer_h_
|
||||
#define mozilla_layout_ScrollAnchorContainer_h_
|
||||
|
||||
namespace mozilla {
|
||||
class ScrollFrameHelper;
|
||||
} // namespace mozilla
|
||||
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
|
||||
/**
|
||||
* A scroll anchor container finds a descendent element of a scrollable frame
|
||||
* to be an anchor node. After every reflow, the scroll anchor will apply
|
||||
* scroll adjustments to keep the anchor node in the same relative position.
|
||||
*
|
||||
* See: https://drafts.csswg.org/css-scroll-anchoring/
|
||||
*/
|
||||
class ScrollAnchorContainer final {
|
||||
public:
|
||||
explicit ScrollAnchorContainer(ScrollFrameHelper* aScrollFrame);
|
||||
~ScrollAnchorContainer();
|
||||
|
||||
/**
|
||||
* Returns the nearest scroll anchor container that could select aFrame as an
|
||||
* anchor node.
|
||||
*/
|
||||
static ScrollAnchorContainer* FindFor(nsIFrame* aFrame);
|
||||
|
||||
/**
|
||||
* Returns the frame that owns this scroll anchor container. This is always
|
||||
* non-null.
|
||||
*/
|
||||
nsIFrame* Frame() const;
|
||||
|
||||
/**
|
||||
* Returns the frame that owns this scroll anchor container as a scrollable
|
||||
* frame. This is always non-null.
|
||||
*/
|
||||
nsIScrollableFrame* ScrollableFrame() const;
|
||||
|
||||
private:
|
||||
// The owner of this scroll anchor container
|
||||
ScrollFrameHelper* mScrollFrame;
|
||||
};
|
||||
|
||||
} // namespace layout
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_layout_ScrollAnchorContainer_h_
|
|
@ -145,6 +145,7 @@ EXPORTS.mozilla += [
|
|||
|
||||
EXPORTS.mozilla.layout += [
|
||||
'FrameChildList.h',
|
||||
'ScrollAnchorContainer.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
|
@ -202,6 +203,7 @@ UNIFIED_SOURCES += [
|
|||
'ReflowInput.cpp',
|
||||
'ReflowOutput.cpp',
|
||||
'RubyUtils.cpp',
|
||||
'ScrollAnchorContainer.cpp',
|
||||
'ScrollAnimationBezierPhysics.cpp',
|
||||
'ScrollAnimationMSDPhysics.cpp',
|
||||
'ScrollbarActivity.cpp',
|
||||
|
|
|
@ -1960,6 +1960,7 @@ ScrollFrameHelper::ScrollFrameHelper(nsContainerFrame* aOuter, bool aIsRoot)
|
|||
mLastUpdateFramesPos(-1, -1),
|
||||
mDisplayPortAtLastFrameUpdate(),
|
||||
mScrollParentID(mozilla::layers::ScrollableLayerGuid::NULL_SCROLL_ID),
|
||||
mAnchor(this),
|
||||
mAllowScrollOriginDowngrade(false),
|
||||
mHadDisplayPortAtLastFrameUpdate(false),
|
||||
mNeverHasVerticalScrollbar(false),
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "TextOverflow.h"
|
||||
#include "ScrollVelocityQueue.h"
|
||||
#include "mozilla/PresState.h"
|
||||
#include "mozilla/layout/ScrollAnchorContainer.h"
|
||||
|
||||
class nsPresContext;
|
||||
class nsIPresShell;
|
||||
|
@ -52,6 +53,7 @@ class ScrollFrameHelper : public nsIReflowCallback {
|
|||
typedef mozilla::layers::ScrollSnapInfo ScrollSnapInfo;
|
||||
typedef mozilla::layers::Layer Layer;
|
||||
typedef mozilla::layers::LayerManager LayerManager;
|
||||
typedef mozilla::layout::ScrollAnchorContainer ScrollAnchorContainer;
|
||||
|
||||
class AsyncScroll;
|
||||
class AsyncSmoothMSDScroll;
|
||||
|
@ -566,6 +568,8 @@ class ScrollFrameHelper : public nsIReflowCallback {
|
|||
// Timer to remove the displayport some time after scrolling has stopped
|
||||
nsCOMPtr<nsITimer> mDisplayPortExpiryTimer;
|
||||
|
||||
ScrollAnchorContainer mAnchor;
|
||||
|
||||
bool mAllowScrollOriginDowngrade : 1;
|
||||
bool mHadDisplayPortAtLastFrameUpdate : 1;
|
||||
bool mNeverHasVerticalScrollbar : 1;
|
||||
|
@ -723,6 +727,7 @@ class nsHTMLScrollFrame : public nsContainerFrame,
|
|||
typedef mozilla::ScrollFrameHelper ScrollFrameHelper;
|
||||
typedef mozilla::CSSIntPoint CSSIntPoint;
|
||||
typedef mozilla::ScrollReflowInput ScrollReflowInput;
|
||||
typedef mozilla::layout::ScrollAnchorContainer ScrollAnchorContainer;
|
||||
friend nsHTMLScrollFrame* NS_NewHTMLScrollFrame(nsIPresShell* aPresShell,
|
||||
ComputedStyle* aStyle,
|
||||
bool aIsRoot);
|
||||
|
@ -1112,6 +1117,14 @@ class nsHTMLScrollFrame : public nsContainerFrame,
|
|||
return mHelper.IsRootScrollFrameOfDocument();
|
||||
}
|
||||
|
||||
virtual const ScrollAnchorContainer* GetAnchor() const override {
|
||||
return &mHelper.mAnchor;
|
||||
}
|
||||
|
||||
virtual ScrollAnchorContainer* GetAnchor() override {
|
||||
return &mHelper.mAnchor;
|
||||
}
|
||||
|
||||
// Return the scrolled frame.
|
||||
void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override {
|
||||
aResult.AppendElement(OwnedAnonBox(mHelper.GetScrolledFrame()));
|
||||
|
@ -1174,6 +1187,7 @@ class nsXULScrollFrame final : public nsBoxFrame,
|
|||
public:
|
||||
typedef mozilla::ScrollFrameHelper ScrollFrameHelper;
|
||||
typedef mozilla::CSSIntPoint CSSIntPoint;
|
||||
typedef mozilla::layout::ScrollAnchorContainer ScrollAnchorContainer;
|
||||
|
||||
NS_DECL_QUERYFRAME
|
||||
NS_DECL_FRAMEARENA_HELPERS(nsXULScrollFrame)
|
||||
|
@ -1577,6 +1591,14 @@ class nsXULScrollFrame final : public nsBoxFrame,
|
|||
return mHelper.IsRootScrollFrameOfDocument();
|
||||
}
|
||||
|
||||
virtual const ScrollAnchorContainer* GetAnchor() const override {
|
||||
return &mHelper.mAnchor;
|
||||
}
|
||||
|
||||
virtual ScrollAnchorContainer* GetAnchor() override {
|
||||
return &mHelper.mAnchor;
|
||||
}
|
||||
|
||||
// Return the scrolled frame.
|
||||
void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override {
|
||||
aResult.AppendElement(OwnedAnonBox(mHelper.GetScrolledFrame()));
|
||||
|
|
|
@ -39,6 +39,9 @@ struct ScrollMetadata;
|
|||
class Layer;
|
||||
class LayerManager;
|
||||
} // namespace layers
|
||||
namespace layout {
|
||||
class ScrollAnchorContainer;
|
||||
} // namespace layout
|
||||
} // namespace mozilla
|
||||
|
||||
/**
|
||||
|
@ -51,6 +54,7 @@ class nsIScrollableFrame : public nsIScrollbarMediator {
|
|||
typedef mozilla::CSSIntPoint CSSIntPoint;
|
||||
typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
|
||||
typedef mozilla::layers::ScrollSnapInfo ScrollSnapInfo;
|
||||
typedef mozilla::layout::ScrollAnchorContainer ScrollAnchorContainer;
|
||||
|
||||
NS_DECL_QUERYFRAME_TARGET(nsIScrollableFrame)
|
||||
|
||||
|
@ -548,6 +552,12 @@ class nsIScrollableFrame : public nsIScrollbarMediator {
|
|||
* all (ie XUL documents) even though they may contain other scroll frames.
|
||||
*/
|
||||
virtual bool IsRootScrollFrameOfDocument() const = 0;
|
||||
|
||||
/**
|
||||
* Returns the scroll anchor associated with this scrollable frame.
|
||||
*/
|
||||
virtual const ScrollAnchorContainer* GetAnchor() const = 0;
|
||||
virtual ScrollAnchorContainer* GetAnchor() = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче