Bug 2057630 Part 2 - Return the result in a struct from StickyScrollContainer::ComputeStickyLimits(). r=layout-reviewers,emilio
`ComputeStickyLimits()` returned its two rectangles through outparams. Return them in a struct instead, which is easier to use at the call sites. Differential Revision: https://phabricator.services.mozilla.com/D324787
This commit is contained in:
committed by
tlin@mozilla.com
parent
56ab4b6060
commit
f92e5fb2fc
@@ -110,10 +110,8 @@ static constexpr nscoord gUnboundedExtent = nscoord_MAX;
|
||||
static constexpr nscoord gUnboundedPositive =
|
||||
gUnboundedNegative + gUnboundedExtent;
|
||||
|
||||
void StickyScrollContainer::ComputeStickyLimits(nsIFrame* aFrame,
|
||||
nsRect* aStick,
|
||||
nsRect* aContain,
|
||||
StickyLimitSpace aSpace) const {
|
||||
StickyScrollContainer::StickyLimits StickyScrollContainer::ComputeStickyLimits(
|
||||
nsIFrame* aFrame, StickyLimitSpace aSpace) const {
|
||||
NS_ASSERTION(nsLayoutUtils::IsFirstContinuationOrIBSplitSibling(aFrame),
|
||||
"Can't sticky position individual continuations");
|
||||
|
||||
@@ -121,17 +119,16 @@ void StickyScrollContainer::ComputeStickyLimits(nsIFrame* aFrame,
|
||||
? nsPoint()
|
||||
: mScrollPosition;
|
||||
|
||||
aStick->SetRect(gUnboundedNegative, gUnboundedNegative, gUnboundedExtent,
|
||||
gUnboundedExtent);
|
||||
aContain->SetRect(gUnboundedNegative, gUnboundedNegative, gUnboundedExtent,
|
||||
gUnboundedExtent);
|
||||
const nsRect unbounded(gUnboundedNegative, gUnboundedNegative,
|
||||
gUnboundedExtent, gUnboundedExtent);
|
||||
StickyLimits limits{unbounded, unbounded};
|
||||
|
||||
const nsMargin* computedOffsets =
|
||||
aFrame->GetProperty(nsIFrame::ComputedOffsetProperty());
|
||||
if (!computedOffsets) {
|
||||
// We haven't reflowed the scroll frame yet, so offsets haven't been
|
||||
// computed. Bail.
|
||||
return;
|
||||
return limits;
|
||||
}
|
||||
|
||||
nsIFrame* scrolledFrame = mScrollContainerFrame->GetScrolledFrame();
|
||||
@@ -163,11 +160,11 @@ void StickyScrollContainer::ComputeStickyLimits(nsIFrame* aFrame,
|
||||
// area, since we want the content box.
|
||||
MOZ_ASSERT(cbFrame->GetUsedBorder() == nsMargin(),
|
||||
"How did the ::-moz-scrolled-frame end up with border?");
|
||||
*aContain = cbFrame->ScrollableOverflowRectRelativeToSelf();
|
||||
aContain->Deflate(cbFrame->GetUsedPadding());
|
||||
nsLayoutUtils::TransformRect(cbFrame, aFrame->GetParent(), *aContain);
|
||||
limits.mContain = cbFrame->ScrollableOverflowRectRelativeToSelf();
|
||||
limits.mContain.Deflate(cbFrame->GetUsedPadding());
|
||||
nsLayoutUtils::TransformRect(cbFrame, aFrame->GetParent(), limits.mContain);
|
||||
} else {
|
||||
*aContain = nsLayoutUtils::GetAllInFlowRectsUnion(
|
||||
limits.mContain = nsLayoutUtils::GetAllInFlowRectsUnion(
|
||||
cbFrame, aFrame->GetParent(),
|
||||
nsLayoutUtils::GetAllInFlowRectsFlag::UseContentBox);
|
||||
}
|
||||
@@ -176,15 +173,15 @@ void StickyScrollContainer::ComputeStickyLimits(nsIFrame* aFrame,
|
||||
aFrame, aFrame->GetParent(),
|
||||
nsLayoutUtils::GetAllInFlowRectsFlag::UseMarginBoxWithAutoResolvedAsZero);
|
||||
|
||||
// Deflate aContain by the difference between the union of aFrame's
|
||||
// Deflate mContain by the difference between the union of aFrame's
|
||||
// continuations' margin boxes and the union of their border boxes, so that
|
||||
// by keeping aFrame within aContain, we keep the union of the margin boxes
|
||||
// by keeping aFrame within mContain, we keep the union of the margin boxes
|
||||
// within the containing block's content box.
|
||||
aContain->Deflate(marginRect - rect);
|
||||
limits.mContain.Deflate(marginRect - rect);
|
||||
|
||||
// Deflate aContain by the border-box size, to form a constraint on the
|
||||
// Deflate mContain by the border-box size, to form a constraint on the
|
||||
// upper-left corner of aFrame and continuations.
|
||||
aContain->Deflate(nsMargin(0, rect.width, rect.height, 0));
|
||||
limits.mContain.Deflate(nsMargin(0, rect.width, rect.height, 0));
|
||||
|
||||
nsMargin sfPadding = scrolledFrame->GetUsedPadding();
|
||||
nsPoint sfOffset = aFrame->GetParent()->GetOffsetTo(scrolledFrame);
|
||||
@@ -224,44 +221,45 @@ void StickyScrollContainer::ComputeStickyLimits(nsIFrame* aFrame,
|
||||
// aFrame and its continuations, but our consumers expect the limits to be
|
||||
// on the position of aFrame, so we need to shift the limits by the
|
||||
// difference.
|
||||
// - For |aContain| we're otherwise done, so we apply the offset directly.
|
||||
// - For |aStick| we apply the offset as part of setting |aStick| (applying
|
||||
// it via `MoveBy` after we set |aStick| would trash any sentinel values).
|
||||
// - For |mContain| we're otherwise done, so we apply the offset directly.
|
||||
// - For |mStick| we apply the offset as part of setting |mStick| (applying
|
||||
// it via `MoveBy` after we set |mStick| would trash any sentinel values).
|
||||
const nsPoint frameOffset = aFrame->GetPosition() - rect.TopLeft();
|
||||
|
||||
aContain->MoveBy(frameOffset);
|
||||
limits.mContain.MoveBy(frameOffset);
|
||||
|
||||
// Top
|
||||
if (computedOffsets->top != NS_AUTOOFFSET) {
|
||||
aStick->SetTopEdge(scrollPosition.y + sfPadding.top + effectiveOffsets.top -
|
||||
sfOffset.y + frameOffset.y);
|
||||
limits.mStick.SetTopEdge(scrollPosition.y + sfPadding.top +
|
||||
effectiveOffsets.top - sfOffset.y + frameOffset.y);
|
||||
}
|
||||
|
||||
// Bottom
|
||||
if (computedOffsets->bottom != NS_AUTOOFFSET) {
|
||||
aStick->SetBottomEdge(scrollPosition.y + sfPadding.top + sfSize.height -
|
||||
effectiveOffsets.bottom - rect.height - sfOffset.y +
|
||||
frameOffset.y);
|
||||
limits.mStick.SetBottomEdge(scrollPosition.y + sfPadding.top +
|
||||
sfSize.height - effectiveOffsets.bottom -
|
||||
rect.height - sfOffset.y + frameOffset.y);
|
||||
}
|
||||
|
||||
// Left
|
||||
if (computedOffsets->left != NS_AUTOOFFSET) {
|
||||
aStick->SetLeftEdge(scrollPosition.x + sfPadding.left +
|
||||
effectiveOffsets.left - sfOffset.x + frameOffset.x);
|
||||
limits.mStick.SetLeftEdge(scrollPosition.x + sfPadding.left +
|
||||
effectiveOffsets.left - sfOffset.x +
|
||||
frameOffset.x);
|
||||
}
|
||||
|
||||
// Right
|
||||
if (computedOffsets->right != NS_AUTOOFFSET) {
|
||||
aStick->SetRightEdge(scrollPosition.x + sfPadding.left + sfSize.width -
|
||||
effectiveOffsets.right - rect.width - sfOffset.x +
|
||||
frameOffset.x);
|
||||
limits.mStick.SetRightEdge(scrollPosition.x + sfPadding.left +
|
||||
sfSize.width - effectiveOffsets.right -
|
||||
rect.width - sfOffset.x + frameOffset.x);
|
||||
}
|
||||
|
||||
return limits;
|
||||
}
|
||||
|
||||
nsPoint StickyScrollContainer::ComputePosition(nsIFrame* aFrame) const {
|
||||
nsRect stick;
|
||||
nsRect contain;
|
||||
ComputeStickyLimits(aFrame, &stick, &contain);
|
||||
const auto [stick, contain] = ComputeStickyLimits(aFrame);
|
||||
|
||||
nsPoint position = aFrame->GetNormalPosition();
|
||||
|
||||
@@ -290,9 +288,7 @@ void StickyScrollContainer::GetScrollRanges(nsIFrame* aFrame,
|
||||
nsIFrame* firstCont =
|
||||
nsLayoutUtils::FirstContinuationOrIBSplitSibling(aFrame);
|
||||
|
||||
nsRect stickRect;
|
||||
nsRect containRect;
|
||||
ComputeStickyLimits(firstCont, &stickRect, &containRect);
|
||||
const auto [stickRect, containRect] = ComputeStickyLimits(firstCont);
|
||||
|
||||
nsRectAbsolute stick = nsRectAbsolute::FromRect(stickRect);
|
||||
nsRectAbsolute contain = nsRectAbsolute::FromRect(containRect);
|
||||
@@ -367,10 +363,8 @@ StickyScrollContainer::GetStickyScrollRangesForAxis(
|
||||
return result;
|
||||
}
|
||||
|
||||
nsRect stick;
|
||||
nsRect contain;
|
||||
ComputeStickyLimits(firstCont, &stick, &contain,
|
||||
StickyLimitSpace::IgnoreCurrentScroll);
|
||||
const auto [stick, contain] =
|
||||
ComputeStickyLimits(firstCont, StickyLimitSpace::IgnoreCurrentScroll);
|
||||
|
||||
const nsPoint normalPosition = firstCont->GetNormalPosition();
|
||||
const nscoord normal = isVertical ? normalPosition.y : normalPosition.x;
|
||||
|
||||
@@ -145,25 +145,31 @@ class StickyScrollContainer final {
|
||||
|
||||
private:
|
||||
/**
|
||||
* Whether ComputeStickyLimits() positions its aStick outparam (the
|
||||
* sticky-limits rectangle) relative to the current scroll position, or as
|
||||
* if the scroll position were zero (in which case the result is independent
|
||||
* of the current scroll position).
|
||||
* Whether ComputeStickyLimits() positions its returned StickyLimits::mStick
|
||||
* rectangle relative to the current scroll position, or as if the scroll
|
||||
* position were zero (in which case the result is independent of the current
|
||||
* scroll position).
|
||||
*/
|
||||
enum class StickyLimitSpace : uint8_t {
|
||||
RelativeToCurrentScroll,
|
||||
IgnoreCurrentScroll,
|
||||
};
|
||||
|
||||
struct StickyLimits {
|
||||
// Based on the scroll container.
|
||||
nsRect mStick;
|
||||
// Based on the containing block.
|
||||
nsRect mContain;
|
||||
};
|
||||
|
||||
/**
|
||||
* Compute two rectangles that determine sticky positioning: |aStick|, based
|
||||
* on the scroll container, and |aContain|, based on the containing block.
|
||||
* Sticky positioning keeps the frame position (its upper-left corner) always
|
||||
* within |aContain| and secondarily within |aStick|.
|
||||
* Compute the two rectangles that determine sticky positioning. Sticky
|
||||
* positioning keeps the frame position (its upper-left corner) always within
|
||||
* |mContain| and secondarily within |mStick|.
|
||||
*/
|
||||
void ComputeStickyLimits(nsIFrame* aFrame, nsRect* aStick, nsRect* aContain,
|
||||
StickyLimitSpace aSpace =
|
||||
StickyLimitSpace::RelativeToCurrentScroll) const;
|
||||
StickyLimits ComputeStickyLimits(
|
||||
nsIFrame* aFrame, StickyLimitSpace aSpace =
|
||||
StickyLimitSpace::RelativeToCurrentScroll) const;
|
||||
|
||||
ScrollContainerFrame* const mScrollContainerFrame;
|
||||
DepthOrderedFrameList mFrames;
|
||||
|
||||
Reference in New Issue
Block a user