Bug 1923763: Part 5 - Replace inset evaluations with anchor-resolved inset evaluations. r=layout-reviewers,emilio
Differential Revision: https://phabricator.services.mozilla.com/D231259
This commit is contained in:
@@ -3793,8 +3793,10 @@ bool PresShell::ScrollFrameIntoView(
|
||||
// If we're targetting a sticky element, make sure not to apply
|
||||
// scroll-padding on the direction we're stuck.
|
||||
const auto* stylePosition = aFrame->StylePosition();
|
||||
const auto positionProperty = aFrame->StyleDisplay()->mPosition;
|
||||
for (auto side : AllPhysicalSides()) {
|
||||
if (stylePosition->GetInset(side).IsAuto()) {
|
||||
if (stylePosition->GetAnchorResolvedInset(side, positionProperty)
|
||||
.IsAuto()) {
|
||||
continue;
|
||||
}
|
||||
// See if this axis is stuck.
|
||||
|
||||
@@ -1263,16 +1263,24 @@ SideBits nsLayoutUtils::GetSideBitsForFixedPositionContent(
|
||||
SideBits sides = SideBits::eNone;
|
||||
if (aFixedPosFrame) {
|
||||
const nsStylePosition* position = aFixedPosFrame->StylePosition();
|
||||
if (!position->GetInset(eSideRight).IsAuto()) {
|
||||
if (!position
|
||||
->GetAnchorResolvedInset(eSideRight, StylePositionProperty::Fixed)
|
||||
.IsAuto()) {
|
||||
sides |= SideBits::eRight;
|
||||
}
|
||||
if (!position->GetInset(eSideLeft).IsAuto()) {
|
||||
if (!position
|
||||
->GetAnchorResolvedInset(eSideLeft, StylePositionProperty::Fixed)
|
||||
.IsAuto()) {
|
||||
sides |= SideBits::eLeft;
|
||||
}
|
||||
if (!position->GetInset(eSideBottom).IsAuto()) {
|
||||
if (!position
|
||||
->GetAnchorResolvedInset(eSideBottom, StylePositionProperty::Fixed)
|
||||
.IsAuto()) {
|
||||
sides |= SideBits::eBottom;
|
||||
}
|
||||
if (!position->GetInset(eSideTop).IsAuto()) {
|
||||
if (!position
|
||||
->GetAnchorResolvedInset(eSideTop, StylePositionProperty::Fixed)
|
||||
.IsAuto()) {
|
||||
sides |= SideBits::eTop;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -742,8 +742,9 @@ void ReflowInput::InitResizeFlags(nsPresContext* aPresContext,
|
||||
!mStylePosition->BSize(wm).IsAuto()) ||
|
||||
mStylePosition->MinBSizeDependsOnContainer(wm) ||
|
||||
mStylePosition->MaxBSizeDependsOnContainer(wm) ||
|
||||
mStylePosition->GetInset(LogicalSide::BStart, wm).HasPercent() ||
|
||||
!mStylePosition->GetInset(LogicalSide::BEnd, wm).IsAuto();
|
||||
mStylePosition->mOffset.Get(LogicalSide::BStart, wm)
|
||||
.MaybePercentageAware() ||
|
||||
!mStylePosition->mOffset.Get(LogicalSide::BEnd, wm).MaybeAuto();
|
||||
|
||||
// If mFrame is a flex item, and mFrame's block axis is the flex container's
|
||||
// main axis (e.g. in a column-oriented flex container with same
|
||||
@@ -852,15 +853,18 @@ LogicalMargin ReflowInput::ComputeRelativeOffsets(WritingMode aWM,
|
||||
const LogicalSize& aCBSize) {
|
||||
LogicalMargin offsets(aWM);
|
||||
const nsStylePosition* position = aFrame->StylePosition();
|
||||
const auto positionProperty = aFrame->StyleDisplay()->mPosition;
|
||||
|
||||
// Compute the 'inlineStart' and 'inlineEnd' values. 'inlineStart'
|
||||
// moves the boxes to the end of the line, and 'inlineEnd' moves the
|
||||
// boxes to the start of the line. The computed values are always:
|
||||
// inlineStart=-inlineEnd
|
||||
const auto& inlineStart = position->GetInset(LogicalSide::IStart, aWM);
|
||||
const auto& inlineEnd = position->GetInset(LogicalSide::IEnd, aWM);
|
||||
bool inlineStartIsAuto = !inlineStart.IsLengthPercentage();
|
||||
bool inlineEndIsAuto = !inlineEnd.IsLengthPercentage();
|
||||
const auto& inlineStart = position->GetAnchorResolvedInset(
|
||||
LogicalSide::IStart, aWM, positionProperty);
|
||||
const auto& inlineEnd = position->GetAnchorResolvedInset(
|
||||
LogicalSide::IEnd, aWM, positionProperty);
|
||||
bool inlineStartIsAuto = inlineStart.IsAuto();
|
||||
bool inlineEndIsAuto = inlineEnd.IsAuto();
|
||||
|
||||
// If neither 'inlineStart' nor 'inlineEnd' is auto, then we're
|
||||
// over-constrained and we ignore one of them
|
||||
@@ -873,9 +877,12 @@ LogicalMargin ReflowInput::ComputeRelativeOffsets(WritingMode aWM,
|
||||
// If both are 'auto' (their initial values), the computed values are 0
|
||||
offsets.IStart(aWM) = offsets.IEnd(aWM) = 0;
|
||||
} else {
|
||||
// 'inlineEnd' isn't 'auto' so compute its value
|
||||
// 'inlineEnd' isn't being treated as 'auto' so compute its value
|
||||
offsets.IEnd(aWM) =
|
||||
nsLayoutUtils::ComputeCBDependentValue(aCBSize.ISize(aWM), inlineEnd);
|
||||
inlineEnd.IsAuto()
|
||||
? 0
|
||||
: nsLayoutUtils::ComputeCBDependentValue(
|
||||
aCBSize.ISize(aWM), inlineEnd.AsLengthPercentage());
|
||||
|
||||
// Computed value for 'inlineStart' is minus the value of 'inlineEnd'
|
||||
offsets.IStart(aWM) = -offsets.IEnd(aWM);
|
||||
@@ -885,8 +892,8 @@ LogicalMargin ReflowInput::ComputeRelativeOffsets(WritingMode aWM,
|
||||
NS_ASSERTION(inlineEndIsAuto, "unexpected specified constraint");
|
||||
|
||||
// 'InlineStart' isn't 'auto' so compute its value
|
||||
offsets.IStart(aWM) =
|
||||
nsLayoutUtils::ComputeCBDependentValue(aCBSize.ISize(aWM), inlineStart);
|
||||
offsets.IStart(aWM) = nsLayoutUtils::ComputeCBDependentValue(
|
||||
aCBSize.ISize(aWM), inlineStart.AsLengthPercentage());
|
||||
|
||||
// Computed value for 'inlineEnd' is minus the value of 'inlineStart'
|
||||
offsets.IEnd(aWM) = -offsets.IStart(aWM);
|
||||
@@ -896,8 +903,10 @@ LogicalMargin ReflowInput::ComputeRelativeOffsets(WritingMode aWM,
|
||||
// and 'blockEnd' properties move relatively positioned elements in
|
||||
// the block progression direction. They also must be each other's
|
||||
// negative
|
||||
const auto& blockStart = position->GetInset(LogicalSide::BStart, aWM);
|
||||
const auto& blockEnd = position->GetInset(LogicalSide::BEnd, aWM);
|
||||
const auto& blockStart = position->GetAnchorResolvedInset(
|
||||
LogicalSide::BStart, aWM, positionProperty);
|
||||
const auto& blockEnd = position->GetAnchorResolvedInset(
|
||||
LogicalSide::BEnd, aWM, positionProperty);
|
||||
bool blockStartIsAuto = blockStart.IsAuto();
|
||||
bool blockEndIsAuto = blockEnd.IsAuto();
|
||||
|
||||
@@ -922,9 +931,12 @@ LogicalMargin ReflowInput::ComputeRelativeOffsets(WritingMode aWM,
|
||||
// If both are 'auto' (their initial values), the computed values are 0
|
||||
offsets.BStart(aWM) = offsets.BEnd(aWM) = 0;
|
||||
} else {
|
||||
// 'blockEnd' isn't 'auto' so compute its value
|
||||
// 'blockEnd' isn't being treated as 'auto' so compute its value
|
||||
offsets.BEnd(aWM) =
|
||||
nsLayoutUtils::ComputeCBDependentValue(aCBSize.BSize(aWM), blockEnd);
|
||||
blockEnd.IsAuto()
|
||||
? 0
|
||||
: nsLayoutUtils::ComputeCBDependentValue(
|
||||
aCBSize.BSize(aWM), blockEnd.AsLengthPercentage());
|
||||
|
||||
// Computed value for 'blockStart' is minus the value of 'blockEnd'
|
||||
offsets.BStart(aWM) = -offsets.BEnd(aWM);
|
||||
@@ -934,8 +946,8 @@ LogicalMargin ReflowInput::ComputeRelativeOffsets(WritingMode aWM,
|
||||
NS_ASSERTION(blockEndIsAuto, "unexpected specified constraint");
|
||||
|
||||
// 'blockStart' isn't 'auto' so compute its value
|
||||
offsets.BStart(aWM) =
|
||||
nsLayoutUtils::ComputeCBDependentValue(aCBSize.BSize(aWM), blockStart);
|
||||
offsets.BStart(aWM) = nsLayoutUtils::ComputeCBDependentValue(
|
||||
aCBSize.BSize(aWM), blockStart.AsLengthPercentage());
|
||||
|
||||
// Computed value for 'blockEnd' is minus the value of 'blockStart'
|
||||
offsets.BEnd(aWM) = -offsets.BStart(aWM);
|
||||
@@ -1554,8 +1566,8 @@ void ReflowInput::CalculateHypotheticalPosition(
|
||||
bool ReflowInput::IsInlineSizeComputableByBlockSizeAndAspectRatio(
|
||||
nscoord aBlockSize) const {
|
||||
WritingMode wm = GetWritingMode();
|
||||
MOZ_ASSERT(!mStylePosition->GetInset(LogicalSide::BStart, wm).IsAuto() &&
|
||||
!mStylePosition->GetInset(LogicalSide::BEnd, wm).IsAuto(),
|
||||
MOZ_ASSERT(!mStylePosition->mOffset.Get(LogicalSide::BStart, wm).IsAuto() &&
|
||||
!mStylePosition->mOffset.Get(LogicalSide::BEnd, wm).IsAuto(),
|
||||
"If any of the block-start and block-end are auto, aBlockSize "
|
||||
"doesn't make sense");
|
||||
NS_WARNING_ASSERTION(
|
||||
@@ -1578,10 +1590,22 @@ bool ReflowInput::IsInlineSizeComputableByBlockSizeAndAspectRatio(
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto position = mStyleDisplay->mPosition;
|
||||
// If both inline insets are non-auto, mFrame->ComputeSize() should get a
|
||||
// possible inline size by those insets, so we don't rely on aspect-ratio.
|
||||
if (!mStylePosition->GetInset(LogicalSide::IStart, wm).IsAuto() &&
|
||||
!mStylePosition->GetInset(LogicalSide::IEnd, wm).IsAuto()) {
|
||||
if (!mStylePosition->GetAnchorResolvedInset(LogicalSide::IStart, wm, position)
|
||||
.IsAuto() &&
|
||||
!mStylePosition->GetAnchorResolvedInset(LogicalSide::IEnd, wm, position)
|
||||
.IsAuto()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If block direction insets reference use any anchor positioning function
|
||||
// that does not resolve, we can't rely on them.
|
||||
if (mStylePosition->GetAnchorResolvedInset(LogicalSide::BStart, wm, position)
|
||||
.IsAuto() ||
|
||||
mStylePosition->GetAnchorResolvedInset(LogicalSide::BEnd, wm, position)
|
||||
.IsAuto()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1661,12 +1685,14 @@ void ReflowInput::InitAbsoluteConstraints(const ReflowInput* aCBReflowInput,
|
||||
NS_ASSERTION(mFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW),
|
||||
"Why are we here?");
|
||||
|
||||
const auto& iStartOffset =
|
||||
mStylePosition->GetInset(LogicalSide::IStart, cbwm);
|
||||
const auto& iEndOffset = mStylePosition->GetInset(LogicalSide::IEnd, cbwm);
|
||||
const auto& bStartOffset =
|
||||
mStylePosition->GetInset(LogicalSide::BStart, cbwm);
|
||||
const auto& bEndOffset = mStylePosition->GetInset(LogicalSide::BEnd, cbwm);
|
||||
const auto& iStartOffset = mStylePosition->GetAnchorResolvedInset(
|
||||
LogicalSide::IStart, cbwm, StylePositionProperty::Absolute);
|
||||
const auto& iEndOffset = mStylePosition->GetAnchorResolvedInset(
|
||||
LogicalSide::IEnd, cbwm, StylePositionProperty::Absolute);
|
||||
const auto& bStartOffset = mStylePosition->GetAnchorResolvedInset(
|
||||
LogicalSide::BStart, cbwm, StylePositionProperty::Absolute);
|
||||
const auto& bEndOffset = mStylePosition->GetAnchorResolvedInset(
|
||||
LogicalSide::BEnd, cbwm, StylePositionProperty::Absolute);
|
||||
bool iStartIsAuto = iStartOffset.IsAuto();
|
||||
bool iEndIsAuto = iEndOffset.IsAuto();
|
||||
bool bStartIsAuto = bStartOffset.IsAuto();
|
||||
@@ -1752,13 +1778,13 @@ void ReflowInput::InitAbsoluteConstraints(const ReflowInput* aCBReflowInput,
|
||||
offsets.IStart(cbwm) = 0;
|
||||
} else {
|
||||
offsets.IStart(cbwm) = nsLayoutUtils::ComputeCBDependentValue(
|
||||
cbSize.ISize(cbwm), iStartOffset);
|
||||
cbSize.ISize(cbwm), iStartOffset.AsLengthPercentage());
|
||||
}
|
||||
if (iEndIsAuto) {
|
||||
offsets.IEnd(cbwm) = 0;
|
||||
} else {
|
||||
offsets.IEnd(cbwm) =
|
||||
nsLayoutUtils::ComputeCBDependentValue(cbSize.ISize(cbwm), iEndOffset);
|
||||
nsLayoutUtils::ComputeCBDependentValue(cbSize.ISize(cbwm), iEndOffset.AsLengthPercentage());
|
||||
}
|
||||
|
||||
if (iStartIsAuto && iEndIsAuto) {
|
||||
@@ -1775,13 +1801,13 @@ void ReflowInput::InitAbsoluteConstraints(const ReflowInput* aCBReflowInput,
|
||||
offsets.BStart(cbwm) = 0;
|
||||
} else {
|
||||
offsets.BStart(cbwm) = nsLayoutUtils::ComputeCBDependentValue(
|
||||
cbSize.BSize(cbwm), bStartOffset);
|
||||
cbSize.BSize(cbwm), bStartOffset.AsLengthPercentage());
|
||||
}
|
||||
if (bEndIsAuto) {
|
||||
offsets.BEnd(cbwm) = 0;
|
||||
} else {
|
||||
offsets.BEnd(cbwm) =
|
||||
nsLayoutUtils::ComputeCBDependentValue(cbSize.BSize(cbwm), bEndOffset);
|
||||
nsLayoutUtils::ComputeCBDependentValue(cbSize.BSize(cbwm), bEndOffset.AsLengthPercentage());
|
||||
}
|
||||
|
||||
if (bStartIsAuto && bEndIsAuto) {
|
||||
|
||||
@@ -65,8 +65,9 @@ StickyScrollContainer::GetStickyScrollContainerForScrollFrame(
|
||||
static nscoord ComputeStickySideOffset(Side aSide,
|
||||
const nsStylePosition& aPosition,
|
||||
nscoord aPercentBasis) {
|
||||
const auto& side = aPosition.GetInset(aSide);
|
||||
if (!side.IsLengthPercentage()) {
|
||||
const auto& side =
|
||||
aPosition.GetAnchorResolvedInset(aSide, StylePositionProperty::Sticky);
|
||||
if (side.IsAuto()) {
|
||||
return NS_AUTOOFFSET;
|
||||
}
|
||||
return nsLayoutUtils::ComputeCBDependentValue(aPercentBasis,
|
||||
|
||||
@@ -2125,11 +2125,6 @@ inline const mozilla::StyleMaxSize& nsStylePosition::MaxSize(
|
||||
return aAxis == mozilla::LogicalAxis::Inline ? MaxISize(aWM) : MaxBSize(aWM);
|
||||
}
|
||||
|
||||
inline const mozilla::StyleInset& nsStylePosition::GetInset(
|
||||
mozilla::LogicalSide aSide, mozilla::WritingMode aWM) const {
|
||||
return GetInset(aWM.PhysicalSide(aSide));
|
||||
}
|
||||
|
||||
inline bool nsStylePosition::ISizeDependsOnContainer(WritingMode aWM) const {
|
||||
const auto& iSize = ISize(aWM);
|
||||
return iSize.IsAuto() || ISizeCoordDependsOnContainer(iSize);
|
||||
|
||||
@@ -286,6 +286,8 @@ static inline bool IsFixedMarginSize(const StyleMargin& aCoord) {
|
||||
return aCoord.ConvertsToLength();
|
||||
}
|
||||
static inline bool IsFixedOffset(const StyleInset& aInset) {
|
||||
// For anchor positioning functions, even if the computed value may be a
|
||||
// fixed length, it depends on the absolute containing block's size.
|
||||
return aInset.ConvertsToLength();
|
||||
}
|
||||
|
||||
@@ -340,8 +342,8 @@ bool nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f,
|
||||
// lengths?
|
||||
if ((pos->BSizeDependsOnContainer(wm) &&
|
||||
!(pos->BSize(wm).IsAuto() &&
|
||||
pos->GetInset(LogicalSide::BEnd, wm).IsAuto() &&
|
||||
!pos->GetInset(LogicalSide::BStart, wm).IsAuto())) ||
|
||||
pos->mOffset.Get(LogicalSide::BEnd, wm).MaybeAuto() &&
|
||||
!pos->mOffset.Get(LogicalSide::BStart, wm).MaybeAuto())) ||
|
||||
pos->MinBSizeDependsOnContainer(wm) ||
|
||||
pos->MaxBSizeDependsOnContainer(wm) ||
|
||||
!IsFixedPaddingSize(padding->mPadding.GetBStart(wm)) ||
|
||||
@@ -363,7 +365,7 @@ bool nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f,
|
||||
// sides (left and top) that we use to store coordinates, these tests
|
||||
// are easier to do using physical coordinates rather than logical.
|
||||
if (aCBWidthChanged) {
|
||||
if (!IsFixedOffset(pos->GetInset(eSideLeft))) {
|
||||
if (!IsFixedOffset(pos->mOffset.Get(eSideLeft))) {
|
||||
return true;
|
||||
}
|
||||
// Note that even if 'left' is a length, our position can still
|
||||
@@ -375,17 +377,17 @@ bool nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f,
|
||||
// sure of.
|
||||
if ((wm.GetInlineDir() == WritingMode::InlineDir::RTL ||
|
||||
wm.GetBlockDir() == WritingMode::BlockDir::RL) &&
|
||||
!pos->GetInset(eSideRight).IsAuto()) {
|
||||
!pos->mOffset.Get(eSideRight).MaybeAuto()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (aCBHeightChanged) {
|
||||
if (!IsFixedOffset(pos->GetInset(eSideTop))) {
|
||||
if (!IsFixedOffset(pos->mOffset.Get(eSideTop))) {
|
||||
return true;
|
||||
}
|
||||
// See comment above for width changes.
|
||||
if (wm.GetInlineDir() == WritingMode::InlineDir::BTT &&
|
||||
!pos->GetInset(eSideBottom).IsAuto()) {
|
||||
!pos->mOffset.Get(eSideBottom).MaybeAuto()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -925,12 +927,25 @@ void nsAbsoluteContainingBlock::ReflowAbsoluteFrame(
|
||||
// align the child by its margin box:
|
||||
// https://drafts.csswg.org/css-position-3/#abspos-layout
|
||||
const auto* stylePos = aKidFrame->StylePosition();
|
||||
auto positionProperty = aKidFrame->StyleDisplay()->mPosition;
|
||||
const bool iInsetAuto =
|
||||
stylePos->GetInset(LogicalSide::IStart, outerWM).IsAuto() ||
|
||||
stylePos->GetInset(LogicalSide::IEnd, outerWM).IsAuto();
|
||||
stylePos
|
||||
->GetAnchorResolvedInset(LogicalSide::IStart, outerWM,
|
||||
positionProperty)
|
||||
.IsAuto() ||
|
||||
stylePos
|
||||
->GetAnchorResolvedInset(LogicalSide::IEnd, outerWM,
|
||||
positionProperty)
|
||||
.IsAuto();
|
||||
const bool bInsetAuto =
|
||||
stylePos->GetInset(LogicalSide::BStart, outerWM).IsAuto() ||
|
||||
stylePos->GetInset(LogicalSide::BEnd, outerWM).IsAuto();
|
||||
stylePos
|
||||
->GetAnchorResolvedInset(LogicalSide::BStart, outerWM,
|
||||
positionProperty)
|
||||
.IsAuto() ||
|
||||
stylePos
|
||||
->GetAnchorResolvedInset(LogicalSide::BEnd, outerWM,
|
||||
positionProperty)
|
||||
.IsAuto();
|
||||
const LogicalSize logicalCBSizeOuterWM(outerWM, aContainingBlock.Size());
|
||||
const LogicalSize kidMarginBox{
|
||||
outerWM, margin.IStartEnd(outerWM) + kidSize.ISize(outerWM),
|
||||
|
||||
@@ -4640,8 +4640,8 @@ void nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
|
||||
if (bsize.HasPercent() ||
|
||||
(StyleDisplay()->IsAbsolutelyPositionedStyle() &&
|
||||
(bsize.IsAuto() || !bsize.IsLengthPercentage()) &&
|
||||
!stylePos->GetInset(LogicalSide::BStart, wm).IsAuto() &&
|
||||
!stylePos->GetInset(LogicalSide::BEnd, wm).IsAuto())) {
|
||||
!stylePos->mOffset.Get(LogicalSide::BStart, wm).MaybeAuto() &&
|
||||
!stylePos->mOffset.Get(LogicalSide::BEnd, wm).MaybeAuto())) {
|
||||
AddStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE);
|
||||
}
|
||||
|
||||
|
||||
@@ -8434,8 +8434,10 @@ nscoord nsGridContainerFrame::MasonryLayout(GridReflowInput& aState,
|
||||
? LogicalSide::IStart
|
||||
: LogicalSide::BStart;
|
||||
if (masonryStart == 0 ||
|
||||
(masonryStart == kAutoLine && item->mFrame->StylePosition()
|
||||
->GetInset(masonrySide, wm)
|
||||
(masonryStart == kAutoLine &&
|
||||
item->mFrame->StylePosition()
|
||||
->GetAnchorResolvedInset(
|
||||
masonrySide, wm, item->mFrame->StyleDisplay()->mPosition)
|
||||
.IsAuto())) {
|
||||
sortedItems.AppendElement(item);
|
||||
} else {
|
||||
|
||||
@@ -1252,7 +1252,7 @@ void nsIFrame::DidSetComputedStyle(ComputedStyle* aOldComputedStyle) {
|
||||
const nsStylePosition* pos = StylePosition();
|
||||
const nsStylePosition* oldPos = aOldComputedStyle->StylePosition();
|
||||
if (!needAnchorSuppression &&
|
||||
(!oldPos->InsetEquals(*pos) ||
|
||||
(oldPos->mOffset != pos->mOffset ||
|
||||
oldPos->GetWidth() != pos->GetWidth() ||
|
||||
oldPos->GetMinWidth() != pos->GetMinWidth() ||
|
||||
oldPos->GetMaxWidth() != pos->GetMaxWidth() ||
|
||||
@@ -6902,14 +6902,21 @@ LogicalSize nsIFrame::ComputeAbsolutePosAutoSize(
|
||||
const auto& styleBSize = aSizeOverrides.mStyleBSize
|
||||
? *aSizeOverrides.mStyleBSize
|
||||
: stylePos->BSize(aWM);
|
||||
const auto positionProperty = StyleDisplay()->mPosition;
|
||||
const auto iStartOffsetIsAuto =
|
||||
stylePos->GetInset(LogicalSide::IStart, aWM).IsAuto();
|
||||
stylePos
|
||||
->GetAnchorResolvedInset(LogicalSide::IStart, aWM, positionProperty)
|
||||
.IsAuto();
|
||||
const auto iEndOffsetIsAuto =
|
||||
stylePos->GetInset(LogicalSide::IEnd, aWM).IsAuto();
|
||||
stylePos->GetAnchorResolvedInset(LogicalSide::IEnd, aWM, positionProperty)
|
||||
.IsAuto();
|
||||
const auto bStartOffsetIsAuto =
|
||||
stylePos->GetInset(LogicalSide::BStart, aWM).IsAuto();
|
||||
stylePos
|
||||
->GetAnchorResolvedInset(LogicalSide::BStart, aWM, positionProperty)
|
||||
.IsAuto();
|
||||
const auto bEndOffsetIsAuto =
|
||||
stylePos->GetInset(LogicalSide::BEnd, aWM).IsAuto();
|
||||
stylePos->GetAnchorResolvedInset(LogicalSide::BEnd, aWM, positionProperty)
|
||||
.IsAuto();
|
||||
const auto boxSizingAdjust = stylePos->mBoxSizing == StyleBoxSizing::Border
|
||||
? aBorderPadding
|
||||
: LogicalSize(aWM);
|
||||
@@ -7022,12 +7029,8 @@ LogicalSize nsIFrame::ComputeAbsolutePosAutoSize(
|
||||
} else if (!iShouldStretch) {
|
||||
// If one axis has `auto` inset, that is the ratio dependent axis,
|
||||
// otherwise the block axis is.
|
||||
const bool inlineInsetHasAuto =
|
||||
stylePos->GetInset(LogicalSide::IStart, aWM).IsAuto() ||
|
||||
stylePos->GetInset(LogicalSide::IEnd, aWM).IsAuto();
|
||||
const bool blockInsetHasAuto =
|
||||
stylePos->GetInset(LogicalSide::BStart, aWM).IsAuto() ||
|
||||
stylePos->GetInset(LogicalSide::BEnd, aWM).IsAuto();
|
||||
const bool inlineInsetHasAuto = iStartOffsetIsAuto || iEndOffsetIsAuto;
|
||||
const bool blockInsetHasAuto = bStartOffsetIsAuto || bEndOffsetIsAuto;
|
||||
aspectRatioUsage = inlineInsetHasAuto && !blockInsetHasAuto
|
||||
? AspectRatioUsage::ToComputeISize
|
||||
: AspectRatioUsage::ToComputeBSize;
|
||||
|
||||
@@ -669,8 +669,8 @@ static bool IsPercentageAware(const nsIFrame* aFrame, WritingMode aWM) {
|
||||
if ((pos->ISizeDependsOnContainer(aWM) && !pos->ISize(aWM).IsAuto()) ||
|
||||
pos->MaxISizeDependsOnContainer(aWM) ||
|
||||
pos->MinISizeDependsOnContainer(aWM) ||
|
||||
pos->GetInset(LogicalSide::IStart, aWM).HasPercent() ||
|
||||
pos->GetInset(LogicalSide::IEnd, aWM).HasPercent()) {
|
||||
pos->mOffset.Get(LogicalSide::IStart, aWM).MaybePercentageAware() ||
|
||||
pos->mOffset.Get(LogicalSide::IEnd, aWM).MaybePercentageAware()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -815,6 +815,16 @@ inline bool StyleInset::IsAnchorPositioningFunction() const {
|
||||
return IsAnchorFunction() || IsAnchorSizeFunction();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool StyleInset::MaybeAuto() const {
|
||||
return IsAuto() || IsAnchorPositioningFunction();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool StyleInset::MaybePercentageAware() const {
|
||||
return HasPercent() || IsAnchorPositioningFunction();
|
||||
}
|
||||
|
||||
#undef IMPL_LENGTHPERCENTAGE_FORWARDS
|
||||
|
||||
template <>
|
||||
|
||||
@@ -1910,18 +1910,20 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetNonStaticPositionOffset(
|
||||
PercentageBaseGetter aHeightGetter) {
|
||||
const nsStylePosition* positionData = StylePosition();
|
||||
int32_t sign = 1;
|
||||
auto coord = positionData->GetInset(aSide);
|
||||
const auto positionProperty = StyleDisplay()->mPosition;
|
||||
auto coord = positionData->GetAnchorResolvedInset(aSide, positionProperty);
|
||||
|
||||
if (!coord.IsLengthPercentage()) {
|
||||
if (coord.IsAuto()) {
|
||||
if (!aResolveAuto) {
|
||||
auto val = MakeRefPtr<nsROCSSPrimitiveValue>();
|
||||
val->SetString("auto");
|
||||
return val.forget();
|
||||
}
|
||||
coord = positionData->GetInset(NS_OPPOSITE_SIDE(aSide));
|
||||
coord = positionData->GetAnchorResolvedInset(NS_OPPOSITE_SIDE(aSide),
|
||||
positionProperty);
|
||||
sign = -1;
|
||||
}
|
||||
if (!coord.IsLengthPercentage()) {
|
||||
if (coord.IsAuto()) {
|
||||
return PixelsToCSSValue(0.0f);
|
||||
}
|
||||
|
||||
@@ -1943,14 +1945,17 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetNonStaticPositionOffset(
|
||||
|
||||
already_AddRefed<CSSValue> nsComputedDOMStyle::GetAbsoluteOffset(
|
||||
mozilla::Side aSide) {
|
||||
const auto& coord = StylePosition()->GetInset(aSide);
|
||||
const auto& oppositeCoord =
|
||||
StylePosition()->GetInset(NS_OPPOSITE_SIDE(aSide));
|
||||
const auto positionProperty = StyleDisplay()->mPosition;
|
||||
const auto coord =
|
||||
StylePosition()->GetAnchorResolvedInset(aSide, positionProperty);
|
||||
const auto oppositeCoord = StylePosition()->GetAnchorResolvedInset(
|
||||
NS_OPPOSITE_SIDE(aSide), positionProperty);
|
||||
|
||||
if (coord.IsAuto() || oppositeCoord.IsAuto()) {
|
||||
return AppUnitsToCSSValue(GetUsedAbsoluteOffset(aSide));
|
||||
}
|
||||
|
||||
// TODO(dshin): We're resolving anchor offset potentially twice...
|
||||
return GetNonStaticPositionOffset(
|
||||
aSide, false, &nsComputedDOMStyle::GetCBPaddingRectWidth,
|
||||
&nsComputedDOMStyle::GetCBPaddingRectHeight);
|
||||
@@ -2022,7 +2027,13 @@ nscoord nsComputedDOMStyle::GetUsedAbsoluteOffset(mozilla::Side aSide) {
|
||||
already_AddRefed<CSSValue> nsComputedDOMStyle::GetStaticOffset(
|
||||
mozilla::Side aSide) {
|
||||
auto val = MakeRefPtr<nsROCSSPrimitiveValue>();
|
||||
SetValueToInset(val, StylePosition()->GetInset(aSide));
|
||||
const auto resolved =
|
||||
StylePosition()->GetAnchorResolvedInset(aSide, StyleDisplay()->mPosition);
|
||||
if (resolved.IsAuto()) {
|
||||
val->SetString("auto");
|
||||
} else {
|
||||
SetValueToLengthPercentage(val, resolved.AsLengthPercentage(), false);
|
||||
}
|
||||
return val.forget();
|
||||
}
|
||||
|
||||
@@ -2148,17 +2159,6 @@ void nsComputedDOMStyle::SetValueToLengthPercentageOrAuto(
|
||||
aClampNegativeCalc);
|
||||
}
|
||||
|
||||
void nsComputedDOMStyle::SetValueToInset(nsROCSSPrimitiveValue* aValue,
|
||||
const mozilla::StyleInset& aInset) {
|
||||
// This function isn't used for absolutely positioned insets, so just assume
|
||||
// `anchor()` or `anchor-size()` is `auto`.
|
||||
if (!aInset.IsLengthPercentage()) {
|
||||
aValue->SetString("auto");
|
||||
return;
|
||||
}
|
||||
SetValueToLengthPercentage(aValue, aInset.AsLengthPercentage(), false);
|
||||
}
|
||||
|
||||
void nsComputedDOMStyle::SetValueToMargin(nsROCSSPrimitiveValue* aValue,
|
||||
const mozilla::StyleMargin& aMargin) {
|
||||
// May have to compute `anchor-size()` value here.
|
||||
|
||||
@@ -287,8 +287,6 @@ class nsComputedDOMStyle final : public nsDOMCSSDeclaration,
|
||||
void SetValueToLengthPercentageOrAuto(nsROCSSPrimitiveValue* aValue,
|
||||
const LengthPercentageOrAuto&,
|
||||
bool aClampNegativeCalc);
|
||||
void SetValueToInset(nsROCSSPrimitiveValue* aValue,
|
||||
const mozilla::StyleInset&);
|
||||
void SetValueToMargin(nsROCSSPrimitiveValue* aValue,
|
||||
const mozilla::StyleMargin&);
|
||||
|
||||
|
||||
@@ -1309,8 +1309,12 @@ nsChangeHint nsStylePosition::CalcDifference(
|
||||
// Don't try to handle changes between types efficiently; at least for
|
||||
// changing into/out of `auto`, we will hardly ever be able to avoid a reflow.
|
||||
// TODO(dshin, Bug 1917695): Re-evaulate this for `anchor()`.
|
||||
if (!InsetEquals(aNewData)) {
|
||||
if (IsEqualInsetType(mOffset, aNewData.mOffset)) {
|
||||
if (mOffset != aNewData.mOffset) {
|
||||
if (IsEqualInsetType(mOffset, aNewData.mOffset) &&
|
||||
aNewData.mOffset.All([](const StyleInset& aInset) {
|
||||
// Err on the side of triggering reflow for anchor positioning.
|
||||
return !aInset.IsAnchorPositioningFunction();
|
||||
})) {
|
||||
hint |=
|
||||
nsChangeHint_RecomputePosition | nsChangeHint_UpdateParentOverflow;
|
||||
} else {
|
||||
@@ -1378,49 +1382,51 @@ nsStylePosition::AnchorResolvedInset nsStylePosition::GetAnchorResolvedInset(
|
||||
};
|
||||
switch (inset.tag) {
|
||||
case StyleInset::Tag::Auto:
|
||||
return AnchorResolvedInset{InsetAuto{}};
|
||||
return AnchorResolvedInset{AnchorResolvedInset::V{InsetAuto{}}};
|
||||
case StyleInset::Tag::LengthPercentage: {
|
||||
const auto& lp = inset.AsLengthPercentage();
|
||||
if (lp.IsCalc()) {
|
||||
const auto& c = lp.AsCalc();
|
||||
if (!c.has_anchor_function) {
|
||||
return AnchorResolvedInset{LengthPercentageReference{lp}};
|
||||
return AnchorResolvedInset{
|
||||
AnchorResolvedInset::V{LengthPercentageReference{lp}}};
|
||||
}
|
||||
auto resolved = StyleCalcAnchorPositioningFunctionResolution::Invalid();
|
||||
Servo_ResolveAnchorPositioningFunctionInCalc(&c, side(aSide), aPosition,
|
||||
&resolved);
|
||||
if (resolved.IsInvalid()) {
|
||||
return AnchorResolvedInset{InsetAuto{}};
|
||||
return AnchorResolvedInset{AnchorResolvedInset::V{InsetAuto{}}};
|
||||
}
|
||||
return AnchorResolvedInset{resolved.AsValid()};
|
||||
return AnchorResolvedInset{AnchorResolvedInset::V{resolved.AsValid()}};
|
||||
}
|
||||
return AnchorResolvedInset{LengthPercentageReference{lp}};
|
||||
return AnchorResolvedInset{
|
||||
AnchorResolvedInset::V{LengthPercentageReference{lp}}};
|
||||
}
|
||||
case StyleInset::Tag::AnchorFunction: {
|
||||
auto resolved = StyleAnchorPositioningFunctionResolution::Invalid();
|
||||
Servo_ResolveAnchorFunction(&*inset.AsAnchorFunction(), side(aSide),
|
||||
aPosition, &resolved);
|
||||
if (resolved.IsInvalid()) {
|
||||
return AnchorResolvedInset{InsetAuto{}};
|
||||
return AnchorResolvedInset{AnchorResolvedInset::V{InsetAuto{}}};
|
||||
}
|
||||
if (resolved.IsResolvedReference()) {
|
||||
const auto* fallback = resolved.AsResolvedReference();
|
||||
return AnchorResolvedInset{LengthPercentageReference{*fallback}};
|
||||
return AnchorResolvedInset{AnchorResolvedInset::V{LengthPercentageReference{*fallback}}};
|
||||
}
|
||||
return AnchorResolvedInset{resolved.AsResolved()};
|
||||
return AnchorResolvedInset{AnchorResolvedInset::V{resolved.AsResolved()}};
|
||||
}
|
||||
case StyleInset::Tag::AnchorSizeFunction: {
|
||||
auto resolved = StyleAnchorPositioningFunctionResolution::Invalid();
|
||||
Servo_ResolveAnchorSizeFunction(&*inset.AsAnchorSizeFunction(), aPosition,
|
||||
&resolved);
|
||||
if (resolved.IsInvalid()) {
|
||||
return AnchorResolvedInset{InsetAuto{}};
|
||||
return AnchorResolvedInset{AnchorResolvedInset::V{InsetAuto{}}};
|
||||
}
|
||||
if (resolved.IsResolvedReference()) {
|
||||
const auto* fallback = resolved.AsResolvedReference();
|
||||
return AnchorResolvedInset{LengthPercentageReference{*fallback}};
|
||||
return AnchorResolvedInset{AnchorResolvedInset::V{LengthPercentageReference{*fallback}}};
|
||||
}
|
||||
return AnchorResolvedInset{resolved.AsResolved()};
|
||||
return AnchorResolvedInset{AnchorResolvedInset::V{resolved.AsResolved()}};
|
||||
}
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unhandled inset type");
|
||||
@@ -1434,7 +1440,6 @@ nsStylePosition::AnchorResolvedInset nsStylePosition::GetAnchorResolvedInset(
|
||||
return GetAnchorResolvedInset(aWM.PhysicalSide(aSide), aPosition);
|
||||
}
|
||||
|
||||
MOZ_RUNINIT const StyleInset nsStylePosition::kAutoInset = StyleInset::Auto();
|
||||
MOZ_RUNINIT const StyleSize nsStylePosition::kAutoSize = StyleSize::Auto();
|
||||
MOZ_RUNINIT const StyleMaxSize nsStylePosition::kNoneMaxSize =
|
||||
StyleMaxSize::None();
|
||||
|
||||
@@ -726,10 +726,18 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition {
|
||||
// Returns whether we need to compute an hypothetical position if we were
|
||||
// absolutely positioned.
|
||||
bool NeedsHypotheticalPositionIfAbsPos() const {
|
||||
return (GetInset(mozilla::eSideRight).IsAuto() &&
|
||||
GetInset(mozilla::eSideLeft).IsAuto()) ||
|
||||
(GetInset(mozilla::eSideTop).IsAuto() &&
|
||||
GetInset(mozilla::eSideBottom).IsAuto());
|
||||
return (GetAnchorResolvedInset(mozilla::eSideRight,
|
||||
mozilla::StylePositionProperty::Absolute)
|
||||
.IsAuto() &&
|
||||
GetAnchorResolvedInset(mozilla::eSideLeft,
|
||||
mozilla::StylePositionProperty::Absolute)
|
||||
.IsAuto()) ||
|
||||
(GetAnchorResolvedInset(mozilla::eSideTop,
|
||||
mozilla::StylePositionProperty::Absolute)
|
||||
.IsAuto() &&
|
||||
GetAnchorResolvedInset(mozilla::eSideBottom,
|
||||
mozilla::StylePositionProperty::Absolute)
|
||||
.IsAuto());
|
||||
}
|
||||
|
||||
const mozilla::StyleContainIntrinsicSize& ContainIntrinsicBSize(
|
||||
@@ -839,41 +847,39 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition {
|
||||
|
||||
struct InsetAuto {};
|
||||
using LengthPercentageReference = std::reference_wrapper<const mozilla::StyleLengthPercentage>;
|
||||
using AnchorResolvedInset =
|
||||
mozilla::Variant<InsetAuto, LengthPercentageReference,
|
||||
struct AnchorResolvedInset {
|
||||
using V = mozilla::Variant<InsetAuto, LengthPercentageReference,
|
||||
mozilla::StyleLengthPercentage>;
|
||||
V mVariant;
|
||||
|
||||
bool IsAuto() const { return mVariant.is<InsetAuto>(); }
|
||||
|
||||
const mozilla::StyleLengthPercentage& AsLengthPercentage() const {
|
||||
const bool isReference = mVariant.is<LengthPercentageReference>();
|
||||
MOZ_ASSERT(isReference || mVariant.is<mozilla::StyleLengthPercentage>(),
|
||||
"Not LengthPercentage type");
|
||||
if (isReference) {
|
||||
return mVariant.as<LengthPercentageReference>().get();
|
||||
}
|
||||
return mVariant.as<mozilla::StyleLengthPercentage>();
|
||||
}
|
||||
|
||||
bool HasPercent() const {
|
||||
if (IsAuto()) {
|
||||
return false;
|
||||
}
|
||||
return AsLengthPercentage().HasPercent();
|
||||
}
|
||||
};
|
||||
|
||||
// TODO(dshin): These inset getters are to be removed when
|
||||
// interleaving computation is implemented.
|
||||
AnchorResolvedInset GetAnchorResolvedInset(
|
||||
mozilla::Side aSide, mozilla::StylePositionProperty aPosition) const;
|
||||
AnchorResolvedInset GetAnchorResolvedInset(
|
||||
mozilla::LogicalSide aSide, WritingMode aWM,
|
||||
mozilla::StylePositionProperty aPosition) const;
|
||||
|
||||
// TODO(dshin): The following functions are used as shims to deal
|
||||
// anchor positioning functions as if it's `auto`, before the computation
|
||||
// is implemented.
|
||||
static const mozilla::StyleInset kAutoInset;
|
||||
const mozilla::StyleInset& GetInset(mozilla::Side aSide) const {
|
||||
const auto& result = mOffset.Get(aSide);
|
||||
if (MOZ_UNLIKELY(result.IsAnchorPositioningFunction())) {
|
||||
return kAutoInset;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool InsetEquals(const nsStylePosition& aOther) const {
|
||||
for (const auto side : mozilla::AllPhysicalSides()) {
|
||||
if (GetInset(side) != aOther.GetInset(side)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// As with other logical-coordinate accessors, definitions for these
|
||||
// are found in WritingModes.h.
|
||||
inline const mozilla::StyleInset& GetInset(mozilla::LogicalSide aSide,
|
||||
WritingMode) const;
|
||||
|
||||
// TODO(dshin): These size getters can be removed when anchor
|
||||
// size is actually calculated.
|
||||
static const StyleSize kAutoSize;
|
||||
|
||||
@@ -1154,6 +1154,8 @@ renaming_overrides_prefixing = true
|
||||
inline nscoord ToLength() const;
|
||||
inline bool ConvertsToPercentage() const;
|
||||
inline float ToPercentage() const;
|
||||
inline bool MaybeAuto() const;
|
||||
inline bool MaybePercentageAware() const;
|
||||
"""
|
||||
|
||||
"GenericMargin" = """
|
||||
|
||||
Reference in New Issue
Block a user