Bug 1739541 - Introduce TriggeredByScript in ScrollPositionUpdate and set `Yes` for ScrollToCSSPixels and ScrollByCSSPixels. r=botond

Both ScrollToCSSPixels and ScrollByCSSPixels are called only from JS via
Element.scrollTo, Element.scrollTop, Element.scrollLeft, Window.scroll,
Window.scrollTo and Window.scrollBy.

Note that we don't target either Window.scrollByLines or Window.scrollByPages
(both end up calling ScrollFrameHelper::ScrollBy) because both are triggered by
user interactions for our XUL tree implementation, for example
Window.scrollByLines gets called in response to a DOMMouseScroll event in
tree.js [1].

[1] https://searchfox.org/mozilla-central/rev/a12c2c2e59c92d8f969d8f3f290ab16919449c9d/toolkit/content/widgets/tree.js#788

Differential Revision: https://phabricator.services.mozilla.com/D130418
This commit is contained in:
Hiroyuki Ikezoe 2021-11-09 09:19:25 +00:00
Родитель eb9d902442
Коммит 1aea05dff0
4 изменённых файлов: 62 добавлений и 32 удалений

Просмотреть файл

@ -40,7 +40,8 @@ std::ostream& operator<<(std::ostream& aStream, const ScrollGeneration& aGen) {
ScrollPositionUpdate::ScrollPositionUpdate()
: mType(ScrollUpdateType::Absolute),
mScrollMode(ScrollMode::Normal),
mScrollOrigin(ScrollOrigin::None) {}
mScrollOrigin(ScrollOrigin::None),
mTriggeredByScript(ScrollTriggeredByScript::No) {}
/*static*/
ScrollPositionUpdate ScrollPositionUpdate::NewScrollframe(
@ -82,7 +83,8 @@ ScrollPositionUpdate ScrollPositionUpdate::NewRelativeScroll(
/*static*/
ScrollPositionUpdate ScrollPositionUpdate::NewSmoothScroll(
ScrollOrigin aOrigin, nsPoint aDestination) {
ScrollOrigin aOrigin, nsPoint aDestination,
ScrollTriggeredByScript aTriggeredByScript) {
MOZ_ASSERT(aOrigin != ScrollOrigin::NotSpecified);
MOZ_ASSERT(aOrigin != ScrollOrigin::None);
@ -92,6 +94,7 @@ ScrollPositionUpdate ScrollPositionUpdate::NewSmoothScroll(
ret.mScrollMode = ScrollMode::SmoothMsd;
ret.mScrollOrigin = aOrigin;
ret.mDestination = CSSPoint::FromAppUnits(aDestination);
ret.mTriggeredByScript = aTriggeredByScript;
return ret;
}
@ -150,7 +153,8 @@ std::ostream& operator<<(std::ostream& aStream,
<< ", mode=" << (int)aUpdate.mScrollMode
<< ", origin=" << (int)aUpdate.mScrollOrigin
<< ", dst=" << aUpdate.mDestination << ", src=" << aUpdate.mSource
<< ", delta=" << aUpdate.mDelta << " }";
<< ", delta=" << aUpdate.mDelta
<< ", triggered by script=" << aUpdate.WasTriggeredByScript() << " }";
return aStream;
}

Просмотреть файл

@ -29,6 +29,8 @@ enum class ScrollUpdateType {
PureRelative,
};
enum class ScrollTriggeredByScript : bool { No, Yes };
struct ScrollGeneration {
private:
// Private constructor; use New() to get a new instance.
@ -80,8 +82,9 @@ class ScrollPositionUpdate {
// Create a ScrollPositionUpdate for a new absolute/smooth scroll, which
// animates smoothly to the given destination from whatever the current
// scroll position is in the receiver.
static ScrollPositionUpdate NewSmoothScroll(ScrollOrigin aOrigin,
nsPoint aDestination);
static ScrollPositionUpdate NewSmoothScroll(
ScrollOrigin aOrigin, nsPoint aDestination,
ScrollTriggeredByScript aTriggeredByScript);
// Create a ScrollPositionUpdate for a new pure-relative scroll. The
// aMode parameter controls whether or not this is a smooth animation or
// instantaneous scroll.
@ -103,6 +106,13 @@ class ScrollPositionUpdate {
// GetDelta is only valid for the PureRelative type; it asserts otherwise.
CSSPoint GetDelta() const;
ScrollTriggeredByScript GetScrollTriggeredByScript() const {
return mTriggeredByScript;
}
bool WasTriggeredByScript() const {
return mTriggeredByScript == ScrollTriggeredByScript::Yes;
}
friend std::ostream& operator<<(std::ostream& aStream,
const ScrollPositionUpdate& aUpdate);
@ -119,6 +129,7 @@ class ScrollPositionUpdate {
CSSPoint mSource;
// mDelta is not populated when mType == Absolute || mType == Relative.
CSSPoint mDelta;
ScrollTriggeredByScript mTriggeredByScript;
};
} // namespace mozilla

Просмотреть файл

@ -2350,11 +2350,13 @@ bool ScrollFrameHelper::HasBgAttachmentLocal() const {
void ScrollFrameHelper::ScrollTo(nsPoint aScrollPosition, ScrollMode aMode,
ScrollOrigin aOrigin, const nsRect* aRange,
nsIScrollbarMediator::ScrollSnapMode aSnap) {
nsIScrollbarMediator::ScrollSnapMode aSnap,
ScrollTriggeredByScript aTriggeredByScript) {
if (aOrigin == ScrollOrigin::NotSpecified) {
aOrigin = ScrollOrigin::Other;
}
ScrollToWithOrigin(aScrollPosition, aMode, aOrigin, aRange, aSnap);
ScrollToWithOrigin(aScrollPosition, aMode, aOrigin, aRange, aSnap,
aTriggeredByScript);
}
void ScrollFrameHelper::ScrollToCSSPixels(const CSSIntPoint& aScrollPosition,
@ -2380,7 +2382,7 @@ void ScrollFrameHelper::ScrollToCSSPixels(const CSSIntPoint& aScrollPosition,
range.height = 0;
}
ScrollTo(pt, aMode, ScrollOrigin::Other, &range,
nsIScrollableFrame::ENABLE_SNAP);
nsIScrollableFrame::ENABLE_SNAP, ScrollTriggeredByScript::Yes);
// 'this' might be destroyed here
}
@ -2404,7 +2406,8 @@ CSSIntPoint ScrollFrameHelper::GetScrollPositionCSSPixels() {
*/
void ScrollFrameHelper::ScrollToWithOrigin(
nsPoint aScrollPosition, ScrollMode aMode, ScrollOrigin aOrigin,
const nsRect* aRange, nsIScrollbarMediator::ScrollSnapMode aSnap) {
const nsRect* aRange, nsIScrollbarMediator::ScrollSnapMode aSnap,
ScrollTriggeredByScript aTriggeredByScript) {
// None is never a valid scroll origin to be passed in.
MOZ_ASSERT(aOrigin != ScrollOrigin::None);
@ -2471,7 +2474,7 @@ void ScrollFrameHelper::ScrollToWithOrigin(
}
if (nsLayoutUtils::AsyncPanZoomEnabled(mOuter) && WantAsyncScroll()) {
ApzSmoothScrollTo(mDestination, aOrigin);
ApzSmoothScrollTo(mDestination, aOrigin, aTriggeredByScript);
return;
}
@ -2868,8 +2871,9 @@ gfxSize GetPaintedLayerScaleForFrame(nsIFrame* aFrame) {
transformToAncestorScale.yScale);
}
void ScrollFrameHelper::ScrollToImpl(nsPoint aPt, const nsRect& aRange,
ScrollOrigin aOrigin) {
void ScrollFrameHelper::ScrollToImpl(
nsPoint aPt, const nsRect& aRange, ScrollOrigin aOrigin,
ScrollTriggeredByScript aTriggeredByScript) {
// None is never a valid scroll origin to be passed in.
MOZ_ASSERT(aOrigin != ScrollOrigin::None);
@ -4833,7 +4837,8 @@ void ScrollFrameHelper::ScrollByCSSPixels(const CSSIntPoint& aDelta,
range.height = 0;
}
ScrollToWithOrigin(pt, aMode, ScrollOrigin::Relative, &range,
nsIScrollableFrame::ENABLE_SNAP);
nsIScrollableFrame::ENABLE_SNAP,
ScrollTriggeredByScript::Yes);
// 'this' might be destroyed here
}
@ -7814,8 +7819,9 @@ void ScrollFrameHelper::AsyncScrollbarDragRejected() {
::AsyncScrollbarDragRejected(mVScrollbarBox);
}
void ScrollFrameHelper::ApzSmoothScrollTo(const nsPoint& aDestination,
ScrollOrigin aOrigin) {
void ScrollFrameHelper::ApzSmoothScrollTo(
const nsPoint& aDestination, ScrollOrigin aOrigin,
ScrollTriggeredByScript aTriggeredByScript) {
if (mApzSmoothScrollDestination == Some(aDestination)) {
// If we already sent APZ a smooth-scroll request to this
// destination (i.e. it was the last request
@ -7836,8 +7842,8 @@ void ScrollFrameHelper::ApzSmoothScrollTo(const nsPoint& aDestination,
// animation for this scroll.
MOZ_ASSERT(aOrigin != ScrollOrigin::None);
mApzSmoothScrollDestination = Some(aDestination);
AppendScrollUpdate(
ScrollPositionUpdate::NewSmoothScroll(aOrigin, aDestination));
AppendScrollUpdate(ScrollPositionUpdate::NewSmoothScroll(
aOrigin, aDestination, aTriggeredByScript));
nsIContent* content = mOuter->GetContent();
if (!DisplayPortUtils::HasNonMinimalNonZeroDisplayPort(content)) {
@ -7889,9 +7895,11 @@ bool ScrollFrameHelper::SmoothScrollVisual(
mDestination = GetVisualScrollRange().ClampPoint(aVisualViewportOffset);
// Perform the scroll.
ApzSmoothScrollTo(mDestination, aUpdateType == FrameMetrics::eRestore
? ScrollOrigin::Restore
: ScrollOrigin::Other);
ApzSmoothScrollTo(mDestination,
aUpdateType == FrameMetrics::eRestore
? ScrollOrigin::Restore
: ScrollOrigin::Other,
ScrollTriggeredByScript::No);
return true;
}

Просмотреть файл

@ -245,11 +245,13 @@ class ScrollFrameHelper : public nsIReflowCallback {
* aScrollPosition. Null means only aScrollPosition is allowed.
* This is a closed-ended range --- aRange.XMost()/aRange.YMost() are allowed.
*/
void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode,
ScrollOrigin aOrigin = ScrollOrigin::NotSpecified,
const nsRect* aRange = nullptr,
nsIScrollbarMediator::ScrollSnapMode aSnap =
nsIScrollbarMediator::DISABLE_SNAP);
void ScrollTo(
nsPoint aScrollPosition, ScrollMode aMode,
ScrollOrigin aOrigin = ScrollOrigin::NotSpecified,
const nsRect* aRange = nullptr,
nsIScrollbarMediator::ScrollSnapMode aSnap =
nsIScrollbarMediator::DISABLE_SNAP,
ScrollTriggeredByScript aTriggeredByScript = ScrollTriggeredByScript::No);
/**
* @note This method might destroy the frame, pres shell and other objects.
*/
@ -266,8 +268,10 @@ class ScrollFrameHelper : public nsIReflowCallback {
/**
* @note This method might destroy the frame, pres shell and other objects.
*/
void ScrollToImpl(nsPoint aScrollPosition, const nsRect& aRange,
ScrollOrigin aOrigin = ScrollOrigin::NotSpecified);
void ScrollToImpl(
nsPoint aPt, const nsRect& aRange,
ScrollOrigin aOrigin = ScrollOrigin::NotSpecified,
ScrollTriggeredByScript aTriggeredByScript = ScrollTriggeredByScript::No);
void ScrollVisual();
/**
* @note This method might destroy the frame, pres shell and other objects.
@ -764,10 +768,12 @@ class ScrollFrameHelper : public nsIReflowCallback {
/**
* @note This method might destroy the frame, pres shell and other objects.
*/
void ScrollToWithOrigin(nsPoint aScrollPosition, ScrollMode aMode,
ScrollOrigin aOrigin, const nsRect* aRange,
nsIScrollbarMediator::ScrollSnapMode aSnap =
nsIScrollbarMediator::DISABLE_SNAP);
void ScrollToWithOrigin(
nsPoint aScrollPosition, ScrollMode aMode, ScrollOrigin aOrigin,
const nsRect* aRange,
nsIScrollbarMediator::ScrollSnapMode aSnap =
nsIScrollbarMediator::DISABLE_SNAP,
ScrollTriggeredByScript aTriggeredByScript = ScrollTriggeredByScript::No);
void CompleteAsyncScroll(const nsRect& aRange,
ScrollOrigin aOrigin = ScrollOrigin::NotSpecified);
@ -780,7 +786,8 @@ class ScrollFrameHelper : public nsIReflowCallback {
// This method does not clamp the destination; callers should clamp it to
// either the layout or the visual scroll range (APZ will happily smooth
// scroll to either).
void ApzSmoothScrollTo(const nsPoint& aDestination, ScrollOrigin aOrigin);
void ApzSmoothScrollTo(const nsPoint& aDestination, ScrollOrigin aOrigin,
ScrollTriggeredByScript aTriggeredByScript);
// Removes any RefreshDriver observers we might have registered.
void RemoveObservers();